comparison nes.py @ 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
comparison
equal deleted inserted replaced
123:7b3cb931be9c 124:a74c65cd0ce3
5 from colours import TILE_PALETTES, palette_to_qt 5 from colours import TILE_PALETTES, palette_to_qt
6 from exceptions import ROMOpeningError 6 from exceptions import ROMOpeningError
7 7
8 8
9 class NES_ROM(object): 9 class NES_ROM(object):
10 def __init__(self, filename): 10 def __init__(self, filename=None, initial_position=0, palettes=None):
11 self.filename = filename 11 self.filename = filename
12 12
13 # To track circular rotation of the PRG bytes, in case the 13 # To track circular rotation of the PRG bytes, in case the
14 # tiles aren't aligned to 16-byte boundaries and the user 14 # tiles aren't aligned to 16-byte boundaries and the user
15 # moves it. 15 # moves it.
16 self.initial_position = 0 16 self.initial_position = initial_position
17 self.read_rom() 17
18 18 self.parse_rom(palettes)
19 def read_rom(self): 19
20 if self.filename.lower().endswith('.nes'): 20 @staticmethod
21 with open(self.filename, 'rb') as rom: 21 def read_ines(filename):
22 self.ines = rom.read() 22 if filename.lower().endswith('.nes'):
23 elif self.filename.lower().endswith('.zip'): 23 with open(filename, 'rb') as rom:
24 ines = rom.read()
25 elif filename.lower().endswith('.zip'):
24 try: 26 try:
25 with ZipFile(self.filename, 'r') as rom: 27 with ZipFile(filename, 'r') as rom:
26 nesfiles = [f for f in rom.filelist if not f.is_dir() 28 nesfiles = [f for f in rom.filelist if not f.is_dir()
27 and f.filename.lower().endswith(".nes")] 29 and f.filename.lower().endswith(".nes")]
28 if len(nesfiles) != 1: 30 if len(nesfiles) != 1:
29 raise ROMOpeningError( 31 raise ROMOpeningError(
30 "Zipfile does not contain exactly one NES file" 32 "Zipfile does not contain exactly one NES file"
31 ) 33 )
32 self.ines = rom.open(nesfiles[0]).read() 34 ines = rom.open(nesfiles[0]).read()
33 except BadZipFile as exc: 35 except BadZipFile as exc:
34 raise ROMOpeningError(f"Problem opening zip file:\n{exc}") 36 raise ROMOpeningError(f"Problem opening zip file:\n{exc}")
35 else: 37 else:
36 raise ROMOpeningError( 38 raise ROMOpeningError(
37 f"Cannot deduce file type from file name:\n\n" 39 f"Cannot deduce file type from file name:\n\n"
38 f"{self.filename.split('/')[-1]}" 40 f"{filename.split('/')[-1]}"
39 ) 41 )
42 return ines
43
44 def parse_rom(self, palettes):
45 self.ines = self.read_ines(self.filename)
40 46
41 self.header = self.ines[0:16] 47 self.header = self.ines[0:16]
42 body = self.ines[16:] 48 body = self.ines[16:]
43 PRG_size = self.header[4]*16384 49 PRG_size = self.header[4]*16384
44 CHR_size = self.header[5]*8192 50 CHR_size = self.header[5]*8192
45 51
46 self.PRG = body[0:PRG_size] 52 self.PRG = body[0:PRG_size]
53
47 if CHR_size == 0: 54 if CHR_size == 0:
48 # No chr, just read the whole ROM as tiles 55 # No chr, just read the whole ROM as tiles
49 self.CHR = None 56 self.CHR = None
50 self.tile_data = list(body) 57 self.tile_data = list(body)
51 else: 58 else:
52 self.CHR = body[PRG_size:PRG_size+CHR_size] 59 self.CHR = body[PRG_size:PRG_size+CHR_size]
53 self.tile_data = list(self.CHR) 60 self.tile_data = list(self.CHR)
54 61
55 self.tiles = [Tile(idx, self.tile_data) 62 self.rotate_tile_data(self.initial_position)
56 for idx in range(0, len(self.tile_data)//16)] 63
64 numtiles = len(self.tile_data)//16
65 if not palettes:
66 palettes = [None]*numtiles
67 elif len(palettes) != numtiles:
68 raise ValueError(
69 "JSON data does not contain the same amount of tile palattes as tiles in ROM"
70 )
71
72 self.tiles = [Tile(idx, self.tile_data, palette=palette)
73 for (idx, palette) in enumerate(palettes)]
57 74
58 def update_tiles(self): 75 def update_tiles(self):
59 for tile in self.tiles: 76 for tile in self.tiles:
60 tile.clear_caches() 77 tile.clear_caches()
61 78