Qt: Add additional info to map view

This commit is contained in:
Vicki Pfau 2019-05-30 17:45:34 -07:00
parent ba00cdfc02
commit 06657d9fde
9 changed files with 231 additions and 88 deletions

View File

@ -7,7 +7,7 @@ Features:
- GB: Expose platform information to CLI debugger
- Support Discord Rich Presence
- Debugger: Add tracing to file
- Map viewer supports bitmapped GBA modes
- Enhanced map viewer, supporting bitmapped GBA modes and more displayed info
- OpenGL renderer with high-resolution upscaling support
- Experimental high level "XQ" audio for most GBA games
- Interframe blending for games that use flicker effects

View File

@ -0,0 +1,40 @@
/* Copyright (c) 2013-2019 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 "AssetInfo.h"
#include <QFontDatabase>
#include <QHBoxLayout>
using namespace QGBA;
AssetInfo::AssetInfo(QWidget* parent)
: QGroupBox(parent)
{
}
void AssetInfo::addCustomProperty(const QString& id, const QString& visibleName) {
QHBoxLayout* newLayout = new QHBoxLayout;
newLayout->addWidget(new QLabel(visibleName));
QLabel* value = new QLabel;
value->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
value->setAlignment(Qt::AlignRight);
newLayout->addWidget(value);
m_customProperties[id] = value;
int index = customLocation();
static_cast<QBoxLayout*>(layout())->insertLayout(index, newLayout);
}
void AssetInfo::setCustomProperty(const QString& id, const QVariant& value) {
QLabel* label = m_customProperties[id];
if (!label) {
return;
}
label->setText(value.toString());
}
int AssetInfo::customLocation(const QString&) {
return layout()->count();
}

View File

@ -0,0 +1,34 @@
/* Copyright (c) 2013-2019 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/. */
#pragma once
#include <QGroupBox>
#include <QHash>
#include <QLabel>
#include <QVariant>
namespace QGBA {
class CoreController;
class AssetInfo : public QGroupBox {
Q_OBJECT
public:
AssetInfo(QWidget* parent = nullptr);
void addCustomProperty(const QString& id, const QString& visibleName);
public slots:
void setCustomProperty(const QString& id, const QVariant& value);
protected:
virtual int customLocation(const QString& id = {});
private:
QHash<QString, QLabel*> m_customProperties;
};
}

View File

