From 12d9e1b08f2529106b369333fb92a28b9a91be14 Mon Sep 17 00:00:00 2001 From: MaxED Date: Tue, 30 Jul 2013 09:25:27 +0000 Subject: [PATCH] Fixed several crashes when trying to load not existing images and models from folder/pk3/pk7 resources. --- Source/Core/Data/DataManager.cs | 10 ++-- Source/Core/Data/FileImage.cs | 51 +++++++++---------- Source/Core/Data/PK3Reader.cs | 3 +- Source/Core/GZBuilder/md3/ModelReader.cs | 8 +-- Source/Core/Geometry/Tools.cs | 13 ----- Source/Core/Map/Thing.cs | 2 +- Source/Core/Rendering/Renderer2D.cs | 18 +++---- .../ClassicModes/DrawGeometryMode.cs | 30 ++++++----- 8 files changed, 60 insertions(+), 75 deletions(-) diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index 0924229e..fb44412b 100644 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -672,17 +672,19 @@ namespace CodeImp.DoomBuilder.Data } //mxd. This loads a model - internal void ProcessModel(int type) { - if(modeldefEntries[type].LoadState != ModelLoadState.None) return; + internal bool ProcessModel(int type) { + if(modeldefEntries[type].LoadState != ModelLoadState.None) return true; //create models ModelReader.Load(modeldefEntries[type], containers, General.Map.Graphics.Device); if(modeldefEntries[type].Model != null) { modeldefEntries[type].LoadState = ModelLoadState.Ready; - } else { - modeldefEntries.Remove(type); + return true; } + + modeldefEntries.Remove(type); + return false; } // This updates the used-in-map status on all textures and flats diff --git a/Source/Core/Data/FileImage.cs b/Source/Core/Data/FileImage.cs index 65d8d49b..e50892ee 100644 --- a/Source/Core/Data/FileImage.cs +++ b/Source/Core/Data/FileImage.cs @@ -91,37 +91,32 @@ namespace CodeImp.DoomBuilder.Data // Load file data if(bitmap != null) bitmap.Dispose(); bitmap = null; - if(!File.Exists(fullName)) { //mxd - General.ErrorLogger.Add(ErrorType.Error, "Image file '" + fullName + "' could not be read: no such file."); + MemoryStream filedata = new MemoryStream(File.ReadAllBytes(fullName)); + + // Get a reader for the data + IImageReader reader = ImageDataFormat.GetImageReader(filedata, probableformat, General.Map.Data.Palette); + if(!(reader is UnknownImageReader)) { + // Load the image + filedata.Seek(0, SeekOrigin.Begin); + try { bitmap = reader.ReadAsBitmap(filedata); } catch(InvalidDataException) { + // Data cannot be read! + bitmap = null; + } + } + + // Not loaded? + if(bitmap == null) { + General.ErrorLogger.Add(ErrorType.Error, "Image file '" + fullName + "' data format could not be read, while loading image '" + this.Name + "'. Is this a valid picture file at all?"); loadfailed = true; } else { - MemoryStream filedata = new MemoryStream(File.ReadAllBytes(fullName)); - - // Get a reader for the data - IImageReader reader = ImageDataFormat.GetImageReader(filedata, probableformat, General.Map.Data.Palette); - if(!(reader is UnknownImageReader)) { - // Load the image - filedata.Seek(0, SeekOrigin.Begin); - try { bitmap = reader.ReadAsBitmap(filedata); } catch(InvalidDataException) { - // Data cannot be read! - bitmap = null; - } - } - - // Not loaded? - if(bitmap == null) { - General.ErrorLogger.Add(ErrorType.Error, "Image file '" + fullName + "' data format could not be read, while loading image '" + this.Name + "'. Is this a valid picture file at all?"); - loadfailed = true; - } else { - // Get width and height - width = bitmap.Size.Width; - height = bitmap.Size.Height; - } - - // Pass on to base - filedata.Dispose(); - base.LocalLoadImage(); + // Get width and height + width = bitmap.Size.Width; + height = bitmap.Size.Height; } + + // Pass on to base + filedata.Dispose(); + base.LocalLoadImage(); } } diff --git a/Source/Core/Data/PK3Reader.cs b/Source/Core/Data/PK3Reader.cs index 90dca575..22d76966 100644 --- a/Source/Core/Data/PK3Reader.cs +++ b/Source/Core/Data/PK3Reader.cs @@ -346,9 +346,8 @@ namespace CodeImp.DoomBuilder.Data // Nothing found? if (filedata == null){ //mxd - //throw new FileNotFoundException("Cannot find the file " + filename + " in archive " + location.location + "."); General.ErrorLogger.Add(ErrorType.Error, "Cannot find the file " + filename + " in archive " + location.location + "."); - return null; + return new MemoryStream(); } filedata.Position = 0; //mxd. rewind before use diff --git a/Source/Core/GZBuilder/md3/ModelReader.cs b/Source/Core/GZBuilder/md3/ModelReader.cs index 23c07580..12ba132d 100644 --- a/Source/Core/GZBuilder/md3/ModelReader.cs +++ b/Source/Core/GZBuilder/md3/ModelReader.cs @@ -43,7 +43,10 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 //load mesh MemoryStream ms = LoadFile(containers, mde.ModelNames[i], true); - if(ms == null) continue; + if (ms == null) { + General.ErrorLogger.Add(ErrorType.Error, "ModelLoader: error while loading '" + mde.ModelNames[i] + "': unable to find file."); + continue; + } string ext = Path.GetExtension(mde.ModelNames[i]); @@ -59,8 +62,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 //got errors? if(!String.IsNullOrEmpty(result.Errors)) { - General.ErrorLogger.Add(ErrorType.Error, "ModelLoader: error while loading " + mde.ModelNames[i] + ": " + result.Errors); - continue; + General.ErrorLogger.Add(ErrorType.Error, "ModelLoader: error while loading '" + mde.ModelNames[i] + "': " + result.Errors); } else { //add loaded data to ModeldefEntry mde.Model.Meshes.AddRange(result.Meshes); diff --git a/Source/Core/Geometry/Tools.cs b/Source/Core/Geometry/Tools.cs index 0a702291..1cc7827b 100644 --- a/Source/Core/Geometry/Tools.cs +++ b/Source/Core/Geometry/Tools.cs @@ -1438,19 +1438,6 @@ namespace CodeImp.DoomBuilder.Geometry } } - //mxd. Clamp texture offsets of changed lines - List changedLines = new List(); - - foreach(Vertex v in newverts) { - if(v.Linedefs == null) - continue; - - foreach(Linedef l in v.Linedefs) { - if(!changedLines.Contains(l)) - changedLines.Add(l); - } - } - // Mark new geometry only General.Map.Map.ClearMarkedLinedefs(false); General.Map.Map.ClearMarkedVertices(false); diff --git a/Source/Core/Map/Thing.cs b/Source/Core/Map/Thing.cs index 4f2c6886..56a8de45 100644 --- a/Source/Core/Map/Thing.cs +++ b/Source/Core/Map/Thing.cs @@ -250,7 +250,7 @@ namespace CodeImp.DoomBuilder.Map if(!isModel) return; if(General.Map.Data.ModeldefEntries[type].LoadState == ModelLoadState.None) - General.Map.Data.ProcessModel(type); + isModel = General.Map.Data.ProcessModel(type); } // This translates the flags into UDMF fields diff --git a/Source/Core/Rendering/Renderer2D.cs b/Source/Core/Rendering/Renderer2D.cs index 43716b51..f48936cd 100644 --- a/Source/Core/Rendering/Renderer2D.cs +++ b/Source/Core/Rendering/Renderer2D.cs @@ -1154,18 +1154,16 @@ namespace CodeImp.DoomBuilder.Rendering ModelData mde; foreach(KeyValuePair> group in thingsWithModel) { - lock(General.Map.Data.ModeldefEntries[group.Key]) { - mde = General.Map.Data.ModeldefEntries[group.Key]; - foreach(KeyValuePair thingData in group.Value) { - graphics.Shaders.Things2D.FillColor = thingData.Value.Selected ? cSel : cWire; + mde = General.Map.Data.ModeldefEntries[group.Key]; + foreach(KeyValuePair thingData in group.Value) { + graphics.Shaders.Things2D.FillColor = thingData.Value.Selected ? cSel : cWire; - for(int i = 0; i < mde.Model.Meshes.Count; i++) { - graphics.Shaders.Things2D.SetTransformSettings(thingData.Key, thingData.Value.Angle, scale * thingData.Value.Scale); - graphics.Shaders.Things2D.ApplySettings(); + for(int i = 0; i < mde.Model.Meshes.Count; i++) { + graphics.Shaders.Things2D.SetTransformSettings(thingData.Key, thingData.Value.Angle, scale * thingData.Value.Scale); + graphics.Shaders.Things2D.ApplySettings(); - // Draw - mde.Model.Meshes[i].DrawSubset(0); - } + // Draw + mde.Model.Meshes[i].DrawSubset(0); } } } diff --git a/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs index 81fc3682..adbb2c2f 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs @@ -213,6 +213,8 @@ namespace CodeImp.DoomBuilder.BuilderModes public static DrawnVertex GetCurrentPosition(Vector2D mousemappos, bool snaptonearest, bool snaptogrid, IRenderer2D renderer, List points) { DrawnVertex p = new DrawnVertex(); + p.stitch = true; //mxd. Setting these to false seems to be a good way to create invalid geometry... + p.stitchline = true; //mxd Vector2D vm = mousemappos; float vrange = BuilderPlug.Me.StitchRange / renderer.Scale; @@ -225,8 +227,8 @@ namespace CodeImp.DoomBuilder.BuilderModes if(Vector2D.DistanceSq(mousemappos, v.pos) < (vrange * vrange)) { p.pos = v.pos; - p.stitch = true; - p.stitchline = true; + //p.stitch = true; + //p.stitchline = true; return p; } } @@ -236,8 +238,8 @@ namespace CodeImp.DoomBuilder.BuilderModes if(nv != null) { p.pos = nv.Position; - p.stitch = true; - p.stitchline = true; + //p.stitch = true; + //p.stitchline = true; return p; } @@ -270,8 +272,8 @@ namespace CodeImp.DoomBuilder.BuilderModes { // Align to the closest grid intersection p.pos = found_coord; - p.stitch = true; - p.stitchline = true; + //p.stitch = true; + //p.stitchline = true; return p; } } @@ -279,8 +281,8 @@ namespace CodeImp.DoomBuilder.BuilderModes { // Aligned to line p.pos = nl.NearestOnLine(mousemappos); - p.stitch = true; - p.stitchline = true; + //p.stitch = true; + //p.stitchline = true; return p; } } @@ -293,8 +295,8 @@ namespace CodeImp.DoomBuilder.BuilderModes if(Vector2D.DistanceSq(mousemappos, points[0].pos) < (vrange * vrange)) { p.pos = points[0].pos; - p.stitch = true; - p.stitchline = false; + //p.stitch = true; + //p.stitchline = false; return p; } } @@ -349,16 +351,16 @@ namespace CodeImp.DoomBuilder.BuilderModes // special handling if (p.pos.x > General.Map.Config.RightBoundary) p.pos.x = General.Map.Config.RightBoundary; if (p.pos.y < General.Map.Config.BottomBoundary) p.pos.y = General.Map.Config.BottomBoundary; - p.stitch = snaptonearest; - p.stitchline = snaptonearest; + //p.stitch = snaptonearest; + //p.stitchline = snaptonearest; return p; } else { // Normal position p.pos = vm; - p.stitch = snaptonearest; - p.stitchline = snaptonearest; + //p.stitch = snaptonearest; + //p.stitchline = snaptonearest; return p; } }