+# include <windows.h>\r
+# include <mmsystem.h>\r
+# include <regstr.h>\r
+\r
+\r
+\r
+/* Inspired by\r
+ http://msdn.microsoft.com/archive/en-us/dnargame/html/msdn_sidewind3d.asp\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
+{\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
+\r
+ if ( lr != ERROR_SUCCESS ) return 0;\r
+\r
+ /* Get OEM Name */\r
+ dwcb = buf_sz;\r
+\r
+ lr = RegQueryValueEx ( hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, (LPBYTE) buf,\r
+ &dwcb );\r
+ RegCloseKey ( hKey );\r
+\r
+ if ( lr != ERROR_SUCCESS ) return 0;\r
+\r
+ return 1;\r
+}\r
+\r
+\r
+void fgPlatformJoystickOpen( SFG_Joystick* joy )\r
+{\r
+ int i = 0;\r
+\r
+ joy->js.dwFlags = JOY_RETURNALL;\r
+ joy->js.dwSize = sizeof( joy->js );\r
+\r
+ memset( &joy->jsCaps, 0, sizeof( joy->jsCaps ) );\r
+\r
+ joy->error =\r
+ ( joyGetDevCaps( joy->js_id, &joy->jsCaps, sizeof( joy->jsCaps ) ) !=\r
+ JOYERR_NOERROR );\r
+\r
+ if( joy->jsCaps.wNumAxes == 0 )\r
+ {\r
+ joy->num_axes = 0;\r
+ joy->error = GL_TRUE;\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
+\r
+ /* Guess all the rest judging on the axes extremals */\r
+ for( i = 0; i < joy->num_axes; i++ )\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
+ }\r
+}\r
+\r
+\r
+\r