Page 1 of 1

SDL Joystick Event Example

Posted: Tue Aug 14, 2012 7:18 pm
by Guimauve
Hello everyone,

Ok this is an example to show how to use SDL to manage Joystick Event. The following code has been created for Linux only but it should work on all platform where SDL can be imported (Windows and Mac OSX).
I have successfully tested it with a Logitech Extreme 3D Pro joystick.

Thanks to Wilbert for the SDL_JoyAxisEvent_CorrectedValue(SDL_EventA) macro to simplify my original code. See here http://www.purebasic.fr/english/viewtop ... 16&t=50855

Have fun !

Best regards
Guimauve

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : SDL Joystick Event Example
; File Name : SDL Joystick Event Example.pb
; File version: 1.0.0
; Programming : OK
; Programmed by : Guimauve
; Date : 14-08-2012
; Last Update : 14-08-2012
; PureBasic code : 4.70
; Platform : LinuxMint 13 x64 + Gnome-Shell
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

ImportC "-lSDL"
  
  ; <<<<<<<<<<<<<<<<<<<
  ; <<<<< General <<<<<
  
  SDL_Init(Flag.l)
  SDL_Quit()
  SDL_GetError()
  SDL_ClearError()
  SDL_Linked_Version()

  ; <<<<<<<<<<<<<<<<<
  ; <<<<< Video <<<<<
  
  SDL_GetVideoSurface()
  SDL_GetVideoInfo()
  SDL_VideoDriverName(namebuf.s, maxlen.l)
  SDL_ListModes(*Format.SDL_PixelFormat, Flags.l)
  SDL_VideoModeOK(Width.l, Height.l, BitsPerPixel.l, Flags.l)
  SDL_SetVideoMode(Width.l, Height.l, BitsPerPixel.l, Flags.l)

  SDL_GL_GetAttribute(Attribute.l, *Value.l) ; --> À VALIDER
  SDL_GL_SetAttribute(Attribute.l, Value.l)
  SDL_GL_SwapBuffers()

  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Window management <<<<<
  
  SDL_WM_SetCaption(Title.s, Icon.s)
  SDL_WM_SetIcon(*icon.SDL_Surface, *mask.a)
  SDL_WM_IconifyWindow()

  ; <<<<<<<<<<<<<<<<<<
  ; <<<<< Events <<<<<

  SDL_PollEvent(*Event.SDL_Event)

  SDL_EventState(Type.a, State.l)
  SDL_GetKeyState(*numkeys.l)
  SDL_GetModState()
  SDL_SetModState(Modstate.l)
  SDL_GetKeyName(Key.l)
  SDL_EnableUNICODE(Enable.l)
  SDL_JoystickEventState(State.l)

  ; <<<<<<<<<<<<<<<<<
  ; <<<<< Mouse <<<<<

  SDL_ShowCursor(Toggle.l)
  
  ; <<<<<<<<<<<<<<<<<<<<
  ; <<<<< Joystick <<<<<
  
  SDL_NumJoysticks()
  SDL_JoystickUpdate()
  SDL_JoystickName(Index.l)
  SDL_JoystickOpen(Index.l)
  SDL_JoystickOpened(Index.l)
  
  SDL_JoystickIndex(*JoystickA.i)
  SDL_JoystickNumAxes(*JoystickA.i)
  SDL_JoystickNumBalls(*JoystickA.i)
  SDL_JoystickNumHats(*JoystickA.i)
  SDL_JoystickNumButtons(*JoystickA.i)  
  SDL_JoystickClose(*JoystickA.i)
  
  SDL_JoystickGetAxis(*JoystickA.i, Axis.l)
  SDL_JoystickGetHat(*JoystickA.i, Hat.l)
  SDL_JoystickGetButton(*JoystickA.i, Button.l)
  SDL_JoystickGetBall(*JoystickA.i, Ball.l, *Dx.l, *Dy.l)
  
EndImport 

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Macro pour la gestion des événements <<<<<

Macro SDL_EventType(SDL_EventA)
  
  SDL_EventA\type
  
EndMacro 

Macro SDL_KeySym(SDL_EventA)
  
  SDL_EventA\key\keysym\sym
  
EndMacro 

Macro SDL_ActiveGainEvent(SDL_EventA)
  
  SDL_EventA\active\gain
  
EndMacro 

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Évènement à propos de la souris <<<<<

