Mercurial > hg > tilerswift
changeset 124:a74c65cd0ce3 draft
NES_ROM: refactor ctor and read_rom to allow initial position and palettes
This is a prelude to allowing restoring ROMs from json data.
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Wed, 02 Oct 2019 09:13:48 -0400 |
parents | 7b3cb931be9c |
children | 1117edef8b2b |
files | nes.py |
diffstat | 1 files changed, 30 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/nes.py +++ b/nes.py @@ -7,36 +7,42 @@ class NES_ROM(object): - def __init__(self, filename): + def __init__(self, filename=None, initial_position=0, palettes=None): self.filename = filename # To track circular rotation of the PRG bytes, in case the # tiles aren't aligned to 16-byte boundaries and the user # moves it. - self.initial_position = 0 - self.read_rom() + self.initial_position = initial_position + + self.parse_rom(palettes) - def read_rom(self): - if self.filename.lower().endswith('.nes'): - with open(self.filename, 'rb') as rom: - self.ines = rom.read() - elif self.filename.lower().endswith('.zip'): + @staticmethod + def read_ines(filename): + if filename.lower().endswith('.nes'): + with open(filename, 'rb') as rom: + ines = rom.read() + elif filename.lower().endswith('.zip'): try: - with ZipFile(self.filename, 'r') as rom: + with ZipFile(filename, 'r') as rom: nesfiles = [f for f in rom.filelist if not f.is_dir() and f.filename.lower().endswith(".nes")] if len(nesfiles) != 1: raise ROMOpeningError( "Zipfile does not contain exactly one NES file" ) - self.ines = rom.open(nesfiles[0]).read() + ines = rom.open(nesfiles[0]).read() except BadZipFile as exc: raise ROMOpeningError(f"Problem opening zip file:\n{exc}") else: raise ROMOpeningError( f"Cannot deduce file type from file name:\n\n" - f"{self.filename.split('/')[-1]}" + f"{filename.split('/')[-1]}" ) + return ines + + def parse_rom(self, palettes): + self.ines = self.read_ines(self.filename) self.header = self.ines[0:16] body = self.ines[16:] @@ -44,6 +50,7 @@ CHR_size = self.header[5]*8192 self.PRG = body[0:PRG_size] + if CHR_size == 0: # No chr, just read the whole ROM as tiles self.CHR = None @@ -52,8 +59,18 @@ self.CHR = body[PRG_size:PRG_size+CHR_size] self.tile_data = list(self.CHR) - self.tiles = [Tile(idx, self.tile_data) - for idx in range(0, len(self.tile_data)//16)] + self.rotate_tile_data(self.initial_position) + + numtiles = len(self.tile_data)//16 + if not palettes: + palettes = [None]*numtiles + elif len(palettes) != numtiles: + raise ValueError( + "JSON data does not contain the same amount of tile palattes as tiles in ROM" + ) + + self.tiles = [Tile(idx, self.tile_data, palette=palette) + for (idx, palette) in enumerate(palettes)] def update_tiles(self): for tile in self.tiles: