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