Macro SDL_MouseButtonEvent_Button(SDL_EventA)
  
  SDL_EventA\button\button
  
EndMacro 

Macro SDL_MouseButtonEvent_State(SDL_EventA)
  
  SDL_EventA\button\state
  
EndMacro 

Macro SDL_MouseButtonEvent_X(SDL_EventA)
  
  SDL_EventA\button\x
  
EndMacro 

Macro SDL_MouseButtonEvent_Y(SDL_EventA)
  
  SDL_EventA\button\y
  
EndMacro 

Macro SDL_MouseButtonEvent_Position(SDL_EventA, Position)
  
  Position\x = SDL_MouseButtonEvent_X(SDL_EventA)
  Position\y = SDL_MouseButtonEvent_Y(SDL_EventA)
  
EndMacro 

Macro SDL_MouseMotionEvent_State(SDL_EventA)
  
  SDL_EventA\Motion\state
  
EndMacro 

Macro SDL_MouseMotionEvent_X(SDL_EventA)
  
  SDL_EventA\Motion\x
  
EndMacro 

Macro SDL_MouseMotionEvent_Y(SDL_EventA)
  
  SDL_EventA\Motion\y
  
EndMacro 

Macro SDL_MouseMotionEvent_Position(SDL_EventA, Position)
  
  Position\x = SDL_MouseMotionEvent_X(SDL_EventA)
  Position\y = SDL_MouseMotionEvent_Y(SDL_EventA)
  
EndMacro 

Macro SDL_MouseMotionEvent_XRel(SDL_EventA)
  
  SDL_EventA\Motion\xrel
  
EndMacro 

Macro SDL_MouseMotionEvent_YRel(SDL_EventA)
  
  SDL_EventA\Motion\yrel
  
EndMacro 

Macro SDL_MouseMotionEvent_PositionRel(SDL_EventA, Position)
  
  Position\x = SDL_MouseMotionEvent_XRel(SDL_EventA)
  Position\y = SDL_MouseMotionEvent_YRel(SDL_EventA)
  
EndMacro 

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Évènement à propos des axes du Joystick <<<<<

Enumeration
  
  #SDL_JOY_AXIS_X
  #SDL_JOY_AXIS_Y
  #SDL_JOY_AXIS_Z
  #SDL_JOY_AXIS_R
  
EndEnumeration

Macro SDL_JoyAxisEvent_Axis(SDL_EventA) ; Le no d'axe (voir les constantes ci-haut)

  SDL_EventA\jaxis\axis

EndMacro 

Macro SDL_JoyAxisEvent_Value(SDL_EventA) ; La valeur de l'axe (-32768 à 32767)

  SDL_EventA\jaxis\value

EndMacro 

Macro SDL_JoyAxisEvent_CorrectedValue(SDL_EventA) ; La valeur de l'axe (0 à 65535)

  (32767 - SDL_EventA\jaxis\value)

EndMacro 

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Évènement à propos des boutons du Joystick <<<<<

Macro SDL_JoyButtonEvent_Button(SDL_EventA)

  SDL_EventA\jbutton\button
  
EndMacro 

Macro SDL_JoyButtonEvent_State(SDL_EventA)

  SDL_EventA\jbutton\state

EndMacro 

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Évènement à propos du Hat switch du Joystick <<<<<

Macro SDL_JoyHatEvent_Value(SDL_EventA)

  SDL_EventA\jhat\value

EndMacro 

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Commandes supplémentaires à propos de la version de SDL <<<<<

Macro SDL_Format_Version(SDLVersionA)
  
  "V" + Str(SDLVersionA\Major) + "." + Str(SDLVersionA\Minor) + "." + Str(SDLVersionA\Patch)
  
EndMacro

Procedure SDL_Current_Version(*VersionA.i)
  
  *SDLVersionA.SDL_version = SDL_Linked_Version()
  CopyMemory(*SDLVersionA, *VersionA, SizeOf(SDL_version))
  
EndProcedure

