*/
/*
- * PWO: this is not exactly what Steve Baker has done for PLIB, as I had to convert
- * it from C++ to C. And I've also reformatted it a bit (that's my little
- * personal deviation :]) I don't really know if it is still portable...
+ * PWO: This is not exactly what Steve Baker has done for PLIB, as I had to
+ * convert it from C++ to C. And I've also reformatted it a bit (that's
+ * my little personal deviation :]) I don't really know if it is still
+ * portable...
* Steve: could you please add some comments to the code? :)
*
- * FreeBSD port - courtesy of Stephen Montgomery-Smith <stephen@math.missouri.edu>
+ * FreeBSD port by Stephen Montgomery-Smith <stephen@math.missouri.edu>
*/
+#if defined( __FreeBSD__ ) || defined( __NetBSD__ )
+#include <sys/param.h>
+#endif
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#define G_LOG_DOMAIN "freeglut-joystick"
-
#include "../include/GL/freeglut.h"
#include "freeglut_internal.h"
#else
# include <unistd.h>
# include <fcntl.h>
-# ifdef __FreeBSD__
+# if defined(__FreeBSD__) || defined(__NetBSD__)
+# if __FreeBSD_version >= 500000
+# include <sys/joystick.h>
+# else
# include <machine/joystick.h>
+# endif
# define JS_DATA_TYPE joystick
# define JS_RETURN (sizeof(struct JS_DATA_TYPE))
# elif defined(__linux__)
# ifndef JS_DATA_TYPE
/*
- * Not Windoze and no joystick driver...
+ * Not Windoze and no (known) joystick driver...
*
* Well - we'll put these values in and that should
* allow the code to at least compile. The JS open
typedef struct tagSFG_Joystick SFG_Joystick;
struct tagSFG_Joystick
{
+/*
+ * XXX All BSDs might share this?
+ */
#ifdef __FreeBSD__
int id;
#endif
/*
* Read the raw joystick data
*/
-static void fghJoystickRawRead ( SFG_Joystick* joy, int* buttons, float* axes )
+static void fghJoystickRawRead( SFG_Joystick* joy, int* buttons, float* axes )
{
#ifdef WIN32
MMRESULT status;
if( joy->error )
{
if( buttons )
- *buttons = 0 ;
+ *buttons = 0;
if( axes )
for( i=0; i<joy->num_axes; i++ )
if( status != JOYERR_NOERROR )
{
- joy->error = TRUE;
+ joy->error = GL_TRUE;
return;
}
*/
switch( joy->num_axes )
{
- case 6: axes[5] = (float) joy->js.dwVpos;
- case 5: axes[4] = (float) joy->js.dwUpos;
- case 4: axes[3] = (float) joy->js.dwRpos;
- case 3: axes[2] = (float) joy->js.dwZpos;
- case 2: axes[1] = (float) joy->js.dwYpos;
- case 1: axes[0] = (float) joy->js.dwXpos;
+ case 6: axes[5] = (float) joy->js.dwVpos;
+ case 5: axes[4] = (float) joy->js.dwUpos;
+ case 4: axes[3] = (float) joy->js.dwRpos;
+ case 3: axes[2] = (float) joy->js.dwZpos;
+ case 2: axes[1] = (float) joy->js.dwYpos;
+ case 1: axes[0] = (float) joy->js.dwXpos;
}
}
#else
{
status = read( joy->fd, &joy->js, sizeof(struct js_event) );
- if( status != sizeof(struct js_event) )
+ if( status != sizeof( struct js_event ) )
{
- if( errno == EAGAIN )
- {
- /*
- * Use the old values
- */
- if( buttons ) *buttons = joy->tmp_buttons;
- if( axes ) memcpy( axes, joy->tmp_axes, sizeof(float) * joy->num_axes );
+ if( errno == EAGAIN )
+ {
+ /*
+ * Use the old values
+ */
+ if( buttons )
+ *buttons = joy->tmp_buttons;
+ if( axes )
+ memcpy( axes, joy->tmp_axes,
+ sizeof( float ) * joy->num_axes );
return;
- }
+ }
- fgWarning( "%s", joy->fname );
- joy->error = TRUE;
- return;
+ fgWarning( "%s", joy->fname );
+ joy->error = GL_TRUE;
+ return;
}
switch( joy->js.type & ~JS_EVENT_INIT )
{
- case JS_EVENT_BUTTON:
- if ( joy->js.value == 0 ) /* clear the flag */
- joy->tmp_buttons &= ~(1 << joy->js.number);
- else
- joy->tmp_buttons |= (1 << joy->js.number);
- break;
-
- case JS_EVENT_AXIS:
- joy->tmp_axes[ joy->js.number ] = (float) joy->js.value;
-
- if( axes )
- memcpy( axes, joy->tmp_axes, sizeof(float) * joy->num_axes );
- break;
+ case JS_EVENT_BUTTON:
+ if( joy->js.value == 0 ) /* clear the flag */
+ joy->tmp_buttons &= ~( 1 << joy->js.number );
+ else
+ joy->tmp_buttons |= ( 1 << joy->js.number );
+ break;
+
+ case JS_EVENT_AXIS:
+ joy->tmp_axes[ joy->js.number ] = ( float )joy->js.value;
+
+ if( axes )
+ memcpy( axes, joy->tmp_axes, sizeof(float) * joy->num_axes );
+ break;
}
if( buttons )
- *buttons = joy->tmp_buttons;
+ *buttons = joy->tmp_buttons;
}
# else
if( status != JS_RETURN )
{
- g_warning( joy->fname );
- joy->error = TRUE;
+ fgWarning( "%s", joy->fname );
+ joy->error = GL_TRUE;
return;
}
if( buttons )
-# ifdef __FreeBSD__
- *buttons = (joy->js.b1 ? 1 : 0) | (joy->js.b2 ? 2 : 0);
+# if defined( __FreeBSD__ ) || defined( __NetBSD__ )
+ *buttons = ( joy->js.b1 ? 1 : 0 ) | ( joy->js.b2 ? 2 : 0 );
# else
*buttons = joy->js.buttons;
# endif
{
if( value < joy->center[ axis ] )
{
- float xx = (value - joy->center[ axis ]) / (joy->center[ axis ] - joy->min[ axis ]);
+ float xx = ( value - joy->center[ axis ] ) / ( joy->center[ axis ] -
+ joy->min[ axis ] );
if( xx < -joy->saturate[ axis ] )
- return( -1.0f );
+ return -1.0f;
if( xx > -joy->dead_band [ axis ] )
- return( 0.0f );
+ return 0.0f;
- xx = (xx + joy->dead_band[ axis ]) / (joy->saturate[ axis ] - joy->dead_band[ axis ]);
+ xx = ( xx + joy->dead_band[ axis ] ) / ( joy->saturate[ axis ] -
+ joy->dead_band[ axis ] );
- return( ( xx < -1.0f ) ? -1.0f : xx );
+ return ( xx < -1.0f ) ? -1.0f : xx;
}
else
{
- float xx = (value - joy->center [ axis ]) / (joy->max[ axis ] - joy->center[ axis ]);
+ float xx = ( value - joy->center [ axis ] ) / ( joy->max[ axis ] -
+ joy->center[ axis ] );
if( xx > joy->saturate[ axis ] )
- return 1.0f ;
+ return 1.0f;
if( xx < joy->dead_band[ axis ] )
- return 0.0f ;
+ return 0.0f;
- xx = (xx - joy->dead_band[ axis ]) / (joy->saturate[ axis ] - joy->dead_band[ axis ]);
+ xx = ( xx - joy->dead_band[ axis ] ) / ( joy->saturate[ axis ] -
+ joy->dead_band[ axis ] );
- return( ( xx > 1.0f ) ? 1.0f : xx );
+ return ( xx > 1.0f ) ? 1.0f : xx;
}
}
joy->js.dwFlags = JOY_RETURNALL;
joy->js.dwSize = sizeof( joy->js );
- memset( &jsCaps, 0, sizeof(jsCaps) );
+ 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;
+ 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;
+ 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 = TRUE; break;
+ default:
+ joy->error = GL_TRUE;
+ break;
}
/*
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 ;
+ return;
- sprintf( joyfname, "%s/.joy%drc", g_getenv( "HOME" ), joy->id );
+ sprintf( joyfname, "%s/.joy%drc", getenv( "HOME" ), joy->id );
joyfile = fopen( joyfname, "r" );
- joy->error = (joyfile == NULL);
+ joy->error =( joyfile == NULL );
if( joy->error )
return;
&joy->min[ 1 ], &joy->center[ 1 ], &joy->max[ 1 ]
);
- joy->error = (noargs != 7) || (in_no_axes != _JS_MAX_AXES);
+ joy->error =( noargs != 7 ) || ( in_no_axes != _JS_MAX_AXES );
fclose( joyfile );
if( joy->error )
- return;
+ return;
- for( i=0 ; i<_JS_MAX_AXES ; i++ )
+ for( i = 0; i < _JS_MAX_AXES; i++ )
{
joy->dead_band[ i ] = 0.0f;
joy->saturate [ i ] = 1.0f;
* 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 );
* PWO: shouldn't be that done somehow wiser on the kernel level?
*/
# ifndef JS_NEW
- counter = 0 ;
+ counter = 0;
do
{
fghJoystickRawRead( joy, NULL, joy->center );
counter++;
- } while( !joy->error && counter < 100 && joy->center[ 0 ] == 512.0f && joy->center[ 1 ] == 512.0f );
+ } while( !joy->error &&
+ counter < 100 &&
+ joy->center[ 0 ] == 512.0f &&
+ joy->center[ 1 ] == 512.0f );
if( counter >= 100 )
- joy->error = TRUE;
+ joy->error = GL_TRUE;
# endif
- for( i=0 ; i<_JS_MAX_AXES ; i++ )
+ for( i = 0; i < _JS_MAX_AXES; i++ )
{
# ifdef JS_NEW
joy->max [ i ] = 32767.0f;
*/
void fgJoystickInit( int ident )
{
- /*
- * Make sure we don't get reinitialized
- */
- if( fgJoystick != NULL )
+ if( fgJoystick )
fgError( "illegal attemp to initialize joystick device" );
- /*
- * Have the global joystick structure created
- */
- fgJoystick = calloc( sizeof(SFG_Joystick), 1 );
+ fgJoystick = ( SFG_Joystick * )calloc( sizeof( SFG_Joystick ), 1 );
#ifdef WIN32
switch( ident )
{
- case 0: fgJoystick->js_id = JOYSTICKID1; fghJoystickOpen( fgJoystick ); break;
- case 1: fgJoystick->js_id = JOYSTICKID2; fghJoystickOpen( fgJoystick ); break;
- default: fgJoystick->num_axes = 0; fgJoystick->error = TRUE; break;
+ case 0:
+ fgJoystick->js_id = JOYSTICKID1;
+ fghJoystickOpen( fgJoystick );
+ break;
+ case 1:
+ fgJoystick->js_id = JOYSTICKID2;
+ fghJoystickOpen( fgJoystick );
+ break;
+ default:
+ fgJoystick->num_axes = 0;
+ fgJoystick->error = GL_TRUE;
+ break;
}
#else
+/*
+ * XXX All BSDs should share this code?
+ */
# ifdef __FreeBSD__
fgJoystick->id = ident;
sprintf( fgJoystick->fname, "/dev/joy%d", ident );
sprintf( fgJoystick->fname, "/dev/js%d", ident );
# endif
- /*
- * Let's try opening the joystick device now:
- */
fghJoystickOpen( fgJoystick );
#endif
}
*/
void fgJoystickClose( void )
{
- if( fgJoystick == NULL )
+ if( !fgJoystick )
fgError( "illegal attempt to deinitialize joystick device" );
#ifndef WIN32
- if( fgJoystick->error != TRUE )
+ if( ! fgJoystick->error )
close( fgJoystick->fd );
#endif
- free ( fgJoystick ) ;
- fgJoystick = NULL ; /* show joystick has been deinitialized */
+ free( fgJoystick );
+ fgJoystick = NULL; /* show joystick has been deinitialized */
}
/*
float axes[ _JS_MAX_AXES ];
int buttons;
- /*
- * Make sure the joystick device is initialized, the window seems valid
- * and that there is a joystick callback hooked to it:
- */
- freeglut_return_if_fail( fgJoystick != NULL && window != NULL );
- freeglut_return_if_fail( window->Callbacks.Joystick != NULL );
+ freeglut_return_if_fail( fgJoystick );
+ freeglut_return_if_fail( window );
+ freeglut_return_if_fail( FETCH_WCB( *window, Joystick ) );
- /*
- * Poll the joystick now:
- */
fghJoystickRead( fgJoystick, &buttons, axes );
+ INVOKE_WCB( *window, Joystick,
+ ( buttons,
+ (int) (axes[ 0 ] * 1000.0f ),
+ (int) (axes[ 1 ] * 1000.0f ),
+ (int) (axes[ 2 ] * 1000.0f ) )
+ );
+
/*
- * Execute the freeglut joystick callback now
+ * fgSetWindow (window);
+ * window->Callbacks.Joystick(
+ * buttons,
+ * (int) (axes[ 0 ] * 1000.0f),
+ * (int) (axes[ 1 ] * 1000.0f),
+ * (int) (axes[ 2 ] * 1000.0f)
+ * );
*/
- window->Callbacks.Joystick(
- buttons,
- (int) (axes[ 0 ] * 1000.0f),
- (int) (axes[ 1 ] * 1000.0f),
- (int) (axes[ 2 ] * 1000.0f)
- );
}
/*
* We might consider adding such functions to freeglut-2.0.
*/
#if 0
- int getNumAxes () { return num_axes ; }
- int notWorking () { return error ; }
-
- float getDeadBand ( int axis ) { return dead_band [ axis ] ; }
- void setDeadBand ( int axis, float db ) { dead_band [ axis ] = db ; }
-
- float getSaturation ( int axis ) { return saturate [ axis ] ; }
- void setSaturation ( int axis, float st ) { saturate [ axis ] = st ; }
-
- void setMinRange ( float *axes ) { memcpy ( min , axes, num_axes * sizeof(float) ) ; }
- void setMaxRange ( float *axes ) { memcpy ( max , axes, num_axes * sizeof(float) ) ; }
- void setCenter ( float *axes ) { memcpy ( center, axes, num_axes * sizeof(float) ) ; }
-
- void getMinRange ( float *axes ) { memcpy ( axes, min , num_axes * sizeof(float) ) ; }
- void getMaxRange ( float *axes ) { memcpy ( axes, max , num_axes * sizeof(float) ) ; }
- void getCenter ( float *axes ) { memcpy ( axes, center, num_axes * sizeof(float) ) ; }
+int getNumAxes ()
+ { return num_axes; }
+int notWorking ()
+ { return error; }
+
+float getDeadBand ( int axis )
+ { return dead_band [ axis ]; }
+void setDeadBand ( int axis, float db )
+ { dead_band [ axis ] = db; }
+
+float getSaturation ( int axis )
+ { return saturate [ axis ]; }
+void setSaturation ( int axis, float st )
+ { saturate [ axis ] = st; }
+
+void setMinRange ( float *axes )
+ { memcpy ( min , axes, num_axes * sizeof(float) ); }
+void setMaxRange ( float *axes )
+ { memcpy ( max , axes, num_axes * sizeof(float) ); }
+void setCenter ( float *axes )
+ { memcpy ( center, axes, num_axes * sizeof(float) ); }
+
+void getMinRange ( float *axes )
+ { memcpy ( axes, min , num_axes * sizeof(float) ); }
+void getMaxRange ( float *axes )
+ { memcpy ( axes, max , num_axes * sizeof(float) ); }
+void getCenter ( float *axes )
+ { memcpy ( axes, center, num_axes * sizeof(float) ); }
#endif
/*** END OF FILE ***/
-
-
-
-