From 2a00be9ade0b4e2b0b5e977247104f2310d2cf25 Mon Sep 17 00:00:00 2001 From: Luke Hubmayer-Werner Date: Sun, 1 Apr 2018 21:47:26 +0930 Subject: [PATCH] Added batching to worldmap rendering --- ff5reader.py | 4 +++- includes/snes.py | 17 ++++++++++++++++- includes/snestile.py | 11 +++++++++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/ff5reader.py b/ff5reader.py index abe029c..4fc8d5e 100755 --- a/ff5reader.py +++ b/ff5reader.py @@ -228,7 +228,7 @@ class FF5Reader(QMainWindow): print('Generating map tiles') worldmap_palettes = [generate_palette(ROM_jp, 0x0FFCC0+(i*0x100), length=0x160, transparent=True) for i in range(3)] world_tiles = [make_worldmap_blocks(ROM_jp, 0x0FF0C0+(i*0x300), 0x1B8000+(i*0x2000), 0x0FF9C0+(i*0x100)) for i in range(3)] - worldpixmaps = [make_worldmap_pixmap(ROM_jp, i, 0x0FFCC0+(t*0x100), world_tiles[t]) for i, t in enumerate([0, 1, 0, 2, 2])] + #worldpixmaps = [make_worldmap_pixmap(ROM_jp, i, 0x0FFCC0+(t*0x100), world_tiles[t]) for i, t in enumerate([0, 1, 0, 2, 2])] world_blocks_pixmaps = [] for i, tiles in enumerate(world_tiles): a = [] @@ -236,6 +236,8 @@ class FF5Reader(QMainWindow): t.setColorTable(worldmap_palettes[i]) a.append(QPixmap.fromImage(t)) world_blocks_pixmaps.append(a) + world_tile_stitches = [stitch_tileset_px(t) for t in world_blocks_pixmaps] + worldpixmaps = [make_worldmap_pixmap2(ROM_jp, i, world_tile_stitches[t]) for i, t in enumerate([0, 1, 0, 2, 2])] perfcount() worldmap_tiles = make_worldmap_tiles_pixmap(ROM_jp, 0x1B8000, 0x0FF9C0, 0x0FFCC0) worldmap_tiles += make_worldmap_tiles_pixmap(ROM_jp, 0x1BA000, 0x0FFAC0, 0x0FFDC0) diff --git a/includes/snes.py b/includes/snes.py index 0f11751..aef4db7 100644 --- a/includes/snes.py +++ b/includes/snes.py @@ -191,6 +191,21 @@ def make_worldmap_pixmap(rom, map_id, palette_address, tiles): canvas.draw_tile(i, j, tiles[c]) return canvas.pixmap(palette) +def make_worldmap_pixmap2(rom, map_id, tiles): + ''' + Batched version using QPainter.drawPixmapFragments + Tiles is a pixmap tilemap. + ''' + id_offset = map_id*256 + canvas = Canvas(256, 256, tilesize=16) + fragments = [] + for j in range(256): + chunk = make_worldmap_chunk(rom, j+id_offset) + for i, c in enumerate(chunk): + fragments.append(make_pixmapfragment(c, i*16, j*16)) + canvas.drawPixmapFragments(fragments, tiles) + return canvas.pixmap() + def make_field_tiles(rom, id): tiles_address = indirect(rom, 0x1C2D84 + id*4, length=4) + 0x1C2E24 return [create_tile_indexed(rom[tiles_address+i*32:tiles_address+i*32+32]) for i in range(256)] @@ -212,7 +227,7 @@ def stitch_tileset(tiles): return canvas def stitch_tileset_px(tiles_px): - canvas = Canvas(16, len(tiles_px)//16) + canvas = Canvas(16, len(tiles_px)//16, tilesize=tiles_px[0].width()) for i, tile in enumerate(tiles_px): canvas.draw_pixmap(i%16, i//16, tile) return canvas.pixmap() diff --git a/includes/snestile.py b/includes/snestile.py index bfa5473..2eb24d2 100644 --- a/includes/snestile.py +++ b/includes/snestile.py @@ -24,14 +24,14 @@ skip_pyqt5 = "PYQT4" in os.environ if not skip_pyqt5: try: - from PyQt5 import QtGui + from PyQt5 import QtGui, QtCore from PyQt5.QtGui import QImage, QPixmap, QColor, QPainter, QTransform pyqt_version = 5 except ImportError: print("Missing PyQt5, trying PyQt4...") if pyqt_version == 0: try: - from PyQt4 import QtGui + from PyQt4 import QtGui, QtCore from PyQt4.QtGui import QImage, QPixmap, QColor, QPainter, QTransform pyqt_version = 4 except ImportError: @@ -211,6 +211,10 @@ def generate_palette(rom, offset, length=32, transparent=False): palette[0] = 0 return palette +def make_pixmapfragment(id, source_x, source_y): + pos = QtCore.QPoint(source_x, source_y) + source = QtCore.QRectF((id%16)*16, (id//16)*16, 16, 16) + return QtGui.QPainter.PixmapFragment.create(pos, source, 1, 1, 0, 1) class Canvas: def __init__(self, cols, rows, color=bg_trans, tilesize=8): @@ -237,6 +241,9 @@ class Canvas: if row > self.max_row: self.max_row = row + def drawPixmapFragments(self, *args, **kwargs): + self.painter.drawPixmapFragments(*args, **kwargs) + def pixmap(self, trim=False): if trim: return QPixmap.fromImage(self.image.copy(0, 0, (self.max_col+1)*self.tilesize, (self.max_row+1)*self.tilesize))