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
}
}