Mouse to WASD Topic is solved

Ask gaming related questions (AHK v1.1 and older)
Douglas Renato
Posts: 7
Joined: 29 Nov 2021, 01:02

Mouse to WASD

29 Nov 2021, 01:27

Hello people, I'm new at this, I don't know how to script... I need help.
I need a script that when I hold the mouse's side button or M2 it behaves like a WASD based on the coordinates, when I hold the button and if I tilt the mouse up, it sends W input, to the left the input is A, and if possible with the inputs combined as if placed between D and S the diagonal movement of the two pressed keys.

that way i can play the game i want just by mouse with just one hand... can someone help me please?
ludamo
Posts: 44
Joined: 25 Mar 2015, 02:21

Re: Mouse to WASD  Topic is solved

29 Nov 2021, 02:21

You may have to polish this code a bit to get rid of some rough edges or to adapt it to your particular use.

Code: Select all

XButton1::
	; requires AHK_L version 1
	
	MouseGetPos, Xi, Yi		; inital values

	hRgn_0 := DllCall("CreateRectRgn", "int", Xi-4, "int", Yi-4, "int", Xi+4, "int", Yi+4)	; area around initial mouse position 
	
   VarSetCapacity( Points, 32, 0 )		; 4 sectors based on 200px x 200px rectangle
   NumPut( Xi-200, Points, 0, "int" ),	NumPut( Yi-200, Points, 4, "int" )
   NumPut( Xi-4, Points, 8, "int" ), NumPut( Yi-4, Points, 12, "int" )
   NumPut( Xi+4, Points, 16, "int" ), NumPut( Yi-4, Points, 20, "int" ) 
   NumPut( Xi+200, Points, 24, "int" ), NumPut( Yi-200, Points, 28, "int" ) 
	hRgn_N := DllCall("CreatePolygonRgn", "uint", &Points, "int", 4, "int", 1)		; North	ALTERNATE=1, WINDING=2

   NumPut( Xi+200, Points, 0, "int" ),	NumPut( Yi-200, Points, 4, "int" )
   NumPut( Xi+4, Points, 8, "int" ), NumPut( Yi-4, Points, 12, "int" )
   NumPut( Xi+4, Points, 16, "int" ), NumPut( Yi+4, Points, 20, "int" ) 
   NumPut( Xi+200, Points, 24, "int" ), NumPut( Yi+200, Points, 28, "int" ) 
	hRgn_E := DllCall("CreatePolygonRgn", "uint", &Points, "int", 4, "int", 1)		; East
	
   NumPut( Xi-200, Points, 0, "int" ),	NumPut( Yi+200, Points, 4, "int" )
   NumPut( Xi-4, Points, 8, "int" ), NumPut( Yi+4, Points, 12, "int" )
   NumPut( Xi+4, Points, 16, "int" ), NumPut( Yi+4, Points, 20, "int" ) 
   NumPut( Xi+200, Points, 24, "int" ), NumPut( Yi+200, Points, 28, "int" ) 
	hRgn_S := DllCall("CreatePolygonRgn", "uint", &Points, "int", 4, "int", 1)		; South
	
   NumPut( Xi-200, Points, 0, "int" ),	NumPut( Yi-200, Points, 4, "int" )
   NumPut( Xi-4, Points, 8, "int" ), NumPut( Yi-4, Points, 12, "int" )
   NumPut( Xi-4, Points, 16, "int" ), NumPut( Yi+4, Points, 20, "int" ) 
   NumPut( Xi-200, Points, 24, "int" ), NumPut( Yi+200, Points, 28, "int" ) 
	hRgn_W := DllCall("CreatePolygonRgn", "uint", &Points, "int", 4, "int", 1)		; West
	
	KeyWait, XButton1		; move mouse to new position and release button
	MouseGetPos, mX, mY		; new position
	If DllCall("PtInRegion", "uint", hRgn_N, "int", mX, "int", mY)
	{	
		Send W
		Tooltip, North
	}
	Else If DllCall("PtInRegion", "uint", hRgn_W, "int", mX, "int", mY)
	{
		Send A
		Tooltip, West
	}
	Else If DllCall("PtInRegion", "uint", hRgn_S, "int", mX, "int", mY)
	{
		Send S
		Tooltip, South
	}
	Else If DllCall("PtInRegion", "uint", hRgn_E, "int", mX, "int", mY)
	{
		Send D
		Tooltip, East
	}
	Else
		Tooltip, outside
		
	Return
