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.

724 lines
17 KiB

  1. #include "sol.h"
  2. VSZASSERT
  3. VOID FreeGm(GM *pgm)
  4. {
  5. INT icol;
  6. COL *pcol;
  7. if(pgm != NULL)
  8. {
  9. for(icol = pgm->icolMac-1; icol >= 0; icol--)
  10. if((pcol = pgm->rgpcol[icol]) != NULL)
  11. SendColMsg(pcol, msgcEnd, 0, 0);
  12. if(pgm == pgmCur)
  13. pgmCur = NULL;
  14. FreeUndo(&pgm->udr);
  15. FreeP(pgm);
  16. }
  17. }
  18. BOOL FCreateDCBM(HDC hdc, HDC *phdc, HBITMAP *phbmOld, DY dyCol)
  19. {
  20. HDC hdcT;
  21. HBITMAP hbm;
  22. if((hdcT = CreateCompatibleDC(hdc)) == NULL)
  23. return fFalse;
  24. if((hbm = CreateCompatibleBitmap(hdc, dxCrd, dyCol)) == NULL)
  25. {
  26. Error:
  27. DeleteDC(hdcT);
  28. return fFalse;
  29. }
  30. if((*phbmOld = SelectObject(hdcT, hbm)) == NULL)
  31. {
  32. /* Delete the bitmap */
  33. DeleteObject(hbm);
  34. goto Error;
  35. }
  36. *phdc = hdcT;
  37. return fTrue;
  38. }
  39. BOOL FSetDrag(BOOL fOutline)
  40. {
  41. HDC hdc;
  42. fOutlineDrag = fOutline;
  43. if(fOutline && move.fHdc)
  44. {
  45. Assert(move.hdcScreenSave);
  46. Assert(move.hdcCol);
  47. Assert(move.hbmScreenSaveOld);
  48. Assert(move.hbmColOld);
  49. Assert(move.hdcT);
  50. DeleteObject(SelectObject(move.hdcCol, move.hbmColOld));
  51. DeleteDC(move.hdcCol);
  52. DeleteObject(SelectObject(move.hdcScreenSave, move.hbmScreenSaveOld));
  53. DeleteDC(move.hdcScreenSave);
  54. DeleteObject(SelectObject(move.hdcT, move.hbmT));
  55. DeleteDC(move.hdcT);
  56. move.fHdc = fFalse;
  57. }
  58. if(!fOutline && !move.fHdc)
  59. {
  60. hdc = GetDC(hwndApp);
  61. if(hdc == NULL)
  62. {
  63. OOM:
  64. ErrorIds(idsNoFullDrag);
  65. fOutlineDrag = fFalse;
  66. move.fHdc = fFalse;
  67. return fFalse;
  68. }
  69. move.hdcScreen = NULL;
  70. if(!FCreateDCBM(hdc, &move.hdcScreenSave, &move.hbmScreenSaveOld, pgmCur->dyDragMax))
  71. {
  72. ReleaseDC(hwndApp,hdc);
  73. goto OOM;
  74. }
  75. if(!FCreateDCBM(hdc, &move.hdcT, &move.hbmT, pgmCur->dyDragMax))
  76. {
  77. OOM1:
  78. ReleaseDC(hwndApp,hdc);
  79. DeleteObject(SelectObject(move.hdcScreenSave, move.hbmScreenSaveOld));
  80. DeleteDC(move.hdcScreenSave);
  81. goto OOM;
  82. }
  83. if(!FCreateDCBM(hdc, &move.hdcCol, &move.hbmColOld, pgmCur->dyDragMax))
  84. {
  85. DeleteObject(SelectObject(move.hdcT, move.hbmT));
  86. DeleteDC(move.hdcT);
  87. goto OOM1;
  88. }
  89. move.fHdc = fTrue;
  90. ReleaseDC(hwndApp, hdc);
  91. }
  92. return fTrue;
  93. }
  94. BOOL FInitGm()
  95. {
  96. BOOL FInitKlondGm();
  97. return FInitKlondGm();
  98. }
  99. #ifdef DEBUG
  100. LRESULT SendGmMsg(GM *pgm, INT msgg, WPARAM wp1, LPARAM wp2)
  101. {
  102. INT imdbg;
  103. LRESULT wResult;
  104. Assert(pgm != NULL);
  105. imdbg = ILogMsg(pgm, msgg, wp1, wp2, fTrue);
  106. wResult =(*(pgm->lpfnGmProc))(pgm, msgg, wp1, wp2);
  107. LogMsgResult(imdbg, wResult);
  108. return wResult;
  109. }
  110. #endif
  111. BOOL DefGmInit(GM *pgm, BOOL fResetScore)
  112. {
  113. pgm->fDealt = fFalse;
  114. if(fResetScore)
  115. pgm->sco = 0;
  116. pgm->iqsecScore = 0;
  117. pgm->irep = 0;
  118. pgm->icolHilight = pgm->icolSel = icolNil;
  119. pgm->icolKbd = 0;
  120. pgm->icrdKbd = 0;
  121. pgm->fInput = fFalse;
  122. pgm->fWon = fFalse;
  123. pgm->ccrdDeal = ccrdDeal;
  124. return fTrue;
  125. }
  126. BOOL DefGmMouseDown(GM *pgm, PT *ppt, INT icolFirst)
  127. {
  128. INT icol;
  129. /* sel already in effect */
  130. if(FSelOfGm(pgm))
  131. return fFalse;
  132. if(!pgm->fDealt)
  133. return fFalse;
  134. pgm->fInput = fTrue;
  135. pgm->fButtonDown = fTrue;
  136. for(icol = icolFirst; icol < pgm->icolMac; icol++)
  137. {
  138. if(SendColMsg(pgm->rgpcol[icol], msgcHit, (INT_PTR) ppt, 0) != icrdNil)
  139. {
  140. pgm->icolSel = icol;
  141. pgm->ptMousePrev = ptNil;
  142. /* KLUDGE: in col render, we redraw the column after a selection
  143. is made. if the mouse isn't moved, no image of the selected
  144. card shows up.
  145. */
  146. if(!fOutlineDrag)
  147. {
  148. /* SendGmMsg(pgm, msggMouseMove, (INT_PTR) ppt, 0); */
  149. pgm->ptMousePrev = *ppt;
  150. }
  151. return fTrue;
  152. }
  153. }
  154. return fFalse;
  155. }
  156. BOOL DefGmMouseUp(GM *pgm, PT *pptBogus, BOOL fNoMove)
  157. {
  158. COL *pcolSel, *pcolHilight;
  159. BOOL fResult = fFalse;
  160. pgm->fButtonDown = fFalse;
  161. if(FSelOfGm(pgm))
  162. {
  163. pcolSel = pgm->rgpcol[pgm->icolSel];
  164. if(FHilightOfGm(pgm))
  165. {
  166. pcolHilight = pgm->rgpcol[pgm->icolHilight];
  167. SendGmMsg(pgm, msggSaveUndo, pgm->icolHilight, pgm->icolSel);
  168. SendColMsg(pcolHilight, msgcDragInvert, 0, 0);
  169. if(fNoMove)
  170. {
  171. SendColMsg(pcolSel, msgcMouseUp, (INT_PTR) &pgm->ptMousePrev, fTrue);
  172. fResult = fTrue;
  173. goto Return;
  174. }
  175. SendColMsg(pcolSel, msgcMouseUp, (INT_PTR) &pgm->ptMousePrev, fFalse);
  176. fResult = SendColMsg(pcolHilight, msgcMove, (INT_PTR) pcolSel, icrdToEnd) &&
  177. SendGmMsg(pgm, msggScore, (INT_PTR) pcolHilight, (INT_PTR) pcolSel);
  178. pgm->icolHilight = icolNil;
  179. if(SendGmMsg(pgm, msggIsWinner, 0, 0))
  180. SendGmMsg(pgm, msggWinner, 0, 0);
  181. }
  182. else
  183. SendColMsg(pcolSel, msgcMouseUp, (INT_PTR) &pgm->ptMousePrev, fTrue);
  184. Return:
  185. SendColMsg(pcolSel, msgcEndSel, fFalse, 0);
  186. }
  187. pgm->icolSel = icolNil;
  188. return fResult;
  189. }
  190. BOOL DefGmMouseDblClk(GM *pgm, PT * ppt)
  191. {
  192. INT icol;
  193. for(icol = 0; icol < pgm->icolMac; icol++)
  194. if(SendColMsg(pgm->rgpcol[icol], msgcDblClk, (INT_PTR) ppt, icol))
  195. return fTrue;
  196. return fFalse;
  197. }
  198. // This routine moves all the "playable" cards
  199. // to the four suit stacks.
  200. // It's invoked when the user right-clicks or
  201. // presses Ctrl-A.
  202. BOOL DefGmMouseRightClk(GM *pgm, PT * ppt)
  203. {
  204. INT icol;
  205. CRD *pcrd;
  206. INT icolDest;
  207. COL *pcolDest;
  208. BOOL fResult;
  209. COL *pcol;
  210. INT iContinue;
  211. fResult = fFalse;
  212. // Keep doing this as long as in every iteration
  213. // we move one card to the suit stack.
  214. do
  215. {
  216. iContinue = 0;
  217. for(icol = 0; icol < pgm->icolMac; icol++)
  218. {
  219. // We don't want to move cards from one suit stack
  220. // to another.
  221. if (icol >= icolFoundFirst && icol < icolFoundFirst+ccolFound)
  222. continue;
  223. // Now the column we have is one of the 7 columns
  224. // or the deck.
  225. pcol = pgm->rgpcol[icol];
  226. // If this column contains cards and the top one faces up
  227. if(pcol->icrdMac > 0 && (pcrd=&pcol->rgcrd[pcol->icrdMac-1])->fUp)
  228. {
  229. if(pcol->pmove == NULL)
  230. SendColMsg(pcol, msgcSel, icrdEnd, ccrdToEnd);
  231. Assert(pcol->pmove != NULL);
  232. // Check if it can be moved to any of the suit stacks.
  233. for(icolDest = icolFoundFirst; icolDest < icolFoundFirst+ccolFound; icolDest++)
  234. {
  235. pcolDest = pgmCur->rgpcol[icolDest];
  236. if(SendColMsg(pcolDest, msgcValidMove, (INT_PTR)pcol, 0))
  237. {
  238. SendGmMsg(pgmCur, msggSaveUndo, icolDest, icol);
  239. fResult = SendColMsg(pcolDest, msgcMove, (INT_PTR) pcol, icrdToEnd) &&
  240. (fOutlineDrag || SendColMsg(pcol, msgcRender, pcol->icrdMac-1, icrdToEnd)) &&
  241. SendGmMsg(pgmCur, msggScore, (INT_PTR) pcolDest, (INT_PTR) pcol);
  242. iContinue ++;
  243. if(SendGmMsg(pgmCur, msggIsWinner, 0, 0))
  244. SendGmMsg(pgmCur, msggWinner, 0, 0);
  245. break;
  246. }
  247. }
  248. }
  249. SendColMsg(pcol, msgcEndSel, fFalse, 0);
  250. }
  251. } while (iContinue > 0);
  252. return fResult;
  253. }
  254. BOOL DefGmMouseMove(GM *pgm, PT *ppt)
  255. {
  256. COL *pcol;
  257. INT icol;
  258. if(FSelOfGm(pgm))
  259. {
  260. Assert(pgm->icolSel < pgm->icolMac);
  261. /* draw new outline */
  262. pcol = pgm->rgpcol[pgm->icolSel];
  263. SendColMsg(pcol, msgcDrawOutline, (INT_PTR) ppt, (INT_PTR) &pgm->ptMousePrev);
  264. pgm->ptMousePrev = *ppt;
  265. for(icol = 0; icol < pgm->icolMac; icol++)
  266. if(SendColMsg(pgm->rgpcol[icol], msgcValidMovePt, (INT_PTR)pgm->rgpcol[pgm->icolSel], (INT_PTR) ppt) != icrdNil)
  267. {
  268. if(icol != pgm->icolHilight)
  269. {
  270. if(FHilightOfGm(pgm))
  271. SendColMsg(pgm->rgpcol[pgm->icolHilight], msgcDragInvert, 0, 0);
  272. pgm->icolHilight = icol;
  273. return SendColMsg(pgm->rgpcol[icol], msgcDragInvert, 0, 0);
  274. }
  275. else
  276. return fTrue;
  277. }
  278. /* nothing to hilight */
  279. if(FHilightOfGm(pgm))
  280. {
  281. SendColMsg(pgm->rgpcol[pgm->icolHilight], msgcDragInvert, 0, 0);
  282. pgm->icolHilight = icolNil;
  283. return fTrue;
  284. }
  285. }
  286. return fFalse;
  287. }
  288. BOOL DefGmPaint(GM *pgm, PAINTSTRUCT *ppaint)
  289. {
  290. INT icol;
  291. HDC hdc;
  292. hdc = HdcSet(ppaint->hdc, 0, 0);
  293. if(!pgm->fDealt)
  294. goto Return;
  295. for(icol = 0; icol < pgm->icolMac; icol++)
  296. SendColMsg(pgm->rgpcol[icol], msgcPaint, (INT_PTR) ppaint, 0);
  297. Return:
  298. HdcSet(hdc, 0, 0);
  299. return fTrue;
  300. }
  301. BOOL DefGmUndo(GM *pgm)
  302. {
  303. UDR *pudr;
  304. Assert(!FSelOfGm(pgm));
  305. pudr = &pgm->udr;
  306. if(!pudr->fAvail)
  307. return fFalse;
  308. Assert(pudr->icol1 != icolNil);
  309. Assert(pudr->icol2 != icolNil);
  310. Assert(pudr->icol1 < pgm->icolMax);
  311. Assert(pudr->icol2 < pgm->icolMax);
  312. pgm->sco = pudr->sco;
  313. pgm->irep = pudr->irep;
  314. SendGmMsg(pgm, msggChangeScore, 0, 0);
  315. SendColMsg(pgm->rgpcol[pudr->icol1], msgcCopy, (INT_PTR) pudr->rgpcol[0], fTrue);
  316. SendColMsg(pgm->rgpcol[pudr->icol2], msgcCopy, (INT_PTR) pudr->rgpcol[1], fTrue);
  317. /* end any selectons if we had 'em */
  318. SendColMsg(pgm->rgpcol[pudr->icol1], msgcEndSel, 0, 0);
  319. SendColMsg(pgm->rgpcol[pudr->icol2], msgcEndSel, 0, 0);
  320. SendGmMsg(pgm, msggKillUndo, 0, 0);
  321. return fTrue;
  322. }
  323. /* in future: may want to alloc columns */
  324. BOOL DefGmSaveUndo(GM *pgm, INT icol1, INT icol2)
  325. {
  326. Assert(icol1 != icolNil);
  327. Assert(icol2 != icolNil);
  328. Assert(icol1 < pgm->icolMac);
  329. Assert(icol2 < pgm->icolMac);
  330. Assert(icol1 != icol2);
  331. /* should use msgcCopy, but undo colcls's may not be set correctly */
  332. bltb(pgm->rgpcol[icol1], pgm->udr.rgpcol[0], sizeof(COL)+(pgm->rgpcol[icol1]->icrdMac-1)*sizeof(CRD));
  333. bltb(pgm->rgpcol[icol2], pgm->udr.rgpcol[1], sizeof(COL)+(pgm->rgpcol[icol2]->icrdMac-1)*sizeof(CRD));
  334. pgm->udr.icol1 = icol1;
  335. pgm->udr.icol2 = icol2;
  336. pgm->udr.fAvail = fTrue;
  337. pgm->udr.sco = pgm->sco;
  338. pgm->udr.irep = pgm->irep;
  339. if(pgm->udr.fEndDeck)
  340. {
  341. pgm->udr.fEndDeck = FALSE;
  342. pgm->udr.irep--;
  343. }
  344. return fTrue;
  345. }
  346. #ifdef DEBUG
  347. VOID DisplayKbdSel(GM *pgm)
  348. {
  349. HDC hdc;
  350. TCHAR sz[20];
  351. INT cch;
  352. hdc = GetDC(hwndApp);
  353. PszCopy(TEXT(" "), sz);
  354. cch = CchDecodeInt(sz, pgm->icolKbd);
  355. TextOut(hdc, 0, 10, sz, 5);
  356. PszCopy(TEXT(" "), sz);
  357. cch = CchDecodeInt(sz, pgm->icrdKbd);
  358. TextOut(hdc, 0, 20, sz, 5);
  359. PszCopy(TEXT(" "), sz);
  360. cch = CchDecodeInt(sz, pgm->icolSel);
  361. TextOut(hdc, 0, 30, sz, 5);
  362. ReleaseDC(hwndApp, hdc);
  363. }
  364. #endif
  365. VOID NewKbdColAbs(GM *pgm, INT icol)
  366. {
  367. Assert(icol >= 0);
  368. Assert(icol < pgm->icolMac);
  369. if(!SendColMsg(pgm->rgpcol[icol], msgcValidKbdColSel, FSelOfGm(pgm), 0))
  370. /* beep? */
  371. return;
  372. pgm->icolKbd = icol;
  373. pgm->icrdKbd = SendColMsg(pgm->rgpcol[pgm->icolKbd], msgcNumCards, fFalse, 0)-1;
  374. if(pgm->icrdKbd < 0)
  375. pgm->icrdKbd = 0;
  376. }
  377. VOID NewKbdCol(GM *pgm, INT dcol, BOOL fNextGroup)
  378. {
  379. INT icolNew;
  380. icolNew = pgm->icolKbd;
  381. if(icolNew == icolNil)
  382. icolNew = 0;
  383. if(dcol != 0)
  384. {
  385. do
  386. {
  387. icolNew += dcol;
  388. if(icolNew < 0)
  389. icolNew = pgm->icolMac-1;
  390. else if(icolNew >= pgm->icolMac)
  391. icolNew = 0;
  392. /* only one col class and looped through all col's */
  393. if(icolNew == pgm->icolKbd)
  394. break;
  395. }
  396. while (!SendColMsg(pgm->rgpcol[icolNew], msgcValidKbdColSel, FSelOfGm(pgm), 0) ||
  397. (fNextGroup &&
  398. pgm->rgpcol[icolNew]->pcolcls->tcls ==
  399. pgm->rgpcol[pgm->icolKbd]->pcolcls->tcls));
  400. }
  401. NewKbdColAbs(pgm, icolNew);
  402. }
  403. VOID NewKbdCrd(GM *pgm, INT dcrd)
  404. {
  405. INT icrdUpMac, icrdMac;
  406. INT icrdKbdNew;
  407. icrdUpMac = SendColMsg(pgm->rgpcol[pgm->icolKbd], msgcNumCards, fTrue, 0);
  408. icrdMac = SendColMsg(pgm->rgpcol[pgm->icolKbd], msgcNumCards, fFalse, 0);
  409. if(icrdMac == 0)
  410. icrdKbdNew = 0;
  411. else
  412. {
  413. if(icrdUpMac == 0)
  414. icrdKbdNew = icrdMac-1;
  415. else
  416. icrdKbdNew = PegRange(pgm->icrdKbd+dcrd, icrdMac-icrdUpMac, icrdMac-1);
  417. }
  418. if(SendColMsg(pgm->rgpcol[pgm->icolKbd], msgcValidKbdCrdSel, icrdKbdNew, 0))
  419. pgm->icrdKbd = icrdKbdNew;
  420. }
  421. BOOL DefGmKeyHit(GM *pgm, INT vk)
  422. {
  423. PT pt, ptCurs;
  424. COLCLS *pcolcls;
  425. /* cancel any mouse selections */
  426. switch(vk)
  427. {
  428. case VK_SPACE:
  429. case VK_RETURN:
  430. if(!FSelOfGm(pgm))
  431. {
  432. /* begin a selection */
  433. NewKbdCrd(pgm, 0); /* !!! */
  434. SendColMsg(pgm->rgpcol[pgm->icolKbd], msgcGetPtInCrd, pgm->icrdKbd, (INT_PTR) &pt);
  435. if(!SendGmMsg(pgm, msggMouseDown, (INT_PTR) &pt, 0))
  436. return fFalse;
  437. NewKbdCol(pgm, 0, fFalse);
  438. goto Display;
  439. }
  440. else
  441. {
  442. /* possibly make a move */
  443. SendGmMsg(pgm, msggMouseUp, 0, fFalse);
  444. NewKbdCol(pgm, 0, fFalse);
  445. return fTrue;
  446. }
  447. case VK_ESCAPE:
  448. SendGmMsg(pgm, msggMouseUp, 0, fTrue);
  449. return fTrue;
  450. case VK_A:
  451. if (GetKeyState(VK_CONTROL) < 0)
  452. SendGmMsg(pgm, msggMouseRightClk, 0, fTrue);
  453. return fTrue;
  454. case VK_LEFT:
  455. /* Should these be VK_CONTROL??? */
  456. NewKbdCol(pgm, -1, GetKeyState(VK_SHIFT) < 0);
  457. goto Display;
  458. case VK_RIGHT:
  459. NewKbdCol(pgm, 1, GetKeyState(VK_SHIFT) < 0);
  460. goto Display;
  461. case VK_UP:
  462. NewKbdCrd(pgm, -1);
  463. goto Display;
  464. case VK_DOWN:
  465. NewKbdCrd(pgm, 1);
  466. goto Display;
  467. case VK_HOME:
  468. NewKbdColAbs(pgm, 0);
  469. goto Display;
  470. case VK_END:
  471. NewKbdColAbs(pgm, pgm->icolMac-1);
  472. goto Display;
  473. case VK_TAB:
  474. NewKbdCol(pgm, GetKeyState(VK_SHIFT) < 0 ? -1 : 1, fTrue);
  475. Display:
  476. SendColMsg(pgm->rgpcol[pgm->icolKbd], msgcGetPtInCrd, pgm->icrdKbd, (INT_PTR) &pt);
  477. ptCurs = pt;
  478. ClientToScreen(hwndApp, (LPPOINT) &ptCurs);
  479. if(FSelOfGm(pgm))
  480. {
  481. if(SendColMsg(pgm->rgpcol[pgm->icolKbd], msgcNumCards, fFalse, 0) > 0)
  482. {
  483. pcolcls = pgm->rgpcol[pgm->icolKbd]->pcolcls;
  484. ptCurs.y += pcolcls->dyUp;
  485. /* dxUp ? */
  486. }
  487. }
  488. /* SetCursorPos will cause WM_MOUSEMOVE to be sent */
  489. SetCursorPos(ptCurs.x, ptCurs.y);
  490. return fTrue;
  491. }
  492. return fFalse;
  493. }
  494. BOOL DefGmChangeScore(GM *pgm, INT cs, INT sco)
  495. {
  496. if(smd == smdNone)
  497. return fTrue;
  498. switch(cs)
  499. {
  500. default:
  501. return fTrue;
  502. case csAbs:
  503. pgm->sco = sco;
  504. break;
  505. case csDel:
  506. pgm->sco += sco;
  507. break;
  508. case csDelPos:
  509. pgm->sco = WMax(pgm->sco+sco, 0);
  510. break;
  511. }
  512. StatUpdate();
  513. return fTrue;
  514. }
  515. BOOL DefGmWinner(GM *pgm)
  516. {
  517. pgm->fWon = fFalse;
  518. if(FYesNoAlert(idsDealAgain))
  519. PostMessage(hwndApp, WM_COMMAND, idsInitiate, 0L);
  520. return fTrue;
  521. }
  522. INT DefGmProc(GM *pgm, INT msgg, WPARAM wp1, LPARAM wp2)
  523. {
  524. switch(msgg)
  525. {
  526. case msggInit:
  527. return DefGmInit(pgm, (BOOL)wp1);
  528. case msggEnd:
  529. FreeGm(pgm);
  530. break;
  531. case msggKeyHit:
  532. return DefGmKeyHit(pgm, (INT)wp1);
  533. case msggMouseRightClk:
  534. return DefGmMouseRightClk(pgm, (PT *)wp1);
  535. case msggMouseDown: /* wp1 == ppt, wp2 = icolFirst (normally 0) */
  536. return DefGmMouseDown(pgm, (PT *)wp1, (INT)wp2);
  537. case msggMouseUp:
  538. return DefGmMouseUp(pgm, (PT *)wp1, (BOOL)wp2);
  539. case msggMouseMove:
  540. return DefGmMouseMove(pgm, (PT *)wp1);
  541. case msggMouseDblClk:
  542. return DefGmMouseDblClk(pgm, (PT *)wp1);
  543. case msggPaint:
  544. return DefGmPaint(pgm, (PAINTSTRUCT *)wp1);
  545. case msggDeal:
  546. Assert(fFalse);
  547. break;
  548. case msggUndo:
  549. return DefGmUndo(pgm);
  550. case msggSaveUndo:
  551. return DefGmSaveUndo(pgm, (INT)wp1, (INT)wp2);
  552. case msggKillUndo:
  553. /* in future may want to free columns */
  554. pgm->udr.fAvail = fFalse;
  555. break;
  556. case msggIsWinner:
  557. return fFalse;
  558. case msggWinner:
  559. return DefGmWinner(pgm);
  560. case msggForceWin:
  561. NYI();
  562. break;
  563. case msggTimer:
  564. return fFalse;
  565. case msggScore:
  566. return fTrue;
  567. case msggChangeScore:
  568. return DefGmChangeScore(pgm, (INT)wp1, (INT)wp2);
  569. }
  570. return fFalse;
  571. }