-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathCPakFile.bt
More file actions
139 lines (127 loc) · 3.54 KB
/
CPakFile.bt
File metadata and controls
139 lines (127 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#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