Files
2025-12-09 22:49:14 -07:00

140 lines
3.5 KiB
Plaintext

#ifndef _CPAKFILE
#define _CPAKFILE
#include "Common.bt"
struct File;
struct CPakFile;
typedef struct
{
FourCC type;
GUID id;
if (!isDKCTF)
{
uint32 versionA;
uint32 versionB;
}
uint64 offset <format=hex>;
if (!isDKCTF)
{
uint64 decompressedSize <format=hex>;
}
uint64 size <format=hex>;
if (isDKCTF)
{
local uint64 decompressedSize <hidden=true> = size;
}
if (pak.toc.readerVersion == 4) {
uint64 unk;
}
local uint64 pos <format=hex, hidden=true> = FTell();
FSeek(offset);
if (size == decompressedSize) {
File data <size=size>;
} else {
CompressionType compressionType;
byte pad[3] <hidden=true>;
byte compressedData[size - 4];
}
FSeek(pos);
} AssetDirectoryEntry <
size=(isDKCTF ? 36 : (pak.toc.readerVersion == 4 ? 60 : 52)), // Parse on-demand
name=AssetDirectoryEntryName,
comment=(SizeComment(this.size))
>;
string AssetDirectoryEntryName(AssetDirectoryEntry& entry)
{
if (isDKCTF) {
// Read the chunk ver and subver from form descriptor
return Str("%s v%d.%d %s", entry.type, entry.data.form.readerVersion, entry.data.form.writerVersion, GUIDToString(entry.id)); //Fix broken DKCTF version display
} else {
return Str("%s v%d.%d %s", entry.type, entry.versionA, entry.versionB, GUIDToString(entry.id));
}
}
typedef struct
{
GUID id;
uint32 offset <format=hex>;
// Find the FourCC for the asset ID
// Assumes TOCC chunk 0 is ADIR
local FourCC type <hidden=true>;
local uint64 fileOffset <hidden=true>;
local uint32 i <hidden=true>;
for (i = 0; i < pak.chunk[0].count; i++) {
if (pak.chunk[0].entry[i].id == id) {
type = pak.chunk[0].entry[i].type;
fileOffset = pak.chunk[0].entry[i].offset;
break;
}
}
local uint64 pos <format=hex, hidden=true> = FTell();
FSeek(start + offset);
uint32 size <format=hex>;
Meta data(type, size, fileOffset);
FSeek(pos);
} MetaEntry <
size=20, // Parse on-demand
name=(Str("%s %s", this.type, GUIDToString(this.id))),
comment=(SizeComment(size))
>;
typedef struct
{
// Byteswapped
uint32 type <read=FourCCInt>;
GUID id;
// Wii U DKCTF uses a null terminated string here
// but PACK/TOCC version is the same
if (!isDKCTF || ReadByte() == 0) {
uint32 length;
char name[length];
} else {
string name;
}
} StringEntry <
name=(Str("%s (%s) %s", name, FourCCInt(type), GUIDToString(id)))
>;
typedef struct(CPakFile& pak)
{
ChunkDescriptor chunk;
local uint64 start <format=hex, hidden=true> = FTell();
switch (chunk.id)
{
case "ADIR":
uint32 count <format=decimal, name="ADIR entry count">;
AssetDirectoryEntry entry[count] <optimize=false>;
break;
case "META":
uint32 count <format=decimal, name="META entry count">;
MetaEntry entry[count] <optimize=false>;
break;
case "STRG":
uint32 count <format=decimal, name="STRG entry count">;
StringEntry entry[count] <optimize=false>;
break;
}
FSeek(start + chunk.size);
} TOCChunk <
name=(Str("%s chunk", chunk.id)),
comment=(Str("%d entries", count))
>;
typedef struct
{
FormDescriptor toc;
local uint64 start <format=hex, hidden=true> = FTell();
while (FTell() < start + toc.size)
{
TOCChunk chunk(this);
}
} CPakFile <name="PACK chunks">;
#endif// _CPAKFILE