* interspersed\r
*/\r
\r
-/* XXX It might be better to poll the operating system for the numbers of buttons and\r
- * XXX axes and then dynamically allocate the arrays.\r
- */\r
-#define _JS_MAX_BUTTONS 32\r
-\r
#if TARGET_HOST_MACINTOSH\r
-# define _JS_MAX_AXES 9\r
# include <InputSprocket.h>\r
#endif\r
\r
#if TARGET_HOST_MAC_OSX\r
-# define _JS_MAX_AXES 16\r
# include <mach/mach.h>\r
# include <IOKit/IOkitLib.h>\r
# include <IOKit/hid/IOHIDLib.h>\r
#endif\r
\r
#if TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE)\r
-# define _JS_MAX_AXES 8\r
# include <windows.h>\r
# include <mmsystem.h>\r
# include <regstr.h>\r
#endif\r
\r
#if TARGET_HOST_POSIX_X11\r
-# define _JS_MAX_AXES 16\r
# ifdef HAVE_SYS_IOCTL_H\r
# include <sys/ioctl.h>\r
# endif\r
#endif\r
\r
/*\r
- * Definition of "SFG_Joystick" structure -- based on JS's "jsJoystick" object class.\r
- * See "js.h" lines 80-178.\r
- */\r
-typedef struct tagSFG_Joystick SFG_Joystick;\r
-struct tagSFG_Joystick\r
-{\r
-#if TARGET_HOST_MACINTOSH\r
-#define ISP_NUM_AXIS 9\r
-#define ISP_NUM_NEEDS 41\r
- ISpElementReference isp_elem [ ISP_NUM_NEEDS ];\r
- ISpNeed isp_needs [ ISP_NUM_NEEDS ];\r
-#endif\r
-\r
-#if TARGET_HOST_MAC_OSX\r
- IOHIDDeviceInterface ** hidDev;\r
- IOHIDElementCookie buttonCookies[41];\r
- IOHIDElementCookie axisCookies[_JS_MAX_AXES];\r
- long minReport[_JS_MAX_AXES],\r
- maxReport[_JS_MAX_AXES];\r
-#endif\r
-\r
-#if TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE)\r
- JOYCAPS jsCaps;\r
- JOYINFOEX js;\r
- UINT js_id;\r
-#endif\r
-\r
-\r
-#if TARGET_HOST_POSIX_X11\r
-# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)\r
- struct os_specific_s *os;\r
-# endif\r
-\r
-# ifdef JS_NEW\r
- struct js_event js;\r
- int tmp_buttons;\r
- float tmp_axes [ _JS_MAX_AXES ];\r
-# else\r
- struct JS_DATA_TYPE js;\r
-# endif\r
-\r
- char fname [ 128 ];\r
- int fd;\r
-#endif\r
-\r
- int id;\r
- GLboolean error;\r
- char name [ 128 ];\r
- int num_axes;\r
- int num_buttons;\r
-\r
- float dead_band[ _JS_MAX_AXES ];\r
- float saturate [ _JS_MAX_AXES ];\r
- float center [ _JS_MAX_AXES ];\r
- float max [ _JS_MAX_AXES ];\r
- float min [ _JS_MAX_AXES ];\r
-};\r
-\r
-/*\r
* Functions associated with the "jsJoystick" class in PLIB\r
*/\r
#if TARGET_HOST_MAC_OSX\r
\r
\r
/* External function declarations (mostly platform-specific) */\r
+extern void fgPlatformJoystickRawRead( SFG_Joystick* joy, int* buttons, float* axes );\r
+extern void fgPlatformJoystickOpen( SFG_Joystick* joy );\r
+extern void fgPlatformJoystickInit( SFG_Joystick *fgJoystick[], int ident );\r
extern void fgPlatformJoystickClose ( int ident );\r
\r
/*\r
#define MAX_NUM_JOYSTICKS 2\r
static SFG_Joystick *fgJoystick [ MAX_NUM_JOYSTICKS ];\r
\r
-\r
/*\r
* Read the raw joystick data\r
*/\r
static void fghJoystickRawRead( SFG_Joystick* joy, int* buttons, float* axes )\r
{\r
-#if TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE)\r
- MMRESULT status;\r
-#else\r
- int status;\r
-#endif\r
-\r
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)\r
- int len;\r
-#endif\r
-\r
int i;\r
\r
/* Defaults */\r
if( joy->error )\r
return;\r
\r
-#if TARGET_HOST_MACINTOSH\r
- if ( buttons )\r
+ fgPlatformJoystickRawRead ( joy, buttons, axes );\r
+}\r
+\r
+/*\r
+ * Correct the joystick axis data\r
+ */\r
+static float fghJoystickFudgeAxis( SFG_Joystick* joy, float value, int axis )\r
+{\r
+ if( value < joy->center[ axis ] )\r
{\r
- *buttons = 0;\r
+ float xx = ( value - joy->center[ axis ] ) / ( joy->center[ axis ] -\r
+ joy->min[ axis ] );\r
\r
- for ( i = 0; i < joy->num_buttons; i++ )\r
- {\r
- UInt32 state;\r
- int err = ISpElement_GetSimpleState ( isp_elem [ i + isp_num_axis ], &state);\r
- ISP_CHECK_ERR(err)\r
+ if( xx < -joy->saturate[ axis ] )\r
+ return -1.0f;\r
\r
- *buttons |= state << i;\r
- }\r
- }\r
+ if( xx > -joy->dead_band [ axis ] )\r
+ return 0.0f;\r
\r
- if ( axes )\r
- {\r
- for ( i = 0; i < joy->num_axes; i++ )\r
- {\r
- UInt32 state;\r
- int err = ISpElement_GetSimpleState ( isp_elem [ i ], &state );\r
- ISP_CHECK_ERR(err)\r
+ xx = ( xx + joy->dead_band[ axis ] ) / ( joy->saturate[ axis ] -\r
+ joy->dead_band[ axis ] );\r
\r
- axes [i] = (float) state;\r
- }\r
+ return ( xx < -1.0f ) ? -1.0f : xx;\r
}\r
-#endif\r
-\r
-#if TARGET_HOST_MAC_OSX\r
- if ( buttons != NULL )\r
+ else\r
{\r
- *buttons = 0;\r
+ float xx = ( value - joy->center [ axis ] ) / ( joy->max[ axis ] -\r
+ joy->center[ axis ] );\r
\r
- for ( i = 0; i < joy->num_buttons; i++ )\r
- {\r
- IOHIDEventStruct hidEvent;\r
- (*(joy->hidDev))->getElementValue ( joy->hidDev, buttonCookies[i], &hidEvent );\r
- if ( hidEvent.value )\r
- *buttons |= 1 << i;\r
- }\r
- }\r
+ if( xx > joy->saturate[ axis ] )\r
+ return 1.0f;\r
\r
- if ( axes != NULL )\r
- {\r
- for ( i = 0; i < joy->num_axes; i++ )\r
- {\r
- IOHIDEventStruct hidEvent;\r
- (*(joy->hidDev))->getElementValue ( joy->hidDev, axisCookies[i], &hidEvent );\r
- axes[i] = hidEvent.value;\r
- }\r
- }\r
-#endif\r
+ if( xx < joy->dead_band[ axis ] )\r
+ return 0.0f;\r
\r
-#if TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE)\r
- status = joyGetPosEx( joy->js_id, &joy->js );\r
+ xx = ( xx - joy->dead_band[ axis ] ) / ( joy->saturate[ axis ] -\r
+ joy->dead_band[ axis ] );\r
\r
- if ( status != JOYERR_NOERROR )\r
- {\r
- joy->error = GL_TRUE;\r
- return;\r
+ return ( xx > 1.0f ) ? 1.0f : xx;\r
}\r
+}\r
\r
- if ( buttons )\r
- *buttons = joy->js.dwButtons;\r
+/*\r
+ * Read the corrected joystick data\r
+ */\r
+static void fghJoystickRead( SFG_Joystick* joy, int* buttons, float* axes )\r
+{\r
+ float raw_axes[ _JS_MAX_AXES ];\r
+ int i;\r
\r
- if ( axes )\r
+ if( joy->error )\r
{\r
- /*\r
- * WARNING - Fall through case clauses!!\r
- */\r
- switch ( joy->num_axes )\r
- {\r
- case 8:\r
- /* Generate two POV axes from the POV hat angle.\r
- * Low 16 bits of js.dwPOV gives heading (clockwise from ahead) in\r
- * hundredths of a degree, or 0xFFFF when idle.\r
- */\r
- if ( ( joy->js.dwPOV & 0xFFFF ) == 0xFFFF )\r
- {\r
- axes [ 6 ] = 0.0;\r
- axes [ 7 ] = 0.0;\r
- }\r
- else\r
- {\r
- /* This is the contentious bit: how to convert angle to X/Y.\r
- * wk: I know of no define for PI that we could use here:\r
- * SG_PI would pull in sg, M_PI is undefined for MSVC\r
- * But the accuracy of the value of PI is very unimportant at\r
- * this point.\r
- */\r
- float s = (float) sin ( ( joy->js.dwPOV & 0xFFFF ) * ( 0.01 * 3.1415926535f / 180.0f ) );\r
- float c = (float) cos ( ( joy->js.dwPOV & 0xFFFF ) * ( 0.01 * 3.1415926535f / 180.0f ) );\r
-\r
- /* Convert to coordinates on a square so that North-East\r
- * is (1,1) not (.7,.7), etc.\r
- * s and c cannot both be zero so we won't divide by zero.\r
- */\r
- if ( fabs ( s ) < fabs ( c ) )\r
- {\r
- axes [ 6 ] = ( c < 0.0 ) ? -s/c : s/c ;\r
- axes [ 7 ] = ( c < 0.0 ) ? -1.0f : 1.0f;\r
- }\r
- else\r
- {\r
- axes [ 6 ] = ( s < 0.0 ) ? -1.0f : 1.0f;\r
- axes [ 7 ] = ( s < 0.0 ) ? -c/s : c/s ;\r
- }\r
- }\r
+ if( buttons )\r
+ *buttons = 0;\r
\r
- case 6: axes[5] = (float) joy->js.dwVpos;\r
- case 5: axes[4] = (float) joy->js.dwUpos;\r
- case 4: axes[3] = (float) joy->js.dwRpos;\r
- case 3: axes[2] = (float) joy->js.dwZpos;\r
- case 2: axes[1] = (float) joy->js.dwYpos;\r
- case 1: axes[0] = (float) joy->js.dwXpos;\r
- }\r
+ if( axes )\r
+ for ( i=0; i<joy->num_axes; i++ )\r
+ axes[ i ] = 0.0f;\r
}\r
-#endif\r
\r
-#if TARGET_HOST_POSIX_X11\r
-# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)\r
- if ( joy->os->is_analog )\r
- {\r
- int status = read ( joy->os->fd, &joy->os->ajs, sizeof(joy->os->ajs) );\r
- if ( status != sizeof(joy->os->ajs) ) {\r
- perror ( joy->os->fname );\r
- joy->error = GL_TRUE;\r
- return;\r
- }\r
- if ( buttons != NULL )\r
- *buttons = ( joy->os->ajs.b1 ? 1 : 0 ) | ( joy->os->ajs.b2 ? 2 : 0 );\r
+ fghJoystickRawRead( joy, buttons, raw_axes );\r
\r
- if ( axes != NULL )\r
- {\r
- axes[0] = (float) joy->os->ajs.x;\r
- axes[1] = (float) joy->os->ajs.y;\r
- }\r
+ if( axes )\r
+ for( i=0; i<joy->num_axes; i++ )\r
+ axes[ i ] = fghJoystickFudgeAxis( joy, raw_axes[ i ], i );\r
+}\r
\r
- return;\r
- }\r
+/*\r
+ * Happy happy happy joy joy joy (happy new year toudi :D)\r
+ */\r
\r
-# ifdef HAVE_USB_JS\r
- while ( ( len = read ( joy->os->fd, joy->os->hid_data_buf, joy->os->hid_dlen ) ) == joy->os->hid_dlen )\r
- {\r
- struct hid_item *h;\r
\r
- for ( h = joy->os->hids; h; h = h->next )\r
- {\r
- int d = hid_get_data ( joy->os->hid_data_buf, h );\r
+#if TARGET_HOST_MAC_OSX\r
+/** open the IOKit connection, enumerate all the HID devices, add their\r
+interface references to the static array. We then use the array index\r
+as the device number when we come to open() the joystick. */\r
+static int fghJoystickFindDevices ( SFG_Joystick *joy, mach_port_t masterPort )\r
+{\r
+ CFMutableDictionaryRef hidMatch = NULL;\r
+ IOReturn rv = kIOReturnSuccess;\r
\r
- int page = HID_PAGE ( h->usage );\r
- int usage = HID_USAGE ( h->usage );\r
+ io_iterator_t hidIterator;\r
+ io_object_t ioDev;\r
\r
- if ( page == HUP_GENERIC_DESKTOP )\r
- {\r
- int i;\r
- for ( i = 0; i < joy->num_axes; i++ )\r
- if (joy->os->axes_usage[i] == usage)\r
- {\r
- if (usage == HUG_HAT_SWITCH)\r
- {\r
- if (d < 0 || d > 8)\r
- d = 0; /* safety */\r
- joy->os->cache_axes[i] = (float)hatmap_x[d];\r
- joy->os->cache_axes[i + 1] = (float)hatmap_y[d];\r
- }\r
- else\r
- {\r
- joy->os->cache_axes[i] = (float)d;\r
- }\r
- break;\r
- }\r
- }\r
- else if (page == HUP_BUTTON)\r
- {\r
- if (usage > 0 && usage < _JS_MAX_BUTTONS + 1)\r
- {\r
- if (d)\r
- joy->os->cache_buttons |= (1 << ( usage - 1 ));\r
- else\r
- joy->os->cache_buttons &= ~(1 << ( usage - 1 ));\r
- }\r
- }\r
- }\r
- }\r
-#ifdef HAVE_ERRNO_H\r
- if ( len < 0 && errno != EAGAIN )\r
-#else\r
- if ( len < 0 )\r
-#endif\r
- {\r
- perror( joy->os->fname );\r
- joy->error = 1;\r
+ /* build a dictionary matching HID devices */\r
+ hidMatch = IOServiceMatching(kIOHIDDeviceKey);\r
+\r
+ rv = IOServiceGetMatchingServices(masterPort, hidMatch, &hidIterator);\r
+ if (rv != kIOReturnSuccess || !hidIterator) {\r
+ fgWarning( "no joystick (HID) devices found" );\r
+ return;\r
}\r
- if ( buttons != NULL ) *buttons = joy->os->cache_buttons;\r
- if ( axes != NULL )\r
- memcpy ( axes, joy->os->cache_axes, sizeof(float) * joy->num_axes );\r
-# endif\r
-# endif\r
\r
-# ifdef JS_NEW\r
+ /* iterate */\r
+ while ((ioDev = IOIteratorNext(hidIterator))) {\r
+ /* filter out keyboard and mouse devices */\r
+ CFDictionaryRef properties = getCFProperties(ioDev);\r
+ long usage, page;\r
\r
- while ( 1 )\r
- {\r
- status = read ( joy->fd, &joy->js, sizeof(struct js_event) );\r
-\r
- if ( status != sizeof( struct js_event ) )\r
- {\r
-#ifdef HAVE_ERRNO_H\r
- if ( errno == EAGAIN )\r
- {\r
- /* Use the old values */\r
- if ( buttons )\r
- *buttons = joy->tmp_buttons;\r
- if ( axes )\r
- memcpy( axes, joy->tmp_axes,\r
- sizeof( float ) * joy->num_axes );\r
- return;\r
- }\r
-#endif\r
-\r
- fgWarning ( "%s", joy->fname );\r
- joy->error = GL_TRUE;\r
- return;\r
- }\r
-\r
- switch ( joy->js.type & ~JS_EVENT_INIT )\r
- {\r
- case JS_EVENT_BUTTON:\r
- if( joy->js.value == 0 ) /* clear the flag */\r
- joy->tmp_buttons &= ~( 1 << joy->js.number );\r
- else\r
- joy->tmp_buttons |= ( 1 << joy->js.number );\r
- break;\r
-\r
- case JS_EVENT_AXIS:\r
- if ( joy->js.number < joy->num_axes )\r
- {\r
- joy->tmp_axes[ joy->js.number ] = ( float )joy->js.value;\r
-\r
- if( axes )\r
- memcpy( axes, joy->tmp_axes, sizeof(float) * joy->num_axes );\r
- }\r
- break;\r
-\r
- default:\r
- fgWarning ( "PLIB_JS: Unrecognised /dev/js return!?!" );\r
-\r
- /* use the old values */\r
-\r
- if ( buttons != NULL ) *buttons = joy->tmp_buttons;\r
- if ( axes != NULL )\r
- memcpy ( axes, joy->tmp_axes, sizeof(float) * joy->num_axes );\r
-\r
- return;\r
- }\r
-\r
- if( buttons )\r
- *buttons = joy->tmp_buttons;\r
- }\r
-# else\r
-\r
- status = read( joy->fd, &joy->js, JS_RETURN );\r
-\r
- if ( status != JS_RETURN )\r
- {\r
- fgWarning( "%s", joy->fname );\r
- joy->error = GL_TRUE;\r
- return;\r
- }\r
-\r
- if ( buttons )\r
-# if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
- *buttons = ( joy->js.b1 ? 1 : 0 ) | ( joy->js.b2 ? 2 : 0 ); /* XXX Should not be here -- BSD is handled earlier */\r
-# else\r
- *buttons = joy->js.buttons;\r
-# endif\r
-\r
- if ( axes )\r
- {\r
- axes[ 0 ] = (float) joy->js.x;\r
- axes[ 1 ] = (float) joy->js.y;\r
- }\r
-# endif\r
-#endif\r
-}\r
-\r
-/*\r
- * Correct the joystick axis data\r
- */\r
-static float fghJoystickFudgeAxis( SFG_Joystick* joy, float value, int axis )\r
-{\r
- if( value < joy->center[ axis ] )\r
- {\r
- float xx = ( value - joy->center[ axis ] ) / ( joy->center[ axis ] -\r
- joy->min[ axis ] );\r
-\r
- if( xx < -joy->saturate[ axis ] )\r
- return -1.0f;\r
-\r
- if( xx > -joy->dead_band [ axis ] )\r
- return 0.0f;\r
-\r
- xx = ( xx + joy->dead_band[ axis ] ) / ( joy->saturate[ axis ] -\r
- joy->dead_band[ axis ] );\r
-\r
- return ( xx < -1.0f ) ? -1.0f : xx;\r
- }\r
- else\r
- {\r
- float xx = ( value - joy->center [ axis ] ) / ( joy->max[ axis ] -\r
- joy->center[ axis ] );\r
-\r
- if( xx > joy->saturate[ axis ] )\r
- return 1.0f;\r
-\r
- if( xx < joy->dead_band[ axis ] )\r
- return 0.0f;\r
-\r
- xx = ( xx - joy->dead_band[ axis ] ) / ( joy->saturate[ axis ] -\r
- joy->dead_band[ axis ] );\r
-\r
- return ( xx > 1.0f ) ? 1.0f : xx;\r
- }\r
-}\r
-\r
-/*\r
- * Read the corrected joystick data\r
- */\r
-static void fghJoystickRead( SFG_Joystick* joy, int* buttons, float* axes )\r
-{\r
- float raw_axes[ _JS_MAX_AXES ];\r
- int i;\r
-\r
- if( joy->error )\r
- {\r
- if( buttons )\r
- *buttons = 0;\r
-\r
- if( axes )\r
- for ( i=0; i<joy->num_axes; i++ )\r
- axes[ i ] = 0.0f;\r
- }\r
-\r
- fghJoystickRawRead( joy, buttons, raw_axes );\r
-\r
- if( axes )\r
- for( i=0; i<joy->num_axes; i++ )\r
- axes[ i ] = fghJoystickFudgeAxis( joy, raw_axes[ i ], i );\r
-}\r
-\r
-/*\r
- * Happy happy happy joy joy joy (happy new year toudi :D)\r
- */\r
-\r
-\r
-#if TARGET_HOST_MAC_OSX\r
-/** open the IOKit connection, enumerate all the HID devices, add their\r
-interface references to the static array. We then use the array index\r
-as the device number when we come to open() the joystick. */\r
-static int fghJoystickFindDevices ( SFG_Joystick *joy, mach_port_t masterPort )\r
-{\r
- CFMutableDictionaryRef hidMatch = NULL;\r
- IOReturn rv = kIOReturnSuccess;\r
-\r
- io_iterator_t hidIterator;\r
- io_object_t ioDev;\r
-\r
- /* build a dictionary matching HID devices */\r
- hidMatch = IOServiceMatching(kIOHIDDeviceKey);\r
-\r
- rv = IOServiceGetMatchingServices(masterPort, hidMatch, &hidIterator);\r
- if (rv != kIOReturnSuccess || !hidIterator) {\r
- fgWarning( "no joystick (HID) devices found" );\r
- return;\r
- }\r
-\r
- /* iterate */\r
- while ((ioDev = IOIteratorNext(hidIterator))) {\r
- /* filter out keyboard and mouse devices */\r
- CFDictionaryRef properties = getCFProperties(ioDev);\r
- long usage, page;\r
-\r
- CFTypeRef refPage = CFDictionaryGetValue (properties, CFSTR(kIOHIDPrimaryUsagePageKey));\r
- CFTypeRef refUsage = CFDictionaryGetValue (properties, CFSTR(kIOHIDPrimaryUsageKey));\r
- CFNumberGetValue((CFNumberRef) refUsage, kCFNumberLongType, &usage);\r
- CFNumberGetValue((CFNumberRef) refPage, kCFNumberLongType, &page);\r
+ CFTypeRef refPage = CFDictionaryGetValue (properties, CFSTR(kIOHIDPrimaryUsagePageKey));\r
+ CFTypeRef refUsage = CFDictionaryGetValue (properties, CFSTR(kIOHIDPrimaryUsageKey));\r
+ CFNumberGetValue((CFNumberRef) refUsage, kCFNumberLongType, &usage);\r
+ CFNumberGetValue((CFNumberRef) refPage, kCFNumberLongType, &page);\r
\r
/* keep only joystick devices */\r
if ( ( page == kHIDPage_GenericDesktop ) && (\r
}\r
#endif\r
\r
-#if TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE)\r
-/* Inspired by\r
- http://msdn.microsoft.com/archive/en-us/dnargame/html/msdn_sidewind3d.asp\r
+/*\r
+ * Platform-Specific Code\r
*/\r
-# if FREEGLUT_LIB_PRAGMAS\r
-# pragma comment (lib, "advapi32.lib")\r
-# endif\r
\r
-static int fghJoystickGetOEMProductName ( SFG_Joystick* joy, char *buf, int buf_sz )\r
+#if TARGET_HOST_MACINTOSH\r
+void fgPlatformJoystickRawRead( SFG_Joystick* joy, int* buttons, float* axes )\r
{\r
- char buffer [ 256 ];\r
-\r
- char OEMKey [ 256 ];\r
-\r
- HKEY hKey;\r
- DWORD dwcb;\r
- LONG lr;\r
-\r
- if ( joy->error )\r
- return 0;\r
-\r
- /* Open .. MediaResources\CurrentJoystickSettings */\r
- _snprintf ( buffer, sizeof(buffer), "%s\\%s\\%s",\r
- REGSTR_PATH_JOYCONFIG, joy->jsCaps.szRegKey,\r
- REGSTR_KEY_JOYCURR );\r
-\r
- lr = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, buffer, 0, KEY_QUERY_VALUE, &hKey);\r
-\r
- if ( lr != ERROR_SUCCESS ) return 0;\r
-\r
- /* Get OEM Key name */\r
- dwcb = sizeof(OEMKey);\r
-\r
- /* JOYSTICKID1-16 is zero-based; registry entries for VJOYD are 1-based. */\r
- _snprintf ( buffer, sizeof(buffer), "Joystick%d%s", joy->js_id + 1, REGSTR_VAL_JOYOEMNAME );\r
-\r
- lr = RegQueryValueEx ( hKey, buffer, 0, 0, (LPBYTE) OEMKey, &dwcb);\r
- RegCloseKey ( hKey );\r
-\r
- if ( lr != ERROR_SUCCESS ) return 0;\r
-\r
- /* Open OEM Key from ...MediaProperties */\r
- _snprintf ( buffer, sizeof(buffer), "%s\\%s", REGSTR_PATH_JOYOEM, OEMKey );\r
-\r
- lr = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, buffer, 0, KEY_QUERY_VALUE, &hKey );\r
+ int i;\r
\r
- if ( lr != ERROR_SUCCESS ) return 0;\r
+ if ( buttons )\r
+ {\r
+ *buttons = 0;\r
\r
- /* Get OEM Name */\r
- dwcb = buf_sz;\r
+ for ( i = 0; i < joy->num_buttons; i++ )\r
+ {\r
+ UInt32 state;\r
+ int err = ISpElement_GetSimpleState ( isp_elem [ i + isp_num_axis ], &state);\r
+ ISP_CHECK_ERR(err)\r
\r
- lr = RegQueryValueEx ( hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, (LPBYTE) buf,\r
- &dwcb );\r
- RegCloseKey ( hKey );\r
+ *buttons |= state << i;\r
+ }\r
+ }\r
\r
- if ( lr != ERROR_SUCCESS ) return 0;\r
+ if ( axes )\r
+ {\r
+ for ( i = 0; i < joy->num_axes; i++ )\r
+ {\r
+ UInt32 state;\r
+ int err = ISpElement_GetSimpleState ( isp_elem [ i ], &state );\r
+ ISP_CHECK_ERR(err)\r
\r
- return 1;\r
+ axes [i] = (float) state;\r
+ }\r
+ }\r
}\r
-#endif\r
\r
\r
-static void fghJoystickOpen( SFG_Joystick* joy )\r
+void fgPlatformJoystickOpen( SFG_Joystick* joy )\r
{\r
- int i = 0;\r
-#if TARGET_HOST_MACINTOSH\r
+ int i = 0;\r
OSStatus err;\r
-#endif\r
-#if TARGET_HOST_MAC_OSX\r
- IOReturn rv;\r
- SInt32 score;\r
- IOCFPlugInInterface **plugin;\r
\r
- HRESULT pluginResult;\r
-\r
- CFDictionaryRef props;\r
- CFTypeRef topLevelElement;\r
-#endif\r
-#if TARGET_HOST_POSIX_X11\r
-# if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
- char *cp;\r
-# endif\r
-# ifdef JS_NEW\r
- unsigned char u;\r
-# else\r
-# if defined( __linux__ ) || TARGET_HOST_SOLARIS\r
- int counter = 0;\r
-# endif\r
-# endif\r
-#endif\r
-\r
- /* Silence gcc, the correct #ifdefs would be too fragile... */\r
- (void)i;\r
-\r
- /*\r
- * Default values (for no joystick -- each conditional will reset the\r
- * error flag)\r
- */\r
- joy->error = TRUE;\r
- joy->num_axes = joy->num_buttons = 0;\r
- joy->name[ 0 ] = '\0';\r
-\r
-#if TARGET_HOST_MACINTOSH\r
/* XXX FIXME: get joystick name in Mac */\r
\r
err = ISpStartup( );\r
}\r
else\r
joy->num_buttons = joy->num_axes = 0;\r
+}\r
+\r
+\r
+void fgPlatformJoystickInit( SFG_Joystick *fgJoystick[], int ident )\r
+{\r
+ fgJoystick[ ident ]->id = ident;\r
+ snprintf( fgJoystick[ ident ]->fname, sizeof(fgJoystick[ ident ]->fname), "/dev/js%d", ident ); /* FIXME */\r
+ fgJoystick[ ident ]->error = GL_FALSE;\r
+}\r
+\r
+\r
+void fgPlatformJoystickClose ( int ident )\r
+{\r
+ ISpSuspend( );\r
+ ISpStop( );\r
+ ISpShutdown( );\r
+}\r
#endif\r
\r
#if TARGET_HOST_MAC_OSX\r
+void fgPlatformJoystickRawRead( SFG_Joystick* joy, int* buttons, float* axes )\r
+{\r
+ int i;\r
+\r
+ if ( buttons != NULL )\r
+ {\r
+ *buttons = 0;\r
+\r
+ for ( i = 0; i < joy->num_buttons; i++ )\r
+ {\r
+ IOHIDEventStruct hidEvent;\r
+ (*(joy->hidDev))->getElementValue ( joy->hidDev, buttonCookies[i], &hidEvent );\r
+ if ( hidEvent.value )\r
+ *buttons |= 1 << i;\r
+ }\r
+ }\r
+\r
+ if ( axes != NULL )\r
+ {\r
+ for ( i = 0; i < joy->num_axes; i++ )\r
+ {\r
+ IOHIDEventStruct hidEvent;\r
+ (*(joy->hidDev))->getElementValue ( joy->hidDev, axisCookies[i], &hidEvent );\r
+ axes[i] = hidEvent.value;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+void fgPlatformJoystickOpen( SFG_Joystick* joy )\r
+{\r
+ IOReturn rv;\r
+ SInt32 score;\r
+ IOCFPlugInInterface **plugin;\r
+\r
+ HRESULT pluginResult;\r
+\r
+ CFDictionaryRef props;\r
+ CFTypeRef topLevelElement;\r
+\r
if( joy->id >= numDevices )\r
{\r
fgWarning( "device index out of range in fgJoystickOpen()" );\r
&( LPVOID )joy->hidDev\r
);\r
\r
- if( pluginResult != S_OK )\r
- fgWarning ( "QI-ing IO plugin to HID Device interface failed" );\r
+ if( pluginResult != S_OK )\r
+ fgWarning ( "QI-ing IO plugin to HID Device interface failed" );\r
+\r
+ ( *plugin )->Release( plugin ); /* don't leak a ref */\r
+ if( joy->hidDev == NULL )\r
+ return;\r
+\r
+ /* store the interface in this instance */\r
+ rv = ( *( joy->hidDev ) )->open( joy->hidDev, 0 );\r
+ if( rv != kIOReturnSuccess )\r
+ {\r
+ fgWarning( "error opening device interface");\r
+ return;\r
+ }\r
+\r
+ props = getCFProperties( ioDevices[ joy->id ] );\r
+\r
+ /* recursively enumerate all the bits */\r
+ CFTypeRef topLevelElement =\r
+ CFDictionaryGetValue( props, CFSTR( kIOHIDElementKey ) );\r
+ enumerateElements( topLevelElement );\r
+\r
+ CFRelease( props );\r
+}\r
+\r
+\r
+void fgPlatformJoystickInit( SFG_Joystick *fgJoystick[], int ident )\r
+{\r
+ fgJoystick[ ident ]->id = ident;\r
+ fgJoystick[ ident ]->error = GL_FALSE;\r
+ fgJoystick[ ident ]->num_axes = 0;\r
+ fgJoystick[ ident ]->num_buttons = 0;\r
+\r
+ if( numDevices < 0 )\r
+ {\r
+ /* do first-time init (since we can't over-ride jsInit, hmm */\r
+ numDevices = 0;\r
+\r
+ mach_port_t masterPort;\r
+ IOReturn rv = IOMasterPort( bootstrap_port, &masterPort );\r
+ if( rv != kIOReturnSuccess )\r
+ {\r
+ fgWarning( "error getting master Mach port" );\r
+ return;\r
+ }\r
+ fghJoystickFindDevices( masterPort );\r
+ }\r
+\r
+ if ( ident >= numDevices )\r
+ {\r
+ fgJoystick[ ident ]->error = GL_TRUE;\r
+ return;\r
+ }\r
+\r
+ /* get the name now too */\r
+ CFDictionaryRef properties = getCFProperties( ioDevices[ ident ] );\r
+ CFTypeRef ref = CFDictionaryGetValue( properties,\r
+ CFSTR( kIOHIDProductKey ) );\r
+ if (!ref)\r
+ ref = CFDictionaryGetValue(properties, CFSTR( "USB Product Name" ) );\r
+\r
+ if( !ref ||\r
+ !CFStringGetCString( ( CFStringRef )ref, name, 128,\r
+ CFStringGetSystemEncoding( ) ) )\r
+ {\r
+ fgWarning( "error getting device name" );\r
+ name[ 0 ] = '\0';\r
+ }\r
+}\r
+\r
+\r
+void fgPlatformJoystickClose ( int ident )\r
+{\r
+ ( *( fgJoystick[ ident ]->hidDev ) )->\r
+ close( fgJoystick[ ident ]->hidDev );\r
+}\r
+#endif\r
+\r
+#if TARGET_HOST_POSIX_X11\r
+void fgPlatformJoystickRawRead( SFG_Joystick* joy, int* buttons, float* axes )\r
+{\r
+ int status;\r
+\r
+ int i;\r
+\r
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)\r
+ int len;\r
+\r
+ if ( joy->os->is_analog )\r
+ {\r
+ int status = read ( joy->os->fd, &joy->os->ajs, sizeof(joy->os->ajs) );\r
+ if ( status != sizeof(joy->os->ajs) ) {\r
+ perror ( joy->os->fname );\r
+ joy->error = GL_TRUE;\r
+ return;\r
+ }\r
+ if ( buttons != NULL )\r
+ *buttons = ( joy->os->ajs.b1 ? 1 : 0 ) | ( joy->os->ajs.b2 ? 2 : 0 );\r
+\r
+ if ( axes != NULL )\r
+ {\r
+ axes[0] = (float) joy->os->ajs.x;\r
+ axes[1] = (float) joy->os->ajs.y;\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+# ifdef HAVE_USB_JS\r
+ while ( ( len = read ( joy->os->fd, joy->os->hid_data_buf, joy->os->hid_dlen ) ) == joy->os->hid_dlen )\r
+ {\r
+ struct hid_item *h;\r
+\r
+ for ( h = joy->os->hids; h; h = h->next )\r
+ {\r
+ int d = hid_get_data ( joy->os->hid_data_buf, h );\r
+\r
+ int page = HID_PAGE ( h->usage );\r
+ int usage = HID_USAGE ( h->usage );\r
+\r
+ if ( page == HUP_GENERIC_DESKTOP )\r
+ {\r
+ int i;\r
+ for ( i = 0; i < joy->num_axes; i++ )\r
+ if (joy->os->axes_usage[i] == usage)\r
+ {\r
+ if (usage == HUG_HAT_SWITCH)\r
+ {\r
+ if (d < 0 || d > 8)\r
+ d = 0; /* safety */\r
+ joy->os->cache_axes[i] = (float)hatmap_x[d];\r
+ joy->os->cache_axes[i + 1] = (float)hatmap_y[d];\r
+ }\r
+ else\r
+ {\r
+ joy->os->cache_axes[i] = (float)d;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ else if (page == HUP_BUTTON)\r
+ {\r
+ if (usage > 0 && usage < _JS_MAX_BUTTONS + 1)\r
+ {\r
+ if (d)\r
+ joy->os->cache_buttons |= (1 << ( usage - 1 ));\r
+ else\r
+ joy->os->cache_buttons &= ~(1 << ( usage - 1 ));\r
+ }\r
+ }\r
+ }\r
+ }\r
+# ifdef HAVE_ERRNO_H\r
+ if ( len < 0 && errno != EAGAIN )\r
+# else\r
+ if ( len < 0 )\r
+# endif\r
+ {\r
+ perror( joy->os->fname );\r
+ joy->error = 1;\r
+ }\r
+ if ( buttons != NULL ) *buttons = joy->os->cache_buttons;\r
+ if ( axes != NULL )\r
+ memcpy ( axes, joy->os->cache_axes, sizeof(float) * joy->num_axes );\r
+# endif\r
+#endif\r
+\r
+#ifdef JS_NEW\r
+\r
+ while ( 1 )\r
+ {\r
+ status = read ( joy->fd, &joy->js, sizeof(struct js_event) );\r
+\r
+ if ( status != sizeof( struct js_event ) )\r
+ {\r
+# ifdef HAVE_ERRNO_H\r
+ if ( errno == EAGAIN )\r
+ {\r
+ /* Use the old values */\r
+ if ( buttons )\r
+ *buttons = joy->tmp_buttons;\r
+ if ( axes )\r
+ memcpy( axes, joy->tmp_axes,\r
+ sizeof( float ) * joy->num_axes );\r
+ return;\r
+ }\r
+# endif\r
+\r
+ fgWarning ( "%s", joy->fname );\r
+ joy->error = GL_TRUE;\r
+ return;\r
+ }\r
+\r
+ switch ( joy->js.type & ~JS_EVENT_INIT )\r
+ {\r
+ case JS_EVENT_BUTTON:\r
+ if( joy->js.value == 0 ) /* clear the flag */\r
+ joy->tmp_buttons &= ~( 1 << joy->js.number );\r
+ else\r
+ joy->tmp_buttons |= ( 1 << joy->js.number );\r
+ break;\r
\r
- ( *plugin )->Release( plugin ); /* don't leak a ref */\r
- if( joy->hidDev == NULL )\r
- return;\r
+ case JS_EVENT_AXIS:\r
+ if ( joy->js.number < joy->num_axes )\r
+ {\r
+ joy->tmp_axes[ joy->js.number ] = ( float )joy->js.value;\r
\r
- /* store the interface in this instance */\r
- rv = ( *( joy->hidDev ) )->open( joy->hidDev, 0 );\r
- if( rv != kIOReturnSuccess )\r
- {\r
- fgWarning( "error opening device interface");\r
- return;\r
- }\r
+ if( axes )\r
+ memcpy( axes, joy->tmp_axes, sizeof(float) * joy->num_axes );\r
+ }\r
+ break;\r
\r
- props = getCFProperties( ioDevices[ joy->id ] );\r
+ default:\r
+ fgWarning ( "PLIB_JS: Unrecognised /dev/js return!?!" );\r
\r
- /* recursively enumerate all the bits */\r
- CFTypeRef topLevelElement =\r
- CFDictionaryGetValue( props, CFSTR( kIOHIDElementKey ) );\r
- enumerateElements( topLevelElement );\r
+ /* use the old values */\r
\r
- CFRelease( props );\r
-#endif\r
+ if ( buttons != NULL ) *buttons = joy->tmp_buttons;\r
+ if ( axes != NULL )\r
+ memcpy ( axes, joy->tmp_axes, sizeof(float) * joy->num_axes );\r
\r
-#if TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE)\r
- joy->js.dwFlags = JOY_RETURNALL;\r
- joy->js.dwSize = sizeof( joy->js );\r
+ return;\r
+ }\r
\r
- memset( &joy->jsCaps, 0, sizeof( joy->jsCaps ) );\r
+ if( buttons )\r
+ *buttons = joy->tmp_buttons;\r
+ }\r
+#else\r
\r
- joy->error =\r
- ( joyGetDevCaps( joy->js_id, &joy->jsCaps, sizeof( joy->jsCaps ) ) !=\r
- JOYERR_NOERROR );\r
+ status = read( joy->fd, &joy->js, JS_RETURN );\r
\r
- if( joy->jsCaps.wNumAxes == 0 )\r
+ if ( status != JS_RETURN )\r
{\r
- joy->num_axes = 0;\r
+ fgWarning( "%s", joy->fname );\r
joy->error = GL_TRUE;\r
+ return;\r
}\r
- else\r
- {\r
- /* Device name from jsCaps is often "Microsoft PC-joystick driver",\r
- * at least for USB. Try to get the real name from the registry.\r
- */\r
- if ( ! fghJoystickGetOEMProductName( joy, joy->name,\r
- sizeof( joy->name ) ) )\r
- {\r
- fgWarning( "JS: Failed to read joystick name from registry" );\r
- strncpy( joy->name, joy->jsCaps.szPname, sizeof( joy->name ) );\r
- }\r
\r
- /* Windows joystick drivers may provide any combination of\r
- * X,Y,Z,R,U,V,POV - not necessarily the first n of these.\r
- */\r
- if( joy->jsCaps.wCaps & JOYCAPS_HASPOV )\r
- {\r
- joy->num_axes = _JS_MAX_AXES;\r
- joy->min[ 7 ] = -1.0; joy->max[ 7 ] = 1.0; /* POV Y */\r
- joy->min[ 6 ] = -1.0; joy->max[ 6 ] = 1.0; /* POV X */\r
- }\r
- else\r
- joy->num_axes = 6;\r
-\r
- joy->min[ 5 ] = ( float )joy->jsCaps.wVmin;\r
- joy->max[ 5 ] = ( float )joy->jsCaps.wVmax;\r
- joy->min[ 4 ] = ( float )joy->jsCaps.wUmin;\r
- joy->max[ 4 ] = ( float )joy->jsCaps.wUmax;\r
- joy->min[ 3 ] = ( float )joy->jsCaps.wRmin;\r
- joy->max[ 3 ] = ( float )joy->jsCaps.wRmax;\r
- joy->min[ 2 ] = ( float )joy->jsCaps.wZmin;\r
- joy->max[ 2 ] = ( float )joy->jsCaps.wZmax;\r
- joy->min[ 1 ] = ( float )joy->jsCaps.wYmin;\r
- joy->max[ 1 ] = ( float )joy->jsCaps.wYmax;\r
- joy->min[ 0 ] = ( float )joy->jsCaps.wXmin;\r
- joy->max[ 0 ] = ( float )joy->jsCaps.wXmax;\r
- }\r
+ if ( buttons )\r
+# if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
+ *buttons = ( joy->js.b1 ? 1 : 0 ) | ( joy->js.b2 ? 2 : 0 ); /* XXX Should not be here -- BSD is handled earlier */\r
+# else\r
+ *buttons = joy->js.buttons;\r
+# endif\r
\r
- /* Guess all the rest judging on the axes extremals */\r
- for( i = 0; i < joy->num_axes; i++ )\r
+ if ( axes )\r
{\r
- joy->center [ i ] = ( joy->max[ i ] + joy->min[ i ] ) * 0.5f;\r
- joy->dead_band[ i ] = 0.0f;\r
- joy->saturate [ i ] = 1.0f;\r
+ axes[ 0 ] = (float) joy->js.x;\r
+ axes[ 1 ] = (float) joy->js.y;\r
}\r
#endif\r
+}\r
+\r
+\r
+void fgPlatformJoystickOpen( SFG_Joystick* joy )\r
+{\r
+#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
+ int i = 0;\r
+ char *cp;\r
+#endif\r
+#ifdef JS_NEW\r
+ unsigned char u;\r
+#else\r
+# if defined( __linux__ ) || TARGET_HOST_SOLARIS\r
+ int i = 0;\r
+ int counter = 0;\r
+# endif\r
+#endif\r
\r
-#if TARGET_HOST_POSIX_X11\r
#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
for( i = 0; i < _JS_MAX_AXES; i++ )\r
joy->os->cache_axes[ i ] = 0.0f;\r
joy->saturate [ i ] = 1.0f;\r
}\r
#endif\r
-#endif\r
}\r
\r
-/*\r
- * This function replaces the constructor method in the JS library.\r
- */\r
-static void fghJoystickInit( int ident )\r
-{\r
- if( ident >= MAX_NUM_JOYSTICKS )\r
- fgError( "Too large a joystick number: %d", ident );\r
-\r
- if( fgJoystick[ ident ] )\r
- fgError( "illegal attempt to initialize joystick device again" );\r
-\r
- fgJoystick[ ident ] =\r
- ( SFG_Joystick * )calloc( sizeof( SFG_Joystick ), 1 );\r
-\r
- /* Set defaults */\r
- fgJoystick[ ident ]->num_axes = fgJoystick[ ident ]->num_buttons = 0;\r
- fgJoystick[ ident ]->error = GL_TRUE;\r
-\r
-#if TARGET_HOST_MACINTOSH\r
- fgJoystick[ ident ]->id = ident;\r
- snprintf( fgJoystick[ ident ]->fname, sizeof(fgJoystick[ ident ]->fname), "/dev/js%d", ident ); /* FIXME */\r
- fgJoystick[ ident ]->error = GL_FALSE;\r
-#endif\r
-\r
-#if TARGET_HOST_MAC_OSX\r
- fgJoystick[ ident ]->id = ident;\r
- fgJoystick[ ident ]->error = GL_FALSE;\r
- fgJoystick[ ident ]->num_axes = 0;\r
- fgJoystick[ ident ]->num_buttons = 0;\r
-\r
- if( numDevices < 0 )\r
- {\r
- /* do first-time init (since we can't over-ride jsInit, hmm */\r
- numDevices = 0;\r
-\r
- mach_port_t masterPort;\r
- IOReturn rv = IOMasterPort( bootstrap_port, &masterPort );\r
- if( rv != kIOReturnSuccess )\r
- {\r
- fgWarning( "error getting master Mach port" );\r
- return;\r
- }\r
- fghJoystickFindDevices( masterPort );\r
- }\r
-\r
- if ( ident >= numDevices )\r
- {\r
- fgJoystick[ ident ]->error = GL_TRUE;\r
- return;\r
- }\r
-\r
- /* get the name now too */\r
- CFDictionaryRef properties = getCFProperties( ioDevices[ ident ] );\r
- CFTypeRef ref = CFDictionaryGetValue( properties,\r
- CFSTR( kIOHIDProductKey ) );\r
- if (!ref)\r
- ref = CFDictionaryGetValue(properties, CFSTR( "USB Product Name" ) );\r
-\r
- if( !ref ||\r
- !CFStringGetCString( ( CFStringRef )ref, name, 128,\r
- CFStringGetSystemEncoding( ) ) )\r
- {\r
- fgWarning( "error getting device name" );\r
- name[ 0 ] = '\0';\r
- }\r
-#endif\r
-\r
-#if TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE)\r
- switch( ident )\r
- {\r
- case 0:\r
- fgJoystick[ ident ]->js_id = JOYSTICKID1;\r
- fgJoystick[ ident ]->error = GL_FALSE;\r
- break;\r
- case 1:\r
- fgJoystick[ ident ]->js_id = JOYSTICKID2;\r
- fgJoystick[ ident ]->error = GL_FALSE;\r
- break;\r
- default:\r
- fgJoystick[ ident ]->num_axes = 0;\r
- fgJoystick[ ident ]->error = GL_TRUE;\r
- return;\r
- }\r
-#endif\r
\r
-#if TARGET_HOST_POSIX_X11\r
-# if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
+void fgPlatformJoystickInit( SFG_Joystick *fgJoystick[], int ident )\r
+{\r
+#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
fgJoystick[ ident ]->id = ident;\r
fgJoystick[ ident ]->error = GL_FALSE;\r
\r
else\r
snprintf( fgJoystick[ ident ]->os->fname, sizeof(fgJoystick[ ident ]->os->fname), "%s%d", UHIDDEV,\r
ident - USB_IDENT_OFFSET );\r
-# elif defined( __linux__ )\r
+#elif defined( __linux__ )\r
fgJoystick[ ident ]->id = ident;\r
fgJoystick[ ident ]->error = GL_FALSE;\r
\r
\r
if( access( fgJoystick[ ident ]->fname, F_OK ) != 0 )\r
snprintf( fgJoystick[ ident ]->fname, sizeof(fgJoystick[ ident ]->fname), "/dev/js%d", ident );\r
-# endif\r
#endif\r
-\r
- fghJoystickOpen( fgJoystick[ ident ] );\r
-}\r
-\r
-/*\r
- * Try initializing all the joysticks (well, both of them)\r
- */\r
-void fgInitialiseJoysticks ( void )\r
-{\r
- if( !fgState.JoysticksInitialised )\r
- {\r
- int ident ;\r
- for ( ident = 0; ident < MAX_NUM_JOYSTICKS; ident++ )\r
- fghJoystickInit( ident );\r
-\r
- fgState.JoysticksInitialised = GL_TRUE;\r
- }\r
-}\r
-\r
-/*\r
- *\r
- */\r
-\r
-#if TARGET_HOST_MACINTOSH\r
-void fgPlatformJoystickClose ( int ident )\r
-{\r
- ISpSuspend( );\r
- ISpStop( );\r
- ISpShutdown( );\r
}\r
-#endif\r
\r
-#if TARGET_HOST_MAC_OSX\r
-void fgPlatformJoystickClose ( int ident )\r
-{\r
- ( *( fgJoystick[ ident ]->hidDev ) )->\r
- close( fgJoystick[ ident ]->hidDev );\r
-}\r
-#endif\r
\r
-#if TARGET_HOST_POSIX_X11\r
void fgPlatformJoystickClose ( int ident )\r
{\r
#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
#endif\r
\r
\r
+\r
+\r
+\r
+\r
+static void fghJoystickOpen( SFG_Joystick* joy )\r
+{\r
+ /*\r
+ * Default values (for no joystick -- each conditional will reset the\r
+ * error flag)\r
+ */\r
+ joy->error = TRUE;\r
+ joy->num_axes = joy->num_buttons = 0;\r
+ joy->name[ 0 ] = '\0';\r
+\r
+ fgPlatformJoystickOpen ( joy );\r
+\r
+}\r
+\r
+/*\r
+ * This function replaces the constructor method in the JS library.\r
+ */\r
+static void fghJoystickInit( int ident )\r
+{\r
+ if( ident >= MAX_NUM_JOYSTICKS )\r
+ fgError( "Too large a joystick number: %d", ident );\r
+\r
+ if( fgJoystick[ ident ] )\r
+ fgError( "illegal attempt to initialize joystick device again" );\r
+\r
+ fgJoystick[ ident ] =\r
+ ( SFG_Joystick * )calloc( sizeof( SFG_Joystick ), 1 );\r
+\r
+ /* Set defaults */\r
+ fgJoystick[ ident ]->num_axes = fgJoystick[ ident ]->num_buttons = 0;\r
+ fgJoystick[ ident ]->error = GL_TRUE;\r
+\r
+ fgPlatformJoystickInit( fgJoystick, ident );\r
+\r
+ fghJoystickOpen( fgJoystick[ ident ] );\r
+}\r
+\r
+/*\r
+ * Try initializing all the joysticks (well, both of them)\r
+ */\r
+void fgInitialiseJoysticks ( void )\r
+{\r
+ if( !fgState.JoysticksInitialised )\r
+ {\r
+ int ident ;\r
+ for ( ident = 0; ident < MAX_NUM_JOYSTICKS; ident++ )\r
+ fghJoystickInit( ident );\r
+\r
+ fgState.JoysticksInitialised = GL_TRUE;\r
+ }\r
+}\r
+\r
+\r
void fgJoystickClose( void )\r
{\r
int ident ;\r