@ -22,7 +22,7 @@
using namespace QGBA;
AssetTile::AssetTile(QWidget* parent)
: QGroupBox(parent)
: AssetInfo(parent)
{
m_ui.setupUi(this);
@ -42,16 +42,8 @@ AssetTile::AssetTile(QWidget* parent)
m_ui.b->setFont(font);
}
void AssetTile::addCustomProperty(const QString& id, const QString& visibleName) {
QHBoxLayout* newLayout = new QHBoxLayout;
newLayout->addWidget(new QLabel(visibleName));
QLabel* value = new QLabel;
value->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
value->setAlignment(Qt::AlignRight);
newLayout->addWidget(value);
m_customProperties[id] = value;
int index = layout()->indexOf(m_ui.line);
static_cast<QBoxLayout*>(layout())->insertLayout(index, newLayout);
int AssetTile::customLocation(const QString&) {
return layout()->indexOf(m_ui.line);
}
void AssetTile::setController(std::shared_ptr<CoreController> controller) {
@ -149,11 +141,3 @@ void AssetTile::selectColor(int index) {
m_ui.g->setText(tr("0x%0 (%1)").arg(g, 2, 16, QChar('0')).arg(g, 2, 10, QChar('0')));
m_ui.b->setText(tr("0x%0 (%1)").arg(b, 2, 16, QChar('0')).arg(b, 2, 10, QChar('0')));
}
void AssetTile::setCustomProperty(const QString& id, const QVariant& value) {
QLabel* label = m_customProperties[id];
if (!label) {
return;
}
label->setText(value.toString());
}

View File

@ -15,13 +15,12 @@ namespace QGBA {
class CoreController;
class AssetTile : public QGroupBox {
class AssetTile : public AssetInfo {
Q_OBJECT
public:
AssetTile(QWidget* parent = nullptr);
void setController(std::shared_ptr<CoreController>);
void addCustomProperty(const QString& id, const QString& visibleName);
public slots:
void setPalette(int);
@ -29,7 +28,9 @@ public slots:
void selectIndex(int);
void setFlip(bool h, bool v);
void selectColor(int);
void setCustomProperty(const QString& id, const QVariant& value);
protected:
int customLocation(const QString& id = {}) override;
private:
Ui::AssetTile m_ui;

View File

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AssetTile</class>
<widget class="QGroupBox" name="AssetTile">
<widget class="QGBA::AssetInfo" name="AssetTile">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>171</width>
<height>355</height>
<width>241</width>
<height>406</height>
</rect>
</property>
<property name="sizePolicy">
@ -185,6 +185,12 @@
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QGBA::AssetInfo</class>
<extends>QGroupBox</extends>
<header>AssetInfo.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QGBA::Swatch</class>
<extends>QWidget</extends>

View File

@ -59,6 +59,7 @@ set(SOURCE_FILES
AbstractUpdater.cpp
Action.cpp
ActionMapper.cpp
AssetInfo.cpp
AssetTile.cpp
AssetView.cpp
AudioProcessor.cpp

View File

@ -18,6 +18,7 @@
#include <mgba/internal/gba/video.h>
#endif
#ifdef M_CORE_GB
#include <mgba/internal/gb/gb.h>
#include <mgba/internal/gb/memory.h>
#endif
@ -42,6 +43,12 @@ MapView::MapView(std::shared_ptr<CoreController> controller, QWidget* parent)
m_boundary = 2048;
m_addressBase = BASE_VRAM;
m_addressWidth = 8;
m_ui.bgInfo->addCustomProperty("priority", tr("Priority"));
m_ui.bgInfo->addCustomProperty("screenBase", tr("Map base"));
m_ui.bgInfo->addCustomProperty("charBase", tr("Tile base"));
m_ui.bgInfo->addCustomProperty("size", tr("Size"));
m_ui.bgInfo->addCustomProperty("offset", tr("Offset"));
m_ui.bgInfo->addCustomProperty("transform", tr("Xform"));
break;
#endif
#ifdef M_CORE_GB
@ -49,6 +56,9 @@ MapView::MapView(std::shared_ptr<CoreController> controller, QWidget* parent)
m_boundary = 1024;
m_addressBase = GB_BASE_VRAM;
m_addressWidth = 4;
m_ui.bgInfo->addCustomProperty("screenBase", tr("Map base"));
m_ui.bgInfo->addCustomProperty("charBase", tr("Tile base"));
m_ui.bgInfo->addCustomProperty("offset", tr("Offset"));
break;
#endif
default:
@ -143,16 +153,58 @@ void MapView::updateTilesGBA(bool force) {
{
CoreController::Interrupter interrupter(m_controller);
int bitmap = -1;
int priority = -1;
int frame = 0;
QString offset(tr("N/A"));
QString transform(tr("N/A"));
if (m_controller->platform() == PLATFORM_GBA) {
int mode = GBARegisterDISPCNTGetMode(static_cast<GBA*>(m_controller->thread()->core->board)->memory.io[REG_DISPCNT]);
uint16_t* io = static_cast<GBA*>(m_controller->thread()->core->board)->memory.io;
int mode = GBARegisterDISPCNTGetMode(io[REG_DISPCNT >> 1]);
if (m_map == 2 && mode > 2) {
bitmap = mode == 4 ? 1 : 0;
if (mode != 3) {
frame = GBARegisterDISPCNTGetFrameSelect(io[REG_DISPCNT >> 1]);
}
}
priority = GBARegisterBGCNTGetPriority(io[(REG_BG0CNT >> 1) + m_map]);
if (mode == 0 || (mode == 1 && m_map != 2)) {
offset = QString("%1, %2")
.arg(io[(REG_BG0HOFS >> 1) + (m_map << 1)])
.arg(io[(REG_BG0VOFS >> 1) + (m_map << 1)]);
} else if ((mode > 0 && m_map == 2) || (mode == 2 && m_map == 3)) {
int32_t refX = io[(REG_BG2X_LO >> 1) + ((m_map - 2) << 2)];
refX |= io[(REG_BG2X_HI >> 1) + ((m_map - 2) << 2)] << 16;
int32_t refY = io[(REG_BG2Y_LO >> 1) + ((m_map - 2) << 2)];
refY |= io[(REG_BG2Y_HI >> 1) + ((m_map - 2) << 2)] << 16;
refX <<= 4;
refY <<= 4;
refX >>= 4;
refY >>= 4;
offset = QString("%1\n%2").arg(refX / 65536., 0, 'f', 3).arg(refY / 65536., 0, 'f', 3);
transform = QString("%1 %2\n%3 %4")
.arg(io[(REG_BG2PA >> 1) + ((m_map - 2) << 2)] / 256., 3, 'f', 2)
.arg(io[(REG_BG2PB >> 1) + ((m_map - 2) << 2)] / 256., 3, 'f', 2)
.arg(io[(REG_BG2PC >> 1) + ((m_map - 2) << 2)] / 256., 3, 'f', 2)
.arg(io[(REG_BG2PD >> 1) + ((m_map - 2) << 2)] / 256., 3, 'f', 2);
}
}
if (m_controller->platform() == PLATFORM_GB) {
uint8_t* io = static_cast<GB*>(m_controller->thread()->core->board)->memory.io;
int x = io[m_map == 0 ? 0x42 : 0x4A];
int y = io[m_map == 0 ? 0x43 : 0x4B];
offset = QString("%1, %2").arg(x).arg(y);
}
if (bitmap >= 0) {
mBitmapCache* bitmapCache = mBitmapCacheSetGetPointer(&m_cacheSet->bitmaps, bitmap);
int width = mBitmapCacheSystemInfoGetWidth(bitmapCache->sysConfig);
int height = mBitmapCacheSystemInfoGetHeight(bitmapCache->sysConfig);
m_ui.bgInfo->setCustomProperty("screenBase", QString("0x%1").arg(m_addressBase + bitmapCache->bitsStart[frame], 8, 16, QChar('0')));
m_ui.bgInfo->setCustomProperty("charBase", tr("N/A"));
m_ui.bgInfo->setCustomProperty("size", QString("%1×%2").arg(width).arg(height));
m_ui.bgInfo->setCustomProperty("priority", priority);
m_ui.bgInfo->setCustomProperty("offset", offset);
m_ui.bgInfo->setCustomProperty("transform", transform);
m_rawMap = QImage(QSize(width, height), QImage::Format_ARGB32);
uchar* bgBits = m_rawMap.bits();
for (int j = 0; j < height; ++j) {
@ -163,6 +215,16 @@ void MapView::updateTilesGBA(bool force) {
mMapCache* mapCache = mMapCacheSetGetPointer(&m_cacheSet->maps, m_map);
int tilesW = 1 << mMapCacheSystemInfoGetTilesWide(mapCache->sysConfig);
int tilesH = 1 << mMapCacheSystemInfoGetTilesHigh(mapCache->sysConfig);
m_ui.bgInfo->setCustomProperty("screenBase", QString("%0%1")
.arg(m_addressWidth == 8 ? "0x" : "")
.arg(m_addressBase + mapCache->mapStart, m_addressWidth, 16, QChar('0')));
m_ui.bgInfo->setCustomProperty("charBase", QString("%0%1")
.arg(m_addressWidth == 8 ? "0x" : "")
.arg(m_addressBase + mapCache->tileCache->tileBase, m_addressWidth, 16, QChar('0')));
m_ui.bgInfo->setCustomProperty("size", QString("%1×%2").arg(tilesW * 8).arg(tilesH * 8));
m_ui.bgInfo->setCustomProperty("priority", priority);
m_ui.bgInfo->setCustomProperty("offset", offset);
m_ui.bgInfo->setCustomProperty("transform", transform);
m_rawMap = QImage(QSize(tilesW * 8, tilesH * 8), QImage::Format_ARGB32);
uchar* bgBits = m_rawMap.bits();
for (int j = 0; j < tilesH; ++j) {

View File

@ -6,18 +6,80 @@
<rect>
<x>0</x>
<y>0</y>
<width>641</width>
<height>489</height>
<width>1273</width>
<height>736</height>
</rect>
</property>
<property name="windowTitle">
<string>Maps</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="bgLayout"/>
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,0,0">
<item row="3" column="0">
<widget class="QGBA::AssetTile" name="tile"/>
</item>
<item row="0" column="1" rowspan="5">
<item row="2" column="0">
<widget class="QGBA::AssetInfo" name="bgInfo">
<property name="title">
<string/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2"/>
</widget>
</item>
<item row="5" column="0">
<widget class="QPushButton" name="exportButton">
<property name="text">
<string>Export</string>
</property>
</widget>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<layout class="QVBoxLayout" name="bgLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QSpinBox" name="magnification">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="suffix">
<string>×</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>8</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Magnification</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item row="1" column="1" rowspan="5" colspan="2">
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
@ -30,8 +92,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>457</width>
<height>463</height>
<width>835</width>
<height>720</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@ -71,62 +133,15 @@
</widget>
</widget>
</item>
<item row="2" column="0">
<widget class="QGBA::AssetTile" name="tile"/>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QSpinBox" name="magnification">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="suffix">
<string>×</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>8</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Magnification</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QPushButton" name="exportButton">
<property name="text">
<string>Export</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QGBA::AssetInfo</class>
<extends>QGroupBox</extends>
<header>AssetInfo.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QGBA::AssetTile</class>
<extends>QGroupBox</extends>