Last edited by ludamo on 29 Nov 2021, 02:45, edited 1 time in total.
Douglas Renato
Posts: 7
Joined: 29 Nov 2021, 01:02

Re: Mouse to WASD

29 Nov 2021, 02:27

ludamo wrote:
29 Nov 2021, 02:21
You may have to polish this code a bit to get rid of some rough edges or to adapt it to your particular use.

Code: Select all

XButton1::
	; requires AHK_L version 1
	
	MouseGetPos, Xi, Yi		; inital values

	hRgn_0 := DllCall("CreateRectRgn", "int", Xi-4, "int", Yi-4, "int", Xi+4, "int", Yi+4)	; area around initial mouse position 
	
   VarSetCapacity( Points, 32, 0 )		; 4 sectors based on 200px x 200px rectangle
   NumPut( Xi-200, Points, 0, "int" ),	NumPut( Yi-200, Points, 4, "int" )
   NumPut( Xi-4, Points, 8, "int" ), NumPut( Yi-4, Points, 12, "int" )
   NumPut( Xi+4, Points, 16, "int" ), NumPut( Yi-4, Points, 20, "int" ) 
   NumPut( Xi+200, Points, 24, "int" ), NumPut( Yi-200, Points, 28, "int" ) 
	hRgn_N := DllCall("CreatePolygonRgn", "uint", &Points, "int", 4, "int", 1)		; North	ALTERNATE=1, WINDING=2

   NumPut( Xi+200, Points, 0, "int" ),	NumPut( Yi-200, Points, 4, "int" )
   NumPut( Xi+4, Points, 8, "int" ), NumPut( Yi-4, Points, 12, "int" )
   NumPut( Xi+4, Points, 16, "int" ), NumPut( Yi+4, Points, 20, "int" ) 
   NumPut( Xi+200, Points, 24, "int" ), NumPut( Yi+200, Points, 28, "int" ) 
	hRgn_E := DllCall("CreatePolygonRgn", "uint", &Points, "int", 4, "int", 1)		; East
	
   NumPut( Xi-200, Points, 0, "int" ),	NumPut( Yi+200, Points, 4, "int" )
   NumPut( Xi-4, Points, 8, "int" ), NumPut( Yi+4, Points, 12, "int" )
   NumPut( Xi+4, Points, 16, "int" ), NumPut( Yi+4, Points, 20, "int" ) 
   NumPut( Xi+200, Points, 24, "int" ), NumPut( Yi+200, Points, 28, "int" ) 
	hRgn_S := DllCall("CreatePolygonRgn", "uint", &Points, "int", 4, "int", 1)		; South
	
   NumPut( Xi-200, Points, 0, "int" ),	NumPut( Yi-200, Points, 4, "int" )
   NumPut( Xi-4, Points, 8, "int" ), NumPut( Yi-4, Points, 12, "int" )
   NumPut( Xi-4, Points, 16, "int" ), NumPut( Yi+4, Points, 20, "int" ) 
   NumPut( Xi-200, Points, 24, "int" ), NumPut( Yi+200, Points, 28, "int" ) 
	hRgn_W := DllCall("CreatePolygonRgn", "uint", &Points, "int", 4, "int", 1)		; West
	
	KeyWait, XButton1		; move mouse to new position and release button
	MouseGetPos, mX, mY		; new position
	If DllCall("PtInRegion", "uint", hRgn_N, "int", mX, "int", mY)
	{	
		Send W
		Tooltip, North
	}
	Else If DllCall("PtInRegion", "uint", hRgn_W, "int", mX, "int", mY)
	{
		Send A
		Tooltip, West
	Else If DllCall("PtInRegion", "uint", hRgn_S, "int", mX, "int", mY)
	{
		Send S
		Tooltip, South
	}
	Else If DllCall("PtInRegion", "uint", hRgn_E, "int", mX, "int", mY)
	{
		Send D
		Tooltip, East
	}
	Else
		Tooltip, outside
		
	Return
when i run the script says: Error: ELSE with no matching IF.
what i do?
ludamo
Posts: 44
Joined: 25 Mar 2015, 02:21

Re: Mouse to WASD

29 Nov 2021, 02:44

Sorry there was a missing close bracket } after West

