Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
/*
2
 * Portions of this file are copyright Rebirth contributors and licensed as
3
 * described in COPYING.txt.
4
 * Portions of this file are copyright Parallax Software and licensed
5
 * according to the Parallax license below.
6
 * See COPYING.txt for license details.
7
 
8
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
9
SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
10
END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
11
ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
12
IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
13
SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
14
FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
15
CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
16
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
17
COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
18
*/
19
 
20
/*
21
 *
22
 * inferno.c: Entry point of program (main procedure)
23
 *
24
 * After main initializes everything, most of the time is spent in the loop
25
 * while (window_get_front())
26
 * In this loop, the main menu is brought up first.
27
 *
28
 * main() for Inferno
29
 *
30
 */
31
 
32
extern const char copyright[];
33
 
34
const
35
#if defined(DXX_BUILD_DESCENT_I)
36
char copyright[] = "DESCENT   COPYRIGHT (C) 1994,1995 PARALLAX SOFTWARE CORPORATION";
37
#elif defined(DXX_BUILD_DESCENT_II)
38
char copyright[] = "DESCENT II  COPYRIGHT (C) 1994-1996 PARALLAX SOFTWARE CORPORATION";
39
#endif
40
 
41
#include "dxxsconf.h"
42
//#include <stdio.h>
43
//#include <stdlib.h>
44
//#include <string.h>
45
//#include <limits.h>
46
#include <SDL.h>
47
 
48
#ifdef __unix__
49
#include <unistd.h>
50
#include <sys/stat.h>
51
#include <sys/types.h>
52
#endif
53
 
54
#include <cctype>
55
#include <locale>
56
#include "pstypes.h"
57
#include "strutil.h"
58
#include "console.h"
59
#include "gr.h"
60
#include "key.h"
61
#include "3d.h"
62
#include "bm.h"
63
#include "inferno.h"
64
#include "dxxerror.h"
65
#include "player.h"
66
#include "game.h"
67
#include "u_mem.h"
68
#include "screens.h"
69
#include "texmap.h"
70
#include "texmerge.h"
71
#include "menu.h"
72
#include "digi.h"
73
#include "palette.h"
74
#include "args.h"
75
#include "titles.h"
76
#include "text.h"
77
#include "gauges.h"
78
#include "gamefont.h"
79
#include "kconfig.h"
80
#include "newmenu.h"
81
#include "config.h"
82
#include "multi.h"
83
#include "songs.h"
84
#include "gameseq.h"
85
#if defined(DXX_BUILD_DESCENT_II)
86
#include "gamepal.h"
87
#include "movie.h"
88
#endif
89
#include "playsave.h"
90
#include "collide.h"
91
#include "newdemo.h"
92
#include "joy.h"
93
#if !DXX_USE_OGL
94
#include "../texmap/scanline.h" //for select_tmap -MM
95
#endif
96
#include "event.h"
97
#include "rbaudio.h"
98
#if DXX_WORDS_NEED_ALIGNMENT
99
#include <sys/prctl.h>
100
#endif
101
#if DXX_USE_EDITOR
102
#include "messagebox.h"
103
#include "editor/editor.h"
104
#include "editor/kdefs.h"
105
#include "ui.h"
106
#endif
107
#include "vers_id.h"
108
#if DXX_USE_UDP
109
#include "net_udp.h"
110
#endif
111
#include "dsx-ns.h"
112
 
113
#if DXX_USE_SDLIMAGE
114
#include <SDL_image.h>
115
#endif
116
#if DXX_USE_SDLMIXER
117
#include <SDL_mixer.h>
118
#endif
119
 
