comparison src/joystick/win32/SDL_mmjoystick.c @ 937:1e6366bde299

Date: Tue, 27 Jul 2004 17:14:00 +0200 From: "Eckhard Stolberg" Subject: Controller names in SDL for Windows I'm working on an Atari 2600 emulator for different systems that uses the SDL. Some time ago someone created an adaptor that lets you use your old Atari controllers with your computer through the USB port. Some of the Atari controllers require special handling by the emulator, so it would be nice, if it would be possible to detect if any of the controllers connected to the computer is this adaptor. SDL would allow that with the SDL_JoystickName function, but unfortunately it doesn't work properly on Windows. On Linux and MacOSX this function returns the name of the controller, but on Windows you'll only get the name of the joystick driver. Most joysticks nowadays use the generic Microsoft driver, so they all return the same name. In an old MSDN article (http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/dnarinput/html/msdn_extdirect.asp) Microsoft describes how to read out the OEM controller names from the registry. I have implemented this for the SDL controller handler on Windows, and now reading the joystick name works properly there too.
author Sam Lantinga <slouken@libsdl.org>
date Sat, 21 Aug 2004 03:45:58 +0000
parents d37179d10ccc
children fa2ce068b0b6
comparison
equal deleted inserted replaced
936:84f930aebaeb 937:1e6366bde299
35 #include "SDL_sysjoystick.h" 35 #include "SDL_sysjoystick.h"
36 #include "SDL_joystick_c.h" 36 #include "SDL_joystick_c.h"
37 37
38 #include <windows.h> 38 #include <windows.h>
39 #include <mmsystem.h> 39 #include <mmsystem.h>
40 #include <regstr.h>
40 41
41 #define MAX_JOYSTICKS 16 42 #define MAX_JOYSTICKS 16
42 #define MAX_AXES 6 /* each joystick can have up to 6 axes */ 43 #define MAX_AXES 6 /* each joystick can have up to 6 axes */
43 #define MAX_BUTTONS 32 /* and 32 buttons */ 44 #define MAX_BUTTONS 32 /* and 32 buttons */
44 #define AXIS_MIN -32768 /* minimum value for axis coordinate */ 45 #define AXIS_MIN -32768 /* minimum value for axis coordinate */
49 50
50 51
51 /* array to hold joystick ID values */ 52 /* array to hold joystick ID values */
52 static UINT SYS_JoystickID[MAX_JOYSTICKS]; 53 static UINT SYS_JoystickID[MAX_JOYSTICKS];
53 static JOYCAPS SYS_Joystick[MAX_JOYSTICKS]; 54 static JOYCAPS SYS_Joystick[MAX_JOYSTICKS];
55 static char *SYS_JoystickNames[MAX_JOYSTICKS];
54 56
55 /* The private structure used to keep track of a joystick */ 57 /* The private structure used to keep track of a joystick */
56 struct joystick_hwdata 58 struct joystick_hwdata
57 { 59 {
58 /* joystick ID */ 60 /* joystick ID */
68 70
69 /* Convert a win32 Multimedia API return code to a text message */ 71 /* Convert a win32 Multimedia API return code to a text message */
70 static void SetMMerror(char *function, int code); 72 static void SetMMerror(char *function, int code);
71 73
72 74
75 static char *GetJoystickName(const char *szRegKey)
76 {
77 /* added 7/24/2004 by Eckhard Stolberg */
78 /*
79 see if there is a joystick for the current
80 index (1-16) listed in the registry
81 */
82 char *name = NULL;
83 HKEY hKey;
84 DWORD regsize;
85 LONG regresult;
86 unsigned char regkey[256];
87 unsigned char regvalue[256];
88 unsigned char regname[256];
89
90 sprintf(regkey, "%s\\%s\\%s",
91 REGSTR_PATH_JOYCONFIG,
92 szRegKey,
93 REGSTR_KEY_JOYCURR);
94 regresult = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
95 (LPTSTR) &regkey, 0, KEY_READ, &hKey);
96 if (regresult == ERROR_SUCCESS)
97 {
98 /*
99 find the registry key name for the
100 joystick's properties
101 */
102 regsize = sizeof(regname);
103 sprintf(regvalue,
104 "Joystick%d%s", i+1,
105 REGSTR_VAL_JOYOEMNAME);
106 regresult = RegQueryValueExA(hKey,
107 regvalue, 0, 0, (LPBYTE) &regname,
108 (LPDWORD) &regsize);
109 RegCloseKey(hKey);
110 if (regresult == ERROR_SUCCESS)
111 {
112 /* open that registry key */
113 sprintf(regkey, "%s\\%s",
114 REGSTR_PATH_JOYOEM, regname);
115 regresult = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
116 regkey, 0, KEY_READ, &hKey);
117 if (regresult == ERROR_SUCCESS)
118 {
119 /* find the size for the OEM name text */
120 regsize = sizeof(regvalue);
121 regresult =
122 RegQueryValueExA(hKey,
123 REGSTR_VAL_JOYOEMNAME,
124 0, 0, NULL,
125 (LPDWORD) &regsize);
126 if (regresult == ERROR_SUCCESS)
127 {
128 /*
129 allocate enough memory
130 for the OEM name text ...
131 */
132 name = (char *) malloc(regsize);
133 /* ... and read it from the registry */
134 regresult =
135 RegQueryValueExA(hKey,
136 REGSTR_VAL_JOYOEMNAME, 0, 0,
137 (LPBYTE) name,
138 (LPDWORD) &regsize);
139 RegCloseKey(hKey);
140 }
141 }
142 }
143 }
144 return(name);
145 }
146
73 /* Function to scan the system for joysticks. 147 /* Function to scan the system for joysticks.
74 * This function should set SDL_numjoysticks to the number of available 148 * This function should set SDL_numjoysticks to the number of available
75 * joysticks. Joystick 0 should be the system default joystick. 149 * joysticks. Joystick 0 should be the system default joystick.
76 * It should return 0, or -1 on an unrecoverable fatal error. 150 * It should return 0, or -1 on an unrecoverable fatal error.
77 */ 151 */
92 } 166 }
93 167
94 168
95 for ( i = 0; i < MAX_JOYSTICKS; i++ ) { 169 for ( i = 0; i < MAX_JOYSTICKS; i++ ) {
96 SYS_JoystickID[i] = JOYSTICKID1 + i; 170 SYS_JoystickID[i] = JOYSTICKID1 + i;
171 SYS_JoystickNames[i] = NULL;
97 } 172 }
98 173
99 174
100 for ( i = 0; (i < maxdevs); ++i ) { 175 for ( i = 0; (i < maxdevs); ++i ) {
101 176
108 if ( result == JOYERR_NOERROR ) { 183 if ( result == JOYERR_NOERROR ) {
109 result = joyGetDevCaps(SYS_JoystickID[i], &joycaps, sizeof(joycaps)); 184 result = joyGetDevCaps(SYS_JoystickID[i], &joycaps, sizeof(joycaps));
110 if ( result == JOYERR_NOERROR ) { 185 if ( result == JOYERR_NOERROR ) {
111 SYS_JoystickID[numdevs] = SYS_JoystickID[i]; 186 SYS_JoystickID[numdevs] = SYS_JoystickID[i];
112 SYS_Joystick[numdevs] = joycaps; 187 SYS_Joystick[numdevs] = joycaps;
188 SYS_JoystickName[numdevs] = GetJoystickName(joycaps.szRegKey);
113 numdevs++; 189 numdevs++;
114 } 190 }
115 } 191 }
116 } 192 }
117 return(numdevs); 193 return(numdevs);
118 } 194 }
119 195
120 /* Function to get the device-dependent name of a joystick */ 196 /* Function to get the device-dependent name of a joystick */
121 const char *SDL_SYS_JoystickName(int index) 197 const char *SDL_SYS_JoystickName(int index)
122 { 198 {
123 /***-> test for invalid index ? */ 199 if ( SYS_JoystickNames[index] != NULL ) {
124 return(SYS_Joystick[index].szPname); 200 return(SYS_JoystickNames[index]);
201 } else {
202 return(SYS_Joystick[index].szPname);
203 }
125 } 204 }
126 205
127 /* Function to open a joystick for use. 206 /* Function to open a joystick for use.
128 The joystick to open is specified by the index field of the joystick. 207 The joystick to open is specified by the index field of the joystick.
129 This should fill the nbuttons and naxes fields of the joystick structure. 208 This should fill the nbuttons and naxes fields of the joystick structure.
290 } 369 }
291 370
292 /* Function to perform any system-specific joystick related cleanup */ 371 /* Function to perform any system-specific joystick related cleanup */
293 void SDL_SYS_JoystickQuit(void) 372 void SDL_SYS_JoystickQuit(void)
294 { 373 {
295 return; 374 int i;
375 for (i = 0; i < MAX_JOYSTICKS; i++) {
376 if ( SYS_JoystickNames[i] != NULL ) {
377 free(SYS_JoystickNames[i]);
378 }
379 }
296 } 380 }
297 381
298 382
299 /* implementation functions */ 383 /* implementation functions */
300 void SetMMerror(char *function, int code) 384 void SetMMerror(char *function, int code)