Mouse to keyboard / virtual joystick

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

Mouse to keyboard / virtual joystick

14 Aug 2016, 03:05

Edit: This has been updated to do both Mouse to virtual joystick (new) and mouse to keyboard (original script). The script now consist of 5 files, so I have added them to a rar file.
Edit 2: Here is a dropbox link to the file, since it's still not possible to upload files: mouse2joystick.rar (no direct download) Edit: New link below
Edit 3: New download link. No other changes.
mouse2joystick.rar
(18.92 KiB) Downloaded 3639 times
Edit 4: Someone has done further work on this script, I mention it here in case someone is interested. Although, I know nothing about it, I will guess that it is probably better than my version. Please also see github.com/CemuUser8/mouse2joystick_custom_CEMU/releases.

The new script does both Mouse displacement to virtual joystick and to keyboard presses, as dicribed in the original post, see below. The following concerns mouse to virtual joystick:

It has the same features as the mouse to keyboard, but obviously doesn't send keys, but instead output to virtual joystick.
For mouse to virtual joystick, you need to install vJoy, from: http://vjoystick.sourceforge.net/site/
You don't need to install vJoy if you just want to use mouse to keyboard.

Additonal features for the virtual joystick output is:
- Non-linear sensitivity, if desired.
- Optional key binds to all virtual joystick buttons.
- The stick can be auto held in any position, so you can get back normal mouse functionallity, click around, and then switch back to controlling the stick, from where you left off.
- The stick can be fixed to at any radius.
- Options to invert both axes, might be redundant since probably most games can do it anyways.
- Angular deadzones can be modified, this is perhaps not a conventional term, but it means that you can modify the area in which only one axis is considered.
For example, if you move the mouse upwards, there is an area around the y-axis where you can't get any output to the x-axis, this is to enable full forward without left or right drift.

New general features:
- Autoactivate game can be disabled, wow!
- From the Tray menu, you can now click: Select game, and point and click on any running applictions window, to set its executable name as input destination.
- Toggle knob size, small/big.


Notes:
- The key to get a good user experience is to modify the sensitivity, nonlinear sensitivity, deadzones, and perhaps the fallback pause, for each specific application.
- If you want to save your settings, make copies the settings.ini file and manually switch between different setting-setups. There is no profile managment.
- Default is mouse to joystick, you can change it in the settings dialog, Tray menu -> Settings -> General: Output mode.
- If vJoy is not installed you will be asked to either switch to mouse to keyboard or exit application.

Exampel keylist:
To bind keys to joystick buttons, go to Settings->Mouse2Joystick->Keys: Keylist.
The key list should be a list of comma delimited keynames, that is valid ahk-keynames.
Eg, if you want to bind joystick button 1 and 5, to key b and ctrl+u, respectively, the keylist should look like this:
b,,,,^u

Compability:
- Now also tested in Microsoft Flight Simulare 2004.

Links:
- http://vjoystick.sourceforge.net/site/ - vJoy device drivers, needed for mouse to virtual joystick.
- https://autohotkey.com/boards/viewtopic.php?t=5705 - CvJoyInterface.ahk

Acknowledgements:
- crisangelfan and evilC on autohotkey.com forum provided useful input.
- Credit to author(s) of vJoy @ http://vjoystick.sourceforge.net/site/
- evilC did the CvJoyInterface.ahk

Below is the original post, it concerns the mouse to keyboard functionallity, it is now an option in the new script.
There was a request for a script that maps mouse movements to imitate a joystick.
In the end, I had spent a few more hours on it than originally intended, so I decided to complete it and add some more features and some setup options.

The main features are:
- Maps mouse displacment to eight keyboard combinations: UP, UP+RIGHT, RIGHT, RIGHT+DOWN, DOWN, DOWN+LEFT, LEFT, LEFT+UP.
- Mimics joystick feature: Apply pressure along just one axis will still roll the stick along the other, for a maximum of 90 degrees.
- A graphical overlay for visual aid.
- Options for sensitivity and minimum displacement before triggering any keyboard presses.
- Automatically activates game/application.
- Blocks game/application from taking control of the mouse when "joystick" is on (places an invisible gui over the game screen).
- Hide cursor if desired.
- Bind left and right mouse buttons to any key when "joystick" is on.
- Keys are pressed and hold down rather than repeatedly sent.
- By default there is a snap back to the center and a short mouse block when leaving the outer ring, this is to enable quick halt without immediately start going in the other direction, this can be disabled in the settings dialog.

