Mouse Movement to Controller stick/keyboard keys

Post gaming related scripts
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse Movement to Controller stick/keyboard keys

05 Aug 2016, 02:42

evilC wrote:My MouseDelta library has a sample script which maps mouse to WSAD

MouseGetPos is fundamentally flawed for mouse input of this type, as it stops producing meaningful results if the mouse cursor hits the edge of the screen. My MouseDelta code is immune to this problem.
I did test it, I see your point, it's good. However, your example script needs modification in order to be relevant for the (preferable) request in this thread.

Cheers!
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Mouse Movement to Controller stick/keyboard keys

05 Aug 2016, 06:40

Helgef wrote:I did test it, I see your point, it's good. However, your example script needs modification in order to be relevant for the (preferable) request in this thread.
Which requirement is that? Mouse to Joystick?
Altering how a physical controller (eg an XBox controller) appears to games is currently not possible, I am not sure if there is anything that can do that (yet). We are looking into some ways to be able to do this.
However, if you do not have a physical XBox controller, and you just need to make the game think that there is one connected when there really isn't, then that IS possible.

My UCR app has a plugin that will do mouse to (virtual) joystick.
At some point in the (near-ish) future, it will be able to do XInput (XBox) emulation, but at the moment it only does DirectInput (Normal joystick) emulation. Until I properly implement XBox device emulation, you can use XOutput to convert the vJoy output to a virtual XBox controller.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse Movement to Controller stick/keyboard keys

05 Aug 2016, 17:40

evilC wrote: Which requirement is that? Mouse to Joystick?
Mouse to keyboard that acts like joystick, eg, moving the mouse up from "the origin" presses up/w key, and holds until mouse is moved back to the origin, moving the mouse slightly more to the right, presses up/w and right/d, even more to the right presses just d/right, and so on...
evilC wrote: Altering how a physical controller (eg an XBox controller) appears to games is currently not possible, I am not sure if there is anything that can do that (yet). We are looking into some ways to be able to do this.
However, if you do not have a physical XBox controller, and you just need to make the game think that there is one connected when there really isn't, then that IS possible.

My UCR app has a plugin that will do mouse to (virtual) joystick.
At some point in the (near-ish) future, it will be able to do XInput (XBox) emulation, but at the moment it only does DirectInput (Normal joystick) emulation. Until I properly implement XBox device emulation, you can use XOutput to convert the vJoy output to a virtual XBox controller.
I'm not trying to do anything like that, I'm just sending key presses depending on where the mouse cursor is located in the circle-image from post 3.
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Mouse Movement to Controller stick/keyboard keys

06 Aug 2016, 09:46

Right, so what you want is "Absolute" mouse to keyboard - the Absolute position of the mouse controls the keyboard.
The example in the MouseDelta script does "Relative" mouse to keyboard.

Doing "Absolute" mouse to keyboard is not easy when reading mouse via this technique, you want to use MouseGetPos because the cursor lets the user know where the stick currently is.

Here is some code which does basically what you want:

Code: Select all

#SingleInstance,Force
OutputDebug DBGVIEWCLEAR
CoordMode, Mouse, Screen
DeadZone := 100					; if this close to the center, do not move

Center := {x: round(A_ScreenWidth / 2), y: round(A_ScreenHeight / 2)}
DirStates := {x: 0, y: 0}
DirKeys := {x: {-1: "a", 1: "d"}, y: {-1: "w", 1: "s"}}

