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.

879 lines
19 KiB

  1. #include "sol.h"
  2. VSZASSERT
  3. BOOL fMegaDiscardHack = fFalse; /* See klond.c's DiscardMove */
  4. MOVE move = {0}; /* move data, pointed to by current pcol->pmove */
  5. COLCLS *PcolclsCreate(INT tcls, INT (FAR *lpfnColProc)(),
  6. DX dxUp, DY dyUp, DX dxDn, DY dyDn,
  7. INT dcrdUp, INT dcrdDn)
  8. {
  9. COLCLS *pcolcls;
  10. if((pcolcls = PAlloc(sizeof(COLCLS)))==NULL)
  11. return NULL;
  12. Assert(lpfnColProc != NULL);
  13. pcolcls->tcls = tcls;
  14. pcolcls->lpfnColProc = lpfnColProc;
  15. pcolcls->ccolDep = 0;
  16. pcolcls->dxUp = dxUp;
  17. pcolcls->dyUp = dyUp;
  18. pcolcls->dxDn = dxDn;
  19. pcolcls->dyDn = dyDn;
  20. pcolcls->dcrdUp = dcrdUp;
  21. pcolcls->dcrdDn = dcrdDn;
  22. return pcolcls;
  23. }
  24. COL *PcolCreate(COLCLS *pcolcls, X xLeft, Y yTop, X xRight, Y yBot, INT icrdMax)
  25. {
  26. COL *pcol;
  27. if((pcol = PAlloc(sizeof(COL) + (icrdMax-1)*sizeof(CRD)))==NULL)
  28. return NULL;
  29. if( (pcol->pcolcls = pcolcls) != NULL )
  30. pcol->lpfnColProc = pcolcls->lpfnColProc;
  31. pcol->rc.xLeft = xLeft;
  32. pcol->rc.yTop = yTop;
  33. pcol->rc.xRight = xRight;
  34. pcol->rc.yBot = yBot;
  35. pcol->icrdMax = icrdMax;
  36. pcol->icrdMac = 0;
  37. pcol->pmove = NULL;
  38. if(pcol->pcolcls != NULL)
  39. pcol->pcolcls->ccolDep++;
  40. return pcol;
  41. }
  42. #ifdef DEBUG
  43. INT SendColMsg(COL *pcol, INT msgc, WPARAM wp1, LPARAM wp2)
  44. {
  45. INT imdbg;
  46. INT wResult;
  47. Assert(pcol != NULL);
  48. imdbg = ILogMsg(pcol, msgc, wp1, wp2, fFalse);
  49. wResult = (*(pcol->lpfnColProc))(pcol, msgc, wp1, wp2);
  50. LogMsgResult(imdbg, wResult);
  51. return wResult;
  52. }
  53. #endif
  54. VOID DrawBackExcl(COL *pcol, PT *ppt)
  55. {
  56. COLCLS *pcolcls;
  57. pcolcls = pcol->pcolcls;
  58. if(pcolcls->dxUp != 0 || pcolcls->dxDn != 0)
  59. DrawBackground(ppt->x+dxCrd, pcol->rc.yTop, pcol->rc.xRight, pcol->rc.yBot);
  60. if(pcolcls->dyUp != 0 || pcolcls->dyDn != 0)
  61. DrawBackground(pcol->rc.xLeft, ppt->y+dyCrd, pcol->rc.xRight, pcol->rc.yBot);
  62. }
  63. BOOL DefFreeCol(COL *pcol)
  64. {
  65. COLCLS *pcolcls;
  66. if((pcolcls = pcol->pcolcls) != NULL)
  67. {
  68. pcolcls = pcol->pcolcls;
  69. Assert(pcolcls->ccolDep > 0);
  70. if(--pcolcls->ccolDep == 0)
  71. {
  72. FreeP(pcol->pcolcls);
  73. }
  74. }
  75. FreeP(pcol);
  76. return fTrue;
  77. }
  78. INT DefHit(COL *pcol, PT *ppt, INT icrdMin)
  79. {
  80. INT icrd;
  81. CRD *pcrd;
  82. HDC hdc, hdcCurSav;
  83. PT ptCrd;
  84. RC rc;
  85. INT OldusehdcCur;
  86. if(!PtInRect((LPRECT)&pcol->rc, *(POINT *)ppt) || pcol->icrdMac == 0)
  87. return icrdNil;
  88. for(icrd = pcol->icrdMac-1; icrd >= icrdMin && (pcrd = &pcol->rgcrd[icrd])->fUp; icrd--)
  89. {
  90. if(FPtInCrd(pcrd, *ppt))
  91. {
  92. move.ccrdSel = pcol->icrdMac-icrd;
  93. /* save where mouse hit card */
  94. ptCrd = pcol->rgcrd[icrd].pt;
  95. move.delHit.dx = ptCrd.x - ppt->x;
  96. move.delHit.dy = ptCrd.y - ppt->y;
  97. if(fOutlineDrag)
  98. goto Return;
  99. hdc = GetDC(hwndApp);
  100. if(hdc == NULL)
  101. {
  102. // No longer referenced label.
  103. //
  104. //OOM0:
  105. OOM();
  106. return icrdNil;
  107. }
  108. move.hdcScreen = hdc;
  109. move.dyCol = dyCrd+(move.ccrdSel-1)*pcol->pcolcls->dyUp;
  110. rc.xRight = (rc.xLeft = ptCrd.x) + dxCrd;
  111. rc.yTop = ptCrd.y;
  112. rc.yBot = rc.yTop+move.dyCol;
  113. /* optimization: if column already drawn and visible on screen */
  114. /* then blt it to col image right here. */
  115. if(FRectAllVisible(hdc, &rc))
  116. {
  117. BitBlt(move.hdcCol, 0, 0, dxCrd, move.dyCol, hdc, ptCrd.x, ptCrd.y, SRCCOPY);
  118. }
  119. else
  120. {
  121. OldusehdcCur = usehdcCur;
  122. usehdcCur = 1;
  123. hdcCurSav = HdcSet(move.hdcCol, ptCrd.x, ptCrd.y);
  124. DrawBackground(ptCrd.x, ptCrd.y, pcol->rc.xRight, pcol->rc.yBot);
  125. SendColMsg(pcol, msgcRender, icrd, pcol->icrdMac);
  126. HdcSet(hdcCurSav, 0, 0);
  127. usehdcCur = OldusehdcCur;
  128. }
  129. OldusehdcCur = usehdcCur;
  130. usehdcCur = 1;
  131. hdcCurSav = HdcSet(move.hdcScreenSave, ptCrd.x, ptCrd.y);
  132. DrawBackground(ptCrd.x, ptCrd.y, pcol->rc.xRight, pcol->rc.yBot);
  133. SendColMsg(pcol, msgcRender, icrd-1, WMax(0, icrd));
  134. HdcSet(hdcCurSav, 0, 0);
  135. usehdcCur = OldusehdcCur;
  136. Return:
  137. pcol->pmove = &move;
  138. move.icrdSel = icrd;
  139. return icrd;
  140. }
  141. }
  142. return icrdNil;
  143. }
  144. BOOL DefMouseUp(COL *pcol, PT *pptPrev, BOOL fRender)
  145. {
  146. MOVE *pmove;
  147. VOID DrawOutline();
  148. if(fRender)
  149. SendColMsg(pcol, msgcZip, 0, 0);
  150. if(fOutlineDrag)
  151. {
  152. if(pptPrev->x != ptNil.x)
  153. SendColMsg(pcol, msgcDrawOutline, (INT_PTR) pptPrev, (INT_PTR) &ptNil);
  154. return fTrue;
  155. }
  156. pmove = pcol->pmove;
  157. if (pcol->pmove == NULL)
  158. return fTrue;
  159. if(pmove->fHdc)
  160. {
  161. if(pptPrev->x != ptNil.x)
  162. {
  163. BitBlt(pmove->hdcScreen, pptPrev->x+pmove->delHit.dx, pptPrev->y+pmove->delHit.dy,
  164. dxCrd, pmove->dyCol, pmove->hdcScreenSave, 0, 0, SRCCOPY);
  165. }
  166. if(fRender)
  167. {
  168. SendColMsg(pcol, msgcRender, pmove->icrdSel-1, icrdToEnd);
  169. }
  170. ReleaseDC(hwndApp, pmove->hdcScreen);
  171. pmove->hdcScreen = NULL;
  172. }
  173. return fTrue;
  174. }
  175. /* Removes cards from pcol and puts them into pcolTemp */
  176. /* ccrdSel and icrdSel must be set in pcol->pmove */
  177. BOOL DefRemove(COL *pcol, COL *pcolTemp)
  178. {
  179. INT icrdSel;
  180. INT ccrdSel;
  181. INT ccrdShiftDown; /* amount left over in pcol */
  182. Assert(pcol->pmove != NULL);
  183. if (pcol->pmove == NULL)
  184. return fTrue;
  185. icrdSel = pcol->pmove->icrdSel;
  186. ccrdSel = pcol->pmove->ccrdSel;
  187. Assert(ccrdSel <= pcolTemp->icrdMax);
  188. /* save the cards to remove in pcolTemp */
  189. bltb(&pcol->rgcrd[icrdSel], &pcolTemp->rgcrd[0], sizeof(CRD) * ccrdSel);
  190. pcolTemp->icrdMac = ccrdSel;
  191. /* remove the cards from pcol */
  192. Assert(icrdSel+ccrdSel <= pcol->icrdMax);
  193. ccrdShiftDown = pcol->icrdMac - (icrdSel+ccrdSel);
  194. /* copy down any left over above the deleted cards */
  195. if (ccrdShiftDown > 0)
  196. {
  197. bltb(&pcol->rgcrd[icrdSel+ccrdSel], &pcol->rgcrd[icrdSel],
  198. sizeof(CRD) * ccrdShiftDown);
  199. }
  200. pcol->icrdMac -= ccrdSel; /* no longer have this many cards */
  201. /* pcol->pmove = NULL; Done in DefEndSel.. */
  202. return fTrue;
  203. }
  204. /* insert cards from pcolTemp into pcol at icrd */
  205. BOOL DefInsert(COL *pcol, COL *pcolTemp, INT icrd)
  206. {
  207. INT icrdT;
  208. icrdT = icrd == icrdToEnd ? pcol->icrdMac : icrd;
  209. Assert(icrdT <= pcol->icrdMac);
  210. Assert(pcol->icrdMac+pcolTemp->icrdMac <= pcol->icrdMax);
  211. /* is it the hard case of inserting in the middle of a col? */
  212. /* if so, expand pcol->rgcrd */
  213. if(icrd != icrdToEnd)
  214. bltb(&pcol->rgcrd[icrdT], &pcol->rgcrd[icrdT+pcolTemp->icrdMac],
  215. sizeof(CRD) * pcolTemp->icrdMac);
  216. else
  217. icrd = pcol->icrdMac;
  218. /* Insert the cards from pcolTemp to pcol */
  219. bltb(&pcolTemp->rgcrd[0], &pcol->rgcrd[icrdT], sizeof(CRD) * pcolTemp->icrdMac);
  220. pcol->icrdMac += pcolTemp->icrdMac;
  221. pcolTemp->icrdMac = 0;
  222. return fTrue;
  223. }
  224. BOOL DefMove(COL *pcolDest, COL *pcolSrc, INT icrd)
  225. {
  226. INT icrdMacDestSav, icrdSelSav;
  227. COL *pcolTemp;
  228. BOOL fResult;
  229. BOOL fZip;
  230. fZip = icrd & bitFZip;
  231. icrd &= icrdMask;
  232. Assert(pcolSrc->pmove != NULL);
  233. if (pcolSrc->pmove == NULL)
  234. return fTrue;
  235. icrdSelSav = WMax(pcolSrc->pmove->icrdSel-1, 0);
  236. icrdMacDestSav = (icrd == icrdToEnd) ? pcolDest->icrdMac : icrd;
  237. if((pcolTemp = PcolCreate(NULL, 0, 0, 0, 0, pcolSrc->pmove->ccrdSel)) == NULL)
  238. return fFalse;
  239. fResult = SendColMsg(pcolSrc, msgcRemove, (INT_PTR)pcolTemp, 0) &&
  240. SendColMsg(pcolDest, msgcInsert, (INT_PTR) pcolTemp, icrd) &&
  241. SendColMsg(pcolDest, msgcComputeCrdPos, icrdMacDestSav, fFalse) &&
  242. (!fZip || SendColMsg(pcolSrc, msgcZip, 0, 0)) &&
  243. (!fOutlineDrag || SendColMsg(pcolSrc, msgcRender, icrdSelSav, icrdToEnd)) &&
  244. SendColMsg(pcolDest, msgcRender, icrdMacDestSav, icrdToEnd) &&
  245. SendColMsg(pcolSrc, msgcEndSel, fFalse, 0);
  246. FreeP(pcolTemp);
  247. return fResult;
  248. }
  249. BOOL DefCopy(COL *pcolDest, COL *pcolSrc, BOOL fAll)
  250. {
  251. Assert(pcolSrc->icrdMac <= pcolDest->icrdMax);
  252. if(fAll)
  253. bltb(pcolSrc, pcolDest, sizeof(COL)+(pcolSrc->icrdMac-1)*sizeof(CRD));
  254. else
  255. {
  256. bltb(pcolSrc->rgcrd, pcolDest->rgcrd, pcolSrc->icrdMac*sizeof(CRD));
  257. pcolDest->icrdMac = pcolSrc->icrdMac;
  258. }
  259. return(SendColMsg(pcolDest, msgcRender, 0, icrdToEnd));
  260. }
  261. BOOL DefRender(COL *pcol, INT icrdFirst, INT icrdLast)
  262. {
  263. INT icrd;
  264. INT icrdMac;
  265. CRD *pcrd, *pcrdPrev;
  266. COLCLS *pcolcls;
  267. icrdFirst = WMax(icrdFirst, 0);
  268. Assert(icrdLast >= 0);
  269. if(!FGetHdc())
  270. return fFalse;
  271. if(pcol->icrdMac == 0 || icrdLast == 0)
  272. {
  273. DrawBackground(pcol->rc.xLeft, pcol->rc.yTop, pcol->rc.xRight, pcol->rc.yBot);
  274. if(icrdLast == 0)
  275. goto EraseExtra;
  276. }
  277. else
  278. {
  279. Assert(icrdToEnd >= 0);
  280. Assert(icrdToEnd > pcol->icrdMac);
  281. Assert(icrdLast == icrdToEnd || icrdLast <= pcol->icrdMac);
  282. icrdMac = WMin(pcol->icrdMac, icrdLast);
  283. for(icrd = icrdFirst; icrd < icrdMac; icrd++)
  284. {
  285. pcrd = &pcol->rgcrd[icrd];
  286. if(icrd == icrdFirst ||
  287. pcrd->pt.x != pcrdPrev->pt.x || pcrd->pt.y != pcrdPrev->pt.y ||
  288. pcrd->fUp)
  289. DrawCard(pcrd);
  290. pcrdPrev = pcrd;
  291. }
  292. EraseExtra:
  293. /* hack to make dealing quicker */
  294. if(pgmCur->fDealt || pcol->pcolcls->tcls == tclsDeck)
  295. {
  296. pcolcls = pcol->pcolcls;
  297. pcrd = &pcol->rgcrd[icrdLast == 0 ? 0 : icrdMac-1];
  298. DrawBackExcl(pcol, &pcrd->pt);
  299. }
  300. }
  301. ReleaseHdc();
  302. return fTrue;
  303. }
  304. BOOL DefPaint(COL *pcol, PAINTSTRUCT *ppaint)
  305. {
  306. INT icrd;
  307. if(ppaint == NULL)
  308. icrd = 0;
  309. else
  310. {
  311. if(!FRectIsect(&pcol->rc, (RC *)&ppaint->rcPaint))
  312. return fFalse;
  313. if(pcol->icrdMac == 0)
  314. icrd = 0;
  315. else
  316. {
  317. for(icrd = 0; icrd < pcol->icrdMac ;icrd++)
  318. if(FCrdRectIsect(&pcol->rgcrd[icrd], (RC *)&ppaint->rcPaint))
  319. break;
  320. if(icrd == pcol->icrdMac)
  321. return fFalse;
  322. }
  323. }
  324. return SendColMsg(pcol, msgcRender, icrd, icrdToEnd);
  325. }
  326. /* New super cool dragging, does five blts, but no clippin' */
  327. BOOL DefDrawOutline(COL *pcol, PT *ppt, PT *pptPrev)
  328. {
  329. HDC hdc, hdcT;
  330. HBITMAP hbmT;
  331. MOVE *pmove;
  332. PT pt, ptPrev;
  333. DEL del;
  334. COLCLS *pcolcls;
  335. Assert(pcol->pmove != NULL);
  336. pmove = pcol->pmove;
  337. if (pcol->pmove == NULL)
  338. return fTrue;
  339. OffsetPt(ppt, &pmove->delHit, &pt);
  340. if(pptPrev->x != ptNil.x)
  341. OffsetPt(pptPrev, &pmove->delHit, &ptPrev);
  342. if(fOutlineDrag)
  343. {
  344. pcolcls = pcol->pcolcls;
  345. DrawOutline(&pt, pmove->ccrdSel, 0, pcolcls->dyUp);
  346. if(pptPrev->x != ptNil.x)
  347. {
  348. DrawOutline(&ptPrev, pmove->ccrdSel, 0, pcolcls->dyUp);
  349. }
  350. return fTrue;
  351. }
  352. hdc = pmove->hdcScreen;
  353. Assert(hdc != NULL);
  354. hdcT = pmove->hdcT;
  355. Assert(hdcT != NULL);
  356. hbmT = pmove->hbmT;
  357. Assert(hbmT != NULL);
  358. /* screen to save hdc */
  359. BitBlt(hdcT, 0, 0, dxCrd, pmove->dyCol, hdc, pt.x, pt.y, SRCCOPY);
  360. /* if not the first time */
  361. if(pptPrev->x != ptNil.x)
  362. {
  363. del.dx = pptPrev->x - ppt->x;
  364. del.dy = pptPrev->y - ppt->y;
  365. /* save old screen to save hdc */
  366. BitBlt(hdcT, del.dx, del.dy, dxCrd, pmove->dyCol, pmove->hdcScreenSave, 0, 0, SRCCOPY);
  367. BitBlt(pmove->hdcScreenSave, -del.dx, -del.dy, dxCrd, pmove->dyCol, pmove->hdcCol, 0, 0, SRCCOPY);
  368. }
  369. BitBlt(hdc, pt.x, pt.y, dxCrd, pmove->dyCol, pmove->hdcCol, 0, 0, SRCCOPY);
  370. if(pptPrev->x != ptNil.x)
  371. {
  372. BitBlt(hdc, ptPrev.x, ptPrev.y, dxCrd, pmove->dyCol, pmove->hdcScreenSave, 0, 0, SRCCOPY);
  373. }
  374. /* swap pmove->hdcT and pmove->hdcScreenSave */
  375. hdcT = pmove->hdcScreenSave;
  376. pmove->hdcScreenSave = pmove->hdcT;
  377. pmove->hdcT = hdcT;
  378. /* swap pmove->hbmT and pmove->hbmScreenSaveOld */
  379. hbmT = pmove->hbmScreenSaveOld;
  380. pmove->hbmScreenSaveOld = pmove->hbmT;
  381. pmove->hbmT = hbmT;
  382. return fTrue;
  383. }
  384. BOOL DefComputeCrdPos(COL *pcol, INT icrdFirst, BOOL fAssumeDown)
  385. {
  386. INT icrd;
  387. CRD *pcrd;
  388. COLCLS *pcolcls;
  389. PT pt;
  390. Assert(icrdFirst >= 0);
  391. if(icrdFirst == 0)
  392. {
  393. pt.x = pcol->rc.xLeft;
  394. pt.y = pcol->rc.yTop;
  395. }
  396. else
  397. {
  398. Assert(icrdFirst < pcol->icrdMac);
  399. pt = pcol->rgcrd[--icrdFirst].pt;
  400. /* Used by discard, because discard piles are handled differently */
  401. if(fMegaDiscardHack)
  402. icrdFirst++;
  403. }
  404. pcolcls = pcol->pcolcls;
  405. for(icrd = icrdFirst; icrd < pcol->icrdMac; icrd++)
  406. {
  407. pcrd = &pcol->rgcrd[icrd];
  408. pcrd->pt = pt;
  409. if(pcrd->fUp && !fAssumeDown)
  410. {
  411. if(icrd % pcolcls->dcrdUp == pcolcls->dcrdUp-1)
  412. {
  413. pt.x += pcolcls->dxUp;
  414. pt.y += pcolcls->dyUp;
  415. }
  416. }
  417. else if(icrd % pcolcls->dcrdDn == pcolcls->dcrdDn-1)
  418. {
  419. pt.x += pcolcls->dxDn;
  420. pt.y += pcolcls->dyDn;
  421. }
  422. }
  423. return fTrue;
  424. }
  425. VOID InvertCardPt(PT *ppt)
  426. {
  427. RC rc;
  428. rc.xRight = (rc.xLeft = ppt->x) + dxCrd;
  429. rc.yBot = (rc.yTop = ppt->y) + dyCrd;
  430. InvertRc(&rc);
  431. }
  432. INT DefValidMovePt(COL *pcolDest, COL *pcolSrc, PT *ppt)
  433. {
  434. RC rc;
  435. Assert(pcolSrc->pmove != NULL);
  436. if (pcolSrc->pmove == NULL)
  437. return fTrue;
  438. Assert((X *)&(((RC *)(0))->xLeft) == (X *)&(((PT *)(0))->x));
  439. Assert((Y *)&(((RC *)(0))->yTop) == (Y *)&(((PT *)(0))->y));
  440. OffsetPt(ppt, &pcolSrc->pmove->delHit, (PT *)&rc);
  441. rc.xRight = rc.xLeft+dxCrd;
  442. rc.yBot = rc.yTop+dyCrd;
  443. if(pcolDest->icrdMac == 0)
  444. {
  445. if(!FRectIsect(&rc, &pcolDest->rc))
  446. return icrdNil;
  447. }
  448. else if(!(FCrdRectIsect(&pcolDest->rgcrd[pcolDest->icrdMac-1], &rc)))
  449. return icrdNil;
  450. return SendColMsg(pcolDest, msgcValidMove, (INT_PTR) pcolSrc, 0) ? pcolDest->icrdMac : icrdNil;
  451. }
  452. BOOL DefSel(COL *pcol, INT icrdFirst, INT ccrd)
  453. {
  454. #ifdef DEBUG
  455. INT icol;
  456. for(icol = 0; icol < pgmCur->icolMac; icol++)
  457. Assert(pgmCur->rgpcol[icol]->pmove == NULL);
  458. #endif
  459. move.delHit.dx = move.delHit.dy = 0;
  460. if(icrdFirst == icrdEnd)
  461. {
  462. if(pcol->icrdMac > 0)
  463. {
  464. move.icrdSel = pcol->icrdMac-1;
  465. move.ccrdSel = 1;
  466. goto Return;
  467. }
  468. else
  469. return icrdNil;
  470. }
  471. if(ccrd == ccrdToEnd)
  472. ccrd = pcol->icrdMac-icrdFirst;
  473. Assert(icrdFirst < pcol->icrdMac);
  474. Assert(icrdFirst+ccrd <= pcol->icrdMac);
  475. move.icrdSel = icrdFirst;
  476. move.ccrdSel = ccrd;
  477. Return:
  478. pcol->pmove = &move;
  479. return move.icrdSel;
  480. }
  481. BOOL DefEndSel(COL *pcol, BOOL fReleaseDC)
  482. {
  483. pcol->pmove = NULL;
  484. return fTrue;
  485. }
  486. BOOL DefFlip(COL *pcol, BOOL fUp)
  487. {
  488. INT icrd;
  489. MOVE *pmove;
  490. INT icrdMac;
  491. Assert(pcol->pmove != NULL);
  492. if (pcol->pmove == NULL)
  493. return fTrue;
  494. pmove = pcol->pmove;
  495. icrdMac = pmove->icrdSel+pmove->ccrdSel;
  496. for(icrd = pmove->icrdSel; icrd < icrdMac; icrd++)
  497. pcol->rgcrd[icrd].fUp = (short)fUp;
  498. return fTrue;
  499. }
  500. BOOL DefInvert(COL *pcol)
  501. {
  502. INT icrdSel, ccrdSel;
  503. INT icrd, icrdMid;
  504. Assert(pcol->pmove != NULL);
  505. if (pcol->pmove == NULL)
  506. return fTrue;
  507. icrdSel = pcol->pmove->icrdSel;
  508. ccrdSel = pcol->pmove->ccrdSel;
  509. icrdMid = icrdSel+ccrdSel/2;
  510. for(icrd = icrdSel; icrd < icrdMid; icrd++)
  511. SwapCards(&pcol->rgcrd[icrd], &pcol->rgcrd[2*icrdSel+ccrdSel-1-icrd]);
  512. return fTrue;
  513. }
  514. BOOL DefDragInvert(COL *pcol)
  515. {
  516. if(fOutlineDrag)
  517. {
  518. if(!FGetHdc())
  519. return fFalse;
  520. Assert((X *)&((RC *)(0))->xLeft == (X *)&((PT *)(0))->x);
  521. Assert((Y *)&((RC *)(0))->yTop == (Y *)&((PT *)(0))->y);
  522. InvertCardPt(pcol->icrdMac > 0 ? &pcol->rgcrd[pcol->icrdMac-1].pt : (PT *)&pcol->rc);
  523. ReleaseHdc();
  524. }
  525. return fTrue;
  526. }
  527. INT DefNumCards(COL *pcol, BOOL fUpOnly)
  528. {
  529. INT icrd;
  530. if(fUpOnly)
  531. {
  532. for(icrd = pcol->icrdMac-1; icrd >= 0 && pcol->rgcrd[icrd].fUp; icrd--)
  533. ;
  534. Assert(pcol->icrdMac-1-icrd >= 0);
  535. return pcol->icrdMac-1-icrd;
  536. }
  537. else
  538. return pcol->icrdMac;
  539. }
  540. BOOL DefGetPtInCrd(COL *pcol, INT icrd, PT *ppt)
  541. {
  542. PT *pptT;
  543. if(icrd == 0)
  544. pptT = (PT *)&pcol->rc;
  545. else
  546. {
  547. pptT = &pcol->rgcrd[icrd].pt;
  548. Assert(icrd < pcol->icrdMac);
  549. }
  550. ppt->x = pptT->x+dxCrd/2;
  551. ppt->y = pptT->y;
  552. return fTrue;
  553. }
  554. BOOL DefShuffle(COL *pcol)
  555. {
  556. INT iSwitch;
  557. CRD crdT;
  558. INT icrd;
  559. CRD *pcrdS;
  560. // INT cdecl rand();
  561. #define iSwitchMax 5
  562. for(iSwitch = 0; iSwitch < iSwitchMax; iSwitch++)
  563. {
  564. for(icrd = 0; icrd < pcol->icrdMac; icrd++)
  565. {
  566. pcrdS = &pcol->rgcrd[rand() % pcol->icrdMac];
  567. crdT = pcol->rgcrd[icrd];
  568. pcol->rgcrd[icrd] = *pcrdS;
  569. *pcrdS = crdT;
  570. }
  571. }
  572. return fTrue;
  573. }
  574. #define izipMax 35
  575. VOID APIENTRY DdaProc(INT x, INT y, LPARAM lpextra)
  576. {
  577. COL *pcol;
  578. PT pt;
  579. pcol = (COL *)lpextra;
  580. if (pcol->pmove == NULL)
  581. return;
  582. if(pcol->pmove->izip++ < izipMax)
  583. return;
  584. pcol->pmove->izip = 0;
  585. pt.x = x;
  586. pt.y = y;
  587. SendColMsg(pcol, msgcDrawOutline, (INT_PTR) &pt, (INT_PTR) &pgmCur->ptMousePrev);
  588. pgmCur->ptMousePrev = pt;
  589. }
  590. INT DefZip(COL *pcol)
  591. {
  592. PT ptDest;
  593. MOVE *pmove;
  594. /* When outline-dragging is checked, that starting point can be ptNil and
  595. * in this case we draw a line starting from (7FFF, 7FFF) and this
  596. * causes the temporary hang! So, avoid the LineDDA() call when the
  597. * prev point is ptNil;
  598. * Fix for Bug #8182 --SANKAR-- 01-23-90
  599. */
  600. if(pgmCur->ptMousePrev.x == ptNil.x)
  601. return(fTrue);
  602. pmove = pcol->pmove;
  603. if (pcol->pmove == NULL)
  604. return fTrue;
  605. /* Don't use OffsetPt here, it's sense is wrong */
  606. ptDest = pcol->rgcrd[pmove->icrdSel].pt;
  607. ptDest.x -= pmove->delHit.dx;
  608. ptDest.y -= pmove->delHit.dy;
  609. pmove->izip = 0;
  610. LineDDA(pgmCur->ptMousePrev.x, pgmCur->ptMousePrev.y, ptDest.x, ptDest.y, DdaProc, (LPARAM) pcol );
  611. return fTrue;
  612. }
  613. INT DefColProc(COL *pcol, INT msgc, WPARAM wp1, LPARAM wp2)
  614. {
  615. switch(msgc)
  616. {
  617. case msgcInit:
  618. return fTrue;
  619. case msgcEnd:
  620. return DefFreeCol(pcol);
  621. case msgcClearCol:
  622. pcol->pmove = NULL;
  623. pcol->icrdMac = 0;
  624. /* more? */
  625. return fTrue;
  626. case msgcHit: /* wp1 = ppt, return icrdHit/icrdNil */
  627. return DefHit(pcol, (PT *)wp1, (INT)wp2);
  628. case msgcMouseUp:
  629. return DefMouseUp(pcol, (PT *) wp1, (INT)wp2);
  630. case msgcDblClk:
  631. return fFalse;
  632. case msgcSel: /* wp1 = icrdSel, icrdEnd if last card, wp2 = ccrdSel, ccrdToEnd if all to end */
  633. return DefSel(pcol, (INT)wp1, (INT)wp2);
  634. case msgcEndSel:
  635. return DefEndSel(pcol, (BOOL)wp1);
  636. case msgcNumCards:
  637. return DefNumCards(pcol, (BOOL)wp1);
  638. case msgcFlip: /* wp1 = fUp */
  639. return DefFlip(pcol, (BOOL)wp1);
  640. case msgcInvert:
  641. return DefInvert(pcol);
  642. case msgcRemove: /* wp1 = pcolTemp, return fTrue/fFalse */
  643. return DefRemove(pcol, (COL *) wp1);
  644. case msgcInsert: /* wp1 = pcolTemp, */
  645. /* wp2 = icrd to insert after, icrdToEnd if at end*/
  646. return DefInsert(pcol, (COL *)wp1, (INT)wp2);
  647. case msgcMove: /* wp1 = pcolSrc, wp2 = icrd, (icrdToEnd = to endcrd) */
  648. /* return fTrue/fFalse */
  649. return DefMove(pcol, (COL *) wp1, (INT)wp2);
  650. case msgcCopy: /* wp1 = pcolSrc, wp2 = fAll (if true then copy all of col struct)*/
  651. return DefCopy(pcol, (COL *) wp1, (BOOL)wp2);
  652. case msgcValidMove: /* wp1 = pcolSrc, wp2 = icrd, (icrdToEnd = to endcrd) */
  653. /* this must be supplied by game */
  654. return fFalse;
  655. case msgcValidMovePt:
  656. return DefValidMovePt(pcol, (COL *) wp1, (PT *)wp2);
  657. case msgcRender: /* wp1 = icrdFirst, return fTrue/fFalse*/
  658. return DefRender(pcol, (INT)wp1, (INT)wp2);
  659. case msgcPaint: /* wp1 = ppaint, if NULL then paint all */
  660. return DefPaint(pcol, (PAINTSTRUCT *) wp1);
  661. case msgcDrawOutline: /* wp1 = ppt , wp2 = pptPrev*/
  662. return DefDrawOutline(pcol, (PT *) wp1, (PT *) wp2);
  663. case msgcComputeCrdPos: /* wp1 = icrdFirst */
  664. return DefComputeCrdPos(pcol, (INT)wp1, (BOOL)wp2);
  665. case msgcDragInvert:
  666. return DefDragInvert(pcol);
  667. case msgcGetPtInCrd:
  668. return DefGetPtInCrd(pcol, (INT)wp1, (PT *)wp2);
  669. case msgcValidKbdColSel:
  670. return fTrue;
  671. case msgcValidKbdCrdSel:
  672. return fTrue;
  673. case msgcShuffle:
  674. return DefShuffle(pcol);
  675. case msgcAnimate:
  676. return fFalse;
  677. case msgcZip:
  678. return DefZip(pcol);
  679. }
  680. Assert(fFalse);
  681. return fFalse;
  682. }