linux_joystick.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. /*
  19. ** linux_joystick.c
  20. **
  21. ** This file contains ALL Linux specific stuff having to do with the
  22. ** Joystick input. When a port is being made the following functions
  23. ** must be implemented by the port:
  24. **
  25. ** Authors: mkv, bk
  26. **
  27. */
  28. #include <linux/joystick.h>
  29. #include <sys/types.h>
  30. #include <fcntl.h>
  31. #include <sys/ioctl.h>
  32. #include <unistd.h> // bk001204
  33. #include "../client/client.h"
  34. #include "linux_local.h"
  35. /* We translate axes movement into keypresses. */
  36. int joy_keys[16] = {
  37. K_LEFTARROW, K_RIGHTARROW,
  38. K_UPARROW, K_DOWNARROW,
  39. K_JOY16, K_JOY17,
  40. K_JOY18, K_JOY19,
  41. K_JOY20, K_JOY21,
  42. K_JOY22, K_JOY23,
  43. K_JOY24, K_JOY25,
  44. K_JOY26, K_JOY27
  45. };
  46. /* Our file descriptor for the joystick device. */
  47. static int joy_fd = -1;
  48. // bk001130 - from linux_glimp.c
  49. extern cvar_t * in_joystick;
  50. extern cvar_t * in_joystickDebug;
  51. extern cvar_t * joy_threshold;
  52. /**********************************************/
  53. /* Joystick routines. */
  54. /**********************************************/
  55. // bk001130 - from cvs1.17 (mkv), removed from linux_glimp.c
  56. void IN_StartupJoystick( void )
  57. {
  58. int i = 0;
  59. joy_fd = -1;
  60. if( !in_joystick->integer ) {
  61. Com_Printf( "Joystick is not active.\n" );
  62. return;
  63. }
  64. for( i = 0; i < 4; i++ ) {
  65. char filename[PATH_MAX];
  66. snprintf( filename, PATH_MAX, "/dev/js%d", i );
  67. joy_fd = open( filename, O_RDONLY | O_NONBLOCK );
  68. if( joy_fd != -1 ) {
  69. struct js_event event;
  70. char axes = 0;
  71. char buttons = 0;
  72. char name[128];
  73. int n = -1;
  74. Com_Printf( "Joystick %s found\n", filename );
  75. /* Get rid of initialization messages. */
  76. do {
  77. n = read( joy_fd, &event, sizeof( event ) );
  78. if( n == -1 ) {
  79. break;
  80. }
  81. } while( ( event.type & JS_EVENT_INIT ) );
  82. /* Get joystick statistics. */
  83. ioctl( joy_fd, JSIOCGAXES, &axes );
  84. ioctl( joy_fd, JSIOCGBUTTONS, &buttons );
  85. if( ioctl( joy_fd, JSIOCGNAME( sizeof( name ) ), name ) < 0 ) {
  86. strncpy( name, "Unknown", sizeof( name ) );
  87. }
  88. Com_Printf( "Name: %s\n", name );
  89. Com_Printf( "Axes: %d\n", axes );
  90. Com_Printf( "Buttons: %d\n", buttons );
  91. /* Our work here is done. */
  92. return;
  93. }
  94. }
  95. /* No soup for you. */
  96. if( joy_fd == -1 ) {
  97. Com_Printf( "No joystick found.\n" );
  98. return;
  99. }
  100. }
  101. void IN_JoyMove( void )
  102. {
  103. /* Store instantaneous joystick state. Hack to get around
  104. * event model used in Linux joystick driver.
  105. */
  106. static int axes_state[16];
  107. /* Old bits for Quake-style input compares. */
  108. static unsigned int old_axes = 0;
  109. /* Our current goodies. */
  110. unsigned int axes = 0;
  111. int i = 0;
  112. if( joy_fd == -1 ) {
  113. return;
  114. }
  115. /* Empty the queue, dispatching button presses immediately
  116. * and updating the instantaneous state for the axes.
  117. */
  118. do {
  119. int n = -1;
  120. struct js_event event;
  121. n = read( joy_fd, &event, sizeof( event ) );
  122. if( n == -1 ) {
  123. /* No error, we're non-blocking. */
  124. break;
  125. }
  126. if( event.type & JS_EVENT_BUTTON ) {
  127. Sys_QueEvent( 0, SE_KEY, K_JOY1 + event.number, event.value, 0, NULL );
  128. } else if( event.type & JS_EVENT_AXIS ) {
  129. if( event.number >= 16 ) {
  130. continue;
  131. }
  132. axes_state[event.number] = event.value;
  133. } else {
  134. Com_Printf( "Unknown joystick event type\n" );
  135. }
  136. } while( 1 );
  137. /* Translate our instantaneous state to bits. */
  138. for( i = 0; i < 16; i++ ) {
  139. float f = ( (float) axes_state[i] ) / 32767.0f;
  140. if( f < -joy_threshold->value ) {
  141. axes |= ( 1 << ( i * 2 ) );
  142. } else if( f > joy_threshold->value ) {
  143. axes |= ( 1 << ( ( i * 2 ) + 1 ) );
  144. }
  145. }
  146. /* Time to update axes state based on old vs. new. */
  147. for( i = 0; i < 16; i++ ) {
  148. if( ( axes & ( 1 << i ) ) && !( old_axes & ( 1 << i ) ) ) {
  149. Sys_QueEvent( 0, SE_KEY, joy_keys[i], qtrue, 0, NULL );
  150. }
  151. if( !( axes & ( 1 << i ) ) && ( old_axes & ( 1 << i ) ) ) {
  152. Sys_QueEvent( 0, SE_KEY, joy_keys[i], qfalse, 0, NULL );
  153. }
  154. }
  155. /* Save for future generations. */
  156. old_axes = axes;
  157. }