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

Last change on this file since 10367 was 8470, checked in by sandervl, 23 years ago

added debug wrappers (.def)

File size: 12.3 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 _Optlink 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 _Optlink 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.