120
namespace dsx {
121
 
122
int Screen_mode=-1;                                     //game screen or editor screen?
123
 
124
#if defined(DXX_BUILD_DESCENT_I)
125
int HiresGFXAvailable = 0;
126
int MacHog = 0; // using a Mac hogfile?
127
#endif
128
 
129
//read help from a file & print to screen
130
static void print_commandline_help()
131
{
132
#define DXX_COMMAND_LINE_HELP_FMT(FMT,...)      FMT
133
#define DXX_COMMAND_LINE_HELP_ARG(FMT,...)      , ## __VA_ARGS__
134
 
135
#define DXX_if_defined_placeholder1     ,
136
#define DXX_if_defined_unwrap(A,...)    A, ## __VA_ARGS__
137
#define DXX_if_defined(V,F)     DXX_if_defined2(V,F)
138
#define DXX_if_defined2(V,F)    DXX_if_defined3(DXX_if_defined_placeholder##V, F)
139
#define DXX_if_defined3(V,F)    DXX_if_defined4(F, V 1, 0)
140
#define DXX_if_defined4(F,_,V,...)      DXX_if_defined5_##V(F)
141
#define DXX_if_defined5_0(F)
142
#define DXX_if_defined5_1(F)    DXX_if_defined_unwrap F
143
#define DXX_if_defined_01(V,F)  DXX_if_defined4(F,,V)
144
 
145
#define DXX_COMMAND_LINE_HELP_unix(V)   DXX_if_defined(__unix__, (V))
146
#define DXX_COMMAND_LINE_HELP_D1(V)     DXX_if_defined(DXX_BUILD_DESCENT_I, (V))
147
#define DXX_COMMAND_LINE_HELP_D2(V)     DXX_if_defined(DXX_BUILD_DESCENT_II, (V))
148
#define DXX_STRINGIZE2(X)       #X
149
#define DXX_STRINGIZE(X)        DXX_STRINGIZE2(X)
150
 
151
#if DXX_USE_OGL
152
#define DXX_COMMAND_LINE_HELP_OGL(V)    V
153
#define DXX_COMMAND_LINE_HELP_SDL(V)
154
#else
155
#define DXX_COMMAND_LINE_HELP_OGL(V)
156
#define DXX_COMMAND_LINE_HELP_SDL(V)    V
157
#endif
158
 
159
#define DXX_COMMAND_LINE_HELP(VERB)     \
160
        VERB("\n System Options:\n\n")  \
161
        VERB("  -nonicefps                    Don't free CPU-cycles\n") \
162
        VERB("  -maxfps <n>                   Set maximum framerate to <n>\n\t\t\t\t(default: " DXX_STRINGIZE(MAXIMUM_FPS) ", available: " DXX_STRINGIZE(MINIMUM_FPS) "-" DXX_STRINGIZE(MAXIMUM_FPS) ")\n")     \
163
        VERB("  -hogdir <s>                   set shared data directory to <s>\n")      \
164
        DXX_COMMAND_LINE_HELP_unix(     \
165
                VERB("  -nohogdir                     don't try to use shared data directory\n")        \
166
        )       \
167
        VERB("  -add-missions-dir <s>         Add contents of location <s> to the missions directory\n")        \
168
        VERB("  -use_players_dir              Put player files and saved games in Players subdirectory\n")      \
169
        VERB("  -lowmem                       Lowers animation detail for better performance with\n\t\t\t\tlow memory\n")       \
170
        VERB("  -pilot <s>                    Select pilot <s> automatically\n")        \
171
        VERB("  -auto-record-demo             Start recording on level entry\n")        \
172
        VERB("  -record-demo-format           Set demo name automatically\n")   \
173
        VERB("  -autodemo                     Start in demo mode\n")    \
174
        VERB("  -window                       Run the game in a window\n")      \
175
        VERB("  -noborders                    Don't show borders in window mode\n")     \
176
        DXX_COMMAND_LINE_HELP_D1(       \
177
                VERB("  -notitles                     Skip title screens\n")    \
178
        )       \
179
        DXX_COMMAND_LINE_HELP_D2(       \
180
                VERB("  -nomovies                     Don't play movies\n")     \
181
        )       \
182
        VERB("\n Controls:\n\n")        \
183
        VERB("  -nocursor                     Hide mouse cursor\n")     \
184
        VERB("  -nomouse                      Deactivate mouse\n")      \
185
        VERB("  -nojoystick                   Deactivate joystick\n")   \
186
        VERB("  -nostickykeys                 Make CapsLock and NumLock non-sticky\n")  \
187
        VERB("\n Sound:\n\n")   \
188
        VERB("  -nosound                      Disables sound output\n") \
189
        VERB("  -nomusic                      Disables music output\n") \
190
        DXX_COMMAND_LINE_HELP_D2(       \
191
                VERB("  -sound11k                     Use 11KHz sounds\n")      \
192
        )       \
193
        DXX_if_defined_01(DXX_USE_SDLMIXER, (   \
194
                VERB("  -nosdlmixer                   Disable Sound output via SDL_mixer\n")    \
195
        ))      \
196
        VERB("\n Graphics:\n\n")        \
197
        VERB("  -lowresfont                   Force use of low resolution fonts\n")     \
198
        DXX_COMMAND_LINE_HELP_D2(       \
199
                VERB("  -lowresgraphics               Force use of low resolution graphics\n")  \
200
                VERB("  -lowresmovies                 Play low resolution movies if available (for slow machines)\n")   \
201
        )       \
202
        DXX_COMMAND_LINE_HELP_OGL(      \
203
                VERB("  -gl_fixedfont                 Don't scale fonts to current resolution\n")       \
204
                VERB("  -gl_syncmethod <n>            OpenGL sync method (default: %i)\n", OGL_SYNC_METHOD_DEFAULT)     \
205
                VERB("                                    0: Disabled\n")       \
206
                VERB("                                    1: Fence syncs, limit GPU latency to at most one frame\n")    \
207
                VERB("                                    2: Like 1, but sleep during sync to reduce CPU load\n")       \
208
                VERB("                                    3: Immediately sync after buffer swap\n")     \
209
                VERB("                                    4: Immediately sync after buffer swap\n")     \
210
                VERB("                                    5: Auto: if VSync is enabled and ARB_sync is supported, use mode 2, otherwise mode 0\n")      \
211
                VERB("  -gl_syncwait <n>              Wait interval (ms) for sync mode 2 (default: " DXX_STRINGIZE(OGL_SYNC_WAIT_DEFAULT) ")\n")        \
212
                VERB("  -gl_darkedges                 Re-enable dark edges around filtered textures (as present in earlier versions of the engine)\n")  \
213
        )       \
214
        DXX_if_defined_01(DXX_USE_UDP, (        \
215
                VERB("\n Multiplayer:\n\n")     \
216
                VERB("  -udp_hostaddr <s>             Use IP address/Hostname <s> for manual game joining\n\t\t\t\t(default: %s)\n", UDP_MANUAL_ADDR_DEFAULT)   \
217
                VERB("  -udp_hostport <n>             Use UDP port <n> for manual game joining (default: %hu)\n", UDP_PORT_DEFAULT)     \
218
                VERB("  -udp_myport <n>               Set my own UDP port to <n> (default: %hu)\n", UDP_PORT_DEFAULT)   \
219
                DXX_if_defined_01(DXX_USE_TRACKER, (    \
220
                        VERB("  -no-tracker                   Disable tracker (unless overridden by later -tracker_hostaddr)\n")        \
221
                        VERB("  -tracker_hostaddr <n>         Address of tracker server to register/query games to/from\n\t\t\t\t(default: %s)\n", TRACKER_ADDR_DEFAULT)        \
222
                        VERB("  -tracker_hostport <n>         Port of tracker server to register/query games to/from\n\t\t\t\t(default: %hu)\n", TRACKER_PORT_DEFAULT)  \
223
                ))      \
224
        ))      \
225
        DXX_if_defined(EDITOR, (        \
226
                VERB("\n Editor:\n\n")  \
227
                DXX_COMMAND_LINE_HELP_D1(       \
228
                        VERB("  -nobm                         Don't load BITMAPS.TBL and BITMAPS.BIN - use internal data\n")    \
229
                )       \
230
                DXX_COMMAND_LINE_HELP_D2(       \
231
                        VERB("  -autoload <s>                 Autoload level <s> in the editor\n")      \
232
                        VERB("  -macdata                      Read and write Mac data files in editor (swap colors)\n") \
233
                        VERB("  -hoarddata                    Make the Hoard ham file from some files, then exit\n")    \
234
                )       \
235
        ))      \
236
        VERB("\n Debug (use only if you know what you're doing):\n\n")  \
237
        VERB("  -debug                        Enable debugging output.\n")      \
238
        VERB("  -verbose                      Enable verbose output.\n")        \
239
        VERB("  -safelog                      Write gamelog.txt unbuffered.\n\t\t\t\tUse to keep helpful output to trace program crashes.\n")   \
240
        VERB("  -norun                        Bail out after initialization\n") \
241
        VERB("  -no-grab                      Never grab keyboard/mouse\n")     \
242
        VERB("  -renderstats                  Enable renderstats info by default\n")    \
243
        VERB("  -text <s>                     Specify alternate .tex file\n")   \
244
        VERB("  -showmeminfo                  Show memory statistics\n")        \
245
        VERB("  -nodoublebuffer               Disable Doublebuffering\n")       \
246
        VERB("  -bigpig                       Use uncompressed RLE bitmaps\n")  \
247
        VERB("  -16bpp                        Use 16Bpp instead of 32Bpp\n")    \
248
        DXX_COMMAND_LINE_HELP_OGL(      \
249
                VERB("  -gl_oldtexmerge               Use old texmerge, uses more ram, but might be faster\n")  \
250
                VERB("  -gl_intensity4_ok <n>         Override DbgGlIntensity4Ok (default: 1)\n")       \
251
                VERB("  -gl_luminance4_alpha4_ok <n>  Override DbgGlLuminance4Alpha4Ok (default: 1)\n") \
252
                VERB("  -gl_rgba2_ok <n>              Override DbgGlRGBA2Ok (default: 1)\n")    \
253
                VERB("  -gl_readpixels_ok <n>         Override DbgGlReadPixelsOk (default: 1)\n")       \
254
                VERB("  -gl_gettexlevelparam_ok <n>   Override DbgGlGetTexLevelParamOk (default: 1)\n") \
255
        )       \
256
        DXX_COMMAND_LINE_HELP_SDL(      \
257
                VERB("  -tmap <s>                     Select texmapper <s> to use\n\t\t\t\t(default: c, available: c, fp, quad)\n")     \
258
                VERB("  -hwsurface                    Use SDL HW Surface\n")    \
259
                VERB("  -asyncblit                    Use queued blits over SDL. Can speed up rendering\n")     \
260
        )       \
261
        VERB("\n Help:\n\n")    \
262
        VERB("  -help, -h, -?, ?             View this help screen\n")  \
263
        VERB("\n\n")    \
264
 
265
        //printf(DXX_COMMAND_LINE_HELP(DXX_COMMAND_LINE_HELP_FMT) DXX_COMMAND_LINE_HELP(DXX_COMMAND_LINE_HELP_ARG));
266
        printf("\n");
267
        printf(" System Options:\n");
268
        printf("\n");
269
        printf("  -nonicefps                    Don't free CPU-cycles\n");
270
        printf("  -maxfps <n>                   Set maximum framerate to <n>\n");
271
        printf("                                default: " DXX_STRINGIZE(MAXIMUM_FPS) ", available: " DXX_STRINGIZE(MINIMUM_FPS) "-" DXX_STRINGIZE(MAXIMUM_FPS) ")\n");
272
        printf("  -hogdir <s>                   set shared data directory to <s>\n");
273
#ifdef __unix__
274
        printf("  -nohogdir                     don't try to use shared data directory\n");
275
#endif
276
        printf("  -add-missions-dir <s>         Add contents of location <s> to the missions directory\n");
277
        printf("  -use_players_dir              Put player files and saved games in Players subdirectory\n");
278
        printf("  -lowmem                       Lowers animation detail for better performance with\n");
279
        printf("                                low memory\n");
280
        printf("  -pilot <s>                    Select pilot <s> automatically\n");
281
        printf("  -auto-record-demo             Start recording on level entry\n");
282
        printf("  -record-demo-format           Set demo name automatically\n");
283
        printf("  -autodemo                     Start in demo mode\n");
284
        printf("  -window                       Run the game in a window\n");
285
        printf("  -noborders                    Don't show borders in window mode\n");
286
#ifdef DXX_BUILD_DESCENT_I
287
        printf("  -notitles                     Skip title screens\n");
288
#endif
289
#ifdef DXX_BUILD_DESCENT_II
290
        printf("  -nomovies                     Don't play movies\n");
291
#endif
292
        printf("\n");
293
        printf(" Controls:\n");
294
        printf("\n");
295
        printf("  -nocursor                     Hide mouse cursor\n");
296
        printf("  -nomouse                      Deactivate mouse\n");
297
        printf("  -nojoystick                   Deactivate joystick\n");
298
        printf("  -nostickykeys                 Make CapsLock and NumLock non-sticky\n");
299
        printf("\n");
300
        printf(" Sound:\n");
301
        printf("\n");
302
        printf("  -nosound                      Disables sound output\n");
303
        printf("  -nomusic                      Disables music output\n");
304
#ifdef DXX_BUILD_DESCENT_II
305
        printf("  -sound11k                     Use 11KHz sounds\n");
306
#endif
307
#ifdef DXX_USE_SDLMIXER
308
        printf("  -nosdlmixer                   Disable Sound output via SDL_mixer\n");
309
#endif
310
        printf("\n");
311
        printf(" Graphics:\n");
312
        printf("\n");
313
        printf("  -lowresfont                   Force use of low resolution fonts\n");
314
#ifdef DXX_BUILD_DESCENT_II
315
        printf("  -lowresgraphics               Force use of low resolution graphics\n");
316
        printf("  -lowresmovies                 Play low resolution movies if available (for slow machines)\n");
317
#endif
318
#ifdef DXX_USE_OGL
319
        printf("  -gl_fixedfont                 Don't scale fonts to current resolution\n");
320
        printf("  -gl_syncmethod <n>            OpenGL sync method (default: %i)\n", OGL_SYNC_METHOD_DEFAULT);
321
        printf("                                    0: Disabled\n");
322
        printf("                                    1: Fence syncs, limit GPU latency to at most one frame\n");
323
        printf("                                    2: Like 1, but sleep during sync to reduce CPU load\n");
324
        printf("                                    3: Immediately sync after buffer swap\n");
325
        printf("                                    4: Immediately sync after buffer swap\n");
326
        printf("                                    5: Auto: if VSync is enabled and ARB_sync is supported, use mode 2, otherwise mode 0\n");
327
        printf("  -gl_syncwait <n>              Wait interval (ms) for sync mode 2 (default: " DXX_STRINGIZE(OGL_SYNC_WAIT_DEFAULT) ")\n");
328
        printf("  -gl_darkedges                 Re-enable dark edges around filtered textures (as present in earlier versions of the engine)\n");
329
#endif
330
#ifdef DXX_USE_UDP
331
        printf("\n");
332
        printf(" Multiplayer:\n");
333
        printf("\n");
334
        printf("  -udp_hostaddr <s>             Use IP address/Hostname <s> for manual game joining\n");
335
        printf("                                (default: %s)\n", UDP_MANUAL_ADDR_DEFAULT);
336
        printf("  -udp_hostport <n>             Use UDP port <n> for manual game joining (default: %hu)\n", UDP_PORT_DEFAULT);
337
        printf("  -udp_myport <n>               Set my own UDP port to <n> (default: %hu)\n", UDP_PORT_DEFAULT);
338
#ifdef DXX_USE_TRACKER
339
        printf("  -no-tracker                   Disable tracker (unless overridden by later -tracker_hostaddr)\n");
340
        printf("  -tracker_hostaddr <n>         Address of tracker server to register/query games to/from\n"
341
        printf("                                (default: %s)\n", TRACKER_ADDR_DEFAULT);
342
        printf("  -tracker_hostport <n>         Port of tracker server to register/query games to/from\n");
343
        printf("                                (default: %hu)\n", TRACKER_PORT_DEFAULT);
344
#endif
345
#endif
346
#ifdef EDITOR
347
        printf("\n");
348
        printf(" Editor:\n");
349
        printf("\n");
350
#ifdef DXX_BUILD_DESCENT_I
351
        printf("  -nobm                         Don't load BITMAPS.TBL and BITMAPS.BIN - use internal data\n");
352
#endif
353
#ifdef DXX_BUILD_DESCENT_II
354
        printf("  -autoload <s>                 Autoload level <s> in the editor\n");
355
        printf("  -macdata                      Read and write Mac data files in editor (swap colors)\n");
356
        printf("  -hoarddata                    Make the Hoard ham file from some files, then exit\n");
357
#endif
358
#endif
359
        printf("\n");
360
        printf(" Debug (use only if you know what you're doing):\n");
361
        printf("\n");
362
        printf("  -debug                        Enable debugging output.\n");
363
        printf("  -verbose                      Enable verbose output.\n");
364
        printf("  -safelog                      Write gamelog.txt unbuffered.\n");
365
        printf("                                Use to keep helpful output to trace program crashes.\n");
366
        printf("  -norun                        Bail out after initialization\n");
367
        printf("  -no-grab                      Never grab keyboard/mouse\n");
368
        printf("  -renderstats                  Enable renderstats info by default\n");
369
        printf("  -text <s>                     Specify alternate .tex file\n");
370
        printf("  -showmeminfo                  Show memory statistics\n");
371
        printf("  -nodoublebuffer               Disable Doublebuffering\n");
372
        printf("  -bigpig                       Use uncompressed RLE bitmaps\n");
373
        printf("  -16bpp                        Use 16Bpp instead of 32Bpp\n");
374
#ifdef DXX_USE_OGL
375
        printf("  -gl_oldtexmerge               Use old texmerge, uses more ram, but might be faster\n");
376
        printf("  -gl_intensity4_ok <n>         Override DbgGlIntensity4Ok (default: 1)\n");
377
        printf("  -gl_luminance4_alpha4_ok <n>  Override DbgGlLuminance4Alpha4Ok (default: 1)\n");
378
        printf("  -gl_rgba2_ok <n>              Override DbgGlRGBA2Ok (default: 1)\n");
379
        printf("  -gl_readpixels_ok <n>         Override DbgGlReadPixelsOk (default: 1)\n");
380
        printf("  -gl_gettexlevelparam_ok <n>   Override DbgGlGetTexLevelParamOk (default: 1)\n");
381
#else /* SDL */
382
        printf("  -tmap <s>                     Select texmapper <s> to use\n");
383
        printf("                                (default: c, available: c, fp, quad)\n");
384
        printf("  -hwsurface                    Use SDL HW Surface\n");
385
        printf("  -asyncblit                    Use queued blits over SDL. Can speed up rendering\n");
386
#endif
387
        printf("\n");
388
        printf(" Help:\n");
389
        printf("\n");
390
        printf("  -help, -h, -?, ?             View this help screen\n");
391
        printf("\n");
392
        printf("\n");
393
}
394
 
395
int Quitting = 0;
396
 
397
}
398
 
399
namespace dcx {
400
 
401
// Default event handler for everything except the editor
402
window_event_result standard_handler(const d_event &event)
403
{
404
        int key;
405
 
406
        if (Quitting)
407
        {
408
                window *wind = window_get_front();
409
                if (!wind)
410
                        return window_event_result::ignored;    // finished quitting
411
 
412
                if (wind == Game_wind)
413
                {
414
                        int choice;
415
                        Quitting = 0;
416
                        choice=nm_messagebox( NULL, 2, TXT_YES, TXT_NO, TXT_ABORT_GAME );
417
                        if (choice != 0)
418
                                return window_event_result::handled;    // aborted quitting
419
                        else
420
                        {
421
                                CGameArg.SysAutoDemo = false;
422
                                Quitting = 1;
423
                        }
424
                }
425
 
426
                // Close front window, let the code flow continue until all windows closed or quit cancelled
427
                if (!window_close(wind))
428
                {
429
                        Quitting = 0;
430
                        return window_event_result::handled;
431
                }
432
 
433
                return window_event_result::deleted;    // tell the event system we deleted some window
434
        }
435
 
436
        switch (event.type)
437
        {
438
                case EVENT_MOUSE_BUTTON_DOWN:
439
                case EVENT_MOUSE_BUTTON_UP:
440
                        // No window selecting
441
                        // We stay with the current one until it's closed/hidden or another one is made
442
                        // Not the case for the editor
443
                        break;
444
 
445
                case EVENT_KEY_COMMAND:
446
                        key = event_key_get(event);
447
 
448
                        switch (key)
449
                        {
450
#if DXX_USE_SCREENSHOT
451
#ifdef macintosh
452
                                case KEY_COMMAND + KEY_SHIFTED + KEY_3:
453
#endif
454
                                case KEY_PRINT_SCREEN:
455
                                {
456
                                        gr_set_default_canvas();
457
                                        save_screen_shot(0);
458
                                        return window_event_result::handled;
459
                                }
460
#endif
461
 
462
                                case KEY_ALTED+KEY_ENTER:
463
                                case KEY_ALTED+KEY_PADENTER:
464
                                        if (Game_wind)
465
                                                if (Game_wind == window_get_front())
466
                                                        return window_event_result::ignored;
467
                                        gr_toggle_fullscreen();
468
#if SDL_MAJOR_VERSION == 2
469
                                        {
470
                                                /* Hack to force the canvas to adjust to the new
471
                                                 * dimensions.  Without this, the canvas
472
                                                 * continues to use the old window size until
473
                                                 * the hack of calling `init_cockpit` from
474
                                                 * `game_handler` fixes the dimensions.  If the
475
                                                 * window became bigger, the game fails to draw
476
                                                 * in the full new area.  If the window became
477
                                                 * smaller, part of the game is outside the
478
                                                 * cropped area.
479
                                                 *
480
                                                 * If the automap is open, the view is still
481
                                                 * wrong, since the automap uses its own private
482
                                                 * canvas.  That will need to be fixed
483
                                                 * separately.  Ideally, the whole window
484
                                                 * system would be reworked to provide a general
485
                                                 * notification to every interested canvas when
486
                                                 * the top level window resizes.
487
                                                 */
488
                                                auto sm = Screen_mode;
489
                                                Screen_mode = SCREEN_GAME;
490
                                                init_cockpit();
491
                                                Screen_mode = sm;
492
                                        }
493
#endif
494
                                        return window_event_result::handled;
495
 
496
#if defined(__APPLE__) || defined(macintosh)
497
                                case KEY_COMMAND+KEY_Q:
498
                                        // Alt-F4 already taken, too bad
499
                                        Quitting = 1;
500
                                        return window_event_result::handled;
501
#endif
502
                                case KEY_SHIFTED + KEY_ESC:
503
                                        con_showup();
504
                                        return window_event_result::handled;
505
                        }
506
                        break;
507
 
508
                case EVENT_WINDOW_DRAW:
509
                case EVENT_IDLE:
510
                        //see if redbook song needs to be restarted
511
#if DXX_USE_SDL_REDBOOK_AUDIO
512
                        RBACheckFinishedHook();
513
#endif
514
                        return window_event_result::handled;
515
 
516
                case EVENT_QUIT:
517
#if DXX_USE_EDITOR
518
                        if (SafetyCheck())
519
#endif
520
                                Quitting = 1;
521
                        return window_event_result::handled;
522
 
523
                default:
524
                        break;
525
        }
526
 
527
        return window_event_result::ignored;
528
}
529
 
530
#if DXX_HAVE_POISON
531
d_interface_unique_state::d_interface_unique_state()
532
{
533
        DXX_MAKE_VAR_UNDEFINED(PilotName);
534
}
535
#endif
536
 
537
void d_interface_unique_state::update_window_title()
538
{
539
#if SDL_MAJOR_VERSION == 1
540
        if (!PilotName[0u])
541
                SDL_WM_SetCaption(DESCENT_VERSION, DXX_SDL_WINDOW_CAPTION);
542
        else
543
        {
544
                const char *const pilot = PilotName;
545
                std::array<char, 80> wm_caption_name, wm_caption_iconname;
546
                snprintf(wm_caption_name.data(), wm_caption_name.size(), "%s: %s", DESCENT_VERSION, pilot);
547
                snprintf(wm_caption_iconname.data(), wm_caption_iconname.size(), "%s: %s", DXX_SDL_WINDOW_CAPTION, pilot);
548
                SDL_WM_SetCaption(wm_caption_name.data(), wm_caption_iconname.data());
549
        }
550
#endif
551
}
552
 
553
}
554
 
555
namespace dsx {
556
 
557
#define PROGNAME argv[0]
558
#define DXX_RENAME_IDENTIFIER2(I,N)     I##$##N
559
#define DXX_RENAME_IDENTIFIER(I,N)      DXX_RENAME_IDENTIFIER2(I,N)
560
#define argc    DXX_RENAME_IDENTIFIER(argc_gc, DXX_git_commit)
561
#define argv    DXX_RENAME_IDENTIFIER(argv_gd$b32, DXX_git_describe)
562
 
563
//      DESCENT by Parallax Software
564
//      DESCENT II by Parallax Software
565
//      (varies based on preprocessor options)
566
//              Descent Main
567
 
568
static int main(int argc, char *argv[])
569
{
570
        if (!PHYSFSX_init(argc, argv))
571
                return 1;
572
        con_init();  // Initialise the console
573
 
574
        setbuf(stdout, NULL); // unbuffered output via printf
575
#ifdef _WIN32
576
        freopen( "CON", "w", stdout );
577
        freopen( "CON", "w", stderr );
578
#endif
579
 
580
        if (CGameArg.SysShowCmdHelp) {
581
                print_commandline_help();
582
 
583
                return(0);
584
        }
585
 
586
        printf("\nType '%s -help' for a list of command-line options.\n\n", PROGNAME);
587
 
588
        PHYSFSX_listSearchPathContent();
589
 
590
        if (!PHYSFSX_checkSupportedArchiveTypes())
591
                return(0);
592
 
593
#if defined(DXX_BUILD_DESCENT_I)
594
        if (! PHYSFSX_contfile_init("descent.hog", 1))
595
#define DXX_NAME_NUMBER "1"
596
#define DXX_HOGFILE_NAMES       "descent.hog"
597
#elif defined(DXX_BUILD_DESCENT_II)
598
        if (! PHYSFSX_contfile_init("descent2.hog", 1) && ! PHYSFSX_contfile_init("d2demo.hog", 1))
599
#define DXX_NAME_NUMBER "2"
600
#define DXX_HOGFILE_NAMES       "descent2.hog or d2demo.hog"
601
#endif
602
        {
603
#if defined(__unix__) && !defined(__APPLE__)
604
#define DXX_HOGFILE_PROGRAM_DATA_DIRECTORY      \
605
                              "\t$HOME/.d" DXX_NAME_NUMBER "x-rebirth\n"        \
606
                                        DXX_HOGFILE_SHAREPATH_INDENTED
607
#if DXX_USE_SHAREPATH
608
#define DXX_HOGFILE_SHAREPATH_INDENTED  \
609
                              "\t" DXX_SHAREPATH "\n"
610
#else
611
#define DXX_HOGFILE_SHAREPATH_INDENTED
612
#endif
613
#else
614
#define DXX_HOGFILE_PROGRAM_DATA_DIRECTORY      \
615
                                  "\tDirectory containing D" DXX_NAME_NUMBER "X\n"
616
#endif
617
#if (defined(__APPLE__) && defined(__MACH__)) || defined(macintosh)
618
#define DXX_HOGFILE_APPLICATION_BUNDLE  \
619
                                  "\tIn 'Resources' inside the application bundle\n"
620
#else
621
#define DXX_HOGFILE_APPLICATION_BUNDLE  ""
622
#endif
623
#define DXX_MISSING_HOGFILE_ERROR_TEXT  \
624
                "Could not find a valid hog file (" DXX_HOGFILE_NAMES ")\nPossible locations are:\n"    \
625
                DXX_HOGFILE_PROGRAM_DATA_DIRECTORY      \
626
                "\tIn a subdirectory called 'data'\n"   \
627
                DXX_HOGFILE_APPLICATION_BUNDLE  \
628
                "Or use the -hogdir option to specify an alternate location."
629
                UserError(DXX_MISSING_HOGFILE_ERROR_TEXT);
630
        }
631
 
632
#if defined(DXX_BUILD_DESCENT_I)
633
        switch (PHYSFSX_fsize("descent.hog"))
634
        {
635
                case D1_MAC_SHARE_MISSION_HOGSIZE:
636
                case D1_MAC_MISSION_HOGSIZE:
637
                        MacHog = 1;     // used for fonts and the Automap
638
                        break;
639
        }
640
#endif
641
 
642
        load_text();
643
 
644
        //print out the banner title
645
#if defined(DXX_BUILD_DESCENT_I)
646
        con_printf(CON_NORMAL, "%s  %s", DESCENT_VERSION, g_descent_build_datetime); // D1X version
647
        con_puts(CON_NORMAL, "This is a MODIFIED version of Descent, based on " BASED_VERSION ".");
648
        con_puts(CON_NORMAL, TXT_COPYRIGHT);
649
        con_puts(CON_NORMAL, TXT_TRADEMARK);
650
        con_puts(CON_NORMAL, "Copyright (C) 2005-2013 Christian Beckhaeuser, 2013-2017 Kp");
651
#elif defined(DXX_BUILD_DESCENT_II)
652
        con_printf(CON_NORMAL, "%s%s  %s", DESCENT_VERSION, PHYSFSX_exists(MISSION_DIR "d2x.hog",1) ? "  Vertigo Enhanced" : "", g_descent_build_datetime); // D2X version
653
        con_puts(CON_NORMAL, "This is a MODIFIED version of Descent 2, based on " BASED_VERSION ".");
654
        con_puts(CON_NORMAL, TXT_COPYRIGHT);
655
        con_puts(CON_NORMAL, TXT_TRADEMARK);
656
        con_puts(CON_NORMAL, "Copyright (C) 1999 Peter Hawkins, 2002 Bradley Bell, 2005-2013 Christian Beckhaeuser, 2013-2017 Kp");
657
#endif
658
 
659
        if (CGameArg.DbgVerbose)
660
        {
661
                {
662
                        PHYSFS_Version vc, vl;
663
                        PHYSFS_VERSION(&vc);
664
                        PHYSFS_getLinkedVersion(&vl);
665
                        con_printf(CON_VERBOSE, "D" DXX_NAME_NUMBER "X-Rebirth built with PhysFS %u.%u.%u; loaded with PhysFS %u.%u.%u", vc.major, vc.minor, vc.patch, vl.major, vl.minor, vl.patch);
666
                }
667
                {
668
                        SDL_version vc;
669
                        SDL_VERSION(&vc);
670
#if SDL_MAJOR_VERSION == 1
671
                        const auto vl = SDL_Linked_Version();
672
#else
673
                        SDL_version vlv;
674
                        const auto vl = &vlv;
675
                        SDL_GetVersion(vl);
676
#endif
677
                        con_printf(CON_VERBOSE, "D" DXX_NAME_NUMBER "X-Rebirth built with libSDL %u.%u.%u; loaded with libSDL %u.%u.%u", vc.major, vc.minor, vc.patch, vl->major, vl->minor, vl->patch);
678
                }
679
#if DXX_USE_SDLIMAGE
680
                {
681
                        SDL_version vc;
682
                        SDL_IMAGE_VERSION(&vc);
683
                        const auto vl = IMG_Linked_Version();
684
                        con_printf(CON_VERBOSE, "D" DXX_NAME_NUMBER "X-Rebirth built with SDL_image %u.%u.%u; loaded with SDL_image %u.%u.%u", vc.major, vc.minor, vc.patch, vl->major, vl->minor, vl->patch);
685
                }
686
#endif
687
#if DXX_USE_SDLMIXER
688
                {
689
                        SDL_version vc;
690
                        SDL_MIXER_VERSION(&vc);
691
                        const auto vl = Mix_Linked_Version();
692
                        con_printf(CON_VERBOSE, "D" DXX_NAME_NUMBER "X-Rebirth built with SDL_mixer %u.%u.%u; loaded with SDL_mixer %u.%u.%u", vc.major, vc.minor, vc.patch, vl->major, vl->minor, vl->patch);
693
                }
694
#endif
695
                con_puts(CON_VERBOSE, TXT_VERBOSE_1);
696
        }
697
 
698
        ReadConfigFile();
699
 
700
        PHYSFSX_addArchiveContent();
701
 
702
        const auto &&arch_atexit_result = arch_init();
703
        /* This variable exists for the side effects that occur when it is
704
         * destroyed.  clang-9 fails to recognize those side effects as a
705
         * "use" and warns that the variable is unused.  Cast it to void to
706
         * create a "use" to suppress the warning.
707
         */
708
        (void)arch_atexit_result;
709
 
710
#if !DXX_USE_OGL
711
        select_tmap(CGameArg.DbgTexMap);
712
 
713
#if defined(DXX_BUILD_DESCENT_II)
714
        Lighting_on = 1;
715
#endif
716
#endif
717
 
718
        con_puts(CON_VERBOSE, "Going into graphics mode...");
719
#if DXX_USE_OGL
720
        gr_set_mode_from_window_size();
721
#else
722
        gr_set_mode(Game_screen_mode);
723
#endif
724
 
725
        // Load the palette stuff. Returns non-zero if error.
726
        con_puts(CON_DEBUG, "Initializing palette system...");
727
#if defined(DXX_BUILD_DESCENT_I)
728
        gr_use_palette_table( "PALETTE.256" );
729
#elif defined(DXX_BUILD_DESCENT_II)
730
        gr_use_palette_table(D2_DEFAULT_PALETTE );
731
#endif
732
 
733
        con_puts(CON_DEBUG, "Initializing font system...");
734
        gamefont_init();        // must load after palette data loaded.
735
 
736
#if defined(DXX_BUILD_DESCENT_II)
737
        con_puts(CON_DEBUG, "Initializing movie libraries...");
738
        init_movies();          //init movie libraries
739
#endif
740
 
741
        show_titles();
742
 
743
        set_screen_mode(SCREEN_MENU);
744
#ifdef DEBUG_MEMORY_ALLOCATIONS
745
        /* Memdebug runs before global destructors, so it incorrectly
746
         * reports as leaked any allocations that would be freed by a global
747
         * destructor.  This local will force the newmenu globals to be
748
         * reset before memdebug scans, which prevents memdebug falsely
749
         * reporting them as leaked.
750
         *
751
         * External tools, such as Valgrind, know to run global destructors
752
         * before checking for leaks, so this hack is only necessary when
753
         * memdebug is used.
754
         */
755
        struct hack_free_global_backgrounds
756
        {
757
                ~hack_free_global_backgrounds()
758
                {
759
                        newmenu_free_background();
760
                }
761
        };
762
        hack_free_global_backgrounds hack_free_global_background;
763
#endif
764
 
765
        con_puts(CON_DEBUG, "Doing gamedata_init...");
766
        gamedata_init();
767
 
768
#if defined(DXX_BUILD_DESCENT_II)
769
#if DXX_USE_EDITOR
770
        if (GameArg.EdiSaveHoardData) {
771
                save_hoard_data();
772
                exit(1);
773
        }
774
        #endif
775
#endif
776
 
777
        if (CGameArg.DbgNoRun)
778
                return(0);
779
 
780
        con_puts(CON_DEBUG, "Initializing texture caching system...");
781
        texmerge_init();                // 10 cache bitmaps
782
 
783
#if defined(DXX_BUILD_DESCENT_II)
784
        piggy_init_pigfile("groupa.pig");       //get correct pigfile
785
#endif
786
 
787
        con_puts(CON_DEBUG, "Running game...");
788
        init_game();
789
 
790
#if defined(DXX_BUILD_DESCENT_I)
791
        key_flush();
792
#endif
793
        {
794
                InterfaceUniqueState.PilotName.fill(0);
795
                if (!CGameArg.SysPilot.empty())
796
                {
797
                        char filename[sizeof(PLAYER_DIRECTORY_TEXT) + CALLSIGN_LEN + 4];
798
 
799
                        /* Step over the literal PLAYER_DIRECTORY_TEXT when it is
800
                         * present.  Point at &filename[0] when
801
                         * PLAYER_DIRECTORY_TEXT is absent.
802
                         */
803
                        const auto b = &filename[-CGameArg.SysUsePlayersDir];
804
                        snprintf(filename, sizeof(filename), PLAYER_DIRECTORY_STRING("%.12s"), CGameArg.SysPilot.c_str());
805
                        /* The pilot name is never used after this.  Clear it to
806
                         * free the allocated memory, if any.
807
                         */
808
                        CGameArg.SysPilot.clear();
809
                        auto p = b;
810
                        for (const auto &facet = std::use_facet<std::ctype<char>>(std::locale::classic()); char &c = *p; ++p)
811
                        {
812
                                c = facet.tolower(static_cast<uint8_t>(c));
813
                        }
814
                        auto j = p - filename;
815
                        if (j < sizeof(filename) - 4 && (j <= 4 || strcmp(&filename[j - 4], ".plr"))) // if player hasn't specified .plr extension in argument, add it
816
                        {
817
                                strcpy(&filename[j], ".plr");
818
                                j += 4;
819
                        }
820
                        if(PHYSFSX_exists(filename,0))
821
                        {
822
                                InterfaceUniqueState.PilotName.copy(b, std::distance(b, &filename[j - 4]));
823
                                InterfaceUniqueState.update_window_title();
824
                                read_player_file();
825
                                WriteConfigFile();
826
                        }
827
                }
828
        }
829
 
830
#if defined(DXX_BUILD_DESCENT_II)
831
#if DXX_USE_EDITOR
832
        if (!GameArg.EdiAutoLoad.empty()) {
833
                /* Any number >= FILENAME_LEN works */
834
                Level_names[0].copy_if(GameArg.EdiAutoLoad.c_str(), GameArg.EdiAutoLoad.size());
835
                LoadLevel(1, 1);
836
        }
837
        else
838
#endif
839
#endif
840
        {
841
                Game_mode = GM_GAME_OVER;
842
                DoMenu();
843
        }
844
 
845
        while (window_get_front())
846
                // Send events to windows and the default handler
847
                event_process();
848
 
849
        // Tidy up - avoids a crash on exit
850
        {
851
                window *wind;
852
 
853
                show_menus();
854
                while ((wind = window_get_front()))
855
                        window_close(wind);
856
        }
857
 
858
        WriteConfigFile();
859
        show_order_form();
860
 
861
        con_puts(CON_DEBUG, "Cleanup...");
862
        close_game();
863
        texmerge_close();
864
        gamedata_close();
865
        gamefont_close();
866
        Current_mission.reset();
867
        PHYSFSX_removeArchiveContent();
868
 
869
        return(0);              //presumably successful exit
870
}
871
 
872
}
873
 
874
int main(int argc, char *argv[])
875
{
876
        mem_init();
877
#if DXX_WORDS_NEED_ALIGNMENT
878
        prctl(PR_SET_UNALIGN, PR_UNALIGN_NOPRINT, 0, 0, 0);
879
#endif
880
#if defined(WIN32) || defined(__APPLE__) || defined(__MACH__)
881
#if DXX_USE_EDITOR
882
        set_warn_func(msgbox_warning);
883
#endif
884
#ifdef WIN32
885
        void d_set_exception_handler();
886
        d_set_exception_handler();
887
#endif
888
#endif
889
        return dsx::main(argc, argv);
890
}
891
 
892
#undef argv
893
#undef argc