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

Last change on this file since 5472 was 5472, checked in by sandervl, 24 years ago

compile fix

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