1 /*------------------------------------------------------------------
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 ------------------------------------------------------------------*/
26 #include <sys/types.h>
29 /*================================================================*/
35 HPEN color_table_pens
[MAX_COLORS
];
36 HBRUSH color_table_brushes
[MAX_COLORS
];
37 unsigned short color_data
[MAX_COLORS
][3];
41 /* Menu item IDs for the message boxes */
42 #define aboutItemId 1000
43 #define rulesItemId 1001
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
)
63 if ( !Graphics_init ( WIN_WIDTH
, WIN_HEIGHT
) )
66 "Error: could not initialize graphics!\n",
72 if ( !Game_init ( WIN_WIDTH
, WIN_HEIGHT
) )
75 "Error: could not initialize game data!\n",
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
;
92 /* get end-time of current frame, msec elapsed, and calc fps */
98 showGameInfo(game_about_info
, "About XInvaders 3D",
99 "Ported to Windows by Thomas Boutell");
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
;
116 MENUITEMINFO menuitem
;
120 height
= (int) win_height
;
122 window_width
= win_width
;
123 window_height
= win_height
;
125 /* Create a window class */
127 wc
.lpfnWndProc
= winv3dWndProc
;
130 wc
.hInstance
= hInst
;
131 wc
.hIcon
= 0; /* LoadIcon(hInst, MAKEINTRESOURCE(WINV3D_ICON)); */
132 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
133 wc
.hbrBackground
= 0;
135 wc
.lpszClassName
= "xinv3d";
136 if (!RegisterClass(&wc
)) {
140 /* create a simple window*/
147 window_width
, window_height
,
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
);
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
);
178 /* load default color scheme */
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;
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;
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;
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;
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 */
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));
237 oldPen
= SelectObject(double_buffer_dc
, blackPen
);
238 oldBrush
= SelectObject(double_buffer_dc
, blackBrush
);
240 Rectangle(double_buffer_dc
,
244 SelectObject(double_buffer_dc
, oldPen
);
245 SelectObject(double_buffer_dc
, oldBrush
);
246 /* display the window */
247 ShowWindow(win
, SW_SHOW
);
252 /*================================================================*/
254 void Graphics_shutdown ( void )
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 )
271 HDC hdc
= GetDC(win
);
283 r
.right
= window_width
;
284 r
.bottom
= window_height
;
285 FillRect(double_buffer_dc
,
291 /*================================================================*/
293 void handleMessage(MSG
*msg
);
295 int Handle_events ( void )
298 while(PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
)) {
299 if (msg
.message
== WM_QUIT
) {
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
)
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
)
330 /* Consistent with the original odd logic */
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));
347 TextOut(double_buffer_dc
,
353 /*================================================================*/
355 long FAR PASCAL
winv3dWndProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
359 * Process whatever messages you want here and send the
360 * rest to DefWindowProc.
363 if (lParam
& 0x4000000) {
387 gv
->key_RIGHT
= TRUE
;
391 PostMessage(win
, WM_QUIT
, 0, 0L);
403 /* display frames per second */
404 gv
->display_fps
^= TRUE
;
409 Game_paused_toggle ();
423 gv
->key_FIRE
= FALSE
;
431 gv
->key_DOWN
= FALSE
;
435 gv
->key_LEFT
= FALSE
;
439 gv
->key_RIGHT
= FALSE
;
448 PostMessage(win
, WM_QUIT
, 0, 0L);
451 showGameInfo(game_about_info
,
452 "About XInvaders 3D",
453 "Ported to Windows by Thomas Boutell");
456 showGameInfo(game_rules_info
,
457 "How to Play XInvaders 3D",
461 /* Inherit default behavior */
462 return (DefWindowProc(hwnd
, msg
, wParam
, lParam
));
465 /* Inherit default behavior */
466 return (DefWindowProc(hwnd
, msg
, wParam
, lParam
));
471 static void showGameInfo(char **gameInfo
, char *title
, char *append
)
473 /* Must be less than 16K to work properly. */
477 strcat(message
, *gameInfo
);
478 strcat(message
, "\r\n");
482 strcat(message
, append
);
486 title
? title
: "XInvaders 3D",
490 void Timer_init ( TIMER
*t
)
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;
501 /*================================================================*/
503 CLOCK_T
Timer_ticks ( void )
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
;