perfect_dark/tools/mkgamezips

216 lines
19 KiB
Python
Executable File

#!/usr/bin/env python3
import os
import zlib
"""
mkgamezips - Creates the segments/gamezips.bin from segments/game.bin
game.bin is the compiled game code from ld. This game code is split into
4KB chunks. Each chunk is individually zipped.
The format of the gamezips binary is:
* Array of offsets to each zip, where each offset is 4 bytes and relative to the
start of the gamezips segment.
* After the array of offsets comes the data it points to. Each data consists of:
* A 2 byte checksum of the uncompressed chunk.
* Zip data (starting with 0x1173001000).
* Optional single byte to align it to the next 2 byte boundary. The added
byte is probable garbage data.
"""
def main():
bins = get_bins()
sums = get_sums(bins)
zips = get_zips(bins)
fd = open('build/%s/segments/gamezips.bin' % os.environ['ROMID'], 'wb+')
pos = len(zips) * 4 + 4
# Write pointer array
for zip in zips:
fd.write(pos.to_bytes(4, byteorder='big'))
pos += 2 + len(zip)
if pos % 2 == 1:
pos += 1
# Last pointer points to end
fd.write(pos.to_bytes(4, byteorder='big'))
# Write checksums and compressed data
padding_index = 0
for index, zip in enumerate(zips):
if pos % 2 == 1:
try:
pad_value = padding[os.environ['ROMID']][padding_index]
except IndexError:
pad_value = 0
fd.write(pad_value.to_bytes(1, 'big'))
padding_index += 1
pos += 1
fd.write(sums[index].to_bytes(2, 'big'))
fd.write(zip)
pos += len(zip)
# The previous two bytes are repeated at the end
fd.seek(-2, os.SEEK_CUR)
value = fd.read(2)
fd.write(value)
fd.close()
def get_filecontents(filename):
fd = open(filename, 'rb')
binary = fd.read()
fd.close()
return binary
def get_bins():
binary = get_filecontents('build/%s/segments/game.bin' % os.environ['ROMID'])
return [binary[i:i+0x1000] for i in range(0, len(binary), 0x1000)]
def get_sums(bins):
return [sum(part) for part in bins]
def get_zips(bins):
return [zip(part, index) for part, index in enumerate(bins)]
def sum(binary):
sum = 0
for i in range(0, len(binary), 4):
sum += int.from_bytes(binary[i:i+4], 'big')
return sum & 0xffff
def zip(index, binary):
obj = zlib.compressobj(level=9, wbits=-15)
stream = obj.compress(binary) + obj.flush()
for override in overrides[os.environ['ROMID']]:
if override[0] == index and zlib.crc32(stream) == override[1]:
stream = stream[0:override[2]]
stream += override[3]
break
return b'\x11\x73' + len(binary).to_bytes(3, 'big') + stream
"""
Rare's zip compression method is different to any known version of zlib.
In a few cases (49 out of 2651) their algorithm produces differing files,
where the final match directive chooses a seemingly random backtrack distance.
To get matching zips, decomp patches the zips with this overrides list.
Values are chunk index, crc32 checksum, write offset, write bytes
"""
overrides = {
'ntsc-beta': [],
'ntsc-1.0': [],
'ntsc-final': [],
'pal-final': [
(0x002e, 0x938a5928, 0x091a, b'\xc2\x9f\x7f\x03'),
(0x00e1, 0xae07cb57, 0x0b1b, b'\xe4\xd5\xff\x00'),
(0x00ea, 0xf80d6c37, 0x09ca, b'\xa9\xcb\xff\x02'),
(0x00f6, 0xdbd3f03a, 0x0002, b'\x6d\x6c\x1c\xd5\x15\x3d\x6f\x67\x6d\x6f\xec\xb5\x77\xe3\x6c\x94\x35\x8e\xda\x1d\x3c\x63\x2f\x09\x10\xdb\x81\x2a\x48\x9b\xb2\x80\xb1\x2a\xe2\x80\x0d\xa6\xb8\x52\x2b\x39\x35\x50\x23\x42\x30\xf0\xa3\x8e\x1a\x29\x43\x30\xb1\xd5\xec\x66\x36\x25\xb4\x06\x21\xb4\x24\x76\x92\xca\x6b\x8f\x93\x26\xad\x2d\x59\xaa\x91\x9d\x60\x68\x48\xd3\x12\x2a\x47\xca\x0f\x23\x8c\x40\xc2\x69\xa8\x14\xb5\xa9\x84\xb2\x3d\x77\x76\xed\xb8\x81\xf6\xc7\xe8\xcd\xbc\x77\xdf\xbd\xe7\xdd\x8f\x73\xdf\x38\x69\xac\x1d\xf1\x00\x88\x47\x4c\xcf\x64\xd4\xf4\xb4\xd7\x72\xdc\x64\x3a\x27\x11\x74\x4e\x20\xe4\x1c\x47\x38\x30\xd5\x3a\xe4\xdc\x2c\x67\x51\x2e\x9d\x97\x3b\x4e\xb9\x13\xdf\x22\x97\x5e\x26\xf7\xbb\x6f\xea\x33\xc2\x50\x22\xeb\x8c\x61\xed\x92\xfc\xa2\xfd\xbc\xbc\x2b\xcb\x3d\x86\x3f\x2f\x9b\xc9\xcb\xde\x8c\xf5\x78\x5e\x96\x38\x8c\x8a\xbc\xec\xf8\x32\xd9\xe5\x78\x97\xeb\x0d\xe4\x65\x9d\x65\x18\x96\x63\x5e\xa6\xd7\x1e\x51\x0b\x22\x9b\xfc\x90\xcf\x00\x82\xb5\xfb\x14\x54\x7b\xc4\x0c\x59\xf8\x34\xa6\x59\xc5\x89\x8e\xef\x3e\x69\x28\x68\xc1\x6d\xf0\x70\x2c\x09\x6d\x83\x3f\x16\xb6\x4a\xec\xf0\x5f\xee\xda\xe8\x87\xa7\xc5\xc2\x0a\xfb\xb0\x9a\xb3\x2f\x7a\x53\x5c\xf7\xd4\x0c\xa8\x89\x55\x3a\xb4\x9a\x41\x35\x16\x98\xfa\xf8\xaf\x35\x47\xd4\x49\x59\xef\x75\xd4\x07\xf6\x11\x75\xc9\x1e\x56\x13\xf6\x90\x1a\xa3\xdd\x93\xea\xd3\xa0\x6e\xb4\x50\x6f\x57\xf6\xba\xf1\x31\x4a\x9c\x53\x08\x7a\x40\xac\x11\xe2\x3c\x84\x3e\x7b\x40\x7d\xe1\x0c\xd3\xbf\x43\xe2\xdf\xbe\x7f\x38\x23\x58\x6b\x67\xb8\x9f\x7a\x8c\x52\xa8\xba\x37\x90\x45\x45\xf7\xfd\x46\x09\xa2\xc6\x2c\x14\x7d\x1e\xa4\xec\x5a\x9e\x3b\xc4\x7d\x61\xf7\xec\x79\x7d\x81\xa9\x44\x3b\xe3\x13\xa1\xdd\xdc\xfe\x0a\x44\xeb\x66\xb9\x3f\xdc\x7e\xbf\xf8\x8b\x7b\x22\x8c\x43\x68\xc9\xbf\x8b\x38\x88\x89\xfb\xc2\xb2\xdf\x38\x83\x62\xfb\x04\xcf\x3a\xaa\x2e\x89\x4c\xf5\xa3\xf0\x54\x07\xe1\x71\x46\xd5\xd9\xc0\xe9\xe6\x3f\x3b\x27\xd4\x79\x9e\xef\xaa\x73\x88\xb8\xd3\x6a\x74\x65\x1a\x5a\xac\xcc\x2a\x22\x3e\xe5\x0c\xa9\x51\xf3\xdc\x9a\x63\xc9\x77\x01\xfa\x63\xa1\xe6\xa4\x6a\x1d\x79\x99\x3e\xbf\x08\xef\xc8\x1b\xf0\x72\xde\xc7\x6f\x1f\xbf\xfd\xb1\xb2\xdd\x95\xe6\xb9\xfa\x34\xe7\xfd\xd3\x9d\x88\x37\x86\xe2\x31\x66\x1f\x1e\xf4\xa0\x24\xb5\x1d\x9b\x53\xcf\x23\x16\x2b\xd9\x5d\x89\xc0\x33\x54\xdc\x59\x85\xd2\x4e\x4b\x3d\xd7\xa6\x27\x9f\xad\xcf\x04\x81\x95\xb4\x35\xb1\x28\x97\x78\x1a\x0d\xf0\xd3\x28\x65\x35\xff\x64\xd5\xa2\x3c\xc2\x93\x96\x56\x36\xa3\xab\x11\xee\x7b\x0a\xfe\xc0\xe4\x2d\x31\xdb\x80\x9f\xd8\x27\x04\x5f\xea\xa7\xb4\xe1\xdd\x5d\x19\x2b\xa0\x1d\xcf\x36\xa8\x3d\xed\x55\xf0\x07\x2d\xec\x89\xe8\x38\x14\xd5\x13\x83\x77\x85\x02\xa7\x1f\xfd\x28\xd1\x73\xf7\x2e\x37\xfe\x83\xf4\x69\x07\x34\x63\x10\x9a\x33\xa8\xce\xfa\x71\xe7\x13\xce\x61\xfa\xc3\x51\x13\xb1\x95\x96\x2f\xb6\xca\xf2\x55\xbf\x84\xed\xd5\x75\xe8\xda\xbf\x09\xd8\xbf\x13\xe8\x1d\x51\x1f\xd4\x5d\x46\x56\x62\x25\xb1\x66\xce\x9c\x67\xbe\x9c\xf5\xcc\xb9\xf1\x8f\xd0\xef\x06\x9f\xa8\x1b\xd7\x71\xe6\xec\xe9\x1f\x37\x4b\x0e\xb8\xfe\xa5\xaf\x5d\x1b\xf4\xfd\xfe\xf5\xd4\xb7\x9d\x7e\x1d\x53\x13\xbd\xe3\xcc\xb3\xff\xa7\x6b\x88\xba\x24\xce\x63\x8c\xa9\xe8\x63\xbc\x97\xe7\xb9\xe8\x66\xae\x17\xf1\xdd\xcb\xb1\x80\x63\x01\x47\x2d\x9f\xfb\x95\x12\x07\xfb\x30\xfa\xc4\xae\xd1\x91\xfd\xd7\xe2\x39\x63\x01\xab\x28\x79\x65\x4d\x74\x11\x0b\x02\x9d\x96\x27\xd9\xa5\x27\xdf\xbb\x81\xcb\xb5\x2f\x38\x88\x67\x39\xc6\x6f\xc3\x24\x38\x02\xa7\x5b\x4c\xb7\x06\xf8\x6e\x1f\x52\x0b\xf6\x29\x75\x89\x76\x8a\xa7\xe3\xf8\x41\xf5\x29\x94\x34\x86\x90\xcb\x0b\x0d\x95\xa9\x2d\x68\x4f\x5e\x71\xcf\xe0\x6d\xf9\x04\xdf\xb1\x33\xe8\x49\x6d\x45\x3b\xb0\xc9\xbc\xed\x1d\x68\xad\x11\xac\x68\x28\x04\xe4\x49\x34\x20\x94\x78\x50\x6c\x3d\xba\xd5\x28\x82\x62\xce\x14\x1a\x65\x50\x8b\x6b\x32\x2f\xeb\x32\x17\x53\x96\x2f\x73\x27\xbe\xa6\x8c\x4f\x30\x88\x1d\xf1\xd3\xe3\xf4\x8d\xd8\xa0\xec\xd1\xe9\x26\x34\xbb\xf8\xf8\x2d\x79\x69\x3e\x5b\x9f\x56\xaf\xfb\xd6\x35\x47\xa0\x4d\x3f\x84\xb8\x73\x4a\x5d\x90\xb1\x31\xd4\x7c\x23\x8f\xb7\x32\x3f\xdb\x98\x63\x01\xe6\x57\xf8\x7d\x68\x9b\x66\xaa\x50\x31\x63\xa9\x7f\x77\xeb\xc9\x2b\xf5\xa3\x6e\x1e\x33\x77\x16\xe5\x12\x8d\xcc\xe3\xd2\x17\x20\xb2\xea\xc3\xae\xaa\x45\x79\x94\x75\x59\xea\x4f\xed\xba\xb6\x9e\xfb\x3e\x43\x50\xf2\x38\xd9\x43\x7f\x4a\x1e\x13\x53\x62\x2b\xfc\xf4\xe1\x04\x58\xcf\x2d\x69\x94\x4c\x37\x23\x2e\x32\x46\x21\x6e\x17\x2e\x31\x54\x16\xb8\xaf\xcb\xa8\xeb\x47\x56\xcd\xce\x98\xce\x78\x6e\x9f\xc8\xc5\xc2\xbb\x2b\x6b\xc2\xf5\xe9\xc6\x90\x75\x03\x77\x13\xf1\x6c\x21\xee\x52\xe2\x2e\xd9\x09\xf5\x65\x77\x15\x02\xdd\x16\xeb\x4a\x4f\x0e\xd7\x9f\x74\x71\x0f\xab\xb1\x45\x39\x17\xb7\x9f\xb8\x45\xf6\x6c\x57\xd5\xa2\xbc\x8b\x7b\x96\xf5\x77\x8d\xfb\x06\xe9\xf3\x5c\xfd\x85\x88\x7b\x2c\xe7\x4b\x75\xd5\xfe\xad\x9a\x7b\xdc\xc2\x2f\x25\x8e\xa9\x07\xd0\x2e\xf5\x42\xdf\x2b\xe6\x61\x48\xbd\x1f\xd7\x63\xea\x5e\xab\xe1\xe5\x14\xec\x71\x75\x81\x9c\x3a\xc1\x5a\x1b\x33\x6b\xa1\xcc\x95\xd9\xac\x70\x97\x70\x98\xe4\x8f\x27\x5d\x2b\x35\x20\xdc\x16\xfc\xfc\x04\x6b\xc1\xe5\xd3\x57\x6f\x95\xfe\x40\xbc\x35\x92\x5f\xc2\xdd\xd4\xbb\x4a\xe4\x99\xaf\x17\x5c\x9e\xce\xa8\x31\x77\x9f\xd4\x1f\x6b\x54\xfa\xd4\x74\x03\x9a\xff\x97\x0d\xd1\xf9\xf9\x00\x22\xd4\x59\x2e\x3a\x63\xea\x8f\xc4\x57\x0b\x72\xee\x05\x7b\x3c\xc7\xfb\x37\xef\x5d\xc2\x36\x42\x6c\x47\x88\x6d\x3c\x8f\x6d\x28\x57\x03\x6e\x0c\x1f\x21\x4f\x5e\x43\x70\x63\xa9\x02\x63\xd8\x28\xfe\x60\x0d\xc4\x97\xf2\x5f\xe2\xb2\x85\xfe\x6e\x62\x5c\x2a\x18\xb3\x7b\xea\xd3\xe2\x73\xf1\xb7\xeb\xe7\x8b\x61\x9d\x98\x2a\x13\x2f\x02\x4b\x72\xe1\x5c\xfc\x44\x4e\x62\x2c\x71\x59\x94\x77\xe3\xc9\xb8\x48\x7c\x6c\xd3\xed\x8b\x90\xf8\xb8\xb1\x8c\xa7\x4c\xc1\x14\xf3\x33\xcf\x13\xf5\xe9\xd4\x23\x88\x09\x96\xff\xe2\xe2\x4c\x58\x17\x6c\xc2\x9f\xc4\xe6\x4d\x3d\x8c\xcd\xb4\x5f\x92\xe8\x84\x4f\xde\x13\x4f\xc1\xe7\xea\x2a\x7b\x17\x5a\xd9\x64\x95\x70\x31\xfa\x23\xba\x6b\xa3\xa7\xfe\x18\xe2\x71\x93\xfe\xba\xe4\xfa\x95\x3e\xaa\xd9\x40\x5e\x76\xd8\x1b\xe9\x2b\xb7\x27\xb9\xbd\x3e\xf9\x82\x73\x8c\x31\xc9\xfb\x48\x7c\xe2\xf6\xd9\x8c\xfa\x60\x35\xfb\x8e\xf1\x22\x3c\x41\x78\x87\xb8\xf6\x85\x7a\xa5\x4d\x27\x4f\x1d\xa0\x4f\xfb\xd8\x8f\x7c\xc9\x73\x88\xe0\x61\xdc\x02\xf4\x97\xaf\x9e\x84\xdc\x6c\x80\x22\x94\xb2\x16\xb2\xab\xdf\x85\x97\x35\x8f\xd0\x7d\xf9\xf9\x42\x94\x72\xef\xeb\xf2\x2a\x3a\x10\x4f\x9b\xf0\xf4\x00\xc1\x69\x8d\xdf\x2f\x69\xb0\x4c\x72\x92\x2f\x79\x85\x3a\x9b\x67\x74\x6d\x83\xe8\xed\x2b\x5f\x3d\x77\x93\xde\x4f\x72\x7a\xd7\xe8\xdf\xd4\x9b\xd3\xb7\x5d\xf4\xfd\x5c\xa5\x2d\x93\x3c\xd2\x17\xf3\x59\xc5\xa6\xcf\x9c\x8d\x15\x5b\xc5\xc3\xe5\x00\xf7\x16\x9b\xfb\xb2\xd7\xcd\x87\xcc\x4b\x99\xf5\xe6\x25\xc9\xa9\x64\x03\xe7\xc9\xdd\xb1\x15\x5c\xbb\xcd\x9c\x33\x3a\xcc\x79\x73\x36\x9b\xc5\x6b\xbe\x75\xc3\x77\x53\x25\xf9\x27\xd3\xcd\x11\xde\x67\xc4\x0f\xf4\x3b\x70\xd2\xe5\x25\x6f\xb2\xd0\x9d\xef\x90\x79\x79\xf7\x54\xe7\xe7\x6b\xdc\xf9\x9f\xb8\xf3\x7c\x47\x73\x58\xc7\xcf\x72\x6b\x1e\xc3\xb7\x8e\x6b\x3f\x94\x35\x79\x97\x39\x3c\x45\x5b\x2d\xdc\x1f\x89\x98\xf2\x4e\x9b\x72\xce\xe2\x4c\x95\x39\x1f\x2b\x60\x5f\x19\x34\xe7\xf1\x51\x8e\x0b\x71\x90\xb2\xab\xa8\xf3\xa0\x2b\xe7\xfa\x61\xb8\x35\x77\xb6\x4c\xcd\x7c\x6e\x34\xe7\xbd\x81\xa9\xbf\x05\x25\xf6\xb1\x0a\xab\xc8\xbe\x67\x4d\x34\x56\xca\xf3\x0d\x7f\x96\xe6\x5d\x67\x92\xfc\x98\xe3\x1b\xf2\x24\xc7\xfc\x37\xb9\xe5\x72\x58\xb7\x8f\xb2\x56\xb6\x7b\xaf\xc9\xdd\xa4\x75\x01\x1b\x53\xd7\xc8\x3f\x5f\x42\xf8\xe1\x6a\x72\x07\x82\xbc\xef\x78\x1e\x03\xee\x90\xf9\x27\x22\x58\xef\xae\x3f\x5f\xfa\x55\xac\xe4\x0f\x10\xae\x47\xa0\xc3\x2a\xb0\x60\xf0\x7e\x57\x94\xd9\x02\x64\x1e\x86\xd7\x0e\x2f\xb3\x1f\x9e\x99\x5c\xe4\x5d\x8e\x3a\xc7\xfc\xf7\xfb\xa8\xd9\xe0\x8b\x1b\x3d\xf0\xa9\xcb\x51\x3d\x30\x75\x5e\x01\xb5\xa6\xd1\x04\x9f\x93\xe1\x39\x4a\x7e\xef\xea\x17\x7d\xa2\xd7\x3e\xef\xe9\xd9\xeb\x2d\xbc\x8b\xf1\xfe\xc5\xde\x82\xc2\xef\xc9\xf7\x19\x7f\xb8\xf5\x4c\x59\xb8\x6d\x6f\x61\x61\x2d\xe7\xdf\xdb\x5b\x54\x58\x2f\xe7\x11\x3f\xb8\x78\xa5\xff\x8c\xab\xb9\xe9\x2f\x58\x6b\x56\xbf\xd9\xe8\x4b\x7f\x3f\x57\xfb\x9e\x5f\x89\x5d\x59\xe3\x9d\xab\x96\xcf\xbc\x23\x3d\x73\x5c\x1d\x4c\x5d\x41\xc1\x8f\xe6\xd4\xe7\xee\x9d\x6c\x20\xdf\x43\x87\xd9\x43\x79\xa7\x49\x34\xe1\x49\xca\x46\x55\xa6\x4d\x37\x77\xb0\xbe\x46\xd4\xed\xd2\x67\x38\x37\x29\xbd\x6a\xb1\x27\xb9\x3d\x4b\xfa\xcc\xb8\xdc\x79\xea\xc7\x58\xcf\x05\xac\xf9\xcd\xbc\xe3\x08\xcf\x95\x92\x97\xbd\xf2\x2d\xb5\xee\xd6\xf4\x32\x1e\x40\x72\xa9\xa6\xc9\xa3\x2a\xe2\xd6\x29\xe5\xc9\x83\x11\xe2\x9d\x97\xde\xa3\xb6\x75\x19\x77\xcf\xe2\x5e\x67\x4c\x45\x56\x45\x98\x7a\x3b\x2d\x5d\xf8\x8e\x67\x3f\x28\xf7\xd4\xe4\x65\xb8\xb9\x60\x7c\x96\xcd\xd6\x65\xbc\x58\x6d\xf1\x6e\x72\x86\x3d\x6d\x48\x5d\x20\x2f\xe7\xee\x0c\x53\xc9\xfd\xee\x1d\x42\xb8\x60\x44\x7d\x85\x20\xe3\x53\xeb\xc6\x27\xae\x2e\x46\xf5\x9e\x81\xc2\x76\xf6\x86\x5a\xf2\xfa\x02\xf7\xcd\xab\xf9\x76\x9d\x71\xa9\xa5\x4f\x8c\xd7\x34\x14\xf0\xfc\xca\x1e\x47\xdf\xea\x29\xac\x80\xd5\x69\x52\x76\x4e\xdb\x10\xac\x32\xee\xcf\x5e\x57\x7b\xdc\x5c\xd5\xd4\xa1\x49\x5d\xf3\xb7\x55\xf1\x6e\x69\xa4\x46\x0a\x3b\x85\x9f\x2a\x26\x55\x6f\x9e\x9b\x7a\x9c\x41\x58\xf6\x18\x2c\xfa\x2f\x44\x1b\x93\xbf\xf1\x17\x3e\x2d\x58\xe8\xef\x05\xb5\x8f\x35\xa4\xb1\xb7\x5f\x0c\xea\xa9\x47\xbc\xd7\x93\x19\x89\x5c\xd4\x24\xa9\x5a\xc9\x7d\xf0\x69\x81\x49\xdd\xbd\x8f\x96\xd4\xea\xce\x11\x45\x4e\xc3\xae\xe4\x08\x7c\x40\xc4\x94\xff\x9e\xd6\x73\x8c\xef\x18\x76\x31\xa6\xa1\xa4\x03\x3f\xff\x9b\xb4\x96\x39\x68\xee\x5c\x86\xf6\x38\x0a\xc7\x90\xff\x6e\x7f\xc5\xe3\xcd\xd2\xfe\x57\xc4\x77\x30\x78\x1f\x6b\xce\x43\xfe\xdf\x11\xd5\x8d\xc1\x42\xf9\xf7\x30\x6c\x07\xbb\x8e\x8e\xab\xfe\xa3\x87\xd5\x9b\x47\x87\xd5\x5b\xaf\x2e\x78\xbf\xb6\x47\xd0\x03\x2d\xc4\x22\x9e\xd6\x78\x46\x5d\xed\xf0\xad\xd3\x10\x34\xa5\x46\x8f\x66\xd4\xdb\x86\x57\xfc\xa3\x2e\xf4\x0e\xab\xb7\xe9\x9b\xb0\x76\xeb\x8d\xfa\x95\x35\xf2\xed\xd2\x7b\xab\xa5\x36\x52\xdf\x2e\x62\x88\xd2\xdf\x21\xf6\xd0\x05\xde\x63\xd2\xcc\x97\x0c\x63\x3c\xb0\xb2\x1d\x65\xc4\x7c\x8c\x58\x23\xbd\xa3\xea\xd7\xec\xe9\xd5\x6e\x7c\x1b\xb3\x59\x9e\x3b\x28\x39\xe9\x1c\x66\x5c\x0f\x23\x2c\xdc\x2f\xb1\xf5\x94\x6d\xd2\xdd\xd8\x8e\xab\x30\x75\x5e\xb5\xef\x80\xb7\xce\x89\x83\x3e\x68\xe4\x5c\x68\x0d\xf0\x80\xf8\xf9\xf4\x28\xe2\xd4\xd9\x4f\x9d\x6f\xc9\x9d\xa5\xf7\xb8\x7a\x93\xf7\xce\xb7\xd5\xf9\x94\x2e\xff\x79\x0f\x02\x2b\xb4\xba\x7e\xfd\x80\x93\xeb\x4d\x08\xb0\xff\x04\x6e\xf4\x1f\xb9\xbb\x30\x57\x67\x0e\x9c\xc5\x66\xc3\x83\xd8\x81\x0f\x49\x49\x7b\x50\x11\xd3\x76\x57\x1a\x1d\xf5\xe9\xe4\x19\xe6\x37\x66\xca\xb1\x93\xff\x0c\x4f\x22\xaa\x0e\xa1\x02\xe8\x2e\xc7\xf3\x93\x6e\x9e\xdb\x05\x88\x0a\xf7\xb8\x77\xaa\x97\xa3\x46\xfe\x9e\xb5\x5b\xce\xc7\xbb\x6c\x0c\xf1\xa8\x49\xbe\xf6\xf1\x3f\x21\x92\xd8\x2e\xbc\xf7\x4f\xd4\x77\x6b\x59\x4f\x13\xf5\x84\xbb\x2c\xa3\x41\x62\x3e\x53\xbe\x71\xbd\x96\x45\xc9\xb3\x96\x7a\xa7\xdb\x54\x7f\x6f\x37\x33\x4d\xbc\x97\xb2\x55\xd7\x6f\xe0\x7c\xa0\xcb\xf2\x54\x88\xdd\xb6\xf2\xba\xe7\xf8\x5d\x3a\xc5\xff\x98\x76\x93\xfa\x1f\xa3\x9c\x57\xfe\x0d\xfe\x03'),
(0x00f8, 0xb681689e, 0x0994, b'\xf8\xf7\xbf'),
(0x0117, 0x230a2b89, 0x068f, b'\x77\xc6\xfe\x0f'),
(0x0144, 0x7965231d, 0x09b8, b'\xce\xeb\xff\x02'),
(0x017c, 0x328ab6aa, 0x0a99, b'\x6a\xd4\x7f\x01'),
(0x0199, 0x98c16cb9, 0x0a57, b'\xd1\xff\x00'),
],
}
padding = {
'ntsc-beta': [],
'ntsc-1.0': [
0x00, 0x00, 0x00, 0x73, 0x75, 0x47, 0xa4, 0x79,
0x91, 0x1e, 0xd8, 0xd8, 0x7b, 0xe2, 0x13, 0x51,
0xaa, 0x2a, 0xa1, 0x5a, 0xbd, 0x24, 0x87, 0x0d,
0xdc, 0x50, 0xd3, 0xe2, 0x39, 0x9f, 0x1a, 0x86,
0x73, 0xc5, 0x72, 0xdd, 0xc8, 0xa9, 0xd9, 0x21,
0xf2, 0xd4, 0x66, 0xa5, 0xbb, 0xfa, 0xbe, 0x6d,
0xc4, 0xce, 0x63, 0x6f, 0xba, 0xf7, 0xe3, 0xc9,
0xd4, 0xd3, 0xfb, 0x9c, 0xff, 0x76, 0xcf, 0x20,
0x6e, 0xbb, 0x2c, 0x90, 0xd3, 0xc1, 0xc4, 0x9f,
0xb4, 0x70, 0x38, 0xe3, 0x22, 0x3e, 0xec, 0x5c,
0xa4, 0xdc, 0x39, 0xe8, 0x8b, 0x5e, 0xcc, 0x3e,
0xa2, 0x62, 0x87, 0x20, 0xd3, 0x05, 0x1c, 0xa5,
0xd4, 0xca, 0x0e, 0xef, 0xed, 0x23, 0x67, 0xc6,
0xff, 0x69, 0x66, 0x66, 0x9d, 0xaf, 0xb1, 0x2e,
0x61, 0xc7, 0x9c, 0x56, 0x60, 0xe6, 0x95, 0xf8,
0x21, 0x79, 0x93, 0x37, 0xe1, 0x8c, 0xb2, 0xcf,
0x26, 0x01, 0x9d, 0xf8, 0x6a, 0x8b, 0x71, 0x79,
0x57, 0xef, 0xaf, 0xb2, 0x27, 0xad, 0x4a, 0xf2,
0xcc, 0x46, 0x3e, 0x34, 0x0f, 0x31, 0xec, 0xe3,
0xc2, 0x11, 0xee, 0xb1, 0x4e, 0x3b, 0xcc, 0xd1,
0xad, 0x4f, 0xbe, 0xef, 0x7b, 0x39, 0xd6, 0x97,
0xf5, 0xf7, 0x02, 0xa8, 0x36, 0xa1, 0xd7, 0x50,
0xd6, 0xaf, 0xdf, 0xb9, 0x22, 0x73, 0x4a, 0x37,
0xf9, 0x46, 0x9d, 0x30, 0x1d, 0x1a, 0x13, 0x1c,
0x9a, 0xa1, 0x22, 0xa7, 0xb4, 0x9b, 0x88, 0x19,
0xd4, 0x00, 0xb9, 0xcf, 0xe6, 0xce, 0xf2, 0xd8,
0xfd, 0x9c, 0x26, 0xe9, 0x4c, 0x59, 0x3d, 0xa6,
0xa6, 0xa6, 0x07, 0x29, 0x24, 0x7a, 0xba,
],
'ntsc-final': [
0x00, 0xc2, 0xf9, 0x3a, 0x4d, 0x18, 0x8a, 0x07,
0x4c, 0x68, 0x38, 0x17, 0x3c, 0x94, 0x98, 0x25,
0x82, 0x6f, 0xf7, 0x2e, 0x41, 0xed, 0xe4, 0x88,
0xf5, 0x48, 0x59, 0x5a, 0x7a, 0xb4, 0x3b, 0xf9,
0xc7, 0xc7, 0xab, 0xf6, 0xef, 0x23, 0x8b, 0x6a,
0x58, 0xb0, 0x27, 0x84, 0x77, 0x88, 0xe1, 0x34,
0xf5, 0xf4, 0xa9, 0xb9, 0x30, 0x8a, 0x64, 0x23,
0xb5, 0x6c, 0x87, 0xff, 0xd4, 0x84, 0xe4, 0x7c,
0x93, 0xa0, 0x5b, 0x41, 0x28, 0xfa, 0x65, 0x3e,
0xad, 0x51, 0x35, 0xf9, 0xec, 0x6a, 0xe9, 0xaf,
0xe0, 0x7f, 0xe5, 0x8e, 0x0e, 0x6b, 0x42, 0x97,
0xee, 0xad, 0x5d, 0xba, 0x91, 0x7c, 0xd6, 0x91,
0xb3, 0xbd, 0x5f, 0x3d, 0x48, 0xd1, 0x37, 0xba,
0xfc, 0x83, 0x51, 0x2b, 0xcb, 0x2f, 0x6b, 0xbf,
0xb0, 0xe5, 0x9c, 0xac, 0x1d, 0x63, 0xcb, 0xa5,
0x5e, 0x66, 0x24, 0x2d, 0xe3, 0x86, 0x3e, 0x0c,
0xcf, 0x1a, 0x57, 0xc9, 0x4b, 0x29, 0x70, 0x31,
0xbb, 0x55, 0xc4, 0x42, 0x62, 0x5e, 0x9a, 0xa0,
0xff, 0x41, 0xf5, 0x62, 0x9f, 0xc9, 0x61, 0xee,
0xbe, 0x7b, 0x0e, 0xf2, 0xd7, 0xf1, 0x90, 0x69,
0xfa, 0xff, 0xf7, 0xb1, 0x3a, 0x27, 0xac, 0xc2,
0x57, 0x7e, 0xcc, 0x92, 0xdd, 0x2d, 0x63, 0xa0,
0x53, 0x74, 0x35, 0xbb, 0x24, 0xde, 0x6d, 0xbb,
0x2c, 0xe5, 0xff, 0xeb, 0x37, 0xde, 0xd0, 0x6e,
0x96, 0xfa, 0xbe, 0x79, 0xe3, 0x1e, 0x7f, 0xff,
0x67, 0x86, 0x86, 0x86, 0x15, 0x6e,
],
'pal-final': [
0x00, 0x00, 0x00, 0x73, 0xe6, 0xc7, 0xd1, 0xe6,
0x7c, 0x76, 0xec, 0xdc, 0x9a, 0xf1, 0x6e, 0x54,
0x05, 0xd9, 0x72, 0x53, 0x7b, 0xb4, 0xbe, 0x5d,
0xaf, 0xf8, 0x3e, 0xcc, 0x53, 0x8a, 0x75, 0x17,
0x26, 0x40, 0x29, 0x29, 0x5f, 0xf3, 0x44, 0xc6,
0xf9, 0xfe, 0x57, 0x1b, 0xf6, 0x7e, 0x45, 0xfa,
0x9e, 0x75, 0x67, 0xb7, 0x71, 0xb2, 0x9f, 0x19,
0x02, 0xb2, 0xc5, 0x7c, 0xe2, 0x5b, 0xbb, 0xef,
0xb2, 0x0f, 0xbe, 0x9a, 0x9c, 0x6b, 0x0d, 0x9a,
0xfd, 0xed, 0x6d, 0xee, 0xfb, 0x7c, 0x1b, 0xf7,
0xcf, 0x53, 0xac, 0xf3, 0xeb, 0xcd, 0x8a, 0x4f,
0x18, 0x4c, 0x5d, 0xeb, 0x52, 0x28, 0x9b, 0xf4,
0x7d, 0xbf, 0x3f, 0xe9, 0x8f, 0x12, 0x6c, 0x67,
0xd7, 0x82, 0x6a, 0xdd, 0x4a, 0x9e, 0x5c, 0x23,
0x7c, 0x18, 0x8a, 0x7d, 0x87, 0x6e, 0x7b, 0x5f,
0xd5, 0x9d, 0xd4, 0x3f, 0x9f, 0xf9, 0xb6, 0xf6,
0xd4, 0x9f, 0x71, 0x21, 0x9d, 0xd1, 0xc0, 0x86,
0x63, 0x6b, 0xd8, 0x87, 0xac, 0x8c, 0x53, 0x6d,
0xac, 0xc9, 0xbc, 0x8e, 0xdf, 0x13, 0x73, 0x45,
0x5a, 0xf7, 0x3b, 0xbb, 0x72, 0x66, 0xa5, 0xc0,
0xb6, 0x9b, 0xe5, 0x98, 0x0b, 0x27, 0xed, 0xc2,
0x7f, 0x78, 0xb6, 0x39, 0x26, 0xb6, 0x19, 0x7a,
0x77, 0xea, 0x70, 0x79, 0xff, 0xd7, 0x0f, 0x5f,
0x53, 0xea, 0x78, 0x30, 0x9b, 0xd2, 0x51, 0x62,
0xd7, 0xb9, 0x7a, 0xfd, 0x9d, 0x10, 0x64, 0x72,
0x35, 0x3b, 0xa9, 0xeb, 0x65, 0x8e, 0x25, 0xe8,
0xe7, 0x51, 0xfa, 0x1f, 0xd1, 0xf7, 0x35, 0x82,
0x4d, 0xf5, 0xdd, 0x55, 0x23, 0x9b, 0x15, 0xc8,
0x5a, 0xa2, 0x63, 0x63, 0x63, 0x6f,
],
}
main()