CGDoom/cgdoom/d_main.c

579 lines
13 KiB
C

// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id:$
//
// Copyright (C) 1993-1996 by id Software, Inc.
//
// This source is available for distribution and/or modification
// only under the terms of the DOOM Source Code License as
// published by id Software. All rights reserved.
//
// The source is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
// for more details.
//
// $Log:$
//
// 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.
//
//-----------------------------------------------------------------------------
#define BGCOLOR 7
#define FGCOLOR 8
#include "os.h"
#include "cgdoom.h"
#include "cgdoom-alloc.h"
#include <stdlib.h>
#include "doomdef.h"
#include "doomstat.h"
#include "dstrings.h"
#include "z_zone.h"
#include "w_wad.h"
#include "v_video.h"
#include "f_finale.h"
#include "f_wipe.h"
#include "m_misc.h"
#include "m_menu.h"
#include "i_system.h"
#include "i_video.h"
#include "g_game.h"
#include "hu_stuff.h"
#include "wi_stuff.h"
#include "st_stuff.h"
#include "am_map.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);
boolean devparm; // started game with -devparm
boolean nomonsters; // checkparm of -nomonsters
boolean respawnparm; // checkparm of -respawn
boolean fastparm; // checkparm of -fast
boolean drone;
boolean singletics = true;
boolean fuck = false;
extern boolean inhelpscreens;
skill_t startskill;
int startepisode;
int startmap;
boolean autostart;
boolean advancedemo;
void D_ProcessEvents (void);
void G_BuildTiccmd (ticcmd_t* cmd);
void D_DoAdvanceDemo (void);
//
// D_PostEvent
// Called by the I/O functions when input is detected
//
void D_PostEvent (event_t* ev)
{
if (M_Responder (ev))
return; // 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
gamestate_t wipegamestate = GS_DEMOSCREEN;
extern boolean setsizeneeded;
extern int showMessages;
void R_ExecuteSetViewSize (void);
void D_Display (void)
{
static boolean viewactivestate = false;
static boolean menuactivestate = false;
static boolean inhelpscreensstate = false;
static boolean fullscreen = false;
static gamestate_t oldgamestate = (gamestate_t)-1;
static int borderdrawcount;
int nowtime;
int tics;
int wipestart;
int y;
boolean done;
boolean wipe;
boolean redrawsbar;
redrawsbar = false;
// change the view size if needed
if (setsizeneeded)
{
R_ExecuteSetViewSize ();
oldgamestate = (gamestate_t)-1; // force background redraw
borderdrawcount = 3;
}
// save the current screen if about to wipe
if (gamestate != wipegamestate)
{
wipe = true;
wipe_StartScreen();
}
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;
if (inhelpscreensstate && !inhelpscreens)
redrawsbar = true; // just put away the help screen
ST_Drawer ((boolean)(viewheight == 200), redrawsbar );
fullscreen = (boolean)(viewheight == 200);
break;
case GS_INTERMISSION:
WI_Drawer ();
break;
case GS_FINALE:
F_Drawer ();
break;
case GS_DEMOSCREEN:
D_PageDrawer ();
break;
}
// draw the view directly
if (gamestate == GS_LEVEL && !automapactive && gametic)
R_RenderPlayerView (&players[0]);
if (gamestate == GS_LEVEL && gametic)
HU_Drawer ();
// clean up border stuff
if (gamestate != oldgamestate && gamestate != GS_LEVEL)
I_SetPalette ((byte *)W_CacheLumpNameConst ("PLAYPAL", PU_CACHE));
menuactivestate = menuactive;
viewactivestate = viewactive;
inhelpscreensstate = inhelpscreens;
oldgamestate = gamestate;
// draw pause pic
if (paused)
{
if (automapactive)
y = 4;
else
y = viewwindowy+4;
V_DrawPatchDirect(viewwindowx+(scaledviewwidth-68)/2, y ,0 ,W_CacheLumpNamePatch("M_PAUSE", PU_CACHE) );
}
// menus go directly to the screen
M_Drawer (); // menu is drawn even on top of everything
// normal update
if (!wipe)
{
I_Flip (); // 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;
} while (tics<=0);
wipestart = nowtime;
done = wipe_ScreenWipe(wipe_Melt, SCREENWIDTH, SCREENHEIGHT, tics);
M_Drawer (); // menu is drawn even on top of wipes
I_Flip (); // page flip or blit buffer
} while (!done);
gamestate = oldgamestate;
wipegamestate= oldgamestate;
}
//
// D_DoomLoop
//
extern boolean demorecording;
void D_DoomLoop (void)
{
I_InitGraphics ();
while (!fuck)
{
I_StartTic ();
if (advancedemo)
D_DoAdvanceDemo ();
M_Ticker (); //Menu ticker
G_Ticker (); //Game ticker
if (fuck) break; //Quick exit after save game
gametic++;
// Update display, next frame, with current state
if(!(gametic % (CGD_Frameskip + 1)))
D_Display ();
}
G_CheckDemoStatus();
Z_Free(lumpinfo);
CGD_PRAM_Free(lumpcache);
I_ShutdownGraphics();
return;
}
//
// 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
//
void D_PageDrawer (void)
{
// V_DrawPatch (0,0, 0, (const patch_t *)W_CacheLumpNameConst(pagename, PU_CACHE));
V_DrawFullscreenPatchFragmented(0, pagename);
}
//
// D_AdvanceDemo
// Called after each demo or intro demosequence finishes
//
void D_AdvanceDemo (void)
{
advancedemo = true;
}
int episode = 1;
int map = 1; //HACK
int skill = 2;
//
// This cycles through the demo sequences.
// FIXME - version dependend demo numbers?
//
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;
if ( gamemode == retail )
demosequence = (demosequence+1)%7;
else
demosequence = (demosequence+1)%6;
switch (demosequence)
{
case 0:
if ( gamemode == commercial )
pagetic = 35 * 11;
else
pagetic = 170;
gamestate = GS_DEMOSCREEN;
pagename = "TITLEPIC";
break;
case 1:
G_DeferedPlayDemo ("demo1");
break;
case 2:
pagetic = 200;
gamestate = GS_DEMOSCREEN;
pagename = "CREDIT";
break;
case 3:
G_DeferedPlayDemo ("demo2");
break;
case 4:
gamestate = GS_DEMOSCREEN;
if ( gamemode == commercial)
{
pagetic = 35 * 11;
pagename = "TITLEPIC";
}
else
{
pagetic = 200;
if ( gamemode == retail )
pagename = "CREDIT";
else
pagename = "HELP2";
}
break;
case 5:
G_DeferedPlayDemo ("demo3");
break;
case 6:
G_DeferedPlayDemo ("demo4");
break;
}
/* CGDoom: Skip demos on option (often incompatible) */
if (gameaction == ga_playdemo && !CGD_Options.EnableDemos) {
D_DoAdvanceDemo();
}
}
//
// D_StartTitle
//
void D_StartTitle (void)
{
gameaction = ga_nothing;
demosequence = -1;
D_AdvanceDemo ();
}
// print title for every printed line
//char title[128];
//
// D_DoomMain
//
void D_DoomMain()
{
int ok_wad=0;
// int selected=1;
// int rskill=1;
int maxepisode=1;
skill=3;
// int repisode=1;
// int rmap=1;
/* CGDoom: Z_Init is executed early because we rely on the larger heap to
allocate the lump cache and lump info; normal heap isn't enough for WADs
larger than the shareware WAD */
Z_Init ();
for (int i = 0; true; i++)
{
int zone_size;
void *zone_base = I_ZoneBase(&zone_size, i);
if (zone_base == NULL)
break;
Z_AddZone (zone_base, zone_size);
}
ok_wad=W_InitMultipleFiles();
if(W_CheckNumForName("MAP01")!=-1)
gamemode=commercial;
else if(W_CheckNumForName("E1M1")==-1)
gamemode=indetermined;
else if (W_CheckNumForName("E2M1")==-1)
gamemode=shareware;
else if (W_CheckNumForName("E4M1")==-1)
gamemode=registered;
else
gamemode=retail;
if(gamemode == indetermined) // CX port
return; // CX port
if (W_CheckNumForName("E4M1")!=-1)
maxepisode = 4;
else if (W_CheckNumForName("E3M1")!=-1)
maxepisode = 3;
else if (W_CheckNumForName("E2M1")!=-1)
maxepisode = 2;
/* CGDoom: Override game mode for split WADs; we have single-episode WADs for
all episodes of Ultimate Doom, and they should identify as retail.Note
that CGD_SingleEpisodeUltimate might have been set before based on the WAD
file name. */
if (!CGD_SingleEpisodeUltimate && maxepisode == 1) {
/* Shareware Doom */
if (W_CheckNumForName("DEMO4") == -1)
{}
/* Each individual Ultimate Doom episode */
else if (W_CheckNumForName("WIMAP0") != -1)
CGD_SingleEpisodeUltimate = 1;
else if (W_CheckNumForName("WIMAP1") != -1)
CGD_SingleEpisodeUltimate = 2;
else if (W_CheckNumForName("WIMAP2") != -1)
CGD_SingleEpisodeUltimate = 3;
else if (W_CheckNumForName("INTERPIC") != -1)
CGD_SingleEpisodeUltimate = 4;
}
if (CGD_SingleEpisodeUltimate > 0) {
gamemode=retail;
maxepisode = CGD_SingleEpisodeUltimate;
}
nomonsters = 0;
respawnparm = 0;
fastparm = 0;
devparm = 0;
// get skill / episode / map from parms // DON'T, LEFT IN UNTIL OPCHECK
if(skill==0) startskill = sk_baby;
else if(skill==1) startskill = sk_easy;
else if(skill==2) startskill = sk_medium;
else if(skill==3) startskill = sk_hard;
else if(skill==4) startskill = sk_nightmare;
// init subsystems
printf ("V_Init: Allocate screens\n");
V_Init ();
printf ("Z_Init: Init zone memory allocation daemon \n");
//Z_Init ();
printf ("W_Init: Init WADfiles\n");
W_InitMultipleFiles ();
//Just in case we haven't found the WAD files...
if (fuck)
return;
// Check and print which version is executed.
switch ( gamemode )
{
case shareware:
case indetermined:
printf (
"=====================================\n"
" Shareware!\n"
"=====================================\n"
);
break;
case registered:
case retail:
case commercial:
printf (
"=====================================\n"
" Commercial product\n"
" do not distribute!\n"
"=====================================\n"
);
break;
default:
// Ouch.
break;
}
printf ("I_Init: Setting up machine state\n");
I_Init ();
printf ("M_Init: Init miscellaneous info\n");
M_Init ();
printf ("R_Init: Init DOOM refresh daemon \n");
R_Init ();
printf ("P_Init: Init Playloop state\n");
P_Init ();
printf ("HU_Init: Setup heads up display\n");
HU_Init ();
printf ("ST_Init: Init status bar\n");
ST_Init ();
printf ("Engage... \n");
if (CGD_RecordDemoSlot >= 0) {
static char filename[32];
sprintf(filename, "%s_demo%02d", CGD_WADFileName, CGD_RecordDemoSlot);
G_RecordDemo(filename);
}
/* CGDoom: Demo file was specified from main menu */
if (gameaction == ga_playdemo)
{}
else if (autostart)
G_DeferedInitNew (startskill, startepisode, startmap);
else
D_StartTitle ();
D_DoomLoop (); // never returns, except when it does
I_Restore (); //calckill = bad
return;
}