summaryrefslogtreecommitdiff
path: root/src/strife/d_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/strife/d_main.c')
-rw-r--r--src/strife/d_main.c2041
1 files changed, 2041 insertions, 0 deletions
diff --git a/src/strife/d_main.c b/src/strife/d_main.c
new file mode 100644
index 00000000..bd4ac6a1
--- /dev/null
+++ b/src/strife/d_main.c
@@ -0,0 +1,2041 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 2005 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// DESCRIPTION:
+// DOOM main program (D_DoomMain) and game loop (D_DoomLoop),
+// plus functions to determine game mode (shareware, registered),
+// parse command line parameters, configure game parameters (turbo),
+// and call the startup functions.
+//
+//-----------------------------------------------------------------------------
+
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "deh_main.h"
+#include "doomdef.h"
+#include "doomstat.h"
+
+#include "dstrings.h"
+#include "doomfeatures.h"
+#include "sounds.h"
+
+#include "d_iwad.h"
+
+#include "z_zone.h"
+#include "w_main.h"
+#include "w_wad.h"
+#include "s_sound.h"
+#include "v_video.h"
+
+#include "f_finale.h"
+#include "f_wipe.h"
+
+#include "m_argv.h"
+#include "m_config.h"
+#include "m_controls.h"
+#include "m_misc.h"
+#include "m_menu.h"
+#include "m_saves.h" // haleyjd [STRIFE]
+#include "p_saveg.h"
+#include "p_dialog.h" // haleyjd [STRIFE]
+
+#include "i_endoom.h"
+#include "i_joystick.h"
+#include "i_system.h"
+#include "i_timer.h"
+#include "i_video.h"
+#include "i_swap.h"
+
+#include "g_game.h"
+
+#include "hu_stuff.h"
+#include "wi_stuff.h"
+#include "st_stuff.h"
+#include "am_map.h"
+#include "net_client.h"
+#include "net_dedicated.h"
+#include "net_query.h"
+
+#include "p_setup.h"
+#include "r_local.h"
+
+#include "d_main.h"
+
+//
+// D-DoomLoop()
+// Not a globally visible function,
+// just included for source reference,
+// called by D_DoomMain, never exits.
+// Manages timing and IO,
+// calls all ?_Responder, ?_Ticker, and ?_Drawer,
+// calls I_GetTime, I_StartFrame, and I_StartTic
+//
+void D_DoomLoop (void);
+
+static boolean D_AddFile(char *filename);
+
+// Location where savegames are stored
+
+char * savegamedir;
+
+// location of IWAD and WAD files
+
+char * iwadfile;
+
+
+boolean devparm; // started game with -devparm
+boolean nomonsters; // checkparm of -nomonsters
+boolean respawnparm; // checkparm of -respawn
+boolean fastparm; // checkparm of -fast
+boolean flipparm; // [STRIFE] haleyjd 20110629: checkparm of -flip
+
+boolean showintro = true; // [STRIFE] checkparm of -nograph, disables intro
+boolean singletics = false; // debug flag to cancel adaptiveness
+
+
+//extern int soundVolume;
+//extern int sfxVolume;
+//extern int musicVolume;
+
+extern boolean inhelpscreens;
+
+skill_t startskill;
+int startepisode;
+int startmap;
+boolean autostart;
+int startloadgame;
+
+boolean advancedemo;
+
+// villsa [STRIFE] workparm variable (similar to devparm?)
+boolean workparm = false;
+
+// villsa [STRIFE] stonecold cheat variable
+boolean stonecold = false;
+
+// haleyjd 09/11/10: [STRIFE] Game type variables
+boolean isregistered;
+boolean isdemoversion;
+
+// Store demo, do not accept any inputs
+// haleyjd [STRIFE] Unused.
+//boolean storedemo;
+
+
+char wadfile[1024]; // primary wad file
+char mapdir[1024]; // directory of development maps
+
+int show_endoom = 1;
+
+// fraggle 06/03/11 [STRIFE]: Unused config variable, preserved
+// for compatibility:
+
+static int comport = 0;
+
+// fraggle 06/03/11 [STRIFE]: Multiplayer nickname?
+
+static char *nickname = NULL;
+
+void D_CheckNetGame (void);
+void D_ProcessEvents (void);
+void G_BuildTiccmd (ticcmd_t* cmd);
+void D_DoAdvanceDemo (void);
+
+
+//
+// D_ProcessEvents
+// Send all the events of the given timestamp down the responder chain
+//
+void D_ProcessEvents (void)
+{
+ event_t* ev;
+
+ // haleyjd 08/22/2010: [STRIFE] there is no such thing as a "store demo"
+ // version of Strife
+
+ // IF STORE DEMO, DO NOT ACCEPT INPUT
+ //if (storedemo)
+ // return;
+
+ while ((ev = D_PopEvent()) != NULL)
+ {
+ if (M_Responder (ev))
+ continue; // menu ate the event
+ G_Responder (ev);
+ }
+}
+
+
+
+
+//
+// D_Display
+// draw current display, possibly wiping it from the previous
+//
+// wipegamestate can be set to -1 to force a wipe on the next draw
+//
+// haleyjd 08/23/10: [STRIFE]:
+// * Changes to eliminate intermission and change timing of screenwipe
+// * 20100901: Added ST_DrawExternal and popupactivestate static variable
+// * 20110206: Start wipegamestate at GS_UNKNOWN (STRIFE-TODO: rename?)
+//
+gamestate_t wipegamestate = GS_UNKNOWN;
+extern boolean setsizeneeded;
+//extern int showMessages; [STRIFE] no such variable
+void R_ExecuteSetViewSize (void);
+
+void D_Display (void)
+{
+ static boolean viewactivestate = false;
+ static boolean menuactivestate = false;
+ static boolean inhelpscreensstate = false;
+ static boolean popupactivestate = false; // [STRIFE]
+ static boolean fullscreen = false;
+ static gamestate_t oldgamestate = -1;
+ static int borderdrawcount;
+ int nowtime;
+ int tics;
+ int wipestart;
+ int y;
+ boolean done;
+ boolean wipe;
+ boolean redrawsbar;
+
+ if (nodrawers)
+ return; // for comparative timing / profiling
+
+ redrawsbar = false;
+
+ // change the view size if needed
+ if (setsizeneeded)
+ {
+ R_ExecuteSetViewSize ();
+ oldgamestate = -1; // force background redraw
+ borderdrawcount = 3;
+ }
+
+ // save the current screen if about to wipe
+ if (gamestate != wipegamestate)
+ {
+ wipe = true;
+ wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);
+ }
+ else
+ wipe = false;
+
+ if (gamestate == GS_LEVEL && gametic)
+ HU_Erase();
+
+ // do buffered drawing
+ switch (gamestate)
+ {
+ case GS_LEVEL:
+ if (!gametic)
+ break;
+ if (automapactive)
+ AM_Drawer ();
+ if (wipe || (viewheight != 200 && fullscreen) )
+ redrawsbar = true;
+ // haleyjd 08/29/10: [STRIFE] Always redraw sbar if menu is/was active
+ if (menuactivestate || (inhelpscreensstate && !inhelpscreens))
+ redrawsbar = true; // just put away the help screen
+ ST_Drawer (viewheight == 200, redrawsbar );
+ fullscreen = viewheight == 200;
+ break;
+
+ // haleyjd 08/23/2010: [STRIFE] No intermission
+ /*
+ case GS_INTERMISSION:
+ WI_Drawer ();
+ break;
+ */
+
+ case GS_FINALE:
+ F_Drawer ();
+ break;
+
+ case GS_DEMOSCREEN:
+ D_PageDrawer ();
+ break;
+
+ default:
+ break;
+ }
+
+ // draw buffered stuff to screen
+ I_UpdateNoBlit ();
+
+ // draw the view directly
+ if (gamestate == GS_LEVEL && !automapactive && gametic)
+ R_RenderPlayerView (&players[displayplayer]);
+
+ if (gamestate == GS_LEVEL && gametic)
+ {
+ HU_Drawer ();
+ if(ST_DrawExternal())
+ popupactivestate = true;
+ else if(popupactivestate)
+ {
+ popupactivestate = false;
+ menuactivestate = 1;
+ }
+ }
+
+ // clean up border stuff
+ if (gamestate != oldgamestate && gamestate != GS_LEVEL)
+ I_SetPalette (W_CacheLumpName (DEH_String("PLAYPAL"),PU_CACHE));
+
+ // see if the border needs to be initially drawn
+ if (gamestate == GS_LEVEL && oldgamestate != GS_LEVEL)
+ {
+ viewactivestate = false; // view was not active
+ R_FillBackScreen (); // draw the pattern into the back screen
+ }
+
+ // see if the border needs to be updated to the screen
+ if (gamestate == GS_LEVEL && !automapactive && scaledviewwidth != 320)
+ {
+ if (menuactive || menuactivestate || !viewactivestate)
+ {
+ borderdrawcount = 3;
+ popupactivestate = false;
+ }
+ if (borderdrawcount)
+ {
+ R_DrawViewBorder (); // erase old menu stuff
+ borderdrawcount--;
+ }
+
+ }
+
+ if (testcontrols)
+ {
+ // Box showing current mouse speed
+
+ G_DrawMouseSpeedBox();
+ }
+
+ menuactivestate = menuactive;
+ viewactivestate = viewactive;
+ inhelpscreensstate = inhelpscreens;
+ oldgamestate = wipegamestate = gamestate;
+
+ // draw pause pic
+ if (paused)
+ {
+ if (automapactive)
+ y = 4;
+ else
+ y = viewwindowy+4;
+ V_DrawPatchDirect(viewwindowx + (scaledviewwidth - 68) / 2, y,
+ W_CacheLumpName (DEH_String("M_PAUSE"), PU_CACHE));
+ }
+
+
+ // menus go directly to the screen
+ M_Drawer (); // menu is drawn even on top of everything
+ NetUpdate (); // send out any new accumulation
+
+
+ // normal update
+ if (!wipe)
+ {
+ I_FinishUpdate (); // page flip or blit buffer
+ return;
+ }
+
+ // wipe update
+ wipe_EndScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);
+
+ wipestart = I_GetTime () - 1;
+
+ do
+ {
+ do
+ {
+ nowtime = I_GetTime ();
+ tics = nowtime - wipestart;
+ I_Sleep(1);
+ } while (tics < 3); // haleyjd 08/23/2010: [STRIFE] Changed from == 0 to < 3
+
+ // haleyjd 08/26/10: [STRIFE] Changed to use ColorXForm wipe.
+ wipestart = nowtime;
+ done = wipe_ScreenWipe(wipe_ColorXForm
+ , 0, 0, SCREENWIDTH, SCREENHEIGHT, tics);
+ I_UpdateNoBlit ();
+ M_Drawer (); // menu is drawn even on top of wipes
+ I_FinishUpdate (); // page flip or blit buffer
+ } while (!done);
+}
+
+//
+// Add configuration file variable bindings.
+//
+
+void D_BindVariables(void)
+{
+ int i;
+
+ M_ApplyPlatformDefaults();
+
+ I_BindVideoVariables();
+ I_BindJoystickVariables();
+ I_BindSoundVariables();
+
+ M_BindBaseControls();
+ M_BindWeaponControls();
+ M_BindMapControls();
+ M_BindMenuControls();
+ M_BindStrifeControls(); // haleyjd 09/01/10: [STRIFE]
+ M_BindChatControls(MAXPLAYERS);
+
+ key_multi_msgplayer[0] = HUSTR_KEYGREEN;
+ key_multi_msgplayer[1] = HUSTR_KEYINDIGO;
+ key_multi_msgplayer[2] = HUSTR_KEYBROWN;
+ key_multi_msgplayer[3] = HUSTR_KEYRED;
+
+#ifdef FEATURE_MULTIPLAYER
+ NET_BindVariables();
+#endif
+
+ // haleyjd 08/29/10: [STRIFE]
+ // * Added voice volume
+ // * Added back flat
+ // * Removed show_messages
+ // * Added show_talk
+ // fraggle 03/06/10: [STRIFE]
+ // * Removed detailLevel
+ // * screenblocks -> screensize
+ // * Added nickname, comport
+
+ M_BindVariable("mouse_sensitivity", &mouseSensitivity);
+ M_BindVariable("sfx_volume", &sfxVolume);
+ M_BindVariable("music_volume", &musicVolume);
+ M_BindVariable("voice_volume", &voiceVolume);
+ M_BindVariable("show_talk", &dialogshowtext);
+ M_BindVariable("screensize", &screenblocks);
+ M_BindVariable("snd_channels", &snd_channels);
+ M_BindVariable("vanilla_savegame_limit", &vanilla_savegame_limit);
+ M_BindVariable("vanilla_demo_limit", &vanilla_demo_limit);
+ M_BindVariable("show_endoom", &show_endoom);
+ M_BindVariable("back_flat", &back_flat);
+
+ M_BindVariable("nickname", &nickname);
+ M_BindVariable("comport", &comport);
+
+ // Multiplayer chat macros
+
+ for (i=0; i<10; ++i)
+ {
+ char buf[12];
+
+ sprintf(buf, "chatmacro%i", i);
+ M_BindVariable(buf, &chat_macros[i]);
+ }
+}
+
+//
+// D_GrabMouseCallback
+//
+// Called to determine whether to grab the mouse pointer
+//
+
+boolean D_GrabMouseCallback(void)
+{
+ // Drone players don't need mouse focus
+
+ if (drone)
+ return false;
+
+ // when menu is active or game is paused, release the mouse
+
+ if (menuactive || paused)
+ return false;
+
+ // only grab mouse when playing levels (but not demos)
+
+ return (gamestate == GS_LEVEL) && !demoplayback;
+}
+
+//
+// D_DoomLoop
+//
+// haleyjd 08/23/10: [STRIFE] Verified unmodified.
+//
+extern boolean demorecording;
+
+void D_DoomLoop (void)
+{
+ if (demorecording)
+ G_BeginRecording ();
+
+ TryRunTics();
+
+ if(!showintro) // [STRIFE]
+ {
+ I_SetWindowTitle(gamedescription);
+ I_InitGraphics();
+ }
+ I_EnableLoadingDisk();
+ I_SetGrabMouseCallback(D_GrabMouseCallback);
+
+ V_RestoreBuffer();
+ R_ExecuteSetViewSize();
+
+ D_StartGameLoop();
+
+ if (testcontrols)
+ {
+ wipegamestate = gamestate;
+ }
+
+ while (1)
+ {
+ // frame syncronous IO operations
+ I_StartFrame ();
+
+ // process one or more tics
+ if (singletics)
+ {
+ I_StartTic ();
+ D_ProcessEvents ();
+ G_BuildTiccmd (&netcmds[consoleplayer][maketic%BACKUPTICS]);
+ if (advancedemo)
+ D_DoAdvanceDemo ();
+ M_Ticker ();
+ G_Ticker ();
+ gametic++;
+ maketic++;
+ }
+ else
+ {
+ TryRunTics (); // will run at least one tic
+ }
+
+ S_UpdateSounds (players[consoleplayer].mo);// move positional sounds
+
+ // Update display, next frame, with current state.
+ if (screenvisible)
+ D_Display ();
+ }
+}
+
+
+
+//
+// DEMO LOOP
+//
+int demosequence;
+int pagetic;
+char *pagename;
+
+
+//
+// D_PageTicker
+// Handles timing for warped projection
+//
+// haleyjd 08/22/2010: [STRIFE] verified unmodified
+//
+void D_PageTicker (void)
+{
+ if (--pagetic < 0)
+ D_AdvanceDemo ();
+}
+
+
+
+//
+// D_PageDrawer
+//
+// haleyjd 08/22/2010: [STRIFE] verified unmodified
+//
+void D_PageDrawer (void)
+{
+ V_DrawPatch (0, 0, W_CacheLumpName(pagename, PU_CACHE));
+}
+
+
+//
+// D_AdvanceDemo
+// Called after each demo or intro demosequence finishes
+//
+// haleyjd 08/22/2010: [STRIFE] verified unmodified
+//
+void D_AdvanceDemo (void)
+{
+ advancedemo = true;
+}
+
+
+//
+// This cycles through the demo sequences.
+// FIXME - version dependend demo numbers?
+//
+// [STRIFE] Modified for the opening slideshow and the exit screen
+//
+void D_DoAdvanceDemo (void)
+{
+ players[consoleplayer].playerstate = PST_LIVE; // not reborn
+ advancedemo = false;
+ usergame = false; // no save / end game here
+ paused = false;
+ gameaction = ga_nothing;
+
+ // villsa 09/12/10: [STRIFE] converted pagetics to ticrate
+ switch (demosequence)
+ {
+ case -5: // exit the game
+ I_Quit();
+ return;
+ case -4: // show exit screen
+ menuactive = false;
+ pagetic = 3*TICRATE;
+ gamestate = GS_DEMOSCREEN;
+ pagename = DEH_String("PANEL7");
+ S_StartMusic(mus_fast);
+ if(isdemoversion)
+ demosequence = -3; // show Velocity logo
+ else
+ demosequence = -5; // exit
+ return;
+ case -3: // show Velocity logo for demo version
+ pagetic = 6*TICRATE;
+ gamestate = GS_DEMOSCREEN;
+ pagename = DEH_String("vellogo");
+ demosequence = -5; // exit
+ return;
+ case -2: // title screen
+ pagetic = 6*TICRATE;
+ gamestate = GS_DEMOSCREEN;
+ pagename = DEH_String("TITLEPIC");
+ S_StartMusic(mus_logo);
+ demosequence = -1; // start intro cinematic
+ return;
+ case -1: // start of intro cinematic
+ pagetic = 10;
+ gamestate = GS_DEMOSCREEN;
+ pagename = DEH_String("PANEL0");
+ S_StartSound(NULL, sfx_rb2act);
+ wipegamestate = -1;
+ break;
+ case 0: // Rogue logo
+ pagetic = 4*TICRATE;
+ gamestate = GS_DEMOSCREEN;
+ pagename = DEH_String("RGELOGO");
+ wipegamestate = -1;
+ break;
+ case 1:
+ pagetic = 7*TICRATE; // The comet struck our planet without
+ gamestate = GS_DEMOSCREEN; // warning.We lost our paradise in a
+ pagename = DEH_String("PANEL1"); // single, violent stroke.
+ I_StartVoice(DEH_String("pro1"));
+ S_StartMusic(mus_intro);
+ break;
+ case 2:
+ pagetic = 9*TICRATE; // The impact released a virus which
+ gamestate = GS_DEMOSCREEN; // swept through the land and killed
+ pagename = DEH_String("PANEL2"); // millions. They turned out to be
+ I_StartVoice(DEH_String("pro2")); // the lucky ones...
+ break;
+ case 3:
+ pagetic = 12*TICRATE; // For those that did not die became
+ gamestate = GS_DEMOSCREEN; // mutations of humanity. Some became
+ pagename = DEH_String("PANEL3"); // fanatics who heard the voice of a
+ I_StartVoice(DEH_String("pro3")); // malignant God in their heads, and
+ break; // called themselves the Order.
+ case 4:
+ pagetic = 11*TICRATE; // Those of us who were deaf to this
+ pagename = DEH_String("PANEL4"); // voice suffer horribly and are
+ gamestate = GS_DEMOSCREEN; // forced to serve these ruthless
+ I_StartVoice(DEH_String("pro4")); // psychotics, who wield weapons more
+ break; // powerful than anything we can muster.
+ case 5:
+ pagetic = 10*TICRATE; // They destroy our women and children,
+ gamestate = GS_DEMOSCREEN; // so that we must hide them underground,
+ pagename = DEH_String("PANEL5"); // and live like animals in constant
+ I_StartVoice(DEH_String("pro5")); // fear for our lives.
+ break;
+ case 6: // But there are whispers of discontent.
+ pagetic = 16*TICRATE; // If we organize, can we defeat our
+ gamestate = GS_DEMOSCREEN; // masters? Weapons are being stolen,
+ pagename = DEH_String("PANEL6"); // soldiers are being trained. A
+ I_StartVoice(DEH_String("pro6")); // Movement is born! Born of lifelong
+ break; // STRIFE!
+ case 7: // titlepic again - unused...
+ pagetic = 9*TICRATE;
+ gamestate = GS_DEMOSCREEN;
+ pagename = DEH_String("TITLEPIC");
+ wipegamestate = -1;
+ break;
+ case 8: // demo
+ ClearTmp();
+ pagetic = 9*TICRATE;
+ G_DeferedPlayDemo(DEH_String("demo1"));
+ break;
+ case 9: // velocity logo? - unused...
+ pagetic = 6*TICRATE;
+ gamestate = GS_DEMOSCREEN;
+ pagename = DEH_String("vellogo");
+ wipegamestate = -1;
+ break;
+ case 10: // credits
+ gamestate = GS_DEMOSCREEN;
+ pagetic = 12*TICRATE;
+ pagename = DEH_String("CREDIT");
+ wipegamestate = -1;
+ break;
+ default:
+ break;
+ }
+
+ ++demosequence;
+
+ if(demosequence > 11)
+ demosequence = -2;
+ if(demosequence == 7 || demosequence == 9)
+ ++demosequence;
+}
+
+
+
+//
+// D_StartTitle
+//
+// [STRIFE]
+// haleyjd 09/11/10: Small modifications for new demo sequence.
+//
+void D_StartTitle (void)
+{
+ gamestate = GS_DEMOSCREEN;
+ gameaction = ga_nothing;
+ demosequence = -2;
+ D_AdvanceDemo ();
+}
+
+//
+// D_QuitGame
+//
+// [STRIFE] New function
+// haleyjd 09/11/10: Sets up the quit game snippet powered by the
+// demo sequence.
+//
+void D_QuitGame(void)
+{
+ gameaction = ga_nothing;
+ demosequence = -4;
+ D_AdvanceDemo();
+}
+
+// Strings for dehacked replacements of the startup banner
+//
+// These are from the original source: some of them are perhaps
+// not used in any dehacked patches
+
+static char *banners[] =
+{
+ // strife1.wad:
+
+ " "
+ "STRIFE: Quest for the Sigil v1.31"
+ " "
+};
+
+//
+// Get game name: if the startup banner has been replaced, use that.
+// Otherwise, use the name given
+//
+
+static char *GetGameName(char *gamename)
+{
+ size_t i;
+ char *deh_sub;
+
+ for (i=0; i<arrlen(banners); ++i)
+ {
+ // Has the banner been replaced?
+
+ deh_sub = DEH_String(banners[i]);
+
+ if (deh_sub != banners[i])
+ {
+ // Has been replaced
+ // We need to expand via printf to include the Doom version
+ // number
+ // We also need to cut off spaces to get the basic name
+
+ gamename = Z_Malloc(strlen(deh_sub) + 10, PU_STATIC, 0);
+ sprintf(gamename, deh_sub, STRIFE_VERSION / 100, STRIFE_VERSION % 100);
+
+ while (gamename[0] != '\0' && isspace(gamename[0]))
+ strcpy(gamename, gamename+1);
+
+ while (gamename[0] != '\0' && isspace(gamename[strlen(gamename)-1]))
+ gamename[strlen(gamename) - 1] = '\0';
+
+ return gamename;
+ }
+ }
+
+ return gamename;
+}
+
+//
+// Find out what version of Doom is playing.
+//
+
+void D_IdentifyVersion(void)
+{
+ // gamemission is set up by the D_FindIWAD function. But if
+ // we specify '-iwad', we have to identify using
+ // IdentifyIWADByName. However, if the iwad does not match
+ // any known IWAD name, we may have a dilemma. Try to
+ // identify by its contents.
+
+ // STRIFE-TODO: some elaborate checks? for now we assume...
+ // The logic in strife1.exe is simple:
+ // * if strife1.wad is found, set isregistered = true
+ // * if strife0.wad is found, set isdemoversion = true
+
+ // Make sure gamemode is set up correctly
+ gamemode = commercial;
+ gamemission = strife;
+ isregistered = true;
+
+ // Load voices.wad
+ if(isregistered)
+ {
+ char *name = D_FindWADByName("voices.wad");
+
+ if(!name) // not found?
+ {
+ int p;
+
+ // haleyjd STRIFE-FIXME: Temporary?
+ // If -iwad was used, check and see if voices.wad exists on the
+ // same filepath.
+ if((p = M_CheckParm("-iwad")) && p < myargc - 1)
+ {
+ char *iwad = myargv[p + 1];
+ size_t len = strlen(iwad) + 24;
+ char *filename = malloc(len);
+ char sepchar;
+
+ // how the heck is Choco surviving without this routine?
+ sepchar = M_GetFilePath(iwad, filename, len);
+ filename[strlen(filename)] = sepchar;
+ strcat(filename, "voices.wad");
+
+ if(!M_FileExists(filename))
+ disable_voices = 1;
+ else
+ name = filename; // STRIFE-FIXME: memory leak!!
+ }
+ else
+ disable_voices = 1;
+ }
+
+ if(disable_voices) // voices disabled?
+ {
+ if(devparm)
+ printf("Voices disabled\n");
+ return;
+ }
+
+ D_AddFile(name);
+ }
+}
+
+#if 0
+//
+// DoTimeBomb
+//
+// haleyjd 08/23/2010: [STRIFE] New function
+// Code with no xrefs; probably left over from a private alpha or beta.
+// Translated here because it explains what the SERIAL lump was meant to do.
+//
+void DoTimeBomb(void)
+{
+ dosdate_t date;
+ char *serial;
+ int serialnum;
+ int serial_year;
+ int serial_month;
+
+ serial = W_CacheLumpName("serial", PU_CACHE);
+ serialnum = atoi(serial);
+
+ // Rogue, much like Governor Mourel, were lousy liars. These deceptive
+ // error messages are pretty low :P
+ dos_getdate(&date);
+ if(date.year > 1996 || date.day > 15 && date.month > 4)
+ I_Error("Data error! Corrupted WAD File!");
+ serial_year = serialnum / 10000;
+ serial_month = serialnum / 100 - 100 * serial_year;
+ if(date.year < serial_year ||
+ date.day < serialnum - 100 * serial_month - 10000 * serial_year &&
+ date.month < serial_month)
+ I_Error("Bad wadfile");
+}
+#endif
+
+// Set the gamedescription string
+
+void D_SetGameDescription(void)
+{
+ gamedescription = GetGameName("Strife: Quest for the Sigil");
+}
+
+static void SetSaveGameDir(char *iwad_filename)
+{
+ char *sep;
+ char *basefile;
+
+ // Extract the base filename
+
+ sep = strrchr(iwad_filename, DIR_SEPARATOR);
+
+ if (sep == NULL)
+ {
+ basefile = iwad_filename;
+ }
+ else
+ {
+ basefile = sep + 1;
+ }
+
+ // ~/.chocolate-doom/savegames/
+
+ savegamedir = Z_Malloc(strlen(configdir) + 30, PU_STATIC, 0);
+ sprintf(savegamedir, "%ssavegames%c", configdir,
+ DIR_SEPARATOR);
+
+ M_MakeDirectory(savegamedir);
+
+ // eg. ~/.chocolate-doom/savegames/doom2.wad/
+
+ sprintf(savegamedir + strlen(savegamedir), "%s%c",
+ basefile, DIR_SEPARATOR);
+
+ M_MakeDirectory(savegamedir);
+
+ // haleyjd 20110210: Create Strife hub save folders
+ M_CreateSaveDirs(savegamedir);
+}
+
+// Check if the IWAD file is the Chex Quest IWAD.
+// Returns true if this is chex.wad.
+// haleyjd 08/23/10: there is no Chex Quest based on Strife,
+// though I must admit that makes an intriguing idea....
+/*
+static boolean CheckChex(char *iwadname)
+{
+ char *chex_iwadname = "chex.wad";
+
+ return (strlen(iwadname) > strlen(chex_iwadname)
+ && !strcasecmp(iwadname + strlen(iwadname) - strlen(chex_iwadname),
+ chex_iwadname));
+}
+*/
+
+// print title for every printed line
+char title[128];
+
+static boolean D_AddFile(char *filename)
+{
+ wad_file_t *handle;
+
+ printf(" adding %s\n", filename);
+ handle = W_AddFile(filename);
+
+ return handle != NULL;
+}
+
+// Copyright message banners
+// Some dehacked mods replace these. These are only displayed if they are
+// replaced by dehacked.
+// haleyjd 08/22/2010: [STRIFE] altered to match strings from binary
+static char *copyright_banners[] =
+{
+ "===========================================================================\n"
+ "ATTENTION: This version of STRIFE has extra files added to it.\n"
+ " You will not receive technical support for modified games.\n"
+ "===========================================================================\n",
+
+ "===========================================================================\n"
+ " This version is NOT SHAREWARE, do not distribute!\n"
+ " Please report software piracy to the SPA: 1-800-388-PIR8\n"
+ "===========================================================================\n",
+
+ "===========================================================================\n"
+ " Shareware!\n"
+ "===========================================================================\n"
+};
+
+// Prints a message only if it has been modified by dehacked.
+
+void PrintDehackedBanners(void)
+{
+ size_t i;
+
+ for (i=0; i<arrlen(copyright_banners); ++i)
+ {
+ char *deh_s;
+
+ deh_s = DEH_String(copyright_banners[i]);
+
+ if (deh_s != copyright_banners[i])
+ {
+ printf("%s", deh_s);
+
+ // Make sure the modified banner always ends in a newline character.
+ // If it doesn't, add a newline. This fixes av.wad.
+
+ if (deh_s[strlen(deh_s) - 1] != '\n')
+ {
+ printf("\n");
+ }
+ }
+ }
+}
+
+static struct
+{
+ char *description;
+ char *cmdline;
+ GameVersion_t version;
+} gameversions[] = {
+ {"Doom 1.9", "1.9", exe_doom_1_9},
+ {"Ultimate Doom", "ultimate", exe_ultimate},
+ {"Final Doom", "final", exe_final},
+ {"Chex Quest", "chex", exe_chex},
+ { NULL, NULL, 0},
+};
+
+// Initialize the game version
+
+static void InitGameVersion(void)
+{
+ int p;
+ int i;
+
+ //!
+ // @arg <version>
+ // @category compat
+ //
+ // Emulate a specific version of Doom. Valid values are "1.9",
+ // "ultimate" and "final".
+ //
+
+ p = M_CheckParmWithArgs("-gameversion", 1);
+
+ if (p)
+ {
+ for (i=0; gameversions[i].description != NULL; ++i)
+ {
+ if (!strcmp(myargv[p+1], gameversions[i].cmdline))
+ {
+ gameversion = gameversions[i].version;
+ break;
+ }
+ }
+
+ if (gameversions[i].description == NULL)
+ {
+ printf("Supported game versions:\n");
+
+ for (i=0; gameversions[i].description != NULL; ++i)
+ {
+ printf("\t%s (%s)\n", gameversions[i].cmdline,
+ gameversions[i].description);
+ }
+
+ I_Error("Unknown game version '%s'", myargv[p+1]);
+ }
+ }
+ else
+ {
+ // Determine automatically
+
+ // haleyjd 08/23/10: Removed Chex mode, as it is irrelevant to Strife
+ if (gamemode == shareware || gamemode == registered)
+ {
+ // original
+
+ gameversion = exe_doom_1_9;
+ }
+ else if (gamemode == retail)
+ {
+ gameversion = exe_ultimate;
+ }
+ else if (gamemode == commercial)
+ {
+ if (gamemission == doom2)
+ {
+ gameversion = exe_doom_1_9;
+ }
+ else
+ {
+ // Final Doom: tnt or plutonia
+
+ gameversion = exe_final;
+ }
+ }
+ }
+
+ // The original exe does not support retail - 4th episode not supported
+
+ if (gameversion < exe_ultimate && gamemode == retail)
+ {
+ gamemode = registered;
+ }
+
+ // EXEs prior to the Final Doom exes do not support Final Doom.
+
+ if (gameversion < exe_final && gamemode == commercial)
+ {
+ gamemission = doom2;
+ }
+}
+
+void PrintGameVersion(void)
+{
+ int i;
+
+ for (i=0; gameversions[i].description != NULL; ++i)
+ {
+ if (gameversions[i].version == gameversion)
+ {
+ printf("Emulating the behavior of the "
+ "'%s' executable.\n", gameversions[i].description);
+ break;
+ }
+ }
+}
+
+// Load the Chex Quest dehacked file, if we are in Chex mode.
+// haleyjd 08/23/2010: Removed, as irrelevant to Strife.
+/*
+static void LoadChexDeh(void)
+{
+ char *chex_deh;
+
+ if (gameversion == exe_chex)
+ {
+ chex_deh = D_FindWADByName("chex.deh");
+
+ if (chex_deh == NULL)
+ {
+ I_Error("Unable to find Chex Quest dehacked file (chex.deh).\n"
+ "The dehacked file is required in order to emulate\n"
+ "chex.exe correctly. It can be found in your nearest\n"
+ "/idgames repository mirror at:\n\n"
+ " utils/exe_edit/patches/chexdeh.zip");
+ }
+
+ if (!DEH_LoadFile(chex_deh))
+ {
+ I_Error("Failed to load chex.deh needed for emulating chex.exe.");
+ }
+ }
+}
+*/
+
+// Function called at exit to display the ENDOOM screen
+
+static void D_Endoom(void)
+{
+ byte *endoom;
+
+ // Don't show ENDOOM if we have it disabled, or we're running
+ // in screensaver or control test mode.
+
+ if (!show_endoom || screensaver_mode || M_CheckParm("-testcontrols") > 0)
+ {
+ return;
+ }
+
+ // haleyjd 08/27/10: [STRIFE] ENDOOM -> ENDSTRF
+ endoom = W_CacheLumpName(DEH_String("ENDSTRF"), PU_STATIC);
+
+ I_Endoom(endoom);
+}
+
+//=============================================================================
+//
+// haleyjd: Chocolate Strife Specifics
+//
+// None of the code in here is from the original executable, but is needed for
+// other reasons.
+
+//
+// D_PatchClipCallback
+//
+// haleyjd 08/28/10: Clip patches to the framebuffer without errors.
+// Returns false if V_DrawPatch should return without drawing.
+//
+boolean D_PatchClipCallback(patch_t *patch, int x, int y)
+{
+ // note that offsets were already accounted for in V_DrawPatch
+ return (x >= 0 && y >= 0
+ && x + SHORT(patch->width) <= SCREENWIDTH
+ && y + SHORT(patch->height) <= SCREENHEIGHT);
+}
+
+//
+// D_InitChocoStrife
+//
+// haleyjd 08/28/10: Take care of some Strife-specific initialization
+// that is necessitated by Chocolate Doom issues, such as setting global
+// callbacks.
+//
+static void D_InitChocoStrife(void)
+{
+ // set the V_DrawPatch clipping callback
+ V_SetPatchClipCallback(D_PatchClipCallback);
+}
+
+
+//
+// STRIFE Graphical Intro Sequence
+//
+
+#define MAXINTROPROGRESS 69
+
+static int introprogress; // track the progress of the intro
+
+static byte *rawgfx_startup0; // raw linear gfx for intro
+static byte *rawgfx_startp[4];
+static byte *rawgfx_startlz[2];
+static byte *rawgfx_startbot;
+
+//
+// D_IntroBackground
+//
+// [STRIFE] New function
+// haleyjd 20110206: Strife only drew this once, but for supporting double-
+// buffered or page-flipped surfaces it is best to redraw the entire screen
+// every frame.
+//
+static void D_IntroBackground(void)
+{
+ patch_t *panel0;
+
+ if(!showintro)
+ return;
+
+ // Slam up PANEL0 to fill the background entirely (wasn't needed in vanilla)
+ panel0 = W_CacheLumpName("PANEL0", PU_CACHE);
+ V_DrawPatch(0, 0, panel0);
+
+ // Strife cleared the screen somewhere in the low-level code between the
+ // intro and the titlescreen, so this is to take care of that and get
+ // proper fade-in behavior on the titlescreen
+ if(introprogress >= MAXINTROPROGRESS)
+ {
+ I_FinishUpdate();
+ return;
+ }
+
+ // Draw a 95-pixel rect from STARTUP0 starting at y=57 to (0,41) on the
+ // screen (this was a memcpy directly to 0xA3340 in low DOS memory)
+ V_DrawBlock(0, 41, 320, 95, rawgfx_startup0 + (320*57));
+}
+
+//
+// D_InitIntroSequence
+//
+// [STRIFE] New function
+// haleyjd 20110206: Initialize the graphical introduction sequence
+//
+static void D_InitIntroSequence(void)
+{
+ if(showintro)
+ {
+ // In vanilla Strife, Mode 13h was initialized directly in D_DoomMain.
+ // We have to be a little more courteous of the low-level code here.
+ I_SetWindowTitle(gamedescription);
+ I_InitGraphics();
+ V_RestoreBuffer(); // make the V_ routines work
+
+ // Load all graphics
+ rawgfx_startup0 = W_CacheLumpName("STARTUP0", PU_STATIC);
+ rawgfx_startp[0] = W_CacheLumpName("STRTPA1", PU_STATIC);
+ rawgfx_startp[1] = W_CacheLumpName("STRTPB1", PU_STATIC);
+ rawgfx_startp[2] = W_CacheLumpName("STRTPC1", PU_STATIC);
+ rawgfx_startp[3] = W_CacheLumpName("STRTPD1", PU_STATIC);
+ rawgfx_startlz[0] = W_CacheLumpName("STRTLZ1", PU_STATIC);
+ rawgfx_startlz[1] = W_CacheLumpName("STRTLZ2", PU_STATIC);
+ rawgfx_startbot = W_CacheLumpName("STRTBOT", PU_STATIC);
+
+ // Draw the background
+ D_IntroBackground();
+ }
+ /*
+ // STRIFE-FIXME: This was actually displayed on a special textmode
+ // screen with ANSI color codes... would require use of textlib to
+ // emulate properly...
+ else
+ {
+ puts(DEH_String("Conversation ON"));
+ puts(DEH_String("Rogue Entertainment"));
+ puts(DEH_String("and"));
+ puts(DEH_String("Velocity Games"));
+ puts(DEH_String("present"));
+ puts(DEH_String("S T R I F E"));
+ puts(DEH_String("Loading..."));
+ }
+ */
+}
+
+//
+// D_DrawIntroSequence
+//
+// [STRIFE] New function
+// haleyjd 20110206: Refresh the intro sequence
+//
+static void D_DrawIntroSequence(void)
+{
+ int laserpos;
+ int robotpos;
+
+ if(!showintro)
+ return;
+
+ D_IntroBackground(); // haleyjd: refresh the background
+
+ // Laser position
+ laserpos = (200 * introprogress / MAXINTROPROGRESS) + 60;
+
+ // BUG: (?) Due to this clip, the laser never even comes close to
+ // touching the peasant; confirmed with vanilla. This MAY have been
+ // intentional, for effect, however, since no death frames are shown
+ // either... kind of a black-out death.
+ if(laserpos > 200)
+ laserpos = 200;
+
+ // Draw the laser
+ // Blitted 16 bytes for 16 rows starting at 705280 + laserpos
+ // (705280 - 0xA0000) / 320 == 156
+ V_DrawBlock(laserpos, 156, 16, 16, rawgfx_startlz[laserpos % 2]);
+
+ // Robot position
+ robotpos = laserpos % 5 - 2;
+
+ // Draw the robot
+ // Blitted 48 bytes for 48 rows starting at 699534 + (320*robotpos)
+ // 699534 - 0xA0000 == 44174, which % 320 == 14, / 320 == 138
+ V_DrawBlock(14, 138 + robotpos, 48, 48, rawgfx_startbot);
+
+ // Draw the peasant
+ // Blitted 32 bytes for 64 rows starting at 699142
+ // 699142 - 0xA0000 == 43782, which % 320 == 262, / 320 == 136
+ V_DrawBlock(262, 136, 32, 64, rawgfx_startp[laserpos % 4]);
+
+ I_FinishUpdate();
+}
+
+//
+// D_IntroTick
+//
+// Advance the intro sequence
+//
+void D_IntroTick(void)
+{
+ if(devparm)
+ return;
+
+ ++introprogress;
+ if(introprogress >= MAXINTROPROGRESS)
+ {
+ D_IntroBackground(); // haleyjd: clear the bg anyway
+ S_StartSound(NULL, sfx_psdtha);
+ }
+ else
+ D_DrawIntroSequence();
+}
+
+//
+// End Chocolate Strife Specifics
+//
+//=============================================================================
+
+//
+// D_DoomMain
+//
+void D_DoomMain (void)
+{
+ int p;
+ char file[256];
+ char demolumpname[9];
+
+ I_AtExit(D_Endoom, false);
+
+ // haleyjd 20110206 [STRIFE]: -nograph parameter
+
+ //!
+ // @vanilla
+ //
+ // Disable graphical introduction sequence
+ //
+
+ if (M_CheckParm("-nograph") > 0)
+ showintro = false;
+
+ // haleyjd 20110206: Moved up -devparm for max visibility
+
+ //!
+ // @vanilla
+ //
+ // Developer mode. F1 saves a screenshot in the current working
+ // directory.
+ //
+
+ devparm = M_CheckParm ("-devparm");
+
+ // print banner
+
+ I_PrintBanner(PACKAGE_STRING);
+
+ //DEH_printf("Z_Init: Init zone memory allocation daemon. \n"); [STRIFE] removed
+ Z_Init ();
+
+#ifdef FEATURE_MULTIPLAYER
+ //!
+ // @category net
+ //
+ // Start a dedicated server, routing packets but not participating
+ // in the game itself.
+ //
+
+ if (M_CheckParm("-dedicated") > 0)
+ {
+ printf("Dedicated server mode.\n");
+ NET_DedicatedServer();
+
+ // Never returns
+ }
+
+ //!
+ // @category net
+ //
+ // Query the Internet master server for a global list of active
+ // servers.
+ //
+
+ if (M_CheckParm("-search"))
+ {
+ printf("\nSearching for servers on Internet ...\n");
+ p = NET_MasterQuery(NET_QueryPrintCallback, NULL);
+ printf("\n%i server(s) found.\n", p);
+ exit(0);
+ }
+
+ //!
+ // @arg <address>
+ // @category net
+ //
+ // Query the status of the server running on the given IP
+ // address.
+ //
+
+ p = M_CheckParmWithArgs("-query", 1);
+
+ if (p)
+ {
+ NET_QueryAddress(myargv[p+1]);
+ exit(0);
+ }
+
+ //!
+ // @category net
+ //
+ // Search the local LAN for running servers.
+ //
+
+ if (M_CheckParm("-localsearch"))
+ {
+ printf("\nSearching for servers on local LAN ...\n");
+ p = NET_LANQuery(NET_QueryPrintCallback, NULL);
+ printf("\n%i server(s) found.\n", p);
+ exit(0);
+ }
+
+#endif
+
+#ifdef FEATURE_DEHACKED
+ if(devparm)
+ printf("DEH_Init: Init Dehacked support.\n");
+ DEH_Init();
+#endif
+
+ iwadfile = D_FindIWAD(IWAD_MASK_STRIFE, &gamemission);
+
+ // None found?
+
+ if (iwadfile == NULL)
+ {
+ I_Error("Game mode indeterminate. No IWAD file was found. Try\n"
+ "specifying one with the '-iwad' command line parameter.\n");
+ }
+
+ modifiedgame = false;
+
+ //!
+ // @vanilla
+ //
+ // Disable monsters.
+ //
+
+ nomonsters = M_CheckParm ("-nomonsters");
+
+ //!
+ // @category strife
+ //
+ // Sets Rogue playtesting mode (godmode, noclip toggled by backspace)
+ //
+
+ workparm = M_CheckParm ("-work");
+
+ //!
+ // @category strife
+ //
+ // Attemps to flip player gun sprites, but is broken.
+ //
+
+ flipparm = M_CheckParm ("-flip");
+
+ //!
+ // @vanilla
+ //
+ // Monsters respawn after being killed.
+ //
+
+ respawnparm = M_CheckParm ("-respawn");
+
+ //!
+ // @vanilla
+ //
+ // Monsters move faster.
+ //
+
+ fastparm = M_CheckParm ("-fast");
+
+ I_DisplayFPSDots(devparm);
+
+ // haleyjd 20110206 [STRIFE]: -devparm implies -nograph
+ if(devparm)
+ showintro = false;
+
+ //!
+ // @category net
+ // @vanilla
+ //
+ // Start a deathmatch game.
+ //
+
+ if (M_CheckParm ("-deathmatch"))
+ deathmatch = 1;
+
+ //!
+ // @category net
+ // @vanilla
+ //
+ // Start a deathmatch 2.0 game. Weapons do not stay in place and
+ // all items respawn after 30 seconds.
+ //
+
+ if (M_CheckParm ("-altdeath"))
+ deathmatch = 2;
+
+ if (devparm)
+ DEH_printf(D_DEVSTR);
+
+ // find which dir to use for config files
+
+#ifdef _WIN32
+
+ //!
+ // @platform windows
+ // @vanilla
+ //
+ // Save configuration data and savegames in c:\doomdata,
+ // allowing play from CD.
+ //
+
+ if (M_CheckParm("-cdrom") > 0)
+ {
+ printf(D_CDROM);
+
+ // haleyjd 08/22/2010: [STRIFE] Use strife.cd folder for -cdrom
+ M_SetConfigDir("c:\\strife.cd\\");
+ }
+ else
+#endif
+ {
+ // Auto-detect the configuration dir.
+
+ M_SetConfigDir(NULL);
+ }
+
+ //!
+ // @arg <x>
+ // @vanilla
+ //
+ // Turbo mode. The player's speed is multiplied by x%. If unspecified,
+ // x defaults to 200. Values are rounded up to 10 and down to 400.
+ //
+
+ if ( (p=M_CheckParm ("-turbo")) )
+ {
+ int scale = 200;
+ extern int forwardmove[2];
+ extern int sidemove[2];
+
+ if (p<myargc-1)
+ scale = atoi (myargv[p+1]);
+ if (scale < 10)
+ scale = 10;
+ if (scale > 400)
+ scale = 400;
+ DEH_printf("turbo scale: %i%%\n", scale);
+ forwardmove[0] = forwardmove[0]*scale/100;
+ forwardmove[1] = forwardmove[1]*scale/100;
+ sidemove[0] = sidemove[0]*scale/100;
+ sidemove[1] = sidemove[1]*scale/100;
+ }
+
+ // init subsystems
+ // DEH_printf("V_Init: allocate screens.\n"); [STRIFE] removed
+ V_Init ();
+
+ // Load configuration files before initialising other subsystems.
+ // haleyjd 08/22/2010: [STRIFE] - use strife.cfg
+ // DEH_printf("M_LoadDefaults: Load system defaults.\n"); [STRIFE] removed
+ M_SetConfigFilenames("strife.cfg", PROGRAM_PREFIX "strife.cfg");
+ D_BindVariables();
+ M_LoadDefaults();
+
+ // Save configuration at exit.
+ I_AtExit(M_SaveDefaults, false);
+
+ if(devparm) // [STRIFE] Devparm only
+ DEH_printf("W_Init: Init WADfiles.\n");
+ D_AddFile(iwadfile);
+ modifiedgame = W_ParseCommandLine();
+
+ // [STRIFE] serial number output
+ if(devparm)
+ {
+ char msgbuf[80];
+ char *serial = W_CacheLumpName("SERIAL", PU_CACHE);
+ int serialnum = atoi(serial);
+
+ DEH_snprintf(msgbuf, sizeof(msgbuf), "Wad Serial Number: %d:", serialnum);
+ printf("%s\n", msgbuf);
+ }
+
+ // add any files specified on the command line with -file wadfile
+ // to the wad list
+ //
+
+ // Debug:
+// W_PrintDirectory();
+
+ //!
+ // @arg <demo>
+ // @category demo
+ // @vanilla
+ //
+ // Play back the demo named demo.lmp.
+ //
+
+ p = M_CheckParmWithArgs ("-playdemo", 1);
+
+ if (!p)
+ {
+ //!
+ // @arg <demo>
+ // @category demo
+ // @vanilla
+ //
+ // Play back the demo named demo.lmp, determining the framerate
+ // of the screen.
+ //
+ p = M_CheckParmWithArgs("-timedemo", 1);
+
+ }
+
+ if (p)
+ {
+ if (!strcasecmp(myargv[p+1] + strlen(myargv[p+1]) - 4, ".lmp"))
+ {
+ strcpy(file, myargv[p + 1]);
+ }
+ else
+ {
+ sprintf (file,"%s.lmp", myargv[p+1]);
+ }
+
+ if (D_AddFile (file))
+ {
+ strncpy(demolumpname, lumpinfo[numlumps - 1].name, 8);
+ demolumpname[8] = '\0';
+
+ printf("Playing demo %s.\n", file);
+ }
+ else
+ {
+ // If file failed to load, still continue trying to play
+ // the demo in the same way as Vanilla Doom. This makes
+ // tricks like "-playdemo demo1" possible.
+
+ strncpy(demolumpname, myargv[p + 1], 8);
+ demolumpname[8] = '\0';
+ }
+
+ }
+
+ I_AtExit((atexit_func_t) G_CheckDemoStatus, true);
+
+ // Generate the WAD hash table. Speed things up a bit.
+
+ W_GenerateHashTable();
+
+ D_IdentifyVersion();
+ InitGameVersion();
+ //LoadChexDeh(); - haleyjd: removed, as irrelevant to Strife
+ D_SetGameDescription();
+ SetSaveGameDir(iwadfile);
+
+ // haleyjd 20110206 [STRIFE] Startup the introduction sequence
+ D_InitIntroSequence();
+ D_IntroTick();
+
+ // Check for -file in shareware
+ if (modifiedgame)
+ {
+ // These are the lumps that will be checked in IWAD,
+ // if any one is not present, execution will be aborted.
+ // haleyjd 08/22/2010: [STRIFE] Check for Strife lumps.
+ char name[3][8]=
+ {
+ "map23", "map30", "ROB3E1"
+ };
+ int i;
+
+ // haleyjd 08/22/2010: [STRIFE] Changed string to match binary
+ // STRIFE-FIXME: Needs to test isdemoversion variable
+ if ( gamemode == shareware)
+ I_Error(DEH_String("\nYou cannot -file with the demo "
+ "version. You must buy the real game!"));
+
+ // Check for fake IWAD with right name,
+ // but w/o all the lumps of the registered version.
+ // STRIFE-FIXME: Needs to test isregistered variable
+ if (gamemode == registered)
+ for (i = 0; i < 3; i++)
+ if (W_CheckNumForName(name[i])<0)
+ I_Error(DEH_String("\nThis is not the registered version."));
+ }
+
+ D_IntroTick(); // [STRIFE]
+
+ // get skill / episode / map from parms
+ startskill = sk_medium;
+ startepisode = 1;
+ startmap = 1;
+ autostart = false;
+
+ //!
+ // @arg <skill>
+ // @vanilla
+ //
+ // Set the game skill, 1-5 (1: easiest, 5: hardest). A skill of
+ // 0 disables all monsters.
+ //
+
+ p = M_CheckParmWithArgs("-skill", 1);
+
+ if (p)
+ {
+ startskill = myargv[p+1][0]-'1';
+ autostart = true;
+ }
+
+ //!
+ // @arg <n>
+ // @vanilla
+ //
+ // Start playing on episode n (1-4)
+ //
+
+ p = M_CheckParmWithArgs("-episode", 1);
+
+ if (p)
+ {
+ startepisode = myargv[p+1][0]-'0';
+ startmap = 1;
+ autostart = true;
+ }
+
+ timelimit = 0;
+
+ //!
+ // @arg <n>
+ // @category net
+ // @vanilla
+ //
+ // For multiplayer games: exit each level after n minutes.
+ //
+
+ p = M_CheckParmWithArgs("-timer", 1);
+
+ if (p)
+ {
+ timelimit = atoi(myargv[p+1]);
+ printf("timer: %i\n", timelimit);
+ }
+
+ //!
+ // @category net
+ // @vanilla
+ //
+ // Austin Virtual Gaming: end levels after 20 minutes.
+ //
+
+ p = M_CheckParm ("-avg");
+
+ if (p)
+ {
+ timelimit = 20;
+ }
+
+ //!
+ // @arg [<x> <y> | <xy>]
+ // @vanilla
+ //
+ // Start a game immediately, warping to ExMy (Doom 1) or MAPxy
+ // (Doom 2)
+ //
+
+ p = M_CheckParmWithArgs("-warp", 1);
+
+ if (p)
+ {
+ if (gamemode == commercial)
+ startmap = atoi (myargv[p+1]);
+ else
+ {
+ startepisode = myargv[p+1][0]-'0';
+
+ if (p + 2 < myargc)
+ {
+ startmap = myargv[p+2][0]-'0';
+ }
+ else
+ {
+ startmap = 1;
+ }
+ }
+ autostart = true;
+ }
+
+ // Undocumented:
+ // Invoked by setup to test the controls.
+
+ p = M_CheckParm("-testcontrols");
+
+ if (p > 0)
+ {
+ startepisode = 1;
+ startmap = 1;
+ autostart = true;
+ testcontrols = true;
+ }
+
+ // Check for load game parameter
+ // We do this here and save the slot number, so that the network code
+ // can override it or send the load slot to other players.
+
+ //!
+ // @arg <s>
+ // @vanilla
+ //
+ // Load the game in slot s.
+ //
+
+ p = M_CheckParmWithArgs("-loadgame", 1);
+
+ if (p)
+ {
+ startloadgame = atoi(myargv[p+1]);
+ }
+ else
+ {
+ // Not loading a game
+ startloadgame = -1;
+ }
+
+ if (W_CheckNumForName("SS_START") >= 0
+ || W_CheckNumForName("FF_END") >= 0)
+ {
+ I_PrintDivider();
+ printf(" WARNING: The loaded WAD file contains modified sprites or\n"
+ " floor textures. You may want to use the '-merge' command\n"
+ " line option instead of '-file'.\n");
+ }
+
+ I_PrintStartupBanner(gamedescription);
+ PrintDehackedBanners();
+
+ // haleyjd 08/28/10: Init Choco Strife stuff.
+ D_InitChocoStrife();
+
+ // haleyjd 08/22/2010: [STRIFE] Modified string to match binary
+ if(devparm) // [STRIFE]
+ DEH_printf("R_Init: Loading Graphics - ");
+ R_Init ();
+ D_IntroTick(); // [STRIFE]
+
+ if(devparm) // [STRIFE]
+ DEH_printf("\nP_Init: Init Playloop state.\n");
+ P_Init ();
+ D_IntroTick(); // [STRIFE]
+
+ if(devparm) // [STRIFE]
+ DEH_printf("I_Init: Setting up machine state.\n");
+ I_CheckIsScreensaver();
+ I_InitTimer();
+ I_InitJoystick();
+ D_IntroTick(); // [STRIFE]
+
+#ifdef FEATURE_MULTIPLAYER
+ if(devparm) // [STRIFE]
+ printf ("NET_Init: Init network subsystem.\n");
+ NET_Init ();
+#endif
+ D_IntroTick(); // [STRIFE]
+
+ if(devparm) // [STRIFE]
+ DEH_printf("M_Init: Init Menu.\n");
+ M_Init ();
+ D_IntroTick(); // [STRIFE]
+
+ if(devparm) // [STRIFE]
+ DEH_printf("S_Init: Setting up sound.\n");
+ S_Init (sfxVolume * 8, musicVolume * 8, voiceVolume * 8); // [STRIFE]: voice
+ D_IntroTick(); // [STRIFE]
+
+ // haleyjd 20110220: This stuff was done in I_StartupSound in vanilla, but
+ // we'll do it here instead so we don't have to modify the low-level shared
+ // code with Strife-specific stuff.
+ if(disable_voices || M_CheckParm("-novoice"))
+ {
+ dialogshowtext = disable_voices = 1;
+ }
+ if(devparm)
+ DEH_printf(" Play voices = %d\n", disable_voices == 0);
+
+ if(devparm) // [STRIFE]
+ DEH_printf("D_CheckNetGame: Checking network game status.\n");
+ D_CheckNetGame ();
+
+ PrintGameVersion();
+
+ if(devparm)
+ DEH_printf("HU_Init: Setting up heads up display.\n");
+ HU_Init ();
+ D_IntroTick(); // [STRIFE]
+
+ if(devparm)
+ DEH_printf("ST_Init: Init status bar.\n");
+ ST_Init ();
+ D_IntroTick(); // [STRIFE]
+
+ // haleyjd [STRIFE] -statcopy used to be here...
+ D_IntroTick();
+
+ // If Doom II without a MAP01 lump, this is a store demo.
+ // Moved this here so that MAP01 isn't constantly looked up
+ // in the main loop.
+ // haleyjd 08/23/2010: [STRIFE] There is no storedemo version of Strife
+ /*
+ if (gamemode == commercial && W_CheckNumForName("map01") < 0)
+ storedemo = true;
+ */
+
+ //!
+ // @arg <x>
+ // @category demo
+ // @vanilla
+ //
+ // Record a demo named x.lmp.
+ //
+
+ p = M_CheckParmWithArgs("-record", 1);
+
+ if (p)
+ {
+ G_RecordDemo (myargv[p+1]);
+ autostart = true;
+ }
+ D_IntroTick(); // [STRIFE]
+
+ p = M_CheckParmWithArgs("-playdemo", 1);
+ if (p)
+ {
+ singledemo = true; // quit after one demo
+ G_DeferedPlayDemo (demolumpname);
+ D_DoomLoop (); // never returns
+ }
+ D_IntroTick(); // [STRIFE]
+
+ p = M_CheckParmWithArgs("-timedemo", 1);
+ if (p)
+ {
+ G_TimeDemo (demolumpname);
+ D_DoomLoop (); // never returns
+ }
+ D_IntroTick(); // [STRIFE]
+
+ if (startloadgame >= 0)
+ {
+ // [STRIFE]: different, for hubs
+ M_LoadSelect(startloadgame);
+ }
+ D_IntroTick(); // [STRIFE]
+
+ if (gameaction != ga_loadgame )
+ {
+ if (autostart || netgame)
+ G_InitNew (startskill, startmap);
+ else
+ D_StartTitle (); // start up intro loop
+ }
+
+ D_DoomLoop (); // never returns
+}
+