Mouse too fast for PureBasic?
-
- Enthusiast
- Posts: 107
- Joined: Thu May 06, 2010 11:36 pm
Mouse too fast for PureBasic?
Hello,
i currently write a little 2D game and got a weird problem. I use the mouse commands to navigate on a map, but sadly ExamineMouse() fails often. (The problem doesnt have to do anything with my code, the same problem also occurs with the PureBasic default example Mouse.pb)
After some time i figured out that it had something to do with my mouse (Logitech G5). After exchanging it with another mouse it worked perfect. So i played a bit with the mouse driver and found out that the problem has something to do with the status updates per second.
I can set it to 125, 200, 250, 333, 500 ,1000. If i set it to 1000 it is almost impossible to use the mouse commands. Something around 200 seems to cause a good result. In other games my mouse always worked perfect with the default settings (1000), so it seems to be a bug with PureBasic ? Has someone of you discovered the same problem or knows a solution for it?
DarkPlayer
i currently write a little 2D game and got a weird problem. I use the mouse commands to navigate on a map, but sadly ExamineMouse() fails often. (The problem doesnt have to do anything with my code, the same problem also occurs with the PureBasic default example Mouse.pb)
After some time i figured out that it had something to do with my mouse (Logitech G5). After exchanging it with another mouse it worked perfect. So i played a bit with the mouse driver and found out that the problem has something to do with the status updates per second.
I can set it to 125, 200, 250, 333, 500 ,1000. If i set it to 1000 it is almost impossible to use the mouse commands. Something around 200 seems to cause a good result. In other games my mouse always worked perfect with the default settings (1000), so it seems to be a bug with PureBasic ? Has someone of you discovered the same problem or knows a solution for it?
DarkPlayer
My blog: http://fds-team.de/cms/
Re: Mouse too fast for PureBasic?
Not really a bug with PureBasic.
It's got to do with the USB report rate and the system's timing resoution.
200 is like 5ms. while 1000 would equal 1ms. It's almost impossible to get any normal OS to be fully consistent at 1ms, 2ms (500Hz setting on mice) should work ok though.
Not all mice report in hardware their polling/report rate and might need a driver or "tool" to change the USB report rate for that device.
Mice like A4 Tech's X7 series let you set the mouse to tell the hardware/OS the rate, while Logitech (at least older mice) need the Logitech software software to set this, ditto with most Windows branded mice.
You also say you are using ExamineMouse() please be aware that the looping of the program is limited to the timing granularty of the system.
So if the OS is running on 5ms then it at best can only handle 200Hz. By default Windows is set to 15ms I believe. (66.xxxx something Hz).
Windows Media player tends to set the system to 5ms. Some not so system friendly apps tend to set it to 1ms, MicroSoft advice 2ms as minimum to avoid the increased CPU load that 1ms might cause.
It's got to do with the USB report rate and the system's timing resoution.
200 is like 5ms. while 1000 would equal 1ms. It's almost impossible to get any normal OS to be fully consistent at 1ms, 2ms (500Hz setting on mice) should work ok though.
Not all mice report in hardware their polling/report rate and might need a driver or "tool" to change the USB report rate for that device.
Mice like A4 Tech's X7 series let you set the mouse to tell the hardware/OS the rate, while Logitech (at least older mice) need the Logitech software software to set this, ditto with most Windows branded mice.
You also say you are using ExamineMouse() please be aware that the looping of the program is limited to the timing granularty of the system.
So if the OS is running on 5ms then it at best can only handle 200Hz. By default Windows is set to 15ms I believe. (66.xxxx something Hz).
Windows Media player tends to set the system to 5ms. Some not so system friendly apps tend to set it to 1ms, MicroSoft advice 2ms as minimum to avoid the increased CPU load that 1ms might cause.
-
- Enthusiast
- Posts: 107
- Joined: Thu May 06, 2010 11:36 pm
Re: Mouse too fast for PureBasic?
This does not explain why i can move the mouse without a problem in every other program, but when i use 1000 and ExamineMouse() it only works like 1 or 2 times in a second. The weird thing is that i can move the mouse straight without a problem, but when i move it diagonally it stops working.Rescator wrote:Not really a bug with PureBasic.
It's got to do with the USB report rate and the system's timing resoution.
200 is like 5ms. while 1000 would equal 1ms. It's almost impossible to get any normal OS to be fully consistent at 1ms, 2ms (500Hz setting on mice) should work ok though.
Not all mice report in hardware their polling/report rate and might need a driver or "tool" to change the USB report rate for that device.
Mice like A4 Tech's X7 series let you set the mouse to tell the hardware/OS the rate, while Logitech (at least older mice) need the Logitech software software to set this, ditto with most Windows branded mice.
You also say you are using ExamineMouse() please be aware that the looping of the program is limited to the timing granularty of the system.
So if the OS is running on 5ms then it at best can only handle 200Hz. By default Windows is set to 15ms I believe. (66.xxxx something Hz).
Windows Media player tends to set the system to 5ms. Some not so system friendly apps tend to set it to 1ms, MicroSoft advice 2ms as minimum to avoid the increased CPU load that 1ms might cause.
My blog: http://fds-team.de/cms/
Re: Mouse too fast for PureBasic?
That does not sound like a PureBasic issue, it seems more like a bug in your code, you should completely isolate (make a tiny mouse tool) as it could be due to the way you poll or calculate. (some source would help to spot any issue), sounds to me like there is a delay or pause in the code somewhere.
You could take a peek at this small tool, although it doesn't use the same call it might be helpful to test with or compare against...
http://www.purebasic.fr/english/viewtop ... 14&t=43281
You could take a peek at this small tool, although it doesn't use the same call it might be helpful to test with or compare against...
http://www.purebasic.fr/english/viewtop ... 14&t=43281
Re: Mouse too fast for PureBasic?
As I realize it might be difficult to turn that source into one that works with a DirectX screen I quickly did this example.
(incidentally the mouse thread also shows how to make a very rudimentary monitor refresh rate independent graphics rending thread. something I realized afterward *laughs*)
Hopefully this will help you spot the issue.
I assume you simply used MouseX and MouseY, it might be better to use the delta functions instead.
You might also want to read this: Taking Advantage of High-Definition Mouse Movement http://msdn.microsoft.com/en-us/library ... 85%29.aspx
(incidentally the mouse thread also shows how to make a very rudimentary monitor refresh rate independent graphics rending thread. something I realized afterward *laughs*)
Hopefully this will help you spot the issue.
I assume you simply used MouseX and MouseY, it might be better to use the delta functions instead.
You might also want to read this: Taking Advantage of High-Definition Mouse Movement http://msdn.microsoft.com/en-us/library ... 85%29.aspx
Code: Select all
; Copyright (c) 2010 Roger Hågensen, EmSai.
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Permission is granted to anyone to use this software for any purpose,
; including commercial applications, and to alter it and redistribute it
; freely, subject to the following restrictions:
;
; 1. The origin of this software must not be misrepresented; you must not
; claim that you wrote the original software. If you use this software
; in a product, an acknowledgment in the product documentation would be
; appreciated but is not required.
;
; 2. Altered source versions must be plainly marked as such, and must not be
; misrepresented as being the original software.
;
; 3. This notice may not be removed or altered from any source
; distribution.
;
; http://www.EmSai.net/projects/mousespeed/
Enumeration 0
#Mouserate_Init
#Mouserate_Quit
#Mouserate_Reset
EndEnumeration
Procedure Mouserate_Thread(flag.i)
Static quit.i=#False,reset.i=#False
Define time.l,oldtime.l,dpi.l
Define x.l,y.l,oldx.l,y.l,oldy.l,dif.l,pix_peak.l,pix_max.l,ydif.l,xdif.l,timesum.l,timesumpeak.l,dist.l
If flag=#Mouserate_Init
time=timeGetTime_()
ExamineMouse()
x=MouseDeltaX()
y=MouseDeltaY()
oldtime=time
oldx=x
oldy=y
Repeat
timesum=time-oldtime
If timesum>timesumpeak
timesumpeak=timesum
EndIf
If (x<>oldx) Or (y<>oldy)
xdif=(x-oldx)
dist+1
If xdif<0
xdif=-xdif
EndIf
ydif=(y-oldy)
If ydif<0
ydif=-ydif
EndIf
If xdif=0
xdif=1
EndIf
If ydif=0
ydif=1
EndIf
dif=xdif*ydif
If dif>pix_peak
pix_peak=dif
If pix_peak>pix_max
pix_max=dif
EndIf
EndIf
oldx=x
oldy=y
EndIf
If (time-oldtime)>999
FlipBuffers()
ClearScreen(RGB(0,0,0))
If StartDrawing(ScreenOutput())
DrawText(16,16,Str(pix_peak))
DrawText(16,32,Str(pix_max))
DrawText(16,64,Str(timesumpeak-1000)+"ms")
DrawText(16,48,Str(dist)+" Hz")
StopDrawing()
EndIf
timesumpeak=0
oldtime=time
dist=0
If pix_peak>0
pix_peak=0
EndIf
EndIf
If reset
pix_max=0
pix_peak=0
reset=#False
EndIf
Delay(1)
time=timeGetTime_()
ExamineMouse()
x=MouseDeltaX()
y=MouseDeltaY()
Until quit
quit=#False
Else
If flag=#Mouserate_Quit
quit=#True
While quit
Wend
ElseIf flag=#Mouserate_Reset
reset=#True
EndIf
EndIf
EndProcedure
timeBeginPeriod_(1)
If InitMouse() = 0 Or InitSprite() = 0
MessageRequester("Error", "Can't open DirectX 7", 0)
End
EndIf
;
;-------- MessageReq and OpenScreen --------
;
MessageRequester("Information", "This will test the fast mouse access..."+Chr(10)+"Press any mouse button to quit!", 0)
If OpenScreen(1920, 1080, 32, "Mouse",#PB_Screen_NoSynchronization) = 0
MessageRequester("Error", "Impossible to open a 800*600 16 bit screen",0)
End
EndIf
;
;-------- Init and Load Stuff --------
;
x = 100
y = 100
;
;-------- MainLoop --------
;
CreateThread(@Mouserate_Thread(),#Mouserate_Init)
Repeat
If IsScreenActive()
ReleaseMouse(0)
Else
ReleaseMouse(1)
EndIf
Delay(1)
Until MouseButton(#PB_MouseButton_Left) Or MouseButton(#PB_MouseButton_Right)
Mouserate_Thread(#Mouserate_Quit)
timeEndPeriod_(1)
End
Re: Mouse too fast for PureBasic?
It might not be a bug but it's not the USB timing, and it's always been this way DarkPlayer.Rescator wrote:Not really a bug with PureBasic.
If the mouse moves slowly it's fine but any movements a bit faster and it becomes jerky.
Check the two examples below 1st is PB's ExamineMouse() which is okay until you move the mouse fast (If your mouse is on 1000hz polling, 125hz and 500hz are fine)
It's not even that fast when it becomes jerky and ExamineMouse() doesn't update the position.
Code: Select all
InitSprite()
InitMouse()
OpenWindow(0, 0, 0, 640, 480, "Crap Mouse Movement", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered | #PB_Window_BorderLess)
OpenWindowedScreen(WindowID(0), 0, 0, 640, 480, 0, 0, 0, #PB_Screen_SmartSynchronization)
CreateSprite(0, 32, 32)
StartDrawing(SpriteOutput(0))
Box(0, 0, 32, 32, #Blue)
StopDrawing()
Repeat
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_CloseWindow
Quit = 1
EndSelect
Until Event = 0
ClearScreen(#Black)
ExamineMouse()
DisplaySprite(0, MouseX(), MouseY())
FlipBuffers()
Delay(10)
Until Quit Or (GetKeyState_(#VK_ESCAPE)&%10000000 And GetActiveWindow() = pWnd)
CloseScreen()
End
So PB's ExamineMouse() doesn't work very well if you have a gaming mouse on 1000hz polling, maybe this should be said in the docs

Code: Select all
InitSprite()
OpenWindow(0, 0, 0, 640, 480, "Fine Mouse Movement", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered | #PB_Window_BorderLess)
OpenWindowedScreen(WindowID(0), 0, 0, 640, 480, 0, 0, 0, #PB_Screen_SmartSynchronization)
CreateSprite(0, 32, 32)
StartDrawing(SpriteOutput(0))
Box(0, 0, 32, 32, #Blue)
StopDrawing()
Repeat
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_CloseWindow
Quit = 1
EndSelect
Until Event = 0
ClearScreen(#Black)
DisplaySprite(0, WindowMouseX(0), WindowMouseY(0))
FlipBuffers()
Delay(10)
Until Quit Or (GetKeyState_(#VK_ESCAPE)&%10000000 And GetActiveWindow() = pWnd)
CloseScreen()
End

Re: Mouse too fast for PureBasic?
How about this then moogle? It performs almost the same as your second source.
This is basically a refresh rate independent input loop.
Now combine that with a refresh independent rendering loop and things should be smooth both input and output wise.
As you can see it's damn simple, and I even did (by accident) a rudimentary refresh independent graphics loop in the DirectX example previously. (it lacked a virtual framerate control though)
Odd that more games don't do this because I have seen the horrible jerking of the first source in your post moogle if Vsync is enabled. A clear sign that the input loop of the game is not refresh independent. In a good game you should be able to turn on Vsync (freeing up system resources since stuff only gets sent/drawn to the GFX card at the rate the monitor is actually able to display it).
Nothing worse than a game where input/output/AI etc. is dependent on the refresh rate, it shouldn't matter a single millisecond (pun intended) if Vsync is used or not.
(PS! The lag is due to the framerate or refresh as the sprite is moved at refresh intervals, while it should have been calculated independently, depending on the refresh it would still be jerky (it can't visually move faster than the refresh) in some situations but the lag should be gone though. Although I guess you could do motion blur to fool the eyei n that case.)
This is basically a refresh rate independent input loop.
Now combine that with a refresh independent rendering loop and things should be smooth both input and output wise.
As you can see it's damn simple, and I even did (by accident) a rudimentary refresh independent graphics loop in the DirectX example previously. (it lacked a virtual framerate control though)
Odd that more games don't do this because I have seen the horrible jerking of the first source in your post moogle if Vsync is enabled. A clear sign that the input loop of the game is not refresh independent. In a good game you should be able to turn on Vsync (freeing up system resources since stuff only gets sent/drawn to the GFX card at the rate the monitor is actually able to display it).
Nothing worse than a game where input/output/AI etc. is dependent on the refresh rate, it shouldn't matter a single millisecond (pun intended) if Vsync is used or not.
(PS! The lag is due to the framerate or refresh as the sprite is moved at refresh intervals, while it should have been calculated independently, depending on the refresh it would still be jerky (it can't visually move faster than the refresh) in some situations but the lag should be gone though. Although I guess you could do motion blur to fool the eyei n that case.)
Code: Select all
InitSprite()
InitMouse()
OpenWindow(0, 0, 0, 640, 480, "Crap Mouse Movement", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered | #PB_Window_BorderLess)
OpenWindowedScreen(WindowID(0), 0, 0, 640, 480, 0, 0, 0, #PB_Screen_SmartSynchronization)
CreateSprite(0, 32, 32)
StartDrawing(SpriteOutput(0))
Box(0, 0, 32, 32, #Blue)
StopDrawing()
Global mousex.i,mousey.i
Procedure mousethread(flag.i)
Static quit.i
If flag
Repeat
ExamineMouse()
mousex=MouseX()
mousey=MouseY()
Delay(1)
Until quit
quit=#False
Else
If Not flag
quit=#True
While quit
Delay(1)
Wend
EndIf
EndIF
EndProcedure
CreateThread(@mousethread(),#True)
Repeat
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_CloseWindow
Quit = 1
EndSelect
Until Event = 0
ClearScreen(#Black)
DisplaySprite(0, mousex, mousey)
FlipBuffers()
Delay(10)
Until Quit Or (GetKeyState_(#VK_ESCAPE)&%10000000 And GetActiveWindow() = pWnd)
mousethread(#False)
CloseScreen()
End
Re: Mouse too fast for PureBasic?
It works fine nowRescator wrote:How about this then moogle? It performs almost the same as your second source.

So in the first example is the flipbuffers() limiting the refresh rate and loop code too? I always thought that if vsync is on it wouldn't flip until needed but game code runs at full speed.

Re: Mouse too fast for PureBasic?
What is "full speed" ? Only the programmer can define that. And how can it know when it needs to flip? Only you can tell it when to flip by using the flip command (the only thing it will do is try to make sure a flip when it happens is in sync wit the refresh).moogle wrote:It works fine nowRescator wrote:How about this then moogle? It performs almost the same as your second source.
So in the first example is the flipbuffers() limiting the refresh rate and loop code too? I always thought that if vsync is on it wouldn't flip until needed but game code runs at full speed.
In your second source you artificially limited the game speed or main loop thread (or only loop thread in your case) to let's see. 1000ms/10=100fps.
But since my monitor (and yours as well if a typical LCD) is 60fps. If you where to set OpenScreen to use no sync then you would get 100fps (as per your Delay) but you would also get tearing in the graphics.
Then again, no point in 100fps if only 60 of them is displayed on the monitor anyway, that's 40 frames of wasted rendering that could be used for other stuff. (as well as 40% waste of GPU/CPU), I'm pretty sure a nice motion blur could be done using 40% of the rending resources, or maybe let the user use higher antialising etc...
From PB manual on OpenScreen and vsync/flipbuffers: "This also link the flip frequence to the actual screen refresh, ie: for 60Hz screen it could have at most 60 flip per seconds,"
60Hz vsync would thus equal around 16ms delay in the loop with vsync off. (but you'd get tearing obviously)
If you remove the delay you get rid of the jerkiness, although due to the independent input thread in my example it doesn't really matter if the delay is there, as the mouse movement is not really affected at all.

Normally you would have a main loop, then a graphics thread, and a input thread (mouse + keyboard) an audio thread, and a AI/calculations thread, and possibly a timer thread running at 1ms or 2ms to help make syncing all the stuff easier.
The main loop would mostly just sit there. maybe only using WaitWindowEvent() as it really only need to pay attention to a Close event or loosing window/screen focus and so on.
The OS would probably put the main, input and timer threads on a single core, and the graphics on it's own core and the AI and Audio on a third core, dependent on anything else already running on the system obviously. Some games may even have worker queues and a worker thread as well.
To put it another way. If a "typical" PureBasic game performs worse than Crysis then it's not PureBasic (or Fred's) fault but rather the programmer for not taking advantage of threading to make input and output and other things refresh rate independent.
And for example the graphics thread, optimally if nothing has visually changed then there is no need to really render the scene again, just simply repeat the last frame. (depending on the implementation this may mean a buffer flip or so, or it might simply mean to not flip at all since the GFX card is currently showing the previous frame anyway).
Re: Mouse too fast for PureBasic?
Thanks for the explanation Rescator, it's never been explained that those parts of a game need to be in their own threads (and I'll admit I haven't used them much either
)


Re: Mouse too fast for PureBasic?
Well, you don't have to, you could in theory do it all in one thread (the main process thread you always have) but it would not be that efficient.
Another benefit with the program spread over threads in that particular case (games esp.) is that certain threads can run at different speeds.
A graphics thread should only run at max the refresh rate, but could also throttle down to 0fps when appropriate. Timing threads would need very high fps like 1ms or 2ms (1000 or 500fps) to make sure timing is very consistent, an audio thread would need a "fps" that matches the audio playback and buffering etc. A Network thread would have to have a speed that fits the latency/speed of the network.
But in all cases those are max speeds, all threads should be able to throttle down if there is little or nothing to do.
Example: all threads (like the graphics thread) throttle down because the game scene is very quiet right now, all except the scene calculation or AI thread that are using all the extra free CPU because in just a few moments as the player rounds the corner all hell will break loose with hundreds of NPC's fighting each other in a huge battle.
So conserving CPU and GPU when possible is always wise as you never know when you need it, or in that particular case even planning ahead and taking advantage of it in the game design.
The end result is that for the player they get to have a smooth experience from being alone in a tiny corridor and exiting into a huge battle with hundreds of characters with barely a hiccup. (assuming the graphics card doesn't choke that is... *laughs*)
Take these two examples:
The first one there is no graphics updates when there is nothing to update.
And in the second it is the same, but in addition the entire flipping is avoided as well,
so in the 2nd source the graphics card isn't even "used" unless there is stuff to update.
The 2nd source is obviously more sensitive to timing issues. And I have no idea how much CPU is saved comparing the two sources.
But I assume that not having to flip buffers saves bandwidth (+CPU?) and some GPU as well.
Note that the source above is "slightly" flawed, it should be tweaked some more because currently you could end up with a slight shimmering as the buffer is flipped back and forth,
basically both buffers should be identical first.
Another benefit with the program spread over threads in that particular case (games esp.) is that certain threads can run at different speeds.
A graphics thread should only run at max the refresh rate, but could also throttle down to 0fps when appropriate. Timing threads would need very high fps like 1ms or 2ms (1000 or 500fps) to make sure timing is very consistent, an audio thread would need a "fps" that matches the audio playback and buffering etc. A Network thread would have to have a speed that fits the latency/speed of the network.
But in all cases those are max speeds, all threads should be able to throttle down if there is little or nothing to do.
Example: all threads (like the graphics thread) throttle down because the game scene is very quiet right now, all except the scene calculation or AI thread that are using all the extra free CPU because in just a few moments as the player rounds the corner all hell will break loose with hundreds of NPC's fighting each other in a huge battle.
So conserving CPU and GPU when possible is always wise as you never know when you need it, or in that particular case even planning ahead and taking advantage of it in the game design.
The end result is that for the player they get to have a smooth experience from being alone in a tiny corridor and exiting into a huge battle with hundreds of characters with barely a hiccup. (assuming the graphics card doesn't choke that is... *laughs*)
Take these two examples:
The first one there is no graphics updates when there is nothing to update.
And in the second it is the same, but in addition the entire flipping is avoided as well,
so in the 2nd source the graphics card isn't even "used" unless there is stuff to update.
The 2nd source is obviously more sensitive to timing issues. And I have no idea how much CPU is saved comparing the two sources.
But I assume that not having to flip buffers saves bandwidth (+CPU?) and some GPU as well.
Code: Select all
InitSprite()
InitMouse()
OpenWindow(0, 0, 0, 640, 480, "Crap Mouse Movement", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered | #PB_Window_BorderLess)
OpenWindowedScreen(WindowID(0), 0, 0, 640, 480, 0, 0, 0, #PB_Screen_SmartSynchronization)
CreateSprite(0, 32, 32)
StartDrawing(SpriteOutput(0))
Box(0, 0, 32, 32, #Blue)
StopDrawing()
Global mousex.i,mousey.i
Procedure mousethread(flag.i)
Static quit.i
If flag
Repeat
ExamineMouse()
mousex=MouseX()
mousey=MouseY()
Delay(1)
Until quit
quit=#False
Else
If Not flag
quit=#True
While quit
Delay(1)
Wend
EndIf
EndIF
EndProcedure
Define oldmousex.i,oldmousey.i
CreateThread(@mousethread(),#True)
Repeat
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_CloseWindow
Quit = 1
EndSelect
Until Event = 0
If mousex<>oldmousex Or mousey<>oldmousey ;only update graphics if something has changed.
oldmousex=mousex
oldmousey=mousey
ClearScreen(#Black)
DisplaySprite(0, mousex, mousey)
EndIf
FlipBuffers() ;Just to keep our loop synced to the refresh, could be improved to avoid the flip as well.
Until Quit Or (GetKeyState_(#VK_ESCAPE)&%10000000 And GetActiveWindow() = pWnd)
mousethread(#False)
CloseScreen()
End
basically both buffers should be identical first.
Code: Select all
InitSprite()
InitMouse()
OpenWindow(0, 0, 0, 640, 480, "Crap Mouse Movement", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered | #PB_Window_BorderLess)
OpenWindowedScreen(WindowID(0), 0, 0, 640, 480, 0, 0, 0, #PB_Screen_SmartSynchronization)
CreateSprite(0, 32, 32)
StartDrawing(SpriteOutput(0))
Box(0, 0, 32, 32, #Blue)
StopDrawing()
Global mousex.i,mousey.i
Procedure mousethread(flag.i)
Static quit.i
If flag
Repeat
ExamineMouse()
mousex=MouseX()
mousey=MouseY()
Delay(1)
Until quit
quit=#False
Else
If Not flag
quit=#True
While quit
Delay(1)
Wend
EndIf
EndIF
EndProcedure
Define oldmousex.i,oldmousey.i
CreateThread(@mousethread(),#True)
Repeat
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_CloseWindow
Quit = 1
EndSelect
Until Event = 0
If mousex<>oldmousex Or mousey<>oldmousey ;only update graphics if something has changed.
oldmousex=mousex
oldmousey=mousey
ClearScreen(#Black)
DisplaySprite(0,mousex, mousey)
FlipBuffers()
Else
;Kinda tricky this one, we avoid the flip if nothing is updated but we could hae a small delay "waking" up again.
Delay(10) ;This is aprox 100fps delay (1000/10=100), so we asically check 100 times per second if there was any changes or not when there are no changes.
EndIf
Until Quit Or (GetKeyState_(#VK_ESCAPE)&%10000000 And GetActiveWindow() = pWnd)
mousethread(#False)
CloseScreen()
End
Re: Mouse too fast for PureBasic?
This one is kinda neat, try to move the mouse as slow as possible. (like 1pixel at a time) the fps should be around 1fps.
Now move it faster and faster and you'll see the framerate go up until it maxes out at the refresh rate.
Now move it faster and faster and you'll see the framerate go up until it maxes out at the refresh rate.
Code: Select all
InitSprite()
InitMouse()
OpenWindow(0, 0, 0, 640, 480, "Crap Mouse Movement", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered | #PB_Window_BorderLess)
OpenWindowedScreen(WindowID(0), 0, 0, 640, 480, 0, 0, 0, #PB_Screen_SmartSynchronization)
CreateSprite(0, 32, 32)
StartDrawing(SpriteOutput(0))
Box(0, 0, 32, 32, #Blue)
StopDrawing()
Global mousex.i,mousey.i
Procedure mousethread(flag.i)
Static quit.i
If flag
Repeat
ExamineMouse()
mousex=MouseX()
mousey=MouseY()
Delay(1)
Until quit
quit=#False
Else
If Not flag
quit=#True
While quit
Delay(1)
Wend
EndIf
EndIF
EndProcedure
Define oldmousex.i,oldmousey.i
CreateThread(@mousethread(),#True)
Repeat
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_CloseWindow
Quit = 1
EndSelect
Until Event = 0
If mousex<>oldmousex Or mousey<>oldmousey ;only update graphics if something has changed.
oldmousex=mousex
oldmousey=mousey
ClearScreen(#Black)
DisplaySprite(0,mousex, mousey)
FlipBuffers()
fps+1
Else
;Kinda tricky this one, we avoid the flip if nothing is updated but we could hae a small delay "waking" up again.
Delay(10) ;This is aprox 100fps delay (1000/10=100), so we asically check 100 times per second if there was any changes or not when there are no changes.
EndIf
time=timeGetTime_()
If (time-oldtime)>999
Debug fps
oldtime=time
fps=0
EndIF
Until Quit Or (GetKeyState_(#VK_ESCAPE)&%10000000 And GetActiveWindow() = pWnd)
mousethread(#False)
CloseScreen()
End
Re: Mouse too fast for PureBasic?
I had this very problem with my G5 on 500-1000z. It turns out that the application is not looping fast enough to catch every mouse event. Delay(1) = 1000hz BUT Delay(1) is really Delay(15) unless you use
Code: Select all
timeBeginPeriod_(1)
Repeat
Delay(1)
;Your code here
Forever
timeEndPeriod_(1)
-
- User
- Posts: 37
- Joined: Mon Jul 13, 2009 5:41 pm
Re: Mouse too fast for PureBasic?
Interesting. Is there a way to control the mouse's refresh rate from a pb app, or do we need to create a thread looping every 1 ms to check the mouse in order to catch all events? But with that said, shouldn't the events be stored until you retreive them?
Re: Mouse too fast for PureBasic?
Well, I'm not sure if most games use timeBeginPeriod and timeEndPeriod any more, they may instead use Windows timer API's which will change the timing period of the system is needed (based on the period you wish to check for), result is the same though.jerico2day wrote:Interesting. Is there a way to control the mouse's refresh rate from a pb app, or do we need to create a thread looping every 1 ms to check the mouse in order to catch all events? But with that said, shouldn't the events be stored until you retreive them?
And yeah you would need a input thread to hope that it stays smooth, I guess you could merge the input thread into some other frequent thread, maybe a input/timer thread?
Depending on the game and how "fast" it is, i.e. the games "internal" FPS you may not need 1ms periods but could do ok with 2 or even just 5ms which is close to no system overhead on a modern system. (probably why Windows Media Player seems to only set the period to 5ms)
As for storing events until you need them? Outch. That could potentially mean 60 move left commands in a buffer which means your character could jerk or rubberband or skip into a wall if you are unlucky.
So a realtime game would need to know what the user is doing "right now" as far as input goes rather than what they did during the last "internal" frame.
A non-realtime or semi-realtime game does not have this issue at all and input can actually remain smooth even if it's in the GUI or main loop.
Maybe someone on the forum could put together a pong clone (or something) with a separate input, graphics, sound, main threads and let Fred put it in the PureBasic dist as an example of a good multitasking friendly but responsive and refresh independent game example, it should help a lot of amateurs make smoother games.
Reason I said a pong clone is that you do need smooth and accurate user input, and refresh independent graphics rendering will make the display smooth too,
and together they will make it very easy to do pixel perfect collision detection that actually work pretty damn well (1 pixel margin of error would be worst case scenario and acceptable in this case IMO) with minimal CPU load.