Add mesh conversion and kanji, DAT extraction commands
This commit is contained in:
parent
52f0aed09f
commit
1c07e44a00
3 changed files with 194 additions and 2 deletions
|
@ -9,6 +9,7 @@
|
||||||
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="4.0.0-beta.74" />
|
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="4.0.0-beta.74" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.2" />
|
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.2" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
|
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
|
||||||
|
<PackageReference Include="System.Text.Encoding.CodePages" Version="6.0.0-preview.1.21102.12" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -3,7 +3,10 @@ using LibDgf.Aqualead.Image;
|
||||||
using LibDgf.Aqualead.Image.Conversion;
|
using LibDgf.Aqualead.Image.Conversion;
|
||||||
using LibDgf.Aqualead.Texture;
|
using LibDgf.Aqualead.Texture;
|
||||||
using LibDgf.Dat;
|
using LibDgf.Dat;
|
||||||
|
using LibDgf.Font;
|
||||||
using LibDgf.Graphics;
|
using LibDgf.Graphics;
|
||||||
|
using LibDgf.Graphics.Mesh;
|
||||||
|
using LibDgf.Mesh;
|
||||||
using LibDgf.Txm;
|
using LibDgf.Txm;
|
||||||
using McMaster.Extensions.CommandLineUtils;
|
using McMaster.Extensions.CommandLineUtils;
|
||||||
using SixLabors.ImageSharp;
|
using SixLabors.ImageSharp;
|
||||||
|
@ -13,6 +16,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
using Path = System.IO.Path;
|
using Path = System.IO.Path;
|
||||||
|
|
||||||
namespace DgfTxmConvert
|
namespace DgfTxmConvert
|
||||||
|
@ -25,6 +29,7 @@ namespace DgfTxmConvert
|
||||||
|
|
||||||
static int Main(string[] args)
|
static int Main(string[] args)
|
||||||
{
|
{
|
||||||
|
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||||
imageConverters = new List<IAlImageConverter>
|
imageConverters = new List<IAlImageConverter>
|
||||||
{
|
{
|
||||||
new PkmConverter(),
|
new PkmConverter(),
|
||||||
|
@ -91,6 +96,78 @@ namespace DgfTxmConvert
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.Command("dump-font", config =>
|
||||||
|
{
|
||||||
|
config.FullName = "Dump kanji font";
|
||||||
|
config.Description = "Extracts all characters from kanji font pack.";
|
||||||
|
|
||||||
|
var pakPath = config.Argument("pakPath", "Path of the kanji pack").IsRequired();
|
||||||
|
pakPath.Accepts().ExistingFile();
|
||||||
|
var txmPath = config.Argument("txmPath", "Path of the kana TXM").IsRequired();
|
||||||
|
txmPath.Accepts().ExistingFile();
|
||||||
|
var outputPath = config.Argument("outputPath", "Path of directory to extract character images to");
|
||||||
|
txmPath.Accepts().LegalFilePath();
|
||||||
|
config.HelpOption();
|
||||||
|
|
||||||
|
config.OnExecute(() =>
|
||||||
|
{
|
||||||
|
ExtractFontPack(pakPath.Value, txmPath.Value, outputPath.Value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.Command("extract-dat", config =>
|
||||||
|
{
|
||||||
|
config.FullName = "Extracts DAT";
|
||||||
|
config.Description = "Extracts files from DAT.";
|
||||||
|
|
||||||
|
var datPathArg = config.Argument("datPath", "Path of the DAT to extract").IsRequired();
|
||||||
|
datPathArg.Accepts().ExistingFile();
|
||||||
|
var outBaseArg = config.Argument("outBase", "Directory to write extracted files");
|
||||||
|
outBaseArg.Accepts().LegalFilePath();
|
||||||
|
config.HelpOption();
|
||||||
|
|
||||||
|
config.OnExecute(() =>
|
||||||
|
{
|
||||||
|
ExtractDat(datPathArg.Value, outBaseArg.Value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.Command("convert-trm", config =>
|
||||||
|
{
|
||||||
|
config.FullName = "Converts TRM";
|
||||||
|
config.Description = "Converts train models.";
|
||||||
|
|
||||||
|
var trmPathArg = config.Argument("trmPath", "Path of the train model to extract").IsRequired();
|
||||||
|
trmPathArg.Accepts().ExistingFile();
|
||||||
|
var outBaseArg = config.Argument("outBase", "Directory to write converted files");
|
||||||
|
outBaseArg.Accepts().LegalFilePath();
|
||||||
|
config.HelpOption();
|
||||||
|
|
||||||
|
config.OnExecute(() =>
|
||||||
|
{
|
||||||
|
ExtractTrm(trmPathArg.Value, outBaseArg.Value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.Command("convert-pdb", config =>
|
||||||
|
{
|
||||||
|
config.FullName = "Converts PDB";
|
||||||
|
config.Description = "Converts PDB models.";
|
||||||
|
|
||||||
|
var pdbPathArg = config.Argument("pdbPath", "Path of the model pack to extract").IsRequired();
|
||||||
|
pdbPathArg.Accepts().ExistingFile();
|
||||||
|
var txmPathArg = config.Argument("txmPath", "Path of the associated texture pack").IsRequired();
|
||||||
|
txmPathArg.Accepts().ExistingFile();
|
||||||
|
var outBaseArg = config.Argument("outBase", "Directory to write converted files");
|
||||||
|
outBaseArg.Accepts().LegalFilePath();
|
||||||
|
config.HelpOption();
|
||||||
|
|
||||||
|
config.OnExecute(() =>
|
||||||
|
{
|
||||||
|
ExtractPdb(pdbPathArg.Value, txmPathArg.Value, outBaseArg.Value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
app.VersionOptionFromAssemblyAttributes(System.Reflection.Assembly.GetExecutingAssembly());
|
app.VersionOptionFromAssemblyAttributes(System.Reflection.Assembly.GetExecutingAssembly());
|
||||||
app.HelpOption();
|
app.HelpOption();
|
||||||
|
|
||||||
|
@ -116,6 +193,19 @@ namespace DgfTxmConvert
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ExtractDat(string datPath, string outBase)
|
||||||
|
{
|
||||||
|
if (outBase == null) outBase = Path.GetDirectoryName(datPath);
|
||||||
|
using (DatReader dat = new DatReader(Utils.CheckDecompress(File.OpenRead(datPath))))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < dat.EntriesCount; ++i)
|
||||||
|
{
|
||||||
|
string outPath = Path.Combine(outBase, Path.GetFileName(datPath + $"_{i}.bin"));
|
||||||
|
File.WriteAllBytes(outPath, dat.GetData(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void ReplaceDatImages(string srcDatPath, string destDatPath, string replacementList)
|
static void ReplaceDatImages(string srcDatPath, string destDatPath, string replacementList)
|
||||||
{
|
{
|
||||||
List<string> tempPaths = new List<string>();
|
List<string> tempPaths = new List<string>();
|
||||||
|
@ -137,8 +227,8 @@ namespace DgfTxmConvert
|
||||||
throw new InvalidDataException($"Invalid index on line \"{line}\".");
|
throw new InvalidDataException($"Invalid index on line \"{line}\".");
|
||||||
|
|
||||||
byte level = 1;
|
byte level = 1;
|
||||||
short bufferBase = 0;
|
ushort bufferBase = 0;
|
||||||
short paletteBufferBase = 0;
|
ushort paletteBufferBase = 0;
|
||||||
|
|
||||||
if (imageIndex < dat.EntriesCount)
|
if (imageIndex < dat.EntriesCount)
|
||||||
{
|
{
|
||||||
|
@ -419,5 +509,101 @@ namespace DgfTxmConvert
|
||||||
|
|
||||||
throw new Exception($"Cannot find converter for {img.PixelFormat}");
|
throw new Exception($"Cannot find converter for {img.PixelFormat}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ExtractFontPack(string pakPath, string txmPath, string basePath)
|
||||||
|
{
|
||||||
|
if (basePath == null) basePath = pakPath + "_extracted";
|
||||||
|
using (Stream fs = Utils.CheckDecompress(File.OpenRead(txmPath)))
|
||||||
|
using (Stream datFs = Utils.CheckDecompress(File.OpenRead(pakPath)))
|
||||||
|
{
|
||||||
|
var fontTxmHeader = new TxmHeader();
|
||||||
|
BinaryReader br = new BinaryReader(fs);
|
||||||
|
fontTxmHeader.Read(br);
|
||||||
|
var palette = TxmConversion.ReadRgba32Palette(br, fontTxmHeader.ClutWidth, fontTxmHeader.ClutHeight);
|
||||||
|
|
||||||
|
var fontPak = new FontPack();
|
||||||
|
fontPak.Read(datFs);
|
||||||
|
Directory.CreateDirectory(basePath);
|
||||||
|
|
||||||
|
foreach (var ch in fontPak.Characters)
|
||||||
|
{
|
||||||
|
using MemoryStream ms = new MemoryStream(fontPak[ch]);
|
||||||
|
BinaryReader charBr = new BinaryReader(ms);
|
||||||
|
using (var img = TxmConversion.ConvertTxmIndexed4bpp(charBr, 24, 22, palette))
|
||||||
|
{
|
||||||
|
img.SaveAsPng(Path.Combine(basePath, $"{ch}.png"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ExtractTrm(string trmPath, string basePath = null)
|
||||||
|
{
|
||||||
|
if (basePath == null)
|
||||||
|
basePath = Path.ChangeExtension(trmPath, null);
|
||||||
|
else
|
||||||
|
basePath = Path.Combine(basePath, Path.GetFileNameWithoutExtension(trmPath));
|
||||||
|
|
||||||
|
using DatReader dat = new DatReader(Utils.CheckDecompress(File.OpenRead(trmPath)));
|
||||||
|
// First entry is texture DAT
|
||||||
|
using DatReader txmDat = new DatReader(new MemoryStream(dat.GetData(0)));
|
||||||
|
using ObjConverter converter = new ObjConverter(txmDat);
|
||||||
|
string mtlPath = basePath + ".mtl";
|
||||||
|
string mtlName = Path.GetFileName(mtlPath);
|
||||||
|
// Subsequent entries are train car DATs
|
||||||
|
for (int i = 1; i < dat.EntriesCount; ++i)
|
||||||
|
{
|
||||||
|
using DatReader innerDat = new DatReader(new MemoryStream(dat.GetData(i)));
|
||||||
|
// And within each train car DAT are PDBs
|
||||||
|
for (int j = 0; j < innerDat.EntriesCount; ++j)
|
||||||
|
{
|
||||||
|
using MemoryStream ms = new MemoryStream(innerDat.GetData(j));
|
||||||
|
BinaryReader br = new BinaryReader(ms);
|
||||||
|
Pdb pdb = new Pdb();
|
||||||
|
pdb.Read(br);
|
||||||
|
using StreamWriter sw = File.CreateText($"{basePath}.{i}_{j}.obj");
|
||||||
|
sw.WriteLine($"mtllib {mtlName}");
|
||||||
|
sw.WriteLine();
|
||||||
|
|
||||||
|
converter.ConvertObj(pdb, sw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using (StreamWriter sw = File.CreateText(mtlPath))
|
||||||
|
{
|
||||||
|
converter.ExportTextures(sw, basePath + ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ExtractPdb(string pdbPath, string txmPath, string basePath = null)
|
||||||
|
{
|
||||||
|
if (basePath == null)
|
||||||
|
basePath = Path.ChangeExtension(pdbPath, null);
|
||||||
|
else
|
||||||
|
basePath = Path.Combine(basePath, Path.GetFileNameWithoutExtension(pdbPath));
|
||||||
|
|
||||||
|
DatReader dat = new DatReader(Utils.CheckDecompress(File.OpenRead(pdbPath)));
|
||||||
|
using DatReader txmDat = new DatReader(Utils.CheckDecompress(File.OpenRead(txmPath)));
|
||||||
|
using ObjConverter converter = new ObjConverter(txmDat);
|
||||||
|
string mtlPath = basePath + ".mtl";
|
||||||
|
string mtlName = Path.GetFileName(mtlPath);
|
||||||
|
for (int i = 0; i < dat.EntriesCount; ++i)
|
||||||
|
{
|
||||||
|
using MemoryStream ms = new MemoryStream(dat.GetData(i));
|
||||||
|
BinaryReader br = new BinaryReader(ms);
|
||||||
|
Pdb pdb = new Pdb();
|
||||||
|
pdb.Read(br);
|
||||||
|
using StreamWriter sw = File.CreateText($"{basePath}.{i}.obj");
|
||||||
|
sw.WriteLine($"mtllib {mtlName}");
|
||||||
|
sw.WriteLine();
|
||||||
|
|
||||||
|
converter.ConvertObj(pdb, sw);
|
||||||
|
}
|
||||||
|
|
||||||
|
using (StreamWriter sw = File.CreateText(mtlPath))
|
||||||
|
{
|
||||||
|
converter.ExportTextures(sw, basePath + ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ Usage
|
||||||
The following commands are available. For arguments please use the `--help`
|
The following commands are available. For arguments please use the `--help`
|
||||||
option.
|
option.
|
||||||
|
|
||||||
|
- `extract-dat`: Unpacks files from .DAT container as-is.
|
||||||
- `convert-dat`: Unpacks a .DAT container of textures and converts everything
|
- `convert-dat`: Unpacks a .DAT container of textures and converts everything
|
||||||
to PNG.
|
to PNG.
|
||||||
- `convert-txm`: Converts a single .TXM file to PNG.
|
- `convert-txm`: Converts a single .TXM file to PNG.
|
||||||
|
@ -19,6 +20,10 @@ option.
|
||||||
Requires a text file with a line for each texture to be replaced, consisting
|
Requires a text file with a line for each texture to be replaced, consisting
|
||||||
of the index number and the path to the corresponding image (can be relative
|
of the index number and the path to the corresponding image (can be relative
|
||||||
to working directory).
|
to working directory).
|
||||||
|
- `dump-font`: Extracts characters from kanji font pack.
|
||||||
|
- `convert-trm`: Converts train model file contents to Wavefront OBJ models.
|
||||||
|
- `convert-pdb`: Converts other model files to Wavefront OBJ models. Note the
|
||||||
|
corresponding texture DAT needs to be supplied as well.
|
||||||
|
|
||||||
Other
|
Other
|
||||||
-----
|
-----
|
||||||
|
|
Loading…
Add table
Reference in a new issue