Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

852 lines
25 KiB

4 years ago
  1. /******************************************************************************
  2. Copyright (C) Microsoft Corporation 1985-1992. All rights reserved.
  3. Title: joy.c - MMSYSTEM Joystick interface code
  4. Version: 1.00
  5. Date: 10-Jun-1990
  6. Author: GLENNS ROBWI
  7. ------------------------------------------------------------------------------
  8. Change log:
  9. DATE REV DESCRIPTION
  10. -------- ----- -----------------------------------------------------------
  11. 2/7/90 Changes to avoid a bug in Windows which won't allow
  12. FreeLibrary to be called during WEP.
  13. 10/11/90 .61 Use windows timer + general cleanup
  14. 20-Aug-92 Convert to Windows NT
  15. *****************************************************************************/
  16. #define UNICODE
  17. #include "winmmi.h"
  18. #include <stdlib.h>
  19. extern HANDLE mmDrvOpen(LPWSTR szAlias);
  20. static void joyGetCalibration(void);
  21. /****************************************************************************
  22. strings
  23. ****************************************************************************/
  24. WSZCODE wszJoystick[] = L"joystick";
  25. WSZCODE wszJoystickDrv[]= L"joystick.drv";
  26. static WSZCODE wszJoyKey[] = L"JoyCal";
  27. /****************************************************************************
  28. Joystick Capture Internal Structure
  29. ****************************************************************************/
  30. #define Threshold(w1, w2) (UINT)(w1 > w2 ? w1-w2 : w2-w1)
  31. #if 0
  32. typedef struct joycapture_tag {
  33. HWND hWnd;
  34. UINT uPeriod;
  35. BOOL bChanged;
  36. UINT wThreshold;
  37. UINT uIDEvent;
  38. } JOYCAPTURE;
  39. #endif
  40. typedef struct tagJoyCapture {
  41. // HMD hmd;
  42. HWND hwnd;
  43. UINT uPeriod;
  44. BOOL fChanged;
  45. UINT uThreshold;
  46. UINT uIDEvent;
  47. UINT uJoyID;
  48. DWORD dwFlags;
  49. JOYINFOEX ji;
  50. // struct tagJoyCapture *pjcNext;
  51. } JOYCAPTURE, * PJOYCAPTURE;
  52. #define iJoyMax 2
  53. // !!! Code assumes these constants equal 0 and 1
  54. #if JOYSTICKID1 != 0
  55. ERROR IN ASSUMMED CONSTANT
  56. #endif
  57. #if JOYSTICKID2 != 1
  58. ERROR IN ASSUMMED CONSTANT
  59. #endif
  60. /****************************************************************************
  61. Local data
  62. ****************************************************************************/
  63. static JOYCAPTURE JoyCapture[iJoyMax];
  64. static HDRVR hDrvJoy[iJoyMax];
  65. static UINT uNumDevs;
  66. void CALLBACK joyPollCallback(HWND hWnd, UINT wMsg, UINT uIDEvent, DWORD dwTime);
  67. /****************************************************************************
  68. @doc INTERNAL
  69. @api void | joyGetCalibration | Retrieve and set calibration from
  70. [joystick.drv] section of system.ini file.
  71. ****************************************************************************/
  72. // !!! need to do clean up of strings in all of mmsystem
  73. static void joyGetCalibration(void)
  74. {
  75. WCHAR wszKeyName[sizeof(wszJoyKey) / sizeof(WCHAR) + 1];
  76. #define hexval(h) (int)(h>=L'a'?h-L'a'+10:h-L'0')
  77. UINT val[6];
  78. UINT wDev,wVal;
  79. int hv;
  80. WCHAR c, wsz[80], *psz;
  81. for (wDev=0; wDev < uNumDevs; wDev++) {
  82. wsprintf(wszKeyName, L"%ls%d", wszJoyKey, wDev);
  83. if (winmmGetPrivateProfileString(wszJoystickDrv,
  84. wszKeyName,
  85. wszNull,
  86. wsz,
  87. sizeof(wsz) / sizeof(WCHAR),
  88. wszSystemIni)) {
  89. CharLower(wsz);
  90. for (psz=wsz,wVal=0; c = *psz, wVal < 6; psz++)
  91. {
  92. if (c != L' ')
  93. {
  94. hv=0;
  95. do
  96. {
  97. hv = (hv << 4) + hexval(c);
  98. } while ((c=*++psz) && (c!=L' '));
  99. val[wVal++] = (UINT)hv;
  100. }
  101. }
  102. joySetCalibration (wDev,val+0,val+1,val+2,val+3,val+4,val+5);
  103. }
  104. }
  105. }
  106. /****************************************************************************
  107. @doc INTERNAL
  108. @api BOOL | JoyInit | This function initializes the joystick services.
  109. @rdesc The return value is TRUE if the services are initialised, FALSE
  110. if an error occurs
  111. ****************************************************************************/
  112. BOOL JoyInit(void)
  113. {
  114. // joystick 0 - don't default to opening joystick.dll by calling
  115. // DrvOpen directly!
  116. if ((hDrvJoy[0] = mmDrvOpen(wszJoystick)) == NULL)
  117. return TRUE;
  118. // joystick 1
  119. hDrvJoy[1] = DrvOpen(wszJoystick, NULL, (LPARAM)1L);
  120. // Initialize joycapture...
  121. // Code relies on hWnd being NULL or an invalid window handle
  122. // if joystick is not captured.
  123. JoyCapture[0].hwnd = NULL;
  124. JoyCapture[1].hwnd = NULL;
  125. // Code relies on joystick threshold being initialized to a rational
  126. // value. 0 essentially turns threshold off - any change in joystick
  127. // position will be reported.
  128. JoyCapture[0].uThreshold= 0;
  129. JoyCapture[1].uThreshold= 0;
  130. JoyCapture[0].uIDEvent= 0;
  131. JoyCapture[1].uIDEvent= 0;
  132. // fChanged, and uPeriod do not need initializing.
  133. uNumDevs = (UINT)(DrvSendMessage(hDrvJoy[0], JDD_GETNUMDEVS, 0l, 0l));
  134. joyGetCalibration ();
  135. return TRUE;
  136. }
  137. /****************************************************************************
  138. @doc INTERNAL
  139. @api void | JoyTerminate | This function terminates the joystick services.
  140. @rdesc There is no return value.
  141. ****************************************************************************/
  142. #if 0 // totally unused
  143. void NEAR PASCAL JoyTerminate(void)
  144. {
  145. }
  146. #endif
  147. /****************************************************************************
  148. *
  149. * MMSYSTEM JOYSTICK API'S
  150. *
  151. ****************************************************************************/
  152. /****************************************************************************
  153. @doc EXTERNAL
  154. @api UINT | joyGetDevCaps | This function queries a joystick device to
  155. determine its capabilities.
  156. @parm UINT | uId | Identifies the device to be queried. This value
  157. is either JOYSTICKID1 or JOYSTICKID2.
  158. @parm LPJOYCAPS | lpCaps | Specifies a far pointer to a <t JOYCAPS>
  159. data structure. This structure is filled with information about the
  160. capabilities of the joystick device.
  161. @parm UINT | wSize | Specifies the size of the <t JOYCAPS> structure.
  162. @rdesc Returns JOYERR_NOERROR if successful. Otherwise, returns one of the
  163. following error codes:
  164. @flag MMSYSERR_NODRIVER | The joystick driver is not present.
  165. @flag JOYERR_PARMS | The specified joystick device ID <p uId> is invalid.
  166. @comm Use <f joyGetNumDevs> to determine the number of
  167. joystick devices supported by the driver.
  168. @xref joyGetNumDevs
  169. ****************************************************************************/
  170. MMRESULT APIENTRY joyGetDevCapsA(UINT id, LPJOYCAPSA lpCaps, UINT uSize)
  171. {
  172. JOYCAPSW CapsW;
  173. JOYCAPSA CapsA;
  174. MMRESULT mRc;
  175. V_WPOINTER(lpCaps, uSize, MMSYSERR_INVALPARAM);
  176. mRc = joyGetDevCapsW(id, &CapsW, sizeof(CapsW));
  177. if (mRc != MMSYSERR_NOERROR) {
  178. return mRc;
  179. }
  180. //
  181. // Copy product name (etc) into ASCII version
  182. //
  183. Iwcstombs(CapsA.szPname, CapsW.szPname, sizeof(CapsA.szPname));
  184. Iwcstombs(CapsA.szRegKey, CapsW.szRegKey, sizeof(CapsA.szRegKey));
  185. Iwcstombs(CapsA.szOEMVxD, CapsW.szOEMVxD, sizeof(CapsA.szOEMVxD));
  186. //
  187. // Copy the rest of the fields
  188. //
  189. CapsA.wMid = CapsW.wMid;
  190. CapsA.wPid = CapsW.wPid;
  191. CapsA.wXmin = CapsW.wXmin;
  192. CapsA.wXmax = CapsW.wXmax;
  193. CapsA.wYmin = CapsW.wYmin;
  194. CapsA.wYmax = CapsW.wYmax;
  195. CapsA.wZmin = CapsW.wZmin;
  196. CapsA.wZmax = CapsW.wZmax;
  197. CapsA.wNumButtons = CapsW.wNumButtons;
  198. CapsA.wPeriodMin = CapsW.wPeriodMin;
  199. CapsA.wPeriodMax = CapsW.wPeriodMax;
  200. CapsA.wRmin = CapsW.wRmin;
  201. CapsA.wRmax = CapsW.wRmax;
  202. CapsA.wUmin = CapsW.wUmin;
  203. CapsA.wUmax = CapsW.wUmax;
  204. CapsA.wVmin = CapsW.wVmin;
  205. CapsA.wVmax = CapsW.wVmax;
  206. CapsA.wCaps = CapsW.wCaps;
  207. CapsA.wMaxAxes = CapsW.wMaxAxes;
  208. CapsA.wNumAxes = CapsW.wNumAxes;
  209. CapsA.wMaxButtons = CapsW.wMaxButtons;
  210. //
  211. // Pass back as much data as the requestor asked for
  212. //
  213. CopyMemory(lpCaps, &CapsA, uSize);
  214. return MMSYSERR_NOERROR;
  215. }
  216. MMRESULT APIENTRY joyGetDevCapsW(UINT Id, LPJOYCAPSW lpCaps, UINT uSize)
  217. {
  218. V_WPOINTER(lpCaps, sizeof(JOYCAPS), MMSYSERR_INVALPARAM);
  219. if (!hDrvJoy[0])
  220. return MMSYSERR_NODRIVER;
  221. if (Id >= uNumDevs)
  222. return MMSYSERR_NODRIVER;
  223. return (UINT)(DrvSendMessage(hDrvJoy[Id],
  224. JDD_GETDEVCAPS,
  225. (LPARAM)lpCaps,
  226. (LPARAM)uSize));
  227. }
  228. /****************************************************************************
  229. @doc EXTERNAL
  230. @api UINT | joyGetNumDevs | This function returns the number of joystick
  231. devices supported by the system.
  232. @rdesc Returns the number of joystick devices supported by the joystick
  233. driver. If no driver is present, the function returns zero.
  234. @comm Use <f joyGetPos> to determine whether a given
  235. joystick is actually attached to the system. The <f joyGetPos> function returns
  236. a JOYERR_UNPLUGGED error code if the specified joystick is not connected.
  237. @xref joyGetDevCaps joyGetPos
  238. ****************************************************************************/
  239. UINT WINAPI joyGetNumDevs(void)
  240. {
  241. // Return 0 on error (Can't return JOYERR_NODRIVER
  242. // since no way to distinguish error code from valid count.)
  243. if (!hDrvJoy[0])
  244. return 0;
  245. return uNumDevs;
  246. }
  247. /****************************************************************************
  248. @doc EXTERNAL
  249. @api UINT | joyGetPos | This function queries for the position and button
  250. activity of a joystick device.
  251. @parm UINT | uId | Identifies the joystick device to be queried.
  252. This value is either JOYSTICKID1 or JOYSTICKID2.
  253. @parm LPJOYINFO | lpInfo | Specifies a far pointer to a <t JOYINFO>
  254. data structure. This structure is filled with information about the
  255. position and button activity of the joystick device.
  256. @rdesc Returns JOYERR_NOERROR if successful. Otherwise, returns one of the
  257. following error codes:
  258. @flag MMSYSERR_NODRIVER | The joystick driver is not present.
  259. @flag JOYERR_PARMS | The specified joystick device ID <p uId> is invalid.
  260. @flag JOYERR_UNPLUGGED | The specified joystick is not connected to the
  261. system.
  262. ****************************************************************************/
  263. MMRESULT APIENTRY joyGetPos(UINT uId, LPJOYINFO lpInfo)
  264. {
  265. V_WPOINTER(lpInfo, sizeof(JOYINFO), MMSYSERR_INVALPARAM);
  266. if (!hDrvJoy[0])
  267. return MMSYSERR_NODRIVER;
  268. if (uId >= uNumDevs)
  269. return JOYERR_PARMS;
  270. return (UINT)(DrvSendMessage(hDrvJoy[uId],
  271. JDD_GETPOS,
  272. (LPARAM)lpInfo,
  273. 0l));
  274. }
  275. /****************************************************************************
  276. @doc EXTERNAL
  277. @api MMRESULT | joyGetPosEx | Queries a joystick for its position and button
  278. activity.
  279. @parm UINT | uJoyID | Identifies the joystick device (JOYSTICKID1 or
  280. JOYSTICKID2) to be queried.
  281. @parm LPJOYINFOEX | pji | Specifies a far pointer to a <t JOYINFOEX>
  282. data structure. This structure is filled with information about the
  283. position and button activity of the joystick device.
  284. @rdesc Returns JOYERR_NOERROR if successful. Otherwise, returns one of the
  285. following error codes:
  286. @flag MMSYSERR_BADDEVICEID | The joystick driver is not present.
  287. @flag MMSYSERR_INVALPARAM | An invalid parameter was passed.
  288. @flag JOYERR_UNPLUGGED | The specified joystick is not connected to the
  289. system.
  290. ****************************************************************************/
  291. MMRESULT WINAPI joyGetPosEx(
  292. UINT uJoyID,
  293. LPJOYINFOEX pji)
  294. {
  295. V_WPOINTER(pji, sizeof(JOYINFOEX), MMSYSERR_INVALPARAM);
  296. if (pji->dwSize < sizeof(JOYINFOEX))
  297. return MMSYSERR_INVALPARAM;
  298. if (!hDrvJoy[0])
  299. return MMSYSERR_NODRIVER;
  300. if (uJoyID >= uNumDevs)
  301. return JOYERR_PARMS;
  302. return DrvSendMessage(hDrvJoy[uJoyID], JDD_GETPOSEX, (LPARAM)pji, 0);
  303. }
  304. /****************************************************************************
  305. @doc EXTERNAL
  306. @api UINT | joyGetThreshold | This function queries the current
  307. movement threshold of a joystick device.
  308. @parm UINT | uId | Identifies the joystick device to be queried.
  309. This value is either JOYSTICKID1 or JOYSTICKID2.
  310. @parm PUINT | lpwThreshold | Specifies a far pointer to a UINT variable
  311. that is filled with the movement threshold value.
  312. @rdesc Returns JOYERR_NOERROR if successful. Otherwise, returns one of the
  313. following error codes:
  314. @flag MMSYSERR_NODRIVER | The joystick driver is not present.
  315. @flag JOYERR_PARMS | The specified joystick device ID <p uId> is invalid.
  316. @comm The movement threshold is the distance the joystick must be
  317. moved before a WM_JOYMOVE message is sent to a window that has
  318. captured the device. The threshold is initially zero.
  319. @xref joySetThreshold
  320. ****************************************************************************/
  321. MMRESULT APIENTRY joyGetThreshold(UINT uId,PUINT lpwThreshold)
  322. {
  323. V_WPOINTER(lpwThreshold, sizeof(UINT), MMSYSERR_INVALPARAM);
  324. if (!hDrvJoy[0])
  325. return MMSYSERR_NODRIVER;
  326. if (uId >= uNumDevs)
  327. return MMSYSERR_INVALPARAM;
  328. *lpwThreshold = (JoyCapture[uId].uThreshold);
  329. return JOYERR_NOERROR;
  330. }
  331. /****************************************************************************
  332. @doc EXTERNAL
  333. @api UINT | joyReleaseCapture | This function releases the capture
  334. set by <f joySetCapture> on the specified joystick device.
  335. @parm UINT | uId | Identifies the joystick device to be released.
  336. This value is either JOYSTICKID1 or JOYSTICK2.
  337. @rdesc Returns JOYERR_NOERROR if successful. Otherwise, returns one of the
  338. following error codes:
  339. @flag MMSYSERR_NODRIVER | The joystick driver is not present.
  340. @flag JOYERR_PARMS | The specified joystick device ID <p uId> is invalid.
  341. @xref joySetCapture
  342. ****************************************************************************/
  343. MMRESULT APIENTRY joyReleaseCapture(UINT uId)
  344. {
  345. if (!hDrvJoy[0])
  346. return MMSYSERR_NODRIVER;
  347. if (uId >= uNumDevs)
  348. return MMSYSERR_INVALPARAM;
  349. if (JoyCapture[uId].hwnd == NULL)
  350. return JOYERR_NOERROR;
  351. KillTimer (NULL, JoyCapture[uId].uIDEvent);
  352. JoyCapture[uId].uIDEvent = 0;
  353. JoyCapture[uId].hwnd = NULL;
  354. return JOYERR_NOERROR;
  355. }
  356. /****************************************************************************
  357. @doc EXTERNAL
  358. @api UINT | joySetCapture | This function causes joystick messages to
  359. be sent to the specified window.
  360. @parm HWND | hWnd | Specifies a handle to the window to which messages
  361. are to be sent.
  362. @parm UINT | uId | Identifies the joystick device to be captured.
  363. This value is either JOYSTICKID1 or JOYSTICKID2.
  364. @parm UINT | uPeriod | Specifies the polling rate, in milliseconds.
  365. @parm BOOL | fChanged | If this parameter is set to TRUE, then messages
  366. are sent only when the position changes by a value greater than the
  367. joystick movement threshold.
  368. @rdesc Returns JOYERR_NOERROR if successful. Otherwise, returns one of the
  369. following error codes:
  370. @flag MMSYSERR_NODRIVER | The joystick driver is not present.
  371. @flag JOYERR_PARMS | The specified window handle <p hWnd>
  372. or joystick device ID <p uId> is invalid.
  373. @flag JOYERR_NOCANDO | Cannot capture joystick input because some
  374. required service (for example, a Windows timer) is unavailable.
  375. @flag JOYERR_UNPLUGGED | The specified joystick is not connected to the
  376. system.
  377. @comm This function fails if the specified joystick device is
  378. currently captured. You should call the <f joyReleaseCapture> function when
  379. the joystick capture is no longer needed. If the window is destroyed,
  380. the joystick will be released automatically.
  381. @xref joyReleaseCapture joySetThreshold joyGetThreshold
  382. ****************************************************************************/
  383. MMRESULT APIENTRY joySetCapture(HWND hwnd, UINT uId, UINT uPeriod, BOOL fChanged)
  384. {
  385. JOYINFO joyinfo;
  386. LPJOYINFO lpinfo = &joyinfo;
  387. UINT w;
  388. JOYCAPS JoyCaps;
  389. if (!hwnd || !IsWindow(hwnd))
  390. return JOYERR_PARMS;
  391. if (!hDrvJoy[0])
  392. return MMSYSERR_NODRIVER;
  393. if (uId >= uNumDevs)
  394. return MMSYSERR_INVALPARAM;
  395. if (JoyCapture[uId].hwnd)
  396. if (IsWindow(JoyCapture[uId].hwnd))
  397. return JOYERR_NOCANDO;
  398. else
  399. joyReleaseCapture(uId);
  400. if (joyGetDevCaps (uId, &JoyCaps, sizeof(JOYCAPS)) == 0)
  401. uPeriod = min(JoyCaps.wPeriodMax,max(JoyCaps.wPeriodMin,uPeriod));
  402. else
  403. return JOYERR_NOCANDO;
  404. // ensure that position info. is ok.
  405. if (w = joyGetPos(uId, lpinfo))
  406. return (w);
  407. JoyCapture[uId].uPeriod = uPeriod;
  408. JoyCapture[uId].fChanged = fChanged;
  409. if (!(JoyCapture[uId].uIDEvent = SetTimer(NULL, 0, uPeriod, joyPollCallback)))
  410. {
  411. DOUT(("MMSYSTEM: Couldn't allocate timer in joy.c\r\n"));
  412. return JOYERR_NOCANDO;
  413. }
  414. JoyCapture[uId].hwnd = hwnd;
  415. return JOYERR_NOERROR;
  416. }
  417. /****************************************************************************
  418. @doc EXTERNAL
  419. @api UINT | joySetThreshold | This function sets the movement threshold
  420. of a joystick device.
  421. @parm UINT | uId | Identifies the joystick device. This value is either
  422. JOYSTICKID1 or JOYSTICKID2.
  423. @parm UINT | uThreshold | Specifies the new movement threshold.
  424. @rdesc Returns JOYERR_NOERROR if successful. Otherwise, returns one of the
  425. following error codes:
  426. @flag MMSYSERR_NODRIVER | The joystick driver is not present.
  427. @flag JOYERR_PARMS | The specified joystick device ID <p uId> is invalid.
  428. @comm The movement threshold is the distance the joystick must be
  429. moved before a MM_JOYMOVE message is sent to a window that has
  430. captured the device.
  431. @xref joyGetThreshold joySetCapture
  432. ****************************************************************************/
  433. MMRESULT APIENTRY joySetThreshold(UINT id, UINT uThreshold)
  434. {
  435. if (!hDrvJoy[0])
  436. return MMSYSERR_NODRIVER;
  437. if (id >= uNumDevs)
  438. return MMSYSERR_INVALPARAM;
  439. JoyCapture[id].uThreshold = (UINT)uThreshold;
  440. return JOYERR_NOERROR;
  441. }
  442. /****************************************************************************
  443. @doc INTERNAL
  444. @api MMRESULT | joyConfigChanged | tells the joystick driver to that
  445. the configuration information about the joystick has changed.
  446. @rdesc Returns JOYERR_NOERROR if successful. Otherwise, returns one of the
  447. following error codes:
  448. @flag MMSYSERR_BADDEVICEID | The joystick driver is not present.
  449. @comm This is used by configuration utilites to tell the driver
  450. to update its info. As well, it can be used by apps to
  451. set specific capabilites. This will be documented later...
  452. ****************************************************************************/
  453. MMRESULT WINAPI joyConfigChanged( DWORD dwFlags )
  454. {
  455. if (!hDrvJoy[0])
  456. return MMSYSERR_NODRIVER;
  457. if (dwFlags)
  458. return MMSYSERR_INVALPARAM;
  459. return DrvSendMessage( hDrvJoy[0], JDD_CONFIGCHANGED, 0L, 0L );
  460. }
  461. /****************************************************************************
  462. @doc INTERNAL
  463. @api UINT | joySetCalibration | This function sets the values used to
  464. convert the values returned by the joystick drivers GetPos function
  465. to the range specified in GetDevCaps.
  466. @parm UINT | uId | Identifies the joystick device
  467. @parm PUINT | pwXbase | Specifies the base value for the X pot. The
  468. previous value will be copied back to the variable pointed to here.
  469. @parm PUINT | pwXdelta | Specifies the delta value for the X pot. The
  470. previous value will be copied back to the variable pointed to here.
  471. @parm PUINT | pwYbase | Specifies the base value for the Y pot. The
  472. previous value will be copied back to the variable pointed to here.
  473. @parm PUINT | pwYdelta | Specifies the delta value for the Y pot. The
  474. previous value will be copied back to the variable pointed to here.
  475. @parm PUINT | pwZbase | Specifies the base value for the Z pot. The
  476. previous value will be copied back to the variable pointed to here.
  477. @parm PUINT | pwZdelta | Specifies the delta value for the Z pot. The
  478. previous value will be copied back to the variable pointed to here.
  479. @rdesc The return value is zero if the function was successful, otherwise
  480. it is an error number.
  481. @comm The base represents the lowest value the joystick driver returns,
  482. whereas the delta represents the multiplier to use to convert
  483. the actual value returned by the driver to the valid range
  484. for the joystick API's.
  485. i.e. If the driver returns a range of 43-345 for the X pot, and
  486. the valid mmsystem API range is 0-65535, the base value will be
  487. 43, and the delta will be 65535/(345-43)=217. Thus the base,
  488. and delta convert 43-345 to a range of 0-65535 with the formula:
  489. ((wXvalue-43)*217) , where wXvalue was given by the joystick driver.
  490. ****************************************************************************/
  491. UINT APIENTRY joySetCalibration(UINT id,
  492. PUINT pwXbase,
  493. PUINT pwXdelta,
  494. PUINT pwYbase,
  495. PUINT pwYdelta,
  496. PUINT pwZbase,
  497. PUINT pwZdelta)
  498. {
  499. JOYCALIBRATE oldCal,newCal;
  500. UINT w;
  501. if (!hDrvJoy[0])
  502. return MMSYSERR_NODRIVER;
  503. if (id >= uNumDevs)
  504. return MMSYSERR_NODRIVER;
  505. newCal.wXbase = *pwXbase;
  506. newCal.wXdelta = *pwXdelta;
  507. newCal.wYbase = *pwYbase;
  508. newCal.wYdelta = *pwYdelta;
  509. newCal.wZbase = *pwZbase;
  510. newCal.wZdelta = *pwZdelta;
  511. w = (UINT)(DrvSendMessage(hDrvJoy[id], JDD_SETCALIBRATION,
  512. (LPARAM)(LPSTR)&newCal,
  513. (LPARAM)(LPSTR)&oldCal));
  514. *pwXbase = oldCal.wXbase;
  515. *pwXdelta = oldCal.wXdelta;
  516. *pwYbase = oldCal.wYbase;
  517. *pwYdelta = oldCal.wYdelta;
  518. *pwZbase = oldCal.wZbase;
  519. *pwZdelta = oldCal.wZdelta;
  520. return w;
  521. }
  522. /****************************************************************************
  523. @doc INTERNAL
  524. @api void | joyPollCallback | Function called for joystick
  525. timer polling scheme initiated from SetCapture call.
  526. @parm HWND | hWnd | Identifies the window associated with the timer
  527. event.
  528. @parm UINT | wMsg | Specifies the WM_TIMER message.
  529. @parm UINT | uIDEvent | Specifies the timer's ID.
  530. @parm DWORD | dwTime | Specifies the current system time.
  531. ****************************************************************************/
  532. void CALLBACK joyPollCallback(HWND hWnd, UINT wMsg, UINT uIDEvent, DWORD dwTime)
  533. {
  534. #define diff(w1,w2) (UINT)(w1 > w2 ? w1-w2 : w2-w1)
  535. static JOYINFO oldInfo[2] = {{ 0, 0, 0, 0 },{ 0, 0, 0, 0 }};
  536. JOYINFO Info;
  537. UINT w ,fBtnMask;
  538. if (uIDEvent == JoyCapture[0].uIDEvent)
  539. uIDEvent = 0;
  540. else if (uIDEvent == JoyCapture[1].uIDEvent)
  541. uIDEvent = 1;
  542. #ifdef DEBUG
  543. else
  544. {
  545. DOUT(("MMSYSTEM: Invalid timer handle in joy.c\r\n"));
  546. KillTimer (NULL, uIDEvent);
  547. }
  548. #endif
  549. if (!JoyCapture[uIDEvent].hwnd || !IsWindow(JoyCapture[uIDEvent].hwnd))
  550. joyReleaseCapture(uIDEvent);
  551. if (!(UINT)(DrvSendMessage(hDrvJoy[uIDEvent],
  552. JDD_GETPOS,(LPARAM)(LPJOYINFO)&Info,0l)))
  553. {
  554. for (w=0,fBtnMask=1; w < 4; w++,fBtnMask <<=1)
  555. {
  556. if ((Info.wButtons ^ oldInfo[uIDEvent].wButtons) & fBtnMask)
  557. {
  558. PostMessage(
  559. JoyCapture[uIDEvent].hwnd,
  560. uIDEvent + ((Info.wButtons & fBtnMask) ?
  561. MM_JOY1BUTTONDOWN : MM_JOY1BUTTONUP ),
  562. (WPARAM)(Info.wButtons | fBtnMask << 8),
  563. MAKELPARAM(Info.wXpos,Info.wYpos));
  564. }
  565. }
  566. if (!JoyCapture[uIDEvent].fChanged ||
  567. diff(Info.wXpos,oldInfo[uIDEvent].wXpos)>JoyCapture[uIDEvent].uThreshold ||
  568. diff(Info.wYpos,oldInfo[uIDEvent].wYpos)>JoyCapture[uIDEvent].uThreshold)
  569. {
  570. PostMessage(
  571. JoyCapture[uIDEvent].hwnd,
  572. MM_JOY1MOVE+uIDEvent,
  573. (WPARAM)(Info.wButtons),
  574. MAKELPARAM(Info.wXpos,Info.wYpos)); // WARNING: note the truncations
  575. }
  576. else if (!JoyCapture[uIDEvent].fChanged ||
  577. diff(Info.wZpos,oldInfo[uIDEvent].wZpos)>JoyCapture[uIDEvent].uThreshold)
  578. {
  579. PostMessage(
  580. JoyCapture[uIDEvent].hwnd,
  581. MM_JOY1ZMOVE+uIDEvent,
  582. (WPARAM)Info.wButtons,
  583. MAKELPARAM(Info.wZpos,0));
  584. }
  585. oldInfo[uIDEvent] = Info;
  586. }
  587. #undef diff
  588. }