Does anyone know why in the following code SDL_JoystickClose() and SDL_GameControllerClose() work perfectly fine in Windows but not in Linux?
Code: Select all
; Joystick module 2023
; Generic module for use with controllers
; A joystick is an unmanaged device and a controller is managed
; Controllers are able to map buttons to known configurations
DeclareModule Joystick
EnableExplicit
Enumeration Joystick_Type_Enumeration
#Type_Joystick
#Type_Controller
EndEnumeration
#MAX_JOYSTICKS = $00000010
#MAX_BUTTONS_PER_JOYSTICK = $00000028
#MAX_AXES_PER_JOYSTICK = $00000028
#MAX_HATS_PER_JOYSTICK = $00000028
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
#SDL_ENABLE = $00000001
#SDL_INIT_JOYSTICK = $00000200
#SDL_JOYAXISMOTION = $00000600
#SDL_JOYHATMOTION = $00000602
#SDL_JOYBUTTONDOWN = $00000603
#SDL_JOYBUTTONUP = $00000604
#SDL_JOYDEVICEADDED = $00000605
#SDL_JOYDEVICEREMOVED = $00000606
#SDL_CONTROLLERAXISMOTION = $00000650
#SDL_CONTROLLERBUTTONDOWN = $00000651
#SDL_CONTROLLERBUTTONUP = $00000652
#SDL_INIT_GAMECONTROLLER = $00002000
#SDL_INIT_EVENTS = $00004000
Enumeration Controller_Buttons
#SDL_CONTROLLER_BUTTON_INVALID = -1
#SDL_CONTROLLER_BUTTON_A = 0
#SDL_CONTROLLER_BUTTON_B = 1
#SDL_CONTROLLER_BUTTON_X = 2
#SDL_CONTROLLER_BUTTON_Y = 3
#SDL_CONTROLLER_BUTTON_BACK = 4
#SDL_CONTROLLER_BUTTON_GUIDE = 5
#SDL_CONTROLLER_BUTTON_START = 6
#SDL_CONTROLLER_BUTTON_LEFTSTICK = 7
#SDL_CONTROLLER_BUTTON_RIGHTSTICK = 8
#SDL_CONTROLLER_BUTTON_LEFTSHOULDER = 9
#SDL_CONTROLLER_BUTTON_RIGHTSHOULDER = 10
#SDL_CONTROLLER_BUTTON_DPAD_UP = 11
#SDL_CONTROLLER_BUTTON_DPAD_DOWN = 12
#SDL_CONTROLLER_BUTTON_DPAD_LEFT = 13
#SDL_CONTROLLER_BUTTON_DPAD_RIGHT = 14
#SDL_CONTROLLER_BUTTON_MAX = 15
EndEnumeration
Enumeration Controller_Axes
#SDL_CONTROLLER_AXIS_INVALID = -1
#SDL_CONTROLLER_AXIS_LEFTX = 0
#SDL_CONTROLLER_AXIS_LEFTY = 1
#SDL_CONTROLLER_AXIS_RIGHTX = 2
#SDL_CONTROLLER_AXIS_RIGHTY = 3
#SDL_CONTROLLER_AXIS_TRIGGERLEFT = 4
#SDL_CONTROLLER_AXIS_TRIGGERRIGHT = 5
#SDL_CONTROLLER_AXIS_MAX = 6
EndEnumeration
CompilerCase #PB_OS_Linux
#SDL_JOYDEVICEADDED = $00000605
#SDL_JOYDEVICEREMOVED = $00000606
#SDL_CONTROLLERBUTTONDOWN = $00000651
#SDL_CONTROLLERBUTTONUP = $00000652
#SDL_CONTROLLERAXISMOTION = $00000650
#SDL_INIT_GAMECONTROLLER = $00002000
#SDL_INIT_EVENTS = $00004000
Enumeration Controller_Buttons
#SDL_CONTROLLER_BUTTON_INVALID = -1
#SDL_CONTROLLER_BUTTON_A = 0
#SDL_CONTROLLER_BUTTON_B = 1
#SDL_CONTROLLER_BUTTON_X = 2
#SDL_CONTROLLER_BUTTON_Y = 3
#SDL_CONTROLLER_BUTTON_BACK = 4
#SDL_CONTROLLER_BUTTON_GUIDE = 5
#SDL_CONTROLLER_BUTTON_START = 6
#SDL_CONTROLLER_BUTTON_LEFTSTICK = 7
#SDL_CONTROLLER_BUTTON_RIGHTSTICK = 8
#SDL_CONTROLLER_BUTTON_LEFTSHOULDER = 9
#SDL_CONTROLLER_BUTTON_RIGHTSHOULDER = 10
#SDL_CONTROLLER_BUTTON_DPAD_UP = 11
#SDL_CONTROLLER_BUTTON_DPAD_DOWN = 12
#SDL_CONTROLLER_BUTTON_DPAD_LEFT = 13
#SDL_CONTROLLER_BUTTON_DPAD_RIGHT = 14
#SDL_CONTROLLER_BUTTON_MAX = 15
EndEnumeration
Enumeration Controller_Axes
#SDL_CONTROLLER_AXIS_INVALID = -1
#SDL_CONTROLLER_AXIS_LEFTX = 0
#SDL_CONTROLLER_AXIS_LEFTY = 1
#SDL_CONTROLLER_AXIS_RIGHTX = 2
#SDL_CONTROLLER_AXIS_RIGHTY = 3
#SDL_CONTROLLER_AXIS_TRIGGERLEFT = 4
#SDL_CONTROLLER_AXIS_TRIGGERRIGHT = 5
#SDL_CONTROLLER_AXIS_MAX = 6
EndEnumeration
CompilerEndSelect
Structure SDL_JoyDeviceEvent_Structure
Type.l
Timestamp.l
Which.l
EndStructure
Structure SDL_JoyButtonEvent_Structure
Type.l
Timestamp.l
Which.l ; Joystick ID
Button.b
State.b
EndStructure
Structure SDL_JoyAxisEvent_Structure
Type.l
Timestamp.l
Which.l ; Joystick ID
Axis.b
Padding1.b
Padding2.b
Padding3.b
Value.w
EndStructure
Structure SDL_JoyHatEvent_Structure
Type.l
Timestamp.l
Which.l ; Joystick ID
Hat.b
Value.w
EndStructure
Structure SDL_Event_Structure
StructureUnion
Type.l
JoyDeviceEvent.SDL_JoyDeviceEvent_Structure
JoyButtonEvent.SDL_JoyButtonEvent_Structure
JoyAxisEvent.SDL_JoyAxisEvent_Structure
JoyHatEvent.SDL_JoyHatEvent_Structure
EndStructureUnion
EndStructure
Global SDL_Event.SDL_Event_Structure
Structure Button_Structure
B.w[#MAX_BUTTONS_PER_JOYSTICK]
EndStructure
Structure Axis_Structure
Axis.w[#MAX_AXES_PER_JOYSTICK]
EndStructure
Structure Hat_Structure
Hat.w[#MAX_HATS_PER_JOYSTICK]
EndStructure
Structure Controller_Data_Structure
Type.i ; 0 = Joystick, 1 = controller
Joystick_ID.l
Joystick_ID_From_Instance.l
Controller_ID.l
Controller_ID_From_Instance.l
GUID.s
Index_From_Instance.l
Joystick_Type.l
Controller_Type.l
Joystick_Instance_ID.l
Joystick_Name.s
Joystick_GUID.s
Num_Axes.i
Num_Hats.i
Num_Buttons.i
Button_State.Button_Structure
Axis_State.Axis_Structure
Hat_State.Hat_Structure
EndStructure
Dim Joysticks.Controller_Data_Structure(#MAX_JOYSTICKS)
Global SDL_Library.i = 0
Global Num_Joysticks.i ; count of all available controllers and joysticks
Global Use_Events.i, Use_Joystick_Events.i
Declare.i Initialise()
Declare.i GetDeviceInformation(Array Joysticks.Controller_Data_Structure(1))
Declare ProcessJoysticks(Array Joysticks.Controller_Data_Structure(1))
Declare Shutdown(Array Joysticks.Controller_Data_Structure(1))
EndDeclareModule
Module Joystick
EnableExplicit
Define SDL2_Library_Result.i
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
SDL2_Library_Result = OpenLibrary(SDL_Library, "Lib\SDL2\32bit\SDL2.dll")
CompilerElse
SDL2_Library_Result = OpenLibrary(SDL_Library, "Lib\SDL2\64bit\SDL2.dll")
CompilerEndIf
If SDL2_Library_Result : Debug "SDL2 initialised" : Else : Debug "SDL2.dll not found" : End : EndIf
CompilerCase #PB_OS_Linux
SDL2_Library_Result = OpenLibrary(SDL_Library, "/usr/lib/x86_64-linux-gnu/libSDL2.so")
CompilerEndSelect
PrototypeC.i _SDL_Init(flags.l) : Global SDL_Init._SDL_Init = GetFunction(SDL_Library, "SDL_Init")
PrototypeC.i _SDL_InitSubSystem(flags.l) : Global SDL_InitSubSystem._SDL_InitSubSystem = GetFunction(SDL_Library, "SDL_InitSubSystem")
PrototypeC.i _SDL_NumJoysticks() : Global SDL_NumJoysticks._SDL_NumJoysticks = GetFunction(SDL_Library, "SDL_NumJoysticks")
PrototypeC.i _SDL_JoystickOpen(Device_Index.l) : Global SDL_JoystickOpen._SDL_JoystickOpen = GetFunction(SDL_Library, "SDL_JoystickOpen")
PrototypeC.i _SDL_IsGameController(Device_Index.l) : Global SDL_IsGameController._SDL_IsGameController = GetFunction(SDL_Library, "SDL_IsGameController")
PrototypeC.i _SDL_GameControllerOpen(Device_Index.l) : Global SDL_GameControllerOpen._SDL_GameControllerOpen = GetFunction(SDL_Library, "SDL_GameControllerOpen")
PrototypeC.i _SDL_JoystickNameForIndex(Device_Index.l) : Global SDL_JoystickNameForIndex._SDL_JoystickNameForIndex = GetFunction(SDL_Library, "SDL_JoystickNameForIndex")
PrototypeC.i _SDL_JoystickNumButtons(SDL_Joystick.l) : Global SDL_JoystickNumButtons._SDL_JoystickNumButtons = GetFunction(SDL_Library, "SDL_JoystickNumButtons")
PrototypeC.i _SDL_JoystickNumAxes(SDL_Joystick.l) : Global SDL_JoystickNumAxes._SDL_JoystickNumAxes = GetFunction(SDL_Library, "SDL_JoystickNumAxes")
PrototypeC.i _SDL_JoystickNumHats(SDL_Joystick.l) : Global SDL_JoystickNumHats._SDL_JoystickNumHats = GetFunction(SDL_Library, "SDL_JoystickNumHats")
PrototypeC.i _SDL_JoystickInstanceID(SDL_Joystick.l) : Global SDL_JoystickInstanceID._SDL_JoystickInstanceID = GetFunction(SDL_Library, "SDL_JoystickInstanceID")
PrototypeC.i _SDL_JoystickGetType(Device_Index.l) : Global SDL_JoystickGetType._SDL_JoystickGetType = GetFunction(SDL_Library, "SDL_JoystickGetType")
PrototypeC.i _SDL_GameControllerNameForIndex(Device_Index.l) : Global SDL_GameControllerNameForIndex._SDL_GameControllerNameForIndex = GetFunction(SDL_Library, "SDL_GameControllerNameForIndex")
PrototypeC.i _SDL_GameControllerGetType(SDL_GameController.l) : Global SDL_GameControllerGetType._SDL_GameControllerGetType = GetFunction(SDL_Library, "SDL_GameControllerGetType")
PrototypeC.i _SDL_GameControllerMapping(Game_Controller.l) : Global SDL_GameControllerMapping._SDL_GameControllerMapping = GetFunction(SDL_Library, "SDL_GameControllerMapping")
PrototypeC.a _SDL_GameControllerGetButton(SDL_GameController.l, SDL_GameControllerButton.l) : Global SDL_GameControllerGetButton._SDL_GameControllerGetButton = GetFunction(SDL_Library, "SDL_GameControllerGetButton")
PrototypeC.w _SDL_GameControllerGetAxis(SDL_GameController.l, SDL_GameControllerAxis.l) : Global SDL_GameControllerGetAxis._SDL_GameControllerGetAxis = GetFunction(SDL_Library, "SDL_GameControllerGetAxis")
PrototypeC.a _SDL_JoystickGetButton(SDL_Joystick.l, Button.l) : Global SDL_JoystickGetButton._SDL_JoystickGetButton = GetFunction(SDL_Library, "SDL_JoystickGetButton")
PrototypeC.w _SDL_JoystickGetAxis(SDL_Joystick.l, Axis.l) : Global SDL_JoystickGetAxis._SDL_JoystickGetAxis = GetFunction(SDL_Library, "SDL_JoystickGetAxis")
PrototypeC.a _SDL_JoystickGetHat(SDL_Joystick.l, Hat.l) : Global SDL_JoystickGetHat._SDL_JoystickGetHat = GetFunction(SDL_Library, "SDL_JoystickGetHat")
PrototypeC _SDL_PumpEvents() : Global SDL_PumpEvents._SDL_PumpEvents = GetFunction(SDL_Library, "SDL_PumpEvents")
PrototypeC.i _SDL_PollEvent(SDL_Event.l) : Global SDL_PollEvent._SDL_PollEvent = GetFunction(SDL_Library, "SDL_PollEvent")
PrototypeC.i _SDL_GameControllerEventState(State.i) : Global SDL_GameControllerEventState._SDL_GameControllerEventState = GetFunction(SDL_Library, "SDL_GameControllerEventState")
PrototypeC.i _SDL_JoystickEventState(State.i) : Global SDL_JoystickEventState._SDL_JoystickEventState = GetFunction(SDL_Library, "SDL_JoystickEventState")
PrototypeC _SDL_JoystickClose(SDL_Joystick.l) : Global SDL_JoystickClose._SDL_JoystickClose = GetFunction(SDL_Library, "SDL_JoystickClose")
PrototypeC _SDL_GameControllerClose(SDL_GameController.l) : Global SDL_GameControllerClose._SDL_GameControllerClose = GetFunction(SDL_Library, "SDL_GameControllerClose")
PrototypeC.i _SDL_GetError() : Global SDL_GetError._SDL_GetError = GetFunction(SDL_Library, "SDL_GetError")
PrototypeC _SDL_Quit() : Global SDL_Quit._SDL_Quit = GetFunction(SDL_Library, "SDL_Quit")
; Others: SDL_JoystickGetGUID, SDL_JoystickGetGUIDString, SDL_JoystickGetDeviceGUID, SDL_GameControllerAddMapping
; SDL_JoystickUpdate, SDL_GameControllerUpdate, SDL_GameControllerGetAttached
Procedure.i Initialise()
Protected.i Result
Result = SDL_Init(#SDL_INIT_JOYSTICK | #SDL_INIT_GAMECONTROLLER | #SDL_INIT_EVENTS)
If Result = 0
Debug "Success initialising the controller subsystem"
Else
Debug "Failed trying to initialise the required subsystems"
ProcedureReturn 0
EndIf
Num_Joysticks = SDL_NumJoysticks()
ProcedureReturn 1
EndProcedure
Procedure.s NameForGCButton(Btn.i)
Select Btn
Case #SDL_CONTROLLER_BUTTON_A : ProcedureReturn "A"
Case #SDL_CONTROLLER_BUTTON_B : ProcedureReturn "B"
Case #SDL_CONTROLLER_BUTTON_X : ProcedureReturn "X"
Case #SDL_CONTROLLER_BUTTON_Y : ProcedureReturn "Y"
Case #SDL_CONTROLLER_BUTTON_BACK : ProcedureReturn "Bk"
Case #SDL_CONTROLLER_BUTTON_DPAD_DOWN : ProcedureReturn "v"
Case #SDL_CONTROLLER_BUTTON_DPAD_LEFT : ProcedureReturn "<"
Case #SDL_CONTROLLER_BUTTON_DPAD_RIGHT : ProcedureReturn ">"
Case #SDL_CONTROLLER_BUTTON_DPAD_UP : ProcedureReturn "^"
Case #SDL_CONTROLLER_BUTTON_GUIDE : ProcedureReturn "Gd"
Case #SDL_CONTROLLER_BUTTON_LEFTSHOULDER : ProcedureReturn "[L]"
Case #SDL_CONTROLLER_BUTTON_LEFTSTICK : ProcedureReturn "(L)"
Case #SDL_CONTROLLER_BUTTON_RIGHTSHOULDER : ProcedureReturn "[R]"
Case #SDL_CONTROLLER_BUTTON_RIGHTSTICK : ProcedureReturn "(R)"
Case #SDL_CONTROLLER_BUTTON_START : ProcedureReturn "St"
Default : ProcedureReturn "?"
EndSelect
EndProcedure
Procedure.s GetControllerType(ID.i)
Select ID
Case 1: ProcedureReturn "Xbox 360"
Case 2: ProcedureReturn "Xbox One"
Case 3: ProcedureReturn "PS3"
Case 4: ProcedureReturn "PS4"
Case 5: ProcedureReturn "Nintendo Switch Pro"
Case 6: ProcedureReturn "Virtual"
Case 7: ProcedureReturn "PS5"
Case 8: ProcedureReturn "Amazon Luna"
Case 9: ProcedureReturn "Google Stadia"
Default: ProcedureReturn "Unknown"
EndSelect
EndProcedure
Procedure.s GetJoystickType(ID.i)
Select ID
Case 1: ProcedureReturn "Game controller"
Case 2: ProcedureReturn "Wheel"
Case 3: ProcedureReturn "Arcade stick"
Case 4: ProcedureReturn "Flight stick"
Case 5: ProcedureReturn "Dance pad"
Case 6: ; GUITAR
Case 7: ; GUITAR_ALTERNATE
Case 11: ; GUITAR_BASS
ProcedureReturn "Guitar"
Case 8: ProcedureReturn "Drum kit"
Case 19: ProcedureReturn "Arcade pad"
Default: ProcedureReturn "Unknown"
EndSelect
EndProcedure
Procedure.i GetDeviceInformation(Array Joysticks.Controller_Data_Structure(1))
Protected.i c
Protected.i Is_Controller
Protected.i Num_Controllers
Protected *Mapping_String
Debug "Number of joysticks connected: " + Num_Joysticks
Debug "----------"
For c = 0 To Num_Joysticks-1
Is_Controller = SDL_IsGameController(c)
If Is_Controller
; process controller
Joysticks(c)\Type = #Type_Controller
Joysticks(c)\Joystick_ID = SDL_JoystickOpen(c)
If Not Joysticks(c)\Joystick_ID
Debug "Failed to open controller"
ProcedureReturn 0
EndIf
Num_Controllers = Num_Controllers + 1
Joysticks(c)\Controller_ID = SDL_GameControllerOpen(c)
Joysticks(c)\Joystick_Instance_ID = SDL_JoystickInstanceID(Joysticks(c)\Joystick_ID)
Joysticks(Joysticks(c)\Joystick_Instance_ID)\Controller_ID_From_Instance = Joysticks(c)\Controller_ID
Joysticks(Joysticks(c)\Joystick_Instance_ID)\Index_From_Instance = c
Joysticks(c)\Joystick_Name = PeekS(SDL_GameControllerNameForIndex(c), -1, #PB_Ascii)
Joysticks(c)\Controller_Type = SDL_GameControllerGetType(Joysticks(c)\Controller_ID)
Debug "Joystick: " + Str(c) + " is a recognised game controller"
Debug "Name: " + Joysticks(c)\Joystick_Name
Debug "Type: " + GetControllerType(Joysticks(c)\Controller_Type)
Debug "Controller ID: " + Joysticks(c)\Controller_ID
Debug "Instance ID: " + Joysticks(c)\Joystick_Instance_ID
If Joysticks(c)\Joystick_Instance_ID = -1
Debug "Error: " + PeekS(CallFunctionFast(SDL_GetError), -1, #PB_Ascii)
Debug "Failed to get instance of controller"
ProcedureReturn 0
EndIf
*Mapping_String = SDL_GameControllerMapping(Joysticks(c)\Controller_ID)
If *Mapping_String <> #Null
Debug "Mapping string: " + PeekS(*Mapping_String, -1, #PB_UTF8)
EndIf
Else
; Process joystick
Joysticks(c)\Type = #Type_Joystick
Joysticks(c)\Joystick_ID = SDL_JoystickOpen(c)
If Not Joysticks(c)\Joystick_ID
Debug "Failed to open joystick"
ProcedureReturn 0
EndIf
Joysticks(c)\Joystick_Instance_ID = SDL_JoystickInstanceID(Joysticks(c)\Joystick_ID)
Joysticks(Joysticks(c)\Joystick_Instance_ID)\Joystick_ID_From_Instance = Joysticks(c)\Joystick_ID
Joysticks(Joysticks(c)\Joystick_Instance_ID)\Index_From_Instance = c
Joysticks(c)\Joystick_Name = PeekS(SDL_JoystickNameForIndex(c), -1, #PB_Ascii)
Joysticks(c)\Joystick_Type = SDL_JoystickGetType(Joysticks(c)\Joystick_ID)
Debug "Joystick: " + c + " is not a recognised game controller"
Debug "Name: " + Joysticks(c)\Joystick_Name
Debug "Type: " + GetJoystickType(Joysticks(c)\Joystick_Type)
Debug "Joystick ID: " + Joysticks(c)\Joystick_ID
Debug "Instance ID: " + Joysticks(c)\Joystick_Instance_ID
If Joysticks(c)\Joystick_Instance_ID = -1
Debug "Error: " + PeekS(CallFunctionFast(SDL_GetError), -1, #PB_Ascii)
Debug "Failed to get instance of controller"
ProcedureReturn 0
EndIf
Joysticks(c)\Num_Axes = SDL_JoystickNumAxes(Joysticks(c)\Joystick_ID)
Debug "Joystick " + Str(c) + " has " + Str(Joysticks(c)\Num_Axes) + " axes"
Joysticks(c)\Num_Hats = SDL_JoystickNumHats(Joysticks(c)\Joystick_ID)
Debug "Joystick " + Str(c) + " has " + Str(Joysticks(c)\Num_Hats) + " hats"
Joysticks(c)\Num_Buttons = SDL_JoystickNumButtons(Joysticks(c)\Joystick_ID)
Debug "Joystick " + Str(c) + " has " + Str(Joysticks(c)\Num_Buttons) + " buttons"
EndIf
; Future development: get GUID
Debug "----------"
Next c
ProcedureReturn 1
EndProcedure
Procedure ProcessJoysticks(Array Joysticks.Controller_Data_Structure(1))
Protected.i c1
Protected.i c2
Protected.i Result
If Use_Events
While (SDL_PollEvent(@SDL_Event))
Select SDL_Event\Type
Case #SDL_JOYDEVICEADDED
Debug "ProcessJoysticks: Joystick added"
If SDL_Event\JoyDeviceEvent\Which > Num_Joysticks-1
Num_Joysticks = SDL_NumJoysticks()
GetDeviceInformation(Joysticks())
EndIf
Case #SDL_JOYDEVICEREMOVED
Debug "ProcessJoysticks: Joystick removed"
Num_Joysticks = SDL_NumJoysticks()
GetDeviceInformation(Joysticks())
EndSelect
If Use_Joystick_Events
Select SDL_Event\Type
Case #SDL_CONTROLLERBUTTONDOWN
If Joysticks(Joysticks(SDL_Event\JoyButtonEvent\Which)\Index_From_Instance)\Type = #Type_Controller
Joysticks(Joysticks(SDL_Event\JoyButtonEvent\Which)\Index_From_Instance)\Button_State\B[SDL_Event\JoyButtonEvent\Button] = 1
EndIf
Case #SDL_CONTROLLERBUTTONUP
If Joysticks(Joysticks(SDL_Event\JoyButtonEvent\Which)\Index_From_Instance)\Type = #Type_Controller
Joysticks(Joysticks(SDL_Event\JoyButtonEvent\Which)\Index_From_Instance)\Button_State\B[SDL_Event\JoyButtonEvent\Button] = 0
EndIf
Case #SDL_CONTROLLERAXISMOTION
If Joysticks(Joysticks(SDL_Event\JoyButtonEvent\Which)\Index_From_Instance)\Type = #Type_Controller
Joysticks(Joysticks(SDL_Event\JoyButtonEvent\Which)\Index_From_Instance)\Axis_State\Axis[SDL_Event\JoyAxisEvent\Axis] = SDL_Event\JoyAxisEvent\Value
EndIf
Case #SDL_JOYBUTTONDOWN
If Joysticks(Joysticks(SDL_Event\JoyButtonEvent\Which)\Index_From_Instance)\Type = #Type_Joystick
Joysticks(Joysticks(SDL_Event\JoyButtonEvent\Which)\Index_From_Instance)\Button_State\B[SDL_Event\JoyButtonEvent\Button] = 1
EndIf
Case #SDL_JOYBUTTONUP
If Joysticks(Joysticks(SDL_Event\JoyButtonEvent\Which)\Index_From_Instance)\Type = #Type_Joystick
Joysticks(Joysticks(SDL_Event\JoyButtonEvent\Which)\Index_From_Instance)\Button_State\B[SDL_Event\JoyButtonEvent\Button] = 0
EndIf
Case #SDL_JOYAXISMOTION
If Joysticks(Joysticks(SDL_Event\JoyButtonEvent\Which)\Index_From_Instance)\Type = #Type_Joystick
Joysticks(Joysticks(SDL_Event\JoyButtonEvent\Which)\Index_From_Instance)\Axis_State\Axis[SDL_Event\JoyAxisEvent\Axis] = SDL_Event\JoyAxisEvent\Value
EndIf
Case #SDL_JOYHATMOTION
If Joysticks(Joysticks(SDL_Event\JoyButtonEvent\Which)\Index_From_Instance)\Type = #Type_Joystick
Joysticks(Joysticks(SDL_Event\JoyButtonEvent\Which)\Index_From_Instance)\Hat_State\Hat[SDL_Event\JoyHatEvent\Hat] = SDL_Event\JoyHatEvent\Value
EndIf
EndSelect
Else
; don't use events, directly query the joysticks
SDL_PumpEvents()
For c1 = 0 To Num_Joysticks-1
If Joysticks(c1)\Type = #Type_Controller
For c2 = 0 To #SDL_CONTROLLER_BUTTON_MAX-1
Joysticks(c1)\Button_State\B[c2] = SDL_GameControllerGetButton(Joysticks(c1)\Controller_ID, c2)
Next c2
For c2 = 0 To #SDL_CONTROLLER_AXIS_MAX-1
Joysticks(c1)\Axis_State\Axis[c2] = SDL_GameControllerGetAxis(Joysticks(c1)\Controller_ID, c2)
Next c2
Else
For c2 = 0 To Joysticks(c1)\Num_Buttons-1
Joysticks(c1)\Button_State\B[c2] = SDL_JoystickGetButton(Joysticks(c1)\Joystick_ID, c2)
Next c2
For c2 = 0 To Joysticks(c1)\Num_Axes-1
Joysticks(c1)\Axis_State\Axis[c2] = SDL_JoystickGetAxis(Joysticks(c1)\Joystick_ID, c2)
Next c2
For c2 = 0 To Joysticks(c1)\Num_Hats-1
Joysticks(c1)\Hat_State\Hat[c2] = SDL_JoystickGetHat(Joysticks(c1)\Joystick_ID, c2)
Next c2
EndIf
Next c1
EndIf
Wend
EndIf
EndProcedure
Procedure Shutdown(Array Joysticks.Controller_Data_Structure(1))
Protected.i c
For c = 0 To Num_Joysticks-1
If Joysticks(c)\Type = #Type_Controller
SDL_GameControllerClose(Joysticks(c)\Controller_ID)
Else
SDL_JoystickClose(Joysticks(c)\Joystick_ID)
EndIf
Next c
SDL_Quit()
Debug "Shutdown: SDL_Quit"
CloseLibrary(SDL_Library)
Debug "Shutdown: Library closed"
End
EndProcedure
CompilerIf #PB_Compiler_IsMainFile
Procedure DrawLists(Array Joysticks.Controller_Data_Structure(1))
Protected.i c1
Protected.i c2
Protected.s Row_Text
Protected.s Text
For c1 = 0 To Num_Joysticks-1
If Joysticks(c1)\Type = #Type_Controller
; process controller
Row_Text = Joysticks(c1)\Joystick_Name
Row_Text + #LF$ + StrF(Joysticks(c1)\Axis_State\Axis[#SDL_CONTROLLER_AXIS_LEFTX]/32768.0,2)
Row_Text + ", " + StrF(Joysticks(c1)\Axis_State\Axis[#SDL_CONTROLLER_AXIS_LEFTY]/32768.0,2)
Row_Text + #LF$ + StrF(Joysticks(c1)\Axis_State\Axis[#SDL_CONTROLLER_AXIS_RIGHTX]/32768.0,2)
Row_Text + ", " + StrF(Joysticks(c1)\Axis_State\Axis[#SDL_CONTROLLER_AXIS_RIGHTY]/32768.0,2)
Row_Text + #LF$ + StrF(Joysticks(c1)\Axis_State\Axis[#SDL_CONTROLLER_AXIS_TRIGGERLEFT]/32768.0,2)
Row_Text + ", " + StrF(Joysticks(c1)\Axis_State\Axis[#SDL_CONTROLLER_AXIS_TRIGGERRIGHT]/32768.0,2)
Text = #LF$
For c2 = 0 To #SDL_CONTROLLER_BUTTON_MAX-1
If Joysticks(c1)\Button_State\B[c2]
Text = Text + NameForGCButton(c2)
Else
Text = Text + "-"
EndIf
Next c2
Row_Text + Text
AddGadgetItem(0, c1, Row_Text)
EndIf
Next c1
For c1 = 0 To Num_Joysticks-1
If Joysticks(c1)\Type = #Type_Joystick
; process joystick
Row_Text = Joysticks(c1)\Joystick_Name
For c2 = 0 To 5
Row_Text + #LF$ + StrF(Joysticks(c1)\Axis_State\Axis[c2]/32768.0,2)
Next
For c2 = 0 To 3
Row_Text + #LF$ + StrF(Joysticks(c1)\Hat_State\Hat[c2]/32768.0,2)
Next
Text = #LF$
For c2 = 0 To #SDL_CONTROLLER_BUTTON_MAX-1
If Joysticks(c1)\Button_State\B[c2]
Text = Text + "*"
Else
Text = Text + "-"
EndIf
Next c2
Row_Text + Text
AddGadgetItem(1, c1, Row_Text)
EndIf
Next c1
EndProcedure
Define.i Result
Define.i Wait_Window_Event
Define.i c
Use_Events.i = 1
Use_Joystick_Events.i = 0
If Not Initialise()
Shutdown(Joysticks())
EndIf
If Not GetDeviceInformation(Joysticks())
Shutdown(Joysticks())
EndIf
OpenWindow(0, 0, 0, 800, 600, "Controller Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIconGadget(0, 10, 30, 780, 250, "Name", 180, #PB_ListIcon_GridLines)
AddGadgetColumn(0, 1, "Left Stick", 80)
AddGadgetColumn(0, 2, "Right Stick", 80)
AddGadgetColumn(0, 3, "Triggers", 80)
AddGadgetColumn(0, 4, "Buttons", 160)
ListIconGadget(1, 10, 330, 780, 250, "Name", 180, #PB_ListIcon_GridLines)
AddGadgetColumn(1, 1, "Axis0", 40)
AddGadgetColumn(1, 2, "Axis1", 40)
AddGadgetColumn(1, 3, "Axis2", 40)
AddGadgetColumn(1, 4, "Axis3", 40)
AddGadgetColumn(1, 5, "Axis4", 40)
AddGadgetColumn(1, 6, "Axis5", 40)
AddGadgetColumn(1, 7, "Hat0", 40)
AddGadgetColumn(1, 8, "Hat1", 40)
AddGadgetColumn(1, 9, "Hat2", 40)
AddGadgetColumn(1, 10, "Hat3", 40)
AddGadgetColumn(1, 11, "Buttons", 160)
TextGadget(2, 10, 10, 780, 20, "Game Controllers (fully mapped)", #PB_Text_Center)
TextGadget(3, 10, 310, 780, 20, "Joysticks (unmapped)", #PB_Text_Center)
AddWindowTimer(0, 0, 100)
If Use_Events
Debug "Enabling events"
SDL_GameControllerEventState(#SDL_ENABLE)
SDL_JoystickEventState(#SDL_ENABLE)
EndIf
Repeat
Wait_Window_Event = WaitWindowEvent()
Select Wait_Window_Event
Case #PB_Event_Timer
If EventTimer() = 0
ProcessJoysticks(Joysticks())
ClearGadgetItems(0)
ClearGadgetItems(1)
DrawLists(Joysticks())
EndIf
EndSelect
Until (Wait_Window_Event = #PB_Event_CloseWindow)
For c = 0 To Num_Joysticks-1
If Joysticks(c)\Type = #Type_Controller
SDL_GameControllerClose(Joysticks(c)\Controller_ID)
Else
SDL_JoystickClose(Joysticks(c)\Joystick_ID)
EndIf
Next c
Shutdown(Joysticks())
CompilerEndIf
EndModule