- cleaned up g_level.cpp

SVN r1392 (newmapinfo)
This commit is contained in:
Christoph Oelckers 2009-02-03 18:13:58 +00:00
parent fabc0906a7
commit 92d17c0397
10 changed files with 656 additions and 330 deletions

View file

@ -73,6 +73,7 @@
#include "cmdlib.h" #include "cmdlib.h"
#include "d_net.h" #include "d_net.h"
#include "d_event.h" #include "d_event.h"
#include "p_acs.h"
#include <zlib.h> #include <zlib.h>
@ -1574,128 +1575,6 @@ bool G_CheckSaveGameWads (PNGHandle *png, bool printwarn)
return true; return true;
} }
static void WriteVars (FILE *file, SDWORD *vars, size_t count, DWORD id)
{
size_t i, j;
for (i = 0; i < count; ++i)
{
if (vars[i] != 0)
break;
}
if (i < count)
{
// Find last non-zero var. Anything beyond the last stored variable
// will be zeroed at load time.
for (j = count-1; j > i; --j)
{
if (vars[j] != 0)
break;
}
FPNGChunkArchive arc (file, id);
for (i = 0; i <= j; ++i)
{
DWORD var = vars[i];
arc << var;
}
}
}
static void ReadVars (PNGHandle *png, SDWORD *vars, size_t count, DWORD id)
{
size_t len = M_FindPNGChunk (png, id);
size_t used = 0;
if (len != 0)
{
DWORD var;
size_t i;
FPNGChunkArchive arc (png->File->GetFile(), id, len);
used = len / 4;
for (i = 0; i < used; ++i)
{
arc << var;
vars[i] = var;
}
png->File->ResetFilePtr();
}
if (used < count)
{
memset (&vars[used], 0, (count-used)*4);
}
}
static void WriteArrayVars (FILE *file, FWorldGlobalArray *vars, unsigned int count, DWORD id)
{
unsigned int i, j;
// Find the first non-empty array.
for (i = 0; i < count; ++i)
{
if (vars[i].CountUsed() != 0)
break;
}
if (i < count)
{
// Find last non-empty array. Anything beyond the last stored array
// will be emptied at load time.
for (j = count-1; j > i; --j)
{
if (vars[j].CountUsed() != 0)
break;
}
FPNGChunkArchive arc (file, id);
arc.WriteCount (i);
arc.WriteCount (j);
for (; i <= j; ++i)
{
arc.WriteCount (vars[i].CountUsed());
FWorldGlobalArray::ConstIterator it(vars[i]);
const FWorldGlobalArray::Pair *pair;
while (it.NextPair (pair))
{
arc.WriteCount (pair->Key);
arc.WriteCount (pair->Value);
}
}
}
}
static void ReadArrayVars (PNGHandle *png, FWorldGlobalArray *vars, size_t count, DWORD id)
{
size_t len = M_FindPNGChunk (png, id);
unsigned int i, k;
for (i = 0; i < count; ++i)
{
vars[i].Clear ();
}
if (len != 0)
{
DWORD max, size;
FPNGChunkArchive arc (png->File->GetFile(), id, len);
i = arc.ReadCount ();
max = arc.ReadCount ();
for (; i <= max; ++i)
{
size = arc.ReadCount ();
for (k = 0; k < size; ++k)
{
SDWORD key, val;
key = arc.ReadCount();
val = arc.ReadCount();
vars[i].Insert (key, val);
}
}
png->File->ResetFilePtr();
}
}
void G_DoLoadGame () void G_DoLoadGame ()
{ {
@ -1815,10 +1694,7 @@ void G_DoLoadGame ()
delete[] map; delete[] map;
savegamerestore = false; savegamerestore = false;
ReadVars (png, ACS_WorldVars, NUM_WORLDVARS, MAKE_ID('w','v','A','r')); P_ReadACSVars(png);
ReadVars (png, ACS_GlobalVars, NUM_GLOBALVARS, MAKE_ID('g','v','A','r'));
ReadArrayVars (png, ACS_WorldArrays, NUM_WORLDVARS, MAKE_ID('w','a','R','r'));
ReadArrayVars (png, ACS_GlobalArrays, NUM_GLOBALVARS, MAKE_ID('g','a','R','r'));
NextSkill = -1; NextSkill = -1;
if (M_FindPNGChunk (png, MAKE_ID('s','n','X','t')) == 1) if (M_FindPNGChunk (png, MAKE_ID('s','n','X','t')) == 1)
@ -2064,10 +1940,7 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio
FRandom::StaticWriteRNGState (stdfile); FRandom::StaticWriteRNGState (stdfile);
P_WriteACSDefereds (stdfile); P_WriteACSDefereds (stdfile);
WriteVars (stdfile, ACS_WorldVars, NUM_WORLDVARS, MAKE_ID('w','v','A','r')); P_WriteACSVars(stdfile);
WriteVars (stdfile, ACS_GlobalVars, NUM_GLOBALVARS, MAKE_ID('g','v','A','r'));
WriteArrayVars (stdfile, ACS_WorldArrays, NUM_WORLDVARS, MAKE_ID('w','a','R','r'));
WriteArrayVars (stdfile, ACS_GlobalArrays, NUM_GLOBALVARS, MAKE_ID('g','a','R','r'));
if (NextSkill != -1) if (NextSkill != -1)
{ {

View file

@ -98,6 +98,7 @@ EXTERN_CVAR (Int, disableautosave)
static void SetEndSequence (char *nextmap, int type); static void SetEndSequence (char *nextmap, int type);
void G_VerifySkill(); void G_VerifySkill();
static FRandom pr_classchoice ("RandomPlayerClassChoice"); static FRandom pr_classchoice ("RandomPlayerClassChoice");
TArray<EndSequence> EndSequences; TArray<EndSequence> EndSequences;
@ -110,20 +111,13 @@ EndSequence::EndSequence()
PlayTheEnd = false; PlayTheEnd = false;
} }
extern level_info_t TheDefaultLevelInfo;
extern bool timingdemo; extern bool timingdemo;
// Start time for timing demos // Start time for timing demos
int starttime; int starttime;
// ACS variables with world scope
SDWORD ACS_WorldVars[NUM_WORLDVARS];
FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
// ACS variables with global scope
SDWORD ACS_GlobalVars[NUM_GLOBALVARS];
FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
extern bool netdemo; extern bool netdemo;
extern FString BackupSaveName; extern FString BackupSaveName;
@ -137,19 +131,10 @@ void *statcopy; // for statistics driver
FLevelLocals level; // info about current level FLevelLocals level; // info about current level
TArray<cluster_info_t> wadclusterinfos; //==========================================================================
TArray<level_info_t> wadlevelinfos; //
//
static level_info_t TheDefaultLevelInfo; //==========================================================================
static cluster_info_t TheDefaultClusterInfo;
int FindWadLevelInfo (const char *name);
int FindWadClusterInfo (int cluster);
void ClearEpisodes();
int FindEndSequence (int type, const char *picname) int FindEndSequence (int type, const char *picname)
{ {
@ -167,6 +152,11 @@ int FindEndSequence (int type, const char *picname)
return -1; return -1;
} }
//==========================================================================
//
//
//==========================================================================
static void SetEndSequence (char *nextmap, int type) static void SetEndSequence (char *nextmap, int type)
{ {
int seqnum; int seqnum;
@ -182,6 +172,11 @@ static void SetEndSequence (char *nextmap, int type)
*((WORD *)(nextmap + 6)) = (WORD)seqnum; *((WORD *)(nextmap + 6)) = (WORD)seqnum;
} }
//==========================================================================
//
//
//==========================================================================
void G_SetForEndGame (char *nextmap) void G_SetForEndGame (char *nextmap)
{ {
if (!strncmp(nextmap, "enDSeQ",6)) return; // If there is already an end sequence please leave it alone!!! if (!strncmp(nextmap, "enDSeQ",6)) return; // If there is already an end sequence please leave it alone!!!
@ -205,74 +200,14 @@ void G_SetForEndGame (char *nextmap)
} }
} }
void G_UnloadMapInfo () //==========================================================================
{
G_ClearSnapshots ();
wadlevelinfos.Clear();
wadclusterinfos.Clear();
ClearEpisodes();
}
level_info_t *FindLevelByWarpTrans (int num)
{
for (unsigned i = wadlevelinfos.Size(); i-- != 0; )
if (wadlevelinfos[i].WarpTrans == num)
return &wadlevelinfos[i];
return NULL;
}
static void zapDefereds (acsdefered_t *def)
{
while (def)
{
acsdefered_t *next = def->next;
delete def;
def = next;
}
}
void P_RemoveDefereds (void)
{
// Remove any existing defereds
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
{
if (wadlevelinfos[i].defered)
{
zapDefereds (wadlevelinfos[i].defered);
wadlevelinfos[i].defered = NULL;
}
}
}
bool CheckWarpTransMap (FString &mapname, bool substitute)
{
if (mapname[0] == '&' && (mapname[1] & 0xDF) == 'W' &&
(mapname[2] & 0xDF) == 'T' && mapname[3] == '@')
{
level_info_t *lev = FindLevelByWarpTrans (atoi (&mapname[4]));
if (lev != NULL)
{
mapname = lev->mapname;
return true;
}
else if (substitute)
{
char a = mapname[4], b = mapname[5];
mapname = "MAP";
mapname << a << b;
}
}
return false;
}
// //
// G_InitNew // G_InitNew
// Can be called by the startup code or the menu task, // Can be called by the startup code or the menu task,
// consoleplayer, playeringame[] should be set. // consoleplayer, playeringame[] should be set.
// //
//==========================================================================
static FString d_mapname; static FString d_mapname;
static int d_skill=-1; static int d_skill=-1;
@ -284,6 +219,11 @@ void G_DeferedInitNew (const char *mapname, int newskill)
gameaction = ga_newgame2; gameaction = ga_newgame2;
} }
//==========================================================================
//
//
//==========================================================================
CCMD (map) CCMD (map)
{ {
if (netgame) if (netgame)
@ -309,6 +249,11 @@ CCMD (map)
} }
} }
//==========================================================================
//
//
//==========================================================================
CCMD (open) CCMD (open)
{ {
if (netgame) if (netgame)
@ -337,6 +282,11 @@ CCMD (open)
} }
//==========================================================================
//
//
//==========================================================================
void G_NewInit () void G_NewInit ()
{ {
int i; int i;
@ -369,6 +319,11 @@ void G_NewInit ()
NextSkill = -1; NextSkill = -1;
} }
//==========================================================================
//
//
//==========================================================================
void G_DoNewGame (void) void G_DoNewGame (void)
{ {
G_NewInit (); G_NewInit ();
@ -381,10 +336,15 @@ void G_DoNewGame (void)
gameaction = ga_nothing; gameaction = ga_nothing;
} }
//==========================================================================
//
// Initializes player classes in case they are random. // Initializes player classes in case they are random.
// This gets called at the start of a new game, and the classes // This gets called at the start of a new game, and the classes
// chosen here are used for the remainder of a single-player // chosen here are used for the remainder of a single-player
// or coop game. These are ignored for deathmatch. // or coop game. These are ignored for deathmatch.
//
//==========================================================================
static void InitPlayerClasses () static void InitPlayerClasses ()
{ {
@ -403,6 +363,11 @@ static void InitPlayerClasses ()
} }
} }
//==========================================================================
//
//
//==========================================================================
void G_InitNew (const char *mapname, bool bTitleLevel) void G_InitNew (const char *mapname, bool bTitleLevel)
{ {
EGameSpeed oldSpeed; EGameSpeed oldSpeed;
@ -518,16 +483,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
rngseed = rngseed*3/2; rngseed = rngseed*3/2;
} }
FRandom::StaticClearRandom (); FRandom::StaticClearRandom ();
memset (ACS_WorldVars, 0, sizeof(ACS_WorldVars)); P_ClearACSVars(true);
memset (ACS_GlobalVars, 0, sizeof(ACS_GlobalVars));
for (i = 0; i < NUM_WORLDVARS; ++i)
{
ACS_WorldArrays[i].Clear ();
}
for (i = 0; i < NUM_GLOBALVARS; ++i)
{
ACS_GlobalArrays[i].Clear ();
}
level.time = 0; level.time = 0;
level.maptime = 0; level.maptime = 0;
level.totaltime = 0; level.totaltime = 0;
@ -581,9 +537,14 @@ static bool resetinventory; // Reset the inventory to the player's default for
static bool unloading; static bool unloading;
static bool g_nomonsters; static bool g_nomonsters;
//==========================================================================
//
// [RH] The position parameter to these next three functions should // [RH] The position parameter to these next three functions should
// match the first parameter of the single player start spots // match the first parameter of the single player start spots
// that should appear in the next map. // that should appear in the next map.
//
//==========================================================================
void G_ChangeLevel(const char *levelname, int position, bool keepFacing, int nextSkill, void G_ChangeLevel(const char *levelname, int position, bool keepFacing, int nextSkill,
bool nointermission, bool resetinv, bool nomonsters) bool nointermission, bool resetinv, bool nomonsters)
@ -598,7 +559,7 @@ void G_ChangeLevel(const char *levelname, int position, bool keepFacing, int nex
if (strncmp(levelname, "enDSeQ", 6)) if (strncmp(levelname, "enDSeQ", 6))
{ {
level_info_t *nextinfo = CheckLevelRedirect (FindLevelInfo (nextlevel)); level_info_t *nextinfo = FindLevelInfo (nextlevel)->CheckLevelRedirect ();
if (nextinfo) if (nextinfo)
{ {
nextlevel = nextinfo->mapname; nextlevel = nextinfo->mapname;
@ -660,6 +621,11 @@ void G_ChangeLevel(const char *levelname, int position, bool keepFacing, int nex
} }
} }
//==========================================================================
//
//
//==========================================================================
const char *G_GetExitMap() const char *G_GetExitMap()
{ {
return level.nextmap; return level.nextmap;
@ -679,6 +645,11 @@ const char *G_GetSecretExitMap()
return nextmap; return nextmap;
} }
//==========================================================================
//
//
//==========================================================================
void G_ExitLevel (int position, bool keepFacing) void G_ExitLevel (int position, bool keepFacing)
{ {
G_ChangeLevel(G_GetExitMap(), position, keepFacing); G_ChangeLevel(G_GetExitMap(), position, keepFacing);
@ -689,6 +660,11 @@ void G_SecretExitLevel (int position)
G_ChangeLevel(G_GetSecretExitMap(), position, false); G_ChangeLevel(G_GetSecretExitMap(), position, false);
} }
//==========================================================================
//
//
//==========================================================================
void G_DoCompleted (void) void G_DoCompleted (void)
{ {
int i; int i;
@ -809,11 +785,7 @@ void G_DoCompleted (void)
if (mode == FINISH_NextHub) if (mode == FINISH_NextHub)
{ // Reset world variables for the new hub. { // Reset world variables for the new hub.
memset (ACS_WorldVars, 0, sizeof(ACS_WorldVars)); P_ClearACSVars(false);
for (i = 0; i < NUM_WORLDVARS; ++i)
{
ACS_WorldArrays[i].Clear ();
}
} }
// With hub statistics the time should be per hub. // With hub statistics the time should be per hub.
// Additionally there is a global time counter now so nothing is missed by changing it // Additionally there is a global time counter now so nothing is missed by changing it
@ -843,6 +815,11 @@ void G_DoCompleted (void)
WI_Start (&wminfo); WI_Start (&wminfo);
} }
//==========================================================================
//
//
//==========================================================================
class DAutosaver : public DThinker class DAutosaver : public DThinker
{ {
DECLARE_CLASS (DAutosaver, DThinker) DECLARE_CLASS (DAutosaver, DThinker)
@ -858,9 +835,12 @@ void DAutosaver::Tick ()
Destroy (); Destroy ();
} }
//==========================================================================
// //
// G_DoLoadLevel // G_DoLoadLevel
// //
//==========================================================================
extern gamestate_t wipegamestate; extern gamestate_t wipegamestate;
void G_DoLoadLevel (int position, bool autosave) void G_DoLoadLevel (int position, bool autosave)
@ -1005,9 +985,12 @@ void G_DoLoadLevel (int position, bool autosave)
} }
//==========================================================================
// //
// G_WorldDone // G_WorldDone
// //
//==========================================================================
void G_WorldDone (void) void G_WorldDone (void)
{ {
cluster_info_t *nextcluster; cluster_info_t *nextcluster;
@ -1062,6 +1045,11 @@ void G_WorldDone (void)
} }
} }
//==========================================================================
//
//
//==========================================================================
void G_DoWorldDone (void) void G_DoWorldDone (void)
{ {
gamestate = GS_LEVEL; gamestate = GS_LEVEL;
@ -1205,6 +1193,11 @@ void G_FinishTravel ()
} }
} }
//==========================================================================
//
//
//==========================================================================
void G_InitLevelLocals () void G_InitLevelLocals ()
{ {
level_info_t *info; level_info_t *info;
@ -1225,7 +1218,6 @@ void G_InitLevelLocals ()
level.info = info; level.info = info;
level.skyspeed1 = info->skyspeed1; level.skyspeed1 = info->skyspeed1;
level.skyspeed2 = info->skyspeed2; level.skyspeed2 = info->skyspeed2;
info = (level_info_t *)info;
strncpy (level.skypic2, info->skypic2, 8); strncpy (level.skypic2, info->skypic2, 8);
level.fadeto = info->fadeto; level.fadeto = info->fadeto;
level.cdtrack = info->cdtrack; level.cdtrack = info->cdtrack;
@ -1307,6 +1299,11 @@ void G_InitLevelLocals ()
NormalLight.ChangeFade (level.fadeto); NormalLight.ChangeFade (level.fadeto);
} }
//==========================================================================
//
//
//==========================================================================
bool FLevelLocals::IsJumpingAllowed() const bool FLevelLocals::IsJumpingAllowed() const
{ {
if (dmflags & DF_NO_JUMP) if (dmflags & DF_NO_JUMP)
@ -1316,6 +1313,11 @@ bool FLevelLocals::IsJumpingAllowed() const
return !(level.flags & LEVEL_JUMP_NO); return !(level.flags & LEVEL_JUMP_NO);
} }
//==========================================================================
//
//
//==========================================================================
bool FLevelLocals::IsCrouchingAllowed() const bool FLevelLocals::IsCrouchingAllowed() const
{ {
if (dmflags & DF_NO_CROUCH) if (dmflags & DF_NO_CROUCH)
@ -1325,6 +1327,11 @@ bool FLevelLocals::IsCrouchingAllowed() const
return !(level.flags & LEVEL_CROUCH_NO); return !(level.flags & LEVEL_CROUCH_NO);
} }
//==========================================================================
//
//
//==========================================================================
bool FLevelLocals::IsFreelookAllowed() const bool FLevelLocals::IsFreelookAllowed() const
{ {
if (level.flags & LEVEL_FREELOOK_NO) if (level.flags & LEVEL_FREELOOK_NO)
@ -1334,6 +1341,11 @@ bool FLevelLocals::IsFreelookAllowed() const
return !(dmflags & DF_NO_FREELOOK); return !(dmflags & DF_NO_FREELOOK);
} }
//==========================================================================
//
//
//==========================================================================
FString CalcMapName (int episode, int level) FString CalcMapName (int episode, int level)
{ {
FString lumpname; FString lumpname;
@ -1350,66 +1362,10 @@ FString CalcMapName (int episode, int level)
return lumpname; return lumpname;
} }
level_info_t *FindLevelInfo (const char *mapname) //==========================================================================
{ //
int i; //
//==========================================================================
if ((i = FindWadLevelInfo (mapname)) > -1)
return &wadlevelinfos[i];
else
{
if (TheDefaultLevelInfo.LevelName.IsEmpty())
{
uppercopy(TheDefaultLevelInfo.skypic1, "SKY1");
uppercopy(TheDefaultLevelInfo.skypic2, "SKY1");
TheDefaultLevelInfo.LevelName = "Unnamed";
}
return &TheDefaultLevelInfo;
}
}
level_info_t *FindLevelByNum (int num)
{
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
if (wadlevelinfos[i].levelnum == num)
return &wadlevelinfos[i];
return NULL;
}
level_info_t *CheckLevelRedirect (level_info_t *info)
{
if (info->RedirectType != NAME_None)
{
const PClass *type = PClass::FindClass(info->RedirectType);
if (type != NULL)
{
for (int i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i] && players[i].mo->FindInventory (type))
{
// check for actual presence of the map.
if (P_CheckMapData(info->RedirectMap))
{
return FindLevelInfo(info->RedirectMap);
}
break;
}
}
}
}
return NULL;
}
cluster_info_t *FindClusterInfo (int cluster)
{
int i;
if ((i = FindWadClusterInfo (cluster)) > -1)
return &wadclusterinfos[i];
else
return &TheDefaultClusterInfo;
}
void G_AirControlChanged () void G_AirControlChanged ()
{ {
@ -1425,6 +1381,11 @@ void G_AirControlChanged ()
} }
} }
//==========================================================================
//
//
//==========================================================================
void G_SerializeLevel (FArchive &arc, bool hubLoad) void G_SerializeLevel (FArchive &arc, bool hubLoad)
{ {
int i = level.totaltime; int i = level.totaltime;
@ -1537,13 +1498,18 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
} }
} }
//==========================================================================
//
// Archives the current level // Archives the current level
//
//==========================================================================
void G_SnapshotLevel () void G_SnapshotLevel ()
{ {
if (level.info->snapshot) if (level.info->snapshot)
delete level.info->snapshot; delete level.info->snapshot;
if (level.info->mapname[0] != 0 || level.info == &TheDefaultLevelInfo) if (level.info->isValid())
{ {
level.info->snapshotVer = SAVEVER; level.info->snapshotVer = SAVEVER;
level.info->snapshot = new FCompressedMemFile; level.info->snapshot = new FCompressedMemFile;
@ -1556,14 +1522,19 @@ void G_SnapshotLevel ()
} }
} }
//==========================================================================
//
// Unarchives the current level based on its snapshot // Unarchives the current level based on its snapshot
// The level should have already been loaded and setup. // The level should have already been loaded and setup.
//
//==========================================================================
void G_UnSnapshotLevel (bool hubLoad) void G_UnSnapshotLevel (bool hubLoad)
{ {
if (level.info->snapshot == NULL) if (level.info->snapshot == NULL)
return; return;
if (level.info->mapname[0] != 0 || level.info == &TheDefaultLevelInfo) if (level.info->isValid())
{ {
SaveVersion = level.info->snapshotVer; SaveVersion = level.info->snapshotVer;
level.info->snapshot->Reopen (); level.info->snapshot->Reopen ();
@ -1601,21 +1572,13 @@ void G_UnSnapshotLevel (bool hubLoad)
} }
} }
// No reason to keep the snapshot around once the level's been entered. // No reason to keep the snapshot around once the level's been entered.
delete level.info->snapshot; level.info->ClearSnapshot();
level.info->snapshot = NULL;
} }
void G_ClearSnapshots (void) //==========================================================================
{ //
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++) //
{ //==========================================================================
if (wadlevelinfos[i].snapshot)
{
delete wadlevelinfos[i].snapshot;
wadlevelinfos[i].snapshot = NULL;
}
}
}
static void writeMapName (FArchive &arc, const char *name) static void writeMapName (FArchive &arc, const char *name)
{ {
@ -1632,6 +1595,11 @@ static void writeMapName (FArchive &arc, const char *name)
arc.Write (name, size); arc.Write (name, size);
} }
//==========================================================================
//
//
//==========================================================================
static void writeSnapShot (FArchive &arc, level_info_t *i) static void writeSnapShot (FArchive &arc, level_info_t *i)
{ {
arc << i->snapshotVer; arc << i->snapshotVer;
@ -1639,6 +1607,11 @@ static void writeSnapShot (FArchive &arc, level_info_t *i)
i->snapshot->Serialize (arc); i->snapshot->Serialize (arc);
} }
//==========================================================================
//
//
//==========================================================================
void G_WriteSnapshots (FILE *file) void G_WriteSnapshots (FILE *file)
{ {
unsigned int i; unsigned int i;
@ -1706,6 +1679,11 @@ void G_WriteSnapshots (FILE *file)
} }
} }
//==========================================================================
//
//
//==========================================================================
void G_ReadSnapshots (PNGHandle *png) void G_ReadSnapshots (PNGHandle *png)
{ {
DWORD chunkLen; DWORD chunkLen;
@ -1792,12 +1770,22 @@ void G_ReadSnapshots (PNGHandle *png)
} }
//==========================================================================
//
//
//==========================================================================
static void writeDefereds (FArchive &arc, level_info_t *i) static void writeDefereds (FArchive &arc, level_info_t *i)
{ {
writeMapName (arc, i->mapname); writeMapName (arc, i->mapname);
arc << i->defered; arc << i->defered;
} }
//==========================================================================
//
//
//==========================================================================
void P_WriteACSDefereds (FILE *file) void P_WriteACSDefereds (FILE *file)
{ {
FPNGChunkArchive *arc = NULL; FPNGChunkArchive *arc = NULL;
@ -1823,6 +1811,11 @@ void P_WriteACSDefereds (FILE *file)
} }
} }
//==========================================================================
//
//
//==========================================================================
void P_ReadACSDefereds (PNGHandle *png) void P_ReadACSDefereds (PNGHandle *png)
{ {
BYTE namelen; BYTE namelen;
@ -1853,6 +1846,11 @@ void P_ReadACSDefereds (PNGHandle *png)
} }
//==========================================================================
//
//
//==========================================================================
void FLevelLocals::Tick () void FLevelLocals::Tick ()
{ {
// Reset carry sectors // Reset carry sectors
@ -1862,6 +1860,11 @@ void FLevelLocals::Tick ()
} }
} }
//==========================================================================
//
//
//==========================================================================
void FLevelLocals::AddScroller (DScroller *scroller, int secnum) void FLevelLocals::AddScroller (DScroller *scroller, int secnum)
{ {
if (secnum < 0) if (secnum < 0)

View file

@ -112,9 +112,6 @@ struct FMapOptInfo
bool old; bool old;
}; };
#define NUM_WORLDVARS 256
#define NUM_GLOBALVARS 64
enum ELevelFlags enum ELevelFlags
{ {
LEVEL_NOINTERMISSION = 0x00000001, LEVEL_NOINTERMISSION = 0x00000001,
@ -283,9 +280,21 @@ struct level_info_t
TArray<FSpecialAction> specialactions; TArray<FSpecialAction> specialactions;
level_info_t() { Reset(); } level_info_t()
{
Reset();
}
~level_info_t()
{
ClearSnapshot();
ClearDefered();
}
void Reset(); void Reset();
bool isValid();
FString LookupLevelName (); FString LookupLevelName ();
void ClearSnapshot();
void ClearDefered();
level_info_t *CheckLevelRedirect ();
}; };
@ -423,21 +432,6 @@ extern FLevelLocals level;
extern TArray<level_info_t> wadlevelinfos; extern TArray<level_info_t> wadlevelinfos;
extern TArray<cluster_info_t> wadclusterinfos; extern TArray<cluster_info_t> wadclusterinfos;
extern SDWORD ACS_WorldVars[NUM_WORLDVARS];
extern SDWORD ACS_GlobalVars[NUM_GLOBALVARS];
struct InitIntToZero
{
void Init(int &v)
{
v = 0;
}
};
typedef TMap<SDWORD, SDWORD, THashTraits<SDWORD>, InitIntToZero> FWorldGlobalArray;
extern FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
extern FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
extern bool savegamerestore; extern bool savegamerestore;
// mapname will be changed if it is a valid warptrans // mapname will be changed if it is a valid warptrans
@ -477,9 +471,9 @@ level_info_t *CheckLevelRedirect (level_info_t *info);
FString CalcMapName (int episode, int level); FString CalcMapName (int episode, int level);
void G_ParseMapInfo (void); void G_ParseMapInfo (void);
void G_UnloadMapInfo ();
void G_ClearSnapshots (void); void G_ClearSnapshots (void);
void P_RemoveDefereds ();
void G_SnapshotLevel (void); void G_SnapshotLevel (void);
void G_UnSnapshotLevel (bool keepPlayers); void G_UnSnapshotLevel (bool keepPlayers);
struct PNGHandle; struct PNGHandle;

