diff --git a/docs/rh-log.txt b/docs/rh-log.txt index b5207d419..29ea577a3 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,28 @@ +June 14, 2006 (Changes by Graf Zahl) +- Fixed: Saving on maps that don't contain a MAPINFO definition didn't work. +- Fixed: The Zip loader loaded all WADs inside a Zip into the lump directory. + This is only supposed to be done for WADs in the root directory. + +June 12-14, 2006 (Changes by Graf Zahl) +- Complete restructuring of the map loading code. Previously the only way + to put maps into Zips was to load them as embedded WADs which caused + some problems, most importantly that the map's file name was irrelevant + and the internal map label was used instead. With the new code there + is now a properly defined way to add maps to Zips: + * Maps are placed in a subdirectory called 'maps'. + * Maps are stored as WADs that contain all map related lumps. + * The first lump in the map's WAD directory must be the map label. + * All lumps not belonging to the first map are ignored. + * The map's file name determines the name the map is identified with. + For maps stored this way the internal map label is ignored so with this + method renaming maps is as easy as renaming a file and it is no longer + necessary to manipulate the map label. + With the new code it is also possible to load external maps without + adding them to the WAD list. Type 'open mapfile.wad' in the console + to start such a map. + The new code also performs stricter lump name checks to prevent accidental + loading of non-map data. + June 13, 2006 - Fixed: In the past, ZDoom worked like Doom and used integral values for monster speeds. Now it uses fixed point so that an actor's speed property diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index fa2714972..38300f104 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -65,6 +65,7 @@ #include "templates.h" #include "p_local.h" #include "r_sky.h" +#include "p_setup.h" extern FILE *Logfile; extern bool insave; @@ -308,12 +309,14 @@ CCMD (changemap) if (argv.argc() > 1) { - if (Wads.CheckNumForName (argv[1]) == -1) + MapData * map = P_OpenMapData(argv[1]); + if (map == NULL) { Printf ("No map %s\n", argv[1]); } else { + delete map; if (argv.argc() > 2) { Net_WriteByte (DEM_CHANGEMAP2); diff --git a/src/g_game.cpp b/src/g_game.cpp index aea91129c..11fb7289a 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1852,7 +1852,7 @@ static void PutSaveWads (FILE *file) M_AppendPNGText (file, "Game WAD", name); // Name of wad the map resides in - if (Wads.GetLumpFile (level.lumpnum) != 1) + if (Wads.GetLumpFile (level.lumpnum) > 1) { name = Wads.GetWadName (Wads.GetLumpFile (level.lumpnum)); M_AppendPNGText (file, "Map WAD", name); @@ -2064,6 +2064,14 @@ void G_DoSaveGame (bool okForQuicksave) BackupSaveName = savegamefile; savegamefile = ""; + + // We don't need the snapshot any longer. + if (level.info->snapshot != NULL) + { + delete level.info->snapshot; + level.info->snapshot = NULL; + } + insave = false; } diff --git a/src/g_level.cpp b/src/g_level.cpp index 12c9d63a9..2ca0aa5a2 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -85,6 +85,7 @@ EXTERN_CVAR (Int, disableautosave) #define cioffset(x) ((size_t)&((cluster_info_t*)1)->x - 1) #define SNAP_ID MAKE_ID('s','n','A','p') +#define DSNP_ID MAKE_ID('d','s','N','p') #define VIST_ID MAKE_ID('v','i','S','t') #define ACSD_ID MAKE_ID('a','c','S','d') #define RCLS_ID MAKE_ID('r','c','L','s') @@ -1298,7 +1299,7 @@ bool CheckWarpTransMap (char mapname[9], bool substitute) // Can be called by the startup code or the menu task, // consoleplayer, playeringame[] should be set. // -static char d_mapname[9]; +static char d_mapname[256]; void G_DeferedInitNew (char *mapname) { @@ -1317,10 +1318,14 @@ CCMD (map) } if (argv.argc() > 1) { - if (Wads.CheckNumForName (argv[1]) == -1) + MapData * map = P_OpenMapData(argv[1]); + if (map == NULL) Printf ("No map %s\n", argv[1]); else + { + delete map; G_DeferedInitNew (argv[1]); + } } else { @@ -1328,6 +1333,32 @@ CCMD (map) } } +CCMD (open) +{ + if (netgame) + { + Printf ("You cannot use open in multiplayer games.\n"); + return; + } + if (argv.argc() > 1) + { + sprintf(d_mapname, "file:%s", argv[1]); + MapData * map = P_OpenMapData(d_mapname); + if (map == NULL) + Printf ("No map %s\n", d_mapname); + else + { + delete map; + gameaction = ga_newgame2; + } + } + else + { + Printf ("Usage: open \n"); + } +} + + void G_NewInit () { int i; @@ -1431,10 +1462,12 @@ void G_InitNew (char *mapname, bool bTitleLevel) } // [RH] If this map doesn't exist, bomb out - if (Wads.CheckNumForName (mapname) == -1) + MapData * map = P_OpenMapData(mapname); + if (!map) { I_Error ("Could not find map %s\n", mapname); } + delete map; if (dmflags & DF_MONSTERS_RESPAWN) { @@ -1504,8 +1537,7 @@ void G_InitNew (char *mapname, bool bTitleLevel) bglobal.Init (); } - strncpy (level.mapname, mapname, 8); - level.mapname[8] = 0; + strcpy (level.mapname, mapname); if (bTitleLevel) { gamestate = GS_TITLELEVEL; @@ -2560,7 +2592,7 @@ void G_SnapshotLevel () if (level.info->snapshot) delete level.info->snapshot; - if (level.info->mapname[0] != 0) + if (level.info->mapname[0] != 0 || level.info == &TheDefaultLevelInfo) { level.info->snapshotVer = SAVEVER; level.info->snapshot = new FCompressedMemFile; @@ -2580,7 +2612,7 @@ void G_UnSnapshotLevel (bool hubLoad) if (level.info->snapshot == NULL) return; - if (level.info->mapname[0] != 0) + if (level.info->mapname[0] != 0 || level.info == &TheDefaultLevelInfo) { SaveVersion = level.info->snapshotVer; level.info->snapshot->Reopen (); @@ -2654,6 +2686,11 @@ void G_WriteSnapshots (FILE *file) writeSnapShot (arc, (level_info_t *)&wadlevelinfos[i]); } } + if (TheDefaultLevelInfo.snapshot != NULL) + { + FPNGChunkArchive arc (file, DSNP_ID); + writeSnapShot(arc, &TheDefaultLevelInfo); + } FPNGChunkArchive *arc = NULL; @@ -2730,6 +2767,20 @@ void G_ReadSnapshots (PNGHandle *png) chunkLen = (DWORD)M_NextPNGChunk (png, SNAP_ID); } + chunkLen = (DWORD)M_FindPNGChunk (png, DSNP_ID); + if (chunkLen != 0) + { + FPNGChunkArchive arc (png->File->GetFile(), DSNP_ID, chunkLen); + DWORD snapver; + + arc << snapver; + arc << namelen; + arc.Read (mapname, namelen); + TheDefaultLevelInfo.snapshotVer = snapver; + TheDefaultLevelInfo.snapshot = new FCompressedMemFile; + TheDefaultLevelInfo.snapshot->Serialize (arc); + } + chunkLen = (DWORD)M_FindPNGChunk (png, VIST_ID); if (chunkLen != 0) { diff --git a/src/g_level.h b/src/g_level.h index 2b76e2f60..945dc04ce 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -193,7 +193,7 @@ struct level_locals_s int levelnum; int lumpnum; char level_name[64]; // the descriptive name (Outer Base, etc) - char mapname[9]; // the server name (base1, etc) + char mapname[256]; // the server name (base1, etc) char nextmap[9]; // go here when fraglimit is hit char secretmap[9]; // map to go to when used secret exit diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 9c108d546..b8179c9bd 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -490,7 +490,7 @@ void FBehavior::StaticLoadDefaultModules () } } -FBehavior *FBehavior::StaticLoadModule (int lumpnum) +FBehavior *FBehavior::StaticLoadModule (int lumpnum, FileReader * fr, int len) { for (unsigned int i = 0; i < StaticModules.Size(); ++i) { @@ -500,7 +500,7 @@ FBehavior *FBehavior::StaticLoadModule (int lumpnum) } } - return new FBehavior (lumpnum); + return new FBehavior (lumpnum, fr, len); } bool FBehavior::StaticCheckAllGood () @@ -653,10 +653,9 @@ void FBehavior::SerializeVarSet (FArchive &arc, SDWORD *vars, int max) } } -FBehavior::FBehavior (int lumpnum) +FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) { BYTE *object; - int len; int i; NumScripts = 0; @@ -673,7 +672,7 @@ FBehavior::FBehavior (int lumpnum) memset (MapVarStore, 0, sizeof(MapVarStore)); ModuleName[0] = 0; - len = Wads.LumpLength (lumpnum); + if (fr == NULL) len = Wads.LumpLength (lumpnum); // Any behaviors smaller than 32 bytes cannot possibly contain anything useful. // (16 bytes for a completely empty behavior + 12 bytes for one script header @@ -685,7 +684,14 @@ FBehavior::FBehavior (int lumpnum) } object = new byte[len]; - Wads.ReadLump (lumpnum, object); + if (fr == NULL) + { + Wads.ReadLump (lumpnum, object); + } + else + { + fr->Read (object, len); + } if (object[0] != 'A' || object[1] != 'C' || object[2] != 'S') { @@ -707,8 +713,16 @@ FBehavior::FBehavior (int lumpnum) return; } - Wads.GetLumpName (ModuleName, lumpnum); - ModuleName[8] = 0; + if (fr == NULL) + { + Wads.GetLumpName (ModuleName, lumpnum); + ModuleName[8] = 0; + } + else + { + strcpy(ModuleName, "BEHAVIOR"); + } + Data = object; DataSize = len; diff --git a/src/p_acs.h b/src/p_acs.h index e14bd02ed..3895444c0 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -42,6 +42,7 @@ #define NUM_MAPVARS 128 class FFont; +class FileReader; // The in-memory version struct ScriptPtr @@ -123,7 +124,7 @@ enum ACSFormat { ACS_Old, ACS_Enhanced, ACS_LittleEnhanced, ACS_Unknown }; class FBehavior { public: - FBehavior (int lumpnum); + FBehavior (int lumpnum, FileReader * fr=NULL, int len=0); ~FBehavior (); bool IsGood (); @@ -145,7 +146,7 @@ public: SDWORD *MapVars[NUM_MAPVARS]; - static FBehavior *StaticLoadModule (int lumpnum); + static FBehavior *StaticLoadModule (int lumpnum, FileReader * fr=NULL, int len=0); static void StaticLoadDefaultModules (); static void StaticUnloadModules (); static bool StaticCheckAllGood (); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 2222e267f..49b25f403 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -57,6 +57,7 @@ #include "a_keys.h" #include "s_sndseq.h" #include "sbar.h" +#include "p_setup.h" extern void P_SpawnMapThing (mapthing2_t *mthing, int position); extern bool P_LoadBuildMap (BYTE *mapdata, size_t len, mapthing2_t **things, int *numthings); @@ -76,6 +77,8 @@ CVAR (Bool, showloadtimes, false, 0); static void P_InitTagLists (); static void P_Shutdown (); + + // // MAP related Lookup tables. // Store VERTEXES, LINEDEFS, SIDEDEFS, etc. @@ -130,9 +133,6 @@ struct sidei_t // [RH] Only keep BOOM sidedef init stuff around for init } *sidetemp; static WORD *linemap; -// [RH] Set true if the map contains a BEHAVIOR lump -BOOL HasBehavior; - bool UsingGLNodes; // BLOCKMAP @@ -174,7 +174,188 @@ mapthing2_t playerstarts[MAXPLAYERS]; static void P_AllocateSideDefs (int count); static void P_SetSideNum (DWORD *sidenum_p, WORD sidenum); + + + +//=========================================================================== +// +// GetMapIndex +// +// Gets the type of map lump or -1 if invalid +// +//=========================================================================== + +static int GetMapIndex(const char * mapname, int lastindex, const char * lumpname) +{ + static struct + { + char * lumpname; + bool required; + } check[]={ + {NULL, true}, + {"THINGS", true}, + {"LINEDEFS", true}, + {"SIDEDEFS", true}, + {"VERTEXES", true}, + {"SEGS", false}, + {"SSECTORS", false}, + {"NODES", false}, + {"SECTORS", true}, + {"REJECT", false}, + {"BLOCKMAP", false}, + {"BEHAVIOR", false}, + {"SCRIPTS", false}, + }; + + if (lumpname==NULL) lumpname=""; + + for(size_t i=lastindex+1;ifile = new FileReader(mapname); + map->CloseOnDestruct = true; + } + else + { + FString fmt; + int lump_wad; + int lump_map; + int lump_name; + + // Check for both *.wad and *.map in order to load Build maps + // as well. The higher one will take precedence. + lump_name = Wads.CheckNumForName(mapname); + fmt.Format("maps/%s.wad", mapname); + lump_wad = Wads.CheckNumForFullName(fmt); + fmt.Format("maps/%s.map", mapname); + lump_map = Wads.CheckNumForFullName(fmt); + + if (lump_name > lump_wad && lump_name > lump_map && lump_name != -1) + { + map->file = Wads.GetFileReader(Wads.GetLumpFile (lump_name)); + map->CloseOnDestruct = false; + map->lumpnum = lump_name; + + map->MapLumps[0].FilePos = Wads.GetLumpOffset(lump_name); + map->MapLumps[0].Size = Wads.LumpLength(lump_name); + + int index=0; + for(int i=1;;i++) + { + // Since levels must be stored in WADs they can't really have full + // names and for any valid level lump this always returns the short name. + const char * lumpname = Wads.GetLumpFullName(lump_name + i); + index = GetMapIndex(mapname, index, lumpname); + + // The next lump is not part of this map anymore + if (index < 0) break; + + map->MapLumps[index].FilePos = Wads.GetLumpOffset(lump_name + i); + map->MapLumps[index].Size = Wads.LumpLength(lump_name + i); + strncpy(map->MapLumps[i].Name, lumpname, 8); + } + return map; + } + else + { + if (lump_map > lump_wad) + { + lump_wad = lump_map; + } + if (lump_wad == -1) + { + delete map; + return NULL; + } + map->lumpnum = lump_wad; + map->file = Wads.ReopenLumpNum(lump_wad); + map->CloseOnDestruct = true; + } + } + DWORD id; + (*map->file) >> id; + + if (id == IWAD_ID || id == PWAD_ID) + { + char maplabel[9]=""; + int index=0; + DWORD dirofs, numentries; + + (*map->file) >> numentries >> dirofs; + + map->file->Seek(dirofs, SEEK_SET); + for(DWORD i = 0; i < numentries; i++) + { + DWORD offset, size; + char lumpname[8]; + + (*map->file) >> offset >> size; + map->file->Read(lumpname, 8); + + if (i>0) + { + index = GetMapIndex(maplabel, index, lumpname); + + // The next lump is not part of this map anymore + if (index < 0) break; + } + else + { + strncpy(maplabel, lumpname, 8); + maplabel[8]=0; + } + + map->MapLumps[index].FilePos = offset; + map->MapLumps[index].Size = size; + strncpy(map->MapLumps[i].Name, lumpname, 8); + } + } + else + { + // This is a Build map and not subject to WAD consistency checks. + map->MapLumps[0].Size = map->file->GetLength(); + } + return map; +} + + +//=========================================================================== +// // [RH] Figure out blends for deep water sectors +// +//=========================================================================== + static void SetTexture (short *texture, DWORD *blend, char *name8) { char name[9]; @@ -227,6 +408,12 @@ static void SetTextureNoErr (short *texture, DWORD *color, char *name8, bool *va } } +//=========================================================================== +// +// Sound enviroment handling +// +//=========================================================================== + void P_FloodZone (sector_t *sec, int zonenum) { int i; @@ -273,17 +460,20 @@ void P_FloodZones () } } +//=========================================================================== // // P_LoadVertexes // -void P_LoadVertexes (int lump) +//=========================================================================== + +void P_LoadVertexes (MapData * map) { FWadLump data; int i; // Determine number of vertices: // total lump length / vertex record length. - numvertexes = Wads.LumpLength (lump) / sizeof(mapvertex_t); + numvertexes = map->MapLumps[ML_VERTEXES].Size / sizeof(mapvertex_t); if (numvertexes == 0) { @@ -293,22 +483,25 @@ void P_LoadVertexes (int lump) // Allocate memory for buffer. vertexes = new vertex_t[numvertexes]; - data = Wads.OpenLumpNum (lump); + map->Seek(ML_VERTEXES); // Copy and convert vertex coordinates, internal representation as fixed. for (i = 0; i < numvertexes; i++) { SWORD x, y; - data >> x >> y; + (*map->file) >> x >> y; vertexes[i].x = x << FRACBITS; vertexes[i].y = y << FRACBITS; } } +//=========================================================================== // // P_LoadZSegs // +//=========================================================================== + void P_LoadZSegs (FileReaderZ &data) { for (int i = 0; i < numsegs; ++i) @@ -338,11 +531,14 @@ void P_LoadZSegs (FileReaderZ &data) } } +//=========================================================================== // // P_LoadGLZSegs // // This is the GL nodes version of the above function. // +//=========================================================================== + void P_LoadGLZSegs (FileReaderZ &data) { for (int i = 0; i < numsubsectors; ++i) @@ -401,9 +597,12 @@ void P_LoadGLZSegs (FileReaderZ &data) } } +//=========================================================================== // // P_LoadZNodes // +//=========================================================================== + static void P_LoadZNodes (FileReader &dalump, DWORD id) { FileReaderZ data (dalump); @@ -528,16 +727,18 @@ static void P_LoadZNodes (FileReader &dalump, DWORD id) } +//=========================================================================== // // P_LoadSegs // // killough 5/3/98: reformatted, cleaned up +// +//=========================================================================== -void P_LoadSegs (int lump) +void P_LoadSegs (MapData * map) { int i; - FMemLump lumpdata; - const byte *data; + byte *data; byte *vertchanged = new byte[numvertexes]; // phares 10/4/98 DWORD segangle; line_t* line; // phares 10/4/98 @@ -546,10 +747,11 @@ void P_LoadSegs (int lump) int dis; // phares 10/4/98 int dx,dy; // phares 10/4/98 int vnum1,vnum2; // phares 10/4/98 + int lumplen = map->MapLumps[ML_SEGS].Size; memset (vertchanged,0,numvertexes); // phares 10/4/98 - numsegs = Wads.LumpLength (lump) / sizeof(mapseg_t); + numsegs = lumplen / sizeof(mapseg_t); if (numsegs == 0) { @@ -563,8 +765,9 @@ void P_LoadSegs (int lump) segs = new seg_t[numsegs]; memset (segs, 0, numsegs*sizeof(seg_t)); - lumpdata = Wads.ReadLump (lump); - data = (const BYTE *)lumpdata.GetMem(); + + data = new byte[lumplen]; + map->Read(ML_SEGS, data); // phares: 10/4/98: Vertchanged is an array that represents the vertices. // Mark those used by linedefs. A marked vertex is one that is not a @@ -592,35 +795,35 @@ void P_LoadSegs (int lump) segangle = (WORD)LittleShort(ml->angle); -// phares 10/4/98: In the case of a lineseg that was created by splitting -// another line, it appears that the line angle is inherited from the -// father line. Due to roundoff, the new vertex may have been placed 'off -// the line'. When you get close to such a line, and it is very short, -// it's possible that the roundoff error causes 'firelines', the thin -// lines that can draw from screen top to screen bottom occasionally. This -// is due to all the angle calculations that are done based on the line -// angle, the angles from the viewer to the vertices, and the viewer's -// angle in the world. In the case of firelines, the rounded-off position -// of one of the vertices determines one of these angles, and introduces -// an error in the scaling factor for mapping textures and determining -// where on the screen the ceiling and floor spans should be shown. For a -// fireline, the engine thinks the ceiling bottom and floor top are at the -// midpoint of the screen. So you get ceilings drawn all the way down to the -// screen midpoint, and floors drawn all the way up. Thus 'firelines'. The -// name comes from the original sighting, which involved a fire texture. -// -// To correct this, reset the vertex that was added so that it sits ON the -// split line. -// -// To know which of the two vertices was added, its number is greater than -// that of the last of the author-created vertices. If both vertices of the -// line were added by splitting, pick the higher-numbered one. Once you've -// changed a vertex, don't change it again if it shows up in another seg. -// -// To determine if there's an error in the first place, find the -// angle of the line between the two seg vertices. If it's one degree or more -// off, then move one vertex. This may seem insignificant, but one degree -// errors _can_ cause firelines. + // phares 10/4/98: In the case of a lineseg that was created by splitting + // another line, it appears that the line angle is inherited from the + // father line. Due to roundoff, the new vertex may have been placed 'off + // the line'. When you get close to such a line, and it is very short, + // it's possible that the roundoff error causes 'firelines', the thin + // lines that can draw from screen top to screen bottom occasionally. This + // is due to all the angle calculations that are done based on the line + // angle, the angles from the viewer to the vertices, and the viewer's + // angle in the world. In the case of firelines, the rounded-off position + // of one of the vertices determines one of these angles, and introduces + // an error in the scaling factor for mapping textures and determining + // where on the screen the ceiling and floor spans should be shown. For a + // fireline, the engine thinks the ceiling bottom and floor top are at the + // midpoint of the screen. So you get ceilings drawn all the way down to the + // screen midpoint, and floors drawn all the way up. Thus 'firelines'. The + // name comes from the original sighting, which involved a fire texture. + // + // To correct this, reset the vertex that was added so that it sits ON the + // split line. + // + // To know which of the two vertices was added, its number is greater than + // that of the last of the author-created vertices. If both vertices of the + // line were added by splitting, pick the higher-numbered one. Once you've + // changed a vertex, don't change it again if it shows up in another seg. + // + // To determine if there's an error in the first place, find the + // angle of the line between the two seg vertices. If it's one degree or more + // off, then move one vertex. This may seem insignificant, but one degree + // errors _can_ cause firelines. ptp_angle = R_PointToAngle2 (li->v1->x, li->v1->y, li->v2->x, li->v2->y); dis = 0; @@ -707,22 +910,24 @@ void P_LoadSegs (int lump) } delete[] vertchanged; // phares 10/4/98 + delete[] data; } +//=========================================================================== // // P_LoadSubsectors // -void P_LoadSubsectors (int lump) +//=========================================================================== + +void P_LoadSubsectors (MapData * map) { - DWORD maxseg; - FWadLump data; int i; + int maxseg = map->Size(ML_SEGS) / sizeof(mapseg_t); - numsubsectors = Wads.LumpLength (lump) / sizeof(mapsubsector_t); - maxseg = Wads.LumpLength (lump - ML_SSECTORS + ML_SEGS) / sizeof(mapseg_t); + numsubsectors = map->MapLumps[ML_SSECTORS].Size / sizeof(mapsubsector_t); - if (numsubsectors == 0 || maxseg == 0) + if (numsubsectors == 0 || maxseg == 0 ) { Printf ("This map has an incomplete BSP tree.\n"); delete[] nodes; @@ -731,7 +936,7 @@ void P_LoadSubsectors (int lump) } subsectors = new subsector_t[numsubsectors]; - data = Wads.OpenLumpNum (lump); + map->Seek(ML_SSECTORS); memset (subsectors, 0, numsubsectors*sizeof(subsector_t)); @@ -739,7 +944,7 @@ void P_LoadSubsectors (int lump) { WORD numsegs, firstseg; - data >> numsegs >> firstseg; + (*map->file) >> numsegs >> firstseg; if (numsegs == 0) { @@ -777,24 +982,26 @@ void P_LoadSubsectors (int lump) } - +//=========================================================================== // // P_LoadSectors // -void P_LoadSectors (int lump) +//=========================================================================== + +void P_LoadSectors (MapData * map) { - FMemLump data; char fname[9]; int i; - mapsector_t* ms; + char *msp; + mapsector_t *ms; sector_t* ss; int defSeqType; FDynamicColormap *fogMap, *normMap; + int lumplen = map->Size(ML_SECTORS); - numsectors = Wads.LumpLength (lump) / sizeof(mapsector_t); + numsectors = lumplen / sizeof(mapsector_t); sectors = new sector_t[numsectors]; memset (sectors, 0, numsectors*sizeof(sector_t)); - data = Wads.ReadLump (lump); if (level.flags & LEVEL_SNDSEQTOTALCTRL) defSeqType = 0; @@ -804,7 +1011,9 @@ void P_LoadSectors (int lump) fogMap = normMap = NULL; fname[8] = 0; - ms = (mapsector_t *)data.GetMem(); + msp = new char[lumplen]; + map->Read(ML_SECTORS, msp); + ms = (mapsector_t*)msp; ss = sectors; for (i = 0; i < numsectors; i++, ss++, ms++) { @@ -821,7 +1030,7 @@ void P_LoadSectors (int lump) strncpy (fname, ms->ceilingpic, 8); ss->ceilingpic = TexMan.GetTexture (fname, FTexture::TEX_Flat, FTextureManager::TEXMAN_Overridable); ss->lightlevel = clamp (LittleShort(ms->lightlevel), (short)0, (short)255); - if (HasBehavior) + if (map->HasBehavior) ss->special = LittleShort(ms->special); else // [RH] Translate to new sector special ss->special = P_TranslateSectorSpecial (LittleShort(ms->special)); @@ -864,25 +1073,30 @@ void P_LoadSectors (int lump) ss->friction = ORIG_FRICTION; ss->movefactor = ORIG_FRICTION_FACTOR; } + delete[] msp; } +//=========================================================================== // // P_LoadNodes // -void P_LoadNodes (int lump) +//=========================================================================== + +void P_LoadNodes (MapData * map) { FMemLump data; int i; int j; int k; - mapnode_t* mn; + char *mnp; + mapnode_t *mn; node_t* no; - int maxss; WORD* used; + int lumplen = map->Size(ML_NODES); + int maxss = map->Size(ML_SSECTORS) / sizeof(mapsubsector_t); - numnodes = Wads.LumpLength (lump) / sizeof(mapnode_t); - maxss = Wads.LumpLength (lump - ML_NODES + ML_SSECTORS) / sizeof(mapsubsector_t); + numnodes = lumplen / sizeof(mapnode_t); if ((numnodes == 0 && maxss != 1) || maxss == 0) { @@ -891,11 +1105,12 @@ void P_LoadNodes (int lump) } nodes = new node_t[numnodes]; - data = Wads.ReadLump (lump); used = (WORD *)alloca (sizeof(WORD)*numnodes); memset (used, 0, sizeof(WORD)*numnodes); - mn = (mapnode_t *)data.GetMem(); + mnp = new char[lumplen]; + mn = (mapnode_t*)mnp; + map->Read(ML_NODES, mn); no = nodes; for (i = 0; i < numnodes; i++, no++, mn++) @@ -916,6 +1131,7 @@ void P_LoadNodes (int lump) "The BSP will be rebuilt.\n", i, child); ForceNodeBuild = true; delete[] nodes; + delete[] mnp; return; } no->children[j] = (BYTE *)&subsectors[child] + 1; @@ -926,6 +1142,7 @@ void P_LoadNodes (int lump) "The BSP will be rebuilt.\n", i, (node_t *)no->children[j] - nodes); ForceNodeBuild = true; delete[] nodes; + delete[] mnp; return; } else if (used[child]) @@ -935,6 +1152,7 @@ void P_LoadNodes (int lump) "The BSP will be rebuilt.\n", i, child, used[child]-1); ForceNodeBuild = true; delete[] nodes; + delete[] mnp; return; } else @@ -948,23 +1166,33 @@ void P_LoadNodes (int lump) } } } + delete[] mnp; } +//=========================================================================== // // P_LoadThings // -void P_LoadThings (int lump, int position) +//=========================================================================== + +void P_LoadThings (MapData * map, int position) { mapthing2_t mt2; // [RH] for translation - FMemLump data = Wads.ReadLump (lump); - const mapthing_t *mt = (mapthing_t *)data.GetMem(); - const mapthing_t *lastmt = (mapthing_t *)((BYTE*)data.GetMem() + Wads.LumpLength (lump)); + int lumplen = map->Size(ML_THINGS); + int numthings = lumplen / sizeof(mapthing_t); + + char *mtp; + mapthing_t *mt; + + mtp = new char[lumplen]; + map->Read(ML_THINGS, mtp); + mt = (mapthing_t*)mtp; // [RH] ZDoom now uses Hexen-style maps as its native format. // Since this is the only place where Doom-style Things are ever // referenced, we translate them into a Hexen-style thing. - for ( ; mt < lastmt; mt++) + for (int i=0 ; i < numthings; i++, mt++) { // [RH] At this point, monsters unique to Doom II were weeded out // if the IWAD wasn't for Doom II. R_SpawnMapThing() can now @@ -1004,11 +1232,14 @@ void P_LoadThings (int lump, int position) P_SpawnMapThing (&mt2, position); } + delete [] mtp; } +//=========================================================================== // // P_SpawnSlopeMakers // +//=========================================================================== static void P_SlopeLineToPoint (int lineid, fixed_t x, fixed_t y, fixed_t z, BOOL slopeCeil) { @@ -1080,6 +1311,12 @@ static void P_SlopeLineToPoint (int lineid, fixed_t x, fixed_t y, fixed_t z, BOO } } +//=========================================================================== +// +// P_CopyPlane +// +//=========================================================================== + static void P_CopyPlane (int tag, fixed_t x, fixed_t y, BOOL copyCeil) { sector_t *dest = R_PointInSubsector (x, y)->sector; @@ -1106,6 +1343,12 @@ static void P_CopyPlane (int tag, fixed_t x, fixed_t y, BOOL copyCeil) *(secplane_t *)((BYTE *)dest + planeofs) = *(secplane_t *)((BYTE *)source + planeofs); } +//=========================================================================== +// +// P_SetSlope +// +//=========================================================================== + void P_SetSlope (secplane_t *plane, BOOL setCeil, int xyangi, int zangi, fixed_t x, fixed_t y, fixed_t z) { @@ -1149,10 +1392,12 @@ void P_SetSlope (secplane_t *plane, BOOL setCeil, int xyangi, int zangi, } -//----------------------------------------------------------------------------- +//=========================================================================== // +// P_VavoomSlope // -//----------------------------------------------------------------------------- +//=========================================================================== + void P_VavoomSlope(sector_t * sec, int id, fixed_t x, fixed_t y, fixed_t z, int which) { for (int i=0;ilinecount;i++) @@ -1215,10 +1460,12 @@ enum THING_VavoomCeiling=1501, }; -//----------------------------------------------------------------------------- +//=========================================================================== // +// P_SpawnSlopeMakers // -//----------------------------------------------------------------------------- +//=========================================================================== + static void P_SpawnSlopeMakers (mapthing2_t *firstmt, mapthing2_t *lastmt) { mapthing2_t *mt; @@ -1272,6 +1519,8 @@ static void P_SpawnSlopeMakers (mapthing2_t *firstmt, mapthing2_t *lastmt) } } +//=========================================================================== +// // [RH] // P_LoadThings2 // @@ -1280,15 +1529,22 @@ static void P_SpawnSlopeMakers (mapthing2_t *firstmt, mapthing2_t *lastmt) // player start spots are spawned by filtering out those // whose first parameter don't match position. // -void P_LoadThings2 (int lump, int position) +//=========================================================================== + +void P_LoadThings2 (MapData * map, int position) { - FMemLump data = Wads.ReadLump (lump); + int lumplen = map->MapLumps[ML_THINGS].Size; + int numthings = lumplen / sizeof(mapthing2_t); + + int i; + char *mtp; mapthing2_t *mt; - mapthing2_t *firstmt = (mapthing2_t *)data.GetMem(); - mapthing2_t *lastmt = (mapthing2_t *)((BYTE *)firstmt + Wads.LumpLength (lump)); + + mtp = new char[lumplen]; + map->Read(ML_THINGS, mtp); #ifdef WORDS_BIGENDIAN - for (mt = firstmt; mt < lastmt; ++mt) + for (i=0, mt = (mapthing2_t*)mtp; i < numthings; i++,mt++) { mt->thingid = LittleShort(mt->thingid); mt->x = LittleShort(mt->x); @@ -1301,15 +1557,17 @@ void P_LoadThings2 (int lump, int position) #endif // [RH] Spawn slope creating things first. - P_SpawnSlopeMakers (firstmt, lastmt); + P_SpawnSlopeMakers ((mapthing2_t*)mtp, ((mapthing2_t*)mtp)+numthings); - for (mt = firstmt; mt < lastmt; mt++) + for (i=0, mt = (mapthing2_t*)mtp; i < numthings; i++,mt++) { P_SpawnMapThing (mt, position); } + delete[] mtp; } +//=========================================================================== // // P_LoadLineDefs // @@ -1317,6 +1575,9 @@ void P_LoadThings2 (int lump, int position) // // [RH] Actually split into four functions to allow for Hexen and Doom // linedefs. +// +//=========================================================================== + void P_AdjustLine (line_t *ld) { vertex_t *v1, *v2; @@ -1359,7 +1620,7 @@ void P_AdjustLine (line_t *ld) // [RH] Set line id (as appropriate) here // for Doom format maps this must be done in P_TranslateLineDef because // the tag doesn't always go into the first arg. - if (HasBehavior) + if (level.flags & LEVEL_HEXENFORMAT) { if (ld->special == Line_SetIdentification) { @@ -1479,17 +1740,21 @@ void P_FinishLoadingLineDefs () } } -void P_LoadLineDefs (int lump) +void P_LoadLineDefs (MapData * map) { - FMemLump data; int i, skipped; line_t *ld; + int lumplen = map->Size(ML_LINEDEFS); + char * mldf; + maplinedef_t *mld; - numlines = Wads.LumpLength (lump) / sizeof(maplinedef_t); + numlines = lumplen / sizeof(maplinedef_t); lines = new line_t[numlines]; linemap = new WORD[numlines]; memset (lines, 0, numlines*sizeof(line_t)); - data = Wads.ReadLump (lump); + + mldf = new char[lumplen]; + map->Read(ML_LINEDEFS, mldf); // [RH] Count the number of sidedef references. This is the number of // sidedefs we need. The actual number in the SIDEDEFS lump might be less. @@ -1497,12 +1762,13 @@ void P_LoadLineDefs (int lump) for (skipped = sidecount = i = 0; i < numlines; ) { - maplinedef_t *mld = ((maplinedef_t *)data.GetMem()) + i; + mld = ((maplinedef_t*)mldf) + i; int v1 = LittleShort(mld->v1); int v2 = LittleShort(mld->v2); if (v1 >= numvertexes || v2 >= numvertexes) { + delete [] mldf; I_Error ("Line %d has invalid vertices: %d and/or %d.\nThe map only contains %d vertices.", i+skipped, v1, v2, numvertexes); } else if (v1 == v2 || @@ -1528,7 +1794,7 @@ void P_LoadLineDefs (int lump) P_AllocateSideDefs (sidecount); - maplinedef_t *mld = (maplinedef_t *)data.GetMem(); + mld = (maplinedef_t *)mldf; ld = lines; for (i = numlines; i > 0; i--, mld++, ld++) { @@ -1550,26 +1816,30 @@ void P_LoadLineDefs (int lump) if (level.flags & LEVEL_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX; if (level.flags & LEVEL_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX; } + delete[] mldf; } // [RH] Same as P_LoadLineDefs() except it uses Hexen-style LineDefs. -void P_LoadLineDefs2 (int lump) +void P_LoadLineDefs2 (MapData * map) { - FMemLump data; - int i, skipped; - maplinedef2_t* mld; - line_t* ld; - - numlines = Wads.LumpLength (lump) / sizeof(maplinedef2_t); + int i, skipped; + line_t *ld; + int lumplen = map->Size(ML_LINEDEFS); + char * mldf; + maplinedef2_t *mld; + + numlines = lumplen / sizeof(maplinedef2_t); lines = new line_t[numlines]; linemap = new WORD[numlines]; memset (lines, 0, numlines*sizeof(line_t)); - data = Wads.ReadLump (lump); + + mldf = new char[lumplen]; + map->Read(ML_LINEDEFS, mldf); // [RH] Remove any lines that have 0 length and count sidedefs used for (skipped = sidecount = i = 0; i < numlines; ) { - maplinedef2_t *mld = ((maplinedef2_t *)data.GetMem()) + i; + mld = ((maplinedef2_t*)mldf) + i; if (mld->v1 == mld->v2 || (vertexes[LittleShort(mld->v1)].x == vertexes[LittleShort(mld->v2)].x && @@ -1597,7 +1867,7 @@ void P_LoadLineDefs2 (int lump) P_AllocateSideDefs (sidecount); - mld = (maplinedef2_t *)data.GetMem(); + mld = (maplinedef2_t *)mldf; ld = lines; for (i = numlines; i > 0; i--, mld++, ld++) { @@ -1622,6 +1892,7 @@ void P_LoadLineDefs2 (int lump) if (level.flags & LEVEL_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX; if (level.flags & LEVEL_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX; } + delete[] mldf; } @@ -1629,9 +1900,9 @@ void P_LoadLineDefs2 (int lump) // P_LoadSideDefs // // killough 4/4/98: split into two functions -void P_LoadSideDefs (int lump) +void P_LoadSideDefs (MapData * map) { - numsides = Wads.LumpLength (lump) / sizeof(mapsidedef_t); + numsides = map->Size(ML_SIDEDEFS) / sizeof(mapsidedef_t); } static void P_AllocateSideDefs (int count) @@ -1794,17 +2065,19 @@ static void P_LoopSidedefs () // after linedefs are loaded, to allow overloading. // killough 5/3/98: reformatted, cleaned up -void P_LoadSideDefs2 (int lump) +void P_LoadSideDefs2 (MapData * map) { - char name[9]; - FMemLump data = Wads.ReadLump (lump); int i; + char name[9]; + mapsidedef_t * msdf = new mapsidedef_t[numsides+1]; + + map->Read(ML_SIDEDEFS, msdf); name[8] = 0; for (i = 0; i < numsides; i++) { - mapsidedef_t *msd = (mapsidedef_t *)data.GetMem() + sidetemp[i].a.map; + mapsidedef_t *msd = msdf + sidetemp[i].a.map; side_t *sd = sides + i; sector_t *sec; @@ -1908,6 +2181,7 @@ void P_LoadSideDefs2 (int lump) break; } } + delete[] msdf; } // [RH] Set slopes for sectors, based on line specials @@ -2322,23 +2596,26 @@ static void P_CreateBlockMap () // killough 3/30/98: Rewritten to remove blockmap limit // -void P_LoadBlockMap (int lump) +void P_LoadBlockMap (MapData * map) { - int count; + int count = map->Size(ML_BLOCKMAP); if (ForceNodeBuild || genblockmap || - (count = Wads.LumpLength(lump)/2) >= 0x10000 || - Args.CheckParm("-blockmap") || - Wads.LumpLength (lump) == 0) + count/2 >= 0x10000 || count == 0 || + Args.CheckParm("-blockmap") + ) { DPrintf ("Generating BLOCKMAP\n"); P_CreateBlockMap (); } else { - FMemLump lumpy = Wads.ReadLump (lump); - const short *wadblockmaplump = (short *)lumpy.GetMem(); + byte * data = new byte[count]; + map->Read(ML_BLOCKMAP, data); + const short *wadblockmaplump = (short *)data; int i; + + count/=2; blockmaplump = new int[count]; // killough 3/1/98: Expand wad blockmap into larger internal one, @@ -2356,6 +2633,7 @@ void P_LoadBlockMap (int lump) short t = LittleShort(wadblockmaplump[i]); // killough 3/1/98 blockmaplump[i] = t == -1 ? (DWORD)0xffffffff : (DWORD) t & 0xffff; } + delete[] data; } bmaporgx = blockmaplump[0]<> 3; int rejectsize; - Wads.GetLumpName (lname, lump); - if (strcmp (lname, "REJECT") != 0) + if (strnicmp (map->MapLumps[ML_REJECT].Name, "REJECT", 8) != 0) { rejectsize = 0; } else { - rejectsize = junk ? 0 : Wads.LumpLength (lump); + rejectsize = junk ? 0 : map->Size(ML_REJECT); } if (rejectsize < neededsize) @@ -2741,8 +3017,8 @@ void P_LoadReject (int lump, bool junk) rejectsize = MIN (rejectsize, neededsize); rejectmatrix = new BYTE[rejectsize]; - FWadLump reader = Wads.OpenLumpNum (lump); - reader.Read (rejectmatrix, rejectsize); + map->Seek(ML_REJECT); + map->file->Read (rejectmatrix, rejectsize); int qwords = rejectsize / 8; int i; @@ -2775,9 +3051,10 @@ void P_LoadReject (int lump, bool junk) // // [RH] P_LoadBehavior // -void P_LoadBehavior (int lumpnum) +void P_LoadBehavior (MapData * map) { - FBehavior::StaticLoadModule (lumpnum); + map->Seek(ML_BEHAVIOR); + FBehavior::StaticLoadModule (-1, map->file, map->Size(ML_BEHAVIOR)); if (!FBehavior::StaticCheckAllGood ()) { Printf ("ACS scripts unloaded.\n"); @@ -2811,14 +3088,20 @@ static void P_InitTagLists () } } -void P_GetPolySpots (int lump, TArray &spots, TArray &anchors) +void P_GetPolySpots (MapData * map, TArray &spots, TArray &anchors) { - if (HasBehavior) + if (map->HasBehavior) { int spot1, spot2, spot3, anchor; - FMemLump lumpy = Wads.ReadLump (lump); - const mapthing2_t *mt = (mapthing2_t *)lumpy.GetMem(); - int num = Wads.LumpLength (lump) / sizeof(*mt); + + int lumplen = map->Size(ML_THINGS); + int num = lumplen / sizeof(mapthing2_t); + + mapthing2_t *mt; + + map->Seek(ML_THINGS); + mt = new mapthing2_t[num]; + map->file->Read(mt, num * sizeof(mapthing2_t)); if (gameinfo.gametype == GAME_Hexen) { @@ -2852,6 +3135,7 @@ void P_GetPolySpots (int lump, TArray &spots, TArraylumpnum; // [RH] Support loading Build maps (because I felt like it. :-) buildmap = false; - if (Wads.LumpLength (lumpnum) > 0) + if (map->MapLumps[0].Size > 0) { - BYTE *mapdata = new BYTE[Wads.LumpLength (lumpnum)]; - Wads.ReadLump (lumpnum, mapdata); - buildmap = P_LoadBuildMap (mapdata, Wads.LumpLength (lumpnum), &buildthings, &numbuildthings); + BYTE *mapdata = new BYTE[map->MapLumps[0].Size]; + map->file->Read(mapdata, map->MapLumps[0].Size); + buildmap = P_LoadBuildMap (mapdata, map->MapLumps[0].Size, &buildthings, &numbuildthings); delete[] mapdata; } if (!buildmap) { - char lname[9]; - - // [RH] Check if this map is Hexen-style. - // LINEDEFS and THINGS need to be handled accordingly. - HasBehavior = Wads.CheckLumpName (lumpnum+ML_BEHAVIOR, "BEHAVIOR"); - // note: most of this ordering is important - ForceNodeBuild = gennodes; // [RH] Load in the BEHAVIOR lump FBehavior::StaticUnloadModules (); - if (HasBehavior) + if (map->HasBehavior) { - P_LoadBehavior (lumpnum+ML_BEHAVIOR); + P_LoadBehavior (map); level.flags |= LEVEL_HEXENFORMAT; } else @@ -3104,36 +3387,27 @@ void P_SetupLevel (char *lumpname, int position) P_LoadStrifeConversations (lumpname); clock (times[0]); - P_LoadVertexes (lumpnum+ML_VERTEXES); + P_LoadVertexes (map); unclock (times[0]); // Check for maps without any BSP data at all (e.g. SLIGE) clock (times[1]); - Wads.GetLumpName (lname, lumpnum+ML_SEGS); - if (strcmp (lname, "SECTORS") == 0) - { - P_LoadSectors (lumpnum+ML_SEGS); - ForceNodeBuild = true; - } - else - { - P_LoadSectors (lumpnum+ML_SECTORS); - } + P_LoadSectors (map); unclock (times[1]); clock (times[2]); - P_LoadSideDefs (lumpnum+ML_SIDEDEFS); + P_LoadSideDefs (map); unclock (times[2]); clock (times[3]); - if (!HasBehavior) - P_LoadLineDefs (lumpnum+ML_LINEDEFS); + if (!map->HasBehavior) + P_LoadLineDefs (map); else - P_LoadLineDefs2 (lumpnum+ML_LINEDEFS); // [RH] Load Hexen-style linedefs + P_LoadLineDefs2 (map); // [RH] Load Hexen-style linedefs unclock (times[3]); clock (times[4]); - P_LoadSideDefs2 (lumpnum+ML_SIDEDEFS); + P_LoadSideDefs2 (map); unclock (times[4]); clock (times[5]); @@ -3159,24 +3433,24 @@ void P_SetupLevel (char *lumpname, int position) FWadLump test; DWORD id = MAKE_ID('X','x','X','x'), idcheck; - if (Wads.LumpLength (lumpnum + ML_ZNODES) != 0) + if (map->MapLumps[ML_ZNODES].Size != 0) { - test = Wads.OpenLumpNum (lumpnum + ML_ZNODES); + map->Seek(ML_ZNODES); idcheck = MAKE_ID('Z','N','O','D'); } else { // If normal nodes are not present but GL nodes are, use them. - test = Wads.OpenLumpNum (lumpnum + ML_GLZNODES); + map->Seek(ML_GLZNODES); idcheck = MAKE_ID('Z','G','L','N'); } - test.Read (&id, 4); + map->file->Read (&id, 4); if (id == idcheck) { try { - P_LoadZNodes (test, id); + P_LoadZNodes (*map->file, id); } catch (CRecoverableError &error) { @@ -3203,15 +3477,15 @@ void P_SetupLevel (char *lumpname, int position) else { clock (times[7]); - P_LoadSubsectors (lumpnum+ML_SSECTORS); + P_LoadSubsectors (map); unclock (times[7]); clock (times[8]); - if (!ForceNodeBuild) P_LoadNodes (lumpnum+ML_NODES); + if (!ForceNodeBuild) P_LoadNodes (map); unclock (times[8]); clock (times[9]); - if (!ForceNodeBuild) P_LoadSegs (lumpnum+ML_SEGS); + if (!ForceNodeBuild) P_LoadSegs (map); unclock (times[9]); } @@ -3237,7 +3511,7 @@ void P_SetupLevel (char *lumpname, int position) startTime = I_MSTime (); TArray polyspots, anchors; - P_GetPolySpots (lumpnum+ML_THINGS, polyspots, anchors); + P_GetPolySpots (map, polyspots, anchors); FNodeBuilder::FLevel leveldata = { vertexes, numvertexes, @@ -3257,11 +3531,11 @@ void P_SetupLevel (char *lumpname, int position) } clock (times[10]); - P_LoadBlockMap (lumpnum+ML_BLOCKMAP); + P_LoadBlockMap (map); unclock (times[10]); clock (times[11]); - P_LoadReject (lumpnum+ML_REJECT, buildmap); + P_LoadReject (map, buildmap); unclock (times[11]); clock (times[12]); @@ -3284,10 +3558,10 @@ void P_SetupLevel (char *lumpname, int position) if (!buildmap) { clock (times[14]); - if (!HasBehavior) - P_LoadThings (lumpnum+ML_THINGS, position); + if (!map->HasBehavior) + P_LoadThings (map, position); else - P_LoadThings2 (lumpnum+ML_THINGS, position); // [RH] Load Hexen-style things + P_LoadThings2 (map, position); // [RH] Load Hexen-style things for (i = 0; i < MAXPLAYERS; ++i) { if (playeringame[i] && players[i].mo != NULL) @@ -3296,7 +3570,7 @@ void P_SetupLevel (char *lumpname, int position) unclock (times[14]); clock (times[15]); - if (!HasBehavior) + if (!map->HasBehavior) P_TranslateTeleportThings (); // [RH] Assign teleport destination TIDs unclock (times[15]); } @@ -3308,6 +3582,7 @@ void P_SetupLevel (char *lumpname, int position) } delete[] buildthings; } + delete map; clock (times[16]); PO_Init (); // Initialize the polyobjs diff --git a/src/p_setup.h b/src/p_setup.h index 83b3da1e2..ceee29f87 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -23,8 +23,63 @@ #ifndef __P_SETUP__ #define __P_SETUP__ +#include "w_wad.h" +#include "files.h" +#include "doomdata.h" +struct MapData +{ + wadlump_t MapLumps[ML_BEHAVIOR+1]; + bool HasBehavior; + bool CloseOnDestruct; + int lumpnum; + FileReader * file; + + MapData() + { + memset(MapLumps, 0, sizeof(MapLumps)); + file = NULL; + lumpnum=-1; + HasBehavior=false; + CloseOnDestruct=true; + } + + ~MapData() + { + if (CloseOnDestruct && file != NULL) delete file; + file = NULL; + } + + void Seek(int lumpindex) + { + if (lumpindex>=0 && lumpindexSeek(MapLumps[lumpindex].FilePos, SEEK_SET); + } + } + + void Read(int lumpindex, void * buffer) + { + if (lumpindex>=0 && lumpindexSeek(MapLumps[lumpindex].FilePos, SEEK_SET); + file->Read(buffer, MapLumps[lumpindex].Size); + } + } + + DWORD Size(int lumpindex) + { + if (lumpindex>=0 && lumpindex= NumLumps) { - I_Error ("W_LumpLength: %i >= NumLumps",lump); + I_Error ("GetLumpOffset: %i >= NumLumps",lump); } return LumpInfo[lump].position; @@ -1751,6 +1753,23 @@ FWadLump *FWadCollection::ReopenLumpNum (int lump) } +//========================================================================== +// +// GetFileReader +// +// Retrieves the FileReader object to access the given WAD +// +//========================================================================== + +FileReader *FWadCollection::GetFileReader(int wadnum) +{ + if ((DWORD)wadnum >= NumWads) + { + return NULL; + } + return Wads[wadnum]; +} + //========================================================================== // // W_GetWadName diff --git a/src/w_wad.h b/src/w_wad.h index 3e21308d0..8e3c7a348 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -171,7 +171,9 @@ public: FWadLump OpenLumpNum (int lump); FWadLump OpenLumpName (const char *name) { return OpenLumpNum (GetNumForName (name)); } - FWadLump *ReopenLumpNum (int lump); // Opens a new, independant FILE + FWadLump *ReopenLumpNum (int lump); // Opens a new, independent FILE + + FileReader * GetFileReader(int wadnum); // Gets a FileReader object to the entire WAD int FindLump (const char *name, int *lastlump, bool anyns=false); // [RH] Find lumps with duplication bool CheckLumpName (int lump, const char *name); // [RH] True if lump's name == name