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.

292 lines
6.3 KiB

  1. // "Shuffle" module for IdleWild.
  2. //
  3. // Blts a pattern over the screen (to "darken" it), then
  4. // divides the screen into blocks and shuffles them around.
  5. //
  6. // By Tony Krueger
  7. #ifdef PM
  8. #define INCL_WIN
  9. #define INCL_GPI
  10. #include <os2.h>
  11. /*int _acrtused = 0;*/
  12. #endif
  13. #ifdef WIN
  14. #include <windows.h>
  15. #include <port1632.h>
  16. #endif
  17. #include "std.h"
  18. #include "scrsave.h"
  19. INT rand();
  20. INT dxScreen, dyScreen;
  21. INT xBlock, yBlock;
  22. INT xBlockMax, yBlockMax;
  23. INT dx, dy, dir, lastOppDirection = 0;
  24. INT xBlockSize, yBlockSize;
  25. #define ROP_PANDD (DWORD)0x00A000C9 /* dest = pattern AND dest */
  26. #define ROP_INVPANDD (DWORD)0x000A0329 /* dest = ~pattern AND dest */
  27. typedef WORD BMP[8]; /* Monochrome brush-sized bitmap is 8 words */
  28. #define stdchance 2 /* One in 2 times only pick from standard bmps */
  29. #define ibmpStdMax 5
  30. #define ibmpMax 17
  31. BMP rgbmp[ibmpMax] =
  32. {
  33. { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 }, /* Dither 1x1 */
  34. { 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xCC }, /* Dither 2x1 */
  35. { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 }, /* Horiz stripe */
  36. { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00 }, /* Vert stripe */
  37. { 0x88, 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44 }, /* Slash */
  38. { 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC }, /* Dither 2x2 */
  39. { 0xFF, 0x0C, 0x0C, 0x0C, 0xFF, 0xC0, 0xC0, 0xC0 }, /* Brick */
  40. { 0x38, 0x7C, 0xEE, 0xC6, 0xEE, 0x7C, 0x38, 0x00 }, /* Small Hollow Circle */
  41. { 0x38, 0x7C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x00 }, /* Small Circle */
  42. { 0xF8, 0xF1, 0xE3, 0xC7, 0x8F, 0x1F, 0x3E, 0x7C }, /* Thick Slash */
  43. { 0xF8, 0xF1, 0xE3, 0xC7, 0x8F, 0xC7, 0xE3, 0xF1 }, /* Thick ZigZag */
  44. { 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x3F, 0x7F }, /* Tile edge */
  45. { 0xF8, 0x74, 0x22, 0x47, 0x8F, 0x17, 0x22, 0x71 }, /* Thatch */
  46. { 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xF0 }, /* Waffle */
  47. { 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00 }, /* Small Solid Box */
  48. { 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00 }, /* Solid Diamond */
  49. { 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0 }, /* Dither 4x1 */
  50. };
  51. /* Pick new direction */
  52. /* Don't move back onto square just vacated */
  53. /* Also don't move off screen */
  54. VOID GetDxDy()
  55. {
  56. INT xNew, yNew, oppDir;
  57. do
  58. {
  59. dir = WRand(4);
  60. switch(dir)
  61. {
  62. case 0: /* Left */
  63. dx = -1;
  64. dy = 0;
  65. oppDir = 1;
  66. break;
  67. case 1: /* Right */
  68. dx = 1;
  69. dy = 0;
  70. oppDir = 0;
  71. break;
  72. case 2: /* Up */
  73. dx = 0;
  74. dy = 1;
  75. oppDir = 3;
  76. break;
  77. case 3: /* Down */
  78. dx = 0;
  79. dy = -1;
  80. oppDir = 2;
  81. break;
  82. }
  83. xNew = xBlock + dx;
  84. yNew = yBlock + dy;
  85. }
  86. while (dir == lastOppDirection || xNew < 0 || xNew >= xBlockMax ||
  87. yNew < 0 || yNew >= yBlockMax);
  88. lastOppDirection = oppDir;
  89. }
  90. BOOL EXPENTRY ScrSaveProc(INT ssm, LPVOID l1, LONG_PTR l2, LONG_PTR l3)
  91. {
  92. static INT csecReblank;
  93. CHAR FAR * lpsz;
  94. CHAR FAR * lpch;
  95. switch (ssm)
  96. {
  97. default:
  98. return fFalse;
  99. case SSM_OPEN:
  100. lpsz = (PSZ) l1;
  101. lpch = "Shuffle";
  102. while ((*lpsz++ = *lpch++) != '\0')
  103. ;
  104. lpsz = (PSZ) l2;
  105. lpch = "Divide and\nShuffle Screen\n\nby Tony Krueger";
  106. while ((*lpsz++ = *lpch++) != '\0')
  107. ;
  108. #ifdef PM
  109. dxScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
  110. dyScreen = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  111. #endif
  112. #ifdef WIN
  113. dxScreen = GetSystemMetrics(SM_CXSCREEN);
  114. dyScreen = GetSystemMetrics(SM_CYSCREEN);
  115. #endif
  116. break;
  117. case SSM_BLANK:
  118. {
  119. CVS cvs;
  120. HBITMAP hbmp;
  121. HBRUSH hbr, hbrOld;
  122. HPEN hpenOld;
  123. INT x, y;
  124. ScrRestoreScreen();
  125. cvs = (CVS) l1;
  126. csecReblank = 60 * 20;
  127. #ifdef DARKEN
  128. /* Darken screen */
  129. hbmp = NULL;
  130. hbr = NULL;
  131. /*hbmp = +++CreateBitmap - Not Recommended(use CreateDIBitmap)+++(8, 8, 1, 1, (LPSTR) &(rgbmp[ */
  132. hbmp = CreateBitmap(8, 8, 1, 1, (LPSTR) &(rgbmp[
  133. WRand(stdchance) ? WRand(ibmpMax) : WRand(ibmpStdMax)]));
  134. if (hbmp == NULL)
  135. goto LFail;
  136. hbr = CreatePatternBrush(hbmp);
  137. if (hbr == NULL)
  138. goto LFail;
  139. hbrOld = SelectObject(cvs, hbr);
  140. PatBlt(cvs, 0, 0, dxScreen, dyScreen,
  141. WRand(2) ? ROP_PANDD : ROP_INVPANDD);
  142. SelectObject(cvs, hbrOld);
  143. LFail:
  144. if (hbmp != NULL)
  145. DeleteObject(hbmp);
  146. if (hbr != NULL)
  147. DeleteObject(hbr);
  148. #endif
  149. /* Select and Blacken random block */
  150. xBlockSize = 24 + 8*WRand(10);
  151. yBlockSize = xBlockSize * GetDeviceCaps(cvs, ASPECTX)
  152. / GetDeviceCaps(cvs, ASPECTY);
  153. yBlockSize = ((yBlockSize + 4) / 8) * 8; /* Round to nearest 8 */
  154. if (yBlockSize == 0) /* Assure a minimum */
  155. yBlockSize = 8;
  156. xBlockMax = dxScreen / xBlockSize;
  157. yBlockMax = dyScreen / yBlockSize;
  158. xBlock = WRand(xBlockMax);
  159. yBlock = WRand(yBlockMax);
  160. PatBlt(cvs, xBlock * xBlockSize, yBlock * yBlockSize,
  161. xBlockSize, yBlockSize, BLACKNESS);
  162. /* Draw Gridlines */
  163. hpenOld = SelectObject(cvs, GetStockObject(BLACK_PEN));
  164. for (x = 0; x < dxScreen; x += xBlockSize)
  165. {
  166. (VOID)MMoveTo(cvs, x, 0);
  167. LineTo(cvs, x, dyScreen);
  168. }
  169. for (y = 0; y < dyScreen; y += yBlockSize)
  170. {
  171. (VOID)MMoveTo(cvs, 0, y);
  172. LineTo(cvs, dxScreen, y);
  173. }
  174. SelectObject(cvs, hpenOld);
  175. }
  176. break;
  177. case SSM_SECOND:
  178. if (csecReblank-- == 0)
  179. ScrChooseRandomServer();
  180. break;
  181. case SSM_ANIMATE:
  182. {
  183. CVS cvs;
  184. INT cd, step;
  185. INT xSrc, ySrc;
  186. INT xDest, yDest;
  187. INT xFill, yFill;
  188. INT dxFill, dyFill;
  189. static INT iSkip = 0;
  190. if (iSkip++ == 1)
  191. {
  192. iSkip = 0;
  193. break;
  194. }
  195. cvs = (CVS) l1;
  196. GetDxDy();
  197. xBlock += dx;
  198. yBlock += dy;
  199. dx *= 4;
  200. step = dx + dy;
  201. if (step < 0)
  202. step = -step;
  203. /* Source */
  204. xSrc = xBlock * xBlockSize;
  205. ySrc = yBlock * yBlockSize;
  206. /* Dest */
  207. xDest = xSrc - dx;
  208. yDest = ySrc - dy;
  209. for (cd = 0; cd < (dx == 0 ? yBlockSize : xBlockSize); cd += step)
  210. {
  211. BitBlt(cvs, xDest, yDest, xBlockSize, yBlockSize,
  212. cvs, xSrc, ySrc, SRCCOPY);
  213. xFill = xSrc;
  214. yFill = ySrc;
  215. dxFill = dx > 0 ? dx : -dx;
  216. dyFill = dy > 0 ? dy : -dy;
  217. switch (dir)
  218. {
  219. case 0: /* Left */
  220. dyFill = yBlockSize;
  221. break;
  222. case 1: /* Right */
  223. xFill = xDest + xBlockSize;
  224. dyFill = yBlockSize;
  225. break;
  226. case 2: /* Up */
  227. yFill = yDest + yBlockSize;
  228. dxFill = xBlockSize;
  229. break;
  230. case 3: /* Down */
  231. dxFill = xBlockSize;
  232. break;
  233. }
  234. PatBlt(cvs, xFill, yFill, dxFill, dyFill, BLACKNESS);
  235. xSrc -= dx;
  236. ySrc -= dy;
  237. xDest -= dx;
  238. yDest -= dy;
  239. }
  240. break;
  241. }
  242. }
  243. return fTrue;
  244. }