diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 6471c97ac8..6d15d485e3 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -363,6 +363,11 @@ true true + + true + true + true + true true @@ -598,6 +603,11 @@ true true + + true + true + true + true true @@ -853,6 +863,11 @@ true true + + true + true + true + true true @@ -1088,6 +1103,11 @@ true true + + true + true + true + true true @@ -1301,6 +1321,7 @@ + @@ -1787,6 +1808,24 @@ .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\wolfssl" "-I.\..\3rdparty\curl\include" "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB "-DBRANCH=$(BRANCH)" -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" + $(QTDIR)\bin\moc.exe;%(FullPath) Moc%27ing %(Identity)... diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index 1ef9787ac5..a3f0cc56ec 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -646,6 +646,9 @@ Gui\debugger + + Gui\debugger + Generated Files\Release - LLVM @@ -658,6 +661,18 @@ Generated Files\Debug - LLVM + + Generated Files\Release - LLVM + + + Generated Files\Debug + + + Generated Files\Release + + + Generated Files\Debug - LLVM + Generated Files @@ -1157,6 +1172,9 @@ Gui\debugger + + Gui\debugger + Resource Files diff --git a/rpcs3/rpcs3qt/CMakeLists.txt b/rpcs3/rpcs3qt/CMakeLists.txt index 99fbd7e497..4fd2e42991 100644 --- a/rpcs3/rpcs3qt/CMakeLists.txt +++ b/rpcs3/rpcs3qt/CMakeLists.txt @@ -3,6 +3,7 @@ auto_pause_settings_dialog.cpp breakpoint_handler.cpp breakpoint_list.cpp + call_stack_list.cpp cg_disasm_window.cpp cheat_manager.cpp curl_handle.cpp diff --git a/rpcs3/rpcs3qt/call_stack_list.cpp b/rpcs3/rpcs3qt/call_stack_list.cpp new file mode 100644 index 0000000000..c59c94c307 --- /dev/null +++ b/rpcs3/rpcs3qt/call_stack_list.cpp @@ -0,0 +1,37 @@ +#include "call_stack_list.h" + +constexpr auto qstr = QString::fromStdString; + +call_stack_list::call_stack_list(QWidget* parent) : QListWidget(parent) +{ + setEditTriggers(QAbstractItemView::NoEditTriggers); + setContextMenuPolicy(Qt::CustomContextMenu); + setSelectionMode(QAbstractItemView::ExtendedSelection); + + // connects + connect(this, &QListWidget::itemDoubleClicked, this, &call_stack_list::OnCallStackListDoubleClicked); +} + +void call_stack_list::UpdateCPUData(std::weak_ptr cpu, std::shared_ptr disasm) +{ + this->cpu = cpu; +} + +void call_stack_list::HandleUpdate(std::vector call_stack) +{ + clear(); + + for (auto addr : call_stack) + { + const QString call_stack_item_text = qstr(fmt::format("0x%08llx", addr)); + QListWidgetItem* callStackItem = new QListWidgetItem(call_stack_item_text); + callStackItem->setData(Qt::UserRole, { addr }); + addItem(callStackItem); + } +} + +void call_stack_list::OnCallStackListDoubleClicked() +{ + const u32 address = currentItem()->data(Qt::UserRole).value(); + Q_EMIT RequestShowAddress(address); +} diff --git a/rpcs3/rpcs3qt/call_stack_list.h b/rpcs3/rpcs3qt/call_stack_list.h new file mode 100644 index 0000000000..ca778e5e3b --- /dev/null +++ b/rpcs3/rpcs3qt/call_stack_list.h @@ -0,0 +1,26 @@ +#pragma once + +#include "stdafx.h" + +#include "Emu/CPU/CPUThread.h" +#include "Emu/CPU/CPUDisAsm.h" + +#include + +class call_stack_list : public QListWidget +{ + Q_OBJECT + +public: + call_stack_list(QWidget* parent); + void UpdateCPUData(std::weak_ptr cpu, std::shared_ptr disasm); + +Q_SIGNALS: + void RequestShowAddress(u32 addr); +public Q_SLOTS: + void HandleUpdate(std::vector call_stack); +private Q_SLOTS: + void OnCallStackListDoubleClicked(); +private: + std::weak_ptr cpu; +}; diff --git a/rpcs3/rpcs3qt/debugger_frame.cpp b/rpcs3/rpcs3qt/debugger_frame.cpp index 10864abee2..472c27f044 100644 --- a/rpcs3/rpcs3qt/debugger_frame.cpp +++ b/rpcs3/rpcs3qt/debugger_frame.cpp @@ -5,6 +5,7 @@ #include "debugger_list.h" #include "breakpoint_list.h" #include "breakpoint_handler.h" +#include "call_stack_list.h" #include "qt_utils.h" #include "Emu/System.h" @@ -48,10 +49,12 @@ debugger_frame::debugger_frame(std::shared_ptr settings, QWidget * hbox_b_main->setContentsMargins(0, 0, 0, 0); m_breakpoint_handler = new breakpoint_handler(); + m_breakpoint_list = new breakpoint_list(this, m_breakpoint_handler); + m_debugger_list = new debugger_list(this, settings, m_breakpoint_handler); m_debugger_list->installEventFilter(this); - m_breakpoint_list = new breakpoint_list(this, m_breakpoint_handler); + m_call_stack_list = new call_stack_list(this); m_choice_units = new QComboBox(this); m_choice_units->setSizeAdjustPolicy(QComboBox::AdjustToContents); @@ -97,13 +100,20 @@ debugger_frame::debugger_frame(std::shared_ptr settings, QWidget * m_debugger_list->setFont(m_mono); m_misc_state->setFont(m_mono); m_regs->setFont(m_mono); + m_call_stack_list->setFont(m_mono); m_right_splitter = new QSplitter(this); m_right_splitter->setOrientation(Qt::Vertical); m_right_splitter->addWidget(m_misc_state); m_right_splitter->addWidget(m_regs); + m_right_splitter->addWidget(m_call_stack_list); m_right_splitter->addWidget(m_breakpoint_list); - m_right_splitter->setStretchFactor(0, 1); + + // Set relative sizes for widgets + m_right_splitter->setStretchFactor(0, 2); // misc state + m_right_splitter->setStretchFactor(1, 8); // registers + m_right_splitter->setStretchFactor(2, 3); // call stack + m_right_splitter->setStretchFactor(3, 1); // breakpoint list m_splitter = new QSplitter(this); m_splitter->addWidget(m_debugger_list); @@ -161,6 +171,9 @@ debugger_frame::debugger_frame(std::shared_ptr settings, QWidget * connect(m_debugger_list, &debugger_list::BreakpointRequested, m_breakpoint_list, &breakpoint_list::HandleBreakpointRequest); connect(m_breakpoint_list, &breakpoint_list::RequestShowAddress, m_debugger_list, &debugger_list::ShowAddress); + connect(this, &debugger_frame::CallStackUpdateRequested, m_call_stack_list, &call_stack_list::HandleUpdate); + connect(m_call_stack_list, &call_stack_list::RequestShowAddress, m_debugger_list, &debugger_list::ShowAddress); + m_debugger_list->ShowAddress(m_debugger_list->m_pc); UpdateUnitList(); } @@ -409,6 +422,7 @@ void debugger_frame::OnSelectUnit() m_debugger_list->UpdateCPUData(this->cpu, m_disasm); m_breakpoint_list->UpdateCPUData(this->cpu, m_disasm); + m_call_stack_list->UpdateCPUData(this->cpu, m_disasm); DoUpdate(); UpdateUI(); } @@ -448,6 +462,8 @@ void debugger_frame::WritePanels() m_regs->clear(); m_regs->setText(qstr(cpu->dump_regs())); m_regs->verticalScrollBar()->setValue(loc); + + Q_EMIT CallStackUpdateRequested(cpu->dump_callstack_list()); } void debugger_frame::ShowGotoAddressDialog() @@ -560,6 +576,11 @@ void debugger_frame::ClearBreakpoints() m_breakpoint_list->ClearBreakpoints(); } +void debugger_frame::ClearCallStack() +{ + Q_EMIT CallStackUpdateRequested({}); +} + void debugger_frame::ShowPC() { m_debugger_list->ShowAddress(GetPc()); diff --git a/rpcs3/rpcs3qt/debugger_frame.h b/rpcs3/rpcs3qt/debugger_frame.h index 9b9c877fb1..e16908282e 100644 --- a/rpcs3/rpcs3qt/debugger_frame.h +++ b/rpcs3/rpcs3qt/debugger_frame.h @@ -15,6 +15,7 @@ class gui_settings; class debugger_list; class breakpoint_list; class breakpoint_handler; +class call_stack_list; class debugger_frame : public custom_dock_widget { @@ -53,6 +54,8 @@ class debugger_frame : public custom_dock_widget breakpoint_list* m_breakpoint_list; breakpoint_handler* m_breakpoint_handler; + call_stack_list* m_call_stack_list; + std::shared_ptr xgui_settings; public: @@ -71,6 +74,7 @@ public: void ShowGotoAddressDialog(); u64 EvaluateExpression(const QString& expression); void ClearBreakpoints(); // Fallthrough method into breakpoint_list. + void ClearCallStack(); /** Needed so key press events work when other objects are selected in debugger_frame. */ bool eventFilter(QObject* object, QEvent* event) override; @@ -83,6 +87,7 @@ protected: Q_SIGNALS: void DebugFrameClosed(); + void CallStackUpdateRequested(std::vector call_stack); public Q_SLOTS: void DoStep(bool stepOver = false); diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index 7ac39586d3..7737d1d474 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -991,6 +991,7 @@ void main_window::OnEmuStop() m_debugger_frame->EnableButtons(false); m_debugger_frame->ClearBreakpoints(); + m_debugger_frame->ClearCallStack(); ui->sysPauseAct->setText(Emu.IsReady() ? tr("&Play\tCtrl+E") : tr("&Resume\tCtrl+E")); ui->sysPauseAct->setIcon(m_icon_play);