diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj index a26ef5c9..1746a388 100644 --- a/Source/Core/Builder.csproj +++ b/Source/Core/Builder.csproj @@ -312,6 +312,7 @@ + diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index 215aa094..7f148423 100755 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -471,6 +471,11 @@ namespace CodeImp.DoomBuilder.Data LoadInternalSprites(); LoadInternalTextures(); //mxd + // Load SRB2 map information from parsed level headers + string mapname = General.Map.Options.LevelName.ToLowerInvariant(); + if (soc.MapHeaders.ContainsKey(mapname)) + mapinfo = soc.MapHeaders[mapname]; + //mxd. Load more stuff LoadReverbs(); LoadSndSeq(); @@ -1866,7 +1871,6 @@ namespace CodeImp.DoomBuilder.Data data.Stream.Seek(0, SeekOrigin.Begin); lua.Parse(data, true); - //mxd. DECORATE lumps are interdepandable. Can't carry on... if (lua.HasError) { lua.LogError(); @@ -1882,7 +1886,7 @@ namespace CodeImp.DoomBuilder.Data lua.ClearActors(); } - // sphere: This loads things from SRB2 Lua files. + // sphere: This loads things and level headers from SRB2 SOC files. private void LoadSOCThings() { // Create new parser @@ -1900,7 +1904,6 @@ namespace CodeImp.DoomBuilder.Data data.Stream.Seek(0, SeekOrigin.Begin); soc.Parse(data, true); - //mxd. DECORATE lumps are interdepandable. Can't carry on... if (soc.HasError) { soc.LogError(); @@ -1984,7 +1987,7 @@ namespace CodeImp.DoomBuilder.Data ThingCategory cat = GetThingCategory(null, thingcategories, GetCategoryInfo(actor)); //mxd // Add new thing - ThingTypeInfo t = new ThingTypeInfo(cat, actor); ; + ThingTypeInfo t = new ThingTypeInfo(cat, actor); cat.AddThing(t); thingtypes.Add(t.Index, t); diff --git a/Source/Core/SRB2/SOCLevelHeader.cs b/Source/Core/SRB2/SOCLevelHeader.cs new file mode 100644 index 00000000..47886702 --- /dev/null +++ b/Source/Core/SRB2/SOCLevelHeader.cs @@ -0,0 +1,87 @@ +using CodeImp.DoomBuilder.Config; +using CodeImp.DoomBuilder.Data; +using CodeImp.DoomBuilder.GZBuilder.Data; +using CodeImp.DoomBuilder.Types; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace CodeImp.DoomBuilder.ZDoom +{ + + public sealed class SOCLevelHeader + { + + #region ================== Variables + + private MapInfo mapinfo; + + #endregion + + #region ================== Properties + + public MapInfo MapInfo { get { return mapinfo; } } + + #endregion + + #region ================== SOC level header parsing + + internal SOCLevelHeader(ZDTextParser zdparser) + { + mapinfo = new MapInfo(); + string levelname = "Unnamed map"; + int actnum = 0; + bool nozone = false; + + SOCParser parser = (SOCParser)zdparser; + + // Now parse the contents of actor structure + string line = parser.ReadLine(); + while (line != null) + { + line = parser.ReadLine(); + if (string.IsNullOrEmpty(line) || line.StartsWith("\n")) break; + if (line.StartsWith("#")) continue; + + line = line.Split(new char[] { '#' })[0]; + + string[] tokens = line.Split(new char[] { '=' }); + if (tokens.Length != 2) + { + parser.ReportError("Invalid line"); + return; + } + + tokens[0] = tokens[0].Trim().ToLowerInvariant(); + tokens[1] = tokens[1].Trim(); + + //mxd. Translate scale to xscale and yscale + switch (tokens[0]) + { + case "levelname": + levelname = tokens[1]; + break; + case "act": + actnum = int.Parse(tokens[1]); + break; + case "nozone": + string value = tokens[1].ToLowerInvariant(); + nozone = (value.StartsWith("t") || value.StartsWith("y")); + break; + case "skynum": + mapinfo.Sky1 = "SKY" + tokens[1]; + break; + default: + break; + } + + } + + mapinfo.Title = levelname + (nozone ? "" : " Zone") + (actnum > 0 ? ", Act " + actnum : ""); + } + + #endregion + } +} diff --git a/Source/Core/SRB2/SOCMobjStructure.cs b/Source/Core/SRB2/SOCMobjStructure.cs index 68627a1e..3f8065de 100644 --- a/Source/Core/SRB2/SOCMobjStructure.cs +++ b/Source/Core/SRB2/SOCMobjStructure.cs @@ -12,7 +12,7 @@ namespace CodeImp.DoomBuilder.ZDoom public sealed class SOCMobjStructure : ActorStructure { - #region ================== SOC Actor Structure parsing + #region ================== SOC Mobj Structure parsing internal SOCMobjStructure(ZDTextParser zdparser, string objname) { diff --git a/Source/Core/SRB2/SOCParser.cs b/Source/Core/SRB2/SOCParser.cs index b4103f98..ea03d0d4 100644 --- a/Source/Core/SRB2/SOCParser.cs +++ b/Source/Core/SRB2/SOCParser.cs @@ -19,10 +19,9 @@ using System; using System.Collections.Generic; using System.Globalization; -using System.IO; using CodeImp.DoomBuilder.Config; using CodeImp.DoomBuilder.Data; -using CodeImp.DoomBuilder.Types; +using CodeImp.DoomBuilder.GZBuilder.Data; #endregion @@ -49,6 +48,7 @@ namespace CodeImp.DoomBuilder.ZDoom // SRB2 mobjs private Dictionary mobjs; + private Dictionary mapheaders; //mxd. Includes tracking private HashSet parsedlumps; @@ -67,6 +67,7 @@ namespace CodeImp.DoomBuilder.ZDoom /// All mobjs that are supported by the current game. /// public ICollection Mobjs { get { return mobjs.Values; } } + public Dictionary MapHeaders { get { return mapheaders; } } #endregion @@ -87,7 +88,7 @@ namespace CodeImp.DoomBuilder.ZDoom public void Dispose() { mobjs = null; - + mapheaders = null; isdisposed = true; } @@ -124,9 +125,6 @@ namespace CodeImp.DoomBuilder.ZDoom if (!string.IsNullOrEmpty(token)) { - string objname = null; - //General.WriteLogLine("token = " + token); - token = token.ToLowerInvariant(); // SOC object @@ -136,11 +134,9 @@ namespace CodeImp.DoomBuilder.ZDoom token = ReadToken(); if (!token.ToUpper().StartsWith("MT_")) - { continue; - } - objname = token; + string objname = token; // Read actor structure ActorStructure mobj = new SOCMobjStructure(this, objname); @@ -154,8 +150,15 @@ namespace CodeImp.DoomBuilder.ZDoom SkipWhitespace(true, true); token = ReadToken(); - if (!(token.Length > 2)) - General.WriteLogLine("Map token: MAP" + token); + string mapname = GetMapName(token); + + if (mapname == null) + continue; + + SOCLevelHeader levelheader = new SOCLevelHeader(this); + if (this.HasError) return false; + + mapheaders[mapname.ToLowerInvariant()] = levelheader.MapInfo; } } } @@ -178,9 +181,45 @@ namespace CodeImp.DoomBuilder.ZDoom { // Initialize mobjs = new Dictionary(); + mapheaders = new Dictionary(); parsedlumps = new HashSet(StringComparer.OrdinalIgnoreCase); //mxd } + private string GetMapName(string number) + { + if (int.TryParse(number, NumberStyles.Integer, CultureInfo.InvariantCulture, out int n)) + return ConvertToExtendedMapNum(n); + else + { + if (number.Length != 2 || number[0] < 'A' || number[0] > 'Z' || !((number[1] >= '0' && number[1] <= '9') || (number[1] >= 'A' && number[1] <= 'Z'))) + { + //ReportError("Invalid level number"); + return null; + } + return "MAP" + number; + } + + } + private string ConvertToExtendedMapNum(int n) + { + if (n <= 0 || n > 1035) + { + //ReportError("Invalid level number"); + return null; + } + if (n < 10) + return "MAP0" + n; + if (n < 100) + return "MAP" + n.ToString(); + + int x = n - 100; + int p = x / 36; + int q = x % 36; + char a = (char)('A' + p); + char b = (q < 10) ? (char)('0' + q) : (char)('A' + q - 10); + return "MAP" + String.Concat(a, b); + } + #endregion } }