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.

454 lines
14 KiB

  1. /*
  2. STARS.C
  3. Starfield simulator screensaver.
  4. History:
  5. 6/17/91 stevecat ported to NT Windows
  6. 2/10/92 stevecat snapped to latest ported to NT Windows
  7. */
  8. #include <windows.h>
  9. #include <scrnsave.h>
  10. #include <commctrl.h>
  11. #include "stars.dlg"
  12. #include "strings.h"
  13. #include "uniconv.h"
  14. #define SCOPE 256
  15. #define MAXWARP 10 // Maximum warp speed
  16. #define MINWARP 0 // Minimum warp speed
  17. #define CLICKRANGE (MAXWARP-MINWARP)// Range for WarpSpeed scroll bar
  18. #define MINSTARS 10 // Minimum number of stars in field
  19. #define MAXSTARS 200 // Maximum number of stars in field
  20. #define WARPFACTOR 10 // Warp Factor 10 Mr. Sulu!
  21. #define SIZE 64
  22. #define DEF_DENSITY 25 // Default number of stars in field
  23. #define RAND(x) ((rand() % (x))+1)
  24. #define ZRAND(x) (rand() % (x))
  25. #define MINTIMERSPEED 50
  26. VOID CreateStar (WORD wIndex);
  27. LONG GetDlgItemLong (HWND hDlg, WORD wID, BOOL *pfTranslated, BOOL fSigned);
  28. VOID GetIniEntries (VOID);
  29. LONG GetPrivateProfileLong (LPTSTR pszApp, LPTSTR pszKey, LONG lDefault);
  30. WORD rand (VOID);
  31. VOID srand (DWORD dwSeed);
  32. DWORD dwRand; // Current random seed
  33. TCHAR szWarpSpeed [] = TEXT("WarpSpeed"); // .INI WarpSpeed key
  34. TCHAR szDensity [] = TEXT("Density"); // .INI Density key
  35. LONG nX[MAXSTARS],
  36. nY[MAXSTARS],
  37. nZ[MAXSTARS];
  38. WORD wXScreen,
  39. wYScreen,
  40. wX2Screen,
  41. wY2Screen;
  42. WORD wWarpSpeed, // Global WarpSpeed value
  43. wDensity; // Global starfield density value
  44. //
  45. // Help IDs
  46. //
  47. DWORD aStarsDlgHelpIds[] = {
  48. ((DWORD) -1), ((DWORD) -1),
  49. ID_SPEED_SLOW, IDH_DISPLAY_SCREENSAVER_STARFIELD_WARP,
  50. ID_SPEED_FAST, IDH_DISPLAY_SCREENSAVER_STARFIELD_WARP,
  51. ID_SPEED, IDH_DISPLAY_SCREENSAVER_STARFIELD_WARP,
  52. ID_DENSITY_LABEL, IDH_DISPLAY_SCREENSAVER_STARFIELD_DENSITY,
  53. ID_DENSITY, IDH_DISPLAY_SCREENSAVER_STARFIELD_DENSITY,
  54. ID_DENSITYARROW, IDH_DISPLAY_SCREENSAVER_STARFIELD_DENSITY,
  55. 0,0
  56. };
  57. #define DIVIDE_SAFE(nNumber) ((0 == (nNumber)) ? 1 : (nNumber))
  58. /* This is the main window procedure to be used when the screen saver is
  59. activated in a screen saver mode ( as opposed to configure mode ). This
  60. function must be declared as an EXPORT in the EXPORTS section of the
  61. DEFinition file... */
  62. LRESULT ScreenSaverProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  63. {
  64. RECT rRect;
  65. WORD wLoop;
  66. static UINT_PTR wTimer;
  67. static WORD wWarp;
  68. static WORD wTimerSet=MINTIMERSPEED;
  69. static WORD wCurrentWarp;
  70. static int nPassCount=0;
  71. int nXTemp, nYTemp, nTemp;
  72. BOOL fHyperSpace = TRUE;
  73. HDC hDC;
  74. switch (message)
  75. {
  76. case WM_CREATE:
  77. /* Do anything that you need to do when you initialize the window
  78. here... */
  79. GetIniEntries ();
  80. srand (GetCurrentTime ());
  81. /* Make sure we use the entire virtual desktop size for multiple
  82. displays... */
  83. wXScreen = (WORD) ((LPCREATESTRUCT)lParam)->cx;
  84. wYScreen = (WORD) ((LPCREATESTRUCT)lParam)->cy;
  85. wX2Screen = wXScreen / 2;
  86. wY2Screen = wYScreen / 2;
  87. for (wLoop = 0; wLoop < wDensity; wLoop++)
  88. CreateStar (wLoop);
  89. wWarp = wWarpSpeed * WARPFACTOR + WARPFACTOR; // ZRAND (((wWarpSpeed)*WARPFACTOR)+1)+1;
  90. wTimer = SetTimer (hWnd, 1, wTimerSet, NULL);
  91. break;
  92. case WM_SIZE:
  93. wXScreen = LOWORD(lParam);
  94. wYScreen = HIWORD(lParam);
  95. break;
  96. case WM_TIMER:
  97. {
  98. MSG msg;
  99. hDC = GetDC (hWnd);
  100. /* Begin to loop through each star, accelerating so it seems that
  101. we are traversing the starfield... */
  102. for (wLoop = 0; wLoop < wDensity; wLoop++)
  103. {
  104. nXTemp = (int)((nX[wLoop] * (LONG)(SCOPE * WARPFACTOR))
  105. / DIVIDE_SAFE(nZ[wLoop])) + wX2Screen;
  106. nYTemp = (int)((nY[wLoop] * SCOPE * WARPFACTOR) / DIVIDE_SAFE(nZ[wLoop]))
  107. + wY2Screen;
  108. nTemp = (int)((SCOPE * WARPFACTOR - nZ[wLoop]) /
  109. (SIZE * WARPFACTOR)) + 1;
  110. PatBlt (hDC, nXTemp, nYTemp, nTemp, nTemp, BLACKNESS);
  111. if (wCurrentWarp < wWarp)
  112. wCurrentWarp++;
  113. else if (wCurrentWarp > wWarp)
  114. wCurrentWarp--;
  115. nZ[wLoop] = max (0, (int)(nZ[wLoop] - wCurrentWarp));
  116. if (!nZ[wLoop])
  117. CreateStar (wLoop);
  118. nXTemp = (int)((nX[wLoop] * (LONG)(SCOPE * WARPFACTOR))
  119. / DIVIDE_SAFE(nZ[wLoop])) + wX2Screen;
  120. nYTemp = (int)((nY[wLoop] * SCOPE * WARPFACTOR)
  121. / DIVIDE_SAFE(nZ[wLoop])) + wY2Screen;
  122. if ((nXTemp < 0 || nYTemp < 0) ||
  123. (nXTemp > (int) wXScreen || nYTemp > (int) wYScreen))
  124. {
  125. CreateStar (wLoop);
  126. nXTemp = (int)((nX[wLoop] * (LONG)(SCOPE * WARPFACTOR))
  127. / DIVIDE_SAFE(nZ[wLoop])) + wX2Screen;
  128. nYTemp = (int)((nY[wLoop] * SCOPE * WARPFACTOR)
  129. / DIVIDE_SAFE(nZ[wLoop])) + wY2Screen;
  130. }
  131. nTemp = (int)((SCOPE * WARPFACTOR - nZ[wLoop]) /
  132. (SIZE * WARPFACTOR)) + 1;
  133. PatBlt (hDC, nXTemp, nYTemp, nTemp, nTemp, WHITENESS);
  134. }
  135. ReleaseDC (hWnd, hDC);
  136. if (PeekMessage(&msg, hWnd, WM_TIMER, WM_TIMER, PM_REMOVE))
  137. {
  138. // There is another WM_TIMER message in the queue. We have
  139. // removed it, but now we want to adjust the timer a bit so
  140. // hopefully we won't get another WM_TIMER message before we
  141. // finish the screen update. (bug #8423) TG:11/25/91
  142. wTimerSet += 10;
  143. SetTimer(hWnd, 1, wTimerSet, NULL);
  144. nPassCount = 0;
  145. }
  146. else
  147. ++nPassCount;
  148. if (nPassCount >= 100)
  149. {
  150. nPassCount = 0;
  151. wTimerSet -= 100;
  152. if ((short)wTimerSet < MINTIMERSPEED)
  153. wTimerSet = MINTIMERSPEED;
  154. SetTimer(hWnd, 1, wTimerSet, NULL);
  155. }
  156. break;
  157. }
  158. case WM_ERASEBKGND:
  159. /* If you want something put on the background, do it right here
  160. using wParam as a handle to a device context. Remember to
  161. unrealize a brush if it is not a solid color. If you do
  162. something here, you want to use the line:
  163. return 0l;
  164. So the program knows not to take the default action. Otherwise
  165. just use:
  166. break;
  167. */
  168. break;
  169. GetClientRect (hWnd, &rRect);
  170. FillRect ((HDC) wParam, &rRect, GetStockObject (GRAY_BRUSH));
  171. return 0l;
  172. case WM_DESTROY:
  173. /* Anything that needs to be deleted when the window is closed
  174. goes here... */
  175. if (wTimer)
  176. KillTimer (hWnd, wTimer);
  177. break;
  178. }
  179. /* Unless it is told otherwise, the program will take default actions... */
  180. return (DefScreenSaverProc (hWnd, message, wParam, lParam));
  181. }
  182. //***************************************************************************
  183. BOOL ScreenSaverConfigureDialog (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  184. {
  185. BOOL fError; // Error flag
  186. UINT wTemp;
  187. TCHAR szTemp[20]; // Temporary string buffer
  188. static WORD wPause, wScroll;
  189. static HWND hWarpSpeed, // window handle of Speed scrollbar
  190. hIDOK, // window handle of OK button
  191. hSetPassword, // window handle of SetPassword button
  192. hDensity; // window handle of Density EditControl
  193. static WORD wIncScroll = 1; // density spin button parameters
  194. static WORD wStartScroll = 1;
  195. static WORD wStartPause = 1;
  196. static WORD wMaxScroll = 10;
  197. static WORD wPauseScroll = 20;
  198. static LONG lMinScroll = MINSTARS;
  199. static LONG lMaxScroll = MAXSTARS;
  200. switch (message)
  201. {
  202. case WM_INITDIALOG:
  203. GetIniEntries ();
  204. hWarpSpeed = GetDlgItem (hDlg, ID_SPEED);
  205. hIDOK = GetDlgItem (hDlg, IDOK);
  206. hDensity = GetDlgItem (hDlg, ID_DENSITY);
  207. SendMessage (hDensity, EM_LIMITTEXT, 3, 0);
  208. SendDlgItemMessage( hDlg, ID_DENSITYARROW, UDM_SETBUDDY, (WPARAM)hDensity, 0);
  209. SendDlgItemMessage( hDlg, ID_DENSITYARROW, UDM_SETRANGE, 0, MAKELONG(lMaxScroll, lMinScroll));
  210. SetScrollRange (hWarpSpeed, SB_CTL, MINWARP, MAXWARP, FALSE);
  211. SetScrollPos (hWarpSpeed, SB_CTL, wWarpSpeed, TRUE);
  212. SetDlgItemInt (hDlg, ID_DENSITY, wDensity, FALSE);
  213. return TRUE;
  214. case WM_HSCROLL:
  215. switch (LOWORD(wParam))
  216. {
  217. case SB_LINEUP:
  218. case SB_PAGEUP:
  219. --wWarpSpeed;
  220. break;
  221. case SB_LINEDOWN:
  222. case SB_PAGEDOWN:
  223. ++wWarpSpeed;
  224. break;
  225. case SB_THUMBPOSITION:
  226. wWarpSpeed = HIWORD (wParam);
  227. break;
  228. case SB_TOP:
  229. wWarpSpeed = MINWARP;
  230. break;
  231. case SB_BOTTOM:
  232. wWarpSpeed = MAXWARP;
  233. break;
  234. case SB_THUMBTRACK:
  235. case SB_ENDSCROLL:
  236. return TRUE;
  237. break;
  238. }
  239. if ((int)((short)wWarpSpeed) <= MINWARP)
  240. wWarpSpeed = MINWARP;
  241. if ((int)wWarpSpeed >= MAXWARP)
  242. wWarpSpeed = MAXWARP;
  243. SetScrollPos ((HWND) lParam, SB_CTL, wWarpSpeed, TRUE);
  244. break;
  245. case WM_COMMAND:
  246. switch (LOWORD(wParam))
  247. {
  248. case ID_DENSITY:
  249. if (HIWORD(wParam) == EN_UPDATE)
  250. {
  251. wTemp = GetDlgItemInt (hDlg, ID_DENSITY, &fError, FALSE);
  252. fError = ((wTemp <= MAXSTARS) && (wTemp >= MINSTARS));
  253. EnableWindow (GetDlgItem (hDlg, ID_DENSITYARROW), fError);
  254. EnableWindow (GetDlgItem (hDlg, IDOK), fError);
  255. }
  256. break;
  257. case IDOK:
  258. wTemp = GetDlgItemInt (hDlg, ID_DENSITY, &fError, FALSE);
  259. wsprintf (szTemp, TEXT("%d"), wTemp);
  260. WritePrivateProfileString (szAppName, szDensity, szTemp, szIniFile);
  261. wsprintf (szTemp, TEXT("%d"), wWarpSpeed);
  262. WritePrivateProfileString (szAppName, szWarpSpeed, szTemp, szIniFile);
  263. case IDCANCEL:
  264. EndDialog (hDlg, LOWORD(wParam) == IDOK);
  265. return TRUE;
  266. }
  267. break;
  268. case WM_HELP: // F1
  269. WinHelp(
  270. (HWND) ((LPHELPINFO) lParam)->hItemHandle,
  271. szHelpFile,
  272. HELP_WM_HELP,
  273. (ULONG_PTR) (LPSTR) aStarsDlgHelpIds
  274. );
  275. break;
  276. case WM_CONTEXTMENU: // right mouse click
  277. WinHelp(
  278. (HWND) wParam,
  279. szHelpFile,
  280. HELP_CONTEXTMENU,
  281. (ULONG_PTR) (LPSTR) aStarsDlgHelpIds
  282. );
  283. break;
  284. default:
  285. break;
  286. }
  287. return FALSE;
  288. }
  289. /* This procedure is called right before the dialog box above is created in
  290. order to register any child windows that are custom controls. If no
  291. custom controls need to be registered, then simply return TRUE.
  292. Otherwise, register the child controls however is convenient... */
  293. BOOL RegisterDialogClasses (HANDLE hInst)
  294. {
  295. InitCommonControls();
  296. return TRUE;
  297. }
  298. VOID srand (DWORD dwSeed)
  299. {
  300. dwRand = dwSeed;
  301. }
  302. WORD rand (VOID)
  303. {
  304. dwRand = dwRand * 214013L + 2531011L;
  305. return (WORD)((dwRand >> 16) & 0xffff);
  306. }
  307. VOID CreateStar (WORD wIndex)
  308. {
  309. nX[wIndex] = wXScreen ? (LONG)((int)(ZRAND (wXScreen)) - (int)wX2Screen) : 0;
  310. nY[wIndex] = wXScreen ? (LONG)((int)(ZRAND (wYScreen)) - (int)wY2Screen) : 0;
  311. nZ[wIndex] = SCOPE * WARPFACTOR;
  312. }
  313. LONG GetDlgItemLong (HWND hDlg, WORD wID, BOOL *pfTranslated, BOOL fSigned)
  314. {
  315. TCHAR szTemp[20];
  316. LPTSTR pszTemp;
  317. LONG lTemp = 0l;
  318. BOOL fNegative;
  319. if (!GetDlgItemText (hDlg, wID, szTemp, CharSizeOf(szTemp)))
  320. goto GetDlgItemLongError;
  321. szTemp[19] = TEXT('\0');
  322. pszTemp = szTemp;
  323. while (*pszTemp == TEXT(' ') || *pszTemp == TEXT('\t'))
  324. pszTemp++;
  325. if ((!fSigned && *pszTemp == TEXT('-')) || !*pszTemp)
  326. goto GetDlgItemLongError;
  327. fNegative = (*pszTemp == TEXT('-')) ? TRUE : FALSE;
  328. while (*pszTemp >= TEXT('0') && *pszTemp <= TEXT('9'))
  329. lTemp = lTemp * 10l + (LONG)(*(pszTemp++) - TEXT('0'));
  330. if (*pszTemp)
  331. goto GetDlgItemLongError;
  332. if (fNegative)
  333. lTemp *= -1;
  334. *pfTranslated = TRUE;
  335. return lTemp;
  336. GetDlgItemLongError:
  337. *pfTranslated = FALSE;
  338. return 0l;
  339. }
  340. LONG GetPrivateProfileLong (LPTSTR pszApp, LPTSTR pszKey, LONG lDefault)
  341. {
  342. LONG lTemp = 0l;
  343. TCHAR szTemp[20];
  344. LPTSTR pszTemp;
  345. if (!GetPrivateProfileString (pszApp, pszKey, TEXT(""), szTemp, CharSizeOf(szTemp), szIniFile))
  346. goto GetProfileLongError;
  347. szTemp[19] = TEXT('\0');
  348. pszTemp = szTemp;
  349. while (*pszTemp >= TEXT('0') && *pszTemp <= TEXT('9'))
  350. lTemp = lTemp * 10l + (LONG)(*(pszTemp++) - TEXT('0'));
  351. if (*pszTemp)
  352. goto GetProfileLongError;
  353. return lTemp;
  354. GetProfileLongError:
  355. return lDefault;
  356. }
  357. VOID GetIniEntries (VOID)
  358. {
  359. LoadString (hMainInstance, idsName, szName, CharSizeOf(szName));
  360. LoadString (hMainInstance, idsAppName, szAppName, CharSizeOf(szAppName));
  361. //Load Common Strings from stringtable...
  362. LoadString (hMainInstance, idsIniFile, szIniFile, CharSizeOf(szIniFile));
  363. LoadString (hMainInstance, idsScreenSaver, szScreenSaver, CharSizeOf(szScreenSaver));
  364. LoadString (hMainInstance, idsHelpFile, szHelpFile, CharSizeOf(szHelpFile));
  365. LoadString (hMainInstance, idsNoHelpMemory, szNoHelpMemory, CharSizeOf(szNoHelpMemory));
  366. wWarpSpeed = (WORD) GetPrivateProfileInt (szAppName, szWarpSpeed, MINWARP + ((MAXWARP - MINWARP) / 2), szIniFile);
  367. if (wWarpSpeed > MAXWARP)
  368. wWarpSpeed = MINWARP + ((MAXWARP - MINWARP) / 2);
  369. wDensity = (WORD) GetPrivateProfileInt (szAppName, szDensity, DEF_DENSITY, szIniFile);
  370. if (wDensity > MAXSTARS)
  371. wDensity = MAXSTARS;
  372. if (wDensity < MINSTARS)
  373. wDensity = MINSTARS;
  374. }