2024-08-11 14:23:56 +00:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.IO;
|
2024-08-13 18:11:03 +00:00
|
|
|
using System.IO.Compression;
|
2024-08-11 14:23:56 +00:00
|
|
|
using System.Linq;
|
|
|
|
using Godot;
|
|
|
|
|
|
|
|
namespace KeepersCompound.TMV;
|
|
|
|
|
2024-08-12 17:46:30 +00:00
|
|
|
public partial class TextureLoader
|
2024-08-11 14:23:56 +00:00
|
|
|
{
|
2024-08-13 18:11:03 +00:00
|
|
|
private readonly string _userTexturesPath;
|
|
|
|
private readonly string _rootFamPath; // TODO: Load from installation resources
|
2024-08-11 14:23:56 +00:00
|
|
|
private readonly string _fmPath;
|
2024-08-13 18:11:03 +00:00
|
|
|
private readonly Dictionary<string, string> _rootTexturePaths = new();
|
2024-08-11 14:23:56 +00:00
|
|
|
private readonly Dictionary<string, string> _fmTexturePaths = new();
|
|
|
|
|
|
|
|
private readonly List<ImageTexture> _textureCache = new();
|
|
|
|
private readonly Dictionary<int, int> _idMap = new();
|
|
|
|
private readonly Dictionary<string, int> _pathMap = new();
|
|
|
|
|
2024-08-13 18:11:03 +00:00
|
|
|
public TextureLoader(string rootFamPath, string fmPath)
|
2024-08-11 14:23:56 +00:00
|
|
|
{
|
2024-08-13 18:11:03 +00:00
|
|
|
_rootFamPath = rootFamPath;
|
2024-08-11 14:23:56 +00:00
|
|
|
_fmPath = fmPath;
|
2024-08-13 18:11:03 +00:00
|
|
|
_userTexturesPath = ProjectSettings.GlobalizePath($"user://textures/tmp");
|
2024-08-11 14:23:56 +00:00
|
|
|
|
2024-08-13 18:11:03 +00:00
|
|
|
ExtractRootFamFiles();
|
2024-08-11 14:23:56 +00:00
|
|
|
LoadDefaultTexture();
|
2024-08-13 18:11:03 +00:00
|
|
|
RegisterTexturePaths(_fmPath, _fmTexturePaths);
|
|
|
|
RegisterTexturePaths(_userTexturesPath, _rootTexturePaths);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void ExtractRootFamFiles()
|
|
|
|
{
|
|
|
|
var dir = new DirectoryInfo(_userTexturesPath);
|
|
|
|
if (dir.Exists)
|
|
|
|
{
|
|
|
|
dir.Delete(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
var zip = ZipFile.OpenRead(_rootFamPath);
|
|
|
|
zip.ExtractToDirectory(_userTexturesPath.PathJoin("fam"));
|
2024-08-11 14:23:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void LoadDefaultTexture()
|
|
|
|
{
|
|
|
|
// TODO: This should be a resource loaded from RES
|
|
|
|
const string path = "user://textures/jorge.png";
|
|
|
|
var texture = ImageTexture.CreateFromImage(Image.LoadFromFile(path));
|
|
|
|
_textureCache.Add(texture);
|
|
|
|
}
|
|
|
|
|
2024-08-13 18:11:03 +00:00
|
|
|
private static void RegisterTexturePaths(string rootDir, Dictionary<string, string> map)
|
2024-08-11 14:23:56 +00:00
|
|
|
{
|
2024-08-12 18:52:36 +00:00
|
|
|
// TODO: Load DDS BMP GIF CEL
|
|
|
|
string[] validExtensions = { "png", "tga", "pcx" };
|
2024-08-11 14:23:56 +00:00
|
|
|
|
|
|
|
var famOptions = new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive };
|
|
|
|
var textureOptions = new EnumerationOptions
|
|
|
|
{
|
|
|
|
MatchCasing = MatchCasing.CaseInsensitive,
|
|
|
|
RecurseSubdirectories = true,
|
|
|
|
};
|
|
|
|
|
2024-08-13 18:11:03 +00:00
|
|
|
foreach (var dirPath in Directory.EnumerateDirectories(rootDir, "fam", famOptions))
|
2024-08-11 14:23:56 +00:00
|
|
|
{
|
|
|
|
foreach (var path in Directory.EnumerateFiles(dirPath, "*", textureOptions))
|
|
|
|
{
|
|
|
|
if (validExtensions.Contains(path.GetExtension().ToLower()))
|
|
|
|
{
|
|
|
|
// TODO: This only adds the first one found rather than the highest priority
|
2024-08-13 18:11:03 +00:00
|
|
|
var key = path.TrimPrefix(rootDir).GetBaseName().ToLower();
|
|
|
|
map.TryAdd(key, path);
|
2024-08-11 14:23:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-08-13 18:11:03 +00:00
|
|
|
|
|
|
|
GD.Print($"Registered {map.Count} texture paths at : {rootDir}");
|
2024-08-11 14:23:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public bool Load(int id, string path)
|
|
|
|
{
|
|
|
|
var loaded = false;
|
2024-08-13 18:11:03 +00:00
|
|
|
if (_fmTexturePaths.TryGetValue(path.ToLower(), out var fmTexPath))
|
2024-08-11 14:23:56 +00:00
|
|
|
{
|
2024-08-13 18:11:03 +00:00
|
|
|
_textureCache.Add(LoadTexture(fmTexPath));
|
2024-08-11 14:23:56 +00:00
|
|
|
loaded = true;
|
|
|
|
}
|
2024-08-13 18:11:03 +00:00
|
|
|
else if (_rootTexturePaths.TryGetValue(path.ToLower(), out var rootTexPath))
|
2024-08-11 14:23:56 +00:00
|
|
|
{
|
2024-08-13 18:11:03 +00:00
|
|
|
_textureCache.Add(LoadTexture(rootTexPath));
|
2024-08-11 14:23:56 +00:00
|
|
|
loaded = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
var index = loaded ? _textureCache.Count - 1 : 0;
|
|
|
|
_idMap.TryAdd(id, index);
|
|
|
|
_pathMap.TryAdd(path, index);
|
|
|
|
return loaded;
|
|
|
|
}
|
|
|
|
|
2024-08-18 09:27:44 +00:00
|
|
|
public static ImageTexture LoadTexture(string path)
|
2024-08-12 17:46:30 +00:00
|
|
|
{
|
|
|
|
var ext = path.GetExtension().ToLower();
|
|
|
|
var texture = ext switch
|
|
|
|
{
|
|
|
|
"pcx" => LoadPcx(path),
|
2024-08-18 09:27:44 +00:00
|
|
|
"gif" => LoadGif(path),
|
2024-08-12 17:46:30 +00:00
|
|
|
_ => ImageTexture.CreateFromImage(Image.LoadFromFile(path)),
|
|
|
|
};
|
|
|
|
return texture;
|
|
|
|
}
|
|
|
|
|
2024-08-11 14:23:56 +00:00
|
|
|
public ImageTexture Get(int id)
|
|
|
|
{
|
|
|
|
if (!_idMap.ContainsKey(id))
|
|
|
|
{
|
|
|
|
return _textureCache[0];
|
|
|
|
}
|
|
|
|
return _textureCache[_idMap[id]];
|
|
|
|
}
|
|
|
|
|
|
|
|
public ImageTexture Get(string path)
|
|
|
|
{
|
|
|
|
if (!_pathMap.ContainsKey(path))
|
|
|
|
{
|
|
|
|
return _textureCache[0];
|
|
|
|
}
|
|
|
|
return _textureCache[_pathMap[path]];
|
|
|
|
}
|
|
|
|
}
|