mirror of
https://github.com/BrianPugh/game-and-watch-patch.git
synced 2025-12-16 07:16:26 +01:00
100 lines
3.0 KiB
Python
100 lines
3.0 KiB
Python
"""Script to view the pattern table of an NES ROM
|
|
|
|
usage: view_pattern_table.py <filename>
|
|
|
|
By Jake Vanderplas, 2013 <http://jakevdp.github.com>
|
|
License: GPL.
|
|
Feel free to use and distribute, but keep this attribution intact.
|
|
"""
|
|
import zipfile
|
|
|
|
import numpy as np
|
|
from matplotlib import pyplot as plt
|
|
|
|
|
|
class ROMViewer(object):
|
|
"""Visually inspect an NES ROM"""
|
|
|
|
def __init__(self, filename, start=0, N1=16, N2=16, sep=1):
|
|
if zipfile.is_zipfile(filename):
|
|
zp = zipfile.ZipFile(filename)
|
|
data = np.unpackbits(np.frombuffer(zp.read(zp.filelist[0]), dtype=np.uint8))
|
|
else:
|
|
data = np.unpackbits(np.fromfile(filename, dtype=np.uint8))
|
|
|
|
self.data = data.reshape((-1, 8, 8))
|
|
self.N1 = N1
|
|
self.N2 = N2
|
|
self.sep = sep
|
|
|
|
self.fig, self.ax = plt.subplots(
|
|
figsize=(6, 6), subplot_kw=dict(xticks=[], yticks=[])
|
|
)
|
|
self.fig.subplots_adjust(bottom=0.04, top=0.94, left=0.05, right=0.95)
|
|
self.fig.rom_viewer = self # needed for object persistence
|
|
self.update_offset(start)
|
|
self.fig.canvas.mpl_connect("key_press_event", self.key_press)
|
|
|
|
def update_offset(self, offset):
|
|
"""update offset and re-draw figure"""
|
|
offset = max(offset, 0)
|
|
offset = int(min(offset, self.data.shape[0] / 2 - self.N1 * self.N2))
|
|
self.current_offset = offset
|
|
self.ax.set_title("offset = %i" % offset)
|
|
|
|
# starting at offset, take 128-bit chunks and view as
|
|
# 2-bit 8x8 thumbnails in an 8x8 grid
|
|
im_array = np.zeros(
|
|
(self.sep + self.N1 * (8 + self.sep), self.sep + self.N2 * (8 + self.sep))
|
|
)
|
|
|
|
for i in range(self.N1):
|
|
for j in range(self.N2):
|
|
thumb = self.data[2 * offset] + 2 * self.data[2 * offset + 1]
|
|
|
|
ind_i = self.sep + (8 + self.sep) * i
|
|
ind_j = self.sep + (8 + self.sep) * j
|
|
im_array[ind_i : ind_i + 8, ind_j : ind_j + 8] = thumb
|
|
offset += 1
|
|
|
|
if not hasattr(self, "im"):
|
|
self.im = self.ax.imshow(
|
|
im_array, cmap=plt.cm.binary, interpolation="nearest"
|
|
)
|
|
else:
|
|
self.im.set_data(im_array)
|
|
plt.draw()
|
|
|
|
def key_press(self, event):
|
|
"""Use arrow keys to navigate"""
|
|
offset_dict = dict(
|
|
right=1,
|
|
left=-1,
|
|
up=-self.N1 * self.N2,
|
|
down=self.N1 * self.N2,
|
|
home=-self.data.shape[0],
|
|
end=self.data.shape[0],
|
|
)
|
|
|
|
if event.key in offset_dict:
|
|
self.update_offset(self.current_offset + offset_dict[event.key])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
|
|
try:
|
|
filename = sys.argv[1]
|
|
except Exception:
|
|
print(__doc__)
|
|
sys.exit(0)
|
|
|
|
try:
|
|
start_index = int(sys.argv[2], base=0)
|
|
except IndexError:
|
|
start_index = 0
|
|
pass
|
|
|
|
ROMViewer(filename, start=start_index)
|
|
plt.show()
|