Port LGS changes from lightmapper

This commit is contained in:
Jarrod Doyle 2024-12-22 08:50:45 +00:00
parent 7c38c876de
commit f924470e8d
Signed by: Jayrude
GPG Key ID: 38B57B16E7C0ADF7
5 changed files with 51 additions and 25 deletions

View File

@ -17,7 +17,7 @@ public class RendParams : IChunk
public string palette; public string palette;
public Vector3 ambientLight; public Vector3 ambientLight;
public int useSunlight; public bool useSunlight;
public SunlightMode sunlightMode; public SunlightMode sunlightMode;
public Vector3 sunlightDirection; public Vector3 sunlightDirection;
public float sunlightHue; public float sunlightHue;
@ -32,7 +32,8 @@ public class RendParams : IChunk
{ {
palette = reader.ReadNullString(16); palette = reader.ReadNullString(16);
ambientLight = reader.ReadVec3(); ambientLight = reader.ReadVec3();
useSunlight = reader.ReadInt32(); useSunlight = reader.ReadBoolean();
reader.ReadBytes(3);
sunlightMode = (SunlightMode)reader.ReadUInt32(); sunlightMode = (SunlightMode)reader.ReadUInt32();
sunlightDirection = reader.ReadVec3(); sunlightDirection = reader.ReadVec3();
sunlightHue = reader.ReadSingle(); sunlightHue = reader.ReadSingle();
@ -59,6 +60,7 @@ public class RendParams : IChunk
writer.WriteNullString(palette, 16); writer.WriteNullString(palette, 16);
writer.WriteVec3(ambientLight); writer.WriteVec3(ambientLight);
writer.Write(useSunlight); writer.Write(useSunlight);
writer.Write(new byte[3]);
writer.Write((uint)sunlightMode); writer.Write((uint)sunlightMode);
writer.WriteVec3(sunlightDirection); writer.WriteVec3(sunlightDirection);
writer.Write(sunlightHue); writer.Write(sunlightHue);

View File

@ -246,12 +246,30 @@ public class WorldRep : IChunk
// TODO: This ONLY works for rgba (bpp = 4)!!! // TODO: This ONLY works for rgba (bpp = 4)!!!
public void AddLight(int layer, int x, int y, float r, float g, float b) 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 idx = (x + y * Width) * Bpp;
var pLayer = Pixels[layer]; var pLayer = Pixels[layer];
pLayer[idx] = (byte)Math.Clamp(pLayer[idx] + r, 0, 255); switch (Bpp)
pLayer[idx + 1] = (byte)Math.Clamp(pLayer[idx + 1] + g, 0, 255); {
pLayer[idx + 2] = (byte)Math.Clamp(pLayer[idx + 2] + b, 0, 255); // 1bpp isn't really supported (does nd dromed even produce it?)
pLayer[idx + 3] = 255; 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; _litLayers[layer] = true;
} }
@ -274,7 +292,7 @@ public class WorldRep : IChunk
c /= ratio; 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) public void Reset(Vector3 ambientLight, bool hdr)

View File

@ -159,6 +159,8 @@ public class DbFile
"P$Scale" => new PropertyChunk<PropVector>(), "P$Scale" => new PropertyChunk<PropVector>(),
"P$RenderTyp" => new PropertyChunk<PropRenderType>(), "P$RenderTyp" => new PropertyChunk<PropRenderType>(),
"P$JointPos" => new PropertyChunk<PropJointPos>(), "P$JointPos" => new PropertyChunk<PropJointPos>(),
"P$Immobile" => new PropertyChunk<PropBool>(),
"P$StatShad" => new PropertyChunk<PropBool>(),
"P$OTxtRepr0" => new PropertyChunk<PropString>(), "P$OTxtRepr0" => new PropertyChunk<PropString>(),
"P$OTxtRepr1" => new PropertyChunk<PropString>(), "P$OTxtRepr1" => new PropertyChunk<PropString>(),
"P$OTxtRepr2" => new PropertyChunk<PropString>(), "P$OTxtRepr2" => new PropertyChunk<PropString>(),

View File

@ -94,6 +94,8 @@ public class ObjectHierarchy
AddProp<PropVector>("P$Scale"); AddProp<PropVector>("P$Scale");
AddProp<PropRenderType>("P$RenderTyp"); AddProp<PropRenderType>("P$RenderTyp");
AddProp<PropJointPos>("P$JointPos"); AddProp<PropJointPos>("P$JointPos");
AddProp<PropBool>("P$Immobile");
AddProp<PropBool>("P$StatShad");
AddProp<PropString>("P$OTxtRepr0"); AddProp<PropString>("P$OTxtRepr0");
AddProp<PropString>("P$OTxtRepr1"); AddProp<PropString>("P$OTxtRepr1");
AddProp<PropString>("P$OTxtRepr2"); AddProp<PropString>("P$OTxtRepr2");

View File

@ -151,38 +151,40 @@ public class ResourcePathManager
throw new InvalidOperationException("Failed to find all installation config paths."); 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]); var installCfgLines = File.ReadAllLines(configPaths[(int)ConfigFile.Install]);
FindConfigVar(installCfgLines, "resname_base", out var resPaths); if (!FindConfigVar(installCfgLines, "resname_base", out var resPaths))
var baseFamPath = ""; {
var baseObjPath = ""; throw new InvalidOperationException("Failed to find resnames in install config");
}
var zipPaths = new List<string>();
foreach (var resPath in resPaths.Split('+')) foreach (var resPath in resPaths.Split('+'))
{ {
var dir = Path.Join(installPath, ConvertSeparator(resPath)); var dir = Path.Join(installPath, ConvertSeparator(resPath));
if (!Directory.Exists(dir))
{
continue;
}
foreach (var path in Directory.GetFiles(dir)) foreach (var path in Directory.GetFiles(dir))
{ {
var name = Path.GetFileName(path).ToLower(); var name = Path.GetFileName(path).ToLower();
if (name == "fam.crf" && baseFamPath == "") if (name is "fam.crf" or "obj.crf")
{ {
baseFamPath = path; zipPaths.Add(path);
}
else if (name == "obj.crf" && baseObjPath == "")
{
baseObjPath = path;
} }
} }
} }
// Do the extraction bro // Do the extraction bro
(string, string)[] resources = [("fam", baseFamPath), ("obj", baseObjPath)]; // The path order is a priority order, so we don't want to overwrite any files when extracting
foreach (var (extractName, zipPath) in resources) // TODO: Check if there's any problems caused by case sensitivity
foreach (var zipPath in zipPaths)
{ {
var extractPath = Path.Join(_extractionPath, extractName); var resType = Path.GetFileNameWithoutExtension(zipPath);
if (Directory.Exists(extractPath)) var extractPath = Path.Join(_extractionPath, resType);
{ ZipFile.OpenRead(zipPath).ExtractToDirectory(extractPath, false);
Directory.Delete(extractPath, true);
}
ZipFile.OpenRead(zipPath).ExtractToDirectory(extractPath);
} }
FindConfigVar(installCfgLines, "load_path", out var omsPath); FindConfigVar(installCfgLines, "load_path", out var omsPath);