foxygit / doom Log in
commit dbdd53e7734b1166185a9906897d5dc87fd95376
Merge: 97ddedc9 68f51552
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Sun Mar 6 22:42:12 2011 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Sun Mar 6 22:42:12 2011 +0000

    Merge from raven-branch.

    Subversion-branch: /branches/strife-branch
    Subversion-revision: 2293

 NEWS                      |  6 ++++++
 pkg/osx/IWADController.h  |  4 ++++
 pkg/osx/IWADController.m  | 35 ++++++++++++++++++++++++++++++++++-
 pkg/osx/LauncherManager.m | 24 +++++++++++++++++++++---
 src/doom/d_main.c         |  2 --
 src/heretic/d_main.c      |  1 -
 src/hexen/h2_main.c       |  1 -
 src/i_main.c              |  2 ++
 src/i_sdlsound.c          | 14 +++++++++++++-
 src/setup/display.c       | 11 +++++++----
 src/setup/keyboard.c      |  6 ------
 src/strife/d_main.c       |  2 --
 12 files changed, 87 insertions(+), 21 deletions(-)

diff --cc src/i_sdlsound.c
index 03e9d85b,2bce2fb1..e3118a82
--- a/src/i_sdlsound.c
+++ b/src/i_sdlsound.c
@@@ -669,12 -490,15 +675,18 @@@ static boolean CacheSFX(sfxinfo_t *sfxi
          return false;
      }

+     // The DMX sound library seems to skip the first 16 and last 16
+     // bytes of the lump - reason unknown.
+
+     data += 16;
+     length -= 32;
+
      // Sample rate conversion

 -    ExpandSoundData(sfxinfo, data + 8, samplerate, length);
 +    if (!ExpandSoundData(sfxinfo, data + 8, samplerate, length))
 +    {
 +        return false;
 +    }

  #ifdef DEBUG_DUMP_WAVS
      {
diff --cc src/strife/d_main.c
index 6367818a,00000000..663d2028
mode 100644,000000..100644
--- a/src/strife/d_main.c
+++ b/src/strife/d_main.c
@@@ -1,2011 -1,0 +1,2009 @@@
 +// 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         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;
 +
 +
 +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_text
 +    M_BindVariable("mouse_sensitivity",      &mouseSensitivity);
 +    M_BindVariable("sfx_volume",             &sfxVolume);
 +    M_BindVariable("music_volume",           &musicVolume);
 +    M_BindVariable("voice_volume",           &voiceVolume);
 +    M_BindVariable("show_text",              &dialogshowtext);
 +    M_BindVariable("screenblocks",           &screenblocks);
 +    M_BindVariable("detaillevel",            &detailLevel);
 +    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);
 +
 +    // 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);
 +
-     M_FindResponseFile ();
-
 +    // 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");
 +
 +    //!
 +    // @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
 +}
 +