; If SDL_Init(#SDL_INIT_EVERYTHING) <> -1
;   SDL_Current_Version(Version.SDL_Version)
;   Debug SDL_Format_Version(Version)
; EndIf

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
; <<<<< !!! WARNING - YOU ARE NOW IN A TESTING ZONE - WARNING !!! <<<<< 
; <<<<< !!! WARNING - THIS CODE SHOULD BE COMMENTED - WARNING !!! <<<<< 
; <<<<< !!! WARNING - BEFORE THE FINAL COMPILATION. - WARNING !!! <<<<< 
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 

#Joystick_Threshold = 6400

If SDL_Init(#SDL_INIT_EVERYTHING) = -1
  Debug "Impossible to Initialize SDL !"
Else
  
  ExamineDesktops()
  Width = 400
  Height = 300
  Depth = DesktopDepth(0)
  SDL_Surface.i = SDL_SetVideoMode(Width, Height, Depth, #SDL_OPENGL)
  
  If SDL_Surface = #Null
    Debug "Impossible to set the video mode !"
  Else
    
    SDL_WM_SetCaption("Joystick Events", "")
    SDL_JoystickEventState(#SDL_ENABLE)
    
    
    NumJoysticks = SDL_NumJoysticks()
    Debug NumJoysticks
    Debug ""
    
    For JoysticksID = 0 To NumJoysticks - 1
      
      joystick = SDL_JoystickOpen(JoysticksID)
      Debug PeekS(SDL_JoystickName(JoysticksID))
      Debug SDL_JoystickIndex(joystick)
      Debug SDL_JoystickNumAxes(joystick)
      Debug SDL_JoystickNumButtons(joystick)    
      Debug SDL_JoystickNumHats(joystick)
      Debug SDL_JoystickNumBalls(joystick)
      
      If SDL_JoystickOpened(JoysticksID)
        SDL_JoystickClose(joystick)
      EndIf
      
      Debug ""
    Next
    
    joystick = SDL_JoystickOpen(0)
    
    Repeat 
      
      While SDL_PollEvent(Event.SDL_Event)
        
        Select SDL_EventType(Event)
            
          Case #SDL_ACTIVEEVENT
            If SDL_ActiveGainEvent(Event) = 0
              IsActive = #False
            Else
              IsActive = #True
            EndIf 
            
          Case #SDL_KEYUP
            
            Select SDL_KeySym(Event)
                
              Case #SDLK_ESCAPE
                ExitJoystickExample.b = #True
                Break
 
            EndSelect 

          Case #SDL_JOYBUTTONDOWN
            
            Select SDL_JoyButtonEvent_Button(Event)
                
              Case 0
                Debug "Joystick Button 0 - Down"
                
              Case 1
                Debug "Joystick Button 1 - Down"
                
              Case 2
                Debug "Joystick Button 2 - Down"
                
              Case 3
                Debug "Joystick Button 3 - Down"
                
              Case 4
                Debug "Joystick Button 4 - Down"
                
              Case 5
                Debug "Joystick Button 5 - Down"
                
              Case 6
                Debug "Joystick Button 6 - Down"
                
              Case 7
                Debug "Joystick Button 7 - Down"
                
              Case 8
                Debug "Joystick Button 8 - Down"
                
              Case 9
                Debug "Joystick Button 9 - Down"      
                
              Case 10
                Debug "Joystick Button 10 - Down"
                
              Case 11
                Debug "Joystick Button 11 - Down" 
                
            EndSelect
            
          Case #SDL_JOYBUTTONUP
            
            Select SDL_JoyButtonEvent_Button(Event)
                
              Case 0
                Debug "Joystick Button 0 - Up"
                
              Case 1
                Debug "Joystick Button 1 - Up"
                
              Case 2
                Debug "Joystick Button 2 - Up"
                
              Case 3
                Debug "Joystick Button 3 - Up"
                
              Case 4
                Debug "Joystick Button 4 - Up"
                
              Case 5
                Debug "Joystick Button 5 - Up"
                
              Case 6
                Debug "Joystick Button 6 - Up"
                
              Case 7
                Debug "Joystick Button 7 - Up"
                
              Case 8
                Debug "Joystick Button 8 - Up"
                
              Case 9
                Debug "Joystick Button 9 - Up"
                
              Case 10
                Debug "Joystick Button 10 - Up"
                
              Case 11
                Debug "Joystick Button 11 - Up" 
                
            EndSelect
            
          Case #SDL_JOYAXISMOTION
            
            
            Select SDL_JoyAxisEvent_Axis(Event)
                
              Case #SDL_JOY_AXIS_X
                If SDL_JoyAxisEvent_Value(Event) < -#Joystick_Threshold Or SDL_JoyAxisEvent_Value(Event) > #Joystick_Threshold
                  Debug "Left-Right Mouvement " + Str(SDL_JoyAxisEvent_Value(Event))
                  ; Le code pour les mouvements gauche-droit vont ici
                EndIf
                
              Case #SDL_JOY_AXIS_Y
                If SDL_JoyAxisEvent_Value(Event) < -#Joystick_Threshold Or SDL_JoyAxisEvent_Value(Event) > #Joystick_Threshold
                  Debug "Up-Down Mouvement " + Str(SDL_JoyAxisEvent_Value(Event))
                  ; Le code pour les mouvements monter-descendre vont ici
                EndIf
                
              Case #SDL_JOY_AXIS_Z
                If SDL_JoyAxisEvent_Value(Event) < -#Joystick_Threshold Or SDL_JoyAxisEvent_Value(Event) > #Joystick_Threshold
                  Debug "Rudder Mouvement " + Str(SDL_JoyAxisEvent_Value(Event))
                  ; Le code pour les mouvements du palonier vont ici
                EndIf
                
              Case #SDL_JOY_AXIS_R
                Debug "Throttle Mouvement " + Str(SDL_JoyAxisEvent_CorrectedValue(Event))
                ; Le code pour les mouvements de la manette des gaz vont ici
                
            EndSelect
            
          Case #SDL_JOYHATMOTION
            
            Select SDL_JoyHatEvent_Value(Event)
                
              Case #SDL_HAT_CENTERED
                Debug "Hat Centred"
                ; Faire quelque chose lorsque le hat est centré
                
              Case #SDL_HAT_UP
                Debug "Hat Up"
                ; Faire quelque chose lorsque le hat est haut
                
              Case #SDL_HAT_RIGHT
                Debug "Hat right"
                ; Faire quelque chose lorsque le hat est droite
                
              Case #SDL_HAT_DOWN
                Debug "Hat down"
                ; Faire quelque chose lorsque le hat est bas
                
              Case #SDL_HAT_LEFT
                Debug "Hat left"
                ; Faire quelque chose lorsque le hat est gauche
                
              Case #SDL_HAT_RIGHTUP
                Debug "Hat Right-up"
                ; Faire quelque chose lorsque le hat est haut-droite
                
              Case #SDL_HAT_RIGHTDOWN
                Debug "Hat Right-down"
                ; Faire quelque chose lorsque le hat est bas-droite
                
              Case #SDL_HAT_LEFTUP
                Debug "Hat left-up"
                ; Faire quelque chose lorsque le hat est haut-gauche
                
              Case #SDL_HAT_LEFTDOWN
                Debug "Hat left-down"
                ; Faire quelque chose lorsque le hat est bas-gauche
                
            EndSelect
            
          Case #SDL_QUIT
            ExitJoystickExample = #True  
            Break

        EndSelect 
        
      Wend
      
    Until ExitJoystickExample = #True 
    
    If SDL_JoystickOpened(0)
      SDL_JoystickClose(joystick)
    EndIf

    SDL_Quit() 
    End

  EndIf

EndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<

Re: SDL Joystick Event Example

Posted: Tue Aug 14, 2012 7:53 pm
by J. Baker
Nice! ;)

After SDL_JoystickClose(), don't forget and SDL_Quit().

EDIT: I see you SDL_Init(#SDL_INIT_EVERYTHING). Which you don't have to init everything if you're just wanting joystick. ;)

Re: SDL Joystick Event Example

Posted: Tue Aug 14, 2012 8:20 pm
by Guimauve
J. Baker wrote:Nice! ;)

After SDL_JoystickClose(), don't forget and SDL_Quit().

EDIT: I see you SDL_Init(#SDL_INIT_EVERYTHING). Which you don't have to init everything if you're just wanting joystick. ;)
Yeah, I know but this example is part of a prototype of a complete game I'm currently working on (3D graphics engine, 3D physics engine , AI, everything developed in house from the scratch). Unfortunately, SDL 1.2 is not compatible with OpenGL 3.0+ core function but apparently the V2.0 is about to be publicly released. So I will be able to continue on the graphics engine.

I have added the SDL_Quit() on the program exit, but for sure if someone just use SDL to manage the Joystick events only (because the PB internal one is little bit outdated, sorry Fred) the Joystick sub-system has to be Initialize and Quit on program exit.

Best regards.
Guimauve

Re: SDL Joystick Event Example

Posted: Tue Aug 14, 2012 8:32 pm
by J. Baker
Understood. ;)