-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathmicrosoft_xbox.bms
More file actions
372 lines (365 loc) · 12.5 KB
/
microsoft_xbox.bms
File metadata and controls
372 lines (365 loc) · 12.5 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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
get dvd_size asize
get dvd_name filename
math xbox_type = 0
if dvd_name == "Data0000"
math xbox_type = 1
print " file is too complex for this script to handle for various reasons. \n a severe lack of documentation regarding the format used for this file is one of them. "
cleanexit
endif
if xbox_type = 0
/*
putarray 0 0 0 # just a zero (coming right from Xbox 360 disc dumps by scene group PI, scrambled zeroes and all that)
putarray 0 1 0x4100
putarray 0 2 0x1fb20 # Xbox 360
putarray 0 3 0x30600 # Xbox
*/
# all Xbox/Xbox360 DVD images (no known exceptions aside from PI/RADIAN dumps)
# have a partition using some sort of ISO9660 file system that contains a video intended to be compatible with any device
# telling the end user that this disk is only compatible with Xbox/Xbox360 and nothing else,
# alongside some system update files if said disk comes from an individual Xbox360 product (e.g. a game).
# if you want those files turn to IsoBuster, 7-Zip or basically any program that can handle said filesystem.
# this is not the focus of this script however as said file system is known by some quickBMS programmers
# to be very pesky to handle...
math padding_number = 0x20
math xbox_file_system_base_number = 0
print " finding Xbox file system. \n please wait... "
for i = 0 < 0x30601
xmath goto_01 "(xbox_file_system_base_number + padding_number) << 11"
goto goto_01
getdstring is_mxm 0x14
if is_mxm == "MICROSOFT*XBOX*MEDIA"
print " the Xbox file system has been found. \n the script can now work on it. "
math xbox_file_system_starting_offset = goto_01
break
else
math xbox_file_system_base_number + 1
endif
next i
endif
if xbox_type = 1
math xbox_file_system_base_number = 4
math padding_number = 0x20
xmath goto_01 "xbox_file_system_base_number << 11"
goto goto_01
get is_xsf long
if is_xsf == 0x1a465358 # "XSF\x1a"
get xsf_02 long
get xsf_03 longlong
endif
xmath goto_02 "(xbox_file_system_base_number + padding_number) << 11"
math xbox_file_system_starting_offset = goto_02
endif
goto xbox_file_system_starting_offset
for i = 0 < 2
getdstring mxm_01 0x14
if mxm_01 != "MICROSOFT*XBOX*MEDIA"
cleanexit
endif
if i = 0
get first_directory_sector long
get first_directory_size long
get timecode time64
string tc_report p " master date for this disc is %s " timecode
print " %tc_report% "
getdstring dummy_data 0x7c8
elif i = 1
if xbox_type == 0
getdstring command 0x20
get info_related_to_command_01 long
get info_related_to_command_02 long
get info_related_to_command_03 long
get info_related_to_command_04 long
endif
endif
next i
xmath goto_02 "(first_directory_sector + xbox_file_system_base_number) << 11"
math current_file_number = 0
if xbox_type = 1
math target_offset = goto_02
callfunction mxm_helper_02 1
endif
if xbox_type < 1
math current_directory_info_offset = goto_02
endif
if xbox_type = 1
math current_directory_info_offset = data_offset_for_single_spot
endif
xmath modulus_test "first_directory_size % (1 << 11)"
if modulus_test = 0
math current_directory_size = first_directory_size
else
xmath current_directory_size "((first_directory_size >> 11) + 1) << 11"
endif
math overall_directory_entry = 0
math directory_number = 0
math current_directory_to_process = 0
math future_directory_to_process = 0
math directory_entry_to_fetch_from = 0
math previous_directory_entry_number = 0
math next_directory_entry_to_parse = 0
math parsing_directory_entry = 0
math next_parsing_directory_entry = 0
math final_directory_entries = 0
set directory_name string ""
for j = 0 <= 256
putarray 101 j 0
putarray 102 j 0
putarray 103 j 0
putarray 104 j 0
putarray 105 j 0
putarray 106 j 0
putarray 107 j 0
putarray 108 j 0
putarray 109 j 0
putarray 110 j 0
putarray 111 j ""
next j
if xbox_type != 0
cleanexit
endif
callfunction parse_mxm 1
startfunction parse_mxm
goto current_directory_info_offset current_file_number
math current_directory_entry = 0
for i2 = 0
math dont_put_this_into_array = 0
callfunction mxm_helper_01 1
if i2 = 0
math directory_entry_to_fetch_from = overall_directory_entry
endif
get d1 short current_file_number
if d1 == 0xffff
math dont_put_this_into_array = 1
else
math dont_put_this_into_array = 0
endif
callfunction mxm_helper_01 1
get d2 short current_file_number
if d2 == 0xffff
math dont_put_this_into_array = 1
else
math dont_put_this_into_array = 0
endif
callfunction mxm_helper_01 1
if dont_put_this_into_array = 0
putarray 1 overall_directory_entry d1
putarray 2 overall_directory_entry d2
get d3 long current_file_number
putarray 3 overall_directory_entry d3
get d4 long current_file_number
putarray 4 overall_directory_entry d4
get d5 byte current_file_number
xmath flag_01 "d5 & 1"
xmath flag_02 "(d5 >> 1) & 1"
xmath flag_03 "(d5 >> 2) & 1"
xmath flag_04 "(d5 >> 3) & 1"
xmath flag_05 "(d5 >> 4) & 1"
xmath flag_06 "(d5 >> 5) & 1"
xmath flag_07 "(d5 >> 6) & 1"
xmath flag_08 "(d5 >> 7) & 1"
putarray 5 overall_directory_entry flag_01
putarray 6 overall_directory_entry flag_02
putarray 7 overall_directory_entry flag_03
putarray 8 overall_directory_entry flag_04
putarray 9 overall_directory_entry flag_05
putarray 10 overall_directory_entry flag_06
putarray 11 overall_directory_entry flag_07
putarray 12 overall_directory_entry flag_08
get d6 byte current_file_number
callfunction mxm_helper_01 1
if d6 != 0
xmath d6_1_1 "(d6 - 2) / 4"
xmath d6_1_2 "(d6 - 2) % 4"
if d6_1_2 != 0
math d6_1_1 + 1
endif
xmath d6_2 "(d6_1_1 * 4) + 2"
getdstring dn d6 current_file_number
putarray 13 overall_directory_entry dn
xmath d8 "d6_2 - d6"
getdstring dp d8 current_file_number
callfunction mxm_helper_01 1
endif
math current_directory_entry + 1
math overall_directory_entry + 1
endif
next
math final_directory_entries = current_directory_entry
putarray 103 directory_number final_directory_entries
for i3 = parsing_directory_entry < final_directory_entries
xmath last_entry "final_directory_entries - 1"
getarray previous_entry_offset 1 directory_entry_to_fetch_from
getarray next_entry_offset 2 directory_entry_to_fetch_from
getarray entry_offset 3 directory_entry_to_fetch_from
getarray entry_size 4 directory_entry_to_fetch_from
getarray is_read_only 5 directory_entry_to_fetch_from
getarray is_hidden 6 directory_entry_to_fetch_from
getarray is_system_file 7 directory_entry_to_fetch_from
getarray unknown_flag_05 8 directory_entry_to_fetch_from
getarray is_directory 9 directory_entry_to_fetch_from
getarray is_archive 10 directory_entry_to_fetch_from
getarray is_compressed 11 directory_entry_to_fetch_from
getarray is_its_own_thing 12 directory_entry_to_fetch_from
getarray entry_name 13 directory_entry_to_fetch_from
math directory_entry_to_fetch_from + 1
if is_directory = 1
math directory_number + 1
math previous_directory_entry_number = directory_entry_to_fetch_from
math current_directory_size = entry_size
callfunction mxm_helper_03 1
math current_directory_info_offset = fully_realized_entry_offset
putarray 101 directory_number current_directory_info_offset
putarray 102 directory_number current_directory_size
if xbox_type = 1
putarray 109 directory_number data_number_for_single_spot
putarray 110 directory_number data_offset_for_single_spot
endif
putarray 105 directory_number previous_directory_entry_number
xmath future_directory_to_process "current_directory_to_process + 1"
putarray 106 directory_number future_directory_to_process
math next_directory_entry_to_parse = directory_entry_to_fetch_from
putarray 107 directory_number next_directory_entry_to_parse
math next_parsing_directory_entry = i3
putarray 108 directory_number next_parsing_directory_entry
math parsing_directory_entry = 0
putarray 111 directory_number entry_name
math current_directory_to_process + 1
if xbox_type = 1
math target_offset = current_directory_info_offset
callfunction mxm_helper_02 1
math current_file_number = data_number_for_single_spot
math current_directory_info_offset = data_offset_for_single_spot
endif
callfunction parse_mxm 1
else
callfunction mxm_helper_03 1
math file_offset = fully_realized_entry_offset
math file_size = entry_size
if xbox_type = 1
math target_offset = file_offset
callfunction mxm_helper_02 1
math file_offset = data_offset_for_single_spot
print "%data_name% - %file_offset%"
endif
set file_name string ""
math name_number = 0
for
getarray previous_entry_name 111 name_number
string file_name + previous_entry_name
if previous_entry_name == ""
if name_number != 0
string file_name + entry_name
break
endif
else
if name_number != 0
string file_name + "\"
endif
endif
math name_number + 1
next
if is_compressed == 1
math lzx_type = 0
comtype xmemlzx
savepos temp_91
goto file_offset
endian big
get lzx_sign long
get lzx_02 long
get lzx_crc long
get lzx_flags long
if lzx_sign == 0x0ff512ed
math lzx_type = 1
elif lzx_sign == 0xed12f50f
xmath rvs "((lzx_flags & 0xff) << 24) | (((lzx_flags >> 8) & 0xff) << 16) | (((lzx_flags >> 16) & 0xff) << 8) | ((lzx_flags >> 24) & 0xff)"
math lzx_flags == rvs
math lzx_type = 1
endif
endian little
goto temp_91
if lzx_type == 1
math bits_per_size = 0
xmath window_size "1 << ((lzx_flags & 0xf) + 0xf)"
xmath compressed_block_size "0x8000 << ((lzx_flags >> 4) & 3)"
xmath segments "(lzx_flags >> 6) & 0xffff"
xmath bps_number "(lzx_flags >> 0x16) & 3"
xmath lzx_unk_05 "(lzx_flags >> 0x18) & 0xff"
if bps_number == 0
math bits_per_size = 20
elif bps_number == 1
math bits_per_size = 32
endif
if segments == 0
math file_offset + 16
math file_size - 16
log file_name file_offset file_size
else
clog file_name file_offset file_size file_size
endif
endif
else
log file_name file_offset file_size
endif
endif
if i3 == last_entry || final_directory_entries = 0 || i3 == final_directory_entries
if directory_number != 0
getarray parsing_directory_entry 108 directory_number
getarray directory_entry_to_fetch_from 107 directory_number
getarray final_directory_entries 103 directory_number
math directory_number - 1
getarray final_directory_entries 103 directory_number
math current_directory_to_process - 1
if final_directory_entries != 0
math i3 = parsing_directory_entry
endif
math directory_number + 1
putarray 101 directory_number 0
putarray 102 directory_number 0
putarray 103 directory_number 0
putarray 104 directory_number 0
putarray 105 directory_number 0
putarray 106 directory_number 0
putarray 107 directory_number 0
putarray 108 directory_number 0
putarray 109 directory_number 0
putarray 110 directory_number 0
putarray 111 directory_number ""
math directory_number - 1
endif
endif
next i3
endfunction
startfunction mxm_helper_01
savepos p1 current_file_number
xmath i2 "p1 - current_directory_info_offset"
xmath directory_size_limit_1 "current_directory_size / 0x800"
xmath directory_size_limit_2 "current_directory_size % 0x800"
if directory_size_limit_2 != 0
math directory_size_limit_1 + 1
endif
math directory_size_limit_1 * 0x800
if i2 >= directory_size_limit_1
break
endif
endfunction
startfunction mxm_helper_02
if xbox_type = 1
math data_size = 0x14520
xmath data_number_for_single_spot "(target_offset >> 11) / data_size"
string data_name p "Data%04d" data_number_for_single_spot
open FDSE data_name data_number_for_single_spot
xmath data_offset_for_single_spot "target_offset % (data_size << 11)"
endif
if is_directory = 1
math current_file_number = data_number_for_single_spot
endif
math separate_file_number = data_number_for_single_spot
endfunction
startfunction mxm_helper_03
if xbox_type = 0
math padding_number = 0
elif xbox_type = 1
math padding_number = 0
endif
xmath fully_realized_entry_offset "((entry_offset + xbox_file_system_base_number) + padding_number) << 11"
endfunction