summaryrefslogtreecommitdiff
path: root/src/unix/linux_joystick.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/unix/linux_joystick.c')
-rw-r--r--src/unix/linux_joystick.c212
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
+
+