Instructions:
- For the visual aid you need to put the images in a folder named "images" in the script folder. Script can be used without this though, will automatically disable the visual aid.
- Toggle on/off, default key: Winkey+s
- Exit app, defualt key: Winkey+q
- Move visual aid, default key: Winkey+d (By default visual aid is automatically placed)
- Default up/down/left/right keys are: w/a/s/d.
- Relevant settings are accessed via tray icon->settings.
- Specify the game's application name, default is notepad.exe for testing purposes.
- Game needs to be run in window mode. If this i a problem, then check out evilCs scripts, links below.

Additonal comments:
- If needed, modify the update rate via "freq"-parameter in script, this is not available in the settings dialog.
- There is little or none input validation in the settings dialog, don't try to break it.
- There will probably be bugs, you are welcome to report these.

Compability:
- Tested only on Windows 7, ahk v1.1.22.09 64 bit, in quake live and notepad.
- You are welcome to report where it works and not.

Further options:
- Check out evilCs more elaborate scripts, eg, UCR, UJR (related to joystick, but not mouse) and MouseDelta.
- Get a real joystick.

-Screenshot:
Image
Shows the visual aid.

-Code:
Orignial script, perhaps I'll keep it here as a historical monument.
Spoiler
Last edited by Helgef on 07 Feb 2018, 07:51, edited 8 times in total.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Mouse to joystick

14 Aug 2016, 09:16

Bravo! The look and feel of this is really nice.

I reckon this could be quite possibly be adapted to also do mouse to joystick as well. Have you seen my CvJoyInterface class? It makes outputting to a vJoy stick really easy.

I would certainly be interested in trying to implement something like this as a UCR plugin. It would, however, not be trivial as everything would need to be wrapped into a class, and seeing as all plugins share settings such as CoordMode, then they would probably need to be re-declared each time you were about to use a command that depended on them.

FYI, UJR does not support mouse as an input, so probably best to remove that as an alternative.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse to joystick

14 Aug 2016, 11:32

evilC wrote:Bravo! The look and feel of this is really nice.
I'm glad to hear, thanks for trying it! :D
evilC wrote: Have you seen my CvJoyInterface class? It makes outputting to a vJoy stick really easy.
I'll check it out, when time be.
evilC wrote: I would certainly be interested in trying to implement something like this as a UCR plugin. It would, however, not be trivial as everything would need to be wrapped into a class, and seeing as all plugins share settings such as CoordMode, then they would probably need to be re-declared each time you were about to use a command that depended on them.
It would be great if anything of this could be useful for anyone in any way. The core of this is very simple and I don't think that the choice of CoordMode is really significant, but I'm not really familiar with your implementations so I can't really make any relevant statements in that matter.
evilC wrote: FYI, UJR does not support mouse as an input, so probably best to remove that as an alternative.
I'll make an edit.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse to joystick

15 Aug 2016, 09:32

evilC wrote: Have you seen my CvJoyInterface class? It makes outputting to a vJoy stick really easy.
I did some testing and I must say, I'm impressed!
I have modified this script do vJoy instead of keyboard, it was really easy, and it seems to work really good.
I tested in Microsoft Flightsim 2004 and it is smooth as butter.

I'll need to do some more testing and add some options and such, I'll post when I get time to finish it.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Mouse to joystick

15 Aug 2016, 13:06

By the way, be aware...

Your current implementation is round-throw only. PC joysticks (not gamepads) are square-throw. If you used this script for a flightsim, when at full pitch, you will not be able to roll at all, and vice versa. It may be worth seeing if your technique can be enhanced to support square throw. Supporting square throw only is better than round throw only, as games that are designed for round throw will typically be fine with square input (And often you can do stuff that people actually using a gamepad cannot - eg, you may be able to move faster diagonally than would normally be possible)
Last edited by evilC on 15 Aug 2016, 13:46, edited 1 time in total.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse to joystick

15 Aug 2016, 13:15

I don't know what that means, I'll look it up. Thanks for the input.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Mouse to joystick

15 Aug 2016, 13:19

The range of motion of the thumbsticks on an XBox pad is round. The range of motion of a normal joystick is square.
Go into the joystick preview for a gamepad and try and hit the corners. You can't. You can with a normal joystick.

