Joystick support generalized, autoconfiscated. Systems without joystick

support are built with joy_null.c. To create a joystick driver for a new
system, take a look at joystick.h and joy_null.c for the driver
interface. I'd like to see a Windows driver using this interface, it would
probably simplify in_win.c greatly.
This commit is contained in:
Jeff Teunissen 2000-09-26 14:16:09 +00:00
parent 68a4e60eaf
commit 50abe6080e
8 changed files with 413 additions and 215 deletions

View file

@ -659,6 +659,27 @@ AM_CONDITIONAL(SNDTYPE_SUN, test "$SNDTYPE" = "SUN")
AM_CONDITIONAL(SNDTYPE_WIN32, test "$SNDTYPE" = "WIN32")
AM_CONDITIONAL(SNDTYPE_NULL, test "$SNDTYPE" != "ALSA_0_5" -a "$SNDTYPE" != "ALSA_0_6" -a "$SNDTYPE" != "MME" -a "$SNDTYPE" != "OSS" -a "$SNDTYPE" != "SUN" -a "$SNDTYPE" != "WIN32")
dnl Tests for joystick support
AC_MSG_CHECKING(for joystick support)
if test -z "$JOYTYPE" -a "x$ac_cv_header_linux_joystick_h" = "xyes"; then
AC_EGREP_CPP([QF_maGiC_VALUE],[
#include <linux/joystick.h>
#ifdef JS_VERSION
QF_maGiC_VALUE
#endif
], JOYTYPE="Linux")
fi
if test "$JOYTYPE"; then
AC_MSG_RESULT([yes ($JOYTYPE)])
else
AC_MSG_RESULT([no, using null joystick driver])
fi
AC_SUBST(JOY_LIBS)
AC_SUBST(JOY_CFLAGS)
AM_CONDITIONAL(JOYTYPE_LINUX, test "$JOYTYPE" = "Linux")
AM_CONDITIONAL(JOYTYPE_NULL, test "$JOYTYPE" != "Linux")
dnl ==================================================================
dnl Checks for CD-ROM
dnl ==================================================================

View file

@ -1,25 +1,82 @@
/*
joystick.h
/*
* Copyright (C) 2000 David Jeffery
*/
QuakeForge joystick DPI (driver programming interface)
Copyright (C) 1996-1997 Jeff Teunissen <deek@dusknet.dhs.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "cvar.h"
#include "protocol.h"
extern cvar_t *joy_device; // Joystick device name
extern cvar_t *joy_enable; // Joystick enabling flag
extern cvar_t *joy_sensitivity; // Joystick sensitivity
extern qboolean joy_found; // Joystick present?
extern qboolean joy_active; // Joystick in use?
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
JOY_Command ()
void joystick_init(void);
void joystick_command(void);
void joystick_move(usercmd_t *cmd);
Use this function to process joystick button presses and generate key
events. It is called inside the IN_Commands () input function, once each
frame.
You should exit this function immediately if either joy_active or
joy_enable->int_val are zero.
*/
void JOY_Command (void);
/*
JOY_Move (usercmd_t *)
Use this function to process joystick movements to move the player around.
You should exit this function immediately if either joy_active or
joy_enable->int_val are zero.
*/
void JOY_Move (usercmd_t *);
/*
JOY_Init ()
Use this function to initialize the joystick Cvars, open your joystick
device, and get it ready for use. You MUST obey the value of the
joy_enable Cvar. Set joy_found if there is a device, and joy_active if
you have successfully enabled it.
*/
void JOY_Init (void);
/*
JOY_Shutdown ()
Use this function to close the joystick device and tell QuakeForge that it
is no longer available. It is called from IN_Init (), but may be called
elsewhere to disable the device.
*/
void JOY_Shutdown (void);

View file

