Help pressing keys and executing functions with a joystick, please?

Ask gaming related questions (AHK v1.1 and older)
RecklessPrudence
Posts: 11
Joined: 27 Sep 2016, 07:40

Help pressing keys and executing functions with a joystick, please?

13 Jan 2018, 05:48

Hi, I haven't written any AutoHotKey scripts for a while, and it seems I've forgotten everything I knew. All my old scripts work, but when I tried ripping the guts out of one and writing a new script with it, something's not working right, and I don't know what. I've done some testing, and the problem is twofold: First, I can't seem to get key or button presses to call functions properly, no matter whether they're on the keyboard or on a joystick. Second, I can't get joystick button presses to even do something as simple as simulate a keyboard press, even when copying directly from the tutorial. But I know the joystick can be used for AutoHotKey purposes, because my old scripts work!

The code I'm trying to convince to work is very simple:

Code: Select all

; Add slight delay to key presses
SetKeyDelay,10,10

; This is the joystick # from JoystickTest.ahk
JoyN := 2

; Keyboard mapping
SYS = {Left}
ENG = {Up}
WEP = {Right}
BAL = {Down}

; Basic commands
Joy6::Send %BAL%

...

; Macros
Joy24::PowerEng2Wep4()

...

; 2 pips to ENG, 4 pips to WEP
PowerEng2Wep4()
{
	Send %BAL%%WEP%%WEP%%ENG%%WEP%
}
But not only does that not work, neither of these do, either!

Code: Select all

Joy1::Send {Left}
Home::PowerEng2Wep4()
While this does!

Code: Select all

Home::Send %ENG%

And yet my old scripts, that have listening loops for the POVHats and mode switching so that a button press changes what some but not all of the buttons on the stick do, and a shift key so things are changed past that, all of that works with this stick! And I've double-checked the JoyN half a dozen times, it's the right one, so it's not that.

Anyway, I'm out of ideas, and thought I'd ask for help.

Any ideas?
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Help pressing keys and executing functions with a joystick, please?

13 Jan 2018, 15:20

Joy2:: remaps Joystick #1 button 2.
Joystick IDs can change. For example, if you installed vJoy, it would grab ID 1 and your physical stick would now be ID 2.

2Joy2:: means joystick 2, button 2

To see the IDs of sticks, use PJP joyIDs: https://theairtacticalassaultgroup.com/ ... hp?t=13009

Also, all the things you are trying to do in this script can be done via a GUI using UCR - See link in signature.
eg to map joystick button 1 to Left, add a ButtonToButton plugin, drop down the input box, select Bind, press button 1 on the stick, then drop down the output box, select bind, press the left button on the keyboard. Job done.
UCR also supports shift states, axis <-> button mappings, and it makes working with POV hats much, much simpler (Normal AHK does not let you declare a hotkey to a hat direction, you can only read a hat as an angle).
Last edited by evilC on 13 Jan 2018, 15:28, edited 1 time in total.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Help pressing keys and executing functions with a joystick, please?

13 Jan 2018, 15:25

Also be aware that in regular AHK, Joy1::Left does NOT properly remap button 1 to left.
When you hold button 1, left will be pressed once, briefly, and then released, because AHK fires the release event for joystick button hotkeys at the wrong time.

So if you need to be able to hold left, you need to add code to only fire the release event when the button is actually released.

Note that the following code appears to work, but in fact is not a proper solution:

Code: Select all

Joy1::
	Send {Left down}
	While(GetKeyState("Joy1")){
		Sleep 10
	}
	Send {Left up}
	return
Whilst this works for one button, if you try do do it for two buttons, it breaks (AHK can only be in one loop at one time). You need to use timers to solve it.
TLDR; If you can, forget coding it yourself and use UCR. I have solved all these issues for you in UCR ;)
RecklessPrudence
Posts: 11
Joined: 27 Sep 2016, 07:40

Re: Help pressing keys and executing functions with a joystick, please?

13 Jan 2018, 18:30

evilC wrote:Joy2:: remaps Joystick #1 button 2.
Joystick IDs can change. For example, if you installed vJoy, it would grab ID 1 and your physical stick would now be ID 2.

2Joy2:: means joystick 2, button 2

