changeset 40:655899862ff6

Training's over. This is now starting to look like a real thing
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Sun, 25 Aug 2019 10:04:43 -0400
parents 8109ee581af9
children 342165317836
files .hgignore colors.py tilerswift tilerswift.py
diffstat 3 files changed, 132 insertions(+), 99 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1,3 @@
+syntax: glob
+
+__pycache__
\ No newline at end of file
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]
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)