- Place a limit on the number of reports per missing texture. On maps with many lines and many

sides of missing textures, this can take a very long time, because each missing textures causes
  a scan of every single line (for the sake of packed sidedefs), and each output line also requires
  an update of the hidden RichEdit logging control.

SVN r3192 (trunk)
This commit is contained in:
Randy Heit 2011-05-08 00:30:32 +00:00
parent 571210fe56
commit 6c70afe0a7
4 changed files with 93 additions and 40 deletions

View File

@ -69,6 +69,8 @@
#include "fragglescript/t_fs.h" #include "fragglescript/t_fs.h"
#define MISSING_TEXTURE_WARN_LIMIT 20
void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt); void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt);
void P_SetSlopes (); void P_SetSlopes ();
void P_CopySlopes(); void P_CopySlopes();
@ -80,7 +82,7 @@ extern bool P_LoadBuildMap (BYTE *mapdata, size_t len, FMapThing **things, int *
extern void P_TranslateTeleportThings (void); extern void P_TranslateTeleportThings (void);
void P_ParseTextMap(MapData *map); void P_ParseTextMap(MapData *map, FMissingTextureTracker &);
extern int numinterpolations; extern int numinterpolations;
extern unsigned int R_OldBlend; extern unsigned int R_OldBlend;
@ -560,7 +562,7 @@ void MapData::GetChecksum(BYTE cksum[16])
// //
//=========================================================================== //===========================================================================
static void SetTexture (side_t *side, int position, const char *name8) static void SetTexture (side_t *side, int position, const char *name8, FMissingTextureTracker &track)
{ {
static const char *positionnames[] = { "top", "middle", "bottom" }; static const char *positionnames[] = { "top", "middle", "bottom" };
static const char *sidenames[] = { "first", "second" }; static const char *sidenames[] = { "first", "second" };
@ -572,16 +574,19 @@ static void SetTexture (side_t *side, int position, const char *name8)
if (!texture.Exists()) if (!texture.Exists())
{ {
// Print an error that lists all references to this sidedef. if (++track[name].Count <= MISSING_TEXTURE_WARN_LIMIT)
// We must scan the linedefs manually for all references to this sidedef.
for(int i = 0; i < numlines; i++)
{ {
for(int j = 0; j < 2; j++) // Print an error that lists all references to this sidedef.
// We must scan the linedefs manually for all references to this sidedef.
for(int i = 0; i < numlines; i++)
{ {
if (lines[i].sidedef[j] == side) for(int j = 0; j < 2; j++)
{ {
Printf("Unknown %s texture '%s' on %s side of linedef %d\n", if (lines[i].sidedef[j] == side)
positionnames[position], name, sidenames[j], i); {
Printf("Unknown %s texture '%s' on %s side of linedef %d\n",
positionnames[position], name, sidenames[j], i);
}
} }
} }
} }
@ -597,7 +602,7 @@ static void SetTexture (side_t *side, int position, const char *name8)
// //
//=========================================================================== //===========================================================================
void SetTexture (sector_t *sector, int index, int position, const char *name8) void SetTexture (sector_t *sector, int index, int position, const char *name8, FMissingTextureTracker &track)
{ {
static const char *positionnames[] = { "floor", "ceiling" }; static const char *positionnames[] = { "floor", "ceiling" };
char name[9]; char name[9];
@ -608,13 +613,40 @@ void SetTexture (sector_t *sector, int index, int position, const char *name8)
if (!texture.Exists()) if (!texture.Exists())
{ {
Printf("Unknown %s texture '%s' in sector %d\n", if (++track[name].Count <= MISSING_TEXTURE_WARN_LIMIT)
positionnames[position], name, index); {
Printf("Unknown %s texture '%s' in sector %d\n",
positionnames[position], name, index);
}
texture = TexMan.GetDefaultTexture(); texture = TexMan.GetDefaultTexture();
} }
sector->SetTexture(position, texture); sector->SetTexture(position, texture);
} }
//===========================================================================
//
// SummarizeMissingTextures
//
// Lists textures that were missing more than MISSING_TEXTURE_WARN_LIMIT
// times.
//
//===========================================================================
static void SummarizeMissingTextures(const FMissingTextureTracker &missing)
{
FMissingTextureTracker::ConstIterator it(missing);
FMissingTextureTracker::ConstPair *pair;
while (it.NextPair(pair))
{
if (pair->Value.Count > MISSING_TEXTURE_WARN_LIMIT)
{
Printf("Missing texture '%s' is used %d more times\n",
pair->Key.GetChars(), pair->Value.Count - MISSING_TEXTURE_WARN_LIMIT);
}
}
}
//=========================================================================== //===========================================================================
// //
// [RH] Figure out blends for deep water sectors // [RH] Figure out blends for deep water sectors
@ -1400,7 +1432,7 @@ void P_LoadSubsectors (MapData * map)
// //
//=========================================================================== //===========================================================================
void P_LoadSectors (MapData * map) void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex)
{ {
char fname[9]; char fname[9];
int i; int i;
@ -1443,8 +1475,8 @@ void P_LoadSectors (MapData * map)
ss->ceilingplane.d = ss->GetPlaneTexZ(sector_t::ceiling); ss->ceilingplane.d = ss->GetPlaneTexZ(sector_t::ceiling);
ss->ceilingplane.c = -FRACUNIT; ss->ceilingplane.c = -FRACUNIT;
ss->ceilingplane.ic = -FRACUNIT; ss->ceilingplane.ic = -FRACUNIT;
SetTexture(ss, i, sector_t::floor, ms->floorpic); SetTexture(ss, i, sector_t::floor, ms->floorpic, missingtex);
SetTexture(ss, i, sector_t::ceiling, ms->ceilingpic); SetTexture(ss, i, sector_t::ceiling, ms->ceilingpic, missingtex);
ss->lightlevel = (BYTE)clamp (LittleShort(ms->lightlevel), (short)0, (short)255); ss->lightlevel = (BYTE)clamp (LittleShort(ms->lightlevel), (short)0, (short)255);
if (map->HasBehavior) if (map->HasBehavior)
ss->special = LittleShort(ms->special); ss->special = LittleShort(ms->special);
@ -2344,7 +2376,7 @@ int P_DetermineTranslucency (int lumpnum)
return newcolor.r; return newcolor.r;
} }
void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapsidedef_t *msd, int special, int tag, short *alpha) void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapsidedef_t *msd, int special, int tag, short *alpha, FMissingTextureTracker &missingtex)
{ {
char name[9]; char name[9];
name[8] = 0; name[8] = 0;
@ -2375,7 +2407,7 @@ void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapside
SetTextureNoErr (sd, side_t::bottom, &fog, msd->bottomtexture, &foggood, true); SetTextureNoErr (sd, side_t::bottom, &fog, msd->bottomtexture, &foggood, true);
SetTextureNoErr (sd, side_t::top, &color, msd->toptexture, &colorgood, false); SetTextureNoErr (sd, side_t::top, &color, msd->toptexture, &colorgood, false);
strncpy (name, msd->midtexture, 8); strncpy (name, msd->midtexture, 8);
SetTexture(sd, side_t::mid, msd->midtexture); SetTexture(sd, side_t::mid, msd->midtexture, missingtex);
if (colorgood | foggood) if (colorgood | foggood)
{ {
@ -2411,11 +2443,11 @@ void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapside
} }
else else
{ {
SetTexture(sd, side_t::top, msd->toptexture); SetTexture(sd, side_t::top, msd->toptexture, missingtex);
} }
SetTexture(sd, side_t::mid, msd->midtexture); SetTexture(sd, side_t::mid, msd->midtexture, missingtex);
SetTexture(sd, side_t::bottom, msd->bottomtexture); SetTexture(sd, side_t::bottom, msd->bottomtexture, missingtex);
break; break;
#endif #endif
@ -2437,20 +2469,20 @@ void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapside
} }
else else
{ {
SetTexture(sd, side_t::mid, msd->midtexture); SetTexture(sd, side_t::mid, msd->midtexture, missingtex);
} }
SetTexture(sd, side_t::top, msd->toptexture); SetTexture(sd, side_t::top, msd->toptexture, missingtex);
SetTexture(sd, side_t::bottom, msd->bottomtexture); SetTexture(sd, side_t::bottom, msd->bottomtexture, missingtex);
break; break;
} }
// Fallthrough for Hexen maps is intentional // Fallthrough for Hexen maps is intentional
default: // normal cases default: // normal cases
SetTexture(sd, side_t::mid, msd->midtexture); SetTexture(sd, side_t::mid, msd->midtexture, missingtex);
SetTexture(sd, side_t::top, msd->toptexture); SetTexture(sd, side_t::top, msd->toptexture, missingtex);
SetTexture(sd, side_t::bottom, msd->bottomtexture); SetTexture(sd, side_t::bottom, msd->bottomtexture, missingtex);
break; break;
} }
} }
@ -2459,7 +2491,7 @@ void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapside
// after linedefs are loaded, to allow overloading. // after linedefs are loaded, to allow overloading.
// killough 5/3/98: reformatted, cleaned up // killough 5/3/98: reformatted, cleaned up
void P_LoadSideDefs2 (MapData * map) void P_LoadSideDefs2 (MapData *map, FMissingTextureTracker &missingtex)
{ {
int i; int i;
char * msdf = new char[map->Size(ML_SIDEDEFS)]; char * msdf = new char[map->Size(ML_SIDEDEFS)];
@ -2501,7 +2533,7 @@ void P_LoadSideDefs2 (MapData * map)
sd->sector = sec = &sectors[LittleShort(msd->sector)]; sd->sector = sec = &sectors[LittleShort(msd->sector)];
} }
P_ProcessSideTextures(!map->HasBehavior, sd, sec, msd, P_ProcessSideTextures(!map->HasBehavior, sd, sec, msd,
sidetemp[i].a.special, sidetemp[i].a.tag, &sidetemp[i].a.alpha); sidetemp[i].a.special, sidetemp[i].a.tag, &sidetemp[i].a.alpha, missingtex);
} }
delete[] msdf; delete[] msdf;
} }
@ -3550,6 +3582,8 @@ void P_SetupLevel (char *lumpname, int position)
P_LoadStrifeConversations (map, lumpname); P_LoadStrifeConversations (map, lumpname);
FMissingTextureTracker missingtex;
if (!map->isText) if (!map->isText)
{ {
times[0].Clock(); times[0].Clock();
@ -3558,7 +3592,7 @@ void P_SetupLevel (char *lumpname, int position)
// Check for maps without any BSP data at all (e.g. SLIGE) // Check for maps without any BSP data at all (e.g. SLIGE)
times[1].Clock(); times[1].Clock();
P_LoadSectors (map); P_LoadSectors (map, missingtex);
times[1].Unclock(); times[1].Unclock();
times[2].Clock(); times[2].Clock();
@ -3573,7 +3607,7 @@ void P_SetupLevel (char *lumpname, int position)
times[3].Unclock(); times[3].Unclock();
times[4].Clock(); times[4].Clock();
P_LoadSideDefs2 (map); P_LoadSideDefs2 (map, missingtex);
times[4].Unclock(); times[4].Unclock();
times[5].Clock(); times[5].Clock();
@ -3589,7 +3623,7 @@ void P_SetupLevel (char *lumpname, int position)
} }
else else
{ {
P_ParseTextMap(map); P_ParseTextMap(map, missingtex);
} }
times[6].Clock(); times[6].Clock();
@ -3598,6 +3632,8 @@ void P_SetupLevel (char *lumpname, int position)
linemap.Clear(); linemap.Clear();
linemap.ShrinkToFit(); linemap.ShrinkToFit();
SummarizeMissingTextures(missingtex);
} }
else else
{ {

View File

@ -142,4 +142,11 @@ extern sidei_t *sidetemp;
extern bool hasglnodes; extern bool hasglnodes;
extern struct glsegextra_t *glsegextras; extern struct glsegextra_t *glsegextras;
struct FMissingCount
{
FMissingCount() : Count(0) {}
int Count;
};
typedef TMap<FString,FMissingCount> FMissingTextureTracker;
#endif #endif

View File

@ -110,9 +110,8 @@ enum
// namespace for each game // namespace for each game
}; };
void SetTexture (sector_t *sector, int index, int position, const char *name8, FMissingTextureTracker &);
void SetTexture (sector_t *sector, int index, int position, const char *name8); void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapsidedef_t *msd, int special, int tag, short *alpha, FMissingTextureTracker &);
void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapsidedef_t *msd, int special, int tag, short *alpha);
void P_AdjustLine (line_t *ld); void P_AdjustLine (line_t *ld);
void P_FinishLoadingLineDef(line_t *ld, int alpha); void P_FinishLoadingLineDef(line_t *ld, int alpha);
void SpawnMapThing(int index, FMapThing *mt, int position); void SpawnMapThing(int index, FMapThing *mt, int position);
@ -393,9 +392,11 @@ class UDMFParser : public UDMFParserBase
TArray<vertexdata_t> ParsedVertexDatas; TArray<vertexdata_t> ParsedVertexDatas;
FDynamicColormap *fogMap, *normMap; FDynamicColormap *fogMap, *normMap;
FMissingTextureTracker &missingTex;
public: public:
UDMFParser() UDMFParser(FMissingTextureTracker &missing)
: missingTex(missing)
{ {
linemap.Clear(); linemap.Clear();
fogMap = normMap = NULL; fogMap = normMap = NULL;
@ -1113,11 +1114,11 @@ public:
continue; continue;
case NAME_Texturefloor: case NAME_Texturefloor:
SetTexture(sec, index, sector_t::floor, CheckString(key)); SetTexture(sec, index, sector_t::floor, CheckString(key), missingTex);
continue; continue;
case NAME_Textureceiling: case NAME_Textureceiling:
SetTexture(sec, index, sector_t::ceiling, CheckString(key)); SetTexture(sec, index, sector_t::ceiling, CheckString(key), missingTex);
continue; continue;
case NAME_Lightlevel: case NAME_Lightlevel:
@ -1427,7 +1428,7 @@ public:
lines[line].sidedef[sd] = &sides[side]; lines[line].sidedef[sd] = &sides[side];
P_ProcessSideTextures(!isExtended, &sides[side], sides[side].sector, &ParsedSideTextures[mapside], P_ProcessSideTextures(!isExtended, &sides[side], sides[side].sector, &ParsedSideTextures[mapside],
lines[line].special, lines[line].args[0], &tempalpha[sd]); lines[line].special, lines[line].args[0], &tempalpha[sd], missingTex);
side++; side++;
} }
@ -1592,9 +1593,9 @@ public:
} }
}; };
void P_ParseTextMap(MapData *map) void P_ParseTextMap(MapData *map, FMissingTextureTracker &missingtex)
{ {
UDMFParser parse; UDMFParser parse(missingtex);
parse.ParseTextMap(map); parse.ParseTextMap(map);
} }

View File

@ -315,5 +315,14 @@ inline FName::FName(const FString &text, bool noCreate) { Index = NameData.FindN
inline FName &FName::operator = (const FString &text) { Index = NameData.FindName (text, text.Len(), false); return *this; } inline FName &FName::operator = (const FString &text) { Index = NameData.FindName (text, text.Len(), false); return *this; }
inline FName &FNameNoInit::operator = (const FString &text) { Index = NameData.FindName (text, text.Len(), false); return *this; } inline FName &FNameNoInit::operator = (const FString &text) { Index = NameData.FindName (text, text.Len(), false); return *this; }
// Hash for TMap
extern unsigned int SuperFastHash(const char *data, size_t len);
template<> struct THashTraits<FString>
{
hash_t Hash(const FString &key) { return (hash_t)SuperFastHash(key, key.Len()+1); }
// Compares two keys, returning zero if they are the same.
int Compare(const FString &left, const FString &right) { return left.Compare(right); }
};
#endif #endif