annotate nes.py @ 109:e3ffae4d7528

NES_ROM: allow ROMs to be provided as zip files Bit barebones, but it works well enough for my collection. Some error handling is now enabled. Starting to look like a real program!
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Thu, 19 Sep 2019 17:05:15 -0400
parents d5e69fe5c81a
children 872637684299
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
109
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
1 from zipfile import ZipFile, BadZipFile
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
2
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
3 from PyQt5 import QtGui as QG
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
4
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
5 from colours import TILE_PALETTES, palette_to_qt
109
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
6 from exceptions import ROMOpeningError
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
7
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
8
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
9 class NES_ROM(object):
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
10 def __init__(self, filename):
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
11 self.filename = filename
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
12 # To track circular rotation of the ROM bytes, in case the
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
13 # tiles aren't aligned to 16-byte boundaries and the user
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
14 # moves it.
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
15 self.initial_position = 0
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
16 self.read_rom()
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
17
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
18 def read_rom(self):
109
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
19 if self.filename.lower().endswith('.nes'):
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
20 with open(self.filename, 'rb') as rom:
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
21 self.ines = rom.read()
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
22 elif self.filename.lower().endswith('.zip'):
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
23 try:
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
24 with ZipFile(self.filename, 'r') as rom:
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
25 nesfiles = [f for f in rom.filelist if not f.is_dir()
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
26 and f.filename.lower().endswith(".nes")]
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
27 if len(nesfiles) != 1:
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
28 raise ROMOpeningError(
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
29 "Zipfile does not contain exactly one NES file"
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
30 )
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
31 self.ines = rom.open(nesfiles[0]).read()
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
32 except BadZipFile as exc:
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
33 raise ROMOpeningError(f"Problem opening zip file:\n{exc}")
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
34 else:
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
35 raise ROMOpeningError(
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
36 f"Cannot deduce file type from file name:\n\n"
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
37 f"{self.filename.split('/')[-1]}"
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
38 )
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
39
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
40 self.header = self.ines[0:16]
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
41 body = self.ines[16:]
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
42 PRG_size = self.header[4]*16384
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
43 CHR_size = self.header[5]*8192
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
44
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
45 self.PRG = body[0:PRG_size]
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
46 if CHR_size == 0:
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
47 # No chr, just read the whole ROM as tiles
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
48 self.tile_data = list(body)
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
49 self.CHR = None
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
50 else:
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
51 self.CHR = body[PRG_size:PRG_size+CHR_size]
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
52 self.tile_data = list(self.CHR)
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
53
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
54 self.tiles = [Tile(i, self.tile_data)
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
55 for i in range(0, len(self.tile_data)//16)]
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
56
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
57 def update_tiles(self):
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
58 for tile in self.tiles:
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
59 tile.clear_caches()
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
60
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
61 def byte_forward(self):
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
62 x = self.tile_data.pop(0)
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
63 self.tile_data.append(x)
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
64 self.initial_position -= 1
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
65 self.update_tiles()
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
66
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
67 def byte_backward(self):
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
68 x = self.tile_data.pop(-1)
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
69 self.tile_data.insert(0, x)
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
70 self.initial_position += 1
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
71 self.update_tiles()
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
72
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
73
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
74 class Tile(object):
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
75
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
76 default_palette = TILE_PALETTES["Primary"]
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
77
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
78 def __init__(self, index, tile_data):
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
79 super().__init__()
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
80
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
81 self.index = index
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
82 self.tile_data = tile_data
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
83 self.clear_caches()
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
84 self.set_palette(self.default_palette.copy())
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
85
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
86 def __repr__(self):
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
87 num_to_ascii = {0: " ", 1: ".", 2: "o", 3: "#"}
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
88 return "_"*10 + "\n" + "\n".join(
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
89 "[" + "".join([num_to_ascii[val] for val in row]) + "]"
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
90 for row in self.tile
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
91 ) + "\n" + "-"*10
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
92
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
93 def clear_caches(self):
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
94 self._raw_tile = None
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
95 self._tile = None
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
96 self._pixmap = None
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
97
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
98 def set_palette(self, new_palette):
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
99 self.palette = new_palette.copy()
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
100 self.update_pixmap()
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
102 def update_pixmap(self):
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
103 img_data = bytes(sum(self.tile, []))
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
104 image = QG.QImage(img_data, 8, 8, QG.QImage.Format_Indexed8)
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
105 image.setColorTable(palette_to_qt(self.palette))
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
106 self._pixmap = QG.QPixmap(image)
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
107
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
108 def get_pixmap(self):
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
109 if self._pixmap is None:
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
110 self.update_pixmap()
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
111 return self._pixmap
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
112
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
113 def set_pixmap(self, pixmap):
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
114 # Not implemented
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
115 pass
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
116
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
117 pixmap = property(get_pixmap, set_pixmap, clear_caches, "Pixmap representation of tile")
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
118
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
119 def get_raw_tile(self):
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
120 if self._raw_tile is None:
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
121 self._raw_tile = self.tile_data[16*self.index:16*(self.index + 1)]
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
122 return self._raw_tile
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
123
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
124 def set_raw_tile(self, raw_tile):
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
125 self.clear_caches()
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
126 self.tile_data[16*self.index:16*(self.index + 1)] = raw_tile
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
127
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
128 raw_tile = property(get_raw_tile, set_raw_tile, clear_caches, "Raw tile bytes as found in ROM")
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
129
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
130 def get_tile(self):
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
131 if self._tile is None:
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
132 self._tile = self.parse_tile(self.raw_tile)
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
133 return self._tile
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
134
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
135 def set_tile(self, tile):
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
136 self.clear_caches()
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
137 self.raw_tile = self.unparse_tile(tile)
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
138
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
139 tile = property(get_tile, set_tile, clear_caches, "A tile parsed as an 8x8 array of ints")
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
140
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
141 @classmethod
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
142 def parse_tile(cls, tile):
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
143 """Given a raw tile's bytes, convert it to an 8x8 array of integers."""
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
144 lowplane, hiplane = tile[0:8], tile[8:16]
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
145 rows = []
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
146 for lowbyte, hibyte in zip(lowplane, hiplane):
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
147 row = [
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
148 ((lowbyte >> idx) & 1) + 2*((hibyte >> idx) & 1)
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
149 for idx in range(7, -1, -1)
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
150 ]
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
151 rows.append(row)
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
152 return rows
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
153
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
154 @classmethod
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
155 def unparse_tile(cls, rows):
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
156 """Given an 8x8 array of integers, convert it to a raw tile's bytes."""
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
157 lowplane = bytes([int(''.join(str(num & 1) for num in row), 2) for row in rows])
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
158 hiplane = bytes([int(''.join(str((num & 2) >> 1) for num in row), 2) for row in rows])
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
159 return lowplane + hiplane