Skip to content

Commit

Permalink
Merge branch 'r_openglmipmaps': Map loading time optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
aufau committed Jun 2, 2024
2 parents cd96799 + f7efb40 commit 9b7828d
Show file tree
Hide file tree
Showing 12 changed files with 900 additions and 434 deletions.
9 changes: 9 additions & 0 deletions CVARS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,15 @@ Client-Side

..
:Name: r_openglMipMaps
:Values: "0", "1"
:Default: "1"
:Description:
Enable / Disable OpenGL mipmap generation. Disable to restore
original downsampling algorithms.

..
:Name: r_saberGlow
:Values: "0", "1"
:Default: "1"
Expand Down
9 changes: 6 additions & 3 deletions src/botlib/l_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1384,10 +1384,13 @@ int MV_MenuPatchFile(const char *in, unsigned long inhash, const char *patch, ch
}

*out = (char *)GetMemory(outlen + 1);
for (size_t i = 0; i < menufile.size(); i++) {
strcat(*out, menufile.at(i).str.c_str());
strcat(*out, "\n");
char *pout = *out;
for (auto it = menufile.begin(); it != menufile.end(); ++it) {
Com_Memcpy(pout, it->str.c_str(), it->str.size());
pout += it->str.size();
*pout++ = '\n';
}
assert(pout == &(*out)[outlen]);
(*out)[outlen] = 0;

return outlen;
Expand Down
7 changes: 7 additions & 0 deletions src/cgame/tr_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,11 @@ typedef enum {
TC_S3TC_DXT
} textureCompression_t;

typedef enum {
QGL_VERSION_1_0,
QGL_VERSION_1_4
} qglVersion_t;

typedef struct {
char renderer_string[MAX_STRING_CHARS];
char vendor_string[MAX_STRING_CHARS];
Expand Down Expand Up @@ -337,6 +342,8 @@ typedef struct {
const char *version_string;
const char *extensions_string;

qglVersion_t glVersion;

int maxTextureSize; // queried from GL
int maxActiveTextures; // multitexture ability

Expand Down
2 changes: 1 addition & 1 deletion src/qcommon/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ int Com_Filter(const char *filter, const char *name, int casesensitive)
Com_FilterPath
============
*/
int Com_FilterPath(char *filter, char *name, int casesensitive)
int Com_FilterPath(char *filter, const char *name, int casesensitive)
{
int i;
char new_filter[MAX_QPATH];
Expand Down
38 changes: 6 additions & 32 deletions src/qcommon/files.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ or configs will never get loaded from disk!
#define MAX_FILEHASH_SIZE 1024

typedef struct fileInPack_s {
char *name; // name of the file
const char *name; // name of the file
unsigned int pos; // file info position in zip
unsigned int len; // uncompress file size
struct fileInPack_s* next; // next file in the hash
Expand Down Expand Up @@ -1967,11 +1967,9 @@ static pack_t *FS_LoadZipFile( char *zipfile, const char *basename, qboolean ass
char filename_inzip[MAX_ZPATH];
unz_file_info file_info;
ZPOS64_T i;
size_t len;
int hash;
int fs_numHeaderLongs;
int *fs_headerLongs;
char *namePtr;
int strLength;

fs_numHeaderLongs = 0;
Expand All @@ -1984,31 +1982,7 @@ static pack_t *FS_LoadZipFile( char *zipfile, const char *basename, qboolean ass

fs_packFiles += gi.number_entry;

len = 0;
unzGoToFirstFile(uf);
for (i = 0; i < gi.number_entry; i++)
{
err = unzGetCurrentFileInfo(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
if (err != UNZ_OK) {
break;
}
strLength = strlen(filename_inzip);
if ( assetsJKA ) {
// Ugly workarounds:
// - rename academy shader files to avoid collisions
// - rename academy sounds.cfg files to prevent them from overriding sounds of jk2 models that don't have a sounds.cfg
if ( strLength > 7 && !Q_stricmp(filename_inzip + strLength - 7, ".shader") ) {
len += 4; // "_jka"
} else if ( strLength > 15 && !Q_stricmpn(filename_inzip, "models/players/", 15) && !Q_stricmp(filename_inzip + strLength - 11, "/sounds.cfg") ) {
len += 4; // "_jka"
}
}
len += strLength + 1;
unzGoToNextFile(uf);
}

buildBuffer = (struct fileInPack_s *)Z_Malloc((int)((gi.number_entry * sizeof(fileInPack_t)) + len), TAG_FILESYS, qtrue);
namePtr = ((char *) buildBuffer) + gi.number_entry * sizeof( fileInPack_t );
buildBuffer = (struct fileInPack_s *)Z_Malloc((int)((gi.number_entry * sizeof(fileInPack_t))), TAG_FILESYS, qtrue);
fs_headerLongs = (int *)Z_Malloc( gi.number_entry * sizeof(int), TAG_FILESYS, qtrue );

// get the hash table size from the number of files in the zip
Expand Down Expand Up @@ -2060,9 +2034,7 @@ static pack_t *FS_LoadZipFile( char *zipfile, const char *basename, qboolean ass
}
Q_strlwr( filename_inzip );
hash = FS_HashFileName(filename_inzip, pack->hashSize);
buildBuffer[i].name = namePtr;
strcpy( buildBuffer[i].name, filename_inzip );
namePtr += strlen(filename_inzip) + 1;
buildBuffer[i].name = CopyString(filename_inzip, TAG_FILESYS);
// store the file position in the zip
buildBuffer[i].pos = unzGetOffset(uf);
buildBuffer[i].len = file_info.uncompressed_size;
Expand Down Expand Up @@ -2264,7 +2236,7 @@ static const char **FS_ListFilteredFiles( const char *path, const char *extensio
pak = search->pack;
buildBuffer = pak->buildBuffer;
for (i = 0; i < pak->numfiles; i++) {
char *name;
const char *name;
int zpathLen, depth;

// check for directory match
Expand Down Expand Up @@ -3053,6 +3025,7 @@ static void FS_AddGameDirectory( const char *path, const char *dir, qboolean ass
if (!found) {
// server has no interest in the file
unzClose(pak->handle);
Z_Free((void *)pak->buildBuffer->name);
Z_Free(pak->buildBuffer);
Z_Free(pak);
continue;
Expand Down Expand Up @@ -3304,6 +3277,7 @@ void FS_Shutdown( qboolean closemfp, qboolean keepModuleFiles ) {

if ( p->pack ) {
unzClose(p->pack->handle);
Z_Free( (void *)p->pack->buildBuffer->name );
Z_Free( p->pack->buildBuffer );
Z_Free( p->pack );
}
Expand Down
166 changes: 166 additions & 0 deletions src/qcommon/msg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1900,6 +1900,165 @@ void MSG_ReadDeltaPlayerstate(msg_t *msg, playerState_t *from, playerState_t *to
}
}

// Huffman code data structure serialization

#pragma pack(push, 1)
typedef struct {
int16_t left, right, parent;
int16_t symbol;
} huffNodeData_t;

typedef struct {
int16_t tree;
int16_t loc[HMAX+1];

huffNodeData_t nodeList[768];
} huffData_t;
#pragma pack(pop)

static void Huff_SerializeEndiannessHelper(huffData_t *huffdat) {
huffdat->tree = LittleShort(huffdat->tree);

for (int i = 0; i < (int)ARRAY_LEN(huffdat->loc); i++) {
huffdat->loc[i] = LittleShort(huffdat->loc[i]);
}

for (int i = 0; i < (int)ARRAY_LEN(huffdat->nodeList); i++) {
huffNodeData_t *nodedat = &huffdat->nodeList[i];

nodedat->left = LittleShort(nodedat->left);
nodedat->right = LittleShort(nodedat->right);
nodedat->parent = LittleShort(nodedat->parent);
nodedat->symbol = LittleShort(nodedat->symbol);
}
}

void Huff_Serialize(huffData_t *huffdat, const huff_t *huff) {
#define HUFF_SERIALIZE_NODEREF(noderef) ((noderef) ? (int16_t)((noderef) - huff->nodeList) : -1)

huffdat->tree = HUFF_SERIALIZE_NODEREF(huff->tree);

for (int i = 0; i < (int)ARRAY_LEN(huffdat->loc); i++) {
huffdat->loc[i] = HUFF_SERIALIZE_NODEREF(huff->loc[i]);
}

for (int i = 0; i < (int)ARRAY_LEN(huffdat->nodeList); i++) {
huffNodeData_t *nodedat = &huffdat->nodeList[i];
const node_t *node = &huff->nodeList[i];

nodedat->left = HUFF_SERIALIZE_NODEREF(node->left);
nodedat->right = HUFF_SERIALIZE_NODEREF(node->right);
nodedat->parent = HUFF_SERIALIZE_NODEREF(node->parent);
nodedat->symbol = node->symbol;
}

Huff_SerializeEndiannessHelper(huffdat);
}

void Huff_Deserialize(huffData_t *huffdat, huff_t *huff) {
#define HUFF_DESERIALIZE_NODEREF(noderef) ((noderef) == -1 ? NULL : &huff->nodeList[noderef])

Huff_SerializeEndiannessHelper(huffdat);

huff->tree = HUFF_DESERIALIZE_NODEREF(huffdat->tree);

for (int i = 0; i < (int)ARRAY_LEN(huff->loc); i++) {
huff->loc[i] = HUFF_DESERIALIZE_NODEREF(huffdat->loc[i]);
}

for (int i = 0; i < (int)ARRAY_LEN(huff->nodeList); i++) {
const huffNodeData_t *nodedat = &huffdat->nodeList[i];
node_t *node = &huff->nodeList[i];

node->left = HUFF_DESERIALIZE_NODEREF(nodedat->left);
node->right = HUFF_DESERIALIZE_NODEREF(nodedat->right);
node->parent = HUFF_DESERIALIZE_NODEREF(nodedat->parent);
node->symbol = nodedat->symbol;
}
}

#define HUFF_DATA_VERSION 1

void Huff_SaveData(const huffman_t *huffman, const char *filename) {
huffData_t huffdata;
unsigned checksum;
fileHandle_t fp = 0;

fp = FS_SV_FOpenFileWrite(filename);

if (!fp) {
Com_DPrintf("Failed to save huffman data to %s", filename);
return;
}

byte version = HUFF_DATA_VERSION;
FS_Write(&version, sizeof(version), fp);

Huff_Serialize(&huffdata, &huffman->compressor);
FS_Write(&huffdata, sizeof(huffdata), fp);
checksum = LittleLong(Com_BlockChecksum(&huffdata, sizeof(huffdata)));
FS_Write(&checksum, sizeof(checksum), fp);

Huff_Serialize(&huffdata, &huffman->decompressor);
FS_Write(&huffdata, sizeof(huffdata), fp);
checksum = LittleLong(Com_BlockChecksum(&huffdata, sizeof(huffdata)));
FS_Write(&checksum, sizeof(checksum), fp);

FS_FCloseFile(fp);
}

qboolean Huff_ReadData(huffman_t *huffman, const char *filename) {
huffData_t huffdata;
unsigned checksum;
byte version;
fileHandle_t fp = 0;

FS_SV_FOpenFileRead(filename, &fp);

if (!fp) {
Com_DPrintf("Failed to open huffman data from %s\n", filename);
return qfalse;
}

if (FS_Read(&version, sizeof(version), fp) != (int)sizeof(version))
goto corrupted;

if (version != HUFF_DATA_VERSION) {
Com_DPrintf("Huffman data in %s has incompatible version\n", filename);
return qfalse;
}

memset(&huffman->compressor, 0, sizeof(huff_t));
memset(&huffman->decompressor, 0, sizeof(huff_t));

if (FS_Read(&huffdata, sizeof(huffdata), fp) != (int)sizeof(huffdata))
goto corrupted;
if (FS_Read(&checksum, sizeof(checksum), fp) != (int)sizeof(checksum))
goto corrupted;
checksum = LittleLong(checksum);
if (checksum != Com_BlockChecksum(&huffdata, sizeof(huffdata))) {
Com_Printf(S_COLOR_YELLOW "WARNING: %s checksum mismatch - recalculating Huffman code...", filename);
return qfalse;
}
Huff_Deserialize(&huffdata, &huffman->compressor);

if (FS_Read(&huffdata, sizeof(huffdata), fp) != (int)sizeof(huffdata))
goto corrupted;
if (FS_Read(&checksum, sizeof(checksum), fp) != (int)sizeof(checksum))
goto corrupted;
checksum = LittleLong(checksum);
if (checksum != Com_BlockChecksum(&huffdata, sizeof(huffdata))) {
Com_Printf(S_COLOR_YELLOW "WARNING: %s checksum mismatch - recalculating Huffman code...", filename);
return qfalse;
}
Huff_Deserialize(&huffdata, &huffman->decompressor);

return qtrue;
corrupted:
Com_Printf(S_COLOR_YELLOW "WARNING: %s corrupted - recalculating Huffman code...\n", filename);
return qfalse;
}

/*
// New data gathered to tune Q3 to JK2MP. Takes longer to crunch and gain was minimal.
int msg_hData[256] =
Expand Down Expand Up @@ -2428,6 +2587,11 @@ static const int msg_hData[256] = {
void MSG_initHuffman() {
int i, j;

if (Huff_ReadData(&msgHuff, "huffman.dat")) {
msgInit = qtrue;
return;
}

#ifdef _NEWHUFFTABLE_
fp = fopen("c:\\netchan.bin", "a");
#endif // _NEWHUFFTABLE_
Expand All @@ -2440,6 +2604,8 @@ void MSG_initHuffman() {
Huff_addRef(&msgHuff.decompressor, (byte)i); // Do update
}
}

Huff_SaveData(&msgHuff, "huffman.dat");
}

#else
Expand Down
7 changes: 6 additions & 1 deletion src/qcommon/qcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ unsigned Com_BlockChecksum( const void *buffer, int length );
unsigned Com_BlockChecksumKey (void *buffer, int length, int key);
int Com_HashKey(const char *string, int maxlen);
int Com_Filter(const char *filter, const char *name, int casesensitive);
int Com_FilterPath(char *filter, char *name, int casesensitive);
int Com_FilterPath(char *filter, const char *name, int casesensitive);
int Com_RealTime(qtime_t *qtime);
qboolean Com_SafeMode( void );
void Com_RunAndTimeServerPacket(netadr_t *evFrom, msg_t *buf);
Expand Down Expand Up @@ -1027,6 +1027,11 @@ typedef struct {
node_t* lhead;
node_t* ltail;
node_t* loc[HMAX+1];
// freelist is a head of linked list of nodePtrs
// elements. nodePtrs element type is overloaded and may hold
// node_t* pointer pointing to nodeList element or node_t**
// pointer pointing to another nodePtrs element when part of
// freelist!
node_t** freelist;

node_t nodeList[768];
Expand Down
7 changes: 6 additions & 1 deletion src/renderer/tr_WorldEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,12 +408,17 @@ CMistyFog::CMistyFog(int index, CWorldEffect *owner, bool buddy) :
}
else
{
pixelFormat_t format;
Com_sprintf(name, MAX_QPATH, "gfx/world/fog%d", index);
R_LoadImage(name, &mData, &mWidth, &mHeight);
R_LoadImage(name, &mData, &mWidth, &mHeight, &format);
if (!mData)
{
ri.Error (ERR_DROP, "Could not load %s", name);
}
if (format != PXF_RGBA)
{
ri.Error (ERR_DROP, "Fog image must be RGBA %s", name);
}

mRendering = true;
AddSlave(new CMistyFog(index, this, true));
Expand Down
Loading

0 comments on commit 9b7828d

Please sign in to comment.