Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion gui/qt/CEmu.pro
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ SOURCES += \
../../core/bus.c \
keyhistorywidget.cpp \
tablewidget.cpp \
gotodialog.cpp \
basicdebugger.cpp

linux|macx: SOURCES += ../../core/os/os-linux.c
Expand Down Expand Up @@ -390,7 +391,8 @@ HEADERS += \
archive/extractor.h \
../../core/bus.h \
keyhistorywidget.h \
tablewidget.h
tablewidget.h \
gotodialog.h

FORMS += \
mainwindow.ui \
Expand Down
1 change: 1 addition & 0 deletions gui/qt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ set(CEmu_Sources
debugger/hexwidget.cpp debugger/hexwidget.h
debugger/visualizerdisplaywidget.cpp debugger/visualizerdisplaywidget.h
dockwidget.cpp dockwidget.h
gotodialog.cpp gotodialog.h
emuthread.cpp emuthread.h
ipc.cpp ipc.h
keyhistorywidget.cpp keyhistorywidget.h
Expand Down
27 changes: 22 additions & 5 deletions gui/qt/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,24 @@
#include "../../core/realclock.h"
#include "../../core/sha256.h"
#include "../../core/schedule.h"
#include "gotodialog.h"

#include <QtWidgets/QToolTip>
#include <QtCore/QFileInfo>
#include <QtCore/QRegularExpression>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QInputDialog>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QDialogButtonBox>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QScrollBar>
#include <QtNetwork/QNetworkReply>
#include <QtGui/QClipboard>
#include <QtGui/QWindow>
#include <QtGui/QScreen>
#include <algorithm>

#ifdef _MSC_VER
#include <direct.h>
Expand Down Expand Up @@ -1968,16 +1975,26 @@
// ------------------------------------------------

void MainWindow::gotoPressed() {
bool accept;

if (m_gotoAddr.isEmpty()) {
m_gotoAddr = m_disasm->getSelectedAddr();
}

QString address = getAddressString(m_gotoAddr, &accept);
GotoDialog dlg(m_gotoAddr, m_disasmGotoHistory, this);
if (dlg.exec() == QDialog::Accepted) {
QString typed = dlg.text().toUpper().trimmed();
bool ok = false;
QString resolved = resolveAddressOrEquate(typed, &ok);
if (ok) {
m_gotoAddr = typed;
disasmUpdateAddr(static_cast<int>(hex2int(resolved)), false);

if (accept) {
disasmUpdateAddr(hex2int(m_gotoAddr = address), false);
auto &hist = m_disasmGotoHistory;
hist.erase(std::remove_if(hist.begin(), hist.end(), [&](const QString &s){ return s.compare(typed, Qt::CaseInsensitive) == 0; }), hist.end());
hist.insert(hist.begin(), typed);
if (hist.size() > 50) { hist.resize(50); }
} else {
QMessageBox::warning(this, MSG_WARNING, tr("Error when reading input string"));
}
}
}

Expand Down Expand Up @@ -2010,7 +2027,7 @@
if (memWidget == Q_NULLPTR) {
for (HexWidget *edit : ui->debugMemoryWidget->findChildren<HexWidget*>()) {
uint32_t offset = address - edit->getBase();
if (offset < edit->getSize()) {

Check warning on line 2030 in gui/qt/debugger.cpp

View workflow job for this annotation

GitHub Actions / Build: macos-13 Qt6_intel

comparison of integers of different signs: 'uint32_t' (aka 'unsigned int') and 'int' [-Wsign-compare]
edit->setOffset(offset);
memWidget = edit;
didGoto = true;
Expand Down Expand Up @@ -2194,7 +2211,7 @@
if (name == QStringLiteral("rregView"))
t = QStringLiteral("r:\t") + val;

QToolTip::showText(static_cast<QMouseEvent*>(e)->globalPos(), t, widget, widget->rect());

Check warning on line 2214 in gui/qt/debugger.cpp

View workflow job for this annotation

GitHub Actions / Build: macos-13 Qt6_intel

'globalPos' is deprecated: Use globalPosition() [-Wdeprecated-declarations]
}
return QMainWindow::eventFilter(obj, e);
}
Expand Down
47 changes: 47 additions & 0 deletions gui/qt/gotodialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "gotodialog.h"

#include <QtWidgets/QComboBox>
#include <QtWidgets/QDialogButtonBox>
#include <QtWidgets/QLabel>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QSizePolicy>

GotoDialog::GotoDialog(const QString &seed,
const std::vector<QString> &history,
QWidget *parent)
: QDialog(parent) {
setWindowTitle(tr("Goto"));
auto *layout = new QVBoxLayout(this); // NOLINT: Qt parent-ownership handles deletion

auto *label = new QLabel(tr("Input Address (Or Equate):"), this); // NOLINT: Qt parent-ownership handles deletion
layout->addWidget(label);

m_combo = new QComboBox(this); // NOLINT: Qt parent-ownership handles deletion
m_combo->setEditable(true);

for (const QString &h : history) {
m_combo->addItem(h);
}
if (!seed.isEmpty()) {
m_combo->setEditText(seed.toUpper());
}
layout->addWidget(m_combo);

auto *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); // NOLINT: Qt parent-ownership handles deletion
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
layout->addWidget(buttons);

layout->setSizeConstraint(QLayout::SetFixedSize);
setMinimumWidth(360);

setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, true);

m_combo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_combo->setFixedHeight(m_combo->sizeHint().height());
adjustSize();
}

QString GotoDialog::text() const {
return m_combo ? m_combo->currentText() : QString();
}
25 changes: 25 additions & 0 deletions gui/qt/gotodialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef GOTODIALOG_H
#define GOTODIALOG_H

#include <QtWidgets/QDialog>
#include <QtCore/QString>
#include <vector>

QT_BEGIN_NAMESPACE
class QComboBox;
QT_END_NAMESPACE

class GotoDialog : public QDialog {
Q_OBJECT
public:
explicit GotoDialog(const QString &seed,
const std::vector<QString> &history,
QWidget *parent = nullptr);

[[nodiscard]] QString text() const;

private:
QComboBox *m_combo = nullptr;
};

#endif // GOTODIALOG_H
29 changes: 29 additions & 0 deletions gui/qt/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,35 @@ MainWindow::MainWindow(CEmuOpts &cliOpts, QWidget *p) : QMainWindow(p), ui(new U
setDebugIgnoreBreakpoints(m_config->value(SETTING_DEBUGGER_BREAK_IGNORE, false).toBool());
setDebugSoftCommands(m_config->value(SETTING_DEBUGGER_ENABLE_SOFT, true).toBool());
setAllowAnyRev(m_config->value(SETTING_DEBUGGER_ALLOW_ANY_REV, false).toBool());

// disassembly goto history
{
const QStringList list = m_config->value(SETTING_DEBUGGER_DISASM_GOTO_HISTORY).toStringList();
m_disasmGotoHistory.clear();
m_disasmGotoHistory.reserve(list.size());
for (const QString &s : list) {
QString t = s.toUpper().trimmed();
if (!t.isEmpty()) {
m_disasmGotoHistory.push_back(t);
if (m_disasmGotoHistory.size() >= 50) { break; }
}
}
}

// memory editors goto history
{
const QStringList list = m_config->value(SETTING_DEBUGGER_MEM_GOTO_HISTORY).toStringList();
m_memGotoHistory.clear();
m_memGotoHistory.reserve(list.size());
for (const QString &s : list) {
QString t = s.toUpper().trimmed();
if (!t.isEmpty()) {
m_memGotoHistory.push_back(t);
if (m_memGotoHistory.size() >= 50) { break; }
}
}
}

setPythonEdition(qvariant_cast<Qt::CheckState>(m_config->value(SETTING_PYTHON_EDITION, Qt::PartiallyChecked)));
setNormalOs(m_config->value(SETTING_DEBUGGER_NORM_OS, true).toBool());
setDebugLcdDma(!m_config->value(SETTING_DEBUGGER_IGNORE_DMA, true).toBool());
Expand Down
7 changes: 7 additions & 0 deletions gui/qt/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <QtCore/QStandardPaths>

#include <functional>
#include <vector>

QT_BEGIN_NAMESPACE
class QButtonGroup;
Expand Down Expand Up @@ -727,6 +728,10 @@ private slots:
QString m_RamGotoAddr;
QString m_memGotoAddr;

std::vector<QString> m_disasmGotoHistory;

std::vector<QString> m_memGotoHistory;

QString m_pathConfig;
QMenu *m_menuDocks;
QMenu *m_menuDebug;
Expand Down Expand Up @@ -781,6 +786,8 @@ private slots:

// Settings definitions
static const QString SETTING_DEBUGGER_TEXT_SIZE;
static const QString SETTING_DEBUGGER_DISASM_GOTO_HISTORY;
static const QString SETTING_DEBUGGER_MEM_GOTO_HISTORY;
static const QString SETTING_DEBUGGER_DISASM_SPACE;
static const QString SETTING_DEBUGGER_DISASM_TAB;
static const QString SETTING_DEBUGGER_RESTORE_ON_OPEN;
Expand Down
70 changes: 51 additions & 19 deletions gui/qt/memorywidget.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "searchwidget.h"
#include "gotodialog.h"
#include "dockwidget.h"
#include "utils.h"
#include "../../core/schedule.h"
Expand All @@ -12,6 +13,7 @@
#include <QtCore/QRegularExpression>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QInputDialog>
#include <algorithm>
#include <QtWidgets/QScrollBar>

#ifdef _MSC_VER
Expand Down Expand Up @@ -105,24 +107,43 @@ void MainWindow::memUpdateEdit(HexWidget *edit, bool force) {
}

void MainWindow::flashGotoPressed() {
bool accept = false;
QString addrStr = getAddressString(m_flashGotoAddr, &accept);

if (accept) {
m_flashGotoAddr = addrStr;
ui->flashEdit->setFocus();
ui->flashEdit->setOffset(hex2int(addrStr));
if (GotoDialog dlg(m_flashGotoAddr, m_memGotoHistory, this); dlg.exec() == QDialog::Accepted) {
const QString typed = dlg.text().toUpper().trimmed();
bool ok = false;
const QString resolved = resolveAddressOrEquate(typed, &ok);
if (ok) {
m_flashGotoAddr = typed;
ui->flashEdit->setFocus();
ui->flashEdit->setOffset(hex2int(resolved));

auto &hist = m_memGotoHistory;
std::erase_if(hist, [&](const QString &s){ return s.compare(typed, Qt::CaseInsensitive) == 0; });
hist.insert(hist.begin(), typed);
if (hist.size() > 50) { hist.resize(50); }
} else {
QMessageBox::warning(this, MSG_WARNING, tr("Error when reading input string"));
}
}
}

void MainWindow::ramGotoPressed() {
bool accept = false;
QString addrStr = getAddressString(m_RamGotoAddr, &accept);

if (accept) {
m_RamGotoAddr = addrStr;
ui->ramEdit->setFocus();
ui->ramEdit->setOffset(hex2int(addrStr) - 0xD00000);
GotoDialog dlg(m_RamGotoAddr, m_memGotoHistory, this);
if (dlg.exec() == QDialog::Accepted) {
const QString typed = dlg.text().toUpper().trimmed();
bool ok = false;
const QString resolved = resolveAddressOrEquate(typed, &ok);
if (ok) {
m_RamGotoAddr = typed;
ui->ramEdit->setFocus();
ui->ramEdit->setOffset(hex2int(resolved) - 0xD00000);

auto &hist = m_memGotoHistory;
std::erase_if(hist, [&](const QString &s){ return s.compare(typed, Qt::CaseInsensitive) == 0; });
hist.insert(hist.begin(), typed);
if (hist.size() > 50) { hist.resize(50); }
} else {
QMessageBox::warning(this, MSG_WARNING, tr("Error when reading input string"));
}
}
}

Expand Down Expand Up @@ -194,11 +215,22 @@ void MainWindow::memGotoEdit(HexWidget *edit) {
return;
}

bool accept = false;
QString address = getAddressString(m_memGotoAddr, &accept);

if (accept) {
memGoto(edit, static_cast<uint32_t>(hex2int(m_memGotoAddr = address)));
GotoDialog dlg(m_memGotoAddr, m_memGotoHistory, this);
if (dlg.exec() == QDialog::Accepted) {
QString typed = dlg.text().toUpper().trimmed();
bool ok = false;
QString resolved = resolveAddressOrEquate(typed, &ok);
if (ok) {
m_memGotoAddr = typed;
memGoto(edit, static_cast<uint32_t>(hex2int(resolved)));
// MRU update
auto &hist = m_memGotoHistory;
hist.erase(std::remove_if(hist.begin(), hist.end(), [&](const QString &s){ return s.compare(typed, Qt::CaseInsensitive) == 0; }), hist.end());
hist.insert(hist.begin(), typed);
if (hist.size() > 50) { hist.resize(50); }
} else {
QMessageBox::warning(this, MSG_WARNING, tr("Error when reading input string"));
}
}
}

Expand Down
19 changes: 18 additions & 1 deletion gui/qt/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#endif

const QString MainWindow::SETTING_DEBUGGER_TEXT_SIZE = QStringLiteral("Debugger/text_size");
const QString MainWindow::SETTING_DEBUGGER_DISASM_GOTO_HISTORY = QStringLiteral("Debugger/disasm_goto_history");
const QString MainWindow::SETTING_DEBUGGER_MEM_GOTO_HISTORY = QStringLiteral("Debugger/mem_goto_history");
const QString MainWindow::SETTING_DEBUGGER_RESTORE_ON_OPEN = QStringLiteral("Debugger/restore_on_open");
const QString MainWindow::SETTING_DEBUGGER_SAVE_ON_CLOSE = QStringLiteral("Debugger/save_on_close");
const QString MainWindow::SETTING_DEBUGGER_RESET_OPENS = QStringLiteral("Debugger/open_on_reset");
Expand Down Expand Up @@ -1280,6 +1282,22 @@ void MainWindow::saveSettings() {
m_config->setValue(SETTING_WINDOW_KEYHISTORY_DOCKS, m_docksKeyHistory);
m_config->setValue(SETTING_WINDOW_KEYHISTORY_CONFIG, QVariant::fromValue(m_docksKeyHistorySize));

// Disassembly Goto history
{
QStringList list;
list.reserve(static_cast<int>(m_disasmGotoHistory.size()));
for (const QString &s : m_disasmGotoHistory) { list.append(s); }
m_config->setValue(SETTING_DEBUGGER_DISASM_GOTO_HISTORY, list);
}

// Memory editors Goto history
{
QStringList list;
list.reserve(static_cast<int>(m_memGotoHistory.size()));
for (const QString &s : m_memGotoHistory) { list.append(s); }
m_config->setValue(SETTING_DEBUGGER_MEM_GOTO_HISTORY, list);
}

saveDebug();
stateSaveInfo();
recentSaveInfo();
Expand Down Expand Up @@ -1368,4 +1386,3 @@ void MainWindow::keymapExport() {
bool MainWindow::isFirstRun() {
return !m_config->value(SETTING_FIRST_RUN, false).toBool();
}

31 changes: 31 additions & 0 deletions gui/qt/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,37 @@ QString int2hex(uint32_t a, uint8_t l) {
return QString::number(a, 16).rightJustified(l, '0', true).toUpper();
}

QString resolveAddressOrEquate(const QString &input, bool *ok) {
if (ok) {
*ok = false;
}
QString in = input.toUpper().trimmed();
if (in.isEmpty()) {
return {};
}

if (QString equ = getAddressOfEquate(in.toStdString()); !equ.isEmpty()) {
if (ok) { *ok = true; }
return equ;
}

QString s = in;
if (s.startsWith(QStringLiteral("0X"))) {
s = s.mid(2);
}
if (s.isEmpty() || s.length() > 6) {
return {};
}
std::string ss = s.toStdString();
if (ss.find_first_not_of("0123456789ABCDEF") != std::string::npos) {
return {};
}

const auto value = static_cast<uint32_t>(hex2int(in));
if (ok) { *ok = true; }
return int2hex(value, 6);
}

std::string calc_var_content_string(const calc_var_t &var) {
decltype(&tivars::TypeHandlers::TH_TempEqu::makeStringFromData) func;
// We need to special case some specific temp-equ variables...
Expand Down
Loading
Loading