To see the IDs of sticks, use PJP joyIDs: https://theairtacticalassaultgroup.com/ ... hp?t=13009
I thought that was what the JoyN thing at the start of the script did? Or am I setting that but not using it?
evilC wrote:Also be aware that in regular AHK, Joy1::Left does NOT properly remap button 1 to left.
When you hold button 1, left will be pressed once, briefly, and then released, because AHK fires the release event for joystick button hotkeys at the wrong time.

So if you need to be able to hold left, you need to add code to only fire the release event when the button is actually released.

Note that the following code appears to work, but in fact is not a proper solution:

Code: Select all

Joy1::
	Send {Left down}
	While(GetKeyState("Joy1")){
		Sleep 10
	}
	Send {Left up}
	return
Whilst this works for one button, if you try do do it for two buttons, it breaks (AHK can only be in one loop at one time). You need to use timers to solve it.
I thought the SetKeyDelay setting did that, with the second 10 being Press Duration?
evilC wrote:TLDR; If you can, forget coding it yourself and use UCR. I have solved all these issues for you in UCR ;)
I usually use UCR, that's why I haven't touched normal AutoHotKey in so long. I was just hoping to brush the dust off my AutoHotKey skills, so I initially started with something I thought would be easy, because I'd just be repurposing a lot of existing code and refactoring it to get rid of a lot of the stuff I've learned is useless by using UCR.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Help pressing keys and executing functions with a joystick, please?

14 Jan 2018, 12:02

2Joy2:: The number at the start is the joystick ID (It can be omitted to mean joystick 1).
If you have vJoy installed, vJoy is very likely stick 1.
If you select "joystick 3, button 1" in UCR, that's 3Joy1:
I thought the SetKeyDelay setting did that, with the second 10 being Press Duration?
No if you do Send {a}, SetKeyDelay controls how long a is held down for.
It has zero effect on reading joysticks.

Support for joystick buttons in native AHK is pretty clunky.
The issue is illustrated by the following code:

Code: Select all

2Joy1::
2Joy2::
	Tooltip % A_ThisHotkey  " down"
	return
	
2Joy1 up::
2Joy2 up::
	Tooltip % A_ThisHotkey " up"
	return
As you can see, the up event always gets fired as soon as you press the button.


So you may try to solve this with:

Code: Select all

2Joy1::
2Joy2::
	Tooltip % A_ThisHotkey  " down"
	while (GetKeyState("2Joy1")){
		Sleep 10
	}
	Tooltip % A_ThisHotkey " up"
	return
Nope. Still does not work. Hold button 1, then hold button 2, then release button 1. The release event does not fire.

In order to properly solve it, you need code something like this:

Code: Select all

#SingleInstance force

HeldButtons := []
SetTimer, WatchButtons, 10
return

3Joy1::
	ToolTip % A_ThisHotkey " down"
	;~ Send {a down}
	HeldButtons.push({btn:A_ThisHotkey, key: "A"})
	return

3Joy2::
	Tooltip % A_ThisHotkey " down"
	;~ Send {b down}
	HeldButtons.push({btn: A_ThisHotkey, key: "B"})
	return

WatchButtons:
	for i, obj in HeldButtons {
		if (!GetKeyState(obj.btn, "P")){
			HeldButtons.Remove(i)
			;~ Send "{" obj.key "} up"
			Tooltip % obj.btn " up"
		}
	}
	return
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Help pressing keys and executing functions with a joystick, please?

14 Jan 2018, 12:14

Ah, I think I sort of see what you mean by SetKeyDelay now.
What you have to understand is that what Joy1::Send {a} is saying is "When I press joystick button 1, press AND RELEASE a".
Therefore, with this hotkey, it is impossible to hold the a key by pressing the joystick button - when you press and hold the button a will be pressed and released once, then nothing more will happen until you release the joystick button and re-press it.
SetKeyDelay controls how long A is held for in this instance. It is a fixed amount of time, totally unrelated to when you release the joystick button.

This is different to the hotkey Joy1::a which is MEANT to press a when you press the button and release a when you release the button.
However, this does not work properly (Because joystick release events fire immediately), meaning you need code like in my last post to fix this.
RecklessPrudence
Posts: 11
Joined: 27 Sep 2016, 07:40

Re: Help pressing keys and executing functions with a joystick, please?

14 Jan 2018, 19:20

That's okay, for the purposes I'm using AutoHotKey for, I only want it to press and release.

