-
Notifications
You must be signed in to change notification settings - Fork 1
/
sphinx_filelistbin.bt
127 lines (106 loc) · 3.22 KB
/
sphinx_filelistbin.bt
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
//--------------------------------------
//--- 010 Editor v6.0.3 Binary Template
//
// File: Sphinx Filelist.bin descriptor
// Author: Swyter
// Revision: 2016-02-28, 2016-03-23, 2016-06-27
// Purpose: For the GameCube (PAL/NTSC), XBOX and PlayStation 2 (PAL) versions.
// Supports the two Filelist.bin variants publicly known to date.
// Should work with anything you throw at it.
//--------------------------------------
/* gamecube is big endian,
ps2 is little endian */
if (ReadByte() & (0x4 | 0x5)) LittleEndian(); else BigEndian();
/* retail is version 5,
standalone demo is version 4 */
uint magic;
uint total_size <format=hex>;
uint list_item_count;
if (magic == 0x5)
{
/* 1 and 0, respectively */
uint16 unk_a <format=hex>;
uint16 unk_b <format=hex>;
}
/* points to the strings pointers array */
uint next_section <format=hex>; // + offset (address relative to this field)
struct
{
/* the standalone version only supports a single offset per file */
if (magic == 0x4)
{
uint loc_addr <format=hex>;
}
uint len <format=hex>;
uint hash <format=hex>;
uint ver;
uint unk_flags <format=hex>;
/* the retail game supports multiple offsets for the
same file, even within the same container */
if (magic == 0x5)
{
uint offset_count;
struct
{
uint loc_addr <format=hex>;
uint loc_file;
}offsets[offset_count] <optimize=false>;
}
}list_item[list_item_count] <optimize=false>;
/* the string pointer array always appears right
after the last entry, so this shouldn't be necessary in theory */
FSeek(startof(next_section) + next_section);
uint string_pointer_array[list_item_count];
struct
{
string ss <optimize=false>;
}ss[list_item_count] <optimize=false>;
/* --- */
local uint i;
local uint j;
local uint filename_addr;
local string filename_stri;
/* make a pretty listing in the Output window */
for (i=0; i<list_item_count; i++)
{
filename_addr = startof(string_pointer_array[i]) + string_pointer_array[i];
filename_stri = ReadString(filename_addr);
Printf("\n" +
"File: %s (string at %#x) \n" +
" Len: %u \n" +
" Ver: %u \n" +
"Flag: %#x \n" +
"Hash: %#x \n" +
" Loc: %9x:",
filename_stri,
filename_addr,
list_item[i].len,
list_item[i].ver,
list_item[i].unk_flags,
list_item[i].hash,
(magic == 0x5 ?
list_item[i].offsets[0].loc_addr :
list_item[i].loc_addr
)
);
if (magic == 0x5)
{
/* retail supports up to 999 data containers, starting by Filelist.000,
only two containers have appeared in the wild, though */
Printf("%03u", list_item[i].offsets[0].loc_file);
/* the file of an entry can be stored in various containers and duplicated
in various offsets per file to improve DVD seek times */
for (j=1; j<list_item[i].offset_count; j++)
Printf(", %9x:%03u",
list_item[i].offsets[j].loc_addr,
list_item[i].offsets[j].loc_file
);
}
else
{
/* the demo version only has a single
data container with .dat extension */
Printf("%s", "DAT");
}
Printf("\n-- (%d) \n", i);
}