How do you use SDL in Linux?

Linux specific forum
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

How do you use SDL in Linux?

Post 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.
User avatar
mk-soft
Always Here
Always Here
Posts: 6245
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: How do you use SDL in Linux?

Post 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)
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: How do you use SDL in Linux?

Post 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.
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: How do you use SDL in Linux?

Post 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
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: How do you use SDL in Linux?

Post 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
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: How do you use SDL in Linux?

Post 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:
Post Reply