Code: Select all

	Tooltip, West
	}
	Else If DllCall("PtInRegion", "uint", hRgn_S, "int", mX, "int", mY)
Rohwedder
Posts: 7608
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Mouse to WASD

29 Nov 2021, 05:20

Hallo,
or (also diagonal):

Code: Select all

Directions := ["sd","s","as","a","wa","w","wd","d"]
; down+right,right,up+right,up,... counterclockwise
XButton1::
MouseGetPos, X2, Y2
KeyWait, XButton1
MouseGetPos, X1, Y1
Send,% Directions[1+(Round(3+Atan2(X2-X1,Y2-Y1)/Atan(1))&7)]
Return
Atan2(x,y)
{
	return dllcall("msvcrt\atan2","Double",y,"Double",x,"CDECL Double")
}
Douglas Renato
Posts: 7
Joined: 29 Nov 2021, 01:02

Mouse to WASD 2

29 Nov 2021, 22:30

hello people, before I created the Mouse to WASD Post and the users Ludam and Rohwedder were generous and sent me scripts so that I can get the script to walk with WASD with the mouse side button with Mouse coordinates,
for some reason my replies aren't getting approved in that post so i'm being forced to create another one.
and the last one they sent me was this

Code: Select all

Directions := ["sd","s","as","a","wa","w","wd","d"]
; down+right,right,up+right,up,... counterclockwise
XButton1::
MouseGetPos, X2, Y2
KeyWait, XButton1
MouseGetPos, X1, Y1
Send,% Directions[1+(Round(3+Atan2(X2-X1,Y2-Y1)/Atan(1))&7)]
Return
Atan2(x,y)
{
	return dllcall("msvcrt\atan2","Double",y,"Double",x,"CDECL Double")
}
[Mod edit: [code][/code] tags added. Please use code tags. Thank you!]

this one is almost perfect, I just need the key to keep being pressed and not pressed just once for the script to work as it should, can someone help me?
Last edited by gregster on 29 Nov 2021, 22:52, edited 1 time in total.
Reason: Post was merged from another topic.
Douglas Renato
Posts: 7
Joined: 29 Nov 2021, 01:02

Re: Mouse to WASD

29 Nov 2021, 22:30

this one is almost perfect, I just need the key to keep being pressed and not pressed just once for the script to work as it should, can help me friend?
gregster
Posts: 8988
Joined: 30 Sep 2013, 06:48

Re: Mouse to WASD

29 Nov 2021, 22:50

Sometimes it takes a little time, before a post gets approved. Please be patient, if that happens.
I merged your topics.

btw, please use code tags. Thank you! (If you have questions how to do this, please ask!)
Douglas Renato
Posts: 7
Joined: 29 Nov 2021, 01:02

Re: Mouse to WASD

29 Nov 2021, 23:03

gregster wrote:
29 Nov 2021, 22:50
Sometimes it takes a little time, before a post gets approved. Please be patient, if that happens.
I merged your topics.

btw, please use code tags. Thank you! (If you have questions how to do this, please ask!)
sorry man i completely noob sorry for the inconvenience,
i wait for a replay to finish the script here, thanks for helping me anyway.
Rohwedder
Posts: 7608
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Mouse to WASD

30 Nov 2021, 04:20

Then try:

Code: Select all

