From 95ad8061d144bd4de142832d07485f35d86f18c9 Mon Sep 17 00:00:00 2001 From: pouillot Date: Wed, 26 Nov 2008 22:44:57 +0000 Subject: [PATCH] Removed interfaces/js.h to windows/include/plib git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@326 30fe4595-0a0c-4342-8851-515496e4dcbd Former-commit-id: bf9484697b6f7d3bc2248fea8d32d3bbaa0cf413 Former-commit-id: 81f274f8cc99ca8519e12526dc55651c070bd02c --- src/windows/include/{ => plib}/js.h | 1552 +++++++++++++-------------- 1 file changed, 776 insertions(+), 776 deletions(-) rename src/windows/include/{ => plib}/js.h (96%) mode change 100755 => 100644 diff --git a/src/windows/include/js.h b/src/windows/include/plib/js.h old mode 100755 new mode 100644 similarity index 96% rename from src/windows/include/js.h rename to src/windows/include/plib/js.h index 55dd17041..e28dcc45c --- a/src/windows/include/js.h +++ b/src/windows/include/plib/js.h @@ -1,776 +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 - +/* + 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 +