1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
12 */
13
14
15 #pragma off (unreferenced)
16 static char rcsid[] = "$Id: descentw.c,v 1.1.1.1 2001/01/19 03:30:14 bradleyb Exp $";
17 #pragma on (unreferenced)
18
19 #include "desw.h"
20
21 #include <mmsystem.h>
22 #include <setjmp.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdio.h>
26
27
28 #include "winapp.h"
29 #include "error.h"
30 #include "gr.h"
31 #include "digi.h"
32 #include "key.h"
33 #include "inferno.h"
34 #include "gamepal.h"
35 #include "game.h"
36 #include "songs.h"
37 #include "mono.h"
38 #include "screens.h"
39 #include "config.h"
40 #include "newdemo.h"
41 #include "text.h"
42 #include "menu.h"
43 #include "vers_id.h"
44 #include "mvelibw.h"
45 #include "modem.h"
46 #include "cntrlcen.h"
47
48 #define D2_ICON 50
49
50 #define MIN_VIRTUAL_MEM_FREE (16 * (1024*1024))
51 #define MIN_PHYSICAL_MEM_FREE (16 * (1024*1024))
52 #define SOUND_22K_CUTOFF (16 *1024*1024) // 8.0 MB
53
54
55 // Globals --------------------------------------------------------------------
56
57 HWND _hAppWnd; // Descent Window
58 HINSTANCE _hAppInstance;
59 int _DDraw = 0; // No DirectX
60 char *_OffscreenCanvasBits; // Pointer to Offscreen Canvas Bits.
61 BOOL _AppActive = FALSE; // Is application active?
62 BOOL _AppPaused = FALSE; // Shall we run game?
63 BOOL _AppInit = FALSE; // Is application initialized?
64 BOOL _RedrawScreen=FALSE; // Shall we force a redraw of the screen?
65 SCREEN_CONTEXT _SCRContext;
66
67 HANDLE hDescent2Mutex = NULL; // handle to determine whether D2 is already running
68 HANDLE hDescent2Mutex2 = NULL;
69
70 BOOL AllowActivates = FALSE;
71
72 // HACK, to keep original CD audio vol.
73 DWORD CD_audio_desktop_vol = 0;
74 int CD_audio_desktop_dev = -1;
75
76 // EXTERNS
77
78 int Platform_system=0;
79
80
81 extern int Mono_initialized;
82 extern int WinEnableInt3;
83 extern int DD_Emulation;
84 extern int Skip_briefing_screens; // So we can skip the briefing
85 extern int digi_system_initialized;
86 extern int framerate_on;
87 extern int Current_display_mode;
88 extern ubyte gr_palette_faded_out;
89 extern int piggy_low_memory; // FROM PIGGY.C!
90 extern RECT ViewportRect;
91 extern int Joystick_calibrating;
92
93 // Game State and other Variables ---------------------------------------------
94
95 static char WinErrorMessage[512];
96 static BOOL WinErrorTrap = FALSE;
97 static BOOL GameShutdown = FALSE;
98 //static BOOL GameInitialized = FALSE;
99 static BOOL WinEnableMovies = TRUE;
100
101
102 // External Functions ---------------------------------------------------------
103
104 extern void grwin_gdi_realizepal(HDC hdc);
105 extern void grwin_cleanup_palette();
106
107 extern void GameLoop(int, int);
108 extern void game_setup(void);
109 extern void check_joystick_calibration();
110 extern void DDResizeViewport(void);
111 extern void SetWinMonoInfo(HWND hWnd, HINSTANCE hInstance);
112
113 extern void InitCD(char *arg);
114 extern void InitVideo(void);
115 extern void InitIO(void);
116 extern void InitData(void);
117 extern void InitSound(void);
118 extern void InitNetwork(void);
119 extern void InitDescent(void);
120 extern void InitPilot(void);
121
122
123 // Function Prototypes --------------------------------------------------------
124
125 int RunGame(int argc, char *argv[]);
126 int RestoreGameSurfaces(void);
127 void ValidateSystem(void);
128 void MakeCodeWritable(void);
129 int ParseArgs(char *argv[], LPSTR lpCmdLine);
130 void WErrorCatch(char *message);
131
132 void DoRegisterCheck(void);
133
134 void AppExit();
135 void AppPaint(HWND hWnd, HDC hdc);
136 void AppSize(HWND hWnd);
137 void AppActivate(HWND hWnd, UINT wParam);
138 void AppQueryPalette(HWND hWnd);
139 void AppPaletteChange(HWND hWnd, UINT wParam);
140 void AppDisplayChange(HWND hWnd, int w, int h, int bpp);
141 BOOL AppHandleSystemKeys(UINT msg, UINT wParam, UINT lParam);
142
143 BOOL GameCheckMultiReactor();
144
145 LRESULT WINAPI _export DescentWndProc(HWND hWnd,UINT msg,UINT wParam,
146 LPARAM lParam);
147
148
149
150 // Initialization and Destruction
151 // ----------------------------------------------------------------------------
152
AppInit(HINSTANCE hInst,HINSTANCE hPrev,LPSTR szCmdLine,int nCmdShow)153 BOOL AppInit(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow)
154 {
155 // Create Application Window and Initialize WinG stuff.
156 WNDCLASS wc;
157
158 #ifdef RELEASE
159 WinEnableInt3=0;
160 #else
161 WinEnableInt3=1;
162 #endif
163
164 #ifndef NDEBUG
165 if (FindArg("-logfile")) loginit("descentw.log");
166 #endif
167
168 ValidateSystem();
169
170 if (!hPrev) {
171 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
172 wc.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(D2_ICON));
173 wc.lpszMenuName = NULL;
174 wc.lpszClassName = "DescentWndClass";
175 wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
176 wc.hInstance = hInst;
177 wc.style = CS_DBLCLKS;
178 wc.lpfnWndProc = (WNDPROC)DescentWndProc;
179 wc.cbWndExtra = 0;
180 wc.cbClsExtra = 0;
181
182 if (!RegisterClass(&wc)) return FALSE;
183 }
184
185 // Arrgh, make entire code segment writable for now.
186 // -codereadonly forces read only code (debug purposes)
187
188 if (!FindArg("-codereadonly"))
189 MakeCodeWritable();
190
191 #ifndef RELEASE
192 cinit();
193 #endif
194
195 atexit(AppExit);
196
197 _hAppInstance = hInst;
198 _hAppWnd = CreateWindowEx(WS_EX_APPWINDOW,
199 "DescentWndClass",
200 WINAPP_NAME,
201 WS_POPUP | WS_SYSMENU | WS_BORDER,
202 0, 0,
203 GetSystemMetrics(SM_CXSCREEN),
204 GetSystemMetrics(SM_CYSCREEN),
205 NULL,
206 NULL,
207 hInst,
208 NULL);
209
210 Assert(_hAppWnd != 0);
211
212 ShowWindow(_hAppWnd, SW_SHOWNORMAL);
213 UpdateWindow(_hAppWnd);
214
215 // Tell Descent Libraries about Windows
216 HideCursorW();
217 // LoadCursorWin(MOUSE_WAIT_CURSOR);
218 // ShowCursorW();
219
220 #ifdef RELEASE
221 #ifndef NDEBUG
222 if (FindArg("-monodebug")) Mono_initialized = 1;
223 else // link to below line!
224 #endif
225 Mono_initialized = 0;
226 #else
227 Mono_initialized = 1;
228 #endif
229
230 minit();
231
232 SetLibraryWinInfo(_hAppWnd, _hAppInstance);
233
234 #ifndef NDEBUG
235 mopen( 0, 9, 1, 78, 15, "Debug Spew");
236 mopen( 1, 2, 1, 78, 5, "Errors & Serious Warnings");
237 #endif
238
239 return TRUE;
240 }
241
242
AppExit()243 void AppExit()
244 {
245 // HACK do this when the application is closing! restore the CD audio volume.
246 if (CD_audio_desktop_dev != -1)
247 auxSetVolume(CD_audio_desktop_dev, CD_audio_desktop_vol);
248
249 grwin_cleanup_palette();
250
251 LoadCursorWin(MOUSE_DEFAULT_CURSOR);
252 ShowCursorW();
253
254 #ifndef RELEASE
255 if (WinErrorTrap) {
256 cprintf("\n\n%s", WinErrorMessage);
257 cgetch();
258 }
259 else {
260 CloseWindow(_hAppWnd);
261 cprintf("\n\nDescent II for Win95 done...\n");
262 cgetch();
263 }
264 cclose();
265 #else
266 if (WinErrorTrap)
267 MessageBox(NULL, WinErrorMessage, "Descent II error", MB_OK);
268 #endif
269
270 #ifndef NDEBUG
271 logclose();
272 #endif
273
274 if (hDescent2Mutex2)
275 CloseHandle(hDescent2Mutex2);
276
277 if (hDescent2Mutex)
278 CloseHandle(hDescent2Mutex); // Destroy Mutex Object!
279 }
280
281 extern char CDROM_dir[30];
282
DoRegisterCheck()283 void DoRegisterCheck()
284 {
285 STARTUPINFO si;
286 PROCESS_INFORMATION pi;
287 BOOL flag;
288 char filename[64];
289
290 strcpy(filename, CDROM_dir);
291 strcat(filename, "regcard.exe");
292
293 memset(&si, 0, sizeof(si));
294 si.cb = sizeof(si);
295 si.dwFlags = STARTF_USESHOWWINDOW;
296 si.wShowWindow = SW_SHOW;
297
298 flag = CreateProcess(
299 NULL,
300 filename, NULL, NULL,
301 FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL,
302 &si, &pi);
303 if (flag) {
304 DWORD dwval;
305 dwval = WaitForInputIdle(pi.hProcess, INFINITE);
306
307 while (WaitForSingleObject(pi.hProcess, 0) != WAIT_OBJECT_0)
308 {
309 }
310
311 mprintf((1, "JOY.CPL process finished?\n"));
312 ShowWindow(_hAppWnd, SW_MAXIMIZE);
313 SetForegroundWindow(_hAppWnd);
314 }
315 }
316
317
318 // Game -----------------------------------------------------------------------
319
320 char commandline_help[] =
321 "Command-line options (case is not significant):\n"
322 "\n"
323 " General Options:\n"
324 "\n"
325 " -LowMem Lower animation detail for better performance with low memory\n"
326 " -NoLowMem Force high animation detail even when low memory\n"
327 " -Subtitles Turn on movie subtitles (English-only)\n"
328 "\n"
329 " Input devices: -SpecialDevice\n"
330 "\n"
331 " -IForce <n> Use Immersion tactile feedback joystick on port <n>\n"
332 "\n"
333 " Sound & Music:\n"
334 "\n"
335 " -NoSound Turns off sound & music\n"
336 " -NoMusic Disables music; sound effects remain enabled\n"
337 " -Sound22K Use 22KHz sounds, even if machine has less than 16 MB\n"
338 " -Sound11K Use 11KHz sounds, even if machine has more than 16 MB\n"
339 "\n"
340 " Network & Modem:\n"
341 "\n"
342 " -CtsRts Enables CTS/RTS handshaking during null-modem games\n"
343 " -NoNetwork Disables network drivers\n"
344 " -NoSerial Disables serial drivers\n"
345 " -Packets # Specifies the packets per second where # is the number of packets\n"
346 " -Shortpackets Turn on short packets\n"
347 " -Norankings Disable multiplayer ranking system\n"
348 " -Noredunancy suppresses duplicate messages such as \"You already have ....\"\n"
349 "\n"
350 "Diagnostic:\n"
351 " -emul Certain video cards need this option in order to run game.\n"
352 " -ddemul If -emul doesn't work, use this option.\n";
353
print_commandline_help()354 print_commandline_help()
355 {
356 ShowCursorW();
357 MessageBox(NULL, commandline_help, "Descent II Command-line Options", MB_OK);
358 }
359
RunGame(int argc,char * argv[])360 int RunGame(int argc, char *argv[])
361 {
362 MSG msg;
363 int val;
364
365 setbuf(stdout, NULL);
366 error_init(WErrorCatch, NULL);
367
368 #ifndef RELEASE
369 if (FindArg("-stopwatch"))
370 timer_init(1);
371 else
372 timer_init(0);
373 #else
374 timer_init(0);
375 #endif
376
377 // InitArgs(argc, argv);
378
379 InitCD(argv[0]);
380
381 #ifdef RELEASE
382 DoRegisterCheck();
383 #endif
384
385 InitVideo();
386 InitIO();
387 InitData();
388 InitSound();
389
390 if (!FindArg("-nonetwork"))
391 InitNetwork();
392
393 if (!FindArg("-noserial"))
394 serial_active = 1;
395
396 AllowActivates = TRUE;
397
398 InitDescent();
399
400 InitPilot();
401
402 if (Auto_demo) {
403 newdemo_start_playback("DESCENT.DEM");
404 if (Newdemo_state == ND_STATE_PLAYBACK )
405 Function_mode = FMODE_GAME;
406 }
407
408 // do this here because the demo code can do a longjmp when trying to
409 // autostart a demo from the main menu, never having gone into the game
410 setjmp(LeaveGame);
411
412 while (Function_mode != FMODE_EXIT)
413 {
414 val = DoMessageStuff(&msg);
415
416 DDGRRESTORE;
417
418 switch (Function_mode)
419 {
420 case FMODE_MENU:
421 {
422 set_screen_mode(SCREEN_MENU);
423 if (Auto_demo) {
424 DEFINE_SCREEN(NULL);
425 newdemo_start_playback(NULL);
426 if (Newdemo_state != ND_STATE_PLAYBACK)
427 Error("No demo files were found for autodemo mode!");
428 }
429 else {
430 DEFINE_SCREEN(Menu_pcx_name);
431 mprintf((1, "%s\n", Menu_pcx_name));
432 gr_palette_clear();
433 DoMenu();
434 }
435 break;
436 }
437 case FMODE_GAME:
438 {
439 HideCursorW();
440 DEFINE_SCREEN(NULL);
441 game();
442 digi_reset();
443 digi_reset();
444 if ( Function_mode == FMODE_MENU )
445 songs_play_song( SONG_TITLE, 1 );
446 mprintf((0, "Function mode = %d\n", Function_mode));
447 }
448 }
449
450 }
451
452 dd_gr_set_current_canvas(NULL);
453 dd_gr_clear_canvas(BM_XRGB(0,0,0));
454
455 WriteConfigFile();
456
457 return msg.wParam;
458 }
459
460
461 // Window Message Functions
462 // ----------------------------------------------------------------------------
463
AppPaint(HWND hWnd,HDC hdc)464 void AppPaint(HWND hWnd, HDC hdc)
465 {
466 // grwin_gdi_realizepal(hdc);
467 }
468
469
AppSize(HWND hWnd)470 void AppSize(HWND hWnd)
471 {
472 if (IsIconic(hWnd)) {
473 _AppPaused = TRUE;
474 InvalidateRect(hWnd, NULL, TRUE);
475 }
476 else if (GetForegroundWindow() == hWnd) {
477 _AppPaused = FALSE;
478 }
479
480 DDResizeViewport();
481 mprintf((0, "Resized window (%d,%d,%d,%d).\n", ViewportRect.left, ViewportRect.top, ViewportRect.right, ViewportRect.bottom));
482 }
483
484
AppActivate(HWND hWnd,UINT wParam)485 void AppActivate(HWND hWnd, UINT wParam)
486 {
487 _AppActive = (BOOL)(wParam) && GetForegroundWindow()==hWnd && !IsIconic(hWnd);
488
489 if (_AppActive) {
490 mprintf((0, "Descent II is gaining Window focus.\n"));
491 cprintf("Descent II is gaining Window focus.\n");
492 }
493 else {
494 mprintf((0, "Descent II is losing Window focus.\n"));
495 cprintf("Descent II is losing Window focus.\n");
496 }
497
498 // Must now unpause if paused and app is active now.
499 mprintf((0, "AppActivate: Active: %d, Paused: %d\n", _AppActive, _AppPaused));
500
501 if (_AppActive && AllowActivates && !_AppPaused)
502 {
503 D2Restore();
504 }
505 else if (AllowActivates) {
506 D2Shutdown();
507 }
508
509 }
510
511
AppQueryPalette(HWND hWnd)512 void AppQueryPalette(HWND hWnd)
513 {
514 // if (!_DDFullScreen && _lpDDPalette && _lpDDSPrimary) {
515 // gr_palette_load(gr_palette);
516 // }
517 mprintf((0, "QUERY PALETTE!\n"));
518 }
519
520
AppCreate(HWND hWnd)521 void AppCreate(HWND hWnd)
522 {
523 HMENU hMenu;
524
525 // Remove system menu components not good
526 hMenu = GetSystemMenu(hWnd, FALSE);
527
528 RemoveMenu(hMenu, SC_SIZE, MF_BYCOMMAND);
529 RemoveMenu(hMenu, SC_MOVE, MF_BYCOMMAND);
530 }
531
532
AppPaletteChange(HWND hWnd,UINT wParam)533 void AppPaletteChange(HWND hWnd, UINT wParam)
534 {
535 if ((HWND)wParam != hWnd) {
536 if (!_DDFullScreen) {
537 mprintf((0, "Palette changed!\n"));
538 _AppPaused = TRUE;
539 mprintf((0, "Descent 2 is paused.\n"));
540 }
541 }
542 }
543
544 //static LPDIRECTDRAWSURFACE Page0Buffer = 0;
545
AppDisplayChange(HWND hWnd,int w,int h,int bpp)546 void AppDisplayChange(HWND hWnd, int w, int h, int bpp)
547 {
548 // mprintf((0, "Windows feels a display change coming...\n"));
549 }
550
551
AppHandleSystemKeys(UINT msg,UINT wParam,UINT lParam)552 BOOL AppHandleSystemKeys(UINT msg, UINT wParam, UINT lParam)
553 {
554 // Intercept ALT keystrokes
555
556 if (msg == WM_SYSKEYUP) {
557 mprintf((0,"ALT key down!"));
558 }
559
560 send_key_msg(msg, wParam, lParam);
561
562 if (wParam == VK_TAB || wParam == VK_ESCAPE) return FALSE;
563
564 return TRUE;
565 }
566
567
RestoreGameSurfaces()568 int RestoreGameSurfaces()
569 {
570 if (dd_VR_offscreen_buffer) {
571 if (!dd_VR_offscreen_buffer->lpdds) return 1;
572 if (IDirectDrawSurface_Restore(dd_VR_offscreen_buffer->lpdds) != DD_OK) {
573 mprintf((1, "Warning: Unable to restore dd_VR_offscreen_buffer!\n"));
574 return 0;
575 }
576 mprintf((0, "Restored dd_VR_offscreen_buffer\n"));
577 }
578
579 return 1;
580 }
581
582
DescentWndProc(HWND hWnd,UINT msg,UINT wParam,LPARAM lParam)583 LRESULT WINAPI _export DescentWndProc(HWND hWnd,
584 UINT msg,
585 UINT wParam,
586 LPARAM lParam)
587 {
588 //HANDLE h;
589 //static int nTimer = 0;
590
591 switch (msg)
592 {
593 case WM_CREATE:
594 AppCreate(hWnd);
595 return 0;
596
597 case WM_SYSCOMMAND:
598 if((wParam&0xFFF0)==SC_SCREENSAVE || (wParam&0xFFF0)==SC_MONITORPOWER)
599 return 0;
600
601 if ((wParam&0xfff0)== SC_KEYMENU && _AppActive) {
602 mprintf((0, "W32: Bypassing system menu.\n"));
603 return 0;
604 }
605 break;
606
607 case WM_SIZE:
608 case WM_MOVE:
609 AppSize(hWnd);
610 return 0;
611
612 case WM_ACTIVATEAPP: // Application is losing focus.
613 AppActivate(hWnd, wParam);
614 return 0;
615
616 case WM_QUERYNEWPALETTE:
617 AppQueryPalette(hWnd);
618 break;
619
620 case WM_PALETTECHANGED:
621 AppPaletteChange(hWnd, wParam);
622 break;
623
624 case WM_DISPLAYCHANGE: // Screen Mode is changing.
625 AppDisplayChange(hWnd, LOWORD(lParam), HIWORD(lParam), wParam);
626 break;
627
628 case WM_SYSKEYUP:
629 case WM_SYSKEYDOWN:
630 if (AppHandleSystemKeys(msg, wParam,lParam))
631 return 0;
632 break;
633
634 case WM_KEYDOWN:
635 case WM_KEYUP:
636 if (wParam == VK_SNAPSHOT) {
637 mprintf((0, "Capture screen begins...\n"));
638 save_screen_shot(0);
639 if (!clipboard_screenshot())
640 mprintf((1, "Failed to create clipboard screenshot!\n"));
641 }
642 // #ifndef NDEBUG
643 // if (msg == WM_KEYDOWN && wParam == 0x49) ipx_debug_hold_packets = 1;
644 // if (msg == WM_KEYUP && wParam == 0x49) ipx_debug_hold_packets = 0;
645 // #endif
646 send_key_msg(msg, wParam, lParam);
647 break;
648
649 case WM_PAINT:
650 // hdc = BeginPaint(hWnd, &ps);
651 // AppPaint(hWnd, hdc);
652 // EndPaint(hWnd, &ps);
653 // return 0;
654 break;
655
656 case MM_JOY1MOVE:
657 case MM_JOY1BUTTONDOWN:
658 case MM_JOY1BUTTONUP:
659 if (!_AppPaused && (_AppActive || !_DDFullScreen)) {
660 joy_handler_win(hWnd, msg, wParam, lParam);
661 }
662 break;
663
664 case WM_DESTROY:
665 mprintf((0, "Killing main window...\n"));
666 PostQuitMessage(0);
667 break;
668 }
669
670 // digi_midi_debug();
671 mouse_win_callback(msg, wParam, lParam);
672
673 return DefWindowProc(hWnd, msg, wParam, lParam);
674 }
675
676
677 static char *WinArgs[64];
678
679 // Main Program
680 // ----------------------------------------------------------------------------
681
WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR szCmdLine,int nCmdShow)682 int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine,
683 int nCmdShow)
684 {
685 int retval = 1;
686 int argc;
687
688
689 argc = ParseArgs(WinArgs, szCmdLine);
690 InitArgs(argc, WinArgs);
691
692 if (FindArg( "-?" ) || FindArg( "-help" ) || FindArg( "?" ) ) {
693 print_commandline_help();
694 set_exit_message("");
695 return(0);
696 }
697
698 if (AppInit(hInst, hPrev, szCmdLine, nCmdShow)) {
699 retval = RunGame(argc, WinArgs);
700 }
701
702 return retval;
703 }
704
705
706
707 // Low Level Routines
708 // ----------------------------------------------------------------------------
709
710 static char *NoMovieArg = "-nomovies";
711 static char *PathArg = "descentw.exe";
712
ParseArgs(char * argv[],LPSTR lpCmdLine)713 int ParseArgs(char *argv[], LPSTR lpCmdLine)
714 {
715 int argc;
716 int i;
717
718 argc = 0;
719 i = 0;
720
721 argv[argc++] = PathArg;
722
723 // while (lpCmdLine[i] == '-' || lpCmdLine[i] == '/' )
724
725 while (lpCmdLine[i])
726 {
727 if (lpCmdLine[i] == ' ') i++;
728 else {
729 argv[argc++] = &lpCmdLine[i];
730
731 while (lpCmdLine[i]!=' ' && lpCmdLine[i]!= 0) {
732 //mprintf((0, "%c", lpCmdLine[i]));
733 i++;
734 }
735 lpCmdLine[i++] = 0;
736 // mprintf((0, "Argument %s.\n", argv[argc-1]));
737 }
738 }
739
740 if (!WinEnableMovies)
741 argv[argc++] = NoMovieArg;
742
743 return argc;
744 }
745
746
747 extern void rls_stretch_scanline_asm();
748
749
MakeCodeWritable(void)750 void MakeCodeWritable(void)
751 {
752 typedef DWORD __stdcall translator(DWORD);
753
754 HMODULE modCode;
755 BYTE *pImageBase = 0;
756 DWORD version;
757
758 modCode = GetModuleHandle(0);
759 version = GetVersion();
760
761 // For Win32s we have to use undocumented features
762 if ((version < 0x80000000) || ((BYTE)version >=0x04)) {
763 // Win NT, Win95.
764 pImageBase = (BYTE *)modCode;
765 }
766 else {
767 MessageBox(NULL, "Descent II cannot run under Windows 3.x", "Descent II", MB_OK);
768 exit(1);
769
770 }
771
772 if (pImageBase) {
773 DWORD oldRights;
774 //char buf[256];
775 IMAGE_OPTIONAL_HEADER *pHeader =
776 (IMAGE_OPTIONAL_HEADER *)(pImageBase + ((IMAGE_DOS_HEADER *)pImageBase)->e_lfanew +
777 sizeof(IMAGE_NT_SIGNATURE) + sizeof(IMAGE_FILE_HEADER));
778
779 //@@ if (!VirtualProtect(pImageBase+pHeader->BaseOfCode, pHeader->SizeOfCode,
780 //@@ PAGE_READWRITE, &oldRights)) {
781 //@@ exit(1);
782 //@@ }
783
784 if (!VirtualProtect(rls_stretch_scanline_asm, 4096*2, PAGE_READWRITE, &oldRights)) {
785 MessageBox(NULL, "Unable to gain write access to requested page.", "Descent II Error", MB_OK);
786 exit(1);
787 }
788
789 // wsprintf(buf, "Start:%x FN1:%x",(DWORD)pImageBase+pHeader->BaseOfCode, (DWORD)rls_stretch_scanline_asm);
790 // MessageBox(NULL, buf, "Info", MB_OK);
791 }
792 }
793
794
ValidateSystem()795 void ValidateSystem()
796 {
797 DWORD version;
798
799 version = GetVersion();
800
801 if ((version < 0x80000000) || ((BYTE)version >=0x04)) {
802 if ((version < 0x80000000) && ((BYTE)version >= 0x04)) {
803 Platform_system = WINNT_PLATFORM;
804 DD_Emulation = 1;
805 }
806 else Platform_system = WIN95_PLATFORM;
807 }
808 else {
809 MessageBox(NULL, "Descent II will not run under Windows 3.x", "DESCENT II", MB_OK);
810 exit(1);
811 }
812
813 // Do the named mutex thingy.
814 {
815 HANDLE hMutex, hMutex2;
816
817 hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "BigRedStinksMutex");
818 if (hMutex) {
819 hMutex2 = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "BigRedSucksMutex");
820 if (hMutex2) {
821 CloseHandle(hMutex2);
822 exit(1); // Don't even tell user he's trying to run a third copy
823 }
824
825 hDescent2Mutex2 = CreateMutex(NULL, FALSE, "BigRedSucksMutex");
826 if (!hDescent2Mutex2) {
827 MessageBox(NULL, "Unable to create second mutex object.", "Descent II error", MB_OK);
828 exit(1);
829 }
830 MessageBox(NULL, "You may only run one instance of Descent II at a time.",
831 "Descent II error", MB_OK);
832 CloseHandle(hMutex);
833 exit(1);
834 }
835 hDescent2Mutex = CreateMutex(NULL, FALSE, "BigRedStinksMutex");
836 if (!hDescent2Mutex) {
837 MessageBox(NULL, "Unable to create mutex object.", "Descent II error", MB_OK);
838 exit(1);
839 }
840 }
841 // Do the Version ID thing for Beta testers
842 #if defined(RELEASE) && defined(VERSION_NAME) && !defined(NDEBUG)
843 {
844 char buf[256];
845
846 sprintf(buf, "Descent II %s v%d.%d\n%s\n%s %s", VERSION_TYPE, Version_major, Version_minor,
847 VERSION_NAME, __DATE__, __TIME__);
848 MessageBox(NULL, buf, "Descent II beta information", MB_OK);
849 }
850 #endif
851
852 // Super memory check
853 {
854 MEMORYSTATUS memstat;
855 int mem_free;
856
857 memset(&memstat, 0, sizeof(memstat));
858 memstat.dwLength = sizeof(memstat);
859 GlobalMemoryStatus(&memstat);
860
861 logentry("Memory: \n");
862 logentry(" MemoryLoad = %10d\n",memstat.dwMemoryLoad);
863 logentry(" TotalPhys = %10d\n",memstat.dwTotalPhys);
864 logentry(" AvailPhys = %10d\n",memstat.dwAvailPhys);
865 logentry(" TotalPageFile = %10d\n",memstat.dwTotalPageFile);
866 logentry(" AvailPageFile = %10d\n",memstat.dwAvailPageFile);
867 logentry(" TotalVirtual = %10d\n",memstat.dwTotalVirtual);
868 logentry(" AvailVirtual = %10d\n",memstat.dwAvailVirtual);
869
870 mem_free = memstat.dwTotalPhys;
871 // mem_free=100;
872 // logentry(" mem_free = %10d\n",mem_free);
873
874 if ( mem_free < MIN_PHYSICAL_MEM_FREE) {
875 logentry("Using low memory option.\n");
876 piggy_low_memory = 1;
877 }
878
879 if ( memstat.dwAvailPageFile < MIN_VIRTUAL_MEM_FREE) {
880 MessageBox(NULL, "Not enough virtual memory.\n You need at least 16MB of free drive space.\n",
881 "Descent II Error", MB_OK);
882 exit(1);
883 }
884
885 if ( ((mem_free > SOUND_22K_CUTOFF) || FindArg("-sound22k")) && !FindArg("-sound11k") && !FindArg("-lowmem") ) {
886 logentry("Using 22KHz sounds\n");
887 digi_sample_rate = SAMPLE_RATE_22K;
888 } else {
889 logentry("Using 11KHz sounds\n");
890 digi_sample_rate = SAMPLE_RATE_11K;
891 }
892 }
893 }
894
895
DoMessageStuff(MSG * msg)896 int DoMessageStuff(MSG *msg)
897 {
898
899 while(1)
900 {
901 if (PeekMessage(msg, NULL, 0, 0, PM_REMOVE)) {
902 if (msg->message == WM_QUIT) {
903 WriteConfigFile();
904 exit(0);
905 }
906
907 TranslateMessage(msg);
908 DispatchMessage(msg);
909 }
910 else if (!_AppPaused && (_AppActive || !_DDFullScreen)) {
911 break;
912 } else {
913
914 if ((Game_mode & GM_MULTI)) {
915 if (Control_center_destroyed) {
916 ShowWindow(_hAppWnd, SW_MAXIMIZE);
917 WinDelayIdle();
918 SetForegroundWindow(_hAppWnd);
919 WinDelayIdle();
920 _RedrawScreen = TRUE;
921 }
922 else if (multi_menu_poll() == -1) {
923 ShowWindow(_hAppWnd, SW_MAXIMIZE);
924 WinDelayIdle();
925
926 if (GetForegroundWindow() == _hAppWnd) {
927 if (_AppPaused || !_AppActive) {
928 mprintf((0, "Descent2 Daemon...Pause: %d, Active %d\n",_AppPaused, _AppActive));
929 SetActiveWindow(_hAppWnd);
930 _RedrawScreen = FALSE;
931 break;
932 }
933 }
934 else {
935 SetForegroundWindow(_hAppWnd);
936 WinDelayIdle();
937 _RedrawScreen = FALSE;
938 }
939 }
940 }
941 else {
942 mprintf((0, "Waiting...Pause: %d, Active %d\n",_AppPaused, _AppActive));
943 WaitMessage();
944 }
945 }
946 }
947
948
949 return MSG_NORMAL;
950 }
951
952
WinDelayIdle()953 void WinDelayIdle()
954 {
955 MSG msg;
956
957 mprintf((0, "Entering Idle message loop...\n"));
958
959 while (1)
960 {
961 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
962 if (msg.message == WM_QUIT) {
963 WriteConfigFile();
964 exit(0);
965 }
966
967 mprintf((0, "Retreiving message(0x%x:0x%x,0x%x) in idle loop.\n",msg.message, msg.wParam, msg.lParam));
968
969 TranslateMessage(&msg);
970 DispatchMessage(&msg);
971
972 }
973 else break;
974 }
975 }
976
977
WinDelay(int msecs)978 void WinDelay(int msecs)
979 {
980 int timeout;
981 MSG msg;
982
983
984 timeout = timeGetTime() + msecs;
985
986 while (timeout > timeGetTime())
987 {
988 DoMessageStuff(&msg);
989 if (msg.message == WM_QUIT) exit(0);
990 }
991 }
992
993
WErrorCatch(char * message)994 void WErrorCatch(char *message)
995 {
996 mprintf((1, "Bye Bye: %s\n", message));
997
998 strcpy(WinErrorMessage, message);
999
1000 WinErrorTrap = 1;
1001
1002 logentry("%s", WinErrorMessage);
1003 CloseWindow(_hAppWnd);
1004 }
1005
1006
1007 //static BOOL CursorVisible = TRUE;
1008 static HANDLE CursorHandle = NULL;
1009
1010
LoadCursorWin(int cursor)1011 void LoadCursorWin(int cursor)
1012 {
1013 switch (cursor)
1014 {
1015 case MOUSE_DEFAULT_CURSOR:
1016 CursorHandle = LoadCursor(NULL, IDC_ARROW);
1017 break;
1018
1019 case MOUSE_WAIT_CURSOR:
1020 CursorHandle = LoadCursor(NULL, IDC_WAIT);
1021 break;
1022
1023 default:
1024 CursorHandle = NULL;
1025 }
1026
1027 SetCursor(CursorHandle);
1028 }
1029
1030
HideCursorW()1031 void HideCursorW()
1032 {
1033 while (ShowCursor(FALSE) >=0);
1034 }
1035
1036
ShowCursorW()1037 void ShowCursorW()
1038 {
1039 if (DD_Emulation) return;
1040
1041 if (CursorHandle == NULL)
1042 LoadCursorWin(MOUSE_DEFAULT_CURSOR);
1043
1044 while (ShowCursor(TRUE) < 0);
1045 }
1046
1047
1048
1049 // Descent 2 Shutdown and Restore functions
1050 // ----------------------------------------------------------------------------
1051
1052 void SaveVideoState();
1053 void RestoreVideoState();
1054
1055 static int Saved_Game_window_w;
1056 static int Saved_Game_window_h;
1057 static int SavedScreenMode = 0;
1058
1059 extern int Digi_initialized;
1060 extern int Current_display_mode;
1061 extern BOOL WMVEPlaying, RMVEPlaying;
1062 extern int current_song_level;
1063
1064
RestoreScreenContext()1065 void RestoreScreenContext()
1066 {
1067 if ( _SCRContext.bkg_filename != NULL ) {
1068 mprintf((0, "Loading background file...\n"));
1069 nm_draw_background1( _SCRContext.bkg_filename );
1070 }
1071 gr_palette_load(gr_palette);
1072 }
1073
1074
D2Shutdown()1075 void D2Shutdown()
1076 {
1077 if (GameShutdown) return;
1078
1079 _AppPaused = TRUE;
1080
1081 if (!Joystick_calibrating) joy_stop_poll();
1082
1083 key_flush();
1084
1085 SaveVideoState();
1086
1087 songs_stop_all();
1088
1089 if (CD_audio_desktop_dev != -1)
1090 auxSetVolume(CD_audio_desktop_dev, CD_audio_desktop_vol);
1091
1092 if (Function_mode == FMODE_GAME && !(Game_mode &GM_MULTI)) {
1093 stop_time();
1094 }
1095
1096 mprintf((0, "WMVE: %d, RMVE: %d\n", WMVEPlaying, RMVEPlaying));
1097
1098 if (WMVEPlaying) MovieShutdown();
1099 if (RMVEPlaying) MVE_rmHoldMovie();
1100
1101 if (!WMVEPlaying) digi_reset();
1102
1103 mprintf((0, "Descent 2 is asleep...\n"));
1104
1105 GameShutdown = TRUE;
1106 }
1107
1108
D2Restore()1109 void D2Restore()
1110 {
1111 if (!GameShutdown) return;
1112
1113 if (!WMVEPlaying) digi_reset();
1114 if (WMVEPlaying) {
1115 MovieRestore();
1116 key_flush();
1117 if (CD_audio_desktop_dev != -1)
1118 auxGetVolume(CD_audio_desktop_dev, &CD_audio_desktop_vol);
1119 _AppPaused = FALSE;
1120 goto EndD2Restore;
1121 }
1122 else if (RMVEPlaying) {
1123 key_flush();
1124 // if (_lpDD) RestoreVideoState();
1125 dd_gr_init_screen();
1126 W95DisplayMode = -1;
1127
1128 if (SavedScreenMode != -1)
1129 set_screen_mode(SavedScreenMode);
1130
1131 if (CD_audio_desktop_dev != -1)
1132 auxGetVolume(CD_audio_desktop_dev, &CD_audio_desktop_vol);
1133 MVE_rmHoldMovie();
1134 _RedrawScreen = TRUE;
1135 _AppPaused = FALSE;
1136 goto EndD2Restore;
1137 }
1138 else {
1139 if (_lpDD) RestoreVideoState();
1140
1141 if (CD_audio_desktop_dev != -1)
1142 auxGetVolume(CD_audio_desktop_dev, &CD_audio_desktop_vol);
1143
1144 if (Function_mode == FMODE_MENU) songs_play_song(SONG_TITLE, 1);
1145 if (Function_mode == FMODE_GAME) {
1146 songs_play_level_song(current_song_level);
1147 }
1148 key_flush();
1149 _AppPaused = FALSE;
1150
1151 }
1152
1153 if (Function_mode == FMODE_GAME && !(Game_mode & GM_MULTI)) start_time();
1154 else if (Function_mode == FMODE_MENU)
1155 keyd_time_when_last_pressed = timer_get_fixed_seconds();
1156
1157 EndD2Restore:
1158 if (!Joystick_calibrating) joy_start_poll();
1159 set_redbook_volume(Config_redbook_volume);
1160 mprintf((0, "...Descent 2 is awake!\n"));
1161
1162 GameShutdown = FALSE;
1163 }
1164
1165
SaveVideoState()1166 void SaveVideoState()
1167 {
1168 // If in game mode, then restore window size
1169 if (Screen_mode == SCREEN_GAME) {
1170 Saved_Game_window_w = Game_window_w;
1171 Saved_Game_window_h = Game_window_h;
1172
1173 }
1174
1175 SavedScreenMode = Screen_mode;
1176 Screen_mode = -1;
1177 }
1178
1179
RestoreVideoState()1180 void RestoreVideoState()
1181 {
1182 // Just reinitialize screen state.
1183 dd_gr_init_screen();
1184 W95DisplayMode = -1;
1185
1186
1187 // If in game mode, then restore window size
1188 if (SavedScreenMode != -1)
1189 set_screen_mode(SavedScreenMode);
1190
1191 if (SavedScreenMode == SCREEN_GAME) {
1192 Game_window_w = Saved_Game_window_w;
1193 Game_window_h = Saved_Game_window_h;
1194 init_cockpit();
1195 }
1196 if (Function_mode == FMODE_GAME) {
1197 load_palette(Current_level_palette,1,1);
1198 }
1199
1200 _RedrawScreen = TRUE;
1201 RestoreScreenContext();
1202 }
1203
1204
1205