Use Xinput API without using a loop

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Peter Njeim

Use Xinput API without using a loop

21 Feb 2018, 15:50

Hello, I've been trying to make a script for the Xbox One controller to use its joystick as a mouse. I found many here on the forums, and it only worked in the script window, and failed when in any other window. I found a solution online to use certain drivers and the solution actually worked, however it made the 2 analog triggers under one axis, so I found another newer driver that separated the 2 analog sticks and also fixed the previous issue. However, the Xbox controller no longer had xinput support, so I ditched this solution and reinstalled the normal drivers that come with the OS. I found Lexikos's Xinput API and used that, it does indeed work in all windows (and if run as admin it also works in admin windows).

The only issue I have with it is that the example given uses a loop. I made it so that my analog triggers scroll up and down, and that my left analog stick moves the cursor. However, when both are done at the same time (analog stick is not centered and analog trigger is held down) my mouse cursor becomes choppy, and changing the sleep to 0 doesn't change this behaviour (everything is faster, but it still becomes half speed when both are being used) and also -1 and 0 sleep make my CPU usage go up, so I don't want that. I was trying to make a timer and hotkeys so that they could run on separate threads, but I just can't figure it out.

Is it possible to make loops multi-threaded? Is it possible to not use a loop when using Lexikos's Xinput API? Any help would be gratefully appreciated.

Code: Select all

#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.
SetBatchLines, -1

#include XInput.ahk

XInput_Init()
Loop {
    Loop, 1 {
        if State := XInput_GetState(A_Index-1) {
            ; Constants
            DeadZone = 0
            DeadZone2 = 3500
            JoyMultiplier = 0.001
            
            ; States
            Pressed := State.wButtons
            LT := State.bLeftTrigger
            RT := State.bRightTrigger
            LSX := State.sThumbLX
            LSY := State.sThumbLY
            RSY := State.sThumbRY
            RSX := State.sThumbRX
            
            ; Variables
            MouseNeedsToBeMoved := false
            ScrollUp := Round(Sqrt(16384)*2/Sqrt(LT))
            ScrollDown := Round(Sqrt(16384)*2/Sqrt(RT))
        }
        { ; Buttons

            ; A Button
            if Pressed = 4096
            {
                if !ADown
                {
                    SetMouseDelay, -1
                    Click L Down
                    ADown := true
                }
            }
            if Pressed != 4096
            {
                if ADown
                {
                    SetMouseDelay, -1
                    Click L Up
                    ADown := false
                }
            }

            ; B Button
            if Pressed = 8192
            {
                if !BDown
                {
                    SetMouseDelay, -1
                    Click R Down
                    BDown := true
                }
            }
            if Pressed != 8192
            {
                if BDown
                {
                    SetMouseDelay, -1
                    Click R Up
                    BDown := false
                }
            }

            ; Start Button
            if Pressed = 16
            {
                if !StartDown
                {
                    SendInput {LWin down}
                    StartDown := true
                }
            }
            if Pressed != 16
            {
                if StartDown
                {
                    SendInput {LWin up}
                    StartDown := false
                }
            }

            ; Select Button
            if Pressed = 32
            {
                if !SelectDown
                {
                    SendInput {LWin down}
                    SelectDown := true
                }
            }
            if Pressed != 32
            {
                if SelectDown
                {
                    SendInput {LWin up}
                    SelectDown := false
                }
            }

        }
        { ; Mouse
            if LSX > %DeadZone2%
            {
                MouseNeedsToBeMoved := true
                DeltaX := LSX - DeadZone2
            }
            else if LSX < -%DeadZone2%
            {
                MouseNeedsToBeMoved := true
                DeltaX := LSX + DeadZone2
            }
            else
                DeltaX = 0
            if LSY > %DeadZone2%
            {
                MouseNeedsToBeMoved := true
                DeltaY := LSY - DeadZone2
            }
            else if LSY < -%DeadZone2%
            {
                MouseNeedsToBeMoved := true
                DeltaY := LSY + DeadZone2
            }
            else
                DeltaY = 0
            if MouseNeedsToBeMoved
            {
                SetMouseDelay, -1
                MouseMove, DeltaX * JoyMultiplier, -DeltaY * JoyMultiplier, 0, R
            }
        }
        { ; Scroll
            if (ScrollUp > 0) && (ScrollDown > 0)
            {
                ScrollUp := 0
                ScrollDown := 0
            }
            if ScrollUp > %DeadZone%
            {
                Loop, 1 {
                    SendInput {WheelUp}
                }
                Sleep, %ScrollUp%
            }

            if ScrollDown > %DeadZone% 
            {
                Loop, 1 {
                    SendInput {WheelDown}
                }
                Sleep, %ScrollDown%
            }
        }
    }
    Sleep, 1
}
gregster
Posts: 9001
Joined: 30 Sep 2013, 06:48

Re: Use Xinput API without using a loop

23 Nov 2022, 04:13

chinagreenelvis wrote:
23 Nov 2022, 03:36
Uh... how exactly is this topic solved?
It's a quirk of the forum software. Anonymous topics can be set to 'solved' by anyone, even other anonymous posters, since the original poster doesn't get recognized anymore after their session and hence no one owns the topic (would probably be better, if only staff could do that).
Only one reason why I'd suggest to create an account when creating topics.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: ishida20 and 414 guests