annotate nes.py @ 121:bfced396acca draft

NES_ROM: style fix Switch around the order of a statment so it look like the other branch of the if.
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Wed, 02 Oct 2019 09:09:16 -0400
parents 0c40b4e8270e
children d3ee52820f6b
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
120
0c40b4e8270e NES_ROM: modify comment to explain that we only rotate bytes on the PRG
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 119
diff changeset
12
0c40b4e8270e NES_ROM: modify comment to explain that we only rotate bytes on the PRG
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 119
diff changeset
13 # To track circular rotation of the PRG bytes, in case the
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
14 # 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
15 # moves it.
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
16 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
17 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
18
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
19 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
20 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
21 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
22 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
23 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
24 try:
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
25 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
26 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
27 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
28 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
29 raise ROMOpeningError(
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
30 "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
31 )
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
32 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
33 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
34 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
35 else:
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
36 raise ROMOpeningError(
e3ffae4d7528 NES_ROM: allow ROMs to be provided as zip files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 106
diff changeset
37 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
38 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
39 )
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
40
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
41 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
42 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
43 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
44 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
45
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
46 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
47 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
48 # No chr, just read the whole ROM as tiles
121
bfced396acca NES_ROM: style fix
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 120
diff changeset
49 self.CHR = None
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
50 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
51 else:
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
52 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
53 self.tile_data = list(self.CHR)
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
54
116
b52d47e78ff8 nes: use better name for index variable
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 111
diff changeset
55 self.tiles = [Tile(idx, self.tile_data)
b52d47e78ff8 nes: use better name for index variable
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 111
diff changeset
56 for idx in range(0, len(self.tile_data)//16)]
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
57
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
58 def update_tiles(self):
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
59 for tile in self.tiles:
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
60 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
61
119
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
62 def rotate_tile_data(self, steps):
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
63 """
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
64 Rotates the tile data by given number of steps, either
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
65 positively or negatively. The maximum rotation in either
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
66 direction is 8 steps.
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
67 """
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
68
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
69 if steps > 0:
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
70 steps = min(8 - self.initial_position, steps)
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
71 elif steps < 0:
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
72 steps = max(-8 - self.initial_position, steps)
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
73
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
74 if steps == 0:
111
872637684299 NES_ROM: limit byte-shifting functions to 8 bytes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 109
diff changeset
75 return
872637684299 NES_ROM: limit byte-shifting functions to 8 bytes
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 109
diff changeset
76
119
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
77 self.tile_data[:] = self.tile_data[steps:] + self.tile_data[:steps]
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
78 self.initial_position += steps
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
79
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
80 def byte_forward(self):
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
81 self.rotate_tile_data(1)
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
82 self.update_tiles()
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
83
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
84 def byte_backward(self):
119
9c97adbb349c NES: factor out byte_forward and byte_backward into general rotate_tile_data
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 118
diff changeset
85 self.rotate_tile_data(-1)
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
86 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
87
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
88
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
89 class Tile(object):
117
fbb04916a5a7 Tile: add a short docstring
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 116
diff changeset
90 """
fbb04916a5a7 Tile: add a short docstring
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 116
diff changeset
91 A tile is a view into a part of a NES ROM (either its PRG or its
fbb04916a5a7 Tile: add a short docstring
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 116
diff changeset
92 CHR). A tile just keeps an index into the ROM position by 16-byte
fbb04916a5a7 Tile: add a short docstring
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 116
diff changeset
93 offsets as well as individual palette information for this one
fbb04916a5a7 Tile: add a short docstring
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 116
diff changeset
94 view.
fbb04916a5a7 Tile: add a short docstring
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 116
diff changeset
95
fbb04916a5a7 Tile: add a short docstring
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 116
diff changeset
96 """
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
97
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
98 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
99
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
100 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
101 super().__init__()
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
102
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
103 self.index = index
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
104 self.tile_data = tile_data
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
105 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
106 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
107
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
108 def __repr__(self):
118
72c36fb13706 Tile: replace __repr__ method
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 117
diff changeset
109 return f"Tile(bytes={self.raw_tile}, palette={self.palette})"
72c36fb13706 Tile: replace __repr__ method
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 117
diff changeset
110
72c36fb13706 Tile: replace __repr__ method
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 117
diff changeset
111 def __str__(self):
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
112 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
113 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
114 "[" + "".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
115 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
116 ) + "\n" + "-"*10
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
117
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
118 def clear_caches(self):
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
119 self._raw_tile = None
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
120 self._tile = None
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
121 self._pixmap = None
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
122
101
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
123 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
124 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
125 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
126
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
127 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
128 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
129 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
130 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
131 self._pixmap = QG.QPixmap(image)
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
132
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
133 def get_pixmap(self):
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
134 if self._pixmap is None:
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
135 self.update_pixmap()
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
136 return self._pixmap
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
137
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
138 def set_pixmap(self, pixmap):
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
139 # Not implemented
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
140 pass
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
141
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
142 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
143
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
144 def get_raw_tile(self):
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
145 if self._raw_tile is None:
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
146 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
147 return self._raw_tile
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
148
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
149 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
150 self.clear_caches()
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
151 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
152
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
153 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
154
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
155 def get_tile(self):
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
156 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
157 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
158 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
159
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
160 def set_tile(self, tile):
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
161 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
162 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
163
106
d5e69fe5c81a NES_ROM: implement circular byte shifting
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 101
diff changeset
164 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
165
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
166 @classmethod
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
167 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
168 """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
169 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
170 rows = []
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
171 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
172 row = [
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
173 ((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
174 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
175 ]
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
176 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
177 return rows
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
178
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
179 @classmethod
822e2fb5197c refactor: move the NES ROM manipulation code into its own module
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff changeset
180 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
181 """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
182 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
183 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
184 return lowplane + hiplane