source: trunk/src/winmm/joy.cpp@ 21927

Last change on this file since 21927 was 21927, checked in by dmik, 14 years ago

Fix build breaks with the newest GCC 4.4.6 from GIT.

In particular, GCC is now strict about matching the calling convention
of the prototype (argument) and the real function used.

File size: 12.2 KB
Line 
1/* $Id: joy.cpp,v 1.10 2002-05-22 15:50:24 sandervl Exp $ */
2/*
3 * Odin Joystick apis
4 *
5 * Copyright 1999 Przemyslaw Dobrowolski <dobrawka@asua.org.pl>
6 *
7 *
8 * Project Odin Software License can be found in LICENSE.TXT
9 *
10 */
11
12/****************************************************************************
13 * Includes *
14 ****************************************************************************/
15
16#include <os2win.h>
17#include <mmsystem.h>
18#include <odinwrap.h>
19#include <misc.h>
20#include <string.h>
21#include <stdlib.h>
22#include <process.h>
23
24#include "winmm.h"
25#include "os2timer.h"
26#include "joyos2.h"
27
28#define DBG_LOCALLOG DBG_joy
29#include "dbglocal.h"
30
31#define MAXJOYDRIVERS 2
32
33static INT aJoyThreshold[MAXJOYDRIVERS] = {0,0};
34static BOOL aJoyCaptured[MAXJOYDRIVERS] = {FALSE,FALSE};
35
36void joySendMessages(void *pData);
37
38LONG JoyGetPos(HANDLE hGame, UINT wID, LPJOYINFO lpInfo)
39{
40 GAME_STATUS_STRUCT gs;
41
42 if (wID >= MAXJOYDRIVERS) return (JOYERR_PARMS);
43
44 if (hGame==0) return (JOYERR_NOCANDO);
45
46 JoyGetStatus( hGame, &gs );
47
48 if (wID==JOYSTICKID1)
49 {
50 if (gs.curdata.A.x < 1024)
51 lpInfo->wXpos = gs.curdata.A.x * 64;
52 else
53 lpInfo->wXpos = 65535; // _NOT_ 65536!!! ;-)
54
55 if (gs.curdata.A.y < 1024)
56 lpInfo->wYpos = gs.curdata.A.y * 64;
57 else
58 lpInfo->wYpos = 65535; // _NOT_ 65536!!! ;-)
59
60 lpInfo->wZpos = 0;
61 lpInfo->wButtons = 0;
62 if ( (gs.curdata.butMask & JOY_BUT1_BIT) == 0 )
63 lpInfo->wButtons |= JOY_BUTTON1;
64
65 if ( (gs.curdata.butMask & JOY_BUT2_BIT) == 0 )
66 lpInfo->wButtons |= JOY_BUTTON2;
67 }
68
69 if (wID==JOYSTICKID2)
70 {
71 if (gs.curdata.B.x < 1024)
72 lpInfo->wXpos = gs.curdata.A.x * 64;
73 else
74 lpInfo->wXpos = 65535; // _NOT_ 65536!!!
75
76 if (gs.curdata.B.y < 1024)
77 lpInfo->wYpos = gs.curdata.A.x * 64;
78 else
79 lpInfo->wYpos = 65535; // _NOT_ 65536!!!
80
81 lpInfo->wZpos = 0;
82 lpInfo->wButtons = 0;
83 if ( (gs.curdata.butMask & JOY_BUT3_BIT) == 0 )
84 lpInfo->wButtons |= JOY_BUTTON1;
85
86 if ( (gs.curdata.butMask & JOY_BUT4_BIT) == 0 )
87 lpInfo->wButtons |= JOY_BUTTON2;
88 }
89
90 return (0);
91}
92
93/**
94 * Get number of installed joysticks
95 * @status Completely Done
96 * @author Przemyslaw Dobrowolski [Tue, 1999/06/29 10:00]
97 */
98UINT WINAPI joyGetNumDevs()
99{
100 HANDLE hJoy;
101 GAME_PARM_STRUCT gameInfo;
102 WORD rc;
103 INT joy_count = 0;
104
105 rc=JoyOpen(&hJoy);
106 if ( rc==0 )
107 {
108 JoyGetParams(hJoy,&gameInfo);
109 JoyClose(hJoy);
110 if ((gameInfo.useA == FALSE) && (gameInfo.useB == FALSE))
111 joy_count = 0;
112 else if (gameInfo.useA == FALSE)
113 joy_count = 1;
114 else if (gameInfo.useB == FALSE)
115 joy_count = 1;
116 else
117 joy_count = 2;
118
119 dprintf(("WINMM:joyGetNumDevs = %d\n",joy_count));
120 }
121 else
122 // No GAMEDD$ driver
123 dprintf(("WINMM: joyGetNumDevs - No GAMEDD$ driver\n"));
124
125 return(joy_count);
126}
127
128/**
129 * Get Joystick capatibities (Unicode)
130 * @status Completely
131 * @author Przemyslaw Dobrowolski [Tue, 1999/06/29 09:40]
132 */
133MMRESULT WINAPI joyGetDevCapsW(UINT wID, LPJOYCAPSW lpCaps, UINT wSize)
134{
135 if (wID >= MAXJOYDRIVERS) return JOYERR_PARMS;
136
137 if (JoyInstalled(wID) == 0)
138 {
139 lpCaps->wMid = MM_MICROSOFT;
140 lpCaps->wPid = MM_PC_JOYSTICK;
141 lstrcpyW(lpCaps->szPname, (LPWSTR)L"OS/2 Joystick");
142 lpCaps->wXmin = 0;
143 lpCaps->wXmax = 0xffff;
144 lpCaps->wYmin = 0;
145 lpCaps->wYmax = 0xffff;
146 // OS/2 Joystick unknown Z-axes
147 lpCaps->wZmin = 0;
148 lpCaps->wZmax = 0;
149 lpCaps->wNumButtons = 2; // FIXME: OS/2 can use Joysticks with 4 buttons?
150 lpCaps->wPeriodMin = 10;
151 lpCaps->wPeriodMax = 1000;
152 lpCaps->wRmin = 0;
153 lpCaps->wRmax = 0;
154 lpCaps->wUmin = 0;
155 lpCaps->wUmax = 0;
156 lpCaps->wVmin = 0;
157 lpCaps->wVmax = 0;
158 lpCaps->wCaps = 0;
159 lpCaps->wMaxAxes = 4;
160 lpCaps->wNumAxes = 2;
161 lpCaps->wMaxButtons = 2;
162 lpCaps->szRegKey[0] = 0;
163 lpCaps->szOEMVxD[0] = 0;
164 dprintf(("OK!!!\n"));
165 return JOYERR_NOERROR;
166 }
167 else
168 return MMSYSERR_NODRIVER;
169}
170
171/**
172 * Get Joystick capatibities (Ascii)
173 * @status Completely Done
174 * @author Przemyslaw Dobrowolski [Tue, 1999/06/29 09:00]
175 */
176MMRESULT WINAPI joyGetDevCapsA(UINT wID, LPJOYCAPSA lpCaps, UINT wSize)
177{
178 if (wID >= MAXJOYDRIVERS) return JOYERR_PARMS;
179
180 if (JoyInstalled(wID) == 0)
181 {
182 lpCaps->wMid = MM_MICROSOFT;
183 lpCaps->wPid = MM_PC_JOYSTICK;
184 strcpy(lpCaps->szPname, "OS/2 Joystick"); /* joystick product name */
185 lpCaps->wXmin = 0;
186 lpCaps->wXmax = 0xffff;
187 lpCaps->wYmin = 0;
188 lpCaps->wYmax = 0xffff;
189 // OS/2 Joystick unknown Z-axes
190 lpCaps->wZmin = 0;
191 lpCaps->wZmax = 0;
192 lpCaps->wNumButtons = 2; // FIXME: OS/2 can use Joysticks with 4 buttons?
193 lpCaps->wPeriodMin = 10;
194 lpCaps->wPeriodMax = 1000;
195 lpCaps->wRmin = 0;
196 lpCaps->wRmax = 0;
197 lpCaps->wUmin = 0;
198 lpCaps->wUmax = 0;
199 lpCaps->wVmin = 0;
200 lpCaps->wVmax = 0;
201 lpCaps->wCaps = 0;
202 lpCaps->wMaxAxes = 4;
203 lpCaps->wNumAxes = 2;
204 lpCaps->wMaxButtons = 2;
205 strcpy(lpCaps->szRegKey,"");
206 strcpy(lpCaps->szOEMVxD,"");
207 return JOYERR_NOERROR;
208 }
209 else
210 return MMSYSERR_NODRIVER;
211}
212
213/**
214 * Get the extended actual joystick position
215 * @status Partially
216 * @author Przemyslaw Dobrowolski [Tue, 1999/06/29 23:42]
217 * @remark Not all functions are functionally but Quake2
218 * running with this function.
219 */
220MMRESULT WINAPI joyGetPosEx(UINT uJoyID, LPJOYINFOEX pji)
221{
222 JOYINFO ji;
223 HANDLE hGamePort;
224 GAME_CALIB_STRUCT gc;
225 DWORD rc;
226
227 if (uJoyID >= MAXJOYDRIVERS) return JOYERR_PARMS;
228
229 rc=JoyInstalled(uJoyID);
230
231 if (rc) return (rc);
232
233 rc=JoyOpen(&hGamePort);
234
235 if (rc) return (MMSYSERR_NODRIVER);
236
237 JoyGetPos(hGamePort,uJoyID,&ji);
238 JoyGetCalValues(hGamePort,&gc);
239
240 JoyClose(hGamePort);
241
242 if (pji->dwSize>11) pji->dwXpos = 0;
243 if (pji->dwSize>15) pji->dwYpos = 0;
244 if (pji->dwSize>19) pji->dwZpos = 0;// not supported for OS/2 driver!
245 if (pji->dwSize>23) pji->dwRpos = 0;// not supported for OS/2 driver!
246 if (pji->dwSize>27) pji->dwUpos = 0;// not supported for OS/2 driver!
247 if (pji->dwSize>31) pji->dwVpos = 0;// not supported for OS/2 driver!
248 if (pji->dwSize>35) pji->dwButtons = 0;
249 if (pji->dwSize>35) pji->dwButtonNumber = 0;
250 if (pji->dwSize>43) pji->dwPOV = -1;// FIXME: Win98 returns that code!!! Wrong?
251 if (pji->dwSize>47) pji->dwReserved1 = 0;// FIXME!
252 if (pji->dwSize>51) pji->dwReserved2 = 0;// FIXME!
253
254 if (pji->dwFlags & JOY_RETURNCENTERED)
255 {
256 if (uJoyID==JOYSTICKID1)
257 {
258 if (pji->dwSize>11)
259 if (gc.Ax.centre < 1024)
260 pji->dwXpos = gc.Ax.centre * 64;
261 else
262 pji->dwXpos = 65535; // _NOT_ 65536!!! ;-)
263
264 if (pji->dwSize>15)
265 if (gc.Ay.centre < 1024)
266 pji->dwYpos = gc.Ay.centre * 64;
267 else
268 pji->dwYpos = 65535; // _NOT_ 65536!!! ;-)
269 }
270 if (uJoyID==JOYSTICKID2)
271 {
272 if (pji->dwSize>11)
273 if (gc.Ax.centre < 1024)
274 pji->dwXpos = gc.Bx.centre * 64;
275 else
276 pji->dwXpos = 65535; // _NOT_ 65536!!! ;-)
277
278 if (pji->dwSize>15)
279 if (gc.Ay.centre < 1024)
280 pji->dwYpos = gc.By.centre * 64;
281 else
282 pji->dwYpos = 65535; // _NOT_ 65536!!! ;-)
283 }
284 }
285
286 if (pji->dwFlags & JOY_RETURNBUTTONS)
287 {
288 if (pji->dwSize>35) pji->dwButtons = ji.wButtons;
289 if (pji->dwSize>35) pji->dwButtonNumber = (ji.wButtons & 2) ? 2 : 1;
290 }
291
292 if (pji->dwFlags & JOY_RETURNX)
293 if (pji->dwSize>11) pji->dwXpos = ji.wXpos;
294
295 if (pji->dwFlags & JOY_RETURNY)
296 if (pji->dwSize>11) pji->dwYpos = ji.wXpos;
297
298 return JOYERR_NOERROR;
299}
300
301/**
302 * Get the actual joystick position
303 * @status Completely implemented
304 * @author Przemyslaw Dobrowolski [Tue, 1999/06/29 09:00]
305 */
306MMRESULT WINAPI joyGetPos(UINT uJoyID, LPJOYINFO pji)
307{
308 HANDLE hGame;
309 MMRESULT rc;
310 if (uJoyID >= MAXJOYDRIVERS) return JOYERR_PARMS;
311
312 rc=JoyInstalled(uJoyID);
313
314 if (rc) return (rc);
315
316 if (JoyOpen(&hGame)) return (MMSYSERR_NODRIVER);
317
318 rc=JoyGetPos(hGame,uJoyID,pji);
319
320 JoyClose(hGame);
321
322 return JOYERR_NOERROR;
323}
324
325/**
326 *
327 * @status Completely implemented. ?
328 * @author Przemyslaw Dobrowolski [Tue, 1999/06/29 09:00]
329 */
330MMRESULT WINAPI joyGetThreshold(UINT wID, LPUINT lpThreshold)
331{
332 dprintf(("WINMM:joyGetThreshold %d %X\n",wID, lpThreshold));
333
334 if (wID >= MAXJOYDRIVERS) return JOYERR_PARMS;
335
336 *lpThreshold = aJoyThreshold[wID];
337
338 return JOYERR_NOERROR;
339}
340
341/**
342 * @status Completely implemented?
343 * @author Przemyslaw Dobrowolski [Tue, 1999/06/29 09:00]
344 */
345MMRESULT WINAPI joySetThreshold(UINT wID, UINT wThreshold)
346{
347 if (wID >= MAXJOYDRIVERS) return JOYERR_PARMS;
348
349 aJoyThreshold[wID] = wThreshold;
350
351 return JOYERR_NOERROR;
352}
353
354typedef struct _JOYTHREADOPT
355{
356 HWND hWnd;
357 UINT wID;
358 UINT wPeriod;
359 BOOL bChanged;
360} JOYTHREADOPT;
361typedef JOYTHREADOPT *PJOYTHREADOPT;
362
363/**
364 * Start joystick movescapturing,
365 * @status Completely implemented?
366 * @author Przemyslaw Dobrowolski [Tue, 1999/06/29 09:00]
367 */
368MMRESULT WINAPI joySetCapture(HWND hWnd, UINT wID, UINT wPeriod, BOOL bChanged)
369{
370 JOYTHREADOPT *newthr;
371 INT iThreadId;
372 DWORD rc;
373
374 if (wID >= MAXJOYDRIVERS) return JOYERR_PARMS;
375
376 rc=JoyInstalled(wID);
377 if (rc != JOYERR_NOERROR) return (rc);
378
379 newthr=(PJOYTHREADOPT)malloc(sizeof(JOYTHREADOPT));
380 newthr->hWnd = hWnd;
381 newthr->wID = wID;
382 newthr->wPeriod = wPeriod;
383 newthr->bChanged = bChanged;
384 aJoyCaptured[wID] = TRUE;
385 iThreadId = _beginthread(joySendMessages, NULL, 0x4000, (void *)newthr);
386 if (iThreadId!=0)
387 {
388 dprintf(("WINMM:joySetCapture ThreadID = %d\n", iThreadId));
389 return JOYERR_NOERROR;
390 }
391 else
392 dprintf(("WINMM:joySetCapture Thread not created!!!!\n"));
393
394 return JOYERR_NOCANDO; /* FIXME: what should be returned ? */
395}
396
397/**
398 * Stop capturing joystick moves.
399 * @status Completely implemented?
400 * @author Przemyslaw Dobrowolski [Tue, 1999/06/29 09:00]
401 * @remark Must be rewritten.
402 */
403MMRESULT WINAPI joyReleaseCapture(UINT wID)
404{
405 // TODO: Semaphores or waiting for thread...
406 if (wID >= MAXJOYDRIVERS) return JOYERR_PARMS;
407
408 if (aJoyCaptured[wID] != TRUE) return JOYERR_NOCANDO;
409
410 aJoyCaptured[wID] = FALSE;
411
412 return JOYERR_NOERROR;
413}
414
415/**
416 * @status Stub
417 * @author Przemyslaw Dobrowolski [Tue, 1999/06/29 09:00]
418 */
419MMRESULT WINAPI joyConfigChanged(DWORD dwFlags)
420{
421 return JOYERR_NOERROR;
422}
423
424
425// ***************************************************************************
426// * [Internal]
427// * Name : _Optlink joySendMessages
428// * Purpose : Capturing thread
429// * Status : Done
430// *
431// * Author : Przemyslaw Dobrowolski [Tue, 1999/06/29 09:00]
432// ***************************************************************************
433void joySendMessages(void *pData)
434{
435 PJOYTHREADOPT opt = (PJOYTHREADOPT) pData;
436 JOYINFO ji;
437 JOYINFO jiOld;
438 HANDLE hGame;
439 DWORD wTest;
440 INT rc;
441
442 rc=JoyOpen(&hGame);
443
444 if (rc) aJoyCaptured[opt->wID]=FALSE;
445
446 rc=JoyGetPos( hGame, opt->wID, &ji );
447
448 if (rc) aJoyCaptured[opt->wID]=FALSE;
449
450 jiOld=ji;
451
452 while (aJoyCaptured[opt->wID])
453 {
454 rc=JoyGetPos( hGame, opt->wID, &ji );
455
456 if (rc) aJoyCaptured[opt->wID]=FALSE;
457
458 wTest=MAKELONG(ji.wXpos, ji.wYpos);
459 if ((ji.wXpos!=jiOld.wXpos) || (ji.wYpos!=jiOld.wXpos))
460 PostMessageA(opt->hWnd, MM_JOY1MOVE + opt->wID, ji.wButtons, wTest);
461
462 if (ji.wButtons != jiOld.wButtons)
463 { UINT ButtonChanged = (ji.wButtons ^ jiOld.wButtons)<<8;
464
465 if (jiOld.wButtons < ji.wButtons)
466 PostMessageA(opt->hWnd, MM_JOY1BUTTONDOWN + opt->wID, ButtonChanged, MAKELONG(ji.wXpos, ji.wYpos));
467 else if (jiOld.wButtons > ji.wButtons)
468 PostMessageA(opt->hWnd, MM_JOY1BUTTONUP + opt->wID, ButtonChanged, MAKELONG(ji.wXpos, ji.wYpos));
469
470 }
471 Sleep(opt->wPeriod+1); // Fixme!!!
472 jiOld=ji;
473 }
474 free(opt);
475 dprintf(("WINMM:Joystick-internal->joySendMessages ended!\n"));
476 // Huh... We must close thread ;-)
477 _endthread();
478}
479
Note: See TracBrowser for help on using the repository browser.