cool anti-mouse lag plan!

BlitzMax Forums/BlitzMax Programming/cool anti-mouse lag plan!

Grey Alien(Posted 2006) [#1]
OK, here's the plan, obviously you only need to implement the anti-mouse lag fixes discussed recently if you use DirectX (not OpenGL) AND there is an actual lag!

Why not implement them all the time? Well it's seems there is a performance hit on some systems, even for the most recent best fix.

How can you tell if there is a lag? Well you can't ask the user but you might be able to test it! This BlitzPlus function I wrote returns the mouse cursor in Windows:

Type RectType	
	Field RLeft%, RTop%, RRight%, RBottom%
End Type
Function ccGetCursorPos.PointType()
	;Returns a PointType that the user must free when they are finished with it
	pt.PointType = New PointType	
	If Not User32_GetCursorPos(pt) Then
    	ccRunTimeError ("Error Getting Cursor Pos")	
		Return Null
	Else
		Return pt
	EndIf
End Function


It used this line in user32.decls (which you can do now with extern right?)
User32_GetCursorPos%(lpPoint*):"GetCursorPos" 


If you compare the value of the windows cursor position over a few frames when it is moving against the BlitzMax returned mouse cursor position, will it be different I wonder? I haven't tested this yet... If it's different you know you have lag and how bad it is and can automatically turn on the mosuelag fix, cool! Or of course just use the returned values from that function as your cursor position (but I'm sure some of you would have though of this already hmm ...)

Of course this entire plan falls down if GetCursorPos returns the same position as the BlitzMax cursor pos in full-screen mode (the lag only affects full-screen mode anyway right? or is that wrong? Actually some of the tests might have been in windowed mode come to think of it) Or if I've misunderstood and it's not a problem reading the mouse coords it's just a delay in the DirectX rendering pipeline so what you see is several frames behind all input, including keyboard input, but that's not right is it? Sorry if I'm sounding dumb here but a) it's late and b) I never 100% understood the original problem but had a brainwave that this could be a solution ...

comments?


Gabriel(Posted 2006) [#2]
I don't think it will return a different value, but since I don't use Max2d, I haven't paid a great deal of attention to the issue, although I do see it was being a priority issue.

I've noticed a number of casual and non-casual games have a setting in their options panel called "Fix Mouse Lag". If it's good enough for some successful casual games, I don't see why not for others. That way, it's only enabled if the user sees a problem, which is what you want.

Granted, it's not perfect, but there doesn't appear to *be* a perfect solution, and as I said, they were pretty big games I saw this option in.

Just a thought.


Grey Alien(Posted 2006) [#3]
interesting you saw it in big games. I can't but help think the option is a bit naff though because I think lots of people WILL notice it and never explore the options, so may just not buy the game.


Gabriel(Posted 2006) [#4]
On the other hand, if you implement a mouse lag fix which slows the frame rate ( as all such current fixes appear to ) you're going to lower the frame rate for a lot of people who aren't even experiencing the mouse lag. Aren't you risking them not buying the game?

I'm not saying it's an easy decision. I'm just saying that you're already losing potential customers, so you need to decide which is going to lose you more. Or less.

I can't remember the last casual game I played which didn't have an option to switch between fullscreen and windowed. If people don't go looking for options then presumably anyone who wants a game to run in a window won't buy either, because they invaraibly start in fullscreen by default.


Grey Alien(Posted 2006) [#5]
you're going to lower the frame rate for a lot of people who aren't even experiencing the mouse lag
that's what this whole thread was about, ONLY switching on the fix if it's needed so most people won't be affected by the slower frame rate.

I know what you are saying about options, and yes some people won't look for a windowed mode, but others will because they have "learnt" that there is such an option and it's pretty standard. They might not look for a mosue lag or understand it relates to their problem when they read it.


Gabriel(Posted 2006) [#6]
Meh.. nm


Grey Alien(Posted 2006) [#7]
nm = no more or what?


Gabriel(Posted 2006) [#8]
nm = Never mind. I added something and then realised it was a bad idea, so I removed it again. Sorry, should have been more specific.


Grey Alien(Posted 2006) [#9]
ok no worries.


TartanTangerine (was Indiepath)(Posted 2006) [#10]
This lag, is it just movement or does it also effect clicks? Does the Lag go away if you use WM_MOUSEMOVE?


Grey Alien(Posted 2006) [#11]
haven't tested clicks or key input. It might be hard to spot with either of those though, unless that test code is used with the 1000 scaled textured drawn in loop I guess.


TartanTangerine (was Indiepath)(Posted 2006) [#12]
I would guess it's only mouse movement as Direct Input is not used to detect Mouse Clicks. Can someone confirm?


Robert Cummings(Posted 2006) [#13]
This mouse lag is an illusion. The mouse isn't lagging at all. In high fill rate & low poly situations, the graphics driver is buffering ahead, up to 100's of frames, depending on graphics memory.

You're just seeing history catch up.


Don't bother with these schemes. Fix the 'lag', keep it in and be done with it. The lag is fixed by forcing the driver to flush the frames it's buffered (grabpixmap) or preventing it (while...wend blt test). The rules for Present() option in DX9 means that the driver doesn't attempt this behaviour.

In DX7, Present() is sadly Absent() :)

Note, this will not happen on a lot of machines because those machines have a forced flip. Some laptops and pcs however don't wait for a vertical blank in hardware for whatever reason.


Grey Alien(Posted 2006) [#14]
so Blitz Max is affected as it uses DirectX 7 only even though I have DirectX9.0c installed?

So I just need to implement the anti-lag thing and stop chasing the true cursor position? Does this mean if I used keys to move a shape, it would also appear lagged due to the rendering catching up? I suppose so... I'll test this.


Grey Alien(Posted 2006) [#15]
OK I can 100% confirm that that all input (e.g. keys) is affected because it's a rendering lag, and that I was chasing a wild goose when just thinking of it as mouse lag.

Try this code:

'low poly and high fill rate causes the issue, solvable by flushing the driver's
'buffered frames using grab pixmap or locking a buffer with a large speed penalty.
'opengl is unaffected.

'change how many loops you do till you see the lag and not general slowdown
'this will vary from pc to pc

'SetGraphicsDriver GLMax2DDriver()
Graphics 800,600,0

AutoMidHandle True
image:TImage = LoadImage("arrow.bmp") 'any 32x32 image

Local fix = 0

mx = 300
my = 200

While Not KeyHit(KEY_ESCAPE)
  Cls
  
  If KeyHit(KEY_SPACE) Then fix = 1 - fix
  
  If KeyDown(KEY_Z) Then mx = mx - 10
  If KeyDown(KEY_X) Then mx = mx + 10
  
  SetScale 8,8
  For i = 0 To 1000
    DrawImage image,mx,my
  Next
  
  SetScale 1, 1
  DrawText "Fix = " + fix, 12, 12
  
  Flip
  
  If fix
    If TD3D7Max2DDriver(_max2dDriver)
      While DDERR_WASSTILLDRAWING = PrimaryDevice.PrimarySurface.GetBltStatus(DDGBS_ISBLTDONE) ; Wend
    EndIf
  EndIf
Wend
End


It clearly shows there is a lag when using keys too, and that the fix works!


TartanTangerine (was Indiepath)(Posted 2006) [#16]
I read that Sleep(1) also cures the issue. In BLitz Speak that would be Delay(1).


Grey Alien(Posted 2006) [#17]
yeah but who want's a 1ms delay in their main game loop when If you are running at 85Hz you've only got 11.7ms to play with to maintain smooth graphics?

ok just tested it (delay(1) after Flip) and it doesn't seem to work, would have been nce and easy if it did!


Robert Cummings(Posted 2006) [#18]
Delay does not cure the issue. I think I deserve a bit of trust here...


xlsior(Posted 2006) [#19]
"Compile Error -- Too many function parameters"

on the While DDERR_WASSTILLDRAWING = PrimaryDevice.PrimarySurface.GetBltStatus(DDGBS_ISBLTDONE) ; Wend line.


Yan(Posted 2006) [#20]
Yeah...You need to modify one of the modules for this to work.


Difference(Posted 2006) [#21]
I read that Sleep(1) also cures the issue. In BLitz Speak that would be Delay(1).

That dosen't fix it in Blitz3D. Makes it slightly better as does other "fixes", but: We need the DDERR_WASSTILLDRAWING wend loop as a Blitz3D function.


TartanTangerine (was Indiepath)(Posted 2006) [#22]
I'm just thinking about all those lost cycles while you are waiting for the flip to finish surely you would be better off updating the logic while you are waiting for the flip to occur or even better still only flip when required.

if PrimaryDevice.PrimarySurface.GetFlipStatus(DDGFS_ISFLIPDONE) = DD_OK Then Flip



Grey Alien(Posted 2006) [#23]
I hate lost cycles too (no this isn't a joke) so anyway to do more calculations meanwhile is better.


Robert Cummings(Posted 2006) [#24]
why not time how much time is wasted? I bet it is very little indeed.


TartanTangerine (was Indiepath)(Posted 2006) [#25]
With your existing solution you are putting the game into a loop until the renderer catches up, you are not suspending the app as you would with a delay command. This also means that if your game suddenly dives to < 10FPS your gonna be stuck in that loop for heck of a long time. What I am suggesting is that you check the Flip Status, if the GPU is still rendering then don't bother flipping the backbuffer, in fact if you check the Flip status before your render batch you might not even need to render anything that frame at all.