From d9439850f720ba2f3d933d49f20b4140c004e65f Mon Sep 17 00:00:00 2001 From: MaxED Date: Mon, 2 Dec 2013 15:02:01 +0000 Subject: [PATCH] Error checks: PlaneAlign action is now taken into account when checking for missing upper/lower textures. Several fixes in flat/texture/patch loading and precedence. Texture loading will no longer fail when there's a texture and a flat with the same name. --- Source/Core/Config/ResourceTextureSet.cs | 6 +- Source/Core/Data/DataManager.cs | 67 +++++++------ Source/Core/Data/HighResImage.cs | 16 +++- Source/Core/Data/ImageDataFormat.cs | 93 +++++++++---------- Source/Core/Data/TextureImage.cs | 18 ++-- Source/Core/Data/WADReader.cs | 63 +++++++++---- .../ErrorChecks/CheckMissingTextures.cs | 2 + 7 files changed, 151 insertions(+), 114 deletions(-) diff --git a/Source/Core/Config/ResourceTextureSet.cs b/Source/Core/Config/ResourceTextureSet.cs index 6246b53b..922522e3 100644 --- a/Source/Core/Config/ResourceTextureSet.cs +++ b/Source/Core/Config/ResourceTextureSet.cs @@ -93,13 +93,17 @@ namespace CodeImp.DoomBuilder.Config // Mix the textures and flats internal void MixTexturesAndFlats() { + Dictionary newflats = new Dictionary(); //mxd + // Add flats to textures foreach(KeyValuePair f in flats) { if(!textures.ContainsKey(f.Key)) textures.Add(f.Key, f.Value); + else + newflats.Add(f.Key, f.Value); //mxd } - flats.Clear(); //mxd + flats = newflats; //mxd } #endregion diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index 6b60508d..601c962d 100644 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -342,32 +342,29 @@ namespace CodeImp.DoomBuilder.Data } } - // Process flats - foreach(KeyValuePair f in flatsonly) - { - flats.Add(f.Key, f.Value); - flatnames.Add(f.Value.Name); - } - // Mixed textures and flats? - if(General.Map.Config.MixTexturesFlats) - { + if (General.Map.Config.MixTexturesFlats) { // Add flats to textures - foreach(KeyValuePair f in flatsonly) - { - if(!textures.ContainsKey(f.Key)) - { + foreach (KeyValuePair f in flatsonly) { + if (!textures.ContainsKey(f.Key)) { textures.Add(f.Key, f.Value); texturenames.Add(f.Value.Name); + } else { + //mxd. If there are flats with the same name as textures - add them to flats + flats.Add(f.Key, f.Value); + flatnames.Add(f.Value.Name); } } - flats.Clear(); //mxd - flatnames.Clear(); //mxd - // Do the same on the data readers - foreach(DataReader dr in containers) + foreach (DataReader dr in containers) dr.TextureSet.MixTexturesAndFlats(); + } else { + // Process flats + foreach(KeyValuePair f in flatsonly) { + flats.Add(f.Key, f.Value); + flatnames.Add(f.Value.Name); + } } // Sort names @@ -704,11 +701,9 @@ namespace CodeImp.DoomBuilder.Data } // Set used on all flats - if(!General.Map.Config.MixTexturesFlats) { - foreach(KeyValuePair i in flats) { - i.Value.SetUsedInMap(usedimages.ContainsKey(i.Key)); - if(i.Value.IsImageLoaded != i.Value.IsReferenced) ProcessImage(i.Value); - } + foreach(KeyValuePair i in flats) { + i.Value.SetUsedInMap(usedimages.ContainsKey(i.Key)); + if(i.Value.IsImageLoaded != i.Value.IsReferenced) ProcessImage(i.Value); } // Done @@ -980,13 +975,13 @@ namespace CodeImp.DoomBuilder.Data public bool GetFlatExists(string name) { long longname = Lump.MakeLongName(name); - return General.Map.Config.MixTexturesFlats ? textures.ContainsKey(longname) : flats.ContainsKey(longname); + return General.Map.Config.MixTexturesFlats ? flats.ContainsKey(longname) || textures.ContainsKey(longname) : flats.ContainsKey(longname); } // This checks if a flat is known public bool GetFlatExists(long longname) { - return General.Map.Config.MixTexturesFlats ? textures.ContainsKey(longname) : flats.ContainsKey(longname); + return General.Map.Config.MixTexturesFlats ? flats.ContainsKey(longname) || textures.ContainsKey(longname) : flats.ContainsKey(longname); } // This returns an image by string @@ -1000,16 +995,12 @@ namespace CodeImp.DoomBuilder.Data // This returns an image by long public ImageData GetFlatImage(long longname) { - if(General.Map.Config.MixTexturesFlats) { //mxd - // Does this flat exist? - if(textures.ContainsKey(longname)) { - // Return flat - return textures[longname]; - } - } else if(flats.ContainsKey(longname)) { // Does this flat exist? - // Return flat - return flats[longname]; - } + // Does this flat exist? + if(flats.ContainsKey(longname)) return flats[longname]; + + //mxd. Probably a texture will do? + if(General.Map.Config.MixTexturesFlats && textures.ContainsKey(longname)) + return textures[longname]; // Return null image return unknownImage; //mxd @@ -1018,8 +1009,14 @@ namespace CodeImp.DoomBuilder.Data // This returns an image by long and doesn't check if it exists public ImageData GetFlatImageKnown(long longname) { + //mxd. Err... can't it do without checks... + if(General.Map.Config.MixTexturesFlats) { + if(flats.ContainsKey(longname)) return flats[longname]; + return textures[longname]; + } + // Return flat - return General.Map.Config.MixTexturesFlats ? textures[longname] : flats[longname]; //mxd + return flats[longname]; //mxd } #endregion diff --git a/Source/Core/Data/HighResImage.cs b/Source/Core/Data/HighResImage.cs index 31f0e7f3..701c0830 100644 --- a/Source/Core/Data/HighResImage.cs +++ b/Source/Core/Data/HighResImage.cs @@ -126,12 +126,18 @@ namespace CodeImp.DoomBuilder.Data reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette); if(reader is UnknownImageReader) { - // Data is in an unknown format! - General.ErrorLogger.Add(ErrorType.Error, "Patch lump '" + p.lumpname + "' data format could not be read, while loading texture '" + this.Name + "'"); - failCount++; //mxd + //mxd. Probably that's a flat?.. + if (General.Map.Config.MixTexturesFlats) { + reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMFLAT, General.Map.Data.Palette); + } + if (reader is UnknownImageReader) { + // Data is in an unknown format! + General.ErrorLogger.Add(ErrorType.Error, "Patch lump '" + p.lumpname + "' data format could not be read, while loading texture '" + this.Name + "'"); + failCount++; //mxd + } } - else - { + + if(!(reader is UnknownImageReader)) { // Get the patch mem.Seek(0, SeekOrigin.Begin); Bitmap patchbmp = null; diff --git a/Source/Core/Data/ImageDataFormat.cs b/Source/Core/Data/ImageDataFormat.cs index 88f6d1f7..565c0ea1 100644 --- a/Source/Core/Data/ImageDataFormat.cs +++ b/Source/Core/Data/ImageDataFormat.cs @@ -43,69 +43,66 @@ namespace CodeImp.DoomBuilder.Data // This check image data and returns the appropriate image reader public static IImageReader GetImageReader(Stream data, int guessformat, Playpal palette) { - DoomPictureReader picreader; - DoomFlatReader flatreader; - DoomColormapReader colormapreader; - - // First check the formats that provide the means to 'ensure' that - // it actually is that format. Then guess the Doom image format. - - // Data long enough to check for signatures? - if(data.Length > 10) - { - // Check for PNG signature - data.Seek(0, SeekOrigin.Begin); - if(CheckSignature(data, PNG_SIGNATURE)) return new FileImageReader(DevilImageType.IL_PNG); - - // Check for DDS signature - data.Seek(0, SeekOrigin.Begin); - if (CheckSignature(data, DDS_SIGNATURE)) return new FileImageReader(DevilImageType.IL_DDS); - - // Check for GIF signature - data.Seek(0, SeekOrigin.Begin); - if (CheckSignature(data, GIF_SIGNATURE)) return new FileImageReader(DevilImageType.IL_GIF); - - //mxd. Check for PCX signature - data.Seek(0, SeekOrigin.Begin); - if (CheckSignature(data, PCX_SIGNATURE)) return new FileImageReader(DevilImageType.IL_PCX); - - //mxd. Check for JPG signature - data.Seek(0, SeekOrigin.Begin); - if (CheckSignature(data, JPG_SIGNATURE)) return new FileImageReader(DevilImageType.IL_JPG); - - //mxd. Check for TGA signature - data.Seek(0, SeekOrigin.Begin); - if (CheckSignature(data, TGA_SIGNATURE)) return new FileImageReader(DevilImageType.IL_TGA); - - // Check for BMP signature - data.Seek(0, SeekOrigin.Begin); - if (CheckSignature(data, BMP_SIGNATURE)) return new UnknownImageReader(); //mxd. Not supported in (G)ZDoom - } - + //mxd. Try to read it as "classic" image format first... // Could it be a doom picture? - if(guessformat == DOOMPICTURE) - { + if(guessformat == DOOMPICTURE) { // Check if data is valid for a doom picture data.Seek(0, SeekOrigin.Begin); - picreader = new DoomPictureReader(palette); + DoomPictureReader picreader = new DoomPictureReader(palette); if(picreader.Validate(data)) return picreader; } // Could it be a doom flat? - else if(guessformat == DOOMFLAT) - { + else if(guessformat == DOOMFLAT) { // Check if data is valid for a doom flat data.Seek(0, SeekOrigin.Begin); - flatreader = new DoomFlatReader(palette); + DoomFlatReader flatreader = new DoomFlatReader(palette); if(flatreader.Validate(data)) return flatreader; } // Could it be a doom colormap? - else if(guessformat == DOOMCOLORMAP) - { + else if(guessformat == DOOMCOLORMAP) { // Check if data is valid for a doom colormap data.Seek(0, SeekOrigin.Begin); - colormapreader = new DoomColormapReader(palette); + DoomColormapReader colormapreader = new DoomColormapReader(palette); if(colormapreader.Validate(data)) return colormapreader; } + + // Data long enough to check for signatures? + if(data.Length > 10) { + // Check for PNG signature + data.Seek(0, SeekOrigin.Begin); + if(CheckSignature(data, PNG_SIGNATURE)) + return new FileImageReader(DevilImageType.IL_PNG); + + // Check for DDS signature + data.Seek(0, SeekOrigin.Begin); + if(CheckSignature(data, DDS_SIGNATURE)) + return new FileImageReader(DevilImageType.IL_DDS); + + // Check for GIF signature + data.Seek(0, SeekOrigin.Begin); + if(CheckSignature(data, GIF_SIGNATURE)) + return new FileImageReader(DevilImageType.IL_GIF); + + //mxd. Check for PCX signature + data.Seek(0, SeekOrigin.Begin); + if(CheckSignature(data, PCX_SIGNATURE)) + return new FileImageReader(DevilImageType.IL_PCX); + + //mxd. Check for JPG signature + data.Seek(0, SeekOrigin.Begin); + if(CheckSignature(data, JPG_SIGNATURE)) + return new FileImageReader(DevilImageType.IL_JPG); + + //mxd. Check for TGA signature + data.Seek(0, SeekOrigin.Begin); + if(CheckSignature(data, TGA_SIGNATURE)) + return new FileImageReader(DevilImageType.IL_TGA); + + // Check for BMP signature + data.Seek(0, SeekOrigin.Begin); + if(CheckSignature(data, BMP_SIGNATURE)) + return new UnknownImageReader(); //mxd. Not supported in (G)ZDoom + } // Format not supported return new UnknownImageReader(); diff --git a/Source/Core/Data/TextureImage.cs b/Source/Core/Data/TextureImage.cs index 7acae7db..4b74e4a2 100644 --- a/Source/Core/Data/TextureImage.cs +++ b/Source/Core/Data/TextureImage.cs @@ -118,13 +118,19 @@ namespace CodeImp.DoomBuilder.Data reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette); if(reader is UnknownImageReader) { - // Data is in an unknown format! - General.ErrorLogger.Add(ErrorType.Error, "Patch lump '" + p.lumpname + "' data format could not be read, while loading texture '" + this.Name + "'. Does this lump contain valid picture data at all?"); - loadfailed = true; - failCount++; //mxd + //mxd. Probably that's a flat?.. + if (General.Map.Config.MixTexturesFlats) { + reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMFLAT, General.Map.Data.Palette); + } + if (reader is UnknownImageReader) { + // Data is in an unknown format! + General.ErrorLogger.Add(ErrorType.Error, "Patch lump '" + p.lumpname + "' data format could not be read, while loading texture '" + this.Name + "'. Does this lump contain valid picture data at all?"); + loadfailed = true; + failCount++; //mxd + } } - else - { + + if(!(reader is UnknownImageReader)) { // Draw the patch mem.Seek(0, SeekOrigin.Begin); try { reader.DrawToPixelData(mem, pixels, width, height, p.x, p.y); } diff --git a/Source/Core/Data/WADReader.cs b/Source/Core/Data/WADReader.cs index 9c313979..a0048388 100644 --- a/Source/Core/Data/WADReader.cs +++ b/Source/Core/Data/WADReader.cs @@ -53,6 +53,7 @@ namespace CodeImp.DoomBuilder.Data // Lump ranges private List flatranges; + private List invertedflatranges; //mxd private List patchranges; private List spriteranges; private List textureranges; @@ -93,6 +94,33 @@ namespace CodeImp.DoomBuilder.Data FindRanges(textureranges, General.Map.Config.TextureRanges, "textures"); FindRanges(colormapranges, General.Map.Config.ColormapRanges, "colormaps"); + //mxd + invertedflatranges = new List(); + + if(flatranges.Count > 0 && flatranges[0].start > 0) { + LumpRange range = new LumpRange(); + range.start = 0; + range.end = flatranges[0].start - 1; + invertedflatranges.Add(range); + } + + for (int i = 0; i < flatranges.Count; i++) { + if (flatranges[i].start == 0) continue; + LumpRange range = new LumpRange(); + + if(i == flatranges.Count - 1) { + if (flatranges[i].end < file.Lumps.Count - 1) { + range.start = flatranges[i].end + 1; + range.end = file.Lumps.Count - 1; + invertedflatranges.Add(range); + } + } else { + range.start = flatranges[i - 1].end + 1; + range.end = flatranges[i].start - 1; + invertedflatranges.Add(range); + } + } + // We have no destructor GC.SuppressFinalize(this); } @@ -445,8 +473,8 @@ namespace CodeImp.DoomBuilder.Data } // Determine actual scales - if(scalebytex == 0) scalex = defaultscale; else scalex = 1f / ((float)scalebytex / 8f); - if(scalebytey == 0) scaley = defaultscale; else scaley = 1f / ((float)scalebytey / 8f); + if(scalebytex == 0) scalex = defaultscale; else scalex = 1f / (scalebytex / 8f); + if(scalebytey == 0) scaley = defaultscale; else scaley = 1f / (scalebytey / 8f); // Validate data if((width > 0) && (height > 0) && (patches > 0) && @@ -532,22 +560,23 @@ namespace CodeImp.DoomBuilder.Data // Error when suspended if(issuspended) throw new Exception("Data reader is suspended"); - // Strictly read patches only between P_START and P_END? - if(strictpatches) - { - // Find the lump in ranges - foreach(LumpRange range in patchranges) - { + // mxd. First strictly read patches between P_START and P_END + foreach(LumpRange range in patchranges) { + lump = file.FindLump(pname, range.start, range.end); + if(lump != null) return lump.Stream; + } + + if (!strictpatches) { + //mxd. Find the lump anywhere EXCEPT flat ranges (the way it's done in ZDoom) + foreach (LumpRange range in invertedflatranges) { lump = file.FindLump(pname, range.start, range.end); if(lump != null) return lump.Stream; } - } - else - { - // Find the lump anywhere - lump = file.FindLump(pname); - if (lump != null) { - return lump.Stream; + + // Find the lump anywhere IN flat ranges + foreach (LumpRange range in flatranges) { + lump = file.FindLump(pname, range.start, range.end); + if(lump != null) return lump.Stream; } } @@ -623,12 +652,8 @@ namespace CodeImp.DoomBuilder.Data private void LoadFlatsRange(string startlump, string endlump, ref List images) { int startindex, endindex; - float defaultscale; FlatImage image; - // Determine default scale - defaultscale = General.Map.Config.DefaultTextureScale; - // Continue until no more start can be found startindex = file.FindLumpIndex(startlump); while(startindex > -1) diff --git a/Source/Plugins/BuilderModes/ErrorChecks/CheckMissingTextures.cs b/Source/Plugins/BuilderModes/ErrorChecks/CheckMissingTextures.cs index 8f81fdfa..630ea95a 100644 --- a/Source/Plugins/BuilderModes/ErrorChecks/CheckMissingTextures.cs +++ b/Source/Plugins/BuilderModes/ErrorChecks/CheckMissingTextures.cs @@ -59,6 +59,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // set to be sky if (sd.HighRequired() && sd.HighTexture == "-") { + if(sd.Line.Action == 181 && sd.Line.Args[1] > 0) continue; //mxd. Ceiling slopes doesn't require upper texture if (sd.Other != null && sd.Other.Sector.CeilTexture != General.Map.Config.SkyFlatName) { SubmitResult(new ResultMissingTexture(sd, SidedefPart.Upper)); @@ -76,6 +77,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // set to be sky if (sd.LowRequired() && sd.LowTexture == "-") { + if(sd.Line.Action == 181 && sd.Line.Args[0] > 0) continue; //mxd. Floor slopes doesn't require lower texture if (sd.Other != null && sd.Other.Sector.FloorTexture != General.Map.Config.SkyFlatName) { SubmitResult(new ResultMissingTexture(sd, SidedefPart.Lower));