Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / modules / rosapps / applications / screensavers / butterflies / butterflies.c
1 #include <windows.h>
2 #include <scrnsave.h>
3 #include <tchar.h>
4 #include <math.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <GL/gl.h>
8 #include <GL/glu.h>
9 #include <GL/glext.h>
10 #include "resource.h"
11
12 HINSTANCE hInstance; // Holds The Instance Of The Application
13
14 GLuint texture[3]; //stores texture objects and display list
15
16 LPCTSTR registryPath = _T("Software\\Microsoft\\ScreenSavers\\Butterflies");
17 BOOL dRotate;
18
19
20 struct object // Create A Structure Called Object
21 {
22 int tex; // Integer Used To Select Our Texture
23 float x; // X Position
24 float y; // Y Position
25 float z; // Z Position
26 float yi; // Y Increase Speed (Fall Speed)
27 float spinz; // Z Axis Spin
28 float spinzi; // Z Axis Spin Speed
29 float flap; // Flapping Triangles :)
30 float fi; // Flap Direction (Increase Value)
31 };
32
33 struct object obj[50];
34 //object obj[50]; // Create 50 Objects Using The Object Structure
35
36 void SetDefaults()
37 {
38 dRotate = TRUE;
39 }
40
41 void ReadRegistry(){
42 LONG result;
43 HKEY skey;
44 DWORD valtype, valsize, val;
45
46 SetDefaults();
47
48 result = RegOpenKeyEx(HKEY_CURRENT_USER, registryPath, 0, KEY_READ, &skey);
49 if(result != ERROR_SUCCESS)
50 return;
51
52 valsize=sizeof(val);
53
54 result = RegQueryValueEx(skey, _T("Rotate"), 0, &valtype, (LPBYTE)&val, &valsize);
55 if(result == ERROR_SUCCESS)
56 dRotate = val;
57 RegCloseKey(skey);
58 }
59
60 void WriteRegistry(){
61 LONG result;
62 HKEY skey;
63 DWORD val, disp;
64
65 result = RegCreateKeyEx(HKEY_CURRENT_USER, registryPath, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &skey, &disp);
66 if(result != ERROR_SUCCESS)
67 return;
68
69 val = dRotate;
70 RegSetValueEx(skey, _T("Rotate"), 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val));
71
72 RegCloseKey(skey);
73 }
74
75 void SetObject(int loop) // Sets The Initial Value Of Each Object (Random)
76 {
77 obj[loop].tex=rand()%3; // Texture Can Be One Of 3 Textures
78 obj[loop].x=rand()%34-17.0f; // Random x Value From -17.0f To 17.0f
79 obj[loop].y=18.0f; // Set y Position To 18 (Off Top Of Screen)
80 obj[loop].z=-((rand()%30000/1000.0f)+10.0f); // z Is A Random Value From -10.0f To -40.0f
81 obj[loop].spinzi=(rand()%10000)/5000.0f-1.0f; // spinzi Is A Random Value From -1.0f To 1.0f
82 obj[loop].flap=0.0f; // flap Starts Off At 0.0f;
83 obj[loop].fi=0.05f+(rand()%100)/1000.0f; // fi Is A Random Value From 0.05f To 0.15f
84 obj[loop].yi=0.001f+(rand()%1000)/10000.0f; // yi Is A Random Value From 0.001f To 0.101f
85 }
86
87 void LoadGLTextures() // Creates Textures From Bitmaps In The Resource File
88 {
89 HBITMAP hBMP; // Handle Of The Bitmap
90 BITMAP BMP; // Bitmap Structure
91 int loop;
92
93 // The ID Of The 3 Bitmap Images We Want To Load From The Resource File
94 byte Texture[]={ IDB_BUTTERFLY1, IDB_BUTTERFLY2, IDB_BUTTERFLY3 };
95
96 glGenTextures(sizeof(Texture), &texture[0]); // Generate 3 Textures (sizeof(Texture)=3 ID's)
97 for (loop=0; loop<sizeof(Texture); loop++) // Loop Through All The ID's (Bitmap Images)
98 {
99 hBMP=(HBITMAP)LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(Texture[loop]), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
100 if (hBMP) // Does The Bitmap Exist?
101 { // If So...
102 GetObject(hBMP,sizeof(BMP), &BMP); // Get The Object
103 // hBMP: Handle To Graphics Object
104 // sizeof(BMP): Size Of Buffer For Object Information
105 // Buffer For Object Information
106 glPixelStorei(GL_UNPACK_ALIGNMENT,4); // Pixel Storage Mode (Word Alignment / 4 Bytes)
107 glBindTexture(GL_TEXTURE_2D, texture[loop]); // Bind Our Texture
108 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering
109 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); // Mipmap Linear Filtering
110
111 // Generate Mipmapped Texture (3 Bytes, Width, Height And Data From The BMP)
112 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, BMP.bmWidth, BMP.bmHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, BMP.bmBits);
113 }
114 }
115 }
116
117 HGLRC InitOGLWindow(HWND hWnd)
118 {
119 HDC hDC = GetDC(hWnd);
120 HGLRC hRC = 0;
121 PIXELFORMATDESCRIPTOR pfd;
122 int nFormat;
123
124 ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR));
125
126 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
127 pfd.nVersion = 1;
128 pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
129 pfd.cColorBits = 24;
130 pfd.cDepthBits = 24;
131
132 nFormat = ChoosePixelFormat(hDC, &pfd);
133 DescribePixelFormat(hDC, nFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
134 SetPixelFormat(hDC, nFormat, &pfd);
135
136 hRC = wglCreateContext(hDC);
137 wglMakeCurrent(hDC, hRC);
138
139 ReleaseDC(hWnd, hDC);
140
141 return hRC;
142 }
143
144 void InitOpenGL(GLsizei width, GLsizei height)
145 {
146 int loop;
147
148 if (height==0) // Prevent A Divide By Zero By
149 {
150 height=1; // Making Height Equal One
151 }
152
153 glViewport(0,0,width,height); // Reset The Current Viewport
154
155 glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
156 glLoadIdentity(); // Reset The Projection Matrix
157
158 // Calculate The Aspect Ratio Of The Window
159 gluPerspective (45.0f, (GLfloat)(width)/(GLfloat)(height),1.0f, 1000.0f);
160
161 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
162 glLoadIdentity();
163 // Start Of User Initialization
164 LoadGLTextures(); // Load The Textures From Our Resource File
165
166 glClearColor (0.0f, 0.0f, 0.0f, 0.5f); // Black Background
167 glClearDepth (1.0f); // Depth Buffer Setup
168 glDepthFunc (GL_LEQUAL); // The Type Of Depth Testing (Less Or Equal)
169 glDisable(GL_DEPTH_TEST); // Disable Depth Testing
170 glShadeModel (GL_SMOOTH); // Select Smooth Shading
171 glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Set Perspective Calculations To Most Accurate
172 glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
173 glBlendFunc(GL_ONE,GL_SRC_ALPHA); // Set Blending Mode (Cheap / Quick)
174 glEnable(GL_BLEND);
175
176
177 for (loop=0; loop<50; loop++) // Loop To Initialize 50 Objects
178 {
179 SetObject(loop); // Call SetObject To Assign New Random Values
180 }
181
182 }
183
184 void Display()
185 {
186 int loop;
187 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
188
189 for (loop=0; loop<50; loop++) // Loop Of 50 (Draw 50 Objects)
190 {
191 glLoadIdentity (); // Reset The Modelview Matrix
192 glBindTexture(GL_TEXTURE_2D, texture[obj[loop].tex]); // Bind Our Texture
193 glTranslatef(obj[loop].x,obj[loop].y,obj[loop].z); // Position The Object
194 glRotatef(45.0f,1.0f,0.0f,0.0f); // Rotate On The X-Axis
195 if (dRotate)
196 {
197 glRotatef((obj[loop].spinz),0.0f,0.0f,1.0f); // Spin On The Z-Axis
198 }
199 glBegin(GL_TRIANGLES); // Begin Drawing Triangles
200 // First Triangle _____
201 glTexCoord2f(1.0f,1.0f); glVertex3f( 1.0f, 1.0f, 0.0f); // (2)| / (1)
202 glTexCoord2f(0.0f,1.0f); glVertex3f(-1.0f, 1.0f, obj[loop].flap); // | /
203 glTexCoord2f(0.0f,0.0f); glVertex3f(-1.0f,-1.0f, 0.0f); // (3)|/
204
205 // Second Triangle
206 glTexCoord2f(1.0f,1.0f); glVertex3f( 1.0f, 1.0f, 0.0f); // /|(1)
207 glTexCoord2f(0.0f,0.0f); glVertex3f(-1.0f,-1.0f, 0.0f); // / |
208 glTexCoord2f(1.0f,0.0f); glVertex3f( 1.0f,-1.0f, obj[loop].flap); // (2)/____|(3)
209
210 glEnd(); // Done Drawing Triangles
211
212 obj[loop].y-=obj[loop].yi; // Move Object Down The Screen
213 obj[loop].spinz+=obj[loop].spinzi; // Increase Z Rotation By spinzi
214 obj[loop].flap+=obj[loop].fi; // Increase flap Value By fi
215
216 if (obj[loop].y<-18.0f) // Is Object Off The Screen?
217 {
218 SetObject(loop); // If So, Reassign New Values
219 }
220
221 if ((obj[loop].flap>1.0f) || (obj[loop].flap<-1.0f)) // Time To Change Flap Direction?
222 {
223 obj[loop].fi=-obj[loop].fi; // Change Direction By Making fi = -fi
224 }
225 }
226
227 Sleep(15); // Create A Short Delay (15 Milliseconds)
228
229 glFlush ();
230
231 }
232
233 BOOL AboutProc(HWND hdlg, UINT msg, WPARAM wpm, LPARAM lpm){
234
235 switch(msg){
236 case WM_CTLCOLORSTATIC:
237 if(((HWND)lpm == GetDlgItem(hdlg, WEBPAGE1)) || ((HWND)lpm == GetDlgItem(hdlg, WEBPAGE2)))
238 {
239 SetTextColor((HDC)wpm, RGB(0,0,255));
240 SetBkColor((HDC)wpm, (COLORREF)GetSysColor(COLOR_3DFACE));
241 return((int)GetSysColorBrush(COLOR_3DFACE));
242 }
243 break;
244 case WM_COMMAND:
245 switch(LOWORD(wpm)){
246 case IDOK:
247 EndDialog(hdlg, LOWORD(wpm));
248 break;
249 case WEBPAGE1:
250 ShellExecute(NULL, _T("open"), _T("http://nehe.gamedev.net"), NULL, NULL, SW_SHOWNORMAL);
251 break;
252 case WEBPAGE2:
253 ShellExecute(NULL, _T("open"), _T("http://www.thaputer.com"), NULL, NULL, SW_SHOWNORMAL);
254 break;
255 }
256 }
257 return FALSE;
258 }
259
260 LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT message,
261 WPARAM wParam, LPARAM lParam)
262 {
263 static HGLRC hRC;
264 static DWORD timer = 1;
265 HDC hDC;
266 RECT WindowRect;
267 int width;
268 int height;
269
270 switch (message)
271 {
272 case WM_CREATE:
273 ReadRegistry();
274 hRC = InitOGLWindow(hWnd);
275 GetClientRect (hWnd, &WindowRect);
276 width = WindowRect.right - WindowRect.left;
277 height = WindowRect.bottom - WindowRect.top;
278 InitOpenGL(width,height);
279 SetTimer(hWnd, timer, 5, NULL);
280 break;
281 case WM_TIMER:
282 hDC = GetDC(hWnd);
283 Display();
284 SwapBuffers(hDC);
285 ReleaseDC(hWnd, hDC);
286 break;
287 case WM_DESTROY:
288 wglMakeCurrent(NULL, NULL);
289 wglDeleteContext(hRC);
290 break;
291 }
292
293 return DefScreenSaverProc(hWnd, message, wParam, lParam);
294 }
295
296 BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message,
297 WPARAM wParam, LPARAM lParam)
298 {
299 switch (message)
300 {
301 case WM_INITDIALOG:
302 ReadRegistry();
303 CheckDlgButton(hDlg, ROTATE, dRotate);
304 return TRUE;
305 case WM_COMMAND:
306 switch (LOWORD(wParam))
307 {
308 case IDOK:
309 dRotate = (IsDlgButtonChecked(hDlg, ROTATE) == BST_CHECKED);
310 WriteRegistry();
311 EndDialog(hDlg, TRUE);
312 return TRUE;
313 case IDCANCEL:
314 EndDialog(hDlg, TRUE);
315 break;
316 case IDABOUT:
317 DialogBox(hInstance, MAKEINTRESOURCE(IDD_DLG_ABOUT), hDlg, (DLGPROC)AboutProc);
318 break;
319 }
320 }
321
322 return FALSE;
323 }
324
325 BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
326 {
327 return TRUE;
328 }
329