Directions := ["sd","s","as","a","wa","w","wd","d"]
; down+right,right,up+right,up,... counterclockwise
XButton1::
MouseGetPos, X2, Y2
KeyWait, XButton1
MouseGetPos, X1, Y1
Direction := Directions[1+(Round(3+Atan2(X2-X1,Y2-Y1)/Atan(1))&7)]
Loop, Parse,% "wasd"
{
    Is := GetKeyState(A_LoopField) ;Is pressed
    Should := InStr(Direction, A_LoopField) ;Should be pressed
    IF (Is And !Should)
        SendInput, {%A_LoopField% Up}
    Else IF (!Is And Should)
        SendInput, {%A_LoopField% Down}
}
Return
Atan2(x,y)
{
    return dllcall("msvcrt\atan2","Double",y,"Double",x,"CDECL Double")
}
Douglas Renato
Posts: 7
Joined: 29 Nov 2021, 01:02

Re: Mouse to WASD

30 Nov 2021, 17:26

Rohwedder wrote:
30 Nov 2021, 04:20
Then try:

Code: Select all

Directions := ["sd","s","as","a","wa","w","wd","d"]
; down+right,right,up+right,up,... counterclockwise
XButton1::
MouseGetPos, X2, Y2
KeyWait, XButton1
MouseGetPos, X1, Y1
Direction := Directions[1+(Round(3+Atan2(X2-X1,Y2-Y1)/Atan(1))&7)]
Loop, Parse,% "wasd"
{
    Is := GetKeyState(A_LoopField) ;Is pressed
    Should := InStr(Direction, A_LoopField) ;Should be pressed
    IF (Is And !Should)
        SendInput, {%A_LoopField% Up}
    Else IF (!Is And Should)
        SendInput, {%A_LoopField% Down}
}
Return
Atan2(x,y)
{
    return dllcall("msvcrt\atan2","Double",y,"Double",x,"CDECL Double")
}
it's not working as it should :/
so... i found a similar post with this script

Code: Select all

 ; using-mouse-position-as-hotkey.ahk
; ver1.1 ... added 8-directions support.

; get current mouse area and send correspond key
; press F1 and move mouse

CoordMode, Mouse, Screen
CoordMode, ToolTip, Screen

; for debug
SetTimer, tm_get_area, 100

; center position define(memo: my machine is 1920/1080)
pixx := 1600
pixy := 900
basex := pixx/2
basey := pixy/2
return

tm_get_area:
    get_area()
return

get_area() {
    Global basex, basey

    MouseGetPos, cx, cy
    cur_degree := Atan((basey-cy)/(basex-cx)) * 180 / 3.141592653589793
    if (cx >= basex) {
        cur_degree360 := cur_degree + 90
    } else {
        cur_degree360 := cur_degree + 270
    }
   ;ToolTip, degree: %cur_degree360%, basex, basey+20, 1

    dx := (basex-cx)
    dy := (basey-cy)
    cur_area := get_area_id(cur_degree360)
    ToolTip, Area: %cur_area%, basex, basey, 2
    return cur_area
}

; area  area degree total degree
;-------------------------------
;  1      50          50
; 12      20          70
;  2      40          110
; 23      20          130
;  3      100         230
; 34      20          250
;  4      40          290
; 41      20          310
;  1      50          360
get_area_id(degree) {
    return degree < 50 ? 1
        : degree < 70 ?  12
        : degree < 110 ? 2
        : degree < 130 ? 23
        : degree < 230 ? 3
        : degree < 250 ? 34
        : degree < 290 ? 4
        : degree < 310 ? 41
        : 1 ; 310 to 360 degree
}

F1::
    area := get_area()
    if (area=1) {
        key1=w
        key2=
    }
    if (area=2) {
        key1=d
        key2=
    }
    if (area=3) {
        key1=s
        key2=
    }
    if (area=4) {
        key1=a
        key2=
    }
    if (area=12) {
        key1=w
        ; Second key is d
        key2=d
    }
    if (area=23) {
        key1=d
        ; Second key is s
        key2=s
    }
    if (area=34) {
        key1=s
        ; Second key is a
        key2=a
    }
    if (area=41) {
        key1=a
        ; Second key is w
        key2=w
    }

    ; other changes??? ... need to proceed 2nd key.

    ; Release keys that were previous pressed
    if (prevkey1 != key1) {
        if (prevkey1) {
            Send, {%prevkey1% Up}
        }
        prevkey1 := key1
    }
    if (prevkey2 != key2) {
        if (prevkey2) {
            Send, {%prevkey2% Up}
        }
        prevkey2 := key2
    }

    Send, {%key1% Down}
    if (key2) {
        Send, {%key2% Down}
    }
