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.

423 lines
6.9 KiB

  1. #ifdef PM
  2. #define INCL_WIN
  3. #define INCL_GPI
  4. #include <os2.h>
  5. INT _acrtused = 0;
  6. #endif
  7. #ifdef WIN
  8. #include <windows.h>
  9. #include <port1632.h>
  10. #endif
  11. #include "std.h"
  12. #include "scrsave.h"
  13. #ifdef WIN
  14. LONG mppenrgb [] =
  15. {
  16. RGB(0x00, 0x00, 0x00),
  17. RGB(0x00, 0x00, 0x80),
  18. RGB(0x00, 0x80, 0x00),
  19. RGB(0x00, 0x80, 0x80),
  20. RGB(0x80, 0x00, 0x00),
  21. RGB(0x80, 0x00, 0x80),
  22. RGB(0x80, 0x80, 0x00),
  23. RGB(0x80, 0x80, 0x80),
  24. RGB(0xc0, 0xc0, 0xc0),
  25. RGB(0x00, 0x00, 0xff),
  26. RGB(0x00, 0xff, 0x00),
  27. RGB(0x00, 0xff, 0xff),
  28. RGB(0xff, 0x00, 0x00),
  29. RGB(0xff, 0x00, 0xff),
  30. RGB(0xff, 0xff, 0x00),
  31. RGB(0xff, 0xff, 0xff)
  32. };
  33. #define CLR_BLACK 0
  34. #define CLR_BACKGROUND 0
  35. #endif
  36. #define MultDiv(a, b, c) ((int) (((long) (a) * (long) (b)) / (c)))
  37. INT dxScreen, dyScreen;
  38. #define dxcMax 80
  39. #define dycMax 50
  40. typedef UCHAR GRID [dxcMax][dycMax];
  41. GRID gridOld, gridNew;
  42. BOOL fRedraw;
  43. INT csecRandomize;
  44. VOID SetCell(CVS hps, GRID grid, INT dxc, INT dyc, INT clr);
  45. VOID Redraw(CVS hps);
  46. Randomize();
  47. Animate(CVS hps);
  48. ClrAverage(GRID grid, INT dxc, INT dyc);
  49. BOOL EXPENTRY ScrSaveProc(INT ssm, LPVOID l1, LONG_PTR l2, LONG_PTR l3)
  50. {
  51. CHAR FAR * lpsz;
  52. CHAR FAR * lpch;
  53. switch (ssm)
  54. {
  55. default:
  56. return FALSE;
  57. case SSM_OPEN:
  58. lpsz = (PSZ) l1;
  59. lpch = "Life";
  60. while ((*lpsz++ = *lpch++) != '\0')
  61. ;
  62. lpsz = (PSZ) l2;
  63. lpch = "Life in Color\n\nby Brad Christian";
  64. while ((*lpsz++ = *lpch++) != '\0')
  65. ;
  66. #ifdef PM
  67. dxScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
  68. dyScreen = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  69. #endif
  70. #ifdef WIN
  71. dxScreen = GetSystemMetrics(SM_CXSCREEN);
  72. dyScreen = GetSystemMetrics(SM_CYSCREEN);
  73. #endif
  74. // FALL THROUGH
  75. case SSM_SECOND:
  76. if (--csecRandomize < 0)
  77. {
  78. Randomize();
  79. csecRandomize = 60 + WRand(120);
  80. }
  81. break;
  82. case SSM_BLANK:
  83. Randomize();
  84. fRedraw = TRUE;
  85. break;
  86. case SSM_ANIMATE:
  87. {
  88. static INT foo;
  89. if (foo++ & 1)
  90. return TRUE;
  91. }
  92. if (GetInputState())
  93. return TRUE;
  94. if (fRedraw)
  95. {
  96. Redraw((CVS) l1);
  97. if (fRedraw)
  98. return TRUE;
  99. }
  100. Animate((CVS) l1);
  101. break;
  102. }
  103. return TRUE;
  104. }
  105. Randomize()
  106. {
  107. INT dxc, dyc;
  108. for (dyc = 0; dyc < dycMax; dyc += 1)
  109. {
  110. for (dxc = 0; dxc < dxcMax; dxc += 1)
  111. {
  112. gridOld[dxc][dyc] = CLR_BACKGROUND << 4;
  113. }
  114. }
  115. for (dyc = 0; dyc < dycMax; dyc += 1)
  116. {
  117. for (dxc = 0; dxc < dxcMax; dxc += 1)
  118. {
  119. if (WRand(10) < 5)
  120. SetCell(NULL, gridOld, dxc, dyc, WRand(16));
  121. }
  122. }
  123. fRedraw = TRUE;
  124. }
  125. VOID Redraw(CVS hps)
  126. {
  127. INT dxc, dyc;
  128. for (dyc = 0; dyc < dycMax; dyc += 1)
  129. {
  130. if (GetInputState())
  131. return;
  132. for (dxc = 0; dxc < dxcMax; dxc += 1)
  133. {
  134. #ifdef PM
  135. RECTL rectl;
  136. LONG clr;
  137. rectl.xLeft = MultDiv(dxc, dxScreen, dxcMax);
  138. rectl.xRight = MultDiv(dxc + 1, dxScreen, dxcMax);
  139. rectl.yBottom = MultDiv(dyc, dyScreen, dycMax);
  140. rectl.yTop = MultDiv(dyc + 1, dyScreen, dycMax);
  141. if ((clr = gridOld[dxc][dyc] >> 4) == CLR_BACKGROUND)
  142. clr = CLR_BLACK;
  143. WinFillRect(hps, &rectl, clr);
  144. #endif
  145. #ifdef WIN
  146. HANDLE hT;
  147. LOGBRUSH lbrush;
  148. INT clr, x, y;
  149. if ((clr = gridOld[dxc][dyc] >> 4) == CLR_BACKGROUND)
  150. clr = CLR_BLACK;
  151. lbrush.lbStyle = BS_SOLID;
  152. lbrush.lbColor = mppenrgb[clr];
  153. lbrush.lbHatch = 0;
  154. hT = SelectObject(hps,
  155. CreateBrushIndirect(&lbrush));
  156. x = MultDiv(dxc, dxScreen, dxcMax);
  157. y = MultDiv(dyc, dyScreen, dycMax);
  158. PatBlt(hps, x, y,
  159. MultDiv(dxc + 1, dxScreen, dxcMax) - x,
  160. MultDiv(dyc + 1, dyScreen, dycMax) - y,
  161. PATCOPY);
  162. DeleteObject(SelectObject(hps, hT));
  163. #endif
  164. }
  165. }
  166. fRedraw = FALSE;
  167. }
  168. Animate(CVS hps)
  169. {
  170. INT dxc, dyc;
  171. INT c;
  172. for (dyc = 0; dyc < dycMax; dyc += 1)
  173. {
  174. for (dxc = 0; dxc < dxcMax; dxc += 1)
  175. {
  176. gridNew[dxc][dyc] = gridOld[dxc][dyc];
  177. }
  178. }
  179. for (dyc = 0; dyc < dycMax; dyc += 1)
  180. {
  181. for (dxc = 0; dxc < dxcMax; dxc += 1)
  182. {
  183. c = gridOld[dxc][dyc] & 0x0f;
  184. if ((gridOld[dxc][dyc] >> 4) != CLR_BACKGROUND)
  185. {
  186. if (c < 2 || c > 3)
  187. {
  188. SetCell(hps, gridNew, dxc, dyc,
  189. CLR_BACKGROUND);
  190. }
  191. }
  192. else
  193. {
  194. if (c == 3)
  195. {
  196. SetCell(hps, gridNew, dxc, dyc,
  197. ClrAverage(gridOld, dxc, dyc));
  198. }
  199. }
  200. }
  201. }
  202. for (dyc = 0; dyc < dycMax; dyc += 1)
  203. {
  204. for (dxc = 0; dxc < dxcMax; dxc += 1)
  205. {
  206. gridOld[dxc][dyc] = gridNew[dxc][dyc];
  207. }
  208. }
  209. }
  210. // Boy, this is ugly! Find the average color around cell [dxc][dyc]...
  211. ClrAverage(GRID grid, INT dxc, INT dyc)
  212. {
  213. INT c, clr, clrT;
  214. c = clr = 0;
  215. if (dxc > 0)
  216. {
  217. if ((clrT = grid[dxc - 1][dyc] >> 4) != 0)
  218. {
  219. clr += clrT;
  220. c += 1;
  221. }
  222. if (dyc > 0)
  223. {
  224. if ((clrT = grid[dxc - 1][dyc - 1] >> 4) != 0)
  225. {
  226. clr += clrT;
  227. c += 1;
  228. }
  229. }
  230. if (dyc < dycMax - 1)
  231. {
  232. if ((clrT = grid[dxc - 1][dyc + 1] >> 4) != 0)
  233. {
  234. clr += clrT;
  235. c += 1;
  236. }
  237. }
  238. }
  239. if (dyc > 0)
  240. {
  241. if ((clrT = grid[dxc][dyc - 1] >> 4) != 0)
  242. {
  243. clr += clrT;
  244. c += 1;
  245. }
  246. }
  247. if (dyc < dycMax - 1)
  248. {
  249. if ((clrT = grid[dxc][dyc + 1] >> 4) != 0)
  250. {
  251. clr += clrT;
  252. c += 1;
  253. }
  254. }
  255. if (dxc < dxcMax - 1)
  256. {
  257. if ((clrT = grid[dxc + 1][dyc] >> 4) != 0)
  258. {
  259. clr += clrT;
  260. c += 1;
  261. }
  262. if (dyc > 0)
  263. {
  264. if ((clrT = grid[dxc + 1][dyc - 1] >> 4) != 0)
  265. {
  266. clr += clrT;
  267. c += 1;
  268. }
  269. }
  270. if (dyc < dycMax - 1)
  271. {
  272. if ((clrT = grid[dxc + 1][dyc + 1] >> 4) != 0)
  273. {
  274. clr += clrT;
  275. c += 1;
  276. }
  277. }
  278. }
  279. return clr / c;
  280. }
  281. VOID SetCell(CVS hps, GRID grid, INT dxc, INT dyc, INT clr)
  282. {
  283. INT d, clrPrev;
  284. clrPrev = grid[dxc][dyc] >> 4;
  285. if (clr == clrPrev)
  286. return;
  287. grid[dxc][dyc] &= 0x0f;
  288. grid[dxc][dyc] |= clr << 4;
  289. if (hps != NULL)
  290. {
  291. #ifdef PM
  292. RECTL rectl;
  293. rectl.xLeft = MultDiv(dxc, dxScreen, dxcMax);
  294. rectl.xRight = MultDiv(dxc + 1, dxScreen, dxcMax);
  295. rectl.yBottom = MultDiv(dyc, dyScreen, dycMax);
  296. rectl.yTop = MultDiv(dyc + 1, dyScreen, dycMax);
  297. WinFillRect(hps, &rectl,
  298. (clr == CLR_BACKGROUND ? CLR_BLACK : (LONG) clr));
  299. #endif
  300. #ifdef WIN
  301. HANDLE hT;
  302. LOGBRUSH lbrush;
  303. INT x, y;
  304. if (clr == CLR_BACKGROUND)
  305. clr = CLR_BLACK;
  306. lbrush.lbStyle = BS_SOLID;
  307. lbrush.lbColor = mppenrgb[clr];
  308. lbrush.lbHatch = 0;
  309. hT = SelectObject(hps,
  310. CreateBrushIndirect(&lbrush));
  311. x = MultDiv(dxc, dxScreen, dxcMax);
  312. y = MultDiv(dyc, dyScreen, dycMax);
  313. PatBlt(hps, x, y,
  314. MultDiv(dxc + 1, dxScreen, dxcMax) - x,
  315. MultDiv(dyc + 1, dyScreen, dycMax) - y,
  316. PATCOPY);
  317. DeleteObject(SelectObject(hps, hT));
  318. #endif
  319. }
  320. if ((clrPrev == CLR_BACKGROUND) == (clr == CLR_BACKGROUND))
  321. return;
  322. d = clr > 0 ? 1 : -1;
  323. if (dxc > 0)
  324. {
  325. grid[dxc - 1][dyc] += (UCHAR)d;
  326. if (dyc > 0)
  327. grid[dxc - 1][dyc - 1] += (UCHAR)d;
  328. if (dyc < dycMax - 1)
  329. grid[dxc - 1][dyc + 1] += (UCHAR)d;
  330. }
  331. if (dyc > 0)
  332. grid[dxc][dyc - 1] += (UCHAR)d;
  333. if (dyc < dycMax - 1)
  334. grid[dxc][dyc + 1] += (UCHAR)d;
  335. if (dxc < dxcMax - 1)
  336. {
  337. grid[dxc + 1][dyc] += (UCHAR)d;
  338. if (dyc > 0)
  339. grid[dxc + 1][dyc - 1] += (UCHAR)d;
  340. if (dyc < dycMax - 1)
  341. grid[dxc + 1][dyc + 1] += (UCHAR)d;
  342. }
  343. }