Page 1 of 1

How do you use SDL in Linux?

Posted: Tue Dec 19, 2023 1:57 am
by coco2
How do I use SDL in Linux (in particular for joysticks)? I got as far as trying to initialise it with SDL_INIT() but it gets the error: "Invalid Memory Address".

I'm using PrototypeC to create prototypes of all the functions I need.

Re: How do you use SDL in Linux?

Posted: Tue Dec 19, 2023 9:26 am
by mk-soft
Without code it is not possible to say where the error lies.
But search the forum. SDL has often been used there.
But I suspect that your definition is not correct (PrototypeC)

Re: How do you use SDL in Linux?

Posted: Tue Dec 19, 2023 9:36 am
by coco2
I guess my first question is what file do I open to open the library?

Code: Select all

Define.i SDL_Library = 0
Define.i SDL2_Library_Result
SDL2_Library_Result = OpenLibrary(SDL_Library, "SDL2.dll")
It won't be the dll so what is the Linux file?

I'll keep trying to search the forum with Google because the forum search doesn't search for three letter words.

Re: How do you use SDL in Linux?

Posted: Thu Dec 21, 2023 4:43 am
by coco2
I got it working with OpenLibrary(SDL_Library, "/usr/lib/x86_64-linux-gnu/libSDL2.so")

Code: Select all

  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, "SDL2\32bit\SDL2.dll")
      CompilerElse
        SDL2_Library_Result = OpenLibrary(SDL_Library, "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

Re: How do you use SDL in Linux?

Posted: Thu Dec 21, 2023 7:17 am
by coco2
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

Re: How do you use SDL in Linux?

Posted: Thu Dec 21, 2023 7:35 am
by coco2
Don't worry I figured out my problem, I had double up of code which somehow worked in Windows but not Linux. Whoopsie :oops: