Source code of Windows XP (NT5)
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.

1947 lines
55 KiB

  1. //****************************************************************************
  2. //
  3. // File: joycal.c
  4. // Content: Joystick calibration dialog
  5. // History:
  6. // Date By Reason
  7. // ==== == ======
  8. // 11-dec-94 craige split out of joycpl.c; some tweaks
  9. // 15-dec-94 craige allow N joysticks
  10. // 17-dec-94 craige new UI as requested by ChrisB
  11. // 18-dec-94 craige process UV
  12. // 05-jan-95 craige new centering confirmation messages
  13. // 04-mar-95 craige bug 10761 - separate strings for pluralization
  14. // bug 12036 - now works when "Back" clicked off of
  15. // custom 4-axis with POV hat
  16. //
  17. // Copyright (c) Microsoft Corporation 1994-1995
  18. //
  19. //****************************************************************************
  20. #pragma pack (8)
  21. #include "stdafx.h"
  22. #include "joycpl.h"
  23. #include "resource.h"
  24. #include "pov.h"
  25. #include "assert.h"
  26. #include "baseids.h"
  27. #include "comstr.h"
  28. #undef NewLoadString
  29. #define NewLoadString(a, b, c, d) \
  30. pszCommonString->LoadString(b); \
  31. lstrcpy( c, (LPCTSTR)*pszCommonString )
  32. // Context sensitive help stuff!
  33. static void OnContextMenu(WPARAM wParam);
  34. static void OnHelp (LPARAM);
  35. static const DWORD CalibrateHelpIDs[] =
  36. {
  37. IDC_JOYLIST1, IDC_JOYLIST1,
  38. IDC_JOYLIST2, IDC_JOYLIST2,
  39. IDC_JOYLIST3, IDC_JOYLIST3,
  40. IDC_JOYLIST4, IDC_JOYLIST4,
  41. 0, 0
  42. };
  43. /*
  44. * This has the look and feel of a wizard, but isn't This leads to the
  45. * obvious...
  46. *
  47. * Q: Why isn't this a "real" wizard?
  48. *
  49. * A: - it doesn't have multiple pages, it has a single page. the user
  50. * sees different joystick items activate and de-activate on the dialog
  51. * as he/she calibrates each axis. fussing with multiple sheets for each
  52. * axis would be confusing and unnecessary.
  53. */
  54. /*
  55. * calibration states
  56. */
  57. // %%% debug %%% alpha days
  58. extern "C"
  59. {
  60. typedef enum
  61. {
  62. JCS_INIT=-1,
  63. JCS_XY_CENTER1,
  64. JCS_XY_MOVE,
  65. JCS_XY_CENTER2,
  66. JCS_Z_MOVE,
  67. JCS_Z_PLACEHOLDER,
  68. JCS_R_MOVE,
  69. JCS_R_PLACEHOLDER,
  70. JCS_U_MOVE,
  71. JCS_U_PLACEHOLDER,
  72. JCS_V_MOVE,
  73. JCS_V_PLACEHOLDER,
  74. JCS_POV_MOVEUP,
  75. JCS_POV_MOVERIGHT,
  76. JCS_POV_MOVEDOWN,
  77. JCS_POV_MOVELEFT,
  78. JCS_FINI
  79. } cal_states;
  80. typedef enum
  81. {
  82. JC_XY=0,
  83. JC_Z,
  84. JC_POV_UP,
  85. JC_POV_RIGHT,
  86. JC_POV_DOWN,
  87. JC_POV_LEFT,
  88. JC_R,
  89. JC_U,
  90. JC_V,
  91. JC_FINI
  92. } cal_wins;
  93. // variables used in calibration
  94. typedef struct
  95. {
  96. LPGLOBALVARS pgv;
  97. cal_states cState;
  98. BOOL bHasTimer;
  99. BOOL bUseTimer;
  100. HINSTANCE hinst;
  101. JOYINFOEX ji;
  102. JOYRANGE jr;
  103. DWORD pov[JOY_POV_NUMDIRS];
  104. int iAxisCount;
  105. BOOL bPOVdone;
  106. } CALVARS, *LPCALVARS;
  107. extern "C" WINMMAPI MMRESULT WINAPI joyConfigChanged(DWORD);
  108. #define JOY_CALIB_FLAGS JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | \
  109. JOY_RETURNR | JOY_RETURNU | JOY_RETURNV | \
  110. JOY_RETURNBUTTONS | JOY_RETURNRAWDATA
  111. /*
  112. * we use raw data during calibration; RAW_SHIFT allows us to convert to
  113. * a reasonable "real" value
  114. */
  115. #define RAW_SHIFT 100
  116. } // extern "C"
  117. // setDefaultButton - make a button the default window
  118. static void setDefaultButton( HWND hwnd, HWND hwdb )
  119. {
  120. // Optimized New Method
  121. SendMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)hwdb, (LPARAM)TRUE);
  122. /* Optimized Old Method
  123. DWORD style;
  124. HWND hCtrl;
  125. int idList[] = { IDC_JOYCALDONE, IDC_JOYCALNEXT,
  126. IDC_JOYCALBACK, IDC_JOYPICKPOV };
  127. #define SIZEOF_LIST 4
  128. // turn off the current default push button
  129. for (short i=0; i < SIZEOF_LIST; i++ )
  130. {
  131. hCtrl = GetDlgItem( hwnd, idList[i] );
  132. if (hCtrl)
  133. {
  134. style = GetWindowLong( hCtrl, GWL_STYLE );
  135. if ( style & BS_DEFPUSHBUTTON )
  136. {
  137. style &= ~BS_DEFPUSHBUTTON;
  138. style |= BS_PUSHBUTTON;
  139. SetWindowLong( hCtrl, GWL_STYLE, style );
  140. break;
  141. }
  142. }
  143. }
  144. // make the specified button the default
  145. style = GetWindowLong( hwdb, GWL_STYLE );
  146. style &= ~(BS_PUSHBUTTON|BS_DEFPUSHBUTTON);
  147. style |= BS_DEFPUSHBUTTON;
  148. SetWindowLong( hwdb, GWL_STYLE, style );
  149. */
  150. } // setDefaultButton
  151. /*
  152. * setLabel
  153. *
  154. * set the label for an axis based on current calibration state
  155. */
  156. static void setLabel(
  157. LPGLOBALVARS pgv,
  158. HWND hwnd,
  159. UINT id,
  160. LPJOYREGHWCONFIG pcfg,
  161. DWORD bit )
  162. {
  163. char str[MAX_STR];
  164. int type;
  165. HINSTANCE hinst;
  166. HWND hwtext;
  167. hinst = GetResourceInstance( );
  168. assert(hinst);
  169. // get text for this axis label...
  170. if( pcfg->dwUsageSettings & JOY_US_ISOEM )
  171. {
  172. type = pcfg->dwType - JOY_HW_LASTENTRY;
  173. if( type < 0 || type >= pgv->pjd->oemCount )
  174. {
  175. type = -1;
  176. }
  177. } else
  178. {
  179. type = -1;
  180. }
  181. switch( id )
  182. {
  183. case IDC_JOYLIST1_LABEL:
  184. if( (type == -1) || (pgv->pjd->oemList[type].xy_label[0] == 0) )
  185. {
  186. NewLoadString( hinst, IDS_XYAXIS_LABEL, str, sizeof( str ) );
  187. if( !lstrlen(str) ) return;
  188. } else lstrcpy( str, pgv->pjd->oemList[type].xy_label );
  189. break;
  190. case IDC_JOYLIST2_LABEL:
  191. if( (type == -1) || (pgv->pjd->oemList[type].z_label[0] == 0 ) )
  192. {
  193. NewLoadString( hinst, IDS_ZAXIS_LABEL, str, sizeof( str ) );
  194. if( !lstrlen(str) ) return;
  195. } else lstrcpy( str, pgv->pjd->oemList[type].z_label );
  196. break;
  197. case IDC_JOYLIST3_LABEL:
  198. if( (type == -1) || (pgv->pjd->oemList[type].r_label[0] == 0) )
  199. {
  200. NewLoadString( hinst, IDS_RAXIS_LABEL, str, sizeof( str ) );
  201. if( !lstrlen(str) ) return;
  202. } else lstrcpy( str, pgv->pjd->oemList[type].r_label );
  203. break;
  204. case IDC_JOYLIST4_LABEL:
  205. if( (type == -1) || (pgv->pjd->oemList[type].u_label[0] == 0) )
  206. {
  207. NewLoadString( hinst, IDS_UAXIS_LABEL, str, sizeof( str ) );
  208. if( !lstrlen(str) ) return;
  209. } else lstrcpy( str, pgv->pjd->oemList[type].u_label );
  210. break;
  211. case IDC_JOYLIST5_LABEL:
  212. if( (type == -1) || (pgv->pjd->oemList[type].v_label[0] == 0) )
  213. {
  214. NewLoadString( hinst, IDS_VAXIS_LABEL, str, sizeof( str ) );
  215. if( !lstrlen(str) ) return;
  216. } else lstrcpy( str, pgv->pjd->oemList[type].v_label );
  217. break;
  218. case IDC_JOYPOV_LABEL:
  219. if( (type == -1) || (pgv->pjd->oemList[type].pov_label[0] == 0) )
  220. {
  221. NewLoadString( hinst, IDS_POVAXIS_LABEL, str, sizeof( str ) );
  222. if( !lstrlen(str) ) return;
  223. } else lstrcpy( str, pgv->pjd->oemList[type].pov_label );
  224. break;
  225. }
  226. hwtext = GetDlgItem( hwnd, id );
  227. ASSERT (::IsWindow(hwtext));
  228. if( hwtext != NULL )
  229. SetWindowText( hwtext, str );
  230. } /* setLabel */
  231. // enableCalWindows - enable or disable specific calibration windows
  232. static void enableCalWindows(
  233. LPGLOBALVARS pgv,
  234. LPJOYREGHWCONFIG pcfg,
  235. HWND hwnd,
  236. cal_wins id )
  237. {
  238. BOOL on;
  239. HWND hwlb;
  240. HWND hwb;
  241. int iid;
  242. // set up the buttons
  243. hwb = GetDlgItem( hwnd,IDC_JOYCALDONE );
  244. ASSERT (hwb);
  245. if( id == JC_FINI )
  246. {
  247. hwlb = GetDlgItem( hwnd, IDC_JOYCALNEXT );
  248. ASSERT (::IsWindow(hwlb));
  249. ShowWindow(hwlb, SW_HIDE );
  250. EnableWindow( hwb, TRUE );
  251. ShowWindow( hwb, SW_NORMAL );
  252. SetFocus( hwb );
  253. setDefaultButton( hwnd, hwb );
  254. } else
  255. {
  256. hwlb = GetDlgItem( hwnd, IDC_JOYCALNEXT );
  257. ASSERT (::IsWindow(hwlb));
  258. ShowWindow( hwlb, SW_NORMAL );
  259. EnableWindow( hwb, FALSE );
  260. ShowWindow( hwb, SW_HIDE );
  261. }
  262. setLabel( pgv, hwnd, IDC_JOYLIST1_LABEL, pcfg, JOY_ISCAL_XY );
  263. // set up the XY window
  264. on = FALSE;
  265. if( id == JC_XY )
  266. on = TRUE;
  267. hwlb = GetDlgItem( hwnd, IDC_JOYLIST1 );
  268. ASSERT (::IsWindow(hwlb));
  269. if( !on )
  270. InvalidateRect( hwlb, NULL, TRUE );
  271. EnableWindow( hwlb, on );
  272. EnableWindow( GetDlgItem( hwnd, IDC_JOYLIST1_LABEL ), on );
  273. /*
  274. * set up the Z window
  275. */
  276. on = FALSE;
  277. if( id == JC_Z )
  278. on = TRUE;
  279. hwlb = GetDlgItem( hwnd, IDC_JOYLIST2 );
  280. if( !on )
  281. {
  282. InvalidateRect( hwlb, NULL, TRUE );
  283. }
  284. EnableWindow( hwlb, on );
  285. EnableWindow( GetDlgItem( hwnd, IDC_JOYLIST2_LABEL ), on );
  286. /*
  287. * set up the R window
  288. */
  289. on = FALSE;
  290. if( id == JC_R )
  291. {
  292. on = TRUE;
  293. }
  294. hwlb = GetDlgItem( hwnd, IDC_JOYLIST3 );
  295. if( !on )
  296. {
  297. InvalidateRect( hwlb, NULL, TRUE );
  298. }
  299. EnableWindow( hwlb, on );
  300. EnableWindow( GetDlgItem( hwnd, IDC_JOYLIST3_LABEL ), on );
  301. /*
  302. * set up the U window
  303. */
  304. on = FALSE;
  305. if( id == JC_U )
  306. {
  307. on = TRUE;
  308. }
  309. hwlb = GetDlgItem( hwnd, IDC_JOYLIST4 );
  310. if( hwlb != NULL )
  311. {
  312. if( !on )
  313. {
  314. InvalidateRect( hwlb, NULL, TRUE );
  315. }
  316. EnableWindow( hwlb, on );
  317. EnableWindow( GetDlgItem( hwnd, IDC_JOYLIST4_LABEL ), on );
  318. }
  319. /*
  320. * set up the V window
  321. */
  322. on = FALSE;
  323. if( id == JC_V )
  324. {
  325. on = TRUE;
  326. }
  327. hwlb = GetDlgItem( hwnd, IDC_JOYLIST5 );
  328. if( hwlb != NULL )
  329. {
  330. if( !on )
  331. {
  332. InvalidateRect( hwlb, NULL, TRUE );
  333. }
  334. EnableWindow( hwlb, on );
  335. EnableWindow( GetDlgItem( hwnd, IDC_JOYLIST5_LABEL ), on );
  336. }
  337. /*
  338. * set up the POV icon
  339. */
  340. on = FALSE;
  341. if( id >= JC_POV_UP && id <= JC_POV_LEFT )
  342. {
  343. on = TRUE;
  344. }
  345. EnableWindow( GetDlgItem( hwnd, IDC_JOYPOV_LABEL ), on );
  346. hwb = GetDlgItem( hwnd, IDC_JOYPICKPOV );
  347. EnableWindow( hwb, on );
  348. if( on )
  349. {
  350. ShowWindow( hwb, SW_NORMAL );
  351. SetFocus( hwb );
  352. setDefaultButton( hwnd, hwb );
  353. switch( id )
  354. {
  355. case JC_POV_UP:
  356. iid = IDI_JOYPOV_UP;
  357. break;
  358. case JC_POV_RIGHT:
  359. iid = IDI_JOYPOV_RIGHT;
  360. break;
  361. case JC_POV_LEFT:
  362. iid = IDI_JOYPOV_LEFT;
  363. break;
  364. case JC_POV_DOWN:
  365. iid = IDI_JOYPOV_DOWN;
  366. break;
  367. }
  368. } else
  369. {
  370. ShowWindow( hwb, SW_HIDE );
  371. UpdateWindow( hwb );
  372. iid = IDI_JOYPOV_GRAYED;
  373. }
  374. ChangeIcon( hwnd, iid, IDC_JOYPOV );
  375. } /* enableCalWindows */
  376. /*
  377. * getJoyName - get the name of a joystick
  378. */
  379. static int getJoyName( LPJOYREGHWCONFIG pcfg, BOOL plural )
  380. {
  381. int str2id;
  382. if( pcfg->hws.dwFlags & JOY_HWS_ISYOKE )
  383. {
  384. str2id = ( plural ) ? IDS_JOYCAL_YOKES : IDS_JOYCAL_YOKE;
  385. } else if( pcfg->hws.dwFlags & JOY_HWS_ISCARCTRL )
  386. {
  387. str2id = ( plural ) ? IDS_JOYCAL_CARS : IDS_JOYCAL_CAR;
  388. } else if( pcfg->hws.dwFlags & JOY_HWS_ISGAMEPAD )
  389. {
  390. str2id = ( plural ) ? IDS_JOYCAL_GAMEPADS : IDS_JOYCAL_GAMEPAD;
  391. } else
  392. {
  393. str2id = ( plural ) ? IDS_JOY2S : IDS_JOY2;
  394. }
  395. return(str2id);
  396. } /* getJoyName */
  397. /*
  398. * joyCalStateChange - calibration state change
  399. */
  400. static BOOL joyCalStateChange( LPCALVARS pcv, HWND hwnd, BOOL back )
  401. {
  402. HINSTANCE hinst;
  403. HWND hwtext;
  404. int strid;
  405. int stridx = 0; // BUG FIX: CML 6/21/96 (FLASH RAID 270)
  406. int str2id;
  407. int str3id;
  408. int str4id;
  409. char str[2*MAX_STR];
  410. char buff[2*MAX_STR];
  411. char str2[64];
  412. char str3[64];
  413. char str4[64];
  414. BOOL done;
  415. LPJOYREGHWCONFIG pcfg;
  416. BOOL rc;
  417. int type;
  418. LPGLOBALVARS pgv;
  419. BOOL isdone;
  420. assert(pcv);
  421. assert(hwnd);
  422. /*
  423. * move to the next state: get the appropriate string
  424. * to display, and enable the correct controls
  425. */
  426. pgv = pcv->pgv;
  427. assert(pgv);
  428. rc = TRUE;
  429. done = FALSE;
  430. pcfg = &pgv->joyHWCurr;
  431. str2id = -1;
  432. str3id = -1;
  433. str4id = -1;
  434. (pcv->cState) = (cal_states) (pcv->cState + ((cal_states) 1));
  435. EnableWindow( GetDlgItem( hwnd, IDC_JOYCALBACK ), back );
  436. while( !done )
  437. {
  438. done = TRUE;
  439. switch( pcv->cState )
  440. {
  441. case JCS_XY_CENTER1:
  442. /*
  443. * init. range variables
  444. */
  445. pcv->jr.jpMin.dwX = (DWORD) -1;
  446. pcv->jr.jpMin.dwY = (DWORD) -1;
  447. pcv->jr.jpMin.dwZ = (DWORD) -1;
  448. pcv->jr.jpMin.dwR = (DWORD) -1;
  449. pcv->jr.jpMin.dwU = (DWORD) -1;
  450. pcv->jr.jpMin.dwV = (DWORD) -1;
  451. pcv->jr.jpMax.dwX = 0;
  452. pcv->jr.jpMax.dwY = 0;
  453. pcv->jr.jpMax.dwZ = 0;
  454. pcv->jr.jpMax.dwR = 0;
  455. pcv->jr.jpMax.dwU = 0;
  456. pcv->jr.jpMax.dwV = 0;
  457. // set strings to display
  458. stridx = CALSTR1;
  459. if( pcfg->hws.dwFlags & JOY_HWS_ISYOKE )
  460. {
  461. strid = IDS_JOYCALXY_CENTERYOKE;
  462. } else if( pcfg->hws.dwFlags & JOY_HWS_ISCARCTRL )
  463. {
  464. strid = IDS_JOYCALXY_CENTERCAR;
  465. } else if( pcfg->hws.dwFlags & JOY_HWS_ISGAMEPAD )
  466. {
  467. strid = IDS_JOYCALXY_CENTERGAMEPAD;
  468. } else
  469. {
  470. strid = IDS_JOYCALXY_CENTER;
  471. }
  472. enableCalWindows( pgv, pcfg, hwnd, JC_XY );
  473. break;
  474. case JCS_XY_MOVE:
  475. stridx = CALSTR2;
  476. if( pcfg->hws.dwFlags & JOY_HWS_ISYOKE )
  477. {
  478. strid = IDS_JOYCALXY_MOVEYOKE;
  479. } else if( pcfg->hws.dwFlags & JOY_HWS_ISCARCTRL )
  480. {
  481. strid = IDS_JOYCALXY_MOVECAR;
  482. } else if( pcfg->hws.dwFlags & JOY_HWS_ISGAMEPAD )
  483. {
  484. strid = IDS_JOYCALXY_MOVEGAMEPAD;
  485. } else
  486. {
  487. strid = IDS_JOYCALXY_MOVE;
  488. }
  489. break;
  490. case JCS_XY_CENTER2:
  491. stridx = CALSTR3;
  492. if( pcfg->hws.dwFlags & JOY_HWS_ISYOKE )
  493. {
  494. strid = IDS_JOYCALXY_CENTERYOKE2;
  495. } else if( pcfg->hws.dwFlags & JOY_HWS_ISCARCTRL )
  496. {
  497. strid = IDS_JOYCALXY_CENTERCAR2;
  498. } else if( pcfg->hws.dwFlags & JOY_HWS_ISGAMEPAD )
  499. {
  500. strid = IDS_JOYCALXY_CENTERGAMEPAD2;
  501. } else
  502. {
  503. strid = IDS_JOYCALXY_CENTER2;
  504. }
  505. break;
  506. case JCS_Z_MOVE:
  507. stridx = CALSTR4;
  508. if( !(pcfg->hws.dwFlags & JOY_HWS_HASZ) )
  509. {
  510. pcv->cState = JCS_R_MOVE;
  511. done = FALSE;
  512. } else
  513. {
  514. enableCalWindows( pgv, pcfg, hwnd, JC_Z );
  515. strid = IDS_JOYCALZ_MOVE;
  516. str2id = getJoyName( pcfg, TRUE );
  517. }
  518. break;
  519. case JCS_Z_PLACEHOLDER:
  520. pcv->cState = JCS_R_MOVE;
  521. done = FALSE;
  522. break;
  523. case JCS_R_MOVE:
  524. stridx = CALSTR5;
  525. if( !(pcfg->hws.dwFlags & JOY_HWS_HASR) && !(pcfg->dwUsageSettings & JOY_US_HASRUDDER) )
  526. {
  527. pcv->cState = JCS_U_MOVE;
  528. done = FALSE;
  529. } else
  530. {
  531. enableCalWindows( pgv, pcfg, hwnd, JC_R );
  532. strid = IDS_JOYCALRUDDER_MOVE;
  533. str2id = getJoyName( pcfg, TRUE );
  534. }
  535. break;
  536. case JCS_R_PLACEHOLDER:
  537. pcv->cState = JCS_U_MOVE;
  538. done = FALSE;
  539. break;
  540. case JCS_U_MOVE:
  541. stridx = CALSTR6;
  542. if( !(pcfg->hws.dwFlags & JOY_HWS_HASU) )
  543. {
  544. pcv->cState = JCS_V_MOVE;
  545. done = FALSE;
  546. } else
  547. {
  548. enableCalWindows( pgv, pcfg, hwnd, JC_U );
  549. strid = IDS_JOYCALU_MOVE;
  550. str2id = getJoyName( pcfg, TRUE );
  551. }
  552. break;
  553. case JCS_U_PLACEHOLDER:
  554. pcv->cState = JCS_V_MOVE;
  555. done = FALSE;
  556. break;
  557. case JCS_V_MOVE:
  558. stridx = CALSTR7;
  559. if( !(pcfg->hws.dwFlags & JOY_HWS_HASV) )
  560. {
  561. pcv->cState = JCS_POV_MOVEUP;
  562. done = FALSE;
  563. } else
  564. {
  565. enableCalWindows( pgv, pcfg, hwnd, JC_V );
  566. strid = IDS_JOYCALV_MOVE;
  567. str2id = getJoyName( pcfg, TRUE );
  568. }
  569. break;
  570. case JCS_V_PLACEHOLDER:
  571. pcv->cState = JCS_POV_MOVEUP;
  572. done = FALSE;
  573. break;
  574. case JCS_POV_MOVEUP:
  575. stridx = CALSTR8;
  576. if( !(pcfg->hws.dwFlags & JOY_HWS_HASPOV) )
  577. {
  578. pcv->cState = JCS_FINI;
  579. done = FALSE;
  580. } else
  581. {
  582. enableCalWindows( pgv, pcfg, hwnd, JC_POV_UP );
  583. strid = IDS_JOYCALPOV_MOVE;
  584. str2id = IDS_JOYCAL_UP;
  585. str3id = getJoyName( pcfg, TRUE );
  586. str4id = IDS_JOYCAL_UP;
  587. }
  588. break;
  589. case JCS_POV_MOVERIGHT:
  590. stridx = CALSTR9;
  591. enableCalWindows( pgv, pcfg, hwnd, JC_POV_RIGHT );
  592. strid = IDS_JOYCALPOV_MOVE;
  593. str2id = IDS_JOYCAL_RIGHT;
  594. str3id = getJoyName( pcfg, TRUE );
  595. str4id = IDS_JOYCAL_RIGHT;
  596. break;
  597. case JCS_POV_MOVEDOWN:
  598. stridx = CALSTR10;
  599. enableCalWindows( pgv, pcfg, hwnd, JC_POV_DOWN );
  600. strid = IDS_JOYCALPOV_MOVE;
  601. str2id = IDS_JOYCAL_DOWN;
  602. str3id = getJoyName( pcfg, TRUE );
  603. str4id = IDS_JOYCAL_DOWN;
  604. break;
  605. case JCS_POV_MOVELEFT:
  606. stridx = CALSTR11;
  607. enableCalWindows( pgv, pcfg, hwnd, JC_POV_LEFT );
  608. strid = IDS_JOYCALPOV_MOVE;
  609. str2id = IDS_JOYCAL_LEFT;
  610. str3id = getJoyName( pcfg, TRUE );
  611. str4id = IDS_JOYCAL_LEFT;
  612. break;
  613. case JCS_FINI:
  614. /*
  615. * see if everything that needs to be calibrated
  616. * was actually calibrated
  617. */
  618. if( !(pcfg->hwv.dwCalFlags & JOY_ISCAL_XY) )
  619. {
  620. isdone = FALSE;
  621. } else if( (pcfg->hws.dwFlags & JOY_HWS_HASZ) &&
  622. !(pcfg->hwv.dwCalFlags & JOY_ISCAL_Z) )
  623. {
  624. isdone = FALSE;
  625. } else if( ((pcfg->hws.dwFlags & JOY_HWS_HASR) ||
  626. (pcfg->dwUsageSettings & JOY_US_HASRUDDER)) &&
  627. !(pcfg->hwv.dwCalFlags & JOY_ISCAL_R) )
  628. {
  629. isdone = FALSE;
  630. } else if( (pcfg->hws.dwFlags & JOY_HWS_HASPOV) &&
  631. !(pcfg->hwv.dwCalFlags & JOY_ISCAL_POV) )
  632. {
  633. isdone = FALSE;
  634. } else if( (pcfg->hws.dwFlags & JOY_HWS_HASU) &&
  635. !(pcfg->hwv.dwCalFlags & JOY_ISCAL_U) )
  636. {
  637. isdone = FALSE;
  638. } else if( (pcfg->hws.dwFlags & JOY_HWS_HASV) &&
  639. !(pcfg->hwv.dwCalFlags & JOY_ISCAL_V) )
  640. {
  641. isdone = FALSE;
  642. } else
  643. {
  644. isdone = TRUE;
  645. }
  646. strid = ( isdone ) ? IDS_JOYCAL_DONE : IDS_JOYCAL_NOTDONE;
  647. str2id = getJoyName( pcfg, FALSE );
  648. str3id = getJoyName( pcfg, TRUE );
  649. stridx = CALSTR12;
  650. enableCalWindows( pgv, pcfg, hwnd, JC_FINI );
  651. rc = FALSE;
  652. break;
  653. } // END OF SWITCH
  654. } // END OF WHILE
  655. // see if there is any OEM text specified
  656. hinst = GetResourceInstance( );
  657. assert(hinst);
  658. hwtext = GetDlgItem( hwnd, IDC_JOYCALMSG );
  659. if( pcfg->dwUsageSettings & JOY_US_ISOEM )
  660. {
  661. LPJOYDATA pjd;
  662. pjd = pgv->pjd;
  663. assert(pjd);
  664. type = pcfg->dwType - JOY_HW_LASTENTRY;
  665. if( pjd->oemList[type].cal_strs[ stridx ][0] != 0 )
  666. {
  667. SetWindowText( hwtext, pjd->oemList[type].cal_strs[ stridx] );
  668. return(rc);
  669. }
  670. }
  671. // no OEM text, use the defaults
  672. LoadString( hinst, strid, str, sizeof(str));
  673. if( lstrlen(str) )
  674. {
  675. if( str2id != -1 )
  676. {
  677. NewLoadString( hinst, str2id, str2, sizeof( str2 ) );
  678. if( str2 )
  679. {
  680. if( str3id != -1 )
  681. {
  682. NewLoadString( hinst, str3id, str3, sizeof( str3 ) );
  683. if( lstrlen(str3) )
  684. {
  685. if( str4id != -1 )
  686. {
  687. NewLoadString( hinst, str4id, str4, sizeof( str4 ) );
  688. if( lstrlen(str4) )
  689. {
  690. // wsprintf( buff, str, str2, str3, str4 );
  691. assert(str2);
  692. assert(str3);
  693. assert(str4);
  694. LPSTR lpargs[] = {str2, str3, str4};
  695. FormatMessage(FORMAT_MESSAGE_FROM_STRING |
  696. FORMAT_MESSAGE_ARGUMENT_ARRAY,
  697. (LPSTR) str,
  698. 0, 0,
  699. buff,
  700. sizeof(buff),
  701. lpargs);
  702. SetWindowText( hwtext, buff );
  703. }
  704. } else
  705. {
  706. wsprintf( buff, str, str2, str3 );
  707. SetWindowText( hwtext, buff );
  708. }
  709. }
  710. } else
  711. {
  712. wsprintf( buff, str, str2, str2 );
  713. SetWindowText( hwtext, buff );
  714. }
  715. }
  716. } else
  717. {
  718. SetWindowText( hwtext, str );
  719. }
  720. }
  721. return(rc);
  722. } /* joyCalStateChange */
  723. /*
  724. * joyCalStateSkip - skip the current state, move to the next one
  725. */
  726. static void joyCalStateSkip( LPCALVARS pcv, HWND hwnd )
  727. {
  728. assert(pcv);
  729. assert(hwnd);
  730. #if 0
  731. /*
  732. * if we're calibrating XY, skip to Z
  733. */
  734. if( pcv->cState <= JCS_XY_CENTER2 )
  735. {
  736. pcv->cState = JCS_XY_CENTER2;
  737. /*
  738. * if we're calibrating Z, skip to R
  739. */
  740. } else if( pcv->cState < JCS_Z_PLACEHOLDER )
  741. {
  742. pcv->cState = JCS_Z_PLACEHOLDER;
  743. /*
  744. * if we're calibrating R, skip to U
  745. */
  746. } else if( pcv->cState < JCS_R_PLACEHOLDER )
  747. {
  748. pcv->cState = JCS_R_PLACEHOLDER;
  749. /*
  750. * if we're calibrating U, skip to V
  751. */
  752. } else if( pcv->cState < JCS_U_PLACEHOLDER )
  753. {
  754. pcv->cState = JCS_U_PLACEHOLDER;
  755. /*
  756. * if we're calibrating V, skip to POV
  757. */
  758. } else if( pcv->cState < JCS_V_PLACEHOLDER )
  759. {
  760. pcv->cState = JCS_V_PLACEHOLDER;
  761. /*
  762. * we must be calibration POV, skip to the end
  763. */
  764. } else
  765. {
  766. pcv->cState = JCS_POV_MOVELEFT;
  767. }
  768. #endif
  769. /*
  770. * state changed, reset to the new one
  771. */
  772. CauseRedraw( &pcv->ji, FALSE );
  773. joyCalStateChange( pcv, hwnd, TRUE );
  774. } /* joyCalStateSkip */
  775. /*
  776. * resetCustomPOVFlags - set POV flags based on original values for custom joystick
  777. */
  778. static void resetCustomPOVFlags( LPGLOBALVARS pgv, LPJOYREGHWCONFIG pcfg )
  779. {
  780. assert(pgv);
  781. assert(pcfg);
  782. if( pcfg->dwType == JOY_HW_CUSTOM )
  783. {
  784. pcfg->hws.dwFlags &= ~(JOY_HWS_POVISPOLL|JOY_HWS_POVISBUTTONCOMBOS);
  785. if( pgv->bOrigPOVIsPoll )
  786. pcfg->hws.dwFlags |= JOY_HWS_POVISPOLL;
  787. if( pgv->bOrigPOVIsButtonCombos )
  788. pcfg->hws.dwFlags |= JOY_HWS_POVISBUTTONCOMBOS;
  789. }
  790. } /* resetCustomPOVFlags */
  791. /*
  792. * joyCalStateBack - move back to start the previous state
  793. */
  794. static void joyCalStateBack( LPCALVARS pcv, HWND hwnd )
  795. {
  796. assert(pcv);
  797. assert(hwnd);
  798. BOOL back;
  799. LPJOYREGHWCONFIG pcfg;
  800. LPGLOBALVARS pgv;
  801. pgv = pcv->pgv;
  802. assert(pgv);
  803. back = TRUE;
  804. pcfg = &pgv->joyHWCurr;
  805. assert(pcfg);
  806. /*
  807. * at the end, backup
  808. */
  809. if( pcv->cState == JCS_FINI )
  810. {
  811. // ADDED BY CML 6/21/96 TO FIX LOST FOCUS BUG (FLASH RAID 167)
  812. SetFocus(GetDlgItem(hwnd, IDC_JOYCALBACK));
  813. // END ADD
  814. /*
  815. * if there is POV, back up to it
  816. */
  817. if( pcfg->hws.dwFlags & JOY_HWS_HASPOV )
  818. {
  819. pcv->cState = JCS_V_PLACEHOLDER;
  820. resetCustomPOVFlags( pgv, pcfg );
  821. /*
  822. * if there is V, back up to it
  823. */
  824. } else if( pcfg->hws.dwFlags & JOY_HWS_HASV )
  825. {
  826. pcv->cState = JCS_U_PLACEHOLDER;
  827. /*
  828. * if there is U, back up to it
  829. */
  830. } else if( pcfg->hws.dwFlags & JOY_HWS_HASU )
  831. {
  832. pcv->cState = JCS_R_PLACEHOLDER;
  833. /*
  834. * if there is R, back up to it
  835. */
  836. } else if( (pcfg->hws.dwFlags & JOY_HWS_HASR) || (pcfg->dwUsageSettings & JOY_US_HASRUDDER) )
  837. {
  838. pcv->cState = JCS_Z_PLACEHOLDER;
  839. /*
  840. * if there is Z, back up to it
  841. */
  842. } else if( pcfg->hws.dwFlags & JOY_HWS_HASZ )
  843. {
  844. pcv->cState = JCS_XY_CENTER2;
  845. /*
  846. * no where else to go, back up to XY
  847. */
  848. } else
  849. {
  850. // ADDED BY CML 6/21/96 TO FIX LOST FOCUS BUG (FLASH RAID 167)
  851. SetFocus(GetDlgItem(hwnd, IDC_JOYCALNEXT));
  852. // END ADD
  853. // pcv->cState = JCS_INIT;
  854. pcv->cState = JCS_XY_MOVE;
  855. // back = FALSE;
  856. }
  857. /*
  858. * doing POV, so restart it
  859. */
  860. } else if( pcv->cState > JCS_POV_MOVEUP )
  861. {
  862. pcv->cState = JCS_V_PLACEHOLDER;
  863. // pcfg->hws.dwFlags &= ~(JOY_HWS_POVISPOLL|JOY_HWS_POVISBUTTONCOMBOS);
  864. resetCustomPOVFlags( pgv, pcfg );
  865. /*
  866. * just starting POV, back up
  867. */
  868. } else if( pcv->cState == JCS_POV_MOVEUP )
  869. {
  870. // ADDED BY CML 6/21/96 TO FIX LOST FOCUS BUG (FLASH RAID 167)
  871. SetFocus(GetDlgItem(hwnd, IDC_JOYCALBACK));
  872. // END ADD
  873. /*
  874. * if there is V, back up to it
  875. */
  876. if( pcfg->hws.dwFlags & JOY_HWS_HASV )
  877. {
  878. pcv->cState = JCS_U_PLACEHOLDER;
  879. /*
  880. * if there is U, back up to it
  881. */
  882. } else if( pcfg->hws.dwFlags & JOY_HWS_HASU )
  883. {
  884. pcv->cState = JCS_R_PLACEHOLDER;
  885. /*
  886. * if there is R, back up to it
  887. */
  888. } else if( (pcfg->hws.dwFlags & JOY_HWS_HASR) ||
  889. (pcfg->dwUsageSettings & JOY_US_HASRUDDER) )
  890. {
  891. pcv->cState = JCS_Z_PLACEHOLDER;
  892. /*
  893. * if there is Z, back up to it
  894. */
  895. } else if( pcfg->hws.dwFlags & JOY_HWS_HASZ )
  896. {
  897. pcv->cState = JCS_XY_CENTER2;
  898. /*
  899. * no where else to go, back up to XY
  900. */
  901. } else
  902. {
  903. // ADDED BY CML 6/21/96 TO FIX LOST FOCUS BUG (FLASH RAID 167)
  904. SetFocus(GetDlgItem(hwnd, IDC_JOYCALNEXT));
  905. // END ADD
  906. // pcv->cState = JCS_INIT;
  907. pcv->cState = JCS_XY_MOVE;
  908. // back = FALSE;
  909. }
  910. /*
  911. * doing V, backup
  912. */
  913. } else if( pcv->cState == JCS_V_MOVE )
  914. {
  915. /*
  916. * if there is U, back up to it
  917. */
  918. if( pcfg->hws.dwFlags & JOY_HWS_HASU )
  919. {
  920. pcv->cState = JCS_R_PLACEHOLDER;
  921. /*
  922. * if there is R, back up to it
  923. */
  924. } else if( (pcfg->hws.dwFlags & JOY_HWS_HASR) ||
  925. (pcfg->dwUsageSettings & JOY_US_HASRUDDER) )
  926. {
  927. pcv->cState = JCS_Z_PLACEHOLDER;
  928. /*
  929. * if there is Z, back up to it
  930. */
  931. } else if( pcfg->hws.dwFlags & JOY_HWS_HASZ )
  932. {
  933. pcv->cState = JCS_XY_CENTER2;
  934. /*
  935. * no where else to go, back up to XY
  936. */
  937. } else
  938. {
  939. // ADDED BY CML 6/21/96 TO FIX LOST FOCUS BUG (FLASH RAID 167)
  940. SetFocus(GetDlgItem(hwnd, IDC_JOYCALNEXT));
  941. // END ADD
  942. // pcv->cState = JCS_INIT;
  943. pcv->cState = JCS_XY_MOVE;
  944. // back = FALSE;
  945. }
  946. /*
  947. * doing U, backup
  948. */
  949. } else if( pcv->cState == JCS_U_MOVE )
  950. {
  951. /*
  952. * if there is R, back up to it
  953. */
  954. if( (pcfg->hws.dwFlags & JOY_HWS_HASR) ||
  955. (pcfg->dwUsageSettings & JOY_US_HASRUDDER) )
  956. {
  957. pcv->cState = JCS_Z_PLACEHOLDER;
  958. /*
  959. * if there is Z, back up to it
  960. */
  961. } else if( pcfg->hws.dwFlags & JOY_HWS_HASZ )
  962. {
  963. pcv->cState = JCS_XY_CENTER2;
  964. /*
  965. * no where else to go, back up to XY
  966. */
  967. } else
  968. {
  969. // pcv->cState = JCS_INIT;
  970. pcv->cState = JCS_XY_MOVE;
  971. // back = FALSE;
  972. }
  973. /*
  974. * doing R, backup
  975. */
  976. } else if( pcv->cState == JCS_R_MOVE )
  977. {
  978. /*
  979. * if there is Z, back up to it
  980. */
  981. if( pcfg->hws.dwFlags & JOY_HWS_HASZ )
  982. {
  983. pcv->cState = JCS_XY_CENTER2;
  984. /*
  985. * no where else to go, back up to XY
  986. */
  987. } else
  988. {
  989. // ADDED BY CML 6/21/96 TO FIX LOST FOCUS BUG (FLASH RAID 167)
  990. SetFocus(GetDlgItem(hwnd, IDC_JOYCALNEXT));
  991. // END ADD
  992. // pcv->cState = JCS_INIT;
  993. pcv->cState = JCS_XY_MOVE;
  994. // back = FALSE;
  995. }
  996. /*
  997. * if we're doing Z or in the middle of XY, backup to XY
  998. */
  999. } else if( pcv->cState == JCS_XY_MOVE )
  1000. {
  1001. SetFocus(GetDlgItem(hwnd, IDC_JOYCALNEXT));
  1002. pcv->cState = JCS_INIT;
  1003. back = FALSE;
  1004. } else
  1005. {
  1006. // ADDED BY CML 6/21/96 TO FIX LOST FOCUS BUG (FLASH RAID 167)
  1007. SetFocus(GetDlgItem(hwnd, IDC_JOYCALNEXT));
  1008. // END ADD
  1009. pcv->cState = (cal_states)(pcv->cState - 2);
  1010. // pcv->cState = JCS_INIT;
  1011. // back = FALSE;
  1012. }
  1013. /*
  1014. * state changed, reset to the new one
  1015. */
  1016. CauseRedraw( &pcv->ji, FALSE );
  1017. joyCalStateChange( pcv, hwnd, back );
  1018. } /* joyCalStateBack */
  1019. // macro to get new max/min data for an axis
  1020. #define NEWMINMAX( a ) \
  1021. if( pji->dw##a##pos > pcv->jr.jpMax.dw##a ) { \
  1022. pcv->jr.jpMax.dw##a = pji->dw##a##pos; \
  1023. } \
  1024. if( pji->dw##a##pos < pcv->jr.jpMin.dw##a ) { \
  1025. pcv->jr.jpMin.dw##a = pji->dw##a##pos; \
  1026. } \
  1027. pji->dw##a##pos *= RAW_SHIFT;
  1028. // joyCollectCalInfo - record calibration info
  1029. static BOOL joyCollectCalInfo( LPCALVARS pcv, HWND hwnd, LPJOYINFOEX pji )
  1030. {
  1031. assert(pcv);
  1032. assert(hwnd);
  1033. assert(pji);
  1034. LPGLOBALVARS pgv;
  1035. LPJOYREGHWCONFIG pcfg;
  1036. pgv = pcv->pgv;
  1037. assert(pgv);
  1038. switch( pcv->cState )
  1039. {
  1040. // remember XY center
  1041. case JCS_XY_CENTER1:
  1042. case JCS_XY_CENTER2:
  1043. #ifdef _DEBUG
  1044. TRACE("%s: %d: dwXpos is %d dwYpos is %d\n", __FILE__, __LINE__, pji->dwXpos, pji->dwYpos);
  1045. #endif // _DEBUG
  1046. if( !pcv->jr.jpCenter.dwY )
  1047. {
  1048. pgv->joyRange.jpMax.dwY = pji->dwYpos << 1;
  1049. pcv->jr.jpCenter.dwY = pji->dwYpos;
  1050. }
  1051. if( !pcv->jr.jpCenter.dwX )
  1052. {
  1053. pgv->joyRange.jpMax.dwX = pji->dwXpos << 1;
  1054. pcv->jr.jpCenter.dwX = pji->dwXpos;
  1055. }
  1056. pgv->joyRange.jpMin.dwX = 0;
  1057. pgv->joyRange.jpMin.dwY = 0;
  1058. DoJoyMove( pgv, hwnd, pji, &pcv->ji, JOYMOVE_DRAWXY );
  1059. break;
  1060. // remember max/min XY values
  1061. case JCS_XY_MOVE:
  1062. if( pji->dwXpos > pcv->jr.jpMax.dwX )
  1063. {
  1064. pcv->jr.jpMax.dwX = pji->dwXpos;
  1065. }
  1066. if( pji->dwXpos < pcv->jr.jpMin.dwX )
  1067. {
  1068. pcv->jr.jpMin.dwX = pji->dwXpos;
  1069. }
  1070. if( pji->dwYpos > pcv->jr.jpMax.dwY )
  1071. {
  1072. pcv->jr.jpMax.dwY = pji->dwYpos;
  1073. }
  1074. if( pji->dwYpos < pcv->jr.jpMin.dwY )
  1075. {
  1076. pcv->jr.jpMin.dwY = pji->dwYpos;
  1077. }
  1078. DoJoyMove( pgv, hwnd, pji, &pcv->ji, JOYMOVE_DRAWXY );
  1079. break;
  1080. // remember max/min Z value
  1081. case JCS_Z_MOVE:
  1082. NEWMINMAX( Z );
  1083. DoJoyMove( pgv, hwnd, pji, &pcv->ji, JOYMOVE_DRAWZ );
  1084. break;
  1085. // remember max/min R value
  1086. case JCS_R_MOVE:
  1087. NEWMINMAX( R );
  1088. DoJoyMove( pgv, hwnd, pji, &pcv->ji, JOYMOVE_DRAWR );
  1089. break;
  1090. // remember max/min U value
  1091. case JCS_U_MOVE:
  1092. NEWMINMAX( U );
  1093. DoJoyMove( pgv, hwnd, pji, &pcv->ji, JOYMOVE_DRAWU );
  1094. break;
  1095. // remember max/min V value
  1096. case JCS_V_MOVE:
  1097. NEWMINMAX( V );
  1098. DoJoyMove( pgv, hwnd, pji, &pcv->ji, JOYMOVE_DRAWV );
  1099. break;
  1100. }
  1101. // if a button was pressed, move to the next state
  1102. if( ((pcv->ji.dwButtons & ALL_BUTTONS) != (pji->dwButtons & ALL_BUTTONS)) &&
  1103. ((pji->dwButtons & JOY_BUTTON1) ||
  1104. (pji->dwButtons & JOY_BUTTON2) ||
  1105. (pji->dwButtons & JOY_BUTTON3) ||
  1106. (pji->dwButtons & JOY_BUTTON4) ||
  1107. (pji->dwButtons & JOY_BUTTON5) ||
  1108. (pji->dwButtons & JOY_BUTTON6) ||
  1109. (pji->dwButtons & JOY_BUTTON7) ||
  1110. (pji->dwButtons & JOY_BUTTON8) ||
  1111. (pji->dwButtons & JOY_BUTTON9) ||
  1112. (pji->dwButtons & JOY_BUTTON10) ||
  1113. (pji->dwButtons & JOY_BUTTON11) ||
  1114. (pji->dwButtons & JOY_BUTTON12) ||
  1115. (pji->dwButtons & JOY_BUTTON13) ||
  1116. (pji->dwButtons & JOY_BUTTON14) ||
  1117. (pji->dwButtons & JOY_BUTTON15) ||
  1118. (pji->dwButtons & JOY_BUTTON16) ||
  1119. (pji->dwButtons & JOY_BUTTON17) ||
  1120. (pji->dwButtons & JOY_BUTTON18) ||
  1121. (pji->dwButtons & JOY_BUTTON19) ||
  1122. (pji->dwButtons & JOY_BUTTON20) ||
  1123. (pji->dwButtons & JOY_BUTTON21) ||
  1124. (pji->dwButtons & JOY_BUTTON22) ||
  1125. (pji->dwButtons & JOY_BUTTON23) ||
  1126. (pji->dwButtons & JOY_BUTTON24) ||
  1127. (pji->dwButtons & JOY_BUTTON25) ||
  1128. (pji->dwButtons & JOY_BUTTON26) ||
  1129. (pji->dwButtons & JOY_BUTTON27) ||
  1130. (pji->dwButtons & JOY_BUTTON28) ||
  1131. (pji->dwButtons & JOY_BUTTON29) ||
  1132. (pji->dwButtons & JOY_BUTTON30) ||
  1133. (pji->dwButtons & JOY_BUTTON31) ||
  1134. (pji->dwButtons & JOY_BUTTON32) ) )
  1135. {
  1136. // check and see if we are leaving one calibration to the next;
  1137. // if yes, take time to stop and remember what the user just did
  1138. pcfg = &pgv->joyHWCurr;
  1139. assert(pcfg);
  1140. switch( pcv->cState )
  1141. {
  1142. case JCS_XY_CENTER1:
  1143. pcv->jr.jpCenter.dwX = pji->dwXpos;
  1144. pcv->jr.jpCenter.dwY = pji->dwYpos;
  1145. DPF( "Center 1: %d,%d\r\n", pji->dwXpos, pji->dwYpos );
  1146. break;
  1147. case JCS_XY_CENTER2:
  1148. DPF( "Center 2: %d,%d\r\n", pji->dwXpos, pji->dwYpos );
  1149. pcv->jr.jpCenter.dwX += pji->dwXpos;
  1150. pcv->jr.jpCenter.dwY += pji->dwYpos;
  1151. pcv->jr.jpCenter.dwX /= 2;
  1152. pcv->jr.jpCenter.dwY /= 2;
  1153. DPF( "Center Avg: %d,%d\r\n", pcv->jr.jpCenter.dwX, pcv->jr.jpCenter.dwY );
  1154. pcfg->hwv.jrvHardware.jpMin.dwX = pcv->jr.jpMin.dwX;
  1155. pcfg->hwv.jrvHardware.jpMin.dwY = pcv->jr.jpMin.dwY;
  1156. pcfg->hwv.jrvHardware.jpMax.dwX = pcv->jr.jpMax.dwX;
  1157. pcfg->hwv.jrvHardware.jpMax.dwY = pcv->jr.jpMax.dwY;
  1158. pcfg->hwv.jrvHardware.jpCenter.dwX = pcv->jr.jpCenter.dwX;
  1159. pcfg->hwv.jrvHardware.jpCenter.dwY = pcv->jr.jpCenter.dwY;
  1160. pcfg->hwv.dwCalFlags |= JOY_ISCAL_XY;
  1161. break;
  1162. case JCS_Z_MOVE:
  1163. pcfg->hwv.jrvHardware.jpMin.dwZ = pcv->jr.jpMin.dwZ;
  1164. pcfg->hwv.jrvHardware.jpMax.dwZ = pcv->jr.jpMax.dwZ;
  1165. pcfg->hwv.dwCalFlags |= JOY_ISCAL_Z;
  1166. break;
  1167. case JCS_R_MOVE:
  1168. pcfg->hwv.jrvHardware.jpMin.dwR = pcv->jr.jpMin.dwR;
  1169. pcfg->hwv.jrvHardware.jpMax.dwR = pcv->jr.jpMax.dwR;
  1170. pcfg->hwv.dwCalFlags |= JOY_ISCAL_R;
  1171. break;
  1172. case JCS_U_MOVE:
  1173. pcfg->hwv.jrvHardware.jpMin.dwU = pcv->jr.jpMin.dwU;
  1174. pcfg->hwv.jrvHardware.jpMax.dwU = pcv->jr.jpMax.dwU;
  1175. pcfg->hwv.dwCalFlags |= JOY_ISCAL_U;
  1176. break;
  1177. case JCS_V_MOVE:
  1178. pcfg->hwv.jrvHardware.jpMin.dwV = pcv->jr.jpMin.dwV;
  1179. pcfg->hwv.jrvHardware.jpMax.dwV = pcv->jr.jpMax.dwV;
  1180. pcfg->hwv.dwCalFlags |= JOY_ISCAL_V;
  1181. break;
  1182. }
  1183. pcv->ji.dwButtons = pji->dwButtons;
  1184. return(joyCalStateChange( pcv, hwnd, TRUE ));
  1185. }
  1186. pcv->ji.dwButtons = pji->dwButtons;
  1187. return(TRUE);
  1188. } /* joyCollectCalInfo */
  1189. /*
  1190. * joyCalibrateInitDialog - init the calibration dialog
  1191. */
  1192. static BOOL joyCalibrateInitDialog( HWND hwnd, LPARAM lParam )
  1193. {
  1194. LPJOYREGHWCONFIG pcfg;
  1195. LPCALVARS pcv = NULL;
  1196. LPGLOBALVARS pgv = NULL;
  1197. ASSERT (::IsWindow(hwnd));
  1198. // set up calibration variables
  1199. pcv = (CALVARS *) DoAlloc( sizeof( CALVARS ) );
  1200. ASSERT(pcv);
  1201. if( pcv == NULL ) return(FALSE);
  1202. SetWindowLong( hwnd, DWL_USER, (LONG) pcv );
  1203. assert(pcv);
  1204. pgv = (LPGLOBALVARS) lParam;
  1205. assert(pgv);
  1206. pcv->pgv = pgv;
  1207. //
  1208. // set labels
  1209. //
  1210. LPSTR psz1 = new char[MAX_STR_LEN];
  1211. ASSERT (psz1);
  1212. LPSTR psz2 = new char[MAX_STR_LEN];
  1213. ASSERT (psz2);
  1214. if( !LoadString(GetResourceInstance(), IDS_JOYCALCAPN, psz1, MAX_STR_LEN) )
  1215. {
  1216. TRACE( "%s: %s - LoadString Failure!\n", __FILE__, __LINE__);
  1217. }
  1218. wsprintf(psz2, psz1, pgv->iJoyId+1);
  1219. SetWindowText(hwnd, psz2);
  1220. if( psz1 )
  1221. delete[] (psz1);
  1222. if( psz2 )
  1223. delete[] (psz2);
  1224. // init state info
  1225. pcv->cState = JCS_INIT;
  1226. // set dialog text based on OEM strings
  1227. SetOEMText( pgv, hwnd, FALSE );
  1228. // customize dialog based on Z axis, R axis, and POV hat
  1229. pcfg = &pgv->joyHWCurr;
  1230. assert(pcfg);
  1231. pcv->iAxisCount = 2;
  1232. if( pcfg->hws.dwFlags & JOY_HWS_HASZ )
  1233. pcv->iAxisCount++;
  1234. if( (pcfg->hws.dwFlags & JOY_HWS_HASR) || (pcfg->dwUsageSettings & JOY_US_HASRUDDER) )
  1235. pcv->iAxisCount++;
  1236. if( (pcfg->hws.dwFlags & JOY_HWS_HASPOV) && (pcfg->hws.dwFlags & JOY_HWS_POVISPOLL) )
  1237. pcv->iAxisCount++;
  1238. if( pcfg->hws.dwFlags & JOY_HWS_HASU )
  1239. pcv->iAxisCount++;
  1240. if( pcfg->hws.dwFlags & JOY_HWS_HASV )
  1241. pcv->iAxisCount++;
  1242. ShowControls( pcfg, hwnd );
  1243. HWND hCtrl = GetDlgItem( hwnd, IDC_JOYPOV_LABEL );
  1244. ASSERT (::IsWindow(hCtrl));
  1245. ShowWindow(hCtrl, pcfg->hws.dwFlags & JOY_HWS_HASPOV ? SW_SHOW : SW_HIDE);
  1246. // if all axes are used and we have POV then it MUST be buttons
  1247. if( pcfg->hws.dwFlags & JOY_HWS_HASPOV )
  1248. {
  1249. if( pgv->dwMaxAxes == 4 && pcv->iAxisCount == 4 )
  1250. pcfg->hws.dwFlags |= JOY_HWS_POVISBUTTONCOMBOS;
  1251. }
  1252. // other misc setup
  1253. pcv->bPOVdone = FALSE;
  1254. pcv->bHasTimer = SetTimer( hwnd, TIMER_ID, JOYPOLLTIME, NULL );
  1255. pcv->bUseTimer = TRUE;
  1256. if( !pcv->bHasTimer )
  1257. {
  1258. DPF( "No timer for joystick calibration!\r\n" );
  1259. return(FALSE);
  1260. }
  1261. if( !joyCalStateChange( pcv, hwnd, FALSE ) )
  1262. {
  1263. DPF( "Could not initialize joystick calibration\r\n" );
  1264. return(FALSE);
  1265. }
  1266. return(TRUE);
  1267. } /* joyCalibrateInitDialog */
  1268. /*
  1269. * setJIFlagsForPOV - get joyinfo flags to allow a raw POV poll
  1270. */
  1271. static void setJIFlagsForPOV( LPCALVARS pcv, LPJOYREGHWCONFIG pcfg, DWORD *pflags )
  1272. {
  1273. /*
  1274. * for polled POV, we need to specifiy JOY_CAL_READ(3|4) to make
  1275. * the driver give us position values back instead of trying to
  1276. * give us a POV value back
  1277. */
  1278. // if( pcfg->hws.dwFlags & JOY_HWS_HASPOV )
  1279. {
  1280. if( pcfg->hws.dwFlags & JOY_HWS_POVISPOLL )
  1281. {
  1282. switch( pcv->iAxisCount )
  1283. {
  1284. case 6:
  1285. (*pflags) |= JOY_CAL_READ6;
  1286. break;
  1287. case 5:
  1288. (*pflags) |= JOY_CAL_READ5;
  1289. break;
  1290. case 4:
  1291. (*pflags) |= JOY_CAL_READ4;
  1292. break;
  1293. case 3:
  1294. (*pflags) |= JOY_CAL_READ3;
  1295. break;
  1296. }
  1297. // If we don't have a 3rd or 4th axis on this joystick, try reading
  1298. // another axis anyway to see if the POV hat is on it
  1299. } else if( !(pcfg->hws.dwFlags & (JOY_HWS_POVISPOLL|JOY_HWS_POVISBUTTONCOMBOS)) )
  1300. {
  1301. switch( pcv->iAxisCount )
  1302. {
  1303. case 5:
  1304. (*pflags) |= JOY_CAL_READ6;
  1305. break;
  1306. case 4:
  1307. (*pflags) |= JOY_CAL_READ5;
  1308. break;
  1309. case 3:
  1310. (*pflags) |= JOY_CAL_READ4;
  1311. break;
  1312. case 2:
  1313. (*pflags) |= JOY_CAL_READ3;
  1314. break;
  1315. }
  1316. }
  1317. }
  1318. } /* setJIFlagsForPOV */
  1319. // tryPOV - try for a POV access
  1320. static BOOL tryPOV( LPCALVARS pcv, HWND hwnd )
  1321. {
  1322. assert(pcv);
  1323. assert(hwnd);
  1324. int rc;
  1325. BOOL ispoll;
  1326. BOOL isb;
  1327. BOOL nowaypoll;
  1328. JOYINFOEX ji;
  1329. DWORD val;
  1330. LPJOYREGHWCONFIG pcfg;
  1331. LPGLOBALVARS pgv;
  1332. int i;
  1333. pgv = pcv->pgv;
  1334. assert(pgv);
  1335. // reject call if not in a POV state
  1336. if( !(pcv->cState == JCS_POV_MOVEUP || pcv->cState == JCS_POV_MOVEDOWN ||
  1337. pcv->cState == JCS_POV_MOVELEFT || pcv->cState == JCS_POV_MOVERIGHT) )
  1338. return(FALSE);
  1339. // take a snapshot of the current joystick state
  1340. pcfg = &pgv->joyHWCurr;
  1341. assert(pcfg);
  1342. nowaypoll = FALSE;
  1343. ji.dwSize = sizeof( ji );
  1344. while( 1 )
  1345. {
  1346. // get joystick info
  1347. ji.dwFlags = JOY_CALIB_FLAGS;
  1348. // if you have a POV, set the flags for it!
  1349. if( pcfg->hws.dwFlags & JOY_HWS_HASPOV )
  1350. setJIFlagsForPOV( pcv, pcfg, &ji.dwFlags );
  1351. rc = joyGetPosEx( pgv->iJoyId, &ji );
  1352. if( rc == JOYERR_NOERROR )
  1353. break;
  1354. if( !(pcfg->hws.dwFlags & JOY_HWS_POVISPOLL) && (ji.dwFlags & (JOY_CAL_READ3|JOY_CAL_READ4|JOY_CAL_READ5|JOY_CAL_READ6)) )
  1355. {
  1356. // try again, but don't ask for extra axis
  1357. ji.dwFlags &= ~(JOY_CAL_READ6 | JOY_CAL_READ5 | JOY_CAL_READ4 | JOY_CAL_READ3);
  1358. rc = joyGetPosEx( pgv->iJoyId, &ji );
  1359. if( rc == JOYERR_NOERROR )
  1360. {
  1361. nowaypoll = TRUE; // pov can't possibly be polled
  1362. break;
  1363. } else return(JoyError( hwnd )) ? TRUE : FALSE; // have to wait for next "Select POV" to retry
  1364. } else return(JoyError( hwnd )) ? TRUE : FALSE; // have to wait for next "Select POV" to retry
  1365. }
  1366. /*
  1367. * here is where we determine if POV is polled or is button combos.
  1368. *
  1369. * See if we already know the answer (bits in joyHWCurr):
  1370. * if yes:
  1371. * we're done.
  1372. * if no:
  1373. * We see if there are currently multiple buttons down.
  1374. * if yes:
  1375. * POV is assumed to be button combos.
  1376. * if no:
  1377. * POV is assumed to be done with polling
  1378. */
  1379. ispoll = FALSE;
  1380. isb = FALSE;
  1381. if( pcfg->hws.dwFlags & JOY_HWS_POVISPOLL )
  1382. {
  1383. ispoll = TRUE;
  1384. } else if( pcfg->hws.dwFlags & JOY_HWS_POVISBUTTONCOMBOS )
  1385. {
  1386. isb = TRUE;
  1387. }
  1388. if( !isb && !ispoll )
  1389. {
  1390. // the type is indeterminate, so we identify it
  1391. if( nowaypoll ||((ji.dwButtons != 0) &&
  1392. (ji.dwButtons != JOY_BUTTON1) &&
  1393. (ji.dwButtons != JOY_BUTTON2) &&
  1394. (ji.dwButtons != JOY_BUTTON3) &&
  1395. (ji.dwButtons != JOY_BUTTON4) &&
  1396. (ji.dwButtons != JOY_BUTTON5) &&
  1397. (ji.dwButtons != JOY_BUTTON6) &&
  1398. (ji.dwButtons != JOY_BUTTON7) &&
  1399. (ji.dwButtons != JOY_BUTTON8) &&
  1400. (ji.dwButtons != JOY_BUTTON9) &&
  1401. (ji.dwButtons != JOY_BUTTON10) &&
  1402. (ji.dwButtons != JOY_BUTTON11) &&
  1403. (ji.dwButtons != JOY_BUTTON12) &&
  1404. (ji.dwButtons != JOY_BUTTON13) &&
  1405. (ji.dwButtons != JOY_BUTTON14) &&
  1406. (ji.dwButtons != JOY_BUTTON15) &&
  1407. (ji.dwButtons != JOY_BUTTON16) &&
  1408. (ji.dwButtons != JOY_BUTTON17) &&
  1409. (ji.dwButtons != JOY_BUTTON18) &&
  1410. (ji.dwButtons != JOY_BUTTON19) &&
  1411. (ji.dwButtons != JOY_BUTTON20) &&
  1412. (ji.dwButtons != JOY_BUTTON21) &&
  1413. (ji.dwButtons != JOY_BUTTON22) &&
  1414. (ji.dwButtons != JOY_BUTTON23) &&
  1415. (ji.dwButtons != JOY_BUTTON24) &&
  1416. (ji.dwButtons != JOY_BUTTON25) &&
  1417. (ji.dwButtons != JOY_BUTTON26) &&
  1418. (ji.dwButtons != JOY_BUTTON27) &&
  1419. (ji.dwButtons != JOY_BUTTON28) &&
  1420. (ji.dwButtons != JOY_BUTTON29) &&
  1421. (ji.dwButtons != JOY_BUTTON30) &&
  1422. (ji.dwButtons != JOY_BUTTON31) &&
  1423. (ji.dwButtons != JOY_BUTTON32) ) )
  1424. {
  1425. isb = TRUE;
  1426. pcfg->hws.dwFlags |= JOY_HWS_POVISBUTTONCOMBOS;
  1427. } else
  1428. {
  1429. // we always assume J2 Y for a polling POV if unspecified
  1430. ispoll = TRUE;
  1431. pcfg->hws.dwFlags |= JOY_HWS_POVISPOLL;
  1432. }
  1433. // the driver needs to notified that we've made this decision
  1434. RegSaveCurrentJoyHW( pgv );
  1435. RegistryUpdated( pgv );
  1436. }
  1437. // record the data value for this POV reading
  1438. if( isb )
  1439. val = ji.dwButtons;
  1440. else
  1441. val = (pcfg->hws.dwFlags & JOY_HWS_HASZ) ? ji.dwRpos : ji.dwZpos;
  1442. switch( pcv->cState )
  1443. {
  1444. case JCS_POV_MOVEUP:
  1445. pcv->pov[JOY_POVVAL_FORWARD] = val;
  1446. break;
  1447. case JCS_POV_MOVERIGHT:
  1448. pcv->pov[JOY_POVVAL_RIGHT] = val;
  1449. break;
  1450. case JCS_POV_MOVEDOWN:
  1451. pcv->pov[JOY_POVVAL_BACKWARD] = val;
  1452. break;
  1453. case JCS_POV_MOVELEFT:
  1454. pcv->pov[JOY_POVVAL_LEFT] = val;
  1455. // since this was the last POV thing to calibrate, we need to save the calibration info
  1456. for( i=0;i<JOY_POV_NUMDIRS;i++ )
  1457. pcfg->hwv.dwPOVValues[i] = pcv->pov[i];
  1458. pcfg->hwv.dwCalFlags |= JOY_ISCAL_POV;
  1459. pcv->bPOVdone = TRUE;
  1460. break;
  1461. }
  1462. return(joyCalStateChange( pcv, hwnd, TRUE ));
  1463. } /* tryPOV */
  1464. #ifdef DEAD_CODE
  1465. // FixCustomPOVType - fix custom POV type info if POV wasn't calibrated; called by test dlg to update config
  1466. void FixCustomPOVType( LPCALVARS pcv )
  1467. {
  1468. assert(pcv);
  1469. if( !pcv->bPOVdone )
  1470. resetCustomPOVFlags( pcv->pgv, &pcv->pgv->joyHWCurr );
  1471. } /* FixCustomPOVType */
  1472. #endif // DEAD_CODE
  1473. // CalibrateProc - calibrate a joystick
  1474. BOOL CALLBACK CalibrateProc( HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
  1475. {
  1476. switch( umsg )
  1477. {
  1478. case WM_CONTEXTMENU:
  1479. OnContextMenu(wParam);
  1480. return(1);
  1481. case WM_HELP:
  1482. OnHelp(lParam);
  1483. return(1);
  1484. case WM_TIMER:
  1485. {
  1486. LPCALVARS pcv = (LPCALVARS) GetWindowLong( hwnd, DWL_USER );
  1487. assert(pcv);
  1488. if( pcv->bUseTimer )
  1489. {
  1490. JOYINFOEX *ji = new JOYINFOEX;
  1491. ASSERT (ji);
  1492. MMRESULT rc;
  1493. LPJOYREGHWCONFIG pcfg;
  1494. LPGLOBALVARS pgv;
  1495. pgv = pcv->pgv;
  1496. assert(pgv);
  1497. pcv->bUseTimer = FALSE;
  1498. ji->dwSize = sizeof( JOYINFOEX );
  1499. while( 1 )
  1500. {
  1501. // get current joystick info
  1502. ji->dwFlags = JOY_CALIB_FLAGS;
  1503. pcfg = &pgv->joyHWCurr;
  1504. ASSERT(pcfg);
  1505. // if there is a POV, set the flags for it!
  1506. if( pcfg->hws.dwFlags & JOY_HWS_HASPOV )
  1507. setJIFlagsForPOV( pcv, pcfg, &ji->dwFlags );
  1508. rc = joyGetPosEx( pgv->iJoyId, ji );
  1509. if( rc == JOYERR_NOERROR )
  1510. break;
  1511. // didn't work, try without extra POV axis
  1512. if( !(pcfg->hws.dwFlags & JOY_HWS_POVISPOLL) && (ji->dwFlags & (JOY_CAL_READ3|JOY_CAL_READ4|JOY_CAL_READ5|JOY_CAL_READ6)) )
  1513. {
  1514. ji->dwFlags &= ~(JOY_CAL_READ6 | JOY_CAL_READ5 | JOY_CAL_READ4 | JOY_CAL_READ3);
  1515. rc = joyGetPosEx( pgv->iJoyId, ji );
  1516. if( rc == JOYERR_NOERROR )
  1517. break;
  1518. }
  1519. if( !JoyError( hwnd ) )
  1520. {
  1521. // return now if cancel selected; don't turn back on the timer
  1522. PostMessage(hwnd, WM_COMMAND, IDCANCEL, 0); // ADDED CML 7/05/96
  1523. return(FALSE);
  1524. }
  1525. continue;
  1526. }
  1527. // how could you get here and rc != JOYERR_NOERROR?
  1528. if( rc == JOYERR_NOERROR )
  1529. joyCollectCalInfo( pcv, hwnd, ji );
  1530. if( ji )
  1531. delete (ji);
  1532. /*
  1533. * If we've started POV calibration, we need to look at the
  1534. * keyboard and ignore joystick, so don't turn the timer
  1535. * back on if we've started the POV calibration
  1536. */
  1537. if( pcv->cState < JCS_POV_MOVEUP )
  1538. pcv->bUseTimer = TRUE;
  1539. }
  1540. break;
  1541. }
  1542. case WM_DESTROY:
  1543. {
  1544. LPCALVARS pcv = (LPCALVARS) GetWindowLong( hwnd, DWL_USER );
  1545. assert(pcv);
  1546. DoFree( pcv );
  1547. break;
  1548. }
  1549. case WM_INITDIALOG:
  1550. if( !joyCalibrateInitDialog( hwnd, lParam ) )
  1551. {
  1552. LPCALVARS pcv = (LPCALVARS) GetWindowLong( hwnd, DWL_USER );
  1553. assert(pcv);
  1554. if( pcv != NULL && pcv->bHasTimer )
  1555. {
  1556. KillTimer( hwnd, TIMER_ID );
  1557. pcv->bHasTimer = FALSE;
  1558. }
  1559. EndDialog( hwnd, 0 );
  1560. }
  1561. return(FALSE);
  1562. case WM_PAINT:
  1563. {
  1564. LPCALVARS pcv = (LPCALVARS) GetWindowLong( hwnd, DWL_USER );
  1565. assert(pcv);
  1566. CauseRedraw( &pcv->ji, FALSE );
  1567. return(FALSE);
  1568. }
  1569. case WM_COMMAND:
  1570. {
  1571. LPCALVARS pcv = (LPCALVARS) GetWindowLong( hwnd, DWL_USER );
  1572. assert(pcv);
  1573. int id = GET_WM_COMMAND_ID(wParam, lParam);
  1574. switch( id )
  1575. {
  1576. #ifdef DEAD_CODE
  1577. case IDC_JOYTEST:
  1578. {
  1579. BOOL timeon;
  1580. timeon = pcv->bUseTimer;
  1581. pcv->bUseTimer = FALSE;
  1582. DoTest( pcv->pgv, hwnd, (void (__cdecl *)(void *)) FixCustomPOVType, pcv );
  1583. pcv->bUseTimer = timeon;
  1584. break;
  1585. }
  1586. #endif //DEAD_CODE
  1587. case IDCANCEL:
  1588. // fall through
  1589. case IDC_JOYCALDONE:
  1590. if( pcv->bHasTimer )
  1591. {
  1592. KillTimer( hwnd, TIMER_ID );
  1593. pcv->bHasTimer = FALSE;
  1594. }
  1595. // {
  1596. // LPJOYREGHWCONFIG pcfg = &pcv->pgv->joyHWCurr;
  1597. // assert(pcfg);
  1598. // }
  1599. EndDialog( hwnd, (id == IDC_JOYCALDONE) );
  1600. break;
  1601. case IDC_JOYPICKPOV:
  1602. if( !tryPOV( pcv, hwnd ) )
  1603. {
  1604. ASSERT (::IsWindow(hwnd));
  1605. HWND hwb = GetDlgItem( hwnd, IDC_JOYPICKPOV );
  1606. ASSERT (::IsWindow(hwb));
  1607. ShowWindow( hwb, SW_HIDE );
  1608. EnableWindow( hwb, FALSE );
  1609. }
  1610. break;
  1611. case IDC_JOYCALNEXT:
  1612. pcv->bUseTimer = TRUE;
  1613. joyCalStateSkip( pcv, hwnd );
  1614. break;
  1615. case IDC_JOYCALBACK:
  1616. pcv->bUseTimer = TRUE;
  1617. joyCalStateBack( pcv, hwnd );
  1618. break;
  1619. default:
  1620. break;
  1621. }
  1622. break;
  1623. }
  1624. default:
  1625. break;
  1626. }
  1627. return(FALSE);
  1628. } // CalibrateProc
  1629. // DoCalibrate - do the calibration dialog
  1630. void DoCalibrate( LPGLOBALVARS pgv, HWND hwnd )
  1631. {
  1632. assert(pgv);
  1633. JOYREGHWCONFIG save_joycfg;
  1634. int rc;
  1635. int id;
  1636. // save the current config, and then add the rudder if it is present
  1637. save_joycfg = pgv->joyHWCurr;
  1638. // if this is a custom joystick, then don't assume anything
  1639. // about how the POV is set up
  1640. if( pgv->joyHWCurr.dwType == JOY_HW_CUSTOM )
  1641. {
  1642. pgv->bOrigPOVIsPoll = (pgv->joyHWCurr.hws.dwFlags & JOY_HWS_POVISPOLL);
  1643. pgv->bOrigPOVIsButtonCombos = (pgv->joyHWCurr.hws.dwFlags & JOY_HWS_POVISBUTTONCOMBOS);
  1644. pgv->joyHWCurr.hws.dwFlags &= ~(JOY_HWS_POVISPOLL|JOY_HWS_POVISBUTTONCOMBOS);
  1645. }
  1646. // update the registry with our new joystick info
  1647. RegSaveCurrentJoyHW( pgv );
  1648. RegistryUpdated( pgv );
  1649. // Fix for 8738, missing IDD_JOYCALIBRATE1 in resource table!
  1650. id = ( pgv->joyHWCurr.hws.dwFlags & (JOY_HWS_HASU|JOY_HWS_HASV)) ? IDD_JOYCALIBRATE1 : IDD_CAL;
  1651. rc = DialogBoxParam(GetResourceInstance(), MAKEINTRESOURCE( id ), hwnd,
  1652. (int (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long)) CalibrateProc, (LONG) pgv );
  1653. // update the registry with the new info or the old info
  1654. if( rc )
  1655. PropSheet_Changed( GetParent(hwnd), hwnd );
  1656. else
  1657. pgv->joyHWCurr = save_joycfg;
  1658. RegSaveCurrentJoyHW( pgv );
  1659. RegistryUpdated( pgv );
  1660. } /* DoCalibrate */
  1661. ////////////////////////////////////////////////////////////////////////////////////////
  1662. // OnContextMenu(WPARAM wParam)
  1663. ////////////////////////////////////////////////////////////////////////////////////////
  1664. void OnContextMenu(WPARAM wParam)
  1665. {
  1666. short nSize = STR_LEN_32;
  1667. // point to help file
  1668. char *pszHelpFileName = new char[nSize];
  1669. ASSERT (pszHelpFileName);
  1670. // returns help file name and size of string
  1671. GetHelpFileName(pszHelpFileName, &nSize);
  1672. WinHelp((HWND)wParam, pszHelpFileName, HELP_CONTEXTMENU, (DWORD)CalibrateHelpIDs);
  1673. if( pszHelpFileName ) delete[] (pszHelpFileName);
  1674. }
  1675. ////////////////////////////////////////////////////////////////////////////////////////
  1676. // OnHelp(LPARAM lParam)
  1677. ////////////////////////////////////////////////////////////////////////////////////////
  1678. void OnHelp(LPARAM lParam)
  1679. {
  1680. short nSize = STR_LEN_32;
  1681. // point to help file
  1682. char *pszHelpFileName = new char[nSize];
  1683. ASSERT (pszHelpFileName);
  1684. // returns help file name and size of string
  1685. GetHelpFileName(pszHelpFileName, &nSize);
  1686. LPHELPINFO lphi = (LPHELPINFO)lParam;
  1687. if( lphi->iContextType==HELPINFO_WINDOW )
  1688. WinHelp((HWND)lphi->hItemHandle, pszHelpFileName, HELP_WM_HELP, (DWORD)CalibrateHelpIDs);
  1689. if( pszHelpFileName ) delete[] (pszHelpFileName);
  1690. }