Add preliminary support for ZSPR Format

This commit is contained in:
Kevin Cathcart 2017-12-07 19:43:22 -05:00
parent 1528489201
commit 1d223dc0b8
1 changed files with 54 additions and 3 deletions

57
Rom.py
View File

@ -7,6 +7,7 @@ import random
import json import json
import hashlib import hashlib
import logging import logging
import struct
JAP10HASH = '03a63945398191337e896e5771f77173' JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = '1deebb05eccefd2ab68297c6e9c0d25f' RANDOMIZERBASEHASH = '1deebb05eccefd2ab68297c6e9c0d25f'
@ -97,8 +98,9 @@ class Sprite(object):
default_glove_palette = [246, 82, 118, 3] default_glove_palette = [246, 82, 118, 3]
def __init__(self, filename): def __init__(self, filename):
filedata = bytearray(open(filename, 'rb').read()) with open(filename, 'rb') as file:
self.valid=True filedata = bytearray(file.read())
self.valid = True
if len(filedata) == 0x7000: if len(filedata) == 0x7000:
# sprite file with graphics and without palette data # sprite file with graphics and without palette data
self.sprite = filedata[:0x7000] self.sprite = filedata[:0x7000]
@ -109,13 +111,40 @@ class Sprite(object):
self.sprite = filedata[:0x7000] self.sprite = filedata[:0x7000]
self.palette = filedata[0x7000:] self.palette = filedata[0x7000:]
self.glove_palette = filedata[0x7036:0x7038] + filedata[0x7054:0x7056] self.glove_palette = filedata[0x7036:0x7038] + filedata[0x7054:0x7056]
elif len(filedata) == 0x707C:
# sprite file with graphics and palette data including gloves
self.sprite = filedata[:0x7000]
self.palette = filedata[0x7000:0x7078]
self.glove_palette = filedata[0x7078:]
elif len(filedata) in [0x100000, 0x200000]: elif len(filedata) in [0x100000, 0x200000]:
# full rom with patched sprite, extract it # full rom with patched sprite, extract it
self.sprite = filedata[0x80000:0x87000] self.sprite = filedata[0x80000:0x87000]
self.palette = filedata[0xDD308:0xDD380] self.palette = filedata[0xDD308:0xDD380]
self.glove_palette = filedata[0xDEDF5:0xDEDF9] self.glove_palette = filedata[0xDEDF5:0xDEDF9]
elif filedata.startswith(b'ZSPR'):
result = self.parse_zspr(filedata,1)
print(result)
if result is None:
self.valid = False
return
(sprite, palette) = result
if len(sprite) != 0x7000:
self.valid = False
return
self.sprite = sprite
if len(palette) == 0:
self.palette = None
self.glove_palette = None
elif len(palette) == 0x78:
self.palette = palette
self.glove_palette = None
elif len(palette) == 0x7C:
self.palette = palette[:0x78]
self.glove_palette = palette[0x78:]
else:
self.valid = False
else: else:
self.valid=False self.valid = False
def decode8(self, pos): def decode8(self, pos):
arr=[[0 for _ in range(8)] for _ in range(8)] arr=[[0 for _ in range(8)] for _ in range(8)]
@ -144,6 +173,28 @@ class Sprite(object):
arr[y+8][x+8] = bottom_right[y][x] arr[y+8][x+8] = bottom_right[y][x]
return arr return arr
def parse_zspr(self, filedata, expected_kind):
headerstr = "<4xBHHIHIHH6x"
headersize = struct.calcsize(headerstr)
if len(filedata) < headersize:
return None
(version, csum, icsum, sprite_offset, sprite_size, palette_offset, palette_size, kind) = struct.unpack_from(headerstr,filedata)
if version not in [1]:
#ZSPR Version not supported
return None
if kind != expected_kind:
return None
real_csum = sum(filedata) % 0x10000
if real_csum != csum or real_csum ^ 0xFFFF != icsum:
#invalid checksum
pass
sprite = filedata[sprite_offset:sprite_offset + sprite_size]
palette = filedata[palette_offset:palette_offset + palette_size]
#FIXME: Check lengths of those byte arrays against the _size values
return (sprite, palette)
def decode_palette(self): def decode_palette(self):
"Returns the palettes as an array of arrays of 15 colors" "Returns the palettes as an array of arrays of 15 colors"
def array_chunk(arr,size): def array_chunk(arr,size):