AHK vJoy Library - (Virtual) Joystick output for AHK

Post your working scripts, libraries and tools
User avatar
evilC
Posts: 4792
Joined: 27 Feb 2014, 12:30

AHK vJoy Library - (Virtual) Joystick output for AHK

10 Nov 2014, 15:48

This is not new, it was originally created by Axlar, but I have made some fixes over the years. I have obtained his permission to redistribute his code.

It has resided in the UJR project for some time now, but I think it is time to set it free and maybe let it become the basis for a standard library or something. The code aint that great, it could probably do with spit and polish, and it certainly needs documentation - all of which I would encourage community members to get involved with.

The project is hosted on GitHub here: https://github.com/evilC/AHK-vJoy-Library
Noesis
Posts: 299
Joined: 26 Apr 2014, 07:57

RegRead64() Assumes ANSI Encoding

11 Nov 2014, 07:22

Hi evilC been using an earlier version of this library for a while and thought I'd try this one, and couldn't get it to work due to some of the DLL calls in RegRead64(). Essentially the calls were assuming ANSI encoding which wasn't working for me using Unicode ahk. Fixed it and thought you'd like to know. The altered code for that function follows (essentially it's just the introduction of the ENC variable, the other code I added (2 variable initializations) is simply to stop warnings if including in a script with #warn set.

Code: Select all

RegRead64(sRootKey, sKeyName, sValueName = "", DataMaxSize=1024) {
	HKEY_CLASSES_ROOT   := 0x80000000   ; http://msdn.microsoft.com/en-us/library/aa393286.aspx
	HKEY_CURRENT_USER   := 0x80000001
	HKEY_LOCAL_MACHINE  := 0x80000002
	HKEY_USERS          := 0x80000003
	HKEY_CURRENT_CONFIG := 0x80000005
	HKEY_DYN_DATA       := 0x80000006
	HKCR := HKEY_CLASSES_ROOT
	HKCU := HKEY_CURRENT_USER
	HKLM := HKEY_LOCAL_MACHINE
	HKU  := HKEY_USERS
	HKCC := HKEY_CURRENT_CONFIG
	
	REG_NONE                := 0    ; http://msdn.microsoft.com/en-us/library/ms724884.aspx
	REG_SZ                  := 1
	REG_EXPAND_SZ           := 2
	REG_BINARY              := 3
	REG_DWORD               := 4
	REG_DWORD_BIG_ENDIAN    := 5
	REG_LINK                := 6
	REG_MULTI_SZ            := 7
	REG_RESOURCE_LIST       := 8

	KEY_QUERY_VALUE := 0x0001   ; http://msdn.microsoft.com/en-us/library/ms724878.aspx
	KEY_WOW64_64KEY := 0x0100   ; http://msdn.microsoft.com/en-gb/library/aa384129.aspx (do not redirect to Wow6432Node on 64-bit machines)
	KEY_SET_VALUE   := 0x0002
	KEY_WRITE       := 0x20006
	ENC := A_IsUnicode?"W":"A"
	hKey := "", sValueType := ""

	myhKey := %sRootKey%        ; pick out value (0x8000000x) from list of HKEY_xx vars
	IfEqual,myhKey,, {      ; Error - Invalid root key
		ErrorLevel := 3
		return ""
	}
	RegAccessRight := KEY_QUERY_VALUE + KEY_WOW64_64KEY
	;VarSetCapacity(sValueType, 4)
	DllCall("Advapi32.dll\RegOpenKeyEx" ENC, "uint", myhKey, "str", sKeyName, "uint", 0, "uint", RegAccessRight, "uint*", hKey)    ; open key
	DllCall("Advapi32.dll\RegQueryValueEx" ENC, "uint", hKey, "str", sValueName, "uint", 0, "uint*", sValueType, "uint", 0, "uint", 0)     ; get value type
	If (sValueType == REG_SZ or sValueType == REG_EXPAND_SZ) {
		VarSetCapacity(sValue, vValueSize:=DataMaxSize)
		DllCall("Advapi32.dll\RegQueryValueEx" ENC, "uint", hKey, "str", sValueName, "uint", 0, "uint", 0, "str", sValue, "uint*", vValueSize) ; get string or string-exp
	} Else If (sValueType == REG_DWORD) {
		VarSetCapacity(sValue, vValueSize:=4)
		DllCall("Advapi32.dll\RegQueryValueEx" ENC, "uint", hKey, "str", sValueName, "uint", 0, "uint", 0, "uint*", sValue, "uint*", vValueSize)   ; get dword
	} Else If (sValueType == REG_MULTI_SZ) {
		VarSetCapacity(sTmp, vValueSize:=DataMaxSize)
		DllCall("Advapi32.dll\RegQueryValueEx" ENC, "uint", hKey, "str", sValueName, "uint", 0, "uint", 0, "str", sTmp, "uint*", vValueSize)   ; get string-mult
		sValue := ExtractData(&sTmp) "`n"
		Loop {
			If (errorLevel+2 >= &sTmp + vValueSize)
				Break
			sValue := sValue ExtractData( errorLevel+1 ) "`n" 
		}
	} Else If (sValueType == REG_BINARY) {
		VarSetCapacity(sTmp, vValueSize:=DataMaxSize)
		DllCall("Advapi32.dll\RegQueryValueEx" ENC, "uint", hKey, "str", sValueName, "uint", 0, "uint", 0, "str", sTmp, "uint*", vValueSize)   ; get binary
		sValue := ""
		SetFormat, integer, h
		Loop %vValueSize% {
			hex := SubStr(Asc(SubStr(sTmp,A_Index,1)),3)
			StringUpper, hex, hex
			sValue := sValue hex
		}
		SetFormat, integer, d
	} Else {                ; value does not exist or unsupported value type
		DllCall("Advapi32.dll\RegCloseKey", "uint", hKey)
		ErrorLevel := 1
		return ""
	}
	DllCall("Advapi32.dll\RegCloseKey", "uint", hKey)
	return sValue
}
Noesis
Noesis
Posts: 299
Joined: 26 Apr 2014, 07:57

Re: AHK vJoy Library - (Virtual) Joystick output for AHK

12 Nov 2014, 01:58

No particular reason as far as I recall, I just elected to use Unicode ages ago when I first installed it, and I'm using the 64-bit version just because I always elect for a 64-bit version if one is available. As far as compiling goes, I don't really do it with ahk, but I'm not really sure if ANSI/Unicode would make much of a difference in compiled code for windows (i.e. the executable used to compile the code will take that into account ?). Naturally though you're correct with the 32-bit aspect.

Also I updated that other thread, thanks for pointing out it was from there, I'd overlooked that.
User avatar
evilC
Posts: 4792
Joined: 27 Feb 2014, 12:30

Re: AHK vJoy Library - (Virtual) Joystick output for AHK

28 Dec 2014, 18:07

This library has been updated for the new vJoy release which stores both (x64, x86) DLLs in the vJoy folder and includes a reg key pointing to them, thus negating the need to package DLLs with any release using the library.

This will probably be my last update to this library, I am now migrating to my new CvJoyInterface library.
Exigeous
Posts: 2
Joined: 05 Jan 2017, 17:26

Re: AHK vJoy Library - (Virtual) Joystick output for AHK

05 Jan 2017, 17:32

Quick question that I'm not sure this will do - what I'd like to do is simulate the output of an existing, physical joystick. Here's what I'm trying to do:

- Joystick for flight
- 2 degree motion platform
- When I stick back, seat leans back, forward and seat leans forward
(the game I'm playing, Elite Dangerous doesn't support telemetry so I just track my stick)

What I'd like to add is when I jump into Frame Shift (warp drive) that software would send a command telling the seat software that I've pulled the stick all the way back. When the jump is over the software would return it to middle/normal. Unfortunately the app that drives the motion isn't great for that kind of thing, it's built around having great telemetry/etc. I think it would be a cool effect to have the seat shoot back while in warp but return to normal when I'm out of warp.

Any thoughts on how to do that? Would this only emulate another/non-existant joystick device?

Thanks for any help you can provide!!

~X
User avatar
evilC
Posts: 4792
Joined: 27 Feb 2014, 12:30

Re: AHK vJoy Library - (Virtual) Joystick output for AHK

05 Jan 2017, 18:34

Currently that's all you can do with vJoy, but times are changing. There is a new app in development, early versions are becoming available, which can hide physical devices from selected apps.
The software is called HidGuardian, and it is part of ViGEm (A new vJoy-like app) but it should play ball with vJoy.
Keep an eye on my UCR thread (See link in signature) as I am in the process of implementing HidGuardian into UCR, so once I get a handle on that I would be able to show you how to do it. You would probably need to remap the whole stick to a virtual version, then hide the physical stick from the game.
Exigeous
Posts: 2
Joined: 05 Jan 2017, 17:26

Re: AHK vJoy Library - (Virtual) Joystick output for AHK

05 Jan 2017, 22:00

Thanks for the thoughts - I'm sure there are many ways to do it but all I'd want to do would be emulate the stick moving 100% in a specific direction then back to neutral, then 100% in another then back. It's the stick that I'm flying with so if we did some kind of emulate, hide, emulate, unhide, etc. I'd worry that would really screw up inputs to the game.

That said obviously I'm not coding it so I'd certainly be open to any ideas/suggestions you'd have to make it work. Honestly I'm not even sure my idea would work that well as there's no way for me to get data/API from the game to know when my ship enters and exits Frame Shift Drive (Elite Dangerous' version of warp drive). I'd have to just use simple timers, so when I press the jump button wait X seconds then full stick back for 1 and release, count X more seconds the stick full forward for 1 then back. The trouble is that FSD is *usually* 5 seconds but about 10% of the time it's say 6 or 9 or 3. So I'm not sure it would even be a cool feature.

