bei meinen Projekt ist ein XBox360 Controller die Basis.
Es werden Tastaturtasten simuliert und im Einzelnen funktioniert alles.
Aber der Bug sitzt in der Kombination, wenn ich:
eine Richtung mit dem linken Analog-Stick einschlage,
+ zwei Knöpfe (meistens B & X) gleichzeitig drücke
= bleibt die Richtungstaste stecken.
Mit der selben Kombination kann ich die Richtungstaste wieder befreien.
Habe hier und dort kleinere Änderungen vorgenommen aber das Problem blieb und ich habe keine Ahnung woran das liegen könnte.
Ich benutze Win7 mit der AHK Version: 1.0.48.05 .
Zum Code:
Geladen wird XInput (XInput_Init()). http://www.autohotkey.com/board/topic/3 ... oller-api/
Den Teil mit dem Analog-Stick habe ich so gestalten weil bei Meinem die Grenzen von Oben-Links nach Unten-Rechts etwas verschoben sind.
Die Windows Kalibrierung hat nicht helfen können, also habe ich sie innerhalb des Codes vorgenommen.
Wahrscheinlich werdet ihr eure eigenen Werte eintragen müssen, wenn ich den Code mit euren Controllern testen wollt.
Dafür einfach die Zeile ";Tooltip angle: %varAngle% length: %varLength% " unkommentieren/einkommentieren und die passenden Werte eintragen.
Code: Select all
;
; AutoHotkey Version: 1.x
; Language: English
; Platform: Win9x/NT
; Author: A.N.Other <[email protected]>
;
; Script Function:
;
; +-----+
; ¦ LB +-----+-----+
; +-----+-----¦ ¦ RB ¦ RT ¦
; ¦Start¦ LT +-----¦ ¦ ¦
; ¦ ¦ ¦ B +-----+-----¦
; +-----+-----¦ ¦ A ¦ RS-H¦
; ¦ Bck ¦ X +-----¦ ¦ ¦
; ¦ ¦ ¦ Up +-----+-----¦
; +-----+-----¦ ¦Right¦ RS-V¦
; ¦ Y ¦ Lft +-----¦ ¦ ¦
; ¦ ¦ ¦ Dwn +-----+-----+
; +-----+-----¦ ¦
; ¦ RS-C¦ +-----+
; ¦ ¦
; +-----+
;
; Button Number: Joy#
;
; A = 1
; B = 2
; X = 3
; Y = 4
; LB = 5
; RB = 6
; Back = 7
; Start = 8
; leftS.Click = 9
; rightS.Click = 10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;; CONFIGUTATION: ;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
varJoy1_Btn = Space
varJoy2_Btn = Shift
varJoy3_Btn = Alt
varJoy4_Btn = q
varJoy5_Btn = 3
varJoy6_Btn = 4
varJoy7_Btn = 1
varJoy8_Btn = Esc
varJoy9_Btn =
varJoy10_Btn = f
varUp_Btn = c
varLeft_Btn = Ctrl
varDown_Btn = Tab
varRight_Btn =
varRSh_Btn = r
varRSv_Btn = e
varLT_Btn = 2
varRT_Btn = 5
;Left Stick
varLS_Up_Btn = w
varLS_Left_Btn = a
varLS_Down_Btn = s
varLS_Right_Btn = d
;;;;;- Analogstick -;;;;;
;;;;;- Calibration -;;;;;
varDeadzone = 0.2 ; 0.2 = 20%, 0.5 = 50%
; Limitaion of the Length of the Analogstick
; termed after a clock 1,2,3.. 11,12 o'clock
; 12:00 - 0°
varLim_1200 = 50
; 01:30 - 45°
varLim_0130 = 57
; 03:00 - 90°
varLim_0300 = 50
; 04:30 - 135°
varLim_0430 = 70
; 06:00 - 180°
varLim_0600 = 50
; 07:30 - 225°
varLim_0730 = 49
; 09:00 - 270°
varLim_0900 = 48
; 10:30 - 315°
varLim_1030 = 35
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;; END OF CONFIGUTATION ;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#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.
;;D-Pad POV;;
#Persistent
SetTimer, WatchPOV, 10
;;Left Analogstick;;
SetTimer, WatchLeftStick, 10
;;Axes to Buttons;;
#include xinput.ahk
SetTimer, WatchATB, 10
XInput_Init()
;;;;;;;;;;;;;;;;;;;;;
;; Axes to Buttons ;;
;;;;;;;;;;;;;;;;;;;;;
; Left and Right Triggers
Loop {
Loop, 4 {
if State := XInput_GetState(A_Index-1) {
LT := State.bLeftTrigger
RT := State.bRightTrigger
}
}
If ( !LTPressed ) = LTPressed := ( LT > 200 )
If LTPressed
{
SendInput, {Blind}{%varLT_Btn% down}
}
Else SendInput, {Blind}{%varLT_Btn% up}
If ( !RTPressed ) = RTPressed := ( RT > 200 )
If RTPressed
{
SendInput, {Blind}{%varRT_Btn% down}
}
Else SendInput, {Blind}{%varRT_Btn% up}
Sleep, 10
}
WatchATB:
; axeU is Rightstick horizontal
; axeR is Rightstick vertical
GetKeyState, aU, JoyU
GetKeyState, aR, JoyR
If ( !RShPressed ) = RShPressed := ( aU < 10 )
If RShPressed
{
SendInput, {Blind}{%varRSh_Btn% down}
}
Else SendInput, {Blind}{%varRSh_Btn% up}
If ( !RSvPressed ) = RSvPressed := ( aR > 90 )
If RSvPressed
{
SendInput, {Blind}{%varRSv_Btn% down}
}
Else SendInput, {Blind}{%varRSv_Btn% up}
Return ; End of WatchATB
;;;;;;;;;;;;;;;;;;;;;;
;; Left Analogstick ;;
;;;;;;;;;;;;;;;;;;;;;;
WatchLeftStick:
;Get Axes
GetKeyState, varLsX, JoyX
GetKeyState, varLsY, JoyY
varLsVecX := varLsX - 50
varLsVecY := varLsY - 50
varAngle := AngleOfVector(varLsVecX, varLsVecY)
varLength := LengthOfVector(varLsVecX, varLsVecY)
;;; Uncomment the following line to help you with the calibration of your left Analogstick
;Tooltip angle: %varAngle% length: %varLength%
AngleOfVector(x, y)
{
; Angle between Vector U and Vector V (position vectors)
; U is fixed: U1= 0, U2= -50 //The 12 o'clock on the Analogstick
; V1= x and V2= y
;
; U * V
; Cos(c) = _________
; |U|*|V|
;
; U1*V1 + U2*V2
; Cos(c) = __________________________
; Sqrt(U1²+U2²)*Sqrt(V1²+V2²)
;
; 0*x + (-50*y)
; Cos(c) = ___________________________________________
; Sqrt((0*0)+((-50)*(-50))) * Sqrt((x*x)+(y*y))
;
; Angle : RadToDeg(ACos(c))
varCos := ((-50)*y) / (50 * Sqrt((x*x)+(y*y)))
varDeg := RadToDeg(ACos(varCos))
If x < 0
varDeg := 360 - varDeg
Return varDeg
}
RadToDeg(rad)
{
static pi := 3.14159265358979323846
return rad * 180 / pi
}
LengthOfVector(x, y)
{
; Length of one Vector (position vector)
; Pythagoras' theorem
; =Sqrt((x)²+(y)²)
Return Sqrt((x*x) + (y*y))
}
;Determines the direction
If ((varAngle <= 22.5 Or varAngle > 337.5) And (varLength >= (varLim_1200 * varDeadzone))) ; 12:00 _ 337.5° >-< 22.5°
varDirection := 1
Else If ((varAngle > 22.5 And varAngle <= 67.5) And (varLength >= (varLim_0130 * varDeadzone))) ; 01:30 _ 22.5° >-< 67.5°
varDirection := 2
Else If ((varAngle > 67.5 And varAngle <= 112.5) And (varLength >= (varLim_0300 * varDeadzone))) ; 03:00 _ 67.5° >-< 112.5°
varDirection := 3
Else If ((varAngle > 112.5 And varAngle <= 157.5) And (varLength >= (varLim_0430 * varDeadzone))) ; 04:30 _ 112.5° >-< 157.5°
varDirection := 4
Else If ((varAngle > 157.5 And varAngle <= 202.5) And (varLength >= (varLim_0600 * varDeadzone))) ; 06:00 _ 157.5° >-< 202.5°
varDirection := 5
Else If ((varAngle > 202.5 And varAngle <= 247.5) And (varLength >= (varLim_0730 * varDeadzone))) ; 07:30 _ 202.5° >-< 247.5°
varDirection := 6
Else If ((varAngle > 247.5 And varAngle <= 292.5) And (varLength >= (varLim_0900 * varDeadzone))) ; 09:00 _ 247.5° >-< 292.5°
varDirection := 7
Else If ((varAngle > 292.5 And varAngle <= 337.5) And (varLength >= (varLim_1030 * varDeadzone))) ; 10:30 _ 292.5° >-< 337.5°
varDirection := 8
Else ; No direction
varDirection := 0
; This order of operations trick makes the entire expression 'true' when the contents of
; 'LS_UpPressed' change from '1' to '0' or from '0' to '1'. The value in 'LS_UpPressed' is boolean
; and indicates whether the LeftStick is pushed and in which direction.
If ( !LS_UpPressed ) = LS_UpPressed := ( ((varDirection = 8) || (varDirection = 1) || (varDirection = 2)) )
If LS_UpPressed
{
SendInput, {Blind}{%varLS_Up_Btn% down}
}
Else SendInput, {Blind}{%varLS_Up_Btn% up}
If ( !LS_RightPressed ) = LS_RightPressed := ( ((varDirection = 2) || (varDirection = 3) || (varDirection = 4)) )
If LS_RightPressed
{
SendInput, {Blind}{%varLS_Right_Btn% down}
}
Else SendInput, {Blind}{%varLS_Right_Btn% up}
If ( !LS_DownPressed ) = LS_DownPressed := ( ((varDirection = 4) || (varDirection = 5) || (varDirection = 6)) )
If LS_DownPressed
{
SendInput, {Blind}{%varLS_Down_Btn% down}
}
Else SendInput, {Blind}{%varLS_Down_Btn% up}
If ( !LS_LeftPressed ) = LS_LeftPressed := ( ((varDirection = 6) || (varDirection = 7) || (varDirection = 8)) )
If LS_LeftPressed
{
SendInput, {Blind}{%varLS_Left_Btn% down}
}
Else SendInput, {Blind}{%varLS_Left_Btn% up}
Return ; END 'WatchLeftStick'
;;;;;;;;;;;;;;;
;; D-Pad POV ;;
;;;;;;;;;;;;;;;
WatchPOV:
; Get the joystick PoV position and convert it into an exponent of 2, with center being zero.
; So, clockwise beginning at the up, the newpov values are 1,2,4,8,16,32,64,128
NewJoyPov := 1 << ( ( GetKeyState( "JoyPoV" ) + 4500 ) // 4500 ) >> 1
; This order of operations trick makes the entire expression 'true' when the contents of
; 'UpPressed' change from '1' to '0' or from '0' to '1'. The value in 'UpPressed' is boolean
; and indicates whether the POV position is or isn't one of these numbers ( 1, 2, 128 ). And NOT 0!
If ( !UpPressed ) = UpPressed := ( 0 != NewJoyPov & 1 + 2 + 128 )
If UpPressed
{
SendInput, {Blind}{%varUp_Btn% down}
}
Else SendInput, {Blind}{%varUp_Btn% up}
If ( !RightPressed ) = RightPressed := ( 0 != NewJoyPov & 2 + 4 + 8 )
If RightPressed
{
SendInput, {Blind}{%varRight_Btn% down}
}
Else SendInput, {Blind}{%varRight_Btn% up}
If ( !DownPressed ) = DownPressed := ( 0 != NewJoyPov & 8 + 16 + 32 )
If DownPressed
{
SendInput, {Blind}{%varDown_Btn% down}
}
Else SendInput, {Blind}{%varDown_Btn% up}
If ( !LeftPressed ) = LeftPressed := ( 0 != NewJoyPov & 32 + 64 + 128 )
If LeftPressed
{
SendInput, {Blind}{%varLeft_Btn% down}
}
Else SendInput, {Blind}{%varLeft_Btn% up}
Return ; END 'WatchPOV'
;;;;;;;;;;;;;;;;
;; JoyButtons ;;
;;;;;;;;;;;;;;;;
Joy1::
SendInput {%varJoy1_Btn% down} ; Hold down the varJoy1_Btn button.
SetTimer, WaitForButtonUpJoy1, 10
return
WaitForButtonUpJoy1:
if !GetKeyState("Joy1") ; The button is released (fasle)
{
SendInput {%varJoy1_Btn% up} ; Release the varJoy1_Btn button.
SetTimer, WaitForButtonUpJoy1, off
}
return
Joy2::
SendInput {%varJoy2_Btn% down}
SetTimer, WaitForButtonUpJoy2, 10
return
WaitForButtonUpJoy2:
if !GetKeyState("Joy2")
{
SendInput {%varJoy2_Btn% up}
SetTimer, WaitForButtonUpJoy2, off
}
return
Joy3::
SendInput {%varJoy3_Btn% down}
SetTimer, WaitForButtonUpJoy3, 10
return
WaitForButtonUpJoy3:
if !GetKeyState("Joy3")
{
SendInput {%varJoy3_Btn% up}
SetTimer, WaitForButtonUpJoy3, off
}
return
Joy4::
SendInput {%varJoy4_Btn% down}
SetTimer, WaitForButtonUpJoy4, 10
return
WaitForButtonUpJoy4:
if !GetKeyState("Joy4")
{
SendInput {%varJoy4_Btn% up}
SetTimer, WaitForButtonUpJoy4, off
}
return
Joy5::
SendInput {%varJoy5_Btn% down}
SetTimer, WaitForButtonUpJoy5, 10
return
WaitForButtonUpJoy5:
if !GetKeyState("Joy5")
{
SendInput {%varJoy5_Btn% up}
SetTimer, WaitForButtonUpJoy5, off
}
return
Joy6::
SendInput {%varJoy6_Btn% down}
SetTimer, WaitForButtonUpJoy6, 10
return
WaitForButtonUpJoy6:
if !GetKeyState("Joy6")
{
SendInput {%varJoy6_Btn% up}
SetTimer, WaitForButtonUpJoy6, off
}
return
Joy7::
SendInput {%varJoy7_Btn% down}
SetTimer, WaitForButtonUpJoy7, 10
return
WaitForButtonUpJoy7:
if !GetKeyState("Joy7")
{
SendInput {%varJoy7_Btn% up}
SetTimer, WaitForButtonUpJoy7, off
}
return
Joy8::
SendInput {%varJoy8_Btn% down}
SetTimer, WaitForButtonUpJoy8, 10
return
WaitForButtonUpJoy8:
if !GetKeyState("Joy8")
{
SendInput {%varJoy8_Btn% up}
SetTimer, WaitForButtonUpJoy8, off
}
return
Joy9::
SendInput {%varJoy9_Btn% down}
SetTimer, WaitForButtonUpJoy9, 10
return
WaitForButtonUpJoy9:
if !GetKeyState("Joy9")
{
SendInput {%varJoy9_Btn% up}
SetTimer, WaitForButtonUpJoy9, off
}
return
Joy10::
SendInput {%varJoy10_Btn% down}
SetTimer, WaitForButtonUpJoy10, 10
return
WaitForButtonUpJoy10:
if !GetKeyState("Joy10")
{
SendInput {%varJoy10_Btn% up}
SetTimer, WaitForButtonUpJoy10, off
}
return
Für jegliche Antwort ein Dank im Voraus.
MfG ABedAHK