Disclaimer: I do have a gamepad that I can hit the corners with, but that is only because it considers about 60% deflection "full deflection". This makes is pretty useless for ANYTHING, because it exasperates the big problem with joypads which is that their range of motion is so small, that you require "micro-touches" to get any accuracy at all. Setting a linear sensitivity so that you can hit the corners only makes things worse.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse to joystick

15 Aug 2016, 16:45

evilC wrote: Your current implementation is round-throw only.
It can not be deduced from the script above, it's a matter of translating the distance from the center and the angle to an output on the joystick, it can be handled in many ways.
evilC wrote:If you used this script for a flightsim, when at full pitch, you will not be able to roll at all, and vice versa.
Again, it can not be deduced from the script. For any valid pair of directions, I can have any tilt I want, eg. 100% up and 100% right.
evilC wrote: Setting a linear sensitivity so that you can hit the corners only makes things worse.
The linearity in my script does not dictate which output I can get, or perhaps you are refering to your gamepad. I think non-linear sensitivity might be a good idea though, I could just square/cube my linear function, or perhaps there are more suitable curves I could take?

My main consideration is, however, that it should be useable, not that it behaves like a joystick in theory, there is a vast difference moving a mouse in 2-d vs, the 3-d joystick.
To that end, I'm considering (optional) hotkeys for snap back to center, locking to axis and tilt.

Also, in your experience, do you think it is useful to add options for binding keys to the joystick buttons? I mean, one could just set up hotkeys on the keyboard anyway. Do people use the other axis available, like the z-axis for example? It could be controlled via the mouse wheel I guess.

Your input is very useful, keep it coming, although, at this point is kind of your fault I'm spending time on this... :lol:
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Mouse to joystick

15 Aug 2016, 18:20

What I meant by "round throw only" is that the mouse is limited to a round area, like the round throw of a joypad. Even if your script outputs to a square area, the input area is still round, so you are going to be losing something somewhere.
So all I am saying is that it would be nice to be able to have a square input area (Alternate logic, but obviously much simpler) - the "knob" could remain round.

