' testjoy.bmx [hacked]Import Pub.FreeJoy' -----------------------------------------------------------------------------' Support functions. Most of this just checks carefully for the right DLL!' -----------------------------------------------------------------------------Function GetSystemFolder$ ()?Win32 ' Windows only!' Function ArrayFromString:Byte [] (source$)' Local newarray:Byte [Len (source$)]' MemCopy (newarray, source.ToCString (), Len (source$))' Return newarray' End Function Function StringFromArray$ (source:Byte []) Return String.FromCString (source) End Function Local GetSystemDirectory_ (location:Byte Ptr, pathsize) "win32" kernel32 = LoadLibraryA ("kernel32.dll") Local patharray:Byte [260] If kernel32 GetSystemDirectory_ = GetProcAddress (kernel32, "GetSystemDirectoryA") GetSystemDirectory_ (patharray, 260) EndIf Return StringFromArray (patharray)?End Function' -----------------------------------------------------------------------------' Find most recent XInput DLL...' -----------------------------------------------------------------------------Function GetXInputDLL$ () x$ = "xinput9_1_0.dll" If FileType (GetSystemFolder () + "" + x$) = 0 x$ = "" ' Old DLL Not found... EndIf dir = ReadDir (GetSystemFolder ()) If dir Repeat f$ = Lower (NextFile (dir)) If f$.StartsWith ("xinput") And f$.EndsWith (".dll") ' Should probably check Mid values are 0-9 here... version = Int (Mid (f$, 7, 1) + Mid (f$, 9, 1)) ' Result is 10 for 1.0, 11 for 1.1, 12 for 1.2, etc... If version = 91 ' Likely to be 1.0 -- see below! ' Non-public versions might return 9, 8, etc for 0.9, 0.8, etc, ' but 91 is the earliest public version! Exercise for the reader... If Mid (f$, 11, 1) = "0" version = 10 ' Ha! Stupid old "xinput9_1_0.dll" found -- really version 1.0 EndIf EndIf If version > hiversion hiversion = version xinput$ = f$ EndIf EndIf Until f$ = "" CloseDir dir EndIf Return xinput$ End Function' -----------------------------------------------------------------------------' XInput function pointers...' -----------------------------------------------------------------------------' For more information:' <a href="http://msdn.microsoft.com/en-us/library/bb173048(VS.85).aspx" target="_blank">http://msdn.microsoft.com/en-us/library/bb173048(VS.85).aspx</a>Global XInput_SetState (port, hilo:Byte Ptr) "win32"Global XInput_Enable (enable) "win32"' -----------------------------------------------------------------------------' Wrapper functions...' -----------------------------------------------------------------------------Global XInput10 = 0Function InitXInput () x$ = GetXInputDLL () xinput = LoadLibraryA (x$) If xinput XInput_SetState = GetProcAddress (xinput, "XInputSetState") XInput_Enable = GetProcAddress (xinput, "XInputEnable") ok = True If XInput_Enable = Null If x$ = "xinput9_1_0.dll" ' Not in 1.0. Can continue but EnableController won't do anything... XInput10 = True ' Can check this from other parts of the program if necessary... Print "" Print "XInputEnable not available in XInput 1.0 -- update Xbox controller driver!~nContinuing, but EnableController will have no effect..." Else ok = False ' Not found at all! EndIf EndIf If XInput_SetState = Null ok = False EndIf Else ok = False EndIf If ok Return xinput End Function' Vibration continues until next Rumble call!Function Rumble (port, rumble_left:Short, rumble_right:Short) ' From <a href="http://msdn.microsoft.com/en-us/library/bb174835(VS.85).aspx" target="_blank">http://msdn.microsoft.com/en-us/library/bb174835(VS.85).aspx</a> : ' "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." ' Combine two shorts into an integer... freqs = (rumble_right Shl 16) | rumble_left XInput_SetState (port, Varptr freqs) End Function' Call DisableRumble before exiting program, or when app is suspended, to stop all vibrations. ' NOTE! This also affects return results for controller inputs! Makes everything return' as 'neutral', ie. no buttons pressed, no stick movement, etc, regardless of what' the player may be doing with the controller. (Doesn't apply to XInput 1.0.)Function DisableRumble () ' The For loop below is intended to stop the vibrations for XInput 1.0, but although ' XInput_Enable (0) stops vibration for later versions under normal usage, it appears to ' have no effect if the controller is still vibrating after a program has terminated ' abnormally, hence I'm calling this regardless... For port = 0 To 3 Rumble (port, 0, 0) Next ' For later versions, to disable ALL controller input/output... If Not XInput10 XInput_Enable (0) EndIf End Function' Call this to re-enable vibration effects, input values, etc, if you have called' DisableRumble while your app is suspended.' NOTE! This also affects return results for controller inputs! Makes everything return' as 'neutral', ie. no buttons pressed, no stick movement, etc, regardless of what' the player may be doing with the controller. (Doesn't apply to XInput 1.0.)' M$ recommend using this when the program is suspended (eg. Alt-Tab, etc)...Function EnableRumble () If Not XInput10 ' Only available if XInput version > 1.0! XInput_Enable (1) EndIfEnd FunctionIf Not JoyCount() RuntimeError "No joystick found!"If InitXInput () = 0 RuntimeError "Install Xbox controller driver!"Graphics 640,480Function drawprop(n$,p#,y) Local w DrawText n$,0,y w=Abs(p)*256 If p<0 DrawRect 320-w,y,w,16 Else DrawRect 320,y,w,16 EndIfEnd Function Local t=0While Not KeyHit(KEY_ESCAPE) Cls SetColor 255,255,255 Local n=JoyCount() DrawText "joycount="+n,0,0 DrawText "JoyName(0)="+JoyName(0),0,20 DrawText "JoyButtonCaps(0)="+Bin$(JoyButtonCaps(0)),0,40 DrawText "JoyAxisCaps(0)="+Bin$(JoyAxisCaps(0)),0,60 For Local i=0 To 31 SetColor 255,255,255 If JoyDown(i) SetColor 255,0,0 DrawOval i*16,80,14,14 Next SetColor 255,255,0 drawprop "JoyX=",JoyX(0),100 drawprop "JoyY:",JoyY(0),120 freqlo# = 65535.0 * JoyY (0) ' 0.0 - 2.0 (1.0 = centered) freqlo = 65535.0 - (freqlo + 65535.0) / 2.0 DrawText freqlo, 0, 400 drawprop "JoyZ:",JoyZ(0),140 drawprop "JoyR:",JoyR(0),160 freqhi# = 65535.0 * JoyR (0) ' 0.0 - 2.0 (1.0 = centered) freqhi = 65535.0 - (freqhi + 65535.0) / 2.0 DrawText freqhi, 0, 420 drawprop "JoyU:",JoyU(0),180 drawprop "JoyV:",JoyV(0),200 drawprop "JoyHat:",JoyHat(0),220 drawprop "JoyWheel:",JoyWheel(0),240 DrawRect 0,280,t,10 t=(t+1)&511 Rumble port, freqlo, freqhi Flip WendEnd
Did anyone ever figure out how to correctly read the Xbox 360 controller Left and Right Triggers? If you press them at the same time they read 0. This is fine if you were actually using them as a rudder...but not so good if users want to remap jump or run or something to the trigger(s). Any solution?