# HG changeset patch # User Jordi GutiƩrrez Hermoso # Date 1566741883 14400 # Node ID 655899862ff6df13530bd5a0ecac88ebdf91b9d5 # Parent 8109ee581af9342c0feb25c130c0581ec26d6350 Training's over. This is now starting to look like a real thing diff --git a/.hgignore b/.hgignore new file mode 100644 --- /dev/null +++ b/.hgignore @@ -0,0 +1,3 @@ +syntax: glob + +__pycache__ \ No newline at end of file diff --git a/colors.py b/colors.py new file mode 100644 --- /dev/null +++ b/colors.py @@ -0,0 +1,73 @@ +from PyQt5 import QtGui + +NES_PALETTE = [ + "#7C7C7C", # 0 + "#0000FC", # 1 + "#0000BC", # 2 + "#4428BC", # 3 + "#940084", # 4 + "#A80020", # 5 + "#A81000", # 6 + "#881400", # 7 + "#503000", # 8 + "#007800", # 9 + "#006800", # 10 + "#005800", # 11 + "#004058", # 12 + "#000000", # 13 + "#000000", # 14 + "#000000", # 15 + + "#BCBCBC", # 16 + "#0078F8", # 17 + "#0058F8", # 18 + "#6844FC", # 19 + "#D800CC", # 20 + "#E40058", # 21 + "#F83800", # 22 + "#E45C10", # 23 + "#AC7C00", # 24 + "#00B800", # 25 + "#00A800", # 26 + "#00A844", # 27 + "#008888", # 28 + "#000000", # 29 + "#000000", # 30 + "#000000", # 31 + + "#F8F8F8", # 32 + "#3CBCFC", # 33 + "#6888FC", # 34 + "#9878F8", # 35 + "#F878F8", # 36 + "#F85898", # 37 + "#F87858", # 38 + "#FCA044", # 39 + "#F8B800", # 40 + "#B8F818", # 41 + "#58D854", # 42 + "#58F898", # 43 + "#00E8D8", # 44 + "#787878", # 45 + "#000000", # 46 + "#000000", # 47 + + "#FCFCFC", # 48 + "#A4E4FC", # 49 + "#B8B8F8", # 50 + "#D8B8F8", # 51 + "#F8B8F8", # 52 + "#F8A4C0", # 53 + "#F0D0B0", # 54 + "#FCE0A8", # 55 + "#F8D878", # 56 + "#D8F878", # 57 + "#B8F8B8", # 58 + "#B8F8D8", # 59 + "#00FCFC", # 60 + "#F8D8F8", # 61 + "#000000", # 62 + "#000000", # 63 +] + +QT_NES_PALETTE = [QtGui.QColor(color).rgb() for color in NES_PALETTE] diff --git a/tilerswift.py b/tilerswift rename from tilerswift.py rename to tilerswift --- a/tilerswift.py +++ b/tilerswift @@ -2,15 +2,15 @@ import sys from PyQt5 import QtCore, QtGui, QtWidgets -num_displaycols = 16 -num_displayrows = 24 +from colors import QT_NES_PALETTE def read_rom(filename): with open(filename, 'rb') as f: ines = f.read() prg = ines[16:] - return [prg[i:i+16] for i in range(0, len(prg), 16)] + tiles = [prg[i:i+16] for i in range(0, len(prg), 16)] + return tiles def parse_tile(tile): @@ -25,122 +25,79 @@ return rows -def layout_tiles(tiles): - numcols = num_displaycols - numrows = len(tiles)//numcols - - out = [] - for rowidx in range(0, 8*numrows): - out.append([0]*(8*numcols)) +class DisplayTile(QtWidgets.QLabel): + default_palette = [ + QT_NES_PALETTE[32], + QT_NES_PALETTE[15], + QT_NES_PALETTE[33], + QT_NES_PALETTE[1], + ] - for rowidx in range(0, numrows): - for colidx in range(0, numcols): - tile = parse_tile(tiles[colidx + numcols * rowidx]) - for i in range(0, 8): - for j in range(0, 8): - out[i + 8*rowidx][j + 8*colidx] = tile[i][j] - return out - - -class Canvas(QtWidgets.QLabel): - - def __init__(self): + def __init__(self, row, col, tile): super().__init__() self.scalefactor = 5 - self.numcols = num_displaycols*8 - self.numrows = num_displayrows*8 - self.file_name = QtWidgets.QFileDialog.getOpenFileName( - self, - "Open ROM", "/home/jordi", "NES Files (*.nes)" - ) - self.laid_tiles = layout_tiles(read_rom(self.file_name[0])) - - offset = self.numrows//2 - self.data = bytes(sum(self.laid_tiles[offset:offset+self.numrows], [])) - image = QtGui.QImage(self.data, self.numcols, self.numrows, QtGui.QImage.Format_Indexed8) - image.setColorTable([ - QtGui.QColor("#FFFFFF").rgb(), - QtGui.QColor("#000000").rgb(), - QtGui.QColor("#8888FF").rgb(), - QtGui.QColor("#0000FF").rgb(), - ]) - pixmap = QtGui.QPixmap(image) - #pixmap.fill(QtGui.QColor("white")) - self.setPixmap(pixmap.scaled(QtCore.QSize(self.scalefactor*self.numcols, self.scalefactor*self.numrows))) - - self.last_x, self.last_y = None, None - self.set_pen_color('#000000') + self.row = row + self.col = col + self.raw_tile = tile + self.tile = parse_tile(self.raw_tile) + self.palette = self.default_palette - def set_pen_color(self, c): - self.pen_color = QtGui.QColor(c) - - def mouseMoveEvent(self, e): - if self.last_x is None: # First event. - self.last_x = e.x() - self.last_y = e.y() - return # Ignore the first time. + data = bytes(sum(self.tile, [])) + image = QtGui.QImage(data, 8, 8, QtGui.QImage.Format_Indexed8) + image.setColorTable(self.palette) + pixmap = QtGui.QPixmap(image) + self.setPixmap(pixmap.scaled(QtCore.QSize(self.scalefactor*8, self.scalefactor*8))) - painter = QtGui.QPainter(self.pixmap()) - # painter.scale(self.scalefactor, self.scalefactor) - p = painter.pen() - p.setWidth(1) - p.setColor(self.pen_color) - painter.setPen(p) - painter.drawLine(self.last_x, self.last_y, e.x(), e.y()) - painter.end() - self.update() - - # Update the origin for next time. - self.last_x = e.x() - self.last_y = e.y() - - def mouseReleaseEvent(self, e): - self.last_x = None - self.last_y = None + def mousePressEvent(self, event): + print("Tile clicked at ", self.row, self.col) + print("Raw bytes from ROM", repr(self.raw_tile)) + print("Parsed tile values:") + for row in self.tile: + print(row) + print() -COLORS = [ - # 17 undertones https://lospec.com/palette-list/17undertones - '#000000', '#141923', '#414168', '#3a7fa7', '#35e3e3', '#8fd970', '#5ebb49', - '#458352', '#dcd37b', '#fffee5', '#ffd035', '#cc9245', '#a15c3e', '#a42f3b', - '#f45b7a', '#c24998', '#81588d', '#bcb0c2', '#ffffff', -] +class GridCanvas(QtWidgets.QGridLayout): + + def __init__(self, filename): + super().__init__() + num_displaycols = 16 + + self.setHorizontalSpacing(2) + self.setVerticalSpacing(2) -class QPaletteButton(QtWidgets.QPushButton): + self.file_name = filename + self.tiles = read_rom(self.file_name[0]) - def __init__(self, color): - super().__init__() - self.setFixedSize(QtCore.QSize(24, 24)) - self.color = color - self.setStyleSheet("background-color: %s;" % color) + numrows = len(self.tiles)//num_displaycols + for i in range(numrows): + for j in range(num_displaycols): + tile = self.tiles[i*num_displaycols + j] + display_tile = DisplayTile(i, j, tile) + self.addWidget(display_tile, i, j) class MainWindow(QtWidgets.QMainWindow): - def __init__(self): super().__init__() - self.canvas = Canvas() - - w = QtWidgets.QWidget() - l = QtWidgets.QVBoxLayout() - w.setLayout(l) - l.addWidget(self.canvas) + filename = QtWidgets.QFileDialog.getOpenFileName( + self, + "Open ROM", "", "NES Files (*.nes)" + ) - palette = QtWidgets.QHBoxLayout() - self.add_palette_buttons(palette) - l.addLayout(palette) - - self.setCentralWidget(w) + widget = QtWidgets.QWidget() + widget.setStyleSheet("background-color: pink;") + gridcanvas = GridCanvas(filename) + widget.setLayout(gridcanvas) - def add_palette_buttons(self, layout): - for c in COLORS: - b = QPaletteButton(c) - b.pressed.connect(lambda c=c: self.canvas.set_pen_color(c)) - layout.addWidget(b) + scroll = QtWidgets.QScrollArea() + scroll.setWidget(widget) + + self.setCentralWidget(scroll) app = QtWidgets.QApplication(sys.argv)