And it's weird that you say I have to go 2Joy2 to get button 2 on joystick 2, when on my older scripts having JoyN := 2 not only worked, but still works!

The other thing I'm confused about is that Home::PowerEng2Wep4() doesn't work - I'm just calling a function I created elsewhere in the script, with a key on the keyboard I know works for simple Send commands. Is that not the right syntax, or something?
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Help pressing keys and executing functions with a joystick, please?

14 Jan 2018, 19:44

It's hard to see why Home::PowerEng2Wep4() does not work, when I do not see what is in the function
I guess it is maybe

Code: Select all

PowerEng2Wep4(){
	Send %ENG%
}
in which case, your problem is scope. Add global Eng to the start of the function
RecklessPrudence
Posts: 11
Joined: 27 Sep 2016, 07:40

Re: Help pressing keys and executing functions with a joystick, please?

14 Jan 2018, 20:29

evilC wrote:It's hard to see why Home::PowerEng2Wep4() does not work, when I do not see what is in the function
I guess it is maybe

Code: Select all

PowerEng2Wep4(){
	Send %ENG%
}
in which case, your problem is scope. Add global Eng to the start of the function
Ah, whoops, didn't copy that properly. It's:

Code: Select all

PowerEng2Wep4()
{
	Send %BAL%%WEP%%WEP%%ENG%%WEP%
}
I did get rid of the Global, as I wasn't sure it was necessary to be a global function. I thought I could call PowerEng2Wep4() without it being global. I'll change that, and see if it works. But I've tried that before, and it didn't work.

It does! Yes! Thanks-you very much. Wonder why it didn't work before? Probably because I didn't update the script that was running before testing it. Oops.

Now, how about 'JoyN := 2', why do you think that isn't working when it does in older scripts? Was I doing something somewhat clever in older scripts, that I didn't copy out properly?
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Help pressing keys and executing functions with a joystick, please?

15 Jan 2018, 05:23

Code: Select all

PowerEng2Wep4()
{
	Global BAL, WEP, ENG
	Send %BAL%%WEP%%WEP%%ENG%%WEP%
}
Functions have their own scope. BAL, WEP and ENG are in the global scope, so you need to pull all of them in for the function to work.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Help pressing keys and executing functions with a joystick, please?

15 Jan 2018, 05:25

JoyN := 2 does nothing in any of the code you posted because you do not use the variable.
You assign it, but you never use it.
In all likelihood though, you have no use for a joystick button name in a variable. All of your hotkeys are static and you cannot use variables in static hotkey declarations (ie you cannot do %JoyN%::)
RecklessPrudence
Posts: 11
Joined: 27 Sep 2016, 07:40

Re: Help pressing keys and executing functions with a joystick, please?

20 Jan 2018, 04:31

evilC wrote:JoyN := 2 does nothing in any of the code you posted because you do not use the variable.
You assign it, but you never use it.
In all likelihood though, you have no use for a joystick button name in a variable. All of your hotkeys are static and you cannot use variables in static hotkey declarations (ie you cannot do %JoyN%::)
Ah, derp. Obviously.

Now that I'm back at my main machine, I took a look at the original code that I ripped the guts out of, and it turns out I missed some crucial portions of it necessary for the transplant.

In the old version, I had defined many keys, thus:

Code: Select all

UIUp = w
And was then using them like this:

Code: Select all

Hotkey,%JoyN%Joy6,UIUp
Which meant that when I plugged in my joystick and Windows decided it was a different number to the last time I did so, I only had to change JoyN in notepad, rather than fire up a proper editor and use a find-replace. Since this new joystick seems to like being Joystick 2 and has been so every time I've used it, that's no longer necessary.

Really you solved my problem a while ago, I just didn't want to stop until I understood both why the new code wasn't working and why the same pieces of code worked in my older stuff. Now that I've done that, I can happily use UCR. Otherwise it wouldn't have left me alone.

Thanks!
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Help pressing keys and executing functions with a joystick, please?

20 Jan 2018, 12:38

Code: Select all

UIUp = w
Hotkey,%JoyN%Joy6,UIUp
UIUp is a variable not a label. This is not valid syntax.
It says "When I press a hotkey, do variable". Obviously, this makes zero sense.

Maybe you meant Hotkey,%JoyN%Joy6,Send %UIUp% ?

Return to “Gaming Help (v1)”

Who is online

Users browsing this forum: No registered users and 55 guests