src/platform/qt/IOViewer.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#include "IOViewer.h"
7
8#include "GameController.h"
9
10#include <QFontDatabase>
11
12extern "C" {
13#include "gba/io.h"
14}
15
16using namespace QGBA;
17
18IOViewer::IOViewer(GameController* controller, QWidget* parent)
19 : QDialog(parent)
20 , m_controller(controller)
21{
22 m_ui.setupUi(this);
23
24 for (unsigned i = 0; i < REG_MAX >> 1; ++i) {
25 const char* reg = GBAIORegisterNames[i];
26 if (!reg) {
27 continue;
28 }
29 m_ui.regSelect->addItem("0x0400" + QString("%1: %2").arg(i << 1, 4, 16, QChar('0')).toUpper().arg(reg), i << 1);
30 }
31
32 const QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
33 m_ui.regValue->setFont(font);
34
35 connect(m_ui.buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonPressed(QAbstractButton*)));
36 connect(m_ui.buttonBox, SIGNAL(rejected()), this, SLOT(close()));
37 connect(m_ui.regSelect, SIGNAL(currentIndexChanged(int)), this, SLOT(selectRegister()));
38
39 connect(m_ui.b0, SIGNAL(toggled(bool)), this, SLOT(bitFlipped()));
40 connect(m_ui.b1, SIGNAL(toggled(bool)), this, SLOT(bitFlipped()));
41 connect(m_ui.b2, SIGNAL(toggled(bool)), this, SLOT(bitFlipped()));
42 connect(m_ui.b3, SIGNAL(toggled(bool)), this, SLOT(bitFlipped()));
43 connect(m_ui.b4, SIGNAL(toggled(bool)), this, SLOT(bitFlipped()));
44 connect(m_ui.b5, SIGNAL(toggled(bool)), this, SLOT(bitFlipped()));
45 connect(m_ui.b6, SIGNAL(toggled(bool)), this, SLOT(bitFlipped()));
46 connect(m_ui.b7, SIGNAL(toggled(bool)), this, SLOT(bitFlipped()));
47 connect(m_ui.b8, SIGNAL(toggled(bool)), this, SLOT(bitFlipped()));
48 connect(m_ui.b9, SIGNAL(toggled(bool)), this, SLOT(bitFlipped()));
49 connect(m_ui.bA, SIGNAL(toggled(bool)), this, SLOT(bitFlipped()));
50 connect(m_ui.bB, SIGNAL(toggled(bool)), this, SLOT(bitFlipped()));
51 connect(m_ui.bC, SIGNAL(toggled(bool)), this, SLOT(bitFlipped()));
52 connect(m_ui.bD, SIGNAL(toggled(bool)), this, SLOT(bitFlipped()));
53 connect(m_ui.bE, SIGNAL(toggled(bool)), this, SLOT(bitFlipped()));
54 connect(m_ui.bF, SIGNAL(toggled(bool)), this, SLOT(bitFlipped()));
55
56 selectRegister(0);
57}
58
59void IOViewer::update() {
60 m_value = 0;
61 m_controller->threadInterrupt();
62 if (m_controller->isLoaded()) {
63 m_value = GBAIORead(m_controller->thread()->gba, m_register);
64 }
65 m_controller->threadContinue();
66
67 m_ui.regValue->setText("0x" + QString("%1").arg(m_value, 4, 16, QChar('0')).toUpper());
68 bool signalsBlocked;
69 signalsBlocked = m_ui.b0->blockSignals(true);
70 m_ui.b0->setChecked(m_value & 0x0001 ? Qt::Checked : Qt::Unchecked);
71 m_ui.b0->blockSignals(signalsBlocked);
72 signalsBlocked = m_ui.b1->blockSignals(true);
73 m_ui.b1->setChecked(m_value & 0x0002 ? Qt::Checked : Qt::Unchecked);
74 m_ui.b1->blockSignals(signalsBlocked);
75 signalsBlocked = m_ui.b2->blockSignals(true);
76 m_ui.b2->setChecked(m_value & 0x0004 ? Qt::Checked : Qt::Unchecked);
77 m_ui.b2->blockSignals(signalsBlocked);
78 signalsBlocked = m_ui.b3->blockSignals(true);
79 m_ui.b3->setChecked(m_value & 0x0008 ? Qt::Checked : Qt::Unchecked);
80 m_ui.b3->blockSignals(signalsBlocked);
81 signalsBlocked = m_ui.b4->blockSignals(true);
82 m_ui.b4->setChecked(m_value & 0x0010 ? Qt::Checked : Qt::Unchecked);
83 m_ui.b4->blockSignals(signalsBlocked);
84 signalsBlocked = m_ui.b5->blockSignals(true);
85 m_ui.b5->setChecked(m_value & 0x0020 ? Qt::Checked : Qt::Unchecked);
86 m_ui.b5->blockSignals(signalsBlocked);
87 signalsBlocked = m_ui.b6->blockSignals(true);
88 m_ui.b6->setChecked(m_value & 0x0040 ? Qt::Checked : Qt::Unchecked);
89 m_ui.b6->blockSignals(signalsBlocked);
90 signalsBlocked = m_ui.b7->blockSignals(true);
91 m_ui.b7->setChecked(m_value & 0x0080 ? Qt::Checked : Qt::Unchecked);
92 m_ui.b7->blockSignals(signalsBlocked);
93 signalsBlocked = m_ui.b8->blockSignals(true);
94 m_ui.b8->setChecked(m_value & 0x0100 ? Qt::Checked : Qt::Unchecked);
95 m_ui.b8->blockSignals(signalsBlocked);
96 signalsBlocked = m_ui.b9->blockSignals(true);
97 m_ui.b9->setChecked(m_value & 0x0200 ? Qt::Checked : Qt::Unchecked);
98 m_ui.b9->blockSignals(signalsBlocked);
99 signalsBlocked = m_ui.bA->blockSignals(true);
100 m_ui.bA->setChecked(m_value & 0x0400 ? Qt::Checked : Qt::Unchecked);
101 m_ui.bA->blockSignals(signalsBlocked);
102 signalsBlocked = m_ui.bB->blockSignals(true);
103 m_ui.bB->setChecked(m_value & 0x0800 ? Qt::Checked : Qt::Unchecked);
104 m_ui.bB->blockSignals(signalsBlocked);
105 signalsBlocked = m_ui.bC->blockSignals(true);
106 m_ui.bC->setChecked(m_value & 0x1000 ? Qt::Checked : Qt::Unchecked);
107 m_ui.bC->blockSignals(signalsBlocked);
108 signalsBlocked = m_ui.bD->blockSignals(true);
109 m_ui.bD->setChecked(m_value & 0x2000 ? Qt::Checked : Qt::Unchecked);
110 m_ui.bD->blockSignals(signalsBlocked);
111 signalsBlocked = m_ui.bE->blockSignals(true);
112 m_ui.bE->setChecked(m_value & 0x4000 ? Qt::Checked : Qt::Unchecked);
113 m_ui.bE->blockSignals(signalsBlocked);
114 signalsBlocked = m_ui.bF->blockSignals(true);
115 m_ui.bF->setChecked(m_value & 0x8000 ? Qt::Checked : Qt::Unchecked);
116 m_ui.bF->blockSignals(signalsBlocked);
117}
118
119void IOViewer::bitFlipped() {
120 m_value = 0;
121 m_value |= m_ui.b0->isChecked() << 0x0;
122 m_value |= m_ui.b1->isChecked() << 0x1;
123 m_value |= m_ui.b2->isChecked() << 0x2;
124 m_value |= m_ui.b3->isChecked() << 0x3;
125 m_value |= m_ui.b4->isChecked() << 0x4;
126 m_value |= m_ui.b5->isChecked() << 0x5;
127 m_value |= m_ui.b6->isChecked() << 0x6;
128 m_value |= m_ui.b7->isChecked() << 0x7;
129 m_value |= m_ui.b8->isChecked() << 0x8;
130 m_value |= m_ui.b9->isChecked() << 0x9;
131 m_value |= m_ui.bA->isChecked() << 0xA;
132 m_value |= m_ui.bB->isChecked() << 0xB;
133 m_value |= m_ui.bC->isChecked() << 0xC;
134 m_value |= m_ui.bD->isChecked() << 0xD;
135 m_value |= m_ui.bE->isChecked() << 0xE;
136 m_value |= m_ui.bF->isChecked() << 0xF;
137 m_ui.regValue->setText("0x" + QString("%1").arg(m_value, 4, 16, QChar('0')).toUpper());
138}
139
140void IOViewer::writeback() {
141 m_controller->threadInterrupt();
142 if (m_controller->isLoaded()) {
143 GBAIOWrite(m_controller->thread()->gba, m_register, m_value);
144 }
145 m_controller->threadContinue();
146 update();
147}
148
149void IOViewer::selectRegister(unsigned address) {
150 m_register = address;
151 update();
152}
153
154void IOViewer::selectRegister() {
155 selectRegister(m_ui.regSelect->currentData().toUInt());
156}
157
158void IOViewer::buttonPressed(QAbstractButton* button) {
159 switch (m_ui.buttonBox->standardButton(button)) {
160 case QDialogButtonBox::Reset:
161 update();
162 break;
163 case QDialogButtonBox::Apply:
164 writeback();
165 break;
166 default:
167 break;
168 }
169}