From 3b07c29c39d7d8664d541896728b84d8478ea7d9 Mon Sep 17 00:00:00 2001 From: codeimp Date: Thu, 19 Jun 2008 07:25:01 +0000 Subject: [PATCH] added automatic association highlighting for things, sectors and linedefs --- Documents/todo.txt | 12 +- Source/BuilderModes/BuilderModes.csproj | 1 + .../BuilderModes/ClassicModes/LinedefsMode.cs | 125 +++++++++++++----- .../BuilderModes/ClassicModes/SectorsMode.cs | 105 +++++++++------ .../BuilderModes/ClassicModes/ThingsMode.cs | 99 +++++++++++--- Source/BuilderModes/General/Association.cs | 87 ++++++++++++ Source/BuilderModes/General/BuilderPlug.cs | 88 ++++++++++++ Source/Config/ThingCategory.cs | 4 +- Source/Config/ThingTypeInfo.cs | 4 +- Source/Data/ImageData.cs | 44 ++++-- Source/Types/UniversalType.cs | 2 +- 11 files changed, 461 insertions(+), 110 deletions(-) create mode 100644 Source/BuilderModes/General/Association.cs diff --git a/Documents/todo.txt b/Documents/todo.txt index 2ccf49a4..c34592ae 100644 --- a/Documents/todo.txt +++ b/Documents/todo.txt @@ -1,4 +1,8 @@ -- Show action associations when highlighting line/sector/thing +- Make find/replace features + +- Make advanced drag/rotate/resize/flip/skew/turn/barf mode + +- Make copy/paste features - Make sector gradient features @@ -8,14 +12,8 @@ - Make texture alignment features -- Make find/replace features - -- Make copy/paste features - - Make error checking feature -- Make advanced drag/rotate/resize/flip/skew/turn/barf mode - - Make quick sector draw (square/circle) mode - Make script editor diff --git a/Source/BuilderModes/BuilderModes.csproj b/Source/BuilderModes/BuilderModes.csproj index 49eb451b..0e5a67e7 100644 --- a/Source/BuilderModes/BuilderModes.csproj +++ b/Source/BuilderModes/BuilderModes.csproj @@ -40,6 +40,7 @@ + Form diff --git a/Source/BuilderModes/ClassicModes/LinedefsMode.cs b/Source/BuilderModes/ClassicModes/LinedefsMode.cs index e39f2dfc..935e48d2 100644 --- a/Source/BuilderModes/ClassicModes/LinedefsMode.cs +++ b/Source/BuilderModes/ClassicModes/LinedefsMode.cs @@ -31,6 +31,8 @@ using CodeImp.DoomBuilder.Rendering; using CodeImp.DoomBuilder.Geometry; using CodeImp.DoomBuilder.Editing; using CodeImp.DoomBuilder.Actions; +using CodeImp.DoomBuilder.Types; +using CodeImp.DoomBuilder.Config; #endregion @@ -54,6 +56,8 @@ namespace CodeImp.DoomBuilder.BuilderModes // Highlighted item private Linedef highlighted; + private Association[] association = new Association[Linedef.NUM_ARGS]; + private Association highlightasso = new Association(); // Interface private bool editpressed; @@ -136,8 +140,12 @@ namespace CodeImp.DoomBuilder.BuilderModes if(renderer.StartPlotter(true)) { renderer.PlotLinedefSet(General.Map.Map.Linedefs); + for(int i = 0; i < Linedef.NUM_ARGS; i++) BuilderPlug.Me.PlotAssociations(renderer, association[i]); if((highlighted != null) && !highlighted.IsDisposed) + { + BuilderPlug.Me.PlotReverseAssociations(renderer, highlightasso); renderer.PlotLinedef(highlighted, General.Colors.Highlight); + } renderer.PlotVerticesSet(General.Map.Map.Vertices); renderer.Finish(); } @@ -150,15 +158,13 @@ namespace CodeImp.DoomBuilder.BuilderModes renderer.Finish(); } - // Selecting? - if(selecting) + // Render selection + if(renderer.StartOverlay(true)) { - // Render selection - if(renderer.StartOverlay(true)) - { - RenderMultiSelection(); - renderer.Finish(); - } + for(int i = 0; i < Linedef.NUM_ARGS; i++) BuilderPlug.Me.RenderAssociations(renderer, association[i]); + if((highlighted != null) && !highlighted.IsDisposed) BuilderPlug.Me.RenderReverseAssociations(renderer, highlightasso); + if(selecting) RenderMultiSelection(); + renderer.Finish(); } renderer.Present(); @@ -167,31 +173,88 @@ namespace CodeImp.DoomBuilder.BuilderModes // This highlights a new item protected void Highlight(Linedef l) { - // Update display - if(renderer.StartPlotter(false)) - { - // Undraw previous highlight - if((highlighted != null) && !highlighted.IsDisposed) - { - renderer.PlotLinedef(highlighted, renderer.DetermineLinedefColor(highlighted)); - renderer.PlotVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start)); - renderer.PlotVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End)); - } - - // Set new highlight - highlighted = l; + bool completeredraw = false; + LinedefActionInfo action = null; - // Render highlighted item - if((highlighted != null) && !highlighted.IsDisposed) - { - renderer.PlotLinedef(highlighted, General.Colors.Highlight); - renderer.PlotVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start)); - renderer.PlotVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End)); - } + // Often we can get away by simply undrawing the previous + // highlight and drawing the new highlight. But if associations + // are or were drawn we need to redraw the entire display. + + // Previous association highlights something? + if((highlighted != null) && (highlighted.Tag > 0)) completeredraw = true; + + // Set highlight association + if(l != null) + highlightasso.Set(l.Tag, UniversalType.LinedefTag); + else + highlightasso.Set(0, 0); + + // New association highlights something? + if((l != null) && (l.Tag > 0)) completeredraw = true; + + if(l != null) + { + // Check if we can find the linedefs action + if((l.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(l.Action)) + action = General.Map.Config.LinedefActions[l.Action]; + } + + // Determine linedef associations + for(int i = 0; i < Linedef.NUM_ARGS; i++) + { + // Previous association highlights something? + if((association[i].type == UniversalType.SectorTag) || + (association[i].type == UniversalType.LinedefTag) || + (association[i].type == UniversalType.ThingTag)) completeredraw = true; - // Done - renderer.Finish(); - renderer.Present(); + // Make new association + if(action != null) + association[i].Set(l.Args[i], action.Args[i].Type); + else + association[i].Set(0, 0); + + // New association highlights something? + if((association[i].type == UniversalType.SectorTag) || + (association[i].type == UniversalType.LinedefTag) || + (association[i].type == UniversalType.ThingTag)) completeredraw = true; + } + + // If we're changing associations, then we + // need to redraw the entire display + if(completeredraw) + { + // Set new highlight and redraw completely + highlighted = l; + General.Interface.RedrawDisplay(); + } + else + { + // Update display + if(renderer.StartPlotter(false)) + { + // Undraw previous highlight + if((highlighted != null) && !highlighted.IsDisposed) + { + renderer.PlotLinedef(highlighted, renderer.DetermineLinedefColor(highlighted)); + renderer.PlotVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start)); + renderer.PlotVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End)); + } + + // Set new highlight + highlighted = l; + + // Render highlighted item + if((highlighted != null) && !highlighted.IsDisposed) + { + renderer.PlotLinedef(highlighted, General.Colors.Highlight); + renderer.PlotVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start)); + renderer.PlotVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End)); + } + + // Done + renderer.Finish(); + renderer.Present(); + } } // Show highlight info diff --git a/Source/BuilderModes/ClassicModes/SectorsMode.cs b/Source/BuilderModes/ClassicModes/SectorsMode.cs index f065dc67..1f675204 100644 --- a/Source/BuilderModes/ClassicModes/SectorsMode.cs +++ b/Source/BuilderModes/ClassicModes/SectorsMode.cs @@ -32,6 +32,7 @@ using CodeImp.DoomBuilder.Geometry; using CodeImp.DoomBuilder.Editing; using System.Drawing; using CodeImp.DoomBuilder.Actions; +using CodeImp.DoomBuilder.Types; #endregion @@ -53,6 +54,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Highlighted item protected Sector highlighted; + private Association highlightasso = new Association(); // Interface protected bool editpressed; @@ -199,7 +201,10 @@ namespace CodeImp.DoomBuilder.BuilderModes renderer.PlotLinedefSet(General.Map.Map.Linedefs); renderer.PlotVerticesSet(General.Map.Map.Vertices); if((highlighted != null) && !highlighted.IsDisposed) + { renderer.PlotSector(highlighted, General.Colors.Highlight); + BuilderPlug.Me.PlotReverseAssociations(renderer, highlightasso); + } renderer.Finish(); } @@ -211,15 +216,12 @@ namespace CodeImp.DoomBuilder.BuilderModes renderer.Finish(); } - // Selecting? - if(selecting) + // Render selection + if(renderer.StartOverlay(true)) { - // Render selection - if(renderer.StartOverlay(true)) - { - RenderMultiSelection(); - renderer.Finish(); - } + if((highlighted != null) && !highlighted.IsDisposed) BuilderPlug.Me.RenderReverseAssociations(renderer, highlightasso); + if(selecting) RenderMultiSelection(); + renderer.Finish(); } renderer.Present(); @@ -228,39 +230,68 @@ namespace CodeImp.DoomBuilder.BuilderModes // This highlights a new item protected void Highlight(Sector s) { - // Update display - if(renderer.StartPlotter(false)) + bool completeredraw = false; + + // Often we can get away by simply undrawing the previous + // highlight and drawing the new highlight. But if associations + // are or were drawn we need to redraw the entire display. + + // Previous association highlights something? + if((highlighted != null) && (highlighted.Tag > 0)) completeredraw = true; + + // Set highlight association + if(s != null) + highlightasso.Set(s.Tag, UniversalType.SectorTag); + else + highlightasso.Set(0, 0); + + // New association highlights something? + if((s != null) && (s.Tag > 0)) completeredraw = true; + + // If we're changing associations, then we + // need to redraw the entire display + if(completeredraw) { - // Undraw previous highlight - if((highlighted != null) && !highlighted.IsDisposed) - renderer.PlotSector(highlighted); - - /* - // Undraw highlighted things - if(highlighted != null) - foreach(Thing t in highlighted.Things) - renderer.RenderThing(t, renderer.DetermineThingColor(t)); - */ - - // Set new highlight + // Set new highlight and redraw completely highlighted = s; - - // Render highlighted item - if((highlighted != null) && !highlighted.IsDisposed) - renderer.PlotSector(highlighted, General.Colors.Highlight); - - /* - // Render highlighted things - if(highlighted != null) - foreach(Thing t in highlighted.Things) - renderer.RenderThing(t, General.Colors.Highlight); - */ - - // Done - renderer.Finish(); - renderer.Present(); + General.Interface.RedrawDisplay(); } + else + { + // Update display + if(renderer.StartPlotter(false)) + { + // Undraw previous highlight + if((highlighted != null) && !highlighted.IsDisposed) + renderer.PlotSector(highlighted); + /* + // Undraw highlighted things + if(highlighted != null) + foreach(Thing t in highlighted.Things) + renderer.RenderThing(t, renderer.DetermineThingColor(t)); + */ + + // Set new highlight + highlighted = s; + + // Render highlighted item + if((highlighted != null) && !highlighted.IsDisposed) + renderer.PlotSector(highlighted, General.Colors.Highlight); + + /* + // Render highlighted things + if(highlighted != null) + foreach(Thing t in highlighted.Things) + renderer.RenderThing(t, General.Colors.Highlight); + */ + + // Done + renderer.Finish(); + renderer.Present(); + } + } + // Show highlight info if((highlighted != null) && !highlighted.IsDisposed) General.Interface.ShowSectorInfo(highlighted); diff --git a/Source/BuilderModes/ClassicModes/ThingsMode.cs b/Source/BuilderModes/ClassicModes/ThingsMode.cs index eaa89bb6..4ed08c2e 100644 --- a/Source/BuilderModes/ClassicModes/ThingsMode.cs +++ b/Source/BuilderModes/ClassicModes/ThingsMode.cs @@ -31,6 +31,8 @@ using CodeImp.DoomBuilder.Rendering; using CodeImp.DoomBuilder.Geometry; using CodeImp.DoomBuilder.Editing; using CodeImp.DoomBuilder.Actions; +using CodeImp.DoomBuilder.Config; +using CodeImp.DoomBuilder.Types; #endregion @@ -54,6 +56,8 @@ namespace CodeImp.DoomBuilder.BuilderModes // Highlighted item private Thing highlighted; + private Association[] association = new Association[Thing.NUM_ARGS]; + private Association highlightasso = new Association(); // Interface private bool editpressed; @@ -121,6 +125,8 @@ namespace CodeImp.DoomBuilder.BuilderModes { renderer.PlotLinedefSet(General.Map.Map.Linedefs); renderer.PlotVerticesSet(General.Map.Map.Vertices); + for(int i = 0; i < Thing.NUM_ARGS; i++) BuilderPlug.Me.PlotAssociations(renderer, association[i]); + if((highlighted != null) && !highlighted.IsDisposed) BuilderPlug.Me.PlotReverseAssociations(renderer, highlightasso); renderer.Finish(); } @@ -129,8 +135,12 @@ namespace CodeImp.DoomBuilder.BuilderModes { renderer.RenderThingSet(General.Map.ThingsFilter.HiddenThings, Presentation.THINGS_HIDDEN_ALPHA); renderer.RenderThingSet(General.Map.ThingsFilter.VisibleThings, 1.0f); + for(int i = 0; i < Thing.NUM_ARGS; i++) BuilderPlug.Me.RenderAssociations(renderer, association[i]); if((highlighted != null) && !highlighted.IsDisposed) + { + BuilderPlug.Me.RenderReverseAssociations(renderer, highlightasso); renderer.RenderThing(highlighted, General.Colors.Highlight, 1.0f); + } renderer.Finish(); } @@ -151,25 +161,82 @@ namespace CodeImp.DoomBuilder.BuilderModes // This highlights a new item protected void Highlight(Thing t) { - // Update display - if(renderer.StartThings(false)) + bool completeredraw = false; + LinedefActionInfo action = null; + + // Often we can get away by simply undrawing the previous + // highlight and drawing the new highlight. But if associations + // are or were drawn we need to redraw the entire display. + + // Previous association highlights something? + if((highlighted != null) && (highlighted.Tag > 0)) completeredraw = true; + + // Set highlight association + if(t != null) + highlightasso.Set(t.Tag, UniversalType.ThingTag); + else + highlightasso.Set(0, 0); + + // New association highlights something? + if((t != null) && (t.Tag > 0)) completeredraw = true; + + if(t != null) { - // Undraw previous highlight - if((highlighted != null) && !highlighted.IsDisposed) - renderer.RenderThing(highlighted, renderer.DetermineThingColor(highlighted), 1.0f); - - // Set new highlight - highlighted = t; - - // Render highlighted item - if((highlighted != null) && !highlighted.IsDisposed) - renderer.RenderThing(highlighted, General.Colors.Highlight, 1.0f); - - // Done - renderer.Finish(); - renderer.Present(); + // Check if we can find the linedefs action + if((t.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(t.Action)) + action = General.Map.Config.LinedefActions[t.Action]; } + + // Determine linedef associations + for(int i = 0; i < Thing.NUM_ARGS; i++) + { + // Previous association highlights something? + if((association[i].type == UniversalType.SectorTag) || + (association[i].type == UniversalType.LinedefTag) || + (association[i].type == UniversalType.ThingTag)) completeredraw = true; + + // Make new association + if(action != null) + association[i].Set(t.Args[i], action.Args[i].Type); + else + association[i].Set(0, 0); + + // New association highlights something? + if((association[i].type == UniversalType.SectorTag) || + (association[i].type == UniversalType.LinedefTag) || + (association[i].type == UniversalType.ThingTag)) completeredraw = true; + } + + // If we're changing associations, then we + // need to redraw the entire display + if(completeredraw) + { + // Set new highlight and redraw completely + highlighted = t; + General.Interface.RedrawDisplay(); + } + else + { + // Update display + if(renderer.StartThings(false)) + { + // Undraw previous highlight + if((highlighted != null) && !highlighted.IsDisposed) + renderer.RenderThing(highlighted, renderer.DetermineThingColor(highlighted), 1.0f); + // Set new highlight + highlighted = t; + + // Render highlighted item + if((highlighted != null) && !highlighted.IsDisposed) + renderer.RenderThing(highlighted, General.Colors.Highlight, 1.0f); + + // Done + renderer.Finish(); + renderer.Present(); + } + } + // Show highlight info if((highlighted != null) && !highlighted.IsDisposed) General.Interface.ShowThingInfo(highlighted); diff --git a/Source/BuilderModes/General/Association.cs b/Source/BuilderModes/General/Association.cs new file mode 100644 index 00000000..6620dfc5 --- /dev/null +++ b/Source/BuilderModes/General/Association.cs @@ -0,0 +1,87 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.Windows.Forms; +using System.IO; +using System.Reflection; +using CodeImp.DoomBuilder.Windows; +using CodeImp.DoomBuilder.IO; +using CodeImp.DoomBuilder.Map; +using CodeImp.DoomBuilder.Rendering; +using CodeImp.DoomBuilder.Geometry; +using System.Drawing; +using CodeImp.DoomBuilder.Editing; +using CodeImp.DoomBuilder.Plugins; +using CodeImp.DoomBuilder.Types; +using CodeImp.DoomBuilder.Config; + +#endregion + +namespace CodeImp.DoomBuilder.BuilderModes +{ + public struct Association + { + public int tag; + public UniversalType type; + + // This sets up the association + public Association(int tag, int type) + { + this.tag = tag; + this.type = (UniversalType)type; + } + + // This sets up the association + public Association(int tag, UniversalType type) + { + this.tag = tag; + this.type = type; + } + + // This sets up the association + public void Set(int tag, int type) + { + this.tag = tag; + this.type = (UniversalType)type; + } + + // This sets up the association + public void Set(int tag, UniversalType type) + { + this.tag = tag; + this.type = type; + } + + // This compares an association + public static bool operator ==(Association a, Association b) + { + return (a.tag == b.tag) && (a.type == b.type); + } + + // This compares an association + public static bool operator !=(Association a, Association b) + { + return (a.tag != b.tag) || (a.type != b.type); + } + } +} diff --git a/Source/BuilderModes/General/BuilderPlug.cs b/Source/BuilderModes/General/BuilderPlug.cs index f9fedf86..a4c92b5f 100644 --- a/Source/BuilderModes/General/BuilderPlug.cs +++ b/Source/BuilderModes/General/BuilderPlug.cs @@ -32,6 +32,8 @@ using CodeImp.DoomBuilder.Geometry; using System.Drawing; using CodeImp.DoomBuilder.Editing; using CodeImp.DoomBuilder.Plugins; +using CodeImp.DoomBuilder.Types; +using CodeImp.DoomBuilder.Config; #endregion @@ -110,5 +112,91 @@ namespace CodeImp.DoomBuilder.BuilderModes } #endregion + + #region ================== Tools + + // This renders the associated sectors/linedefs with the indication color + public void PlotAssociations(IRenderer2D renderer, Association asso) + { + // Tag must be above zero + if(asso.tag <= 0) return; + + // Sectors? + if(asso.type == UniversalType.SectorTag) + { + foreach(Sector s in General.Map.Map.Sectors) + if(s.Tag == asso.tag) renderer.PlotSector(s, General.Colors.Indication); + } + // Linedefs? + else if(asso.type == UniversalType.LinedefTag) + { + foreach(Linedef l in General.Map.Map.Linedefs) + { + if(l.Tag == asso.tag) renderer.PlotLinedef(l, General.Colors.Indication); + } + } + } + + // This renders the associated things with the indication color + public void RenderAssociations(IRenderer2D renderer, Association asso) + { + // Tag must be above zero + if(asso.tag <= 0) return; + + // Things? + if(asso.type == UniversalType.ThingTag) + { + foreach(Thing t in General.Map.Map.Things) + { + if(t.Tag == asso.tag) renderer.RenderThing(t, General.Colors.Indication, 1.0f); + } + } + } + + // This renders the associated sectors/linedefs with the indication color + public void PlotReverseAssociations(IRenderer2D renderer, Association asso) + { + // Tag must be above zero + if(asso.tag <= 0) return; + + // Linedefs + foreach(Linedef l in General.Map.Map.Linedefs) + { + // Known action on this line? + if((l.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(l.Action)) + { + LinedefActionInfo action = General.Map.Config.LinedefActions[l.Action]; + if((action.Args[0].Type == (int)asso.type) && (l.Args[0] == asso.tag)) renderer.PlotLinedef(l, General.Colors.Indication); + if((action.Args[1].Type == (int)asso.type) && (l.Args[1] == asso.tag)) renderer.PlotLinedef(l, General.Colors.Indication); + if((action.Args[2].Type == (int)asso.type) && (l.Args[2] == asso.tag)) renderer.PlotLinedef(l, General.Colors.Indication); + if((action.Args[3].Type == (int)asso.type) && (l.Args[3] == asso.tag)) renderer.PlotLinedef(l, General.Colors.Indication); + if((action.Args[4].Type == (int)asso.type) && (l.Args[4] == asso.tag)) renderer.PlotLinedef(l, General.Colors.Indication); + } + } + } + + // This renders the associated things with the indication color + public void RenderReverseAssociations(IRenderer2D renderer, Association asso) + { + // Tag must be above zero + if(asso.tag <= 0) return; + + // Things + foreach(Thing t in General.Map.Map.Things) + { + // Known action on this thing? + if((t.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(t.Action)) + { + LinedefActionInfo action = General.Map.Config.LinedefActions[t.Action]; + if((action.Args[0].Type == (int)asso.type) && (t.Args[0] == asso.tag)) renderer.RenderThing(t, General.Colors.Indication, 1.0f); + if((action.Args[1].Type == (int)asso.type) && (t.Args[1] == asso.tag)) renderer.RenderThing(t, General.Colors.Indication, 1.0f); + if((action.Args[2].Type == (int)asso.type) && (t.Args[2] == asso.tag)) renderer.RenderThing(t, General.Colors.Indication, 1.0f); + if((action.Args[3].Type == (int)asso.type) && (t.Args[3] == asso.tag)) renderer.RenderThing(t, General.Colors.Indication, 1.0f); + if((action.Args[4].Type == (int)asso.type) && (t.Args[4] == asso.tag)) renderer.RenderThing(t, General.Colors.Indication, 1.0f); + } + } + } + + #endregion } } diff --git a/Source/Config/ThingCategory.cs b/Source/Config/ThingCategory.cs index e144e82b..5a2cf814 100644 --- a/Source/Config/ThingCategory.cs +++ b/Source/Config/ThingCategory.cs @@ -106,8 +106,8 @@ namespace CodeImp.DoomBuilder.Config this.errorcheck = cfg.ReadSetting("thingtypes." + name + ".errorcheck", 0); // Safety - if(this.width < 2f) this.width = 2f; - if(this.height < 2f) this.height = 2f; + if(this.width < 8f) this.width = 8f; + if(this.height < 8f) this.height = 8f; // Go for all items in category dic = cfg.ReadSetting("thingtypes." + name, new Hashtable()); diff --git a/Source/Config/ThingTypeInfo.cs b/Source/Config/ThingTypeInfo.cs index 4f16851f..cadc98da 100644 --- a/Source/Config/ThingTypeInfo.cs +++ b/Source/Config/ThingTypeInfo.cs @@ -122,8 +122,8 @@ namespace CodeImp.DoomBuilder.Config this.errorcheck = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".errorcheck", cat.ErrorCheck); // Safety - if(this.width < 2f) this.width = 2f; - if(this.height < 2f) this.height = 2f; + if(this.width < 8f) this.width = 8f; + if(this.height < 8f) this.height = 8f; // Make long name for sprite lookup this.spritelongname = Lump.MakeLongName(this.sprite); diff --git a/Source/Data/ImageData.cs b/Source/Data/ImageData.cs index 96e476fa..c03ccf60 100644 --- a/Source/Data/ImageData.cs +++ b/Source/Data/ImageData.cs @@ -153,7 +153,7 @@ namespace CodeImp.DoomBuilder.Data // This requests loading the image public virtual void LoadImage() { - BitmapData bmpdata; + BitmapData bmpdata = null; // Determine amounts float gamma = (float)(General.Settings.ImageBrightness + 10) * 0.1f; @@ -162,21 +162,37 @@ namespace CodeImp.DoomBuilder.Data // This applies brightness correction on the image if((bitmap != null) && usecolorcorrection) { - bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); - byte* pixels = (byte*)(bmpdata.Scan0.ToPointer()); - for(int p = 0; p < bmpdata.Stride * bmpdata.Height; p += 4) + try { - // Apply color correction for individual colors - float r = (float)pixels[p + 0] * gamma + bright; - float g = (float)pixels[p + 1] * gamma + bright; - float b = (float)pixels[p + 2] * gamma + bright; - - // Clamp to 0..255 range - if(r < 0f) pixels[p + 0] = 0; else if(r > 255f) pixels[p + 0] = 255; else pixels[p + 0] = (byte)r; - if(g < 0f) pixels[p + 1] = 0; else if(g > 255f) pixels[p + 1] = 255; else pixels[p + 1] = (byte)g; - if(b < 0f) pixels[p + 2] = 0; else if(b > 255f) pixels[p + 2] = 255; else pixels[p + 2] = (byte)b; + // Try locking the bitmap + bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); + } + catch(Exception e) + { + General.WriteLogLine("ERROR: Cannot lock image '" + name + "' for color correction. " + e.GetType().Name + ": " + e.Message); + } + + // Bitmap locked? + if(bmpdata != null) + { + // Apply color correction + byte* pixels = (byte*)(bmpdata.Scan0.ToPointer()); + for(int p = 0; p < bmpdata.Stride * bmpdata.Height; p += 4) + { + // Apply color correction for individual colors + float r = (float)pixels[p + 0] * gamma + bright; + float g = (float)pixels[p + 1] * gamma + bright; + float b = (float)pixels[p + 2] * gamma + bright; + + // Clamp to 0..255 range + if(r < 0f) pixels[p + 0] = 0; else if(r > 255f) pixels[p + 0] = 255; else pixels[p + 0] = (byte)r; + if(g < 0f) pixels[p + 1] = 0; else if(g > 255f) pixels[p + 1] = 255; else pixels[p + 1] = (byte)g; + if(b < 0f) pixels[p + 2] = 0; else if(b > 255f) pixels[p + 2] = 255; else pixels[p + 2] = (byte)b; + } + + // Done with the lock + bitmap.UnlockBits(bmpdata); } - bitmap.UnlockBits(bmpdata); } // Done, reset load state diff --git a/Source/Types/UniversalType.cs b/Source/Types/UniversalType.cs index 4189c617..d184c1b2 100644 --- a/Source/Types/UniversalType.cs +++ b/Source/Types/UniversalType.cs @@ -27,7 +27,7 @@ using System.IO; namespace CodeImp.DoomBuilder.Types { - internal enum UniversalType : int + public enum UniversalType : int { Integer = 0, Float = 1,