mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-01-19 14:55:38 +00:00
Qt: Keep debugger open outside of game
This commit is contained in:
parent
4a70164dac
commit
e3a287de44
|
@ -1,12 +1,14 @@
|
||||||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
|
||||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||||
|
|
||||||
#include "debuggerwindow.h"
|
#include "debuggerwindow.h"
|
||||||
#include "common/assert.h"
|
|
||||||
#include "core/cpu_core_private.h"
|
|
||||||
#include "debuggermodels.h"
|
#include "debuggermodels.h"
|
||||||
#include "qthost.h"
|
#include "qthost.h"
|
||||||
#include "qtutils.h"
|
#include "qtutils.h"
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "core/cpu_core_private.h"
|
||||||
|
|
||||||
#include <QtCore/QSignalBlocker>
|
#include <QtCore/QSignalBlocker>
|
||||||
#include <QtGui/QFontDatabase>
|
#include <QtGui/QFontDatabase>
|
||||||
#include <QtWidgets/QFileDialog>
|
#include <QtWidgets/QFileDialog>
|
||||||
|
@ -20,14 +22,24 @@ DebuggerWindow::DebuggerWindow(QWidget* parent /* = nullptr */)
|
||||||
connectSignals();
|
connectSignals();
|
||||||
createModels();
|
createModels();
|
||||||
setMemoryViewRegion(Bus::MemoryRegion::RAM);
|
setMemoryViewRegion(Bus::MemoryRegion::RAM);
|
||||||
setUIEnabled(false);
|
setUIEnabled(QtHost::IsSystemPaused(), QtHost::IsSystemValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
DebuggerWindow::~DebuggerWindow() = default;
|
DebuggerWindow::~DebuggerWindow() = default;
|
||||||
|
|
||||||
void DebuggerWindow::onEmulationPaused()
|
void DebuggerWindow::onSystemStarted()
|
||||||
{
|
{
|
||||||
setUIEnabled(true);
|
setUIEnabled(false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebuggerWindow::onSystemDestroyed()
|
||||||
|
{
|
||||||
|
setUIEnabled(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebuggerWindow::onSystemPaused()
|
||||||
|
{
|
||||||
|
setUIEnabled(true, true);
|
||||||
refreshAll();
|
refreshAll();
|
||||||
refreshBreakpointList();
|
refreshBreakpointList();
|
||||||
|
|
||||||
|
@ -37,9 +49,9 @@ void DebuggerWindow::onEmulationPaused()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerWindow::onEmulationResumed()
|
void DebuggerWindow::onSystemResumed()
|
||||||
{
|
{
|
||||||
setUIEnabled(false);
|
setUIEnabled(false, true);
|
||||||
|
|
||||||
{
|
{
|
||||||
QSignalBlocker sb(m_ui.actionPause);
|
QSignalBlocker sb(m_ui.actionPause);
|
||||||
|
@ -84,7 +96,7 @@ void DebuggerWindow::onPauseActionToggled(bool paused)
|
||||||
if (!paused)
|
if (!paused)
|
||||||
{
|
{
|
||||||
m_registers_model->saveCurrentValues();
|
m_registers_model->saveCurrentValues();
|
||||||
setUIEnabled(false);
|
setUIEnabled(false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_emu_thread->setSystemPaused(paused);
|
g_emu_thread->setSystemPaused(paused);
|
||||||
|
@ -422,8 +434,10 @@ void DebuggerWindow::setupAdditionalUi()
|
||||||
|
|
||||||
void DebuggerWindow::connectSignals()
|
void DebuggerWindow::connectSignals()
|
||||||
{
|
{
|
||||||
connect(g_emu_thread, &EmuThread::systemPaused, this, &DebuggerWindow::onEmulationPaused);
|
connect(g_emu_thread, &EmuThread::systemPaused, this, &DebuggerWindow::onSystemPaused);
|
||||||
connect(g_emu_thread, &EmuThread::systemResumed, this, &DebuggerWindow::onEmulationResumed);
|
connect(g_emu_thread, &EmuThread::systemResumed, this, &DebuggerWindow::onSystemResumed);
|
||||||
|
connect(g_emu_thread, &EmuThread::systemStarted, this, &DebuggerWindow::onSystemStarted);
|
||||||
|
connect(g_emu_thread, &EmuThread::systemDestroyed, this, &DebuggerWindow::onSystemDestroyed);
|
||||||
connect(g_emu_thread, &EmuThread::debuggerMessageReported, this, &DebuggerWindow::onDebuggerMessageReported);
|
connect(g_emu_thread, &EmuThread::debuggerMessageReported, this, &DebuggerWindow::onDebuggerMessageReported);
|
||||||
|
|
||||||
connect(m_ui.actionPause, &QAction::toggled, this, &DebuggerWindow::onPauseActionToggled);
|
connect(m_ui.actionPause, &QAction::toggled, this, &DebuggerWindow::onPauseActionToggled);
|
||||||
|
@ -483,8 +497,10 @@ void DebuggerWindow::createModels()
|
||||||
m_ui.breakpointsWidget->setRootIsDecorated(false);
|
m_ui.breakpointsWidget->setRootIsDecorated(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerWindow::setUIEnabled(bool enabled)
|
void DebuggerWindow::setUIEnabled(bool enabled, bool allow_pause)
|
||||||
{
|
{
|
||||||
|
m_ui.actionPause->setEnabled(allow_pause);
|
||||||
|
|
||||||
// Disable all UI elements that depend on execution state
|
// Disable all UI elements that depend on execution state
|
||||||
m_ui.codeView->setEnabled(enabled);
|
m_ui.codeView->setEnabled(enabled);
|
||||||
m_ui.registerView->setEnabled(enabled);
|
m_ui.registerView->setEnabled(enabled);
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
|
||||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "core/types.h"
|
|
||||||
#include "ui_debuggerwindow.h"
|
#include "ui_debuggerwindow.h"
|
||||||
|
|
||||||
|
#include "core/types.h"
|
||||||
|
|
||||||
#include <QtWidgets/QMainWindow>
|
#include <QtWidgets/QMainWindow>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
@ -27,14 +30,14 @@ public:
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void closed();
|
void closed();
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
void onEmulationPaused();
|
|
||||||
void onEmulationResumed();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent* event);
|
void closeEvent(QCloseEvent* event);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
|
void onSystemStarted();
|
||||||
|
void onSystemDestroyed();
|
||||||
|
void onSystemPaused();
|
||||||
|
void onSystemResumed();
|
||||||
void onDebuggerMessageReported(const QString& message);
|
void onDebuggerMessageReported(const QString& message);
|
||||||
|
|
||||||
void refreshAll();
|
void refreshAll();
|
||||||
|
@ -47,7 +50,7 @@ private Q_SLOTS:
|
||||||
void onGoToAddressTriggered();
|
void onGoToAddressTriggered();
|
||||||
void onDumpAddressTriggered();
|
void onDumpAddressTriggered();
|
||||||
void onFollowAddressTriggered();
|
void onFollowAddressTriggered();
|
||||||
void onTraceTriggered();
|
void onTraceTriggered();
|
||||||
void onAddBreakpointTriggered();
|
void onAddBreakpointTriggered();
|
||||||
void onToggleBreakpointTriggered();
|
void onToggleBreakpointTriggered();
|
||||||
void onClearBreakpointsTriggered();
|
void onClearBreakpointsTriggered();
|
||||||
|
@ -59,13 +62,12 @@ private Q_SLOTS:
|
||||||
void onMemorySearchTriggered();
|
void onMemorySearchTriggered();
|
||||||
void onMemorySearchStringChanged(const QString&);
|
void onMemorySearchStringChanged(const QString&);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupAdditionalUi();
|
void setupAdditionalUi();
|
||||||
void connectSignals();
|
void connectSignals();
|
||||||
void disconnectSignals();
|
void disconnectSignals();
|
||||||
void createModels();
|
void createModels();
|
||||||
void setUIEnabled(bool enabled);
|
void setUIEnabled(bool enabled, bool allow_pause);
|
||||||
void setMemoryViewRegion(Bus::MemoryRegion region);
|
void setMemoryViewRegion(Bus::MemoryRegion region);
|
||||||
void toggleBreakpoint(VirtualMemoryAddress address);
|
void toggleBreakpoint(VirtualMemoryAddress address);
|
||||||
void clearBreakpoints();
|
void clearBreakpoints();
|
||||||
|
|
|
@ -608,12 +608,6 @@ void MainWindow::onSystemDestroyed()
|
||||||
delete m_cheat_manager_dialog;
|
delete m_cheat_manager_dialog;
|
||||||
m_cheat_manager_dialog = nullptr;
|
m_cheat_manager_dialog = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_debugger_window)
|
|
||||||
{
|
|
||||||
delete m_debugger_window;
|
|
||||||
m_debugger_window = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onRunningGameChanged(const QString& filename, const QString& game_serial, const QString& game_title)
|
void MainWindow::onRunningGameChanged(const QString& filename, const QString& game_serial, const QString& game_title)
|
||||||
|
@ -1733,7 +1727,7 @@ void MainWindow::updateEmulationActions(bool starting, bool running, bool cheevo
|
||||||
m_ui.menuChangeDisc->setDisabled(starting || !running);
|
m_ui.menuChangeDisc->setDisabled(starting || !running);
|
||||||
m_ui.menuCheats->setDisabled(starting || !running || cheevos_challenge_mode);
|
m_ui.menuCheats->setDisabled(starting || !running || cheevos_challenge_mode);
|
||||||
m_ui.actionCheatManager->setDisabled(starting || !running || cheevos_challenge_mode);
|
m_ui.actionCheatManager->setDisabled(starting || !running || cheevos_challenge_mode);
|
||||||
m_ui.actionCPUDebugger->setDisabled(starting || !running || cheevos_challenge_mode);
|
m_ui.actionCPUDebugger->setDisabled(cheevos_challenge_mode);
|
||||||
m_ui.actionDumpRAM->setDisabled(starting || !running || cheevos_challenge_mode);
|
m_ui.actionDumpRAM->setDisabled(starting || !running || cheevos_challenge_mode);
|
||||||
m_ui.actionDumpVRAM->setDisabled(starting || !running || cheevos_challenge_mode);
|
m_ui.actionDumpVRAM->setDisabled(starting || !running || cheevos_challenge_mode);
|
||||||
m_ui.actionDumpSPURAM->setDisabled(starting || !running || cheevos_challenge_mode);
|
m_ui.actionDumpSPURAM->setDisabled(starting || !running || cheevos_challenge_mode);
|
||||||
|
@ -2871,19 +2865,19 @@ void MainWindow::onToolsCheatManagerTriggered()
|
||||||
|
|
||||||
void MainWindow::openCPUDebugger()
|
void MainWindow::openCPUDebugger()
|
||||||
{
|
{
|
||||||
g_emu_thread->setSystemPaused(true, true);
|
if (m_debugger_window)
|
||||||
if (!System::IsValid())
|
{
|
||||||
|
m_debugger_window->raise();
|
||||||
|
m_debugger_window->activateWindow();
|
||||||
|
m_debugger_window->setFocus();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Assert(!m_debugger_window);
|
Assert(!m_debugger_window);
|
||||||
|
|
||||||
m_debugger_window = new DebuggerWindow();
|
m_debugger_window = new DebuggerWindow();
|
||||||
m_debugger_window->setWindowIcon(windowIcon());
|
m_debugger_window->setWindowIcon(windowIcon());
|
||||||
connect(m_debugger_window, &DebuggerWindow::closed, this, &MainWindow::onCPUDebuggerClosed);
|
connect(m_debugger_window, &DebuggerWindow::closed, this, &MainWindow::onCPUDebuggerClosed);
|
||||||
m_debugger_window->show();
|
m_debugger_window->show();
|
||||||
|
|
||||||
// the debugger will miss the pause event above (or we were already paused), so fire it now
|
|
||||||
m_debugger_window->onEmulationPaused();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onCPUDebuggerClosed()
|
void MainWindow::onCPUDebuggerClosed()
|
||||||
|
|
Loading…
Reference in a new issue