View file

@ -46,11 +46,26 @@
#include "i_system.h" #include "i_system.h"
#include "gi.h" #include "gi.h"
#include "gstrings.h" #include "gstrings.h"
#include "farchive.h"
#include "p_acs.h"
#include "doomstat.h"
#include "d_player.h"
int FindEndSequence (int type, const char *picname); int FindEndSequence (int type, const char *picname);
int FindWadLevelInfo (const char *name) TArray<cluster_info_t> wadclusterinfos;
TArray<level_info_t> wadlevelinfos;
level_info_t TheDefaultLevelInfo;
static cluster_info_t TheDefaultClusterInfo;
//==========================================================================
//
//
//==========================================================================
static int FindWadLevelInfo (const char *name)
{ {
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++) for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
if (!strnicmp (name, wadlevelinfos[i].mapname, 8)) if (!strnicmp (name, wadlevelinfos[i].mapname, 8))
@ -59,7 +74,90 @@ int FindWadLevelInfo (const char *name)
return -1; return -1;
} }
int FindWadClusterInfo (int cluster) //==========================================================================
//
//
//==========================================================================
level_info_t *FindLevelInfo (const char *mapname)
{
int i;
if ((i = FindWadLevelInfo (mapname)) > -1)
return &wadlevelinfos[i];
else
{
if (TheDefaultLevelInfo.LevelName.IsEmpty())
{
uppercopy(TheDefaultLevelInfo.skypic1, "SKY1");
uppercopy(TheDefaultLevelInfo.skypic2, "SKY1");
TheDefaultLevelInfo.LevelName = "Unnamed";
}
return &TheDefaultLevelInfo;
}
}
//==========================================================================
//
//
//==========================================================================
level_info_t *FindLevelByNum (int num)
{
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
if (wadlevelinfos[i].levelnum == num)
return &wadlevelinfos[i];
return NULL;
}
//==========================================================================
//
//
//==========================================================================
static level_info_t *FindLevelByWarpTrans (int num)
{
for (unsigned i = wadlevelinfos.Size(); i-- != 0; )
if (wadlevelinfos[i].WarpTrans == num)
return &wadlevelinfos[i];
return NULL;
}
//==========================================================================
//
//
//==========================================================================
bool CheckWarpTransMap (FString &mapname, bool substitute)
{
if (mapname[0] == '&' && (mapname[1] & 0xDF) == 'W' &&
(mapname[2] & 0xDF) == 'T' && mapname[3] == '@')
{
level_info_t *lev = FindLevelByWarpTrans (atoi (&mapname[4]));
if (lev != NULL)
{
mapname = lev->mapname;
return true;
}
else if (substitute)
{
char a = mapname[4], b = mapname[5];
mapname = "MAP";
mapname << a << b;
}
}
return false;
}
//==========================================================================
//
//
//==========================================================================
static int FindWadClusterInfo (int cluster)
{ {
for (unsigned int i = 0; i < wadclusterinfos.Size(); i++) for (unsigned int i = 0; i < wadclusterinfos.Size(); i++)
if (wadclusterinfos[i].cluster == cluster) if (wadclusterinfos[i].cluster == cluster)
@ -68,6 +166,49 @@ int FindWadClusterInfo (int cluster)
return -1; return -1;
} }
//==========================================================================
//
//
//==========================================================================
cluster_info_t *FindClusterInfo (int cluster)
{
int i;
if ((i = FindWadClusterInfo (cluster)) > -1)
return &wadclusterinfos[i];
else
return &TheDefaultClusterInfo;
}
//==========================================================================
//
//
//==========================================================================
void G_ClearSnapshots (void)
{
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
{
wadlevelinfos[i].ClearSnapshot();
}
}
//==========================================================================
//
// Remove any existing defereds
//
//==========================================================================
void P_RemoveDefereds (void)
{
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
{
wadlevelinfos[i].ClearDefered();
}
}
//========================================================================== //==========================================================================
// //
// //
@ -169,6 +310,73 @@ FString level_info_t::LookupLevelName()
} }
//==========================================================================
//
//
//==========================================================================
void level_info_t::ClearSnapshot()
{
if (snapshot != NULL) delete snapshot;
snapshot = NULL;
}
//==========================================================================
//
//
//==========================================================================
void level_info_t::ClearDefered()
{
acsdefered_t *def = defered;
while (def)
{
acsdefered_t *next = def->next;
delete def;
def = next;
}
defered = NULL;
}
//==========================================================================
//
//
//==========================================================================
level_info_t *level_info_t::CheckLevelRedirect ()
{
if (RedirectType != NAME_None)
{
const PClass *type = PClass::FindClass(RedirectType);
if (type != NULL)
{
for (int i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i] && players[i].mo->FindInventory (type))
{
// check for actual presence of the map.
if (P_CheckMapData(RedirectMap))
{
return FindLevelInfo(RedirectMap);
}
break;
}
}
}
}
return NULL;
}
//==========================================================================
//
//
//==========================================================================
bool level_info_t::isValid()
{
return mapname[0] != 0 || this == &TheDefaultLevelInfo;
}
//========================================================================== //==========================================================================
// //
// //
@ -1609,6 +1817,8 @@ void G_ParseMapInfo ()
int lump, lastlump = 0; int lump, lastlump = 0;
level_info_t gamedefaults; level_info_t gamedefaults;
atterm(ClearEpisodes);
// Parse the default MAPINFO for the current game. // Parse the default MAPINFO for the current game.
for(int i=0; i<2; i++) for(int i=0; i<2; i++)
{ {

View file

@ -56,6 +56,7 @@
#include "a_strifeglobal.h" #include "a_strifeglobal.h"
#include "g_level.h" #include "g_level.h"
#include "v_palette.h" #include "v_palette.h"
#include "p_acs.h"
static FRandom pr_chainwiggle; //use the same method of chain wiggling as heretic. static FRandom pr_chainwiggle; //use the same method of chain wiggling as heretic.

View file

@ -46,6 +46,7 @@
#include "gi.h" #include "gi.h"
#include "i_system.h" #include "i_system.h"
#include "g_level.h" #include "g_level.h"
#include "p_acs.h"
SBarInfo *SBarInfoScript[NUM_SCRIPTS] = {NULL,NULL,NULL,NULL,NULL}; SBarInfo *SBarInfoScript[NUM_SCRIPTS] = {NULL,NULL,NULL,NULL,NULL};
static const char *DefaultScriptNames[NUM_SCRIPTS] = static const char *DefaultScriptNames[NUM_SCRIPTS] =

View file

@ -69,6 +69,7 @@
#include "r_translate.h" #include "r_translate.h"
#include "sbarinfo.h" #include "sbarinfo.h"
#include "cmdlib.h" #include "cmdlib.h"
#include "m_png.h"
extern FILE *Logfile; extern FILE *Logfile;
@ -118,6 +119,222 @@ struct FBehavior::ArrayInfo
TArray<FBehavior *> FBehavior::StaticModules; TArray<FBehavior *> FBehavior::StaticModules;
//============================================================================
//
// Global and world variables
//
//============================================================================
// ACS variables with world scope
SDWORD ACS_WorldVars[NUM_WORLDVARS];
FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
// ACS variables with global scope
SDWORD ACS_GlobalVars[NUM_GLOBALVARS];
FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
//============================================================================
//
//
//
//============================================================================
void P_ClearACSVars(bool alsoglobal)
{
int i;
memset (ACS_WorldVars, 0, sizeof(ACS_WorldVars));
for (i = 0; i < NUM_WORLDVARS; ++i)
{
ACS_WorldArrays[i].Clear ();
}
if (alsoglobal)
{
memset (ACS_GlobalVars, 0, sizeof(ACS_GlobalVars));
for (i = 0; i < NUM_GLOBALVARS; ++i)
{
ACS_GlobalArrays[i].Clear ();
}
}
}
//============================================================================
//
//
//
//============================================================================
static void WriteVars (FILE *file, SDWORD *vars, size_t count, DWORD id)
{
size_t i, j;
for (i = 0; i < count; ++i)
{
if (vars[i] != 0)
break;
}
if (i < count)
{
// Find last non-zero var. Anything beyond the last stored variable
// will be zeroed at load time.
for (j = count-1; j > i; --j)
{
if (vars[j] != 0)
break;
}
FPNGChunkArchive arc (file, id);
for (i = 0; i <= j; ++i)
{
DWORD var = vars[i];
arc << var;
}
}
}
//============================================================================
//
//
//
//============================================================================
static void ReadVars (PNGHandle *png, SDWORD *vars, size_t count, DWORD id)
{
size_t len = M_FindPNGChunk (png, id);
size_t used = 0;
if (len != 0)
{
DWORD var;
size_t i;
FPNGChunkArchive arc (png->File->GetFile(), id, len);
used = len / 4;
for (i = 0; i < used; ++i)
{
arc << var;
vars[i] = var;
}
png->File->ResetFilePtr();
}
if (used < count)
{
memset (&vars[used], 0, (count-used)*4);
}
}
//============================================================================
//
//
//
//============================================================================
static void WriteArrayVars (FILE *file, FWorldGlobalArray *vars, unsigned int count, DWORD id)
{
unsigned int i, j;
// Find the first non-empty array.
for (i = 0; i < count; ++i)
{
if (vars[i].CountUsed() != 0)
break;
}
if (i < count)
{
// Find last non-empty array. Anything beyond the last stored array
// will be emptied at load time.
for (j = count-1; j > i; --j)
{
if (vars[j].CountUsed() != 0)
break;
}
FPNGChunkArchive arc (file, id);
arc.WriteCount (i);
arc.WriteCount (j);
for (; i <= j; ++i)
{
arc.WriteCount (vars[i].CountUsed());
FWorldGlobalArray::ConstIterator it(vars[i]);
const FWorldGlobalArray::Pair *pair;
while (it.NextPair (pair))
{
arc.WriteCount (pair->Key);
arc.WriteCount (pair->Value);
}
}
}
}
//============================================================================
//
//
//
//============================================================================
static void ReadArrayVars (PNGHandle *png, FWorldGlobalArray *vars, size_t count, DWORD id)
{
size_t len = M_FindPNGChunk (png, id);
unsigned int i, k;
for (i = 0; i < count; ++i)
{
vars[i].Clear ();
}
if (len != 0)
{
DWORD max, size;
FPNGChunkArchive arc (png->File->GetFile(), id, len);
i = arc.ReadCount ();
max = arc.ReadCount ();
for (; i <= max; ++i)
{
size = arc.ReadCount ();
for (k = 0; k < size; ++k)
{
SDWORD key, val;
key = arc.ReadCount();
val = arc.ReadCount();
vars[i].Insert (key, val);
}
}
png->File->ResetFilePtr();
}
}
//============================================================================
//
//
//
//============================================================================
void P_ReadACSVars(PNGHandle *png)
{
ReadVars (png, ACS_WorldVars, NUM_WORLDVARS, MAKE_ID('w','v','A','r'));
ReadVars (png, ACS_GlobalVars, NUM_GLOBALVARS, MAKE_ID('g','v','A','r'));
ReadArrayVars (png, ACS_WorldArrays, NUM_WORLDVARS, MAKE_ID('w','a','R','r'));
ReadArrayVars (png, ACS_GlobalArrays, NUM_GLOBALVARS, MAKE_ID('g','a','R','r'));
}
//============================================================================
//
//
//
//============================================================================
void P_WriteACSVars(FILE *stdfile)
{
WriteVars (stdfile, ACS_WorldVars, NUM_WORLDVARS, MAKE_ID('w','v','A','r'));
WriteVars (stdfile, ACS_GlobalVars, NUM_GLOBALVARS, MAKE_ID('g','v','A','r'));
WriteArrayVars (stdfile, ACS_WorldArrays, NUM_WORLDVARS, MAKE_ID('w','a','R','r'));
WriteArrayVars (stdfile, ACS_GlobalArrays, NUM_GLOBALVARS, MAKE_ID('g','a','R','r'));
}
//---- Inventory functions --------------------------------------// //---- Inventory functions --------------------------------------//
// //

View file

@ -36,6 +36,7 @@
#define __P_ACS_H__ #define __P_ACS_H__
#include "dobject.h" #include "dobject.h"
#include "dthinker.h"
#include "doomtype.h" #include "doomtype.h"
#define LOCAL_SIZE 20 #define LOCAL_SIZE 20
@ -44,6 +45,34 @@
class FFont; class FFont;
class FileReader; class FileReader;
enum
{
NUM_WORLDVARS = 256,
NUM_GLOBALVARS = 64
};
struct InitIntToZero
{
void Init(int &v)
{
v = 0;
}
};
typedef TMap<SDWORD, SDWORD, THashTraits<SDWORD>, InitIntToZero> FWorldGlobalArray;
// ACS variables with world scope
extern SDWORD ACS_WorldVars[NUM_WORLDVARS];
extern FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
// ACS variables with global scope
extern SDWORD ACS_GlobalVars[NUM_GLOBALVARS];
extern FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
void P_ReadACSVars(PNGHandle *);
void P_WriteACSVars(FILE*);
void P_ClearACSVars(bool);
// The in-memory version // The in-memory version
struct ScriptPtr struct ScriptPtr
{ {

View file

@ -234,7 +234,6 @@ void I_Quit (void)
if (demorecording) if (demorecording)
G_CheckDemoStatus(); G_CheckDemoStatus();
G_ClearSnapshots ();
} }

View file

@ -449,7 +449,6 @@ void I_Quit (void)
if (demorecording) if (demorecording)
G_CheckDemoStatus(); G_CheckDemoStatus();
G_ClearSnapshots ();
} }