@ -38,7 +38,7 @@ EXTRA_PROGRAMS= qf-server \
qf-client-mgl qf-client-ggi qf-client-sdl qf-client-svga qf-client-x11 \
qf-client-3dfx qf-client-glx qf-client-sgl qf-client-wgl
noinst_LIBRARIES= libqfsys_cl.a libqfsys_sv.a libqfsnd.a libqfcd.a
noinst_LIBRARIES= libqfsys_cl.a libqfsys_sv.a libqfsnd.a libqfcd.a libqfjs.a
if ASM_ARCH
math_ASM = math.S
@ -126,7 +126,19 @@ libqfcd_a_SOURCES = cd_null.c
endif
EXTRA_libqfcd_a_SOURCES = cd_audio.c cd_win.c cd_linux.c cd_null.c
CLIENT_LIBS= -L. -lqfsys_cl -lqfsnd -lqfcd $(SOUND_LIBS) $(NET_LIBS)
#
# ... Joystick
#
if JOYTYPE_LINUX
libqfjs_a_SOURCES = joy_linux.c
endif
if JOYTYPE_NULL
libqfjs_a_SOURCES = joy_null.c
endif
libqfjs_a_CFLAGS= $(JOY_CFLAGS)
EXTRA_libqfjs_a_SOURCES = joy_linux.c joy_null.c
CLIENT_LIBS= -L. -lqfsys_cl -lqfsnd -lqfcd -lqfjs $(SOUND_LIBS) $(NET_LIBS) $(JOY_LIBS)
if ASM_ARCH
client_ASM= snd_mixa.S cl_math.S sys_x86.S
@ -136,7 +148,7 @@ client_SOURCES= cl_cmd.c cl_cvar.c cl_demo.c cl_ents.c cl_input.c cl_main.c \
cl_misc.c cl_parse.c cl_pred.c cl_tent.c cl_cam.c teamplay.c \
r_view.c wad.c model_alias.c model_sprite.c \
console.c keys.c menu.c nonintel.c skin.c sbar.c \
cl_slist.c $(client_ASM) joystick.c
cl_slist.c $(client_ASM)
#
# Software-rendering clients
@ -164,7 +176,7 @@ ggi_SOURCES= vid_ggi.c
qf_client_ggi_SOURCES= $(common_SOURCES) $(client_SOURCES) $(soft_SOURCES) $(ggi_SOURCES)
qf_client_ggi_LDADD= $(GGI_LIBS) $(CLIENT_LIBS)
qf_client_ggi_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a
qf_client_ggi_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
#
# ... SciTech MGL
@ -173,7 +185,7 @@ mgl_SOURCES= vid_mgl.c in_win.c
qf_client_mgl_SOURCES= $(common_SOURCES) $(client_SOURCES) $(soft_SOURCES) $(mgl_SOURCES)
qf_client_mgl_LDADD= $(MGL_LIBS) $(CLIENT_LIBS)
qf_client_mgl_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a
qf_client_mgl_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
#
# ... Sam Lantinga's Simple DirectMedia Layer, version 1.0 and higher
@ -182,7 +194,7 @@ sdl_SOURCES= vid_sdl.c
qf_client_sdl_SOURCES= $(common_SOURCES) $(client_SOURCES) $(soft_SOURCES) $(sdl_SOURCES)
qf_client_sdl_LDADD= $(SDL_LIBS) $(CLIENT_LIBS)
qf_client_sdl_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a
qf_client_sdl_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
#
# ... Linux SVGAlib
@ -191,7 +203,7 @@ svga_SOURCES= d_copy.S vid_svgalib.c in_svgalib.c
qf_client_svga_SOURCES= $(common_SOURCES) $(client_SOURCES) $(soft_SOURCES) $(svga_SOURCES)
qf_client_svga_LDADD= $(SVGA_LIBS) $(CLIENT_LIBS)
qf_client_svga_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a
qf_client_svga_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
#
# ... X11
@ -200,7 +212,7 @@ x11_SOURCES= vid_x11.c in_x11.c context_x11.c dga_check.c
qf_client_x11_SOURCES= $(common_SOURCES) $(client_SOURCES) $(soft_SOURCES) $(x11_SOURCES)
qf_client_x11_LDADD= $(X_PRE_LIBS) $(VIDMODE_LIBS) $(DGA_LIBS) $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB) $(CLIENT_LIBS)
qf_client_x11_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a
qf_client_x11_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
#
@ -220,7 +232,7 @@ tdfx_SOURCES= vid_3dfxsvga.c in_svgalib.c
qf_client_3dfx_SOURCES= $(common_SOURCES) $(client_SOURCES) $(ogl_SOURCES) $(tdfx_SOURCES)
qf_client_3dfx_LDADD= $(TDFXGL_LIBS) $(SVGA_LIBS) $(CLIENT_LIBS) $(DL_LIBS)
qf_client_3dfx_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a
qf_client_3dfx_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
#
# ... OpenGL in X Window
@ -229,7 +241,7 @@ glx_SOURCES= vid_glx.c in_x11.c context_x11.c dga_check.c
qf_client_glx_SOURCES= $(common_SOURCES) $(client_SOURCES) $(ogl_SOURCES) $(glx_SOURCES)
qf_client_glx_LDADD= $(GLX_LIBS) $(X_PRE_LIBS) $(VIDMODE_LIBS) $(DGA_LIBS) $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(CLIENT_LIBS) $(DL_LIBS)
qf_client_glx_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a
qf_client_glx_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
#
# ... Sam Lantinga's Simple DirectMedia Layer, version 1.1 and higher, in GL mode
@ -238,7 +250,7 @@ sgl_SOURCES= vid_sgl.c
qf_client_sgl_SOURCES= $(common_SOURCES) $(client_SOURCES) $(ogl_SOURCES) $(sgl_SOURCES)
qf_client_sgl_LDADD= $(SDL_LIBS) $(GLX_LIBS) $(CLIENT_LIBS) $(DL_LIBS)
qf_client_sgl_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a
qf_client_sgl_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
#
# SGI/Microsoft WGL (Windows OpenGL)
@ -247,7 +259,7 @@ wgl_SOURCES= vid_wgl.c
qf_client_wgl_SOURCES= $(common_SOURCES) $(client_SOURCES) $(ogl_SOURCES) $(wgl_SOURCES)
qf_client_wgl_LDADD= $(CLIENT_LIBS)
qf_client_wgl_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a
qf_client_wgl_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
#
# Stuff that doesn't get linked into an executable NEEDS to be mentioned here,

