Mercurial > hg > tilerswift
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 |
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 |