diff options
Diffstat (limited to 'src/d_main.c')
-rw-r--r-- | src/d_main.c | 1725 |
1 files changed, 1725 insertions, 0 deletions
diff --git a/src/d_main.c b/src/d_main.c new file mode 100644 index 0000000..6d8493e --- /dev/null +++ b/src/d_main.c | |||
@@ -0,0 +1,1725 @@ | |||
1 | /* Emacs style mode select -*- C++ -*- | ||
2 | *----------------------------------------------------------------------------- | ||
3 | * | ||
4 | * | ||
5 | * PrBoom: a Doom port merged with LxDoom and LSDLDoom | ||
6 | * based on BOOM, a modified and improved DOOM engine | ||
7 | * Copyright (C) 1999 by | ||
8 | * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman | ||
9 | * Copyright (C) 1999-2004 by | ||
10 | * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze | ||
11 | * Copyright 2005, 2006 by | ||
12 | * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License | ||
16 | * as published by the Free Software Foundation; either version 2 | ||
17 | * of the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
27 | * 02111-1307, USA. | ||
28 | * | ||
29 | * DESCRIPTION: | ||
30 | * DOOM main program (D_DoomMain) and game loop (D_DoomLoop), | ||
31 | * plus functions to determine game mode (shareware, registered), | ||
32 | * parse command line parameters, configure game parameters (turbo), | ||
33 | * and call the startup functions. | ||
34 | * | ||
35 | *----------------------------------------------------------------------------- | ||
36 | */ | ||
37 | |||
38 | |||
39 | #ifdef _MSC_VER | ||
40 | #define F_OK 0 /* Check for file existence */ | ||
41 | #define W_OK 2 /* Check for write permission */ | ||
42 | #define R_OK 4 /* Check for read permission */ | ||
43 | #include <io.h> | ||
44 | #include <direct.h> | ||
45 | #else | ||
46 | #include <unistd.h> | ||
47 | #endif | ||
48 | #include <sys/types.h> | ||
49 | #include <sys/stat.h> | ||
50 | #include <fcntl.h> | ||
51 | |||
52 | #include "doomdef.h" | ||
53 | #include "doomtype.h" | ||
54 | #include "doomstat.h" | ||
55 | #include "d_net.h" | ||
56 | #include "dstrings.h" | ||
57 | #include "sounds.h" | ||
58 | #include "z_zone.h" | ||
59 | #include "w_wad.h" | ||
60 | #include "s_sound.h" | ||
61 | #include "v_video.h" | ||
62 | #include "f_finale.h" | ||
63 | #include "f_wipe.h" | ||
64 | #include "m_argv.h" | ||
65 | #include "m_misc.h" | ||
66 | #include "m_menu.h" | ||
67 | #include "p_checksum.h" | ||
68 | #include "i_main.h" | ||
69 | #include "i_system.h" | ||
70 | #include "i_sound.h" | ||
71 | #include "i_video.h" | ||
72 | #include "g_game.h" | ||
73 | #include "hu_stuff.h" | ||
74 | #include "wi_stuff.h" | ||
75 | #include "st_stuff.h" | ||
76 | #include "am_map.h" | ||
77 | #include "p_setup.h" | ||
78 | #include "r_draw.h" | ||
79 | #include "r_main.h" | ||
80 | #include "r_fps.h" | ||
81 | #include "d_main.h" | ||
82 | #include "d_deh.h" // Ty 04/08/98 - Externalizations | ||
83 | #include "lprintf.h" // jff 08/03/98 - declaration of lprintf | ||
84 | #include "am_map.h" | ||
85 | |||
86 | void GetFirstMap(int *ep, int *map); // Ty 08/29/98 - add "-warp x" functionality | ||
87 | static void D_PageDrawer(void); | ||
88 | |||
89 | // CPhipps - removed wadfiles[] stuff | ||
90 | |||
91 | boolean devparm; // started game with -devparm | ||
92 | |||
93 | // jff 1/24/98 add new versions of these variables to remember command line | ||
94 | boolean clnomonsters; // checkparm of -nomonsters | ||
95 | boolean clrespawnparm; // checkparm of -respawn | ||
96 | boolean clfastparm; // checkparm of -fast | ||
97 | // jff 1/24/98 end definition of command line version of play mode switches | ||
98 | |||
99 | boolean nomonsters; // working -nomonsters | ||
100 | boolean respawnparm; // working -respawn | ||
101 | boolean fastparm; // working -fast | ||
102 | |||
103 | boolean singletics = false; // debug flag to cancel adaptiveness | ||
104 | |||
105 | //jff 1/22/98 parms for disabling music and sound | ||
106 | boolean nosfxparm; | ||
107 | boolean nomusicparm; | ||
108 | |||
109 | //jff 4/18/98 | ||
110 | extern boolean inhelpscreens; | ||
111 | |||
112 | skill_t startskill; | ||
113 | int startepisode; | ||
114 | int startmap; | ||
115 | boolean autostart; | ||
116 | FILE *debugfile; | ||
117 | int ffmap; | ||
118 | |||
119 | boolean advancedemo; | ||
120 | |||
121 | char wadfile[PATH_MAX+1]; // primary wad file | ||
122 | char mapdir[PATH_MAX+1]; // directory of development maps | ||
123 | char baseiwad[PATH_MAX+1]; // jff 3/23/98: iwad directory | ||
124 | char basesavegame[PATH_MAX+1]; // killough 2/16/98: savegame directory | ||
125 | |||
126 | //jff 4/19/98 list of standard IWAD names | ||
127 | const char *const standard_iwads[]= | ||
128 | { | ||
129 | "doom2f.wad", | ||
130 | "doom2.wad", | ||
131 | "plutonia.wad", | ||
132 | "tnt.wad", | ||
133 | "doom.wad", | ||
134 | "doom1.wad", | ||
135 | "doomu.wad", /* CPhipps - alow doomu.wad */ | ||
136 | "freedoom.wad", /* wart@kobold.org: added freedoom for Fedora Extras */ | ||
137 | }; | ||
138 | static const int nstandard_iwads = sizeof standard_iwads/sizeof*standard_iwads; | ||
139 | |||
140 | /* | ||
141 | * D_PostEvent - Event handling | ||
142 | * | ||
143 | * Called by I/O functions when an event is received. | ||
144 | * Try event handlers for each code area in turn. | ||
145 | * cph - in the true spirit of the Boom source, let the | ||
146 | * short ciruit operator madness begin! | ||
147 | */ | ||
148 | |||
149 | void D_PostEvent(event_t *ev) | ||
150 | { | ||
151 | /* cph - suppress all input events at game start | ||
152 | * FIXME: This is a lousy kludge */ | ||
153 | if (gametic < 3) return; | ||
154 | M_Responder(ev) || | ||
155 | (gamestate == GS_LEVEL && ( | ||
156 | HU_Responder(ev) || | ||
157 | ST_Responder(ev) || | ||
158 | AM_Responder(ev) | ||
159 | ) | ||
160 | ) || | ||
161 | G_Responder(ev); | ||
162 | } | ||
163 | |||
164 | // | ||
165 | // D_Wipe | ||
166 | // | ||
167 | // CPhipps - moved the screen wipe code from D_Display to here | ||
168 | // The screens to wipe between are already stored, this just does the timing | ||
169 | // and screen updating | ||
170 | |||
171 | static void D_Wipe(void) | ||
172 | { | ||
173 | boolean done; | ||
174 | int wipestart = I_GetTime () - 1; | ||
175 | |||
176 | do | ||
177 | { | ||
178 | int nowtime, tics; | ||
179 | do | ||
180 | { | ||
181 | I_uSleep(5000); // CPhipps - don't thrash cpu in this loop | ||
182 | nowtime = I_GetTime(); | ||
183 | tics = nowtime - wipestart; | ||
184 | } | ||
185 | while (!tics); | ||
186 | wipestart = nowtime; | ||
187 | done = wipe_ScreenWipe(tics); | ||
188 | I_UpdateNoBlit(); | ||
189 | M_Drawer(); // menu is drawn even on top of wipes | ||
190 | I_FinishUpdate(); // page flip or blit buffer | ||
191 | } | ||
192 | while (!done); | ||
193 | } | ||
194 | |||
195 | // | ||
196 | // D_Display | ||
197 | // draw current display, possibly wiping it from the previous | ||
198 | // | ||
199 | |||
200 | // wipegamestate can be set to -1 to force a wipe on the next draw | ||
201 | gamestate_t wipegamestate = GS_DEMOSCREEN; | ||
202 | extern boolean setsizeneeded; | ||
203 | extern int showMessages; | ||
204 | |||
205 | void D_Display (void) | ||
206 | { | ||
207 | static boolean inhelpscreensstate = false; | ||
208 | static boolean isborderstate = false; | ||
209 | static boolean borderwillneedredraw = false; | ||
210 | static gamestate_t oldgamestate = -1; | ||
211 | boolean wipe; | ||
212 | boolean viewactive = false, isborder = false; | ||
213 | |||
214 | if (nodrawers) // for comparative timing / profiling | ||
215 | return; | ||
216 | |||
217 | if (!I_StartDisplay()) | ||
218 | return; | ||
219 | |||
220 | // save the current screen if about to wipe | ||
221 | if ((wipe = gamestate != wipegamestate) && (V_GetMode() != VID_MODEGL)) | ||
222 | wipe_StartScreen(); | ||
223 | |||
224 | if (gamestate != GS_LEVEL) { // Not a level | ||
225 | switch (oldgamestate) { | ||
226 | case -1: | ||
227 | case GS_LEVEL: | ||
228 | V_SetPalette(0); // cph - use default (basic) palette | ||
229 | default: | ||
230 | break; | ||
231 | } | ||
232 | |||
233 | switch (gamestate) { | ||
234 | case GS_INTERMISSION: | ||
235 | WI_Drawer(); | ||
236 | break; | ||
237 | case GS_FINALE: | ||
238 | F_Drawer(); | ||
239 | break; | ||
240 | case GS_DEMOSCREEN: | ||
241 | D_PageDrawer(); | ||
242 | break; | ||
243 | default: | ||
244 | break; | ||
245 | } | ||
246 | } else if (gametic != basetic) { // In a level | ||
247 | boolean redrawborderstuff; | ||
248 | |||
249 | HU_Erase(); | ||
250 | |||
251 | if (setsizeneeded) { // change the view size if needed | ||
252 | R_ExecuteSetViewSize(); | ||
253 | oldgamestate = -1; // force background redraw | ||
254 | } | ||
255 | |||
256 | // Work out if the player view is visible, and if there is a border | ||
257 | viewactive = (!(automapmode & am_active) || (automapmode & am_overlay)) && !inhelpscreens; | ||
258 | isborder = viewactive ? (viewheight != SCREENHEIGHT) : (!inhelpscreens && (automapmode & am_active)); | ||
259 | |||
260 | if (oldgamestate != GS_LEVEL) { | ||
261 | R_FillBackScreen (); // draw the pattern into the back screen | ||
262 | redrawborderstuff = isborder; | ||
263 | } else { | ||
264 | // CPhipps - | ||
265 | // If there is a border, and either there was no border last time, | ||
266 | // or the border might need refreshing, then redraw it. | ||
267 | redrawborderstuff = isborder && (!isborderstate || borderwillneedredraw); | ||
268 | // The border may need redrawing next time if the border surrounds the screen, | ||
269 | // and there is a menu being displayed | ||
270 | borderwillneedredraw = menuactive && isborder && viewactive && (viewwidth != SCREENWIDTH); | ||
271 | } | ||
272 | if (redrawborderstuff || (V_GetMode() == VID_MODEGL)) | ||
273 | R_DrawViewBorder(); | ||
274 | |||
275 | // Now do the drawing | ||
276 | if (viewactive) | ||
277 | R_RenderPlayerView (&players[displayplayer]); | ||
278 | if (automapmode & am_active) | ||
279 | AM_Drawer(); | ||
280 | ST_Drawer((viewheight != SCREENHEIGHT) || ((automapmode & am_active) && !(automapmode & am_overlay)), redrawborderstuff); | ||
281 | if (V_GetMode() != VID_MODEGL) | ||
282 | R_DrawViewBorder(); | ||
283 | HU_Drawer(); | ||
284 | } | ||
285 | |||
286 | inhelpscreensstate = inhelpscreens; | ||
287 | isborderstate = isborder; | ||
288 | oldgamestate = wipegamestate = gamestate; | ||
289 | |||
290 | // draw pause pic | ||
291 | if (paused) { | ||
292 | // Simplified the "logic" here and no need for x-coord caching - POPE | ||
293 | V_DrawNamePatch((320 - V_NamePatchWidth("M_PAUSE"))/2, 4, | ||
294 | 0, "M_PAUSE", CR_DEFAULT, VPT_STRETCH); | ||
295 | } | ||
296 | |||
297 | // menus go directly to the screen | ||
298 | M_Drawer(); // menu is drawn even on top of everything | ||
299 | #ifdef HAVE_NET | ||
300 | NetUpdate(); // send out any new accumulation | ||
301 | #else | ||
302 | D_BuildNewTiccmds(); | ||
303 | #endif | ||
304 | |||
305 | // normal update | ||
306 | if (!wipe || (V_GetMode() == VID_MODEGL)) | ||
307 | I_FinishUpdate (); // page flip or blit buffer | ||
308 | else { | ||
309 | // wipe update | ||
310 | wipe_EndScreen(); | ||
311 | D_Wipe(); | ||
312 | } | ||
313 | |||
314 | I_EndDisplay(); | ||
315 | |||
316 | //e6y: don't thrash cpu during pausing | ||
317 | if (paused) { | ||
318 | I_uSleep(1000); | ||
319 | } | ||
320 | } | ||
321 | |||
322 | // CPhipps - Auto screenshot Variables | ||
323 | |||
324 | static int auto_shot_count, auto_shot_time; | ||
325 | static const char *auto_shot_fname; | ||
326 | |||
327 | // | ||
328 | // D_DoomLoop() | ||
329 | // | ||
330 | // Not a globally visible function, | ||
331 | // just included for source reference, | ||
332 | // called by D_DoomMain, never exits. | ||
333 | // Manages timing and IO, | ||
334 | // calls all ?_Responder, ?_Ticker, and ?_Drawer, | ||
335 | // calls I_GetTime, I_StartFrame, and I_StartTic | ||
336 | // | ||
337 | |||
338 | static void D_DoomLoop(void) | ||
339 | { | ||
340 | for (;;) | ||
341 | { | ||
342 | WasRenderedInTryRunTics = false; | ||
343 | // frame syncronous IO operations | ||
344 | I_StartFrame (); | ||
345 | |||
346 | if (ffmap == gamemap) ffmap = 0; | ||
347 | |||
348 | // process one or more tics | ||
349 | if (singletics) | ||
350 | { | ||
351 | I_StartTic (); | ||
352 | G_BuildTiccmd (&netcmds[consoleplayer][maketic%BACKUPTICS]); | ||
353 | if (advancedemo) | ||
354 | D_DoAdvanceDemo (); | ||
355 | M_Ticker (); | ||
356 | G_Ticker (); | ||
357 | P_Checksum(gametic); | ||
358 | gametic++; | ||
359 | maketic++; | ||
360 | } | ||
361 | else | ||
362 | TryRunTics (); // will run at least one tic | ||
363 | |||
364 | // killough 3/16/98: change consoleplayer to displayplayer | ||
365 | if (players[displayplayer].mo) // cph 2002/08/10 | ||
366 | S_UpdateSounds(players[displayplayer].mo);// move positional sounds | ||
367 | |||
368 | if (V_GetMode() == VID_MODEGL ? | ||
369 | !movement_smooth || !WasRenderedInTryRunTics : | ||
370 | !movement_smooth || !WasRenderedInTryRunTics || gamestate != wipegamestate | ||
371 | ) | ||
372 | { | ||
373 | // Update display, next frame, with current state. | ||
374 | D_Display(); | ||
375 | } | ||
376 | |||
377 | // CPhipps - auto screenshot | ||
378 | if (auto_shot_fname && !--auto_shot_count) { | ||
379 | auto_shot_count = auto_shot_time; | ||
380 | M_DoScreenShot(auto_shot_fname); | ||
381 | } | ||
382 | } | ||
383 | } | ||
384 | |||
385 | // | ||
386 | // DEMO LOOP | ||
387 | // | ||
388 | |||
389 | static int demosequence; // killough 5/2/98: made static | ||
390 | static int pagetic; | ||
391 | static const char *pagename; // CPhipps - const | ||
392 | |||
393 | // | ||
394 | // D_PageTicker | ||
395 | // Handles timing for warped projection | ||
396 | // | ||
397 | void D_PageTicker(void) | ||
398 | { | ||
399 | if (--pagetic < 0) | ||
400 | D_AdvanceDemo(); | ||
401 | } | ||
402 | |||
403 | // | ||
404 | // D_PageDrawer | ||
405 | // | ||
406 | static void D_PageDrawer(void) | ||
407 | { | ||
408 | // proff/nicolas 09/14/98 -- now stretchs bitmaps to fullscreen! | ||
409 | // CPhipps - updated for new patch drawing | ||
410 | // proff - added M_DrawCredits | ||
411 | if (pagename) | ||
412 | { | ||
413 | V_DrawNamePatch(0, 0, 0, pagename, CR_DEFAULT, VPT_STRETCH); | ||
414 | } | ||
415 | else | ||
416 | M_DrawCredits(); | ||
417 | } | ||
418 | |||
419 | // | ||
420 | // D_AdvanceDemo | ||
421 | // Called after each demo or intro demosequence finishes | ||
422 | // | ||
423 | void D_AdvanceDemo (void) | ||
424 | { | ||
425 | advancedemo = true; | ||
426 | } | ||
427 | |||
428 | /* killough 11/98: functions to perform demo sequences | ||
429 | * cphipps 10/99: constness fixes | ||
430 | */ | ||
431 | |||
432 | static void D_SetPageName(const char *name) | ||
433 | { | ||
434 | pagename = name; | ||
435 | } | ||
436 | |||
437 | static void D_DrawTitle1(const char *name) | ||
438 | { | ||
439 | S_StartMusic(mus_intro); | ||
440 | pagetic = (TICRATE*170)/35; | ||
441 | D_SetPageName(name); | ||
442 | } | ||
443 | |||
444 | static void D_DrawTitle2(const char *name) | ||
445 | { | ||
446 | S_StartMusic(mus_dm2ttl); | ||
447 | D_SetPageName(name); | ||
448 | } | ||
449 | |||
450 | /* killough 11/98: tabulate demo sequences | ||
451 | */ | ||
452 | |||
453 | static struct | ||
454 | { | ||
455 | void (*func)(const char *); | ||
456 | const char *name; | ||
457 | } const demostates[][4] = | ||
458 | { | ||
459 | { | ||
460 | {D_DrawTitle1, "TITLEPIC"}, | ||
461 | {D_DrawTitle1, "TITLEPIC"}, | ||
462 | {D_DrawTitle2, "TITLEPIC"}, | ||
463 | {D_DrawTitle1, "TITLEPIC"}, | ||
464 | }, | ||
465 | |||
466 | { | ||
467 | {G_DeferedPlayDemo, "demo1"}, | ||
468 | {G_DeferedPlayDemo, "demo1"}, | ||
469 | {G_DeferedPlayDemo, "demo1"}, | ||
470 | {G_DeferedPlayDemo, "demo1"}, | ||
471 | }, | ||
472 | { | ||
473 | {D_SetPageName, NULL}, | ||
474 | {D_SetPageName, NULL}, | ||
475 | {D_SetPageName, NULL}, | ||
476 | {D_SetPageName, NULL}, | ||
477 | }, | ||
478 | |||
479 | { | ||
480 | {G_DeferedPlayDemo, "demo2"}, | ||
481 | {G_DeferedPlayDemo, "demo2"}, | ||
482 | {G_DeferedPlayDemo, "demo2"}, | ||
483 | {G_DeferedPlayDemo, "demo2"}, | ||
484 | }, | ||
485 | |||
486 | { | ||
487 | {D_SetPageName, "HELP2"}, | ||
488 | {D_SetPageName, "HELP2"}, | ||
489 | {D_SetPageName, "CREDIT"}, | ||
490 | {D_DrawTitle1, "TITLEPIC"}, | ||
491 | }, | ||
492 | |||
493 | { | ||
494 | {G_DeferedPlayDemo, "demo3"}, | ||
495 | {G_DeferedPlayDemo, "demo3"}, | ||
496 | {G_DeferedPlayDemo, "demo3"}, | ||
497 | {G_DeferedPlayDemo, "demo3"}, | ||
498 | }, | ||
499 | |||
500 | { | ||
501 | {NULL}, | ||
502 | {NULL}, | ||
503 | {NULL}, | ||
504 | {D_SetPageName, "CREDIT"}, | ||
505 | }, | ||
506 | |||
507 | { | ||
508 | {NULL}, | ||
509 | {NULL}, | ||
510 | {NULL}, | ||
511 | {G_DeferedPlayDemo, "demo4"}, | ||
512 | }, | ||
513 | |||
514 | { | ||
515 | {NULL}, | ||
516 | {NULL}, | ||
517 | {NULL}, | ||
518 | {NULL}, | ||
519 | } | ||
520 | }; | ||
521 | |||
522 | /* | ||
523 | * This cycles through the demo sequences. | ||
524 | * killough 11/98: made table-driven | ||
525 | */ | ||
526 | |||
527 | void D_DoAdvanceDemo(void) | ||
528 | { | ||
529 | players[consoleplayer].playerstate = PST_LIVE; /* not reborn */ | ||
530 | advancedemo = usergame = paused = false; | ||
531 | gameaction = ga_nothing; | ||
532 | |||
533 | pagetic = TICRATE * 11; /* killough 11/98: default behavior */ | ||
534 | gamestate = GS_DEMOSCREEN; | ||
535 | |||
536 | if (netgame && !demoplayback) { | ||
537 | demosequence = 0; | ||
538 | } else | ||
539 | if (!demostates[++demosequence][gamemode].func) | ||
540 | demosequence = 0; | ||
541 | demostates[demosequence][gamemode].func | ||
542 | (demostates[demosequence][gamemode].name); | ||
543 | } | ||
544 | |||
545 | // | ||
546 | // D_StartTitle | ||
547 | // | ||
548 | void D_StartTitle (void) | ||
549 | { | ||
550 | gameaction = ga_nothing; | ||
551 | demosequence = -1; | ||
552 | D_AdvanceDemo(); | ||
553 | } | ||
554 | |||
555 | // | ||
556 | // D_AddFile | ||
557 | // | ||
558 | // Rewritten by Lee Killough | ||
559 | // | ||
560 | // Ty 08/29/98 - add source parm to indicate where this came from | ||
561 | // CPhipps - static, const char* parameter | ||
562 | // - source is an enum | ||
563 | // - modified to allocate & use new wadfiles array | ||
564 | void D_AddFile (const char *file, wad_source_t source) | ||
565 | { | ||
566 | char *gwa_filename=NULL; | ||
567 | |||
568 | wadfiles = realloc(wadfiles, sizeof(*wadfiles)*(numwadfiles+1)); | ||
569 | wadfiles[numwadfiles].name = | ||
570 | AddDefaultExtension(strcpy(malloc(strlen(file)+5), file), ".wad"); | ||
571 | wadfiles[numwadfiles].src = source; // Ty 08/29/98 | ||
572 | numwadfiles++; | ||
573 | // proff: automatically try to add the gwa files | ||
574 | // proff - moved from w_wad.c | ||
575 | gwa_filename=AddDefaultExtension(strcpy(malloc(strlen(file)+5), file), ".wad"); | ||
576 | if (strlen(gwa_filename)>4) | ||
577 | if (!strcasecmp(gwa_filename+(strlen(gwa_filename)-4),".wad")) | ||
578 | { | ||
579 | char *ext; | ||
580 | ext = &gwa_filename[strlen(gwa_filename)-4]; | ||
581 | ext[1] = 'g'; ext[2] = 'w'; ext[3] = 'a'; | ||
582 | wadfiles = realloc(wadfiles, sizeof(*wadfiles)*(numwadfiles+1)); | ||
583 | wadfiles[numwadfiles].name = gwa_filename; | ||
584 | wadfiles[numwadfiles].src = source; // Ty 08/29/98 | ||
585 | numwadfiles++; | ||
586 | } | ||
587 | } | ||
588 | |||
589 | // killough 10/98: support -dehout filename | ||
590 | // cph - made const, don't cache results | ||
591 | static const char *D_dehout(void) | ||
592 | { | ||
593 | int p = M_CheckParm("-dehout"); | ||
594 | if (!p) | ||
595 | p = M_CheckParm("-bexout"); | ||
596 | return (p && ++p < myargc ? myargv[p] : NULL); | ||
597 | } | ||
598 | |||
599 | // | ||
600 | // CheckIWAD | ||
601 | // | ||
602 | // Verify a file is indeed tagged as an IWAD | ||
603 | // Scan its lumps for levelnames and return gamemode as indicated | ||
604 | // Detect missing wolf levels in DOOM II | ||
605 | // | ||
606 | // The filename to check is passed in iwadname, the gamemode detected is | ||
607 | // returned in gmode, hassec returns the presence of secret levels | ||
608 | // | ||
609 | // jff 4/19/98 Add routine to test IWAD for validity and determine | ||
610 | // the gamemode from it. Also note if DOOM II, whether secret levels exist | ||
611 | // CPhipps - const char* for iwadname, made static | ||
612 | static void CheckIWAD(const char *iwadname,GameMode_t *gmode,boolean *hassec) | ||
613 | { | ||
614 | if ( !access (iwadname,R_OK) ) | ||
615 | { | ||
616 | int ud=0,rg=0,sw=0,cm=0,sc=0; | ||
617 | FILE* fp; | ||
618 | |||
619 | // Identify IWAD correctly | ||
620 | if ((fp = fopen(iwadname, "rb"))) | ||
621 | { | ||
622 | wadinfo_t header; | ||
623 | |||
624 | // read IWAD header | ||
625 | if (fread(&header, sizeof(header), 1, fp) == 1 && !strncmp(header.identification, "IWAD", 4)) | ||
626 | { | ||
627 | size_t length; | ||
628 | filelump_t *fileinfo; | ||
629 | |||
630 | // read IWAD directory | ||
631 | header.numlumps = LONG(header.numlumps); | ||
632 | header.infotableofs = LONG(header.infotableofs); | ||
633 | length = header.numlumps; | ||
634 | fileinfo = malloc(length*sizeof(filelump_t)); | ||
635 | if (fseek (fp, header.infotableofs, SEEK_SET) || | ||
636 | fread (fileinfo, sizeof(filelump_t), length, fp) != length || | ||
637 | fclose(fp)) | ||
638 | I_Error("CheckIWAD: failed to read directory %s",iwadname); | ||
639 | |||
640 | // scan directory for levelname lumps | ||
641 | while (length--) | ||
642 | if (fileinfo[length].name[0] == 'E' && | ||
643 | fileinfo[length].name[2] == 'M' && | ||
644 | fileinfo[length].name[4] == 0) | ||
645 | { | ||
646 | if (fileinfo[length].name[1] == '4') | ||
647 | ++ud; | ||
648 | else if (fileinfo[length].name[1] == '3') | ||
649 | ++rg; | ||
650 | else if (fileinfo[length].name[1] == '2') | ||
651 | ++rg; | ||
652 | else if (fileinfo[length].name[1] == '1') | ||
653 | ++sw; | ||
654 | } | ||
655 | else if (fileinfo[length].name[0] == 'M' && | ||
656 | fileinfo[length].name[1] == 'A' && | ||
657 | fileinfo[length].name[2] == 'P' && | ||
658 | fileinfo[length].name[5] == 0) | ||
659 | { | ||
660 | ++cm; | ||
661 | if (fileinfo[length].name[3] == '3') | ||
662 | if (fileinfo[length].name[4] == '1' || | ||
663 | fileinfo[length].name[4] == '2') | ||
664 | ++sc; | ||
665 | } | ||
666 | |||
667 | free(fileinfo); | ||
668 | } | ||
669 | else // missing IWAD tag in header | ||
670 | I_Error("CheckIWAD: IWAD tag %s not present", iwadname); | ||
671 | } | ||
672 | else // error from open call | ||
673 | I_Error("CheckIWAD: Can't open IWAD %s", iwadname); | ||
674 | |||
675 | // Determine game mode from levels present | ||
676 | // Must be a full set for whichever mode is present | ||
677 | // Lack of wolf-3d levels also detected here | ||
678 | |||
679 | *gmode = indetermined; | ||
680 | *hassec = false; | ||
681 | if (cm>=30) | ||
682 | { | ||
683 | *gmode = commercial; | ||
684 | *hassec = sc>=2; | ||
685 | } | ||
686 | else if (ud>=9) | ||
687 | *gmode = retail; | ||
688 | else if (rg>=18) | ||
689 | *gmode = registered; | ||
690 | else if (sw>=9) | ||
691 | *gmode = shareware; | ||
692 | } | ||
693 | else // error from access call | ||
694 | I_Error("CheckIWAD: IWAD %s not readable", iwadname); | ||
695 | } | ||
696 | |||
697 | |||
698 | |||
699 | // NormalizeSlashes | ||
700 | // | ||
701 | // Remove trailing slashes, translate backslashes to slashes | ||
702 | // The string to normalize is passed and returned in str | ||
703 | // | ||
704 | // jff 4/19/98 Make killoughs slash fixer a subroutine | ||
705 | // | ||
706 | static void NormalizeSlashes(char *str) | ||
707 | { | ||
708 | int l; | ||
709 | |||
710 | // killough 1/18/98: Neater / \ handling. | ||
711 | // Remove trailing / or \ to prevent // /\ \/ \\, and change \ to / | ||
712 | |||
713 | if (!str || !(l = strlen(str))) | ||
714 | return; | ||
715 | if (str[--l]=='/' || str[l]=='\\') // killough 1/18/98 | ||
716 | str[l]=0; | ||
717 | while (l--) | ||
718 | if (str[l]=='\\') | ||
719 | str[l]='/'; | ||
720 | } | ||
721 | |||
722 | /* | ||
723 | * FindIWADFIle | ||
724 | * | ||
725 | * Search for one of the standard IWADs | ||
726 | * CPhipps - static, proper prototype | ||
727 | * - 12/1999 - rewritten to use I_FindFile | ||
728 | */ | ||
729 | static char *FindIWADFile(void) | ||
730 | { | ||
731 | int i; | ||
732 | char * iwad = NULL; | ||
733 | |||
734 | i = M_CheckParm("-iwad"); | ||
735 | if (i && (++i < myargc)) { | ||
736 | iwad = I_FindFile(myargv[i], ".wad"); | ||
737 | } else { | ||
738 | for (i=0; !iwad && i<nstandard_iwads; i++) | ||
739 | iwad = I_FindFile(standard_iwads[i], ".wad"); | ||
740 | } | ||
741 | return iwad; | ||
742 | } | ||
743 | |||
744 | // | ||
745 | // IdentifyVersion | ||
746 | // | ||
747 | // Set the location of the defaults file and the savegame root | ||
748 | // Locate and validate an IWAD file | ||
749 | // Determine gamemode from the IWAD | ||
750 | // | ||
751 | // supports IWADs with custom names. Also allows the -iwad parameter to | ||
752 | // specify which iwad is being searched for if several exist in one dir. | ||
753 | // The -iwad parm may specify: | ||
754 | // | ||
755 | // 1) a specific pathname, which must exist (.wad optional) | ||
756 | // 2) or a directory, which must contain a standard IWAD, | ||
757 | // 3) or a filename, which must be found in one of the standard places: | ||
758 | // a) current dir, | ||
759 | // b) exe dir | ||
760 | // c) $DOOMWADDIR | ||
761 | // d) or $HOME | ||
762 | // | ||
763 | // jff 4/19/98 rewritten to use a more advanced search algorithm | ||
764 | |||
765 | static void IdentifyVersion (void) | ||
766 | { | ||
767 | int i; //jff 3/24/98 index of args on commandline | ||
768 | struct stat sbuf; //jff 3/24/98 used to test save path for existence | ||
769 | char *iwad; | ||
770 | |||
771 | // set save path to -save parm or current dir | ||
772 | |||
773 | //jff 3/27/98 default to current dir | ||
774 | //V.Aguilar (5/30/99): In LiNUX, default to $HOME/.lxdoom | ||
775 | { | ||
776 | // CPhipps - use DOOMSAVEDIR if defined | ||
777 | char* p = getenv("DOOMSAVEDIR"); | ||
778 | |||
779 | if (p != NULL) | ||
780 | if (strlen(p) > PATH_MAX-12) p = NULL; | ||
781 | |||
782 | strcpy(basesavegame,(p == NULL) ? I_DoomExeDir() : p); | ||
783 | } | ||
784 | if ((i=M_CheckParm("-save")) && i<myargc-1) //jff 3/24/98 if -save present | ||
785 | { | ||
786 | if (!stat(myargv[i+1],&sbuf) && S_ISDIR(sbuf.st_mode)) // and is a dir | ||
787 | { | ||
788 | strcpy(basesavegame,myargv[i+1]); //jff 3/24/98 use that for savegame | ||
789 | NormalizeSlashes(basesavegame); //jff 9/22/98 fix c:\ not working | ||
790 | } | ||
791 | //jff 9/3/98 use logical output routine | ||
792 | else lprintf(LO_ERROR,"Error: -save path does not exist, using %s\n", basesavegame); | ||
793 | } | ||
794 | |||
795 | // locate the IWAD and determine game mode from it | ||
796 | |||
797 | iwad = FindIWADFile(); | ||
798 | |||
799 | #if (defined(GL_DOOM) && defined(_DEBUG)) | ||
800 | // proff 11/99: used for debugging | ||
801 | { | ||
802 | FILE *f; | ||
803 | f=fopen("levelinfo.txt","w"); | ||
804 | if (f) | ||
805 | { | ||
806 | fprintf(f,"%s\n",iwad); | ||
807 | fclose(f); | ||
808 | } | ||
809 | } | ||
810 | #endif | ||
811 | |||
812 | if (iwad && *iwad) | ||
813 | { | ||
814 | //jff 9/3/98 use logical output routine | ||
815 | lprintf(LO_CONFIRM,"IWAD found: %s\n",iwad); //jff 4/20/98 print only if found | ||
816 | CheckIWAD(iwad,&gamemode,&haswolflevels); | ||
817 | |||
818 | /* jff 8/23/98 set gamemission global appropriately in all cases | ||
819 | * cphipps 12/1999 - no version output here, leave that to the caller | ||
820 | */ | ||
821 | switch(gamemode) | ||
822 | { | ||
823 | case retail: | ||
824 | case registered: | ||
825 | case shareware: | ||
826 | gamemission = doom; | ||
827 | break; | ||
828 | case commercial: | ||
829 | i = strlen(iwad); | ||
830 | gamemission = doom2; | ||
831 | if (i>=10 && !strnicmp(iwad+i-10,"doom2f.wad",10)) | ||
832 | language=french; | ||
833 | else if (i>=7 && !strnicmp(iwad+i-7,"tnt.wad",7)) | ||
834 | gamemission = pack_tnt; | ||
835 | else if (i>=12 && !strnicmp(iwad+i-12,"plutonia.wad",12)) | ||
836 | gamemission = pack_plut; | ||
837 | break; | ||
838 | default: | ||
839 | gamemission = none; | ||
840 | break; | ||
841 | } | ||
842 | if (gamemode == indetermined) | ||
843 | //jff 9/3/98 use logical output routine | ||
844 | lprintf(LO_WARN,"Unknown Game Version, may not work\n"); | ||
845 | D_AddFile(iwad,source_iwad); | ||
846 | free(iwad); | ||
847 | } | ||
848 | else | ||
849 | I_Error("IdentifyVersion: IWAD not found\n"); | ||
850 | } | ||
851 | |||
852 | |||
853 | |||
854 | // killough 5/3/98: old code removed | ||
855 | // | ||
856 | // Find a Response File | ||
857 | // | ||
858 | |||
859 | #define MAXARGVS 100 | ||
860 | |||
861 | static void FindResponseFile (void) | ||
862 | { | ||
863 | int i; | ||
864 | |||
865 | for (i = 1;i < myargc;i++) | ||
866 | if (myargv[i][0] == '@') | ||
867 | { | ||
868 | int size; | ||
869 | int index; | ||
870 | int indexinfile; | ||
871 | byte *file = NULL; | ||
872 | const char **moreargs = malloc(myargc * sizeof(const char*)); | ||
873 | const char **newargv; | ||
874 | // proff 04/05/2000: Added for searching responsefile | ||
875 | char fname[PATH_MAX+1]; | ||
876 | |||
877 | strcpy(fname,&myargv[i][1]); | ||
878 | AddDefaultExtension(fname,".rsp"); | ||
879 | |||
880 | // READ THE RESPONSE FILE INTO MEMORY | ||
881 | // proff 04/05/2000: changed for searching responsefile | ||
882 | // cph 2002/08/09 - use M_ReadFile for simplicity | ||
883 | size = M_ReadFile(fname, &file); | ||
884 | // proff 04/05/2000: Added for searching responsefile | ||
885 | if (size < 0) | ||
886 | { | ||
887 | strcat(strcpy(fname,I_DoomExeDir()),&myargv[i][1]); | ||
888 | AddDefaultExtension(fname,".rsp"); | ||
889 | size = M_ReadFile(fname, &file); | ||
890 | } | ||
891 | if (size < 0) | ||
892 | { | ||
893 | /* proff 04/05/2000: Changed from LO_FATAL | ||
894 | * proff 04/05/2000: Simply removed the exit(1); | ||
895 | * cph - made fatal, don't drop through and SEGV | ||
896 | */ | ||
897 | I_Error("No such response file: %s",fname); | ||
898 | } | ||
899 | //jff 9/3/98 use logical output routine | ||
900 | lprintf(LO_CONFIRM,"Found response file %s\n",fname); | ||
901 | // proff 04/05/2000: Added check for empty rsp file | ||
902 | if (size<=0) | ||
903 | { | ||
904 | int k; | ||
905 | lprintf(LO_ERROR,"\nResponse file empty!\n"); | ||
906 | |||
907 | newargv = calloc(sizeof(char *),MAXARGVS); | ||
908 | newargv[0] = myargv[0]; | ||
909 | for (k = 1,index = 1;k < myargc;k++) | ||
910 | { | ||
911 | if (i!=k) | ||
912 | newargv[index++] = myargv[k]; | ||
913 | } | ||
914 | myargc = index; myargv = newargv; | ||
915 | return; | ||
916 | } | ||
917 | |||
918 | // KEEP ALL CMDLINE ARGS FOLLOWING @RESPONSEFILE ARG | ||
919 | memcpy((void *)moreargs,&myargv[i+1],(index = myargc - i - 1) * sizeof(myargv[0])); | ||
920 | |||
921 | { | ||
922 | const char *firstargv = myargv[0]; | ||
923 | newargv = calloc(sizeof(char *),MAXARGVS); | ||
924 | newargv[0] = firstargv; | ||
925 | } | ||
926 | |||
927 | { | ||
928 | byte *infile = file; | ||
929 | indexinfile = 0; | ||
930 | indexinfile++; // SKIP PAST ARGV[0] (KEEP IT) | ||
931 | do { | ||
932 | while (size > 0 && isspace(*infile)) { infile++; size--; } | ||
933 | if (size > 0) { | ||
934 | char *s = malloc(size+1); | ||
935 | char *p = s; | ||
936 | int quoted = 0; | ||
937 | |||
938 | while (size > 0) { | ||
939 | // Whitespace terminates the token unless quoted | ||
940 | if (!quoted && isspace(*infile)) break; | ||
941 | if (*infile == '\"') { | ||
942 | // Quotes are removed but remembered | ||
943 | infile++; size--; quoted ^= 1; | ||
944 | } else { | ||
945 | *p++ = *infile++; size--; | ||
946 | } | ||
947 | } | ||
948 | if (quoted) I_Error("Runaway quoted string in response file"); | ||
949 | |||
950 | // Terminate string, realloc and add to argv | ||
951 | *p = 0; | ||
952 | newargv[indexinfile++] = realloc(s,strlen(s)+1); | ||
953 | } | ||
954 | } while(size > 0); | ||
955 | } | ||
956 | free(file); | ||
957 | |||
958 | memcpy((void *)&newargv[indexinfile],moreargs,index*sizeof(moreargs[0])); | ||
959 | free((void *)moreargs); | ||
960 | |||
961 | myargc = indexinfile+index; myargv = newargv; | ||
962 | |||
963 | // DISPLAY ARGS | ||
964 | //jff 9/3/98 use logical output routine | ||
965 | lprintf(LO_CONFIRM,"%d command-line args:\n",myargc); | ||
966 | for (index=1;index<myargc;index++) | ||
967 | //jff 9/3/98 use logical output routine | ||
968 | lprintf(LO_CONFIRM,"%s\n",myargv[index]); | ||
969 | break; | ||
970 | } | ||
971 | } | ||
972 | |||
973 | // | ||
974 | // DoLooseFiles | ||
975 | // | ||
976 | // Take any file names on the command line before the first switch parm | ||
977 | // and insert the appropriate -file, -deh or -playdemo switch in front | ||
978 | // of them. | ||
979 | // | ||
980 | // Note that more than one -file, etc. entry on the command line won't | ||
981 | // work, so we have to go get all the valid ones if any that show up | ||
982 | // after the loose ones. This means that boom fred.wad -file wilma | ||
983 | // will still load fred.wad and wilma.wad, in that order. | ||
984 | // The response file code kludges up its own version of myargv[] and | ||
985 | // unfortunately we have to do the same here because that kludge only | ||
986 | // happens if there _is_ a response file. Truth is, it's more likely | ||
987 | // that there will be a need to do one or the other so it probably | ||
988 | // isn't important. We'll point off to the original argv[], or the | ||
989 | // area allocated in FindResponseFile, or our own areas from strdups. | ||
990 | // | ||
991 | // CPhipps - OUCH! Writing into *myargv is too dodgy, damn | ||
992 | |||
993 | static void DoLooseFiles(void) | ||
994 | { | ||
995 | char *wads[MAXARGVS]; // store the respective loose filenames | ||
996 | char *lmps[MAXARGVS]; | ||
997 | char *dehs[MAXARGVS]; | ||
998 | int wadcount = 0; // count the loose filenames | ||
999 | int lmpcount = 0; | ||
1000 | int dehcount = 0; | ||
1001 | int i,j,p; | ||
1002 | const char **tmyargv; // use these to recreate the argv array | ||
1003 | int tmyargc; | ||
1004 | boolean skip[MAXARGVS]; // CPhipps - should these be skipped at the end | ||
1005 | |||
1006 | for (i=0; i<MAXARGVS; i++) | ||
1007 | skip[i] = false; | ||
1008 | |||
1009 | for (i=1;i<myargc;i++) | ||
1010 | { | ||
1011 | if (*myargv[i] == '-') break; // quit at first switch | ||
1012 | |||
1013 | // so now we must have a loose file. Find out what kind and store it. | ||
1014 | j = strlen(myargv[i]); | ||
1015 | if (!stricmp(&myargv[i][j-4],".wad")) | ||
1016 | wads[wadcount++] = strdup(myargv[i]); | ||
1017 | if (!stricmp(&myargv[i][j-4],".lmp")) | ||
1018 | lmps[lmpcount++] = strdup(myargv[i]); | ||
1019 | if (!stricmp(&myargv[i][j-4],".deh")) | ||
1020 | dehs[dehcount++] = strdup(myargv[i]); | ||
1021 | if (!stricmp(&myargv[i][j-4],".bex")) | ||
1022 | dehs[dehcount++] = strdup(myargv[i]); | ||
1023 | if (myargv[i][j-4] != '.') // assume wad if no extension | ||
1024 | wads[wadcount++] = strdup(myargv[i]); | ||
1025 | skip[i] = true; // nuke that entry so it won't repeat later | ||
1026 | } | ||
1027 | |||
1028 | // Now, if we didn't find any loose files, we can just leave. | ||
1029 | if (wadcount+lmpcount+dehcount == 0) return; // ******* early return **** | ||
1030 | |||
1031 | if ((p = M_CheckParm ("-file"))) | ||
1032 | { | ||
1033 | skip[p] = true; // nuke the entry | ||
1034 | while (++p != myargc && *myargv[p] != '-') | ||
1035 | { | ||
1036 | wads[wadcount++] = strdup(myargv[p]); | ||
1037 | skip[p] = true; // null any we find and save | ||
1038 | } | ||
1039 | } | ||
1040 | |||
1041 | if ((p = M_CheckParm ("-deh"))) | ||
1042 | { | ||
1043 | skip[p] = true; // nuke the entry | ||
1044 | while (++p != myargc && *myargv[p] != '-') | ||
1045 | { | ||
1046 | dehs[dehcount++] = strdup(myargv[p]); | ||
1047 | skip[p] = true; // null any we find and save | ||
1048 | } | ||
1049 | } | ||
1050 | |||
1051 | if ((p = M_CheckParm ("-playdemo"))) | ||
1052 | { | ||
1053 | skip[p] = true; // nuke the entry | ||
1054 | while (++p != myargc && *myargv[p] != '-') | ||
1055 | { | ||
1056 | lmps[lmpcount++] = strdup(myargv[p]); | ||
1057 | skip[p] = true; // null any we find and save | ||
1058 | } | ||
1059 | } | ||
1060 | |||
1061 | // Now go back and redo the whole myargv array with our stuff in it. | ||
1062 | // First, create a new myargv array to copy into | ||
1063 | tmyargv = calloc(sizeof(char *),MAXARGVS); | ||
1064 | tmyargv[0] = myargv[0]; // invocation | ||
1065 | tmyargc = 1; | ||
1066 | |||
1067 | // put our stuff into it | ||
1068 | if (wadcount > 0) | ||
1069 | { | ||
1070 | tmyargv[tmyargc++] = strdup("-file"); // put the switch in | ||
1071 | for (i=0;i<wadcount;) | ||
1072 | tmyargv[tmyargc++] = wads[i++]; // allocated by strdup above | ||
1073 | } | ||
1074 | |||
1075 | // for -deh | ||
1076 | if (dehcount > 0) | ||
1077 | { | ||
1078 | tmyargv[tmyargc++] = strdup("-deh"); | ||
1079 | for (i=0;i<dehcount;) | ||
1080 | tmyargv[tmyargc++] = dehs[i++]; | ||
1081 | } | ||
1082 | |||
1083 | // for -playdemo | ||
1084 | if (lmpcount > 0) | ||
1085 | { | ||
1086 | tmyargv[tmyargc++] = strdup("-playdemo"); | ||
1087 | for (i=0;i<lmpcount;) | ||
1088 | tmyargv[tmyargc++] = lmps[i++]; | ||
1089 | } | ||
1090 | |||
1091 | // then copy everything that's there now | ||
1092 | for (i=1;i<myargc;i++) | ||
1093 | { | ||
1094 | if (!skip[i]) // skip any zapped entries | ||
1095 | tmyargv[tmyargc++] = myargv[i]; // pointers are still valid | ||
1096 | } | ||
1097 | // now make the global variables point to our array | ||
1098 | myargv = tmyargv; | ||
1099 | myargc = tmyargc; | ||
1100 | } | ||
1101 | |||
1102 | /* cph - MBF-like wad/deh/bex autoload code */ | ||
1103 | const char *wad_files[MAXLOADFILES], *deh_files[MAXLOADFILES]; | ||
1104 | |||
1105 | // CPhipps - misc screen stuff | ||
1106 | unsigned int desired_screenwidth, desired_screenheight; | ||
1107 | |||
1108 | static void L_SetupConsoleMasks(void) { | ||
1109 | int p; | ||
1110 | int i; | ||
1111 | const char *cena="ICWEFDA",*pos; //jff 9/3/98 use this for parsing console masks // CPhipps - const char*'s | ||
1112 | |||
1113 | //jff 9/3/98 get mask for console output filter | ||
1114 | if ((p = M_CheckParm ("-cout"))) { | ||
1115 | lprintf(LO_DEBUG, "mask for stdout console output: "); | ||
1116 | if (++p != myargc && *myargv[p] != '-') | ||
1117 | for (i=0,cons_output_mask=0;(size_t)i<strlen(myargv[p]);i++) | ||
1118 | if ((pos = strchr(cena,toupper(myargv[p][i])))) { | ||
1119 | cons_output_mask |= (1<<(pos-cena)); | ||
1120 | lprintf(LO_DEBUG, "%c", toupper(myargv[p][i])); | ||
1121 | } | ||
1122 | lprintf(LO_DEBUG, "\n"); | ||
1123 | } | ||
1124 | |||
1125 | //jff 9/3/98 get mask for redirected console error filter | ||
1126 | if ((p = M_CheckParm ("-cerr"))) { | ||
1127 | lprintf(LO_DEBUG, "mask for stderr console output: "); | ||
1128 | if (++p != myargc && *myargv[p] != '-') | ||
1129 | for (i=0,cons_error_mask=0;(size_t)i<strlen(myargv[p]);i++) | ||
1130 | if ((pos = strchr(cena,toupper(myargv[p][i])))) { | ||
1131 | cons_error_mask |= (1<<(pos-cena)); | ||
1132 | lprintf(LO_DEBUG, "%c", toupper(myargv[p][i])); | ||
1133 | } | ||
1134 | lprintf(LO_DEBUG, "\n"); | ||
1135 | } | ||
1136 | } | ||
1137 | |||
1138 | // | ||
1139 | // D_DoomMainSetup | ||
1140 | // | ||
1141 | // CPhipps - the old contents of D_DoomMain, but moved out of the main | ||
1142 | // line of execution so its stack space can be freed | ||
1143 | |||
1144 | static void D_DoomMainSetup(void) | ||
1145 | { | ||
1146 | int p,slot; | ||
1147 | |||
1148 | L_SetupConsoleMasks(); | ||
1149 | |||
1150 | setbuf(stdout,NULL); | ||
1151 | |||
1152 | // proff 04/05/2000: Added support for include response files | ||
1153 | /* proff 2001/7/1 - Moved up, so -config can be in response files */ | ||
1154 | { | ||
1155 | boolean rsp_found; | ||
1156 | int i; | ||
1157 | |||
1158 | do { | ||
1159 | rsp_found=false; | ||
1160 | for (i=0; i<myargc; i++) | ||
1161 | if (myargv[i][0]=='@') | ||
1162 | rsp_found=true; | ||
1163 | FindResponseFile(); | ||
1164 | } while (rsp_found==true); | ||
1165 | } | ||
1166 | |||
1167 | lprintf(LO_INFO,"M_LoadDefaults: Load system defaults.\n"); | ||
1168 | M_LoadDefaults(); // load before initing other systems | ||
1169 | |||
1170 | // figgi 09/18/00-- added switch to force classic bsp nodes | ||
1171 | if (M_CheckParm ("-forceoldbsp")) | ||
1172 | { | ||
1173 | extern boolean forceOldBsp; | ||
1174 | forceOldBsp = true; | ||
1175 | } | ||
1176 | |||
1177 | DoLooseFiles(); // Ty 08/29/98 - handle "loose" files on command line | ||
1178 | IdentifyVersion(); | ||
1179 | |||
1180 | // e6y: DEH files preloaded in wrong order | ||
1181 | // http://sourceforge.net/tracker/index.php?func=detail&aid=1418158&group_id=148658&atid=772943 | ||
1182 | // The dachaked stuff has been moved below an autoload | ||
1183 | |||
1184 | // jff 1/24/98 set both working and command line value of play parms | ||
1185 | nomonsters = clnomonsters = M_CheckParm ("-nomonsters"); | ||
1186 | respawnparm = clrespawnparm = M_CheckParm ("-respawn"); | ||
1187 | fastparm = clfastparm = M_CheckParm ("-fast"); | ||
1188 | // jff 1/24/98 end of set to both working and command line value | ||
1189 | |||
1190 | devparm = M_CheckParm ("-devparm"); | ||
1191 | |||
1192 | if (M_CheckParm ("-altdeath")) | ||
1193 | deathmatch = 2; | ||
1194 | else | ||
1195 | if (M_CheckParm ("-deathmatch")) | ||
1196 | deathmatch = 1; | ||
1197 | |||
1198 | { | ||
1199 | // CPhipps - localise title variable | ||
1200 | // print title for every printed line | ||
1201 | // cph - code cleaned and made smaller | ||
1202 | const char* doomverstr; | ||
1203 | |||
1204 | switch ( gamemode ) { | ||
1205 | case retail: | ||
1206 | doomverstr = "The Ultimate DOOM"; | ||
1207 | break; | ||
1208 | case shareware: | ||
1209 | doomverstr = "DOOM Shareware"; | ||
1210 | break; | ||
1211 | case registered: | ||
1212 | doomverstr = "DOOM Registered"; | ||
1213 | break; | ||
1214 | case commercial: // Ty 08/27/98 - fixed gamemode vs gamemission | ||
1215 | switch (gamemission) | ||
1216 | { | ||
1217 | case pack_plut: | ||
1218 | doomverstr = "DOOM 2: Plutonia Experiment"; | ||
1219 | break; | ||
1220 | case pack_tnt: | ||
1221 | doomverstr = "DOOM 2: TNT - Evilution"; | ||
1222 | break; | ||
1223 | default: | ||
1224 | doomverstr = "DOOM 2: Hell on Earth"; | ||
1225 | break; | ||
1226 | } | ||
1227 | break; | ||
1228 | default: | ||
1229 | doomverstr = "Public DOOM"; | ||
1230 | break; | ||
1231 | } | ||
1232 | |||
1233 | /* cphipps - the main display. This shows the build date, copyright, and game type */ | ||
1234 | lprintf(LO_ALWAYS,"PrBoom (built %s), playing: %s\n" | ||
1235 | "PrBoom is released under the GNU General Public license v2.0.\n" | ||
1236 | "You are welcome to redistribute it under certain conditions.\n" | ||
1237 | "It comes with ABSOLUTELY NO WARRANTY. See the file COPYING for details.\n", | ||
1238 | version_date, doomverstr); | ||
1239 | } | ||
1240 | |||
1241 | if (devparm) | ||
1242 | //jff 9/3/98 use logical output routine | ||
1243 | lprintf(LO_CONFIRM,"%s",D_DEVSTR); | ||
1244 | |||
1245 | // turbo option | ||
1246 | if ((p=M_CheckParm ("-turbo"))) | ||
1247 | { | ||
1248 | int scale = 200; | ||
1249 | extern int forwardmove[2]; | ||
1250 | extern int sidemove[2]; | ||
1251 | |||
1252 | if (p<myargc-1) | ||
1253 | scale = atoi(myargv[p+1]); | ||
1254 | if (scale < 10) | ||
1255 | scale = 10; | ||
1256 | if (scale > 400) | ||
1257 | scale = 400; | ||
1258 | //jff 9/3/98 use logical output routine | ||
1259 | lprintf (LO_CONFIRM,"turbo scale: %i%%\n",scale); | ||
1260 | forwardmove[0] = forwardmove[0]*scale/100; | ||
1261 | forwardmove[1] = forwardmove[1]*scale/100; | ||
1262 | sidemove[0] = sidemove[0]*scale/100; | ||
1263 | sidemove[1] = sidemove[1]*scale/100; | ||
1264 | } | ||
1265 | |||
1266 | modifiedgame = false; | ||
1267 | |||
1268 | // get skill / episode / map from parms | ||
1269 | |||
1270 | startskill = sk_none; // jff 3/24/98 was sk_medium, just note not picked | ||
1271 | startepisode = 1; | ||
1272 | startmap = 1; | ||
1273 | autostart = false; | ||
1274 | |||
1275 | if ((p = M_CheckParm ("-skill")) && p < myargc-1) | ||
1276 | { | ||
1277 | startskill = myargv[p+1][0]-'1'; | ||
1278 | autostart = true; | ||
1279 | } | ||
1280 | |||
1281 | if ((p = M_CheckParm ("-episode")) && p < myargc-1) | ||
1282 | { | ||
1283 | startepisode = myargv[p+1][0]-'0'; | ||
1284 | startmap = 1; | ||
1285 | autostart = true; | ||
1286 | } | ||
1287 | |||
1288 | if ((p = M_CheckParm ("-timer")) && p < myargc-1 && deathmatch) | ||
1289 | { | ||
1290 | int time = atoi(myargv[p+1]); | ||
1291 | //jff 9/3/98 use logical output routine | ||
1292 | lprintf(LO_CONFIRM,"Levels will end after %d minute%s.\n", time, time>1 ? "s" : ""); | ||
1293 | } | ||
1294 | |||
1295 | if ((p = M_CheckParm ("-avg")) && p < myargc-1 && deathmatch) | ||
1296 | //jff 9/3/98 use logical output routine | ||
1297 | lprintf(LO_CONFIRM,"Austin Virtual Gaming: Levels will end after 20 minutes\n"); | ||
1298 | |||
1299 | if ((p = M_CheckParm ("-warp")) || // killough 5/2/98 | ||
1300 | (p = M_CheckParm ("-wart"))) | ||
1301 | // Ty 08/29/98 - moved this check later so we can have -warp alone: && p < myargc-1) | ||
1302 | { | ||
1303 | startmap = 0; // Ty 08/29/98 - allow "-warp x" to go to first map in wad(s) | ||
1304 | autostart = true; // Ty 08/29/98 - move outside the decision tree | ||
1305 | if (gamemode == commercial) | ||
1306 | { | ||
1307 | if (p < myargc-1) | ||
1308 | startmap = atoi(myargv[p+1]); // Ty 08/29/98 - add test if last parm | ||
1309 | } | ||
1310 | else // 1/25/98 killough: fix -warp xxx from crashing Doom 1 / UD | ||
1311 | { | ||
1312 | if (p < myargc-2) | ||
1313 | { | ||
1314 | startepisode = atoi(myargv[++p]); | ||
1315 | startmap = atoi(myargv[p+1]); | ||
1316 | } | ||
1317 | } | ||
1318 | } | ||
1319 | // Ty 08/29/98 - later we'll check for startmap=0 and autostart=true | ||
1320 | // as a special case that -warp * was used. Actually -warp with any | ||
1321 | // non-numeric will do that but we'll only document "*" | ||
1322 | |||
1323 | //jff 1/22/98 add command line parms to disable sound and music | ||
1324 | { | ||
1325 | int nosound = M_CheckParm("-nosound"); | ||
1326 | nomusicparm = nosound || M_CheckParm("-nomusic"); | ||
1327 | nosfxparm = nosound || M_CheckParm("-nosfx"); | ||
1328 | } | ||
1329 | //jff end of sound/music command line parms | ||
1330 | |||
1331 | // killough 3/2/98: allow -nodraw -noblit generally | ||
1332 | nodrawers = M_CheckParm ("-nodraw"); | ||
1333 | noblit = M_CheckParm ("-noblit"); | ||
1334 | |||
1335 | //proff 11/22/98: Added setting of viewangleoffset | ||
1336 | p = M_CheckParm("-viewangle"); | ||
1337 | if (p) | ||
1338 | { | ||
1339 | viewangleoffset = atoi(myargv[p+1]); | ||
1340 | viewangleoffset = viewangleoffset<0 ? 0 : (viewangleoffset>7 ? 7 : viewangleoffset); | ||
1341 | viewangleoffset = (8-viewangleoffset) * ANG45; | ||
1342 | } | ||
1343 | |||
1344 | // init subsystems | ||
1345 | |||
1346 | G_ReloadDefaults(); // killough 3/4/98: set defaults just loaded. | ||
1347 | // jff 3/24/98 this sets startskill if it was -1 | ||
1348 | |||
1349 | // Video stuff | ||
1350 | if ((p = M_CheckParm("-width"))) | ||
1351 | if (myargv[p+1]) | ||
1352 | desired_screenwidth = atoi(myargv[p+1]); | ||
1353 | |||
1354 | if ((p = M_CheckParm("-height"))) | ||
1355 | if (myargv[p+1]) | ||
1356 | desired_screenheight = atoi(myargv[p+1]); | ||
1357 | |||
1358 | if ((p = M_CheckParm("-fullscreen"))) | ||
1359 | use_fullscreen = 1; | ||
1360 | |||
1361 | if ((p = M_CheckParm("-nofullscreen"))) | ||
1362 | use_fullscreen = 0; | ||
1363 | |||
1364 | // e6y | ||
1365 | // New command-line options for setting a window (-window) | ||
1366 | // or fullscreen (-nowindow) mode temporarily which is not saved in cfg. | ||
1367 | // It works like "-geom" switch | ||
1368 | desired_fullscreen = use_fullscreen; | ||
1369 | if ((p = M_CheckParm("-window"))) | ||
1370 | desired_fullscreen = 0; | ||
1371 | |||
1372 | if ((p = M_CheckParm("-nowindow"))) | ||
1373 | desired_fullscreen = 1; | ||
1374 | |||
1375 | { // -geometry handling, change screen size for this session only | ||
1376 | // e6y: new code by me | ||
1377 | int w, h; | ||
1378 | |||
1379 | if (!(p = M_CheckParm("-geom"))) | ||
1380 | p = M_CheckParm("-geometry"); | ||
1381 | |||
1382 | if (!(p && (p+1<myargc) && sscanf(myargv[p+1], "%dx%d", &w, &h) == 2)) | ||
1383 | { | ||
1384 | w = desired_screenwidth; | ||
1385 | h = desired_screenheight; | ||
1386 | } | ||
1387 | I_CalculateRes(w, h); | ||
1388 | } | ||
1389 | |||
1390 | #ifdef GL_DOOM | ||
1391 | // proff 04/05/2000: for GL-specific switches | ||
1392 | gld_InitCommandLine(); | ||
1393 | #endif | ||
1394 | |||
1395 | //jff 9/3/98 use logical output routine | ||
1396 | lprintf(LO_INFO,"V_Init: allocate screens.\n"); | ||
1397 | V_Init(); | ||
1398 | |||
1399 | // CPhipps - autoloading of wads | ||
1400 | // Designed to be general, instead of specific to boomlump.wad | ||
1401 | // Some people might find this useful | ||
1402 | // cph - support MBF -noload parameter | ||
1403 | if (!M_CheckParm("-noload")) { | ||
1404 | int i; | ||
1405 | |||
1406 | for (i=0; i<MAXLOADFILES*2; i++) { | ||
1407 | const char *fname = (i < MAXLOADFILES) ? wad_files[i] | ||
1408 | : deh_files[i - MAXLOADFILES]; | ||
1409 | char *fpath; | ||
1410 | |||
1411 | if (!(fname && *fname)) continue; | ||
1412 | // Filename is now stored as a zero terminated string | ||
1413 | fpath = I_FindFile(fname, (i < MAXLOADFILES) ? ".wad" : ".bex"); | ||
1414 | if (!fpath) | ||
1415 | lprintf(LO_WARN, "Failed to autoload %s\n", fname); | ||
1416 | else { | ||
1417 | if (i >= MAXLOADFILES) | ||
1418 | ProcessDehFile(fpath, D_dehout(), 0); | ||
1419 | else { | ||
1420 | D_AddFile(fpath,source_auto_load); | ||
1421 | } | ||
1422 | modifiedgame = true; | ||
1423 | free(fpath); | ||
1424 | } | ||
1425 | } | ||
1426 | } | ||
1427 | |||
1428 | // e6y: DEH files preloaded in wrong order | ||
1429 | // http://sourceforge.net/tracker/index.php?func=detail&aid=1418158&group_id=148658&atid=772943 | ||
1430 | // The dachaked stuff has been moved from above | ||
1431 | |||
1432 | // ty 03/09/98 do dehacked stuff | ||
1433 | // Note: do this before any other since it is expected by | ||
1434 | // the deh patch author that this is actually part of the EXE itself | ||
1435 | // Using -deh in BOOM, others use -dehacked. | ||
1436 | // Ty 03/18/98 also allow .bex extension. .bex overrides if both exist. | ||
1437 | |||
1438 | D_BuildBEXTables(); // haleyjd | ||
1439 | |||
1440 | p = M_CheckParm ("-deh"); | ||
1441 | if (p) | ||
1442 | { | ||
1443 | char file[PATH_MAX+1]; // cph - localised | ||
1444 | // the parms after p are deh/bex file names, | ||
1445 | // until end of parms or another - preceded parm | ||
1446 | // Ty 04/11/98 - Allow multiple -deh files in a row | ||
1447 | |||
1448 | while (++p != myargc && *myargv[p] != '-') | ||
1449 | { | ||
1450 | AddDefaultExtension(strcpy(file, myargv[p]), ".bex"); | ||
1451 | if (access(file, F_OK)) // nope | ||
1452 | { | ||
1453 | AddDefaultExtension(strcpy(file, myargv[p]), ".deh"); | ||
1454 | if (access(file, F_OK)) // still nope | ||
1455 | I_Error("D_DoomMainSetup: Cannot find .deh or .bex file named %s",myargv[p]); | ||
1456 | } | ||
1457 | // during the beta we have debug output to dehout.txt | ||
1458 | ProcessDehFile(file,D_dehout(),0); | ||
1459 | } | ||
1460 | } | ||
1461 | // ty 03/09/98 end of do dehacked stuff | ||
1462 | |||
1463 | // add any files specified on the command line with -file wadfile | ||
1464 | // to the wad list | ||
1465 | |||
1466 | // killough 1/31/98, 5/2/98: reload hack removed, -wart same as -warp now. | ||
1467 | |||
1468 | if ((p = M_CheckParm ("-file"))) | ||
1469 | { | ||
1470 | // the parms after p are wadfile/lump names, | ||
1471 | // until end of parms or another - preceded parm | ||
1472 | modifiedgame = true; // homebrew levels | ||
1473 | while (++p != myargc && *myargv[p] != '-') | ||
1474 | D_AddFile(myargv[p],source_pwad); | ||
1475 | } | ||
1476 | |||
1477 | if (!(p = M_CheckParm("-playdemo")) || p >= myargc-1) { /* killough */ | ||
1478 | if ((p = M_CheckParm ("-fastdemo")) && p < myargc-1) /* killough */ | ||
1479 | fastdemo = true; // run at fastest speed possible | ||
1480 | else | ||
1481 | p = M_CheckParm ("-timedemo"); | ||
1482 | } | ||
1483 | |||
1484 | if (p && p < myargc-1) | ||
1485 | { | ||
1486 | char file[PATH_MAX+1]; // cph - localised | ||
1487 | strcpy(file,myargv[p+1]); | ||
1488 | AddDefaultExtension(file,".lmp"); // killough | ||
1489 | D_AddFile (file,source_lmp); | ||
1490 | //jff 9/3/98 use logical output routine | ||
1491 | lprintf(LO_CONFIRM,"Playing demo %s\n",file); | ||
1492 | if ((p = M_CheckParm ("-ffmap")) && p < myargc-1) { | ||
1493 | ffmap = atoi(myargv[p+1]); | ||
1494 | } | ||
1495 | |||
1496 | } | ||
1497 | |||
1498 | // internal translucency set to config file value // phares | ||
1499 | general_translucency = default_translucency; // phares | ||
1500 | |||
1501 | // 1/18/98 killough: Z_Init() call moved to i_main.c | ||
1502 | |||
1503 | // CPhipps - move up netgame init | ||
1504 | //jff 9/3/98 use logical output routine | ||
1505 | lprintf(LO_INFO,"D_InitNetGame: Checking for network game.\n"); | ||
1506 | D_InitNetGame(); | ||
1507 | |||
1508 | //jff 9/3/98 use logical output routine | ||
1509 | lprintf(LO_INFO,"W_Init: Init WADfiles.\n"); | ||
1510 | W_Init(); // CPhipps - handling of wadfiles init changed | ||
1511 | |||
1512 | lprintf(LO_INFO,"\n"); // killough 3/6/98: add a newline, by popular demand :) | ||
1513 | |||
1514 | // e6y | ||
1515 | // option to disable automatic loading of dehacked-in-wad lump | ||
1516 | if (!M_CheckParm ("-nodeh")) | ||
1517 | if ((p = W_CheckNumForName("DEHACKED")) != -1) // cph - add dehacked-in-a-wad support | ||
1518 | ProcessDehFile(NULL, D_dehout(), p); | ||
1519 | |||
1520 | V_InitColorTranslation(); //jff 4/24/98 load color translation lumps | ||
1521 | |||
1522 | // killough 2/22/98: copyright / "modified game" / SPA banners removed | ||
1523 | |||
1524 | // Ty 04/08/98 - Add 5 lines of misc. data, only if nonblank | ||
1525 | // The expectation is that these will be set in a .bex file | ||
1526 | //jff 9/3/98 use logical output routine | ||
1527 | if (*startup1) lprintf(LO_INFO,"%s",startup1); | ||
1528 | if (*startup2) lprintf(LO_INFO,"%s",startup2); | ||
1529 | if (*startup3) lprintf(LO_INFO,"%s",startup3); | ||
1530 | if (*startup4) lprintf(LO_INFO,"%s",startup4); | ||
1531 | if (*startup5) lprintf(LO_INFO,"%s",startup5); | ||
1532 | // End new startup strings | ||
1533 | |||
1534 | //jff 9/3/98 use logical output routine | ||
1535 | lprintf(LO_INFO,"M_Init: Init miscellaneous info.\n"); | ||
1536 | M_Init(); | ||
1537 | |||
1538 | #ifdef HAVE_NET | ||
1539 | // CPhipps - now wait for netgame start | ||
1540 | D_CheckNetGame(); | ||
1541 | #endif | ||
1542 | |||
1543 | //jff 9/3/98 use logical output routine | ||
1544 | lprintf(LO_INFO,"R_Init: Init DOOM refresh daemon - "); | ||
1545 | R_Init(); | ||
1546 | |||
1547 | //jff 9/3/98 use logical output routine | ||
1548 | lprintf(LO_INFO,"\nP_Init: Init Playloop state.\n"); | ||
1549 | P_Init(); | ||
1550 | |||
1551 | //jff 9/3/98 use logical output routine | ||
1552 | lprintf(LO_INFO,"I_Init: Setting up machine state.\n"); | ||
1553 | I_Init(); | ||
1554 | |||
1555 | //jff 9/3/98 use logical output routine | ||
1556 | lprintf(LO_INFO,"S_Init: Setting up sound.\n"); | ||
1557 | S_Init(snd_SfxVolume /* *8 */, snd_MusicVolume /* *8*/ ); | ||
1558 | |||
1559 | //jff 9/3/98 use logical output routine | ||
1560 | lprintf(LO_INFO,"HU_Init: Setting up heads up display.\n"); | ||
1561 | HU_Init(); | ||
1562 | |||
1563 | if (!(M_CheckParm("-nodraw") && M_CheckParm("-nosound"))) | ||
1564 | I_InitGraphics(); | ||
1565 | |||
1566 | //jff 9/3/98 use logical output routine | ||
1567 | lprintf(LO_INFO,"ST_Init: Init status bar.\n"); | ||
1568 | ST_Init(); | ||
1569 | |||
1570 | idmusnum = -1; //jff 3/17/98 insure idmus number is blank | ||
1571 | |||
1572 | // CPhipps - auto screenshots | ||
1573 | if ((p = M_CheckParm("-autoshot")) && (p < myargc-2)) | ||
1574 | if ((auto_shot_count = auto_shot_time = atoi(myargv[p+1]))) | ||
1575 | auto_shot_fname = myargv[p+2]; | ||
1576 | |||
1577 | // start the apropriate game based on parms | ||
1578 | |||
1579 | // killough 12/98: | ||
1580 | // Support -loadgame with -record and reimplement -recordfrom. | ||
1581 | |||
1582 | if ((slot = M_CheckParm("-recordfrom")) && (p = slot+2) < myargc) | ||
1583 | G_RecordDemo(myargv[p]); | ||
1584 | else | ||
1585 | { | ||
1586 | slot = M_CheckParm("-loadgame"); | ||
1587 | if ((p = M_CheckParm("-record")) && ++p < myargc) | ||
1588 | { | ||
1589 | autostart = true; | ||
1590 | G_RecordDemo(myargv[p]); | ||
1591 | } | ||
1592 | } | ||
1593 | |||
1594 | if ((p = M_CheckParm ("-checksum")) && ++p < myargc) | ||
1595 | { | ||
1596 | P_RecordChecksum (myargv[p]); | ||
1597 | } | ||
1598 | |||
1599 | if ((p = M_CheckParm ("-fastdemo")) && ++p < myargc) | ||
1600 | { // killough | ||
1601 | fastdemo = true; // run at fastest speed possible | ||
1602 | timingdemo = true; // show stats after quit | ||
1603 | G_DeferedPlayDemo(myargv[p]); | ||
1604 | singledemo = true; // quit after one demo | ||
1605 | } | ||
1606 | else | ||
1607 | if ((p = M_CheckParm("-timedemo")) && ++p < myargc) | ||
1608 | { | ||
1609 | singletics = true; | ||
1610 | timingdemo = true; // show stats after quit | ||
1611 | G_DeferedPlayDemo(myargv[p]); | ||
1612 | singledemo = true; // quit after one demo | ||
1613 | } | ||
1614 | else | ||
1615 | if ((p = M_CheckParm("-playdemo")) && ++p < myargc) | ||
1616 | { | ||
1617 | G_DeferedPlayDemo(myargv[p]); | ||
1618 | singledemo = true; // quit after one demo | ||
1619 | } | ||
1620 | |||
1621 | if (slot && ++slot < myargc) | ||
1622 | { | ||
1623 | slot = atoi(myargv[slot]); // killough 3/16/98: add slot info | ||
1624 | G_LoadGame(slot, true); // killough 5/15/98: add command flag // cph - no filename | ||
1625 | } | ||
1626 | else | ||
1627 | if (!singledemo) { /* killough 12/98 */ | ||
1628 | if (autostart || netgame) | ||
1629 | { | ||
1630 | G_InitNew(startskill, startepisode, startmap); | ||
1631 | if (demorecording) | ||
1632 | G_BeginRecording(); | ||
1633 | } | ||
1634 | else | ||
1635 | D_StartTitle(); // start up intro loop | ||
1636 | } | ||
1637 | } | ||
1638 | |||
1639 | // | ||
1640 | // D_DoomMain | ||
1641 | // | ||
1642 | |||
1643 | void D_DoomMain(void) | ||
1644 | { | ||
1645 | D_DoomMainSetup(); // CPhipps - setup out of main execution stack | ||
1646 | |||
1647 | D_DoomLoop (); // never returns | ||
1648 | } | ||
1649 | |||
1650 | // | ||
1651 | // GetFirstMap | ||
1652 | // | ||
1653 | // Ty 08/29/98 - determine first available map from the loaded wads and run it | ||
1654 | // | ||
1655 | |||
1656 | void GetFirstMap(int *ep, int *map) | ||
1657 | { | ||
1658 | int i,j; // used to generate map name | ||
1659 | boolean done = false; // Ty 09/13/98 - to exit inner loops | ||
1660 | char test[6]; // MAPxx or ExMx plus terminator for testing | ||
1661 | char name[6]; // MAPxx or ExMx plus terminator for display | ||
1662 | boolean newlevel = false; // Ty 10/04/98 - to test for new level | ||
1663 | int ix; // index for lookup | ||
1664 | |||
1665 | strcpy(name,""); // initialize | ||
1666 | if (*map == 0) // unknown so go search for first changed one | ||
1667 | { | ||
1668 | *ep = 1; | ||
1669 | *map = 1; // default E1M1 or MAP01 | ||
1670 | if (gamemode == commercial) | ||
1671 | { | ||
1672 | for (i=1;!done && i<33;i++) // Ty 09/13/98 - add use of !done | ||
1673 | { | ||
1674 | sprintf(test,"MAP%02d",i); | ||
1675 | ix = W_CheckNumForName(test); | ||
1676 | if (ix != -1) // Ty 10/04/98 avoid -1 subscript | ||
1677 | { | ||
1678 | if (lumpinfo[ix].source == source_pwad) | ||
1679 | { | ||
1680 | *map = i; | ||
1681 | strcpy(name,test); // Ty 10/04/98 | ||
1682 | done = true; // Ty 09/13/98 | ||
1683 | newlevel = true; // Ty 10/04/98 | ||
1684 | } | ||
1685 | else | ||
1686 | { | ||
1687 | if (!*name) // found one, not pwad. First default. | ||
1688 | strcpy(name,test); | ||
1689 | } | ||
1690 | } | ||
1691 | } | ||
1692 | } | ||
1693 | else // one of the others | ||
1694 | { | ||
1695 | strcpy(name,"E1M1"); // Ty 10/04/98 - default for display | ||
1696 | for (i=1;!done && i<5;i++) // Ty 09/13/98 - add use of !done | ||
1697 | { | ||
1698 | for (j=1;!done && j<10;j++) // Ty 09/13/98 - add use of !done | ||
1699 | { | ||
1700 | sprintf(test,"E%dM%d",i,j); | ||
1701 | ix = W_CheckNumForName(test); | ||
1702 | if (ix != -1) // Ty 10/04/98 avoid -1 subscript | ||
1703 | { | ||
1704 | if (lumpinfo[ix].source == source_pwad) | ||
1705 | { | ||
1706 | *ep = i; | ||
1707 | *map = j; | ||
1708 | strcpy(name,test); // Ty 10/04/98 | ||
1709 | done = true; // Ty 09/13/98 | ||
1710 | newlevel = true; // Ty 10/04/98 | ||
1711 | } | ||
1712 | else | ||
1713 | { | ||
1714 | if (!*name) // found one, not pwad. First default. | ||
1715 | strcpy(name,test); | ||
1716 | } | ||
1717 | } | ||
1718 | } | ||
1719 | } | ||
1720 | } | ||
1721 | //jff 9/3/98 use logical output routine | ||
1722 | lprintf(LO_CONFIRM,"Auto-warping to first %slevel: %s\n", | ||
1723 | newlevel ? "new " : "", name); // Ty 10/04/98 - new level test | ||
1724 | } | ||
1725 | } | ||