Showing with 1,184 additions and 138 deletions.
  1. +13 −4 README.md
  2. +18 −3 TextureExtraction tool/Data/ScanBase.cs
  3. +1 −1 TextureExtraction tool/DolphinTextureExtraction tool.csproj
  4. +93 −0 lib/AuroraLip/Archives/Formats/Asura.cs
  5. +1 −1 lib/AuroraLip/Archives/Formats/BIG.cs
  6. +29 −22 lib/AuroraLip/Archives/Formats/BIN_MP.cs
  7. +1 −1 lib/AuroraLip/Archives/Formats/CMN.cs
  8. +2 −2 lib/AuroraLip/Archives/Formats/FPK.cs
  9. +77 −0 lib/AuroraLip/Archives/Formats/FTEX.cs
  10. +1 −1 lib/AuroraLip/Archives/Formats/Filelist.cs
  11. +2 −1 lib/AuroraLip/Archives/Formats/PAK_Retro.cs
  12. +3 −1 lib/AuroraLip/Archives/Formats/PAK_RetroWii.cs
  13. +60 −0 lib/AuroraLip/Archives/Formats/PAK_TM2.cs
  14. +161 −0 lib/AuroraLip/Archives/Formats/PK_AQ.cs
  15. +1 −1 lib/AuroraLip/Archives/Formats/RSC.cs
  16. +2 −2 lib/AuroraLip/Archives/Formats/ShrekDir.cs
  17. +1 −1 lib/AuroraLip/AuroraLib.csproj
  18. +41 −5 lib/AuroraLip/Common/FormatDictionary_List.cs
  19. +1 −1 lib/AuroraLip/Compression/FlagReader.cs
  20. +32 −0 lib/AuroraLip/Compression/Formats/AKLZ.cs
  21. +37 −0 lib/AuroraLip/Compression/Formats/AsuraZlb.cs
  22. +149 −0 lib/AuroraLip/Compression/Formats/CNS.cs
  23. +5 −5 lib/AuroraLip/Compression/Formats/LZSS.cs
  24. +38 −0 lib/AuroraLip/Compression/Formats/LZSS_Sega.cs
  25. +1 −1 lib/AuroraLip/Compression/Formats/PRS.cs
  26. +1 −1 lib/AuroraLip/Compression/Formats/RefPack.cs
  27. +1 −1 lib/AuroraLip/Compression/Formats/Shrek.cs
  28. +1 −1 lib/AuroraLip/Compression/Formats/ZLB.cs
  29. +20 −22 lib/AuroraLip/Compression/Formats/ZLib.cs
  30. +110 −0 lib/AuroraLip/Texture/Formats/ALIG.cs
  31. +25 −0 lib/AuroraLip/Texture/Formats/ALTX.cs
  32. +1 −1 lib/AuroraLip/Texture/Formats/GCNT.cs
  33. +1 −1 lib/AuroraLip/Texture/Formats/LFXT.cs
  34. +94 −52 lib/AuroraLip/Texture/Formats/PTLG.cs
  35. +68 −0 lib/AuroraLip/Texture/Formats/RES_NLG.cs
  36. +15 −4 lib/AuroraLip/Texture/Formats/TPL_0.cs
  37. +1 −1 lib/AuroraLip/Texture/Formats/TXE.cs
  38. +67 −0 lib/AuroraLip/Texture/Formats/text.cs
  39. +9 −1 lib/AuroraLip/Texture/TexEntry.cs
17 changes: 13 additions & 4 deletions README.md
Expand Up @@ -13,6 +13,8 @@ the tool can also unpack all supported formats.
The most common formats are already supported, new features and formats will be added over time.

## Download
This is a .NET 6.0 application and requires the .NET Runtime 6.0. If you don't have it installed yet, you can download it from [here](https://dotnet.microsoft.com/en-us/download/dotnet/6.0).