;WinActivate, ahk_class Notepad
MouseMove, % Center.x, % Center.y, 0
Loop {
	MouseGetPos, x, y
	pos := {x: x - Center.x, y: y - Center.y}
	Tooltip % "x: " pos.x ", y: " pos.y
	; Loop twice - once with axis holding "x", once with it holding "y"
	For axis in DirStates {
		; Is the magnitude of the deflection greater than DeadZone?
		if (abs(pos[axis]) > DeadZone){
			; (pos[axis] / abs(pos[axis] works out if the movement is -1 or +1. eg -100 to -1 or +100 to 1
			newstate := round(pos[axis] / abs(pos[axis]))
		} else {
			newstate := 0
		}
		; State will now either be -1 (move negative) or +1 (move positive) or 0 (no move)
		oldstate := DirStates[axis]
		; Did the state change?
		if (oldstate != newstate){
			; If the old state was non-zero, release the key that was held
			if (oldstate){
				Send % "{" DirKeys[axis, oldstate] " up}"
			}
			
			; If the new state is non-zero, hold the new key
			DirStates[axis] := newstate
			if (newstate){
				Send % "{" DirKeys[axis, newstate] " down}"
			}
			
		}
	}
	Sleep 10
}

Esc::ExitApp
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse Movement to Controller stick/keyboard keys

06 Aug 2016, 16:55

evilC wrote:Right, so what you want is "Absolute" mouse to keyboard - the Absolute position of the mouse controls the keyboard.
The example in the MouseDelta script does "Relative" mouse to keyboard.
Relative to what?
evilC wrote: [...] you want to use MouseGetPos because the cursor lets the user know where the stick currently is.
Not really, I wouldn't want to see it, it's just a visual aid for callibrations.
evilC wrote: Here is some code which does basically what you want:
I already did the code which I tought would correspond to the needs of the thread starter, and he seemed to concur.

If you look at post number three, that script shows exactly what I intended, start it, press win+s, move the mouse around, the tooltips shows which key is being held down, the star (*) means all keys up. esc::exitapp. In that script there is no actual keypresses, I intended the thread starter to fill it in to his needs and modify it to work with his game.

I (very briefly) tried your script in the new thread you started. In quake, it sent me walking somewhat as expected*, but it would never release all keys and halt. I tried to modify the "deadzones", but didn't find a suitable value.

*Expected means as my script works, I'm not sure we are on the same page here.

Thanks for your efforts evliC, It's clear you are very good at the mouse stuff. Hopefully either the thread starter or someone else gets help from this.

Cheers.
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Mouse Movement to Controller stick/keyboard keys

06 Aug 2016, 17:21

[quote="Helgef"]Relative to what? [/quote]
A fixed position on the screen (The center).

Helgef wrote:I already did the code which I tought would correspond to the needs of the thread starter, and he seemed to concur.

If you look at post number three, that script shows exactly what I intended, start it, press win+s, move the mouse around, the tooltips shows which key is being held down, the star (*) means all keys up. esc::exitapp. In that script there is no actual keypresses, I intended the thread starter to fill it in to his needs and modify it to work with his game.
It's a bit of a stretch to go from that to working out which key events to send. It only works out which keys you need to hold *now*, so if, for example it moves from up+right to right, it has no concept that it needs to release up, only a concept that up + right needs holding.
Furthermore, it requires more mathematical knowledge to understand. Mine does not involve pi.
The image in yours is not always-on-top, nor is it semi-transparent.
Finally, yours is impractical to use. If I am at the top, and I want to move to right - moving the mouse in a straight line would output up, nothing, right - because if you draw a straight line from the top to the right, it clips the black part.
With mine, if you are at up and move in a straight line down+right, you get up, up+right, right.
Please do not take this as me saying "Your script stinks" because clearly you are doing some interesting stuff with it, it just needs more work to be practical.
Helgef wrote:I (very briefly) tried your script in the new thread you started. In quake, it sent me walking somewhat as expected*, but it would never release all keys and halt. I tried to modify the "deadzones", but didn't find a suitable value.
Hmm, to be honest I did not test it with any games. I used OutputDebug to see the keys it was pressing and releasing.
eg instead of Send % "{" DirKeys[axis, oldstate] " up}" I used:

Code: Select all

str := "{" DirKeys[axis, oldstate] " up}"
Send % str
OutputDebug % "Sending " str
Maybe the script is not running as admin? Maybe I goofed? Can you maybe use OutputDebug as above and let me know if you see it not sending the correct keys at the correct time?
Helgef wrote:Thanks for your efforts evliC, It's clear you are very good at the mouse stuff. Hopefully either the thread starter or someone else gets help from this.

Cheers.
No problem, I am particularly interested in getting the best techniques working for remapping keyboard, mouse and joystick to each other as I intend to support all these conversions in UCR at some point. I have a good solution for Mouse to Joystick and Axis <-> Keyboard, but Mouse to Keyboard is still one I haven't implemented yet, as there are a number of "Right" ways to do it, depending on application. I do like the look of your solution, I think it could be great for mouse to joystick axis, so please do keep on refining it...
Last edited by evilC on 08 Aug 2016, 16:15, edited 1 time in total.
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Mouse Movement to Controller stick/keyboard keys

06 Aug 2016, 17:24

When you saw the bug, were you using automatic deadzone calculation? (DeadzoneX/Y := -1)?

I think I just noticed a bug in the non-automatic mode.

dz_vars := {x: "PicW", y: "PicH"} should read dz_vars := {x: PicW, y: PicH}
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse Movement to Controller stick/keyboard keys

07 Aug 2016, 03:42

evilC wrote: It's a bit of a stretch to go from that to working out which key events to send. It only works out which keys you need to hold *now*, so if, for example it moves from up+right to right, it has no concept that it needs to release up, only a concept that up + right needs holding.
No, it is extremly simple. The tooltip says which key should be pressed, that implies the other keys should be up. So, for example, replace ToolTip, Up with {Up down}{Left up}{Right up}{Down up} and ToolTip,*, is replaced with all keys up. send it with whatever method you like.
evilC wrote: The image in yours is not always-on-top, nor is it semi-transparent.
There was not a lot of specifications in the original post, I intended for the thread starter to modify it to his needs.
evilC wrote:When you saw the bug, were you using automatic deadzone calculation? (DeadzoneX/Y := -1)?
I think I just noticed a bug in the non-automatic mode.
dz_vars := {x: "PicW", y: "PicH"} should read dz_vars := {x: PicW, y: PicH}
I tried both modes, and had the same problem. However, your correction and this solves the not-stopping problem:

Code: Select all

if (abs(pos[axis]) > DeadZone[axis]) ; This is wrong: if (abs(pos[axis]) > DeadZone)
evilC wrote: Finally, yours is impractical to use. If I am at the top, and I want to move to right - moving the mouse in a straight line would output up, nothing, right - because if you draw a straight line from the top to the right, it clips the black part.
I intended to mimic some joystick features, and it does exactly what I wanted. With a joystick, you go from top to right either by rolling it, thus keeping input, or you go down to the center, stopping input, then right to continue input.
If you want to be able to make a straight line between, eg, top and right, without going to through the center, adjust either the inner (decrease) or outer (increase) radius.
Also, because I'm keeping the cursor inside the circle, you never get far away from the center, thus, to abort input you never need to move back more than the difference between the outer and inner radius. And the way the mouse is returned to the circle, i.e., moving it back to the closest point on the circle, means that, for example, if you're in the up position, and want to go to the right, then only moving the mouse to the right, without any downward movement, will roll the cursor down to the right, and transistion from UP->UP+RIGHT->RIGHT. Just like a joystick would.
evilC wrote: With mine, if you are at up and move in a straight line down+right, you get up, up+right, right.
I'm not sure I get this, perhaps we have don't have the same preferences, or perhaps we are not really getting what the other person is trying to do.
Since you don't restrict the cursor position, it keeps going over to the game screen and falling back to the center, thus halting the input. I tried it in quake, with an overlay centered at the middle of the game screen. I suppose this is easily fixed though.
evilC wrote: Please do not take this as me saying "Your script stinks" because clearly you are doing some interesting stuff with it, it just needs more work to be practical.
I do not.

Cheers.
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Mouse Movement to Controller stick/keyboard keys

07 Aug 2016, 12:51

Helgef wrote:No, it is extremly simple. The tooltip says which key should be pressed, that implies the other keys should be up. So, for example, replace ToolTip, Up with {Up down}{Left up}{Right up}{Down up} and ToolTip,*, is replaced with all keys up. send it with whatever method you like.
State last tick was up + left.
State this tick is up.
(ie we are transitioning from up+left to up)
According to what you say, you would be sending {up down}{left up}{right up}{down up} when all that really needs to be sent is {left up}. Sending a superfluous bunch of up events is not so bad, but sending a {up down} when up was already held (As a part of the previous state which was up+left) is not ideal.
I intended to mimic some joystick features, and it does exactly what I wanted. With a joystick, you go from top to right either by rolling it, thus keeping input, or you go down to the center, stopping input, then right to continue input.
If you want to be able to make a straight line between, eg, top and right, without going to through the center, adjust either the inner (decrease) or outer (increase) radius.
Also, because I'm keeping the cursor inside the circle, you never get far away from the center, thus, to abort input you never need to move back more than the difference between the outer and inner radius. And the way the mouse is returned to the circle, i.e., moving it back to the closest point on the circle, means that, for example, if you're in the up position, and want to go to the right, then only moving the mouse to the right, without any downward movement, will roll the cursor down to the right, and transistion from UP->UP+RIGHT->RIGHT. Just like a joystick would.
I think I see what you are getting at here. I will have to try it with that in mind.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse Movement to Controller stick/keyboard keys

07 Aug 2016, 23:52

I agree, it's easy to fix though. I mean, it's already solved in your script. I might do it later today if I get time.
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Mouse Movement to Controller stick/keyboard keys

08 Aug 2016, 04:04

Right, the crucial part of what I do is to resolve coordinates (like -10, 100) into vectors (-1, +1) by using the equation vector := value / abs(value)
Then you can have arrays for each axis, like so: {x: {-1: "a", 1: "d"}, y: {-1: "w", 1: "s"}} which can map these vectors to keys.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse Movement to Controller stick/keyboard keys

08 Aug 2016, 15:59

So i just wrote a function changeStateTo(newState) where I also track the currentState, sort of like you do, it works, and seems smoother too, compared to the previous, sloppy version.
I also added dllcalls to ReleaseCapture and SetCapture, so the script activate the game, releases the mouse capture, and the let an almost invisible gui, placed over the game screen, capture the mouse, and prevent the game from fiddeling (if that's a word) with the mouse. Works fine in quake at least, but I don't know if it's good as a general feature? The mouse release/capture stuff, that is.

The irony is that I'm not even a gamer, and if I were, I wouldn't play with a joystick, much less with a "mouse-joystick", and especially not in quake! Well, now it's almost a finished, functional script, I think I'll probably finish it.

Ah! The sidetracks!
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Mouse Movement to Controller stick/keyboard keys

08 Aug 2016, 16:07

Tell me about it, the amount of stuff I write that I don't personally use is insane.
But then that's what happens when you try to write the mother of all remapping apps - I need code to remap everything to everything, and that's just the remapper plugins :/

Make a post when you finish it, I would like to take a look :)
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Mouse Movement to Controller stick/keyboard keys

08 Aug 2016, 16:11

evilC wrote:
Helgef wrote:Relative to what?
A fixed position on the screen (The center).
Hmm, I was also wrong in this statement. I should clarify.
By "Relative" mouse, what I mean is input which only considers delta change - ie x+1, y-1.
This is how you get mouse data from RawInput, where there is no "screen edge" to hit.

By "Absolute" mouse, what I mean is basically reading cursor position, ie x=100, y=100.
In this mode you can hit an edge of a screen.

So the correct answer to "Relative to what?" would have been "Relative to the last position of the mouse".
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse Movement to Controller stick/keyboard keys

08 Aug 2016, 16:46

evilC wrote: I should clarify.
Thanks.
evilC wrote: Make a post when you finish it, I would like to take a look :)
I'll do that

Return to “Gaming Scripts (v1)”

Who is online

Users browsing this forum: No registered users and 42 guests