That said I love hacking with this kinda stuff so if you've got suggestions I'm all ears.
User avatar
evilC
Posts: 4792
Joined: 27 Feb 2014, 12:30

Re: AHK vJoy Library - (Virtual) Joystick output for AHK

06 Jan 2017, 06:42

I know of no way to alter what data is coming from a physical stick.
Your ONLY option is the emulate, remap, hide path.

Unless your physical stick is an XBox controller, in which case X360CE can trick a game into thinking the controller is doing one thing, but is really doing another.
Anyone who plays Elite with an XBox controller seriously needs their head examined though - most people don't seem to realize that with an XBox controller, you can EITHER use the X axis OR the Y axis fully, but not both at the same time! 100% x axis deflection means y deflection must be 0%, due to the round shape of the aperture. M$ bringing out an XBox controller for Elite and claiming it was "Designed from the ground up for Elite" is pure marketing BS. It's not even a 6-axis controller really, more like a 5 axis controller (4 full axes plus 2 trigger half axes).
Anyway, rant over, normal programming will now resume :P
Noesis
Posts: 299
Joined: 26 Apr 2014, 07:57

Re: AHK vJoy Library - (Virtual) Joystick output for AHK

07 Jan 2017, 02:57

Hi guys, Exigeous, you may be able to do it anyway (without hiding your physical stick) but it depends on the "chair" software.

Elite Dangerous won't care what other joysticks are doing, it only cares about the ones setup in the game and they can be virtual or physical or a combination of the two. If you look at the "*.binds" file your using for Elite in a text editor, you can see exactly which joysticks and axes elite is reading for each function, in game it just tells you the axis being used with no mention of which stick it belongs to, so looks like all the same axis but it really isn't), It's more dependent on the chair software, can that read a virtual (emulated) stick, if it can then you could do it but if not you may still be able to fake it, you said something about it using telemetry, perhaps you could create some fake telemetry for it and have it use that ?.

Return to “Scripts and Functions”

Who is online

Users browsing this forum: No registered users and 21 guests