forgotten commit. disabled until egl is adapted.
[AROS-Contrib.git] / Games / XInvaders3D / main-w.c
blob82b8560a1803ee433ca1bba4f8f6f42033a4f580
1 /*------------------------------------------------------------------
2 main-w.c:
4 XINVADERS 3D - 3d Shoot'em up
5 Copyright (C) 2000 Don Llopis
7 WIN32 port by Thomas Boutell
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 ------------------------------------------------------------------*/
25 #include <windows.h>
26 #include <sys/types.h>
27 #include "game.h"
29 /*================================================================*/
30 /* WIN32 globals */
32 HINSTANCE hInst;
33 HWND win;
35 HPEN color_table_pens [MAX_COLORS];
36 HBRUSH color_table_brushes [MAX_COLORS];
37 unsigned short color_data [MAX_COLORS][3];
38 HPEN blackPen;
39 HBRUSH blackBrush;
41 /* Menu item IDs for the message boxes */
42 #define aboutItemId 1000
43 #define rulesItemId 1001
45 /* window buffers */
46 HDC double_buffer_dc;
47 HBITMAP double_buffer;
48 HBITMAP double_buffer_old_bitmap;
49 /* misc window info */
50 char *window_name = "3d";
51 unsigned int window_width, window_height,
52 display_width, display_height;
54 static void showGameInfo(char **gameInfo, char *title, char *append);
56 /*================================================================*/
58 int PASCAL WinMain(HINSTANCE hInstCurrent, HINSTANCE hInstPrevious,
59 LPSTR lpszCmdLine, int nCmdShow)
62 hInst = hInstCurrent;
63 if ( !Graphics_init ( WIN_WIDTH, WIN_HEIGHT ) )
65 MessageBox(0,
66 "Error: could not initialize graphics!\n",
67 "XInvaders 3D Error",
68 MB_ICONEXCLAMATION);
69 exit ( -1 );
72 if ( !Game_init ( WIN_WIDTH, WIN_HEIGHT ) )
74 MessageBox(0,
75 "Error: could not initialize game data!\n",
76 "XInvaders 3D Error",
77 MB_ICONEXCLAMATION);
78 exit ( -1 );
81 /* run the game until ESC key is pressed */
82 while ( Handle_events () )
84 /* get start-time of current frame */
85 gv->msec = Timer_msec ( gt );
86 gv->ftime = (double)gv->msec/1000L;
87 gv->fps = 1.0 / gv->ftime;
88 gv->fadjust = gv->rfps / gv->fps;
90 /* do game */
91 (*Game_actionfn)();
92 /* get end-time of current frame, msec elapsed, and calc fps */
93 /* update display */
94 Update_display ();
97 Graphics_shutdown ();
98 showGameInfo(game_about_info, "About XInvaders 3D",
99 "Ported to Windows by Thomas Boutell");
100 return 0;
104 long FAR PASCAL winv3dWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
106 /*================================================================*/
108 int Graphics_init ( unsigned int win_width, unsigned int win_height )
110 int i, j, width, height;
112 HDC hdc;
113 HPEN oldPen;
114 HBRUSH oldBrush;
115 WNDCLASS wc;
116 MENUITEMINFO menuitem;
117 HMENU menu;
118 int count;
119 width = win_width;
120 height = (int) win_height;
122 window_width = win_width;
123 window_height = win_height;
125 /* Create a window class */
126 wc.style = 0;
127 wc.lpfnWndProc = winv3dWndProc;
128 wc.cbClsExtra = 0;
129 wc.cbWndExtra = 0;
130 wc.hInstance = hInst;
131 wc.hIcon = 0; /* LoadIcon(hInst, MAKEINTRESOURCE(WINV3D_ICON)); */
132 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
133 wc.hbrBackground = 0;
134 wc.lpszMenuName = 0;
135 wc.lpszClassName = "xinv3d";
136 if (!RegisterClass(&wc)) {
137 return FALSE;
140 /* create a simple window*/
141 win = CreateWindow(
142 "xinv3d",
143 "xinv3d",
144 WS_OVERLAPPEDWINDOW,
145 CW_USEDEFAULT,
146 CW_USEDEFAULT,
147 window_width, window_height,
148 HWND_DESKTOP,
150 hInst,
152 /* Get the system menu, so that we can install an
153 about option that explains how to play */
154 menu = GetSystemMenu(win, FALSE);
155 count = GetMenuItemCount(menu);
156 memset(&menuitem, 0, sizeof(menuitem));
157 menuitem.fType = MFT_STRING;
158 menuitem.fMask = MIIM_TYPE | MIIM_ID;
159 menuitem.wID = aboutItemId;
160 menuitem.dwTypeData = (DWORD) "&About xinv3d";
161 menuitem.cch = strlen("&About xinv3d");
162 menuitem.cbSize = sizeof(menuitem);
163 InsertMenuItem(menu,
164 count,
165 TRUE,
166 &menuitem);
167 memset(&menuitem, 0, sizeof(menuitem));
168 menuitem.fType = MFT_STRING;
169 menuitem.fMask = MIIM_TYPE | MIIM_ID;
170 menuitem.wID = rulesItemId;
171 menuitem.dwTypeData = (DWORD) "&How to Play";
172 menuitem.cch = strlen("&How to Play");
173 menuitem.cbSize = sizeof(menuitem);
174 InsertMenuItem(menu,
175 count,
176 TRUE,
177 &menuitem);
178 /* load default color scheme */
180 /* red */
181 for ( i=0, j=0; i<64; i++, j++ )
183 color_data[i][0] = 1024 * j;
184 color_data[i][1] = color_data[i][2] = 0;
187 /* green */
188 for ( i=64, j=0; i<128; i++, j++ )
190 color_data[i][1] = 1024 * j;
191 color_data[i][0] = color_data[i][2] = 0;
194 /* blue */
195 for ( i=128, j=0; i<192; i++, j++ )
197 color_data[i][2] = 1024 * j;
198 color_data[i][0] = color_data[i][1] = 0;
201 /* white */
202 for ( i=192, j=0; i<256; i++, j++ )
204 color_data[i][0] = color_data[i][1] = color_data[i][2] = j * 1024;
207 /* yellow */
208 color_data[192][0] = 63 * 1024;
209 color_data[192][1] = 63 * 1024;
210 color_data[192][2] = 32 * 1024;
213 for ( i=0; i<MAX_COLORS; i++ )
215 color_table_pens[i] = CreatePen(PS_SOLID, 1,
216 RGB(color_data[i][0] >> 8,
217 color_data[i][1] >> 8,
218 color_data[i][2] >> 8));
219 color_table_brushes[i] = CreateSolidBrush(
220 RGB(color_data[i][0] >> 8,
221 color_data[i][1] >> 8,
222 color_data[i][2] >> 8));
224 blackPen = color_table_pens[BLACK];
225 blackBrush = color_table_brushes[BLACK];
227 /* create double buffer */
228 hdc = GetDC(win);
229 double_buffer = CreateCompatibleBitmap(
230 hdc, window_width, window_height);
231 double_buffer_dc = CreateCompatibleDC(hdc);
232 double_buffer_old_bitmap = SelectObject(
233 double_buffer_dc, double_buffer);
234 SetBkColor(double_buffer_dc, RGB(0, 0, 0));
235 ReleaseDC(win, hdc);
237 oldPen = SelectObject(double_buffer_dc, blackPen);
238 oldBrush = SelectObject(double_buffer_dc, blackBrush);
240 Rectangle(double_buffer_dc,
241 0, 0,
242 window_width,
243 window_height);
244 SelectObject(double_buffer_dc, oldPen);
245 SelectObject(double_buffer_dc, oldBrush);
246 /* display the window */
247 ShowWindow(win, SW_SHOW);
249 return TRUE;
252 /*================================================================*/
254 void Graphics_shutdown ( void )
256 int i;
257 SelectObject(double_buffer_dc, double_buffer_old_bitmap);
258 DeleteDC(double_buffer_dc);
259 DeleteObject(double_buffer);
260 for ( i=0; i<MAX_COLORS; i++ ) {
261 DeleteObject(color_table_pens[i]);
262 DeleteObject(color_table_brushes[i]);
266 /*================================================================*/
268 int Update_display ( void )
270 RECT r;
271 HDC hdc = GetDC(win);
272 BitBlt(hdc,
275 window_width,
276 window_height,
277 double_buffer_dc,
280 SRCCOPY);
281 r.left = 0;
282 r.top = 0;
283 r.right = window_width;
284 r.bottom = window_height;
285 FillRect(double_buffer_dc,
287 blackBrush);
288 return TRUE;
291 /*================================================================*/
293 void handleMessage(MSG *msg);
295 int Handle_events ( void )
297 MSG msg;
298 while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
299 if (msg.message == WM_QUIT) {
300 return FALSE;
302 handleMessage(&msg);
304 return TRUE;
308 void handleMessage(MSG *msg) {
309 /* Handle one message */
310 TranslateMessage(msg); /* translates virtual key codes */
311 DispatchMessage(msg); /* dispatches message to window */
314 /*================================================================*/
316 void Draw_line ( int x0, int y0, int x1, int y1, unsigned int color )
318 POINT p;
319 HPEN oldPen = SelectObject(double_buffer_dc, color_table_pens[color]);
320 MoveToEx(double_buffer_dc, x0, y0, &p);
321 LineTo(double_buffer_dc, x1, y1);
322 SelectObject(double_buffer_dc, oldPen);
325 /*================================================================*/
327 void Draw_point ( int x0, int y0, unsigned int color )
329 RECT r;
330 /* Consistent with the original odd logic */
331 r.top = y0 - 3;
332 r.left = x0 + 3;
333 r.bottom = y0;
334 r.right = x0;
335 FillRect(double_buffer_dc, &r, color_table_brushes[color]);
338 /*================================================================*/
340 void Draw_text ( const char *message, int x0, int y0, unsigned int color )
342 SetTextColor(double_buffer_dc,
343 RGB(color_data[color][0] >> 8,
344 color_data[color][1] >> 8,
345 color_data[color][2] >> 8));
346 /* draw text */
347 TextOut(double_buffer_dc,
348 x0, y0,
349 message,
350 strlen(message));
353 /*================================================================*/
355 long FAR PASCAL winv3dWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
357 switch (msg) {
359 * Process whatever messages you want here and send the
360 * rest to DefWindowProc.
362 case WM_KEYDOWN:
363 if (lParam & 0x4000000) {
364 /* Repeat */
365 break;
367 /* Not Repeat */
368 switch (wParam)
370 case VK_SPACE:
371 gv->key_FIRE = TRUE;
372 break;
374 case VK_UP:
375 gv->key_UP = TRUE;
376 break;
378 case VK_DOWN:
379 gv->key_DOWN = TRUE;
380 break;
382 case VK_LEFT:
383 gv->key_LEFT = TRUE;
384 break;
386 case VK_RIGHT:
387 gv->key_RIGHT = TRUE;
388 break;
389 case VK_ESCAPE:
390 /* quit! */
391 PostMessage(win, WM_QUIT, 0, 0L);
392 return FALSE;
393 break;
395 default:
396 break;
398 break;
399 case WM_CHAR:
400 switch (wParam)
402 case 'f':
403 /* display frames per second */
404 gv->display_fps ^= TRUE;
405 break;
407 case 'p':
408 /* pause */
409 Game_paused_toggle ();
410 break;
412 case 'q':
413 Game_reset ();
414 break;
415 default:
416 break;
418 break;
419 case WM_KEYUP:
420 switch (wParam)
422 case VK_SPACE:
423 gv->key_FIRE = FALSE;
424 break;
426 case VK_UP:
427 gv->key_UP = FALSE;
428 break;
430 case VK_DOWN:
431 gv->key_DOWN = FALSE;
432 break;
434 case VK_LEFT:
435 gv->key_LEFT = FALSE;
436 break;
438 case VK_RIGHT:
439 gv->key_RIGHT = FALSE;
440 break;
441 default:
442 break;
444 break;
445 case WM_SYSCOMMAND:
446 switch (wParam) {
447 case SC_CLOSE:
448 PostMessage(win, WM_QUIT, 0, 0L);
449 break;
450 case aboutItemId:
451 showGameInfo(game_about_info,
452 "About XInvaders 3D",
453 "Ported to Windows by Thomas Boutell");
454 break;
455 case rulesItemId:
456 showGameInfo(game_rules_info,
457 "How to Play XInvaders 3D",
459 break;
460 default:
461 /* Inherit default behavior */
462 return (DefWindowProc(hwnd, msg, wParam, lParam));
464 default:
465 /* Inherit default behavior */
466 return (DefWindowProc(hwnd, msg, wParam, lParam));
468 return 0L;
471 static void showGameInfo(char **gameInfo, char *title, char *append)
473 /* Must be less than 16K to work properly. */
474 char message[16384];
475 strcpy(message, "");
476 while (*gameInfo) {
477 strcat(message, *gameInfo);
478 strcat(message, "\r\n");
479 gameInfo++;
481 if (append) {
482 strcat(message, append);
484 MessageBox(win,
485 message,
486 title ? title : "XInvaders 3D",
487 MB_ICONINFORMATION);
490 void Timer_init ( TIMER *t )
492 long msec;
493 t->init_time_stamp = time ( NULL );
494 msec = GetTickCount();
495 t->t0.tv_sec = msec / 1000;
496 t->t0.tv_usec = (msec % 1000) * 1000;
498 t->t1 = t->t0;
501 /*================================================================*/
503 CLOCK_T Timer_ticks ( void )
505 return clock ();
508 /*================================================================*/
510 double Timer_sec ( TIMER *t )
512 return difftime ( time(NULL), t->init_time_stamp );
515 /*================================================================*/
517 long Timer_msec ( TIMER *t )
519 long msec = GetTickCount();
520 t->t1.tv_sec = msec / 1000;
521 t->t1.tv_usec = (msec % 1000) * 1000;
523 msec = ((t->t1.tv_sec-t->t0.tv_sec)*1000L)+
524 ((t->t1.tv_usec-t->t0.tv_usec)/1000L);
526 t->t0.tv_sec = t->t1.tv_sec;
527 t->t0.tv_usec = t->t1.tv_usec;
529 return msec;