diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 79c27c6c1..7d8b9df26 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -69,6 +69,8 @@ #include "fragglescript/t_fs.h" +#define MISSING_TEXTURE_WARN_LIMIT 20 + void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt); void P_SetSlopes (); void P_CopySlopes(); @@ -80,7 +82,7 @@ extern bool P_LoadBuildMap (BYTE *mapdata, size_t len, FMapThing **things, int * extern void P_TranslateTeleportThings (void); -void P_ParseTextMap(MapData *map); +void P_ParseTextMap(MapData *map, FMissingTextureTracker &); extern int numinterpolations; 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 *sidenames[] = { "first", "second" }; @@ -572,16 +574,19 @@ static void SetTexture (side_t *side, int position, const char *name8) if (!texture.Exists()) { - // 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 (++track[name].Count <= MISSING_TEXTURE_WARN_LIMIT) { - 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", - positionnames[position], name, sidenames[j], i); + if (lines[i].sidedef[j] == side) + { + 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" }; char name[9]; @@ -608,13 +613,40 @@ void SetTexture (sector_t *sector, int index, int position, const char *name8) if (!texture.Exists()) { - Printf("Unknown %s texture '%s' in sector %d\n", - positionnames[position], name, index); + if (++track[name].Count <= MISSING_TEXTURE_WARN_LIMIT) + { + Printf("Unknown %s texture '%s' in sector %d\n", + positionnames[position], name, index); + } texture = TexMan.GetDefaultTexture(); } 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 @@ -1400,7 +1432,7 @@ void P_LoadSubsectors (MapData * map) // //=========================================================================== -void P_LoadSectors (MapData * map) +void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) { char fname[9]; int i; @@ -1443,8 +1475,8 @@ void P_LoadSectors (MapData * map) ss->ceilingplane.d = ss->GetPlaneTexZ(sector_t::ceiling); ss->ceilingplane.c = -FRACUNIT; ss->ceilingplane.ic = -FRACUNIT; - SetTexture(ss, i, sector_t::floor, ms->floorpic); - SetTexture(ss, i, sector_t::ceiling, ms->ceilingpic); + SetTexture(ss, i, sector_t::floor, ms->floorpic, missingtex); + SetTexture(ss, i, sector_t::ceiling, ms->ceilingpic, missingtex); ss->lightlevel = (BYTE)clamp (LittleShort(ms->lightlevel), (short)0, (short)255); if (map->HasBehavior) ss->special = LittleShort(ms->special); @@ -2344,7 +2376,7 @@ int P_DetermineTranslucency (int lumpnum) 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]; 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::top, &color, msd->toptexture, &colorgood, false); strncpy (name, msd->midtexture, 8); - SetTexture(sd, side_t::mid, msd->midtexture); + SetTexture(sd, side_t::mid, msd->midtexture, missingtex); if (colorgood | foggood) { @@ -2411,11 +2443,11 @@ void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapside } 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::bottom, msd->bottomtexture); + SetTexture(sd, side_t::mid, msd->midtexture, missingtex); + SetTexture(sd, side_t::bottom, msd->bottomtexture, missingtex); break; #endif @@ -2437,20 +2469,20 @@ void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapside } 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::bottom, msd->bottomtexture); + SetTexture(sd, side_t::top, msd->toptexture, missingtex); + SetTexture(sd, side_t::bottom, msd->bottomtexture, missingtex); break; } // Fallthrough for Hexen maps is intentional default: // normal cases - SetTexture(sd, side_t::mid, msd->midtexture); - SetTexture(sd, side_t::top, msd->toptexture); - SetTexture(sd, side_t::bottom, msd->bottomtexture); + SetTexture(sd, side_t::mid, msd->midtexture, missingtex); + SetTexture(sd, side_t::top, msd->toptexture, missingtex); + SetTexture(sd, side_t::bottom, msd->bottomtexture, missingtex); break; } } @@ -2459,7 +2491,7 @@ void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapside // after linedefs are loaded, to allow overloading. // killough 5/3/98: reformatted, cleaned up -void P_LoadSideDefs2 (MapData * map) +void P_LoadSideDefs2 (MapData *map, FMissingTextureTracker &missingtex) { int i; char * msdf = new char[map->Size(ML_SIDEDEFS)]; @@ -2501,7 +2533,7 @@ void P_LoadSideDefs2 (MapData * map) sd->sector = sec = §ors[LittleShort(msd->sector)]; } 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; } @@ -3550,6 +3582,8 @@ void P_SetupLevel (char *lumpname, int position) P_LoadStrifeConversations (map, lumpname); + FMissingTextureTracker missingtex; + if (!map->isText) { 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) times[1].Clock(); - P_LoadSectors (map); + P_LoadSectors (map, missingtex); times[1].Unclock(); times[2].Clock(); @@ -3573,7 +3607,7 @@ void P_SetupLevel (char *lumpname, int position) times[3].Unclock(); times[4].Clock(); - P_LoadSideDefs2 (map); + P_LoadSideDefs2 (map, missingtex); times[4].Unclock(); times[5].Clock(); @@ -3589,7 +3623,7 @@ void P_SetupLevel (char *lumpname, int position) } else { - P_ParseTextMap(map); + P_ParseTextMap(map, missingtex); } times[6].Clock(); @@ -3598,6 +3632,8 @@ void P_SetupLevel (char *lumpname, int position) linemap.Clear(); linemap.ShrinkToFit(); + + SummarizeMissingTextures(missingtex); } else { diff --git a/src/p_setup.h b/src/p_setup.h index aa860af0e..4bb0435e0 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -142,4 +142,11 @@ extern sidei_t *sidetemp; extern bool hasglnodes; extern struct glsegextra_t *glsegextras; +struct FMissingCount +{ + FMissingCount() : Count(0) {} + int Count; +}; +typedef TMap FMissingTextureTracker; + #endif diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index d59597db9..d96695dd7 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -110,9 +110,8 @@ enum // namespace for each game }; - -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); +void SetTexture (sector_t *sector, int index, int position, const char *name8, FMissingTextureTracker &); +void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapsidedef_t *msd, int special, int tag, short *alpha, FMissingTextureTracker &); void P_AdjustLine (line_t *ld); void P_FinishLoadingLineDef(line_t *ld, int alpha); void SpawnMapThing(int index, FMapThing *mt, int position); @@ -393,9 +392,11 @@ class UDMFParser : public UDMFParserBase TArray ParsedVertexDatas; FDynamicColormap *fogMap, *normMap; + FMissingTextureTracker &missingTex; public: - UDMFParser() + UDMFParser(FMissingTextureTracker &missing) + : missingTex(missing) { linemap.Clear(); fogMap = normMap = NULL; @@ -1113,11 +1114,11 @@ public: continue; case NAME_Texturefloor: - SetTexture(sec, index, sector_t::floor, CheckString(key)); + SetTexture(sec, index, sector_t::floor, CheckString(key), missingTex); continue; case NAME_Textureceiling: - SetTexture(sec, index, sector_t::ceiling, CheckString(key)); + SetTexture(sec, index, sector_t::ceiling, CheckString(key), missingTex); continue; case NAME_Lightlevel: @@ -1427,7 +1428,7 @@ public: lines[line].sidedef[sd] = &sides[side]; 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++; } @@ -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); } diff --git a/src/zstring.h b/src/zstring.h index db42b98e4..6dd80b92c 100644 --- a/src/zstring.h +++ b/src/zstring.h @@ -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 &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 +{ + 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