To be honest, I did not expect you to implement such stuff and a GUI so quickly - I was going to suggest making it into a UCR plugin, as it handles all the INI file and GuiControls for you, but you kind of beat me to it. Having gone this far, it may be worth adding some button mapping stuff to it (There aren't that many buttons anyway), but what about the other stick and the d-pad? You could go on and on, it's up to you how much time and effort you want to put into it...

Personally, as I have said, I would love to implement this as a UCR plugin, then you do not have to bother with adding the other remappings, UCR can handle all that.
I'll see if I can find some time this week.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse to joystick

16 Aug 2016, 03:20

evilC wrote:What I meant by "round throw only" is that the mouse is limited to a round area, like the round throw of a joypad. Even if your script outputs to a square area, the input area is still round, so you are going to be losing something somewhere.
So all I am saying is that it would be nice to be able to have a square input area (Alternate logic, but obviously much simpler) - the "knob" could remain round.
Ok, then I get your point. I'm not using this kinds of stuff myself so I will definitely miss those kinds of details. I wonder though, since you can't physically feel when you hit the input edges with the mouse, how it would impact the user? If I think of a good way to easily add it I might.
evilC wrote: Personally, as I have said, I would love to implement this as a UCR plugin, then you do not have to bother with adding the other remappings, UCR can handle all that.
I'll see if I can find some time this week.
It would probably make more sense to do that, since people would be more likely to find it and it's more of a complete package, so to speak.

I think I'm quite done with the functionality now, so its just a matter of making it somewhat user friendly, that is, the boring part remains. :lol:
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Mouse to joystick

16 Aug 2016, 03:58

Helgef wrote:
evilC wrote:Ok, then I get your point. I'm not using this kinds of stuff myself so I will definitely miss those kinds of details. I wonder though, since you can't physically feel when you hit the input edges with the mouse, how it would impact the user? If I think of a good way to easily add it I might.
If the input area were round, but the game was expecting square, then you would not have full control - eg lets say you were using the stick for accelerate/brake/left/right - you could not turn at all when accelerating or braking @100%, and could not accelerate or brake at all when turning @100% and the user may well not realize *why*. It all depends on the game and how it detects the input. If the vJoy stick does not appear to be an XBox pad (Which will be possible soon - vXBox is starting to become a reality), then the game may well assume it should use a square throw.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Mouse to joystick

16 Aug 2016, 13:57

Gonna sit down now and try to get the basics of your script working as a UCR plugin.
I PMed you contact details, if you want to work together on it, drop me a line.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Mouse to joystick

16 Aug 2016, 18:27

A mate turned up so I got distracted. I didn't manage to finish it, but here is a working implementation as a UCR plugin that maps mouse to joystick. I think it's maybe going to take some more time to flesh out all the features, and I am not sure that all of them are required in UCR, so it will certainly require more thought. Overall though, glad to have the core functionality basically working - beers all round!

Name the file HelgefM2J.ahk (or change all instances of HelgefM2J to a new string) and place it in Plugins\User
Place the images folder in the UCR root folder (Plugins are included into the main code, so paths are relative to UCR, not the plugin). Most stuff is hard-coded (except for hotkeys, axes) for now but I demo'd all the aspects of UCR that you should need (Adding inputs, adding outputs, adding settings GuiControls) and chucked some comments in there as pointers.

If you want to tinker further, fine, if not - quite happy to complete this at my own pace.

Code: Select all

class HelgefM2J extends _Plugin {
	Type := "HelgefM2J"
	Description := "Helgef's Mouse to Joystick plugin"
	
	;toggle:=1													; On/off parameter for the hotkey.	Toggle 0 means controller is on. The placement of this variable is disturbing.
	remapActive := 0

	kr:=21		; Radius of the knob for the visual aid. Needs to match the actuall image, don't change if you don't change the image. (You can test smaller perhaps.)
	vW:=202		; Visual aid image width. Needs to match the actuall image, don't change if you don't change the image.
	vH:=202		; Visual aid image height. Both the inner circle and the outer ring is assumed to have the same dimensions.
	pi:=3.1415	; Approx pi.
 
	dr:=0		; Bounce back when hit outer circle edge, in pixels. (This might not work any more, it is off) Can be seen as a force feedback parameter, can be extended to depend on the over extension beyond the outer ring.
	r:=100		; This is acts as a sensitivity parameter, where values closer to zero corresponds higher sensitivity, should not be less than one.
	k:=0.50		; This parameter dictates the radius of the inner circle, inner=outer*k, k?(0,1)

	hideCursor:=1									; Set to 1 to hide the cursor when controller is on.
	visualAidIsOn:=1								; Set to 1 to show a visual aid for the controller.
	autoplaceVisualAid:=1							; Automatically places visual aid outside game screen.
	 
	freq:=25										; Controllers update frequency, in ms.
	movingAid:=0									; Track when visual aid is in move mode.
	actionTaken:=0									; For handling quick fall back to center. Needs to start at zero.
	fallBackPause:=125								; Short mouse movement block after fall back. Set to zero to disable fallback

	keyNames:=[upKey, leftKey, downKey, rightKey]		; The order is important, corresponds to up/left/down/right on the "stick".
	currentState:=[0,0,0,0]							; 0 means that the corresponding key in keyNames is up, 1 means down
	segmentEndAngles:=Object()						; Each segment is defined by its angle, segment 1,...,12 -> end angle pi/6,pi/3,...,2*pi [rad]. (Unfortuantley its clockwise, with 0/2pi being at three o'clock)

	; Every plugin has it's Init() method called when it loads into a profile. Use it to create a GUI, calculate values etc
	; Do not mess with the default constructor __New() !!!
	Init(){
		; Add the GUI for the settings
		Gui, Add, Text,, Enable / Disable Toggle
		this.AddInputButton("EnableDisableToggle", 0, this.TogglePressed.Bind(this), "x150 yp-2 w200")
		Gui, Add, Text, xm, X Axis
		this.AddOutputAxis("JoyX", 0, "x+5 yp-3 w125")
		Gui, Add, Text, x+5 yp+3, Y Axis
		this.AddOutputAxis("JoyY", 0, "x+5 yp-3 w125")
		this.AddControl("ShowVA", 0, "CheckBox", "xm", "Show Visual Aid")
		Gui, Add, Text, xm, Window Title
		
		this.AddControl("WinTitle", 0, "Edit", "x+10 yp-3 w150", "ahk_exe Notepad.exe")

		; Store the bound function for the SetTimer as a class property, as you need the same one to stop it
		this.MouseToJoystickFn := this.MouseToJoystick.Bind(this)

		; For things like Editboxes to select image, you may want to check that the image is a valid file etc
		; So this is how you would declare a "g-label" to fire when the GUIControl changes
		;this.AddControl("OuterImage", this.SettingsChanged.Bind(this), "Edit", "x+10 yp-3 w150", "images\outerRing.png")
		; Then you would have a function SettingsChanged(filename) which gets passed the new value, or you can read it via this.GuiControls
		
		; If you want, you can use one function for multiple GUIControls by binding extra values:
		;this.AddControl("OuterImage", this.SettingsChanged.Bind(this, "outer"), "Edit", "x+10 yp-3 w150", "images\outerRing.png")
		;this.AddControl("InnerImage", this.SettingsChanged.Bind(this, "inner"), "Edit", "x+10 yp-3 w150", "images\innerRing.png")
		; Then you would have a function like SettingsChanged(whichimage, filename)
		
		;Loop,12
		;	this.segmentEndAngles[A_Index]:=this.pi/6*A_Index
		; Display on screen visual aid for joystick control
		; This code will probably need to be changed to enable changing picture while script is running etc.
		; Use a g-label as above to get notification when a GUIcontrol changes and handle it accordingly.
		;{
			; Visual aid gui, the center circle
			; Calculate the position and dimension of the inner circle.
			this.icX := this.vW *(1-this.k)/2
			this.icY := this.vH *(1-this.k)/2
			this.icW := this.vW * this.k
			Gui, New, hwndhVA
			this.hVA := hVA
			;Gui, % this.hVA ":new"
			Gui, % this.hVA ":+ToolWindow -Caption +AlwaysOnTop"
			Gui, % this.hVA ":add", Picture, BackgroundTrans X0 Y0, images\outerRing.png
			Gui, % this.hVA ":add", Picture, % "BackgroundTrans X" this.icX " Y" this.icY " W" this.icW " H-1 hwndIC", images\innerCircle.png
			Gui, % this.hVA ":Color", FFFFFF
		 
		 
			; Visual aid gui, the knob.
			this.kd := this.kr*2														; Knob diameter.
			Gui, new, hwndhVAKnob
			this.hVAKnob := hVAKnob
			Gui, % this.hVAknob ": +ToolWindow -Caption +AlwaysOnTop"
			Gui, % this.hVAknob ": add", Picture,% "X0 Y0 W" this.kd "H-1", images\knob.png 
			Gui, % this.hVAknob ": Color", FFFFFF
		 
		;}
	}
	
	; The user pressed the toggle button
	TogglePressed(e){
		if (!e){
			return	; ignore button up events
		}
		CoordMode,Mouse,Screen
		this.remapActive := !this.remapActive
		if (this.remapActive){
			;gameExe := "notepad.exe"
			win := WinExist(this.GuiControls.WinTitle.value)
			if (!win)
				return
			WinActivate, % "ahk_id " win
			WinGetPos,gameX,gameY,gameW,gameH,% "ahk_id " win
			autoplaceVisualAid := 1
			if (this.GuiControls.ShowVA.value && autoplaceVisualAid)
			{
				this.vY:=gameY+gameH/2-this.vH/2
				rightBoundExceeded:=gameX+gameW+this.vW+this.kr>A_ScreenWidth
				leftBoundExceeded:=gameX-this.vW-this.kr<0
				if rightBoundExceeded && leftBoundExceeded
					this.vX:=this.kr,this.vY:=this.kr
				else if rightBoundExceeded
					this.vX:=gameX-this.vW-this.kr
				else
					this.vX:=gameX+gameW+this.kr
 
				Gui, % this.hVA ":Show", % "X" this.vX " Y" this.vY " w" this.vW " h" this.vH " NA", Visual aid for controller
				;Gui, VA: Show, % "" X%vX% Y%vY%  w%vW% h%vH%  NA,Visual aid for controller.			; Show visual aid outside bottom right corner of game screen
				WinSet,TransColor, FFFFFF, % "ahk_id " this.hVA

				this.vOX:=round(this.vX+this.vW/2)
				this.vOY:=round(this.vY+this.vH/2)
	 
				Gui, % this.hVAknob ": Show",% "NA X" this.vOX-this.kr " Y" this.vOY-this.kr " W41 H41",Controller knob			; Show visual aid, kr is the knob radius
				WinSet,TransColor, FFFFFF, % "ahk_id " this.hVAKnob
				
				this.OX:=gameX+gameW/2				
				this.OY:=gameY+gameH/2
				MouseMove,% this.OX, % this.OY															; Move mouse to controller origin

			}
			fn := this.MouseToJoystickFn
			SetTimer, % fn , 50
			SoundBeep, 1000
		} else {
			fn := this.MouseToJoystickFn
			SetTimer, % fn , Off			
			SoundBeep, 500
			Gui, % this.hVA ": Hide"
			Gui, % this.hVAKnob ": Hide"
			
		}
	}
	
	MouseToJoystick(){
		CoordMode,Mouse,Screen
		MouseGetPos,X,Y
		X-=this.OX										; Move to controller coord system.
		Y-=this.OY
		RR:=sqrt(X**2+Y**2)
		if (RR>this.r)									; Check if outside controller circle.
		{
			X:=round(X*(this.r-this.dr)/RR)
			Y:=round(Y*(this.r-this.dr)/RR)
			MouseMove,% X+this.OX,% Y+this.OY 					; Calculate point on controller circle, move back to screen/window coords, and move mouse.
		}
		if (this.GuiControls.ShowVA.value)
		{
			; Map controller coords to visual aid coord system
			kX:=round(this.vOX+X/this.r*this.vW/2-this.kr) ;*[UCR]
			kY:=round(this.vOY+Y/this.r*this.vH/2-this.kr)
			SetWinDelay,-1
			WinMove,% "ahk_id " this.hVAKnob,, kX,kY			; Move the knob.
		}
		
		this.OutputAxes.JoyX.SetState((x * 163.84) + 16384)
		this.OutputAxes.JoyY.SetState((y * 163.84) + 16384)
	}
	
}
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse to joystick

17 Aug 2016, 00:17

Cool, I'll take a look later.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse to joystick

17 Aug 2016, 03:04

I took a quick look, I see your concern about the roundness. Compare the two images:

Image
Image 1: UCR-Plugin.
Image
Image 2: Not yet released script. My guess: This is what you would like.

In the plugin, you can't get the output as seen in the second picture. This is because you're considering the coordinates rather than the distance (in script: RR) from the center and the angle (in script: phi), it's fine in the key-pressing case, since it's just on/off.

If you are familiar with basic set notation, this is your mapping:
A -> A
where A={(x,y)∈[-r,r]x[-r,r] : √(x^2+y^2)<=r}, which indeed is circle to circle, my (image 2) mapping is
A -> B -> C
where B={(RR,phi) ∈ (0,r]x(0,2pi] : 0<RR<=r, 0<phi<=2pi} which is rectangle
and C={(x,y)∈[-r,r]x[-r,r] : -r<=x<=r, -r<=y<=r}, which is square, so it is circle to square.

Am I correct that you would like to have the output as seen in image 2? That is at least my guess of what a joystick would put out in that position, although I haven't used a joystick in many years, and have never "measured" the output.

I'm almost finished with the last pieces (user stuff) of my mouse2vJoystick script. (this thread's title is a bit of a misnomer, I realise.) While I finish it I'll think about if there is an easy way to edit

Code: Select all

this.OutputAxes.JoyX.SetState((x * 163.84) + 16384)
this.OutputAxes.JoyY.SetState((y * 163.84) + 16384)
in the plugin.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Mouse to joystick

17 Aug 2016, 07:14

I can see your maths are way better than mine :)

