diff --git a/src/windows/include/js.h b/src/windows/include/js.h new file mode 100755 index 000000000..55dd17041 --- /dev/null +++ b/src/windows/include/js.h @@ -0,0 +1,776 @@ +/* + PLIB - A Suite of Portable Game Libraries + Copyright (C) 2001 Steve Baker + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + For further information visit http://plib.sourceforge.net + + $Id: js.h,v 1.6 2004/10/07 17:05:04 olethros Exp $ +*/ + +#ifndef __INCLUDED_JS_H__ +#define __INCLUDED_JS_H__ 1 + +#include + +#include +#include +#include // -dw- for memcpy + +#ifdef macintosh +# include +#endif + +/* + FreeBSD port - courtesy of Stephen Montgomery-Smith + + + NetBSD mods - courtesy Rene Hexel. + + The next lines are to define BSD + see http://www.freebsd.org/handbook/porting.html for why we do this +*/ +//lint -save -e620 + +#if (defined(__unix__) || defined(unix)) && !defined(USG) +#include +#endif + +#ifdef WIN32 +# include +# if defined( __CYGWIN32__ ) || defined( __CYGWIN__ ) +# define NEAR /* */ +# define FAR /* */ +# endif +# include +# include +#else + +# include +# include + +# if defined(__FreeBSD__) +# include +# define JS_DATA_TYPE joystick +# define JS_RETURN (sizeof(struct JS_DATA_TYPE)) +# elif defined(__NetBSD__) +# include +# define JS_DATA_TYPE joystick +# define JS_RETURN (sizeof(struct JS_DATA_TYPE)) +# elif defined(__linux__) +# include +# include +# include + + /* check the joystick driver version */ + +# ifdef JS_VERSION +# if JS_VERSION >= 0x010000 +# define JS_NEW +# endif +# endif + +# else +# ifndef JS_DATA_TYPE + + /* + Not Windoze and no joystick driver... + + Well - we'll put these values in and that should + allow the code to at least compile. The JS open + routine should error out and shut off all the code + downstream anyway + */ + + struct JS_DATA_TYPE + { + int buttons ; + int x ; + int y ; + } ; + +# define JS_RETURN (sizeof(struct JS_DATA_TYPE)) +# endif +# endif +#endif + +#define JS_TRUE 1 +#define JS_FALSE 0 + +#ifdef WIN32 +# define _JS_MAX_AXES 8 /* X,Y,Z,R,U,V,POV_X,POV_Y */ +#elif defined (macintosh) +# define _JS_MAX_AXES 9 +#else +# if defined(__FreeBSD__) || defined(__NetBSD__) +# define _JS_MAX_AXES 2 +# else +# define _JS_MAX_AXES 9 +# endif +#endif + +class jsJoystick +{ +#ifdef macintosh + + #define isp_num_axis 9 + #define isp_num_needs 41 + + ISpElementReference isp_elem[isp_num_needs]; + ISpNeed isp_needs [isp_num_needs]; + +#endif + +#define NAME_LENGTH 128 + char name [ NAME_LENGTH ] ; + +#if defined(__FreeBSD__) || defined(__NetBSD__) + int id ; +#endif +#ifdef WIN32 + JOYINFOEX js ; + UINT js_id ; +#else +# ifdef JS_NEW + js_event js ; + int tmp_buttons ; + float tmp_axes [ _JS_MAX_AXES ] ; +# else + JS_DATA_TYPE js ; +# endif + char fname [ 128 ] ; + char alt_fname [ 128 ] ; + int fd ; +#endif + + int error ; + int num_axes ; + int num_buttons ; + + float dead_band [ _JS_MAX_AXES ] ; + float saturate [ _JS_MAX_AXES ] ; + float center [ _JS_MAX_AXES ] ; + float max [ _JS_MAX_AXES ] ; + float min [ _JS_MAX_AXES ] ; + + void open () + { + + strcpy ( name, "unknown" ) ; + +#ifdef macintosh + + /* + FIXME: get joystick name in Mac + */ + + OSStatus err; + + err = ISpStartup (); + + if ( err == noErr ) { + + #define ISP_CHECK_ERR(x) if (x != noErr) { setError(); return; } + + setError (); + + // initialize the needs structure + ISpNeed temp_isp_needs[isp_num_needs] = + { + {"\pX-Axis", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, + {"\pY-Axis", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, + {"\pZ-Axis", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, + {"\pR-Axis", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, + {"\pAxis 4", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, + {"\pAxis 5", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, + {"\pAxis 6", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, + {"\pAxis 7", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, + {"\pAxis 8", 128, 0, 0, kISpElementKind_Axis, kISpElementLabel_None, 0, 0, 0, 0 }, + + {"\pButton 0", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 1", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 2", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 3", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 4", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 5", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 6", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 7", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 8", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 9", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 10", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 11", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 12", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 13", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 14", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 15", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 16", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 17", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 18", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 19", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 20", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 21", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 22", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 23", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 24", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 25", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 26", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 27", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 28", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 29", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 30", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + {"\pButton 31", 128, 0, 0, kISpElementKind_Button, kISpElementLabel_Btn_Select, 0, 0, 0, 0 }, + }; + + memcpy (isp_needs, temp_isp_needs, sizeof (temp_isp_needs) ); + + + // next two calls allow keyboard and mouse to emulate other input devices (gamepads, joysticks, etc) + + /* + err = ISpDevices_ActivateClass (kISpDeviceClass_Keyboard); + ISP_CHECK_ERR(err) + + + err = ISpDevices_ActivateClass (kISpDeviceClass_Mouse); + ISP_CHECK_ERR(err) + */ + + err = ISpElement_NewVirtualFromNeeds (isp_num_needs, isp_needs, isp_elem, 0); + ISP_CHECK_ERR(err) + + err = ISpInit (isp_num_needs, isp_needs, isp_elem, 'PLIB', nil, 0, 128, 0); + ISP_CHECK_ERR(err) + + num_buttons = isp_num_needs - isp_num_axis; + num_axes = isp_num_axis; + + for ( int i = 0; i < num_axes; i++ ) { + + dead_band[i] = 0; + saturate [i] = 1; + center[i] = kISpAxisMiddle; + max [i] = kISpAxisMaximum; + min [i] = kISpAxisMinimum; + } + + error = false; + } + else { + setError (); + num_buttons = num_axes = 0; + } + +#elif defined( WIN32 ) + + JOYCAPS jsCaps ; + + js . dwFlags = JOY_RETURNALL ; + js . dwSize = sizeof ( js ) ; + + memset ( &jsCaps, 0, sizeof(jsCaps) ) ; + + error = ( joyGetDevCaps( js_id, &jsCaps, sizeof(jsCaps) ) + != JOYERR_NOERROR ) ; + if ( jsCaps.wNumAxes == 0 ) + { + num_axes = 0 ; + setError () ; + } + else + { + // Windows joystick drivers may provide any combination of + // X,Y,Z,R,U,V,POV - not necessarily the first n of these. + if ( jsCaps.wCaps & JOYCAPS_HASPOV ) { + num_axes = _JS_MAX_AXES ; + min[7] = -1.0 ; max[7] = 1.0 ; // POV Y + min[6] = -1.0 ; max[6] = 1.0 ; // POV X + } else { + num_axes = 6 ; + } + min[5] = (float)jsCaps.wVmin ; max[5] = (float)jsCaps.wVmax ; + min[4] = (float)jsCaps.wUmin ; max[4] = (float)jsCaps.wUmax ; + min[3] = (float)jsCaps.wRmin ; max[3] = (float)jsCaps.wRmax ; + min[2] = (float)jsCaps.wZmin ; max[2] = (float)jsCaps.wZmax ; + min[1] = (float)jsCaps.wYmin ; max[1] = (float)jsCaps.wYmax ; + min[0] = (float)jsCaps.wXmin ; max[0] = (float)jsCaps.wXmax ; + } + + for ( int i = 0 ; i < num_axes ; i++ ) + { + center [ i ] = ( max[i] + min[i] ) / 2.0f ; + dead_band [ i ] = 0.0f ; + saturate [ i ] = 1.0f ; + } + + /* Get the device name */ + strncpy ( name , jsCaps.szPname , NAME_LENGTH - 1 ) ; + name [ NAME_LENGTH - 1 ] = 0; + +#else +# if defined(__FreeBSD__) || defined(__NetBSD__) + FILE *joyfile; + char joyfname[1024]; + int noargs, in_no_axes; +# endif + + /* Default for older Linux systems. */ + + num_axes = 2 ; + num_buttons = 32 ; + +# ifdef JS_NEW + for ( int i = 0 ; i < _JS_MAX_AXES ; i++ ) + tmp_axes [ i ] = 0.0f ; + + tmp_buttons = 0 ; +# endif + + // fd = ::open ( fname, O_RDONLY | O_NONBLOCK ) ; + fd = ::open ( fname, O_RDONLY ) ; + + error = ( fd < 0 ) ; + + if ( error ) + { + if (alt_fname[0] != 0) + { + fd = ::open ( alt_fname, O_RDONLY ) ; + error = ( fd < 0 ) ; + if ( error ) + return; + } + else + return ; + } + + +# if defined(__FreeBSD__) || defined(__NetBSD__) + + /* + FIXME: get joystick name for BSD + */ + + float axes[_JS_MAX_AXES]; + int buttons[_JS_MAX_AXES]; + rawRead ( buttons, axes ); + error = axes[0] < -1000000000.0f; + if ( error ) + return ; + + sprintf(joyfname,"%s/.joy%drc",::getenv( "HOME" ),id); + + joyfile = fopen(joyfname,"r"); + error = joyfile == NULL; + if ( error ) + return ; + noargs = fscanf(joyfile,"%d%f%f%f%f%f%f",&in_no_axes, + &min[0],¢er[0],&max[0], + &min[1],¢er[1],&max[1]); + error = noargs != 7 || in_no_axes != _JS_MAX_AXES; + fclose(joyfile); + if ( error ) + return ; + + for ( int i = 0 ; i < _JS_MAX_AXES ; i++ ) + { + dead_band [ i ] = 0.0f ; + saturate [ i ] = 1.0f ; + } + +# else + + /* + Set the correct number of axes for the linux driver + */ + +# ifdef JS_NEW + ioctl ( fd, JSIOCGAXES , & num_axes ) ; + ioctl ( fd, JSIOCGBUTTONS, & num_buttons ) ; + ioctl ( fd, JSIOCGNAME ( NAME_LENGTH ) , name ) ; + fcntl ( fd, F_SETFL, O_NONBLOCK ) ; + + if ( num_axes > _JS_MAX_AXES ) + num_axes = _JS_MAX_AXES ; +# 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. + */ + +#ifndef JS_NEW + int counter = 0 ; + + do + { + rawRead ( NULL, center ) ; + counter++ ; + } while ( ! error && + counter < 100 && + center[0] == 512.0f && + center[1] == 512.0f ) ; + + if ( counter >= 100 ) + setError() ; +#endif + + for ( int i = 0 ; i < _JS_MAX_AXES ; i++ ) + { +#ifdef JS_NEW + max [ i ] = 32767.0f ; + center [ i ] = 0.0f ; + min [ i ] = -32767.0f ; +#else + max [ i ] = center [ i ] * 2.0f ; + min [ i ] = 0.0f ; +#endif + dead_band [ i ] = 0.0f ; + saturate [ i ] = 1.0f ; + } + +# endif +#endif + } + + void close () + { +#if !defined( WIN32 ) && !defined( macintosh ) + if ( ! error ) + ::close ( fd ) ; +#endif + +#ifdef macintosh + + ISpSuspend (); + ISpStop (); + ISpShutdown (); + +#endif + } + + float fudge_axis ( float value, int axis ) const + { + if ( value < center[axis] ) + { + float xx = ( value - center[ axis ] ) / + ( center [ axis ] - min [ axis ] ) ; + + if ( xx < -saturate [ axis ] ) + return -1.0f ; + + if ( xx > -dead_band [ axis ] ) + return 0.0f ; + + xx = ( xx + dead_band [ axis ] ) / + ( saturate [ axis ] - dead_band [ axis ] ) ; + + return ( xx < -1.0f ) ? -1.0f : xx ; + } + else + { + float xx = ( value - center [ axis ] ) / + ( max [ axis ] - center [ axis ] ) ; + + if ( xx > saturate [ axis ] ) + return 1.0f ; + + if ( xx < dead_band [ axis ] ) + return 0.0f ; + + xx = ( xx - dead_band [ axis ] ) / + ( saturate [ axis ] - dead_band [ axis ] ) ; + + return ( xx > 1.0f ) ? 1.0f : xx ; + } + } + +public: + + jsJoystick ( int ident = 0 ) + { +#ifndef WIN32 + alt_fname [ 0 ] = 0; +#endif +#ifdef WIN32 + if ( ident < 32 ) + { + js_id = ident ; + open () ; + } + else + { + num_axes = 0 ; + setError () ; + } +#if 0 + switch ( ident ) + { + case 0 : js_id = JOYSTICKID1 ; open () ; break ; + case 1 : js_id = JOYSTICKID2 ; open () ; break; + default : num_axes = 0 ; setError () ; break ; + } +#endif + +#else +# if defined(__FreeBSD__) || defined(__NetBSD__) + id = ident; + sprintf ( fname, "/dev/joy%d", ident ) ; +# else + sprintf ( fname, "/dev/input/js%d", ident ) ; /* first try */ + sprintf ( alt_fname, "/dev/js%d", ident ) ; /* second try */ +# endif + open () ; +#endif + } + + ~jsJoystick () + { + close () ; + } + + const char* getName () const { return name ; } + int getNumAxes () const { return num_axes ; } + int notWorking () const { return error ; } + void setError () { error = JS_TRUE ; } + + float getDeadBand ( int axis ) const { return dead_band [ axis ] ; } + void setDeadBand ( int axis, float db ) { dead_band [ axis ] = db ; } + + float getSaturation ( int axis ) const { 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 ) const { memcpy ( axes, min , num_axes * sizeof(float) ) ; } + void getMaxRange ( float *axes ) const { memcpy ( axes, max , num_axes * sizeof(float) ) ; } + void getCenter ( float *axes ) const { memcpy ( axes, center, num_axes * sizeof(float) ) ; } + + void read ( int *buttons, float *axes ) + { + if ( error ) + { + if ( buttons ) + *buttons = 0 ; + + if ( axes ) + for ( int i = 0 ; i < num_axes ; i++ ) + axes[i] = 0.0f ; + } + + float raw_axes [ _JS_MAX_AXES ] ; + + rawRead ( buttons, raw_axes ) ; + + if ( axes ) + for ( int i = 0 ; i < num_axes ; i++ ) + axes[i] = fudge_axis ( raw_axes[i], i ) ; + } + + void rawRead ( int *buttons, float *axes ) + { + if ( error ) + { + if ( buttons ) + *buttons = 0 ; + + if ( axes ) + for ( int i = 0 ; i < num_axes ; i++ ) + axes[i] = 1500.0f ; + + return ; + } + +#ifdef macintosh + + int i; + int err; + UInt32 state; + + if (buttons) { + + *buttons = 0; + + for (i = 0; i < num_buttons; i++) { + + err = ISpElement_GetSimpleState (isp_elem[i + isp_num_axis ], &state); + ISP_CHECK_ERR (err) + + *buttons |= state << i; + } + } + + if (axes) { + + for (i = 0; i < num_axes; i++) { + + err = ISpElement_GetSimpleState (isp_elem[ i ], &state); + ISP_CHECK_ERR (err); + + axes [i] = (float) state; + } + } + +#elif defined ( WIN32 ) + MMRESULT status = joyGetPosEx ( js_id, &js ) ; + + if ( status != JOYERR_NOERROR ) + { + setError() ; + return ; + } + + if ( buttons ) + { + *buttons = (int) js . dwButtons ; + } + + if ( axes ) + { + /* WARNING - Fall through case clauses!! */ +//lint -save -e616 + + switch ( num_axes ) + { + case 8: + // Generate two POV axes from the POV hat angle. + // Low 16 bits of js.dwPOV gives heading (clockwise from ahead) in + // hundredths of a degree, or 0xFFFF when idle. + if ( (js.dwPOV & 0xFFFF) == 0xFFFF ) { + axes[6] = 0.0; + axes[7] = 0.0; + } else { + // This is the contentious bit: how to convert angle to X/Y. + // wk: I know of no define for PI that we could use here: + // SG_PI would pull in sg, M_PI is undefined for MSVC + // But the accuracy of the value of PI is very unimportant at this point. + float s = (float)sin((js.dwPOV & 0xFFFF) * (0.01 * 3.1415926535f / 180)); + float c = (float)cos((js.dwPOV & 0xFFFF) * (0.01 * 3.1415926535f / 180)); + // Convert to coordinates on a square so that North-East + // is (1,1) not (.7,.7), etc. + // s and c cannot both be zero so we won't divide by zero. + if (fabs(s) < fabs(c)) { + axes[6] = (c < 0.0) ? -s/c : s/c; + axes[7] = (c < 0.0) ? -1.0f : 1.0f; + } else { + axes[6] = (s < 0.0) ? -1.0f : 1.0f; + axes[7] = (s < 0.0) ? -c/s : c/s; + } + } + case 6: axes[5] = (float) js . dwVpos ; + case 5: axes[4] = (float) js . dwUpos ; + case 4: axes[3] = (float) js . dwRpos ; + case 3: axes[2] = (float) js . dwZpos ; + case 2: axes[1] = (float) js . dwYpos ; + case 1: axes[0] = (float) js . dwXpos ; + break; + default: + ulSetError ( UL_WARNING, "PLIB_JS: Wrong num_axes. Joystick input is now invalid" ) ; + + } +//lint -restore + } +#else + +# ifdef JS_NEW + + while (1) + { + int status = ::read ( fd, &js, sizeof(js_event) ) ; + + if ( status != sizeof(js_event) ) + { + /* use the old values */ + + if ( buttons ) *buttons = tmp_buttons ; + if ( axes ) memcpy ( axes, tmp_axes, sizeof(float) * num_axes ) ; + + if ( errno == EAGAIN ) + return ; + + perror( fname ) ; + setError () ; + return ; + } + + switch ( js.type & ~JS_EVENT_INIT ) + { + case JS_EVENT_BUTTON : + if ( js.value == 0 ) /* clear the flag */ + tmp_buttons &= ~(1 << js.number) ; + else + tmp_buttons |= (1 << js.number) ; + break ; + + case JS_EVENT_AXIS: + if ( js.number < num_axes ) + { + tmp_axes [ js.number ] = (float) js.value ; + + if ( axes ) + memcpy ( axes, tmp_axes, sizeof(float) * num_axes ) ; + } + break ; + + default: + ulSetError ( UL_WARNING, "PLIB_JS: Unrecognised /dev/js return!?!" ) ; + + /* use the old values */ + + if ( buttons ) *buttons = tmp_buttons ; + if ( axes ) memcpy ( axes, tmp_axes, sizeof(float) * num_axes ) ; + + return ; + } + + if ( buttons ) + *buttons = tmp_buttons ; + } + +# else + + int status = ::read ( fd, &js, JS_RETURN ) ; + + if ( status != JS_RETURN ) + { + perror ( fname ) ; + setError () ; + return ; + } + + if ( buttons ) +# if defined(__FreeBSD__) || defined(__NetBSD__) + *buttons = ( js.b1 ? 1 : 0 ) | ( js.b2 ? 2 : 0 ) ; +# else + *buttons = js.buttons ; +# endif + + if ( axes ) + { + axes[0] = (float) js.x ; + axes[1] = (float) js.y ; + } +# endif +#endif + } +} ; +//lint -restore + +#endif +