return  ; replece to Keywait, F1 if you need

F1 Up::
    Send, {%prevkey1% Up}
    if (prevkey2) {
        Send, {%prevkey2% Up}
    }
return
[Mod edit: [code][/code] tags added.]

this one is almost perfect i just need it to work with the side mouse button and the axis reset when i hold the button again and not based on the center of the screen like this.
is it possible to do that?
Last edited by gregster on 30 Nov 2021, 17:27, edited 1 time in total.
Reason: Please use code tags. Thank you!
Rohwedder
Posts: 7608
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Mouse to WASD

01 Dec 2021, 02:19

… and not based on the center of the screen like this.
is it possible to do that?

As long as the input of the function is the vector distance of two points, you need a second point for reference.
Have fun programming!
VarnKail
Posts: 2
Joined: 04 Jun 2023, 08:38

Re: Mouse to WASD

04 Jun 2023, 08:46

I came across this post because I was too lazy to play game with both of my hand XD so here we go, this should work perfect, just hold ur right mouse and drag it to the dir that you want.
p/s: the code and this post were write with one hand and touch keyboard :) hope this help someone as lazy as me

Code: Select all

Directions := ["sd","s","as","a","wa","w","wd","d"]
; down+right,right,up+right,up,... counterclockwise
RButton::
MouseGetPos, X2, Y2
Loop
{
	Sleep, 100
	if !GetKeyState("RButton", "P")
		break
	MouseGetPos, X1, Y1
	Send,% Directions[1+(Round(3+Atan2(X2-X1,Y2-Y1)/Atan(1))&7)]
}
Return
Atan2(x,y)
{
	return dllcall("msvcrt\atan2","Double",y,"Double",x,"CDECL Double")
}
VarnKail
Posts: 2
Joined: 04 Jun 2023, 08:38

Re: Mouse to WASD

04 Jun 2023, 09:50

VarnKail wrote:
04 Jun 2023, 08:46
I came across this post because I was too lazy to play game with both of my hand XD so here we go, this should work perfect, just hold ur right mouse and drag it to the dir that you want.
p/s: the code and this post were write with one hand and touch keyboard :) hope this help someone as lazy as me

Code: Select all

Directions := ["sd","s","as","a","wa","w","wd","d"]
; down+right,right,up+right,up,... counterclockwise
keypress := ""
RButton::
MouseGetPos, X2, Y2
Loop
{
	Sleep, 100
	if !GetKeyState("RButton", "P")
	{
		Send, {%keypress% up}
		keypress := ""
		break
	}
	MouseGetPos, X1, Y1
	k := Directions[1+(Round(3+Atan2(X2-X1,Y2-Y1)/Atan(1))&7)]
	if(keypress != k)
	{
		Send, {%keypress% up}
		keypress := k
		Send, {%keypress% down}
	}
}
Return
Atan2(x,y)
{
	return dllcall("msvcrt\atan2","Double",y,"Double",x,"CDECL Double")
}
uhhh I forgot to hold down the key xD fixed code
kasim666
Posts: 1
Joined: 08 Apr 2024, 19:49

Re: Mouse to WASD

08 Apr 2024, 19:56

VarnKail wrote:
04 Jun 2023, 09:50
VarnKail wrote:
04 Jun 2023, 08:46
I came across this post because I was too lazy to play game with both of my hand XD so here we go, this should work perfect, just hold ur right mouse and drag it to the dir that you want.
p/s: the code and this post were write with one hand and touch keyboard :) hope this help someone as lazy as me

Code: Select all

