/* STARS.C Starfield simulator screensaver. History: 6/17/91 stevecat ported to NT Windows 2/10/92 stevecat snapped to latest ported to NT Windows */ #include #include #include #include "stars.dlg" #include "strings.h" #include "uniconv.h" #define SCOPE 256 #define MAXWARP 10 // Maximum warp speed #define MINWARP 0 // Minimum warp speed #define CLICKRANGE (MAXWARP-MINWARP)// Range for WarpSpeed scroll bar #define MINSTARS 10 // Minimum number of stars in field #define MAXSTARS 200 // Maximum number of stars in field #define WARPFACTOR 10 // Warp Factor 10 Mr. Sulu! #define SIZE 64 #define DEF_DENSITY 25 // Default number of stars in field #define RAND(x) ((rand() % (x))+1) #define ZRAND(x) (rand() % (x)) #define MINTIMERSPEED 50 VOID CreateStar (WORD wIndex); LONG GetDlgItemLong (HWND hDlg, WORD wID, BOOL *pfTranslated, BOOL fSigned); VOID GetIniEntries (VOID); LONG GetPrivateProfileLong (LPTSTR pszApp, LPTSTR pszKey, LONG lDefault); WORD rand (VOID); VOID srand (DWORD dwSeed); DWORD dwRand; // Current random seed TCHAR szWarpSpeed [] = TEXT("WarpSpeed"); // .INI WarpSpeed key TCHAR szDensity [] = TEXT("Density"); // .INI Density key LONG nX[MAXSTARS], nY[MAXSTARS], nZ[MAXSTARS]; WORD wXScreen, wYScreen, wX2Screen, wY2Screen; WORD wWarpSpeed, // Global WarpSpeed value wDensity; // Global starfield density value // // Help IDs // DWORD aStarsDlgHelpIds[] = { ((DWORD) -1), ((DWORD) -1), ID_SPEED_SLOW, IDH_DISPLAY_SCREENSAVER_STARFIELD_WARP, ID_SPEED_FAST, IDH_DISPLAY_SCREENSAVER_STARFIELD_WARP, ID_SPEED, IDH_DISPLAY_SCREENSAVER_STARFIELD_WARP, ID_DENSITY_LABEL, IDH_DISPLAY_SCREENSAVER_STARFIELD_DENSITY, ID_DENSITY, IDH_DISPLAY_SCREENSAVER_STARFIELD_DENSITY, ID_DENSITYARROW, IDH_DISPLAY_SCREENSAVER_STARFIELD_DENSITY, 0,0 }; #define DIVIDE_SAFE(nNumber) ((0 == (nNumber)) ? 1 : (nNumber)) /* This is the main window procedure to be used when the screen saver is activated in a screen saver mode ( as opposed to configure mode ). This function must be declared as an EXPORT in the EXPORTS section of the DEFinition file... */ LRESULT ScreenSaverProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { RECT rRect; WORD wLoop; static UINT_PTR wTimer; static WORD wWarp; static WORD wTimerSet=MINTIMERSPEED; static WORD wCurrentWarp; static int nPassCount=0; int nXTemp, nYTemp, nTemp; BOOL fHyperSpace = TRUE; HDC hDC; switch (message) { case WM_CREATE: /* Do anything that you need to do when you initialize the window here... */ GetIniEntries (); srand (GetCurrentTime ()); /* Make sure we use the entire virtual desktop size for multiple displays... */ wXScreen = (WORD) ((LPCREATESTRUCT)lParam)->cx; wYScreen = (WORD) ((LPCREATESTRUCT)lParam)->cy; wX2Screen = wXScreen / 2; wY2Screen = wYScreen / 2; for (wLoop = 0; wLoop < wDensity; wLoop++) CreateStar (wLoop); wWarp = wWarpSpeed * WARPFACTOR + WARPFACTOR; // ZRAND (((wWarpSpeed)*WARPFACTOR)+1)+1; wTimer = SetTimer (hWnd, 1, wTimerSet, NULL); break; case WM_SIZE: wXScreen = LOWORD(lParam); wYScreen = HIWORD(lParam); break; case WM_TIMER: { MSG msg; hDC = GetDC (hWnd); /* Begin to loop through each star, accelerating so it seems that we are traversing the starfield... */ for (wLoop = 0; wLoop < wDensity; wLoop++) { nXTemp = (int)((nX[wLoop] * (LONG)(SCOPE * WARPFACTOR)) / DIVIDE_SAFE(nZ[wLoop])) + wX2Screen; nYTemp = (int)((nY[wLoop] * SCOPE * WARPFACTOR) / DIVIDE_SAFE(nZ[wLoop])) + wY2Screen; nTemp = (int)((SCOPE * WARPFACTOR - nZ[wLoop]) / (SIZE * WARPFACTOR)) + 1; PatBlt (hDC, nXTemp, nYTemp, nTemp, nTemp, BLACKNESS); if (wCurrentWarp < wWarp) wCurrentWarp++; else if (wCurrentWarp > wWarp) wCurrentWarp--; nZ[wLoop] = max (0, (int)(nZ[wLoop] - wCurrentWarp)); if (!nZ[wLoop]) CreateStar (wLoop); nXTemp = (int)((nX[wLoop] * (LONG)(SCOPE * WARPFACTOR)) / DIVIDE_SAFE(nZ[wLoop])) + wX2Screen; nYTemp = (int)((nY[wLoop] * SCOPE * WARPFACTOR) / DIVIDE_SAFE(nZ[wLoop])) + wY2Screen; if ((nXTemp < 0 || nYTemp < 0) || (nXTemp > (int) wXScreen || nYTemp > (int) wYScreen)) { CreateStar (wLoop); nXTemp = (int)((nX[wLoop] * (LONG)(SCOPE * WARPFACTOR)) / DIVIDE_SAFE(nZ[wLoop])) + wX2Screen; nYTemp = (int)((nY[wLoop] * SCOPE * WARPFACTOR) / DIVIDE_SAFE(nZ[wLoop])) + wY2Screen; } nTemp = (int)((SCOPE * WARPFACTOR - nZ[wLoop]) / (SIZE * WARPFACTOR)) + 1; PatBlt (hDC, nXTemp, nYTemp, nTemp, nTemp, WHITENESS); } ReleaseDC (hWnd, hDC); if (PeekMessage(&msg, hWnd, WM_TIMER, WM_TIMER, PM_REMOVE)) { // There is another WM_TIMER message in the queue. We have // removed it, but now we want to adjust the timer a bit so // hopefully we won't get another WM_TIMER message before we // finish the screen update. (bug #8423) TG:11/25/91 wTimerSet += 10; SetTimer(hWnd, 1, wTimerSet, NULL); nPassCount = 0; } else ++nPassCount; if (nPassCount >= 100) { nPassCount = 0; wTimerSet -= 100; if ((short)wTimerSet < MINTIMERSPEED) wTimerSet = MINTIMERSPEED; SetTimer(hWnd, 1, wTimerSet, NULL); } break; } case WM_ERASEBKGND: /* If you want something put on the background, do it right here using wParam as a handle to a device context. Remember to unrealize a brush if it is not a solid color. If you do something here, you want to use the line: return 0l; So the program knows not to take the default action. Otherwise just use: break; */ break; GetClientRect (hWnd, &rRect); FillRect ((HDC) wParam, &rRect, GetStockObject (GRAY_BRUSH)); return 0l; case WM_DESTROY: /* Anything that needs to be deleted when the window is closed goes here... */ if (wTimer) KillTimer (hWnd, wTimer); break; } /* Unless it is told otherwise, the program will take default actions... */ return (DefScreenSaverProc (hWnd, message, wParam, lParam)); } //*************************************************************************** BOOL ScreenSaverConfigureDialog (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { BOOL fError; // Error flag UINT wTemp; TCHAR szTemp[20]; // Temporary string buffer static WORD wPause, wScroll; static HWND hWarpSpeed, // window handle of Speed scrollbar hIDOK, // window handle of OK button hSetPassword, // window handle of SetPassword button hDensity; // window handle of Density EditControl static WORD wIncScroll = 1; // density spin button parameters static WORD wStartScroll = 1; static WORD wStartPause = 1; static WORD wMaxScroll = 10; static WORD wPauseScroll = 20; static LONG lMinScroll = MINSTARS; static LONG lMaxScroll = MAXSTARS; switch (message) { case WM_INITDIALOG: GetIniEntries (); hWarpSpeed = GetDlgItem (hDlg, ID_SPEED); hIDOK = GetDlgItem (hDlg, IDOK); hDensity = GetDlgItem (hDlg, ID_DENSITY); SendMessage (hDensity, EM_LIMITTEXT, 3, 0); SendDlgItemMessage( hDlg, ID_DENSITYARROW, UDM_SETBUDDY, (WPARAM)hDensity, 0); SendDlgItemMessage( hDlg, ID_DENSITYARROW, UDM_SETRANGE, 0, MAKELONG(lMaxScroll, lMinScroll)); SetScrollRange (hWarpSpeed, SB_CTL, MINWARP, MAXWARP, FALSE); SetScrollPos (hWarpSpeed, SB_CTL, wWarpSpeed, TRUE); SetDlgItemInt (hDlg, ID_DENSITY, wDensity, FALSE); return TRUE; case WM_HSCROLL: switch (LOWORD(wParam)) { case SB_LINEUP: case SB_PAGEUP: --wWarpSpeed; break; case SB_LINEDOWN: case SB_PAGEDOWN: ++wWarpSpeed; break; case SB_THUMBPOSITION: wWarpSpeed = HIWORD (wParam); break; case SB_TOP: wWarpSpeed = MINWARP; break; case SB_BOTTOM: wWarpSpeed = MAXWARP; break; case SB_THUMBTRACK: case SB_ENDSCROLL: return TRUE; break; } if ((int)((short)wWarpSpeed) <= MINWARP) wWarpSpeed = MINWARP; if ((int)wWarpSpeed >= MAXWARP) wWarpSpeed = MAXWARP; SetScrollPos ((HWND) lParam, SB_CTL, wWarpSpeed, TRUE); break; case WM_COMMAND: switch (LOWORD(wParam)) { case ID_DENSITY: if (HIWORD(wParam) == EN_UPDATE) { wTemp = GetDlgItemInt (hDlg, ID_DENSITY, &fError, FALSE); fError = ((wTemp <= MAXSTARS) && (wTemp >= MINSTARS)); EnableWindow (GetDlgItem (hDlg, ID_DENSITYARROW), fError); EnableWindow (GetDlgItem (hDlg, IDOK), fError); } break; case IDOK: wTemp = GetDlgItemInt (hDlg, ID_DENSITY, &fError, FALSE); wsprintf (szTemp, TEXT("%d"), wTemp); WritePrivateProfileString (szAppName, szDensity, szTemp, szIniFile); wsprintf (szTemp, TEXT("%d"), wWarpSpeed); WritePrivateProfileString (szAppName, szWarpSpeed, szTemp, szIniFile); case IDCANCEL: EndDialog (hDlg, LOWORD(wParam) == IDOK); return TRUE; } break; case WM_HELP: // F1 WinHelp( (HWND) ((LPHELPINFO) lParam)->hItemHandle, szHelpFile, HELP_WM_HELP, (ULONG_PTR) (LPSTR) aStarsDlgHelpIds ); break; case WM_CONTEXTMENU: // right mouse click WinHelp( (HWND) wParam, szHelpFile, HELP_CONTEXTMENU, (ULONG_PTR) (LPSTR) aStarsDlgHelpIds ); break; default: break; } return FALSE; } /* This procedure is called right before the dialog box above is created in order to register any child windows that are custom controls. If no custom controls need to be registered, then simply return TRUE. Otherwise, register the child controls however is convenient... */ BOOL RegisterDialogClasses (HANDLE hInst) { InitCommonControls(); return TRUE; } VOID srand (DWORD dwSeed) { dwRand = dwSeed; } WORD rand (VOID) { dwRand = dwRand * 214013L + 2531011L; return (WORD)((dwRand >> 16) & 0xffff); } VOID CreateStar (WORD wIndex) { nX[wIndex] = wXScreen ? (LONG)((int)(ZRAND (wXScreen)) - (int)wX2Screen) : 0; nY[wIndex] = wXScreen ? (LONG)((int)(ZRAND (wYScreen)) - (int)wY2Screen) : 0; nZ[wIndex] = SCOPE * WARPFACTOR; } LONG GetDlgItemLong (HWND hDlg, WORD wID, BOOL *pfTranslated, BOOL fSigned) { TCHAR szTemp[20]; LPTSTR pszTemp; LONG lTemp = 0l; BOOL fNegative; if (!GetDlgItemText (hDlg, wID, szTemp, CharSizeOf(szTemp))) goto GetDlgItemLongError; szTemp[19] = TEXT('\0'); pszTemp = szTemp; while (*pszTemp == TEXT(' ') || *pszTemp == TEXT('\t')) pszTemp++; if ((!fSigned && *pszTemp == TEXT('-')) || !*pszTemp) goto GetDlgItemLongError; fNegative = (*pszTemp == TEXT('-')) ? TRUE : FALSE; while (*pszTemp >= TEXT('0') && *pszTemp <= TEXT('9')) lTemp = lTemp * 10l + (LONG)(*(pszTemp++) - TEXT('0')); if (*pszTemp) goto GetDlgItemLongError; if (fNegative) lTemp *= -1; *pfTranslated = TRUE; return lTemp; GetDlgItemLongError: *pfTranslated = FALSE; return 0l; } LONG GetPrivateProfileLong (LPTSTR pszApp, LPTSTR pszKey, LONG lDefault) { LONG lTemp = 0l; TCHAR szTemp[20]; LPTSTR pszTemp; if (!GetPrivateProfileString (pszApp, pszKey, TEXT(""), szTemp, CharSizeOf(szTemp), szIniFile)) goto GetProfileLongError; szTemp[19] = TEXT('\0'); pszTemp = szTemp; while (*pszTemp >= TEXT('0') && *pszTemp <= TEXT('9')) lTemp = lTemp * 10l + (LONG)(*(pszTemp++) - TEXT('0')); if (*pszTemp) goto GetProfileLongError; return lTemp; GetProfileLongError: return lDefault; } VOID GetIniEntries (VOID) { LoadString (hMainInstance, idsName, szName, CharSizeOf(szName)); LoadString (hMainInstance, idsAppName, szAppName, CharSizeOf(szAppName)); //Load Common Strings from stringtable... LoadString (hMainInstance, idsIniFile, szIniFile, CharSizeOf(szIniFile)); LoadString (hMainInstance, idsScreenSaver, szScreenSaver, CharSizeOf(szScreenSaver)); LoadString (hMainInstance, idsHelpFile, szHelpFile, CharSizeOf(szHelpFile)); LoadString (hMainInstance, idsNoHelpMemory, szNoHelpMemory, CharSizeOf(szNoHelpMemory)); wWarpSpeed = (WORD) GetPrivateProfileInt (szAppName, szWarpSpeed, MINWARP + ((MAXWARP - MINWARP) / 2), szIniFile); if (wWarpSpeed > MAXWARP) wWarpSpeed = MINWARP + ((MAXWARP - MINWARP) / 2); wDensity = (WORD) GetPrivateProfileInt (szAppName, szDensity, DEF_DENSITY, szIniFile); if (wDensity > MAXSTARS) wDensity = MAXSTARS; if (wDensity < MINSTARS) wDensity = MINSTARS; }