mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-18 10:31:42 +00:00
Merge branch 'FileManagement' into 'master'
File management - PK3 support. See merge request STJr/SRB2Internal!121
This commit is contained in:
commit
927e74e406
16 changed files with 997 additions and 332 deletions
12
src/d_main.c
12
src/d_main.c
|
@ -817,7 +817,7 @@ static void IdentifyVersion(void)
|
||||||
if (srb2wad1 == NULL && srb2wad2 == NULL)
|
if (srb2wad1 == NULL && srb2wad2 == NULL)
|
||||||
I_Error("No more free memory to look in %s", srb2waddir);
|
I_Error("No more free memory to look in %s", srb2waddir);
|
||||||
if (srb2wad1 != NULL)
|
if (srb2wad1 != NULL)
|
||||||
sprintf(srb2wad1, pandf, srb2waddir, "srb2.srb");
|
sprintf(srb2wad1, pandf, srb2waddir, "srb2.pk3");
|
||||||
if (srb2wad2 != NULL)
|
if (srb2wad2 != NULL)
|
||||||
sprintf(srb2wad2, pandf, srb2waddir, "srb2.wad");
|
sprintf(srb2wad2, pandf, srb2waddir, "srb2.wad");
|
||||||
|
|
||||||
|
@ -847,9 +847,6 @@ static void IdentifyVersion(void)
|
||||||
// Add the players
|
// Add the players
|
||||||
D_AddFile(va(pandf,srb2waddir, "player.dta"));
|
D_AddFile(va(pandf,srb2waddir, "player.dta"));
|
||||||
|
|
||||||
// Add the weapons
|
|
||||||
D_AddFile(va(pandf,srb2waddir,"rings.dta"));
|
|
||||||
|
|
||||||
#ifdef USE_PATCH_DTA
|
#ifdef USE_PATCH_DTA
|
||||||
// Add our crappy patches to fix our bugs
|
// Add our crappy patches to fix our bugs
|
||||||
D_AddFile(va(pandf,srb2waddir,"patch.dta"));
|
D_AddFile(va(pandf,srb2waddir,"patch.dta"));
|
||||||
|
@ -1137,16 +1134,15 @@ void D_SRB2Main(void)
|
||||||
//W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad
|
//W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad
|
||||||
//W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta
|
//W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta
|
||||||
//W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta
|
//W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta
|
||||||
//W_VerifyFileMD5(3, ASSET_HASH_RINGS_DTA); // rings.dta
|
|
||||||
#ifdef USE_PATCH_DTA
|
#ifdef USE_PATCH_DTA
|
||||||
W_VerifyFileMD5(4, ASSET_HASH_PATCH_DTA); // patch.dta
|
W_VerifyFileMD5(3, ASSET_HASH_PATCH_DTA); // patch.dta
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// don't check music.dta because people like to modify it, and it doesn't matter if they do
|
// don't check music.dta because people like to modify it, and it doesn't matter if they do
|
||||||
// ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.
|
// ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.
|
||||||
#endif //ifndef DEVELOP
|
#endif //ifndef DEVELOP
|
||||||
|
|
||||||
mainwads = 4; // there are 4 wads not to unload
|
mainwads = 3; // there are 3 wads not to unload
|
||||||
#ifdef USE_PATCH_DTA
|
#ifdef USE_PATCH_DTA
|
||||||
++mainwads; // patch.dta adds one more
|
++mainwads; // patch.dta adds one more
|
||||||
#endif
|
#endif
|
||||||
|
@ -1373,9 +1369,11 @@ void D_SRB2Main(void)
|
||||||
else if (!dedicated && M_MapLocked(pstartmap))
|
else if (!dedicated && M_MapLocked(pstartmap))
|
||||||
I_Error("You need to unlock this level before you can warp to it!\n");
|
I_Error("You need to unlock this level before you can warp to it!\n");
|
||||||
else
|
else
|
||||||
|
{
|
||||||
D_MapChange(pstartmap, gametype, ultimatemode, true, 0, false, false);
|
D_MapChange(pstartmap, gametype, ultimatemode, true, 0, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (M_CheckParm("-skipintro"))
|
else if (M_CheckParm("-skipintro"))
|
||||||
{
|
{
|
||||||
CON_ToggleOff();
|
CON_ToggleOff();
|
||||||
|
|
|
@ -1604,16 +1604,12 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
|
||||||
{
|
{
|
||||||
static char buf[2+MAX_WADPATH+1+4];
|
static char buf[2+MAX_WADPATH+1+4];
|
||||||
static char *buf_p = buf;
|
static char *buf_p = buf;
|
||||||
|
|
||||||
// The supplied data are assumed to be good.
|
// The supplied data are assumed to be good.
|
||||||
I_Assert(delay >= 0 && delay <= 2);
|
I_Assert(delay >= 0 && delay <= 2);
|
||||||
|
|
||||||
if (mapnum != -1)
|
if (mapnum != -1)
|
||||||
CV_SetValue(&cv_nextmap, mapnum);
|
CV_SetValue(&cv_nextmap, mapnum);
|
||||||
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d ultmode=%d resetplayers=%d delay=%d skipprecutscene=%d\n",
|
CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d ultmode=%d resetplayers=%d delay=%d skipprecutscene=%d\n",
|
||||||
mapnum, newgametype, pultmode, resetplayers, delay, skipprecutscene);
|
mapnum, newgametype, pultmode, resetplayers, delay, skipprecutscene);
|
||||||
|
|
||||||
if ((netgame || multiplayer) && !((gametype == newgametype) && (newgametype == GT_COOP)))
|
if ((netgame || multiplayer) && !((gametype == newgametype) && (newgametype == GT_COOP)))
|
||||||
FLS = false;
|
FLS = false;
|
||||||
|
|
||||||
|
@ -1621,9 +1617,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
|
||||||
{
|
{
|
||||||
UINT8 flags = 0;
|
UINT8 flags = 0;
|
||||||
const char *mapname = G_BuildMapName(mapnum);
|
const char *mapname = G_BuildMapName(mapnum);
|
||||||
|
|
||||||
I_Assert(W_CheckNumForName(mapname) != LUMPERROR);
|
I_Assert(W_CheckNumForName(mapname) != LUMPERROR);
|
||||||
|
|
||||||
buf_p = buf;
|
buf_p = buf;
|
||||||
if (pultmode)
|
if (pultmode)
|
||||||
flags |= 1;
|
flags |= 1;
|
||||||
|
@ -3243,6 +3237,8 @@ static void Command_ListWADS_f(void)
|
||||||
CONS_Printf("\x82 IWAD\x80: %s\n", tempname);
|
CONS_Printf("\x82 IWAD\x80: %s\n", tempname);
|
||||||
else if (i <= mainwads)
|
else if (i <= mainwads)
|
||||||
CONS_Printf("\x82 * %.2d\x80: %s\n", i, tempname);
|
CONS_Printf("\x82 * %.2d\x80: %s\n", i, tempname);
|
||||||
|
else if (!wadfiles[i]->important)
|
||||||
|
CONS_Printf("\x86 %.2d: %s\n", i, tempname);
|
||||||
else
|
else
|
||||||
CONS_Printf(" %.2d: %s\n", i, tempname);
|
CONS_Printf(" %.2d: %s\n", i, tempname);
|
||||||
}
|
}
|
||||||
|
|
|
@ -753,11 +753,10 @@ void Got_Filetxpak(void)
|
||||||
char *filename = file->filename;
|
char *filename = file->filename;
|
||||||
static INT32 filetime = 0;
|
static INT32 filetime = 0;
|
||||||
|
|
||||||
if (!(strcmp(filename, "srb2.srb")
|
if (!(strcmp(filename, "srb2.pk3")
|
||||||
&& strcmp(filename, "srb2.wad")
|
&& strcmp(filename, "srb2.wad")
|
||||||
&& strcmp(filename, "zones.dta")
|
&& strcmp(filename, "zones.dta")
|
||||||
&& strcmp(filename, "player.dta")
|
&& strcmp(filename, "player.dta")
|
||||||
&& strcmp(filename, "rings.dta")
|
|
||||||
&& strcmp(filename, "patch.dta")
|
&& strcmp(filename, "patch.dta")
|
||||||
&& strcmp(filename, "music.dta")
|
&& strcmp(filename, "music.dta")
|
||||||
))
|
))
|
||||||
|
|
|
@ -3346,10 +3346,16 @@ static void DEH_LoadDehackedFile(MYFILE *f)
|
||||||
if (gamestate == GS_TITLESCREEN)
|
if (gamestate == GS_TITLESCREEN)
|
||||||
{
|
{
|
||||||
if (introchanged)
|
if (introchanged)
|
||||||
|
{
|
||||||
|
menuactive = false;
|
||||||
COM_BufAddText("playintro");
|
COM_BufAddText("playintro");
|
||||||
|
}
|
||||||
else if (titlechanged)
|
else if (titlechanged)
|
||||||
|
{
|
||||||
|
menuactive = false;
|
||||||
COM_BufAddText("exitgame"); // Command_ExitGame_f() but delayed
|
COM_BufAddText("exitgame"); // Command_ExitGame_f() but delayed
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dbg_line = -1;
|
dbg_line = -1;
|
||||||
if (deh_num_warning)
|
if (deh_num_warning)
|
||||||
|
|
|
@ -441,7 +441,7 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||||
|
|
||||||
char exttable[NUM_EXT_TABLE][5] = {
|
char exttable[NUM_EXT_TABLE][5] = {
|
||||||
".txt", ".cfg", // exec
|
".txt", ".cfg", // exec
|
||||||
".wad", ".soc", ".lua"}; // addfile
|
".wad", ".pk3", ".soc", ".lua"}; // addfile
|
||||||
|
|
||||||
char filenamebuf[MAX_WADFILES][MAX_WADPATH];
|
char filenamebuf[MAX_WADFILES][MAX_WADPATH];
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ typedef enum
|
||||||
EXT_CFG,
|
EXT_CFG,
|
||||||
EXT_LOADSTART,
|
EXT_LOADSTART,
|
||||||
EXT_WAD = EXT_LOADSTART,
|
EXT_WAD = EXT_LOADSTART,
|
||||||
|
EXT_PK3,
|
||||||
EXT_SOC,
|
EXT_SOC,
|
||||||
EXT_LUA, // allowed even if not HAVE_BLUA so that we can yell on load attempt
|
EXT_LUA, // allowed even if not HAVE_BLUA so that we can yell on load attempt
|
||||||
NUM_EXT,
|
NUM_EXT,
|
||||||
|
|
|
@ -4740,6 +4740,7 @@ static void M_Addons(INT32 choice)
|
||||||
addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_STATIC);
|
addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_STATIC);
|
||||||
addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_STATIC);
|
addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_STATIC);
|
||||||
addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_STATIC);
|
addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_STATIC);
|
||||||
|
addonsp[EXT_PK3] = W_CachePatchName("M_FPK3", PU_STATIC);
|
||||||
addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_STATIC);
|
addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_STATIC);
|
||||||
addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_STATIC);
|
addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_STATIC);
|
||||||
addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_STATIC);
|
addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_STATIC);
|
||||||
|
@ -5155,6 +5156,7 @@ static void M_HandleAddons(INT32 choice)
|
||||||
// else intentional fallthrough
|
// else intentional fallthrough
|
||||||
case EXT_SOC:
|
case EXT_SOC:
|
||||||
case EXT_WAD:
|
case EXT_WAD:
|
||||||
|
case EXT_PK3:
|
||||||
COM_BufAddText(va("addfile %s%s", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
|
COM_BufAddText(va("addfile %s%s", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
|
||||||
addonsresponselimit = 5;
|
addonsresponselimit = 5;
|
||||||
break;
|
break;
|
||||||
|
|
382
src/p_setup.c
382
src/p_setup.c
|
@ -354,16 +354,13 @@ UINT32 P_GetScoreForGrade(INT16 map, UINT8 mare, UINT8 grade)
|
||||||
* \param lump VERTEXES lump number.
|
* \param lump VERTEXES lump number.
|
||||||
* \sa ML_VERTEXES
|
* \sa ML_VERTEXES
|
||||||
*/
|
*/
|
||||||
static inline void P_LoadVertexes(lumpnum_t lumpnum)
|
|
||||||
|
static inline void P_LoadRawVertexes(UINT8 *data, size_t i)
|
||||||
{
|
{
|
||||||
UINT8 *data;
|
|
||||||
size_t i;
|
|
||||||
mapvertex_t *ml;
|
mapvertex_t *ml;
|
||||||
vertex_t *li;
|
vertex_t *li;
|
||||||
|
|
||||||
// Determine number of lumps:
|
numvertexes = i / sizeof (mapvertex_t);
|
||||||
// total lump length / vertex record length.
|
|
||||||
numvertexes = W_LumpLength(lumpnum) / sizeof (mapvertex_t);
|
|
||||||
|
|
||||||
if (numvertexes <= 0)
|
if (numvertexes <= 0)
|
||||||
I_Error("Level has no vertices"); // instead of crashing
|
I_Error("Level has no vertices"); // instead of crashing
|
||||||
|
@ -371,9 +368,6 @@ static inline void P_LoadVertexes(lumpnum_t lumpnum)
|
||||||
// Allocate zone memory for buffer.
|
// Allocate zone memory for buffer.
|
||||||
vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL);
|
vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL);
|
||||||
|
|
||||||
// Load data into cache.
|
|
||||||
data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
|
|
||||||
ml = (mapvertex_t *)data;
|
ml = (mapvertex_t *)data;
|
||||||
li = vertexes;
|
li = vertexes;
|
||||||
|
|
||||||
|
@ -383,11 +377,16 @@ static inline void P_LoadVertexes(lumpnum_t lumpnum)
|
||||||
li->x = SHORT(ml->x)<<FRACBITS;
|
li->x = SHORT(ml->x)<<FRACBITS;
|
||||||
li->y = SHORT(ml->y)<<FRACBITS;
|
li->y = SHORT(ml->y)<<FRACBITS;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Free buffer memory.
|
static inline void P_LoadVertexes(lumpnum_t lumpnum)
|
||||||
|
{
|
||||||
|
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||||
|
P_LoadRawVertexes(data, W_LumpLength(lumpnum));
|
||||||
Z_Free(data);
|
Z_Free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Computes the line length in fracunits, the OpenGL render needs this
|
// Computes the line length in fracunits, the OpenGL render needs this
|
||||||
//
|
//
|
||||||
|
@ -427,20 +426,17 @@ static inline float P_SegLengthf(seg_t *seg)
|
||||||
* \param lump Lump number of the SEGS resource.
|
* \param lump Lump number of the SEGS resource.
|
||||||
* \sa ::ML_SEGS
|
* \sa ::ML_SEGS
|
||||||
*/
|
*/
|
||||||
static void P_LoadSegs(lumpnum_t lumpnum)
|
static void P_LoadRawSegs(UINT8 *data, size_t i)
|
||||||
{
|
{
|
||||||
UINT8 *data;
|
|
||||||
size_t i;
|
|
||||||
INT32 linedef, side;
|
INT32 linedef, side;
|
||||||
mapseg_t *ml;
|
mapseg_t *ml;
|
||||||
seg_t *li;
|
seg_t *li;
|
||||||
line_t *ldef;
|
line_t *ldef;
|
||||||
|
|
||||||
numsegs = W_LumpLength(lumpnum) / sizeof (mapseg_t);
|
numsegs = i / sizeof (mapseg_t);
|
||||||
if (numsegs <= 0)
|
if (numsegs <= 0)
|
||||||
I_Error("Level has no segs"); // instead of crashing
|
I_Error("Level has no segs"); // instead of crashing
|
||||||
segs = Z_Calloc(numsegs * sizeof (*segs), PU_LEVEL, NULL);
|
segs = Z_Calloc(numsegs * sizeof (*segs), PU_LEVEL, NULL);
|
||||||
data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
|
|
||||||
ml = (mapseg_t *)data;
|
ml = (mapseg_t *)data;
|
||||||
li = segs;
|
li = segs;
|
||||||
|
@ -476,27 +472,30 @@ static void P_LoadSegs(lumpnum_t lumpnum)
|
||||||
li->numlights = 0;
|
li->numlights = 0;
|
||||||
li->rlights = NULL;
|
li->rlights = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void P_LoadSegs(lumpnum_t lumpnum)
|
||||||
|
{
|
||||||
|
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||||
|
P_LoadRawSegs(data, W_LumpLength(lumpnum));
|
||||||
Z_Free(data);
|
Z_Free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Loads the SSECTORS resource from a level.
|
/** Loads the SSECTORS resource from a level.
|
||||||
*
|
*
|
||||||
* \param lump Lump number of the SSECTORS resource.
|
* \param lump Lump number of the SSECTORS resource.
|
||||||
* \sa ::ML_SSECTORS
|
* \sa ::ML_SSECTORS
|
||||||
*/
|
*/
|
||||||
static inline void P_LoadSubsectors(lumpnum_t lumpnum)
|
static inline void P_LoadRawSubsectors(void *data, size_t i)
|
||||||
{
|
{
|
||||||
void *data;
|
|
||||||
size_t i;
|
|
||||||
mapsubsector_t *ms;
|
mapsubsector_t *ms;
|
||||||
subsector_t *ss;
|
subsector_t *ss;
|
||||||
|
|
||||||
numsubsectors = W_LumpLength(lumpnum) / sizeof (mapsubsector_t);
|
numsubsectors = i / sizeof (mapsubsector_t);
|
||||||
if (numsubsectors <= 0)
|
if (numsubsectors <= 0)
|
||||||
I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)");
|
I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)");
|
||||||
ss = subsectors = Z_Calloc(numsubsectors * sizeof (*subsectors), PU_LEVEL, NULL);
|
ss = subsectors = Z_Calloc(numsubsectors * sizeof (*subsectors), PU_LEVEL, NULL);
|
||||||
data = W_CacheLumpNum(lumpnum,PU_STATIC);
|
|
||||||
|
|
||||||
ms = (mapsubsector_t *)data;
|
ms = (mapsubsector_t *)data;
|
||||||
|
|
||||||
|
@ -510,13 +509,14 @@ static inline void P_LoadSubsectors(lumpnum_t lumpnum)
|
||||||
#endif
|
#endif
|
||||||
ss->validcount = 0;
|
ss->validcount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Z_Free(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
static void P_LoadSubsectors(lumpnum_t lumpnum)
|
||||||
// P_LoadSectors
|
{
|
||||||
//
|
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||||
|
P_LoadRawSubsectors(data, W_LumpLength(lumpnum));
|
||||||
|
Z_Free(data);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// levelflats
|
// levelflats
|
||||||
|
@ -543,24 +543,21 @@ size_t P_PrecacheLevelFlats(void)
|
||||||
return flatmemory;
|
return flatmemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
// help function for P_LoadSectors, find a flat in the active wad files,
|
// Auxiliary function. Find a flat in the active wad files,
|
||||||
// allocate an id for it, and set the levelflat (to speedup search)
|
// allocate an id for it, and set the levelflat (to speedup search)
|
||||||
//
|
|
||||||
INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
|
INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
//
|
// Scan through the already found flats, break if it matches.
|
||||||
// first scan through the already found flats
|
|
||||||
//
|
|
||||||
for (i = 0; i < numlevelflats; i++, levelflat++)
|
for (i = 0; i < numlevelflats; i++, levelflat++)
|
||||||
if (strnicmp(levelflat->name,flatname,8)==0)
|
if (strnicmp(levelflat->name, flatname, 8) == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// that flat was already found in the level, return the id
|
// If there is no match, make room for a new flat.
|
||||||
if (i == numlevelflats)
|
if (i == numlevelflats)
|
||||||
{
|
{
|
||||||
// store the name
|
// Store the name.
|
||||||
strlcpy(levelflat->name, flatname, sizeof (levelflat->name));
|
strlcpy(levelflat->name, flatname, sizeof (levelflat->name));
|
||||||
strupr(levelflat->name);
|
strupr(levelflat->name);
|
||||||
|
|
||||||
|
@ -644,29 +641,31 @@ INT32 P_CheckLevelFlat(const char *flatname)
|
||||||
return (INT32)i;
|
return (INT32)i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_LoadSectors(lumpnum_t lumpnum)
|
// Sets up the ingame sectors structures.
|
||||||
|
// Lumpnum is the lumpnum of a SECTORS lump.
|
||||||
|
static void P_LoadRawSectors(UINT8 *data, size_t i)
|
||||||
{
|
{
|
||||||
UINT8 *data;
|
|
||||||
size_t i;
|
|
||||||
mapsector_t *ms;
|
mapsector_t *ms;
|
||||||
sector_t *ss;
|
sector_t *ss;
|
||||||
levelflat_t *foundflats;
|
levelflat_t *foundflats;
|
||||||
|
|
||||||
numsectors = W_LumpLength(lumpnum) / sizeof (mapsector_t);
|
// We count how many sectors we got.
|
||||||
|
numsectors = i / sizeof (mapsector_t);
|
||||||
if (numsectors <= 0)
|
if (numsectors <= 0)
|
||||||
I_Error("Level has no sectors");
|
I_Error("Level has no sectors");
|
||||||
|
|
||||||
|
// Allocate as much memory as we need into the global sectors table.
|
||||||
sectors = Z_Calloc(numsectors*sizeof (*sectors), PU_LEVEL, NULL);
|
sectors = Z_Calloc(numsectors*sizeof (*sectors), PU_LEVEL, NULL);
|
||||||
data = W_CacheLumpNum(lumpnum,PU_STATIC);
|
|
||||||
|
|
||||||
//Fab : FIXME: allocate for whatever number of flats
|
|
||||||
// 512 different flats per level should be plenty
|
|
||||||
|
|
||||||
|
// Allocate a big chunk of memory as big as our MAXLEVELFLATS limit.
|
||||||
|
//Fab : FIXME: allocate for whatever number of flats - 512 different flats per level should be plenty
|
||||||
foundflats = calloc(MAXLEVELFLATS, sizeof (*foundflats));
|
foundflats = calloc(MAXLEVELFLATS, sizeof (*foundflats));
|
||||||
if (foundflats == NULL)
|
if (foundflats == NULL)
|
||||||
I_Error("Ran out of memory while loading sectors\n");
|
I_Error("Ran out of memory while loading sectors\n");
|
||||||
|
|
||||||
numlevelflats = 0;
|
numlevelflats = 0;
|
||||||
|
|
||||||
|
// For each counted sector, copy the sector raw data from our cache pointer ms, to the global table pointer ss.
|
||||||
ms = (mapsector_t *)data;
|
ms = (mapsector_t *)data;
|
||||||
ss = sectors;
|
ss = sectors;
|
||||||
for (i = 0; i < numsectors; i++, ss++, ms++)
|
for (i = 0; i < numsectors; i++, ss++, ms++)
|
||||||
|
@ -674,9 +673,6 @@ static void P_LoadSectors(lumpnum_t lumpnum)
|
||||||
ss->floorheight = SHORT(ms->floorheight)<<FRACBITS;
|
ss->floorheight = SHORT(ms->floorheight)<<FRACBITS;
|
||||||
ss->ceilingheight = SHORT(ms->ceilingheight)<<FRACBITS;
|
ss->ceilingheight = SHORT(ms->ceilingheight)<<FRACBITS;
|
||||||
|
|
||||||
//
|
|
||||||
// flats
|
|
||||||
//
|
|
||||||
ss->floorpic = P_AddLevelFlat(ms->floorpic, foundflats);
|
ss->floorpic = P_AddLevelFlat(ms->floorpic, foundflats);
|
||||||
ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats);
|
ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats);
|
||||||
|
|
||||||
|
@ -741,8 +737,6 @@ static void P_LoadSectors(lumpnum_t lumpnum)
|
||||||
#endif // ----- end special tricks -----
|
#endif // ----- end special tricks -----
|
||||||
}
|
}
|
||||||
|
|
||||||
Z_Free(data);
|
|
||||||
|
|
||||||
// set the sky flat num
|
// set the sky flat num
|
||||||
skyflatnum = P_AddLevelFlat(SKYFLATNAME, foundflats);
|
skyflatnum = P_AddLevelFlat(SKYFLATNAME, foundflats);
|
||||||
|
|
||||||
|
@ -754,22 +748,26 @@ static void P_LoadSectors(lumpnum_t lumpnum)
|
||||||
P_SetupLevelFlatAnims();
|
P_SetupLevelFlatAnims();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void P_LoadSectors(lumpnum_t lumpnum)
|
||||||
|
{
|
||||||
|
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||||
|
P_LoadRawSectors(data, W_LumpLength(lumpnum));
|
||||||
|
Z_Free(data);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_LoadNodes
|
// P_LoadNodes
|
||||||
//
|
//
|
||||||
static void P_LoadNodes(lumpnum_t lumpnum)
|
static void P_LoadRawNodes(UINT8 *data, size_t i)
|
||||||
{
|
{
|
||||||
UINT8 *data;
|
|
||||||
size_t i;
|
|
||||||
UINT8 j, k;
|
UINT8 j, k;
|
||||||
mapnode_t *mn;
|
mapnode_t *mn;
|
||||||
node_t *no;
|
node_t *no;
|
||||||
|
|
||||||
numnodes = W_LumpLength(lumpnum) / sizeof (mapnode_t);
|
numnodes = i / sizeof (mapnode_t);
|
||||||
if (numnodes <= 0)
|
if (numnodes <= 0)
|
||||||
I_Error("Level has no nodes");
|
I_Error("Level has no nodes");
|
||||||
nodes = Z_Calloc(numnodes * sizeof (*nodes), PU_LEVEL, NULL);
|
nodes = Z_Calloc(numnodes * sizeof (*nodes), PU_LEVEL, NULL);
|
||||||
data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
|
|
||||||
mn = (mapnode_t *)data;
|
mn = (mapnode_t *)data;
|
||||||
no = nodes;
|
no = nodes;
|
||||||
|
@ -787,7 +785,12 @@ static void P_LoadNodes(lumpnum_t lumpnum)
|
||||||
no->bbox[j][k] = SHORT(mn->bbox[j][k])<<FRACBITS;
|
no->bbox[j][k] = SHORT(mn->bbox[j][k])<<FRACBITS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void P_LoadNodes(lumpnum_t lumpnum)
|
||||||
|
{
|
||||||
|
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||||
|
P_LoadRawNodes(data, W_LumpLength(lumpnum));
|
||||||
Z_Free(data);
|
Z_Free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -922,18 +925,16 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum)
|
||||||
//
|
//
|
||||||
// P_LoadThings
|
// P_LoadThings
|
||||||
//
|
//
|
||||||
static void P_PrepareThings(lumpnum_t lumpnum)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
mapthing_t *mt;
|
|
||||||
UINT8 *data, *datastart;
|
|
||||||
|
|
||||||
nummapthings = W_LumpLength(lumpnum) / (5 * sizeof (INT16));
|
static void P_PrepareRawThings(UINT8 *data, size_t i)
|
||||||
|
{
|
||||||
|
mapthing_t *mt;
|
||||||
|
|
||||||
|
nummapthings = i / (5 * sizeof (INT16));
|
||||||
mapthings = Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL);
|
mapthings = Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL);
|
||||||
|
|
||||||
// Spawn axis points first so they are
|
// Spawn axis points first so they are
|
||||||
// at the front of the list for fast searching.
|
// at the front of the list for fast searching.
|
||||||
data = datastart = W_CacheLumpNum(lumpnum, PU_LEVEL);
|
|
||||||
mt = mapthings;
|
mt = mapthings;
|
||||||
for (i = 0; i < nummapthings; i++, mt++)
|
for (i = 0; i < nummapthings; i++, mt++)
|
||||||
{
|
{
|
||||||
|
@ -958,8 +959,13 @@ static void P_PrepareThings(lumpnum_t lumpnum)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Z_Free(datastart);
|
}
|
||||||
|
|
||||||
|
static void P_PrepareThings(lumpnum_t lumpnum)
|
||||||
|
{
|
||||||
|
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||||
|
P_PrepareRawThings(data, W_LumpLength(lumpnum));
|
||||||
|
Z_Free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_LoadThings(void)
|
static void P_LoadThings(void)
|
||||||
|
@ -1159,22 +1165,16 @@ void P_WriteThings(lumpnum_t lumpnum)
|
||||||
CONS_Printf(M_GetText("newthings%d.lmp saved.\n"), gamemap);
|
CONS_Printf(M_GetText("newthings%d.lmp saved.\n"), gamemap);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
static void P_LoadRawLineDefs(UINT8 *data, size_t i)
|
||||||
// P_LoadLineDefs
|
|
||||||
//
|
|
||||||
static void P_LoadLineDefs(lumpnum_t lumpnum)
|
|
||||||
{
|
{
|
||||||
UINT8 *data;
|
|
||||||
size_t i;
|
|
||||||
maplinedef_t *mld;
|
maplinedef_t *mld;
|
||||||
line_t *ld;
|
line_t *ld;
|
||||||
vertex_t *v1, *v2;
|
vertex_t *v1, *v2;
|
||||||
|
|
||||||
numlines = W_LumpLength(lumpnum) / sizeof (maplinedef_t);
|
numlines = i / sizeof (maplinedef_t);
|
||||||
if (numlines <= 0)
|
if (numlines <= 0)
|
||||||
I_Error("Level has no linedefs");
|
I_Error("Level has no linedefs");
|
||||||
lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL);
|
lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL);
|
||||||
data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
|
|
||||||
mld = (maplinedef_t *)data;
|
mld = (maplinedef_t *)data;
|
||||||
ld = lines;
|
ld = lines;
|
||||||
|
@ -1236,7 +1236,7 @@ static void P_LoadLineDefs(lumpnum_t lumpnum)
|
||||||
if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides)
|
if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides)
|
||||||
{
|
{
|
||||||
ld->sidenum[j] = 0xffff;
|
ld->sidenum[j] = 0xffff;
|
||||||
CONS_Debug(DBG_SETUP, "P_LoadLineDefs: linedef %s has out-of-range sidedef number\n", sizeu1(numlines-i-1));
|
CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s has out-of-range sidedef number\n", sizeu1(numlines-i-1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1251,14 +1251,14 @@ static void P_LoadLineDefs(lumpnum_t lumpnum)
|
||||||
{
|
{
|
||||||
ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side
|
ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side
|
||||||
// cph - print a warning about the bug
|
// cph - print a warning about the bug
|
||||||
CONS_Debug(DBG_SETUP, "P_LoadLineDefs: linedef %s missing first sidedef\n", sizeu1(numlines-i-1));
|
CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s missing first sidedef\n", sizeu1(numlines-i-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED))
|
if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED))
|
||||||
{
|
{
|
||||||
ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side
|
ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side
|
||||||
// cph - print a warning about the bug
|
// cph - print a warning about the bug
|
||||||
CONS_Debug(DBG_SETUP, "P_LoadLineDefs: linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(numlines-i-1));
|
CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(numlines-i-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ld->sidenum[0] != 0xffff && ld->special)
|
if (ld->sidenum[0] != 0xffff && ld->special)
|
||||||
|
@ -1270,7 +1270,12 @@ static void P_LoadLineDefs(lumpnum_t lumpnum)
|
||||||
ld->polyobj = NULL;
|
ld->polyobj = NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void P_LoadLineDefs(lumpnum_t lumpnum)
|
||||||
|
{
|
||||||
|
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||||
|
P_LoadRawLineDefs(data, W_LumpLength(lumpnum));
|
||||||
Z_Free(data);
|
Z_Free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1372,22 +1377,24 @@ static void P_LoadLineDefs2(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// P_LoadSideDefs
|
|
||||||
//
|
static inline void P_LoadRawSideDefs(size_t i)
|
||||||
static inline void P_LoadSideDefs(lumpnum_t lumpnum)
|
|
||||||
{
|
{
|
||||||
numsides = W_LumpLength(lumpnum) / sizeof (mapsidedef_t);
|
numsides = i / sizeof (mapsidedef_t);
|
||||||
if (numsides <= 0)
|
if (numsides <= 0)
|
||||||
I_Error("Level has no sidedefs");
|
I_Error("Level has no sidedefs");
|
||||||
sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL);
|
sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delay loading texture names until after loaded linedefs.
|
static inline void P_LoadSideDefs(lumpnum_t lumpnum)
|
||||||
|
{
|
||||||
static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
P_LoadRawSideDefs(W_LumpLength(lumpnum));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void P_LoadRawSideDefs2(void *data)
|
||||||
{
|
{
|
||||||
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
|
||||||
UINT16 i;
|
UINT16 i;
|
||||||
INT32 num;
|
INT32 num;
|
||||||
|
|
||||||
|
@ -1405,7 +1412,7 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
||||||
|
|
||||||
if (sector_num >= numsectors)
|
if (sector_num >= numsectors)
|
||||||
{
|
{
|
||||||
CONS_Debug(DBG_SETUP, "P_LoadSideDefs2: sidedef %u has out-of-range sector num %u\n", i, sector_num);
|
CONS_Debug(DBG_SETUP, "P_LoadRawSideDefs2: sidedef %u has out-of-range sector num %u\n", i, sector_num);
|
||||||
sector_num = 0;
|
sector_num = 0;
|
||||||
}
|
}
|
||||||
sd->sector = sec = §ors[sector_num];
|
sd->sector = sec = §ors[sector_num];
|
||||||
|
@ -1619,11 +1626,18 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Z_Free(data);
|
|
||||||
R_ClearTextureNumCache(true);
|
R_ClearTextureNumCache(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delay loading texture names until after loaded linedefs.
|
||||||
|
static void P_LoadSideDefs2(lumpnum_t lumpnum)
|
||||||
|
{
|
||||||
|
UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC);
|
||||||
|
P_LoadRawSideDefs2(data);
|
||||||
|
Z_Free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static boolean LineInBlock(fixed_t cx1, fixed_t cy1, fixed_t cx2, fixed_t cy2, fixed_t bx1, fixed_t by1)
|
static boolean LineInBlock(fixed_t cx1, fixed_t cy1, fixed_t cx2, fixed_t cy2, fixed_t bx1, fixed_t by1)
|
||||||
{
|
{
|
||||||
fixed_t bbox[4];
|
fixed_t bbox[4];
|
||||||
|
@ -2297,6 +2311,7 @@ void P_LoadThingsOnly(void)
|
||||||
centerid = i; // save id just in case
|
centerid = i; // save id just in case
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (think = thinkercap.next; think != &thinkercap; think = think->next)
|
for (think = thinkercap.next; think != &thinkercap; think = think->next)
|
||||||
{
|
{
|
||||||
if (think->function.acp1 != (actionf_p1)P_MobjThinker)
|
if (think->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||||
|
@ -2313,10 +2328,10 @@ void P_LoadThingsOnly(void)
|
||||||
P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
|
P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
|
||||||
P_LoadThings();
|
P_LoadThings();
|
||||||
|
|
||||||
|
|
||||||
// restore skybox viewpoint/centerpoint if necessary, set them to defaults if we can't do that
|
// restore skybox viewpoint/centerpoint if necessary, set them to defaults if we can't do that
|
||||||
skyboxmo[0] = skyboxviewpnts[(viewid >= 0) ? viewid : 0];
|
skyboxmo[0] = skyboxviewpnts[(viewid >= 0) ? viewid : 0];
|
||||||
skyboxmo[1] = skyboxcenterpnts[(centerid >= 0) ? centerid : 0];
|
skyboxmo[1] = skyboxcenterpnts[(centerid >= 0) ? centerid : 0];
|
||||||
|
|
||||||
P_SpawnSecretItems(true);
|
P_SpawnSecretItems(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2566,6 +2581,7 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
// use gamemap to get map number.
|
// use gamemap to get map number.
|
||||||
// 99% of the things already did, so.
|
// 99% of the things already did, so.
|
||||||
// Map header should always be in place at this point
|
// Map header should always be in place at this point
|
||||||
|
char *lumpfullName;
|
||||||
INT32 i, loadprecip = 1, ranspecialwipe = 0;
|
INT32 i, loadprecip = 1, ranspecialwipe = 0;
|
||||||
INT32 loademblems = 1;
|
INT32 loademblems = 1;
|
||||||
INT32 fromnetsave = 0;
|
INT32 fromnetsave = 0;
|
||||||
|
@ -2728,7 +2744,12 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
}
|
}
|
||||||
|
|
||||||
// internal game map
|
// internal game map
|
||||||
lastloadedmaplumpnum = W_GetNumForName(maplumpname = G_BuildMapName(gamemap));
|
maplumpname = G_BuildMapName(gamemap);
|
||||||
|
//lastloadedmaplumpnum = LUMPERROR;
|
||||||
|
lastloadedmaplumpnum = W_CheckNumForName(maplumpname);
|
||||||
|
|
||||||
|
if (lastloadedmaplumpnum == INT16_MAX)
|
||||||
|
I_Error("Map %s not found.\n", maplumpname);
|
||||||
|
|
||||||
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette);
|
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette);
|
||||||
CON_SetupBackColormap();
|
CON_SetupBackColormap();
|
||||||
|
@ -2738,27 +2759,71 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
|
|
||||||
P_MakeMapMD5(lastloadedmaplumpnum, &mapmd5);
|
P_MakeMapMD5(lastloadedmaplumpnum, &mapmd5);
|
||||||
|
|
||||||
// note: most of this ordering is important
|
|
||||||
loadedbm = P_LoadBlockMap(lastloadedmaplumpnum + ML_BLOCKMAP);
|
|
||||||
|
|
||||||
P_LoadVertexes(lastloadedmaplumpnum + ML_VERTEXES);
|
// HACK ALERT: Cache the WAD, get the map data into the tables, free memory.
|
||||||
P_LoadSectors(lastloadedmaplumpnum + ML_SECTORS);
|
// As it is implemented right now, we're assuming an uncompressed WAD.
|
||||||
|
// (As in, a normal PWAD, not ZWAD or anything. The lump itself can be compressed.)
|
||||||
|
// We're not accounting for extra lumps and scrambled lump positions. Any additional data will cause an error.
|
||||||
|
lumpfullName = (wadfiles[WADFILENUM(lastloadedmaplumpnum)]->lumpinfo + LUMPNUM(lastloadedmaplumpnum))->name2;
|
||||||
|
if (!strnicmp(lumpfullName + strlen(lumpfullName) - 4, ".wad", 4))
|
||||||
|
{
|
||||||
|
// Remember that we're assuming that the WAD will have a specific set of lumps in a specific order.
|
||||||
|
UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC);
|
||||||
|
//filelump_t *fileinfo = wadData + ((wadinfo_t *)wadData)->infotableofs;
|
||||||
|
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
||||||
|
|
||||||
P_LoadSideDefs(lastloadedmaplumpnum + ML_SIDEDEFS);
|
P_LoadRawVertexes(wadData + (fileinfo + ML_VERTEXES)->filepos, (fileinfo + ML_VERTEXES)->size);
|
||||||
|
P_LoadRawSectors(wadData + (fileinfo + ML_SECTORS)->filepos, (fileinfo + ML_SECTORS)->size);
|
||||||
|
P_LoadRawSideDefs((fileinfo + ML_SIDEDEFS)->size);
|
||||||
|
P_LoadRawLineDefs(wadData + (fileinfo + ML_LINEDEFS)->filepos, (fileinfo + ML_LINEDEFS)->size);
|
||||||
|
P_LoadRawSideDefs2(wadData + (fileinfo + ML_SIDEDEFS)->filepos);
|
||||||
|
P_LoadRawSubsectors(wadData + (fileinfo + ML_SSECTORS)->filepos, (fileinfo + ML_SSECTORS)->size);
|
||||||
|
P_LoadRawNodes(wadData + (fileinfo + ML_NODES)->filepos, (fileinfo + ML_NODES)->size);
|
||||||
|
P_LoadRawSegs(wadData + (fileinfo + ML_SEGS)->filepos, (fileinfo + ML_SEGS)->size);
|
||||||
|
|
||||||
P_LoadLineDefs(lastloadedmaplumpnum + ML_LINEDEFS);
|
// Important: take care of the ordering of the next functions.
|
||||||
if (!loadedbm)
|
if (!loadedbm)
|
||||||
P_CreateBlockMap(); // Graue 02-29-2004
|
P_CreateBlockMap(); // Graue 02-29-2004
|
||||||
P_LoadSideDefs2(lastloadedmaplumpnum + ML_SIDEDEFS);
|
|
||||||
|
|
||||||
R_MakeColormaps();
|
R_MakeColormaps();
|
||||||
P_LoadLineDefs2();
|
P_LoadLineDefs2();
|
||||||
|
P_GroupLines();
|
||||||
|
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
||||||
|
|
||||||
|
// reset the player starts
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
playerstarts[i] = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
skyboxmo[i] = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL;
|
||||||
|
|
||||||
|
P_MapStart();
|
||||||
|
|
||||||
|
P_PrepareRawThings(wadData + (fileinfo + ML_THINGS)->filepos, (fileinfo + ML_THINGS)->size);
|
||||||
|
Z_Free(wadData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Important: take care of the ordering of the next functions.
|
||||||
|
loadedbm = P_LoadBlockMap(lastloadedmaplumpnum + ML_BLOCKMAP);
|
||||||
|
P_LoadVertexes(lastloadedmaplumpnum + ML_VERTEXES);
|
||||||
|
P_LoadSectors(lastloadedmaplumpnum + ML_SECTORS);
|
||||||
|
P_LoadSideDefs(lastloadedmaplumpnum + ML_SIDEDEFS);
|
||||||
|
P_LoadLineDefs(lastloadedmaplumpnum + ML_LINEDEFS);
|
||||||
|
P_LoadSideDefs2(lastloadedmaplumpnum + ML_SIDEDEFS);
|
||||||
P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS);
|
P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS);
|
||||||
P_LoadNodes(lastloadedmaplumpnum + ML_NODES);
|
P_LoadNodes(lastloadedmaplumpnum + ML_NODES);
|
||||||
P_LoadSegs(lastloadedmaplumpnum + ML_SEGS);
|
P_LoadSegs(lastloadedmaplumpnum + ML_SEGS);
|
||||||
P_LoadReject(lastloadedmaplumpnum + ML_REJECT);
|
P_LoadReject(lastloadedmaplumpnum + ML_REJECT);
|
||||||
P_GroupLines();
|
|
||||||
|
|
||||||
|
// Important: take care of the ordering of the next functions.
|
||||||
|
if (!loadedbm)
|
||||||
|
P_CreateBlockMap(); // Graue 02-29-2004
|
||||||
|
R_MakeColormaps();
|
||||||
|
P_LoadLineDefs2();
|
||||||
|
P_GroupLines();
|
||||||
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
||||||
|
|
||||||
// reset the player starts
|
// reset the player starts
|
||||||
|
@ -2774,6 +2839,7 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
P_MapStart();
|
P_MapStart();
|
||||||
|
|
||||||
P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
|
P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
|
||||||
|
}
|
||||||
|
|
||||||
// init gravity, tag lists,
|
// init gravity, tag lists,
|
||||||
// anything that P_ResetDynamicSlopes/P_LoadThings needs to know
|
// anything that P_ResetDynamicSlopes/P_LoadThings needs to know
|
||||||
|
@ -2784,7 +2850,6 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
P_LoadThings();
|
P_LoadThings();
|
||||||
// skybox mobj defaults
|
|
||||||
skyboxmo[0] = skyboxviewpnts[0];
|
skyboxmo[0] = skyboxviewpnts[0];
|
||||||
skyboxmo[1] = skyboxcenterpnts[0];
|
skyboxmo[1] = skyboxcenterpnts[0];
|
||||||
|
|
||||||
|
@ -3078,6 +3143,50 @@ boolean P_RunSOC(const char *socfilename)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Auxiliary function for PK3 loading - looks for sound replacements.
|
||||||
|
// NOTE: it does not really add any new sound entry or anything.
|
||||||
|
void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num)
|
||||||
|
{
|
||||||
|
size_t j;
|
||||||
|
lumpinfo_t *lumpinfo = wadfiles[wadnum]->lumpinfo + first;
|
||||||
|
for (; num > 0; num--, lumpinfo++)
|
||||||
|
{
|
||||||
|
// Let's check whether it's replacing an existing sound or it's a brand new one.
|
||||||
|
for (j = 1; j < NUMSFX; j++)
|
||||||
|
{
|
||||||
|
if (S_sfx[j].name && !strnicmp(S_sfx[j].name, lumpinfo->name + 2, 6))
|
||||||
|
{
|
||||||
|
// the sound will be reloaded when needed,
|
||||||
|
// since sfx->data will be NULL
|
||||||
|
CONS_Debug(DBG_SETUP, "Sound %.8s replaced\n", lumpinfo->name);
|
||||||
|
|
||||||
|
I_FreeSfx(&S_sfx[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auxiliary function for PK3 loading - looks for music and music replacements.
|
||||||
|
// NOTE: does nothing but print debug messages. The code is handled somewhere else.
|
||||||
|
void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num)
|
||||||
|
{
|
||||||
|
lumpinfo_t *lumpinfo = wadfiles[wadnum]->lumpinfo + first;
|
||||||
|
char *name;
|
||||||
|
for (; num > 0; num--, lumpinfo++)
|
||||||
|
{
|
||||||
|
name = lumpinfo->name;
|
||||||
|
if (name[0] == 'O' && name[1] == '_')
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name);
|
||||||
|
}
|
||||||
|
else if (name[0] == 'D' && name[1] == '_')
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Add a wadfile to the active wad files,
|
// Add a wadfile to the active wad files,
|
||||||
// replace sounds, musics, patches, textures, sprites and maps
|
// replace sounds, musics, patches, textures, sprites and maps
|
||||||
|
@ -3091,17 +3200,86 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
||||||
lumpinfo_t *lumpinfo;
|
lumpinfo_t *lumpinfo;
|
||||||
boolean replacedcurrentmap = false;
|
boolean replacedcurrentmap = false;
|
||||||
|
|
||||||
if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX)
|
// Vars to help us with the position start and amount of each resource type.
|
||||||
|
// Useful for PK3s since they use folders.
|
||||||
|
// WADs use markers for some resources, but others such as sounds are checked lump-by-lump anyway.
|
||||||
|
// UINT16 luaPos, luaNum = 0;
|
||||||
|
// UINT16 socPos, socNum = 0;
|
||||||
|
UINT16 sfxPos, sfxNum = 0;
|
||||||
|
UINT16 musPos = 0, musNum = 0;
|
||||||
|
// UINT16 sprPos, sprNum = 0;
|
||||||
|
UINT16 texPos, texNum = 0;
|
||||||
|
// UINT16 patPos, patNum = 0;
|
||||||
|
// UINT16 flaPos, flaNum = 0;
|
||||||
|
// UINT16 mapPos, mapNum = 0;
|
||||||
|
|
||||||
|
// Init file.
|
||||||
|
if ((numlumps = W_InitFile(wadfilename)) == INT16_MAX)
|
||||||
{
|
{
|
||||||
refreshdirmenu |= REFRESHDIR_NOTLOADED;
|
refreshdirmenu |= REFRESHDIR_NOTLOADED;
|
||||||
CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename);
|
CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else wadnum = (UINT16)(numwadfiles-1);
|
else
|
||||||
|
wadnum = (UINT16)(numwadfiles-1);
|
||||||
|
|
||||||
//
|
switch(wadfiles[wadnum]->type)
|
||||||
// search for sound replacements
|
{
|
||||||
//
|
case RET_PK3:
|
||||||
|
{
|
||||||
|
// Auxiliary function - input a folder name and gives us the resource markers positions.
|
||||||
|
void FindFolder(const char *folName, UINT16 *start, UINT16 *end)
|
||||||
|
{
|
||||||
|
if (!stricmp(lumpinfo->name2, folName))
|
||||||
|
{
|
||||||
|
lumpinfo++;
|
||||||
|
*start = ++i;
|
||||||
|
for (; i < numlumps; i++, lumpinfo++)
|
||||||
|
if (strnicmp(lumpinfo->name2, folName, strlen(folName)))
|
||||||
|
break;
|
||||||
|
lumpinfo--;
|
||||||
|
*end = i-- - *start;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for the lumps that act as resource delimitation markers.
|
||||||
|
lumpinfo = wadfiles[wadnum]->lumpinfo;
|
||||||
|
for (i = 0; i < numlumps; i++, lumpinfo++)
|
||||||
|
{
|
||||||
|
// FindFolder("Lua/", &luaPos, &luaNum);
|
||||||
|
// FindFolder("SOCs/", &socPos, &socNum);
|
||||||
|
FindFolder("Sounds/", &sfxPos, &sfxNum);
|
||||||
|
FindFolder("Music/", &musPos, &musNum);
|
||||||
|
// FindFolder("Sprites/", &sprPos, &sprNum);
|
||||||
|
FindFolder("Textures/", &texPos, &texNum);
|
||||||
|
// FindFolder("Patches/", &patPos, &patNum);
|
||||||
|
// FindFolder("Flats/", &flaPos, &flaNum);
|
||||||
|
// FindFolder("Maps/", &mapPos, &mapNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the detected resources.
|
||||||
|
// Note: ALWAYS load Lua scripts first, SOCs right after, and the remaining resources afterwards.
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
// if (luaNum) // Lua scripts.
|
||||||
|
// P_LoadLuaScrRange(wadnum, luaPos, luaNum);
|
||||||
|
#endif
|
||||||
|
// if (socNum) // SOCs.
|
||||||
|
// P_LoadDehackRange(wadnum, socPos, socNum);
|
||||||
|
if (sfxNum) // Sounds. TODO: Function currently only updates already existing sounds, the rest is handled somewhere else.
|
||||||
|
P_LoadSoundsRange(wadnum, sfxPos, sfxNum);
|
||||||
|
if (musNum) // Music. TODO: Useless function right now.
|
||||||
|
P_LoadMusicsRange(wadnum, musPos, musNum);
|
||||||
|
// if (sprNum) // Sprites.
|
||||||
|
// R_LoadSpritsRange(wadnum, sprPos, sprNum);
|
||||||
|
// if (texNum) // Textures. TODO: R_LoadTextures() does the folder positioning once again. New function maybe?
|
||||||
|
// R_LoadTextures();
|
||||||
|
// if (mapNum) // Maps. TODO: Actually implement the map WAD loading code, lulz.
|
||||||
|
// P_LoadWadMapRange(wadnum, mapPos, mapNum);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
lumpinfo = wadfiles[wadnum]->lumpinfo;
|
lumpinfo = wadfiles[wadnum]->lumpinfo;
|
||||||
for (i = 0; i < numlumps; i++, lumpinfo++)
|
for (i = 0; i < numlumps; i++, lumpinfo++)
|
||||||
{
|
{
|
||||||
|
@ -3133,6 +3311,8 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
||||||
digmreplaces++;
|
digmreplaces++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (!devparm && sreplaces)
|
if (!devparm && sreplaces)
|
||||||
CONS_Printf(M_GetText("%s sounds replaced\n"), sizeu1(sreplaces));
|
CONS_Printf(M_GetText("%s sounds replaced\n"), sizeu1(sreplaces));
|
||||||
if (!devparm && mreplaces)
|
if (!devparm && mreplaces)
|
||||||
|
@ -3140,9 +3320,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
||||||
if (!devparm && digmreplaces)
|
if (!devparm && digmreplaces)
|
||||||
CONS_Printf(M_GetText("%s digital musics replaced\n"), sizeu1(digmreplaces));
|
CONS_Printf(M_GetText("%s digital musics replaced\n"), sizeu1(digmreplaces));
|
||||||
|
|
||||||
//
|
// Search for sprite replacements.
|
||||||
// search for sprite replacements
|
|
||||||
//
|
|
||||||
R_AddSpriteDefs(wadnum);
|
R_AddSpriteDefs(wadnum);
|
||||||
|
|
||||||
// Reload it all anyway, just in case they
|
// Reload it all anyway, just in case they
|
||||||
|
|
|
@ -61,6 +61,8 @@ void P_LoadThingsOnly(void);
|
||||||
boolean P_SetupLevel(boolean skipprecip);
|
boolean P_SetupLevel(boolean skipprecip);
|
||||||
boolean P_AddWadFile(const char *wadfilename, char **firstmapname);
|
boolean P_AddWadFile(const char *wadfilename, char **firstmapname);
|
||||||
boolean P_RunSOC(const char *socfilename);
|
boolean P_RunSOC(const char *socfilename);
|
||||||
|
void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num);
|
||||||
|
void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num);
|
||||||
void P_WriteThings(lumpnum_t lump);
|
void P_WriteThings(lumpnum_t lump);
|
||||||
size_t P_PrecacheLevelFlats(void);
|
size_t P_PrecacheLevelFlats(void);
|
||||||
void P_AllocMapHeader(INT16 i);
|
void P_AllocMapHeader(INT16 i);
|
||||||
|
|
|
@ -148,16 +148,17 @@ void P_InitPicAnims(void)
|
||||||
|
|
||||||
maxanims = 0;
|
maxanims = 0;
|
||||||
|
|
||||||
if (W_CheckNumForName("ANIMDEFS") != LUMPERROR)
|
|
||||||
{
|
|
||||||
for (w = numwadfiles-1; w >= 0; w--)
|
for (w = numwadfiles-1; w >= 0; w--)
|
||||||
{
|
{
|
||||||
UINT16 animdefsLumpNum;
|
UINT16 animdefsLumpNum;
|
||||||
|
|
||||||
// Find ANIMDEFS lump in the WAD
|
// Find ANIMDEFS lump in the WAD
|
||||||
animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0);
|
animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0);
|
||||||
if (animdefsLumpNum != INT16_MAX)
|
|
||||||
|
while (animdefsLumpNum != INT16_MAX)
|
||||||
|
{
|
||||||
P_ParseANIMDEFSLump(w, animdefsLumpNum);
|
P_ParseANIMDEFSLump(w, animdefsLumpNum);
|
||||||
|
animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", (UINT16)w, animdefsLumpNum + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
106
src/r_data.c
106
src/r_data.c
|
@ -528,8 +528,8 @@ void R_FlushTextureCache(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Need these prototypes for later; defining them here instead of r_data.h so they're "private"
|
// Need these prototypes for later; defining them here instead of r_data.h so they're "private"
|
||||||
int R_CountTexturesInTEXTURESLump(UINT16 wadNum);
|
int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum);
|
||||||
void R_ParseTEXTURESLump(UINT16 wadNum, INT32 *index);
|
void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *index);
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_LoadTextures
|
// R_LoadTextures
|
||||||
|
@ -566,14 +566,23 @@ void R_LoadTextures(void)
|
||||||
// This system will allocate memory for all duplicate/patched textures even if it never uses them,
|
// This system will allocate memory for all duplicate/patched textures even if it never uses them,
|
||||||
// but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures.
|
// but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures.
|
||||||
for (w = 0, numtextures = 0; w < numwadfiles; w++)
|
for (w = 0, numtextures = 0; w < numwadfiles; w++)
|
||||||
|
{
|
||||||
|
if (wadfiles[w]->type == RET_PK3)
|
||||||
|
{
|
||||||
|
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||||
|
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
|
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
|
||||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
}
|
||||||
|
|
||||||
if (texturesLumpPos != INT16_MAX)
|
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||||
|
while (texturesLumpPos != INT16_MAX)
|
||||||
{
|
{
|
||||||
numtextures += R_CountTexturesInTEXTURESLump((UINT16)w);
|
numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos);
|
||||||
|
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all the textures between TX_START and TX_END
|
// Add all the textures between TX_START and TX_END
|
||||||
|
@ -588,7 +597,6 @@ void R_LoadTextures(void)
|
||||||
I_Error("No textures detected in any WADs!\n");
|
I_Error("No textures detected in any WADs!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate memory and initialize to 0 for all the textures we are initialising.
|
// Allocate memory and initialize to 0 for all the textures we are initialising.
|
||||||
// There are actually 5 buffers allocated in one for convenience.
|
// There are actually 5 buffers allocated in one for convenience.
|
||||||
textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL);
|
textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL);
|
||||||
|
@ -610,12 +618,25 @@ void R_LoadTextures(void)
|
||||||
for (i = 0, w = 0; w < numwadfiles; w++)
|
for (i = 0, w = 0; w < numwadfiles; w++)
|
||||||
{
|
{
|
||||||
// Get the lump numbers for the markers in the WAD, if they exist.
|
// Get the lump numbers for the markers in the WAD, if they exist.
|
||||||
|
if (wadfiles[w]->type == RET_PK3)
|
||||||
|
{
|
||||||
|
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||||
|
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||||
|
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||||
|
while (texturesLumpPos != INT16_MAX)
|
||||||
|
{
|
||||||
|
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
|
||||||
|
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
|
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
|
||||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||||
|
|
||||||
if (texturesLumpPos != INT16_MAX)
|
if (texturesLumpPos != INT16_MAX)
|
||||||
R_ParseTEXTURESLump(w,&i);
|
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
|
||||||
|
}
|
||||||
|
|
||||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1013,7 +1034,7 @@ static texture_t *R_ParseTexture(boolean actuallyLoadTexture)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses the TEXTURES lump... but just to count the number of textures.
|
// Parses the TEXTURES lump... but just to count the number of textures.
|
||||||
int R_CountTexturesInTEXTURESLump(UINT16 wadNum)
|
int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum)
|
||||||
{
|
{
|
||||||
char *texturesLump;
|
char *texturesLump;
|
||||||
size_t texturesLumpLength;
|
size_t texturesLumpLength;
|
||||||
|
@ -1024,11 +1045,11 @@ int R_CountTexturesInTEXTURESLump(UINT16 wadNum)
|
||||||
// Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll
|
// Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll
|
||||||
// need to make a space of memory where I can ensure that it will terminate
|
// need to make a space of memory where I can ensure that it will terminate
|
||||||
// correctly. Start by loading the relevant data from the WAD.
|
// correctly. Start by loading the relevant data from the WAD.
|
||||||
texturesLump = (char *)W_CacheLumpNumPwad(wadNum,W_CheckNumForNamePwad("TEXTURES", wadNum, 0),PU_STATIC);
|
texturesLump = (char *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_STATIC);
|
||||||
// If that didn't exist, we have nothing to do here.
|
// If that didn't exist, we have nothing to do here.
|
||||||
if (texturesLump == NULL) return 0;
|
if (texturesLump == NULL) return 0;
|
||||||
// If we're still here, then it DOES exist; figure out how long it is, and allot memory accordingly.
|
// If we're still here, then it DOES exist; figure out how long it is, and allot memory accordingly.
|
||||||
texturesLumpLength = W_LumpLengthPwad(wadNum,W_CheckNumForNamePwad("TEXTURES",wadNum,0));
|
texturesLumpLength = W_LumpLengthPwad(wadNum, lumpNum);
|
||||||
texturesText = (char *)Z_Malloc((texturesLumpLength+1)*sizeof(char),PU_STATIC,NULL);
|
texturesText = (char *)Z_Malloc((texturesLumpLength+1)*sizeof(char),PU_STATIC,NULL);
|
||||||
// Now move the contents of the lump into this new location.
|
// Now move the contents of the lump into this new location.
|
||||||
memmove(texturesText,texturesLump,texturesLumpLength);
|
memmove(texturesText,texturesLump,texturesLumpLength);
|
||||||
|
@ -1060,7 +1081,7 @@ int R_CountTexturesInTEXTURESLump(UINT16 wadNum)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses the TEXTURES lump... for real, this time.
|
// Parses the TEXTURES lump... for real, this time.
|
||||||
void R_ParseTEXTURESLump(UINT16 wadNum, INT32 *texindex)
|
void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *texindex)
|
||||||
{
|
{
|
||||||
char *texturesLump;
|
char *texturesLump;
|
||||||
size_t texturesLumpLength;
|
size_t texturesLumpLength;
|
||||||
|
@ -1073,11 +1094,11 @@ void R_ParseTEXTURESLump(UINT16 wadNum, INT32 *texindex)
|
||||||
// Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll
|
// Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll
|
||||||
// need to make a space of memory where I can ensure that it will terminate
|
// need to make a space of memory where I can ensure that it will terminate
|
||||||
// correctly. Start by loading the relevant data from the WAD.
|
// correctly. Start by loading the relevant data from the WAD.
|
||||||
texturesLump = (char *)W_CacheLumpNumPwad(wadNum,W_CheckNumForNamePwad("TEXTURES", wadNum, 0),PU_STATIC);
|
texturesLump = (char *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_STATIC);
|
||||||
// If that didn't exist, we have nothing to do here.
|
// If that didn't exist, we have nothing to do here.
|
||||||
if (texturesLump == NULL) return;
|
if (texturesLump == NULL) return;
|
||||||
// If we're still here, then it DOES exist; figure out how long it is, and allot memory accordingly.
|
// If we're still here, then it DOES exist; figure out how long it is, and allot memory accordingly.
|
||||||
texturesLumpLength = W_LumpLengthPwad(wadNum,W_CheckNumForNamePwad("TEXTURES",wadNum,0));
|
texturesLumpLength = W_LumpLengthPwad(wadNum, lumpNum);
|
||||||
texturesText = (char *)Z_Malloc((texturesLumpLength+1)*sizeof(char),PU_STATIC,NULL);
|
texturesText = (char *)Z_Malloc((texturesLumpLength+1)*sizeof(char),PU_STATIC,NULL);
|
||||||
// Now move the contents of the lump into this new location.
|
// Now move the contents of the lump into this new location.
|
||||||
memmove(texturesText,texturesLump,texturesLumpLength);
|
memmove(texturesText,texturesLump,texturesLumpLength);
|
||||||
|
@ -1164,12 +1185,60 @@ static void R_InitExtraColormaps(void)
|
||||||
CONS_Printf(M_GetText("Number of Extra Colormaps: %s\n"), sizeu1(numcolormaplumps));
|
CONS_Printf(M_GetText("Number of Extra Colormaps: %s\n"), sizeu1(numcolormaplumps));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 12/14/14 -- only take flats in F_START/F_END
|
// Search for flat name through all
|
||||||
lumpnum_t R_GetFlatNumForName(const char *name)
|
lumpnum_t R_GetFlatNumForName(const char *name)
|
||||||
{
|
{
|
||||||
lumpnum_t lump = W_CheckNumForNameInBlock(name, "F_START", "F_END");
|
INT32 i;
|
||||||
if (lump == LUMPERROR)
|
lumpnum_t lump;
|
||||||
lump = W_CheckNumForNameInBlock(name, "FF_START", "FF_END"); // deutex, some other old things
|
lumpnum_t start;
|
||||||
|
lumpnum_t end;
|
||||||
|
|
||||||
|
// Scan wad files backwards so patched flats take preference.
|
||||||
|
for (i = numwadfiles - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (wadfiles[i]->type == RET_PK3)
|
||||||
|
{
|
||||||
|
start = W_CheckNumForFolderStartPK3("Flats/", i, 0);
|
||||||
|
if (start == INT16_MAX)
|
||||||
|
continue;
|
||||||
|
end = W_CheckNumForFolderEndPK3("Flats/", i, start);
|
||||||
|
if (end == INT16_MAX)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else // WAD type? use markers.
|
||||||
|
{
|
||||||
|
// Find the ranges to work with.
|
||||||
|
start = W_CheckNumForNamePwad("F_START", (UINT16)i, 0);
|
||||||
|
if (start == INT16_MAX)
|
||||||
|
{
|
||||||
|
start = W_CheckNumForNamePwad("FF_START", (UINT16)i, 0);
|
||||||
|
if (start == INT16_MAX)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
end = W_CheckNumForNamePwad("FF_END", (UINT16)i, start);
|
||||||
|
if (end == INT16_MAX)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
end = W_CheckNumForNamePwad("F_END", (UINT16)i, start);
|
||||||
|
if (end == INT16_MAX)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Now find lump with specified name in that range.
|
||||||
|
lump = W_CheckNumForNamePwad(name, (UINT16)i, start);
|
||||||
|
if (lump < end)
|
||||||
|
{
|
||||||
|
lump += (i<<16); // found it, in our constraints
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lump = LUMPERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (lump == LUMPERROR)
|
if (lump == LUMPERROR)
|
||||||
{
|
{
|
||||||
if (strcmp(name, SKYFLATNAME))
|
if (strcmp(name, SKYFLATNAME))
|
||||||
|
@ -1218,7 +1287,6 @@ void R_ReInitColormaps(UINT16 num)
|
||||||
{
|
{
|
||||||
char colormap[9] = "COLORMAP";
|
char colormap[9] = "COLORMAP";
|
||||||
lumpnum_t lump;
|
lumpnum_t lump;
|
||||||
|
|
||||||
if (num > 0 && num <= 10000)
|
if (num > 0 && num <= 10000)
|
||||||
snprintf(colormap, 8, "CLM%04u", num-1);
|
snprintf(colormap, 8, "CLM%04u", num-1);
|
||||||
|
|
||||||
|
|
|
@ -379,10 +379,11 @@ void R_AddSpriteDefs(UINT16 wadnum)
|
||||||
UINT16 start, end;
|
UINT16 start, end;
|
||||||
char wadname[MAX_WADPATH];
|
char wadname[MAX_WADPATH];
|
||||||
|
|
||||||
// find the sprites section in this pwad
|
// Find the sprites section in this resource file.
|
||||||
// we need at least the S_END
|
if (wadfiles[wadnum]->type == RET_PK3)
|
||||||
// (not really, but for speedup)
|
start = W_CheckNumForFolderStartPK3("Sprites/", wadnum, 0);
|
||||||
|
else
|
||||||
|
{
|
||||||
start = W_CheckNumForNamePwad("S_START", wadnum, 0);
|
start = W_CheckNumForNamePwad("S_START", wadnum, 0);
|
||||||
if (start == INT16_MAX)
|
if (start == INT16_MAX)
|
||||||
start = W_CheckNumForNamePwad("SS_START", wadnum, 0); //deutex compatib.
|
start = W_CheckNumForNamePwad("SS_START", wadnum, 0); //deutex compatib.
|
||||||
|
@ -390,20 +391,28 @@ void R_AddSpriteDefs(UINT16 wadnum)
|
||||||
start = 0; //let say S_START is lump 0
|
start = 0; //let say S_START is lump 0
|
||||||
else
|
else
|
||||||
start++; // just after S_START
|
start++; // just after S_START
|
||||||
|
}
|
||||||
|
|
||||||
// ignore skin wads (we don't want skin sprites interfering with vanilla sprites)
|
// ignore skin wads (we don't want skin sprites interfering with vanilla sprites)
|
||||||
if (start == 0 && W_CheckNumForNamePwad("S_SKIN", wadnum, 0) != INT16_MAX)
|
if (start == 0 && W_CheckNumForNamePwad("S_SKIN", wadnum, 0) != UINT16_MAX)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (wadfiles[wadnum]->type == RET_PK3)
|
||||||
|
end = W_CheckNumForFolderEndPK3("Sprites/", wadnum, start);
|
||||||
|
else
|
||||||
|
{
|
||||||
end = W_CheckNumForNamePwad("S_END",wadnum,start);
|
end = W_CheckNumForNamePwad("S_END",wadnum,start);
|
||||||
if (end == INT16_MAX)
|
if (end == INT16_MAX)
|
||||||
end = W_CheckNumForNamePwad("SS_END",wadnum,start); //deutex compatib.
|
end = W_CheckNumForNamePwad("SS_END",wadnum,start); //deutex compatib.
|
||||||
|
}
|
||||||
|
|
||||||
if (end == INT16_MAX)
|
if (end == INT16_MAX)
|
||||||
{
|
{
|
||||||
CONS_Debug(DBG_SETUP, "no sprites in pwad %d\n", wadnum);
|
CONS_Debug(DBG_SETUP, "no sprites in pwad %d\n", wadnum);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// scan through lumps, for each sprite, find all the sprite frames
|
// scan through lumps, for each sprite, find all the sprite frames
|
||||||
//
|
//
|
||||||
|
|
|
@ -231,7 +231,7 @@ char *GetPlayerFacePic(INT32 skinnum);
|
||||||
// Future: [[ ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!@ ]]
|
// Future: [[ ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!@ ]]
|
||||||
FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame)
|
FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame)
|
||||||
{
|
{
|
||||||
#if 1 // 2.1 compat
|
#if 0 // 2.1 compat
|
||||||
return 'A' + frame;
|
return 'A' + frame;
|
||||||
#else
|
#else
|
||||||
if (frame < 26) return 'A' + frame;
|
if (frame < 26) return 'A' + frame;
|
||||||
|
@ -245,7 +245,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame)
|
||||||
|
|
||||||
FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn)
|
FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn)
|
||||||
{
|
{
|
||||||
#if 1 // 2.1 compat
|
#if 0 // 2.1 compat
|
||||||
return cn - 'A';
|
return cn - 'A';
|
||||||
#else
|
#else
|
||||||
if (cn >= 'A' && cn <= 'Z') return cn - 'A';
|
if (cn >= 'A' && cn <= 'Z') return cn - 'A';
|
||||||
|
|
|
@ -142,7 +142,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
|
||||||
|
|
||||||
/** \brief WAD file to look for
|
/** \brief WAD file to look for
|
||||||
*/
|
*/
|
||||||
#define WADKEYWORD1 "srb2.srb"
|
#define WADKEYWORD1 "srb2.pk3"
|
||||||
#define WADKEYWORD2 "srb2.wad"
|
#define WADKEYWORD2 "srb2.wad"
|
||||||
/** \brief holds wad path
|
/** \brief holds wad path
|
||||||
*/
|
*/
|
||||||
|
|
610
src/w_wad.c
610
src/w_wad.c
|
@ -22,6 +22,22 @@
|
||||||
#include "lzf.h"
|
#include "lzf.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _FILE_OFFSET_BITS
|
||||||
|
#define _FILE_OFFSET_BITS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _LARGEFILE64_SOURCE
|
||||||
|
#define _LARGEFILE64_SOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _LFS64_LARGEFILE
|
||||||
|
#define _LFS64_LARGEFILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#ifdef HAVE_ZLIB
|
||||||
|
#include "zlib.h"
|
||||||
|
//#endif // HAVE_ZLIB
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "doomtype.h"
|
#include "doomtype.h"
|
||||||
|
@ -65,14 +81,6 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// a raw entry of the wad directory
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
UINT32 filepos; // file offset of the resource
|
|
||||||
UINT32 size; // size of the resource
|
|
||||||
char name[8]; // name of the resource
|
|
||||||
} ATTRPACK filelump_t;
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
#endif
|
#endif
|
||||||
|
@ -113,6 +121,8 @@ void W_Shutdown(void)
|
||||||
fclose(wadfiles[numwadfiles]->handle);
|
fclose(wadfiles[numwadfiles]->handle);
|
||||||
Z_Free(wadfiles[numwadfiles]->lumpinfo);
|
Z_Free(wadfiles[numwadfiles]->lumpinfo);
|
||||||
Z_Free(wadfiles[numwadfiles]->filename);
|
Z_Free(wadfiles[numwadfiles]->filename);
|
||||||
|
while (wadfiles[numwadfiles]->numlumps--)
|
||||||
|
Z_Free(wadfiles[numwadfiles]->lumpinfo[wadfiles[numwadfiles]->numlumps].name2);
|
||||||
Z_Free(wadfiles[numwadfiles]);
|
Z_Free(wadfiles[numwadfiles]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,6 +182,26 @@ FILE *W_OpenWadFile(const char **filename, boolean useerrors)
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Look for all DEHACKED and Lua scripts inside a PK3 archive.
|
||||||
|
static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum)
|
||||||
|
{
|
||||||
|
UINT16 posStart, posEnd;
|
||||||
|
posStart = W_CheckNumForFolderStartPK3("Lua/", wadnum, 0);
|
||||||
|
if (posStart != INT16_MAX)
|
||||||
|
{
|
||||||
|
posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart);
|
||||||
|
for (; posStart < posEnd; posStart++)
|
||||||
|
LUA_LoadLump(wadnum, posStart);
|
||||||
|
}
|
||||||
|
posStart = W_CheckNumForFolderStartPK3("SOCs/", wadnum, 0);
|
||||||
|
if (posStart != INT16_MAX)
|
||||||
|
{
|
||||||
|
posEnd = W_CheckNumForFolderEndPK3("SOCs/", wadnum, posStart);
|
||||||
|
for(; posStart < posEnd; posStart++)
|
||||||
|
DEH_LoadDehackedLumpPwad(wadnum, posStart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// search for all DEHACKED lump in all wads and load it
|
// search for all DEHACKED lump in all wads and load it
|
||||||
static inline void W_LoadDehackedLumps(UINT16 wadnum)
|
static inline void W_LoadDehackedLumps(UINT16 wadnum)
|
||||||
{
|
{
|
||||||
|
@ -284,12 +314,13 @@ static void W_InvalidateLumpnumCache(void)
|
||||||
//
|
//
|
||||||
// Can now load dehacked files (.soc)
|
// Can now load dehacked files (.soc)
|
||||||
//
|
//
|
||||||
UINT16 W_LoadWadFile(const char *filename)
|
UINT16 W_InitFile(const char *filename)
|
||||||
{
|
{
|
||||||
FILE *handle;
|
FILE *handle;
|
||||||
lumpinfo_t *lumpinfo;
|
lumpinfo_t *lumpinfo;
|
||||||
wadfile_t *wadfile;
|
wadfile_t *wadfile;
|
||||||
UINT32 numlumps;
|
enum restype type;
|
||||||
|
UINT16 numlumps;
|
||||||
size_t i;
|
size_t i;
|
||||||
INT32 compressed = 0;
|
INT32 compressed = 0;
|
||||||
size_t packetsize;
|
size_t packetsize;
|
||||||
|
@ -335,12 +366,32 @@ UINT16 W_LoadWadFile(const char *filename)
|
||||||
packetsizetally = packetsize;
|
packetsizetally = packetsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NOMD5
|
||||||
|
//
|
||||||
|
// w-waiiiit!
|
||||||
|
// Let's not add a wad file if the MD5 matches
|
||||||
|
// an MD5 of an already added WAD file!
|
||||||
|
//
|
||||||
|
W_MakeFileMD5(filename, md5sum);
|
||||||
|
|
||||||
|
for (i = 0; i < numwadfiles; i++)
|
||||||
|
{
|
||||||
|
if (!memcmp(wadfiles[i]->md5sum, md5sum, 16))
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, M_GetText("%s is already loaded\n"), filename);
|
||||||
|
return INT16_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// detect dehacked file with the "soc" extension
|
// detect dehacked file with the "soc" extension
|
||||||
if (!stricmp(&filename[strlen(filename) - 4], ".soc"))
|
if (!stricmp(&filename[strlen(filename) - 4], ".soc"))
|
||||||
{
|
{
|
||||||
// This code emulates a wadfile with one lump name "OBJCTCFG"
|
// This code emulates a wadfile with one lump name "OBJCTCFG"
|
||||||
// at position 0 and size of the whole file.
|
// at position 0 and size of the whole file.
|
||||||
// This allows soc files to be like all wads, copied by network and loaded at the console.
|
// This allows soc files to be like all wads, copied by network and loaded at the console.
|
||||||
|
type = RET_WAD;
|
||||||
|
|
||||||
numlumps = 1;
|
numlumps = 1;
|
||||||
lumpinfo = Z_Calloc(sizeof (*lumpinfo), PU_STATIC, NULL);
|
lumpinfo = Z_Calloc(sizeof (*lumpinfo), PU_STATIC, NULL);
|
||||||
lumpinfo->position = 0;
|
lumpinfo->position = 0;
|
||||||
|
@ -348,6 +399,10 @@ UINT16 W_LoadWadFile(const char *filename)
|
||||||
lumpinfo->size = ftell(handle);
|
lumpinfo->size = ftell(handle);
|
||||||
fseek(handle, 0, SEEK_SET);
|
fseek(handle, 0, SEEK_SET);
|
||||||
strcpy(lumpinfo->name, "OBJCTCFG");
|
strcpy(lumpinfo->name, "OBJCTCFG");
|
||||||
|
// Allocate the lump's full name.
|
||||||
|
lumpinfo->name2 = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||||
|
strcpy(lumpinfo->name2, "OBJCTCFG");
|
||||||
|
lumpinfo->name2[8] = '\0';
|
||||||
}
|
}
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
// detect lua script with the "lua" extension
|
// detect lua script with the "lua" extension
|
||||||
|
@ -356,6 +411,8 @@ UINT16 W_LoadWadFile(const char *filename)
|
||||||
// This code emulates a wadfile with one lump name "LUA_INIT"
|
// This code emulates a wadfile with one lump name "LUA_INIT"
|
||||||
// at position 0 and size of the whole file.
|
// at position 0 and size of the whole file.
|
||||||
// This allows soc files to be like all wads, copied by network and loaded at the console.
|
// This allows soc files to be like all wads, copied by network and loaded at the console.
|
||||||
|
type = RET_WAD;
|
||||||
|
|
||||||
numlumps = 1;
|
numlumps = 1;
|
||||||
lumpinfo = Z_Calloc(sizeof (*lumpinfo), PU_STATIC, NULL);
|
lumpinfo = Z_Calloc(sizeof (*lumpinfo), PU_STATIC, NULL);
|
||||||
lumpinfo->position = 0;
|
lumpinfo->position = 0;
|
||||||
|
@ -363,16 +420,206 @@ UINT16 W_LoadWadFile(const char *filename)
|
||||||
lumpinfo->size = ftell(handle);
|
lumpinfo->size = ftell(handle);
|
||||||
fseek(handle, 0, SEEK_SET);
|
fseek(handle, 0, SEEK_SET);
|
||||||
strcpy(lumpinfo->name, "LUA_INIT");
|
strcpy(lumpinfo->name, "LUA_INIT");
|
||||||
|
// Allocate the lump's full name.
|
||||||
|
lumpinfo->name2 = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||||
|
strcpy(lumpinfo->name2, "LUA_INIT");
|
||||||
|
lumpinfo->name2[8] = '\0';
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
else if (!stricmp(&filename[strlen(filename) - 4], ".pk3"))
|
||||||
|
{
|
||||||
|
char curHeader[4];
|
||||||
|
unsigned long size;
|
||||||
|
char seekPat[] = {0x50, 0x4b, 0x01, 0x02, 0x00};
|
||||||
|
char endPat[] = {0x50, 0x4b, 0x05, 0x06, 0x00};
|
||||||
|
char *s;
|
||||||
|
int c;
|
||||||
|
UINT32 position;
|
||||||
|
boolean matched = false;
|
||||||
|
lumpinfo_t *lump_p;
|
||||||
|
|
||||||
|
type = RET_PK3;
|
||||||
|
|
||||||
|
// Obtain the file's size.
|
||||||
|
fseek(handle, 0, SEEK_END);
|
||||||
|
size = ftell(handle);
|
||||||
|
CONS_Debug(DBG_SETUP, "PK3 size is: %ld\n", size);
|
||||||
|
|
||||||
|
// We must look for the central directory through the file. (Thanks to JTE for this algorithm.)
|
||||||
|
// All of the central directory entry headers have a signature of 0x50 0x4b 0x01 0x02.
|
||||||
|
// The first entry found means the beginning of the central directory.
|
||||||
|
fseek(handle, -min(size, (22 + 65536)), SEEK_CUR);
|
||||||
|
s = endPat;
|
||||||
|
while((c = fgetc(handle)) != EOF)
|
||||||
|
{
|
||||||
|
if (*s != c && s > endPat) // No match?
|
||||||
|
s = endPat; // We "reset" the counter by sending the s pointer back to the start of the array.
|
||||||
|
if (*s == c)
|
||||||
|
{
|
||||||
|
s++;
|
||||||
|
if (*s == 0x00) // The array pointer has reached the key char which marks the end. It means we have matched the signature.
|
||||||
|
{
|
||||||
|
matched = true;
|
||||||
|
CONS_Debug(DBG_SETUP, "Found PK3 central directory at position %ld.\n", ftell(handle));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error if we couldn't find the central directory at all. It likely means this is not a ZIP/PK3 file.
|
||||||
|
if (matched == false)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, "No central directory inside PK3! File may be corrupted or incomplete.\n");
|
||||||
|
return INT16_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(handle, 4, SEEK_CUR);
|
||||||
|
fread(&numlumps, 1, 2, handle);
|
||||||
|
fseek(handle, 6, SEEK_CUR);
|
||||||
|
fread(&position, 1, 4, handle);
|
||||||
|
lump_p = lumpinfo = Z_Malloc(numlumps * sizeof (*lumpinfo), PU_STATIC, NULL);
|
||||||
|
fseek(handle, position, SEEK_SET);
|
||||||
|
|
||||||
|
// Since we found the central directory, now we can map our lumpinfo table.
|
||||||
|
// We will look for file headers inside it, until we reach the central directory end signature.
|
||||||
|
// We exactly know what data to expect this time, so now we don't need to do a byte-by-byte search.
|
||||||
|
CONS_Debug(DBG_SETUP, "Now finding central directory file headers...\n");
|
||||||
|
for (i = 0; i < numlumps; i++, lump_p++)
|
||||||
|
{
|
||||||
|
fread(curHeader, 1, 4, handle);
|
||||||
|
|
||||||
|
// We found a central directory entry signature?
|
||||||
|
if (!strncmp(curHeader, seekPat, 3))
|
||||||
|
{
|
||||||
|
// Let's fill in the fields that we actually need.
|
||||||
|
// (Declaring all those vars might not be the optimal way to do this, sorry.)
|
||||||
|
char *eName;
|
||||||
|
int namePos;
|
||||||
|
int nameEnd;
|
||||||
|
unsigned short int eNameLen = 8;
|
||||||
|
unsigned short int eXFieldLen = 0;
|
||||||
|
unsigned short int lNameLen = 0;
|
||||||
|
unsigned short int lXFieldLen = 0;
|
||||||
|
unsigned short int eCommentLen = 0;
|
||||||
|
unsigned short int eCompression = 0;
|
||||||
|
unsigned int eSize = 0;
|
||||||
|
unsigned int eCompSize = 0;
|
||||||
|
unsigned int eLocalHeaderOffset = 0;
|
||||||
|
unsigned long int rememberPos = 0;
|
||||||
|
|
||||||
|
// We get the compression type indicator value.
|
||||||
|
fseek(handle, 6, SEEK_CUR);
|
||||||
|
fread(&eCompression, 1, 2, handle);
|
||||||
|
// Get the size
|
||||||
|
fseek(handle, 8, SEEK_CUR);
|
||||||
|
fread(&eCompSize, 1, 4, handle);
|
||||||
|
fread(&eSize, 1, 4, handle);
|
||||||
|
// We get the variable length fields.
|
||||||
|
fread(&eNameLen, 1, 2, handle);
|
||||||
|
fread(&eXFieldLen, 1, 2, handle);
|
||||||
|
fread(&eCommentLen, 1, 2, handle);
|
||||||
|
fseek(handle, 8, SEEK_CUR);
|
||||||
|
fread(&eLocalHeaderOffset, 1, 4, handle); // Get the offset.
|
||||||
|
|
||||||
|
eName = malloc(sizeof(char)*(eNameLen + 1));
|
||||||
|
fgets(eName, eNameLen + 1, handle);
|
||||||
|
|
||||||
|
// Don't load lump if folder.
|
||||||
|
// if (*(eName + eNameLen - 1) == '/')
|
||||||
|
// continue;
|
||||||
|
|
||||||
|
// We must calculate the position for the actual data.
|
||||||
|
// Why not eLocalHeaderOffset + 30 + eNameLen + eXFieldLen? That's because the extra field and name lengths MAY be different in the local headers.
|
||||||
|
rememberPos = ftell(handle);
|
||||||
|
fseek(handle, eLocalHeaderOffset + 26, SEEK_SET);
|
||||||
|
fread(&lNameLen, 1, 2, handle);
|
||||||
|
fread(&lXFieldLen, 1, 2, handle);
|
||||||
|
lump_p->position = ftell(handle) + lNameLen + lXFieldLen;
|
||||||
|
|
||||||
|
fseek(handle, rememberPos, SEEK_SET); // Let's go back to the central dir.
|
||||||
|
lump_p->disksize = eCompSize;
|
||||||
|
lump_p->size = eSize;
|
||||||
|
|
||||||
|
// We will trim the file's full name so that only the filename is left.
|
||||||
|
namePos = eNameLen - 1;
|
||||||
|
while(namePos--)
|
||||||
|
if(eName[namePos] == '/')
|
||||||
|
break;
|
||||||
|
namePos++;
|
||||||
|
// We will remove the file extension too.
|
||||||
|
nameEnd = 0;
|
||||||
|
while(nameEnd++ < 8)
|
||||||
|
if(eName[namePos + nameEnd] == '.')
|
||||||
|
break;
|
||||||
|
memset(lump_p->name, '\0', 9);
|
||||||
|
strncpy(lump_p->name, eName + namePos, nameEnd);
|
||||||
|
|
||||||
|
lump_p->name2 = Z_Malloc((eNameLen+1)*sizeof(char), PU_STATIC, NULL);
|
||||||
|
strncpy(lump_p->name2, eName, eNameLen);
|
||||||
|
lump_p->name2[eNameLen] = '\0';
|
||||||
|
|
||||||
|
// We set the compression type from what we're supporting so far.
|
||||||
|
switch(eCompression)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
lump_p->compression = CM_NOCOMPRESSION;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
lump_p->compression = CM_DEFLATE;
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
lump_p->compression = CM_LZF;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CONS_Alert(CONS_WARNING, "Lump has an unsupported compression type!\n");
|
||||||
|
lump_p->compression = CM_UNSUPPORTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
CONS_Debug(DBG_SETUP, "File %s, data begins at: %ld\n", eName, lump_p->position);
|
||||||
|
fseek(handle, eXFieldLen + eCommentLen, SEEK_CUR); // We skip to where we expect the next central directory entry or end marker to be.
|
||||||
|
free(eName);
|
||||||
|
}
|
||||||
|
// We found the central directory end signature?
|
||||||
|
else if (!strncmp(curHeader, endPat, 4))
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_SETUP, "Central directory end signature found at: %ld\n", ftell(handle));
|
||||||
|
|
||||||
|
/*// We will create a "virtual" marker lump at the very end of lumpinfo for convenience.
|
||||||
|
// This marker will be used by the different lump-seeking (eg. textures, sprites, etc.) in PK3-specific cases in an auxiliary way.
|
||||||
|
lumpinfo = (lumpinfo_t*) Z_Realloc(lumpinfo, (numlumps + 1)*sizeof(*lumpinfo), PU_STATIC, NULL);
|
||||||
|
strcpy(lumpinfo[numlumps].name, "PK3_ENDM\0");
|
||||||
|
lumpinfo[numlumps].name2 = Z_Malloc(14 * sizeof(char), PU_STATIC, NULL);
|
||||||
|
strcpy(lumpinfo[numlumps].name2, "PK3_ENDMARKER\0");
|
||||||
|
lumpinfo[numlumps].position = 0;
|
||||||
|
lumpinfo[numlumps].size = 0;
|
||||||
|
lumpinfo[numlumps].disksize = 0;
|
||||||
|
lumpinfo[numlumps].compression = CM_NOCOMPRESSION;
|
||||||
|
numlumps++;*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// ... None of them? We're only expecting either a central directory signature entry or the central directory end signature.
|
||||||
|
// The file may be broken or incomplete...
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
CONS_Alert(CONS_WARNING, "Expected central directory header signature, got something else!");
|
||||||
|
return INT16_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we've reached this far, then it means our dynamically stored lumpinfo has to be ready.
|
||||||
|
// Now we finally build our... incorrectly called wadfile.
|
||||||
|
// TODO: Maybe we should give them more generalized names, like resourcefile or resfile or something.
|
||||||
|
// Mostly for clarity and better understanding when reading the code.
|
||||||
|
}
|
||||||
// assume wad file
|
// assume wad file
|
||||||
|
else
|
||||||
|
{
|
||||||
wadinfo_t header;
|
wadinfo_t header;
|
||||||
lumpinfo_t *lump_p;
|
lumpinfo_t *lump_p;
|
||||||
filelump_t *fileinfo;
|
filelump_t *fileinfo;
|
||||||
void *fileinfov;
|
void *fileinfov;
|
||||||
|
|
||||||
|
type = RET_WAD;
|
||||||
|
|
||||||
// read the header
|
// read the header
|
||||||
if (fread(&header, 1, sizeof header, handle) < sizeof header)
|
if (fread(&header, 1, sizeof header, handle) < sizeof header)
|
||||||
{
|
{
|
||||||
|
@ -427,47 +674,37 @@ UINT16 W_LoadWadFile(const char *filename)
|
||||||
if (realsize != 0)
|
if (realsize != 0)
|
||||||
{
|
{
|
||||||
lump_p->size = realsize;
|
lump_p->size = realsize;
|
||||||
lump_p->compressed = 1;
|
lump_p->compression = CM_LZF;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lump_p->size -= 4;
|
lump_p->size -= 4;
|
||||||
lump_p->compressed = 0;
|
lump_p->compression = CM_NOCOMPRESSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
lump_p->position += 4;
|
lump_p->position += 4;
|
||||||
lump_p->disksize -= 4;
|
lump_p->disksize -= 4;
|
||||||
}
|
}
|
||||||
else lump_p->compressed = 0;
|
else
|
||||||
|
{
|
||||||
|
lump_p->compression = CM_NOCOMPRESSION;
|
||||||
|
}
|
||||||
memset(lump_p->name, 0x00, 9);
|
memset(lump_p->name, 0x00, 9);
|
||||||
strncpy(lump_p->name, fileinfo->name, 8);
|
strncpy(lump_p->name, fileinfo->name, 8);
|
||||||
|
// Allocate the lump's full name.
|
||||||
|
lump_p->name2 = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||||
|
strncpy(lump_p->name2, fileinfo->name, 8);
|
||||||
|
lump_p->name2[8] = '\0';
|
||||||
}
|
}
|
||||||
free(fileinfov);
|
free(fileinfov);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NOMD5
|
|
||||||
//
|
|
||||||
// w-waiiiit!
|
|
||||||
// Let's not add a wad file if the MD5 matches
|
|
||||||
// an MD5 of an already added WAD file!
|
|
||||||
//
|
|
||||||
W_MakeFileMD5(filename, md5sum);
|
|
||||||
|
|
||||||
for (i = 0; i < numwadfiles; i++)
|
|
||||||
{
|
|
||||||
if (!memcmp(wadfiles[i]->md5sum, md5sum, 16))
|
|
||||||
{
|
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("%s is already loaded\n"), filename);
|
|
||||||
return INT16_MAX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// link wad file to search files
|
// link wad file to search files
|
||||||
//
|
//
|
||||||
wadfile = Z_Malloc(sizeof (*wadfile), PU_STATIC, NULL);
|
wadfile = Z_Malloc(sizeof (*wadfile), PU_STATIC, NULL);
|
||||||
wadfile->filename = Z_StrDup(filename);
|
wadfile->filename = Z_StrDup(filename);
|
||||||
|
wadfile->type = type;
|
||||||
wadfile->handle = handle;
|
wadfile->handle = handle;
|
||||||
wadfile->numlumps = (UINT16)numlumps;
|
wadfile->numlumps = (UINT16)numlumps;
|
||||||
wadfile->lumpinfo = lumpinfo;
|
wadfile->lumpinfo = lumpinfo;
|
||||||
|
@ -494,7 +731,13 @@ UINT16 W_LoadWadFile(const char *filename)
|
||||||
CONS_Printf(M_GetText("Added file %s (%u lumps)\n"), filename, numlumps);
|
CONS_Printf(M_GetText("Added file %s (%u lumps)\n"), filename, numlumps);
|
||||||
wadfiles[numwadfiles] = wadfile;
|
wadfiles[numwadfiles] = wadfile;
|
||||||
numwadfiles++; // must come BEFORE W_LoadDehackedLumps, so any addfile called by COM_BufInsertText called by Lua doesn't overwrite what we just loaded
|
numwadfiles++; // must come BEFORE W_LoadDehackedLumps, so any addfile called by COM_BufInsertText called by Lua doesn't overwrite what we just loaded
|
||||||
W_LoadDehackedLumps(numwadfiles-1);
|
|
||||||
|
// TODO: HACK ALERT - Load Lua & SOC stuff right here. I feel like this should be out of this place, but... Let's stick with this for now.
|
||||||
|
if (wadfile->type == RET_WAD)
|
||||||
|
W_LoadDehackedLumps(numwadfiles - 1);
|
||||||
|
else if (wadfile->type == RET_PK3)
|
||||||
|
W_LoadDehackedLumpsPK3(numwadfiles - 1);
|
||||||
|
|
||||||
|
|
||||||
W_InvalidateLumpnumCache();
|
W_InvalidateLumpnumCache();
|
||||||
|
|
||||||
|
@ -523,7 +766,7 @@ INT32 W_InitMultipleFiles(char **filenames)
|
||||||
for (; *filenames; filenames++)
|
for (; *filenames; filenames++)
|
||||||
{
|
{
|
||||||
//CONS_Debug(DBG_SETUP, "Loading %s\n", *filenames);
|
//CONS_Debug(DBG_SETUP, "Loading %s\n", *filenames);
|
||||||
rc &= (W_LoadWadFile(*filenames) != INT16_MAX) ? 1 : 0;
|
rc &= (W_InitFile(*filenames) != INT16_MAX) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!numwadfiles)
|
if (!numwadfiles)
|
||||||
|
@ -591,16 +834,59 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
||||||
{
|
{
|
||||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||||
{
|
|
||||||
if (memcmp(lump_p->name,uname,8) == 0)
|
if (memcmp(lump_p->name,uname,8) == 0)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// not found.
|
// not found.
|
||||||
return INT16_MAX;
|
return INT16_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Look for the first lump from a folder.
|
||||||
|
UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||||
|
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||||
|
{
|
||||||
|
if (strnicmp(name, lump_p->name2, strlen(name)) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In a PK3 type of resource file, it looks for the next lumpinfo entry that doesn't share the specified pathfile.
|
||||||
|
// Useful for finding folder ends.
|
||||||
|
// Returns the position of the lumpinfo entry.
|
||||||
|
UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||||
|
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||||
|
{
|
||||||
|
if (strnicmp(name, lump_p->name2, strlen(name)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In a PK3 type of resource file, it looks for an entry with the specified full name.
|
||||||
|
// Returns lump position in PK3's lumpinfo, or INT16_MAX if not found.
|
||||||
|
UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||||
|
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||||
|
{
|
||||||
|
if (!strnicmp(name, lump_p->name2, strlen(name)))
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Not found at all?
|
||||||
|
return INT16_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// W_CheckNumForName
|
// W_CheckNumForName
|
||||||
// Returns LUMPERROR if name not found.
|
// Returns LUMPERROR if name not found.
|
||||||
|
@ -641,6 +927,37 @@ lumpnum_t W_CheckNumForName(const char *name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Look for valid map data through all added files in descendant order.
|
||||||
|
// Get a map marker for WADs, and a standalone WAD file lump inside PK3s.
|
||||||
|
// TODO: Make it search through cache first, maybe...?
|
||||||
|
lumpnum_t W_CheckNumForMap(const char *name)
|
||||||
|
{
|
||||||
|
UINT16 lumpNum, end;
|
||||||
|
UINT32 i;
|
||||||
|
for (i = numwadfiles - 1; i < numwadfiles; i--)
|
||||||
|
{
|
||||||
|
if (wadfiles[i]->type == RET_WAD)
|
||||||
|
{
|
||||||
|
for (lumpNum = 0; lumpNum < wadfiles[i]->numlumps; lumpNum++)
|
||||||
|
if (!strncmp(name, (wadfiles[i]->lumpinfo + lumpNum)->name, 8))
|
||||||
|
return (i<<16) + lumpNum;
|
||||||
|
}
|
||||||
|
else if (wadfiles[i]->type == RET_PK3)
|
||||||
|
{
|
||||||
|
lumpNum = W_CheckNumForFolderStartPK3("maps/", i, 0);
|
||||||
|
if (lumpNum != INT16_MAX)
|
||||||
|
end = W_CheckNumForFolderEndPK3("maps/", i, lumpNum);
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
// Now look for the specified map.
|
||||||
|
for (++lumpNum; lumpNum < end; lumpNum++)
|
||||||
|
if (!strnicmp(name, (wadfiles[i]->lumpinfo + lumpNum)->name, 8))
|
||||||
|
return (i<<16) + lumpNum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return LUMPERROR;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// W_GetNumForName
|
// W_GetNumForName
|
||||||
//
|
//
|
||||||
|
@ -671,16 +988,21 @@ lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, con
|
||||||
// scan wad files backwards so patch lump files take precedence
|
// scan wad files backwards so patch lump files take precedence
|
||||||
for (i = numwadfiles - 1; i >= 0; i--)
|
for (i = numwadfiles - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
bsid = W_CheckNumForNamePwad(blockstart,(UINT16)i,0);
|
if (wadfiles[i]->type == RET_WAD)
|
||||||
|
{
|
||||||
|
bsid = W_CheckNumForNamePwad(blockstart, (UINT16)i, 0);
|
||||||
if (bsid == INT16_MAX)
|
if (bsid == INT16_MAX)
|
||||||
continue; // block doesn't exist, keep going
|
continue; // Start block doesn't exist?
|
||||||
beid = W_CheckNumForNamePwad(blockend,(UINT16)i,0);
|
beid = W_CheckNumForNamePwad(blockend, (UINT16)i, 0);
|
||||||
// if block end doesn't exist, just search through everything
|
if (beid == INT16_MAX)
|
||||||
|
continue; // End block doesn't exist?
|
||||||
|
|
||||||
check = W_CheckNumForNamePwad(name,(UINT16)i,bsid);
|
check = W_CheckNumForNamePwad(name, (UINT16)i, bsid);
|
||||||
if (check < beid)
|
if (check < beid)
|
||||||
return (i<<16)+check; // found it, in our constraints
|
return (i<<16)+check; // found it, in our constraints
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
return LUMPERROR;
|
return LUMPERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,80 +1038,35 @@ size_t W_LumpLength(lumpnum_t lumpnum)
|
||||||
return W_LumpLengthPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum));
|
return W_LumpLengthPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reads bytes from the head of a lump, without doing decompression.
|
/* report a zlib or i/o error */
|
||||||
*
|
void zerr(int ret)
|
||||||
* \param wad Wad number to read from.
|
|
||||||
* \param lump Lump number to read from, within wad.
|
|
||||||
* \param dest Buffer in memory to serve as destination.
|
|
||||||
* \param size Number of bytes to read.
|
|
||||||
* \param offest Number of bytes to offset.
|
|
||||||
* \return Number of bytes read (should equal size).
|
|
||||||
* \sa W_ReadLumpHeader
|
|
||||||
*/
|
|
||||||
static size_t W_RawReadLumpHeader(UINT16 wad, UINT16 lump, void *dest, size_t size, size_t offset)
|
|
||||||
{
|
{
|
||||||
size_t bytesread;
|
CONS_Printf("zpipe: ");
|
||||||
lumpinfo_t *l;
|
switch (ret) {
|
||||||
FILE *handle;
|
case Z_ERRNO:
|
||||||
|
if (ferror(stdin))
|
||||||
l = wadfiles[wad]->lumpinfo + lump;
|
CONS_Printf("error reading stdin\n");
|
||||||
|
if (ferror(stdout))
|
||||||
handle = wadfiles[wad]->handle;
|
CONS_Printf("error writing stdout\n");
|
||||||
|
break;
|
||||||
fseek(handle, (long)(l->position + offset), SEEK_SET);
|
case Z_STREAM_ERROR:
|
||||||
bytesread = fread(dest, 1, size, handle);
|
CONS_Printf("invalid compression level\n");
|
||||||
|
break;
|
||||||
return bytesread;
|
case Z_DATA_ERROR:
|
||||||
}
|
CONS_Printf("invalid or incomplete deflate data\n");
|
||||||
|
break;
|
||||||
// Read a compressed lump; return it in newly Z_Malloc'd memory.
|
case Z_MEM_ERROR:
|
||||||
// wad is number of wad file, lump is number of lump in wad.
|
CONS_Printf("out of memory\n");
|
||||||
static void *W_ReadCompressedLump(UINT16 wad, UINT16 lump)
|
break;
|
||||||
{
|
case Z_VERSION_ERROR:
|
||||||
#ifdef ZWAD
|
CONS_Printf("zlib version mismatch!\n");
|
||||||
char *compressed, *data;
|
|
||||||
const lumpinfo_t *l = &wadfiles[wad]->lumpinfo[lump];
|
|
||||||
size_t retval;
|
|
||||||
|
|
||||||
compressed = Z_Malloc(l->disksize, PU_STATIC, NULL);
|
|
||||||
data = Z_Malloc(l->size, PU_STATIC, NULL);
|
|
||||||
if (W_RawReadLumpHeader(wad, lump, compressed, l->disksize, 0)
|
|
||||||
< l->disksize)
|
|
||||||
{
|
|
||||||
I_Error("wad %d, lump %d: cannot read compressed data",
|
|
||||||
wad, lump);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = lzf_decompress(compressed, l->disksize, data, l->size);
|
|
||||||
#ifndef AVOID_ERRNO
|
|
||||||
if (retval == 0 && errno == E2BIG)
|
|
||||||
{
|
|
||||||
I_Error("wad %d, lump %d: compressed data too big "
|
|
||||||
"(bigger than %s)", wad, lump, sizeu1(l->size));
|
|
||||||
}
|
|
||||||
else if (retval == 0 && errno == EINVAL)
|
|
||||||
I_Error("wad %d, lump %d: invalid compressed data", wad, lump);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if (retval != l->size)
|
|
||||||
{
|
|
||||||
I_Error("wad %d, lump %d: decompressed to wrong number of "
|
|
||||||
"bytes (expected %s, got %s)", wad, lump,
|
|
||||||
sizeu1(l->size), sizeu2(retval));
|
|
||||||
}
|
|
||||||
Z_Free(compressed);
|
|
||||||
return data;
|
|
||||||
#else
|
|
||||||
(void)wad;
|
|
||||||
(void)lump;
|
|
||||||
//I_Error("ZWAD files not supported on this platform.");
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reads bytes from the head of a lump.
|
/** Reads bytes from the head of a lump.
|
||||||
* Note: If the lump is compressed, the whole thing has to be read anyway.
|
* Note: If the lump is compressed, the whole thing has to be read anyway.
|
||||||
*
|
*
|
||||||
|
* \param wad Wad number to read from.
|
||||||
* \param lump Lump number to read from.
|
* \param lump Lump number to read from.
|
||||||
* \param dest Buffer in memory to serve as destination.
|
* \param dest Buffer in memory to serve as destination.
|
||||||
* \param size Number of bytes to read.
|
* \param size Number of bytes to read.
|
||||||
|
@ -800,6 +1077,8 @@ static void *W_ReadCompressedLump(UINT16 wad, UINT16 lump)
|
||||||
size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, size_t offset)
|
size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, size_t offset)
|
||||||
{
|
{
|
||||||
size_t lumpsize;
|
size_t lumpsize;
|
||||||
|
lumpinfo_t *l;
|
||||||
|
FILE *handle;
|
||||||
|
|
||||||
if (!TestValidLump(wad,lump))
|
if (!TestValidLump(wad,lump))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -813,17 +1092,112 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
||||||
if (!size || size+offset > lumpsize)
|
if (!size || size+offset > lumpsize)
|
||||||
size = lumpsize - offset;
|
size = lumpsize - offset;
|
||||||
|
|
||||||
if (wadfiles[wad]->lumpinfo[lump].compressed)
|
// Let's get the raw lump data.
|
||||||
|
// We setup the desired file handle to read the lump data.
|
||||||
|
l = wadfiles[wad]->lumpinfo + lump;
|
||||||
|
handle = wadfiles[wad]->handle;
|
||||||
|
fseek(handle, (long)(l->position + offset), SEEK_SET);
|
||||||
|
|
||||||
|
// But let's not copy it yet. We support different compression formats on lumps, so we need to take that into account.
|
||||||
|
switch(wadfiles[wad]->lumpinfo[lump].compression)
|
||||||
{
|
{
|
||||||
UINT8 *data;
|
case CM_NOCOMPRESSION: // If it's uncompressed, we directly write the data into our destination, and return the bytes read.
|
||||||
data = W_ReadCompressedLump(wad, lump);
|
return fread(dest, 1, size, handle);
|
||||||
if (!data) return 0;
|
case CM_LZF: // Is it LZF compressed? Used by ZWADs.
|
||||||
M_Memcpy(dest, data+offset, size);
|
{
|
||||||
Z_Free(data);
|
#ifdef ZWAD
|
||||||
|
char *rawData; // The lump's raw data.
|
||||||
|
char *decData; // Lump's decompressed real data.
|
||||||
|
size_t retval; // Helper var, lzf_decompress returns 0 when an error occurs.
|
||||||
|
|
||||||
|
rawData = Z_Malloc(l->disksize, PU_STATIC, NULL);
|
||||||
|
decData = Z_Malloc(l->size, PU_STATIC, NULL);
|
||||||
|
|
||||||
|
if (fread(rawData, 1, l->disksize, handle) < l->disksize)
|
||||||
|
I_Error("wad %d, lump %d: cannot read compressed data", wad, lump);
|
||||||
|
retval = lzf_decompress(rawData, l->disksize, decData, l->size);
|
||||||
|
#ifndef AVOID_ERRNO
|
||||||
|
if (retval == 0 && errno == E2BIG) // errno is a global var set by the lzf functions when something goes wrong.
|
||||||
|
{
|
||||||
|
I_Error("wad %d, lump %d: compressed data too big (bigger than %s)", wad, lump, sizeu1(l->size));
|
||||||
|
}
|
||||||
|
else if (retval == 0 && errno == EINVAL)
|
||||||
|
I_Error("wad %d, lump %d: invalid compressed data", wad, lump);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (retval != l->size)
|
||||||
|
{
|
||||||
|
I_Error("wad %d, lump %d: decompressed to wrong number of bytes (expected %s, got %s)", wad, lump, sizeu1(l->size), sizeu2(retval));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
(void)wad;
|
||||||
|
(void)lump;
|
||||||
|
//I_Error("ZWAD files not supported on this platform.");
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
if (!decData) // Did we get no data at all?
|
||||||
|
return 0;
|
||||||
|
M_Memcpy(dest, decData + offset, size);
|
||||||
|
Z_Free(rawData);
|
||||||
|
Z_Free(decData);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
case CM_DEFLATE: // Is it compressed via DEFLATE? Very common in ZIPs/PK3s, also what most doom-related editors support.
|
||||||
|
{
|
||||||
|
z_const Bytef *rawData; // The lump's raw data.
|
||||||
|
Bytef *decData; // Lump's decompressed real data.
|
||||||
|
|
||||||
|
int zErr; // Helper var.
|
||||||
|
z_stream strm;
|
||||||
|
unsigned long rawSize = l->disksize;
|
||||||
|
unsigned long decSize = l->size;
|
||||||
|
|
||||||
|
rawData = Z_Malloc(rawSize, PU_STATIC, NULL);
|
||||||
|
decData = Z_Malloc(decSize, PU_STATIC, NULL);
|
||||||
|
|
||||||
|
if (fread(rawData, 1, rawSize, handle) < rawSize)
|
||||||
|
I_Error("wad %d, lump %d: cannot read compressed data", wad, lump);
|
||||||
|
|
||||||
|
strm.zalloc = Z_NULL;
|
||||||
|
strm.zfree = Z_NULL;
|
||||||
|
strm.opaque = Z_NULL;
|
||||||
|
|
||||||
|
strm.total_in = strm.avail_in = rawSize;
|
||||||
|
strm.total_out = strm.avail_out = decSize;
|
||||||
|
|
||||||
|
strm.next_in = rawData;
|
||||||
|
strm.next_out = decData;
|
||||||
|
|
||||||
|
zErr = inflateInit2(&strm, -15);
|
||||||
|
if (zErr == Z_OK)
|
||||||
|
{
|
||||||
|
zErr = inflate(&strm, Z_FINISH);
|
||||||
|
if (zErr == Z_STREAM_END)
|
||||||
|
{
|
||||||
|
M_Memcpy(dest, decData, size);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return W_RawReadLumpHeader(wad, lump, dest, size, offset);
|
{
|
||||||
|
size = 0;
|
||||||
|
zerr(zErr);
|
||||||
|
(void)inflateEnd(&strm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CONS_Printf("whopet\n");
|
||||||
|
size = 0;
|
||||||
|
zerr(zErr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Z_Free(rawData);
|
||||||
|
Z_Free(decData);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
I_Error("wad %d, lump %d: unsupported compression type!", wad, lump);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t W_ReadLumpHeader(lumpnum_t lumpnum, void *dest, size_t size, size_t offset)
|
size_t W_ReadLumpHeader(lumpnum_t lumpnum, void *dest, size_t size, size_t offset)
|
||||||
|
@ -1107,12 +1481,12 @@ static int W_VerifyFile(const char *filename, lumpchecklist_t *checklist,
|
||||||
if ((handle = W_OpenWadFile(&filename, false)) == NULL)
|
if ((handle = W_OpenWadFile(&filename, false)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// detect dehacked file with the "soc" extension
|
// detect wad file by the absence of the other supported extensions
|
||||||
if (stricmp(&filename[strlen(filename) - 4], ".soc") != 0
|
if (stricmp(&filename[strlen(filename) - 4], ".soc")
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
&& stricmp(&filename[strlen(filename) - 4], ".lua") != 0
|
&& stricmp(&filename[strlen(filename) - 4], ".lua")
|
||||||
#endif
|
#endif
|
||||||
)
|
&& stricmp(&filename[strlen(filename) - 4], ".pk3"))
|
||||||
{
|
{
|
||||||
// assume wad file
|
// assume wad file
|
||||||
wadinfo_t header;
|
wadinfo_t header;
|
||||||
|
|
33
src/w_wad.h
33
src/w_wad.h
|
@ -34,14 +34,33 @@ typedef struct
|
||||||
UINT32 infotableofs; // the 'directory' of resources
|
UINT32 infotableofs; // the 'directory' of resources
|
||||||
} wadinfo_t;
|
} wadinfo_t;
|
||||||
|
|
||||||
|
// a raw entry of the wad directory
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UINT32 filepos; // file offset of the resource
|
||||||
|
UINT32 size; // size of the resource
|
||||||
|
char name[8]; // name of the resource
|
||||||
|
} ATTRPACK filelump_t;
|
||||||
|
|
||||||
|
// Available compression methods for lumps.
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
CM_NOCOMPRESSION,
|
||||||
|
CM_DEFLATE,
|
||||||
|
CM_LZF,
|
||||||
|
CM_UNSUPPORTED
|
||||||
|
} compmethod;
|
||||||
|
|
||||||
// a memory entry of the wad directory
|
// a memory entry of the wad directory
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned long position; // filelump_t filepos
|
unsigned long position; // filelump_t filepos
|
||||||
unsigned long disksize; // filelump_t size
|
unsigned long disksize; // filelump_t size
|
||||||
char name[9]; // filelump_t name[]
|
char name[9]; // filelump_t name[]
|
||||||
|
char *name2; // Used by PK3s. Dynamically allocated name.
|
||||||
size_t size; // real (uncompressed) size
|
size_t size; // real (uncompressed) size
|
||||||
INT32 compressed; // i
|
INT32 compressed; // i
|
||||||
|
compmethod compression; // lump compression method
|
||||||
} lumpinfo_t;
|
} lumpinfo_t;
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
@ -58,9 +77,13 @@ typedef struct
|
||||||
#include "m_aatree.h"
|
#include "m_aatree.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Resource type of the WAD. Yeah, I know this sounds dumb, but I'll leave it like this until I clean up the code further.
|
||||||
|
enum restype {RET_WAD, RET_PK3};
|
||||||
|
|
||||||
typedef struct wadfile_s
|
typedef struct wadfile_s
|
||||||
{
|
{
|
||||||
char *filename;
|
char *filename;
|
||||||
|
enum restype type;
|
||||||
lumpinfo_t *lumpinfo;
|
lumpinfo_t *lumpinfo;
|
||||||
lumpcache_t *lumpcache;
|
lumpcache_t *lumpcache;
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
|
@ -86,7 +109,7 @@ void W_Shutdown(void);
|
||||||
// Opens a WAD file. Returns the FILE * handle for the file, or NULL if not found or could not be opened
|
// Opens a WAD file. Returns the FILE * handle for the file, or NULL if not found or could not be opened
|
||||||
FILE *W_OpenWadFile(const char **filename, boolean useerrors);
|
FILE *W_OpenWadFile(const char **filename, boolean useerrors);
|
||||||
// Load and add a wadfile to the active wad files, returns numbers of lumps, INT16_MAX on error
|
// Load and add a wadfile to the active wad files, returns numbers of lumps, INT16_MAX on error
|
||||||
UINT16 W_LoadWadFile(const char *filename);
|
UINT16 W_InitFile(const char *filename);
|
||||||
|
|
||||||
// W_InitMultipleFiles returns 1 if all is okay, 0 otherwise,
|
// W_InitMultipleFiles returns 1 if all is okay, 0 otherwise,
|
||||||
// so that it stops with a message if a file was not found, but not if all is okay.
|
// so that it stops with a message if a file was not found, but not if all is okay.
|
||||||
|
@ -96,6 +119,12 @@ const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump);
|
||||||
const char *W_CheckNameForNum(lumpnum_t lumpnum);
|
const char *W_CheckNameForNum(lumpnum_t lumpnum);
|
||||||
|
|
||||||
UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump); // checks only in one pwad
|
UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump); // checks only in one pwad
|
||||||
|
|
||||||
|
UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump);
|
||||||
|
UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump);
|
||||||
|
UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump);
|
||||||
|
|
||||||
|
lumpnum_t W_CheckNumForMap(const char *name);
|
||||||
lumpnum_t W_CheckNumForName(const char *name);
|
lumpnum_t W_CheckNumForName(const char *name);
|
||||||
lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR
|
lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR
|
||||||
lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, const char *blockend);
|
lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, const char *blockend);
|
||||||
|
@ -104,6 +133,8 @@ UINT8 W_LumpExists(const char *name); // Lua uses this.
|
||||||
size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump);
|
size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump);
|
||||||
size_t W_LumpLength(lumpnum_t lumpnum);
|
size_t W_LumpLength(lumpnum_t lumpnum);
|
||||||
|
|
||||||
|
void zerr(int ret); // zlib error checking
|
||||||
|
|
||||||
size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, size_t offset);
|
size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, size_t offset);
|
||||||
size_t W_ReadLumpHeader(lumpnum_t lump, void *dest, size_t size, size_t offest); // read all or a part of a lump
|
size_t W_ReadLumpHeader(lumpnum_t lump, void *dest, size_t size, size_t offest); // read all or a part of a lump
|
||||||
void W_ReadLumpPwad(UINT16 wad, UINT16 lump, void *dest);
|
void W_ReadLumpPwad(UINT16 wad, UINT16 lump, void *dest);
|
||||||
|
|
Loading…
Reference in a new issue