[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