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.

559 lines
11 KiB

  1. /***************/
  2. /* file: blk.c */
  3. /***************/
  4. #define _WINDOWS
  5. #include <windows.h>
  6. #include <port1632.h>
  7. #include "snake.h"
  8. #include "res.h"
  9. #include "rtns.h"
  10. #include "grafix.h"
  11. #include "blk.h"
  12. #include "pref.h"
  13. #define cbDibHeader (16*4 + sizeof(BITMAPINFOHEADER))
  14. BOOL fWipe = fFalse;
  15. extern PREF Preferences;
  16. extern LPSTR lpDibWall;
  17. extern LPSTR lpDibLvl;
  18. extern HDC hdcBlk;
  19. extern HDC hdcCor;
  20. extern HDC hdcMain;
  21. extern HBITMAP hbmpCor;
  22. extern LONG coDarkGreen;
  23. extern LONG coLiteGreen;
  24. extern STATUS status;
  25. #define icoDark 0
  26. #define icoLite 1
  27. /* CO: RESERVED RED GREEN BLUE */
  28. DWORD rgcoDark[coMax+1] =
  29. {0x007F0000, 0x0000007F, 0x007F7F00, 0x007F007F, 0x00007F7F, 0x00000000};
  30. DWORD rgcoLite[coMax+1] =
  31. {0x00FF0000, 0x000000FF, 0x00FFFF00, 0x00FF00FF, 0x0000FFFF, 0x00FFFFFF};
  32. DWORD rgcoFill[coMax+1] =
  33. {0x0000007F, 0x007F0000, 0x00007F7F, 0x007F007F, 0x007F7F00, 0x00BFBFBF};
  34. #define SurFromBlk(blk) ((SUR) ((blk) & 0x0007))
  35. COR rgmpsurcor[4][8] =
  36. {
  37. /* 000 001 010 011 100 101 110 111 */
  38. {corNW*4, corN*4, corNW*4, corN*4, corW*4, corFNW*4, corW*4, corF*4}, /*NW*/
  39. {corNE*4, corE*4, corNE*4, corE*4, corN*4, corFNE*4, corN*4, corF*4}, /*NE*/
  40. {corSE*4, corS*4, corSE*4, corS*4, corE*4, corFSE*4, corE*4, corF*4}, /*SE*/
  41. {corSW*4, corW*4, corSW*4, corW*4, corS*4, corFSW*4, corS*4, corF*4} /*SW*/
  42. };
  43. BYTE rgblknum[10][7] =
  44. {
  45. {0x0E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E}, /* 0 */
  46. {0x04, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x0E}, /* 1 */
  47. {0x1F, 0x01, 0x01, 0x1F, 0x10, 0x10, 0x1F}, /* 2 */
  48. {0x1F, 0x01, 0x01, 0x0F, 0x01, 0x01, 0x1F}, /* 3 */
  49. {0x11, 0x11, 0x11, 0x1F, 0x01, 0x01, 0x01}, /* 4 */
  50. {0x1F, 0x10, 0x10, 0x1F, 0x01, 0x01, 0x1F}, /* 5 */
  51. {0x1F, 0x10, 0x10, 0x1F, 0x11, 0x11, 0x1F}, /* 6 */
  52. {0x1F, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, /* 7 */
  53. {0x0E, 0x11, 0x11, 0x0E, 0x11, 0x11, 0x0E}, /* 8 */
  54. {0x1F, 0x11, 0x11, 0x1F, 0x01, 0x01, 0x01} /* 9 */
  55. };
  56. /*** External Data ***/
  57. extern HWND hwndMain;
  58. extern HANDLE hInst;
  59. extern BLK mpposblk[posMax];
  60. extern INT cLevel;
  61. /****** S E T B L K C O ******/
  62. /* Set Block Color */
  63. VOID SetBlkCo(LONG coDark, LONG coLite)
  64. {
  65. #define SetClr(clr,co) \
  66. { \
  67. ((LPBITMAPINFO)lpDibWall)->bmiColors[clr].rgbBlue = (BYTE)(co); \
  68. ((LPBITMAPINFO)lpDibWall)->bmiColors[clr].rgbGreen = (BYTE)(co>>8); \
  69. ((LPBITMAPINFO)lpDibWall)->bmiColors[clr].rgbRed = (BYTE)(co>>16); \
  70. ((LPBITMAPINFO)lpDibWall)->bmiColors[clr].rgbReserved = (BYTE)(0x00); \
  71. }
  72. SetClr(icoDark,coDark);
  73. SetClr(icoLite,coLite);
  74. SetDIBits(hdcCor, hbmpCor, 0, dypCorMax,
  75. lpDibWall + 8 + sizeof(BITMAPINFOHEADER),
  76. (LPBITMAPINFO) lpDibWall, DIB_RGB_COLORS);
  77. }
  78. /****** D R A W B L K ******/
  79. VOID DrawBlk(INT x, INT y, BLK blk)
  80. {
  81. BitBlt(hdcMain, x, y, dxpBlk, dypBlk, hdcBlk, 0, blk<<3, SRCCOPY);
  82. }
  83. /****** D I S P L A Y B L K ******/
  84. VOID DisplayBlk(INT x, INT y, BLK blk)
  85. {
  86. StartDraw();
  87. DrawBlk(x, y, blk);
  88. EndDraw();
  89. }
  90. /****** D R A W C O R ******/
  91. /* cor must be a multiple of 4 */
  92. VOID DrawCor(INT x, INT y, COR cor)
  93. {
  94. #ifdef DEBUG
  95. if (cor & 0x0003)
  96. OutputDebugString("Invalid Cor\r\n");
  97. #endif
  98. BitBlt(hdcMain, x, y, dxpCor, dypCor, hdcCor, 0, cor, SRCCOPY);
  99. }
  100. /****** D R A W W A L L ******/
  101. VOID DrawWall(INT x, INT y, BLK blk)
  102. {
  103. INT x2, y2;
  104. DrawCor(x,y, rgmpsurcor[0][SurFromBlk(blk)]);
  105. DrawCor(x2 = x+4, y, rgmpsurcor[1][SurFromBlk(blk >>= 2)]);
  106. DrawCor(x2,y2 = y + 4, rgmpsurcor[2][SurFromBlk(blk >>= 2)]);
  107. DrawCor(x,y2, rgmpsurcor[3][SurFromBlk(blk >>= 2)]);
  108. }
  109. /****** D I S P L A Y P O S ******/
  110. VOID DisplayPos(POS pos)
  111. {
  112. INT x = dxpGridOff + ((pos % xMax) << 3);
  113. INT y = dypGridOff + ((pos / xMax) << 3);
  114. BLK blk;
  115. StartDraw();
  116. if ((blk = mpposblk[pos]) > blkMax)
  117. DrawWall(x, y, blk);
  118. else
  119. DrawBlk(x, y, blk);
  120. EndDraw();
  121. }
  122. /****** C L E A R B O R D E R ******/
  123. VOID ClearBorder(VOID)
  124. {
  125. POS pos;
  126. for (pos = posMax; pos--;) /* BLT !! */
  127. mpposblk[pos] = blkNull;
  128. for (pos = xMax; pos < (posMax-xMax); pos += xMax)
  129. mpposblk[pos] = mpposblk[pos+xMax-1] = blkWallNS;
  130. for (pos = xMax-1; --pos > 0;)
  131. mpposblk[pos] = mpposblk[(posMax-1)-pos] = blkWallEW;
  132. mpposblk[posNW] = blkWallNW;
  133. mpposblk[posNE] = blkWallNE;
  134. mpposblk[posSW] = blkWallSW;
  135. mpposblk[posSE] = blkWallSE;
  136. }
  137. /****** S E T L E V E L C O L O R ******/
  138. VOID SetLevelColor(VOID)
  139. {
  140. INT ico = (Preferences.fColor) ? cLevel % coMax : coMax;
  141. SetBlkCo(rgcoDark[ico], rgcoLite[ico]);
  142. }
  143. /****** S E T U P B O R D E R ******/
  144. /* Just draw the border pieces */
  145. VOID SetupBorder(VOID)
  146. {
  147. INT x1,x2;
  148. SetLevelColor();
  149. DrawWall(dxpGridOff, dypGridOff, blkWallNW);
  150. DrawWall(dxpGridOff+dxpGrid-dxpBlk, dypGridOff, blkWallNE);
  151. DrawWall(dxpGridOff, dypGridOff+dypGrid-dypBlk, blkWallSW);
  152. DrawWall(dxpGridOff+dxpGrid-dxpBlk, dypGridOff+dypGrid-dypBlk, blkWallSE);
  153. for (x1 = dxpBlk, x2 = dypGrid - 2*dypBlk;
  154. x1 < (dxpGrid/2); x1 +=dxpBlk, x2 -= dypBlk)
  155. {
  156. DrawWall(dxpGridOff + x1, dypGridOff, blkWallEW);
  157. DrawWall(dxpGridOff -dxpBlk + x2, dypGridOff, blkWallEW);
  158. DrawWall(dxpGridOff, dypGridOff + x1, blkWallNS);
  159. DrawWall(dxpGridOff, dypGridOff + x2, blkWallNS);
  160. DrawWall(dxpGridOff + x1, dypGridOff+dypGrid-dypBlk, blkWallEW);
  161. DrawWall(dxpGridOff -dxpBlk + x2, dypGridOff+dypGrid-dypBlk, blkWallEW);
  162. DrawWall(dxpGridOff+dxpGrid-dxpBlk, dypGridOff + x1, blkWallNS);
  163. DrawWall(dxpGridOff+dxpGrid-dxpBlk, dypGridOff + x2, blkWallNS);
  164. }
  165. }
  166. /****** D R A W G R I D ******/
  167. VOID DrawGrid(VOID)
  168. {
  169. INT x,y;
  170. POS pos;
  171. BLK blk;
  172. x = dxpGridOff;
  173. y = dypGridOff;
  174. for (pos = 0; pos < posMax; pos++)
  175. {
  176. blk = mpposblk[pos];
  177. if (blk > blkMax)
  178. DrawWall(x,y, blk);
  179. else
  180. DrawBlk(x,y, blk);
  181. if ( (x += dxpBlk) >= (dxpGridOff+dxpGrid) )
  182. {
  183. x = dxpGridOff;
  184. y += dypBlk;
  185. }
  186. }
  187. }
  188. /****** G E T L E V E L D A T A ******/
  189. /* Get the level data from the bitmap */
  190. VOID GetLevelData(INT lvl)
  191. {
  192. LONG FAR * lpData;
  193. INT x, b;
  194. LONG lData;
  195. CHAR bData;
  196. POS pos;
  197. lpData = (LONG FAR * ) (lpDibLvl + (lvl * (32 * 4)) );
  198. pos = posMax - (xMax + xMax - 1);
  199. while (pos > xMax)
  200. {
  201. lData = *lpData;
  202. for (b = 4; b--;)
  203. {
  204. bData = (BYTE) lData;
  205. lData >>= 8;
  206. for (x = 8; x--;)
  207. {
  208. if (!(bData & 0x80))
  209. mpposblk[pos] = 0x1000;
  210. bData <<= 1;
  211. pos++;
  212. }
  213. }
  214. lpData++;
  215. pos -= (xMax+xMax-1);
  216. }
  217. }
  218. /****** M A K E W A L L S ******/
  219. VOID MakeWalls(VOID)
  220. {
  221. POS pos;
  222. BLK blk;
  223. pos = posSW;
  224. while (pos > posNE)
  225. {
  226. if (mpposblk[--pos] != blkNull)
  227. {
  228. blk = 0x1000;
  229. if (mpposblk[--pos]) blk |= 0x0101;
  230. if (mpposblk[pos -= xMax]) blk |= 0x0002;
  231. if (mpposblk[++pos]) blk |= 0x0004;
  232. if (mpposblk[++pos]) blk |= 0x0008;
  233. if (mpposblk[pos += xMax]) blk |= 0x0010;
  234. if (mpposblk[pos += xMax]) blk |= 0x0020;
  235. if (mpposblk[--pos]) blk |= 0x0040;
  236. if (mpposblk[--pos]) blk |= 0x0080;
  237. mpposblk[pos -= (xMax-1)]= blk;
  238. }
  239. }
  240. /* Fix Border */
  241. for (pos = xMax; pos < (posSW-1); pos += xMax)
  242. {
  243. mpposblk[pos] &= 0x10FE; /* Left */
  244. mpposblk[pos+posNE] &= 0x11EF; /* Right */
  245. }
  246. for (pos = posNE-1; pos > posNW;)
  247. {
  248. blk = 0x1111;
  249. if (mpposblk[pos += xMax+1]) blk |= 0x0020;
  250. if (mpposblk[--pos]) blk |= 0x0040;
  251. if (mpposblk[--pos]) blk |= 0x0080;
  252. mpposblk[pos -= (xMax-1)] = blk; /* Top */
  253. blk = 0x1111;
  254. pos += posSW;
  255. if (mpposblk[pos -= (xMax-1)]) blk |= 0x0002;
  256. if (mpposblk[--pos]) blk |= 0x0004;
  257. if (mpposblk[--pos]) blk |= 0x0008;
  258. mpposblk[pos += (xMax+1)] = blk; /* Bottom */
  259. pos -= posSW;
  260. pos--;
  261. }
  262. if (mpposblk[posNW +xMax+1])
  263. mpposblk[posNW] = blkWallNW | 0x0020;
  264. else
  265. mpposblk[posNW] = blkWallNW;
  266. if (mpposblk[posNE +xMax-1])
  267. mpposblk[posNE] = blkWallNE | 0x0080;
  268. else
  269. mpposblk[posNE] = blkWallNE;
  270. if (mpposblk[posSW-(xMax-1)])
  271. mpposblk[posSW] = blkWallSW | 0x0008;
  272. else
  273. mpposblk[posSW] = blkWallSW;
  274. if (mpposblk[posSE-(xMax+1)])
  275. mpposblk[posSE] = blkWallSE | 0x0002;
  276. else
  277. mpposblk[posSE] = blkWallSE;
  278. }
  279. /****** A D D N U M ******/
  280. VOID AddNum(POS pos, INT num)
  281. {
  282. INT x,y;
  283. INT b;
  284. for (y = 0; y < 7; y++)
  285. {
  286. b = rgblknum[num][y];
  287. for (x = 0; x++ < 5;)
  288. {
  289. if ((b <<= 1) & 0x20)
  290. mpposblk[pos] = 0x1000;
  291. pos++;
  292. }
  293. pos += (xMax - 5);
  294. }
  295. }
  296. /****** A D D L E V E L N U M ******/
  297. VOID AddLevelNum(INT lvl)
  298. {
  299. AddNum(xMax*20+10, lvl/10);
  300. AddNum(xMax*20+18, lvl%10);
  301. }
  302. /****** D R A W D A T A ******/
  303. VOID DrawData(VOID)
  304. {
  305. POS pos;
  306. BLK blk;
  307. INT x,y;
  308. x = dxpGridOff+dxpBlk;
  309. y = dypGridOff+dypBlk;
  310. for (pos = xMax+1; pos < posMax-xMax; pos++)
  311. {
  312. blk = mpposblk[pos];
  313. if (blk != blkNull)
  314. {
  315. DrawWall(x,y, blk);
  316. }
  317. if ( (x += dxpBlk) >= (dxpGridOff+dxpGrid-dxpBlk) )
  318. {
  319. x = dxpGridOff+dxpBlk;
  320. y += dypBlk;
  321. pos += 2;
  322. }
  323. }
  324. }
  325. /****** W I P E C L E A R ******/
  326. VOID WipeClear(VOID)
  327. {
  328. LONG co = rgcoFill[ Preferences.fColor ? (cLevel % coMax) : coMax];
  329. LONG lco = co & 0x00030303;
  330. INT dxp = dxpGridOff+dxpBlk;
  331. INT dyp = dypGridOff+dypBlk;
  332. INT dxp2;
  333. HBRUSH hbrush, hbrush2;
  334. fWipe = fTrue;
  335. SelectObject(hdcMain, GetStockObject(NULL_PEN));
  336. hbrush = SelectObject(hdcMain, CreateSolidBrush(co));
  337. for (dxp2 = dxp;
  338. dxp < (dxpGridOff + dxpGrid - dxpBlk);
  339. dxp = dxp2, dyp += dypBlk)
  340. {
  341. dxp2 += dxpBlk;
  342. hbrush2 = SelectObject(hdcMain, CreateSolidBrush(co));
  343. if (hbrush2)
  344. DeleteObject(hbrush2);
  345. Rectangle(hdcMain, dxpGridOff+dxpBlk, dyp, dxp2+1, dyp + dypBlk+1);
  346. Rectangle(hdcMain, dxp, dypGridOff+dypBlk, dxp2+1, dyp+1);
  347. co -= lco;
  348. }
  349. hbrush2 = SelectObject(hdcMain, CreateSolidBrush(co));
  350. if (hbrush2)
  351. DeleteObject(hbrush2);
  352. Rectangle(hdcMain, dxpGridOff+dxpBlk, dyp, dxp2+1, dyp+dxpBlk+1);
  353. hbrush2 = SelectObject(hdcMain, hbrush);
  354. if (hbrush2)
  355. DeleteObject(hbrush2);
  356. }
  357. /****** S E T U P L E V E L D A T A ******/
  358. VOID SetupLevelData(VOID)
  359. {
  360. StartDraw();
  361. ClearBorder();
  362. SetupBorder();
  363. EndDraw();
  364. GetLevelData(cLevel % lvlMax);
  365. MakeWalls();
  366. }
  367. /****** D I S P L A Y L E V E L N U M ******/
  368. VOID DrawLevelNum(VOID)
  369. {
  370. if (cLevel > 98)
  371. cLevel = 0;
  372. ClearBorder();
  373. SetupBorder();
  374. WipeClear();
  375. GetLevelData(lvlLevel);
  376. AddLevelNum(cLevel+1);
  377. MakeWalls();
  378. SetBlkCo(coDarkGreen, coLiteGreen);
  379. DrawData();
  380. DrawTime();
  381. DrawLives();
  382. }
  383. VOID DisplayLevelNum(VOID)
  384. {
  385. StartDraw();
  386. DrawLevelNum();
  387. EndDraw();
  388. }
  389. /****** D I S P L A Y G A M E O V E R ******/
  390. VOID DrawGameOver(VOID)
  391. {
  392. ClearBorder();
  393. SetupBorder();
  394. WipeClear();
  395. GetLevelData(lvlGameOver);
  396. MakeWalls();
  397. SetBlkCo(coDarkGreen, coLiteGreen);
  398. DrawData();
  399. }
  400. VOID DisplayGameOver(VOID)
  401. {
  402. StartDraw();
  403. DrawGameOver();
  404. EndDraw();
  405. }
  406. VOID ReWipe(VOID)
  407. {
  408. if (FPlay())
  409. {
  410. POS pos;
  411. BLK mpposblk2[posMax]; /* A copy of the playing grid */
  412. for (pos=posMax; --pos >= 0;)
  413. mpposblk2[pos] = mpposblk[pos];
  414. DrawLevelNum();
  415. for (pos=posMax; --pos >= 0;)
  416. mpposblk[pos] = mpposblk2[pos];
  417. }
  418. else
  419. DrawGameOver();
  420. }