[airstrike] Joystick support (small fix)

Erik Auerswald auerswal at unix-ag.uni-kl.de
Thu May 5 12:10:30 EDT 2005


Hi,

> thanks for the code. I don't own a joystick, so I can't test your code, but
> I have merged it, so it is in CVS now.

Thanks for merging the code. :-)

The files src/core/joystick.[ch] are missing in CVS and I changed a few
things in the joystick code. A patch against the current CVS version is
attached to the mail.

The patch adds 3 files (doc/joystick.txt and src/core/jostick.[ch]) in
addition to modifying src/engine/ai.c.

Erik
-------------- next part --------------
diff -bNru airstrike/doc/joystick.txt airstrike-new/doc/joystick.txt
--- airstrike/doc/joystick.txt	1970-01-01 01:00:00.000000000 +0100
+++ airstrike-new/doc/joystick.txt	2005-05-05 17:53:48.662372150 +0200
@@ -0,0 +1,9 @@
+Joystick input is modeled after the existing keyboard input routines.
+Instead of using the SDL event system the joysticks are polled whenever an
+update message is sent to a sprite controlled by a human player. Different
+to the keyboard input there is a seperate function to get the current
+joystick state that has to be called before checking the state.  Joystick
+input is digital, i.e. any (axis) movement above a certain threshold is
+interpreted as the corresponding action (e.g. acceleration).  The mapping
+of joystick input to game actions is hardcoded in engine/ai.c similar
+to the keyboard configuration.  Each player can use up to one joystick.
diff -bNru airstrike/src/core/joystick.c airstrike-new/src/core/joystick.c
--- airstrike/src/core/joystick.c	1970-01-01 01:00:00.000000000 +0100
+++ airstrike-new/src/core/joystick.c	2005-05-05 17:57:45.710403078 +0200
@@ -0,0 +1,145 @@
+#include <SDL.h>
+#include <stdio.h>
+#include "joystick.h"
+#include "xalloc.h"
+
+static SDL_Joystick **joystick;        /* array to save pointers to joysticks */
+static int number_of_joysticks = 0;    /* number of joysticks found by SDL */
+
+/* initialize joystick subsystem */
+void joystick_setup(void) {
+  /* initialize joystick subsystem of SDL */
+  if(!SDL_WasInit(SDL_INIT_JOYSTICK)) {
+    SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+  }
+  /* disable SDL joystick events if enabled */
+  /* caution: there are two SDL functions to change joystick event state:
+   * SDL_JoystickEventState() and SDL_EventState() */
+  if(SDL_JoystickEventState(SDL_QUERY)) {
+#ifdef DEBUG_JOYSTICK
+    fprintf(stderr, "disabling joystick events\n");
+#endif
+    SDL_JoystickEventState(SDL_IGNORE);
+  }
+  /* allocate memory for joystick-pointers */
+  number_of_joysticks = SDL_NumJoysticks();
+  joystick = xcalloc(number_of_joysticks, sizeof(SDL_Joystick *));
+#ifdef DEBUG_JOYSTICK
+  fprintf(stderr, "joystick_setup(): %d joysticks found\n",number_of_joysticks);
+#endif
+}
+
+/* open joystick */
+/* returns -1 on error, the (unchanged) joystick number (>=0) on success */
+int open_joystick(int joy_no) {
+  if((joy_no > -1) && (joy_no < number_of_joysticks)) {
+    if(SDL_JoystickOpened(joy_no)) {
+#ifndef NDEBUG
+      fprintf(stderr, "joystick %d already opened\n", joy_no);
+#endif
+      return joy_no;
+    } else {
+      if(!(joystick[joy_no] = SDL_JoystickOpen(joy_no))) {
+       fprintf(stderr, "could not open joystick %d\n", joy_no);
+       return -1;
+      } else {
+#ifdef DEBUG_JOYSTICK
+       fprintf(stderr, "opened joystick %d\n", joy_no);
+#endif
+       return joy_no;
+      }
+    }
+  } else {
+    fprintf(stderr, "there is no joystick %d\n", joy_no);
+    return -1;
+  }
+}
+
+/* close all open joysticks */
+void close_joysticks(void) {
+  int joy_no;
+
+  for(joy_no=0; joy_no<number_of_joysticks; joy_no++) {
+    if(joystick[joy_no]) {
+      SDL_JoystickClose(joystick[joy_no]);
+#ifdef DEBUG_JOYSTICK
+      fprintf(stderr, "closed joystick %d\n", joy_no);
+#endif
+    }
+  }
+}
+
+/* update joystick states */
+void update_joysticks(void) {
+  SDL_JoystickUpdate();
+}
+
+/* query status of joystick */
+int joy_active(int joy_no, int actuator) {
+  /* only open joysticks need to be queried */
+  if((joy_no < -1) || (joy_no >= number_of_joysticks) || (!joystick[joy_no])) {
+    return 0;
+  }
+  /* check the joystick component crresponding to actuator */
+  switch(actuator) {
+    case JOY_AXIS0_POS:
+      return ((SDL_JoystickGetAxis(joystick[joy_no], 0) / JOY_THRESHOLD) > 0);
+    case JOY_AXIS0_NEG:
+      return (-(SDL_JoystickGetAxis(joystick[joy_no], 0) / JOY_THRESHOLD) > 0);
+    case JOY_AXIS1_POS:
+      return ((SDL_JoystickGetAxis(joystick[joy_no], 1) / JOY_THRESHOLD) > 0);
+    case JOY_AXIS1_NEG:
+      return (-(SDL_JoystickGetAxis(joystick[joy_no], 1) / JOY_THRESHOLD) > 0);
+    case JOY_AXIS2_POS:
+      return ((SDL_JoystickGetAxis(joystick[joy_no], 2) / JOY_THRESHOLD) > 0);
+    case JOY_AXIS2_NEG:
+      return (-(SDL_JoystickGetAxis(joystick[joy_no], 2) / JOY_THRESHOLD) > 0);
+    case JOY_AXIS3_POS:
+      return ((SDL_JoystickGetAxis(joystick[joy_no], 3) / JOY_THRESHOLD) > 0);
+    case JOY_AXIS3_NEG:
+      return (-(SDL_JoystickGetAxis(joystick[joy_no], 3) / JOY_THRESHOLD) > 0);
+    case JOY_AXIS4_POS:
+      return ((SDL_JoystickGetAxis(joystick[joy_no], 4) / JOY_THRESHOLD) > 0);
+    case JOY_AXIS4_NEG:
+      return (-(SDL_JoystickGetAxis(joystick[joy_no], 4) / JOY_THRESHOLD) > 0);
+    case JOY_AXIS5_POS:
+      return ((SDL_JoystickGetAxis(joystick[joy_no], 5) / JOY_THRESHOLD) > 0);
+    case JOY_AXIS5_NEG:
+      return (-(SDL_JoystickGetAxis(joystick[joy_no], 5) / JOY_THRESHOLD) > 0);
+    case JOY_BUTTON0:
+      return SDL_JoystickGetButton(joystick[joy_no], 0);
+    case JOY_BUTTON1:
+      return SDL_JoystickGetButton(joystick[joy_no], 1);
+    case JOY_BUTTON2:
+      return SDL_JoystickGetButton(joystick[joy_no], 2);
+    case JOY_BUTTON3:
+      return SDL_JoystickGetButton(joystick[joy_no], 3);
+    case JOY_BUTTON4:
+      return SDL_JoystickGetButton(joystick[joy_no], 4);
+    case JOY_BUTTON5:
+      return SDL_JoystickGetButton(joystick[joy_no], 5);
+    case JOY_BUTTON6:
+      return SDL_JoystickGetButton(joystick[joy_no], 6);
+    case JOY_BUTTON7:
+      return SDL_JoystickGetButton(joystick[joy_no], 7);
+    case JOY_BUTTON8:
+      return SDL_JoystickGetButton(joystick[joy_no], 8);
+    case JOY_BUTTON9:
+      return SDL_JoystickGetButton(joystick[joy_no], 9);
+    case JOY_BUTTON10:
+      return SDL_JoystickGetButton(joystick[joy_no], 10);
+    case JOY_BUTTON11:
+      return SDL_JoystickGetButton(joystick[joy_no], 11);
+    case JOY_BUTTON12:
+      return SDL_JoystickGetButton(joystick[joy_no], 12);
+    case JOY_BUTTON13:
+      return SDL_JoystickGetButton(joystick[joy_no], 13);
+    case JOY_BUTTON14:
+      return SDL_JoystickGetButton(joystick[joy_no], 14);
+    case JOY_BUTTON15:
+      return SDL_JoystickGetButton(joystick[joy_no], 15);
+    /* if an unknown actuator is queried it is assumed to be not active */
+    default:
+      return 0;
+  }
+}
diff -bNru airstrike/src/core/joystick.h airstrike-new/src/core/joystick.h
--- airstrike/src/core/joystick.h	1970-01-01 01:00:00.000000000 +0100
+++ airstrike-new/src/core/joystick.h	2005-05-05 17:57:40.909192322 +0200
@@ -0,0 +1,54 @@
+#ifndef JOYSTICK_H
+#define JOYSTICK_H
+
+/* threshold to distinguish between real joystick movement and noise */
+#define JOY_THRESHOLD 100
+
+/* prepare for up to 6 axes and 16 buttons per joystick */
+enum joystick_actuator {
+       JOY_AXIS0_POS,
+       JOY_AXIS0_NEG,
+       JOY_AXIS1_POS,
+       JOY_AXIS1_NEG,
+       JOY_AXIS2_POS,
+       JOY_AXIS2_NEG,
+       JOY_AXIS3_POS,
+       JOY_AXIS3_NEG,
+       JOY_AXIS4_POS,
+       JOY_AXIS4_NEG,
+       JOY_AXIS5_POS,
+       JOY_AXIS5_NEG,
+       JOY_BUTTON0,
+       JOY_BUTTON1,
+       JOY_BUTTON2,
+       JOY_BUTTON3,
+       JOY_BUTTON4,
+       JOY_BUTTON5,
+       JOY_BUTTON6,
+       JOY_BUTTON7,
+       JOY_BUTTON8,
+       JOY_BUTTON9,
+       JOY_BUTTON10,
+       JOY_BUTTON11,
+       JOY_BUTTON12,
+       JOY_BUTTON13,
+       JOY_BUTTON14,
+       JOY_BUTTON15
+};
+
+/* initialize joystick subsystem */
+void joystick_setup(void);
+
+/* assign a joystick to a player */
+int open_joystick(int joy_no);
+
+/* close joystick subsystem */
+void close_joysticks(void);
+
+/* update joystick states */
+void update_joysticks(void);
+
+/* query status of joystick */
+int joy_active(int joy_no, int actuator);
+
+#endif
diff -bNru airstrike/src/engine/ai.c airstrike-new/src/engine/ai.c
--- airstrike/src/engine/ai.c	2005-05-05 14:09:21.000000000 +0200
+++ airstrike-new/src/engine/ai.c	2005-05-05 18:01:16.337780751 +0200
@@ -68,6 +68,10 @@
   switch (message.type)
     {
     case MSG_UPDATE:
+      /* update joystick state just once per update message */
+      if(pai->joy_no > -1) {
+	update_joysticks();
+      }
       if (key_pressed(pai->key_accelerate) ||
 		      joy_active(pai->joy_no, pai->joy_accelerate))
 	obj_message(target,msg_ctrl(MSG_ACCELERATE));
@@ -121,7 +125,7 @@
   ai->key_right = conf_number(key_conf,"right",SDLK_RIGHT);
   ai->key_fire = conf_number(key_conf,"fire",SDLK_RSHIFT);
   ai->key_drop = conf_number(key_conf,"drop",SDLK_RCTRL);
-  ai->joy_no = conf_number(key_conf,"joy_no",0);
+  ai->joy_no = conf_number(key_conf,"joy_no",player_nr-1);
   ai->joy_accelerate = conf_number(key_conf,"joy_accelerate",JOY_AXIS1_NEG);
   ai->joy_break = conf_number(key_conf,"joy_break",JOY_AXIS1_POS);
   ai->joy_left = conf_number(key_conf,"joy_left",JOY_AXIS0_NEG);
@@ -129,7 +133,8 @@
   ai->joy_fire = conf_number(key_conf,"joy_fire",JOY_BUTTON0);
   ai->joy_drop = conf_number(key_conf,"joy_drop",JOY_BUTTON1);
 
-  open_joystick(ai->joy_no);
+  /* try to open joystick and set joy_no to -1 on error */
+  ai->joy_no = open_joystick(ai->joy_no);
   return (ai_t *)ai;
 }
 


More information about the airstrike mailing list