src/platform/qt/MemoryView.cpp (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7#include "MemoryView.h"
8
9#include "GameController.h"
10
11extern "C" {
12#include "core/core.h"
13#include "gba/memory.h"
14}
15
16using namespace QGBA;
17
18MemoryView::MemoryView(GameController* controller, QWidget* parent)
19 : QWidget(parent)
20 , m_controller(controller)
21{
22 m_ui.setupUi(this);
23
24 m_ui.hexfield->setController(controller);
25
26 connect(m_ui.regions, SIGNAL(currentIndexChanged(int)), this, SLOT(setIndex(int)));
27
28 connect(m_ui.width8, &QAbstractButton::clicked, [this]() { m_ui.hexfield->setAlignment(1); });
29 connect(m_ui.width16, &QAbstractButton::clicked, [this]() { m_ui.hexfield->setAlignment(2); });
30 connect(m_ui.width32, &QAbstractButton::clicked, [this]() { m_ui.hexfield->setAlignment(4); });
31 connect(m_ui.setAddress, SIGNAL(valueChanged(const QString&)), m_ui.hexfield, SLOT(jumpToAddress(const QString&)));
32
33 connect(m_ui.hexfield, SIGNAL(selectionChanged(uint32_t, uint32_t)), this, SLOT(updateSelection(uint32_t, uint32_t)));
34
35 connect(controller, SIGNAL(gameStopped(mCoreThread*)), this, SLOT(close()));
36
37 connect(controller, SIGNAL(frameAvailable(const uint32_t*)), this, SLOT(update()));
38 connect(controller, SIGNAL(gamePaused(mCoreThread*)), this, SLOT(update()));
39 connect(controller, SIGNAL(stateLoaded(mCoreThread*)), this, SLOT(update()));
40 connect(controller, SIGNAL(rewound(mCoreThread*)), this, SLOT(update()));
41}
42
43void MemoryView::setIndex(int index) {
44 static struct {
45 const char* name;
46 uint32_t base;
47 uint32_t size;
48 } indexInfo[] = {
49 { "All", 0, 0x10000000 },
50 { "BIOS", BASE_BIOS, SIZE_BIOS },
51 { "EWRAM", BASE_WORKING_RAM, SIZE_WORKING_RAM },
52 { "IWRAM", BASE_WORKING_IRAM, SIZE_WORKING_IRAM },
53 { "MMIO", BASE_IO, SIZE_IO },
54 { "Palette", BASE_PALETTE_RAM, SIZE_PALETTE_RAM },
55 { "VRAM", BASE_VRAM, SIZE_VRAM },
56 { "OAM", BASE_OAM, SIZE_OAM },
57 { "ROM", BASE_CART0, SIZE_CART0 },
58 { "ROM WS1", BASE_CART1, SIZE_CART1 },
59 { "ROM WS2", BASE_CART2, SIZE_CART2 },
60 { "SRAM", BASE_CART_SRAM, SIZE_CART_SRAM },
61 };
62 const auto& info = indexInfo[index];
63 m_ui.hexfield->setRegion(info.base, info.size, info.name);
64}
65
66void MemoryView::update() {
67 m_ui.hexfield->viewport()->update();
68 updateStatus();
69}
70
71void MemoryView::updateSelection(uint32_t start, uint32_t end) {
72 m_selection.first = start;
73 m_selection.second = end;
74 updateStatus();
75}
76
77void MemoryView::updateStatus() {
78 int align = m_ui.hexfield->alignment();
79 if (m_selection.first & (align - 1) || m_selection.second - m_selection.first != align) {
80 m_ui.sintVal->clear();
81 m_ui.uintVal->clear();
82 return;
83 }
84 if (!m_controller->isLoaded()) {
85 return;
86 }
87 ARMCore* cpu = static_cast<ARMCore*>(m_controller->thread()->core->cpu);
88 union {
89 uint32_t u32;
90 int32_t i32;
91 uint16_t u16;
92 int16_t i16;
93 uint8_t u8;
94 int8_t i8;
95 } value;
96 switch (align) {
97 case 1:
98 value.u8 = GBAView8(cpu, m_selection.first);
99 m_ui.sintVal->setText(QString::number(value.i8));
100 m_ui.uintVal->setText(QString::number(value.u8));
101 break;
102 case 2:
103 value.u16 = GBAView16(cpu, m_selection.first);
104 m_ui.sintVal->setText(QString::number(value.i16));
105 m_ui.uintVal->setText(QString::number(value.u16));
106 break;
107 case 4:
108 value.u32 = GBAView32(cpu, m_selection.first);
109 m_ui.sintVal->setText(QString::number(value.i32));
110 m_ui.uintVal->setText(QString::number(value.u32));
111 break;
112 }
113}