diff options
Diffstat (limited to 'src/unix/linux_joystick.c')
-rw-r--r-- | src/unix/linux_joystick.c | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/src/unix/linux_joystick.c b/src/unix/linux_joystick.c new file mode 100644 index 0000000..a932f0b --- /dev/null +++ b/src/unix/linux_joystick.c @@ -0,0 +1,212 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2006 Tim Angus + +This file is part of Tremulous. + +Tremulous 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. + +Tremulous 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 Tremulous; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +/* +** linux_joystick.c +** +** This file contains ALL Linux specific stuff having to do with the +** Joystick input. When a port is being made the following functions +** must be implemented by the port: +** +** Authors: mkv, bk +** +*/ + +#if !USE_SDL_VIDEO + +#include <linux/joystick.h> +#include <sys/types.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <unistd.h> // bk001204 + + +#include "../client/client.h" +#include "linux_local.h" + +/* We translate axes movement into keypresses. */ +int joy_keys[16] = { + K_LEFTARROW, K_RIGHTARROW, + K_UPARROW, K_DOWNARROW, + K_JOY16, K_JOY17, + K_JOY18, K_JOY19, + K_JOY20, K_JOY21, + K_JOY22, K_JOY23, + + K_JOY24, K_JOY25, + K_JOY26, K_JOY27 +}; + +/* Our file descriptor for the joystick device. */ +static int joy_fd = -1; + + +// bk001130 - from linux_glimp.c +extern cvar_t * in_joystick; +extern cvar_t * in_joystickDebug; +extern cvar_t * joy_threshold; + + +/**********************************************/ +/* Joystick routines. */ +/**********************************************/ +// bk001130 - from cvs1.17 (mkv), removed from linux_glimp.c +void IN_StartupJoystick( void ) +{ + int i = 0; + + joy_fd = -1; + + if( !in_joystick->integer ) { + Com_Printf( "Joystick is not active.\n" ); + return; + } + + for( i = 0; i < 4; i++ ) { + char filename[PATH_MAX]; + + snprintf( filename, PATH_MAX, "/dev/js%d", i ); + + joy_fd = open( filename, O_RDONLY | O_NONBLOCK ); + + if( joy_fd != -1 ) { + struct js_event event; + char axes = 0; + char buttons = 0; + char name[128]; + int n = -1; + + Com_Printf( "Joystick %s found\n", filename ); + + /* Get rid of initialization messages. */ + do { + n = read( joy_fd, &event, sizeof( event ) ); + + if( n == -1 ) { + break; + } + + } while( ( event.type & JS_EVENT_INIT ) ); + + /* Get joystick statistics. */ + ioctl( joy_fd, JSIOCGAXES, &axes ); + ioctl( joy_fd, JSIOCGBUTTONS, &buttons ); + + if( ioctl( joy_fd, JSIOCGNAME( sizeof( name ) ), name ) < 0 ) { + strncpy( name, "Unknown", sizeof( name ) ); + } + + Com_Printf( "Name: %s\n", name ); + Com_Printf( "Axes: %d\n", axes ); + Com_Printf( "Buttons: %d\n", buttons ); + + /* Our work here is done. */ + return; + } + + } + + /* No soup for you. */ + if( joy_fd == -1 ) { + Com_Printf( "No joystick found.\n" ); + return; + } + +} + +void IN_JoyMove( void ) +{ + /* Store instantaneous joystick state. Hack to get around + * event model used in Linux joystick driver. + */ + static int axes_state[16]; + /* Old bits for Quake-style input compares. */ + static unsigned int old_axes = 0; + /* Our current goodies. */ + unsigned int axes = 0; + int i = 0; + + if( joy_fd == -1 ) { + return; + } + + /* Empty the queue, dispatching button presses immediately + * and updating the instantaneous state for the axes. + */ + do { + int n = -1; + struct js_event event; + + n = read( joy_fd, &event, sizeof( event ) ); + + if( n == -1 ) { + /* No error, we're non-blocking. */ + break; + } + + if( event.type & JS_EVENT_BUTTON ) { + Sys_QueEvent( 0, SE_KEY, K_JOY1 + event.number, event.value, 0, NULL ); + } else if( event.type & JS_EVENT_AXIS ) { + + if( event.number >= 16 ) { + continue; + } + + axes_state[event.number] = event.value; + } else { + Com_Printf( "Unknown joystick event type\n" ); + } + + } while( 1 ); + + + /* Translate our instantaneous state to bits. */ + for( i = 0; i < 16; i++ ) { + float f = ( (float) axes_state[i] ) / 32767.0f; + + if( f < -joy_threshold->value ) { + axes |= ( 1 << ( i * 2 ) ); + } else if( f > joy_threshold->value ) { + axes |= ( 1 << ( ( i * 2 ) + 1 ) ); + } + + } + + /* Time to update axes state based on old vs. new. */ + for( i = 0; i < 16; i++ ) { + + if( ( axes & ( 1 << i ) ) && !( old_axes & ( 1 << i ) ) ) { + Sys_QueEvent( 0, SE_KEY, joy_keys[i], qtrue, 0, NULL ); + } + + if( !( axes & ( 1 << i ) ) && ( old_axes & ( 1 << i ) ) ) { + Sys_QueEvent( 0, SE_KEY, joy_keys[i], qfalse, 0, NULL ); + } + } + + /* Save for future generations. */ + old_axes = axes; +} + +#endif // !USE_SDL_VIDEO + + |