diff --git a/Build/SlimDX.dll b/Build/SlimDX.dll index ca05cbd716feae38ae43f2f25f5cb870ac574390..c02903f6e1326ca22b4663d9a187b5f290041acd 100755 Binary files a/Build/SlimDX.dll and b/Build/SlimDX.dll differ diff --git a/Build/Updater.ini b/Build/Updater.ini index 688eb2eaa2eb02afd5d6d5c16ff30cd48c09d2f8..fe4d499e58f216c92d86437a32e75c25ebe2dd02 100755 --- a/Build/Updater.ini +++ b/Build/Updater.ini @@ -1,4 +1,4 @@ URL http://devbuilds.drdteam.org/gzdbbf/ FileName Builder.exe -UpdateName GZDoom_Builder_Bugfix-r[REVNUM]-x64.7z -UpdaterName GZDB_Updater-x64.7z \ No newline at end of file +UpdateName GZDoom_Builder_Bugfix-r[REVNUM].7z +UpdaterName GZDB_Updater-x86.7z \ No newline at end of file diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index 6bcf4ad220cc481cdf5aace9e830a9912f936dc3..d3d921e66bfab64f5e2139acc153f83ba25001d4 100755 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -2287,6 +2287,24 @@ namespace CodeImp.DoomBuilder.Data } } } + + // This loads MODELDEF data from a specific file or lump name + private void LoadModeldefFromLocation(ModeldefParser parser, string location) + { + IEnumerable<TextResourceData> streams = currentreader.GetModeldefData(location); + foreach (TextResourceData data in streams) + { + // Parse this data + parser.Parse(data, false); + + //mxd. DECORATE lumps are interdepandable. Can't carry on... + if (parser.HasError) + { + parser.LogError(); + return; + } + } + } // This gets thing information by index public ThingTypeInfo GetThingInfo(int thingtype) @@ -2407,7 +2425,7 @@ namespace CodeImp.DoomBuilder.Data // Abort if no classnames are defined in DECORATE or game config... if(actorsbyclass.Count == 0) return; - ModeldefParser parser = new ModeldefParser(actorsbyclass); + ModeldefParser parser = new ModeldefParser(actorsbyclass) { OnInclude = LoadModeldefFromLocation }; foreach(DataReader dr in containers) { currentreader = dr; diff --git a/Source/Core/Data/DataReader.cs b/Source/Core/Data/DataReader.cs index df6264cb0cb9e1d8822c48e122bc6269dccd40e3..a435c7ab44cc6139cee949cee8f7324f4e1924d7 100755 --- a/Source/Core/Data/DataReader.cs +++ b/Source/Core/Data/DataReader.cs @@ -239,6 +239,9 @@ namespace CodeImp.DoomBuilder.Data // [ZZ] When implemented, this returns ZSCRIPT lumps public abstract IEnumerable<TextResourceData> GetZScriptData(string pname); + // [ZZ] When implemented, this returns MODELDEF lumps + public abstract IEnumerable<TextResourceData> GetModeldefData(string pname); + //mxd. When implemented, this returns MAPINFO lumps public abstract IEnumerable<TextResourceData> GetMapinfoData(); diff --git a/Source/Core/Data/PK3StructuredReader.cs b/Source/Core/Data/PK3StructuredReader.cs index dc48e7127169729cc84d67292956c21882970b06..0c584725a7f1e6330360f43fe861b8858e958a99 100755 --- a/Source/Core/Data/PK3StructuredReader.cs +++ b/Source/Core/Data/PK3StructuredReader.cs @@ -572,6 +572,50 @@ namespace CodeImp.DoomBuilder.Data #endregion + #region ================== MODELDEF + + // This finds and returns MODELDEF streams + public override IEnumerable<TextResourceData> GetModeldefData(string pname) + { + // Error when suspended + if (issuspended) throw new Exception("Data reader is suspended"); + + List<TextResourceData> result = new List<TextResourceData>(); + string[] allfilenames; + + // Find in root directory + string filename = Path.GetFileName(pname); + string pathname = Path.GetDirectoryName(pname); + + if (filename.IndexOf('.') > -1) + { + string fullname = Path.Combine(pathname, filename); + if (FileExists(fullname)) + { + allfilenames = new string[1]; + allfilenames[0] = Path.Combine(pathname, filename); + } + else + { + allfilenames = new string[0]; + General.ErrorLogger.Add(ErrorType.Warning, "Unable to load MODELDEF file \"" + fullname + "\""); + } + } + else + allfilenames = GetAllFilesWithTitle(pathname, filename, false); + + foreach (string foundfile in allfilenames) + result.Add(new TextResourceData(this, LoadFile(foundfile), foundfile, true)); + + // Find in any of the wad files + for (int i = wads.Count - 1; i >= 0; i--) + result.AddRange(wads[i].GetModeldefData(pname)); + + return result; + } + + #endregion + #region ================== VOXELDEF (mxd) //mxd. This returns the list of voxels, which can be used without VOXELDEF definition diff --git a/Source/Core/Data/WADReader.cs b/Source/Core/Data/WADReader.cs index ddee2c4488f4cf28ce4d3556d6d57388f0d8583c..cf7d2ae9fea1b3fe393b5087a45d09299f21c241 100755 --- a/Source/Core/Data/WADReader.cs +++ b/Source/Core/Data/WADReader.cs @@ -1047,6 +1047,20 @@ namespace CodeImp.DoomBuilder.Data return new List<TextResourceData> { result[result.Count - 1] }; } + // [ZZ] This finds and returns MODELDEF streams + public override IEnumerable<TextResourceData> GetModeldefData(string pname) + { + if (issuspended) throw new Exception("Data reader is suspended"); + List<TextResourceData> result = GetAllLumpsData(pname); //mxd + + //mxd. Return ALL DECORATE lumps + if (result.Count == 0 || string.Compare(pname, "MODELDEF", StringComparison.OrdinalIgnoreCase) == 0) + return result; + + //mxd. Return THE LAST include lump, because that's the way ZDoom seems to operate + return new List<TextResourceData> { result[result.Count - 1] }; + } + //mxd. Should be only one entry per wad public override IEnumerable<TextResourceData> GetMapinfoData() { diff --git a/Source/Core/Properties/AssemblyInfo.cs b/Source/Core/Properties/AssemblyInfo.cs index 205e95d0b3fdf381e8f1c3617d2b03dd777c79b3..700e47ddebacd282304d71c6194be525975f0fde 100755 --- a/Source/Core/Properties/AssemblyInfo.cs +++ b/Source/Core/Properties/AssemblyInfo.cs @@ -30,6 +30,6 @@ using CodeImp.DoomBuilder; // Build Number // Revision // -[assembly: AssemblyVersion("2.3.0.3028")] +[assembly: AssemblyVersion("2.3.0.3029")] [assembly: NeutralResourcesLanguageAttribute("en")] -[assembly: AssemblyHash("6768bc7")] +[assembly: AssemblyHash("3c433cf")] diff --git a/Source/Core/ZDoom/ModeldefParser.cs b/Source/Core/ZDoom/ModeldefParser.cs index 2549074af5d10c9182e9527c8cc1f7ef7be879e4..a799d8572ecaa18a8b53e2fbf9b46d1a7b98b6d9 100755 --- a/Source/Core/ZDoom/ModeldefParser.cs +++ b/Source/Core/ZDoom/ModeldefParser.cs @@ -7,6 +7,8 @@ using CodeImp.DoomBuilder.Data; using CodeImp.DoomBuilder.Geometry; using CodeImp.DoomBuilder.GZBuilder.Data; using SlimDX; +using System.IO; +using System.Globalization; #endregion @@ -14,16 +16,24 @@ namespace CodeImp.DoomBuilder.ZDoom { internal class ModeldefParser : ZDTextParser { - #region ================== Variables + public delegate void IncludeDelegate(ModeldefParser parser, string includefile); - private readonly Dictionary<string, int> actorsbyclass; + public IncludeDelegate OnInclude; + + + #region ================== Variables + + private readonly Dictionary<string, int> actorsbyclass; private Dictionary<string, ModelData> entries; //classname, entry + //mxd. Includes tracking + private HashSet<string> parsedlumps; - #endregion - #region ================== Properties + #endregion + + #region ================== Properties - internal override ScriptType ScriptType { get { return ScriptType.MODELDEF; } } + internal override ScriptType ScriptType { get { return ScriptType.MODELDEF; } } internal Dictionary<string, ModelData> Entries { get { return entries; } } #endregion @@ -34,6 +44,7 @@ namespace CodeImp.DoomBuilder.ZDoom { this.actorsbyclass = actorsbyclass; this.entries = new Dictionary<string, ModelData>(StringComparer.OrdinalIgnoreCase); + this.parsedlumps = new HashSet<string>(); } #endregion @@ -53,11 +64,88 @@ namespace CodeImp.DoomBuilder.ZDoom // Cannot process? if(!base.Parse(data, clearerrors)) return false; - // Continue until at the end of the stream - while(SkipWhitespace(true)) + // Keep local data + Stream localstream = datastream; + string localsourcename = sourcename; + BinaryReader localreader = datareader; + DataLocation locallocation = datalocation; //mxd + string localtextresourcepath = textresourcepath; //mxd + + // Continue until at the end of the stream + while (SkipWhitespace(true)) { string token = ReadToken(); - if(string.IsNullOrEmpty(token) || token.ToLowerInvariant() != "model") continue; + + if(string.IsNullOrEmpty(token) || token.ToLowerInvariant() != "model") + { + if (token != null && token.ToLowerInvariant() == "#include") + { + //INFO: ZDoom DECORATE include paths can't be relative ("../actor.txt") + //or absolute ("d:/project/actor.txt") + //or have backward slashes ("info\actor.txt") + //include paths are relative to the first parsed entry, not the current one + //also include paths may or may not be quoted + SkipWhitespace(true); + string filename = StripQuotes(ReadToken(false)); //mxd. Don't skip newline + + //mxd. Sanity checks + if (string.IsNullOrEmpty(filename)) + { + ReportError("Expected file name to include"); + return false; + } + + //mxd. Check invalid path chars + if (!CheckInvalidPathChars(filename)) return false; + + //mxd. Absolute paths are not supported... + if (Path.IsPathRooted(filename)) + { + ReportError("Absolute include paths are not supported by ZDoom"); + return false; + } + + //mxd. Relative paths are not supported + if (filename.StartsWith(RELATIVE_PATH_MARKER) || filename.StartsWith(CURRENT_FOLDER_PATH_MARKER) || + filename.StartsWith(ALT_RELATIVE_PATH_MARKER) || filename.StartsWith(ALT_CURRENT_FOLDER_PATH_MARKER)) + { + ReportError("Relative include paths are not supported by ZDoom"); + return false; + } + + //mxd. Backward slashes are not supported + if (filename.Contains(Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture))) + { + ReportError("Only forward slashes are supported by ZDoom"); + return false; + } + + //mxd. Already parsed? + if (parsedlumps.Contains(filename)) + { + ReportError("Already parsed \"" + filename + "\". Check your include directives"); + return false; + } + + //mxd. Add to collection + parsedlumps.Add(filename); + + // Callback to parse this file now + if (OnInclude != null) OnInclude(this, filename); + + //mxd. Bail out on error + if (this.HasError) return false; + + // Set our buffers back to continue parsing + datastream = localstream; + datareader = localreader; + sourcename = localsourcename; + datalocation = locallocation; //mxd + textresourcepath = localtextresourcepath; //mxd + } + + continue; + } // Find classname SkipWhitespace(true); diff --git a/Source/Plugins/BuilderModes/Properties/AssemblyInfo.cs b/Source/Plugins/BuilderModes/Properties/AssemblyInfo.cs index f701399020daed201a069f65e9f1095e7e677da1..a2e2fca8bd0425f782c6b8817dd54591a55f223e 100755 --- a/Source/Plugins/BuilderModes/Properties/AssemblyInfo.cs +++ b/Source/Plugins/BuilderModes/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Resources; // Build Number // Revision // -[assembly: AssemblyVersion("2.3.0.3028")] +[assembly: AssemblyVersion("2.3.0.3029")] [assembly: NeutralResourcesLanguageAttribute("en")] diff --git a/Source/Plugins/StairSectorBuilder/StairSectorBuilder.csproj b/Source/Plugins/StairSectorBuilder/StairSectorBuilder.csproj index af0dcf67164dd2ba06197821aff7c5596b98c7e2..056ccfa87beda040287805c36f63e260bc5f8902 100755 --- a/Source/Plugins/StairSectorBuilder/StairSectorBuilder.csproj +++ b/Source/Plugins/StairSectorBuilder/StairSectorBuilder.csproj @@ -133,6 +133,7 @@ <ProjectReference Include="..\..\Core\Builder.csproj"> <Project>{818b3d10-f791-4c3f-9af5-bb2d0079b63c}</Project> <Name>Builder</Name> + <Private>False</Private> </ProjectReference> </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />