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