Rev 298 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
298 | serge | 1 | // Emacs style mode select -*- C++ -*- |
2 | //----------------------------------------------------------------------------- |
||
3 | // |
||
4 | // $Id:$ |
||
5 | // |
||
6 | // Copyright (C) 1993-1996 by id Software, Inc. |
||
7 | // |
||
8 | // This source is available for distribution and/or modification |
||
9 | // only under the terms of the DOOM Source Code License as |
||
10 | // published by id Software. All rights reserved. |
||
11 | // |
||
12 | // The source is distributed in the hope that it will be useful, |
||
13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License |
||
15 | // for more details. |
||
16 | // |
||
17 | // $Log:$ |
||
18 | // |
||
19 | // DESCRIPTION: |
||
20 | // DOOM main program (D_DoomMain) and game loop (D_DoomLoop), |
||
21 | // plus functions to determine game mode (shareware, registered), |
||
22 | // parse command line parameters, configure game parameters (turbo), |
||
23 | // and call the startup functions. |
||
24 | // |
||
25 | //----------------------------------------------------------------------------- |
||
26 | |||
27 | |||
28 | static const char rcsid[] = "$Id: d_main.c,v 1.8 1997/02/03 22:45:09 b1 Exp $"; |
||
29 | |||
30 | #define BGCOLOR 7 |
||
31 | #define FGCOLOR 8 |
||
32 | |||
33 | |||
34 | #include |
||
35 | #include |
||
36 | |||
37 | extern int access(char *file, int mode); |
||
38 | |||
39 | #define R_OK 4 |
||
40 | #if 0 |
||
41 | static int access(char *file, int mode) |
||
42 | { |
||
43 | FILE *test_fp; |
||
44 | |||
45 | test_fp = fopen(file, "r"); |
||
46 | if ( test_fp != NULL ) { |
||
47 | fclose(test_fp); |
||
48 | return(0); |
||
49 | } |
||
50 | return(-1); |
||
51 | } |
||
52 | #endif |
||
53 | |||
54 | |||
55 | #include "doomdef.h" |
||
56 | #include "doomstat.h" |
||
57 | |||
58 | #include "dstrings.h" |
||
59 | #include "sounds.h" |
||
60 | |||
61 | |||
62 | #include "z_zone.h" |
||
63 | #include "w_wad.h" |
||
64 | #include "s_sound.h" |
||
65 | #include "v_video.h" |
||
66 | |||
67 | #include "f_finale.h" |
||
68 | #include "f_wipe.h" |
||
69 | |||
70 | #include "m_argv.h" |
||
71 | #include "m_misc.h" |
||
72 | #include "m_menu.h" |
||
73 | |||
74 | #include "i_system.h" |
||
75 | #include "i_sound.h" |
||
76 | #include "i_video.h" |
||
77 | |||
78 | #include "g_game.h" |
||
79 | |||
80 | #include "hu_stuff.h" |
||
81 | #include "wi_stuff.h" |
||
82 | #include "st_stuff.h" |
||
83 | #include "am_map.h" |
||
84 | |||
85 | #include "p_setup.h" |
||
86 | #include "r_local.h" |
||
87 | |||
88 | |||
89 | #include "d_main.h" |
||
90 | |||
91 | // |
||
92 | // D-DoomLoop() |
||
93 | // Not a globally visible function, |
||
94 | // just included for source reference, |
||
95 | // called by D_DoomMain, never exits. |
||
96 | // Manages timing and IO, |
||
97 | // calls all ?_Responder, ?_Ticker, and ?_Drawer, |
||
98 | // calls I_GetTime, I_StartFrame, and I_StartTic |
||
99 | // |
||
100 | void D_DoomLoop (void); |
||
101 | |||
102 | |||
103 | char* wadfiles[MAXWADFILES]; |
||
104 | |||
105 | |||
106 | boolean devparm; // started game with -devparm |
||
107 | boolean nomonsters; // checkparm of -nomonsters |
||
108 | boolean respawnparm; // checkparm of -respawn |
||
109 | boolean fastparm; // checkparm of -fast |
||
110 | |||
111 | boolean drone; |
||
112 | |||
113 | boolean singletics = false; // debug flag to cancel adaptiveness |
||
114 | |||
115 | |||
116 | |||
117 | //extern int soundVolume; |
||
118 | //extern int sfxVolume; |
||
119 | //extern int musicVolume; |
||
120 | |||
121 | extern boolean inhelpscreens; |
||
122 | |||
123 | skill_t startskill; |
||
124 | int startepisode; |
||
125 | int startmap; |
||
126 | boolean autostart; |
||
127 | |||
128 | FILE* debugfile; |
||
129 | |||
130 | boolean advancedemo; |
||
131 | |||
132 | |||
133 | |||
134 | |||
135 | char wadfile[1024]; // primary wad file |
||
136 | char mapdir[1024]; // directory of development maps |
||
137 | char basedefault[1024]; // default file |
||
138 | |||
139 | |||
140 | void D_CheckNetGame (void); |
||
141 | void D_ProcessEvents (void); |
||
142 | void G_BuildTiccmd (ticcmd_t* cmd); |
||
143 | void D_DoAdvanceDemo (void); |
||
144 | |||
145 | |||
146 | // |
||
147 | // EVENT HANDLING |
||
148 | // |
||
149 | // Events are asynchronous inputs generally generated by the game user. |
||
150 | // Events can be discarded if no responder claims them |
||
151 | // |
||
152 | event_t events[MAXEVENTS]; |
||
153 | int eventhead; |
||
154 | int eventtail; |
||
155 | |||
156 | |||
157 | // |
||
158 | // D_PostEvent |
||
159 | // Called by the I/O functions when input is detected |
||
160 | // |
||
161 | void D_PostEvent (event_t* ev) |
||
162 | { |
||
163 | events[eventhead] = *ev; |
||
164 | eventhead = (++eventhead)&(MAXEVENTS-1); |
||
165 | } |
||
166 | |||
167 | |||
168 | // |
||
169 | // D_ProcessEvents |
||
170 | // Send all the events of the given timestamp down the responder chain |
||
171 | // |
||
172 | void D_ProcessEvents (void) |
||
173 | { |
||
174 | event_t* ev; |
||
175 | |||
176 | // IF STORE DEMO, DO NOT ACCEPT INPUT |
||
177 | if ( ( gamemode == commercial ) |
||
178 | && (W_CheckNumForName("map01")<0) ) |
||
179 | return; |
||
180 | |||
181 | for ( ; eventtail != eventhead ; eventtail = (++eventtail)&(MAXEVENTS-1) ) |
||
182 | { |
||
183 | ev = &events[eventtail]; |
||
184 | if (M_Responder (ev)) |
||
185 | continue; // menu ate the event |
||
186 | G_Responder (ev); |
||
187 | } |
||
188 | } |
||
189 | |||
190 | |||
191 | |||
192 | |||
193 | // |
||
194 | // D_Display |
||
195 | // draw current display, possibly wiping it from the previous |
||
196 | // |
||
197 | |||
198 | // wipegamestate can be set to -1 to force a wipe on the next draw |
||
199 | gamestate_t wipegamestate = GS_DEMOSCREEN; |
||
200 | extern boolean setsizeneeded; |
||
201 | extern int showMessages; |
||
202 | void R_ExecuteSetViewSize (void); |
||
203 | |||
204 | |||
205 | // #define XXX(n) __libclog_printf("d_main.c: %u\n",n) |
||
206 | #define XXX(n) |
||
207 | |||
208 | void D_Display (void) |
||
209 | { |
||
210 | static boolean viewactivestate = false; |
||
211 | static boolean menuactivestate = false; |
||
212 | static boolean inhelpscreensstate = false; |
||
213 | static boolean fullscreen = false; |
||
214 | static gamestate_t oldgamestate = -1; |
||
215 | static int borderdrawcount; |
||
216 | int nowtime; |
||
217 | int tics; |
||
218 | int wipestart; |
||
219 | int y; |
||
220 | boolean done; |
||
221 | boolean wipe; |
||
222 | boolean redrawsbar; |
||
223 | |||
224 | if (nodrawers) |
||
225 | { |
||
226 | XXX(0); |
||
227 | return; // for comparative timing / profiling |
||
228 | } |
||
229 | redrawsbar = false; |
||
230 | |||
231 | // change the view size if needed |
||
232 | if (setsizeneeded) |
||
233 | { |
||
234 | XXX(1); |
||
235 | R_ExecuteSetViewSize (); |
||
236 | XXX(2); |
||
237 | oldgamestate = -1; // force background redraw |
||
238 | borderdrawcount = 3; |
||
239 | } |
||
240 | |||
241 | // save the current screen if about to wipe |
||
242 | XXX(3); |
||
243 | if (gamestate != wipegamestate) |
||
244 | { |
||
245 | wipe = true; |
||
246 | XXX(4); |
||
247 | wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT); |
||
248 | XXX(5); |
||
249 | } |
||
250 | else |
||
251 | wipe = false; |
||
252 | XXX(6); |
||
253 | |||
254 | if (gamestate == GS_LEVEL && gametic) |
||
255 | { |
||
256 | XXX(7); |
||
257 | HU_Erase(); |
||
258 | XXX(8); |
||
259 | } |
||
260 | // do buffered drawing |
||
261 | XXX(9); |
||
262 | switch (gamestate) |
||
263 | { |
||
264 | case GS_LEVEL: |
||
265 | XXX(10); |
||
266 | if (!gametic) |
||
267 | break; |
||
268 | if (automapactive) |
||
269 | AM_Drawer (); |
||
270 | if (wipe || (viewheight != 200 && fullscreen) ) |
||
271 | redrawsbar = true; |
||
272 | if (inhelpscreensstate && !inhelpscreens) |
||
273 | redrawsbar = true; // just put away the help screen |
||
274 | ST_Drawer (viewheight == 200, redrawsbar ); |
||
275 | fullscreen = viewheight == 200; |
||
276 | break; |
||
277 | |||
278 | case GS_INTERMISSION: |
||
279 | XXX(11); |
||
280 | WI_Drawer (); |
||
281 | break; |
||
282 | |||
283 | case GS_FINALE: |
||
284 | XXX(12); |
||
285 | F_Drawer (); |
||
286 | break; |
||
287 | |||
288 | case GS_DEMOSCREEN: |
||
289 | XXX(13); |
||
290 | D_PageDrawer (); |
||
291 | XXX(14); |
||
292 | break; |
||
293 | } |
||
294 | |||
295 | // draw buffered stuff to screen |
||
296 | XXX(15); |
||
297 | I_UpdateNoBlit (); |
||
298 | XXX(16); |
||
299 | |||
300 | // draw the view directly |
||
301 | if (gamestate == GS_LEVEL && !automapactive && gametic) |
||
302 | R_RenderPlayerView (&players[displayplayer]); |
||
303 | XXX(17); |
||
304 | |||
305 | if (gamestate == GS_LEVEL && gametic) |
||
306 | HU_Drawer (); |
||
307 | XXX(18); |
||
308 | |||
309 | // clean up border stuff |
||
310 | if (gamestate != oldgamestate && gamestate != GS_LEVEL) |
||
311 | I_SetPalette (W_CacheLumpName ("PLAYPAL",PU_CACHE)); |
||
312 | XXX(19); |
||
313 | |||
314 | // see if the border needs to be initially drawn |
||
315 | if (gamestate == GS_LEVEL && oldgamestate != GS_LEVEL) |
||
316 | { |
||
317 | XXX(20); |
||
318 | viewactivestate = false; // view was not active |
||
319 | R_FillBackScreen (); // draw the pattern into the back screen |
||
320 | XXX(21); |
||
321 | } |
||
322 | XXX(22); |
||
323 | |||
324 | // see if the border needs to be updated to the screen |
||
325 | if (gamestate == GS_LEVEL && !automapactive && scaledviewwidth != 320) |
||
326 | { |
||
327 | XXX(23); |
||
328 | if (menuactive || menuactivestate || !viewactivestate) |
||
329 | borderdrawcount = 3; |
||
330 | if (borderdrawcount) |
||
331 | { |
||
332 | XXX(24); |
||
333 | R_DrawViewBorder (); // erase old menu stuff |
||
334 | XXX(25); |
||
335 | borderdrawcount--; |
||
336 | } |
||
337 | |||
338 | } |
||
339 | XXX(26); |
||
340 | |||
341 | menuactivestate = menuactive; |
||
342 | viewactivestate = viewactive; |
||
343 | inhelpscreensstate = inhelpscreens; |
||
344 | oldgamestate = wipegamestate = gamestate; |
||
345 | |||
346 | // draw pause pic |
||
347 | if (paused) |
||
348 | { |
||
349 | if (automapactive) |
||
350 | y = 4; |
||
351 | else |
||
352 | y = viewwindowy+4; |
||
353 | V_DrawPatchDirect(viewwindowx+(scaledviewwidth-68)/2, |
||
354 | y,0,W_CacheLumpName ("M_PAUSE", PU_CACHE)); |
||
355 | } |
||
356 | |||
357 | |||
358 | // menus go directly to the screen |
||
359 | XXX(27); |
||
360 | M_Drawer (); // menu is drawn even on top of everything |
||
361 | XXX(28); |
||
362 | NetUpdate (); // send out any new accumulation |
||
363 | XXX(29); |
||
364 | |||
365 | |||
366 | // normal update |
||
367 | if (!wipe) |
||
368 | { |
||
369 | XXX(30); |
||
370 | I_FinishUpdate (); // page flip or blit buffer |
||
371 | XXX(31); |
||
372 | return; |
||
373 | } |
||
374 | XXX(32); |
||
375 | |||
376 | // wipe update |
||
377 | wipe_EndScreen(0, 0, SCREENWIDTH, SCREENHEIGHT); |
||
378 | XXX(33); |
||
379 | |||
380 | wipestart = I_GetTime () - 1; |
||
381 | |||
382 | XXX(34); |
||
383 | do |
||
384 | { |
||
385 | do |
||
386 | { |
||
387 | nowtime = I_GetTime (); |
||
388 | tics = nowtime - wipestart; |
||
389 | } while (!tics); |
||
390 | wipestart = nowtime; |
||
391 | XXX(35); |
||
392 | done = wipe_ScreenWipe(wipe_Melt |
||
393 | , 0, 0, SCREENWIDTH, SCREENHEIGHT, tics); |
||
394 | XXX(36); |
||
395 | I_UpdateNoBlit (); |
||
396 | XXX(37); |
||
397 | M_Drawer (); // menu is drawn even on top of wipes |
||
398 | XXX(38); |
||
399 | I_FinishUpdate (); // page flip or blit buffer |
||
400 | XXX(39); |
||
401 | } while (!done); |
||
402 | XXX(40); |
||
403 | } |
||
404 | |||
405 | // |
||
406 | // D_DoomLoop |
||
407 | // |
||
408 | extern boolean demorecording; |
||
409 | |||
410 | void D_DoomLoop (void) |
||
411 | { |
||
412 | if (demorecording) |
||
413 | G_BeginRecording (); |
||
414 | |||
415 | if (M_CheckParm ("-debugfile")) |
||
416 | { |
||
417 | char filename[20]; |
||
418 | sprintf (filename,"debug%i.txt",consoleplayer); |
||
419 | // __libclog_printf ("debug output to: %s\n",filename); |
||
420 | debugfile = fopen (filename,"w"); |
||
421 | } |
||
422 | |||
423 | I_InitGraphics (); |
||
424 | |||
425 | while (1) |
||
426 | { |
||
427 | // frame syncronous IO operations |
||
428 | XXX(100); |
||
429 | I_StartFrame (); |
||
430 | XXX(101); |
||
431 | |||
432 | // process one or more tics |
||
433 | if (singletics) |
||
434 | { |
||
435 | XXX(201); |
||
436 | I_StartTic (); |
||
437 | XXX(202); |
||
438 | D_ProcessEvents (); |
||
439 | XXX(203); |
||
440 | G_BuildTiccmd (&netcmds[consoleplayer][maketic%BACKUPTICS]); |
||
441 | XXX(204); |
||
442 | if (advancedemo) |
||
443 | D_DoAdvanceDemo (); |
||
444 | XXX(205); |
||
445 | M_Ticker (); |
||
446 | XXX(206); |
||
447 | G_Ticker (); |
||
448 | gametic++; |
||
449 | maketic++; |
||
450 | } |
||
451 | else |
||
452 | { |
||
453 | XXX(102); |
||
454 | TryRunTics (); // will run at least one tic |
||
455 | XXX(103); |
||
456 | } |
||
457 | |||
458 | S_UpdateSounds (players[consoleplayer].mo);// move positional sounds |
||
459 | |||
460 | // Update display, next frame, with current state. |
||
461 | XXX(104); |
||
462 | D_Display (); |
||
463 | I_UpdateSound(); |
||
464 | XXX(105); |
||
465 | } |
||
466 | } |
||
467 | |||
468 | |||
469 | |||
470 | // |
||
471 | // DEMO LOOP |
||
472 | // |
||
473 | int demosequence; |
||
474 | int pagetic; |
||
475 | char *pagename; |
||
476 | |||
477 | |||
478 | // |
||
479 | // D_PageTicker |
||
480 | // Handles timing for warped projection |
||
481 | // |
||
482 | void D_PageTicker (void) |
||
483 | { |
||
484 | if (--pagetic < 0) |
||
485 | D_AdvanceDemo (); |
||
486 | } |
||
487 | |||
488 | |||
489 | |||
490 | // |
||
491 | // D_PageDrawer |
||
492 | // |
||
493 | void D_PageDrawer (void) |
||
494 | { |
||
495 | V_DrawPatch (0,0, 0, W_CacheLumpName(pagename, PU_CACHE)); |
||
496 | } |
||
497 | |||
498 | |||
499 | // |
||
500 | // D_AdvanceDemo |
||
501 | // Called after each demo or intro demosequence finishes |
||
502 | // |
||
503 | void D_AdvanceDemo (void) |
||
504 | { |
||
505 | advancedemo = true; |
||
506 | } |
||
507 | |||
508 | |||
509 | // |
||
510 | // This cycles through the demo sequences. |
||
511 | // FIXME - version dependend demo numbers? |
||
512 | // |
||
513 | void D_DoAdvanceDemo (void) |
||
514 | { |
||
515 | players[consoleplayer].playerstate = PST_LIVE; // not reborn |
||
516 | advancedemo = false; |
||
517 | usergame = false; // no save / end game here |
||
518 | paused = false; |
||
519 | gameaction = ga_nothing; |
||
520 | |||
521 | if ( gamemode == retail ) |
||
522 | demosequence = (demosequence+1)%7; |
||
523 | else |
||
524 | demosequence = (demosequence+1)%6; |
||
525 | |||
526 | switch (demosequence) |
||
527 | { |
||
528 | case 0: |
||
529 | if ( gamemode == commercial ) |
||
530 | pagetic = 35 * 11; |
||
531 | else |
||
532 | pagetic = 170; |
||
533 | gamestate = GS_DEMOSCREEN; |
||
534 | pagename = "TITLEPIC"; |
||
535 | // if ( gamemode == commercial ) |
||
536 | // S_StartMusic(mus_dm2ttl); |
||
537 | // else |
||
538 | // S_StartMusic (mus_intro); |
||
539 | break; |
||
540 | case 1: |
||
541 | G_DeferedPlayDemo ("demo1"); |
||
542 | break; |
||
543 | case 2: |
||
544 | pagetic = 200; |
||
545 | gamestate = GS_DEMOSCREEN; |
||
546 | pagename = "CREDIT"; |
||
547 | break; |
||
548 | case 3: |
||
549 | G_DeferedPlayDemo ("demo2"); |
||
550 | break; |
||
551 | case 4: |
||
552 | gamestate = GS_DEMOSCREEN; |
||
553 | if ( gamemode == commercial) |
||
554 | { |
||
555 | pagetic = 35 * 11; |
||
556 | pagename = "TITLEPIC"; |
||
557 | // S_StartMusic(mus_dm2ttl); |
||
558 | } |
||
559 | else |
||
560 | { |
||
561 | pagetic = 200; |
||
562 | |||
563 | if ( gamemode == retail ) |
||
564 | pagename = "CREDIT"; |
||
565 | else |
||
566 | pagename = "HELP2"; |
||
567 | } |
||
568 | break; |
||
569 | case 5: |
||
570 | G_DeferedPlayDemo ("demo3"); |
||
571 | break; |
||
572 | // THE DEFINITIVE DOOM Special Edition demo |
||
573 | case 6: |
||
574 | G_DeferedPlayDemo ("demo4"); |
||
575 | break; |
||
576 | } |
||
577 | } |
||
578 | |||
579 | |||
580 | |||
581 | // |
||
582 | // D_StartTitle |
||
583 | // |
||
584 | void D_StartTitle (void) |
||
585 | { |
||
586 | gameaction = ga_nothing; |
||
587 | demosequence = -1; |
||
588 | D_AdvanceDemo (); |
||
589 | } |
||
590 | |||
591 | |||
592 | |||
593 | |||
594 | // print title for every printed line |
||
595 | char title[128]; |
||
596 | |||
597 | |||
598 | |||
599 | // |
||
600 | // D_AddFile |
||
601 | // |
||
602 | void D_AddFile (char *file) |
||
603 | { |
||
604 | int numwadfiles; |
||
605 | char *newfile; |
||
606 | |||
607 | for (numwadfiles = 0 ; wadfiles[numwadfiles] ; numwadfiles++) |
||
608 | ; |
||
609 | |||
610 | newfile = malloc (strlen(file)+1); |
||
611 | strcpy (newfile, file); |
||
612 | |||
613 | wadfiles[numwadfiles] = newfile; |
||
614 | } |
||
615 | |||
616 | // |
||
617 | // IdentifyVersion |
||
618 | // Checks availability of IWAD files by name, |
||
619 | // to determine whether registered/commercial features |
||
620 | // should be executed (notably loading PWAD's). |
||
621 | // |
||
622 | void IdentifyVersion (void) |
||
623 | { |
||
624 | |||
625 | char* doom1wad; |
||
626 | char* doomwad; |
||
627 | char* doomuwad; |
||
628 | char* doom2wad; |
||
629 | |||
630 | char* doom2fwad; |
||
631 | char* plutoniawad; |
||
632 | char* tntwad; |
||
633 | |||
634 | char *home; |
||
635 | char *doomwaddir; |
||
300 | serge | 636 | // doomwaddir = getenv("DOOMWADDIR"); |
637 | // if (!doomwaddir) |
||
298 | serge | 638 | doomwaddir = "."; |
639 | |||
640 | // Commercial. |
||
641 | doom2wad = malloc(strlen(doomwaddir)+1+9+1); |
||
642 | sprintf(doom2wad, "%s/doom2.wad", doomwaddir); |
||
643 | |||
644 | // Retail. |
||
645 | doomuwad = malloc(strlen(doomwaddir)+1+8+1); |
||
646 | sprintf(doomuwad, "%s/doomu.wad", doomwaddir); |
||
647 | |||
648 | // Registered. |
||
649 | doomwad = malloc(strlen(doomwaddir)+1+8+1); |
||
650 | sprintf(doomwad, "%s/doom.wad", doomwaddir); |
||
651 | |||
652 | // Shareware. |
||
653 | doom1wad = malloc(strlen(doomwaddir)+1+9+1); |
||
654 | sprintf(doom1wad, "%s/doom1.wad", doomwaddir); |
||
655 | |||
656 | // Bug, dear Shawn. |
||
657 | // Insufficient malloc, caused spurious realloc errors. |
||
658 | plutoniawad = malloc(strlen(doomwaddir)+1+/*9*/12+1); |
||
659 | sprintf(plutoniawad, "%s/plutonia.wad", doomwaddir); |
||
660 | |||
661 | tntwad = malloc(strlen(doomwaddir)+1+9+1); |
||
662 | sprintf(tntwad, "%s/tnt.wad", doomwaddir); |
||
663 | |||
664 | |||
665 | // French stuff. |
||
666 | doom2fwad = malloc(strlen(doomwaddir)+1+10+1); |
||
667 | sprintf(doom2fwad, "%s/doom2f.wad", doomwaddir); |
||
668 | |||
300 | serge | 669 | // home = getenv("HOME"); |
670 | // if (!home) |
||
298 | serge | 671 | home = "."; |
672 | sprintf(basedefault, "%s/doomrc.txt", home); |
||
673 | |||
674 | if (M_CheckParm ("-shdev")) |
||
675 | { |
||
676 | gamemode = shareware; |
||
677 | devparm = true; |
||
678 | D_AddFile (DEVDATA"doom1.wad"); |
||
679 | D_AddFile (DEVMAPS"data_se/texture1.lmp"); |
||
680 | D_AddFile (DEVMAPS"data_se/pnames.lmp"); |
||
681 | strcpy (basedefault,DEVDATA"default.cfg"); |
||
682 | return; |
||
683 | } |
||
684 | |||
685 | if (M_CheckParm ("-regdev")) |
||
686 | { |
||
687 | gamemode = registered; |
||
688 | devparm = true; |
||
689 | D_AddFile (DEVDATA"doom.wad"); |
||
690 | D_AddFile (DEVMAPS"data_se/texture1.lmp"); |
||
691 | D_AddFile (DEVMAPS"data_se/texture2.lmp"); |
||
692 | D_AddFile (DEVMAPS"data_se/pnames.lmp"); |
||
693 | strcpy (basedefault,DEVDATA"default.cfg"); |
||
694 | return; |
||
695 | } |
||
696 | |||
697 | if (M_CheckParm ("-comdev")) |
||
698 | { |
||
699 | gamemode = commercial; |
||
700 | devparm = true; |
||
701 | /* I don't bother |
||
702 | if(plutonia) |
||
703 | D_AddFile (DEVDATA"plutonia.wad"); |
||
704 | else if(tnt) |
||
705 | D_AddFile (DEVDATA"tnt.wad"); |
||
706 | else*/ |
||
707 | D_AddFile (DEVDATA"doom2.wad"); |
||
708 | |||
709 | D_AddFile (DEVMAPS"cdata/texture1.lmp"); |
||
710 | D_AddFile (DEVMAPS"cdata/pnames.lmp"); |
||
711 | strcpy (basedefault,DEVDATA"default.cfg"); |
||
712 | return; |
||
713 | } |
||
714 | |||
715 | if ( !access (doom2fwad,R_OK) ) |
||
716 | { |
||
717 | gamemode = commercial; |
||
718 | // C'est ridicule! |
||
719 | // Let's handle languages in config files, okay? |
||
720 | language = french; |
||
721 | // __libclog_printf("French version\n"); |
||
722 | D_AddFile (doom2fwad); |
||
723 | return; |
||
724 | } |
||
725 | |||
726 | if ( !access (doom2wad,R_OK) ) |
||
727 | { |
||
728 | gamemode = commercial; |
||
729 | D_AddFile (doom2wad); |
||
730 | return; |
||
731 | } |
||
732 | |||
733 | if ( !access (plutoniawad, R_OK ) ) |
||
734 | { |
||
735 | gamemode = commercial; |
||
736 | D_AddFile (plutoniawad); |
||
737 | return; |
||
738 | } |
||
739 | |||
740 | if ( !access ( tntwad, R_OK ) ) |
||
741 | { |
||
742 | gamemode = commercial; |
||
743 | D_AddFile (tntwad); |
||
744 | return; |
||
745 | } |
||
746 | |||
747 | if ( !access (doomuwad,R_OK) ) |
||
748 | { |
||
749 | gamemode = retail; |
||
750 | D_AddFile (doomuwad); |
||
751 | return; |
||
752 | } |
||
753 | |||
754 | if ( !access (doomwad,R_OK) ) |
||
755 | { |
||
756 | gamemode = registered; |
||
757 | D_AddFile (doomwad); |
||
758 | return; |
||
759 | } |
||
760 | |||
761 | if ( !access (doom1wad,R_OK) ) |
||
762 | { |
||
763 | gamemode = shareware; |
||
764 | D_AddFile (doom1wad); |
||
765 | return; |
||
766 | } |
||
767 | |||
768 | // __libclog_printf("Game mode indeterminate.\n"); |
||
769 | gamemode = indetermined; |
||
770 | |||
771 | // We don't abort. Let's see what the PWAD contains. |
||
772 | //exit(1); |
||
773 | //I_Error ("Game mode indeterminate\n"); |
||
774 | } |
||
775 | |||
776 | // |
||
777 | // Find a Response File |
||
778 | // |
||
779 | void FindResponseFile (void) |
||
780 | { |
||
781 | int i; |
||
782 | #define MAXARGVS 100 |
||
783 | |||
784 | for (i = 1;i < myargc;i++) |
||
785 | if (myargv[i][0] == '@') |
||
786 | { |
||
787 | FILE * handle; |
||
788 | int size; |
||
789 | int k; |
||
790 | int index; |
||
791 | int indexinfile; |
||
792 | char *infile; |
||
793 | char *file; |
||
794 | char *moreargs[20]; |
||
795 | char *firstargv; |
||
796 | |||
797 | // READ THE RESPONSE FILE INTO MEMORY |
||
798 | handle = fopen (&myargv[i][1],"rb"); |
||
799 | if (!handle) |
||
800 | { |
||
801 | // __libclog_printf ("\nNo such response file!"); |
||
802 | exit(1); |
||
803 | } |
||
804 | // __libclog_printf("Found response file %s!\n",&myargv[i][1]); |
||
805 | fseek (handle,0,SEEK_END); |
||
806 | size = ftell(handle); |
||
807 | fseek (handle,0,SEEK_SET); |
||
808 | file = malloc (size); |
||
809 | fread (file,size,1,handle); |
||
810 | fclose (handle); |
||
811 | |||
812 | // KEEP ALL CMDLINE ARGS FOLLOWING @RESPONSEFILE ARG |
||
813 | for (index = 0,k = i+1; k < myargc; k++) |
||
814 | moreargs[index++] = myargv[k]; |
||
815 | |||
816 | firstargv = myargv[0]; |
||
817 | myargv = malloc(sizeof(char *)*MAXARGVS); |
||
818 | memset(myargv,0,sizeof(char *)*MAXARGVS); |
||
819 | myargv[0] = firstargv; |
||
820 | |||
821 | infile = file; |
||
822 | indexinfile = k = 0; |
||
823 | indexinfile++; // SKIP PAST ARGV[0] (KEEP IT) |
||
824 | do |
||
825 | { |
||
826 | myargv[indexinfile++] = infile+k; |
||
827 | while(k < size && |
||
828 | ((*(infile+k)>= ' '+1) && (*(infile+k)<='z'))) |
||
829 | k++; |
||
830 | *(infile+k) = 0; |
||
831 | while(k < size && |
||
832 | ((*(infile+k)<= ' ') || (*(infile+k)>'z'))) |
||
833 | k++; |
||
834 | } while(k < size); |
||
835 | |||
836 | for (k = 0;k < index;k++) |
||
837 | myargv[indexinfile++] = moreargs[k]; |
||
838 | myargc = indexinfile; |
||
839 | |||
840 | // DISPLAY ARGS |
||
841 | // __libclog_printf("%d command-line args:\n",myargc); |
||
842 | for (k=1;k |
||
843 | // __libclog_printf("%s\n",myargv[k]); |
||
844 | |||
845 | break; |
||
846 | } |
||
847 | } |
||
848 | |||
849 | |||
850 | // |
||
851 | // D_DoomMain |
||
852 | // |
||
853 | void D_DoomMain (void) |
||
854 | { |
||
855 | int p; |
||
856 | char file[256]; |
||
857 | |||
858 | FindResponseFile (); |
||
859 | |||
860 | IdentifyVersion (); |
||
861 | |||
862 | // I_BeginSplash(); |
||
863 | |||
300 | serge | 864 | // setbuf (stdout, NULL); |
298 | serge | 865 | modifiedgame = false; |
866 | |||
867 | nomonsters = M_CheckParm ("-nomonsters"); |
||
868 | respawnparm = M_CheckParm ("-respawn"); |
||
869 | fastparm = M_CheckParm ("-fast"); |
||
870 | devparm = M_CheckParm ("-devparm"); |
||
871 | if (M_CheckParm ("-altdeath")) |
||
872 | deathmatch = 2; |
||
873 | else if (M_CheckParm ("-deathmatch")) |
||
874 | deathmatch = 1; |
||
875 | |||
876 | switch ( gamemode ) |
||
877 | { |
||
878 | case retail: |
||
879 | sprintf (title, |
||
880 | " " |
||
881 | "The Ultimate DOOM Startup v%i.%i" |
||
882 | " ", |
||
883 | VERSION_NUM/100,VERSION_NUM%100); |
||
884 | break; |
||
885 | case shareware: |
||
886 | sprintf (title, |
||
887 | " " |
||
888 | "DOOM Shareware Startup v%i.%i" |
||
889 | " ", |
||
890 | VERSION_NUM/100,VERSION_NUM%100); |
||
891 | break; |
||
892 | case registered: |
||
893 | sprintf (title, |
||
894 | " " |
||
895 | "DOOM Registered Startup v%i.%i" |
||
896 | " ", |
||
897 | VERSION_NUM/100,VERSION_NUM%100); |
||
898 | break; |
||
899 | case commercial: |
||
900 | sprintf (title, |
||
901 | " " |
||
902 | "DOOM 2: Hell on Earth v%i.%i" |
||
903 | " ", |
||
904 | VERSION_NUM/100,VERSION_NUM%100); |
||
905 | break; |
||
906 | /*FIXME |
||
907 | case pack_plut: |
||
908 | sprintf (title, |
||
909 | " " |
||
910 | "DOOM 2: Plutonia Experiment v%i.%i" |
||
911 | " ", |
||
912 | VERSION_NUM/100,VERSION_NUM%100); |
||
913 | break; |
||
914 | case pack_tnt: |
||
915 | sprintf (title, |
||
916 | " " |
||
917 | "DOOM 2: TNT - Evilution v%i.%i" |
||
918 | " ", |
||
919 | VERSION_NUM/100,VERSION_NUM%100); |
||
920 | break; |
||
921 | */ |
||
922 | default: |
||
923 | sprintf (title, |
||
924 | " " |
||
925 | "Public DOOM - v%i.%i" |
||
926 | " ", |
||
927 | VERSION_NUM/100,VERSION_NUM%100); |
||
928 | break; |
||
929 | } |
||
930 | |||
931 | // __libclog_printf ("%s\n",title); |
||
932 | |||
933 | if (devparm) |
||
934 | // __libclog_printf(D_DEVSTR); |
||
935 | |||
936 | // turbo option |
||
937 | if ( (p=M_CheckParm ("-turbo")) ) |
||
938 | { |
||
939 | int scale = 200; |
||
940 | extern int forwardmove[2]; |
||
941 | extern int sidemove[2]; |
||
942 | |||
943 | if (p |
||
944 | scale = atoi (myargv[p+1]); |
||
945 | if (scale < 10) |
||
946 | scale = 10; |
||
947 | if (scale > 400) |
||
948 | scale = 400; |
||
949 | // __libclog_printf ("turbo scale: %i%%\n",scale); |
||
950 | forwardmove[0] = forwardmove[0]*scale/100; |
||
951 | forwardmove[1] = forwardmove[1]*scale/100; |
||
952 | sidemove[0] = sidemove[0]*scale/100; |
||
953 | sidemove[1] = sidemove[1]*scale/100; |
||
954 | } |
||
955 | |||
956 | // add any files specified on the command line with -file wadfile |
||
957 | // to the wad list |
||
958 | // |
||
959 | // convenience hack to allow -wart e m to add a wad file |
||
960 | // prepend a tilde to the filename so wadfile will be reloadable |
||
961 | p = M_CheckParm ("-wart"); |
||
962 | if (p) |
||
963 | { |
||
964 | myargv[p][4] = 'p'; // big hack, change to -warp |
||
965 | |||
966 | // Map name handling. |
||
967 | switch (gamemode ) |
||
968 | { |
||
969 | case shareware: |
||
970 | case retail: |
||
971 | case registered: |
||
972 | sprintf (file,"~"DEVMAPS"E%cM%c.wad", |
||
973 | myargv[p+1][0], myargv[p+2][0]); |
||
974 | // __libclog_printf("Warping to Episode %s, Map %s.\n", |
||
975 | // myargv[p+1],myargv[p+2]); |
||
976 | break; |
||
977 | |||
978 | case commercial: |
||
979 | default: |
||
980 | p = atoi (myargv[p+1]); |
||
981 | if (p<10) |
||
982 | sprintf (file,"~"DEVMAPS"cdata/map0%i.wad", p); |
||
983 | else |
||
984 | sprintf (file,"~"DEVMAPS"cdata/map%i.wad", p); |
||
985 | break; |
||
986 | } |
||
987 | D_AddFile (file); |
||
988 | } |
||
989 | |||
990 | p = M_CheckParm ("-file"); |
||
991 | if (p) |
||
992 | { |
||
993 | // the parms after p are wadfile/lump names, |
||
994 | // until end of parms or another - preceded parm |
||
995 | modifiedgame = true; // homebrew levels |
||
996 | while (++p != myargc && myargv[p][0] != '-') |
||
997 | D_AddFile (myargv[p]); |
||
998 | } |
||
999 | |||
1000 | p = M_CheckParm ("-playdemo"); |
||
1001 | |||
1002 | if (!p) |
||
1003 | p = M_CheckParm ("-timedemo"); |
||
1004 | |||
1005 | if (p && p < myargc-1) |
||
1006 | { |
||
1007 | sprintf (file,"%s.lmp", myargv[p+1]); |
||
1008 | D_AddFile (file); |
||
1009 | printf("Playing demo %s.lmp.\n",myargv[p+1]); |
||
1010 | } |
||
1011 | |||
1012 | // get skill / episode / map from parms |
||
1013 | startskill = sk_medium; |
||
1014 | startepisode = 1; |
||
1015 | startmap = 1; |
||
1016 | autostart = false; |
||
1017 | |||
1018 | |||
1019 | p = M_CheckParm ("-skill"); |
||
1020 | if (p && p < myargc-1) |
||
1021 | { |
||
1022 | startskill = myargv[p+1][0]-'1'; |
||
1023 | autostart = true; |
||
1024 | } |
||
1025 | |||
1026 | p = M_CheckParm ("-episode"); |
||
1027 | if (p && p < myargc-1) |
||
1028 | { |
||
1029 | startepisode = myargv[p+1][0]-'0'; |
||
1030 | startmap = 1; |
||
1031 | autostart = true; |
||
1032 | } |
||
1033 | |||
1034 | p = M_CheckParm ("-timer"); |
||
1035 | if (p && p < myargc-1 && deathmatch) |
||
1036 | { |
||
1037 | int time; |
||
1038 | time = atoi(myargv[p+1]); |
||
1039 | printf("Levels will end after %d minute",time); |
||
1040 | if (time>1) |
||
1041 | printf("s"); |
||
1042 | printf(".\n"); |
||
1043 | } |
||
1044 | |||
1045 | p = M_CheckParm ("-avg"); |
||
1046 | if (p && p < myargc-1 && deathmatch) |
||
1047 | printf("Austin Virtual Gaming: Levels will end after 20 minutes\n"); |
||
1048 | |||
1049 | p = M_CheckParm ("-warp"); |
||
1050 | if (p && p < myargc-1) |
||
1051 | { |
||
1052 | if (gamemode == commercial) |
||
1053 | startmap = atoi (myargv[p+1]); |
||
1054 | else |
||
1055 | { |
||
1056 | startepisode = myargv[p+1][0]-'0'; |
||
1057 | startmap = myargv[p+2][0]-'0'; |
||
1058 | } |
||
1059 | autostart = true; |
||
1060 | } |
||
1061 | |||
1062 | // init subsystems |
||
1063 | printf ("V_Init: allocate screens.\n"); |
||
1064 | V_Init (); |
||
1065 | |||
1066 | printf ("M_LoadDefaults: Load system defaults.\n"); |
||
1067 | M_LoadDefaults (); // load before initing other systems |
||
1068 | |||
1069 | printf ("Z_Init: Init zone memory allocation daemon. \n"); |
||
1070 | Z_Init (); |
||
1071 | |||
1072 | printf ("W_Init: Init WADfiles.\n"); |
||
1073 | W_InitMultipleFiles (wadfiles); |
||
1074 | printf("added\n"); |
||
1075 | |||
1076 | |||
1077 | // Check for -file in shareware |
||
1078 | if (modifiedgame) |
||
1079 | { |
||
1080 | // These are the lumps that will be checked in IWAD, |
||
1081 | // if any one is not present, execution will be aborted. |
||
1082 | char name[23][8]= |
||
1083 | { |
||
1084 | "e2m1","e2m2","e2m3","e2m4","e2m5","e2m6","e2m7","e2m8","e2m9", |
||
1085 | "e3m1","e3m3","e3m3","e3m4","e3m5","e3m6","e3m7","e3m8","e3m9", |
||
1086 | "dphoof","bfgga0","heada1","cybra1","spida1d1" |
||
1087 | }; |
||
1088 | int i; |
||
1089 | |||
1090 | if ( gamemode == shareware) |
||
1091 | I_Error("\nYou cannot -file with the shareware " |
||
1092 | "version. Register!"); |
||
1093 | |||
1094 | // Check for fake IWAD with right name, |
||
1095 | // but w/o all the lumps of the registered version. |
||
1096 | if (gamemode == registered) |
||
1097 | for (i = 0;i < 23; i++) |
||
1098 | if (W_CheckNumForName(name[i])<0) |
||
1099 | I_Error("\nThis is not the registered version."); |
||
1100 | } |
||
1101 | |||
1102 | // Iff additonal PWAD files are used, print modified banner |
||
1103 | if (modifiedgame) |
||
1104 | { |
||
300 | serge | 1105 | printf ( |
1106 | "===========================================================================\n" |
||
1107 | "ATTENTION: This version of DOOM has been modified. If you would like to\n" |
||
1108 | "get a copy of the original game, call 1-800-IDGAMES or see the readme file.\n" |
||
1109 | " You will not receive technical support for modified games.\n" |
||
1110 | " press enter to continue\n" |
||
1111 | "===========================================================================\n" |
||
1112 | ); |
||
1113 | // getchar (); |
||
298 | serge | 1114 | } |
1115 | |||
1116 | |||
1117 | // Check and print which version is executed. |
||
1118 | switch ( gamemode ) |
||
1119 | { |
||
1120 | case shareware: |
||
1121 | case indetermined: |
||
300 | serge | 1122 | printf ( |
1123 | "===========================================================================\n" |
||
1124 | " Shareware!\n" |
||
1125 | "===========================================================================\n" |
||
1126 | ); |
||
298 | serge | 1127 | break; |
1128 | case registered: |
||
1129 | case retail: |
||
1130 | case commercial: |
||
300 | serge | 1131 | printf ( |
1132 | "===========================================================================\n" |
||
1133 | " Commercial product - do not distribute!\n" |
||
1134 | " Please report software piracy to the SPA: 1-800-388-PIR8\n" |
||
1135 | "===========================================================================\n" |
||
1136 | ); |
||
298 | serge | 1137 | break; |
1138 | |||
1139 | default: |
||
1140 | // Ouch. |
||
1141 | break; |
||
1142 | } |
||
1143 | |||
300 | serge | 1144 | printf ("M_Init: Init miscellaneous info.\n"); |
298 | serge | 1145 | M_Init (); |
1146 | |||
300 | serge | 1147 | printf ("R_Init: Init DOOM refresh daemon - "); |
298 | serge | 1148 | R_Init (); |
1149 | |||
300 | serge | 1150 | printf ("\nP_Init: Init Playloop state.\n"); |
298 | serge | 1151 | P_Init (); |
1152 | |||
300 | serge | 1153 | printf ("I_Init: Setting up machine state.\n"); |
298 | serge | 1154 | I_Init (); |
1155 | |||
300 | serge | 1156 | printf ("D_CheckNetGame: Checking network game status.\n"); |
298 | serge | 1157 | D_CheckNetGame (); |
1158 | |||
300 | serge | 1159 | printf ("S_Init: Setting up sound.\n"); |
298 | serge | 1160 | S_Init (snd_SfxVolume /* *8 */, snd_MusicVolume /* *8*/ ); |
1161 | |||
300 | serge | 1162 | printf ("HU_Init: Setting up heads up display.\n"); |
298 | serge | 1163 | HU_Init (); |
1164 | |||
1165 | // I_EndSplash(); |
||
1166 | |||
300 | serge | 1167 | printf ("ST_Init: Init status bar.\n"); |
298 | serge | 1168 | ST_Init (); |
1169 | |||
1170 | // check for a driver that wants intermission stats |
||
1171 | p = M_CheckParm ("-statcopy"); |
||
1172 | if (p && p |
||
1173 | { |
||
1174 | // for statistics driver |
||
1175 | extern void* statcopy; |
||
1176 | |||
1177 | statcopy = (void*)atoi(myargv[p+1]); |
||
1178 | printf ("External statistics registered.\n"); |
||
1179 | } |
||
1180 | |||
1181 | // start the apropriate game based on parms |
||
1182 | p = M_CheckParm ("-record"); |
||
1183 | |||
1184 | if (p && p < myargc-1) |
||
1185 | { |
||
1186 | G_RecordDemo (myargv[p+1]); |
||
1187 | autostart = true; |
||
1188 | } |
||
1189 | |||
1190 | p = M_CheckParm ("-playdemo"); |
||
1191 | if (p && p < myargc-1) |
||
1192 | { |
||
1193 | singledemo = true; // quit after one demo |
||
1194 | G_DeferedPlayDemo (myargv[p+1]); |
||
1195 | D_DoomLoop (); // never returns |
||
1196 | } |
||
1197 | |||
1198 | p = M_CheckParm ("-timedemo"); |
||
1199 | if (p && p < myargc-1) |
||
1200 | { |
||
1201 | G_TimeDemo (myargv[p+1]); |
||
1202 | D_DoomLoop (); // never returns |
||
1203 | } |
||
1204 | |||
1205 | p = M_CheckParm ("-loadgame"); |
||
1206 | if (p && p < myargc-1) |
||
1207 | { |
||
1208 | if (M_CheckParm("-cdrom")) |
||
1209 | sprintf(file, "c:\\doomdata\\"SAVEGAMENAME"%c.dsg",myargv[p+1][0]); |
||
1210 | else |
||
1211 | sprintf(file, SAVEGAMENAME"%c.dsg",myargv[p+1][0]); |
||
1212 | G_LoadGame (file); |
||
1213 | } |
||
1214 | |||
1215 | |||
1216 | if ( gameaction != ga_loadgame ) |
||
1217 | { |
||
1218 | if (autostart || netgame) |
||
1219 | G_InitNew (startskill, startepisode, startmap); |
||
1220 | else |
||
1221 | D_StartTitle (); // start up intro loop |
||
1222 | |||
1223 | } |
||
1224 | |||
1225 | D_DoomLoop (); // never returns |
||
1226 | }>>>> |