From b1f750e441af63b35141702ac00fd2f13313bd44 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Fri, 22 Jul 2016 01:05:49 -0700 Subject: [PATCH] Qt: First pass at a tile view --- src/platform/qt/CMakeLists.txt | 3 + src/platform/qt/TilePainter.cpp | 40 +++++++ src/platform/qt/TilePainter.h | 37 ++++++ src/platform/qt/TileView.cpp | 111 ++++++++++++++++++ src/platform/qt/TileView.h | 45 ++++++++ src/platform/qt/TileView.ui | 199 ++++++++++++++++++++++++++++++++ src/platform/qt/Window.cpp | 12 ++ src/platform/qt/Window.h | 1 + 8 files changed, 448 insertions(+) create mode 100644 src/platform/qt/TilePainter.cpp create mode 100644 src/platform/qt/TilePainter.h create mode 100644 src/platform/qt/TileView.cpp create mode 100644 src/platform/qt/TileView.h create mode 100644 src/platform/qt/TileView.ui diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 8700f5514..8ec615750 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -102,6 +102,8 @@ set(SOURCE_FILES ShortcutController.cpp ShortcutView.cpp Swatch.cpp + TilePainter.cpp + TileView.cpp Window.cpp VFileDevice.cpp VideoView.cpp) @@ -121,6 +123,7 @@ qt5_wrap_ui(UI_FILES SettingsView.ui ShaderSelector.ui ShortcutView.ui + TileView.ui VideoView.ui) set(QT_LIBRARIES) diff --git a/src/platform/qt/TilePainter.cpp b/src/platform/qt/TilePainter.cpp new file mode 100644 index 000000000..5c6ce2310 --- /dev/null +++ b/src/platform/qt/TilePainter.cpp @@ -0,0 +1,40 @@ +/* Copyright (c) 2013-2016 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "TilePainter.h" + +#include +#include +#include + +using namespace QGBA; + +TilePainter::TilePainter(QWidget* parent) + : QWidget(parent) +{ + m_backing = QPixmap(256, 768); + m_backing.fill(Qt::transparent); +} + +void TilePainter::paintEvent(QPaintEvent* event) { + QPainter painter(this); + painter.drawPixmap(QPoint(), m_backing); +} + +void TilePainter::mousePressEvent(QMouseEvent* event) { + int x = event->x() / 8; + int y = event->y() / 8; + emit indexPressed(y * 32 + x); +} + +void TilePainter::setTile(int index, const uint16_t* data) { + QPainter painter(&m_backing); + int x = index & 31; + int y = index / 32; + QRect r(x * 8, y * 8, 8, 8); + QImage tile(reinterpret_cast(data), 8, 8, QImage::Format_RGB555); + painter.fillRect(r, tile.rgbSwapped()); + update(r); +} diff --git a/src/platform/qt/TilePainter.h b/src/platform/qt/TilePainter.h new file mode 100644 index 000000000..412006228 --- /dev/null +++ b/src/platform/qt/TilePainter.h @@ -0,0 +1,37 @@ +/* Copyright (c) 2013-2016 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef QGBA_TILE_PAINTER +#define QGBA_TILE_PAINTER + +#include +#include +#include + +namespace QGBA { + +class TilePainter : public QWidget { +Q_OBJECT + +public: + TilePainter(QWidget* parent = nullptr); + +public slots: + void setTile(int index, const uint16_t*); + +signals: + void indexPressed(int index); + +protected: + void paintEvent(QPaintEvent*) override; + void mousePressEvent(QMouseEvent*) override; + +private: + QPixmap m_backing; +}; + +} + +#endif diff --git a/src/platform/qt/TileView.cpp b/src/platform/qt/TileView.cpp new file mode 100644 index 000000000..5d6c6b880 --- /dev/null +++ b/src/platform/qt/TileView.cpp @@ -0,0 +1,111 @@ +/* Copyright (c) 2013-2016 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "TileView.h" + +#include "GBAApp.h" + +#include + +extern "C" { +#include "gba/gba.h" +} + +using namespace QGBA; + +TileView::TileView(GameController* controller, QWidget* parent) + : QWidget(parent) + , m_controller(controller) + , m_paletteId(0) +{ + m_ui.setupUi(this); + GBAVideoTileCacheInit(&m_tileCache); + + m_ui.preview->setDimensions(QSize(8, 8)); + updateTiles(); + + const QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont); + + m_ui.tileId->setFont(font); + m_ui.address->setFont(font); + + connect(m_controller, SIGNAL(frameAvailable(const uint32_t*)), this, SLOT(updateTiles())); + connect(m_controller, SIGNAL(gameStopped(mCoreThread*)), this, SLOT(close())); + connect(m_ui.tiles, SIGNAL(indexPressed(int)), this, SLOT(selectIndex(int))); + connect(m_ui.paletteId, SIGNAL(valueChanged(int)), this, SLOT(updatePalette(int))); + connect(m_ui.palette256, SIGNAL(toggled(bool)), this, SLOT(updateTiles())); +} + +TileView::~TileView() { + GBAVideoTileCacheDeinit(&m_tileCache); +} + +void TileView::selectIndex(int index) { + const uint16_t* data; + m_ui.tileId->setText(QString::number(index)); + if (m_ui.palette256->isChecked()) { + m_ui.address->setText(tr("0x%0").arg(index * 64 | BASE_VRAM, 8, 16, QChar('0'))); + if (index < 1024) { + data = GBAVideoTileCacheGetTile256(&m_tileCache, index, 0); + } else { + data = GBAVideoTileCacheGetTile256(&m_tileCache, index, 1); + } + } else { + m_ui.address->setText(tr("0x%0").arg(index * 32 | BASE_VRAM, 8, 16, QChar('0'))); + if (index < 2048) { + data = GBAVideoTileCacheGetTile16(&m_tileCache, index, m_paletteId); + } else { + data = GBAVideoTileCacheGetTile16(&m_tileCache, index, m_paletteId + 16); + } + } + for (int i = 0; i < 64; ++i) { + m_ui.preview->setColor(i, data[i]); + } + m_ui.preview->update(); +} + +void TileView::updateTiles() { + if (!m_controller->thread() || !m_controller->thread()->core) { + return; + } + + GBA* gba = static_cast(m_controller->thread()->core->board); + GBAVideoTileCacheAssociate(&m_tileCache, &gba->video); + + if (m_ui.palette256->isChecked()) { + m_ui.tiles->setMinimumSize(256, 384); + for (int i = 0; i < 1024; ++i) { + const uint16_t* data = GBAVideoTileCacheGetTile256IfDirty(&m_tileCache, i, 0); + if (data) { + m_ui.tiles->setTile(i, data); + } + } + for (int i = 1024; i < 1536; ++i) { + const uint16_t* data = GBAVideoTileCacheGetTile256IfDirty(&m_tileCache, i, 1); + if (data) { + m_ui.tiles->setTile(i, data); + } + } + } else { + m_ui.tiles->setMinimumSize(256, 768); + for (int i = 0; i < 2048; ++i) { + const uint16_t* data = GBAVideoTileCacheGetTile16IfDirty(&m_tileCache, i, m_paletteId); + if (data) { + m_ui.tiles->setTile(i, data); + } + } + for (int i = 2048; i < 3072; ++i) { + const uint16_t* data = GBAVideoTileCacheGetTile16IfDirty(&m_tileCache, i, m_paletteId + 16); + if (data) { + m_ui.tiles->setTile(i, data); + } + } + } +} + +void TileView::updatePalette(int palette) { + m_paletteId = palette; + updateTiles(); +} diff --git a/src/platform/qt/TileView.h b/src/platform/qt/TileView.h new file mode 100644 index 000000000..5ef4ad9c2 --- /dev/null +++ b/src/platform/qt/TileView.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2013-2016 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef QGBA_TILE_VIEW +#define QGBA_TILE_VIEW + +#include + +#include "GameController.h" + +#include "ui_TileView.h" + +extern "C" { +#include "gba/renderers/tile-cache.h" +} + +namespace QGBA { + +class TileView : public QWidget { +Q_OBJECT + +public: + TileView(GameController* controller, QWidget* parent = nullptr); + virtual ~TileView(); + +public slots: + void updateTiles(); + void updatePalette(int); + +private slots: + void selectIndex(int); + +private: + Ui::TileView m_ui; + + GameController* m_controller; + GBAVideoTileCache m_tileCache; + int m_paletteId; +}; + +} + +#endif diff --git a/src/platform/qt/TileView.ui b/src/platform/qt/TileView.ui new file mode 100644 index 000000000..cd662adb0 --- /dev/null +++ b/src/platform/qt/TileView.ui @@ -0,0 +1,199 @@ + + + TileView + + + + 0 + 0 + 288 + 269 + + + + Tiles + + + + + + 256 colors + + + + + + + Preview + + + + + + + + Qt::Horizontal + + + + + + + + 87 + 87 + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + + Tile # + + + + + + + 0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + Address + + + + + + + 0x06000000 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + 15 + + + 1 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + + + + + + 0 + 0 + + + + true + + + + + 0 + 0 + 16 + 16 + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + + + + + + + + + QGBA::TilePainter + QWidget +
TilePainter.h
+ 1 +
+ + QGBA::Swatch + QWidget +
Swatch.h
+ 1 +
+
+ + +
diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 3f987853e..6f6fe594d 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -30,6 +30,7 @@ #include "MemoryView.h" #include "OverrideView.h" #include "PaletteView.h" +#include "TileView.h" #include "ROMInfo.h" #include "SensorView.h" #include "SettingsView.h" @@ -430,6 +431,11 @@ void Window::openPaletteWindow() { openView(paletteWindow); } +void Window::openTileWindow() { + TileView* tileWindow = new TileView(m_controller); + openView(tileWindow); +} + void Window::openMemoryWindow() { MemoryView* memoryWindow = new MemoryView(m_controller); openView(memoryWindow); @@ -1288,6 +1294,12 @@ void Window::setupMenu(QMenuBar* menubar) { m_gbaActions.append(paletteView); addControlledAction(toolsMenu, paletteView, "paletteWindow"); + QAction* tileView = new QAction(tr("View &tiles..."), toolsMenu); + connect(tileView, SIGNAL(triggered()), this, SLOT(openTileWindow())); + m_gameActions.append(tileView); + m_gbaActions.append(tileView); + addControlledAction(toolsMenu, tileView, "tileWindow"); + QAction* memoryView = new QAction(tr("View memory..."), toolsMenu); connect(memoryView, SIGNAL(triggered()), this, SLOT(openMemoryWindow())); m_gameActions.append(memoryView); diff --git a/src/platform/qt/Window.h b/src/platform/qt/Window.h index eac223dbd..309fdb784 100644 --- a/src/platform/qt/Window.h +++ b/src/platform/qt/Window.h @@ -82,6 +82,7 @@ public slots: void openCheatsWindow(); void openPaletteWindow(); + void openTileWindow(); void openMemoryWindow(); void openIOViewer();