Created
September 15, 2019 01:29
-
-
Save NWPlayer123/5102f95f132206458de8d01a31cb60ef to your computer and use it in GitHub Desktop.
*.bin.gz converter script for Hyrule Warriors (Wii U only prob bc big endian)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
word 0 = chunk_size (read 0x10000 bytes, compress, store) | |
word 1 = num_chunks | |
word 2 = dec_size | |
table, compressed chunk size + 4 (there's a size word at the start of the section) | |
align to 0x80 | |
(write enc_chunk_size, enc_chunk, align to 0x80) * num_chunks | |
''' | |
from struct import unpack, pack | |
from io import BytesIO | |
import zlib, sys | |
def align_128(f): | |
if (f.tell() % 0x80): | |
f.seek(0x80 - (f.tell() % 0x80), 1) | |
def write_128(o): | |
if (o.tell() % 0x80): | |
o.write(b"\x00" * (0x80 - (o.tell() % 0x80))) | |
def full(f): | |
return unpack(">I", f.read(4))[0] | |
def hyrule_decompress(filename, outname): | |
with open(filename, "rb") as f: | |
with open(outname, "wb") as o: | |
header = unpack(">3I", f.read(12)) | |
section_sizes = unpack(">%dI" % header[1], f.read(4*header[1])) | |
align_128(f) | |
for i in range(header[1]): | |
size = full(f) | |
o.write(zlib.decompress(f.read(size))) | |
align_128(f) | |
def hyrule_compress(filename, outname): | |
with open(filename, "rb") as f: | |
with open(outname, "wb+") as o: | |
section_sizes = [] | |
f.seek(0, 2) | |
if not f.tell() % 0x10000: #multiple of 0x10000 | |
section_count = int(f.tell() / 0x10000) | |
else: #add one chunk for overflow bytes | |
section_count = int(f.tell() / 0x10000) + 1 | |
o.write(pack(">I", 0x10000)) | |
o.write(pack(">I", section_count)) | |
o.write(pack(">I", f.tell())) | |
o.write(b"\x00\x00\x00\x00" * section_count) #sizes, will fix later | |
write_128(o) | |
f.seek(0) #start of file, time to start compressing | |
for i in range(section_count): | |
data = BytesIO(zlib.compress(f.read(0x10000), 9)) | |
data.seek(0, 2) | |
section_sizes.append(data.tell()) | |
data.seek(0) | |
o.write(pack(">I", section_sizes[-1])) | |
o.write(data.read()) | |
write_128(o) | |
o.seek(12) #go back to write section table | |
for i in range(section_count): | |
o.write(pack(">I", section_sizes[i] + 4)) | |
if __name__ == "__main__": | |
if len(sys.argv) == 4: | |
if sys.argv[1] == "decompress": | |
hyrule_decompress(sys.argv[2], sys.argv[3]) | |
elif sys.argv[1] == "compress": | |
hyrule_compress(sys.argv[2], sys.argv[3]) | |
else: | |
print('unknown option, expected "decompress" or "compress"') | |
print("hyrule_convert.py <de/compress> <filename> <outname>") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment