diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj index 2e6f5825..fc431a3e 100644 --- a/Source/Core/Builder.csproj +++ b/Source/Core/Builder.csproj @@ -623,6 +623,8 @@ + + diff --git a/Source/Core/BuilderMono.csproj b/Source/Core/BuilderMono.csproj index a29e6480..46104588 100644 --- a/Source/Core/BuilderMono.csproj +++ b/Source/Core/BuilderMono.csproj @@ -615,6 +615,8 @@ + + diff --git a/Source/Core/Config/ScriptConfiguration.cs b/Source/Core/Config/ScriptConfiguration.cs index 763c8657..999c0ab7 100755 --- a/Source/Core/Config/ScriptConfiguration.cs +++ b/Source/Core/Config/ScriptConfiguration.cs @@ -55,6 +55,7 @@ namespace CodeImp.DoomBuilder.Config ZSCRIPT, DECALDEF, DEHACKED, + IWADINFO, } public class ScriptConfiguration : IComparable diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index 80b9f70a..bdcb7d7a 100755 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -3071,7 +3071,7 @@ namespace CodeImp.DoomBuilder.Data #region ================== Tools - // This finds the first IWAD resource + // This finds the first IWAD or IPK3 resource // Returns false when not found public bool FindFirstIWAD(out DataLocation result) { @@ -3090,6 +3090,15 @@ namespace CodeImp.DoomBuilder.Data return true; } } + else if(dr is PK3Reader) + { + PK3Reader pk3r = dr as PK3Reader; + if(pk3r.GetIWadInfos().Count == 1) + { + result = pk3r.Location; + return true; + } + } } // No IWAD found diff --git a/Source/Core/Data/DataReader.cs b/Source/Core/Data/DataReader.cs index c8b573ba..7bef45e9 100755 --- a/Source/Core/Data/DataReader.cs +++ b/Source/Core/Data/DataReader.cs @@ -254,6 +254,9 @@ namespace CodeImp.DoomBuilder.Data //mxd. When implemented, this returns the voxel lump public abstract Stream GetVoxelData(string name, ref string voxellocation); + // When implemented, this returns the list of IWAD infos + public abstract List GetIWadInfos(); + #endregion #region ================== Load/Save (mxd) diff --git a/Source/Core/Data/PK3StructuredReader.cs b/Source/Core/Data/PK3StructuredReader.cs index 2e30dc5f..c932e976 100755 --- a/Source/Core/Data/PK3StructuredReader.cs +++ b/Source/Core/Data/PK3StructuredReader.cs @@ -512,6 +512,29 @@ namespace CodeImp.DoomBuilder.Data #endregion + #region ================== IWADINFO + + public override List GetIWadInfos() + { + IWadInfoParser parser = new IWadInfoParser(); + + // At least one of IWADINFO should be in the root folder + List files = new List(); + + // Can be several entries + files.AddRange(GetAllFilesWhichTitleStartsWith("", "IWADINFO", false)); + + foreach(string s in files) + { + parser.Parse(new TextResourceData(this, LoadFile(s), s, true), false); + if (parser.HasError) parser.LogError(); + } + + return parser.IWads; + } + + #endregion + #region ================== DECORATE // This finds and returns DECORATE streams diff --git a/Source/Core/Data/WADReader.cs b/Source/Core/Data/WADReader.cs index 691954d2..a0e60b36 100755 --- a/Source/Core/Data/WADReader.cs +++ b/Source/Core/Data/WADReader.cs @@ -1018,6 +1018,23 @@ namespace CodeImp.DoomBuilder.Data return GetAllLumpsData("DEHACKED"); } + #region ================== IWADINFO + + public override List GetIWadInfos() + { + IWadInfoParser parser = new IWadInfoParser(); + + foreach (TextResourceData trd in GetAllLumpsData("IWADINFO")) + { + parser.Parse(trd, false); + if (parser.HasError) parser.LogError(); + } + + return parser.IWads; + } + + #endregion + // This finds and returns DECORATE streams public override IEnumerable GetDecorateData(string pname) { diff --git a/Source/Core/General/Launcher.cs b/Source/Core/General/Launcher.cs index 7ea6b076..310fdaa9 100755 --- a/Source/Core/General/Launcher.cs +++ b/Source/Core/General/Launcher.cs @@ -158,7 +158,7 @@ namespace CodeImp.DoomBuilder foreach(DataLocation dl in locations) { // Location not the IWAD file? - if((dl.type != DataLocation.RESOURCE_WAD) || (dl.location != iwadloc.location)) + if((dl.location != iwadloc.location)) { // Location not included? if(!dl.notfortesting) diff --git a/Source/Core/ZDoom/IWadInfo.cs b/Source/Core/ZDoom/IWadInfo.cs new file mode 100644 index 00000000..9e6b20ae --- /dev/null +++ b/Source/Core/ZDoom/IWadInfo.cs @@ -0,0 +1,44 @@ +#region ================== Copyright (c) 2021 Boris Iwanski + +/* + * This program is free software: you can redistribute it and/or modify + * + * it under the terms of the GNU General Public License as published by + * + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program.If not, see. + */ + +#endregion + +namespace CodeImp.DoomBuilder.ZDoom +{ + class IWadInfo + { + #region ================== Variables + + private string autoname; + + #endregion + + #region ================== Properties + + public string AutoName { get { return autoname; } internal set { autoname = value; } } + + #endregion + + #region ================== Constructors + + #endregion + } +} diff --git a/Source/Core/ZDoom/IWadInfoParser.cs b/Source/Core/ZDoom/IWadInfoParser.cs new file mode 100644 index 00000000..ed3fe91c --- /dev/null +++ b/Source/Core/ZDoom/IWadInfoParser.cs @@ -0,0 +1,181 @@ +#region ================== Copyright (c) 2021 Boris Iwanski + +/* + * This program is free software: you can redistribute it and/or modify + * + * it under the terms of the GNU General Public License as published by + * + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program.If not, see. + */ + +#endregion + +#region ================== Namespaces + +using System.Collections.Generic; +using CodeImp.DoomBuilder.Config; +using CodeImp.DoomBuilder.Data; + +#endregion + +namespace CodeImp.DoomBuilder.ZDoom +{ + class IWadInfoParser : ZDTextParser + { + #region ================== Variables + + private List iwads; + + #endregion + + #region ================== Properties + + internal override ScriptType ScriptType { get { return ScriptType.IWADINFO; } } + public List IWads { get { return iwads; } } + + #endregion + + #region ================== Constructors + + public IWadInfoParser() + { + iwads = new List(); + + whitespace = "\n \t\r\u00A0"; + specialtokens = ",{}=\n"; + } + + #endregion + + #region ================== Methods + + /// + /// Parses DECALDEF data + /// + /// The data to parse + /// If errors should be cleared + /// true if paring worked, otherwise false + public override bool Parse(TextResourceData data, bool clearerrors) + { + if (!AddTextResource(data)) + { + if (clearerrors) ClearError(); + return true; + } + + // Cannot process? + if (!base.Parse(data, clearerrors)) return false; + + while (SkipWhitespace(true)) + { + string token = ReadToken().ToLowerInvariant(); + if (string.IsNullOrEmpty(token)) continue; + + switch (token) + { + case "iwad": + ParseIWad(); + break; + default: + SkipStructure(); + break; + } + } + + return true; + } + + /// + /// Gets a pair of a key and multiple values. + /// The key value pair looks like this: + /// key = value1 [, value2 [, value3 [...] ] ] + /// + /// The key + /// The list of values + /// True if a pair could be parsed, false otherwise + private bool GetKeyValuesPair(out string key, out List values) + { + + string token; + + values = new List(); + + SkipWhitespace(true); + + key = ReadToken().ToLowerInvariant(); + + SkipWhitespace(true); + + token = ReadToken().ToLowerInvariant(); + + if(token != "=") + { + ReportError("Expected \"=\", but got \"" + token + "\""); + return false; + } + + // Get all values + do + { + SkipWhitespace(true); + token = ReadToken(); + values.Add(token); + } while (NextTokenIs(",", false)); + + return true; + } + + /// + /// Parses a Iwad block. + /// + /// True if parsing succeeded, false if it didn't + private bool ParseIWad() + { + if(!NextTokenIs("{", false)) + { + ReportError("Expected opening brace"); + return false; + } + + IWadInfo iwad = new IWadInfo(); + + while(SkipWhitespace(true)) + { + string key; + List values; + + // If we encounter a closing swirly bracke the end of the block is reached + if(NextTokenIs("}", false)) + { + iwads.Add(iwad); + return true; + } + + if (!GetKeyValuesPair(out key, out values)) + return false; + + switch(key) + { + case "autoname": + iwad.AutoName = values[0]; + break; + } + } + + return false; + } + + #endregion + } +}