mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 12:11:25 +00:00
- 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. - 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. SVN r188 (trunk)
This commit is contained in:
parent
2a0216cf6f
commit
fd79fac52c
11 changed files with 648 additions and 195 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <map file>\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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
|
|
617
src/p_setup.cpp
617
src/p_setup.cpp
File diff suppressed because it is too large
Load diff
|
@ -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 && lumpindex<countof(MapLumps))
|
||||
{
|
||||
file->Seek(MapLumps[lumpindex].FilePos, SEEK_SET);
|
||||
}
|
||||
}
|
||||
|
||||
void Read(int lumpindex, void * buffer)
|
||||
{
|
||||
if (lumpindex>=0 && lumpindex<countof(MapLumps))
|
||||
{
|
||||
file->Seek(MapLumps[lumpindex].FilePos, SEEK_SET);
|
||||
file->Read(buffer, MapLumps[lumpindex].Size);
|
||||
}
|
||||
}
|
||||
|
||||
DWORD Size(int lumpindex)
|
||||
{
|
||||
if (lumpindex>=0 && lumpindex<countof(MapLumps))
|
||||
{
|
||||
return MapLumps[lumpindex].Size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
MapData * P_OpenMapData(const char * mapname);
|
||||
|
||||
// NOT called by W_Ticker. Fixme. [RH] Is that bad?
|
||||
//
|
||||
// [RH] The only parameter used is mapname, so I removed playermask and skill.
|
||||
|
|
|
@ -569,10 +569,12 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
|
|||
FixPathSeperator(name);
|
||||
strlwr(name);
|
||||
|
||||
// Check for embedded WADs. They must be extracted and added separately to the lump list.
|
||||
// Check for embedded WADs in the root directory.
|
||||
// They must be extracted and added separately to the lump list.
|
||||
// WADs in subdirectories are added to the lump directory.
|
||||
// Embedded .zips are ignored for now. But they should be allowed later!
|
||||
char * c = strstr(name, ".wad");
|
||||
if (c && strlen(c)==4)
|
||||
if (c && strlen(c)==4 && !strchr(name, '/'))
|
||||
{
|
||||
EmbeddedWADs.Push(zip_fh);
|
||||
skipped++;
|
||||
|
@ -969,7 +971,7 @@ int FWadCollection::GetLumpOffset (int lump) const
|
|||
{
|
||||
if ((size_t)lump >= 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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue