qbsp: make sure to add animating texture frames in order

We take care of adding extra animation frames during loading of the map
file to ensure that we add lower-numbered texture frames before the higher
numbered frames.  Most Quake engines will choke on a BSP if the texture
frames are presented out of order (including the original).

Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
This commit is contained in:
Kevin Shanahan 2013-08-13 16:27:05 +09:30
parent 7a2f4383ff
commit 221d6ca2a3
2 changed files with 50 additions and 36 deletions

View File

@ -28,9 +28,50 @@
#define info_player_deathmatch 2 #define info_player_deathmatch 2
#define info_player_coop 4 #define info_player_coop 4
static int cAnimtex;
static int rgfStartSpots; static int rgfStartSpots;
static void
AddAnimTex(const char *name)
{
int i, j, frame;
char framename[16], basechar = '0';
frame = name[1];
if (frame >= 'a' && frame <= 'j')
frame -= 'a' - 'A';
if (frame >= '0' && frame <= '9') {
frame -= '0';
basechar = '0';
} else if (frame >= 'A' && frame <= 'J') {
frame -= 'A';
basechar = 'A';
}
if (frame < 0 || frame > 9)
Error("Bad animating texture %s", name);
/*
* Always add the lower numbered animation frames first, otherwise
* many Quake engines will exit with an error loading the bsp.
*/
snprintf(framename, sizeof(framename), "%s", name);
for (i = 0; i < frame; i++) {
framename[1] = basechar + i;
for (j = 0; j < map.nummiptex; j++) {
if (!strcasecmp(framename, map.miptex[j]))
break;
}
if (j < map.nummiptex)
continue;
if (map.nummiptex == map.maxmiptex)
Error("Internal error: map.nummiptex > map.maxmiptex");
snprintf(map.miptex[j], sizeof(map.miptex[j]), "%s", framename);
map.nummiptex++;
}
}
int int
FindMiptex(const char *name) FindMiptex(const char *name)
{ {
@ -43,11 +84,14 @@ FindMiptex(const char *name)
if (map.nummiptex == map.maxmiptex) if (map.nummiptex == map.maxmiptex)
Error("Internal error: map.nummiptex > map.maxmiptex"); Error("Internal error: map.nummiptex > map.maxmiptex");
strcpy(map.miptex[i], name); /* Handle animating textures carefully */
map.nummiptex++; if (name[0] == '+') {
AddAnimTex(name);
i = map.nummiptex;
}
if (name[0] == '+') snprintf(map.miptex[i], sizeof(map.miptex[i]), "%s", name);
cAnimtex++; map.nummiptex++;
return i; return i;
} }
@ -701,9 +745,8 @@ LoadMapFile(void)
if (map.nummiptex > map.maxfaces) if (map.nummiptex > map.maxfaces)
Error("Internal error: map.nummiptex > map.maxfaces"); Error("Internal error: map.nummiptex > map.maxfaces");
else if (map.nummiptex < map.maxfaces) { else if (map.nummiptex < map.maxfaces) {
// For stuff in AddAnimatingTex, make room available
pTemp = map.miptex; pTemp = map.miptex;
map.maxmiptex = map.nummiptex + cAnimtex * 20; map.maxmiptex = map.nummiptex;
map.miptex = AllocMem(MIPTEX, map.maxmiptex, true); map.miptex = AllocMem(MIPTEX, map.maxmiptex, true);
memcpy(map.miptex, pTemp, map.nummiptex * rgcMemSize[MIPTEX]); memcpy(map.miptex, pTemp, map.nummiptex * rgcMemSize[MIPTEX]);
FreeMem(pTemp, MIPTEX, map.maxfaces); FreeMem(pTemp, MIPTEX, map.maxfaces);

View File

@ -25,7 +25,6 @@
#include "wad.h" #include "wad.h"
static void WADList_LoadTextures(const wad_t *wadlist, dmiptexlump_t *lump); static void WADList_LoadTextures(const wad_t *wadlist, dmiptexlump_t *lump);
static void WADList_AddAnimatingTextures(const wad_t *wadlist);
static int WAD_LoadLump(const wad_t *wad, const char *name, byte *dest); static int WAD_LoadLump(const wad_t *wad, const char *name, byte *dest);
@ -162,8 +161,6 @@ WADList_Process(const wad_t *wadlist)
dmiptexlump_t *miptexlump; dmiptexlump_t *miptexlump;
struct lumpdata *texdata = &pWorldEnt->lumps[BSPTEX]; struct lumpdata *texdata = &pWorldEnt->lumps[BSPTEX];
WADList_AddAnimatingTextures(wadlist);
/* Count space for miptex header/offsets */ /* Count space for miptex header/offsets */
texdata->count = offsetof(dmiptexlump_t, dataofs[map.nummiptex]); texdata->count = offsetof(dmiptexlump_t, dataofs[map.nummiptex]);
@ -238,29 +235,3 @@ WAD_LoadLump(const wad_t *wad, const char *name, byte *dest)
return 0; return 0;
} }
static void
WADList_AddAnimatingTextures(const wad_t *wadlist)
{
int base;
int i, j;
char name[32];
base = map.nummiptex;
for (i = 0; i < base; i++) {
if (map.miptex[i][0] != '+')
continue;
strcpy(name, map.miptex[i]);
/* Search for all animations (0-9) and alt-animations (A-J) */
for (j = 0; j < 20; j++) {
name[1] = (j < 10) ? '0' + j : 'a' + j - 10;
if (WADList_FindTexture(wadlist, name))
FindMiptex(name);
}
}
Message(msgStat, "%8d texture frames added", map.nummiptex - base);
}