1 /* 2 * Copyright 2003 J Brown 3 * Copyright 2006 Eric Kohl 4 * Copyright 2007 Marc Piulachs (marc.piulachs@codexchange.net) 5 * Copyright 2015 Daniel Reimer 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 20 */ 21 22 #include <windows.h> 23 #include <tchar.h> 24 #include <scrnsave.h> 25 #include "resource.h" 26 27 #define RANDOM( min, max ) ((rand() % (int)(((max)+1) - (min))) + (min)) 28 29 #define MAX_LOADSTRING 100 30 #define MAX_STARS 1000 31 32 #define APPNAME _T("Starfield") 33 #define APP_TIMER 1 34 #define APP_TIMER_INTERVAL 20 35 36 #define MAX_STARS 1000 37 38 // Details of each individual star 39 typedef struct star 40 { 41 int m_nXPos, m_nYPos, m_nZPos; 42 int m_nOldX, m_nOldY; 43 } STAR; 44 45 STAR *stars; 46 47 int m_nTotStars; 48 int m_nCenterX, m_nCenterY; 49 50 void DrawStarField (HDC pDC) 51 { 52 int nX, nY; 53 int i; 54 for (i = 0; i < m_nTotStars; i++) 55 { 56 // Clear last position of this star 57 SetPixel ( 58 pDC, 59 stars[i].m_nOldX, 60 stars[i].m_nOldY, 61 RGB (0, 0, 0)); 62 63 nX = (int)((((long)stars[i].m_nXPos << 7) / (long)stars[i].m_nZPos) + m_nCenterX); 64 nY = (int)((((long)stars[i].m_nYPos << 7) / (long)stars[i].m_nZPos) + m_nCenterY); 65 66 // Draw star 67 SetPixel ( 68 pDC, 69 nX, 70 nY, 71 RGB (255, 255, 255)); 72 73 // Remember current position for clearing later 74 stars[i].m_nOldX = nX; 75 stars[i].m_nOldY = nY; 76 } 77 } 78 79 BOOL SetUpStars (int nNumStars) 80 { 81 int i; 82 if (nNumStars > MAX_STARS) 83 { 84 MessageBox (0, 85 _T("Too many stars! Aborting!"), 86 _T("Error"), 87 MB_OK | MB_ICONWARNING); 88 return FALSE; 89 } 90 91 if (stars) 92 free (stars); 93 94 m_nTotStars = nNumStars; 95 96 stars = (STAR*)malloc(nNumStars * sizeof(STAR)); 97 98 if (!stars) 99 { 100 MessageBox (0, 101 _T("Unable to allocate memory! Aborting!"), 102 _T("Error"), 103 MB_OK | MB_ICONWARNING); 104 return FALSE; 105 } 106 107 for (i = 0; i < m_nTotStars; i++) 108 { 109 do 110 { 111 stars[i].m_nXPos = RANDOM (-320, 320); 112 stars[i].m_nYPos = RANDOM (-200, 200); 113 stars[i].m_nZPos = i+1; 114 stars[i].m_nOldX = -1; 115 stars[i].m_nOldY = -1; 116 } while ((stars[i].m_nXPos == 0) || (stars[i].m_nYPos == 0)); 117 } 118 return TRUE; 119 } 120 121 void MoveStarField (int nXofs, int nYofs, int nZofs) 122 { 123 int i; 124 for (i = 0; i < m_nTotStars; i++) 125 { 126 stars[i].m_nXPos += nXofs; 127 stars[i].m_nYPos += nYofs; 128 stars[i].m_nZPos += nZofs; 129 130 if (stars[i].m_nZPos > m_nTotStars) 131 stars[i].m_nZPos -= m_nTotStars; 132 if (stars[i].m_nZPos < 1) 133 stars[i].m_nZPos += m_nTotStars; 134 } 135 } 136 137 void SetDimensions (int nWidth, int nHeight) 138 { 139 m_nCenterX = nWidth / 2; 140 m_nCenterY = nHeight / 2; 141 } 142 143 LRESULT WINAPI ScreenSaverProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 144 { 145 static HDC pDC; 146 147 switch (msg) 148 { 149 case WM_CREATE: 150 { 151 SetTimer ( 152 hwnd, 153 APP_TIMER, 154 APP_TIMER_INTERVAL, 155 NULL); 156 } 157 break; 158 case WM_PAINT: 159 { 160 PAINTSTRUCT PtStr; 161 HDC pDC = BeginPaint (hwnd, &PtStr); 162 DrawStarField (pDC); 163 EndPaint (hwnd, &PtStr); 164 SetUpStars(250); 165 return (0); 166 } 167 break; 168 case WM_TIMER: 169 { 170 if (wParam == APP_TIMER) 171 { 172 MoveStarField (0, 0, -3); 173 pDC = GetDC(hwnd); 174 DrawStarField (pDC); 175 ReleaseDC(hwnd, pDC); 176 } 177 } 178 break; 179 case WM_SIZE: 180 { 181 // Change the center point of the starfield 182 SetDimensions ( 183 LOWORD(lParam), 184 HIWORD(lParam)); 185 } 186 break; 187 case WM_DESTROY: 188 { 189 KillTimer (hwnd, APP_TIMER); 190 free(stars); 191 ShowCursor(TRUE); 192 PostQuitMessage (0); 193 return 0; 194 } 195 break; 196 default: 197 return DefScreenSaverProc(hwnd, msg, wParam, lParam); 198 } 199 return 0; 200 } 201 202 BOOL WINAPI ScreenSaverConfigureDialog(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam) 203 { 204 return FALSE; 205 } 206 207 BOOL WINAPI RegisterDialogClasses(HANDLE hmodule) 208 { 209 TCHAR szTitle[256]; 210 TCHAR szText[256]; 211 212 LoadString(hmodule, 213 IDS_TITLE, 214 szTitle, 215 256); 216 217 LoadString(hmodule, 218 IDS_TEXT, 219 szText, 220 256); 221 222 MessageBox(0, 223 szText, 224 szTitle, 225 MB_OK | MB_ICONWARNING); 226 return FALSE; 227 }