From f924470e8de88a2c34ab31e81e7bd192a1a83be2 Mon Sep 17 00:00:00 2001 From: Jarrod Doyle Date: Sun, 22 Dec 2024 08:50:45 +0000 Subject: [PATCH] Port LGS changes from lightmapper --- .../code/LGS/Database/Chunks/RendParams.cs | 6 ++- project/code/LGS/Database/Chunks/WorldRep.cs | 28 +++++++++++--- project/code/LGS/Database/File.cs | 2 + project/code/LGS/Database/ObjectHierarchy.cs | 2 + project/code/LGS/ResourcePathManager.cs | 38 ++++++++++--------- 5 files changed, 51 insertions(+), 25 deletions(-) diff --git a/project/code/LGS/Database/Chunks/RendParams.cs b/project/code/LGS/Database/Chunks/RendParams.cs index 5a43c79..a57ce4c 100644 --- a/project/code/LGS/Database/Chunks/RendParams.cs +++ b/project/code/LGS/Database/Chunks/RendParams.cs @@ -17,7 +17,7 @@ public class RendParams : IChunk public string palette; public Vector3 ambientLight; - public int useSunlight; + public bool useSunlight; public SunlightMode sunlightMode; public Vector3 sunlightDirection; public float sunlightHue; @@ -32,7 +32,8 @@ public class RendParams : IChunk { palette = reader.ReadNullString(16); ambientLight = reader.ReadVec3(); - useSunlight = reader.ReadInt32(); + useSunlight = reader.ReadBoolean(); + reader.ReadBytes(3); sunlightMode = (SunlightMode)reader.ReadUInt32(); sunlightDirection = reader.ReadVec3(); sunlightHue = reader.ReadSingle(); @@ -59,6 +60,7 @@ public class RendParams : IChunk writer.WriteNullString(palette, 16); writer.WriteVec3(ambientLight); writer.Write(useSunlight); + writer.Write(new byte[3]); writer.Write((uint)sunlightMode); writer.WriteVec3(sunlightDirection); writer.Write(sunlightHue); diff --git a/project/code/LGS/Database/Chunks/WorldRep.cs b/project/code/LGS/Database/Chunks/WorldRep.cs index 034bf5f..d14a9d1 100644 --- a/project/code/LGS/Database/Chunks/WorldRep.cs +++ b/project/code/LGS/Database/Chunks/WorldRep.cs @@ -246,12 +246,30 @@ public class WorldRep : IChunk // TODO: This ONLY works for rgba (bpp = 4)!!! public void AddLight(int layer, int x, int y, float r, float g, float b) { + ArgumentOutOfRangeException.ThrowIfLessThan(layer, 0, nameof(layer)); + ArgumentOutOfRangeException.ThrowIfGreaterThan(layer, Layers, nameof(layer)); + var idx = (x + y * Width) * Bpp; var pLayer = Pixels[layer]; - pLayer[idx] = (byte)Math.Clamp(pLayer[idx] + r, 0, 255); - pLayer[idx + 1] = (byte)Math.Clamp(pLayer[idx + 1] + g, 0, 255); - pLayer[idx + 2] = (byte)Math.Clamp(pLayer[idx + 2] + b, 0, 255); - pLayer[idx + 3] = 255; + switch (Bpp) + { + // 1bpp isn't really supported (does nd dromed even produce it?) + case 2: + var raw2 = pLayer[idx] + (pLayer[idx + 1] << 8); + var newR = (int)Math.Clamp((raw2 & 31) + r * 32f / 255f, 0, 31); + var newG = (int)Math.Clamp(((raw2 >> 5) & 31) + g * 32f / 255f, 0, 31); + var newB = (int)Math.Clamp(((raw2 >> 10) & 31) + b * 32f / 255f, 0, 31); + raw2 = newR + (newG << 5) + (newB << 10); + pLayer[idx] = (byte)(raw2 & 0xff); + pLayer[idx + 1] = (byte)((raw2 >> 8) & 0xff); + break; + case 4: + pLayer[idx] = (byte)Math.Clamp(pLayer[idx] + b, 0, 255); + pLayer[idx + 1] = (byte)Math.Clamp(pLayer[idx + 1] + g, 0, 255); + pLayer[idx + 2] = (byte)Math.Clamp(pLayer[idx + 2] + r, 0, 255); + pLayer[idx + 3] = 255; + break; + } _litLayers[layer] = true; } @@ -274,7 +292,7 @@ public class WorldRep : IChunk c /= ratio; } - AddLight(layer, x, y, c.Z, c.Y, c.X); + AddLight(layer, x, y, c.X, c.Y, c.Z); } public void Reset(Vector3 ambientLight, bool hdr) diff --git a/project/code/LGS/Database/File.cs b/project/code/LGS/Database/File.cs index 2b7b43d..9bcebc1 100644 --- a/project/code/LGS/Database/File.cs +++ b/project/code/LGS/Database/File.cs @@ -159,6 +159,8 @@ public class DbFile "P$Scale" => new PropertyChunk(), "P$RenderTyp" => new PropertyChunk(), "P$JointPos" => new PropertyChunk(), + "P$Immobile" => new PropertyChunk(), + "P$StatShad" => new PropertyChunk(), "P$OTxtRepr0" => new PropertyChunk(), "P$OTxtRepr1" => new PropertyChunk(), "P$OTxtRepr2" => new PropertyChunk(), diff --git a/project/code/LGS/Database/ObjectHierarchy.cs b/project/code/LGS/Database/ObjectHierarchy.cs index e8ae175..26715a9 100644 --- a/project/code/LGS/Database/ObjectHierarchy.cs +++ b/project/code/LGS/Database/ObjectHierarchy.cs @@ -94,6 +94,8 @@ public class ObjectHierarchy AddProp("P$Scale"); AddProp("P$RenderTyp"); AddProp("P$JointPos"); + AddProp("P$Immobile"); + AddProp("P$StatShad"); AddProp("P$OTxtRepr0"); AddProp("P$OTxtRepr1"); AddProp("P$OTxtRepr2"); diff --git a/project/code/LGS/ResourcePathManager.cs b/project/code/LGS/ResourcePathManager.cs index 6a27c77..d0657f7 100644 --- a/project/code/LGS/ResourcePathManager.cs +++ b/project/code/LGS/ResourcePathManager.cs @@ -151,38 +151,40 @@ public class ResourcePathManager throw new InvalidOperationException("Failed to find all installation config paths."); } - // Get the paths of the base Fam and Obj resources so we can extract them. + // We need to know where all the texture and object resources are var installCfgLines = File.ReadAllLines(configPaths[(int)ConfigFile.Install]); - FindConfigVar(installCfgLines, "resname_base", out var resPaths); - var baseFamPath = ""; - var baseObjPath = ""; + if (!FindConfigVar(installCfgLines, "resname_base", out var resPaths)) + { + throw new InvalidOperationException("Failed to find resnames in install config"); + } + + var zipPaths = new List(); foreach (var resPath in resPaths.Split('+')) { var dir = Path.Join(installPath, ConvertSeparator(resPath)); + if (!Directory.Exists(dir)) + { + continue; + } + foreach (var path in Directory.GetFiles(dir)) { var name = Path.GetFileName(path).ToLower(); - if (name == "fam.crf" && baseFamPath == "") + if (name is "fam.crf" or "obj.crf") { - baseFamPath = path; - } - else if (name == "obj.crf" && baseObjPath == "") - { - baseObjPath = path; + zipPaths.Add(path); } } } // Do the extraction bro - (string, string)[] resources = [("fam", baseFamPath), ("obj", baseObjPath)]; - foreach (var (extractName, zipPath) in resources) + // The path order is a priority order, so we don't want to overwrite any files when extracting + // TODO: Check if there's any problems caused by case sensitivity + foreach (var zipPath in zipPaths) { - var extractPath = Path.Join(_extractionPath, extractName); - if (Directory.Exists(extractPath)) - { - Directory.Delete(extractPath, true); - } - ZipFile.OpenRead(zipPath).ExtractToDirectory(extractPath); + var resType = Path.GetFileNameWithoutExtension(zipPath); + var extractPath = Path.Join(_extractionPath, resType); + ZipFile.OpenRead(zipPath).ExtractToDirectory(extractPath, false); } FindConfigVar(installCfgLines, "load_path", out var omsPath);