From cf3d416967d453ad4c316de2b14172dbc4ee199f Mon Sep 17 00:00:00 2001 From: MaxED Date: Mon, 29 Jul 2013 08:50:50 +0000 Subject: [PATCH] Renderer now works much faster in 2D modes. Textures now load up to 2x faster when "mix textures and flats" flag is set in game configuration. TEXTUREx/TEXTURES: texture will now be created if at least one of it's patches is loaded. Visual mode: fixed a crash when "Slope floor to here" (9500) or "Slope ceiling to here" (9501) things were not inside sector. Fixed: flats were not loaded form wads inside Directory and PK3/PK7 resources. Sector Info Panel, Linedef Info Panel: texture size was shown for unknown textures. --- Source/Core/Builder.csproj | 3 +- Source/Core/Config/ResourceTextureSet.cs | 18 +- Source/Core/Controls/FlatSelectorControl.cs | 2 +- Source/Core/Controls/LinedefInfoPanel.cs | 2 +- Source/Core/Controls/SectorInfoPanel.cs | 2 +- .../Core/Controls/TextureSelectorControl.cs | 2 +- Source/Core/Data/DataManager.cs | 169 +++++------- Source/Core/Data/DirectoryReader.cs | 16 +- Source/Core/Data/FileImage.cs | 62 +++-- Source/Core/Data/HighResImage.cs | 26 +- Source/Core/Data/ImageData.cs | 4 +- Source/Core/Data/PK3Reader.cs | 12 +- Source/Core/Data/PK3StructuredReader.cs | 18 ++ Source/Core/Data/TextureImage.cs | 15 +- Source/Core/Editing/UndoManager.cs | 6 +- .../Data/{GZDoomLight.cs => DynamicLight.cs} | 13 +- .../Data/{ModelDefEntry.cs => ModelData.cs} | 38 ++- Source/Core/GZBuilder/Data/ModelLoadState.cs | 14 + Source/Core/GZBuilder/GZDoom/GldefsParser.cs | 14 +- .../Core/GZBuilder/GZDoom/ModeldefParser.cs | 18 +- .../GZBuilder/GZDoom/ModeldefStructure.cs | 4 +- Source/Core/GZBuilder/GZGeneral.cs | 2 +- Source/Core/GZBuilder/md3/ModelReader.cs | 34 ++- Source/Core/General/MapManager.cs | 44 ++-- Source/Core/Map/Linedef.cs | 3 +- Source/Core/Map/MapSet.cs | 20 +- Source/Core/Map/Thing.cs | 31 ++- Source/Core/Rendering/IRenderer2D.cs | 2 +- Source/Core/Rendering/Renderer2D.cs | 242 ++++++++---------- Source/Core/Rendering/Renderer3D.cs | 31 ++- Source/Core/VisualModes/VisualThing.cs | 69 ++--- Source/Core/Windows/MainForm.cs | 8 +- Source/Core/ZDoom/TexturesParser.cs | 2 +- .../ClassicModes/BaseClassicMode.cs | 4 +- .../BuilderModes/ClassicModes/BridgeMode.cs | 1 + .../ClassicModes/BrightnessMode.cs | 1 + .../ClassicModes/DragGeometryMode.cs | 1 + .../ClassicModes/DrawGeometryMode.cs | 1 + .../ClassicModes/EditSelectionMode.cs | 2 +- .../ClassicModes/FlatAlignMode.cs | 2 +- .../BuilderModes/ClassicModes/LinedefsMode.cs | 16 +- .../ClassicModes/MakeSectorMode.cs | 1 + .../BuilderModes/ClassicModes/SectorsMode.cs | 14 +- .../BuilderModes/ClassicModes/ThingsMode.cs | 12 +- .../BuilderModes/ClassicModes/VerticesMode.cs | 4 +- .../BuilderModes/General/BuilderPlug.cs | 2 +- .../VisualModes/BaseVisualThing.cs | 16 +- Source/Plugins/TagExplorer/BuilderPlug.cs | 7 +- 48 files changed, 518 insertions(+), 512 deletions(-) rename Source/Core/GZBuilder/Data/{GZDoomLight.cs => DynamicLight.cs} (71%) rename Source/Core/GZBuilder/Data/{ModelDefEntry.cs => ModelData.cs} (50%) create mode 100644 Source/Core/GZBuilder/Data/ModelLoadState.cs diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj index 17a1d705..c16056d7 100644 --- a/Source/Core/Builder.csproj +++ b/Source/Core/Builder.csproj @@ -754,7 +754,8 @@ - + + diff --git a/Source/Core/Config/ResourceTextureSet.cs b/Source/Core/Config/ResourceTextureSet.cs index ca353840..6246b53b 100644 --- a/Source/Core/Config/ResourceTextureSet.cs +++ b/Source/Core/Config/ResourceTextureSet.cs @@ -41,7 +41,7 @@ namespace CodeImp.DoomBuilder.Config #region ================== Properties public ICollection Textures { get { return textures.Values; } } - public ICollection Flats { get { return flats.Values; } } + public ICollection Flats { get { return General.Map.Config.MixTexturesFlats ? textures.Values : flats.Values; } } public DataLocation Location { get { return location; } } #endregion @@ -86,28 +86,20 @@ namespace CodeImp.DoomBuilder.Config // Check if this set has a flat internal bool FlatExists(ImageData image) { + if(General.Map.Config.MixTexturesFlats) return textures.ContainsKey(image.LongName); //mxd return flats.ContainsKey(image.LongName); } // Mix the textures and flats internal void MixTexturesAndFlats() { - // Make a copy of the flats only - Dictionary flatsonly = new Dictionary(flats); - - // Add textures to flats - foreach(KeyValuePair t in textures) - { - if(!flats.ContainsKey(t.Key)) - flats.Add(t.Key, t.Value); - } - // Add flats to textures - foreach(KeyValuePair f in flatsonly) - { + foreach(KeyValuePair f in flats) { if(!textures.ContainsKey(f.Key)) textures.Add(f.Key, f.Value); } + + flats.Clear(); //mxd } #endregion diff --git a/Source/Core/Controls/FlatSelectorControl.cs b/Source/Core/Controls/FlatSelectorControl.cs index 71decdc6..0821d847 100644 --- a/Source/Core/Controls/FlatSelectorControl.cs +++ b/Source/Core/Controls/FlatSelectorControl.cs @@ -50,7 +50,7 @@ namespace CodeImp.DoomBuilder.Controls { ImageData texture = General.Map.Data.GetFlatImage(imagename); //mxd - if(string.IsNullOrEmpty(texture.FullName)) DisplayImageSize(0, 0); //mxd + if(string.IsNullOrEmpty(texture.FullName) || texture is UnknownImage) DisplayImageSize(0, 0); //mxd else DisplayImageSize(texture.ScaledWidth, texture.ScaledHeight); //mxd // Set the image diff --git a/Source/Core/Controls/LinedefInfoPanel.cs b/Source/Core/Controls/LinedefInfoPanel.cs index 1eebf6fd..150706e6 100644 --- a/Source/Core/Controls/LinedefInfoPanel.cs +++ b/Source/Core/Controls/LinedefInfoPanel.cs @@ -445,7 +445,7 @@ namespace CodeImp.DoomBuilder.Controls { //mxd ImageData texture = General.Map.Data.GetTextureImage(name); - if(General.Settings.ShowTextureSizes && texture.ImageState == ImageLoadState.Ready) { + if(General.Settings.ShowTextureSizes && texture.ImageState == ImageLoadState.Ready && !(texture is UnknownImage)) { label.Visible = true; label.Text = texture.ScaledWidth + "x" + texture.ScaledHeight; } else { diff --git a/Source/Core/Controls/SectorInfoPanel.cs b/Source/Core/Controls/SectorInfoPanel.cs index 6a45b2e8..0d5c6ece 100644 --- a/Source/Core/Controls/SectorInfoPanel.cs +++ b/Source/Core/Controls/SectorInfoPanel.cs @@ -221,7 +221,7 @@ namespace CodeImp.DoomBuilder.Controls } protected void DisplayTextureSize(Label label, ImageData texture) { - if(General.Settings.ShowTextureSizes && texture.ImageState == ImageLoadState.Ready && !string.IsNullOrEmpty(texture.Name)) { + if(General.Settings.ShowTextureSizes && texture.ImageState == ImageLoadState.Ready && !string.IsNullOrEmpty(texture.Name) && !(texture is UnknownImage)) { label.Visible = true; label.Text = texture.ScaledWidth + "x" + texture.ScaledHeight; } else { diff --git a/Source/Core/Controls/TextureSelectorControl.cs b/Source/Core/Controls/TextureSelectorControl.cs index c6ec8ac5..56fb47db 100644 --- a/Source/Core/Controls/TextureSelectorControl.cs +++ b/Source/Core/Controls/TextureSelectorControl.cs @@ -60,7 +60,7 @@ namespace CodeImp.DoomBuilder.Controls { ImageData texture = General.Map.Data.GetTextureImage(imagename); //mxd - if(string.IsNullOrEmpty(texture.FullName)) DisplayImageSize(0, 0); //mxd + if(string.IsNullOrEmpty(texture.FullName) || texture is UnknownImage) DisplayImageSize(0, 0); //mxd else DisplayImageSize(texture.ScaledWidth, texture.ScaledHeight); //mxd // Set the image diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index cdc35aed..0924229e 100644 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -62,8 +62,8 @@ namespace CodeImp.DoomBuilder.Data private AllTextureSet alltextures; //mxd - private Dictionary modeldefEntries; //Thing.Type, Model entry - private Dictionary gldefsEntries; //Thing.Type, Light entry + private Dictionary modeldefEntries; //Thing.Type, Model entry + private Dictionary gldefsEntries; //Thing.Type, Light entry private MapInfo mapInfo; //mapinfo // Background loading @@ -82,8 +82,6 @@ namespace CodeImp.DoomBuilder.Data private ImageData crosshair; private ImageData crosshairbusy; private Dictionary internalsprites; - //mxd - //private ImageData thingbox; private ImageData whitetexture; // Used images @@ -107,16 +105,16 @@ namespace CodeImp.DoomBuilder.Data #region ================== Properties //mxd - internal Dictionary ModeldefEntries { get { return modeldefEntries; } } - internal Dictionary GldefsEntries { get { return gldefsEntries; } } + internal Dictionary ModeldefEntries { get { return modeldefEntries; } } + internal Dictionary GldefsEntries { get { return gldefsEntries; } } internal MapInfo MapInfo { get { return mapInfo; } } public Playpal Palette { get { return palette; } } public PreviewManager Previews { get { return previews; } } public ICollection Textures { get { return textures.Values; } } - public ICollection Flats { get { return flats.Values; } } + public ICollection Flats { get { return (General.Map.Config.MixTexturesFlats ? textures.Values : flats.Values); } } //mxd public List TextureNames { get { return texturenames; } } - public List FlatNames { get { return flatnames; } } + public List FlatNames { get { return (General.Map.Config.MixTexturesFlats ? texturenames : flatnames); } } //mxd public bool IsDisposed { get { return isdisposed; } } public ImageData MissingTexture3D { get { return missingtexture3d; } } public ImageData UnknownTexture3D { get { return unknowntexture3d; } } @@ -136,13 +134,8 @@ namespace CodeImp.DoomBuilder.Data get { if(imageque != null) - { return (backgroundloader != null) && backgroundloader.IsAlive && ((imageque.Count > 0) || previews.IsLoading); - } - else - { - return false; - } + return false; } } @@ -156,6 +149,10 @@ namespace CodeImp.DoomBuilder.Data // We have no destructor GC.SuppressFinalize(this); + //mxd. + modeldefEntries = new Dictionary(); + gldefsEntries = new Dictionary(); + // Load special images missingtexture3d = new ResourceImage("CodeImp.DoomBuilder.Resources.MissingTexture3D.png"); missingtexture3d.LoadImage(); @@ -167,9 +164,6 @@ namespace CodeImp.DoomBuilder.Data crosshair.LoadImage(); crosshairbusy = new ResourceImage("CodeImp.DoomBuilder.Resources.CrosshairBusy.png"); crosshairbusy.LoadImage(); - //mxd - //thingbox = new ResourceImage("CodeImp.DoomBuilder.Resources.ThingBox.png"); - //thingbox.LoadImage(); whitetexture = new ResourceImage("CodeImp.DoomBuilder.Resources.White.png"); whitetexture.UseColorCorrection = false; whitetexture.LoadImage(); @@ -194,18 +188,9 @@ namespace CodeImp.DoomBuilder.Data crosshair = null; crosshairbusy.Dispose(); crosshairbusy = null; - //mxd - //thingbox.Dispose(); - //thingbox = null; whitetexture.Dispose(); whitetexture = null; - - //mxd - if (modeldefEntries != null) { - foreach (KeyValuePair group in modeldefEntries) - group.Value.Dispose(); - modeldefEntries = null; - } + modeldefEntries = null;//mxd mapInfo = null; // Done @@ -363,16 +348,6 @@ namespace CodeImp.DoomBuilder.Data // Mixed textures and flats? if(General.Map.Config.MixTexturesFlats) { - // Add textures to flats - foreach(KeyValuePair t in texturesonly) - { - if(!flats.ContainsKey(t.Key)) - { - flats.Add(t.Key, t.Value); - flatnames.Add(t.Value.Name); - } - } - // Add flats to textures foreach(KeyValuePair f in flatsonly) { @@ -383,6 +358,9 @@ namespace CodeImp.DoomBuilder.Data } } + flats.Clear(); //mxd + flatnames.Clear(); //mxd + // Do the same on the data readers foreach(DataReader dr in containers) dr.TextureSet.MixTexturesAndFlats(); @@ -401,10 +379,9 @@ namespace CodeImp.DoomBuilder.Data // Add texture names to texture sets foreach(KeyValuePair img in textures) { - // Add to all sets where it matches - bool matchfound = false; + // Add to all sets foreach(MatchingTextureSet ms in texturesets) - matchfound |= ms.AddTexture(img.Value); + ms.AddTexture(img.Value); // Add to all alltextures.AddTexture(img.Value); @@ -413,10 +390,9 @@ namespace CodeImp.DoomBuilder.Data // Add flat names to texture sets foreach(KeyValuePair img in flats) { - // Add to all sets where it matches - bool matchfound = false; + // Add to all sets foreach(MatchingTextureSet ms in texturesets) - matchfound |= ms.AddFlat(img.Value); + ms.AddFlat(img.Value); // Add to all alltextures.AddFlat(img.Value); @@ -426,7 +402,7 @@ namespace CodeImp.DoomBuilder.Data StartBackgroundLoader(); // Output info - General.WriteLogLine("Loaded " + texcount + " textures, " + flatcount + " flats, " + colormapcount + " colormaps, " + spritecount + " sprites, " + thingcount + " decorate things, " + modeldefEntries.Count + " model deinitions, " + gldefsEntries.Count + " gl definitions"); + General.WriteLogLine("Loaded " + texcount + " textures, " + flatcount + " flats, " + colormapcount + " colormaps, " + spritecount + " sprites, " + thingcount + " decorate things, " + modeldefEntries.Count + " model deinitions, " + gldefsEntries.Count + " dynamic light definitions"); } // This unloads all data @@ -450,9 +426,8 @@ namespace CodeImp.DoomBuilder.Data //mxd if (modeldefEntries != null) { - foreach (KeyValuePair group in modeldefEntries) { + foreach (KeyValuePair group in modeldefEntries) group.Value.Dispose(); - } } // Dispose containers @@ -696,6 +671,20 @@ namespace CodeImp.DoomBuilder.Data General.SendMessage(General.MainWindow.Handle, (int)MainForm.ThreadMessages.UpdateStatus, 0, 0); } + //mxd. This loads a model + internal void ProcessModel(int type) { + if(modeldefEntries[type].LoadState != ModelLoadState.None) return; + + //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); + } + } + // This updates the used-in-map status on all textures and flats private void BackgroundUpdateUsedTextures() { @@ -709,10 +698,11 @@ namespace CodeImp.DoomBuilder.Data } // Set used on all flats - foreach(KeyValuePair i in flats) - { - i.Value.SetUsedInMap(usedimages.ContainsKey(i.Key)); - if(i.Value.IsImageLoaded != i.Value.IsReferenced) ProcessImage(i.Value); + 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); + } } // Done @@ -851,7 +841,7 @@ namespace CodeImp.DoomBuilder.Data Stream patch; // Go for all opened containers - for(int i = containers.Count - 1; i >= 0; i--) + for(int i = containers.Count - 1; i > -1; i--) { // This contain provides this patch? patch = containers[i].GetPatchData(pname); @@ -984,13 +974,13 @@ namespace CodeImp.DoomBuilder.Data public bool GetFlatExists(string name) { long longname = Lump.MakeLongName(name); - return flats.ContainsKey(longname); + return General.Map.Config.MixTexturesFlats ? textures.ContainsKey(longname) : flats.ContainsKey(longname); } // This checks if a flat is known public bool GetFlatExists(long longname) { - return flats.ContainsKey(longname); + return General.Map.Config.MixTexturesFlats ? textures.ContainsKey(longname) : flats.ContainsKey(longname); } // This returns an image by string @@ -1004,24 +994,26 @@ namespace CodeImp.DoomBuilder.Data // This returns an image by long public ImageData GetFlatImage(long longname) { - // Does this flat exist? - if(flats.ContainsKey(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]; } - else - { - // Return null image - return new UnknownImage(Properties.Resources.UnknownImage); - } + + // Return null image + return new UnknownImage(Properties.Resources.UnknownImage); } // This returns an image by long and doesn't check if it exists public ImageData GetFlatImageKnown(long longname) { // Return flat - return flats[longname]; + return General.Map.Config.MixTexturesFlats ? textures[longname] : flats[longname]; //mxd } #endregion @@ -1382,39 +1374,7 @@ namespace CodeImp.DoomBuilder.Data #endregion - #region ================== Modeldef, Gldefs, Mapinfo and models loading - - //mxd - public void LoadModels() { - General.MainWindow.DisplayStatus(StatusType.Busy, "Loading models..."); - - foreach (Thing t in General.Map.Map.Things) - t.IsModel = LoadModelForThing(t); - - General.MainWindow.RedrawDisplay(); - } - - //mxd - public bool LoadModelForThing(Thing t) { - if (modeldefEntries.ContainsKey(t.Type)) { - if (modeldefEntries[t.Type].Model == null) { - //load models and textures - ModeldefEntry mde = modeldefEntries[t.Type]; - - //create models - ModelReader.Load(ref mde, containers, General.Map.Graphics.Device); - - if (mde.Model != null) { - return true; - } else { - modeldefEntries.Remove(t.Type); - return false; - } - } - return true; - } - return false; - } + #region ================== mxd. Modeldef, Gldefs, Mapinfo //mxd. This creates dictionary. Should be called after all DECORATE actors are parsed private Dictionary createActorsByClassList() { @@ -1442,13 +1402,14 @@ namespace CodeImp.DoomBuilder.Data //mxd public void ReloadModeldef() { if (modeldefEntries != null) { - foreach (KeyValuePair group in modeldefEntries) + foreach (KeyValuePair group in modeldefEntries) group.Value.Dispose(); } General.MainWindow.DisplayStatus(StatusType.Busy, "Reloading model definitions..."); loadModeldefs(createActorsByClassList()); - LoadModels(); + + foreach(Thing t in General.Map.Map.Things) t.UpdateModelStatus(); //rebuild geometry if in Visual mode if (General.Editing.Mode != null && General.Editing.Mode.GetType().Name == "BaseVisualMode") { @@ -1486,17 +1447,13 @@ namespace CodeImp.DoomBuilder.Data //mxd. This parses modeldefs. Should be called after all DECORATE actors are parsed and actorsByClass dictionary created private void loadModeldefs(Dictionary actorsByClass) { - modeldefEntries = new Dictionary(); //create it in all cases, so we don't have to check if it's null every time we need to access it - //if no actors defined in DECORATE or game config... if (actorsByClass == null || actorsByClass.Count == 0) { General.ErrorLogger.Add(ErrorType.Warning, "Warning: current game has no Actors!"); return; } - foreach(Thing t in General.Map.Map.Things) t.IsModel = false; //drop model flag - - Dictionary modelDefEntriesByName = new Dictionary(); + Dictionary modelDefEntriesByName = new Dictionary(); ModeldefParser mdeParser = new ModeldefParser(); foreach (DataReader dr in containers) { @@ -1506,7 +1463,7 @@ namespace CodeImp.DoomBuilder.Data foreach (KeyValuePair group in streams) { // Parse the data if (mdeParser.Parse(group.Value, currentreader.Location.location + "\\" + group.Key)) { - foreach (KeyValuePair g in mdeParser.ModelDefEntries) { + foreach (KeyValuePair g in mdeParser.ModelDefEntries) { modelDefEntriesByName.Add(g.Key, g.Value); } } @@ -1515,18 +1472,18 @@ namespace CodeImp.DoomBuilder.Data currentreader = null; - foreach (KeyValuePair e in modelDefEntriesByName) { + foreach (KeyValuePair e in modelDefEntriesByName) { if (actorsByClass.ContainsKey(e.Key)) modeldefEntries[actorsByClass[e.Key]] = modelDefEntriesByName[e.Key]; else if(!invalidDecorateActors.Contains(e.Key)) General.ErrorLogger.Add(ErrorType.Warning, "Got MODELDEF override for class '" + e.Key + "', but haven't found such class in Decorate"); } + + foreach(Thing t in General.Map.Map.Things) t.UpdateModelStatus(); } //mxd. This parses gldefs. Should be called after all DECORATE actors are parsed and actorsByClass dictionary created private void loadGldefs(Dictionary actorsByClass, bool loadDefaultDefinitions) { - gldefsEntries = new Dictionary();//create it in all cases, so we don't have to check if it's null every time we need to access it - //if no actors defined in DECORATE or game config... if (actorsByClass == null || actorsByClass.Count == 0) { General.ErrorLogger.Add(ErrorType.Warning, "Warning: current game has no Actors!"); diff --git a/Source/Core/Data/DirectoryReader.cs b/Source/Core/Data/DirectoryReader.cs index 6e748078..69f45007 100644 --- a/Source/Core/Data/DirectoryReader.cs +++ b/Source/Core/Data/DirectoryReader.cs @@ -72,7 +72,7 @@ namespace CodeImp.DoomBuilder.Data // Find in any of the wad files // Note the backward order, because the last wad's images have priority - for(int i = wads.Count - 1; i >= 0; i--) + for(int i = wads.Count - 1; i > -1; i--) { Stream data = wads[i].GetPatchData(pname); if(data != null) return data; @@ -80,15 +80,13 @@ namespace CodeImp.DoomBuilder.Data try { - // Find in patches directory - //string path = Path.Combine(PATCHES_DIR, Path.GetDirectoryName(pname)); - //string filename = FindFirstFile(path, Path.GetFileName(pname), true); + //mxd. Find in directories ZDoom expects them to be + foreach(string location in PatchLocations){ + string path = Path.Combine(location, Path.GetDirectoryName(pname)); + string filename = FindFirstFile(path, Path.GetFileName(pname), true); - //mxd. ZDoom can load them from anywhere, so shall we - string filename = FindFirstFile(Path.GetDirectoryName(pname), Path.GetFileName(pname), true); - if((filename != null) && FileExists(filename)) - { - return LoadFile(filename); + if(!string.IsNullOrEmpty(filename) && FileExists(filename)) + return LoadFile(filename); } } catch(Exception e) diff --git a/Source/Core/Data/FileImage.cs b/Source/Core/Data/FileImage.cs index a6105dac..65d8d49b 100644 --- a/Source/Core/Data/FileImage.cs +++ b/Source/Core/Data/FileImage.cs @@ -28,7 +28,6 @@ namespace CodeImp.DoomBuilder.Data { #region ================== Variables - //private string filepathname; private int probableformat; #endregion @@ -39,9 +38,8 @@ namespace CodeImp.DoomBuilder.Data public FileImage(string name, string filepathname, bool asflat) { // Initialize - //this.filepathname = filepathname; - this.fullName = filepathname; //mxd SetName(name); + this.fullName = filepathname; //mxd if(asflat) { @@ -92,38 +90,38 @@ namespace CodeImp.DoomBuilder.Data { // Load file data if(bitmap != null) bitmap.Dispose(); bitmap = null; - 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?"); + if(!File.Exists(fullName)) { //mxd + General.ErrorLogger.Add(ErrorType.Error, "Image file '" + fullName + "' could not be read: no such file."); 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(); } - else - { - // 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/HighResImage.cs b/Source/Core/Data/HighResImage.cs index 478fac6b..8074e738 100644 --- a/Source/Core/Data/HighResImage.cs +++ b/Source/Core/Data/HighResImage.cs @@ -104,6 +104,8 @@ namespace CodeImp.DoomBuilder.Data loadfailed = true; } + int failCount = 0; //mxd + if(!loadfailed) { // Go for all patches @@ -126,7 +128,7 @@ namespace CodeImp.DoomBuilder.Data { // 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 + "'"); - loadfailed = true; + failCount++; //mxd } else { @@ -138,7 +140,7 @@ namespace CodeImp.DoomBuilder.Data { // Data cannot be read! General.ErrorLogger.Add(ErrorType.Error, "Patch lump '" + p.lumpname + "' data format could not be read, while loading texture '" + this.Name + "'"); - loadfailed = true; + failCount++; //mxd } if(patchbmp != null) { @@ -192,9 +194,9 @@ namespace CodeImp.DoomBuilder.Data float bb = p.blend.b * PixelColor.BYTE_TO_FLOAT; for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--) { - cp->r = (byte)((((float)cp->r * PixelColor.BYTE_TO_FLOAT) * br) * 255.0f); - cp->g = (byte)((((float)cp->g * PixelColor.BYTE_TO_FLOAT) * bg) * 255.0f); - cp->b = (byte)((((float)cp->b * PixelColor.BYTE_TO_FLOAT) * bb) * 255.0f); + cp->r = (byte)(((cp->r * PixelColor.BYTE_TO_FLOAT) * br) * 255.0f); + cp->g = (byte)(((cp->g * PixelColor.BYTE_TO_FLOAT) * bg) * 255.0f); + cp->b = (byte)(((cp->b * PixelColor.BYTE_TO_FLOAT) * bb) * 255.0f); } } else if(p.blendstyle == TexturePathBlendStyle.Tint) { float tintammount = p.tintammount - 0.1f; @@ -206,9 +208,9 @@ namespace CodeImp.DoomBuilder.Data float invTint = 1.0f - tintammount; for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--) { - cp->r = (byte)((((float)cp->r * PixelColor.BYTE_TO_FLOAT) * invTint + br) * 255.0f); - cp->g = (byte)((((float)cp->g * PixelColor.BYTE_TO_FLOAT) * invTint + bg) * 255.0f); - cp->b = (byte)((((float)cp->b * PixelColor.BYTE_TO_FLOAT) * invTint + bb) * 255.0f); + cp->r = (byte)(((cp->r * PixelColor.BYTE_TO_FLOAT) * invTint + br) * 255.0f); + cp->g = (byte)(((cp->g * PixelColor.BYTE_TO_FLOAT) * invTint + bg) * 255.0f); + cp->b = (byte)(((cp->b * PixelColor.BYTE_TO_FLOAT) * invTint + bb) * 255.0f); } } } @@ -216,7 +218,7 @@ namespace CodeImp.DoomBuilder.Data //mxd. apply RenderStyle if(p.style == TexturePathRenderStyle.Blend) { for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--) - cp->a = (byte)((((float)cp->a * PixelColor.BYTE_TO_FLOAT) * p.alpha) * 255.0f); + cp->a = (byte)(((cp->a * PixelColor.BYTE_TO_FLOAT) * p.alpha) * 255.0f); //mxd. we need a copy of underlying part of texture for these styles } else if(p.style != TexturePathRenderStyle.Copy) { @@ -239,7 +241,6 @@ namespace CodeImp.DoomBuilder.Data if(texturebmpdata != null) { PixelColor* texturepixels = (PixelColor*)(texturebmpdata.Scan0.ToPointer()); - int numtexpixels = texturebmpdata.Width * texturebmpdata.Height; PixelColor* tcp = texturepixels + numpixels - 1; if(p.style == TexturePathRenderStyle.Add) { @@ -305,16 +306,17 @@ namespace CodeImp.DoomBuilder.Data { // Missing a patch lump! General.ErrorLogger.Add(ErrorType.Error, "Missing patch lump '" + p.lumpname + "' while loading texture '" + this.Name + "'"); - loadfailed = true; + failCount++; //mxd } } } // Dispose bitmap if load failed - if(loadfailed && (bitmap != null)) + if((bitmap != null) && (loadfailed || failCount >= patches.Count)) //mxd. We can still display texture if at least one of the patches was loaded { bitmap.Dispose(); bitmap = null; + loadfailed = true; } // Pass on to base diff --git a/Source/Core/Data/ImageData.cs b/Source/Core/Data/ImageData.cs index 56f5693f..ee651d48 100644 --- a/Source/Core/Data/ImageData.cs +++ b/Source/Core/Data/ImageData.cs @@ -177,9 +177,7 @@ namespace CodeImp.DoomBuilder.Data { this.name = name; this.longname = Lump.MakeLongName(name); - //mxd - if (this.fullName == null) - this.fullName = name; + fullName = name; //mxd } // This unloads the image diff --git a/Source/Core/Data/PK3Reader.cs b/Source/Core/Data/PK3Reader.cs index b71339b3..90dca575 100644 --- a/Source/Core/Data/PK3Reader.cs +++ b/Source/Core/Data/PK3Reader.cs @@ -33,7 +33,6 @@ namespace CodeImp.DoomBuilder.Data #region ================== Variables private DirectoryFilesList files; - //private IArchive archive;//mxd private ArchiveType archiveType; //mxd private static Dictionary sevenZipEntries; //mxd @@ -123,12 +122,11 @@ namespace CodeImp.DoomBuilder.Data if(data != null) return data; } - // Find in patches directory - //string filename = FindFirstFile(PATCHES_DIR, pname, true); - string filename = FindFirstFile("", pname, true); //mxd. ZDoom can load them from anywhere, so shall we - if((filename != null) && FileExists(filename)) - { - return LoadFile(filename); + //mxd. Find in directories ZDoom expects them to be + foreach(string location in PatchLocations) { + string filename = FindFirstFile(location, pname, true); + if((filename != null) && FileExists(filename)) + return LoadFile(filename); } // Nothing found diff --git a/Source/Core/Data/PK3StructuredReader.cs b/Source/Core/Data/PK3StructuredReader.cs index a7451c1a..25003e4a 100644 --- a/Source/Core/Data/PK3StructuredReader.cs +++ b/Source/Core/Data/PK3StructuredReader.cs @@ -52,6 +52,8 @@ namespace CodeImp.DoomBuilder.Data #region ================== Properties + protected string[] PatchLocations = { PATCHES_DIR, TEXTURES_DIR, FLATS_DIR }; //mxd. Because ZDoom looks for patches in these folders + #endregion #region ================== Constructor / Disposer @@ -326,6 +328,22 @@ namespace CodeImp.DoomBuilder.Data return new List(images.Values); } + + //mxd. + public override Stream GetFlatData(string pname) { + // Error when suspended + if(issuspended) throw new Exception("Data reader is suspended"); + + // Find in any of the wad files + // Note the backward order, because the last wad's images have priority + for(int i = wads.Count - 1; i > -1; i--) { + Stream data = wads[i].GetFlatData(pname); + if(data != null) return data; + } + + // Nothing found + return null; + } #endregion diff --git a/Source/Core/Data/TextureImage.cs b/Source/Core/Data/TextureImage.cs index 7d3a4d31..7acae7db 100644 --- a/Source/Core/Data/TextureImage.cs +++ b/Source/Core/Data/TextureImage.cs @@ -33,7 +33,6 @@ namespace CodeImp.DoomBuilder.Data #region ================== Variables private List patches; - private bool gotFullName;//mxd #endregion @@ -63,12 +62,6 @@ namespace CodeImp.DoomBuilder.Data { // Add it patches.Add(patch); - - //mxd. Get full name from first patch - if (!gotFullName) { - fullName = General.Map.Data.GetPatchLocation(patch.lumpname); - gotFullName = true; - } } // This loads the image @@ -103,6 +96,8 @@ namespace CodeImp.DoomBuilder.Data loadfailed = true; } + int failCount = 0; //mxd + if(!loadfailed) { // Go for all patches @@ -126,6 +121,7 @@ namespace CodeImp.DoomBuilder.Data // 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 { @@ -137,6 +133,7 @@ namespace CodeImp.DoomBuilder.Data // Data cannot be read! 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 } } @@ -148,6 +145,7 @@ namespace CodeImp.DoomBuilder.Data // Missing a patch lump! General.ErrorLogger.Add(ErrorType.Error, "Missing patch lump '" + p.lumpname + "' while loading texture '" + this.Name + "'. Did you forget to include required resources?"); loadfailed = true; + failCount++; //mxd } } @@ -156,10 +154,11 @@ namespace CodeImp.DoomBuilder.Data } // Dispose bitmap if load failed - if(loadfailed && (bitmap != null)) + if((bitmap != null) && (loadfailed || failCount >= patches.Count)) //mxd. We can still display texture if at least one of the patches was loaded { bitmap.Dispose(); bitmap = null; + loadfailed = true; } // Pass on to base diff --git a/Source/Core/Editing/UndoManager.cs b/Source/Core/Editing/UndoManager.cs index e018557e..0c323c07 100644 --- a/Source/Core/Editing/UndoManager.cs +++ b/Source/Core/Editing/UndoManager.cs @@ -691,7 +691,7 @@ namespace CodeImp.DoomBuilder.Editing General.Map.ThingsFilter.Update(); General.Map.Data.UpdateUsedTextures(); General.MainWindow.RefreshInfo(); - General.MainWindow.RedrawDisplay(); + //General.MainWindow.RedrawDisplay(); // Map changed! General.Map.IsChanged = true; @@ -701,6 +701,7 @@ namespace CodeImp.DoomBuilder.Editing General.Plugins.OnUndoEnd(); // Update interface + General.MainWindow.RedrawDisplay(); //mxd dobackgroundwork = true; General.MainWindow.UpdateInterface(); } @@ -833,7 +834,7 @@ namespace CodeImp.DoomBuilder.Editing General.Map.ThingsFilter.Update(); General.Map.Data.UpdateUsedTextures(); General.MainWindow.RefreshInfo(); - General.MainWindow.RedrawDisplay(); + //General.MainWindow.RedrawDisplay(); // Map changed! General.Map.IsChanged = true; @@ -843,6 +844,7 @@ namespace CodeImp.DoomBuilder.Editing General.Plugins.OnRedoEnd(); // Update interface + General.MainWindow.RedrawDisplay(); //mxd dobackgroundwork = true; General.MainWindow.UpdateInterface(); } diff --git a/Source/Core/GZBuilder/Data/GZDoomLight.cs b/Source/Core/GZBuilder/Data/DynamicLight.cs similarity index 71% rename from Source/Core/GZBuilder/Data/GZDoomLight.cs rename to Source/Core/GZBuilder/Data/DynamicLight.cs index 11d33e78..0416f3d0 100644 --- a/Source/Core/GZBuilder/Data/GZDoomLight.cs +++ b/Source/Core/GZBuilder/Data/DynamicLight.cs @@ -2,8 +2,8 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data { - public sealed class GZDoomLight { - public int Type; //holds GZDoomLightType + public sealed class DynamicLightData { + public DynamicLightType Type; //holds DynamicLightType public Color3 Color; public int PrimaryRadius; public int SecondaryRadius; @@ -12,15 +12,16 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data public bool Subtractive; public bool DontLightSelf; - public GZDoomLight() { + public DynamicLightData() { Color = new Color3(); Offset = new Vector3(); } } - public enum GZDoomLightType + public enum DynamicLightType { - NORMAL = 0, + NONE = -1, + NORMAL = 0, PULSE = 1, FLICKER = 2, SECTOR = 3, @@ -30,7 +31,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data } //divide these by 100 to get light color alpha - public enum GZDoomLightRenderStyle + public enum DynamicLightRenderStyle { NONE = 0, NORMAL = 99, diff --git a/Source/Core/GZBuilder/Data/ModelDefEntry.cs b/Source/Core/GZBuilder/Data/ModelData.cs similarity index 50% rename from Source/Core/GZBuilder/Data/ModelDefEntry.cs rename to Source/Core/GZBuilder/Data/ModelData.cs index 8fdd8144..b99e7bb6 100644 --- a/Source/Core/GZBuilder/Data/ModelDefEntry.cs +++ b/Source/Core/GZBuilder/Data/ModelData.cs @@ -2,17 +2,43 @@ using SlimDX; using SlimDX.Direct3D9; using CodeImp.DoomBuilder.GZBuilder.MD3; +using CodeImp.DoomBuilder.Data; +using System.IO; +using System; +using System.Text; +using CodeImp.DoomBuilder.Rendering; +using CodeImp.DoomBuilder.Geometry; +using CodeImp.DoomBuilder.IO; +using System.Drawing; +using System.Drawing.Imaging; namespace CodeImp.DoomBuilder.GZBuilder.Data { - internal sealed class ModeldefEntry + internal sealed class ModelData { - internal string ClassName; + private const float VERTICAL_STRETCH = 1 / 1.2f; + + private class MD3LoadResult + { + public List Skins; + public List Meshes; + public string Errors; + + public MD3LoadResult() { + Skins = new List(); + Meshes = new List(); + } + } + + internal string ClassName; internal List ModelNames; internal List TextureNames; internal GZModel Model; + private ModelLoadState loadstate; + public ModelLoadState LoadState { get { return loadstate; } internal set { loadstate = value; } } + internal Vector3 Scale; internal float zOffset; @@ -20,7 +46,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data internal float PitchOffset; //in radians internal float RollOffset; //in radians - internal ModeldefEntry() { + internal ModelData() { ModelNames = new List(); TextureNames = new List(); } @@ -32,7 +58,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data foreach (Texture t in Model.Textures) t.Dispose(); + + loadstate = ModelLoadState.None; } - } - } + } + } } diff --git a/Source/Core/GZBuilder/Data/ModelLoadState.cs b/Source/Core/GZBuilder/Data/ModelLoadState.cs new file mode 100644 index 00000000..a3c0007d --- /dev/null +++ b/Source/Core/GZBuilder/Data/ModelLoadState.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace CodeImp.DoomBuilder.GZBuilder.Data +{ + public enum ModelLoadState + { + None, + Loading, + Ready + } +} diff --git a/Source/Core/GZBuilder/GZDoom/GldefsParser.cs b/Source/Core/GZBuilder/GZDoom/GldefsParser.cs index 8d42a406..ccafc79d 100644 --- a/Source/Core/GZBuilder/GZDoom/GldefsParser.cs +++ b/Source/Core/GZBuilder/GZDoom/GldefsParser.cs @@ -11,10 +11,10 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom { public delegate void IncludeDelegate(GldefsParser parser, string includefile); public IncludeDelegate OnInclude; - private Dictionary lightsByName; //LightName, light definition + private Dictionary lightsByName; //LightName, light definition private Dictionary objects; //ClassName, LightName - public Dictionary LightsByName { get { return lightsByName; } } + public Dictionary LightsByName { get { return lightsByName; } } public Dictionary Objects { get { return objects; } } private List parsedLumps; @@ -26,12 +26,12 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom { public const string FLICKER2 = "flickerlight2"; public const string SECTOR = "sectorlight"; - public static Dictionary GLDEFS_TO_GZDOOM_LIGHT_TYPE = new Dictionary() { { POINT, 0 }, { PULSE, 1 }, { FLICKER, 2 }, { FLICKER2, 4 }, { SECTOR, 3 } }; + public static Dictionary GLDEFS_TO_GZDOOM_LIGHT_TYPE = new Dictionary() { { POINT, DynamicLightType.NORMAL }, { PULSE, DynamicLightType.PULSE }, { FLICKER, DynamicLightType.FLICKER }, { FLICKER2, DynamicLightType.RANDOM }, { SECTOR, DynamicLightType.SECTOR } }; } public GldefsParser() { parsedLumps = new List(); - lightsByName = new Dictionary(); //LightName, Light params + lightsByName = new Dictionary(); //LightName, Light params objects = new Dictionary(); //ClassName, LightName } @@ -60,7 +60,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom { bool gotErrors = false; string lightType = token; - GZDoomLight light = new GZDoomLight(); + DynamicLightData light = new DynamicLightData(); light.Type = GldefsLightType.GLDEFS_TO_GZDOOM_LIGHT_TYPE[lightType]; //find classname @@ -295,14 +295,14 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom { } //light-type specific checks - if (light.Type == (int)GZDoomLightType.NORMAL) { + if (light.Type == DynamicLightType.NORMAL) { if (light.PrimaryRadius == 0) { General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": light Size is 0. It won't be shown in GZDoom!"); gotErrors = true; } } - if (light.Type == (int)GZDoomLightType.FLICKER || light.Type == (int)GZDoomLightType.PULSE || light.Type == (int)GZDoomLightType.RANDOM) { + if (light.Type == DynamicLightType.FLICKER || light.Type == DynamicLightType.PULSE || light.Type == DynamicLightType.RANDOM) { if (light.PrimaryRadius == 0 && light.SecondaryRadius == 0) { General.ErrorLogger.Add(ErrorType.Error, "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": 'Size' and 'SecondarySize' are 0. This light won't be shown in GZDoom!"); gotErrors = true; diff --git a/Source/Core/GZBuilder/GZDoom/ModeldefParser.cs b/Source/Core/GZBuilder/GZDoom/ModeldefParser.cs index abd8a42a..624533ff 100644 --- a/Source/Core/GZBuilder/GZDoom/ModeldefParser.cs +++ b/Source/Core/GZBuilder/GZDoom/ModeldefParser.cs @@ -6,22 +6,18 @@ using CodeImp.DoomBuilder.GZBuilder.Data; namespace CodeImp.DoomBuilder.GZBuilder.GZDoom { internal class ModeldefParser : ZDTextParser { - private Dictionary modelDefEntries; //classname, entry - internal Dictionary ModelDefEntries { get { return modelDefEntries; } } - - private List classNames; - + private Dictionary modelDefEntries; //classname, entry + internal Dictionary ModelDefEntries { get { return modelDefEntries; } } internal string Source { get { return sourcename; } } internal ModeldefParser() { - modelDefEntries = new Dictionary(); - classNames = new List(); + modelDefEntries = new Dictionary(); } //should be called after all decorate actors are parsed public override bool Parse(Stream stream, string sourcefilename) { base.Parse(stream, sourcefilename); - modelDefEntries = new Dictionary(); + modelDefEntries = new Dictionary(); // Continue until at the end of the stream while (SkipWhitespace(true)) { @@ -36,8 +32,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom { string className = StripTokenQuotes(ReadToken()).ToLowerInvariant(); if (!string.IsNullOrEmpty(className)) { - if (classNames.IndexOf(className) != -1) - continue; //already got this class; continue to next one + if(modelDefEntries.ContainsKey(className)) continue; //already got this class; continue to next one //now find opening brace SkipWhitespace(true); @@ -48,11 +43,10 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom { } ModeldefStructure mds = new ModeldefStructure(); - ModeldefEntry mde = mds.Parse(this); + ModelData mde = mds.Parse(this); if (mde != null) { mde.ClassName = className; modelDefEntries.Add(className, mde); - classNames.Add(mde.ClassName); } } diff --git a/Source/Core/GZBuilder/GZDoom/ModeldefStructure.cs b/Source/Core/GZBuilder/GZDoom/ModeldefStructure.cs index c56fb321..13706c17 100644 --- a/Source/Core/GZBuilder/GZDoom/ModeldefStructure.cs +++ b/Source/Core/GZBuilder/GZDoom/ModeldefStructure.cs @@ -9,7 +9,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom { internal sealed class ModeldefStructure { private const int MAX_MODELS = 4; //maximum models per modeldef entry, zero-based - internal ModeldefEntry Parse(ModeldefParser parser) { + internal ModelData Parse(ModeldefParser parser) { string[] textureNames = new string[4]; string[] modelNames = new string[4]; string path = ""; @@ -311,7 +311,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom { if (gotErrors) return null; //classname is set in ModeldefParser - ModeldefEntry mde = new ModeldefEntry(); + ModelData mde = new ModelData(); mde.Scale = scale; mde.zOffset = zOffset; mde.AngleOffset = Angle2D.DegToRad(angleOffset);// *(float)Math.PI / 180.0f; diff --git a/Source/Core/GZBuilder/GZGeneral.cs b/Source/Core/GZBuilder/GZGeneral.cs index 488cf24a..38166eef 100644 --- a/Source/Core/GZBuilder/GZGeneral.cs +++ b/Source/Core/GZBuilder/GZGeneral.cs @@ -14,7 +14,7 @@ namespace CodeImp.DoomBuilder.GZBuilder public static int[] GZ_LIGHTS { get { return gzLights; } } private static int[] gzLightTypes = { 5, 10, 15 }; //these are actually offsets in gz_lights public static int[] GZ_LIGHT_TYPES { get { return gzLightTypes; } } - private static int[] gzAnimatedLightTypes = { (int)GZDoomLightType.FLICKER, (int)GZDoomLightType.RANDOM, (int)GZDoomLightType.PULSE }; + private static int[] gzAnimatedLightTypes = { (int)DynamicLightType.FLICKER, (int)DynamicLightType.RANDOM, (int)DynamicLightType.PULSE }; public static int[] GZ_ANIMATED_LIGHT_TYPES { get { return gzAnimatedLightTypes; } } //asc script action specials diff --git a/Source/Core/GZBuilder/md3/ModelReader.cs b/Source/Core/GZBuilder/md3/ModelReader.cs index 8ec553dc..23c07580 100644 --- a/Source/Core/GZBuilder/md3/ModelReader.cs +++ b/Source/Core/GZBuilder/md3/ModelReader.cs @@ -31,7 +31,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 } } - public static void Load(ref ModeldefEntry mde, List containers, Device device) { + public static void Load(ModelData mde, List containers, Device device) { mde.Model = new GZModel(); BoundingBoxSizes bbs = new BoundingBoxSizes(); MD3LoadResult result = new MD3LoadResult(); @@ -142,7 +142,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 mde.Model.BoundingBox = BoundingBoxTools.CalculateBoundingBox(bbs); } - private static MD3LoadResult ReadMD3Model(ref BoundingBoxSizes bbs, ModeldefEntry mde, bool useSkins, MemoryStream s, Device device) { + private static MD3LoadResult ReadMD3Model(ref BoundingBoxSizes bbs, ModelData mde, bool useSkins, MemoryStream s, Device device) { long start = s.Position; MD3LoadResult result = new MD3LoadResult(); @@ -224,7 +224,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 return result; } - private static string ReadSurface(ref BoundingBoxSizes bbs, ref string skin, BinaryReader br, List polyIndecesList, List vertList, ModeldefEntry mde) { + private static string ReadSurface(ref BoundingBoxSizes bbs, ref string skin, BinaryReader br, List polyIndecesList, List vertList, ModelData mde) { int vertexOffset = vertList.Count; long start = br.BaseStream.Position; string magic = ReadString(br, 4); @@ -352,7 +352,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 result.Meshes.Add(mesh); } - private static MD3LoadResult ReadMD2Model(ref BoundingBoxSizes bbs, ModeldefEntry mde, MemoryStream s, Device D3DDevice) { + private static MD3LoadResult ReadMD2Model(ref BoundingBoxSizes bbs, ModelData mde, MemoryStream s, Device D3DDevice) { long start = s.Position; MD3LoadResult result = new MD3LoadResult(); @@ -552,25 +552,23 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 ms.Close(); ms.Dispose(); - if(bitmap == null) return null; + if(bitmap != null) { + BitmapData bmlock = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat); + texture = new Texture(device, bitmap.Width, bitmap.Height, 1, Usage.None, Format.A8R8G8B8, Pool.Managed); - BitmapData bmlock = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat); - texture = new Texture(device, bitmap.Width, bitmap.Height, 1, Usage.None, Format.A8R8G8B8, Pool.Managed); + DataRectangle textureLock = texture.LockRectangle(0, LockFlags.None); + textureLock.Data.WriteRange(bmlock.Scan0, bmlock.Height * bmlock.Stride); - DataRectangle textureLock = texture.LockRectangle(0, LockFlags.None); - textureLock.Data.WriteRange(bmlock.Scan0, bmlock.Height * bmlock.Stride); + bitmap.UnlockBits(bmlock); + texture.UnlockRectangle(0); + } + } else { + texture = Texture.FromStream(device, ms); - bitmap.UnlockBits(bmlock); - texture.UnlockRectangle(0); - - return texture; + ms.Close(); + ms.Dispose(); } - texture = Texture.FromStream(device, ms); - - ms.Close(); - ms.Dispose(); - return texture; } diff --git a/Source/Core/General/MapManager.cs b/Source/Core/General/MapManager.cs index 610c2101..70066953 100644 --- a/Source/Core/General/MapManager.cs +++ b/Source/Core/General/MapManager.cs @@ -297,11 +297,8 @@ namespace CodeImp.DoomBuilder { map.Update(); thingsfilter.Update(); - //mxd. load models - data.LoadModels(); - //mxd - namedScripts = new List(); - numberedScripts = new List(); + namedScripts = new List(); //mxd + numberedScripts = new List(); //mxd // Bind any methods General.Actions.BindMethods(this); @@ -360,12 +357,11 @@ namespace CodeImp.DoomBuilder { #if DEBUG tempwad = new WAD(tempfile); #else - try { tempwad = new WAD(tempfile); } - catch(Exception e) - { - General.ShowErrorMessage("Error while creating a temporary wad file:\n" + e.GetType().Name + ": " + e.Message, MessageBoxButtons.OK); - return false; - } + try { tempwad = new WAD(tempfile); } catch(Exception e) + { + General.ShowErrorMessage("Error while creating a temporary wad file:\n" + e.GetType().Name + ": " + e.Message, MessageBoxButtons.OK); + return false; + } #endif // Now open the map file @@ -373,12 +369,11 @@ namespace CodeImp.DoomBuilder { #if DEBUG mapwad = new WAD(filepathname, true); #else - try { mapwad = new WAD(filepathname, true); } - catch(Exception e) - { - General.ShowErrorMessage("Error while opening source wad file:\n" + e.GetType().Name + ": " + e.Message, MessageBoxButtons.OK); - return false; - } + try { mapwad = new WAD(filepathname, true); } catch(Exception e) + { + General.ShowErrorMessage("Error while opening source wad file:\n" + e.GetType().Name + ": " + e.Message, MessageBoxButtons.OK); + return false; + } #endif // Copy the map lumps to the temp file @@ -397,13 +392,12 @@ namespace CodeImp.DoomBuilder { #if DEBUG map = io.Read(map, TEMP_MAP_HEADER); #else - try { map = io.Read(map, TEMP_MAP_HEADER); } - catch(Exception e) - { - General.ErrorLogger.Add(ErrorType.Error, "Unable to read the map data structures with the specified configuration. " + e.GetType().Name + ": " + e.Message); - General.ShowErrorMessage("Unable to read the map data structures with the specified configuration.", MessageBoxButtons.OK); - return false; - } + try { map = io.Read(map, TEMP_MAP_HEADER); } catch(Exception e) + { + General.ErrorLogger.Add(ErrorType.Error, "Unable to read the map data structures with the specified configuration. " + e.GetType().Name + ": " + e.Message); + General.ShowErrorMessage("Unable to read the map data structures with the specified configuration.", MessageBoxButtons.OK); + return false; + } #endif map.EndAddRemove(); @@ -423,8 +417,6 @@ namespace CodeImp.DoomBuilder { map.Update(); thingsfilter.Update(); - //mxd. load models - data.LoadModels(); //mxd. check script names UpdateScriptNames(); diff --git a/Source/Core/Map/Linedef.cs b/Source/Core/Map/Linedef.cs index d28d4fa4..cd9f9b7e 100644 --- a/Source/Core/Map/Linedef.cs +++ b/Source/Core/Map/Linedef.cs @@ -104,6 +104,7 @@ namespace CodeImp.DoomBuilder.Map internal bool FrontInterior { get { return frontinterior; } set { frontinterior = value; } } internal bool ImpassableFlag { get { return impassableflag; } } internal int ColorPresetIndex { get { return colorPresetIndex; } } //mxd + internal bool ExtraFloorFlag; //mxd #endregion @@ -287,7 +288,6 @@ namespace CodeImp.DoomBuilder.Map l.updateneeded = true; l.activate = activate; l.impassableflag = impassableflag; - //l.blocksoundflag = blocksoundflag; l.UpdateColorPreset();//mxd base.CopyPropertiesTo(l); } @@ -812,6 +812,7 @@ namespace CodeImp.DoomBuilder.Map SetEndVertex(v); nl.Selected = this.Selected; nl.marked = this.marked; + nl.ExtraFloorFlag = this.ExtraFloorFlag; //mxd // Copy front sidedef if exists if(front != null) diff --git a/Source/Core/Map/MapSet.cs b/Source/Core/Map/MapSet.cs index cc7bf4e5..d471cbe1 100644 --- a/Source/Core/Map/MapSet.cs +++ b/Source/Core/Map/MapSet.cs @@ -77,7 +77,7 @@ namespace CodeImp.DoomBuilder.Map private int numthings; //mxd - private Sector[] newSectors; + private Dictionary newSectorLineIndices; //line index, sector order private GroupInfo[] groupInfos; // Behavior @@ -160,7 +160,7 @@ namespace CodeImp.DoomBuilder.Map internal bool AutoRemove { get { return autoremove; } set { autoremove = value; } } - public Sector[] NewSectors { get { return newSectors; } } //mxd + public Dictionary NewSectorLineIndices { get { return newSectorLineIndices; } } //mxd public GroupInfo[] GroupInfos { get { return groupInfos; } } //mxd @@ -184,7 +184,6 @@ namespace CodeImp.DoomBuilder.Map indexholes = new List(); lastsectorindex = 0; autoremove = true; - newSectors = new Sector[0]; //mxd groupInfos = new GroupInfo[10]; //mxd // We have no destructor @@ -207,7 +206,6 @@ namespace CodeImp.DoomBuilder.Map indexholes = new List(); lastsectorindex = 0; autoremove = true; - newSectors = new Sector[0]; //mxd groupInfos = new GroupInfo[10]; //mxd // Deserialize @@ -258,7 +256,6 @@ namespace CodeImp.DoomBuilder.Map sel_sectors = null; sel_things = null; indexholes = null; - newSectors = null; //mxd groupInfos = null; //mxd // Done @@ -3043,8 +3040,19 @@ namespace CodeImp.DoomBuilder.Map //mxd private void updateNewSectors() { int n = sectors.Length < General.Settings.GZNewSectorsCount ? sectors.Length : General.Settings.GZNewSectorsCount; - newSectors = new Sector[n]; + Sector[] newSectors = new Sector[n]; Array.Copy(sectors, sectors.Length - n, newSectors, 0, n); + + List newLineIndices = new List(); + newSectorLineIndices = new Dictionary(); + + for(int i = newSectors.Length-1; i > -1; i--) { + foreach (Sidedef side in newSectors[i].Sidedefs){ + if(newLineIndices.Contains(side.Line.Index)) continue; + newLineIndices.Add(side.Line.Index); + newSectorLineIndices.Add(side.Line.Index, i); + } + } } #endregion diff --git a/Source/Core/Map/Thing.cs b/Source/Core/Map/Thing.cs index d6b1c370..4f2c6886 100644 --- a/Source/Core/Map/Thing.cs +++ b/Source/Core/Map/Thing.cs @@ -23,6 +23,7 @@ using CodeImp.DoomBuilder.Rendering; using CodeImp.DoomBuilder.Config; using CodeImp.DoomBuilder.IO; using CodeImp.DoomBuilder.VisualModes; +using CodeImp.DoomBuilder.GZBuilder.Data; #endregion @@ -56,7 +57,8 @@ namespace CodeImp.DoomBuilder.Map private int tag; private int action; private int[] args; - protected float scale; //mxd. Used in model rendering + private float scale; //mxd. Used in model rendering + private bool isModel; //mxd // Configuration private float size; @@ -69,7 +71,7 @@ namespace CodeImp.DoomBuilder.Map #region ================== Properties public MapSet Map { get { return map; } } - public int Type { get { return type; } set { BeforePropsChange(); type = value; } } + public int Type { get { return type; } set { BeforePropsChange(); type = value; UpdateModelStatus(); } } //mxd public Vector3D Position { get { return pos; } } public float Scale { get { return scale; } } //mxd public float Angle { get { return anglerad; } } @@ -83,8 +85,7 @@ namespace CodeImp.DoomBuilder.Map public bool FixedSize { get { return fixedsize; } } public int Tag { get { return tag; } set { BeforePropsChange(); tag = value; if((tag < General.Map.FormatInterface.MinTag) || (tag > General.Map.FormatInterface.MaxTag)) throw new ArgumentOutOfRangeException("Tag", "Invalid tag number"); } } public Sector Sector { get { return sector; } } - //mxd - public bool IsModel; + public bool IsModel { get { return isModel; } } //mxd #endregion @@ -181,9 +182,11 @@ namespace CodeImp.DoomBuilder.Map s.rwInt(ref tag); s.rwInt(ref action); for(int i = 0; i < NUM_ARGS; i++) s.rwInt(ref args[i]); - - if(!s.IsWriting) + + if(!s.IsWriting) { anglerad = Angle2D.DoomToReal(angledoom); + UpdateModelStatus(); //mxd + } } // This copies all properties to another thing @@ -193,6 +196,7 @@ namespace CodeImp.DoomBuilder.Map // Copy properties t.type = type; + t.UpdateModelStatus(); t.anglerad = anglerad; t.angledoom = angledoom; t.pos = pos; @@ -235,6 +239,20 @@ namespace CodeImp.DoomBuilder.Map } } + //mxd. This checks if the thing has model override + internal void UpdateModelStatus() { + if(General.Map.Data == null) { + isModel = false; + return; + } + + isModel = General.Map.Data.ModeldefEntries.ContainsKey(type); + if(!isModel) return; + + if(General.Map.Data.ModeldefEntries[type].LoadState == ModelLoadState.None) + General.Map.Data.ProcessModel(type); + } + // This translates the flags into UDMF fields internal void TranslateToUDMF() { @@ -405,6 +423,7 @@ namespace CodeImp.DoomBuilder.Map this.args = new int[NUM_ARGS]; args.CopyTo(this.args, 0); this.Move(x, y, zoffset); + UpdateModelStatus(); //mxd } // This updates the settings from configuration diff --git a/Source/Core/Rendering/IRenderer2D.cs b/Source/Core/Rendering/IRenderer2D.cs index 9d564564..fd4fb654 100644 --- a/Source/Core/Rendering/IRenderer2D.cs +++ b/Source/Core/Rendering/IRenderer2D.cs @@ -48,7 +48,7 @@ namespace CodeImp.DoomBuilder.Rendering PixelColor DetermineThingColor(Thing t); int DetermineVertexColor(Vertex v); int CalculateBrightness(int level); - void Update3dFloorTagsList(); //mxd + void UpdateExtraFloorFlag(); //mxd // Rendering management methods bool StartPlotter(bool clear); diff --git a/Source/Core/Rendering/Renderer2D.cs b/Source/Core/Rendering/Renderer2D.cs index 35d52904..43716b51 100644 --- a/Source/Core/Rendering/Renderer2D.cs +++ b/Source/Core/Rendering/Renderer2D.cs @@ -39,7 +39,7 @@ namespace CodeImp.DoomBuilder.Rendering * PresentationLayer(s) to specify how to present these layers. */ - internal unsafe sealed class Renderer2D : Renderer, IRenderer2D + internal sealed class Renderer2D : Renderer, IRenderer2D { #region ================== Constants @@ -49,7 +49,7 @@ namespace CodeImp.DoomBuilder.Rendering private const float THING_CIRCLE_SIZE = 1f; private const float THING_CIRCLE_SHRINK = 0f; private const int THING_BUFFER_SIZE = 100; - //private const float THINGS_BACK_ALPHA = 0.3f; + private const float MINIMUM_THING_RADIUS = 1.5f; //mxd private const string FONT_NAME = "Verdana"; private const int FONT_WIDTH = 0; @@ -128,8 +128,7 @@ namespace CodeImp.DoomBuilder.Rendering private Presentation present; //mxd - private Dictionary thingsWithModel; - private List tagsOf3DFloors; + private Dictionary> thingsWithModel; //model index, list of thing positions in screen space, thing #endregion @@ -165,7 +164,6 @@ namespace CodeImp.DoomBuilder.Rendering // Create surface manager surfaces = new SurfaceManager(); - tagsOf3DFloors = new List(); //mxd // Create rendertargets CreateRendertargets(); @@ -203,7 +201,7 @@ namespace CodeImp.DoomBuilder.Rendering } // This draws the image on screen - public void Present() + public unsafe void Present() { General.Plugins.OnPresentDisplayBegin(); @@ -398,7 +396,7 @@ namespace CodeImp.DoomBuilder.Rendering } // Allocates new image memory to render on - public void CreateRendertargets() + public unsafe void CreateRendertargets() { SurfaceDescription sd; DataStream stream; @@ -581,16 +579,17 @@ namespace CodeImp.DoomBuilder.Rendering public PixelColor DetermineThingColor(Thing t) { // Determine color - if (t.Selected) { - return General.Colors.Selection; - //mxd. if thing is light, set it's color to light color: - }else if(Array.IndexOf(GZBuilder.GZGeneral.GZ_LIGHTS, t.Type) != -1){ + if (t.Selected) return General.Colors.Selection; + + //mxd. if thing is light, set it's color to light color: + if(Array.IndexOf(GZBuilder.GZGeneral.GZ_LIGHTS, t.Type) != -1){ if (t.Type == 1502) //vavoom light return new PixelColor(255, 255, 255, 255); if (t.Type == 1503) //vavoom colored light return new PixelColor(255, (byte)t.Args[1], (byte)t.Args[2], (byte)t.Args[3]); return new PixelColor(255, (byte)t.Args[0], (byte)t.Args[1], (byte)t.Args[2]); } + return t.Color; } @@ -605,35 +604,49 @@ namespace CodeImp.DoomBuilder.Rendering // This returns the color for a linedef public PixelColor DetermineLinedefColor(Linedef l) { - if(l.Selected) - return General.Colors.Selection; - - if(l.ImpassableFlag) - { - //mxd. Impassable lines - if(l.ColorPresetIndex != -1) - return General.Map.ConfigSettings.LinedefColorPresets[l.ColorPresetIndex].Color; - return General.Colors.Linedefs; + if(l.Selected) return General.Colors.Selection; + + //mxd. Impassable lines + if(l.ImpassableFlag) { + if(l.ColorPresetIndex != -1) + return General.Map.ConfigSettings.LinedefColorPresets[l.ColorPresetIndex].Color; + return General.Colors.Linedefs; } - //mxd. Passable lines - if(l.ColorPresetIndex != -1) - return General.Map.ConfigSettings.LinedefColorPresets[l.ColorPresetIndex].Color.WithAlpha(General.Settings.DoubleSidedAlphaByte); - return General.Colors.Linedefs.WithAlpha(General.Settings.DoubleSidedAlphaByte); + //mxd. Passable lines + if(l.ColorPresetIndex != -1) + return General.Map.ConfigSettings.LinedefColorPresets[l.ColorPresetIndex].Color.WithAlpha(General.Settings.DoubleSidedAlphaByte); + return General.Colors.Linedefs.WithAlpha(General.Settings.DoubleSidedAlphaByte); } - //mxd - public void Update3dFloorTagsList() { - //mxd. Collect 3d-floors tags - tagsOf3DFloors = new List(); + //mxd. This collects indices of linedefs, which are parts of sectors with 3d floors + public void UpdateExtraFloorFlag() { + List tagList = new List(); + + //find lines with 3d floor action and collect sector tags foreach(Linedef l in General.Map.Map.Linedefs){ if(l.Action == 160) { int sectortag = (l.Args[1] & 8) != 0 ? l.Args[0] : l.Args[0] + (l.Args[4] << 8); - - if(sectortag != 0 && !tagsOf3DFloors.Contains(sectortag)) - tagsOf3DFloors.Add(sectortag); + if(sectortag != 0) tagList.Add(sectortag); } } + + tagList.Sort(); + int[] tags = tagList.ToArray(); + + //find lines, which are related to sectors with 3d floors, and collect their valuable indices + foreach(Linedef l in General.Map.Map.Linedefs) { + if(l.Front != null && l.Front.Sector != null && l.Front.Sector.Tag != 0 && Array.BinarySearch(tags, l.Front.Sector.Tag) > -1) { + l.ExtraFloorFlag = true; + continue; + } + if(l.Back != null && l.Back.Sector != null && l.Back.Sector.Tag != 0 && Array.BinarySearch(tags, l.Back.Sector.Tag) > -1) { + l.ExtraFloorFlag = true; + continue; + } + + l.ExtraFloorFlag = false; + } } #endregion @@ -643,10 +656,7 @@ namespace CodeImp.DoomBuilder.Rendering // This begins a drawing session public unsafe bool StartPlotter(bool clear) { - if(renderlayer != RenderLayers.None) { - //throw new InvalidOperationException("Renderer starting called before finished previous layer. Call Finish() first!"); - return false; //mxd. Can't render. Most probably because previous frame or render layer wasn't finished yet. - } + if(renderlayer != RenderLayers.None) return false; //mxd. Can't render. Most probably because previous frame or render layer wasn't finished yet. renderlayer = RenderLayers.Plotter; try { graphics.Device.SetRenderState(RenderState.FogEnable, false); } catch(Exception) { } @@ -672,21 +682,16 @@ namespace CodeImp.DoomBuilder.Rendering UpdateTransformations(); return true; } - else - { - // Can't render! - Finish(); - return false; - } + + // Can't render! + Finish(); + return false; } // This begins a drawing session - public unsafe bool StartThings(bool clear) + public bool StartThings(bool clear) { - if(renderlayer != RenderLayers.None) { - //throw new InvalidOperationException("Renderer starting called before finished previous layer. Call Finish() first!"); - return false; //mxd. Can't render. Most probably because previous frame or render layer wasn't finished yet. - } + if(renderlayer != RenderLayers.None) return false; //mxd. Can't render. Most probably because previous frame or render layer wasn't finished yet. renderlayer = RenderLayers.Things; try { graphics.Device.SetRenderState(RenderState.FogEnable, false); } catch(Exception) { } @@ -702,29 +707,21 @@ namespace CodeImp.DoomBuilder.Rendering UpdateTransformations(); return true; } - else - { - // Can't render! - Finish(); - return false; - } - } - else - { + // Can't render! Finish(); return false; } + + // Can't render! + Finish(); + return false; } // This begins a drawing session - public unsafe bool StartOverlay(bool clear) + public bool StartOverlay(bool clear) { - if(renderlayer != RenderLayers.None) { - //throw new InvalidOperationException("Renderer starting called before finished previous layer. Call Finish() first!"); - return false; //mxd. Can't render. Most probably because previous frame or render layer wasn't finished yet. - } - + if(renderlayer != RenderLayers.None) throw new InvalidOperationException("Renderer starting called before finished previous layer. Call Finish() first!"); renderlayer = RenderLayers.Overlay; try { graphics.Device.SetRenderState(RenderState.FogEnable, false); } catch(Exception) { } @@ -739,19 +736,15 @@ namespace CodeImp.DoomBuilder.Rendering UpdateTransformations(); return true; } - else - { - // Can't render! - Finish(); - return false; - } - } - else - { + // Can't render! Finish(); return false; } + + // Can't render! + Finish(); + return false; } // This ends a drawing session @@ -794,8 +787,8 @@ namespace CodeImp.DoomBuilder.Rendering private void SetupBackground() { Vector2D ltpos, rbpos; - Vector2D backoffset = new Vector2D((float)General.Map.Grid.BackgroundX, (float)General.Map.Grid.BackgroundY); - Vector2D backimagesize = new Vector2D((float)General.Map.Grid.Background.ScaledWidth, (float)General.Map.Grid.Background.ScaledHeight); + Vector2D backoffset = new Vector2D(General.Map.Grid.BackgroundX, General.Map.Grid.BackgroundY); + Vector2D backimagesize = new Vector2D(General.Map.Grid.Background.ScaledWidth, General.Map.Grid.Background.ScaledHeight); Vector2D backimagescale = new Vector2D(General.Map.Grid.BackgroundScaleX, General.Map.Grid.BackgroundScaleY); // Scale the background image size @@ -835,7 +828,7 @@ namespace CodeImp.DoomBuilder.Rendering } // This renders all grid - private void RenderBackgroundGrid() + private unsafe void RenderBackgroundGrid() { Plotter gridplotter; DataRectangle lockedrect; @@ -951,9 +944,10 @@ namespace CodeImp.DoomBuilder.Rendering // Returns false when not on the screen private bool CreateThingVerts(Thing t, ref FlatVertex[] verts, int offset, PixelColor c) { + if(t.Size * scale < MINIMUM_THING_RADIUS) return false; //mxd. Don't render tiny little things + float circlesize; float arrowsize; - int color; // Transform to screen coordinates Vector2D screenpos = ((Vector2D)t.Position).GetTransformed(translatex, translatey, scale, -scale); @@ -971,20 +965,24 @@ namespace CodeImp.DoomBuilder.Rendering } // Check if the thing is actually on screen - if(((screenpos.x + circlesize) > 0.0f) && ((screenpos.x - circlesize) < (float)windowsize.Width) && - ((screenpos.y + circlesize) > 0.0f) && ((screenpos.y - circlesize) < (float)windowsize.Height)) + if(((screenpos.x + circlesize) > 0.0f) && ((screenpos.x - circlesize) < windowsize.Width) && + ((screenpos.y + circlesize) > 0.0f) && ((screenpos.y - circlesize) < windowsize.Height)) { //mxd. Collect things with models for rendering - if (General.Settings.GZDrawModels && (!General.Settings.GZDrawSelectedModelsOnly || t.Selected)) { - Dictionary mde = General.Map.Data.ModeldefEntries; - if (mde != null && mde.ContainsKey(t.Type)) { - thingsWithModel[screenpos] = t; - } + if(t.IsModel && General.Settings.GZDrawModels && (!General.Settings.GZDrawSelectedModelsOnly || t.Selected)) { + if(!thingsWithModel.ContainsKey(t.Type)) { + thingsWithModel.Add(t.Type, new Dictionary()); + } + + if(thingsWithModel[t.Type].ContainsKey(screenpos)) { + thingsWithModel[t.Type][screenpos] = t; + } else { + thingsWithModel[t.Type].Add(screenpos, t); + } } - // Get integral color - color = c.ToInt(); + int color = c.ToInt(); // Setup fixed rect for circle verts[offset].x = screenpos.x - circlesize; @@ -1051,11 +1049,9 @@ namespace CodeImp.DoomBuilder.Rendering // Done return true; } - else - { - // Not on screen - return false; - } + + // Not on screen + return false; } // This draws a set of things @@ -1099,7 +1095,7 @@ namespace CodeImp.DoomBuilder.Rendering FlatVertex[] verts = new FlatVertex[THING_BUFFER_SIZE * 12]; //mxd - thingsWithModel = new Dictionary(); + thingsWithModel = new Dictionary>(); // Go for all things int buffercount = 0; @@ -1152,25 +1148,28 @@ namespace CodeImp.DoomBuilder.Rendering graphics.Device.SetRenderState(RenderState.FillMode, FillMode.Wireframe); graphics.Shaders.Things2D.BeginPass(1); - foreach(KeyValuePair group in thingsWithModel){ - ModeldefEntry mde = General.Map.Data.ModeldefEntries[group.Value.Type]; - if (mde.Model != null) {//render model - //wire color - graphics.Shaders.Things2D.FillColor = group.Value.Selected ? General.Colors.Selection.ToColorValue() : General.Colors.ModelWireframe.ToColorValue(); + Color4 cSel = General.Colors.Selection.ToColorValue(); + Color4 cWire = General.Colors.ModelWireframe.ToColorValue(); + ModelData mde; - for (int i = 0; i < mde.Model.Meshes.Count; i++) { - graphics.Shaders.Things2D.SetTransformSettings(group.Key, group.Value.Angle, scale * group.Value.Scale); - graphics.Shaders.Things2D.ApplySettings(); + 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; - // Draw - mde.Model.Meshes[i].DrawSubset(0); - } + 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); + } + } + } + } - } else { - group.Value.IsModel = General.Map.Data.LoadModelForThing(group.Value); - } - } graphics.Shaders.Things2D.EndPass(); graphics.Device.SetRenderState(RenderState.FillMode, FillMode.Solid); @@ -1201,9 +1200,7 @@ namespace CodeImp.DoomBuilder.Rendering // This redraws the surface public void RedrawSurface() { - //mxd... - //if(renderlayer != RenderLayers.None) throw new InvalidOperationException("Renderer starting called before finished previous layer. Call Finish() first!"); - if(renderlayer != RenderLayers.None) return; + if(renderlayer != RenderLayers.None) return; //mxd renderlayer = RenderLayers.Surface; // Rendertargets available? @@ -1597,33 +1594,20 @@ namespace CodeImp.DoomBuilder.Rendering Vector2D v2 = l.End.Position.GetTransformed(translatex, translatey, scale, -scale); //mxd. Newly created sectors colouring - if(General.Settings.GZNewSectorsCount > 0 && c.r == 255 && c.g == 255 && c.b == 255){ - int frontIndex = -1; - int backIndex = -1; - - if(l.Front != null) - frontIndex = Array.IndexOf(General.Map.Map.NewSectors, l.Front.Sector); - if(l.Back != null) - backIndex = Array.IndexOf(General.Map.Map.NewSectors, l.Back.Sector); - - if(frontIndex != -1 || backIndex != -1){ + if(General.Settings.GZNewSectorsCount > 0 && l.ColorPresetIndex == -1){ + if(General.Map.Map.NewSectorLineIndices.ContainsKey(l.Index)){ + int index = General.Map.Map.NewSectorLineIndices[l.Index]; PixelColor highlight = General.Colors.NewSector; - - if(frontIndex > backIndex) - highlight.a = (byte)(255 * (1.0f - (float)(frontIndex + 1) / General.Map.Map.NewSectors.Length)); - else - highlight.a = (byte)(255 * (1.0f - (float)(backIndex + 1) / General.Map.Map.NewSectors.Length)); - - float ba = (float)highlight.a * PixelColor.BYTE_TO_FLOAT; - c.r = (byte)Math.Min(255, ((float)highlight.r * (1f - ba) + (float)c.r * ba)); - c.g = (byte)Math.Min(255, ((float)highlight.g * (1f - ba) + (float)c.g * ba)); - c.b = (byte)Math.Min(255, ((float)highlight.b * (1f - ba) + (float)c.b * ba)); + highlight.a = (byte)(255 * (1.0f - (float)(index + 1) / General.Settings.GZNewSectorsCount)); + float ha = highlight.a * PixelColor.BYTE_TO_FLOAT; + c.r = (byte)Math.Min(255, (highlight.r * (1f - ha) + c.r * ha)); + c.g = (byte)Math.Min(255, (highlight.g * (1f - ha) + c.g * ha)); + c.b = (byte)Math.Min(255, (highlight.b * (1f - ha) + c.b * ha)); } } // Draw line. mxd: added 3d-floor indication - if((l.Front != null && l.Front.Sector != null && tagsOf3DFloors.Contains(l.Front.Sector.Tag)) || - (l.Back != null && l.Back.Sector != null && tagsOf3DFloors.Contains(l.Back.Sector.Tag))) { + if(l.ExtraFloorFlag) { plotter.DrawLine3DFloor(v1, v2, ref c, General.Colors.ThreeDFloor); } else { plotter.DrawLineSolid((int)v1.x, (int)v1.y, (int)v2.x, (int)v2.y, ref c); diff --git a/Source/Core/Rendering/Renderer3D.cs b/Source/Core/Rendering/Renderer3D.cs index 49531ab9..1bbd972e 100644 --- a/Source/Core/Rendering/Renderer3D.cs +++ b/Source/Core/Rendering/Renderer3D.cs @@ -74,7 +74,7 @@ namespace CodeImp.DoomBuilder.Rendering private List thingsWithLight; private int[] lightOffsets; private Dictionary> litGeometry; - private Dictionary> thingsWithModel; + private Dictionary> thingsWithModel; // Crosshair private FlatVertex[] crosshairverts; @@ -418,7 +418,7 @@ namespace CodeImp.DoomBuilder.Rendering things = new Dictionary>[RENDER_PASSES]; thingsbydistance = new BinaryHeap(); //mxd - thingsWithModel = new Dictionary>(); + thingsWithModel = new Dictionary>(); litGeometry = new Dictionary>(); for(int i = 0; i < RENDER_PASSES; i++) @@ -537,9 +537,9 @@ namespace CodeImp.DoomBuilder.Rendering lightOffsets = new int[3]; foreach (VisualThing t in thingsWithLight) { //add light to apropriate array. - if (t.LightRenderStyle == (int)GZDoomLightRenderStyle.NORMAL || t.LightRenderStyle == (int)GZDoomLightRenderStyle.VAVOOM) + if (t.LightRenderStyle == DynamicLightRenderStyle.NORMAL || t.LightRenderStyle == DynamicLightRenderStyle.VAVOOM) lightOffsets[0]++; - else if (t.LightRenderStyle == (int)GZDoomLightRenderStyle.ADDITIVE) + else if (t.LightRenderStyle == DynamicLightRenderStyle.ADDITIVE) lightOffsets[1]++; else lightOffsets[2]++; @@ -857,7 +857,7 @@ namespace CodeImp.DoomBuilder.Rendering foreach(VisualThing t in group.Value) { //mxd - if (General.Settings.GZDrawModels && (!General.Settings.GZDrawSelectedModelsOnly || t.Selected) && t.Thing.IsModel) + if (t.Thing.IsModel && General.Settings.GZDrawModels && (!General.Settings.GZDrawSelectedModelsOnly || t.Selected)) continue; // Update buffer if needed @@ -1028,7 +1028,7 @@ namespace CodeImp.DoomBuilder.Rendering // Begin rendering with this shader graphics.Shaders.World3D.BeginPass(currentshaderpass); - foreach (KeyValuePair> group in thingsWithModel) { + foreach (KeyValuePair> group in thingsWithModel) { foreach (VisualThing t in group.Value) { t.Update(); @@ -1110,7 +1110,7 @@ namespace CodeImp.DoomBuilder.Rendering radius = thingsWithLight[i].LightRadius; radiusSquared = radius * radius; if (distSquared < radiusSquared) { - sign = thingsWithLight[i].LightRenderStyle == (int)GZDoomLightRenderStyle.NEGATIVE ? -1 : 1; + sign = thingsWithLight[i].LightRenderStyle == DynamicLightRenderStyle.NEGATIVE ? -1 : 1; scaler = 1 - distSquared / radiusSquared * thingsWithLight[i].LightColor.Alpha; litColor.Red += thingsWithLight[i].LightColor.Red * scaler * sign; litColor.Green += thingsWithLight[i].LightColor.Green * scaler * sign; @@ -1196,7 +1196,7 @@ namespace CodeImp.DoomBuilder.Rendering public void AddThingGeometry(VisualThing t) { //mxd. gater lights - if (General.Settings.GZDrawLights && !fullbrightness && t.LightType != -1) { + if (General.Settings.GZDrawLights && !fullbrightness && t.LightType != DynamicLightType.NONE) { t.UpdateLightRadius(); if (t.LightRadius > 0) { @@ -1210,16 +1210,15 @@ namespace CodeImp.DoomBuilder.Rendering } } - if (!isThingOnScreen(t.BoundingBox)) { - return; - } + if (!isThingOnScreen(t.BoundingBox)) return; //mxd. gather models - if (General.Settings.GZDrawModels && (!General.Settings.GZDrawSelectedModelsOnly || t.Selected) && t.Thing.IsModel) { - ModeldefEntry mde = General.Map.Data.ModeldefEntries[t.Thing.Type]; - if (!thingsWithModel.ContainsKey(mde)) - thingsWithModel.Add(mde, new List()); - thingsWithModel[mde].Add(t); + if(t.Thing.IsModel && General.Settings.GZDrawModels && (!General.Settings.GZDrawSelectedModelsOnly || t.Selected)) { + ModelData mde = General.Map.Data.ModeldefEntries[t.Thing.Type]; + if (!thingsWithModel.ContainsKey(mde)) + thingsWithModel.Add(mde, new List() { t }); + else + thingsWithModel[mde].Add(t); } // Make sure the distance to camera is calculated diff --git a/Source/Core/VisualModes/VisualThing.cs b/Source/Core/VisualModes/VisualThing.cs index d20dcc81..5266092f 100644 --- a/Source/Core/VisualModes/VisualThing.cs +++ b/Source/Core/VisualModes/VisualThing.cs @@ -75,8 +75,8 @@ namespace CodeImp.DoomBuilder.VisualModes protected Matrix scale; //mxd. Used in model rendering //mxd. light properties - private int lightType; - private int lightRenderStyle; + private DynamicLightType lightType; + private DynamicLightRenderStyle lightRenderStyle; private Color4 lightColor; private float lightRadius; //current radius. used in light animation private float lightPrimaryRadius; @@ -118,9 +118,9 @@ namespace CodeImp.DoomBuilder.VisualModes public Vector3 PositionV3 { get { return position_v3; } } public Vector3[] BoundingBox { get { return boundingBox; } } //mxd. light properties - public int LightType { get { return lightType; } } + public DynamicLightType LightType { get { return lightType; } } public float LightRadius { get { return lightRadius; } } - public int LightRenderStyle { get { return lightRenderStyle; } } + public DynamicLightRenderStyle LightRenderStyle { get { return lightRenderStyle; } } public Color4 LightColor { get { return lightColor; } } /// @@ -171,8 +171,8 @@ namespace CodeImp.DoomBuilder.VisualModes this.scale = Matrix.Identity; //mxd //mxd - lightType = -1; - lightRenderStyle = -1; + lightType = DynamicLightType.NONE; + lightRenderStyle = DynamicLightRenderStyle.NONE; lightPrimaryRadius = -1; lightSecondaryRadius = -1; lightInterval = -1; @@ -265,7 +265,7 @@ namespace CodeImp.DoomBuilder.VisualModes //mxd. update bounding box if (thing.IsModel) { updateBoundingBoxForModel(); - } else if (lightType != -1 && lightRadius > thing.Size) { + } else if (lightType != DynamicLightType.NONE && lightRadius > thing.Size) { updateBoundingBox(lightRadius, lightRadius * 2); } else { updateBoundingBox((int)thing.Size, thingHeight); @@ -301,9 +301,6 @@ namespace CodeImp.DoomBuilder.VisualModes // Do we need to update the geometry buffer? if (updategeo) { - //mxd. check if thing is model - checkModelState(); - // Trash geometry buffer if (geobuffer != null) geobuffer.Dispose(); geobuffer = null; @@ -316,7 +313,7 @@ namespace CodeImp.DoomBuilder.VisualModes // Fill the buffer DataStream bufferstream = geobuffer.Lock(0, WorldVertex.Stride * vertices.Length, LockFlags.Discard); - bufferstream.WriteRange(vertices); + bufferstream.WriteRange(vertices); geobuffer.Unlock(); bufferstream.Dispose(); } @@ -329,18 +326,6 @@ namespace CodeImp.DoomBuilder.VisualModes } } - //mxd - protected void checkModelState() { - if (General.Map.Data.ModeldefEntries.ContainsKey(thing.Type)) { - if (General.Map.Data.ModeldefEntries[thing.Type].Model == null) - thing.IsModel = General.Map.Data.LoadModelForThing(thing); - else - thing.IsModel = true; - } else { - thing.IsModel = false; - } - } - //mxd protected void checkLightState() { //mxd. Check if thing is light @@ -362,11 +347,11 @@ namespace CodeImp.DoomBuilder.VisualModes } else { updateBoundingBox((int)thing.Size, thingHeight); } - lightType = -1; + lightType = DynamicLightType.NONE; lightRadius = -1; lightPrimaryRadius = -1; lightSecondaryRadius = -1; - lightRenderStyle = -1; + lightRenderStyle = DynamicLightRenderStyle.NONE; lightInterval = -1; isGldefsLight = false; } @@ -389,21 +374,21 @@ namespace CodeImp.DoomBuilder.VisualModes int n; if (light_id < GZBuilder.GZGeneral.GZ_LIGHT_TYPES[0]) { n = 0; - lightRenderStyle = (int)GZDoomLightRenderStyle.NORMAL; + lightRenderStyle = DynamicLightRenderStyle.NORMAL; //lightColor.Alpha used in shader to perform some calculations based on light type lightColor = new Color4((float)lightRenderStyle / 100.0f, (float)thing.Args[0] / scaled_intensity, (float)thing.Args[1] / scaled_intensity, (float)thing.Args[2] / scaled_intensity); } else if (light_id < GZBuilder.GZGeneral.GZ_LIGHT_TYPES[1]) { n = 10; - lightRenderStyle = (int)GZDoomLightRenderStyle.ADDITIVE; + lightRenderStyle = DynamicLightRenderStyle.ADDITIVE; lightColor = new Color4((float)lightRenderStyle / 100.0f, (float)thing.Args[0] / scaled_intensity, (float)thing.Args[1] / scaled_intensity, (float)thing.Args[2] / scaled_intensity); } else { n = 20; - lightRenderStyle = (int)GZDoomLightRenderStyle.NEGATIVE; + lightRenderStyle = DynamicLightRenderStyle.NEGATIVE; lightColor = new Color4((float)lightRenderStyle / 100.0f, (float)thing.Args[0] / scaled_intensity, (float)thing.Args[1] / scaled_intensity, (float)thing.Args[2] / scaled_intensity); } - lightType = thing.Type - 9800 - n; + lightType = (DynamicLightType)(thing.Type - 9800 - n); - if (lightType == (int)GZDoomLightType.SECTOR) { + if (lightType == DynamicLightType.SECTOR) { int scaler = 1; if (thing.Sector != null) scaler = thing.Sector.Brightness / 4; @@ -414,9 +399,9 @@ namespace CodeImp.DoomBuilder.VisualModes lightSecondaryRadius = (float)(thing.Args[4] * 2) * General.Settings.GZDynamicLightRadius; } } else { //it's one of vavoom lights - lightRenderStyle = (int)GZDoomLightRenderStyle.VAVOOM; - lightType = thing.Type; - if (lightType == (int)GZDoomLightType.VAVOOM_COLORED) + lightRenderStyle = DynamicLightRenderStyle.VAVOOM; + lightType = (DynamicLightType)thing.Type; + if (lightType == DynamicLightType.VAVOOM_COLORED) lightColor = new Color4((float)lightRenderStyle / 100.0f, (float)thing.Args[1] / scaled_intensity, (float)thing.Args[2] / scaled_intensity, (float)thing.Args[3] / scaled_intensity); else lightColor = new Color4((float)lightRenderStyle / 100.0f, General.Settings.GZDynamicLightIntensity, General.Settings.GZDynamicLightIntensity, General.Settings.GZDynamicLightIntensity); @@ -427,17 +412,17 @@ namespace CodeImp.DoomBuilder.VisualModes //mxd private void updateGldefsLight() { - GZDoomLight light = General.Map.Data.GldefsEntries[thing.Type]; + DynamicLightData light = General.Map.Data.GldefsEntries[thing.Type]; float intensity_mod = General.Settings.GZDynamicLightIntensity; float scale_mod = General.Settings.GZDynamicLightRadius; //apply settings - lightRenderStyle = light.Subtractive ? (int)GZDoomLightRenderStyle.NEGATIVE : (int)GZDoomLightRenderStyle.NORMAL; + lightRenderStyle = light.Subtractive ? DynamicLightRenderStyle.NEGATIVE : DynamicLightRenderStyle.NORMAL; lightColor = new Color4((float)lightRenderStyle / 100.0f, light.Color.Red * intensity_mod, light.Color.Green * intensity_mod, light.Color.Blue * intensity_mod); lightOffset = light.Offset; lightType = light.Type; - if (lightType == (int)GZDoomLightType.SECTOR) { + if (lightType == DynamicLightType.SECTOR) { lightPrimaryRadius = light.Interval * thing.Sector.Brightness / 5; } else { lightPrimaryRadius = light.PrimaryRadius * scale_mod; @@ -456,7 +441,7 @@ namespace CodeImp.DoomBuilder.VisualModes //mxd private void updateLightRadius(int interval) { - if (lightType == -1) { + if (lightType == DynamicLightType.NONE) { General.ErrorLogger.Add(ErrorType.Error, "Please check that thing is light before accessing it's PositionAndRadius! You can use lightType, which is -1 if thing isn't light"); return; } @@ -473,11 +458,11 @@ namespace CodeImp.DoomBuilder.VisualModes float diff = rMax - rMin; //pulse - if (lightType == (int)GZDoomLightType.PULSE) { + if (lightType == DynamicLightType.PULSE) { lightDelta = ((float)Math.Sin(time / (interval * 4.0f)) + 1.0f) / 2.0f; //just playing by the eye here... in [0.0 ... 1.0] interval lightRadius = rMin + diff * lightDelta; //flicker - } else if (lightType == (int)GZDoomLightType.FLICKER) { + } else if (lightType == DynamicLightType.FLICKER) { float delta = (float)Math.Sin(time / 0.1f); //just playing by the eye here... if (Math.Sign(delta) != Math.Sign(lightDelta)) { lightDelta = delta; @@ -487,7 +472,7 @@ namespace CodeImp.DoomBuilder.VisualModes lightRadius = rMin; } //random - } else if (lightType == (int)GZDoomLightType.RANDOM) { + } else if (lightType == DynamicLightType.RANDOM) { float delta = (float)Math.Sin(time / (interval * 9.0f)); //just playing by the eye here... if (Math.Sign(delta) != Math.Sign(lightDelta)) lightRadius = rMin + (float)(new Random().Next(0, (int)(diff * 10))) / 10.0f; @@ -500,7 +485,7 @@ namespace CodeImp.DoomBuilder.VisualModes //updateBoundingBox(lightRadius, lightRadius * 2f); if (thing.IsModel) { updateBoundingBoxForModel(); - } else if (lightType != -1 && lightRadius > thing.Size) { + } else if (lightType != DynamicLightType.NONE && lightRadius > thing.Size) { updateBoundingBox(lightRadius, lightRadius * 2); } else { updateBoundingBox((int)thing.Size, thingHeight); @@ -525,7 +510,7 @@ namespace CodeImp.DoomBuilder.VisualModes //mxd. update bounding box from model bounding box private void updateBoundingBoxForModel() { - ModeldefEntry mde = General.Map.Data.ModeldefEntries[thing.Type]; + ModelData mde = General.Map.Data.ModeldefEntries[thing.Type]; int len = mde.Model.BoundingBox.Length; boundingBox = new Vector3[len]; for (int i = 0; i < len; i++) { diff --git a/Source/Core/Windows/MainForm.cs b/Source/Core/Windows/MainForm.cs index 195a544c..4c1b76cf 100644 --- a/Source/Core/Windows/MainForm.cs +++ b/Source/Core/Windows/MainForm.cs @@ -3084,11 +3084,11 @@ namespace CodeImp.DoomBuilder.Windows if(warningsCount > 0) { if(!warnsLabel.Font.Bold){ warnsLabel.Font = new Font(warnsLabel.Font, FontStyle.Bold); - warnsLabel.Image = global::CodeImp.DoomBuilder.Properties.Resources.Warning; + warnsLabel.Image = Resources.Warning; } } else { warnsLabel.Font = new Font(warnsLabel.Font, FontStyle.Regular); - warnsLabel.Image = global::CodeImp.DoomBuilder.Properties.Resources.WarningOff; + warnsLabel.Image = Resources.WarningOff; warnsLabel.BackColor = SystemColors.Control; } @@ -3107,11 +3107,11 @@ namespace CodeImp.DoomBuilder.Windows private void blink() { if(warnsLabel.BackColor == Color.Red) { warnsLabel.Font = new Font(warnsLabel.Font, FontStyle.Regular); - warnsLabel.Image = global::CodeImp.DoomBuilder.Properties.Resources.WarningOff; + warnsLabel.Image = Resources.WarningOff; warnsLabel.BackColor = SystemColors.Control; } else { warnsLabel.Font = new Font(warnsLabel.Font, FontStyle.Bold); - warnsLabel.Image = global::CodeImp.DoomBuilder.Properties.Resources.Warning; + warnsLabel.Image = Resources.Warning; warnsLabel.BackColor = Color.Red; } } diff --git a/Source/Core/ZDoom/TexturesParser.cs b/Source/Core/ZDoom/TexturesParser.cs index 82711926..504969f9 100644 --- a/Source/Core/ZDoom/TexturesParser.cs +++ b/Source/Core/ZDoom/TexturesParser.cs @@ -97,7 +97,7 @@ namespace CodeImp.DoomBuilder.ZDoom { // Add the texture textures[tx.Name] = tx; - flats[tx.Name] = tx; + if(!General.Map.Config.MixTexturesFlats) flats[tx.Name] = tx; //mxd. If MixTexturesFlats is set, textures and flats will be mixed in DataManager anyway } } else if(objdeclaration == "sprite") diff --git a/Source/Plugins/BuilderModes/ClassicModes/BaseClassicMode.cs b/Source/Plugins/BuilderModes/ClassicModes/BaseClassicMode.cs index 2221a3d2..eafa7f78 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/BaseClassicMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/BaseClassicMode.cs @@ -99,7 +99,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { General.Map.Map.ClearAllSelected(); General.Map.Map.SelectMarkedGeometry(true, true); - General.Map.Renderer2D.Update3dFloorTagsList(); //mxd + General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd // Switch to EditSelectionMode EditSelectionMode editmode = new EditSelectionMode(); @@ -144,12 +144,14 @@ namespace CodeImp.DoomBuilder.BuilderModes //mxd public override void OnUndoEnd() { + General.Map.Renderer2D.UpdateExtraFloorFlag(); base.OnUndoEnd(); updateSelectionInfo(); } //mxd public override void OnRedoEnd() { + General.Map.Renderer2D.UpdateExtraFloorFlag(); base.OnRedoEnd(); updateSelectionInfo(); } diff --git a/Source/Plugins/BuilderModes/ClassicModes/BridgeMode.cs b/Source/Plugins/BuilderModes/ClassicModes/BridgeMode.cs index 2ccb34a7..f6f99207 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/BridgeMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/BridgeMode.cs @@ -117,6 +117,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.ClassicModes { // Mouse moves public override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); + if(panning) return; //mxd. Skip all this jass while panning if (curControlHandle != -1) { ControlHandle handle = controlHandles[curControlHandle]; diff --git a/Source/Plugins/BuilderModes/ClassicModes/BrightnessMode.cs b/Source/Plugins/BuilderModes/ClassicModes/BrightnessMode.cs index e7b6f340..b4338687 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/BrightnessMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/BrightnessMode.cs @@ -443,6 +443,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); + if(panning) return; //mxd. Skip all this jass while panning // Not in any editing mode? if(mode == ModifyMode.None) { diff --git a/Source/Plugins/BuilderModes/ClassicModes/DragGeometryMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DragGeometryMode.cs index 0624b73e..2dc88095 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/DragGeometryMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DragGeometryMode.cs @@ -555,6 +555,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); + if(panning) return; //mxd. Skip all this jass while panning Update(); } // When a key is released diff --git a/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs index 46172d15..81fc3682 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs @@ -541,6 +541,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); + if(panning) return; //mxd. Skip all this jass while panning Update(); } diff --git a/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs b/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs index f380f570..54f26843 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs @@ -1381,7 +1381,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); - + if(panning) return; //mxd. Skip all this jass while panning Update(); } diff --git a/Source/Plugins/BuilderModes/ClassicModes/FlatAlignMode.cs b/Source/Plugins/BuilderModes/ClassicModes/FlatAlignMode.cs index 580a577c..423f53d2 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/FlatAlignMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/FlatAlignMode.cs @@ -735,7 +735,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); - + if(panning) return; //mxd. Skip all this jass while panning Update(); } diff --git a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs index bf631c8f..cfdfc75a 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs @@ -321,10 +321,11 @@ 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(!panning) //mxd + 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); + if(!panning) BuilderPlug.Me.PlotReverseAssociations(renderer, highlightasso); //mxd renderer.PlotLinedef(highlighted, General.Colors.Highlight); } renderer.PlotVerticesSet(General.Map.Map.Vertices); @@ -342,8 +343,9 @@ namespace CodeImp.DoomBuilder.BuilderModes // Render selection if(renderer.StartOverlay(true)) { - 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(!panning) //mxd + for(int i = 0; i < Linedef.NUM_ARGS; i++) BuilderPlug.Me.RenderAssociations(renderer, association[i]); + if(!panning && (highlighted != null) && !highlighted.IsDisposed) BuilderPlug.Me.RenderReverseAssociations(renderer, highlightasso); //mxd if(selecting) RenderMultiSelection(); renderer.Finish(); } @@ -473,7 +475,7 @@ namespace CodeImp.DoomBuilder.BuilderModes if(selected.Count == 1) General.Map.Map.ClearSelectedLinedefs(); // Update entire display - General.Map.Renderer2D.Update3dFloorTagsList(); //mxd + General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd General.Interface.RedrawDisplay(); } } @@ -489,6 +491,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); + if(panning) return; //mxd. Skip all this jass while panning //mxd if(selectpressed && !editpressed && !selecting) { @@ -767,6 +770,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Update and redraw General.Map.IsChanged = true; General.Interface.RefreshInfo(); + General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd General.Interface.RedrawDisplay(); } } @@ -896,7 +900,7 @@ namespace CodeImp.DoomBuilder.BuilderModes OnMouseMove(e); // Redraw screen - General.Map.Renderer2D.Update3dFloorTagsList(); //mxd + //General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd General.Interface.RedrawDisplay(); } } diff --git a/Source/Plugins/BuilderModes/ClassicModes/MakeSectorMode.cs b/Source/Plugins/BuilderModes/ClassicModes/MakeSectorMode.cs index f6349746..28e23865 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/MakeSectorMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/MakeSectorMode.cs @@ -455,6 +455,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); + if(panning) return; //mxd. Skip all this jass while panning // Highlight the region Highlight((e.Button != MouseButtons.None)); diff --git a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs index 0d18fd32..efacffe6 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs @@ -481,7 +481,7 @@ namespace CodeImp.DoomBuilder.BuilderModes if((highlighted != null) && !highlighted.IsDisposed) { renderer.PlotSector(highlighted, General.Colors.Highlight); - BuilderPlug.Me.PlotReverseAssociations(renderer, highlightasso); + if(!panning) BuilderPlug.Me.PlotReverseAssociations(renderer, highlightasso); //mxd } renderer.Finish(); } @@ -497,7 +497,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Render selection if(renderer.StartOverlay(true)) { - if((highlighted != null) && !highlighted.IsDisposed) BuilderPlug.Me.RenderReverseAssociations(renderer, highlightasso); + if(!panning && highlighted != null && !highlighted.IsDisposed) BuilderPlug.Me.RenderReverseAssociations(renderer, highlightasso); //mxd if(selecting) RenderMultiSelection(); renderer.Finish(); } @@ -627,7 +627,9 @@ namespace CodeImp.DoomBuilder.BuilderModes General.Interface.OnEditFormValuesChanged += new EventHandler(sectorEditForm_OnValuesChanged); General.Interface.ShowEditSectors(selected); General.Interface.OnEditFormValuesChanged -= sectorEditForm_OnValuesChanged; - + + General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd + // When a single sector was selected, deselect it now if(selected.Count == 1) { @@ -649,7 +651,7 @@ namespace CodeImp.DoomBuilder.BuilderModes private void sectorEditForm_OnValuesChanged(object sender, EventArgs e) { // Update entire display General.Map.Map.Update(); - General.Map.Renderer2D.Update3dFloorTagsList(); + //General.Map.Renderer2D.UpdateExtraFloorFlag(); General.Interface.RedrawDisplay(); } @@ -657,6 +659,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); + if(panning) return; //mxd. Skip all this jass while panning //mxd if(selectpressed && !editpressed && !selecting) { @@ -1121,6 +1124,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Update and redraw General.Map.IsChanged = true; General.Interface.RefreshInfo(); + General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd General.Interface.RedrawDisplay(); } } @@ -1368,7 +1372,7 @@ namespace CodeImp.DoomBuilder.BuilderModes UpdateSelectedLabels(); // Redraw screen - General.Map.Renderer2D.Update3dFloorTagsList(); //mxd + //General.Map.Renderer2D.Update3dFloorIndicators(); //mxd General.Interface.RedrawDisplay(); } } diff --git a/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs index 147162be..44a5d0d9 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs @@ -147,8 +147,10 @@ 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); + if (!panning) { //mxd + 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(); } @@ -157,10 +159,11 @@ 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(!panning) //mxd + 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); + if(!panning) BuilderPlug.Me.RenderReverseAssociations(renderer, highlightasso); //mxd renderer.RenderThing(highlighted, General.Colors.Highlight, 1.0f); } @@ -442,6 +445,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); + if(panning) return; //mxd. Skip all this jass while panning //mxd if(selectpressed && !editpressed && !selecting) { diff --git a/Source/Plugins/BuilderModes/ClassicModes/VerticesMode.cs b/Source/Plugins/BuilderModes/ClassicModes/VerticesMode.cs index 0a76e773..6b3f4518 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/VerticesMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/VerticesMode.cs @@ -428,7 +428,7 @@ namespace CodeImp.DoomBuilder.BuilderModes private void vertexEditForm_OnValuesChanged(object sender, EventArgs e) { // Update entire display General.Map.Map.Update(); - General.Map.Renderer2D.Update3dFloorTagsList(); + //General.Map.Renderer2D.Update3dFloorIndicators(); General.Interface.RedrawDisplay(); } @@ -436,6 +436,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); + if(panning) return; //mxd. Skip all this jass while panning //mxd if(selectpressed && !editpressed && !selecting) { @@ -880,6 +881,7 @@ namespace CodeImp.DoomBuilder.BuilderModes OnMouseMove(e); // Redraw screen + General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd General.Interface.RedrawDisplay(); } diff --git a/Source/Plugins/BuilderModes/General/BuilderPlug.cs b/Source/Plugins/BuilderModes/General/BuilderPlug.cs index 6f6298c0..9228866f 100644 --- a/Source/Plugins/BuilderModes/General/BuilderPlug.cs +++ b/Source/Plugins/BuilderModes/General/BuilderPlug.cs @@ -467,7 +467,7 @@ namespace CodeImp.DoomBuilder.BuilderModes drawRectModeMenuItem.Enabled = true; drawEllipseModeMenuItem.Enabled = true; - General.Map.Renderer2D.Update3dFloorTagsList(); //mxd + General.Map.Renderer2D.UpdateExtraFloorFlag(); //mxd } // Map closed diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs index 14e39ee5..379a5816 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs @@ -197,15 +197,19 @@ namespace CodeImp.DoomBuilder.BuilderModes Vector3D pos = Thing.Position; if(Thing.Type == 9501) { - // This is a special thing that needs special positioning - SectorData sd = mode.GetSectorData(Thing.Sector); - pos.z = sd.Ceiling.sector.CeilHeight + Thing.Position.z; + if(Thing.Sector != null) { //mxd + // This is a special thing that needs special positioning + SectorData sd = mode.GetSectorData(Thing.Sector); + pos.z = sd.Ceiling.sector.CeilHeight + Thing.Position.z; + } } else if(Thing.Type == 9500) { - // This is a special thing that needs special positioning - SectorData sd = mode.GetSectorData(Thing.Sector); - pos.z = sd.Floor.sector.FloorHeight + Thing.Position.z; + if(Thing.Sector != null) { //mxd + // This is a special thing that needs special positioning + SectorData sd = mode.GetSectorData(Thing.Sector); + pos.z = sd.Floor.sector.FloorHeight + Thing.Position.z; + } } else if(info.AbsoluteZ) { diff --git a/Source/Plugins/TagExplorer/BuilderPlug.cs b/Source/Plugins/TagExplorer/BuilderPlug.cs index a86d6b87..6bd1af05 100644 --- a/Source/Plugins/TagExplorer/BuilderPlug.cs +++ b/Source/Plugins/TagExplorer/BuilderPlug.cs @@ -1,10 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Text; - -using CodeImp.DoomBuilder.Config; +using CodeImp.DoomBuilder.Config; using CodeImp.DoomBuilder.Controls; -using CodeImp.DoomBuilder.Editing; using CodeImp.DoomBuilder.Plugins; namespace CodeImp.DoomBuilder.TagExplorer