From acfa909f510bc1d03b17a302b5b3681fef51e6c3 Mon Sep 17 00:00:00 2001 From: Jamie Wilkinson Date: Sun, 13 Oct 2002 13:18:03 +0000 Subject: [PATCH] - Updated joystick support to GLX and X11. (icculus patchsets 62,64,80) - Bugfixed a bit, too. Compiles with --disable-joystick. --- configure.in | 16 +++- src/gl_glx.c | 175 ++++++++++++++++++++++++++++++++++------ src/rw_sdl.c | 91 +++++++++++---------- src/rw_x11.c | 219 ++++++++++++++++++++++++++++++++++++++------------- 4 files changed, 379 insertions(+), 122 deletions(-) diff --git a/configure.in b/configure.in index 9d53e16..40af5c9 100644 --- a/configure.in +++ b/configure.in @@ -277,6 +277,18 @@ AC_SUBST(DL_LIBS) #SDL_FLAGS=`sdl-config --libs` #AC_SUBST(SDL_FLAGS) +dnl -------------------- +dnl Input device support +dnl -------------------- + +AC_MSG_CHECKING(whether to enable joystick support) +AC_ARG_ENABLE(joystick, + [ --disable-joystick disable joystick support ], + AC_MSG_RESULT(no), + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_JOYSTICK, 1, [Define this if you want joystick support to be built]) +) + dnl ------------------------- dnl Optimising compiler flags dnl ------------------------- @@ -286,8 +298,8 @@ USE_OPT="" AC_MSG_CHECKING(whether to allow compiler optimisations) AC_ARG_ENABLE(opt, [ --disable-opt disable compiler optimisations ], - AC_MSG_RESULT(optimisations disabled), - AC_MSG_RESULT(optimisations enabled) + AC_MSG_RESULT(no), + AC_MSG_RESULT(yes) USE_OPT="yes" OPT_CFLAGS="$OPT_CFLAGS -O2 -ffast-math -funroll-loops -fomit-frame-pointer -fexpensive-optimizations" ) diff --git a/src/gl_glx.c b/src/gl_glx.c index 059a0f6..e801608 100644 --- a/src/gl_glx.c +++ b/src/gl_glx.c @@ -67,6 +67,11 @@ #include #include +#ifdef HAVE_JOYSTICK +#include +#include +#endif + glwstate_t glw_state; static Display *dpy = NULL; @@ -88,6 +93,50 @@ static Bool (*qglXMakeCurrent)( Display *dpy, GLXDrawable drawable, GLXContext c static void (*qglXCopyContext)( Display *dpy, GLXContext src, GLXContext dst, GLuint mask ); static void (*qglXSwapBuffers)( Display *dpy, GLXDrawable drawable ); +/* JOYSTICK */ +#ifdef HAVE_JOYSTICK +static cvar_t * in_joystick; +static qboolean joystick_avail = false; +static int joy_fd, jx, jy, jt; +static cvar_t * joystick_invert_y; + +void init_joystick() { + int i, err; + glob_t pglob; + struct js_event e; + + joystick_avail = false; + err = glob("/dev/js*", 0, NULL, &pglob); + if (err) { + switch (err) { + case GLOB_NOSPACE: + ri.Con_Printf(PRINT_ALL, "Error, out of memory while looking for joysticks\n"); + break; + case GLOB_NOMATCH: + ri.Con_Printf(PRINT_ALL, "No joysticks found\n"); + break; + default: + ri.Con_Printf(PRINT_ALL, "Error %d while looking for joysticks\n", err); + } + return; + } + + for (i = 0; i < pglob.gl_pathc; i++) { + ri.Con_Printf(PRINT_ALL, "Trying joystick dev %s\n", pglob.gl_pathv[i]); + joy_fd = open(pglob.gl_pathv[i], O_RDONLY | O_NONBLOCK); + if (joy_fd == -1) + ri.Con_Printf(PRINT_ALL, "Error opening joystick dev %s\n", pglob.gp_pathv[i]); + else { + while (read(joy_fd, &e, sizeof(struct js_event)) != -1 && (e.type &JS_EVENT_INIT)) + ri.Con_Printf(PRINT_ALL, "Read init event\n"); + ri.Con_Printf(PRINT_ALL, "Using joystick dev %s\n", pglob.gl_pathv[i]); + joystick_avail = true; + return; + } + } + globfree(&pglob); +} +#endif /*****************************************************************************/ /* MOUSE */ @@ -96,6 +145,7 @@ static void (*qglXSwapBuffers)( Display *dpy, GLXDrawable drawable ); // this is inside the renderer shared lib, so these are called from vid_so static qboolean mouse_avail; +static int mouse_buttonstate, mouse_oldbuttonstate; static int mx, my; static int old_mouse_x, old_mouse_y; @@ -240,6 +290,11 @@ void RW_IN_Init(in_state_t *in_state_p) { in_state = in_state_p; +#ifdef HAVE_JOYSTICK + in_joystick = ri.Cvar_Get("in_joystick", "1", CVAR_ARCHIVE); + joystick_invert_y = ri.Cvar_Get("joystick_invert_y", "1", CVAR_ARCHIVE); +#endif + // mouse variables m_filter = ri.Cvar_Get ("m_filter", "0", 0); in_mouse = ri.Cvar_Get ("in_mouse", "1", CVAR_ARCHIVE); @@ -259,6 +314,11 @@ void RW_IN_Init(in_state_t *in_state_p) mx = my = 0.0; mouse_avail = true; + +#ifdef HAVE_JOYSTICK + if (in_joystick) + init_joystick(); +#endif } void RW_IN_Shutdown(void) @@ -270,6 +330,12 @@ void RW_IN_Shutdown(void) ri.Cmd_RemoveCommand ("-mlook"); ri.Cmd_RemoveCommand ("force_centerview"); } + +#ifdef HAVE_JOYSTICK + if (joystick_avail) + if (close(joy_fd)) + ri.Con_Printf(PRINT_ALL, "Error, problem closing joystick.\n"); +#endif } /* @@ -277,8 +343,60 @@ void RW_IN_Shutdown(void) IN_Commands =========== */ -void RW_IN_Commands (void) -{ +void RW_IN_Commands(void) { + int i; + +#ifdef HAVE_JOYSTICK + struct js_event e; + int key_index; +#endif + + if (mouse_avail) { + for (i = 0; i < 3; i++) { + if ((mouse_buttonstate & (1<Key_Event_fp(K_MOUSE1 + i, true); + if (!(mouse_buttonstate & (1<Key_Event_fp(K_MOUSE1 + i, false); + } + /* not in loop because K_MOUSE4 doesn't come after K_MOUSE3 */ + if ((mouse_buttonstate & (1<<3)) && !(mouse_oldbuttonstate & (1<<3))) + in_state->Key_Event_fp(K_MOUSE4, true); + if (!(mouse_buttonstate * (1<<3)) && (mouse_oldbuttonstate & (1<<3))) + in_state->Key_Event_fp(K_MOUSE4, false); + + if ((mouse_buttonstate & (1<<4)) && !(mouse_oldbuttonstate & (1<<4))) + in_state->Key_Event_fp(K_MOUSE5, true); + if (!(mouse_buttonstate * (1<<4)) && (mouse_oldbuttonstate & (1<<4))) + in_state->Key_Event_fp(K_MOUSE5, false); + + mouse_oldbuttonstate = mouse_buttonstate; + } + +#ifdef HAVE_JOYSTICK + if (joystick_avail) { + while (read(joy_fd, &e, sizeof(struct js_event)) != -1) { + if (e.type & JS_EVENT_BUTTON) { + key_index = (e.number < 4) ? K_JOY1 : K_AUX1; + if (e.value) + in_state->Key_Event_fp(key_index + e.number, true); + else + in_state->Key_Event_fp(key_index + e.number, false); + } else if (e.type & JS_EVENT_AXIS) { + switch (e.number) { + case 0: + jx = e.value; + break; + case 1: + jy = e.value; + break; + case 3: + jt = e.value; + break; + } + } + } + } +#endif } /* @@ -286,15 +404,11 @@ void RW_IN_Commands (void) IN_Move =========== */ -void RW_IN_Move (usercmd_t *cmd) -{ - if (!mouse_avail) - return; - - if (m_filter->value) - { - mx = (mx + old_mouse_x) * 0.5; - my = (my + old_mouse_y) * 0.5; +void RW_IN_Move (usercmd_t *cmd) { + if (mouse_avail) { + if (m_filter->value) { + mx = (mx + old_mouse_x) * 0.5; + my = (my + old_mouse_y) * 0.5; } old_mouse_x = mx; @@ -303,24 +417,37 @@ void RW_IN_Move (usercmd_t *cmd) mx *= sensitivity->value; my *= sensitivity->value; -// add mouse X/Y movement to cmd - if ( (*in_state->in_strafe_state & 1) || - (lookstrafe->value && mlooking )) - cmd->sidemove += m_side->value * mx; + /* add mouse X/Y movement to cmd */ + if ((*in_state->in_strafe_state & 1) || (lookstrafe->value && mlooking )) + cmd->sidemove += m_side->value * mx; else - in_state->viewangles[YAW] -= m_yaw->value * mx; + in_state->viewangles[YAW] -= m_yaw->value * mx; - if ( (mlooking || freelook->value) && - !(*in_state->in_strafe_state & 1)) - { - in_state->viewangles[PITCH] += m_pitch->value * my; - } + if ((mlooking || freelook->value) && !(*in_state->in_strafe_state & 1)) + in_state->viewangles[PITCH] += m_pitch->value * my; else - { - cmd->forwardmove -= m_forward->value * my; - } + cmd->forwardmove -= m_forward->value * my; mx = my = 0; + } +#ifdef HAVE_JOYSTICK + if (joystick_avail) { + /* add joy X/Y movement to cmd */ + if ((*in_state->in_strafe_state & 1) || (lookstrafe->value && mlooking)) + cmd->sidemove += m_side->value * (jx/100); + else + in_state->viewangles[YAW] -= m_yaw->value * (jx/100); + + if ((mlooking || freelook->value) && !(*in_state->in_strafe_state & 1)) { + if (joystick_invert_y) + in_state->viewangles[PITCH] -= m_pitch->value * (jy/100); + else + in_state->viewangles[PITCH] += m_pitch->value * (jy/100); + cmd->forwardmove -= m_forward->value * (jt/100); + } else + cmd->forwardmove -= m_forward->value * (jy/100); + } +#endif } static void IN_DeactivateMouse( void ) diff --git a/src/rw_sdl.c b/src/rw_sdl.c index 813c5dd..646e56f 100644 --- a/src/rw_sdl.c +++ b/src/rw_sdl.c @@ -159,16 +159,20 @@ void RW_IN_Init(in_state_t *in_state_p) mouse_avail = true; } -void RW_IN_Shutdown(void) -{ - if (mouse_avail) { - mouse_avail = false; +void RW_IN_Shutdown(void) { + if (mouse_avail) { + mouse_avail = false; - ri.Cmd_RemoveCommand ("+mlook"); - ri.Cmd_RemoveCommand ("-mlook"); + ri.Cmd_RemoveCommand ("+mlook"); + ri.Cmd_RemoveCommand ("-mlook"); - ri.Cmd_RemoveCommand ("force_centerview"); - } + ri.Cmd_RemoveCommand ("force_centerview"); + } + +#ifdef HAVE_JOYSTICK + if (joy) + SDL_JoystickClose(joy); +#endif } /* @@ -282,7 +286,7 @@ void RW_IN_Move (usercmd_t *cmd) in_state->viewangles[PITCH] += m_pitch->value * (jy/100); cmd->forwardmove -= m_forward->value * (jt/100); } else { - cmd_forwardmove -= m_forward->value * (jy/100); + cmd->forwardmove -= m_forward->value * (jy/100); } jt = jx = jy = 0; } @@ -530,43 +534,46 @@ void GetEvent(SDL_Event *event) } -void InitJoystick() { - int num_joysticks, i; +void init_joystick() { +#ifdef HAVE_JOYSTICK + int num_joysticks, i; + joy = NULL; - if (!(SDL_INIT_JOYSTICK&SDL_WasInit(SDL_INIT_JOYSTICK))) { - ri.Con_Printf(PRINT_ALL, "SDL Joystick not initialized, trying to init...\n"); - SDL_Init(SDL_INIT_JOYSTICK); - } - if (in_joystick) { - ri.Con_Printf(PRINT_ALL, "Trying to start-up joystick...\n"); - if ((num_joysticks=SDL_NumJoysticks())) { - for(i=0;i #include #include @@ -53,6 +57,13 @@ #include #include +#ifdef HAVE_JOYSTICK +# include +# include +# include +# include +#endif + #include "r_local.h" #include "keys.h" #include "rw.h" @@ -266,6 +277,13 @@ static cvar_t *in_dgamouse; static cvar_t *vid_xpos; // X coordinate of window position static cvar_t *vid_ypos; // Y coordinate of window position +#ifdef HAVE_JOYSTICK +static cvar_t * in_joystick; +static qboolean joystick_avail = false; +static int joy_fd, jx, jy, jt; +static cvar_t * joystick_invert_y; +#endif + static qboolean mlooking; // state struct passed in Init @@ -297,14 +315,56 @@ static void RW_IN_MLookUp (void) in_state->IN_CenterView_fp (); } -void RW_IN_Init(in_state_t *in_state_p) -{ +#ifdef HAVE_JOYSTICK +void init_joystick() { + int i, err; + glob_t pglob; + struct js_event e; + + joystick_avail = false; + err = glob("/dev/js*", 0, NULL, &pglob); + + if (err) { + switch(err) { + case GLOB_NOSPACE: + ri.Con_Printf(PRINT_ALL, "Error, out of memory while looking for joysticks\n"); + break; + case GLOB_NOMATCH: + ri.Con_Printf(PRINT_ALL, "No joysticks found\n"); + break; + default: + ri.Con_Printf(PRINT_ALL, "Error %d while looking for joysticks\n", err); + } + return; + } + + for (i = 0; i < pglob.gl_pathc; i++) { + ri.Con_Printf(PRINT_ALL, "Trying joystick dev %s\n", pglob.gl_pathv[i]); + if (joy_fd == -1) { + ri.Con_Printf(PRINT_ALL, "Error opening joystick dev %s\n", pglob.gl_pathv[i]); + } else { + while (read(joy_fd, &e, sizeof(struct js_event)) != -1 && (e.type & JS_EVENT_INIT)) + ri.Con_Printf(PRINT_ALL, "Read init event\n"); + ri.Con_Printf(PRINT_ALL, "Using joystick dev %s\n", pglob.gl_pathv[i]); + joystick_avail = true; + return; + } + } + globfree(&pglob); +} +#endif + +void RW_IN_Init(in_state_t *in_state_p){ in_state = in_state_p; // mouse variables m_filter = ri.Cvar_Get ("m_filter", "0", 0); - in_mouse = ri.Cvar_Get ("in_mouse", "0", CVAR_ARCHIVE); - in_dgamouse = ri.Cvar_Get ("in_dgamouse", "1", CVAR_ARCHIVE); + in_mouse = ri.Cvar_Get ("in_mouse", "0", CVAR_ARCHIVE); + in_dgamouse = ri.Cvar_Get ("in_dgamouse", "1", CVAR_ARCHIVE); +#ifdef HAVE_JOYSTICK + in_joystick = ri.Cvar_Get("in_joystick", "1", CVAR_ARCHIVE); + joystick_invert_y = ri.Cvar_Get("joystick_invert_y", "1", CVAR_ARCHIVE); +#endif freelook = ri.Cvar_Get( "freelook", "0", 0 ); lookstrafe = ri.Cvar_Get ("lookstrafe", "0", 0); sensitivity = ri.Cvar_Get ("sensitivity", "3", 0); @@ -319,6 +379,12 @@ void RW_IN_Init(in_state_t *in_state_p) ri.Cmd_AddCommand ("force_centerview", Force_CenterView_f); mouse_avail = true; + +#ifdef HAVE_JOYSTICK + if (in_joystick) { + init_joystick(); + } +#endif } /* @@ -326,29 +392,60 @@ void RW_IN_Init(in_state_t *in_state_p) IN_Commands =========== */ -void RW_IN_Commands (void) -{ - int i; - - if (!mouse_avail) - return; - - for (i=0 ; i<5 ; i++) { - if ( (mouse_buttonstate & (1<Key_Event_fp (K_MOUSE1 + i, true); - if ( !(mouse_buttonstate & (1<Key_Event_fp (K_MOUSE1 + i, false); +void RW_IN_Commands(void) { + int i; +#ifdef HAVE_JOYSTICK + struct js_event e; + int key_index; +#endif + + if (mouse_avail) { + for (i = 0; i < 3; i++) { + if ((mouse_buttonstate & (1<Key_Event_fp (K_MOUSE1 + i, true); + if (!(mouse_buttonstate & (1<Key_Event_fp (K_MOUSE1 + i, false); } - if ( (mouse_buttonstate & (1<<3)) && !(mouse_oldbuttonstate & (1<<3)) ) - in_state->Key_Event_fp (K_MWHEELUP, true); - if ( !(mouse_buttonstate & (1<<3)) && (mouse_oldbuttonstate & (1<<3)) ) + if ((mouse_buttonstate & (1<<3)) && !(mouse_oldbuttonstate & (1<<3))) + in_state->Key_Event_fp (K_MWHEELUP, true); + if (!(mouse_buttonstate & (1<<3)) && (mouse_oldbuttonstate & (1<<3))) in_state->Key_Event_fp (K_MWHEELUP, false); - if ( (mouse_buttonstate & (1<<4)) && !(mouse_oldbuttonstate & (1<<4)) ) - in_state->Key_Event_fp (K_MWHEELDOWN, true); - if ( !(mouse_buttonstate & (1<<4)) && (mouse_oldbuttonstate & (1<<4)) ) - in_state->Key_Event_fp (K_MWHEELDOWN, false); + + if ((mouse_buttonstate & (1<<4)) && !(mouse_oldbuttonstate & (1<<4))) + in_state->Key_Event_fp (K_MWHEELDOWN, true); + if (!(mouse_buttonstate & (1<<4)) && (mouse_oldbuttonstate & (1<<4))) + in_state->Key_Event_fp (K_MWHEELDOWN, false); mouse_oldbuttonstate = mouse_buttonstate; + } +#ifdef HAVE_JOYSTICK + if (joystick_avail) { + while (read(joy_fd, &e, sizeof(struct js_event)) != -1) { + if (e.type & JS_EVENT_BUTTON) { + key_index = (e.number < 4) ? K_JOY1 : K_AUX1; + if (e.value) { + in_state->Key_Event_fp(key_index + e.number, true); + } else { + in_state->Key_Event_fp(key_index + e.number, false); + } + } else if (e.type & JS_EVENT_AXIS) { + switch (e.number) { + case 0: + jx = e.value; + break; + case 1: + jy = e.value; + break; + case 3: + jt = e.value; + break; + default: + break; + } + } + } + } +#endif } /* @@ -356,15 +453,11 @@ void RW_IN_Commands (void) IN_Move =========== */ -void RW_IN_Move (usercmd_t *cmd) -{ - if (!mouse_avail) - return; - - if (m_filter->value) - { - mx = (mx + old_mouse_x) * 0.5; - my = (my + old_mouse_y) * 0.5; +void RW_IN_Move(usercmd_t *cmd) { + if (mouse_avail) { + if (m_filter->value) { + mx = (mx + old_mouse_x) * 0.5; + my = (my + old_mouse_y) * 0.5; } old_mouse_x = mx; @@ -373,23 +466,37 @@ void RW_IN_Move (usercmd_t *cmd) mx *= sensitivity->value; my *= sensitivity->value; -// add mouse X/Y movement to cmd - if ( (*in_state->in_strafe_state & 1) || - (lookstrafe->value && mlooking )) - cmd->sidemove += m_side->value * mx; + /* add mouse X/Y movement to cmd */ + if ((*in_state->in_strafe_state & 1) || (lookstrafe->value && mlooking )) + cmd->sidemove += m_side->value * mx; else - in_state->viewangles[YAW] -= m_yaw->value * mx; + in_state->viewangles[YAW] -= m_yaw->value * mx; - if ( (mlooking || freelook->value) && - !(*in_state->in_strafe_state & 1)) - { - in_state->viewangles[PITCH] += m_pitch->value * my; - } - else - { - cmd->forwardmove -= m_forward->value * my; + if ((mlooking || freelook->value) && !(*in_state->in_strafe_state & 1)) { + in_state->viewangles[PITCH] += m_pitch->value * my; + } else { + cmd->forwardmove -= m_forward->value * my; } mx = my = 0; + } +#ifdef HAVE_JOYSTICK + if (joystick_avail) { + /* add joy X/Y movement to cmd */ + if ((*in_state->in_strafe_state & 1) || (lookstrafe->value && mlooking)) + cmd->sidemove += m_side->value * (jx/100); + else + in_state->viewangles[YAW] -= m_yaw->value * (jx/100); + + if ((mlooking || freelook->value) && !(*in_state->in_strafe_state & 1)) { + if (joystick_invert_y) + in_state->viewangles[PITCH] -= m_pitch->value * (jy/100); + else + in_state->viewangles[PITCH] += m_pitch->value * (jy/100); + cmd->forwardmove -= m_forward->value * (jt/100); + } else + cmd->forwardmove -= m_forward->value * (jy/100); + } +#endif } // ======================================================================== @@ -513,17 +620,21 @@ void RW_IN_Activate(qboolean active) IN_DeactivateMouse(); } -void RW_IN_Shutdown(void) -{ - if (mouse_avail) { - RW_IN_Activate (false); +void RW_IN_Shutdown(void) { + if (mouse_avail) { + RW_IN_Activate (false); - mouse_avail = false; + mouse_avail = false; - ri.Cmd_RemoveCommand ("+mlook"); - ri.Cmd_RemoveCommand ("-mlook"); - ri.Cmd_RemoveCommand ("force_centerview"); - } + ri.Cmd_RemoveCommand ("+mlook"); + ri.Cmd_RemoveCommand ("-mlook"); + ri.Cmd_RemoveCommand ("force_centerview"); + } +#ifdef HAVE_JOYSTICK + if (joystick_avail) + if (close(joy_fd)) + ri.Con_Printf(PRINT_ALL, "Error closing joystick device\n"); +#endif } /*****************************************************************************/