MouseSpeed

BlitzMax Forums/BlitzMax Beginners Area/MouseSpeed

flying willy(Posted 2005) [#1]
Anyone got mousespeed routine that -actually works- ?

I don't mean theory. When you use movemouse with it in order to prevent the mouse travelling off the edge of the screen, there's a lot of problems...


bradford6(Posted 2005) [#2]
Graphics 640,480,0
SetBlend ALPHABLEND
Repeat 
cls
	xsp:Int = mousespeed_x()
	ysp:Int = mousespeed_y()

	SetColor 0,0,200
	DrawRect 100,98,xsp*2,16
	DrawRect 100,128,ysp*2,16
	SetColor 255,255,0
	DrawText "Xspeed: "+xsp,100,100
	DrawText "Yspeed: "+ysp,100,130
	
Flip
Until MouseDown(1)

Function mousespeed_x()
	Global oldx#
		newx# = MouseX()
		speed# = oldx#-newX#
		oldx# = newx#
	Return Abs(speed)
End Function 

Function mousespeed_y()
	Global oldy#
		newy# = Mousey()
		speed# = oldy#-newy#
		oldy# = newy#
	Return Abs(speed)
End Function



flying willy(Posted 2005) [#3]
Thanks bill, that works until you use movemouse to stop it going off screen. Then it fails because it is always bouncing the same value back again.

This didn't occur in Blitz3D, and is the root of my problem.


skidracer(Posted 2005) [#4]
Have you tried the MoveMouse example code?


Wayward(Posted 2005) [#5]
I'm using something like this:
Type TMouse
	Field x, y
	
	Method Update()	
		x = x + MouseX() - (GraphicsWidth() / 2)
		y = y + MouseY() - (GraphicsHeight() / 2)
		MoveMouse GraphicsWidth() / 2, GraphicsHeight() / 2
	EndMethod
EndType



Dreamora(Posted 2005) [#6]
off screen means you are in windowed mode and actually there is no "real" windowed mode just for debug purposes. I hope this probs with "off screen" won't arise anymore with real window mode ( there are different other probs with windowed anyway so you better avoid it for "real use" situations )


flying willy(Posted 2005) [#7]
And in full screen.

In full screen, if you don't use movemouse properly. it will hit the edge of the screen and go no further, causing mouse speed to return bad values.

@ skid - will look for this example now.


Dreamora(Posted 2005) [#8]
Don't know how you used mousemov in Blitz3D but I positioned my mousepointer to center of the screen any frame and calculated it basing on the change from this. This works good for 3D games and for others I don't see much use of a "mousemovement" need as you only need the position to draw a mousepointer :)


flying willy(Posted 2005) [#9]
I need it.

Ever heard of a spinner gadget or dragging in the same spot?


Dreamora(Posted 2005) [#10]
yeah heard of but they do not actually need it ... just looks like they need it. But mousemove does only work as long as mouse can be moved -> border of the screen. Not really the optimal thing for spinner gadget and similar thing.

not always the way the system works "behind" is the same as you see. You can draw the mouse pointer in the same spot while dragging on spot and internally position the mouse at a specific point and calculation from this point for example.


flying willy(Posted 2005) [#11]
Look, I need MouseXSpeed, and so do many people - there's a reason for it existing, and thats that.


Dreamora(Posted 2005) [#12]
Then use the functions given above and don't use windowed and most problems should be solved


flying willy(Posted 2005) [#13]
Are you trying to wind me up or do you think you're being helpful? this has nothing to do with windowed mode.


flying willy(Posted 2005) [#14]
Skid: where is the movemouse example code? I have done this code and movemouse gives back bad results.

Basically, it keeps jumping back. The value will go up to say, 10, then when you let go of the mouse, you're looking at a -10 again.

What did mark do exactly with MouseXSpeed() under blitz?


skidracer(Posted 2005) [#15]
' movemouse.bmx

' demonstrates using the mouse as a proportional controller
' by locking the mouse to the center of the screen and reporting
' MouseXSpeed and MouseYSpeed variables 

Global MouseXSpeed,MouseYSpeed

Function SampleMouse()
	MouseXSpeed=MouseX()-320
	MouseYSpeed=MouseY()-240
	MoveMouse 320,240
End Function

Graphics 640,480

HideMouse
MoveMouse 320,240

While Not KeyHit(KEY_ESCAPE)
	SampleMouse
	Cls
	DrawText "MouseXSpeed="+MouseXSpeed,0,0
	DrawText "MouseYSpeed="+MouseYSpeed,0,20
	Flip
Wend



flying willy(Posted 2005) [#16]
aha,

my code was:
Graphics 1024,768,0,85

MoveMouse GraphicsWidth()/2,GraphicsHeight()/2

While Not KeyHit(KEY_ESCAPE)
	Cls
	
	'mousex and y speeds
	mx=MouseX();mxspd=oldmx-mx;oldmx=mx
	my=MouseY();myspd=oldmy-my;oldmy=my
	MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
		
	x:+mxspd
	y:+myspd
	
	DrawOval x,y,32,32
	
	FlushMem;Flip
	
Wend
End



Pudsy(Posted 2005) [#17]
Hi,

Apologies for resurrecting this ancient one, but the example code for keeping the mouse centred is behaving a little strangely here...

It works fine on Win32, but on Mac it seems to give odd results. Can anyone confirm this with the code below please?

With DEPTH set to 16 or 32, no movement at all is detected.
With DEPTH set to 0 (window), the YSpeed flicks between 0 and 1, and XSpeed stays at zero, whichever way the mouse is moved.

Const DEPTH = 32 ' 0

Global MouseXSpeed,MouseYSpeed

Function SampleMouse()
	MouseXSpeed=MouseX()-320
	MouseYSpeed=MouseY()-240
	MoveMouse 320,240
End Function

Graphics 640,480, DEPTH

HideMouse
MoveMouse 320,240

While Not KeyHit(KEY_ESCAPE)
	SampleMouse
	Cls
	DrawText "MouseXSpeed="+MouseXSpeed,0,0
	DrawText "MouseYSpeed="+MouseYSpeed,0,20
	Flip
Wend



Chroma(Posted 2005) [#18]
Who is Unknown?


bradford6(Posted 2005) [#19]
We are all unknown until we are known


Robert Cummings(Posted 2005) [#20]
Actually I'm Unknown :)


bradford6(Posted 2005) [#21]
not any more!


Tom Darby(Posted 2005) [#22]
Here's a routine that almost works. I say almost because on OS X, there's a pause every time you reposition the mouse, which makes this routine unusable:

SuperStrict

Const DEPTH:Int = 32
Const WIDTH:Int = 1024
Const HEIGHT:Int = 768
Const SAFEZONE:Int = 200 ' set this high to disable repositioning; set to 0 to always reposition

Global MouseXSpeed:Int,MouseYSpeed:Int, prevMouseX:Int, prevMouseY:Int, movementZone:Int
Global controllerX#, controllerY#, slowControllerX#, slowControllerY#

Function SampleMouse()
	
	Local curMouseX:Int, curMouseY:Int
	curMouseX = MouseX()
	curMouseY = MouseY()

	MouseXSpeed=curMouseX - prevMouseX
	MouseYSpeed=curMouseY - prevMouseY
	If Abs(centerX - curMouseX) > movementZone Or Abs(centerY - curMouseY) > movementZone Then
		MoveMouse centerX, centerY
		prevMouseX = centerX - MouseXSpeed
		prevMouseY = centerY - MouseYSpeed
	Else
		prevMouseX = curMouseX
		prevMouseY = curMouseY
	EndIf
End Function

Graphics WIDTH, HEIGHT, DEPTH

Global centerX:Int, centerY:Int

Function Reset()
	centerX = GraphicsWidth() / 2
	centerY = GraphicsHeight() / 2
	movementZone = SAFEZONE
	controllerX# = centerX
	controllerY# = centerY
	slowControllerX# = centerX
	slowControllerY# = centerY
	prevMouseX = centerX
	prevMouseY = centerY
	mouseXSpeed = 0
	mouseYSpeed = 0
	MoveMouse centerX, centerY
End Function

HideMouse

Reset()

While Not KeyHit(KEY_ESCAPE)

	If MouseHit(1) Then
		Reset()
	EndIf	
	SampleMouse()
	
	' reposition "controllers"
	controllerX# = controllerX# + Float(MouseXSpeed)
	controllerY# = controllerY# + Float(MouseYSpeed)

	slowControllerX# = slowControllerX# + (Float(MouseXSpeed) / 2)
	slowControllerY# = slowControllerY# + (Float(MouseYSpeed) / 2)
	
	Cls

	' draw 'movement zone'
	SetColor 50,0,0
	DrawRect(centerX - movementZone, centerY - movementZone, movementZone * 2, movementZone * 2)
	
	' draw actual mouse location
	SetColor 255, 0, 0
	DrawLine(prevMouseX - 4, prevMouseY, prevMouseX + 4, prevMouseY)
	DrawLine(prevMouseX, prevMouseY - 4, prevMouseX, prevMouseY + 4)
	
	' draw "controller" locations
	SetColor 0,255,0
	DrawLine(controllerX - 4, controllerY - 4,controllerX + 4, controllerY + 4)
	DrawLine(controllerX + 4, controllerY - 4, controllerX - 4, controllerY + 4)
	
	SetColor 0,255,255
	DrawLine(slowControllerX - 4, slowControllerY - 4, slowControllerX + 4, slowControllerY + 4)
	DrawLine(slowControllerX + 4, slowControllerY - 4, slowControllerX - 4, slowControllerY + 4)
	
	
	SetColor 255, 255, 255
	DrawText "Click to reset, [ESC] to exit.  Green x: full speed controlled object.",0,0
	DrawText "Blue x: 1/2 speed controlled object.  Red +: actual mouse position.",0, 12
	DrawText "Red square: mouse movement area.",0,24
	DrawText "MouseXSpeed="+MouseXSpeed,0,36
	DrawText "MouseYSpeed="+MouseYSpeed,0,48
	Flip
Wend




...basically, anything that involves MoveMouse isn't going to work for OS X. Hence, we either need MoveMouse fixed on OS X or we need a bona-fide MouseSpeed function...


Tom Darby(Posted 2005) [#23]
Ooh, found a "fix" here:

http://blitzmax.com/Community/posts.php?topic=42308

Basically, make the following change to mod/brl.mod/system.mod/system.macos.m (in version 1.14):


.
.
.

void bbSystemMoveMouse( int x,int y ){
	NSEvent *event;
	CGPoint cgPoint={x,y};
	displayCaptured=CGDisplayIsCaptured(kCGDirectMainDisplay);
	CGSetLocalEventsSuppressionInterval(0.0); // ADDED BY TMD TO FIX MOVEMOUSE DELAY

	if( displayCaptured ){

.
.
.



Any chance of getting this added to the official project Mark and/or Skid? Pleeeease? *bat bat smile*


Banshee(Posted 2005) [#24]
If if the mouse goes offscreen put it on the other edge, which is what Max does - and that flogs for £1,600...


Pudsy(Posted 2005) [#25]
Aha! Well spotted Tom.
That one's in the bug bin - probably why I couldn't find it ;)
Maybe it was fixed at some point, but has gone walkies in between 1.09 and 1.14 somewhere...

Definitely agree - this would be good to get added to the official modules.
Unless there's a genuine reason for the interval to be so long? Maybe it causes timing/performance issues elsewhere?