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

Last change on this file since 588 was 588, checked in by phaller, 26 years ago

Add: added ODINWRAP support for WINMM

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