Regarding sensitivity, deadzones and hitting corners...

With a round VA, I would not worry about trying to hit the corners - you are trying to imitate a console controller, so no worries.
I would say that this would be better handled by having an option for a square VA.

WRT deadzones, if the VA is round, the DZ should probably be round, and if the VA is square, the DZ should be square.

WRT sensitivity, I already have code for sensitivity curves, I just did not add it into the plugin yet.

Also, thinking about it, I am not sure there is any point using MouseGetPos as the input for your system.
Because you clamp the mouse to the VA, you are effectively only using Delta information. ie given a VA radius of 100px, if you move the mouse 200px left (ie twice as far left as you need to go to achieve full deflection) it in effect only moves 100px. You then you move the mouse 100px right, and you are back at center.
We may as well just read the input using RawInput, because that way you do not need to release the mouse cursor from the game.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse to joystick

17 Aug 2016, 11:31

evilC wrote: Regarding sensitivity, deadzones and hitting corners...
With a round VA, I would not worry about trying to hit the corners - you are trying to imitate a console controller, so no worries.
Actually, I tried to imitate a "real" joystick, or at least what was my perception of a real joystick, I hardly didn't know there was a difference a couple of days ago. And I certainly didn't know there was some thing physically square on a "real" joystick.
evilC wrote: I would say that this would be better handled by having an option for a square VA.
I suppose this wouldn't be that hard to do. I'll think it would just be another coordinate transformation, it wouldn't really change anything else but the visual, if you turned off the VA you wouldn't know.
evilC wrote: WRT sensitivity, I already have code for sensitivity curves, I just did not add it into the plugin yet.
I'd be intrested in that, in my script I have added an option to get nonlinear sensitivity, but it's just a power of the linear function, it look and feels quite funny. I'm not sure non linearity is useful when working with a mouse, you have no feel of where "the stick" is.
evilC wrote: Also, thinking about it, I am not sure there is any point using MouseGetPos as the input for your system.
There is no reason, that was just the only option I knew.
evilC wrote: Because you clamp the mouse to the VA, you are effectively only using Delta information. ie given a VA radius of 100px, if you move the mouse 200px left (ie twice as far left as you need to go to achieve full deflection) it in effect only moves 100px. You then you move the mouse 100px right, and you are back at center.
It is not clamped to the VA, it is centered at the "game screen", which is a bad idea, really, I should have put it center screen, (the new script does if you don't select autoactivate game), it's the result of building something without having a clear goal from the begining. How much I have to move the mouse to get full deflection is guarded by the (pseudo) sensitivity parameter (r in the script). Set sensitivity to 10, then it's fully deflected after 10 pixels, set to 500, then it's fully deflected after 500 pixels, so the limitiation is half the screen height (unless you are using a wierd resolution, W<H). If you don't hide the mouse you'll see. The deflection of the knob, in the VA, is normalised to fit inside the ring, so it will appear to move faster at higher sensitivty, and vice versa. Ideally, you set your mouse to high sensitivity, and low pseudo sensitivity (that is high r), then you get the best resolution of the output..
evilC wrote: We may as well just read the input using RawInput, because that way you do not need to release the mouse cursor from the game.
Yes, I agree, the way it is now is limiting, but it might be ok anyways I think. I would have to study up on the Rawinput though, if I would change it. With raw input I could set, r=16384, and then (if there were no deadzone) I could really reach all (2^30) possible outputs from the joystick. At least that seems to be the input range of the CvJoyInterface. Probably doesn't matter in practice though.

Cheers!

OT: I still can't upload any files, I saw someone else complain about it in an other thread. I can barely browse the forum at all, it's sloooooow.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Mouse to keyboard / virtual joystick

18 Aug 2016, 14:01

Here is the sensitivity code I mentioned.

Code: Select all

	; Adjust axis for sensitivity
	; sp: Sensitivity, in percent. 100% is "normal".
	Sensitivity(value, sp){
		if (sp == 100){
			return value
		} else {
			sens := sp/100 ; Shift sensitivity to 0 -> 1 scale
			value := value/50	; Shift input value to -1 -> +1 scale
			value := (sens*value)+((1-sens)*value**3)	; Perform sensitivity calc
			value := value*50	; Shift back to -50 -> 50 scale
		}
		return value
	}
value in this code is expected to be in the range [-50...+50]

I did not really come up with this formula, an old friend who isn't really a coder helped me, but he had no experience of joysticks, so I had to explain it to him and thus it may not be doing quite what I think it is, hopefully you will understand it and be able to advise.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse to keyboard / virtual joystick

18 Aug 2016, 16:00

I'll take a look at it, thanks.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Mouse to keyboard / virtual joystick

18 Aug 2016, 16:36

It behaves nice I think, and it hits the endpoint as it should.
Image

You can get any curve between the red and the green curve.
You get a lower sensitivity closer to the deadzone, then it gets a bit higher, but it doesn't "shoot", which is good.
In order to get any noticable effect, you'll probably need to set sp<80.

Return to “Gaming Scripts (v1)”

Who is online

Users browsing this forum: No registered users and 35 guests