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

Last change on this file since 3830 was 2812, checked in by sandervl, 26 years ago

Added new logging feature + fixed waveout query format bug

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