Directions := ["sd","s","as","a","wa","w","wd","d"]
; down+right,right,up+right,up,... counterclockwise
keypress := ""
RButton::
MouseGetPos, X2, Y2
Loop
{
	Sleep, 100
	if !GetKeyState("RButton", "P")
	{
		Send, {%keypress% up}
		keypress := ""
		break
	}
	MouseGetPos, X1, Y1
	k := Directions[1+(Round(3+Atan2(X2-X1,Y2-Y1)/Atan(1))&7)]
	if(keypress != k)
	{
		Send, {%keypress% up}
		keypress := k
		Send, {%keypress% down}
	}
}
Return
Atan2(x,y)
{
	return dllcall("msvcrt\atan2","Double",y,"Double",x,"CDECL Double")
}
uhhh I forgot to hold down the key xD fixed code
This is all good, in a notepad yes, wasd are printed with the mouse movement, but why doesn’t it work in games
Rohwedder
Posts: 7608
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Mouse to WASD

09 Apr 2024, 00:50

Hallo,
1. I corrected errors in this script
2. Maybe with admin rights?:

Code: Select all

#SingleInstance, Force
If !A_IsAdmin
	Try Run *RunAs "%A_ScriptFullPath%"
Directions := ["sd","s","as","a","wa","w","wd","d"]
; down+right,right,up+right,up,... counterclockwise
keypress := ""
RButton::
CoordMode, Mouse, Screen
MouseGetPos, X2, Y2
Loop
{
	Sleep, 100
	if !GetKeyState("RButton", "P")
	{
		Loop, Parse,% keypress
			Send, {%A_LoopField% up}
		keypress := ""
		break
	}
	MouseGetPos, X1, Y1
	k := Directions[1+(Round(3+Atan2(X2-X1,Y2-Y1)/Atan(1))&7)]
	if(keypress != k)
	{
		Loop, Parse,% keypress
			Send, {%A_LoopField% up}
		keypress := k
		Loop, Parse,% keypress
			Send, {%A_LoopField% down}
	}
}
Return
Atan2(x,y)
{
	return dllcall("msvcrt\atan2","Double",y,"Double",x,"CDECL Double")
}
In case it's an FPS game, I replaced the MouseGetPos with evilC's MouseDelta:

Code: Select all

#SingleInstance, Force
; with evilC's MouseDelta
If !A_IsAdmin
	Try Run *RunAs "%A_ScriptFullPath%"
