/* * Read the corrected joystick data */ static void fghJoystickRead( SFG_Joystick* joy, int* buttons, float* axes ) { float raw_axes[ _JS_MAX_AXES ]; int i; if( joy->error ) { if( buttons ) *buttons = 0; if( axes ) for ( i=0; i<joy->num_axes ; i++ ) axes[ i ] = 0.0f ; } fghJoystickRawRead( joy, buttons, raw_axes ); if( axes ) for( i=0 ; i<joy->num_axes ; i++ ) axes[ i ] = fghJoystickFudgeAxis( joy, raw_axes[ i ], i ); }
/* * Happy happy happy joy joy joy (happy new year toudi :D) */ static void fghJoystickOpen( SFG_Joystick* joy ) { #ifdef WIN32 JOYCAPS jsCaps; int i; joy->js.dwFlags = JOY_RETURNALL; joy->js.dwSize = sizeof( joy->js ); memset( &jsCaps, 0, sizeof( jsCaps ) ); joy->error = ( joyGetDevCaps( joy->js_id, &jsCaps, sizeof( jsCaps ) ) != JOYERR_NOERROR ); joy->num_axes = ( jsCaps.wNumAxes < _JS_MAX_AXES ) ? jsCaps.wNumAxes : _JS_MAX_AXES; /* * WARNING - Fall through case clauses!! */ switch( joy->num_axes ) { case 6: joy->min[ 5 ] = (float) jsCaps.wVmin; joy->max[ 5 ] = (float) jsCaps.wVmax; case 5: joy->min[ 4 ] = (float) jsCaps.wUmin; joy->max[ 4 ] = (float) jsCaps.wUmax; case 4: joy->min[ 3 ] = (float) jsCaps.wRmin; joy->max[ 3 ] = (float) jsCaps.wRmax; case 3: joy->min[ 2 ] = (float) jsCaps.wZmin; joy->max[ 2 ] = (float) jsCaps.wZmax; case 2: joy->min[ 1 ] = (float) jsCaps.wYmin; joy->max[ 1 ] = (float) jsCaps.wYmax; case 1: joy->min[ 0 ] = (float) jsCaps.wXmin; joy->max[ 0 ] = (float) jsCaps.wXmax; break; /* * I guess we have no axes at all */ default: joy->error = GL_TRUE; break; } /* * Guess all the rest judging on the axes extremals */ for( i=0 ; i<joy->num_axes ; i++ ) { joy->center [ i ] = (joy->max[i] + joy->min[i]) * 0.5f; joy->dead_band[ i ] = 0.0f; joy->saturate [ i ] = 1.0f; } #else # ifdef __FreeBSD__ int buttons[ _JS_MAX_AXES ]; float axes[ _JS_MAX_AXES ]; int noargs, in_no_axes; char joyfname[ 1024 ]; FILE* joyfile; # else # ifndef JS_NEW int counter; # endif # endif int i; /* * Default for older Linux systems. */ joy->num_axes = 2; joy->num_buttons = 32; # ifdef JS_NEW for( i=0 ; i<_JS_MAX_AXES ; i++ ) joy->tmp_axes[ i ] = 0.0f ; joy->tmp_buttons = 0 ; # endif joy->fd = open( joy->fname, O_RDONLY ); joy->error = (joy->fd < 0); if( joy->error ) return; /* * XXX All BSDs should share this? */ # ifdef __FreeBSD__ fghJoystickRawRead(joy, buttons, axes ); joy->error = axes[ 0 ] < -1000000000.0f; if( joy->error ) return; sprintf( joyfname, "%s/.joy%drc", getenv( "HOME" ), joy->id ); joyfile = fopen( joyfname, "r" ); joy->error =( joyfile == NULL ); if( joy->error ) return; noargs = fscanf( joyfile, "%d%f%f%f%f%f%f", &in_no_axes, &joy->min[ 0 ], &joy->center[ 0 ], &joy->max[ 0 ], &joy->min[ 1 ], &joy->center[ 1 ], &joy->max[ 1 ] ); joy->error =( noargs != 7 ) || ( in_no_axes != _JS_MAX_AXES ); fclose( joyfile ); if( joy->error ) return; for( i = 0; i < _JS_MAX_AXES; i++ ) { joy->dead_band[ i ] = 0.0f; joy->saturate [ i ] = 1.0f; } # else /* * Set the correct number of axes for the linux driver */ # ifdef JS_NEW ioctl( joy->fd, JSIOCGAXES , &joy->num_axes ); ioctl( joy->fd, JSIOCGBUTTONS, &joy->num_buttons ); fcntl( joy->fd, F_SETFL, O_NONBLOCK ); # endif /* * The Linux driver seems to return 512 for all axes * when no stick is present - but there is a chance * that could happen by accident - so it's gotta happen * on both axes for at least 100 attempts. * * PWO: shouldn't be that done somehow wiser on the kernel level? */ # ifndef JS_NEW counter = 0; do { fghJoystickRawRead( joy, NULL, joy->center ); counter++; } while( !joy->error && counter < 100 && joy->center[ 0 ] == 512.0f && joy->center[ 1 ] == 512.0f ); if( counter >= 100 ) joy->error = GL_TRUE; # endif for( i = 0; i < _JS_MAX_AXES; i++ ) { # ifdef JS_NEW joy->max [ i ] = 32767.0f; joy->center[ i ] = 0.0f; joy->min [ i ] = -32767.0f; # else joy->max[ i ] = joy->center[ i ] * 2.0f; joy->min[ i ] = 0.0f; # endif joy->dead_band[ i ] = 0.0f ; joy->saturate [ i ] = 1.0f ; } # endif #endif }
void fgPlatformJoystickOpen( SFG_Joystick* joy ) { #if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ ) int i = 0; char *cp; #endif #ifdef JS_NEW unsigned char u; int i=0; #else # if defined( __linux__ ) || TARGET_HOST_SOLARIS int i = 0; int counter = 0; # endif #endif #if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ ) for( i = 0; i < _JS_MAX_AXES; i++ ) joy->pJoystick.os->cache_axes[ i ] = 0.0f; joy->pJoystick.os->cache_buttons = 0; joy->pJoystick.os->fd = open( joy->pJoystick.os->fname, O_RDONLY | O_NONBLOCK); #ifdef HAVE_ERRNO_H if( joy->pJoystick.os->fd < 0 && errno == EACCES ) fgWarning ( "%s exists but is not readable by you", joy->pJoystick.os->fname ); #endif joy->error =( joy->pJoystick.os->fd < 0 ); if( joy->error ) return; joy->num_axes = 0; joy->num_buttons = 0; if( joy->pJoystick.os->is_analog ) { FILE *joyfile; char joyfname[ 1024 ]; int noargs, in_no_axes; float axes [ _JS_MAX_AXES ]; int buttons[ _JS_MAX_AXES ]; joy->num_axes = 2; joy->num_buttons = 32; fghJoystickRawRead( joy, buttons, axes ); joy->error = axes[ 0 ] < -1000000000.0f; if( joy->error ) return; snprintf( joyfname, sizeof(joyfname), "%s/.joy%drc", getenv( "HOME" ), joy->id ); joyfile = fopen( joyfname, "r" ); joy->error =( joyfile == NULL ); if( joy->error ) return; noargs = fscanf( joyfile, "%d%f%f%f%f%f%f", &in_no_axes, &joy->min[ 0 ], &joy->center[ 0 ], &joy->max[ 0 ], &joy->min[ 1 ], &joy->center[ 1 ], &joy->max[ 1 ] ); joy->error = noargs != 7 || in_no_axes != _JS_MAX_AXES; fclose( joyfile ); if( joy->error ) return; for( i = 0; i < _JS_MAX_AXES; i++ ) { joy->dead_band[ i ] = 0.0f; joy->saturate [ i ] = 1.0f; } return; /* End of analog code */ } # ifdef HAVE_USB_JS if( ! fghJoystickInitializeHID( joy->pJoystick.os, &joy->num_axes, &joy->num_buttons ) ) { close( joy->pJoystick.os->fd ); joy->error = GL_TRUE; return; } cp = strrchr( joy->pJoystick.os->fname, '/' ); if( cp ) { if( fghJoystickFindUSBdev( &cp[1], joy->name, sizeof( joy->name ) ) == 0 ) strcpy( joy->name, &cp[1] ); } if( joy->num_axes > _JS_MAX_AXES ) joy->num_axes = _JS_MAX_AXES; for( i = 0; i < _JS_MAX_AXES; i++ ) { /* We really should get this from the HID, but that data seems * to be quite unreliable for analog-to-USB converters. Punt for * now. */ if( joy->pJoystick.os->axes_usage[ i ] == HUG_HAT_SWITCH ) { joy->max [ i ] = 1.0f; joy->center[ i ] = 0.0f; joy->min [ i ] = -1.0f; } else { joy->max [ i ] = 255.0f; joy->center[ i ] = 127.0f; joy->min [ i ] = 0.0f; } joy->dead_band[ i ] = 0.0f; joy->saturate[ i ] = 1.0f; } # endif #endif #if defined( __linux__ ) || TARGET_HOST_SOLARIS /* Default for older Linux systems. */ joy->num_axes = 2; joy->num_buttons = 32; # ifdef JS_NEW for( i = 0; i < _JS_MAX_AXES; i++ ) joy->pJoystick.tmp_axes[ i ] = 0.0f; joy->pJoystick.tmp_buttons = 0; # endif joy->pJoystick.fd = open( joy->pJoystick.fname, O_RDONLY ); joy->error =( joy->pJoystick.fd < 0 ); if( joy->error ) return; /* Set the correct number of axes for the linux driver */ # ifdef JS_NEW /* Melchior Franz's fixes for big-endian Linuxes since writing * to the upper byte of an uninitialized word doesn't work. * 9 April 2003 */ ioctl( joy->pJoystick.fd, JSIOCGAXES, &u ); joy->num_axes = u; ioctl( joy->pJoystick.fd, JSIOCGBUTTONS, &u ); joy->num_buttons = u; ioctl( joy->pJoystick.fd, JSIOCGNAME( sizeof( joy->name ) ), joy->name ); fcntl( joy->pJoystick.fd, F_SETFL, O_NONBLOCK ); # endif /* * The Linux driver seems to return 512 for all axes * when no stick is present - but there is a chance * that could happen by accident - so it's gotta happen * on both axes for at least 100 attempts. * * PWO: shouldn't be that done somehow wiser on the kernel level? */ # ifndef JS_NEW counter = 0; do { fghJoystickRawRead( joy, NULL, joy->center ); counter++; } while( !joy->error && counter < 100 && joy->center[ 0 ] == 512.0f && joy->center[ 1 ] == 512.0f ); if ( counter >= 100 ) joy->error = GL_TRUE; # endif for( i = 0; i < _JS_MAX_AXES; i++ ) { # ifdef JS_NEW joy->max [ i ] = 32767.0f; joy->center[ i ] = 0.0f; joy->min [ i ] = -32767.0f; # else joy->max[ i ] = joy->center[ i ] * 2.0f; joy->min[ i ] = 0.0f; # endif joy->dead_band[ i ] = 0.0f; joy->saturate [ i ] = 1.0f; } #endif }