[<img src="https://img.shields.io/github/v/release/Venomalia/DolphinTextureExtraction-tool?style=for-the-badge" alt="Release Download" height="34"/>](https://github.com/Venomalia/DolphinTextureExtraction-tool/releases/latest)

[<img src="https://img.shields.io/github/v/release/Venomalia/DolphinTextureExtraction-tool?include_prereleases&sort=semver&label=prerelease&style=for-the-badge" alt="Pre releases Download" height="34"/>](https://github.com/Venomalia/DolphinTextureExtraction-tool/releases/)
Expand Down Expand Up @@ -44,22 +46,26 @@ List of all [commands](https://github.com/Venomalia/DolphinTextureExtraction-too
### ROM images
- GCDisk (ISO), WiiDisk (ISO), WAD
### Archives
- AFS, ALAR, ARC0, BIN_MP, CPK, FBC, FBTI, FSYS, GVMH, NARC, NLCM, ONE_SB, ONE_UN, PAK_FE, PAK_Retro, PAK_RetroWii, PCKG, POD5, POSD, RARC, RKV2, RMHG, RTDP, TXAG, U8, bres, pBin, SevenZip(zip, 7z, tar, deb, dmg, rpm, xar, bz2, lzh, cab, vhd)
- Asura, AFS, ALAR, ALIG, ARC_Pit, ARC0, BIN_MP, BIG, CMN, CPK, FBC, Filelist, FBTI, FSYS, FPK, GVMH, GSW, GSScene, RSC, NARC, NLCM, ONE_SB, ONE_UN, PAK_FE, PAK_Retro, PAK_RetroWii, PAK_TM2, PCKG, POD5, POSD, RARC, RKV2, RMHG, RTDP, TXAG, TXE, U8, bres, pBin, ShrekDir, SevenZip(zip, 7z, tar, deb, dmg, rpm, xar, bz2, lzh, cab, vhd)
### Compressing
- CNX, CLZ, COMP, CRILAYLA, CXLZ, FCMP, GCLZ, GZIP, LH, LZ00, LZ01, LZ10, LZ11, LZ77, LZS, LZSS, PRS, YAY0, YAZ0, YAZ1, ZLib
- AKLZ, AsuraZlb, CNS, CNX, CLZ, COMP, CRILAYLA, CXLZ, FCMP, GCLZ, GZIP, LH, LZ00, LZ01, LZ10, LZ11, LZ77, LZS, LZSS, LZSS_Sega, PRS, PRS_BE, YAY0, YAZ0, YAZ1, ZLB, ZLib, LZ4, LZO, RefPack, Zstd
### Textures
- BTI, FIPAFTEX, GBIX, GCIX, GCT0, GTX, GVRT, HXTB, NUTC, PTLG, REFT, TEX, TEX0, TEX1, TEX_KS, TEX_RFS, TPL, TPL_0, TXE, TXTR, WTMD, ATB
- ALTX, BTI, FIPAFTEX, FTEX, GCNT, GBIX, GCIX, GCT0, GTX, GVRT, HXTB, LFXT, NUTC, PTLG, REFT, TEX, TEX0, TEX1, TEX_KS, TEX_RFS, TPL, TPL_0, TXE, TXTR, WTMD, ATB
### Model archives
- MOD, BMD3, BDL4, MDL_LM, HSF
- MOD, BMD3, BDL4, MDL_LM, HSF, PKX, WZX, GSAGTX, GSFILE11

## Credits

- [ImageSharp](https://github.com/SixLabors/ImageSharp) used as graphics API.

- [Hack.io](https://github.com/SuperHackio/Hack.io) to read RARC, U8, YAZ, YAY, BTI, TPL, TEX1, BMD and BDL Format

- [Puyo Tools](https://github.com/nickworonekin/puyotools) Code reference for ONE GVMH, GBIX, GCIX, GVRT, Format and to read PRS, CNX, Lz00, lz01 Lz10, Lz11 Compressing.

- [HashDepot](https://github.com/ssg/HashDepot) used for xxHash generation

- [Ironcompress](https://github.com/aloneguid/ironcompress) used for LZO, LZ4 and Zstandard.

- [SevenZip](https://github.com/adoconnection/SevenZipExtractor) to read formats supported by 7Zip

- [SharpZipLib](https://github.com/icsharpcode/SharpZipLib) to read ZLib Compressing
Expand All @@ -83,3 +89,6 @@ List of all [commands](https://github.com/Venomalia/DolphinTextureExtraction-too
- [mpatbtools](https://github.com/gamemasterplc/mpatbtools) reference for ATB Format.

- [BrawlCrate](https://github.com/soopercool101/BrawlCrate) reference for ARC0 Format.

- [Helco](https://github.com/Helco/Pitfall) reference for LFXT Format.

21 changes: 18 additions & 3 deletions TextureExtraction tool/Data/ScanBase.cs
Expand Up @@ -258,7 +258,12 @@ protected virtual void Scan(FileInfo file)
{
Stream stream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);
var SubPath = PathEX.GetRelativePath(file.FullName.AsSpan(), ScanPath.AsSpan());
Scan(new ScanObjekt(stream, SubPath, 0, file.Extension));
ScanObjekt objekt = new(stream, SubPath, 0, file.Extension);
if (objekt.Format.Typ != FormatType.Unknown)
{
Log.WriteNotification(NotificationType.Info, $"Scan \"{SubPath}\" recognized as {objekt.Format.GetFullDescription()}");
}
Scan(objekt);
stream.Close();
}

Expand Down Expand Up @@ -292,8 +297,15 @@ private double Scan(string subPath, int deep, List<ArchiveFile> fileInfos)
//Checks all possible illegal characters and converts them to hex
string path = PathEX.GetValidPath(file.FullPath);
path = Path.Combine(subPath, path);
ScanObjekt objekt = new(file, path.AsSpan(), deep);
if (objekt.Format.Typ != FormatType.Unknown)
{
Log.WriteNotification(NotificationType.Info, $"Scan \"{path}\" recognized as {objekt.Format.GetFullDescription()}, Deep:{deep}");
}
Scan(new ScanObjekt(file, Path.Combine(subPath, path).AsSpan(), deep));
Scan(objekt);
lock (Result)
{
ArchLength += Length;
Expand Down Expand Up @@ -365,6 +377,9 @@ protected virtual bool TryExtract(ScanObjekt so)
case ".bti":
case ".onz":
case ".lz":
case ".zlip":
case ".lzo":
case ".lz11":
case ".bin":
case ".zs":
case ".lh":
Expand All @@ -383,7 +398,7 @@ protected virtual bool TryExtract(ScanObjekt so)
case ".cmpres":
if (Reflection.Compression.TryToDecompress(so.Stream, out Stream test, out Type type))
{
Scan(new ScanObjekt(test, so.SubPath, so.Deep + 1, Path.GetExtension(PathEX.WithoutExtension(so.SubPath)).ToString()));
Scan(new ScanObjekt(test, so.SubPath, so.Deep + 1, Path.GetExtension(so.SubPath).ToString()));
return true;
}
break;
Expand Down
Expand Up @@ -7,7 +7,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
<IncludeSymbols>False</IncludeSymbols>
<Version>1.5.10.$([System.DateTime]::Now.ToString(`MMdd`))</Version>
<Version>1.5.25.$([System.DateTime]::Now.ToString(`MMdd`))</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<FileVersion>$(Version)</FileVersion>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand Down
93 changes: 93 additions & 0 deletions lib/AuroraLip/Archives/Formats/Asura.cs
@@ -0,0 +1,93 @@
using AuroraLib.Common;

namespace AuroraLib.Archives.Formats
{
public class Asura : Archive, IMagicIdentify, IFileAccess
{
public bool CanRead => true;

public bool CanWrite => false;

public string Magic => magic;

private const string magic = "Asura ";

public bool IsMatch(Stream stream, in string extension = "")
=> stream.Length > 0x20 && stream.MatchString(magic);

protected override void Read(Stream stream)
{
if (!IsMatch(stream))
throw new InvalidIdentifierException(magic);

Endian endian = stream.At(0xC, s => s.DetectByteOrder<int>());

Root = new ArchiveDirectory() { OwnerArchive = this };

int i = 0;
while (stream.Position < stream.Length - 4)
{
long startpos = stream.Position;

string magic = stream.ReadString(4);
uint size = stream.ReadUInt32(endian);

if (magic == string.Empty || size == 0)
{
break;
}

int nameoffset = GetNamePos(magic);
if (nameoffset != -1)
{
stream.Seek(startpos + nameoffset, SeekOrigin.Begin);
string name = stream.ReadString().TrimStart('\\');

if (magic == "FCSR")
{
stream.Align(4);
size -= (uint)(stream.Position - startpos);
startpos = stream.Position;
}


Root.AddArchiveFile(stream, size, startpos, $"{name}~ID{i++}.{magic.ToLower()}");
}
else
{
Root.AddArchiveFile(stream, size, startpos, $"{magic}~ID{i++}.{magic.ToLower()}");
}

//go to next
stream.Seek(startpos + size, SeekOrigin.Begin);
}
}

protected override void Write(Stream stream) => throw new NotImplementedException();

private static int GetNamePos(string magic) => magic switch
{
"NACH" => 0x2C,
"STUC" => 0x24,
"TPXF" => 0x14,
"TEXF" => 0x14,
"TPMH" => 0x14,
"TSXF" => 0x14,
"DNSH" => 0x14,
"NAIU" => 0x14,
"CATC" => 0x18,
"NKSH" => 0x18,
"FCSR" => 0x1C,
"PMIU" => 0x1C,
"RTTC" => 0x1C,
"VELD" => 0x10,
"AMDS" => 0x10,
"BBSH" => 0x10,
"NLLD" => 0x10,
"TLLD" => 0x10,
"VEDS" => 0x10,
"MSDS" => 0x10,
_ => -1,
};
}
}
2 changes: 1 addition & 1 deletion lib/AuroraLip/Archives/Formats/BIG.cs
Expand Up @@ -2,7 +2,7 @@
using AuroraLib.Common;
using System.Runtime.InteropServices;

namespace AuroraLip.Archives.Formats
namespace AuroraLib.Archives.Formats
{
public class BIG : Archive, IMagicIdentify, IFileAccess
{
Expand Down
51 changes: 29 additions & 22 deletions lib/AuroraLip/Archives/Formats/BIN_MP.cs
Expand Up @@ -13,40 +13,47 @@ public class BIN_MP : Archive, IFileAccess

public static string Extension => ".bin";

private static readonly LZSS lZSS = new LZSS(10, 6, 2);
private static readonly LZSS lZSS = new(10, 6, 2);

public bool IsMatch(Stream stream, in string extension = "")
=> Matcher(stream, extension);

public static bool Matcher(Stream stream, in string extension = "")
{
if (!extension.ToLower().Equals(Extension))
return false;

uint files = stream.ReadUInt32(Endian.Big);
if (files > 1000 || files == 0)
return false;
uint[] offsets = new uint[files];
for (int i = 0; i < files; i++)
{
offsets[i] = stream.ReadUInt32(Endian.Big);
}

uint lastoffset = (uint)stream.Position - 1;
for (int i = 0; i < files; i++)
if (extension.ToLower().Equals(Extension))
{
if (offsets[i] <= lastoffset || stream.Length < offsets[i] + 10)
uint files = stream.ReadUInt32(Endian.Big);
if (files > 1000 || files == 0)
return false;
lastoffset = offsets[i] + 0x10;
uint[] offsets = new uint[files];
for (int i = 0; i < files; i++)
{
offsets[i] = stream.ReadUInt32(Endian.Big);
}

stream.Seek(offsets[i] + 4, SeekOrigin.Begin);
uint type = stream.ReadUInt32(Endian.Big);
if (offsets[0] == stream.Position)
{

if (!Enum.IsDefined(typeof(CompressionType), type))
return false;
uint lastoffset = (uint)stream.Position - 1;
for (int i = 0; i < files; i++)
{
if (offsets[i] <= lastoffset || stream.Length < offsets[i] + 10)
return false;
lastoffset = offsets[i] + 0x20;

stream.Seek(offsets[i], SeekOrigin.Begin);
uint DeSize = stream.ReadUInt32(Endian.Big);
uint type = stream.ReadUInt32(Endian.Big);

if (!Enum.IsDefined(typeof(CompressionType), type) || DeSize > 0xA00000 || DeSize == 0)
return false;
}

return true;
}
}

return true;
return false;
}

protected override void Read(Stream stream)
Expand Down
2 changes: 1 addition & 1 deletion lib/AuroraLip/Archives/Formats/CMN.cs
@@ -1,7 +1,7 @@
using AuroraLib.Archives;
using AuroraLib.Common;

namespace AuroraLip.Archives.Formats
namespace AuroraLib.Archives.Formats
{
public class CMN : Archive, IFileAccess
{
Expand Down
4 changes: 2 additions & 2 deletions lib/AuroraLip/Archives/Formats/FPK.cs
@@ -1,9 +1,9 @@
using AuroraLib.Archives;
using AuroraLib.Common;
using AuroraLib.Compression.Formats;
using AuroraLip.Compression.Formats;
using AuroraLib.Compression.Formats;

namespace AuroraLip.Archives.Formats
namespace AuroraLib.Archives.Formats
{
public class FPK : Archive, IFileAccess
{
Expand Down
77 changes: 77 additions & 0 deletions lib/AuroraLip/Archives/Formats/FTEX.cs
@@ -0,0 +1,77 @@
using AuroraLib.Common;

namespace AuroraLib.Archives.Formats
{
public class FTEX : Archive, IMagicIdentify, IFileAccess
{
public virtual bool CanRead => true;

public virtual bool CanWrite => false;

public virtual string Magic => magic;

private const string magic = "FTEX";

public bool IsMatch(Stream stream, in string extension = "")
=> stream.MatchString(Magic);

protected override void Read(Stream stream)
{
Header header = stream.Read<Header>();
stream.Seek(0x10, SeekOrigin.Current);
NameEntry[] names = stream.For((int)header.Entrys, s => new NameEntry(s));

stream.Seek(header.Offset, SeekOrigin.Begin);
Root = new ArchiveDirectory() { Name = "root", OwnerArchive = this };
for (int i = 0; i < header.Entrys; i++)
{
FTX0 Entry = stream.Read<FTX0>();
stream.Seek(Entry.Offset - 0x10, SeekOrigin.Current);
Root.AddArchiveFile(stream, Entry.Size, names[i].Name);
stream.Seek(Entry.Size, SeekOrigin.Current);
}
}

protected override void Write(Stream stream) => throw new NotImplementedException();

private struct Header
{
public uint Magic; // FTEX 1480938566
public uint Size;
public uint Offset;
public uint Entrys;

public uint FullSize => Size + Offset + 0x10;
}

private struct NameEntry
{
public string Name;
public Propertie Properties;

public NameEntry(Stream stream)
{
Name = stream.ReadString(0x20);
Properties = stream.Read<Propertie>();
}

public struct Propertie
{
public uint Padding;
public uint unk1;
public uint unk2;
public uint unk3;
}
}

private struct FTX0
{
public uint Magic; // FTX0 811095110
public uint Size;
public uint Offset;
public uint Padding;

public uint FullSize => Size + Offset;
}
}
}
2 changes: 1 addition & 1 deletion lib/AuroraLip/Archives/Formats/Filelist.cs
Expand Up @@ -3,7 +3,7 @@
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;

namespace AuroraLip.Archives.Formats
namespace AuroraLib.Archives.Formats
{
public class Filelist : Archive, IFileAccess
{
Expand Down
3 changes: 2 additions & 1 deletion lib/AuroraLip/Archives/Formats/PAK_Retro.cs
Expand Up @@ -88,7 +88,8 @@ protected static MemoryStream Decompress(Stream input, uint decompressedSize)
{
//prime 1, DKCR = Zlip
//prime 2,3 = LZO1X-999
if (input.Read<ZLib.Header>().Validate())
ZLib.Header header = input.Read<ZLib.Header>();
if (header.Validate() && header.HasDictionary == false && header.CompressionInfo == 7 && header.CompressionLevel == 3)
{
input.Seek(0, SeekOrigin.Begin);
ZLib zLib = new();
Expand Down