md := new MouseDelta("MouseEvent")
Directions := ["sd","s","as","a","wa","w","wd","d"]
; down+right,right,up+right,up,... counterclockwise
keypress := "", X1 := Y1 := X2 := Y2 := 0
Return
RButton::
md.SetState(True), X1 := Y1 := X2 := Y2 := 0
Loop {
	Sleep, 100
	if !GetKeyState("RButton", "P") {
		Loop, Parse,% keypress
			Send, {%A_LoopField% up}
		keypress := ""
		break
	}
	k := Directions[1+(Round(3+Atan2(X2-X1,Y2-Y1)/Atan(1))&7)]
	if(keypress != k) {
		Loop, Parse,% keypress
			Send, {%A_LoopField% up}
		keypress := k
		Loop, Parse,% keypress
			Send, {%A_LoopField% down}
	}
}
md.SetState(False)
Return
Atan2(x,y) {
	return dllcall("msvcrt\atan2","Double",y,"Double",x,"CDECL Double")
}
; Gets called when mouse moves
; x and y are DELTA moves (Amount moved since last message), NOT coordinates.
MouseEvent(MouseID, x := 0, y := 0){
	global hOutput, X1, Y1
	static text := ""
	static LastTime := 0 
	t := A_TickCount
	; text := "x: " x ", y: " y (LastTime ? (", Delta Time: " t - LastTime " ms, MouseID: " MouseID) : "")
	X1 += x, Y1 += y
	sendmessage, 0x115, 7, 0,, % "ahk_id " hOutput
	LastTime := t
}
; evilC: https://www.autohotkey.com/boards/viewtopic.php?t=10159
; Instantiate this class and pass it a func name or a Function Object
; The specified function will be called with the delta move for the X and Y axes
; Normally, there is no windows message "mouse stopped", so one is simulated.
; After 10ms of no mouse movement, the callback is called with 0 for X and Y
Class MouseDelta {
	State := 0
	__New(callback){
		;~ this.TimeoutFn := this.TimeoutFunc.Bind(this)
		this.MouseMovedFn := this.MouseMoved.Bind(this)

		this.Callback := callback
	}
	Start(){
		static DevSize := 8 + A_PtrSize, RIDEV_INPUTSINK := 0x00000100
		; Register mouse for WM_INPUT messages.
		VarSetCapacity(RAWINPUTDEVICE, DevSize)
		NumPut(1, RAWINPUTDEVICE, 0, "UShort")
		NumPut(2, RAWINPUTDEVICE, 2, "UShort")
		NumPut(RIDEV_INPUTSINK, RAWINPUTDEVICE, 4, "Uint")
		; WM_INPUT needs a hwnd to route to, so get the hwnd of the AHK Gui.
		; It doesn't matter if the GUI is showing, it still exists
		Gui +hwndhwnd
		NumPut(hwnd, RAWINPUTDEVICE, 8, "Uint") 
		this.RAWINPUTDEVICE := RAWINPUTDEVICE
		DllCall("RegisterRawInputDevices", "Ptr", &RAWINPUTDEVICE, "UInt", 1, "UInt", DevSize )
		OnMessage(0x00FF, this.MouseMovedFn)
		this.State := 1
		return this	; allow chaining
	}	
	Stop(){
		static RIDEV_REMOVE := 0x00000001
		static DevSize := 8 + A_PtrSize
		OnMessage(0x00FF, this.MouseMovedFn, 0)
		RAWINPUTDEVICE := this.RAWINPUTDEVICE
		NumPut(RIDEV_REMOVE, RAWINPUTDEVICE, 4, "Uint")
		DllCall("RegisterRawInputDevices", "Ptr", &RAWINPUTDEVICE, "UInt", 1, "UInt", DevSize )
		this.State := 0
		return this	; allow chaining
	}	
	SetState(state){
		if (state && !this.State)
			this.Start()
		else if (!state && this.State)
			this.Stop()
		return this	; allow chaining
	}
	Delete(){
		this.Stop()
		;~ this.TimeoutFn := ""
		this.MouseMovedFn := ""
	}	
	; Called when the mouse moved.
	; Messages tend to contain small (+/- 1) movements, and happen frequently (~20ms)
	MouseMoved(wParam, lParam){
		Critical
		; RawInput statics
		static DeviceSize := 2 * A_PtrSize, iSize := 0, sz := 0, pcbSize:=8+2*A_PtrSize, offsets := {x: (20+A_PtrSize*2), y: (24+A_PtrSize*2)}, uRawInput
 
		static axes := {x: 1, y: 2}
 
		; Get hDevice from RAWINPUTHEADER to identify which mouse this data came from
		VarSetCapacity(header, pcbSize, 0)
		If (!DllCall("GetRawInputData", "UPtr", lParam, "uint", 0x10000005, "UPtr", &header, "Uint*", pcbSize, "Uint", pcbSize) or ErrorLevel)
			Return 0
		ThisMouse := NumGet(header, 8, "UPtr")

		; Find size of rawinput data - only needs to be run the first time.
		if (!iSize){
			r := DllCall("GetRawInputData", "UInt", lParam, "UInt", 0x10000003, "Ptr", 0, "UInt*", iSize, "UInt", 8 + (A_PtrSize * 2))
			VarSetCapacity(uRawInput, iSize)
		}
		sz := iSize	; param gets overwritten with # of bytes output, so preserve iSize
		; Get RawInput data
		r := DllCall("GetRawInputData", "UInt", lParam, "UInt", 0x10000003, "Ptr", &uRawInput, "UInt*", sz, "UInt", 8 + (A_PtrSize * 2))
		x := 0, y := 0	; Ensure we always report a number for an axis. Needed?
		x := NumGet(&uRawInput, offsets.x, "Int")
		y := NumGet(&uRawInput, offsets.y, "Int") 
		this.Callback.(ThisMouse, x, y) 
		;~ ; There is no message for "Stopped", so simulate one
		;~ fn := this.TimeoutFn
		;~ SetTimer, % fn, -50
	} 
	;~ TimeoutFunc(){
		;~ this.Callback.("", 0, 0)
	;~ } 
}

Return to “Gaming Help (v1)”

Who is online

Users browsing this forum: No registered users and 33 guests