17
17
import dmadata
18
18
19
19
20
+ COMPRESSION_METHODS = {
21
+ "yaz0" : crunch64 .yaz0 .compress ,
22
+ "gzip" : crunch64 .gzip .compress ,
23
+ }
24
+
25
+
20
26
def align (v : int ):
21
27
v += 0xF
22
28
return v // 0x10 * 0x10
@@ -48,15 +54,24 @@ def compress_rom(
48
54
rom_data : memoryview ,
49
55
dmadata_start : int ,
50
56
compress_entries_indices : set [int ],
57
+ compression_format : str ,
58
+ pad_to_multiple_of : int ,
59
+ fill_padding_bytes : bool ,
51
60
n_threads : int = None ,
52
61
):
53
62
"""
54
63
rom_data: the uncompressed rom data
55
64
dmadata_start: the offset in the rom where the dmadata starts
56
65
compress_entries_indices: the indices in the dmadata of the segments that should be compressed
66
+ compression_format: the compression format to use
67
+ pad_to_multiple_of: pad the compressed rom to a multiple of this size, in bytes
68
+ fill_padding_bytes: fill the padding bytes with a 0x00 0x01 0x02 ... pattern instead of zeros
57
69
n_threads: how many cores to use for compression
58
70
"""
59
71
72
+ # Compression function
73
+ compress = COMPRESSION_METHODS [compression_format ]
74
+
60
75
# Segments of the compressed rom (not all are compressed)
61
76
compressed_rom_segments : list [RomSegment ] = []
62
77
@@ -80,7 +95,7 @@ def compress_rom(
80
95
if is_compressed :
81
96
segment_data = None
82
97
segment_data_async = p .apply_async (
83
- crunch64 . yaz0 . compress ,
98
+ compress ,
84
99
(bytes (segment_data_uncompressed ),),
85
100
)
86
101
else :
@@ -149,7 +164,6 @@ def compress_rom(
149
164
compressed_rom_size = sum (
150
165
align (len (segment .data )) for segment in compressed_rom_segments
151
166
)
152
- pad_to_multiple_of = 8 * 2 ** 20 # 8 MiB
153
167
compressed_rom_size_padded = (
154
168
(compressed_rom_size + pad_to_multiple_of - 1 )
155
169
// pad_to_multiple_of
@@ -186,9 +200,10 @@ def compress_rom(
186
200
)
187
201
188
202
assert rom_offset == compressed_rom_size
189
- # Pad the compressed rom with the pattern matching the baseroms
190
- for i in range (compressed_rom_size , compressed_rom_size_padded ):
191
- compressed_rom_data [i ] = i % 256
203
+ if fill_padding_bytes :
204
+ # Pad the compressed rom with the pattern matching the baseroms
205
+ for i in range (compressed_rom_size , compressed_rom_size_padded ):
206
+ compressed_rom_data [i ] = i % 256
192
207
193
208
# Write the new dmadata
194
209
offset = dmadata_start
@@ -233,6 +248,25 @@ def main():
233
248
" e.g. '0-1,3,5,6-9' is all indices from 0 to 9 (included) except 2 and 4."
234
249
),
235
250
)
251
+ parser .add_argument (
252
+ "--format" ,
253
+ dest = "format" ,
254
+ choices = COMPRESSION_METHODS .keys (),
255
+ default = "yaz0" ,
256
+ help = "compression format to use (default: yaz0)" ,
257
+ )
258
+ parser .add_argument (
259
+ "--pad-to" ,
260
+ dest = "pad_to" ,
261
+ type = lambda s : int (s , 16 ),
262
+ help = "pad the compressed rom to a multiple of this size, in hex (e.g. 0x800000 for 8 MiB)" ,
263
+ )
264
+ parser .add_argument (
265
+ "--fill-padding-bytes" ,
266
+ dest = "fill_padding_bytes" ,
267
+ action = "store_true" ,
268
+ help = "fill the padding bytes with a 0x00 0x01 0x02 ... pattern instead of zeros" ,
269
+ )
236
270
parser .add_argument (
237
271
"--threads" ,
238
272
dest = "n_threads" ,
@@ -269,13 +303,19 @@ def main():
269
303
range (compress_range_first , compress_range_last + 1 )
270
304
)
271
305
306
+ compression_format = args .format
307
+ pad_to_multiple_of = args .pad_to
308
+ fill_padding_bytes = args .fill_padding_bytes
272
309
n_threads = args .n_threads
273
310
274
311
in_rom_data = in_rom_p .read_bytes ()
275
312
out_rom_data = compress_rom (
276
313
memoryview (in_rom_data ),
277
314
dmadata_start ,
278
315
compress_entries_indices ,
316
+ compression_format ,
317
+ pad_to_multiple_of ,
318
+ fill_padding_bytes ,
279
319
n_threads ,
280
320
)
281
321
out_rom_p .write_bytes (out_rom_data )
0 commit comments