Additional logging around initialisation
This commit is contained in:
parent
0136dc1141
commit
9bf80b1b5f
|
@ -1,5 +1,6 @@
|
|||
using System.Text;
|
||||
using KeepersCompound.LGS.Database.Chunks;
|
||||
using Serilog;
|
||||
|
||||
namespace KeepersCompound.LGS.Database;
|
||||
|
||||
|
@ -84,8 +85,13 @@ public class DbFile
|
|||
|
||||
public DbFile(string filename)
|
||||
{
|
||||
// TODO: Throw rather than return
|
||||
if (!File.Exists(filename)) return;
|
||||
Log.Information("Loading DbFile: {Path}", filename);
|
||||
|
||||
if (!File.Exists(filename))
|
||||
{
|
||||
Log.Error("Failed to load DbFile. File does not exist.");
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
|
||||
using MemoryStream stream = new(File.ReadAllBytes(filename));
|
||||
using BinaryReader reader = new(stream, Encoding.UTF8, false);
|
||||
|
@ -105,6 +111,8 @@ public class DbFile
|
|||
|
||||
public void Save(string filename)
|
||||
{
|
||||
Log.Information("Saving DbFile: {Path}", filename);
|
||||
|
||||
using var stream = File.Open(filename, FileMode.Create);
|
||||
using var writer = new BinaryWriter(stream, Encoding.UTF8, false);
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.IO.Compression;
|
||||
using Serilog;
|
||||
|
||||
namespace KeepersCompound.LGS;
|
||||
|
||||
|
@ -77,33 +78,41 @@ public class ResourcePathManager
|
|||
}
|
||||
}
|
||||
|
||||
foreach (var (name, path) in GetTexturePaths(resPath))
|
||||
var texPaths = GetTexturePaths(resPath);
|
||||
var objPaths = GetObjectPaths(resPath);
|
||||
var objTexPaths = GetObjectTexturePaths(resPath);
|
||||
Log.Information("Found {TexCount} textures, {ObjCount} objects, {ObjTexCount} object textures for campaign: {CampaignName}",
|
||||
texPaths.Count, objPaths.Count, objTexPaths.Count, name);
|
||||
|
||||
foreach (var (resName, path) in texPaths)
|
||||
{
|
||||
_texturePathMap[name] = path;
|
||||
_texturePathMap[resName] = path;
|
||||
}
|
||||
foreach (var (name, path) in GetObjectPaths(resPath))
|
||||
foreach (var (resName, path) in objPaths)
|
||||
{
|
||||
_objectPathMap[name] = path;
|
||||
_objectPathMap[resName] = path;
|
||||
}
|
||||
foreach (var (name, path) in GetObjectTexturePaths(resPath))
|
||||
foreach (var (resName, path) in objTexPaths)
|
||||
{
|
||||
_objectTexturePathMap[name] = path;
|
||||
_objectTexturePathMap[resName] = path;
|
||||
}
|
||||
|
||||
initialised = true;
|
||||
}
|
||||
|
||||
public void Initialise(string misPath, string resPath, CampaignResources parent)
|
||||
{
|
||||
foreach (var (name, path) in parent._texturePathMap)
|
||||
foreach (var (resName, path) in parent._texturePathMap)
|
||||
{
|
||||
_texturePathMap[name] = path;
|
||||
_texturePathMap[resName] = path;
|
||||
}
|
||||
foreach (var (name, path) in parent._objectPathMap)
|
||||
foreach (var (resName, path) in parent._objectPathMap)
|
||||
{
|
||||
_objectPathMap[name] = path;
|
||||
_objectPathMap[resName] = path;
|
||||
}
|
||||
foreach (var (name, path) in parent._objectTexturePathMap)
|
||||
foreach (var (resName, path) in parent._objectTexturePathMap)
|
||||
{
|
||||
_objectTexturePathMap[name] = path;
|
||||
_objectTexturePathMap[resName] = path;
|
||||
}
|
||||
|
||||
Initialise(misPath, resPath);
|
||||
|
@ -126,7 +135,7 @@ public class ResourcePathManager
|
|||
return path.Replace('\\', '/');
|
||||
}
|
||||
|
||||
public void Init(string installPath)
|
||||
public bool TryInit(string installPath)
|
||||
{
|
||||
// TODO:
|
||||
// - Determine if folder is a thief install
|
||||
|
@ -136,22 +145,25 @@ public class ResourcePathManager
|
|||
// - Initialise OM campaign resource paths
|
||||
// - Lazy load FM campaign resource paths (that inherit OM resources)
|
||||
|
||||
Log.Information("Initialising path manager");
|
||||
|
||||
if (!DirContainsThiefExe(installPath))
|
||||
{
|
||||
throw new ArgumentException($"No Thief installation found at {installPath}", nameof(installPath));
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Should these paths be stored?
|
||||
if (!TryGetConfigPaths(installPath, out var configPaths))
|
||||
{
|
||||
throw new InvalidOperationException("Failed to find all installation config paths.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// We need to know where all the texture and object resources are
|
||||
var installCfgLines = File.ReadAllLines(configPaths[(int)ConfigFile.Install]);
|
||||
if (!FindConfigVar(installCfgLines, "resname_base", out var resPaths))
|
||||
{
|
||||
throw new InvalidOperationException("Failed to find resnames in install config");
|
||||
Log.Error("Failed to find `resname_base` in install config");
|
||||
return false;
|
||||
}
|
||||
|
||||
var zipPaths = new List<string>();
|
||||
|
@ -160,6 +172,7 @@ public class ResourcePathManager
|
|||
var dir = Path.Join(installPath, ConvertSeparator(resPath));
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
Log.Warning("Install config references non-existent `resname_base`: {Path}", dir);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -183,7 +196,12 @@ public class ResourcePathManager
|
|||
ZipFile.OpenRead(zipPath).ExtractToDirectory(extractPath, false);
|
||||
}
|
||||
|
||||
FindConfigVar(installCfgLines, "load_path", out var omsPath);
|
||||
if (!FindConfigVar(installCfgLines, "load_path", out var omsPath))
|
||||
{
|
||||
Log.Error("Failed to find `load_path` in install config");
|
||||
return false;
|
||||
}
|
||||
|
||||
omsPath = Path.Join(installPath, ConvertSeparator(omsPath));
|
||||
_omResources = new CampaignResources();
|
||||
_omResources.name = "";
|
||||
|
@ -192,6 +210,7 @@ public class ResourcePathManager
|
|||
var camModLines = File.ReadAllLines(configPaths[(int)ConfigFile.CamMod]);
|
||||
FindConfigVar(camModLines, "fm_path", out var fmsPath, "FMs");
|
||||
_fmsDir = Path.Join(installPath, fmsPath);
|
||||
Log.Information("Searching for FMS at: {FmsPath}", _fmsDir);
|
||||
|
||||
// Build up the map of FM campaigns. These are uninitialised, we just want
|
||||
// to have their name
|
||||
|
@ -205,6 +224,7 @@ public class ResourcePathManager
|
|||
}
|
||||
|
||||
_initialised = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<string> GetCampaignNames()
|
||||
|
@ -222,8 +242,13 @@ public class ResourcePathManager
|
|||
{
|
||||
return _omResources;
|
||||
}
|
||||
else if (_fmResources.TryGetValue(campaignName, out var campaign))
|
||||
|
||||
if (!_fmResources.TryGetValue(campaignName, out var campaign))
|
||||
{
|
||||
Log.Error("Failed to find campaign: {CampaignName}", campaignName);
|
||||
throw new ArgumentException("No campaign found with given name", nameof(campaignName));
|
||||
}
|
||||
|
||||
if (!campaign.initialised)
|
||||
{
|
||||
var fmPath = Path.Join(_fmsDir, campaignName);
|
||||
|
@ -232,9 +257,6 @@ public class ResourcePathManager
|
|||
return campaign;
|
||||
}
|
||||
|
||||
throw new ArgumentException("No campaign found with given name", nameof(campaignName));
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> GetObjectTexturePaths(string root)
|
||||
{
|
||||
string[] validExtensions = { ".dds", ".png", ".tga", ".pcx", ".gif", ".bmp", ".cel", };
|
||||
|
@ -337,11 +359,12 @@ public class ResourcePathManager
|
|||
}
|
||||
}
|
||||
|
||||
Log.Error("No Thief executable found in {InstallPath}. Is this the right directory?", dir);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get an array of of all the Dark config file paths.
|
||||
/// Get an array of all the Dark config file paths.
|
||||
/// </summary>
|
||||
/// <param name="installPath">Root directory of the Thief installation.</param>
|
||||
/// <param name="configPaths">Output array of config file paths</param>
|
||||
|
@ -362,20 +385,21 @@ public class ResourcePathManager
|
|||
foreach (var path in Directory.GetFiles(installPath, "cam*", searchOptions))
|
||||
{
|
||||
var name = Path.GetFileName(path).ToLower();
|
||||
if (name == "cam.cfg")
|
||||
switch (name)
|
||||
{
|
||||
case "cam.cfg":
|
||||
configPaths[(int)ConfigFile.Cam] = path;
|
||||
}
|
||||
else if (name == "cam_ext.cfg")
|
||||
{
|
||||
break;
|
||||
case "cam_ext.cfg":
|
||||
configPaths[(int)ConfigFile.CamExt] = path;
|
||||
}
|
||||
else if (name == "cam_mod.ini")
|
||||
{
|
||||
break;
|
||||
case "cam_mod.ini":
|
||||
configPaths[(int)ConfigFile.CamMod] = path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Verify we found cam/cam_ext/cam_mod
|
||||
var camExtLines = File.ReadAllLines(configPaths[(int)ConfigFile.CamExt]);
|
||||
var camLines = File.ReadAllLines(configPaths[(int)ConfigFile.Cam]);
|
||||
|
||||
|
@ -386,9 +410,24 @@ public class ResourcePathManager
|
|||
}
|
||||
|
||||
FindCamVar("include_path", out var includePath, "./");
|
||||
FindCamVar("game", out var gameName);
|
||||
FindCamVar($"{gameName}_include_install_cfg", out var installCfgName);
|
||||
FindCamVar("include_user_cfg", out var userCfgName);
|
||||
|
||||
if (!FindCamVar("game", out var gameName))
|
||||
{
|
||||
Log.Error("`game` not specified in Cam/CamExt");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FindCamVar($"{gameName}_include_install_cfg", out var installCfgName))
|
||||
{
|
||||
Log.Error("Install config file path not specified in Cam/CamExt");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FindCamVar("include_user_cfg", out var userCfgName))
|
||||
{
|
||||
Log.Error("User config file path not specified in Cam/CamExt");
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: How to handle case-insensitive absolute paths?
|
||||
// Fixup the include path to "work" cross-platform
|
||||
|
@ -396,6 +435,7 @@ public class ResourcePathManager
|
|||
includePath = Path.Join(installPath, includePath);
|
||||
if (!Directory.Exists(includePath))
|
||||
{
|
||||
Log.Error("Include path specified in Cam/CamExt does not exist: {IncludePath}", includePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -417,15 +457,25 @@ public class ResourcePathManager
|
|||
}
|
||||
|
||||
// Check we found everything
|
||||
var i = 0;
|
||||
foreach (var path in configPaths)
|
||||
var found = 0;
|
||||
for (var i = 0; i < (int)ConfigFile.ConfigFileCount; i++)
|
||||
{
|
||||
var path = configPaths[i];
|
||||
if (path == null || path == "")
|
||||
{
|
||||
Log.Error("Failed to find {ConfigFile} config file", (ConfigFile)i);
|
||||
continue;
|
||||
}
|
||||
|
||||
found++;
|
||||
}
|
||||
|
||||
if (found != (int)ConfigFile.ConfigFileCount)
|
||||
{
|
||||
Log.Error("Failed to find all required config files in Thief installation directory");
|
||||
return false;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,13 +42,20 @@ public class LightMapper
|
|||
string campaignName,
|
||||
string missionName)
|
||||
{
|
||||
var pathManager = SetupPathManager(installPath);
|
||||
if (!SetupPathManager(installPath, out var pathManager))
|
||||
{
|
||||
Log.Error("Failed to configure path manager");
|
||||
throw new Exception("Failed to configure path manager");
|
||||
}
|
||||
|
||||
_campaign = pathManager.GetCampaign(campaignName);
|
||||
_misPath = _campaign.GetResourcePath(ResourceType.Mission, missionName);
|
||||
_mission = Timing.TimeStage("Parse DB", () => new DbFile(_misPath));
|
||||
_hierarchy = Timing.TimeStage("Build Hierarchy", BuildHierarchy);
|
||||
_lights = [];
|
||||
|
||||
VerifyRequiredChunksExist();
|
||||
|
||||
var mesh = Timing.TimeStage("Build Mesh", BuildMesh);
|
||||
_triangleTypeMap = mesh.TriangleSurfaceMap;
|
||||
_scene = Timing.TimeStage("Build RT Scene", () =>
|
||||
|
@ -121,12 +128,36 @@ public class LightMapper
|
|||
Timing.TimeStage("Save DB", () => _mission.Save(savePath));
|
||||
}
|
||||
|
||||
private static ResourcePathManager SetupPathManager(string installPath)
|
||||
private bool VerifyRequiredChunksExist()
|
||||
{
|
||||
var requiredChunkNames = new []
|
||||
{
|
||||
"RENDPARAMS",
|
||||
"LM_PARAM",
|
||||
"WREXT",
|
||||
"BRLIST",
|
||||
"P$AnimLight",
|
||||
};
|
||||
|
||||
var allFound = true;
|
||||
foreach (var name in requiredChunkNames)
|
||||
{
|
||||
if (!_mission.Chunks.ContainsKey(name))
|
||||
{
|
||||
Log.Warning("Failed to find required chunk: {ChunkName}", name);
|
||||
allFound = false;
|
||||
}
|
||||
}
|
||||
|
||||
return allFound;
|
||||
}
|
||||
|
||||
private static bool SetupPathManager(string installPath, out ResourcePathManager pathManager)
|
||||
{
|
||||
var tmpDir = Directory.CreateTempSubdirectory("KCLightmapper");
|
||||
var resPathManager = new ResourcePathManager(tmpDir.FullName);
|
||||
resPathManager.Init(installPath);
|
||||
return resPathManager;
|
||||
|
||||
pathManager = new ResourcePathManager(tmpDir.FullName);
|
||||
return pathManager.TryInit(installPath);
|
||||
}
|
||||
|
||||
private ObjectHierarchy BuildHierarchy()
|
||||
|
@ -144,6 +175,8 @@ public class LightMapper
|
|||
{
|
||||
return new ObjectHierarchy(_mission, new DbFile(paths[0]));
|
||||
}
|
||||
|
||||
Log.Warning("Failed to find GameSys");
|
||||
return new ObjectHierarchy(_mission);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ using System.Numerics;
|
|||
using KeepersCompound.LGS;
|
||||
using KeepersCompound.LGS.Database;
|
||||
using KeepersCompound.LGS.Database.Chunks;
|
||||
using Serilog;
|
||||
|
||||
namespace KeepersCompound.Lightmapper;
|
||||
|
||||
|
@ -117,6 +118,7 @@ public class MeshBuilder
|
|||
var modelPath = campaignResources.GetResourcePath(ResourceType.Object, modelName);
|
||||
if (modelPath == null)
|
||||
{
|
||||
Log.Warning("Failed to find model file: {Path}", modelPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue