diff options
Diffstat (limited to 'apps/plugins/doom/d_main.c')
-rw-r--r-- | apps/plugins/doom/d_main.c | 844 |
1 files changed, 844 insertions, 0 deletions
diff --git a/apps/plugins/doom/d_main.c b/apps/plugins/doom/d_main.c new file mode 100644 index 0000000000..d76779cb2b --- /dev/null +++ b/apps/plugins/doom/d_main.c | |||
@@ -0,0 +1,844 @@ | |||
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-2000 by | ||
10 | * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
25 | * 02111-1307, USA. | ||
26 | * | ||
27 | * DESCRIPTION: | ||
28 | * DOOM main program (D_DoomMain) and game loop (D_DoomLoop), | ||
29 | * plus functions to determine game mode (shareware, registered), | ||
30 | * parse command line parameters, configure game parameters (turbo), | ||
31 | * and call the startup functions. | ||
32 | * | ||
33 | *----------------------------------------------------------------------------- | ||
34 | */ | ||
35 | |||
36 | |||
37 | #include "rockmacros.h" | ||
38 | |||
39 | #include "doomdef.h" | ||
40 | #include "doomtype.h" | ||
41 | #include "doomstat.h" | ||
42 | #include "dstrings.h" | ||
43 | #include "sounds.h" | ||
44 | #include "z_zone.h" | ||
45 | #include "w_wad.h" | ||
46 | #include "s_sound.h" | ||
47 | #include "v_video.h" | ||
48 | #include "f_finale.h" | ||
49 | #include "f_wipe.h" | ||
50 | #include "m_argv.h" | ||
51 | #include "m_misc.h" | ||
52 | #include "m_menu.h" | ||
53 | #include "i_system.h" | ||
54 | #include "i_sound.h" | ||
55 | #include "i_video.h" | ||
56 | #include "g_game.h" | ||
57 | #include "hu_stuff.h" | ||
58 | #include "wi_stuff.h" | ||
59 | #include "st_stuff.h" | ||
60 | #include "am_map.h" | ||
61 | #include "p_setup.h" | ||
62 | #include "r_draw.h" | ||
63 | #include "r_main.h" | ||
64 | #include "d_main.h" | ||
65 | #include "am_map.h" | ||
66 | #include "m_swap.h" | ||
67 | |||
68 | // CPhipps - removed wadfiles[] stuff | ||
69 | |||
70 | boolean devparm; // started game with -devparm | ||
71 | |||
72 | // jff 1/24/98 add new versions of these variables to remember command line | ||
73 | boolean clnomonsters; // checkparm of -nomonsters | ||
74 | boolean clrespawnparm; // checkparm of -respawn | ||
75 | boolean clfastparm; // checkparm of -fast | ||
76 | // jff 1/24/98 end definition of command line version of play mode switches | ||
77 | |||
78 | boolean nomonsters; // working -nomonsters | ||
79 | boolean respawnparm; // working -respawn | ||
80 | boolean fastparm; // working -fast | ||
81 | |||
82 | boolean singletics = false; // debug flag to cancel adaptiveness | ||
83 | |||
84 | boolean doomexit; | ||
85 | |||
86 | //jff 1/22/98 parms for disabling music and sound | ||
87 | boolean nosfxparm; | ||
88 | boolean nomusicparm; | ||
89 | |||
90 | //jff 4/18/98 | ||
91 | extern boolean inhelpscreens; | ||
92 | |||
93 | skill_t startskill; | ||
94 | int startepisode; | ||
95 | int startmap; | ||
96 | boolean autostart; | ||
97 | int debugfile; | ||
98 | int ffmap; | ||
99 | |||
100 | boolean advancedemo; | ||
101 | |||
102 | extern boolean timingdemo, singledemo, demoplayback, fastdemo; // killough | ||
103 | |||
104 | int basetic; | ||
105 | |||
106 | void D_DoAdvanceDemo (void); | ||
107 | |||
108 | /* | ||
109 | * D_PostEvent - Event handling | ||
110 | * | ||
111 | * Called by I/O functions when an event is received. | ||
112 | * Try event handlers for each code area in turn. | ||
113 | * cph - in the true spirit of the Boom source, let the | ||
114 | * short ciruit operator madness begin! | ||
115 | */ | ||
116 | |||
117 | void D_PostEvent(event_t *ev) | ||
118 | { | ||
119 | /* cph - suppress all input events at game start | ||
120 | * FIXME: This is a lousy kludge */ | ||
121 | if (gametic < 3) return; | ||
122 | M_Responder(ev) || | ||
123 | (gamestate == GS_LEVEL && ( | ||
124 | HU_Responder(ev) || | ||
125 | ST_Responder(ev) || | ||
126 | AM_Responder(ev) | ||
127 | ) | ||
128 | ) || | ||
129 | G_Responder(ev); | ||
130 | } | ||
131 | |||
132 | // | ||
133 | // D_Wipe | ||
134 | // | ||
135 | // CPhipps - moved the screen wipe code from D_Display to here | ||
136 | // The screens to wipe between are already stored, this just does the timing | ||
137 | // and screen updating | ||
138 | |||
139 | static void D_Wipe(void) | ||
140 | { | ||
141 | boolean done; | ||
142 | int wipestart = I_GetTime () - 1; | ||
143 | |||
144 | do | ||
145 | { | ||
146 | int nowtime, tics; | ||
147 | do | ||
148 | { | ||
149 | //I_uSleep(5000); // CPhipps - don't thrash cpu in this loop | ||
150 | nowtime = I_GetTime(); | ||
151 | tics = nowtime - wipestart; | ||
152 | } | ||
153 | while (!tics); | ||
154 | wipestart = nowtime; | ||
155 | |||
156 | done = wipe_ScreenWipe(0,0,SCREENWIDTH,SCREENHEIGHT,tics); | ||
157 | I_UpdateNoBlit(); | ||
158 | M_Drawer(); // menu is drawn even on top of wipes | ||
159 | I_FinishUpdate(); // page flip or blit buffer | ||
160 | } | ||
161 | while (!done); | ||
162 | } | ||
163 | |||
164 | // | ||
165 | // D_Display | ||
166 | // draw current display, possibly wiping it from the previous | ||
167 | // | ||
168 | |||
169 | // wipegamestate can be set to -1 to force a wipe on the next draw | ||
170 | gamestate_t wipegamestate = GS_DEMOSCREEN; | ||
171 | extern boolean setsizeneeded; | ||
172 | extern int showMessages; | ||
173 | |||
174 | void D_Display (void) | ||
175 | { | ||
176 | static boolean isborderstate = false; | ||
177 | static boolean borderwillneedredraw = false; | ||
178 | static boolean inhelpscreensstate = false; | ||
179 | static gamestate_t oldgamestate = -1; | ||
180 | boolean wipe; | ||
181 | boolean viewactive = false, isborder = false; | ||
182 | |||
183 | if (nodrawers) // for comparative timing / profiling | ||
184 | return; | ||
185 | |||
186 | // save the current screen if about to wipe | ||
187 | if ((wipe = gamestate != wipegamestate)) | ||
188 | wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT); | ||
189 | |||
190 | if (gamestate != GS_LEVEL) { // Not a level | ||
191 | switch (oldgamestate) { | ||
192 | case -1: | ||
193 | case GS_LEVEL: | ||
194 | V_SetPalette(0); // cph - use default (basic) palette | ||
195 | default: | ||
196 | break; | ||
197 | } | ||
198 | |||
199 | switch (gamestate) { | ||
200 | case GS_INTERMISSION: | ||
201 | WI_Drawer(); | ||
202 | break; | ||
203 | case GS_FINALE: | ||
204 | F_Drawer(); | ||
205 | break; | ||
206 | case GS_DEMOSCREEN: | ||
207 | D_PageDrawer(); | ||
208 | break; | ||
209 | default: | ||
210 | break; | ||
211 | } | ||
212 | } else if (gametic != basetic) { // In a level | ||
213 | boolean redrawborderstuff; | ||
214 | |||
215 | HU_Erase(); | ||
216 | |||
217 | if (setsizeneeded) { // change the view size if needed | ||
218 | R_ExecuteSetViewSize(); | ||
219 | oldgamestate = -1; // force background redraw | ||
220 | } | ||
221 | |||
222 | // Work out if the player view is visible, and if there is a border | ||
223 | viewactive = (!(automapmode & am_active) || (automapmode & am_overlay)) && !inhelpscreens; | ||
224 | isborder = viewactive ? (viewheight != SCREENHEIGHT) : (!inhelpscreens && (automapmode & am_active)); | ||
225 | |||
226 | if (oldgamestate != GS_LEVEL) { | ||
227 | R_FillBackScreen (); // draw the pattern into the back screen | ||
228 | redrawborderstuff = isborder; | ||
229 | } else { | ||
230 | // CPhipps - | ||
231 | // If there is a border, and either there was no border last time, | ||
232 | // or the border might need refreshing, then redraw it. | ||
233 | redrawborderstuff = isborder && (!isborderstate || borderwillneedredraw); | ||
234 | // The border may need redrawing next time if the border surrounds the screen, | ||
235 | // and there is a menu being displayed | ||
236 | borderwillneedredraw = menuactive && isborder && viewactive && (viewwidth != SCREENWIDTH); | ||
237 | } | ||
238 | |||
239 | if (redrawborderstuff) | ||
240 | R_DrawViewBorder(); | ||
241 | |||
242 | // Now do the drawing | ||
243 | if (viewactive) | ||
244 | R_RenderPlayerView (&players[displayplayer]); | ||
245 | if (automapmode & am_active) | ||
246 | AM_Drawer(); | ||
247 | ST_Drawer((viewheight != SCREENHEIGHT) || ((automapmode & am_active) && !(automapmode & am_overlay)), redrawborderstuff); | ||
248 | R_DrawViewBorder(); | ||
249 | |||
250 | HU_Drawer(); | ||
251 | } | ||
252 | |||
253 | inhelpscreensstate = inhelpscreens; | ||
254 | isborderstate = isborder; | ||
255 | oldgamestate = wipegamestate = gamestate; | ||
256 | |||
257 | // draw pause pic | ||
258 | if (paused) { | ||
259 | static int x; | ||
260 | |||
261 | if (!x) { // Cache results of x pos calc | ||
262 | int lump = W_GetNumForName("M_PAUSE"); | ||
263 | const patch_t* p = W_CacheLumpNum(lump); | ||
264 | x = (320 - SHORT(p->width))/2; | ||
265 | W_UnlockLumpNum(lump); | ||
266 | } | ||
267 | |||
268 | // CPhipps - updated for new patch drawing | ||
269 | V_DrawNamePatch(x, (!(automapmode & am_active) || (automapmode & am_overlay)) | ||
270 | ? 4+(viewwindowy*200/SCREENHEIGHT) : 4, // cph - Must un-stretch viewwindowy | ||
271 | 0, "M_PAUSE", CR_DEFAULT, VPT_STRETCH); | ||
272 | } | ||
273 | |||
274 | // menus go directly to the screen | ||
275 | M_Drawer(); // menu is drawn even on top of everything | ||
276 | D_BuildNewTiccmds(); | ||
277 | |||
278 | // normal update | ||
279 | if (!wipe) | ||
280 | I_FinishUpdate (); // page flip or blit buffer | ||
281 | else { | ||
282 | // wipe update | ||
283 | wipe_EndScreen(0, 0, SCREENWIDTH, SCREENHEIGHT); | ||
284 | D_Wipe(); | ||
285 | } | ||
286 | } | ||
287 | |||
288 | // | ||
289 | // D_DoomLoop() | ||
290 | // | ||
291 | // Not a globally visible function, | ||
292 | // just included for source reference, | ||
293 | // called by D_DoomMain, never exits. | ||
294 | // Manages timing and IO, | ||
295 | // calls all ?_Responder, ?_Ticker, and ?_Drawer, | ||
296 | // calls I_GetTime, I_StartFrame, and I_StartTic | ||
297 | // | ||
298 | |||
299 | extern boolean demorecording; | ||
300 | |||
301 | static void D_DoomLoop (void) | ||
302 | { | ||
303 | basetic = gametic; | ||
304 | |||
305 | I_SubmitSound(); | ||
306 | |||
307 | while (!doomexit) | ||
308 | { | ||
309 | // frame syncronous IO operations | ||
310 | //I_StartFrame (); | ||
311 | |||
312 | // process one or more tics | ||
313 | if (singletics) | ||
314 | { | ||
315 | I_StartTic (); | ||
316 | G_BuildTiccmd (&netcmds[consoleplayer][maketic%BACKUPTICS]); | ||
317 | if (advancedemo) | ||
318 | D_DoAdvanceDemo (); | ||
319 | M_Ticker (); | ||
320 | G_Ticker (); | ||
321 | gametic++; | ||
322 | maketic++; | ||
323 | } | ||
324 | else | ||
325 | TryRunTics (); // will run at least one tic | ||
326 | |||
327 | // killough 3/16/98: change consoleplayer to displayplayer | ||
328 | if (players[displayplayer].mo) // cph 2002/08/10 | ||
329 | S_UpdateSounds(players[displayplayer].mo);// move positional sounds | ||
330 | |||
331 | // Update display, next frame, with current state. | ||
332 | D_Display(); | ||
333 | |||
334 | // Sound mixing for the buffer is snychronous. | ||
335 | // I_UpdateSound(); | ||
336 | rb->yield(); | ||
337 | } | ||
338 | } | ||
339 | |||
340 | // | ||
341 | // DEMO LOOP | ||
342 | // | ||
343 | |||
344 | static int demosequence; // killough 5/2/98: made static | ||
345 | static int pagetic; | ||
346 | static const char *pagename; // CPhipps - const | ||
347 | |||
348 | // | ||
349 | // D_PageTicker | ||
350 | // Handles timing for warped projection | ||
351 | // | ||
352 | void D_PageTicker(void) | ||
353 | { | ||
354 | if (--pagetic < 0) | ||
355 | D_AdvanceDemo(); | ||
356 | } | ||
357 | |||
358 | // | ||
359 | // D_PageDrawer | ||
360 | // | ||
361 | void D_PageDrawer(void) | ||
362 | { | ||
363 | // CPhipps - updated for new patch drawing | ||
364 | V_DrawNamePatch(0, 0, 0, pagename, CR_DEFAULT, VPT_STRETCH); | ||
365 | } | ||
366 | |||
367 | // | ||
368 | // D_AdvanceDemo | ||
369 | // Called after each demo or intro demosequence finishes | ||
370 | // | ||
371 | void D_AdvanceDemo (void) | ||
372 | { | ||
373 | advancedemo = true; | ||
374 | } | ||
375 | |||
376 | /* killough 11/98: functions to perform demo sequences | ||
377 | * cphipps 10/99: constness fixes | ||
378 | */ | ||
379 | |||
380 | static void D_SetPageName(const char *name) | ||
381 | { | ||
382 | pagename = name; | ||
383 | } | ||
384 | |||
385 | static void D_DrawTitle1(const char *name) | ||
386 | { | ||
387 | S_StartMusic(mus_intro); | ||
388 | pagetic = (TICRATE*170)/35; | ||
389 | D_SetPageName(name); | ||
390 | } | ||
391 | |||
392 | static void D_DrawTitle2(const char *name) | ||
393 | { | ||
394 | S_StartMusic(mus_dm2ttl); | ||
395 | D_SetPageName(name); | ||
396 | } | ||
397 | |||
398 | /* killough 11/98: tabulate demo sequences | ||
399 | */ | ||
400 | |||
401 | static struct | ||
402 | { | ||
403 | void (*func)(const char *); | ||
404 | const char *name; | ||
405 | } const demostates[][4] = | ||
406 | { | ||
407 | { | ||
408 | {D_DrawTitle1, "TITLEPIC"}, | ||
409 | {D_DrawTitle1, "TITLEPIC"}, | ||
410 | {D_DrawTitle2, "TITLEPIC"}, | ||
411 | {D_DrawTitle1, "TITLEPIC"}, | ||
412 | }, | ||
413 | |||
414 | { | ||
415 | {G_DeferedPlayDemo, "demo1"}, | ||
416 | {G_DeferedPlayDemo, "demo1"}, | ||
417 | {G_DeferedPlayDemo, "demo1"}, | ||
418 | {G_DeferedPlayDemo, "demo1"}, | ||
419 | }, | ||
420 | { | ||
421 | {D_SetPageName, "CREDIT"}, | ||
422 | {D_SetPageName, "CREDIT"}, | ||
423 | {D_SetPageName, "CREDIT"}, | ||
424 | {D_SetPageName, "CREDIT"}, | ||
425 | }, | ||
426 | |||
427 | { | ||
428 | {G_DeferedPlayDemo, "demo2"}, | ||
429 | {G_DeferedPlayDemo, "demo2"}, | ||
430 | {G_DeferedPlayDemo, "demo2"}, | ||
431 | {G_DeferedPlayDemo, "demo2"}, | ||
432 | }, | ||
433 | |||
434 | { | ||
435 | {D_SetPageName, "HELP2"}, | ||
436 | {D_SetPageName, "HELP2"}, | ||
437 | {D_SetPageName, "CREDIT"}, | ||
438 | {D_DrawTitle1, "TITLEPIC"}, | ||
439 | }, | ||
440 | |||
441 | { | ||
442 | {G_DeferedPlayDemo, "demo3"}, | ||
443 | {G_DeferedPlayDemo, "demo3"}, | ||
444 | {G_DeferedPlayDemo, "demo3"}, | ||
445 | {G_DeferedPlayDemo, "demo3"}, | ||
446 | }, | ||
447 | |||
448 | { | ||
449 | {NULL,0}, | ||
450 | {NULL,0}, | ||
451 | {NULL,0}, | ||
452 | {D_SetPageName, "CREDIT"}, | ||
453 | }, | ||
454 | |||
455 | { | ||
456 | {NULL,0}, | ||
457 | {NULL,0}, | ||
458 | {NULL,0}, | ||
459 | {G_DeferedPlayDemo, "demo4"}, | ||
460 | }, | ||
461 | |||
462 | { | ||
463 | {NULL,0}, | ||
464 | {NULL,0}, | ||
465 | {NULL,0}, | ||
466 | {NULL,0}, | ||
467 | } | ||
468 | }; | ||
469 | |||
470 | /* | ||
471 | * This cycles through the demo sequences. | ||
472 | * killough 11/98: made table-driven | ||
473 | */ | ||
474 | |||
475 | void D_DoAdvanceDemo(void) | ||
476 | { | ||
477 | players[consoleplayer].playerstate = PST_LIVE; /* not reborn */ | ||
478 | advancedemo = usergame = paused = false; | ||
479 | gameaction = ga_nothing; | ||
480 | |||
481 | pagetic = TICRATE * 11; /* killough 11/98: default behavior */ | ||
482 | gamestate = GS_DEMOSCREEN; | ||
483 | |||
484 | if (netgame && !demoplayback) { | ||
485 | demosequence = 0; | ||
486 | } else | ||
487 | if (!demostates[++demosequence][gamemode].func) | ||
488 | demosequence = 0; | ||
489 | demostates[demosequence][gamemode].func(demostates[demosequence][gamemode].name); | ||
490 | } | ||
491 | |||
492 | // | ||
493 | // D_StartTitle | ||
494 | // | ||
495 | void D_StartTitle (void) | ||
496 | { | ||
497 | gameaction = ga_nothing; | ||
498 | demosequence = -1; | ||
499 | D_AdvanceDemo(); | ||
500 | } | ||
501 | |||
502 | // | ||
503 | // D_AddFile | ||
504 | // | ||
505 | // Rewritten by Lee Killough | ||
506 | // | ||
507 | // Ty 08/29/98 - add source parm to indicate where this came from | ||
508 | // CPhipps - static, const char* parameter | ||
509 | // - source is an enum | ||
510 | // - modified to allocate & use new wadfiles array | ||
511 | void D_AddFile (const char *file, wad_source_t source) | ||
512 | { | ||
513 | wadfiles = realloc(wadfiles, sizeof(*wadfiles)*(numwadfiles+1)); | ||
514 | wadfiles[numwadfiles].name = | ||
515 | AddDefaultExtension(strcpy(malloc(strlen(file)+5), file), ".wad"); | ||
516 | wadfiles[numwadfiles].src = source; // Ty 08/29/98 | ||
517 | numwadfiles++; | ||
518 | } | ||
519 | |||
520 | // | ||
521 | // CheckIWAD | ||
522 | // | ||
523 | // Verify a file is indeed tagged as an IWAD | ||
524 | // Scan its lumps for levelnames and return gamemode as indicated | ||
525 | // Detect missing wolf levels in DOOM II | ||
526 | // | ||
527 | // The filename to check is passed in iwadname, the gamemode detected is | ||
528 | // returned in gmode, hassec returns the presence of secret levels | ||
529 | // | ||
530 | // jff 4/19/98 Add routine to test IWAD for validity and determine | ||
531 | // the gamemode from it. Also note if DOOM II, whether secret levels exist | ||
532 | // CPhipps - const char* for iwadname, made static | ||
533 | #if 0 | ||
534 | static void CheckIWAD(const char *iwadname,GameMode_t *gmode,boolean *hassec) | ||
535 | { | ||
536 | if ( !fileexists (iwadname) ) | ||
537 | { | ||
538 | int ud=0,rg=0,sw=0,cm=0,sc=0; | ||
539 | int handle; | ||
540 | |||
541 | // Identify IWAD correctly | ||
542 | if ( (handle = open (iwadname,O_RDONLY)) != -1) | ||
543 | { | ||
544 | wadinfo_t header; | ||
545 | |||
546 | // read IWAD header | ||
547 | read (handle, &header, sizeof(header)); | ||
548 | if (!strncmp(header.identification,"IWAD",4)) | ||
549 | { | ||
550 | size_t length; | ||
551 | filelump_t *fileinfo; | ||
552 | |||
553 | // read IWAD directory | ||
554 | header.numlumps = LONG(header.numlumps); | ||
555 | header.infotableofs = LONG(header.infotableofs); | ||
556 | length = header.numlumps; | ||
557 | fileinfo = malloc(length*sizeof(filelump_t)); | ||
558 | lseek (handle, header.infotableofs, SEEK_SET); | ||
559 | read (handle, fileinfo, length*sizeof(filelump_t)); | ||
560 | close(handle); | ||
561 | |||
562 | // scan directory for levelname lumps | ||
563 | while (length--) | ||
564 | if (fileinfo[length].name[0] == 'E' && | ||
565 | fileinfo[length].name[2] == 'M' && | ||
566 | fileinfo[length].name[4] == 0) | ||
567 | { | ||
568 | if (fileinfo[length].name[1] == '4') | ||
569 | ++ud; | ||
570 | else if (fileinfo[length].name[1] == '3') | ||
571 | ++rg; | ||
572 | else if (fileinfo[length].name[1] == '2') | ||
573 | ++rg; | ||
574 | else if (fileinfo[length].name[1] == '1') | ||
575 | ++sw; | ||
576 | } | ||
577 | else if (fileinfo[length].name[0] == 'M' && | ||
578 | fileinfo[length].name[1] == 'A' && | ||
579 | fileinfo[length].name[2] == 'P' && | ||
580 | fileinfo[length].name[5] == 0) | ||
581 | { | ||
582 | ++cm; | ||
583 | if (fileinfo[length].name[3] == '3') | ||
584 | if (fileinfo[length].name[4] == '1' || | ||
585 | fileinfo[length].name[4] == '2') | ||
586 | ++sc; | ||
587 | } | ||
588 | |||
589 | free(fileinfo); | ||
590 | } | ||
591 | else // missing IWAD tag in header | ||
592 | I_Error("CheckIWAD: IWAD tag %s not present", iwadname); | ||
593 | } | ||
594 | else // error from open call | ||
595 | I_Error("CheckIWAD: Can't open IWAD %s", iwadname); | ||
596 | |||
597 | // Determine game mode from levels present | ||
598 | // Must be a full set for whichever mode is present | ||
599 | // Lack of wolf-3d levels also detected here | ||
600 | |||
601 | *gmode = indetermined; | ||
602 | *hassec = false; | ||
603 | if (cm>=30) | ||
604 | { | ||
605 | *gmode = commercial; | ||
606 | *hassec = sc>=2; | ||
607 | } | ||
608 | else if (ud>=9) | ||
609 | *gmode = retail; | ||
610 | else if (rg>=18) | ||
611 | *gmode = registered; | ||
612 | else if (sw>=9) | ||
613 | *gmode = shareware; | ||
614 | } | ||
615 | else // error from access call | ||
616 | I_Error("CheckIWAD: IWAD %s not readable", iwadname); | ||
617 | } | ||
618 | #endif | ||
619 | void D_DoomMainSetup(void) | ||
620 | { | ||
621 | int p; | ||
622 | |||
623 | nomonsters = M_CheckParm ("-nomonsters"); | ||
624 | respawnparm = M_CheckParm ("-respawn"); | ||
625 | fastparm = M_CheckParm ("-fast"); | ||
626 | devparm = M_CheckParm ("-devparm"); | ||
627 | if (M_CheckParm ("-altdeath")) | ||
628 | deathmatch = 2; | ||
629 | else if (M_CheckParm ("-deathmatch")) | ||
630 | deathmatch = 1; | ||
631 | |||
632 | printf("Welcome to Rockdoom"); | ||
633 | |||
634 | switch ( gamemode ) | ||
635 | { | ||
636 | case retail: | ||
637 | printf ("The Ultimate DOOM Startup v%d.%d",DVERSION/100,DVERSION%100); | ||
638 | break; | ||
639 | case shareware: | ||
640 | printf ("DOOM Shareware Startup v%d.%d",DVERSION/100,DVERSION%100); | ||
641 | break; | ||
642 | case registered: | ||
643 | printf ("DOOM Registered Startup v%d.%d",DVERSION/100,DVERSION%100); | ||
644 | break; | ||
645 | case commercial: | ||
646 | switch (gamemission) | ||
647 | { | ||
648 | case pack_plut: | ||
649 | printf ("DOOM 2: Plutonia Experiment v%d.%d",DVERSION/100,DVERSION%100); | ||
650 | break; | ||
651 | case pack_tnt: | ||
652 | printf ("DOOM 2: TNT - Evilution v%d.%d",DVERSION/100,DVERSION%100); | ||
653 | break; | ||
654 | default: | ||
655 | printf ("DOOM 2: Hell on Earth v%d.%d",DVERSION/100,DVERSION%100); | ||
656 | break; | ||
657 | } | ||
658 | break; | ||
659 | default: | ||
660 | printf ("Public DOOM v%d.%d",DVERSION/100,DVERSION%100); | ||
661 | break; | ||
662 | } | ||
663 | |||
664 | if (devparm) | ||
665 | printf(D_DEVSTR); | ||
666 | |||
667 | // turbo option | ||
668 | if ((p=M_CheckParm ("-turbo"))) | ||
669 | { | ||
670 | int scale = 200; | ||
671 | extern int forwardmove[2]; | ||
672 | extern int sidemove[2]; | ||
673 | |||
674 | if (p<myargc-1) | ||
675 | scale = atoi (myargv[p+1]); | ||
676 | if (scale < 10) | ||
677 | scale = 10; | ||
678 | if (scale > 400) | ||
679 | scale = 400; | ||
680 | printf ("turbo scale: %d%%\n",scale); | ||
681 | forwardmove[0] = forwardmove[0]*scale/100; | ||
682 | forwardmove[1] = forwardmove[1]*scale/100; | ||
683 | sidemove[0] = sidemove[0]*scale/100; | ||
684 | sidemove[1] = sidemove[1]*scale/100; | ||
685 | } | ||
686 | |||
687 | // get skill / episode / map from parms | ||
688 | startskill = sk_medium; | ||
689 | startepisode = 1; | ||
690 | startmap = 1; | ||
691 | autostart = false; | ||
692 | |||
693 | p = M_CheckParm ("-skill"); | ||
694 | if (p && p < myargc-1) | ||
695 | { | ||
696 | startskill = myargv[p+1][0]-'1'; | ||
697 | autostart = true; | ||
698 | } | ||
699 | |||
700 | p = M_CheckParm ("-episode"); | ||
701 | if (p && p < myargc-1) | ||
702 | { | ||
703 | startepisode = myargv[p+1][0]-'0'; | ||
704 | startmap = 1; | ||
705 | autostart = true; | ||
706 | } | ||
707 | |||
708 | p = M_CheckParm ("-warp"); | ||
709 | if (p && p < myargc-1) | ||
710 | { | ||
711 | if (gamemode == commercial) | ||
712 | startmap = atoi (myargv[p+1]); | ||
713 | else | ||
714 | { | ||
715 | startepisode = myargv[p+1][0]-'0'; | ||
716 | startmap = myargv[p+2][0]-'0'; | ||
717 | } | ||
718 | autostart = true; | ||
719 | } | ||
720 | |||
721 | // CPhipps - move up netgame init | ||
722 | printf("D_InitNetGame: Checking for network game.\n"); | ||
723 | D_InitNetGame(); | ||
724 | |||
725 | // init subsystems | ||
726 | printf ("V_Init: allocate screens.\n"); | ||
727 | V_Init (); | ||
728 | |||
729 | printf ("W_Init: Init WADfiles.\n"); | ||
730 | W_Init(); | ||
731 | |||
732 | V_InitColorTranslation(); //jff 4/24/98 load color translation lumps | ||
733 | |||
734 | // Check for -file in shareware | ||
735 | if (modifiedgame) | ||
736 | { | ||
737 | // These are the lumps that will be checked in IWAD, | ||
738 | // if any one is not present, execution will be aborted. | ||
739 | char name[23][8]= | ||
740 | { | ||
741 | "e2m1","e2m2","e2m3","e2m4","e2m5","e2m6","e2m7","e2m8","e2m9", | ||
742 | "e3m1","e3m3","e3m3","e3m4","e3m5","e3m6","e3m7","e3m8","e3m9", | ||
743 | "dphoof","bfgga0","heada1","cybra1","spida1d1" | ||
744 | }; | ||
745 | int i; | ||
746 | |||
747 | if ( gamemode == shareware) | ||
748 | I_Error("\nYou cannot -file with the shareware version. Register!"); | ||
749 | |||
750 | // Check for fake IWAD with right name, | ||
751 | // but w/o all the lumps of the registered version. | ||
752 | if (gamemode == registered) | ||
753 | for (i = 0;i < 23; i++) | ||
754 | if (W_CheckNumForName(name[i])<0) | ||
755 | I_Error("\nThis is not the registered version."); | ||
756 | } | ||
757 | |||
758 | // Iff additonal PWAD files are used, print modified banner | ||
759 | if (modifiedgame) | ||
760 | printf ("ATTENTION: This version of DOOM has been modified.\n"); | ||
761 | |||
762 | // Check and print which version is executed. | ||
763 | switch ( gamemode ) | ||
764 | { | ||
765 | case shareware: | ||
766 | case indetermined: | ||
767 | printf ("Shareware!\n"); | ||
768 | break; | ||
769 | case registered: | ||
770 | case retail: | ||
771 | case commercial: | ||
772 | printf ("Commercial product - do not distribute!\n"); | ||
773 | break; | ||
774 | default: | ||
775 | // Ouch. | ||
776 | break; | ||
777 | } | ||
778 | |||
779 | printf ("M_Init: Init miscellaneous info.\n"); | ||
780 | M_Init (); | ||
781 | |||
782 | printf ("R_Init: Init DOOM refresh daemon - "); | ||
783 | R_Init (); | ||
784 | |||
785 | printf ("P_Init: Init Playloop state.\n"); | ||
786 | P_Init (); | ||
787 | |||
788 | printf ("I_Init: Setting up machine state.\n"); | ||
789 | I_Init (); | ||
790 | |||
791 | printf ("S_Init: Setting up sound.\n"); | ||
792 | S_Init (snd_SfxVolume /* *8 */, snd_MusicVolume /* *8*/ ); | ||
793 | |||
794 | printf ("HU_Init: Setting up heads up display.\n"); | ||
795 | HU_Init (); | ||
796 | |||
797 | I_InitGraphics (); | ||
798 | |||
799 | printf ("ST_Init: Init status bar.\n"); | ||
800 | ST_Init (); | ||
801 | |||
802 | // check for a driver that wants intermission stats | ||
803 | p = M_CheckParm ("-statcopy"); | ||
804 | if (p && p<myargc-1) | ||
805 | { | ||
806 | // for statistics driver | ||
807 | extern void* statcopy; | ||
808 | |||
809 | statcopy = (void*)atoi(myargv[p+1]); | ||
810 | printf ("External statistics registered.\n"); | ||
811 | } | ||
812 | |||
813 | // start the apropriate game based on parms | ||
814 | p = M_CheckParm ("-record"); | ||
815 | if (p && p < myargc-1) | ||
816 | { | ||
817 | G_RecordDemo (myargv[p+1]); | ||
818 | autostart = true; | ||
819 | } | ||
820 | |||
821 | p = M_CheckParm ("-loadgame"); | ||
822 | if (p && p < myargc-1) | ||
823 | G_LoadGame (atoi(myargv[p+1]), false); | ||
824 | |||
825 | if ( gameaction != ga_loadgame ) | ||
826 | { | ||
827 | if (!singledemo) { /* killough 12/98 */ | ||
828 | if (autostart || netgame) | ||
829 | G_InitNew (startskill, startepisode, startmap); | ||
830 | else | ||
831 | D_StartTitle (); // start up intro loop | ||
832 | } | ||
833 | } | ||
834 | } | ||
835 | |||
836 | // | ||
837 | // D_DoomMain | ||
838 | // | ||
839 | void D_DoomMain (void) | ||
840 | { | ||
841 | D_DoomMainSetup(); // get this crap off the stack | ||
842 | |||
843 | D_DoomLoop (); // never returns | ||
844 | } | ||