Leaked source code of windows server 2003
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.

1489 lines
38 KiB

  1. // @doc
  2. /******************************************************************************
  3. *
  4. * @module JoyInfoExCollection.cpp |
  5. *
  6. * CControlItemJoyInfoExCollectio and related classes implementation file
  7. *
  8. * History<nl>
  9. * ---------------------------------------------------<nl>
  10. * Daniel M. Sangster Original 2/1/99
  11. *
  12. * (c) 1986-1999 Microsoft Corporation. All rights reserved.
  13. *
  14. * @topic JOYINFOEX Collection |
  15. * The CControlItemJoyInfoExCollection class, the various CJoyInfoExControlItem
  16. * classes and the ControlItemJoyInfoExFactory taken together implement the JOYINFOEX
  17. * collection. This collection is designed as a way to convert between
  18. * CONTROL_ITEM_XFERs and JOYINFOEX structures. A user does this by setting
  19. * the state of the collection with SetState() or SetState2() and reading
  20. * the state of the collection with GetState() or GetState2().
  21. *
  22. * The classes themselves are simple because they rely on CControlItemCollection
  23. * CControlItem, etc. for much of the functionality. The guts of the conversion
  24. * takes place in the SetItemState() and GetItemState() members of each of the
  25. * control items. Here, the methods use accessor functions provided by CControlItem
  26. * and related classes to set or get the state to or from the appropriate member
  27. * of the JOYINFOEX structure for that item. For example, a buttons item would
  28. * set or get data from dwButtons and dwButtonNumber using accessors on CButtonsItem.
  29. ******************************************************************************/
  30. #include "stdhdrs.h"
  31. #include "joyinfoexcollection.h"
  32. #include <math.h>
  33. /***********************************************************************************
  34. **
  35. ** HRESULT ControlItemJoyInfoExFactory
  36. **
  37. ** @func Factory for JoyInfoEx collection
  38. **
  39. ** @rdesc S_OK if successful, S_FALSE if not supported, E_FAIL for any failure.
  40. **
  41. ************************************************************************************/
  42. HRESULT ControlItemJoyInfoExFactory
  43. (
  44. USHORT usType, //@parm [in] Type of object to create
  45. const CONTROL_ITEM_DESC* cpControlItemDesc, //@parm [in] Item descriptor data
  46. CJoyInfoExControlItem **ppJoyInfoExControlItem //@parm [out] CJoyInfoExControlItem we created
  47. )
  48. {
  49. switch(usType)
  50. {
  51. case ControlItemConst::usAxes:
  52. *ppJoyInfoExControlItem = new WDM_NON_PAGED_POOL CJoyInfoExAxesItem(cpControlItemDesc);
  53. break;
  54. case ControlItemConst::usDPAD:
  55. *ppJoyInfoExControlItem = new WDM_NON_PAGED_POOL CJoyInfoExDPADItem(cpControlItemDesc);
  56. break;
  57. case ControlItemConst::usPropDPAD:
  58. *ppJoyInfoExControlItem = new WDM_NON_PAGED_POOL CJoyInfoExPropDPADItem(cpControlItemDesc);
  59. break;
  60. case ControlItemConst::usWheel:
  61. *ppJoyInfoExControlItem= new WDM_NON_PAGED_POOL CJoyInfoExWheelItem(cpControlItemDesc);
  62. break;
  63. case ControlItemConst::usPOV:
  64. *ppJoyInfoExControlItem = new WDM_NON_PAGED_POOL CJoyInfoExPOVItem(cpControlItemDesc);
  65. break;
  66. case ControlItemConst::usThrottle:
  67. *ppJoyInfoExControlItem = new WDM_NON_PAGED_POOL CJoyInfoExThrottleItem(cpControlItemDesc);
  68. break;
  69. case ControlItemConst::usRudder:
  70. *ppJoyInfoExControlItem = new WDM_NON_PAGED_POOL CJoyInfoExRudderItem(cpControlItemDesc);
  71. break;
  72. case ControlItemConst::usPedal:
  73. *ppJoyInfoExControlItem = new WDM_NON_PAGED_POOL CJoyInfoExPedalItem(cpControlItemDesc);
  74. break;
  75. case ControlItemConst::usButton:
  76. *ppJoyInfoExControlItem = new WDM_NON_PAGED_POOL CJoyInfoExButtonsItem(cpControlItemDesc);
  77. break;
  78. case ControlItemConst::usProfileSelectors:
  79. *ppJoyInfoExControlItem = new WDM_NON_PAGED_POOL CJoyInfoExProfileSelectorsItem(cpControlItemDesc);
  80. break;
  81. case ControlItemConst::usDualZoneIndicator:
  82. *ppJoyInfoExControlItem = new WDM_NON_PAGED_POOL CJoyInfoExDualZoneIndicatorItem(cpControlItemDesc);
  83. break;
  84. default:
  85. *ppJoyInfoExControlItem = NULL;
  86. return S_FALSE;
  87. }
  88. if(!*ppJoyInfoExControlItem)
  89. {
  90. return E_FAIL;
  91. }
  92. return S_OK;
  93. }
  94. ////////////////////////////////////////////////////////////////////////////
  95. //
  96. // CControlItemJoyInfoExCollection::CControlItemJoyInfoExCollection
  97. //
  98. // @mfunc The constructor tells the base class what the VidPid and factory
  99. // are for this device and collection.
  100. //
  101. // @rdesc None
  102. //
  103. CControlItemJoyInfoExCollection::CControlItemJoyInfoExCollection(ULONG ulVidPid) :
  104. CControlItemCollection<CJoyInfoExControlItem>(ulVidPid, &ControlItemJoyInfoExFactory)
  105. {
  106. }
  107. /***********************************************************************************
  108. **
  109. ** HRESULT CControlItemCollectionImpl::GetState2
  110. **
  111. ** @mfunc Gets the JOYINFOEX representation of the state of each item in the
  112. ** collection and returns it in the caller.
  113. **
  114. ** @rvalue S_OK | Success
  115. ** @rvalue E_OUTOFMEMORY | Buffer is not large enough
  116. ** @rvalue E_INVALIDARG | Bad argument
  117. **
  118. *************************************************************************************/
  119. HRESULT CControlItemJoyInfoExCollection::GetState2
  120. (
  121. JOYINFOEX* pjix
  122. )
  123. {
  124. _ASSERTE(pjix != NULL);
  125. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  126. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  127. return E_INVALIDARG;
  128. HRESULT hr = S_OK;
  129. pjix->dwSize = sizeof(JOYINFOEX);
  130. pjix->dwFlags = 0;
  131. pjix->dwXpos = 0;
  132. pjix->dwYpos = 0;
  133. pjix->dwZpos = 0;
  134. pjix->dwRpos = 0;
  135. pjix->dwUpos = 0;
  136. pjix->dwVpos = 0;
  137. pjix->dwButtons = 0;
  138. pjix->dwButtonNumber = 0;
  139. pjix->dwPOV = (DWORD)-1;
  140. ULONG ulCookie = 0;
  141. CJoyInfoExControlItem *pControlItem;
  142. hr = GetNext(&pControlItem, ulCookie);
  143. while(S_OK == hr)
  144. {
  145. pControlItem->GetItemState(pjix);
  146. hr = GetNext(&pControlItem, ulCookie);
  147. }
  148. return hr;
  149. }
  150. /***********************************************************************************
  151. **
  152. ** HRESULT CControlItemCollectionImpl::SetState2
  153. **
  154. ** @mfunc Sets the state of each item in the collection from a JOYINFOEX representation.
  155. **
  156. ** @rvalue S_OK | Success
  157. ** @rvalue E_OUTOFMEMORY | Buffer is not large enough
  158. ** @rvalue E_INVALIDARG | Bad argument
  159. **
  160. *************************************************************************************/
  161. HRESULT CControlItemJoyInfoExCollection::SetState2
  162. (
  163. JOYINFOEX* pjix
  164. )
  165. {
  166. _ASSERTE(pjix != NULL);
  167. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  168. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  169. return E_INVALIDARG;
  170. HRESULT hr = S_OK;
  171. ULONG ulCookie = 0;
  172. //PVOID pvControlItem = NULL;
  173. CJoyInfoExControlItem *pControlItem;
  174. hr = GetNext(&pControlItem, ulCookie);
  175. while(S_OK == hr)
  176. {
  177. hr = pControlItem->SetItemState(pjix);
  178. _ASSERTE(SUCCEEDED(hr));
  179. hr = GetNext(&pControlItem, ulCookie);
  180. }
  181. return hr;
  182. }
  183. ////////////////////////////////////////////////////////////////////////////
  184. //
  185. // CJoyInfoExControlItem::CJoyInfoExControlItem
  186. //
  187. // @mfunc Constructor does nothing
  188. //
  189. // @rdesc None
  190. //
  191. CJoyInfoExControlItem::CJoyInfoExControlItem()
  192. {
  193. }
  194. const int cnMaxJoyInfoExAxis = 65535;
  195. const int cnMaxJoyInfoExPOV = 35900;
  196. ////////////////////////////////////////////////////////////////////////////
  197. //
  198. // CJoyInfoExControlItem::CJoyInfoExControlItem
  199. //
  200. // @mfunc Constructor gives CONTROL_ITEM_DESC to base class
  201. //
  202. // @rdesc None
  203. //
  204. CJoyInfoExAxesItem::CJoyInfoExAxesItem
  205. (
  206. const CONTROL_ITEM_DESC *cpControlItemDesc // @parm Description of item
  207. ) :
  208. CAxesItem(cpControlItemDesc)
  209. {
  210. }
  211. ////////////////////////////////////////////////////////////////////////////
  212. //
  213. // CJoyInfoExAxesItem::GetItemState
  214. //
  215. // @mfunc Converts from native format to JOYINFOEX format.
  216. //
  217. // @rvalue S_OK | Success
  218. // @rvalue E_INVALIDARG | Bad argument
  219. //
  220. HRESULT CJoyInfoExAxesItem::GetItemState
  221. (
  222. JOYINFOEX* pjix // @parm Receives state of item
  223. )
  224. {
  225. _ASSERTE(pjix != NULL);
  226. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  227. // argument checking
  228. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  229. return E_INVALIDARG;
  230. // get the axes range
  231. LONG lMinX = 0;
  232. LONG lMaxX = 0;
  233. LONG lMinY = 0;
  234. LONG lMaxY = 0;
  235. GetXYRange(lMinX, lMaxX, lMinY, lMaxY);
  236. // get the raw axes data
  237. LONG lX = 0;
  238. LONG lY = 0;
  239. GetXY(lX, lY);
  240. // scale the data to joyinfoex range
  241. lX = MulDiv(cnMaxJoyInfoExAxis, lX-lMinX, lMaxX-lMinX);
  242. lY = MulDiv(cnMaxJoyInfoExAxis, lY-lMinY, lMaxY-lMinY);
  243. // put result in joyinfoex structure
  244. pjix->dwXpos = lX;
  245. pjix->dwYpos = lY;
  246. // success
  247. return S_OK;
  248. }
  249. ////////////////////////////////////////////////////////////////////////////
  250. //
  251. // CJoyInfoExAxesItem::SetItemState
  252. //
  253. // @mfunc Converts from native format to JOYINFOEX format.
  254. //
  255. // @rvalue S_OK | Success
  256. // @rvalue E_INVALIDARG | Bad argument
  257. //
  258. HRESULT CJoyInfoExAxesItem::SetItemState
  259. (
  260. JOYINFOEX* pjix // @parm Contains state to set into item
  261. )
  262. {
  263. _ASSERTE(pjix != NULL);
  264. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  265. // argument checking
  266. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  267. return E_INVALIDARG;
  268. // get the axes range
  269. LONG lMinX = 0;
  270. LONG lMaxX = 0;
  271. LONG lMinY = 0;
  272. LONG lMaxY = 0;
  273. GetXYRange(lMinX, lMaxX, lMinY, lMaxY);
  274. // scale the data to correct range
  275. LONG lX = lMinX + MulDiv(lMaxX-lMinX, pjix->dwXpos, cnMaxJoyInfoExAxis);
  276. LONG lY = lMinY + MulDiv(lMaxY-lMinY, pjix->dwYpos, cnMaxJoyInfoExAxis);
  277. // set the item data
  278. SetXY(lX, lY);
  279. // success
  280. return S_OK;
  281. }
  282. ////////////////////////////////////////////////////////////////////////////
  283. //
  284. // CJoyInfoExDPADItem::CJoyInfoExDPADItem
  285. //
  286. // @mfunc Constructor gives CONTROL_ITEM_DESC to base class
  287. //
  288. // @rdesc None
  289. //
  290. CJoyInfoExDPADItem::CJoyInfoExDPADItem
  291. (
  292. const CONTROL_ITEM_DESC *cpControlItemDesc // @parm Description of item
  293. ) :
  294. CDPADItem(cpControlItemDesc)
  295. {
  296. }
  297. ////////////////////////////////////////////////////////////////////////////
  298. //
  299. // CJoyInfoExDPADItem::GetItemState
  300. //
  301. // @mfunc Converts from native format to JOYINFOEX format.
  302. //
  303. // @rvalue S_OK | Success
  304. // @rvalue E_INVALIDARG | Bad argument
  305. //
  306. HRESULT CJoyInfoExDPADItem::GetItemState
  307. (
  308. JOYINFOEX* pjix // @parm Receives state of item
  309. )
  310. {
  311. _ASSERTE(pjix != NULL);
  312. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  313. // argument checking
  314. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  315. return E_INVALIDARG;
  316. // TODO talk to mitch about what the range should be
  317. // get the raw POV data
  318. LONG lDirection;
  319. GetDirection(lDirection);
  320. // put result in joyinfoex structure
  321. pjix->dwPOV = lDirection;
  322. // success
  323. return S_OK;
  324. }
  325. ////////////////////////////////////////////////////////////////////////////
  326. //
  327. // CJoyInfoExDPADItem::SetItemState
  328. //
  329. // @mfunc Converts from native format to JOYINFOEX format.
  330. //
  331. // @rvalue S_OK | Success
  332. // @rvalue E_INVALIDARG | Bad argument
  333. //
  334. HRESULT CJoyInfoExDPADItem::SetItemState
  335. (
  336. JOYINFOEX* pjix // @parm Contains state to set into item
  337. )
  338. {
  339. _ASSERTE(pjix != NULL);
  340. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  341. // argument checking
  342. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  343. return E_INVALIDARG;
  344. // TODO talk to mitch about what the range should be
  345. // put result in joyinfoex structure
  346. LONG lDirection = pjix->dwPOV;
  347. // set the raw POV data
  348. SetDirection(lDirection);
  349. // success
  350. return S_OK;
  351. }
  352. ////////////////////////////////////////////////////////////////////////////
  353. //
  354. // CJoyInfoExPropDPADItem::CJoyInfoExPropDPADItem
  355. //
  356. // @mfunc Constructor gives CONTROL_ITEM_DESC to base class
  357. //
  358. // @rdesc None
  359. //
  360. CJoyInfoExPropDPADItem::CJoyInfoExPropDPADItem
  361. (
  362. const CONTROL_ITEM_DESC *cpControlItemDesc // @parm Description of item
  363. ) :
  364. CPropDPADItem(cpControlItemDesc)
  365. {
  366. }
  367. ////////////////////////////////////////////////////////////////////////////
  368. //
  369. // CJoyInfoExPropDPADItem::GetItemState
  370. //
  371. // @mfunc Converts from native format to JOYINFOEX format.
  372. //
  373. // @rvalue S_OK | Success
  374. // @rvalue E_INVALIDARG | Bad argument
  375. //
  376. HRESULT CJoyInfoExPropDPADItem::GetItemState
  377. (
  378. JOYINFOEX* pjix // @parm Receives state of item
  379. )
  380. {
  381. _ASSERTE(pjix != NULL);
  382. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  383. // parameter checking
  384. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  385. return E_INVALIDARG;
  386. // get the axes range
  387. LONG lMinX = 0;
  388. LONG lMaxX = 0;
  389. LONG lMinY = 0;
  390. LONG lMaxY = 0;
  391. GetXYRange(lMinX, lMaxX, lMinY, lMaxY);
  392. // get the raw axes data
  393. LONG lX = 0;
  394. LONG lY = 0;
  395. GetXY(lX, lY);
  396. // scale the data to joyinfoex range
  397. lX = MulDiv(cnMaxJoyInfoExAxis, lX-lMinX, lMaxX-lMinX);
  398. lY = MulDiv(cnMaxJoyInfoExAxis, lY-lMinY, lMaxY-lMinY);
  399. // put result in joyinfoex structure
  400. pjix->dwXpos = lX;
  401. pjix->dwYpos = lY;
  402. // get the raw POV data
  403. LONG lDirection;
  404. GetDirection(lDirection);
  405. // put result in joyinfoex structure
  406. pjix->dwPOV = lDirection;
  407. // success
  408. return S_OK;
  409. }
  410. ////////////////////////////////////////////////////////////////////////////
  411. //
  412. // CJoyInfoExPropDPADItem::SetItemState
  413. //
  414. // @mfunc Converts from native format to JOYINFOEX format.
  415. //
  416. // @rvalue S_OK | Success
  417. // @rvalue E_INVALIDARG | Bad argument
  418. //
  419. HRESULT CJoyInfoExPropDPADItem::SetItemState
  420. (
  421. JOYINFOEX* pjix // @parm Contains state to set into item
  422. )
  423. {
  424. _ASSERTE(pjix != NULL);
  425. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  426. // argument checking
  427. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  428. return E_INVALIDARG;
  429. // get the axes range
  430. LONG lMinX = 0;
  431. LONG lMaxX = 0;
  432. LONG lMinY = 0;
  433. LONG lMaxY = 0;
  434. GetXYRange(lMinX, lMaxX, lMinY, lMaxY);
  435. // scale the data to correct range
  436. LONG lX = lMinX + MulDiv(lMaxX-lMinX, pjix->dwXpos, cnMaxJoyInfoExAxis);
  437. LONG lY = lMinY + MulDiv(lMaxY-lMinY, pjix->dwYpos, cnMaxJoyInfoExAxis);
  438. // set the item data
  439. SetXY(lX, lY);
  440. // success
  441. return S_OK;
  442. }
  443. ////////////////////////////////////////////////////////////////////////////
  444. //
  445. // CJoyInfoExButtonsItem::CJoyInfoExButtonsItem
  446. //
  447. // @mfunc Constructor gives CONTROL_ITEM_DESC to base class
  448. //
  449. // @rdesc None
  450. //
  451. CJoyInfoExButtonsItem::CJoyInfoExButtonsItem
  452. (
  453. const CONTROL_ITEM_DESC *cpControlItemDesc // @parm Description of item
  454. ) :
  455. CButtonsItem(cpControlItemDesc)
  456. {
  457. }
  458. ////////////////////////////////////////////////////////////////////////////
  459. //
  460. // CJoyInfoExButtonsItem::GetItemState
  461. //
  462. // @mfunc Converts from native format to JOYINFOEX format.
  463. //
  464. // @rvalue S_OK | Success
  465. // @rvalue E_INVALIDARG | Bad argument
  466. //
  467. HRESULT CJoyInfoExButtonsItem::GetItemState
  468. (
  469. JOYINFOEX* pjix // @parm Receives state of item
  470. )
  471. {
  472. _ASSERTE(pjix != NULL);
  473. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  474. // parameter checking
  475. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  476. return E_INVALIDARG;
  477. // get the minimum and maximum button numbers
  478. USHORT usButtonMin = GetButtonMin();
  479. USHORT usButtonMax = GetButtonMax();
  480. // get the button number and bit array
  481. USHORT usButtonNumber = 0;
  482. ULONG ulButtonBitArray = 0;
  483. GetButtons(usButtonNumber, ulButtonBitArray);
  484. // shift the bit array by bias amount
  485. ulButtonBitArray = ulButtonBitArray << (usButtonMin-1);
  486. // create a bitmask for this range of buttons
  487. ULONG ulButtonMask = 0;
  488. for(USHORT usButtonIndex=usButtonMin; usButtonIndex<=usButtonMax; usButtonIndex++)
  489. ulButtonMask |= 1 << (usButtonIndex-1);
  490. // handle special case of detecting shift button because
  491. // shift button is not reflected in the bit array
  492. ULONG ulShiftButtonBitArray = 0;
  493. ULONG ulRawShiftButtonBitArray = 0;
  494. ULONG ulShiftButtonMask = 0;
  495. GetShiftButtons(ulRawShiftButtonBitArray);
  496. UINT uShiftButtonCount = GetNumShiftButtons();
  497. if(uShiftButtonCount > 1)
  498. {
  499. for(UINT uShiftButtonIndex=0; uShiftButtonIndex<uShiftButtonCount; uShiftButtonIndex++)
  500. {
  501. USHORT usShiftButtonUsage = GetShiftButtonUsage(uShiftButtonIndex);
  502. if(usShiftButtonUsage != 0)
  503. ulShiftButtonBitArray |= ((ulRawShiftButtonBitArray >> uShiftButtonIndex) & 0x01) << (usShiftButtonUsage - 1);
  504. }
  505. // create a bitmask for this range of shift buttons
  506. for(uShiftButtonIndex=0; uShiftButtonIndex<uShiftButtonCount; uShiftButtonIndex++)
  507. {
  508. USHORT usShiftButtonUsage = GetShiftButtonUsage(uShiftButtonIndex);
  509. if(usShiftButtonUsage != 0)
  510. ulShiftButtonMask |= 1 << (usShiftButtonUsage - 1);
  511. }
  512. }
  513. else if(uShiftButtonCount == 1)
  514. {
  515. ulShiftButtonMask = 0x00200;
  516. if(ulRawShiftButtonBitArray != NULL)
  517. ulShiftButtonBitArray = ulShiftButtonMask;
  518. }
  519. // set this section of the bit array into the joyinfoex structure
  520. ULONG ulMask = ulButtonMask | ulShiftButtonMask;
  521. pjix->dwButtons |= (pjix->dwButtons & ~ulMask) | ulButtonBitArray | ulShiftButtonBitArray;
  522. // set the button number of the joyinfoex structure, if set
  523. pjix->dwButtonNumber = usButtonNumber;
  524. // TODO: remove this hack when driver is fixed
  525. if(usButtonNumber != 0)
  526. pjix->dwButtons |= 1<<(usButtonNumber-1);
  527. // success
  528. return S_OK;
  529. }
  530. ////////////////////////////////////////////////////////////////////////////
  531. //
  532. // CJoyInfoExButtonsItem::SetItemState
  533. //
  534. // @mfunc Converts from native format to JOYINFOEX format.
  535. //
  536. // @rvalue S_OK | Success
  537. // @rvalue E_INVALIDARG | Bad argument
  538. //
  539. HRESULT CJoyInfoExButtonsItem::SetItemState
  540. (
  541. JOYINFOEX* pjix // @parm Contains state to set into item
  542. )
  543. {
  544. _ASSERTE(pjix != NULL);
  545. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  546. // parameter checking
  547. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  548. return E_INVALIDARG;
  549. // get the minimum and maximum button numbers
  550. USHORT usButtonMin = GetButtonMin();
  551. USHORT usButtonMax = GetButtonMax();
  552. // create a bitmask for this range of buttons
  553. ULONG ulButtonMask = 0;
  554. for(USHORT usButtonIndex=usButtonMin; usButtonIndex<=usButtonMax; usButtonIndex++)
  555. ulButtonMask |= 1 << (usButtonIndex-1);
  556. // get the buttons
  557. ULONG ulButtonBitArray = pjix->dwButtons & ulButtonMask;
  558. ulButtonBitArray = ulButtonBitArray >> (usButtonMin-1);
  559. // get the shift buttons
  560. ULONG ulShiftButtonBitArray = 0;
  561. UINT uShiftButtonCount = GetNumShiftButtons();
  562. if(uShiftButtonCount > 1)
  563. {
  564. for(UINT uShiftButtonIndex=0; uShiftButtonIndex<uShiftButtonCount; uShiftButtonIndex++)
  565. {
  566. USHORT usShiftButtonUsage = GetShiftButtonUsage(uShiftButtonIndex);
  567. if(usShiftButtonUsage != 0)
  568. ulShiftButtonBitArray |= ((pjix->dwButtons >> (usShiftButtonUsage - 1)) & 0x01) << uShiftButtonIndex;
  569. }
  570. }
  571. else if(uShiftButtonCount == 1)
  572. {
  573. if(pjix->dwButtons & 0x00200)
  574. ulShiftButtonBitArray = 1;
  575. }
  576. // set the shift button data
  577. SetShiftButtons(ulShiftButtonBitArray);
  578. // set the button data
  579. USHORT usButtonNumber = (USHORT)pjix->dwButtonNumber;
  580. SetButtons(usButtonNumber, ulButtonBitArray);
  581. // success
  582. return S_OK;
  583. }
  584. ////////////////////////////////////////////////////////////////////////////
  585. //
  586. // CJoyInfoExProfileSelectorsItem::CJoyInfoExProfileSelectorsItem
  587. //
  588. // @mfunc Constructor gives CONTROL_ITEM_DESC to base class
  589. //
  590. // @rdesc None
  591. //
  592. CJoyInfoExProfileSelectorsItem::CJoyInfoExProfileSelectorsItem
  593. (
  594. const CONTROL_ITEM_DESC *cpControlItemDesc // @parm Description of item
  595. ) :
  596. CProfileSelector(cpControlItemDesc)
  597. {
  598. }
  599. ////////////////////////////////////////////////////////////////////////////
  600. //
  601. // CJoyInfoExProfileSelectorsItem::GetItemState
  602. //
  603. // @mfunc Converts from native format to JOYINFOEX format.
  604. //
  605. // @rvalue S_OK | Success
  606. // @rvalue E_INVALIDARG | Bad argument
  607. //
  608. HRESULT CJoyInfoExProfileSelectorsItem::GetItemState
  609. (
  610. JOYINFOEX* pjix // @parm Receives state of item
  611. )
  612. {
  613. _ASSERTE(pjix != NULL);
  614. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  615. // parameter checking
  616. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  617. return E_INVALIDARG;
  618. // get the min and max button numbers
  619. UINT uFirstProfileSelectorButton = GetProfileSelectorMin();
  620. UINT uLastProfileSelectorButton = GetProfileSelectorMax();
  621. int iProfileSelectorButtonCount = uLastProfileSelectorButton - uFirstProfileSelectorButton + 1;
  622. // _ASSERTE(iProfileSelectorButtonCount > 0);
  623. // get the profile that is selected
  624. UCHAR ucSelectedProfile;
  625. GetSelectedProfile(ucSelectedProfile);
  626. // create a bit array corresponding to this
  627. ULONG ulButtonBitArray = 1 << (iProfileSelectorButtonCount - ucSelectedProfile - 1);
  628. // shift the bit array by bias amount
  629. ulButtonBitArray = ulButtonBitArray << (uFirstProfileSelectorButton-1);
  630. // create a bitmask for this range of buttons
  631. ULONG ulButtonMask = 0;
  632. for(USHORT usButtonIndex=uFirstProfileSelectorButton; usButtonIndex<=uLastProfileSelectorButton; usButtonIndex++)
  633. ulButtonMask |= 1 << (usButtonIndex-1);
  634. // set this section of the bit array into the joyinfoex structure
  635. pjix->dwButtons = (pjix->dwButtons & ~ulButtonMask) | ulButtonBitArray;
  636. // set the button number of the joyinfoex structure, if it has not already been set
  637. if(pjix->dwButtonNumber == 0)
  638. pjix->dwButtonNumber = ucSelectedProfile + uFirstProfileSelectorButton;
  639. // success
  640. return S_OK;
  641. }
  642. ////////////////////////////////////////////////////////////////////////////
  643. //
  644. // CJoyInfoExProfileSelectorsItem::SetItemState
  645. //
  646. // @mfunc Converts from native format to JOYINFOEX format.
  647. //
  648. // @rvalue S_OK | Success
  649. // @rvalue E_INVALIDARG | Bad argument
  650. //
  651. HRESULT CJoyInfoExProfileSelectorsItem::SetItemState
  652. (
  653. JOYINFOEX* pjix // @parm Contains state to set into item
  654. )
  655. {
  656. _ASSERTE(pjix != NULL);
  657. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  658. // parameter checking
  659. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  660. return E_INVALIDARG;
  661. // get the min and max button numbers
  662. UINT uFirstProfileSelectorButton = GetProfileSelectorMin();
  663. UINT uLastProfileSelectorButton = GetProfileSelectorMax();
  664. int iProfileSelectorButtonCount = uLastProfileSelectorButton - uFirstProfileSelectorButton + 1;
  665. // _ASSERTE(iProfileSelectorButtonCount > 0);
  666. // create a bitmask for this range of buttons
  667. ULONG ulButtonMask = 0;
  668. for(USHORT usButtonIndex=uFirstProfileSelectorButton; usButtonIndex<=uLastProfileSelectorButton; usButtonIndex++)
  669. ulButtonMask |= 1 << (usButtonIndex-1);
  670. // get the buttons
  671. ULONG ulButtonBitArray = pjix->dwButtons & ulButtonMask;
  672. ulButtonBitArray = ulButtonBitArray >> (uFirstProfileSelectorButton-1);
  673. // convert this to an index
  674. UCHAR ucIndex = 0;
  675. for(ucIndex=0; ucIndex<=uLastProfileSelectorButton-uFirstProfileSelectorButton; ucIndex++)
  676. {
  677. // if low order bit is one, we have found our index
  678. if((ulButtonBitArray >> ucIndex) & 0x01)
  679. break;
  680. }
  681. // set the shift button data
  682. UCHAR ucSelectedProfile = iProfileSelectorButtonCount - ucIndex - 1;
  683. SetSelectedProfile(ucSelectedProfile);
  684. // success
  685. return S_OK;
  686. }
  687. ////////////////////////////////////////////////////////////////////////////
  688. //
  689. // CJoyInfoExPOVItem::CJoyInfoExPOVItem
  690. //
  691. // @mfunc Constructor gives CONTROL_ITEM_DESC to base class
  692. //
  693. // @rdesc None
  694. //
  695. CJoyInfoExPOVItem::CJoyInfoExPOVItem
  696. (
  697. const CONTROL_ITEM_DESC *cpControlItemDesc // @parm Description of item
  698. ) :
  699. CPOVItem(cpControlItemDesc)
  700. {
  701. }
  702. ////////////////////////////////////////////////////////////////////////////
  703. //
  704. // CJoyInfoExPOVItem::GetItemState
  705. //
  706. // @mfunc Converts from native format to JOYINFOEX format.
  707. //
  708. // @rvalue S_OK | Success
  709. // @rvalue E_INVALIDARG | Bad argument
  710. //
  711. HRESULT CJoyInfoExPOVItem::GetItemState
  712. (
  713. JOYINFOEX* pjix // @parm Receives state of item
  714. )
  715. {
  716. _ASSERTE(pjix != NULL);
  717. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  718. // parameter checking
  719. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  720. return E_INVALIDARG;
  721. // get the POV range
  722. LONG lMin = 0;
  723. LONG lMax = 0;
  724. GetRange(lMin, lMax);
  725. // get the raw POV data
  726. LONG lVal = 0;
  727. GetValue(lVal);
  728. // scale the data to joyinfoex range
  729. if(lVal >= lMin && lVal <= lMax)
  730. lVal = MulDiv(cnMaxJoyInfoExPOV, lVal-lMin, lMax-lMin);
  731. else
  732. lVal = -1;
  733. // put result in joyinfoex structure
  734. pjix->dwPOV = lVal;
  735. // success
  736. return S_OK;
  737. }
  738. ////////////////////////////////////////////////////////////////////////////
  739. //
  740. // CJoyInfoExPOVItem::SetItemState
  741. //
  742. // @mfunc Converts from native format to JOYINFOEX format.
  743. //
  744. // @rvalue S_OK | Success
  745. // @rvalue E_INVALIDARG | Bad argument
  746. //
  747. HRESULT CJoyInfoExPOVItem::SetItemState
  748. (
  749. JOYINFOEX* pjix // @parm Contains state to set into item
  750. )
  751. {
  752. _ASSERTE(pjix != NULL);
  753. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  754. // parameter checking
  755. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  756. return E_INVALIDARG;
  757. // get the POV range
  758. LONG lMin = 0;
  759. LONG lMax = 0;
  760. GetRange(lMin, lMax);
  761. // scale the data to joyinfoex range
  762. LONG lVal = 0;
  763. if(pjix->dwPOV >= 0)
  764. lVal = lMin + MulDiv(lMax-lMin, pjix->dwPOV, cnMaxJoyInfoExPOV);
  765. else
  766. lVal = -1;
  767. // set the raw POV data
  768. SetValue(lVal);
  769. // success
  770. return S_OK;
  771. }
  772. ////////////////////////////////////////////////////////////////////////////
  773. //
  774. // CJoyInfoExThrottleItem::CJoyInfoExThrottleItem
  775. //
  776. // @mfunc Constructor gives CONTROL_ITEM_DESC to base class
  777. //
  778. // @rdesc None
  779. //
  780. CJoyInfoExThrottleItem::CJoyInfoExThrottleItem
  781. (
  782. const CONTROL_ITEM_DESC *cpControlItemDesc // @parm Description of item
  783. ) :
  784. CThrottleItem(cpControlItemDesc)
  785. {
  786. }
  787. ////////////////////////////////////////////////////////////////////////////
  788. //
  789. // CJoyInfoExThrottleItem::GetItemState
  790. //
  791. // @mfunc Converts from native format to JOYINFOEX format.
  792. //
  793. // @rvalue S_OK | Success
  794. // @rvalue E_INVALIDARG | Bad argument
  795. //
  796. HRESULT CJoyInfoExThrottleItem::GetItemState
  797. (
  798. JOYINFOEX* pjix // @parm Receives state of item
  799. )
  800. {
  801. _ASSERTE(pjix != NULL);
  802. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  803. // parameter checking
  804. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  805. return E_INVALIDARG;
  806. // get the axis range
  807. LONG lMin = 0;
  808. LONG lMax = 0;
  809. GetRange(lMin, lMax);
  810. // get the raw POV data
  811. LONG lVal = 0;
  812. GetValue(lVal);
  813. // scale the data to joyinfoex range
  814. lVal = MulDiv(cnMaxJoyInfoExAxis, lVal-lMin, lMax-lMin);
  815. // put result in joyinfoex structure
  816. pjix->dwZpos = lVal;
  817. // success
  818. return S_OK;
  819. }
  820. ////////////////////////////////////////////////////////////////////////////
  821. //
  822. // CJoyInfoExThrottleItem::SetItemState
  823. //
  824. // @mfunc Converts from native format to JOYINFOEX format.
  825. //
  826. // @rvalue S_OK | Success
  827. // @rvalue E_INVALIDARG | Bad argument
  828. //
  829. HRESULT CJoyInfoExThrottleItem::SetItemState
  830. (
  831. JOYINFOEX* pjix // @parm Contains state to set into item
  832. )
  833. {
  834. _ASSERTE(pjix != NULL);
  835. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  836. // parameter checking
  837. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  838. return E_INVALIDARG;
  839. // get the axis range
  840. LONG lMin = 0;
  841. LONG lMax = 0;
  842. GetRange(lMin, lMax);
  843. // scale the data to correct range
  844. LONG lVal = lMin + MulDiv(lMax-lMin, pjix->dwZpos, cnMaxJoyInfoExAxis);
  845. // set the raw POV data
  846. SetValue(lVal);
  847. // success
  848. return S_OK;
  849. }
  850. ////////////////////////////////////////////////////////////////////////////
  851. //
  852. // CJoyInfoExRudderItem::CJoyInfoExRudderItem
  853. //
  854. // @mfunc Constructor gives CONTROL_ITEM_DESC to base class
  855. //
  856. // @rdesc None
  857. //
  858. CJoyInfoExRudderItem::CJoyInfoExRudderItem
  859. (
  860. const CONTROL_ITEM_DESC *cpControlItemDesc // @parm Description of item
  861. ) :
  862. CRudderItem(cpControlItemDesc)
  863. {
  864. }
  865. ////////////////////////////////////////////////////////////////////////////
  866. //
  867. // CJoyInfoExRudderItem::GetItemState
  868. //
  869. // @mfunc Converts from native format to JOYINFOEX format.
  870. //
  871. // @rvalue S_OK | Success
  872. // @rvalue E_INVALIDARG | Bad argument
  873. //
  874. HRESULT CJoyInfoExRudderItem::GetItemState
  875. (
  876. JOYINFOEX* pjix // @parm Receives state of item
  877. )
  878. {
  879. _ASSERTE(pjix != NULL);
  880. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  881. // parameter checking
  882. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  883. return E_INVALIDARG;
  884. // get the axis range
  885. LONG lMin = 0;
  886. LONG lMax = 0;
  887. GetRange(lMin, lMax);
  888. // get the raw POV data
  889. LONG lVal = 0;
  890. GetValue(lVal);
  891. // scale the data to joyinfoex range
  892. lVal = MulDiv(cnMaxJoyInfoExAxis, lVal-lMin, lMax-lMin);
  893. // put result in joyinfoex structure
  894. pjix->dwRpos = lVal;
  895. // success
  896. return S_OK;
  897. }
  898. ////////////////////////////////////////////////////////////////////////////
  899. //
  900. // CJoyInfoExRudderItem::SetItemState
  901. //
  902. // @mfunc Converts from native format to JOYINFOEX format.
  903. //
  904. // @rvalue S_OK | Success
  905. // @rvalue E_INVALIDARG | Bad argument
  906. //
  907. HRESULT CJoyInfoExRudderItem::SetItemState
  908. (
  909. JOYINFOEX* pjix // @parm Contains state to set into item
  910. )
  911. {
  912. _ASSERTE(pjix != NULL);
  913. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  914. // parameter checking
  915. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  916. return E_INVALIDARG;
  917. // get the axis range
  918. LONG lMin = 0;
  919. LONG lMax = 0;
  920. GetRange(lMin, lMax);
  921. // scale the data to joyinfoex range
  922. LONG lVal = lMin + MulDiv(lMax-lMin, pjix->dwRpos, cnMaxJoyInfoExAxis);
  923. // set the raw POV data
  924. SetValue(lVal);
  925. // success
  926. return S_OK;
  927. }
  928. ////////////////////////////////////////////////////////////////////////////
  929. //
  930. // CJoyInfoExWheelItem::CJoyInfoExWheelItem
  931. //
  932. // @mfunc Constructor gives CONTROL_ITEM_DESC to base class
  933. //
  934. // @rdesc None
  935. //
  936. CJoyInfoExWheelItem::CJoyInfoExWheelItem
  937. (
  938. const CONTROL_ITEM_DESC *cpControlItemDesc // @parm Description of item
  939. ) :
  940. CWheelItem(cpControlItemDesc)
  941. {
  942. }
  943. ////////////////////////////////////////////////////////////////////////////
  944. //
  945. // CJoyInfoExWheelItem::GetItemState
  946. //
  947. // @mfunc Converts from native format to JOYINFOEX format.
  948. //
  949. // @rvalue S_OK | Success
  950. // @rvalue E_INVALIDARG | Bad argument
  951. //
  952. HRESULT CJoyInfoExWheelItem::GetItemState
  953. (
  954. JOYINFOEX* pjix // @parm Receives state of item
  955. )
  956. {
  957. _ASSERTE(pjix != NULL);
  958. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  959. // parameter checking
  960. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  961. return E_INVALIDARG;
  962. // get the axis range
  963. LONG lMin = 0;
  964. LONG lMax = 0;
  965. GetRange(lMin, lMax);
  966. // get the raw POV data
  967. LONG lVal = 0;
  968. GetValue(lVal);
  969. // scale the data to joyinfoex range
  970. lVal = MulDiv(cnMaxJoyInfoExAxis, lVal-lMin, lMax-lMin);
  971. // put result in joyinfoex structure
  972. pjix->dwXpos = lVal;
  973. // success
  974. return S_OK;
  975. }
  976. ////////////////////////////////////////////////////////////////////////////
  977. //
  978. // CJoyInfoExWheelItem::SetItemState
  979. //
  980. // @mfunc Converts from native format to JOYINFOEX format.
  981. //
  982. // @rvalue S_OK | Success
  983. // @rvalue E_INVALIDARG | Bad argument
  984. //
  985. HRESULT CJoyInfoExWheelItem::SetItemState
  986. (
  987. JOYINFOEX* pjix // @parm Contains state to set into item
  988. )
  989. {
  990. _ASSERTE(pjix != NULL);
  991. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  992. // parameter checking
  993. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  994. return E_INVALIDARG;
  995. // get the axis range
  996. LONG lMin = 0;
  997. LONG lMax = 0;
  998. GetRange(lMin, lMax);
  999. // scale the data to joyinfoex range
  1000. LONG lVal = lMin + MulDiv(lMax-lMin, pjix->dwXpos, cnMaxJoyInfoExAxis);
  1001. // set the raw POV data
  1002. SetValue(lVal);
  1003. // success
  1004. return S_OK;
  1005. }
  1006. ////////////////////////////////////////////////////////////////////////////
  1007. //
  1008. // CJoyInfoExPedalItem::CJoyInfoExPedalItem
  1009. //
  1010. // @mfunc Constructor gives CONTROL_ITEM_DESC to base class
  1011. //
  1012. // @rdesc None
  1013. //
  1014. CJoyInfoExPedalItem::CJoyInfoExPedalItem
  1015. (
  1016. const CONTROL_ITEM_DESC *cpControlItemDesc // @parm Description of item
  1017. ) :
  1018. CPedalItem(cpControlItemDesc)
  1019. {
  1020. }
  1021. ////////////////////////////////////////////////////////////////////////////
  1022. //
  1023. // CJoyInfoExPedalItem::GetItemState
  1024. //
  1025. // @mfunc Converts from native format to JOYINFOEX format.
  1026. //
  1027. // @rvalue S_OK | Success
  1028. // @rvalue E_INVALIDARG | Bad argument
  1029. //
  1030. HRESULT CJoyInfoExPedalItem::GetItemState
  1031. (
  1032. JOYINFOEX* pjix // @parm Receives state of item
  1033. )
  1034. {
  1035. _ASSERTE(pjix != NULL);
  1036. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  1037. // parameter checking
  1038. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  1039. return E_INVALIDARG;
  1040. // get the axis range
  1041. LONG lMin = 0;
  1042. LONG lMax = 0;
  1043. GetRange(lMin, lMax);
  1044. // get the raw POV data
  1045. LONG lVal = 0;
  1046. GetValue(lVal);
  1047. // scale the data to joyinfoex range
  1048. lVal = MulDiv(cnMaxJoyInfoExAxis, lVal-lMin, lMax-lMin);
  1049. // put result in joyinfoex structure
  1050. if(IsYAxis())
  1051. {
  1052. pjix->dwYpos = lVal;
  1053. }
  1054. else
  1055. {
  1056. pjix->dwRpos = lVal;
  1057. }
  1058. // mark the JOYINFOEX packet if the pedals are not there
  1059. if(!ArePedalsPresent())
  1060. pjix->dwFlags |= JOY_FLAGS_PEDALS_NOT_PRESENT;
  1061. // success
  1062. return S_OK;
  1063. }
  1064. ////////////////////////////////////////////////////////////////////////////
  1065. //
  1066. // CJoyInfoExPedalItem::SetItemState
  1067. //
  1068. // @mfunc Converts from native format to JOYINFOEX format.
  1069. //
  1070. // @rvalue S_OK | Success
  1071. // @rvalue E_INVALIDARG | Bad argument
  1072. //
  1073. HRESULT CJoyInfoExPedalItem::SetItemState
  1074. (
  1075. JOYINFOEX* pjix // @parm Contains state to set into item
  1076. )
  1077. {
  1078. _ASSERTE(pjix != NULL);
  1079. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  1080. // parameter checking
  1081. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  1082. return E_INVALIDARG;
  1083. // get the axis range
  1084. LONG lMin = 0;
  1085. LONG lMax = 0;
  1086. GetRange(lMin, lMax);
  1087. // scale the data to joyinfoex range
  1088. DWORD dwPos = 0;
  1089. if(IsYAxis())
  1090. {
  1091. dwPos = pjix->dwYpos;
  1092. }
  1093. else
  1094. {
  1095. dwPos = pjix->dwRpos;
  1096. }
  1097. LONG lVal = lMin + MulDiv(lMax-lMin, dwPos, cnMaxJoyInfoExAxis);
  1098. // set the raw POV data
  1099. SetValue(lVal);
  1100. // success
  1101. return S_OK;
  1102. }
  1103. ////////////////////////////////////////////////////////////////////////////
  1104. //
  1105. // CJoyInfoExDualZoneIndicatorItem::CJoyInfoExDualZoneIndicatorItem
  1106. //
  1107. // @mfunc Constructor gives CONTROL_ITEM_DESC to base class
  1108. //
  1109. // @rdesc None
  1110. //
  1111. CJoyInfoExDualZoneIndicatorItem::CJoyInfoExDualZoneIndicatorItem
  1112. (
  1113. const CONTROL_ITEM_DESC *cpControlItemDesc // @parm Description of item
  1114. ) :
  1115. CDualZoneIndicatorItem(cpControlItemDesc)
  1116. {
  1117. }
  1118. ////////////////////////////////////////////////////////////////////////////
  1119. //
  1120. // CJoyInfoExDualZoneIndicatorItem::GetItemState
  1121. //
  1122. // @mfunc Converts from native format to JOYINFOEX format.
  1123. //
  1124. // @rvalue S_OK | Success
  1125. // @rvalue E_INVALIDARG | Bad argument
  1126. //
  1127. HRESULT CJoyInfoExDualZoneIndicatorItem::GetItemState
  1128. (
  1129. JOYINFOEX* pjix // @parm Receives state of item
  1130. )
  1131. {
  1132. _ASSERTE(pjix != NULL);
  1133. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  1134. // parameter checking
  1135. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  1136. return E_INVALIDARG;
  1137. // convert to axes
  1138. UINT uMin = 0;
  1139. UINT uMax = cnMaxJoyInfoExAxis;
  1140. UINT uMid = uMax/2;
  1141. if(IsXYIndicator())
  1142. {
  1143. LONG lActiveZone = GetActiveZone();
  1144. /*
  1145. if ((m_ItemState.DualZoneIndicators.rglVal[0] != 0) || (m_ItemState.DualZoneIndicators.rglVal[1] != 0))
  1146. {
  1147. TCHAR tszDebug[1024];
  1148. wsprintf(tszDebug, "\tlActiveZone = %d\n", lActiveZone);
  1149. OutputDebugString("*****************************************\n");
  1150. OutputDebugString(tszDebug);
  1151. }
  1152. */
  1153. switch(lActiveZone)
  1154. {
  1155. case 0:
  1156. pjix->dwXpos = uMid;
  1157. pjix->dwYpos = uMid;
  1158. break;
  1159. case 1:
  1160. pjix->dwXpos = uMin;
  1161. pjix->dwYpos = uMax;
  1162. break;
  1163. case 2:
  1164. pjix->dwXpos = uMid;
  1165. pjix->dwYpos = uMax;
  1166. break;
  1167. case 3:
  1168. pjix->dwXpos = uMax;
  1169. pjix->dwYpos = uMax;
  1170. break;
  1171. case 4:
  1172. pjix->dwXpos = uMax;
  1173. pjix->dwYpos = uMid;
  1174. break;
  1175. case 5:
  1176. pjix->dwXpos = uMax;
  1177. pjix->dwYpos = uMin;
  1178. break;
  1179. case 6:
  1180. pjix->dwXpos = uMid;
  1181. pjix->dwYpos = uMin;
  1182. break;
  1183. case 7:
  1184. pjix->dwXpos = uMin;
  1185. pjix->dwYpos = uMin;
  1186. break;
  1187. case 8:
  1188. pjix->dwXpos = uMin;
  1189. pjix->dwYpos = uMid;
  1190. break;
  1191. default:
  1192. _ASSERTE(FALSE);
  1193. }
  1194. }
  1195. else if(IsRzIndicator())
  1196. {
  1197. LONG lActiveZone = GetActiveZone();
  1198. switch(lActiveZone)
  1199. {
  1200. case 0:
  1201. pjix->dwRpos = uMid;
  1202. break;
  1203. case 1:
  1204. pjix->dwRpos = uMin;
  1205. break;
  1206. case 2:
  1207. pjix->dwRpos = uMax;
  1208. break;
  1209. default:
  1210. _ASSERTE(FALSE);
  1211. }
  1212. }
  1213. else
  1214. {
  1215. _ASSERTE(FALSE);
  1216. return E_UNEXPECTED;
  1217. }
  1218. //_RPT0(_CRT_WARN, "*********CJoyInfoExDualZoneIndicatorItem::GetItemState()****************\n");
  1219. //_RPT1(_CRT_WARN, "\tlZone = %d\n", GetActiveZone());
  1220. //_RPT1(_CRT_WARN, "\t====> dwXpos = %d\n", pjix->dwXpos);
  1221. //_RPT1(_CRT_WARN, "\t====> dwYpos = %d\n", pjix->dwYpos);
  1222. //_RPT0(_CRT_WARN, "************************************************************************\n");
  1223. // success
  1224. return S_OK;
  1225. }
  1226. ////////////////////////////////////////////////////////////////////////////
  1227. //
  1228. // CJoyInfoExDualZoneIndicatorItem::SetItemState
  1229. //
  1230. // @mfunc Converts from native format to JOYINFOEX format.
  1231. //
  1232. // @rvalue S_OK | Success
  1233. // @rvalue E_INVALIDARG | Bad argument
  1234. //
  1235. HRESULT CJoyInfoExDualZoneIndicatorItem::SetItemState
  1236. (
  1237. JOYINFOEX* pjix // @parm Contains state to set into item
  1238. )
  1239. {
  1240. _ASSERTE(pjix != NULL);
  1241. _ASSERTE(pjix->dwSize == sizeof(JOYINFOEX));
  1242. // parameter checking
  1243. if(pjix == NULL || pjix->dwSize != sizeof(JOYINFOEX))
  1244. return E_INVALIDARG;
  1245. LONG lZone = 0;
  1246. UINT uMin = 0;
  1247. UINT uMax = cnMaxJoyInfoExAxis;
  1248. UINT uMid = uMax/2;
  1249. if(IsXYIndicator())
  1250. {
  1251. int iXPos = (int)pjix->dwXpos - uMid;
  1252. int iYPos = (int)pjix->dwYpos - uMid;
  1253. if((ULONGLONG)iXPos*iXPos + iYPos*iYPos > (ULONGLONG)(uMid*uMid/4))
  1254. {
  1255. double dAngle = atan2(iYPos, iXPos);
  1256. dAngle = dAngle*180.0/3.14159;
  1257. dAngle += 360.0;
  1258. dAngle = fmod(dAngle, 360.0);
  1259. if(dAngle < -1.0)
  1260. _ASSERTE(FALSE);
  1261. else if(dAngle < 22.5)
  1262. lZone = 4;
  1263. else if(dAngle < 67.5)
  1264. lZone = 3;
  1265. else if(dAngle < 112.5)
  1266. lZone = 2;
  1267. else if(dAngle < 157.5)
  1268. lZone = 1;
  1269. else if(dAngle < 202.5)
  1270. lZone = 8;
  1271. else if(dAngle < 247.5)
  1272. lZone = 7;
  1273. else if(dAngle < 292.5)
  1274. lZone = 6;
  1275. else if(dAngle < 337.5)
  1276. lZone = 5;
  1277. else if(dAngle <= 361.0)
  1278. lZone = 4;
  1279. else
  1280. _ASSERTE(FALSE);
  1281. }
  1282. }
  1283. else if(IsRzIndicator())
  1284. {
  1285. int iRPos = (int)pjix->dwRpos - uMid;
  1286. if(iRPos > (int)uMid/2)
  1287. lZone = 2;
  1288. else if(iRPos < -(int)uMid/2)
  1289. lZone = 1;
  1290. }
  1291. else
  1292. {
  1293. _ASSERTE(FALSE);
  1294. return E_UNEXPECTED;
  1295. }
  1296. //_RPT0(_CRT_WARN, "*********CJoyInfoExDualZoneIndicatorItem::SetItemState()****************\n");
  1297. //_RPT1(_CRT_WARN, "\tdwXpos = %d\n", pjix->dwXpos);
  1298. //_RPT1(_CRT_WARN, "\tdwYpos = %d\n", pjix->dwYpos);
  1299. //_RPT1(_CRT_WARN, "\t====> lZone = %d\n", lZone);
  1300. //_RPT0(_CRT_WARN, "************************************************************************\n");
  1301. // set the raw POV data
  1302. SetActiveZone(lZone);
  1303. // success
  1304. return S_OK;
  1305. }