[PATCH] SDL joystick code additions

Erik Auerswald auerswal at unix-ag.uni-kl.de
Sun Apr 2 10:53:52 EDT 2006


Hi,

the attached patch adds a way to select the joystick to use (instead
of the first one) and support for joystick "hats" to the SDL joystick
code. This takes care of two "FIXME"s.

The joystick is selected by setting the new CVar "in_joystickNo" to the
appropriate number.

Erik
-------------- next part --------------
Index: code/unix/sdl_glimp.c
===================================================================
--- code/unix/sdl_glimp.c	(revision 692)
+++ code/unix/sdl_glimp.c	(working copy)
@@ -1361,17 +1361,32 @@
      K_JOY26, K_JOY27
 };
 
+// translate hat events into keypresses
+// the 4 highest buttons are used for the first hat ...
+static int hat_keys[16] = {
+     K_JOY29, K_JOY30,
+     K_JOY31, K_JOY32,
+     K_JOY25, K_JOY26,
+     K_JOY27, K_JOY28,
+     K_JOY21, K_JOY22,
+     K_JOY23, K_JOY24,
+     K_JOY17, K_JOY18,
+     K_JOY19, K_JOY20
+};
 
+
 // bk001130 - from linux_glimp.c
 extern cvar_t *  in_joystick;
 extern cvar_t *  in_joystickDebug;
 extern cvar_t *  joy_threshold;
+cvar_t *in_joystickNo;
 
 #define ARRAYLEN(x) (sizeof (x) / sizeof (x[0]))
 struct
 {
     qboolean buttons[16];  // !!! FIXME: these might be too many.
     unsigned int oldaxes;
+    unsigned int oldhats;
 } stick_state;
 
 
@@ -1411,36 +1426,35 @@
   for (i = 0; i < total; i++)
     Com_Printf("[%d] %s\n", i, SDL_JoystickName(i));
 
-  // !!! FIXME: someone should add a way to select a specific stick.
-  for( i = 0; i < total; i++ ) {
-    stick = SDL_JoystickOpen(i);
-    if (stick == NULL)
-        continue;
+  in_joystickNo = Cvar_Get( "in_joystickNo", "0", CVAR_ARCHIVE );
+  if( in_joystickNo->integer < 0 || in_joystickNo->integer >= total )
+    Cvar_Set( "in_joystickNo", "0" );
 
-    Com_Printf( "Joystick %d opened\n", i );
-    Com_Printf( "Name:    %s\n", SDL_JoystickName(i) );
-    Com_Printf( "Axes:    %d\n", SDL_JoystickNumAxes(stick) );
-    Com_Printf( "Hats:    %d\n", SDL_JoystickNumHats(stick) );
-    Com_Printf( "Buttons: %d\n", SDL_JoystickNumButtons(stick) );
-    Com_Printf( "Balls: %d\n", SDL_JoystickNumBalls(stick) );
+  stick = SDL_JoystickOpen( in_joystickNo->integer );
 
-    SDL_JoystickEventState(SDL_QUERY);
-
-    /* Our work here is done. */
+  if (stick == NULL) {
+    Com_Printf( "No joystick opened.\n" );
     return;
   }
 
-  /* No soup for you. */
-  if( stick == NULL ) {
-    Com_Printf( "No joystick opened.\n" );
-    return;
-  }
+  Com_Printf( "Joystick %d opened\n", in_joystickNo->integer );
+  Com_Printf( "Name:    %s\n", SDL_JoystickName(in_joystickNo->integer) );
+  Com_Printf( "Axes:    %d\n", SDL_JoystickNumAxes(stick) );
+  Com_Printf( "Hats:    %d\n", SDL_JoystickNumHats(stick) );
+  Com_Printf( "Buttons: %d\n", SDL_JoystickNumButtons(stick) );
+  Com_Printf( "Balls: %d\n", SDL_JoystickNumBalls(stick) );
+
+  SDL_JoystickEventState(SDL_QUERY);
+
+  /* Our work here is done. */
+  return;
 }
 
 void IN_JoyMove( void )
 {
     qboolean joy_pressed[ARRAYLEN(joy_keys)];
     unsigned int axes = 0;
+    unsigned int hats = 0;
     int total = 0;
     int i = 0;
 
@@ -1494,8 +1508,95 @@
         }
     }
 
