mirror of https://github.com/mgba-emu/mgba.git
Qt: First pass at a tile view
This commit is contained in:
parent
739df1ed74
commit
b1f750e441
|
@ -102,6 +102,8 @@ set(SOURCE_FILES
|
||||||
ShortcutController.cpp
|
ShortcutController.cpp
|
||||||
ShortcutView.cpp
|
ShortcutView.cpp
|
||||||
Swatch.cpp
|
Swatch.cpp
|
||||||
|
TilePainter.cpp
|
||||||
|
TileView.cpp
|
||||||
Window.cpp
|
Window.cpp
|
||||||
VFileDevice.cpp
|
VFileDevice.cpp
|
||||||
VideoView.cpp)
|
VideoView.cpp)
|
||||||
|
@ -121,6 +123,7 @@ qt5_wrap_ui(UI_FILES
|
||||||
SettingsView.ui
|
SettingsView.ui
|
||||||
ShaderSelector.ui
|
ShaderSelector.ui
|
||||||
ShortcutView.ui
|
ShortcutView.ui
|
||||||
|
TileView.ui
|
||||||
VideoView.ui)
|
VideoView.ui)
|
||||||
|
|
||||||
set(QT_LIBRARIES)
|
set(QT_LIBRARIES)
|
||||||
|
|
|
@ -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 <QImage>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
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<const uchar*>(data), 8, 8, QImage::Format_RGB555);
|
||||||
|
painter.fillRect(r, tile.rgbSwapped());
|
||||||
|
update(r);
|
||||||
|
}
|
|
@ -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 <QColor>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
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
|
|
@ -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 <QFontDatabase>
|
||||||
|
|
||||||
|
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<GBA*>(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();
|
||||||
|
}
|
|
@ -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 <QWidget>
|
||||||
|
|
||||||
|
#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
|
|
@ -0,0 +1,199 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>TileView</class>
|
||||||
|
<widget class="QWidget" name="TileView">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>288</width>
|
||||||
|
<height>269</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Tiles</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="palette256">
|
||||||
|
<property name="text">
|
||||||
|
<string>256 colors</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Preview</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGBA::Swatch" name="preview" native="true">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>87</width>
|
||||||
|
<height>87</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Tile #</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="tileId">
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Address</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="address">
|
||||||
|
<property name="text">
|
||||||
|
<string>0x06000000</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QSlider" name="paletteId">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
<property name="pageStep">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="tickPosition">
|
||||||
|
<enum>QSlider::TicksBelow</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1" rowspan="3">
|
||||||
|
<widget class="QScrollArea" name="scrollArea">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="widgetResizable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>16</width>
|
||||||
|
<height>16</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QGBA::TilePainter" name="tiles" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>QGBA::TilePainter</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>TilePainter.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>QGBA::Swatch</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>Swatch.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -30,6 +30,7 @@
|
||||||
#include "MemoryView.h"
|
#include "MemoryView.h"
|
||||||
#include "OverrideView.h"
|
#include "OverrideView.h"
|
||||||
#include "PaletteView.h"
|
#include "PaletteView.h"
|
||||||
|
#include "TileView.h"
|
||||||
#include "ROMInfo.h"
|
#include "ROMInfo.h"
|
||||||
#include "SensorView.h"
|
#include "SensorView.h"
|
||||||
#include "SettingsView.h"
|
#include "SettingsView.h"
|
||||||
|
@ -430,6 +431,11 @@ void Window::openPaletteWindow() {
|
||||||
openView(paletteWindow);
|
openView(paletteWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::openTileWindow() {
|
||||||
|
TileView* tileWindow = new TileView(m_controller);
|
||||||
|
openView(tileWindow);
|
||||||
|
}
|
||||||
|
|
||||||
void Window::openMemoryWindow() {
|
void Window::openMemoryWindow() {
|
||||||
MemoryView* memoryWindow = new MemoryView(m_controller);
|
MemoryView* memoryWindow = new MemoryView(m_controller);
|
||||||
openView(memoryWindow);
|
openView(memoryWindow);
|
||||||
|
@ -1288,6 +1294,12 @@ void Window::setupMenu(QMenuBar* menubar) {
|
||||||
m_gbaActions.append(paletteView);
|
m_gbaActions.append(paletteView);
|
||||||
addControlledAction(toolsMenu, paletteView, "paletteWindow");
|
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);
|
QAction* memoryView = new QAction(tr("View memory..."), toolsMenu);
|
||||||
connect(memoryView, SIGNAL(triggered()), this, SLOT(openMemoryWindow()));
|
connect(memoryView, SIGNAL(triggered()), this, SLOT(openMemoryWindow()));
|
||||||
m_gameActions.append(memoryView);
|
m_gameActions.append(memoryView);
|
||||||
|
|
|
@ -82,6 +82,7 @@ public slots:
|
||||||
void openCheatsWindow();
|
void openCheatsWindow();
|
||||||
|
|
||||||
void openPaletteWindow();
|
void openPaletteWindow();
|
||||||
|
void openTileWindow();
|
||||||
void openMemoryWindow();
|
void openMemoryWindow();
|
||||||
void openIOViewer();
|
void openIOViewer();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue