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.

231 lines
4.8 KiB

  1. // "Dropout" module for IdleWild.
  2. //
  3. // By Tony Krueger
  4. #ifdef PM
  5. #define INCL_WIN
  6. #define INCL_GPI
  7. #include <os2.h>
  8. /*int _acrtused = 0;*/
  9. #endif
  10. #ifdef WIN
  11. #include <windows.h>
  12. #include <port1632.h>
  13. #endif
  14. #include "std.h"
  15. #include "scrsave.h"
  16. #define cMovesMax 20 /* Max number of moves in one ANIMATE call */
  17. #define cxBlockMax 32 /* Enough for 8514 */
  18. #define cyBlockMax 24
  19. #define FUsedXY(x, y) rgf[x + y * cxBlock]
  20. // Globals
  21. INT dxScreen, dyScreen;
  22. HDC hMemoryDC = NULL;
  23. HBITMAP hbmpScreen = NULL;
  24. HBITMAP hbmpBlock = NULL;
  25. HBITMAP hbmpOld = NULL;
  26. INT fBlock;
  27. INT x, y, dx, dy, dyVel;
  28. INT dxBlock, dyBlock;
  29. INT cxBlock, cyBlock;
  30. INT fAbove;
  31. INT cBlockRemain;
  32. UCHAR rgf[cxBlockMax * cyBlockMax];
  33. INT rand();
  34. BOOL EXPENTRY ScrSaveProc(INT ssm, LPVOID l1, LONG_PTR l2, LONG_PTR l3)
  35. {
  36. CHAR FAR * lpsz;
  37. CHAR FAR * lpch;
  38. switch (ssm)
  39. {
  40. default:
  41. return fFalse;
  42. case SSM_OPEN:
  43. lpsz = (PSZ) l1;
  44. lpch = "Dropout";
  45. while ((*lpsz++ = *lpch++) != '\0')
  46. ;
  47. lpsz = (PSZ) l2;
  48. lpch = "Screen Blocks\nDrop Out\n\nby Tony Krueger";
  49. while ((*lpsz++ = *lpch++) != '\0')
  50. ;
  51. #ifdef PM
  52. dxScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
  53. dyScreen = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  54. #endif
  55. #ifdef WIN
  56. dxScreen = GetSystemMetrics(SM_CXSCREEN);
  57. dyScreen = GetSystemMetrics(SM_CYSCREEN);
  58. #endif
  59. break;
  60. case SSM_BLANK:
  61. {
  62. CVS cvs;
  63. ScrRestoreScreen();
  64. cvs = (CVS) l1;
  65. dxBlock = 32;
  66. dyBlock = dxBlock * GetDeviceCaps(cvs, ASPECTX)
  67. / GetDeviceCaps(cvs, ASPECTY);
  68. if (dyBlock <= 0) // Assure at least one
  69. dyBlock = 1;
  70. cxBlock = (dxScreen + dxBlock - 1) / dxBlock;
  71. cyBlock = (dyScreen + dyBlock - 1) / dyBlock;
  72. // Assure number of blocks small enough
  73. while (cxBlock * cyBlock > cxBlockMax * cyBlockMax)
  74. {
  75. dxBlock *= 2;
  76. dyBlock *= 2;
  77. cxBlock = (dxScreen + dxBlock - 1) / dxBlock;
  78. cyBlock = (dyScreen + dyBlock - 1) / dyBlock;
  79. }
  80. cBlockRemain = cxBlock * cyBlock;
  81. for (x = 0; x < cxBlock; x++)
  82. for (y = 0; y < cyBlock; y++)
  83. FUsedXY(x, y) = fFalse;
  84. hMemoryDC = CreateCompatibleDC(cvs);
  85. hbmpScreen = CreateCompatibleBitmap(cvs, dxScreen, dyScreen);
  86. hbmpBlock = CreateCompatibleBitmap(cvs, dxBlock, dyBlock);
  87. if (hMemoryDC == NULL || hbmpScreen == NULL || hbmpBlock == NULL)
  88. {
  89. if (hMemoryDC != NULL)
  90. DeleteDC(hMemoryDC);
  91. hMemoryDC = NULL;
  92. if (hbmpScreen != NULL)
  93. DeleteObject(hbmpScreen);
  94. hbmpScreen = NULL;
  95. if (hbmpBlock != NULL)
  96. DeleteObject(hbmpBlock);
  97. hbmpBlock = NULL;
  98. ScrChooseRandomServer();
  99. }
  100. else
  101. {
  102. hbmpOld = SelectObject(hMemoryDC, hbmpScreen);
  103. BitBlt(hMemoryDC, 0, 0, dxScreen, dyScreen, cvs, 0, 0, SRCCOPY);
  104. }
  105. fBlock = fFalse;
  106. }
  107. break;
  108. case SSM_UNBLANK:
  109. if (hMemoryDC != NULL)
  110. {
  111. SelectObject(hMemoryDC, hbmpOld);
  112. DeleteDC(hMemoryDC);
  113. }
  114. if (hbmpScreen != NULL)
  115. DeleteObject(hbmpScreen);
  116. if (hbmpBlock != NULL)
  117. DeleteObject(hbmpBlock);
  118. break;
  119. case SSM_ANIMATE:
  120. {
  121. CVS cvs;
  122. cvs = (CVS) l1;
  123. if (fBlock)
  124. {
  125. INT cMoves = 0;
  126. while (cMoves < cMovesMax && x <= dxScreen && x >= -dxBlock)
  127. {
  128. SelectObject(hMemoryDC, hbmpBlock);
  129. BitBlt(cvs, x, y, dxBlock, dyBlock, hMemoryDC, 0, 0, SRCCOPY);
  130. SelectObject(hMemoryDC, hbmpScreen);
  131. dyVel += 1;
  132. dy = dyVel / 16;
  133. if (dy > 0)
  134. BitBlt(cvs, x, y, dxBlock, dy, hMemoryDC, x, y, SRCCOPY);
  135. else if (dy < 0)
  136. BitBlt(cvs, x, y + dyBlock + dy, dxBlock, -dy, hMemoryDC, x, y + dyBlock + dy, SRCCOPY);
  137. if (dx > 0)
  138. BitBlt(cvs, x, y, dx, dyBlock, hMemoryDC, x, y, SRCCOPY);
  139. else if (dx < 0)
  140. BitBlt(cvs, x + dxBlock + dx, y, -dx, dyBlock, hMemoryDC, x + dxBlock + dx, y, SRCCOPY);
  141. y += dy;
  142. x += dx;
  143. if (y >= dyScreen - dyBlock && fAbove)
  144. {
  145. dyVel = -dyVel * 3 / 4 ;
  146. fAbove = fFalse;
  147. }
  148. else
  149. fAbove = fTrue;
  150. cMoves++;
  151. }
  152. fBlock = (x <= dxScreen && x >= -dxBlock);
  153. }
  154. else
  155. {
  156. INT cMoves = 0;
  157. do
  158. {
  159. // Choose random block
  160. x = WRand(cxBlock);
  161. y = WRand(cyBlock);
  162. }
  163. while (cMoves++ < cMovesMax && FUsedXY(x, y) == fTrue);
  164. if (cBlockRemain <= 0 || hMemoryDC == NULL)
  165. {
  166. ScrChooseRandomServer();
  167. }
  168. else if (cMoves < cMovesMax)
  169. {
  170. FUsedXY(x, y) = fTrue;
  171. cBlockRemain--;
  172. x *= dxBlock;
  173. y *= dyBlock;
  174. // Copy original block into block bitmap
  175. SelectObject(hMemoryDC, hbmpBlock);
  176. BitBlt(hMemoryDC, 0, 0, dxBlock, dyBlock, cvs, x, y, SRCCOPY);
  177. // Black out block on screen
  178. PatBlt(cvs, x, y, dxBlock, dyBlock, BLACKNESS);
  179. // And on screen bitmap
  180. SelectObject(hMemoryDC, hbmpScreen);
  181. PatBlt(hMemoryDC, x, y, dxBlock, dyBlock, BLACKNESS);
  182. do
  183. {
  184. dx = WRand(5) - 2;
  185. dyVel = -(WRand(5) * 16);
  186. }
  187. while (dx == 0);
  188. fAbove = fTrue;
  189. fBlock = fTrue;
  190. }
  191. }
  192. }
  193. break;
  194. }
  195. return fTrue;
  196. }