You've already forked PrimeRemasterStructs
mirror of
https://github.com/PrimeDecomp/PrimeRemasterStructs.git
synced 2026-03-31 14:23:23 -07:00
140 lines
3.5 KiB
Plaintext
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
|