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

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

Joystick changes

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