JoeViking245 Posted January 15 Share Posted January 15 20 minutes ago, -neo- said: I swapped over controller to an original Xbox 360 i have kicking around, works spot on as you said it would 😁 Any ideas why it doesn't work with a "Power A enhanced Xbox one/windows 10 controller" Glad you got it to work! At least with one controller. I only have an original 360 controller (wireless), so can't attest to the other. It looks like the Power A is a corded controller. So it may be related to what @skizzosjt was mentioning regarding the joy number (not to be confused with the Button #). That is, it might be being seen as Joy controller #2, or #4 or something other than 1Joy. So "1Joy6" may need to be "2Joy6" or "4Joy6". Quote Link to comment Share on other sites More sharing options...
-neo- Posted January 15 Share Posted January 15 3 hours ago, JoeViking245 said: Glad you got it to work! At least with one controller. I only have an original 360 controller (wireless), so can't attest to the other. It looks like the Power A is a corded controller. So it may be related to what @skizzosjt was mentioning regarding the joy number (not to be confused with the Button #). That is, it might be being seen as Joy controller #2, or #4 or something other than 1Joy. So "1Joy6" may need to be "2Joy6" or "4Joy6". Looks like mine is controller 1 after all, @skizzosjt any ideas how to make this work with the power A controller ? Quote Link to comment Share on other sites More sharing options...
skizzosjt Posted January 15 Share Posted January 15 (edited) 6 hours ago, -neo- said: Any ideas why it doesn't work with a "Power A enhanced Xbox one/windows 10 controller", this does have 2 extra buttons underneath but they don't register on the PC, you can program these to act like the other buttons but i never have, in windows when i run "set up USB controller" the same buttons (5&6) are shown as working the same way on both controllers 🤔 2 hours ago, -neo- said: Looks like mine is controller 1 after all, @skizzosjt any ideas how to make this work with the power A controller ? Hi Neo, I just explained this on page 56 so please go read those two posts. Make sure you read this new post here in it's entirety too. Also the two "underneath" buttons are duplicates of whatever you program them to be via the controller's program button which is also on the underside. These buttons on the bottom of the controller only are detected by any program or game if you assigned them a button, so if you never programmed them, it makes sense why no program or game detects them. 6 hours ago, JoeViking245 said: It looks like the Power A is a corded controller. So it may be related to what @skizzosjt was mentioning regarding the joy number (not to be confused with the Button #). That is, it might be being seen as Joy controller #2, or #4 or something other than 1Joy. So "1Joy6" may need to be "2Joy6" or "4Joy6". They have exact same controller I do and the key issue there is due to it being an Xbox One model. But I'd bet also lending to the issue as a whole is same thing you and I mention about Joy (controller) number. I played around with an example of how to use Xbox One or Xbox Series X controller specific hotkeys, or detecting any controller input from these models without use of xinput library. Since you need an active window for GetKeyState to capture those inputs correctly, I thought maybe I make a little menu to select a few things. This is just a proof of concept script, as it does nothing practical other than demonstrate this. Recently found triple click hotkey examples, so thought I'd show an example of that here too. This one you would need to triple click on the Guide button to bring up a window. Now that a window from the script is in focus, controller specific hotkeys and GetKeyState will work for even Xbox One and Series X controllers. These two examples just will have soundbeep activate when the buttons are detected vk07:: ;Xbox Guide button SetTimer, TripleClickDetect, -200 ;run timer only once after 200ms passes due to negative symbol GuideClickCount++ If (GuideClickCount = 3) { Gui, Main:New, , HTPC Menu Gui, Main:Show, w500 h500 Goto, CheckControllerState } Return TripleClickDetect: ;this will clear the click count variable GuideClickCount := ;creating a 200ms window to detect 3 clicks Return MainGuiClose: ExitApp CheckControllerState: SetTimer, ControllerInputCheck, 16 ;timer will consistently start in 16ms intervals ControllerInputCheck: Return 2Joy6:: ;"2nd controller's Right Bumper" per Windows/AHK If (GetKeyState("2Joy5")) ;"2nd controller's Left Bumper" per Windows/AHK SoundBeep This one the difference from script above is just removing the Return after the ControllerInputCheck timer. So this works more like a normal controller state checking script rather than a hotkey. Changed the controller button used too for sake of example vk07:: ;Xbox Guide button SetTimer, TripleClickDetect, -200 ;run timer only once after 200ms passes due to negative symbol GuideClickCount++ If (GuideClickCount = 3) { Gui, Main:New, , HTPC Menu Gui, Main:Show, w500 h500 Goto, CheckControllerState } Return TripleClickDetect: ;this will clear the click count variable GuideClickCount := ;creating a 200ms window to detect 3 clicks Return MainGuiClose: ExitApp CheckControllerState: SetTimer, ControllerInputCheck, 16 ;timer will consistently start in 16ms intervals ControllerInputCheck: If (GetKeyState("2Joy1")) ;"2nd controller's A button" per Windows/AHK SoundBeep Users with Xbox One and Series X model controllers will notice the script stops detecting controller input as soon as a script window no longer has focus. Once back in focus, it works again. Unlike Xbox 360 controllers that can still have controller specific hotkeys and GetKeyState work even when a script window is not in focus. And here is more specific example of having an interface to use with a controller. Get the GUI to show by triple clicking the Guide button. Then what you can do here is use left/right on the D-Pad to select between the two buttons. You can open an instance of Notepad, or exit the script. Use the "A" button on your controller to select either of them. Note you need to be more specific with your If/Else logic like I did or else you will get "turbo fire" going on.....or you need to really reduce the timer interval/frequency but then that creates input lag. Which may be fine for some silly example like this but actual gaming use you obviously don't want more lag due to needing more X ms before detection. Without being more specific with If/Else logic, when you use the controller to open notepad several instances of notepad will open because maybe you hold the button down for 120ms but it checks every 16ms so there would be multiple fires of the send command. This same method works for using xinput library too. When I have more time I will show what I made a while ago with help from JoeViking since I think that will be helpful to community for understanding vk07:: ;Xbox Guide button SetTimer, TripleClickDetect, -200 ;run timer only once after 200ms passes due to negative symbol GuideClickCount++ If (GuideClickCount = 3) { Gui, Main:New, , HTPC Menu Gui, Main:Show, w500 h500 Gui, Main:Add, Button, x25 y25 w70 gRunNotepad, Launch Notepad Gui, Main:Add, Button, x400 y25 w70 gMainGuiClose, Exit Script Goto, CheckControllerState } Return TripleClickDetect: ;this will clear the click count variable GuideClickCount := ;creating a 200ms window to detect 3 clicks Return MainGuiClose: ExitApp RunNotepad: Run, Notepad Return CheckControllerState: SetTimer, ControllerInputCheck, 16 ;timer will consistently start in 16ms intervals ControllerInputCheck: ;Joy #, button #, POV #, per AHK's Official Controller Test Script If (GetKeyState("2Joy1")) { ;2nd controller's A button If (A_Btn_Pressed != 1) { A_Btn_Pressed := 1 Send {Enter down} } } Else If (A_Btn_Pressed = 1) { A_Btn_Pressed := 0 Send {Enter up} } If (GetKeyState("2JoyPOV") = 9000) { ;2nd controller's Right D-Pad button If (DPad_Right_Pressed != 1 ) { DPad_Right_Pressed := 1 Send {Right down} } } Else If (DPad_Right_Pressed = 1) { DPad_Right_Pressed := 0 Send {Right up} } If (GetKeyState("2JoyPOV") = 27000) { ;2nd controller's Left D-Pad button If (DPad_Left_Pressed != 1 ) { DPad_Left_Pressed := 1 Send {Left down} } } Else If (DPad_Left_Pressed = 1) { DPad_Left_Pressed := 0 Send {Left up} } Note from AHK's docs seems controllers can have different POV values which is the D-pad. Since I know Neo has same controller as I used in this example I know it will work for them but for others left/right might have different values and you would have to find that out through AHK's Controller Test Script https://www.autohotkey.com/docs/v1/misc/RemapController.htm Note for all these scripts I shared in this post just now. Unless your controller comes up as #2, users need to change the Joy (controller) number accordingly per Windows and therefore AHK's Controller Test Script https://www.autohotkey.com/docs/v1/scripts/index.htm#ControllerTest Edited January 15 by skizzosjt changed variable names from "down" to "pressed" (less potential to confuse direction vs button is pressed) 2 Quote Link to comment Share on other sites More sharing options...
pafftis Posted January 16 Share Posted January 16 On 1/15/2024 at 3:21 PM, pafftis said: its my config. I used this code, but I still can't close the emulator. I tried the second joystick, but it still doesn't work. I hold down the button and press the second one after it, but it still doesn't come out. Can you tell me if my script is correct? Quote Link to comment Share on other sites More sharing options...
-neo- Posted January 17 Share Posted January 17 (edited) Thanks @skizzosjt for your in-depth reply, i'll look into them Edited January 20 by -neo- Quote Link to comment Share on other sites More sharing options...
skizzosjt Posted January 26 Share Posted January 26 Here is some example of using xinput library with AHK in order to work with any xinput controller regardless of any script owned window being in focus. You need a few things to make this work. First is the xinput library. For anyone wondering why I keep calling this a library it's just an AHK term for describing a script that typically doesn't do anything by itself, but using a supplement script calling to the functions in the "library" script. The 2nd thing is this supplement script that has all the meat and potatoes part, where you code this button does this and that joystick does that sort of stuff. Now what I've got to show here is something that will basically make your controller work like a mouse. What I discovered is if you put the logic for mouse movement and checking ALL the buttons into the same script, it seems AHK genuinely does not run fast enough to make the mouse movement work well while doing all the additional checks. AHK is not multi-threaded. So a way to make pseudo multi-threaded AHK is to launch multiple scripts simultaneously. So I have one script dedicated to using the left joystick as controlling the mouse (this makes it feel as smooth as possible), and a separate script dedicated to all the buttons. I then created a third script to launch these two meat and potatoes scripts....so in total, I got four scripts here to do this. The latest xinput library will use xinput1_4.dll but will fall back to xinput1_3.dll if you're on an older OS like Windows 7. Please note I did not create any of this specific xinput.ahk library script. All credit for the xinput library goes to the author Lexikos Name this script below as xinput.ahk Spoiler /* XInput by Lexikos * Requires AutoHotkey 1.1+. */ /* Function: XInput_Init Initializes XInput.ahk with the given XInput DLL. Parameters: dll - The path or name of the XInput DLL to load. */ XInput_Init(dll:="") { global if _XInput_hm return ;======== CONSTANTS DEFINED IN XINPUT.H ======== ; NOTE: These are based on my outdated copy of the DirectX SDK. ; Newer versions of XInput may require additional constants. ; Device types available in XINPUT_CAPABILITIES XINPUT_DEVTYPE_GAMEPAD := 0x01 ; Device subtypes available in XINPUT_CAPABILITIES XINPUT_DEVSUBTYPE_GAMEPAD := 0x01 ; Flags for XINPUT_CAPABILITIES XINPUT_CAPS_VOICE_SUPPORTED := 0x0004 ; Constants for gamepad buttons XINPUT_GAMEPAD_DPAD_UP := 0x0001 XINPUT_GAMEPAD_DPAD_DOWN := 0x0002 XINPUT_GAMEPAD_DPAD_LEFT := 0x0004 XINPUT_GAMEPAD_DPAD_RIGHT := 0x0008 XINPUT_GAMEPAD_START := 0x0010 XINPUT_GAMEPAD_BACK := 0x0020 XINPUT_GAMEPAD_LEFT_THUMB := 0x0040 XINPUT_GAMEPAD_RIGHT_THUMB := 0x0080 XINPUT_GAMEPAD_LEFT_SHOULDER := 0x0100 XINPUT_GAMEPAD_RIGHT_SHOULDER := 0x0200 XINPUT_GAMEPAD_GUIDE := 0x0400 XINPUT_GAMEPAD_A := 0x1000 XINPUT_GAMEPAD_B := 0x2000 XINPUT_GAMEPAD_X := 0x4000 XINPUT_GAMEPAD_Y := 0x8000 ; Gamepad thresholds XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE := 7849 XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE := 8689 XINPUT_GAMEPAD_TRIGGER_THRESHOLD := 30 ; Flags to pass to XInputGetCapabilities XINPUT_FLAG_GAMEPAD := 0x00000001 ;=============== END CONSTANTS ================= if (dll = "") Loop %A_WinDir%\System32\XInput1_*.dll dll := A_LoopFileName if (dll = "") dll := "XInput1_3.dll" _XInput_hm := DllCall("LoadLibrary" ,"str",dll ,"ptr") if !_XInput_hm throw Exception("Failed to initialize XInput: " dll " not found.") (_XInput_GetState := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"ptr",100 ,"ptr")) || (_XInput_GetState := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"astr","XInputGetState" ,"ptr")) _XInput_SetState := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"astr","XInputSetState" ,"ptr") _XInput_GetCapabilities := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"astr","XInputGetCapabilities" ,"ptr") if !(_XInput_GetState && _XInput_SetState && _XInput_GetCapabilities) { XInput_Term() throw Exception("Failed to initialize XInput: function not found.") } } /* Function: XInput_GetState Retrieves the current state of the specified controller. Parameters: UserIndex - [in] Index of the user's controller. Can be a value from 0 to 3. Returns: The current state of the controller as an associative array. ErrorLevel: If the function succeeds, ErrorLevel is ERROR_SUCCESS (zero). If the controller is not connected, ErrorLevel is ERROR_DEVICE_NOT_CONNECTED (1167). If the function fails, ErrorLevel is an error code defined in Winerror.h. http://msdn.microsoft.com/en-us/library/ms681381.aspx Remarks: XInput.dll returns controller state as a binary structure: http://msdn.microsoft.com/en-us/library/microsoft.directx_sdk.reference.xinput_state http://msdn.microsoft.com/en-us/library/microsoft.directx_sdk.reference.xinput_gamepad */ XInput_GetState(UserIndex) { global _XInput_GetState VarSetCapacity(xiState,16) if ErrorLevel := DllCall(_XInput_GetState ,"uint",UserIndex ,"uint",&xiState) return 0 return { (Join, dwPacketNumber: NumGet(xiState, 0, "UInt") wButtons: NumGet(xiState, 4, "UShort") bLeftTrigger: NumGet(xiState, 6, "UChar") bRightTrigger: NumGet(xiState, 7, "UChar") sThumbLX: NumGet(xiState, 8, "Short") sThumbLY: NumGet(xiState, 10, "Short") sThumbRX: NumGet(xiState, 12, "Short") sThumbRY: NumGet(xiState, 14, "Short") )} } /* Function: XInput_SetState Sends data to a connected controller. This function is used to activate the vibration function of a controller. Parameters: UserIndex - [in] Index of the user's controller. Can be a value from 0 to 3. LeftMotorSpeed - [in] Speed of the left motor, between 0 and 65535. RightMotorSpeed - [in] Speed of the right motor, between 0 and 65535. Returns: If the function succeeds, the return value is 0 (ERROR_SUCCESS). If the controller is not connected, the return value is 1167 (ERROR_DEVICE_NOT_CONNECTED). If the function fails, the return value is an error code defined in Winerror.h. http://msdn.microsoft.com/en-us/library/ms681381.aspx Remarks: The left motor is the low-frequency rumble motor. The right motor is the high-frequency rumble motor. The two motors are not the same, and they create different vibration effects. */ XInput_SetState(UserIndex, LeftMotorSpeed, RightMotorSpeed) { global _XInput_SetState return DllCall(_XInput_SetState ,"uint",UserIndex ,"uint*",LeftMotorSpeed|RightMotorSpeed<<16) } /* Function: XInput_GetCapabilities Retrieves the capabilities and features of a connected controller. Parameters: UserIndex - [in] Index of the user's controller. Can be a value in the range 0–3. Flags - [in] Input flags that identify the controller type. 0 - All controllers. 1 - XINPUT_FLAG_GAMEPAD: Xbox 360 Controllers only. Returns: The controller capabilities, as an associative array. ErrorLevel: If the function succeeds, ErrorLevel is 0 (ERROR_SUCCESS). If the controller is not connected, ErrorLevel is 1167 (ERROR_DEVICE_NOT_CONNECTED). If the function fails, ErrorLevel is an error code defined in Winerror.h. http://msdn.microsoft.com/en-us/library/ms681381.aspx Remarks: XInput.dll returns capabilities via a binary structure: http://msdn.microsoft.com/en-us/library/microsoft.directx_sdk.reference.xinput_capabilities */ XInput_GetCapabilities(UserIndex, Flags) { global _XInput_GetCapabilities VarSetCapacity(xiCaps,20) if ErrorLevel := DllCall(_XInput_GetCapabilities ,"uint",UserIndex ,"uint",Flags ,"ptr",&xiCaps) return 0 return, (Join { Type: NumGet(xiCaps, 0, "UChar"), SubType: NumGet(xiCaps, 1, "UChar"), Flags: NumGet(xiCaps, 2, "UShort"), Gamepad: { wButtons: NumGet(xiCaps, 4, "UShort"), bLeftTrigger: NumGet(xiCaps, 6, "UChar"), bRightTrigger: NumGet(xiCaps, 7, "UChar"), sThumbLX: NumGet(xiCaps, 8, "Short"), sThumbLY: NumGet(xiCaps, 10, "Short"), sThumbRX: NumGet(xiCaps, 12, "Short"), sThumbRY: NumGet(xiCaps, 14, "Short") }, Vibration: { wLeftMotorSpeed: NumGet(xiCaps, 16, "UShort"), wRightMotorSpeed: NumGet(xiCaps, 18, "UShort") } } ) } /* Function: XInput_Term Unloads the previously loaded XInput DLL. */ XInput_Term() { global if _XInput_hm DllCall("FreeLibrary","uint",_XInput_hm), _XInput_hm :=_XInput_GetState :=_XInput_SetState :=_XInput_GetCapabilities :=0 } ; TODO: XInputEnable, 'GetBatteryInformation and 'GetKeystroke. This is the script for just manipulating the left joystick and it will control your mouse cursor Name this script as xinput remap mouse only.ahk Spoiler #Include xinput.ahk #Persistent XInput_Init() SetMouseDelay, -1 MouseMoveInterval := 3 SetTimer, InputCheck, 0 InputCheck: state := Xinput_GetState(0) If (state) { If (state.bRightTrigger > 175) { ;Right Trigger = modifier to enable fast mouse movement If (RT_Pressed != 1) { MouseMoveInterval := 20 RT_Pressed := 1 } } Else If (MouseMoveInterval != 3) { RT_Pressed := 0 MouseMoveInterval := 3 } ;Left Joy Stick (0 = Center and +/- 9000 is the deadzone) ;Range between -32768 and 32767. If (state.sThumbLX < -9000 && state.sThumbLX >= -32768) ;Left joystick left = move mouse left MouseMove, -%MouseMoveInterval%, 0, 0, R If (state.sThumbLX > 9000 && state.sThumbLX <= 32767) ;Left joystick right = move mouse right MouseMove, %MouseMoveInterval%, 0, 0, R If (state.sThumbLY > 9000 && state.sThumbLY <= 32767) ;Left joystick up = move mouse up MouseMove, 0, -%MouseMoveInterval%, 0, R If (state.sThumbLY < -9000 && state.sThumbLY >= -32768) ;Left joystick down = move mouse down MouseMove, 0, %MouseMoveInterval%, 0, R } This is the script for everything else on the controller Name this script as xinput remap.ahk Spoiler #Include xinput.ahk #Persistent XInput_Init() SetTimer, InputCheck, 16 InputCheck: state := Xinput_GetState(0) If (state) { If (state.wButtons = 4096) { ;A button = Left Mouse Click If (A_BtnDown != 1) { Send {LButton down} Sleep, 50 A_BtnDown := 1 } } Else If (A_BtnDown = 1) { Send {LButton Up} A_BtnDown := 0 } If (state.wButtons = 8192) { ;B button = Right Mouse Click If (B_BtnDown != 1) { Send, {RButton} B_BtnDown := 1 } } Else If (B_BtnDown = 1) B_BtnDown := 0 If (state.wButtons = 16384) { ;X button = Double Left Mouse Click If (X_BtnDown != 1) { Send, {LButton 2} X_BtnDown := 1 } } Else If (X_BtnDown = 1) X_BtnDown := 0 If (state.wButtons = 32768) { ;Y button = rumble test If (Y_BtnDown != 1) { XInput_SetState(0, 65535, 65535) ;making controller #1 rumble at 100% example Sleep, 2000 XInput_SetState(0, 0, 0) ;turning rumble off Y_BtnDown := 1 } } Else If (Y_BtnDown = 1) Y_BtnDown := 0 If (state.wButtons = 1) { ;D-Pad Up = Up key / Page Up key If (DPad_Up_Pressed != 1) { If (RT_Pressed = 1) { Send {Up down} DPad_Up_Pressed := 0 } Else If (LT_Pressed = 1) { Send {PgUp} DPad_Up_Pressed := 1 } Else { Send {Up down} DPad_Up_Pressed := 1 } } } Else If (DPad_Up_Pressed = 1) { DPad_Up_Pressed := 0 Send {Up up} } If (state.wButtons = 2) { ;D-Pad Down = Down key / Page Down key If (DPad_Down_Pressed != 1) { If (RT_Pressed = 1) { Send {Down down} DPad_Down_Pressed := 0 } Else If (LT_Pressed = 1) { Send {PgDn} DPad_Down_Pressed := 1 } Else { Send {Down down} DPad_Down_Pressed := 1 } } } Else If (DPad_Down_Pressed = 1) { DPad_Down_Pressed := 0 Send {Down up} } If (state.wButtons = 4) { ;D-Pad Left = Left key If (DPad_Left_Pressed != 1) { If (RT_Pressed = 1) { Send {Left down} DPad_Left_Pressed := 0 } Else { Send {Left down} DPad_Left_Pressed := 1 } } } Else If (DPad_Left_Pressed = 1) { DPad_Left_Pressed := 0 Send {Left up} } If (state.wButtons = 8) { ;D-Pad Right = Right key If (DPad_Right_Pressed != 1) { If (RT_Pressed = 1) { Send {Right down} DPad_Right_Pressed := 0 } Else { Send {Right down} DPad_Right_Pressed := 1 } } } Else If (DPad_Right_Pressed = 1) { DPad_Right_Pressed := 0 Send {Right up} } If (state.wButtons = 1024) { ;Guide button = NOT IN USE If (Guide_BtnDown != 1) { SoundBeep, 400 Guide_BtnDown := 1 } } Else If (Guide_BtnDown = 1) Guide_BtnDown := 0 If(state.wButtons = 16) { ;Start = NOT IN USE If (Start_Pressed != 1) { SoundBeep, 500 Start_Pressed := 1 } } Else If (Start_Pressed = 1) Start_Pressed := 0 If (state.wButtons = 32) { ;Back = NOT IN USE If (Back_Pressed != 1) { SoundBeep, 600 Back_Pressed := 1 } } Else If (Back_Pressed = 1) Back_Pressed := 0 If (state.wButtons = 256) { ;Left Bumper = NOT IN USE If (Left_Bumper_Pressed != 1) { SoundBeep, 700 Left_Bumper_Pressed := 1 } } Else If (Left_Bumper_Pressed = 1) Left_Bumper_Pressed := 0 If (state.wButtons = 512) { ;Right Bumper = NOT IN USE If (Right_Bumper_Pressed != 1) { SoundBeep, 800 Right_Bumper_Pressed := 1 } } Else If (Right_Bumper_Pressed = 1) Right_Bumper_Pressed := 0 If (state.wButtons = 64) { ;Left Joystick Click = NOT IN USE If (LJS_Pressed != 1) { SoundBeep, 900 LJS_Pressed := 1 } } Else If (LJS_Pressed = 1) LJS_Pressed := 0 If (state.wButtons = 128) { ;Right Joystick Click = NOT IN USE If (RJS_Pressed != 1) { SoundBeep, 1000 RJS_Pressed := 1 } } Else If (RJS_Pressed = 1) RJS_Pressed := 0 If (state.bLeftTrigger > 175) { ;Left Trigger (range 0 - 255) = modifier to enable pg up/dn keys If (LT_Pressed != 1) LT_Pressed := 1 } Else If (LT_Pressed = 1) LT_Pressed := 0 If (state.bRightTrigger > 175) { ;Right Trigger (range 0 - 255) = modifier to enable fast mouse movement, and rapid direction input If (RT_Pressed != 1) RT_Pressed := 1 } Else If (RT_Pressed = 1) RT_Pressed := 0 If (state.sThumbRX < -9000 && state.sThumbLX >= -32768) { ;Right joystick left = NOT IN USE If (RJS_Left_Engaged <= 1) { SoundBeep, 1100 } Else RJS_Left_Engaged := RJS_Left_Engaged - 1 ;maybe don't need this depending on how it will be used } If (state.sThumbRX > 9000 && state.sThumbLX <= 32767) { ;Right joystick right = NOT IN USE If (RJS_Right_Engaged <= 1) { SoundBeep, 1200 } Else RJS_Right_Engaged := RJS_Right_Engaged - 1 ;maybe don't need this depending on how it will be used } If (state.sThumbRY > 9000 && state.sThumbLX <= 32767) { ;Right joystick up = mouse wheel up If (RJS_Up_Engaged <= 1) { Click, WheelUp, 1 RJS_Up_Engaged := 5 } Else RJS_Up_Engaged := RJS_Up_Engaged - 1 } If (state.sThumbRY < -9000 && state.sThumbLX >= -32768) { ;Right joystick down = mouse wheel down If (RJS_Down_Engaged <= 1) { Click, WheelDown, 1 RJS_Down_Engaged := 5 } Else RJS_Down_Engaged := RJS_Down_Engaged - 1 } } +F12:: ;Shift + F12 SoundBeep DetectHiddenWindows, on SetTitleMatchMode, 2 WinClose, xinput remap mouse only.ahk ahk_class AutoHotkey WinClose, xinput remap.ahk ahk_class AutoHotkey ExitApp This is the script to launch this stuff simultaneously. You could alternatively just open them both manually and not use this last script. Name this script as xinput remap launcher.ahk Run, xinput remap mouse only.ahk Run, xinput remap.ahk Put all of these scripts into the SAME FOLDER and then run xinput remap launcher.ahk to play around with this script. Alternatively don't use the last script and just manually run xinput remap.ahk and xinput remap mouse only.ahk. Comments are all over the script to describe what is going on but here is a list of that for understanding. Left joystick = will act like your mouse *Take note if you hold the right trigger it will change from a "slow" mouse movement speed to a "fast" mouse movement speed A button = left mouse click B button = right mouse click X button = double left mouse click Y button = make your controller rumble for 2 seconds D-pad directions all are coordinated to the keyboard arrow keys *Take note if you hold the right trigger it will change from only allowing 1 step per D-pad push to what will mimic "turbo fire" or how keyboards repeat keys when held down *Take note if you hold the left trigger it will change the UP and DOWN D-pad buttons into the Page Up and Page Down keys respectively Right joystick up/down = rolling the mouse wheel up/down respectively The following buttons don't really do anything specific, so I just made them a bunch of various SoundBeep frequencies. Guide button Start button Back/View button Left and Right bumpers Left and Right joystick clicks Right joystick Left and Right You can terminate the script by pushing SHIFT+F12 Have fun! And hope this shows some users how to make use of xinput for making your controller do unique stuff! Also thanks to JoeViking245 for helping me learn how to use this xinput library! 1 Quote Link to comment Share on other sites More sharing options...
skizzosjt Posted February 6 Share Posted February 6 I would like to add onto my last post above. I recently wanted to make a hotkey using two face buttons and quickly realized I couldn't use the same method I had been employing. That is because I only made combo hotkeys using the triggers and a single face button. This worked because the left and right trigger both go to independent variables, being bLeftTrigger and bRightTrigger respectively. Along with the single face button I was using goes to wButtons. So in that example each button (or trigger) pressed to activate the hotkey is stored in it's own variable. But what happens if you want to use multiple buttons that all get stored to the same variable, in this case wButtons? You cannot have a single variable be different values simultaneously so I knew there was a different approach needed As I scratched my head I recalled AHK MsgBox options works by adding all of the various option's values when you need to use multiple options simultaneously. I wondered if it worked the same way here. So as I tested this, it did in fact turn out to be the right way to do this with xinput For ex, this will be pressing the Start button, and the X button together Start button value = 16 X button value = 16384 Add them together for a sum of 16400. Using that value, check wButtons, for ex... If (state.wButtons = 16400) This will be checking if both the Start button and X button are pressed simultaneously. The sum of all the various individual button combos is always a unique value so this is how xinput knows which buttons are pressed like this. All "face buttons" are going to the same wButtons variable. To be specific, that means, A, B, X, Y, Left Bumper, Right Bumper, Back/View, Start, Guide, Left Joystick click, Right Joystick click, and the D-pad directions. Any time you need to check a combo of those, you need to add their values together and check for that value. By contrast, only the left and right triggers, and the joystick axis go to their own individual variable. Quote Link to comment Share on other sites More sharing options...
lightangel Posted May 11 Share Posted May 11 So I have found many scripts to put in the running script for the MK6 emulator but nothing works here are some examples. #NoEnv SetTitleMatchMode, 2 WinWaitActive , Roms Screen 1 SetKeyDelay, -1, 110 Send {Alt Down}{Enter}{Alt Up} Return SetTitleMatchMode, 2 WinWaitActive, Roms Screen 1 Sleep, 1000 Send {Alt down}{Enter down}{Alt up}{Enter up} Quote Link to comment Share on other sites More sharing options...
JoeViking245 Posted May 11 Share Posted May 11 1 hour ago, lightangel said: So I have found many scripts to put in the running script for the MK6 emulator but nothing works It's my understanding the window title ("Roms Screen1") might not always be the same. It might be easier to just wait a certain duration (however long it takes for the window to appear after launching it) before sending Alt+Enter to make it go fullscreen. You might try: Sleep, 10000 SetKeyDelay, -1, 110 Send !{Enter} This will wait 10 seconds (10000 milliseconds) and then send Alt+Enter. You can increase/decrease that wait time accordingly. (But be sure to wait the full 10 seconds before deciding "it doesn't work". ) Quote Link to comment Share on other sites More sharing options...
lightangel Posted May 11 Share Posted May 11 Thanks, but no go put it in the Running Script waited more than 10 seconds nothing Quote Link to comment Share on other sites More sharing options...
Cnells2000 Posted May 22 Share Posted May 22 (edited) hi guys. im trying to force close a process after exiting out a game but no matter what i do i cant get the program to close. besides pressing it manually. please help Test.mov i created a script to start the script program and it works no problem. the problem is the script i created was designed to escape out of castlevania .exe and also close the castlevania input hook program. no matter wht i do, i can not get the program to close by script. ive tried different methods like send alt + f4 but maybe im not doing it correctly. if i manually press alt + F4, it closes no problem. i dont know what im missing... the process is called CastlevaniaArcade_inputs.exe All of the script works fine except closing that last program. the white box at 0:12 in the video. when the screen is black, its just bc im recording. heres the script im using. id appreciate any help. Spoiler ; AutoHotKey script to close hcv.exe and CastlevaniaArcade_Inputs.exe, then exit ; Define the process names processName1 := "hcv.exe" processName2 := "CastlevaniaArcade_Inputs.exe" ; Define the hotkey Esc::CloseProcessesAndExit() ; Function to close both specified processes and exit the script CloseProcessesAndExit() { ; Close the hcv.exe process Process, Close, %processName1% ; Close the CastlevaniaArcade_Inputs.exe process Process, Close, %processName2% ; Exit the script without displaying a prompt ExitApp } Edited May 22 by Cnells2000 Quote Link to comment Share on other sites More sharing options...
JoeViking245 Posted May 22 Share Posted May 22 13 hours ago, Cnells2000 said: the script works fine except closing that last program Just a shot-in-the-dark, try closing the process CastlevaniaArcade_Inputs.exe first, then close hvc.exe. Though seems it should work either way. To use the send alt f4 method you might need to set a key delay. Also make sure that it's actually the active window. if WinExist("ahk_exe CastlevaniaArcade_Inputs.exe") { WinActivate SetKeyDelay, 125, 50 Send !{F4} } 1 Quote Link to comment Share on other sites More sharing options...
Cnells2000 Posted May 22 Share Posted May 22 7 hours ago, JoeViking245 said: if WinExist("ahk_exe CastlevaniaArcade_Inputs.exe") { WinActivate SetKeyDelay, 125, 50 Send !{F4} } what area would i place this in the script? or use this and thats all Quote Link to comment Share on other sites More sharing options...
JoeViking245 Posted May 22 Share Posted May 22 43 minutes ago, Cnells2000 said: what area would i place this in the script? or use this and thats all Replace your one line (Process, Close, %processName2%) with the 6 lines I show. Keep everything else the same. 1 Quote Link to comment Share on other sites More sharing options...
Cnells2000 Posted May 23 Share Posted May 23 1 hour ago, JoeViking245 said: Replace your one line (Process, Close, %processName2%) with the 6 lines I show. Keep everything else the same. it worked! it closes properly! u da man @JoeViking245 1 Quote Link to comment Share on other sites More sharing options...
goofers Posted May 24 Share Posted May 24 (edited) Ryujinx put this in Running Script ESC:: Process, Close, Ryujinx.exe Edited May 24 by goofers Quote Link to comment Share on other sites More sharing options...
lightangel Posted June 7 Share Posted June 7 So, I have tried every Script, I can find to get the MK6 emulator to open in full screen. Here are some below. Does anyone have one that works with LaunchBox, I seen videos of it working I can get it to work. #NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. SendMode Input ; Recommended for new scripts due to its superior speed and reliability. SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. ; When emulation has started, maximise the screen and pass control back to control panel WinWait, Roms Screen 1, IfWinNotActive, Roms Screen 1, , WinActivate, Roms Screen 1, { WinWaitActive, Roms Screen 1, Send, !{Enter} } WinWait, MK6 Emulator, IfWinNotActive, MK6 Emulator, , WinActivate, MK6 Emulator, {WinWaitActive, MK6 Emulator, WinMove,1,600 WinSetTitle, CLICK HERE TO USE BUTTONS } Second one #Persistent #NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. ; #Warn ; Enable warnings to assist with detecting common errors. SendMode Input ; Recommended for new scripts due to its superior speed and reliability. SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. WinWaitActive, Roms Screen 1 ; Look for active game window. Send !{Enter} ; Press ALT-ENTER to enable fullscreen. ~Enter:: WinActivate, MK6 Emulator return ~ESC:: WinActivate, MK6 Emulator Reload Quote Link to comment Share on other sites More sharing options...
JoeViking245 Posted June 7 Share Posted June 7 2 hours ago, lightangel said: Here are some below I don't use that emulator, but I do have a little understanding of AHK scripts. The 1st one looks to have some extra , (commas) and other formatting issues that may affect your script. Also I've read that others use Alt+Ctrl to go fullscreen. Suppose that depends on how you have it set in the emulator. I presume the window Title actually has 3 spaces between "Roms" and "Screen"? Or is there only supposed to be one space? Here's your 1st one cleaned up a little (leaving the spaces as is): WinWait, Roms Screen 1 IfWinNotActive, Roms Screen 1 WinActivate Send, !{Enter} WinWait, MK6 Emulator IfWinNotActive, MK6 Emulator WinActivate WinMove,1,600 WinSetTitle, CLICK HERE TO USE BUTTONS Quote Link to comment Share on other sites More sharing options...
Paultimate Posted June 25 Share Posted June 25 Has anyone looked through all this and consolidated the best ones? I think we have more than enough, the issue now is organizing this in a useful way Quote Link to comment Share on other sites More sharing options...
Muggins Posted June 30 Share Posted June 30 (edited) Hi folks, I launch RPCS3 Lightgun games via AHK scripts so no emulator is selected in Launchbox. I can exit the games using a button on the Lightgun (When offscreen) and pressing escape on the keyboard but would also like them to exit and the script terminate in the same way when pressing Buttons 12 + 1 on my cabinet as do my other games. Currently when I press Buttons 12 + 1 the emulator closes but the script does not complete / terminate, leaving AHK and the Lightgun software running. Would anyone know of a method to get Launchbox to send the escape key using this method please? Many thanks! Edited June 30 by Muggins Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.