-    // !!! FIXME: look at the hats...
+    // look at the hats...
+    total = SDL_JoystickNumHats(stick);
+    if (total > 0)
+    {
+        if (total > 4) total = 4;
+        for (i = 0; i < total; i++)
+        {
+	    ((Uint8 *)&hats)[i] = SDL_JoystickGetHat(stick, i);
+        }
+    }
 
+    // update hat state
+    if (hats != stick_state.oldhats)
+    {
+        for( i = 0; i < 4; i++ ) {
+            if( ((Uint8 *)&hats)[i] != ((Uint8 *)&stick_state.oldhats)[i] ) {
+	        // release event
+	        switch( ((Uint8 *)&stick_state.oldhats)[i] ) {
+		case SDL_HAT_UP:
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 0], qfalse, 0, NULL );
+		  break;
+		case SDL_HAT_RIGHT:
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 1], qfalse, 0, NULL );
+		  break;
+		case SDL_HAT_DOWN:
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 2], qfalse, 0, NULL );
+		  break;
+		case SDL_HAT_LEFT:
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 3], qfalse, 0, NULL );
+		  break;
+		case SDL_HAT_RIGHTUP:
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 0], qfalse, 0, NULL );
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 1], qfalse, 0, NULL );
+		  break;
+		case SDL_HAT_RIGHTDOWN:
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 2], qfalse, 0, NULL );
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 1], qfalse, 0, NULL );
+		  break;
+		case SDL_HAT_LEFTUP:
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 0], qfalse, 0, NULL );
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 3], qfalse, 0, NULL );
+		  break;
+		case SDL_HAT_LEFTDOWN:
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 2], qfalse, 0, NULL );
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 3], qfalse, 0, NULL );
+		  break;
+		default:
+		  break;
+		}
+		// press event
+	        switch( ((Uint8 *)&hats)[i] ) {
+		case SDL_HAT_UP:
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 0], qtrue, 0, NULL );
+		  break;
+		case SDL_HAT_RIGHT:
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 1], qtrue, 0, NULL );
+		  break;
+		case SDL_HAT_DOWN:
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 2], qtrue, 0, NULL );
+		  break;
+		case SDL_HAT_LEFT:
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 3], qtrue, 0, NULL );
+		  break;
+		case SDL_HAT_RIGHTUP:
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 0], qtrue, 0, NULL );
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 1], qtrue, 0, NULL );
+		  break;
+		case SDL_HAT_RIGHTDOWN:
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 2], qtrue, 0, NULL );
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 1], qtrue, 0, NULL );
+		  break;
+		case SDL_HAT_LEFTUP:
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 0], qtrue, 0, NULL );
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 3], qtrue, 0, NULL );
+		  break;
+		case SDL_HAT_LEFTDOWN:
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 2], qtrue, 0, NULL );
+                  Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 3], qtrue, 0, NULL );
+		  break;
+		default:
+		  break;
+		}
+            }
+        }
+    }
+
+    // save hat state
+    stick_state.oldhats = hats;
+
     // finally, look at the axes...
     total = SDL_JoystickNumAxes(stick);
     if (total > 0)
Index: README
===================================================================
--- README	(revision 692)
+++ README	(working copy)
@@ -120,6 +120,7 @@
   in_shiftedKeys          - non-SDL Linux only. Enables binding to shifted keys
   cl_consoleHistory       - read only, stores the console history
   cl_platformSensitivity  - read only, indicates the mouse input scaling
+  in_joystickNo           - select joystick to use
 
 New commands
   video [filename]        - start video capture (use with demo command)


More information about the quake3 mailing list