Joystick Hat Switch - multiple hotkeys to change the function

Ask gaming related questions (AHK v1.1 and older)
GreatGreen
Posts: 5
Joined: 24 Sep 2020, 20:26

Joystick Hat Switch - multiple hotkeys to change the function

24 Sep 2020, 20:44

So I've been playing a lot of flight simulators lately, and all of them seem to require joysticks with two or three mini-dpads on the top of the throttle. However, my joystick only has one hat switch. It does have multiple buttons along with it though.

I'd really like to setup an Autohotkey script that essentially makes each button click reconfigure the hotkeys of the hatswitch to simulate all the different hat switches of fighter jets and things like that. Basically I'd like to do something like this:

Press Joy1 = Hat switch Up, Down, Left, Right, becomes keys 1, 2, 3, 4
Press Joy2 = Hat switch Up, Down, Left, Right, becomes keys 5, 6, 7, 8

...and so on for about 5 different joystick buttons, with one of those buttons returning the hat switch to standard function. I found this script online that allows me to simply change the bindings of the hat switch statically, but I'd love to know how I can apply this to setup dynamic bindings depending on which "modifier" joystick button I press before hand. Here's the script I found:


Code: Select all

#Persistent  ; Keep this script running until the user explicitly exits it.
SetTimer, WatchPOV, 5
return

WatchPOV:
GetKeyState, POV, JoyPOV  ; Get position of the POV control.
KeyToHoldDownPrev = %KeyToHoldDown%  ; Prev now holds the key that was down before (if any).

; Some joysticks might have a smooth/continous POV rather than one in fixed increments.
; To support them all, use a range:
if POV < 0   ; No angle to report
    KeyToHoldDown =
else if POV > 31500                 ; 315 to 360 degrees: Forward
    KeyToHoldDown = Up
else if POV between 0 and 4500      ; 0 to 45 degrees: Forward
    KeyToHoldDown = Up
else if POV between 4501 and 13500  ; 45 to 135 degrees: Right
    KeyToHoldDown = Right
else if POV between 13501 and 22500 ; 135 to 225 degrees: Down
    KeyToHoldDown = Down
else                                ; 225 to 315 degrees: Left
    KeyToHoldDown = Left

if KeyToHoldDown = %KeyToHoldDownPrev%  ; The correct key is already down (or no key is needed).
{
    if KeyToHoldDown
        Send, {%KeyToHoldDown% down}  ; Auto-repeat the keystroke.
    return
}

; Otherwise, release the previous key and press down the new key:
SetKeyDelay -1  ; Avoid delays between keystrokes.
if KeyToHoldDownPrev   ; There is a previous key to release.
    Send, {%KeyToHoldDownPrev% up}  ; Release it.
if KeyToHoldDown   ; There is a key to press down.
    Send, {%KeyToHoldDown% down}  ; Press it down.
return


This script does remap the hat switch, but I'm not sure how to make it work in the way I'm trying to make it work.
A_AhkUser
Posts: 1147
Joined: 06 Mar 2017, 16:18
Location: France
Contact:

Re: Joystick Hat Switch - multiple hotkeys to change the function

25 Sep 2020, 21:16

GreatGreen wrote:
24 Sep 2020, 20:44
I'd really like to setup an Autohotkey script that essentially makes each button click reconfigure the hotkeys of the hatswitch to simulate all the different hat switches of fighter jets and things like that. Basically I'd like to do something like this:

Press Joy1 = Hat switch Up, Down, Left, Right, becomes keys 1, 2, 3, 4
Press Joy2 = Hat switch Up, Down, Left, Right, becomes keys 5, 6, 7, 8
Sample example (using a slighy modified version of POVHelper by EvilC for convinience):

Code: Select all

#NoEnv
#Warn
SendMode Input
SetWorkingDir %A_ScriptDir%
#SingleInstance force


portNumber := 1
ph := new PovHelper(portNumber)

global offset := 0
joyStr := ph.stickId . "Joy"

Loop, 5 {
	Hotkey % joyStr . a_index, setOffset, On
}
ph.Subscribe("Up", Func("Up"))
ph.Subscribe("Left", Func("Left"))
ph.Subscribe("Down", Func("Down"))
ph.Subscribe("Right", Func("Right"))
return

setOffset:
	offset := (StrSplit(A_ThisHotkey, joyStr).pop() - 1) * 4
return

^Esc::ExitApp

Up(state){
    Tooltip % offset+1 ; here use the send command instead of the tooltip one to send keys (https://www.autohotkey.com/docs/commands/Send.htm)
    ; sendinput % offset+1
}
Down(state){
    Tooltip % offset+2
}
Left(state){
    Tooltip % offset+3
}
Right(state){
    Tooltip % offset+4
}

class PovHelper {
    static PovMap := {-1: [0,0,0,0], 1: [1,0,0,0], 2: [1,1,0,0] , 3: [0,1,0,0], 4: [0,1,1,0], 5: [0,0,1,0], 6: [0,0,1,1], 7: [0,0,0,1], 8: [1,0,0,1]}
    static directionNames := {Up: 1, Right: 2, Down: 3, Left: 4}
	static DEAD_POINT := -1
    callbacks := {}
    currentAngle := this.DEAD_POINT
    directionStates := [0,0,0,0]
    __New(stickId){
        fn := this.WatchPov.Bind(this)
        this.stickId := stickId
        this.povStr := stickId "JoyPOV"
		this.getKeyStateFn := Func("GetKeyState").bind(this.povStr)
        SetTimer, % fn, -1
    }
	getKeyState(ByRef _angle:="") {
	static DEAD_POINT := PovHelper.DEAD_POINT
	return ((_angle:=this.getKeyStateFn.call()) >= DEAD_POINT)
	}
    Subscribe(dir, callback){
        if (this.directionNames.HasKey(dir)){   ; Translate from direction name to index, if needed
            dir := this.directionNames[dir]
        }
        this.Callbacks[dir] := callback
    }   
    WatchPov(){
		static connected := false
        if not (this.GetKeyState(angle)) {
			SetTimer,, 1000
			connected := false
		return
		} else if not (connected) {
			SetTimer,, 10
			connected := true
		}
        if (angle == this.currentAngle)
            return
        this.currentAngle := angle
        angle := (angle = -1 ? -1 : round(angle / 4500) + 1)
        newStates := this.PovMap[angle]
        Loop 4 {
            if (this.directionStates[A_Index] != newStates[A_Index]){
                this.directionStates[A_Index] := newStates[A_Index]
                if (this.callbacks.HasKey(A_Index)){
                    this.callbacks[A_Index].call(newStates[A_Index])
                }
            }
        }
    }
}
A_AhkUser
my scripts

Return to “Gaming Help (v1)”

Who is online

Users browsing this forum: No registered users and 46 guests