Started to work towards PK3 support.
-Tweaked compression conditional to a switch-case format, looking towards adding several comrpession algorithms; haven't removed the previous "compressed" boolean yet. -Added dynamically allocated name strings for lumps; haven't removed the previous name field. -Added rudimentary PK3 central directory recognition; nothing is actually loaded in the end.
This commit is contained in:
parent
5608c4b4e7
commit
afba4b2abd
|
@ -2881,7 +2881,7 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
camera.angle = FixedAngle((fixed_t)thing->angle << FRACBITS);
|
camera.angle = FixedAngle((fixed_t)thing->angle << FRACBITS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Salt: CV_ClearChangedFlags() messes with your settings :(
|
// Salt: CV_ClearChangedFlags() messes with your settings :(
|
||||||
/*if (!cv_cam_height.changed)
|
/*if (!cv_cam_height.changed)
|
||||||
CV_Set(&cv_cam_height, cv_cam_height.defaultvalue);
|
CV_Set(&cv_cam_height, cv_cam_height.defaultvalue);
|
||||||
|
|
134
src/w_wad.c
134
src/w_wad.c
|
@ -115,6 +115,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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,6 +342,8 @@ UINT16 W_LoadWadFile(const char *filename)
|
||||||
// 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.
|
||||||
|
//wadfile->restype = 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;
|
||||||
|
@ -347,6 +351,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
|
||||||
|
@ -355,6 +363,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.
|
||||||
|
//wadfile->restype = 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;
|
||||||
|
@ -362,11 +372,99 @@ 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"))
|
||||||
|
{
|
||||||
|
long centralDirPos;
|
||||||
|
long handlePos;
|
||||||
|
long size;
|
||||||
|
char *sigBuffer;
|
||||||
|
|
||||||
|
//wadfile->restype = 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);
|
||||||
|
|
||||||
|
// We must look for the central directory through the file.
|
||||||
|
rewind(handle);
|
||||||
|
sigBuffer = malloc(sizeof(char)*4);
|
||||||
|
for (centralDirPos = 0; centralDirPos < size - 4; centralDirPos++)
|
||||||
|
{
|
||||||
|
fread(sigBuffer, 1, 4, handle);
|
||||||
|
if (memcmp(sigBuffer, "\x50\x4b\x01\x02", 4) == 0)
|
||||||
|
{
|
||||||
|
CONS_Printf("Found PK3 central directory at position %ld.\n", centralDirPos);
|
||||||
|
fseek(handle, -4, SEEK_CUR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fseek(handle, -3, SEEK_CUR); // Backwards 3 steps, since fread advances after giving the data.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error if we couldn't find the central directory at all. It likely means this is not a ZIP/PK3 file.
|
||||||
|
if (centralDirPos + 4 == size)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, "No central directory inside PK3! File may be corrupted or incomplete.\n");
|
||||||
|
free(sigBuffer);
|
||||||
|
return INT16_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
CONS_Printf("Now finding central directory file headers...\n");
|
||||||
|
for (handlePos = centralDirPos; handlePos < size - 3; handlePos++)
|
||||||
|
{
|
||||||
|
fread(sigBuffer, 1, 4, handle);
|
||||||
|
if (!memcmp(sigBuffer, "\x50\x4b\x01\x02", 4)) // Got a central dir file header.
|
||||||
|
{
|
||||||
|
char *eName;
|
||||||
|
unsigned short int eNameLen = 0;
|
||||||
|
unsigned short int eXFieldLen = 0;
|
||||||
|
unsigned short int eCommentLen = 0;
|
||||||
|
CONS_Printf("Entry at %ld:\n", handlePos);
|
||||||
|
// We get the variable length fields.
|
||||||
|
fseek(handle, 24, SEEK_CUR);
|
||||||
|
fscanf(handle, "%hu %hu %hu", &eNameLen, &eXFieldLen, &eCommentLen);
|
||||||
|
CONS_Printf("Name length is %u.\n", eNameLen);
|
||||||
|
|
||||||
|
// We jump straight to the name field now.
|
||||||
|
fseek(handle, 10, SEEK_CUR);
|
||||||
|
eName = malloc(sizeof(char)*(eNameLen + 1));
|
||||||
|
fgets(eName, eNameLen, handle);
|
||||||
|
CONS_Printf("%s\n", eName);
|
||||||
|
free(eName);
|
||||||
|
}
|
||||||
|
else if (!memcmp(sigBuffer, "\x50\x4b\x05\x06", 4)) // Found the central dir end signature, stop seeking.
|
||||||
|
{
|
||||||
|
CONS_Printf("Found central directory end at position %ld.\n", handlePos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fseek(handle, -3, SEEK_CUR);
|
||||||
|
}
|
||||||
|
// We reached way past beyond the file size.
|
||||||
|
// This means we couldn't find the central directory end signature, and thus the file might be broken.
|
||||||
|
if (handlePos + 3 == size)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, "No central dir end inside PK3! File may be corrupted or incomplete.\n");
|
||||||
|
free(sigBuffer);
|
||||||
|
return INT16_MAX;
|
||||||
|
}
|
||||||
|
free(sigBuffer);
|
||||||
|
return INT16_MAX;
|
||||||
|
}
|
||||||
|
// assume wad file
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// assume wad file
|
//wadfile->restype = RET_WAD;
|
||||||
|
|
||||||
wadinfo_t header;
|
wadinfo_t header;
|
||||||
lumpinfo_t *lump_p;
|
lumpinfo_t *lump_p;
|
||||||
filelump_t *fileinfo;
|
filelump_t *fileinfo;
|
||||||
|
@ -427,19 +525,29 @@ UINT16 W_LoadWadFile(const char *filename)
|
||||||
{
|
{
|
||||||
lump_p->size = realsize;
|
lump_p->size = realsize;
|
||||||
lump_p->compressed = 1;
|
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->compressed = 0;
|
||||||
|
lump_p->compression = CM_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
lump_p->position += 4;
|
lump_p->position += 4;
|
||||||
lump_p->disksize -= 4;
|
lump_p->disksize -= 4;
|
||||||
}
|
}
|
||||||
else lump_p->compressed = 0;
|
else
|
||||||
|
{
|
||||||
|
lump_p->compressed = 0;
|
||||||
|
lump_p->compression = CM_NONE;
|
||||||
|
}
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -843,17 +951,21 @@ 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)
|
//
|
||||||
|
switch(wadfiles[wad]->lumpinfo[lump].compressed)
|
||||||
{
|
{
|
||||||
UINT8 *data;
|
case CM_LZF:
|
||||||
data = W_ReadCompressedLump(wad, lump);
|
{
|
||||||
if (!data) return 0;
|
UINT8 *data;
|
||||||
M_Memcpy(dest, data+offset, size);
|
data = W_ReadCompressedLump(wad, lump);
|
||||||
Z_Free(data);
|
if (!data) return 0;
|
||||||
return size;
|
M_Memcpy(dest, data+offset, size);
|
||||||
}
|
Z_Free(data);
|
||||||
else
|
return size;
|
||||||
|
}
|
||||||
|
default:
|
||||||
return W_RawReadLumpHeader(wad, lump, dest, size, offset);
|
return W_RawReadLumpHeader(wad, lump, dest, size, offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -34,14 +34,19 @@ typedef struct
|
||||||
UINT32 infotableofs; // the 'directory' of resources
|
UINT32 infotableofs; // the 'directory' of resources
|
||||||
} wadinfo_t;
|
} wadinfo_t;
|
||||||
|
|
||||||
|
// Available compression methods for lumps.
|
||||||
|
enum compmethod{CM_NONE, CM_LZF};
|
||||||
|
|
||||||
// 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; // Dynamically allocated name.
|
||||||
size_t size; // real (uncompressed) size
|
size_t size; // real (uncompressed) size
|
||||||
INT32 compressed; // i
|
INT32 compressed; // i
|
||||||
|
enum compmethod compression; // lump compression method
|
||||||
} lumpinfo_t;
|
} lumpinfo_t;
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
@ -58,9 +63,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 restype;
|
||||||
lumpinfo_t *lumpinfo;
|
lumpinfo_t *lumpinfo;
|
||||||
lumpcache_t *lumpcache;
|
lumpcache_t *lumpcache;
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
|
|
Loading…
Reference in New Issue