View file

@ -113,7 +113,7 @@ int IN_Init(void)
if (UseMouse)
IN_init_mouse();
joystick_init();
JOY_Init();
in_svgalib_inited = 1;
return 1;
@ -280,6 +280,7 @@ static void IN_init_mouse()
void IN_Shutdown(void)
{
JOY_Shutdown ();
Con_Printf("IN_Shutdown\n");
if (UseMouse) mouse_close();
@ -300,8 +301,8 @@ void IN_SendKeyEvents(void)
void IN_Commands(void)
{
if (UseMouse)
{
JOY_Command ();
if (UseMouse) {
/* Poll mouse values */
while (mouse_update())
;
@ -335,6 +336,7 @@ void IN_Commands(void)
void IN_Move(usercmd_t *cmd)
{
JOY_Move (cmd);
if (!UseMouse) return;
/* Poll mouse values */

View file

@ -299,8 +299,9 @@ event_motion(XEvent *event)
void
IN_Commands(void)
IN_Commands (void)
{
JOY_Command ();
if (old__windowed_mouse != _windowed_mouse->value) {
old__windowed_mouse = _windowed_mouse->value;
@ -319,7 +320,7 @@ IN_Commands(void)
void
IN_SendKeyEvents(void)
IN_SendKeyEvents (void)
{
/* Get events from X server. */
x11_process_events();
@ -327,8 +328,10 @@ IN_SendKeyEvents(void)
void
IN_Move(usercmd_t *cmd)
IN_Move (usercmd_t *cmd)
{
JOY_Move (cmd);
if (!mouse_avail)
return;
@ -352,10 +355,7 @@ IN_Move(usercmd_t *cmd)
if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) {
cl.viewangles[PITCH] += m_pitch->value * mouse_y;
if (cl.viewangles[PITCH] > 80)
cl.viewangles[PITCH] = 80;
if (cl.viewangles[PITCH] < -70)
cl.viewangles[PITCH] = -70;
cl.viewangles[PITCH] = bound (-70, cl.viewangles[PITCH], 80);
} else {
if ((in_strafe.state & 1) && noclip_anglehack)
cmd->upmove -= m_forward->value * mouse_y;
@ -387,8 +387,9 @@ static void IN_ExtraOptionCmd(int option_cursor)
Called at shutdown
*/
void
IN_Shutdown(void)
IN_Shutdown (void)
{
JOY_Shutdown ();
Con_Printf("IN_Shutdown\n");
mouse_avail = 0;
if (x_disp) {
@ -404,7 +405,7 @@ IN_Shutdown(void)
extern int scr_width, scr_height;
int
IN_Init(void)
IN_Init (void)
{
// open the display
if (!x_disp)
@ -412,7 +413,7 @@ IN_Init(void)
if (!x_win)
Sys_Error("IN: No window!!\n");
x11_open_display(); // call to increment the reference counter
x11_open_display (); // call to increment the reference counter
{
int attribmask = CWEventMask;
XWindowAttributes attribs_1;
@ -425,7 +426,7 @@ IN_Init(void)
XChangeWindowAttributes(x_disp, x_win, attribmask, &attribs_2);
}
joystick_init();
JOY_Init ();
_windowed_mouse = Cvar_Get ("_windowed_mouse","0",CVAR_ARCHIVE,"None");
m_filter = Cvar_Get ("m_filter","0",CVAR_ARCHIVE,"None");
@ -441,8 +442,7 @@ IN_Init(void)
in_nodga_grab = Cvar_Get ("in_nodga_grab", "0", CVAR_ROM,
"grab keyboard and mouse input when using -nodga");
if (COM_CheckParm("-nodga"))
{
if (COM_CheckParm ("-nodga")) {
if (in_nodga_grab->value) {
XGrabKeyboard (x_disp, x_win, True, GrabModeAsync,
GrabModeAsync, CurrentTime);

202
source/joy_linux.c Normal file
View file

@ -0,0 +1,202 @@
/*
joy_linux.c
Joystick driver for Linux
Copyright (C) 2000 David Jeffery
Copyright (C) 2000 Jeff Teunissen <deek@dusknet.dhs.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <linux/joystick.h>
#include <fcntl.h>
#include <unistd.h>
#include "console.h"
#include "client.h"
#include "cvar.h"
#include "keys.h"
#include "protocol.h"
#define JOY_MAX_AXES 6
#define JOY_MAX_BUTTONS 10
cvar_t *joy_device; // Joystick device name
cvar_t *joy_enable; // Joystick enabling flag
cvar_t *joy_sensitivity; // Joystick sensitivity
qboolean joy_found = false;
qboolean joy_active = false;
// Variables and structures for this driver
int joy_handle;
typedef struct {
char *name;
char *string;
} ocvar_t;
struct joy_axis {
cvar_t *axis;
ocvar_t var;
int current;
};
struct joy_button {
int old;
int current;
};
struct joy_axis joy_axes[JOY_MAX_AXES] = {
{NULL, {"joyaxis1", "1"}, 0},
{NULL, {"joyaxis2", "2"}, 0},
{NULL, {"joyaxis3", "3"}, 0},
{NULL, {"joyaxis4", "0"}, 0},
{NULL, {"joyaxis5", "0"}, 0},
{NULL, {"joyaxis6", "0"}, 0}
};
struct joy_button joy_buttons[JOY_MAX_BUTTONS];
void
JOY_Command (void)
{
struct js_event event;
if (!joy_active || !joy_enable->int_val)
return;
while (read (joy_handle, &event, sizeof (struct js_event)) > -1) {
if (event.type & JS_EVENT_BUTTON) {
if(event.number >= JOY_MAX_BUTTONS)
continue;
joy_buttons[event.number].current = event.value;
if (joy_buttons[event.number].current > joy_buttons[event.number].old) {
Key_Event(K_AUX1 + event.number, true);
} else {
if (joy_buttons[event.number].current < joy_buttons[event.number].old) {
Key_Event(K_AUX1 + event.number, false);
}
}
joy_buttons[event.number].old = joy_buttons[event.number].current;
} else {
if (event.type & JS_EVENT_AXIS) {
if (event.number >= JOY_MAX_AXES)
continue;
joy_axes[event.number].current = event.value;
}
}
}
}
void
JOY_Move (usercmd_t *cmd)
{
int i;
if (!joy_active || !joy_enable->int_val)
return;
Cvar_SetValue (joy_sensitivity, bound (1, joy_sensitivity->value, 25));
for (i = 0; i < JOY_MAX_AXES; i++) {
switch (joy_axes[i].axis->int_val) {
case 1:
cl.viewangles[YAW] -= m_yaw->value * (float) (joy_axes[i].current / (201 - (joy_sensitivity->value * 4)));
break;
case 2:
cmd->forwardmove -= m_forward->value * (float) (joy_axes[i].current / (201 - (joy_sensitivity->value * 4)));
break;
case 3:
cmd->sidemove += m_side->value * (float) (joy_axes[i].current / (201 - (joy_sensitivity->value * 4)));
break;
case 4:
if (joy_axes[i].current) {
V_StopPitchDrift();
cl.viewangles[PITCH] -= m_pitch->value * (float) (joy_axes[i].current / (201 - (joy_sensitivity->value * 4)));
cl.viewangles[PITCH] = bound (-70, cl.viewangles[PITCH], 80);
}
break;
}
}
}
void
JOY_Init (void)
{
joy_device = Cvar_Get ("joy_device", "/dev/js0", CVAR_NONE|CVAR_ROM, "Joystick device");
joy_enable = Cvar_Get ("joy_enable", "1", CVAR_NONE|CVAR_ARCHIVE, "Joystick enable flag");
joy_sensitivity = Cvar_Get ("joy_sensitivity", "1", CVAR_NONE|CVAR_ARCHIVE, "Joystick sensitivity");
// Open joystick device
joy_handle = open (joy_device->string, O_RDONLY|O_NONBLOCK);
if (joy_handle < 0) {
Con_Printf ("JOY: Joystick not found.\n");
} else {
int i;
joy_found = true;
if (!joy_enable->int_val) {
Con_Printf ("JOY: Joystick found, but not enabled.\n");
i = close (joy_handle);
if (i) {
Con_Printf ("JOY: Failed to close joystick device!\n");
}
} else {
// Initialize joystick if found and enabled
for (i = 0; i < JOY_MAX_AXES; i++) {
joy_axes[i].axis = Cvar_Get (joy_axes[i].var.name,
joy_axes[i].var.string,
CVAR_ARCHIVE, "None");
}
for (i = 0; i < JOY_MAX_BUTTONS; i++) {
joy_buttons[i].old = 0;
joy_buttons[i].current = 0;
}
joy_active = true;
Con_Printf ("JOY: Joystick found and activated.\n");
}
}
}
void
JOY_Shutdown (void)
{
int i;
if (!joy_active)
return;
i = close (joy_handle);
if (i) {
Con_Printf ("JOY: Failed to close joystick device!\n");
} else {
Con_Printf ("JOY_Shutdown\n");
}
joy_active = false;
joy_found = false;
}

70
source/joy_null.c Normal file
View file

@ -0,0 +1,70 @@
/*
joy_null.c
Joystick device driver template
Copyright (C) 2000 Jeff Teunissen <deek@dusknet.dhs.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "cvar.h"
#include "protocol.h"
#include "qtypes.h"
// Joystick variables and structures
cvar_t *joy_device; // Joystick device name
cvar_t *joy_enable; // Joystick enabling flag
cvar_t *joy_sensitivity; // Joystick sensitivity
qboolean joy_found = false;
qboolean joy_active = false;
void
JOY_Command (void)
{
}
void
JOY_Move (usercmd_t *cmd)
{
}
void
JOY_Init (void)
{
joy_device = Cvar_Get ("joy_device", "none", CVAR_NONE|CVAR_ROM, "Joystick device");
joy_enable = Cvar_Get ("joy_enable", "1", CVAR_NONE|CVAR_ARCHIVE, "Joystick enable flag");
joy_sensitivity = Cvar_Get ("joy_sensitivity", "1", CVAR_NONE|CVAR_ARCHIVE, "Joystick sensitivity");
Con_DPrintf ("This system does not have joystick support.\n");
}
void
JOY_Shutdown (void)
{
joy_active = false;
joy_found = false;
}

View file

@ -1,166 +0,0 @@
/*
* Copyright (C) 2000 David Jeffery
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "protocol.h"
#ifdef HAVE_LINUX_JOYSTICK_H
#include <linux/joystick.h>
#include <fcntl.h>
#include <unistd.h>
#include "console.h"
#include "client.h"
#include "cvar.h"
#include "keys.h"
//joystick variables and structures
#define MAX_JOYAXIS 6
#define MAX_JOYBUTTON 10
#define JOYLOOK_MAX 200
#define JOYMOVE_MAX 200
int joydev;
typedef struct {
char *name;
char *string;
} ocvar_t;
struct joyaxis{
int current;
ocvar_t var;
cvar_t *axis;
};
struct joybutton{
int old;
int current;
};
struct joyaxis joyaxiscontrol[MAX_JOYAXIS] = {
{0,{"joyaxis1","1"}} ,
{0,{"joyaxis2","2"}} ,
{0,{"joyaxis3","3"}} ,
{0,{"joyaxis4","0"}} ,
{0,{"joyaxis5","0"}} ,
{0,{"joyaxis6","0"}}
};
struct joybutton joybuttoncontrol[MAX_JOYBUTTON];
int joyfound = 0;
void joystick_command(void)
{
struct js_event event;
if(!joyfound)
return;
while(read(joydev, &event, sizeof(struct js_event)) > -1){
if(event.type & JS_EVENT_BUTTON){
if(event.number >= MAX_JOYBUTTON)
continue;
joybuttoncontrol[event.number].current = event.value;
if(joybuttoncontrol[event.number].current >
joybuttoncontrol[event.number].old)
Key_Event(K_AUX1 + event.number, true);
else if(joybuttoncontrol[event.number].current <
joybuttoncontrol[event.number].old)
Key_Event(K_AUX1 + event.number, false);
joybuttoncontrol[event.number].old =
joybuttoncontrol[event.number].current;
}
else if(event.type & JS_EVENT_AXIS){
if(event.number >= MAX_JOYAXIS)
continue;
joyaxiscontrol[event.number].current = event.value;
}
}
}
void joystick_move(usercmd_t *cmd)
{
int i;
if(!joyfound)
return;
for(i = 0; i < MAX_JOYAXIS; i++) {
switch(joyaxiscontrol[i].axis->int_val){
case 1:
cl.viewangles[YAW] -= m_yaw->value * (float)joyaxiscontrol[i].current/JOYLOOK_MAX;
break;
case 2:
cmd->forwardmove -= m_forward->value * (float)joyaxiscontrol[i].current/JOYMOVE_MAX;
break;
case 3:
cmd->sidemove += m_side->value * (float)joyaxiscontrol[i].current/JOYMOVE_MAX;
break;
case 4:
if(joyaxiscontrol[i].current){
V_StopPitchDrift();
cl.viewangles[PITCH] -= m_pitch->value * (float)joyaxiscontrol[i].current/JOYLOOK_MAX;
if(cl.viewangles[PITCH] > 80)
cl.viewangles[PITCH] = 80;
else if(cl.viewangles[PITCH] < -70)
cl.viewangles[PITCH] = -70;
}
break;
}
}
}
void joystick_init(void)
{
/*initialize joystick if found */
if ((joydev = open("/dev/js0", O_RDONLY | O_NONBLOCK)) < 0) {
joyfound = 0;
Con_DPrintf("no joystick\n");
} else {
int i;
joyfound = 1;
for(i = 0; i < MAX_JOYAXIS; i++) {
joyaxiscontrol[i].axis = Cvar_Get(joyaxiscontrol[i].var.name,
joyaxiscontrol[i].var.string,
CVAR_ARCHIVE, "None");
}
for(i = 0; i < MAX_JOYBUTTON; i++) {
joybuttoncontrol[i].old = 0;
joybuttoncontrol[i].current = 0;
}
Con_DPrintf("joystick enabled\n");
}
}
#else
void joystick_init(void){
}
void joystick_command(void){
}
void joystick_move(usercmd_t *cmd){
}
#endif