Lephenixnoir
b9c676ea4e
lumpinfo is now allocated in Z_Malloc because it's needed for some larger WADs. More heap is needed to compensate and to support larger WADs fully, so the unused part of the user stack is added as a second zone. This makes at least the start of the DOOM Ultimate WAD playable.
527 lines
12 KiB
C
527 lines
12 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 "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 ();
|
|
|
|
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;
|
|
extern int giRefreshMask;
|
|
void D_DoomLoop (void)
|
|
{
|
|
I_InitGraphics ();
|
|
|
|
while (!fuck)
|
|
{
|
|
I_StartTic ();
|
|
|
|
if (advancedemo)
|
|
D_DoAdvanceDemo ();
|
|
|
|
M_Ticker (); //Menu ticker
|
|
|
|
G_Ticker (); //Game ticker
|
|
|
|
gametic++;
|
|
|
|
// Update display, next frame, with current state
|
|
if(!(gametic & giRefreshMask))
|
|
{
|
|
D_Display ();
|
|
}
|
|
|
|
}
|
|
// I_ShutdownGraphics();
|
|
free(lumpinfo);
|
|
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));
|
|
}
|
|
|
|
|
|
//
|
|
// 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)
|
|
{
|
|
pagename = "TITLEPIC";
|
|
gamestate= GS_LEVEL;
|
|
G_DeferedInitNew((skill_t)skill,episode,map);
|
|
advancedemo= false;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// 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
|
|
|
|
{//save sprintf
|
|
if (W_CheckNumForName("E2M1")!=-1)
|
|
{
|
|
maxepisode = 2;
|
|
if (W_CheckNumForName("E3M1")!=-1)
|
|
maxepisode = 3;
|
|
}
|
|
#if 0 //CG:seem to be useless
|
|
while(true)
|
|
{ if(gamemode==commercial)
|
|
sprintf(res,"MAP%02i",maxmap+1);
|
|
else
|
|
sprintf(res,"E1M%i",maxmap+1);
|
|
if (W_CheckNumForName(res)==-1)
|
|
break;
|
|
maxmap++;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if(maxepisode>1) {}
|
|
#if 0 //TODO !
|
|
do
|
|
{
|
|
if(maxepisode>1)
|
|
{ if(isKeyPressed(KEY_NSPIRE_RP) && episode<maxepisode) { episode++; repisode=1; while(isKeyPressed(KEY_NSPIRE_RP)); }
|
|
if(isKeyPressed(KEY_NSPIRE_LP) && episode>1) { episode--; repisode=1; while(isKeyPressed(KEY_NSPIRE_LP)); }
|
|
if(repisode)
|
|
{ sprintf(temp,"%i",episode);
|
|
drwBufStr(SCREEN_BASE_ADDRESS, 13*CHAR_WIDTH, 14*CHAR_HEIGHT, temp, 0, 0);
|
|
repisode = 0;
|
|
}
|
|
}
|
|
if(isKeyPressed(KEY_NSPIRE_PLUS) && skill<4) { skill++; rskill=1; while(isKeyPressed(KEY_NSPIRE_PLUS)); }
|
|
if(isKeyPressed(KEY_NSPIRE_MINUS) && skill>0) { skill--; rskill=1; while(isKeyPressed(KEY_NSPIRE_MINUS)); }
|
|
if(rskill)
|
|
{ if(skill==0) tmp="I'm too young to die";
|
|
else if(skill==1) tmp=" Hey, not to rough ";
|
|
else if(skill==2) tmp=" Hurt me plenty ";
|
|
else if(skill==3) tmp=" Ultra-Violence ";
|
|
else if(skill==4) tmp=" Nightmare! ";
|
|
drwBufStr(SCREEN_BASE_ADDRESS, 11*CHAR_WIDTH, 11*CHAR_HEIGHT, tmp, 0, 0);
|
|
rskill = 0;
|
|
}
|
|
}
|
|
while(!isKeyPressed(KEY_NSPIRE_ESC) && !isKeyPressed(KEY_NSPIRE_ENTER) && !isKeyPressed(KEY_NSPIRE_RET) && !isKeyPressed(KEY_NSPIRE_CLICK));
|
|
#endif
|
|
|
|
//if(isKeyPressed(KEY_NSPIRE_ESC)) // CX port
|
|
//return; // CX port
|
|
|
|
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;
|
|
|
|
startepisode = episode;
|
|
startmap = map;
|
|
autostart = false;
|
|
|
|
// 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;
|
|
|
|
#ifdef CG_EMULATOR
|
|
// 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;
|
|
}
|
|
#endif //#ifdef CG_EMULATOR
|
|
//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");
|
|
D_StartTitle ();
|
|
D_DoomLoop (); // never returns, except when it does
|
|
I_Restore (); //calckill = bad
|
|
|
|
return;
|
|
}
|