mirror of https://github.com/mgba-emu/mgba.git
Qt: MemoryView subregions
This commit is contained in:
parent
a7ad78d46e
commit
c021267ce6
|
@ -49,22 +49,33 @@ MemoryModel::MemoryModel(QWidget* parent)
|
||||||
|
|
||||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||||
m_margins = QMargins(metrics.width("FFFFFF ") + 3, m_cellHeight + 1, metrics.width(" AAAAAAAAAAAAAAAA") + 3, 0);
|
m_margins = QMargins(metrics.width("FFFFFF ") + 4, m_cellHeight + 1, metrics.width(" AAAAAAAAAAAAAAAA") + 3, 0);
|
||||||
|
|
||||||
verticalScrollBar()->setRange(0, 0x01000001 - viewport()->size().height() / m_cellHeight);
|
|
||||||
connect(verticalScrollBar(), &QSlider::sliderMoved, [this](int position) {
|
connect(verticalScrollBar(), &QSlider::sliderMoved, [this](int position) {
|
||||||
m_top = position;
|
m_top = position;
|
||||||
update();
|
update();
|
||||||
});
|
});
|
||||||
update();
|
|
||||||
|
setRegion(0, 0x10000000, tr("All"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryModel::setController(GameController* controller) {
|
void MemoryModel::setController(GameController* controller) {
|
||||||
m_cpu = controller->thread()->cpu;
|
m_cpu = controller->thread()->cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MemoryModel::setRegion(uint32_t base, uint32_t size, const QString& name) {
|
||||||
|
m_top = 0;
|
||||||
|
m_base = base;
|
||||||
|
m_size = size;
|
||||||
|
m_regionName = name;
|
||||||
|
m_regionName.prepare(QTransform(), m_font);
|
||||||
|
verticalScrollBar()->setRange(0, (size >> 4) + 1 - viewport()->size().height() / m_cellHeight);
|
||||||
|
verticalScrollBar()->setValue(0);
|
||||||
|
viewport()->update();
|
||||||
|
}
|
||||||
|
|
||||||
void MemoryModel::resizeEvent(QResizeEvent*) {
|
void MemoryModel::resizeEvent(QResizeEvent*) {
|
||||||
verticalScrollBar()->setRange(0, 0x01000001 - viewport()->size().height() / m_cellHeight);
|
verticalScrollBar()->setRange(0, (m_size >> 4) + 1 - viewport()->size().height() / m_cellHeight);
|
||||||
boundsCheck();
|
boundsCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +85,7 @@ void MemoryModel::paintEvent(QPaintEvent* event) {
|
||||||
QChar c0('0');
|
QChar c0('0');
|
||||||
QSizeF cellSize = QSizeF((viewport()->size().width() - (m_margins.left() + m_margins.right())) / 16.f, m_cellHeight);
|
QSizeF cellSize = QSizeF((viewport()->size().width() - (m_margins.left() + m_margins.right())) / 16.f, m_cellHeight);
|
||||||
QSizeF letterSize = QSizeF(m_letterWidth, m_cellHeight);
|
QSizeF letterSize = QSizeF(m_letterWidth, m_cellHeight);
|
||||||
painter.drawText(QRect(QPoint(0, 0), QSize(m_margins.left(), m_margins.top())), Qt::AlignHCenter, tr("All"));
|
painter.drawStaticText(QPointF((m_margins.left() - m_regionName.size().width() - 1) / 2.0, 0), m_regionName);
|
||||||
painter.drawText(QRect(QPoint(viewport()->size().width() - m_margins.right(), 0), QSize(m_margins.right(), m_margins.top())), Qt::AlignHCenter, tr("ASCII"));
|
painter.drawText(QRect(QPoint(viewport()->size().width() - m_margins.right(), 0), QSize(m_margins.right(), m_margins.top())), Qt::AlignHCenter, tr("ASCII"));
|
||||||
for (int x = 0; x < 16; ++x) {
|
for (int x = 0; x < 16; ++x) {
|
||||||
painter.drawText(QRectF(QPointF(cellSize.width() * x + m_margins.left(), 0), cellSize), Qt::AlignHCenter, QString::number(x, 16).toUpper());
|
painter.drawText(QRectF(QPointF(cellSize.width() * x + m_margins.left(), 0), cellSize), Qt::AlignHCenter, QString::number(x, 16).toUpper());
|
||||||
|
@ -82,10 +93,10 @@ void MemoryModel::paintEvent(QPaintEvent* event) {
|
||||||
int height = (viewport()->size().height() - m_cellHeight) / m_cellHeight;
|
int height = (viewport()->size().height() - m_cellHeight) / m_cellHeight;
|
||||||
for (int y = 0; y < height; ++y) {
|
for (int y = 0; y < height; ++y) {
|
||||||
int yp = m_cellHeight * y + m_margins.top();
|
int yp = m_cellHeight * y + m_margins.top();
|
||||||
QString data = QString("%0").arg(y + m_top, 6, 16, c0).toUpper();
|
QString data = QString("%0").arg(y + m_top + m_base / 16, 6, 16, c0).toUpper();
|
||||||
painter.drawText(QRectF(QPointF(0, yp), QSizeF(m_margins.left(), m_cellHeight)), Qt::AlignHCenter, data);
|
painter.drawText(QRectF(QPointF(0, yp), QSizeF(m_margins.left(), m_cellHeight)), Qt::AlignHCenter, data);
|
||||||
for (int x = 0; x < 16; ++x) {
|
for (int x = 0; x < 16; ++x) {
|
||||||
uint8_t b = m_cpu->memory.load8(m_cpu, (y + m_top) * 16 + x, nullptr);
|
uint8_t b = m_cpu->memory.load8(m_cpu, (y + m_top) * 16 + x + m_base, nullptr);
|
||||||
painter.drawStaticText(QPointF(cellSize.width() * (x + 0.5) - m_letterWidth + m_margins.left(), yp), m_staticNumbers[b]);
|
painter.drawStaticText(QPointF(cellSize.width() * (x + 0.5) - m_letterWidth + m_margins.left(), yp), m_staticNumbers[b]);
|
||||||
painter.drawStaticText(QPointF(viewport()->size().width() - (16 - x) * m_margins.right() / 17.0 - m_letterWidth * 0.5, yp), b < 0x80 ? m_staticAscii[b] : m_staticAscii[0]);
|
painter.drawStaticText(QPointF(viewport()->size().width() - (16 - x) * m_margins.right() / 17.0 - m_letterWidth * 0.5, yp), b < 0x80 ? m_staticAscii[b] : m_staticAscii[0]);
|
||||||
}
|
}
|
||||||
|
@ -99,14 +110,14 @@ void MemoryModel::wheelEvent(QWheelEvent* event) {
|
||||||
m_top -= event->angleDelta().y() / 8;
|
m_top -= event->angleDelta().y() / 8;
|
||||||
boundsCheck();
|
boundsCheck();
|
||||||
event->accept();
|
event->accept();
|
||||||
|
verticalScrollBar()->setValue(m_top);
|
||||||
update();
|
update();
|
||||||
QAbstractScrollArea::wheelEvent(event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryModel::boundsCheck() {
|
void MemoryModel::boundsCheck() {
|
||||||
if (m_top < 0) {
|
if (m_top < 0) {
|
||||||
m_top = 0;
|
m_top = 0;
|
||||||
} else if (m_top > 0x01000001 - viewport()->size().height() / m_cellHeight) {
|
} else if (m_top > (m_size >> 4) + 1 - viewport()->size().height() / m_cellHeight) {
|
||||||
m_top = 0x01000001 - viewport()->size().height() / m_cellHeight;
|
m_top = (m_size >> 4) + 1 - viewport()->size().height() / m_cellHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ public:
|
||||||
|
|
||||||
void setController(GameController* controller);
|
void setController(GameController* controller);
|
||||||
|
|
||||||
|
void setRegion(uint32_t base, uint32_t size, const QString& name = QString());
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent*) override;
|
void resizeEvent(QResizeEvent*) override;
|
||||||
void paintEvent(QPaintEvent*) override;
|
void paintEvent(QPaintEvent*) override;
|
||||||
|
@ -38,10 +40,13 @@ private:
|
||||||
QFont m_font;
|
QFont m_font;
|
||||||
int m_cellHeight;
|
int m_cellHeight;
|
||||||
int m_letterWidth;
|
int m_letterWidth;
|
||||||
|
uint32_t m_base;
|
||||||
|
uint32_t m_size;
|
||||||
int m_top;
|
int m_top;
|
||||||
QMargins m_margins;
|
QMargins m_margins;
|
||||||
QVector<QStaticText> m_staticNumbers;
|
QVector<QStaticText> m_staticNumbers;
|
||||||
QVector<QStaticText> m_staticAscii;
|
QVector<QStaticText> m_staticAscii;
|
||||||
|
QStaticText m_regionName;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
|
|
||||||
#include "GameController.h"
|
#include "GameController.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "gba/memory.h"
|
||||||
|
}
|
||||||
|
|
||||||
using namespace QGBA;
|
using namespace QGBA;
|
||||||
|
|
||||||
MemoryView::MemoryView(GameController* controller, QWidget* parent)
|
MemoryView::MemoryView(GameController* controller, QWidget* parent)
|
||||||
|
@ -17,5 +21,31 @@ MemoryView::MemoryView(GameController* controller, QWidget* parent)
|
||||||
m_ui.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
|
|
||||||
m_ui.hexfield->setController(controller);
|
m_ui.hexfield->setController(controller);
|
||||||
|
|
||||||
|
connect(m_ui.regions, SIGNAL(currentIndexChanged(int)), this, SLOT(setIndex(int)));
|
||||||
|
|
||||||
connect(controller, SIGNAL(gameStopped(GBAThread*)), this, SLOT(close()));
|
connect(controller, SIGNAL(gameStopped(GBAThread*)), this, SLOT(close()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MemoryView::setIndex(int index) {
|
||||||
|
static struct {
|
||||||
|
const char* name;
|
||||||
|
uint32_t base;
|
||||||
|
uint32_t size;
|
||||||
|
} indexInfo[] = {
|
||||||
|
{ "All", 0, 0x10000000 },
|
||||||
|
{ "BIOS", BASE_BIOS, SIZE_BIOS },
|
||||||
|
{ "EWRAM", BASE_WORKING_RAM, SIZE_WORKING_RAM },
|
||||||
|
{ "IWRAM", BASE_WORKING_IRAM, SIZE_WORKING_IRAM },
|
||||||
|
{ "MMIO", BASE_IO, SIZE_IO },
|
||||||
|
{ "Palette", BASE_PALETTE_RAM, SIZE_PALETTE_RAM },
|
||||||
|
{ "VRAM", BASE_VRAM, SIZE_VRAM },
|
||||||
|
{ "OAM", BASE_OAM, SIZE_OAM },
|
||||||
|
{ "ROM", BASE_CART0, SIZE_CART0 },
|
||||||
|
{ "ROM (WS1)", BASE_CART1, SIZE_CART1 },
|
||||||
|
{ "ROM (WS2)", BASE_CART2, SIZE_CART2 },
|
||||||
|
{ "SRAM", BASE_CART_SRAM, SIZE_CART_SRAM },
|
||||||
|
};
|
||||||
|
const auto& info = indexInfo[index];
|
||||||
|
m_ui.hexfield->setRegion(info.base, info.size, info.name);
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,9 @@ Q_OBJECT
|
||||||
public:
|
public:
|
||||||
MemoryView(GameController* controller, QWidget* parent = nullptr);
|
MemoryView(GameController* controller, QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void setIndex(int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MemoryView m_ui;
|
Ui::MemoryView m_ui;
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,112 @@
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGBA::MemoryModel" name="hexfield" native="true"/>
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="regions">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>All</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>BIOS (16kiB)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Working RAM (256kiB)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Internal Working RAM (32kiB)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Memory-Mapped I/O</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Palette RAM (1kiB)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Video RAM (96kiB)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>OBJ Attribute Memory (1kiB)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Game Pak (32MiB)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Game Pak (Waitstate 1)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Game Pak (Waitstate 2)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Static RAM (64kiB)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Inspect Address</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEdit">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="maxLength">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGBA::MemoryModel" name="hexfield" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
Loading…
Reference in New Issue