From 92d17c03975e0c8f91a42fc0dbbd2c32202297e7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 3 Feb 2009 18:13:58 +0000 Subject: [PATCH] - cleaned up g_level.cpp SVN r1392 (newmapinfo) --- src/g_game.cpp | 133 +---------- src/g_level.cpp | 355 +++++++++++++++--------------- src/g_level.h | 34 ++- src/g_mapinfo.cpp | 214 +++++++++++++++++- src/g_shared/sbarinfo_display.cpp | 1 + src/g_shared/sbarinfo_parser.cpp | 1 + src/p_acs.cpp | 217 ++++++++++++++++++ src/p_acs.h | 29 +++ src/sdl/i_system.cpp | 1 - src/win32/i_system.cpp | 1 - 10 files changed, 656 insertions(+), 330 deletions(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index a8791b8fd6..62fd8d0235 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -73,6 +73,7 @@ #include "cmdlib.h" #include "d_net.h" #include "d_event.h" +#include "p_acs.h" #include @@ -1574,128 +1575,6 @@ bool G_CheckSaveGameWads (PNGHandle *png, bool printwarn) 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 () { @@ -1815,10 +1694,7 @@ void G_DoLoadGame () delete[] map; savegamerestore = false; - 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')); + P_ReadACSVars(png); NextSkill = -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); P_WriteACSDefereds (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')); + P_WriteACSVars(stdfile); if (NextSkill != -1) { diff --git a/src/g_level.cpp b/src/g_level.cpp index 3c40a57d1d..7fe3e13b20 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -98,6 +98,7 @@ EXTERN_CVAR (Int, disableautosave) static void SetEndSequence (char *nextmap, int type); void G_VerifySkill(); + static FRandom pr_classchoice ("RandomPlayerClassChoice"); TArray EndSequences; @@ -110,20 +111,13 @@ EndSequence::EndSequence() PlayTheEnd = false; } +extern level_info_t TheDefaultLevelInfo; extern bool timingdemo; // Start time for timing demos 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 FString BackupSaveName; @@ -137,19 +131,10 @@ void *statcopy; // for statistics driver FLevelLocals level; // info about current level -TArray wadclusterinfos; -TArray 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) { @@ -167,6 +152,11 @@ int FindEndSequence (int type, const char *picname) return -1; } +//========================================================================== +// +// +//========================================================================== + static void SetEndSequence (char *nextmap, int type) { int seqnum; @@ -182,6 +172,11 @@ static void SetEndSequence (char *nextmap, int type) *((WORD *)(nextmap + 6)) = (WORD)seqnum; } +//========================================================================== +// +// +//========================================================================== + void G_SetForEndGame (char *nextmap) { 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 // Can be called by the startup code or the menu task, // consoleplayer, playeringame[] should be set. // +//========================================================================== + static FString d_mapname; static int d_skill=-1; @@ -284,6 +219,11 @@ void G_DeferedInitNew (const char *mapname, int newskill) gameaction = ga_newgame2; } +//========================================================================== +// +// +//========================================================================== + CCMD (map) { if (netgame) @@ -309,6 +249,11 @@ CCMD (map) } } +//========================================================================== +// +// +//========================================================================== + CCMD (open) { if (netgame) @@ -337,6 +282,11 @@ CCMD (open) } +//========================================================================== +// +// +//========================================================================== + void G_NewInit () { int i; @@ -369,6 +319,11 @@ void G_NewInit () NextSkill = -1; } +//========================================================================== +// +// +//========================================================================== + void G_DoNewGame (void) { G_NewInit (); @@ -381,10 +336,15 @@ void G_DoNewGame (void) gameaction = ga_nothing; } +//========================================================================== +// // Initializes player classes in case they are random. // This gets called at the start of a new game, and the classes // chosen here are used for the remainder of a single-player // or coop game. These are ignored for deathmatch. +// +//========================================================================== + static void InitPlayerClasses () { @@ -403,6 +363,11 @@ static void InitPlayerClasses () } } +//========================================================================== +// +// +//========================================================================== + void G_InitNew (const char *mapname, bool bTitleLevel) { EGameSpeed oldSpeed; @@ -518,16 +483,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel) rngseed = rngseed*3/2; } FRandom::StaticClearRandom (); - memset (ACS_WorldVars, 0, sizeof(ACS_WorldVars)); - 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 (); - } + P_ClearACSVars(true); level.time = 0; level.maptime = 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 g_nomonsters; +//========================================================================== +// // [RH] The position parameter to these next three functions should // match the first parameter of the single player start spots // that should appear in the next map. +// +//========================================================================== + void G_ChangeLevel(const char *levelname, int position, bool keepFacing, int nextSkill, 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)) { - level_info_t *nextinfo = CheckLevelRedirect (FindLevelInfo (nextlevel)); + level_info_t *nextinfo = FindLevelInfo (nextlevel)->CheckLevelRedirect (); if (nextinfo) { nextlevel = nextinfo->mapname; @@ -660,6 +621,11 @@ void G_ChangeLevel(const char *levelname, int position, bool keepFacing, int nex } } +//========================================================================== +// +// +//========================================================================== + const char *G_GetExitMap() { return level.nextmap; @@ -679,6 +645,11 @@ const char *G_GetSecretExitMap() return nextmap; } +//========================================================================== +// +// +//========================================================================== + void G_ExitLevel (int position, bool keepFacing) { G_ChangeLevel(G_GetExitMap(), position, keepFacing); @@ -689,6 +660,11 @@ void G_SecretExitLevel (int position) G_ChangeLevel(G_GetSecretExitMap(), position, false); } +//========================================================================== +// +// +//========================================================================== + void G_DoCompleted (void) { int i; @@ -809,11 +785,7 @@ void G_DoCompleted (void) if (mode == FINISH_NextHub) { // Reset world variables for the new hub. - memset (ACS_WorldVars, 0, sizeof(ACS_WorldVars)); - for (i = 0; i < NUM_WORLDVARS; ++i) - { - ACS_WorldArrays[i].Clear (); - } + P_ClearACSVars(false); } // With hub statistics the time should be per hub. // 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); } +//========================================================================== +// +// +//========================================================================== + class DAutosaver : public DThinker { DECLARE_CLASS (DAutosaver, DThinker) @@ -858,9 +835,12 @@ void DAutosaver::Tick () Destroy (); } +//========================================================================== // // G_DoLoadLevel // +//========================================================================== + extern gamestate_t wipegamestate; void G_DoLoadLevel (int position, bool autosave) @@ -1005,9 +985,12 @@ void G_DoLoadLevel (int position, bool autosave) } +//========================================================================== // // G_WorldDone // +//========================================================================== + void G_WorldDone (void) { cluster_info_t *nextcluster; @@ -1062,6 +1045,11 @@ void G_WorldDone (void) } } +//========================================================================== +// +// +//========================================================================== + void G_DoWorldDone (void) { gamestate = GS_LEVEL; @@ -1205,6 +1193,11 @@ void G_FinishTravel () } } +//========================================================================== +// +// +//========================================================================== + void G_InitLevelLocals () { level_info_t *info; @@ -1225,7 +1218,6 @@ void G_InitLevelLocals () level.info = info; level.skyspeed1 = info->skyspeed1; level.skyspeed2 = info->skyspeed2; - info = (level_info_t *)info; strncpy (level.skypic2, info->skypic2, 8); level.fadeto = info->fadeto; level.cdtrack = info->cdtrack; @@ -1307,6 +1299,11 @@ void G_InitLevelLocals () NormalLight.ChangeFade (level.fadeto); } +//========================================================================== +// +// +//========================================================================== + bool FLevelLocals::IsJumpingAllowed() const { if (dmflags & DF_NO_JUMP) @@ -1316,6 +1313,11 @@ bool FLevelLocals::IsJumpingAllowed() const return !(level.flags & LEVEL_JUMP_NO); } +//========================================================================== +// +// +//========================================================================== + bool FLevelLocals::IsCrouchingAllowed() const { if (dmflags & DF_NO_CROUCH) @@ -1325,6 +1327,11 @@ bool FLevelLocals::IsCrouchingAllowed() const return !(level.flags & LEVEL_CROUCH_NO); } +//========================================================================== +// +// +//========================================================================== + bool FLevelLocals::IsFreelookAllowed() const { if (level.flags & LEVEL_FREELOOK_NO) @@ -1334,6 +1341,11 @@ bool FLevelLocals::IsFreelookAllowed() const return !(dmflags & DF_NO_FREELOOK); } +//========================================================================== +// +// +//========================================================================== + FString CalcMapName (int episode, int level) { FString lumpname; @@ -1350,66 +1362,10 @@ FString CalcMapName (int episode, int level) 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 () { @@ -1425,6 +1381,11 @@ void G_AirControlChanged () } } +//========================================================================== +// +// +//========================================================================== + void G_SerializeLevel (FArchive &arc, bool hubLoad) { int i = level.totaltime; @@ -1537,13 +1498,18 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad) } } +//========================================================================== +// // Archives the current level +// +//========================================================================== + void G_SnapshotLevel () { if (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->snapshot = new FCompressedMemFile; @@ -1556,14 +1522,19 @@ void G_SnapshotLevel () } } +//========================================================================== +// // Unarchives the current level based on its snapshot // The level should have already been loaded and setup. +// +//========================================================================== + void G_UnSnapshotLevel (bool hubLoad) { if (level.info->snapshot == NULL) return; - if (level.info->mapname[0] != 0 || level.info == &TheDefaultLevelInfo) + if (level.info->isValid()) { SaveVersion = level.info->snapshotVer; 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. - delete level.info->snapshot; - level.info->snapshot = NULL; + level.info->ClearSnapshot(); } -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) { @@ -1632,6 +1595,11 @@ static void writeMapName (FArchive &arc, const char *name) arc.Write (name, size); } +//========================================================================== +// +// +//========================================================================== + static void writeSnapShot (FArchive &arc, level_info_t *i) { arc << i->snapshotVer; @@ -1639,6 +1607,11 @@ static void writeSnapShot (FArchive &arc, level_info_t *i) i->snapshot->Serialize (arc); } +//========================================================================== +// +// +//========================================================================== + void G_WriteSnapshots (FILE *file) { unsigned int i; @@ -1706,6 +1679,11 @@ void G_WriteSnapshots (FILE *file) } } +//========================================================================== +// +// +//========================================================================== + void G_ReadSnapshots (PNGHandle *png) { DWORD chunkLen; @@ -1792,12 +1770,22 @@ void G_ReadSnapshots (PNGHandle *png) } +//========================================================================== +// +// +//========================================================================== + static void writeDefereds (FArchive &arc, level_info_t *i) { writeMapName (arc, i->mapname); arc << i->defered; } +//========================================================================== +// +// +//========================================================================== + void P_WriteACSDefereds (FILE *file) { FPNGChunkArchive *arc = NULL; @@ -1823,6 +1811,11 @@ void P_WriteACSDefereds (FILE *file) } } +//========================================================================== +// +// +//========================================================================== + void P_ReadACSDefereds (PNGHandle *png) { BYTE namelen; @@ -1853,6 +1846,11 @@ void P_ReadACSDefereds (PNGHandle *png) } +//========================================================================== +// +// +//========================================================================== + void FLevelLocals::Tick () { // Reset carry sectors @@ -1862,6 +1860,11 @@ void FLevelLocals::Tick () } } +//========================================================================== +// +// +//========================================================================== + void FLevelLocals::AddScroller (DScroller *scroller, int secnum) { if (secnum < 0) diff --git a/src/g_level.h b/src/g_level.h index 68f65b5fbb..593bd34238 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -112,9 +112,6 @@ struct FMapOptInfo bool old; }; -#define NUM_WORLDVARS 256 -#define NUM_GLOBALVARS 64 - enum ELevelFlags { LEVEL_NOINTERMISSION = 0x00000001, @@ -283,9 +280,21 @@ struct level_info_t TArray specialactions; - level_info_t() { Reset(); } + level_info_t() + { + Reset(); + } + ~level_info_t() + { + ClearSnapshot(); + ClearDefered(); + } void Reset(); + bool isValid(); FString LookupLevelName (); + void ClearSnapshot(); + void ClearDefered(); + level_info_t *CheckLevelRedirect (); }; @@ -423,21 +432,6 @@ extern FLevelLocals level; extern TArray wadlevelinfos; extern TArray wadclusterinfos; -extern SDWORD ACS_WorldVars[NUM_WORLDVARS]; -extern SDWORD ACS_GlobalVars[NUM_GLOBALVARS]; - -struct InitIntToZero -{ - void Init(int &v) - { - v = 0; - } -}; -typedef TMap, InitIntToZero> FWorldGlobalArray; - -extern FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS]; -extern FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS]; - extern bool savegamerestore; // 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); void G_ParseMapInfo (void); -void G_UnloadMapInfo (); void G_ClearSnapshots (void); +void P_RemoveDefereds (); void G_SnapshotLevel (void); void G_UnSnapshotLevel (bool keepPlayers); struct PNGHandle; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 1873ec4ac8..c7bd8ec1c1 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -46,11 +46,26 @@ #include "i_system.h" #include "gi.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 FindWadLevelInfo (const char *name) +TArray wadclusterinfos; +TArray 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++) if (!strnicmp (name, wadlevelinfos[i].mapname, 8)) @@ -59,7 +74,90 @@ int FindWadLevelInfo (const char *name) 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++) if (wadclusterinfos[i].cluster == cluster) @@ -68,6 +166,49 @@ int FindWadClusterInfo (int cluster) 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; level_info_t gamedefaults; + atterm(ClearEpisodes); + // Parse the default MAPINFO for the current game. for(int i=0; i<2; i++) { diff --git a/src/g_shared/sbarinfo_display.cpp b/src/g_shared/sbarinfo_display.cpp index 790a9a49c9..205c820576 100644 --- a/src/g_shared/sbarinfo_display.cpp +++ b/src/g_shared/sbarinfo_display.cpp @@ -56,6 +56,7 @@ #include "a_strifeglobal.h" #include "g_level.h" #include "v_palette.h" +#include "p_acs.h" static FRandom pr_chainwiggle; //use the same method of chain wiggling as heretic. diff --git a/src/g_shared/sbarinfo_parser.cpp b/src/g_shared/sbarinfo_parser.cpp index 8530afe2c7..12ba20152c 100644 --- a/src/g_shared/sbarinfo_parser.cpp +++ b/src/g_shared/sbarinfo_parser.cpp @@ -46,6 +46,7 @@ #include "gi.h" #include "i_system.h" #include "g_level.h" +#include "p_acs.h" SBarInfo *SBarInfoScript[NUM_SCRIPTS] = {NULL,NULL,NULL,NULL,NULL}; static const char *DefaultScriptNames[NUM_SCRIPTS] = diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 3769328f4a..0d6ddf4350 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -69,6 +69,7 @@ #include "r_translate.h" #include "sbarinfo.h" #include "cmdlib.h" +#include "m_png.h" extern FILE *Logfile; @@ -118,6 +119,222 @@ struct FBehavior::ArrayInfo TArray 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 --------------------------------------// // diff --git a/src/p_acs.h b/src/p_acs.h index a92b0d0cfd..59ff1274e1 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -36,6 +36,7 @@ #define __P_ACS_H__ #include "dobject.h" +#include "dthinker.h" #include "doomtype.h" #define LOCAL_SIZE 20 @@ -44,6 +45,34 @@ class FFont; class FileReader; + +enum +{ + NUM_WORLDVARS = 256, + NUM_GLOBALVARS = 64 +}; + +struct InitIntToZero +{ + void Init(int &v) + { + v = 0; + } +}; +typedef TMap, 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 struct ScriptPtr { diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index f39d817551..c1a1a85148 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -234,7 +234,6 @@ void I_Quit (void) if (demorecording) G_CheckDemoStatus(); - G_ClearSnapshots (); } diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 4318d95dd8..9da20744c4 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -449,7 +449,6 @@ void I_Quit (void) if (demorecording) G_CheckDemoStatus(); - G_ClearSnapshots (); }