mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-22 02:42:20 +00:00
More PK3 work. Now we're getting somewhere.
-DEFLATE-compressed lumps work properly now. -All "big" lumps are supported now with the exception of WAD maps. Notes: -Compiler spits out a shitload of warnings still. -Individual lump reading clashes with folders of the same name (see TEXTURES lump, and the Textures/ folder). Signed-off-by: Nevur <apophycens@gmail.com>
This commit is contained in:
parent
8ef6d6fd9e
commit
ea2846394e
4 changed files with 152 additions and 77 deletions
|
@ -3105,9 +3105,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
|||
// UINT16 flaPos, flaNum = 0;
|
||||
// UINT16 mapPos, mapNum = 0;
|
||||
|
||||
|
||||
|
||||
if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX)
|
||||
if ((numlumps = W_InitFile(wadfilename)) == INT16_MAX)
|
||||
{
|
||||
CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename);
|
||||
return false;
|
||||
|
@ -3126,7 +3124,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
|||
{
|
||||
lumpinfo++;
|
||||
*start = ++i;
|
||||
for (i; i < numlumps; i++, lumpinfo++)
|
||||
for (; i < numlumps; i++, lumpinfo++)
|
||||
{
|
||||
if (strnicmp(lumpinfo->name2, folName, strlen(folName)))
|
||||
{
|
||||
|
@ -3172,6 +3170,8 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
|||
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();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
63
src/r_data.c
63
src/r_data.c
|
@ -571,13 +571,14 @@ void R_LoadTextures(void)
|
|||
{
|
||||
texstart = W_CheckNumForFullNamePK3("textures/", (UINT16)w, 0) + 1;
|
||||
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||
texturesLumpPos = W_CheckNumForFullNamePK3("textures", (UINT16)w, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
|
||||
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)
|
||||
{
|
||||
|
@ -1190,12 +1191,64 @@ static void R_InitExtraColormaps(void)
|
|||
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 lump = W_CheckNumForNameInBlock(name, "F_START", "F_END");
|
||||
if (lump == LUMPERROR)
|
||||
lump = W_CheckNumForNameInBlock(name, "FF_START", "FF_END"); // deutex, some other old things
|
||||
INT32 i;
|
||||
lumpnum_t lump;
|
||||
lumpnum_t start;
|
||||
lumpnum_t end;
|
||||
|
||||
// Scan wad files backwards so patched flats take preference.
|
||||
for (i = numwadfiles - 1; i >= 0; i--)
|
||||
{
|
||||
// WAD type? use markers.
|
||||
if (wadfiles[i]->type == RET_WAD)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
else if (wadfiles[i]->type == RET_PK3)
|
||||
{
|
||||
start = W_CheckNumForFullNamePK3("Flats/", i, 0);
|
||||
if (start == INT16_MAX)
|
||||
continue;
|
||||
end = W_CheckNumForFolderEndPK3("Flats/", 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 (strcmp(name, SKYFLATNAME))
|
||||
|
|
154
src/w_wad.c
154
src/w_wad.c
|
@ -291,7 +291,7 @@ static void W_InvalidateLumpnumCache(void)
|
|||
//
|
||||
// Can now load dehacked files (.soc)
|
||||
//
|
||||
UINT16 W_LoadWadFile(const char *filename)
|
||||
UINT16 W_InitFile(const char *filename)
|
||||
{
|
||||
FILE *handle;
|
||||
lumpinfo_t *lumpinfo;
|
||||
|
@ -412,12 +412,11 @@ UINT16 W_LoadWadFile(const char *filename)
|
|||
numlumps = 0;
|
||||
|
||||
type = RET_PK3;
|
||||
CONS_Alert(CONS_NOTICE, "PK3 file detected.\n");
|
||||
|
||||
// Obtain the file's size.
|
||||
fseek(handle, 0, SEEK_END);
|
||||
size = ftell(handle);
|
||||
CONS_Printf("PK3 size is: %ld\n", size);
|
||||
CONS_Debug(DBG_SETUP, "PK3 size is: %ld\n", size);
|
||||
|
||||
// We must look for the central directory through the file.
|
||||
// All of the central directory entry headers have a signature of 0x50 0x4b 0x01 0x02.
|
||||
|
@ -435,7 +434,7 @@ UINT16 W_LoadWadFile(const char *filename)
|
|||
{
|
||||
matched = TRUE;
|
||||
fseek(handle, -4, SEEK_CUR);
|
||||
CONS_Printf("Found PK3 central directory at position %ld.\n", ftell(handle));
|
||||
CONS_Debug(DBG_SETUP, "Found PK3 central directory at position %ld.\n", ftell(handle));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -451,7 +450,7 @@ UINT16 W_LoadWadFile(const char *filename)
|
|||
// 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_Printf("Now finding central directory file headers...\n");
|
||||
CONS_Debug(DBG_SETUP, "Now finding central directory file headers...\n");
|
||||
while(ftell(handle) < size - 4) // Make sure we don't go past the file size!
|
||||
{
|
||||
fread(curHeader, 1, 4, handle);
|
||||
|
@ -477,10 +476,10 @@ UINT16 W_LoadWadFile(const char *filename)
|
|||
// We get the compression type indicator value.
|
||||
fseek(handle, 6, SEEK_CUR);
|
||||
fread(&eCompression, 1, 2, handle);
|
||||
// Get the
|
||||
// Get the size
|
||||
fseek(handle, 8, SEEK_CUR);
|
||||
fread(&eSize, 1, 4, handle);
|
||||
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);
|
||||
|
@ -490,7 +489,6 @@ UINT16 W_LoadWadFile(const char *filename)
|
|||
|
||||
eName = malloc(sizeof(char)*(eNameLen + 1));
|
||||
fgets(eName, eNameLen + 1, handle);
|
||||
CONS_Printf("File %s at: %ld\n", eName, ftell(handle));
|
||||
if (numlumps == 0) // First lump? Let's allocate the first lumpinfo block.
|
||||
lumpinfo = Z_Malloc(sizeof(*lumpinfo), PU_STATIC, NULL);
|
||||
else // Otherwise, reallocate and increase by 1. Might not be optimal, though...
|
||||
|
@ -541,6 +539,7 @@ UINT16 W_LoadWadFile(const char *filename)
|
|||
lumpinfo[numlumps].compression = CM_UNSUPPORTED;
|
||||
break;
|
||||
}
|
||||
CONS_Debug(DBG_SETUP, "File %s, data begins at: %ld\n", eName, lumpinfo[numlumps].position);
|
||||
fseek(handle, eXFieldLen + eCommentLen, SEEK_CUR); // We skip to where we expect the next central directory entry or end marker to be.
|
||||
numlumps++;
|
||||
free(eName);
|
||||
|
@ -548,7 +547,7 @@ UINT16 W_LoadWadFile(const char *filename)
|
|||
// We found the central directory end signature?
|
||||
else if (!strncmp(curHeader, endPat, 4))
|
||||
{
|
||||
CONS_Printf("Central directory end signature found at: %ld\n", ftell(handle));
|
||||
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.
|
||||
|
@ -760,7 +759,7 @@ INT32 W_InitMultipleFiles(char **filenames)
|
|||
for (; *filenames; 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)
|
||||
|
@ -850,8 +849,6 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump)
|
|||
if (strnicmp(name, lump_p->name2, strlen(name)))
|
||||
break;
|
||||
}
|
||||
// Not found at all?
|
||||
CONS_Printf("W_CheckNumForFolderEndPK3: Folder %s end at %d.\n", name, i);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -865,7 +862,6 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump)
|
|||
{
|
||||
if (!strnicmp(name, lump_p->name2, strlen(name)))
|
||||
{
|
||||
CONS_Printf("W_CheckNumForNamePK3: Found %s at %d.\n", name, i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -943,15 +939,20 @@ lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, con
|
|||
// scan wad files backwards so patch lump files take precedence
|
||||
for (i = numwadfiles - 1; i >= 0; i--)
|
||||
{
|
||||
bsid = W_CheckNumForNamePwad(blockstart,(UINT16)i,0);
|
||||
if (bsid == INT16_MAX)
|
||||
continue; // block doesn't exist, keep going
|
||||
beid = W_CheckNumForNamePwad(blockend,(UINT16)i,0);
|
||||
// if block end doesn't exist, just search through everything
|
||||
if (wadfiles[i]->type == RET_WAD)
|
||||
{
|
||||
bsid = W_CheckNumForNamePwad(blockstart, (UINT16)i, 0);
|
||||
if (bsid == INT16_MAX)
|
||||
continue; // Start block doesn't exist?
|
||||
beid = W_CheckNumForNamePwad(blockend, (UINT16)i, 0);
|
||||
if (beid == INT16_MAX)
|
||||
continue; // End block doesn't exist?
|
||||
|
||||
check = W_CheckNumForNamePwad(name, (UINT16)i, bsid);
|
||||
if (check < beid)
|
||||
return (i<<16)+check; // found it, in our constraints
|
||||
}
|
||||
|
||||
check = W_CheckNumForNamePwad(name,(UINT16)i,bsid);
|
||||
if (check < beid)
|
||||
return (i<<16)+check; // found it, in our constraints
|
||||
}
|
||||
return LUMPERROR;
|
||||
}
|
||||
|
@ -988,6 +989,31 @@ size_t W_LumpLength(lumpnum_t lumpnum)
|
|||
return W_LumpLengthPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum));
|
||||
}
|
||||
|
||||
/* report a zlib or i/o error */
|
||||
void zerr(int ret)
|
||||
{
|
||||
CONS_Printf("zpipe: ", stderr);
|
||||
switch (ret) {
|
||||
case Z_ERRNO:
|
||||
if (ferror(stdin))
|
||||
CONS_Printf("error reading stdin\n", stderr);
|
||||
if (ferror(stdout))
|
||||
CONS_Printf("error writing stdout\n", stderr);
|
||||
break;
|
||||
case Z_STREAM_ERROR:
|
||||
CONS_Printf("invalid compression level\n", stderr);
|
||||
break;
|
||||
case Z_DATA_ERROR:
|
||||
CONS_Printf("invalid or incomplete deflate data\n", stderr);
|
||||
break;
|
||||
case Z_MEM_ERROR:
|
||||
CONS_Printf("out of memory\n", stderr);
|
||||
break;
|
||||
case Z_VERSION_ERROR:
|
||||
CONS_Printf("zlib version mismatch!\n", stderr);
|
||||
}
|
||||
}
|
||||
|
||||
/** Reads bytes from the head of a lump.
|
||||
* Note: If the lump is compressed, the whole thing has to be read anyway.
|
||||
*
|
||||
|
@ -1069,59 +1095,55 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
|||
}
|
||||
case CM_DEFLATE: // Is it compressed via DEFLATE? Very common in ZIPs/PK3s, also what most doom-related editors support.
|
||||
{
|
||||
int ret;
|
||||
unsigned have;
|
||||
z_stream strm;
|
||||
unsigned char in[16384];
|
||||
unsigned char out[16384];
|
||||
char *rawData; // The lump's raw data.
|
||||
char *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);
|
||||
|
||||
/* allocate inflate state */
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
strm.avail_in = 0;
|
||||
strm.next_in = Z_NULL;
|
||||
ret = inflateInit(&strm);
|
||||
if (ret != Z_OK)
|
||||
return ret;
|
||||
|
||||
/* decompress until deflate stream ends or end of file */
|
||||
do {
|
||||
strm.avail_in = fread(in, 1, 16384, handle);
|
||||
if (ferror(handle)) {
|
||||
(void)inflateEnd(&strm);
|
||||
return Z_ERRNO;
|
||||
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);
|
||||
}
|
||||
if (strm.avail_in == 0)
|
||||
break;
|
||||
strm.next_in = in;
|
||||
else
|
||||
{
|
||||
size = 0;
|
||||
zerr(zErr);
|
||||
(void)inflateEnd(&strm);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf("whopet\n");
|
||||
size = 0;
|
||||
zerr(zErr);
|
||||
}
|
||||
|
||||
/* run inflate() on input until output buffer not full */
|
||||
do {
|
||||
Z_Free(rawData);
|
||||
Z_Free(decData);
|
||||
|
||||
strm.avail_out = 16384;
|
||||
strm.next_out = out;
|
||||
|
||||
ret = inflate(&strm, Z_NO_FLUSH);
|
||||
//assert(ret != Z_STREAM_ERROR); /* state not clobbered */
|
||||
switch (ret) {
|
||||
case Z_NEED_DICT:
|
||||
ret = Z_DATA_ERROR; /* and fall through */
|
||||
case Z_DATA_ERROR:
|
||||
case Z_MEM_ERROR:
|
||||
(void)inflateEnd(&strm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
have = 16384 - strm.avail_out;
|
||||
memcpy(dest, out, have);
|
||||
} while (strm.avail_out == 0);
|
||||
|
||||
/* done when inflate() says it's done */
|
||||
} while (ret != Z_STREAM_END);
|
||||
|
||||
/* clean up and return */
|
||||
(void)inflateEnd(&strm);
|
||||
return size;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -43,7 +43,7 @@ typedef struct
|
|||
unsigned long position; // filelump_t filepos
|
||||
unsigned long disksize; // filelump_t size
|
||||
char name[9]; // filelump_t name[]
|
||||
char *name2; // Dynamically allocated name.
|
||||
char *name2; // Used by PK3s. Dynamically allocated name.
|
||||
size_t size; // real (uncompressed) size
|
||||
INT32 compressed; // i
|
||||
enum compmethod compression; // lump compression method
|
||||
|
@ -94,7 +94,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
|
||||
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
|
||||
UINT16 W_LoadWadFile(const char *filename);
|
||||
UINT16 W_InitFile(const char *filename);
|
||||
#ifdef DELFILE
|
||||
void W_UnloadWadFile(UINT16 num);
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue