summaryrefslogtreecommitdiff
path: root/src/heretic/d_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/heretic/d_main.c')
-rw-r--r--src/heretic/d_main.c1038
1 files changed, 1038 insertions, 0 deletions
diff --git a/src/heretic/d_main.c b/src/heretic/d_main.c
new file mode 100644
index 00000000..669d7b3d
--- /dev/null
+++ b/src/heretic/d_main.c
@@ -0,0 +1,1038 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 1993-2008 Raven Software
+//
+// 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.
+//
+//-----------------------------------------------------------------------------
+
+// D_main.c
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "ct_chat.h"
+#include "doomdef.h"
+#include "d_iwad.h"
+#include "i_system.h"
+#include "i_video.h"
+#include "m_argv.h"
+#include "m_config.h"
+#include "m_controls.h"
+#include "p_local.h"
+#include "s_sound.h"
+#include "v_video.h"
+
+GameMission_t gamemission = heretic;
+GameMode_t gamemode = indetermined;
+char *gamedescription = "unknown";
+
+boolean nomonsters; // checkparm of -nomonsters
+boolean respawnparm; // checkparm of -respawn
+boolean debugmode; // checkparm of -debug
+boolean ravpic; // checkparm of -ravpic
+boolean cdrom; // true if cd-rom mode active
+boolean singletics; // debug flag to cancel adaptiveness
+boolean noartiskip; // whether shift-enter skips an artifact
+
+skill_t startskill;
+int startepisode;
+int startmap;
+int UpdateState;
+boolean autostart;
+extern boolean automapactive;
+
+boolean advancedemo;
+
+FILE *debugfile;
+
+static int show_endoom = 1;
+
+void D_CheckNetGame(void);
+void D_ProcessEvents(void);
+void G_BuildTiccmd(ticcmd_t * cmd);
+void D_DoAdvanceDemo(void);
+void D_PageDrawer(void);
+void D_AdvanceDemo(void);
+void F_Drawer(void);
+boolean F_Responder(event_t * ev);
+
+//---------------------------------------------------------------------------
+//
+// PROC D_ProcessEvents
+//
+// Send all the events of the given timestamp down the responder chain.
+//
+//---------------------------------------------------------------------------
+
+void D_ProcessEvents(void)
+{
+ event_t *ev;
+
+ while ((ev = D_PopEvent()) != NULL)
+ {
+ if (F_Responder(ev))
+ {
+ continue;
+ }
+ if (MN_Responder(ev))
+ {
+ continue;
+ }
+ G_Responder(ev);
+ }
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC DrawMessage
+//
+//---------------------------------------------------------------------------
+
+void DrawMessage(void)
+{
+ player_t *player;
+
+ player = &players[consoleplayer];
+ if (player->messageTics <= 0 || !player->message)
+ { // No message
+ return;
+ }
+ MN_DrTextA(player->message, 160 - MN_TextAWidth(player->message) / 2, 1);
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC D_Display
+//
+// Draw current display, possibly wiping it from the previous.
+//
+//---------------------------------------------------------------------------
+
+void R_ExecuteSetViewSize(void);
+
+extern boolean finalestage;
+
+void D_Display(void)
+{
+ extern boolean MenuActive;
+ extern boolean askforquit;
+
+ // Change the view size if needed
+ if (setsizeneeded)
+ {
+ R_ExecuteSetViewSize();
+ }
+
+//
+// do buffered drawing
+//
+ switch (gamestate)
+ {
+ case GS_LEVEL:
+ if (!gametic)
+ break;
+ if (automapactive)
+ AM_Drawer();
+ else
+ R_RenderPlayerView(&players[displayplayer]);
+ CT_Drawer();
+ UpdateState |= I_FULLVIEW;
+ SB_Drawer();
+ break;
+ case GS_INTERMISSION:
+ IN_Drawer();
+ break;
+ case GS_FINALE:
+ F_Drawer();
+ break;
+ case GS_DEMOSCREEN:
+ D_PageDrawer();
+ break;
+ }
+
+ if (paused && !MenuActive && !askforquit)
+ {
+ if (!netgame)
+ {
+ V_DrawPatch(160, viewwindowy + 5, W_CacheLumpName("PAUSED",
+ PU_CACHE));
+ }
+ else
+ {
+ V_DrawPatch(160, 70, W_CacheLumpName("PAUSED", PU_CACHE));
+ }
+ }
+ // Handle player messages
+ DrawMessage();
+
+ // Menu drawing
+ MN_Drawer();
+
+ // Send out any new accumulation
+ NetUpdate();
+
+ // Flush buffered stuff to screen
+ I_FinishUpdate();
+}
+
+//
+// D_GrabMouseCallback
+//
+// Called to determine whether to grab the mouse pointer
+//
+
+boolean D_GrabMouseCallback(void)
+{
+ // 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;
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC D_DoomLoop
+//
+//---------------------------------------------------------------------------
+
+void D_DoomLoop(void)
+{
+ if (M_CheckParm("-debugfile"))
+ {
+ char filename[20];
+ sprintf(filename, "debug%i.txt", consoleplayer);
+ debugfile = fopen(filename, "w");
+ }
+ I_InitGraphics();
+ I_SetWindowTitle(gamedescription);
+ I_SetGrabMouseCallback(D_GrabMouseCallback);
+
+ 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();
+ G_Ticker();
+ gametic++;
+ maketic++;
+ }
+ else
+ {
+ // Will run at least one tic
+ TryRunTics();
+ }
+
+ // Move positional sounds
+ S_UpdateSounds(players[consoleplayer].mo);
+ D_Display();
+ }
+}
+
+/*
+===============================================================================
+
+ DEMO LOOP
+
+===============================================================================
+*/
+
+int demosequence;
+int pagetic;
+char *pagename;
+
+
+/*
+================
+=
+= D_PageTicker
+=
+= Handles timing for warped projection
+=
+================
+*/
+
+void D_PageTicker(void)
+{
+ if (--pagetic < 0)
+ D_AdvanceDemo();
+}
+
+
+/*
+================
+=
+= D_PageDrawer
+=
+================
+*/
+
+extern boolean MenuActive;
+
+void D_PageDrawer(void)
+{
+ V_DrawRawScreen(W_CacheLumpName(pagename, PU_CACHE));
+ if (demosequence == 1)
+ {
+ V_DrawPatch(4, 160, W_CacheLumpName("ADVISOR", PU_CACHE));
+ }
+ UpdateState |= I_FULLSCRN;
+}
+
+/*
+=================
+=
+= D_AdvanceDemo
+=
+= Called after each demo or intro demosequence finishes
+=================
+*/
+
+void D_AdvanceDemo(void)
+{
+ advancedemo = true;
+}
+
+void D_DoAdvanceDemo(void)
+{
+ players[consoleplayer].playerstate = PST_LIVE; // don't reborn
+ advancedemo = false;
+ usergame = false; // can't save / end game here
+ paused = false;
+ gameaction = ga_nothing;
+ demosequence = (demosequence + 1) % 7;
+ switch (demosequence)
+ {
+ case 0:
+ pagetic = 210;
+ gamestate = GS_DEMOSCREEN;
+ pagename = "TITLE";
+ S_StartSong(mus_titl, false);
+ break;
+ case 1:
+ pagetic = 140;
+ gamestate = GS_DEMOSCREEN;
+ pagename = "TITLE";
+ break;
+ case 2:
+ BorderNeedRefresh = true;
+ UpdateState |= I_FULLSCRN;
+ G_DeferedPlayDemo("demo1");
+ break;
+ case 3:
+ pagetic = 200;
+ gamestate = GS_DEMOSCREEN;
+ pagename = "CREDIT";
+ break;
+ case 4:
+ BorderNeedRefresh = true;
+ UpdateState |= I_FULLSCRN;
+ G_DeferedPlayDemo("demo2");
+ break;
+ case 5:
+ pagetic = 200;
+ gamestate = GS_DEMOSCREEN;
+ if (gamemode == shareware)
+ {
+ pagename = "ORDER";
+ }
+ else
+ {
+ pagename = "CREDIT";
+ }
+ break;
+ case 6:
+ BorderNeedRefresh = true;
+ UpdateState |= I_FULLSCRN;
+ G_DeferedPlayDemo("demo3");
+ break;
+ }
+}
+
+
+/*
+=================
+=
+= D_StartTitle
+=
+=================
+*/
+
+void D_StartTitle(void)
+{
+ gameaction = ga_nothing;
+ demosequence = -1;
+ D_AdvanceDemo();
+}
+
+
+/*
+==============
+=
+= D_CheckRecordFrom
+=
+= -recordfrom <savegame num> <demoname>
+==============
+*/
+
+void D_CheckRecordFrom(void)
+{
+ int p;
+ char file[256];
+
+ p = M_CheckParm("-recordfrom");
+ if (!p || p > myargc - 2)
+ return;
+
+ if (cdrom)
+ {
+ sprintf(file, SAVEGAMENAMECD "%c.hsg", myargv[p + 1][0]);
+ }
+ else
+ {
+ sprintf(file, SAVEGAMENAME "%c.hsg", myargv[p + 1][0]);
+ }
+ G_LoadGame(file);
+ G_DoLoadGame(); // load the gameskill etc info from savegame
+
+ G_RecordDemo(gameskill, 1, gameepisode, gamemap, myargv[p + 2]);
+ D_DoomLoop(); // never returns
+}
+
+/*
+===============
+=
+= D_AddFile
+=
+===============
+*/
+
+// MAPDIR should be defined as the directory that holds development maps
+// for the -wart # # command
+
+#define MAPDIR "\\data\\"
+
+#define SHAREWAREWADNAME "heretic1.wad"
+
+static iwad_t iwads[] = {
+ { "heretic.wad", heretic },
+ { "heretic1.wad", heretic },
+ { NULL, none },
+};
+
+char *iwadfile;
+
+char *basedefault = "heretic.cfg";
+
+void wadprintf(void)
+{
+ if (debugmode)
+ {
+ return;
+ }
+#ifdef __WATCOMC__
+ _settextposition(23, 2);
+ _setbkcolor(1);
+ _settextcolor(0);
+ _outtext(exrnwads);
+ _settextposition(24, 2);
+ _outtext(exrnwads2);
+#endif
+}
+
+boolean D_AddFile(char *file)
+{
+ wad_file_t *handle;
+
+ printf(" adding %s\n", file);
+
+ handle = W_AddFile(file);
+
+ return handle != NULL;
+}
+
+//==========================================================
+//
+// Startup Thermo code
+//
+//==========================================================
+#define MSG_Y 9
+//#define THERM_X 15
+//#define THERM_Y 16
+//#define THERMCOLOR 3
+#define THERM_X 14
+#define THERM_Y 14
+
+int thermMax;
+int thermCurrent;
+char *startup; // * to text screen
+char smsg[80]; // status bar line
+
+//
+// Heretic startup screen shit
+//
+
+byte *hscreen;
+
+void hgotoxy(int x, int y)
+{
+ hscreen = (byte *) (0xb8000 + y * 160 + x * 2);
+}
+
+void hput(unsigned char c, unsigned char a)
+{
+ *hscreen++ = c;
+ *hscreen++ = a;
+}
+
+void hprintf(char *string, unsigned char a)
+{
+#ifdef __WATCOMC__
+ int i;
+
+ if (debugmode)
+ {
+ puts(string);
+ return;
+ }
+ for (i = 0; i < strlen(string); i++)
+ {
+ hput(string[i], a);
+ }
+#endif
+}
+
+void drawstatus(void)
+{
+ if (debugmode)
+ {
+ return;
+ }
+#ifdef __WATCOMC__
+ _settextposition(25, 2);
+ _setbkcolor(1);
+ _settextcolor(15);
+ _outtext(smsg);
+ _settextposition(25, 1);
+#endif
+}
+
+void status(char *string)
+{
+ strcat(smsg, string);
+ drawstatus();
+}
+
+void DrawThermo(void)
+{
+#ifdef __WATCOMC__
+ unsigned char *screen;
+ int progress;
+ int i;
+
+ if (debugmode)
+ {
+ return;
+ }
+#if 0
+ progress = (98 * thermCurrent) / thermMax;
+ screen = (char *) 0xb8000 + (THERM_Y * 160 + THERM_X * 2);
+ for (i = 0; i < progress / 2; i++)
+ {
+ switch (i)
+ {
+ case 4:
+ case 9:
+ case 14:
+ case 19:
+ case 29:
+ case 34:
+ case 39:
+ case 44:
+ *screen++ = 0xb3;
+ *screen++ = (THERMCOLOR << 4) + 15;
+ break;
+ case 24:
+ *screen++ = 0xba;
+ *screen++ = (THERMCOLOR << 4) + 15;
+ break;
+ default:
+ *screen++ = 0xdb;
+ *screen++ = 0x40 + THERMCOLOR;
+ break;
+ }
+ }
+ if (progress & 1)
+ {
+ *screen++ = 0xdd;
+ *screen++ = 0x40 + THERMCOLOR;
+ }
+#else
+ progress = (50 * thermCurrent) / thermMax + 2;
+// screen = (char *)0xb8000 + (THERM_Y*160 + THERM_X*2);
+ hgotoxy(THERM_X, THERM_Y);
+ for (i = 0; i < progress; i++)
+ {
+// *screen++ = 0xdb;
+// *screen++ = 0x2a;
+ hput(0xdb, 0x2a);
+ }
+#endif
+#endif
+}
+
+#ifdef __WATCOMC__
+void blitStartup(void)
+{
+ byte *textScreen;
+
+ if (debugmode)
+ {
+ return;
+ }
+
+ // Blit main screen
+ textScreen = (byte *) 0xb8000;
+ memcpy(textScreen, startup, 4000);
+
+ // Print version string
+ _setbkcolor(4); // Red
+ _settextcolor(14); // Yellow
+ _settextposition(3, 47);
+ _outtext(HERETIC_VERSION_TEXT);
+
+ // Hide cursor
+ _settextcursor(0x2000);
+}
+#endif
+
+char tmsg[300];
+void tprintf(char *msg, int initflag)
+{
+#ifdef __WATCOMC__
+ char temp[80];
+ int start;
+ int add;
+ int i;
+
+ if (initflag)
+ tmsg[0] = 0;
+ strcat(tmsg, msg);
+ blitStartup();
+ DrawThermo();
+ _setbkcolor(4);
+ _settextcolor(15);
+ for (add = start = i = 0; i <= strlen(tmsg); i++)
+ if ((tmsg[i] == '\n') || (!tmsg[i]))
+ {
+ memset(temp, 0, 80);
+ strncpy(temp, tmsg + start, i - start);
+ _settextposition(MSG_Y + add, 40 - strlen(temp) / 2);
+ _outtext(temp);
+ start = i + 1;
+ add++;
+ }
+ _settextposition(25, 1);
+ drawstatus();
+#else
+ printf("%s", msg);
+#endif
+}
+
+void CheckAbortStartup(void)
+{
+#ifdef __WATCOMC__
+ extern int lastpress;
+
+ if (lastpress == 1)
+ { // Abort if escape pressed
+ CleanExit();
+ }
+#endif
+}
+
+void IncThermo(void)
+{
+ thermCurrent++;
+ DrawThermo();
+ CheckAbortStartup();
+}
+
+void InitThermo(int max)
+{
+ thermMax = max;
+ thermCurrent = 0;
+}
+
+#ifdef __WATCOMC__
+void CleanExit(void)
+{
+ union REGS regs;
+
+ I_ShutdownKeyboard();
+ regs.x.eax = 0x3;
+ int386(0x10, &regs, &regs);
+ printf("Exited from HERETIC.\n");
+ exit(1);
+}
+#endif
+
+//
+// Add configuration file variable bindings.
+//
+
+void D_BindVariables(void)
+{
+ extern int screenblocks;
+ extern int snd_Channels;
+ int i;
+
+ I_BindVariables();
+ M_BindBaseControls();
+ M_BindHereticControls();
+
+ M_BindVariable("mouse_sensitivity", &mouseSensitivity);
+ M_BindVariable("sfx_volume", &snd_MaxVolume);
+ M_BindVariable("music_volume", &snd_MusicVolume);
+ M_BindVariable("screenblocks", &screenblocks);
+ M_BindVariable("snd_channels", &snd_Channels);
+ M_BindVariable("show_endoom", &show_endoom);
+
+ for (i=0; i<10; ++i)
+ {
+ char buf[12];
+
+ sprintf(buf, "chatmacro%i", i);
+ M_BindVariable(buf, &chat_macros[i]);
+ }
+}
+
+//
+// Called at exit to display the ENDOOM screen (ENDTEXT in Heretic)
+//
+
+static void D_Endoom(void)
+{
+ byte *endoom_data;
+
+ // Disable ENDOOM?
+
+ if (!show_endoom)
+ {
+ return;
+ }
+
+ endoom_data = W_CacheLumpName("ENDTEXT", PU_STATIC);
+
+ I_Endoom(endoom_data);
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC D_DoomMain
+//
+//---------------------------------------------------------------------------
+
+void D_DoomMain(void)
+{
+ int p;
+ char file[256];
+
+ I_PrintBanner(PACKAGE_STRING);
+
+ I_AtExit(D_Endoom, false);
+
+ M_FindResponseFile();
+ setbuf(stdout, NULL);
+ nomonsters = M_CheckParm("-nomonsters");
+ respawnparm = M_CheckParm("-respawn");
+ ravpic = M_CheckParm("-ravpic");
+ noartiskip = M_CheckParm("-noartiskip");
+ debugmode = M_CheckParm("-debug");
+ startskill = sk_medium;
+ startepisode = 1;
+ startmap = 1;
+ autostart = false;
+
+ // Check for -CDROM
+ cdrom = false;
+#ifdef __WATCOMC__
+ if (M_CheckParm("-cdrom"))
+ {
+ cdrom = true;
+ mkdir("c:\\heretic.cd");
+ }
+#endif
+
+//
+// get skill / episode / map from parms
+//
+ if (M_CheckParm("-deathmatch"))
+ {
+ deathmatch = true;
+ }
+
+ p = M_CheckParm("-skill");
+ if (p && p < myargc - 1)
+ {
+ startskill = myargv[p + 1][0] - '1';
+ autostart = true;
+ }
+
+ p = M_CheckParm("-episode");
+ if (p && p < myargc - 1)
+ {
+ startepisode = myargv[p + 1][0] - '0';
+ startmap = 1;
+ autostart = true;
+ }
+
+ p = M_CheckParm("-warp");
+ if (p && p < myargc - 2)
+ {
+ startepisode = myargv[p + 1][0] - '0';
+ startmap = myargv[p + 2][0] - '0';
+ autostart = true;
+ }
+
+//
+// init subsystems
+//
+ printf("V_Init: allocate screens.\n");
+ V_Init();
+
+ M_SetConfigDir();
+
+ // Load defaults before initing other systems
+ printf("M_LoadDefaults: Load system defaults.\n");
+ D_BindVariables();
+ M_SetConfigFilenames("heretic.cfg", PROGRAM_PREFIX "heretic.cfg");
+ M_LoadDefaults();
+
+ I_AtExit(M_SaveDefaults, false);
+
+ printf("Z_Init: Init zone memory allocation daemon.\n");
+ Z_Init();
+
+ printf("W_Init: Init WADfiles.\n");
+
+ iwadfile = D_FindIWAD(iwads, &gamemission);
+
+ if (iwadfile == NULL)
+ {
+ I_Error("Game mode indeterminate. No IWAD was found. Try specifying\n"
+ "one with the '-iwad' command line parameter.");
+ }
+
+ D_AddFile(iwadfile);
+
+ // -FILE [filename] [filename] ...
+ // Add files to the wad list.
+ p = M_CheckParm("-file");
+ if (p)
+ { // the parms after p are wadfile/lump names, until end of parms
+ // or another - preceded parm
+ while (++p != myargc && myargv[p][0] != '-')
+ {
+ D_AddFile(myargv[p]);
+ }
+ }
+
+ p = M_CheckParm("-playdemo");
+ if (!p)
+ {
+ p = M_CheckParm("-timedemo");
+ }
+ if (p && p < myargc - 1)
+ {
+ sprintf(file, "%s.lmp", myargv[p + 1]);
+ D_AddFile(file);
+ printf("Playing demo %s.lmp.\n", myargv[p + 1]);
+ }
+
+ if (W_CheckNumForName("E2M1") == -1)
+ {
+ gamemode = shareware;
+ gamedescription = "Heretic (shareware)";
+ }
+ else if (W_CheckNumForName("EXTENDED") != -1)
+ {
+ // Presence of the EXTENDED lump indicates the retail version
+
+ gamemode = retail;
+ gamedescription = "Heretic: Shadow of the Serpent Riders";
+ }
+ else
+ {
+ gamemode = registered;
+ gamedescription = "Heretic (registered)";
+ }
+
+ I_PrintStartupBanner(gamedescription);
+
+#ifdef __WATCOMC__
+ I_StartupKeyboard();
+ I_StartupJoystick();
+#endif
+ startup = W_CacheLumpName("LOADING", PU_CACHE);
+#ifdef __WATCOMC__
+ blitStartup();
+#endif
+
+ //
+ // Build status bar line!
+ //
+ smsg[0] = 0;
+ if (deathmatch)
+ status("DeathMatch...");
+ if (nomonsters)
+ status("No Monsters...");
+ if (respawnparm)
+ status("Respawning...");
+ if (autostart)
+ {
+ char temp[64];
+ sprintf(temp, "Warp to Episode %d, Map %d, Skill %d ",
+ startepisode, startmap, startskill + 1);
+ status(temp);
+ }
+ wadprintf(); // print the added wadfiles
+
+ tprintf("MN_Init: Init menu system.\n", 1);
+ MN_Init();
+
+ CT_Init();
+
+ tprintf("R_Init: Init Heretic refresh daemon.", 1);
+ hgotoxy(17, 7);
+ hprintf("Loading graphics", 0x3f);
+ R_Init();
+ tprintf("\n", 0);
+
+ tprintf("P_Init: Init Playloop state.\n", 1);
+ hgotoxy(17, 8);
+ hprintf("Init game engine.", 0x3f);
+ P_Init();
+ IncThermo();
+
+ tprintf("I_Init: Setting up machine state.\n", 1);
+ I_Init();
+ IncThermo();
+
+ tprintf("S_Init: Setting up sound.\n", 1);
+ S_Init();
+ //IO_StartupTimer();
+ S_Start();
+
+ tprintf("D_CheckNetGame: Checking network game status.\n", 1);
+ hgotoxy(17, 9);
+ hprintf("Checking network game status.", 0x3f);
+ D_CheckNetGame();
+ IncThermo();
+
+#ifdef __WATCOMC__
+ I_CheckExternDriver(); // Check for an external device driver
+#endif
+
+ tprintf("SB_Init: Loading patches.\n", 1);
+ SB_Init();
+ IncThermo();
+
+//
+// start the apropriate game based on parms
+//
+
+ D_CheckRecordFrom();
+
+ p = M_CheckParm("-record");
+ if (p && p < myargc - 1)
+ {
+ G_RecordDemo(startskill, 1, startepisode, startmap, myargv[p + 1]);
+ D_DoomLoop(); // Never returns
+ }
+
+ p = M_CheckParm("-playdemo");
+ if (p && p < myargc - 1)
+ {
+ singledemo = true; // Quit after one demo
+ G_DeferedPlayDemo(myargv[p + 1]);
+ D_DoomLoop(); // Never returns
+ }
+
+ p = M_CheckParm("-timedemo");
+ if (p && p < myargc - 1)
+ {
+ G_TimeDemo(myargv[p + 1]);
+ D_DoomLoop(); // Never returns
+ }
+
+ p = M_CheckParm("-loadgame");
+ if (p && p < myargc - 1)
+ {
+ if (cdrom)
+ {
+ sprintf(file, SAVEGAMENAMECD "%c.hsg", myargv[p + 1][0]);
+ }
+ else
+ {
+ sprintf(file, SAVEGAMENAME "%c.hsg", myargv[p + 1][0]);
+ }
+ G_LoadGame(file);
+ }
+
+ // Check valid episode and map
+ if (autostart || netgame)
+ {
+ if (M_ValidEpisodeMap(startepisode, startmap) == false)
+ {
+ startepisode = 1;
+ startmap = 1;
+ }
+ }
+
+ if (gameaction != ga_loadgame)
+ {
+ UpdateState |= I_FULLSCRN;
+ BorderNeedRefresh = true;
+ if (autostart || netgame)
+ {
+ G_InitNew(startskill, startepisode, startmap);
+ }
+ else
+ {
+ D_StartTitle();
+ }
+ }
+#ifdef __WATCOMC__
+ _settextcursor(0x0607); // bring the cursor back
+#endif
+ D_DoomLoop(); // Never returns
+}