summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/sdl
diff options
context:
space:
mode:
author Andrew Gardner <andrew-gardner@users.noreply.github.com>2013-01-24 17:06:42 +0000
committer Andrew Gardner <andrew-gardner@users.noreply.github.com>2013-01-24 17:06:42 +0000
commitba61a286f382eb9268a6f455365fad9546274e75 (patch)
tree67bd86940e57fbe7951907733be3b3c5b6234383 /src/osd/sdl
parent183b9f0638ba3da0f1b1871334ae0cf0b30fb9a1 (diff)
QT Debugger improvements [Andrew Gardner]
- Save and load window locations. - Preliminary work on "run and hide" and "hard reset" (don't crash on one of my copmilers but do on another - more work to do!) - Fixed color when cursor is the same as PC in debug view. - Closing the main window now shuts down the machine (same as quit) - Help now wraps to the log window size.
Diffstat (limited to 'src/osd/sdl')
-rw-r--r--src/osd/sdl/debugqt.c214
-rw-r--r--src/osd/sdl/debugqtdasmwindow.c8
-rw-r--r--src/osd/sdl/debugqtlogwindow.c8
-rw-r--r--src/osd/sdl/debugqtmainwindow.c35
-rw-r--r--src/osd/sdl/debugqtmainwindow.h7
-rw-r--r--src/osd/sdl/debugqtmemorywindow.c9
-rw-r--r--src/osd/sdl/debugqtview.c4
-rw-r--r--src/osd/sdl/debugqtwindow.c10
-rw-r--r--src/osd/sdl/debugqtwindow.h36
9 files changed, 299 insertions, 32 deletions
diff --git a/src/osd/sdl/debugqt.c b/src/osd/sdl/debugqt.c
index 7998b810c85..8a4972da48d 100644
--- a/src/osd/sdl/debugqt.c
+++ b/src/osd/sdl/debugqt.c
@@ -16,9 +16,13 @@
#include "emu.h"
#include "osdsdl.h"
+#include "config.h"
#include "debugger.h"
#include "debugqtmainwindow.h"
+#include "debugqtmemorywindow.h"
+#include "debugqtdasmwindow.h"
+#include "debugqtlogwindow.h"
//============================================================
@@ -33,13 +37,183 @@ MainWindow* mainQtWindow = NULL;
//============================================================
+// XML configuration save/load
+//============================================================
+
+// Global variable used to feed the xml configuration callbacks
+std::vector<WindowQtConfig> xmlConfigurations;
+
+static void xml_configuration_load(running_machine &machine, int config_type, xml_data_node *parentnode)
+{
+ xml_data_node *wnode;
+
+ // We only care about game files
+ if (config_type != CONFIG_TYPE_GAME)
+ return;
+
+ // Might not have any data
+ if (parentnode == NULL)
+ return;
+
+ xmlConfigurations.clear();
+
+ // Configuration load
+ for (wnode = xml_get_sibling(parentnode->child, "window"); wnode != NULL; wnode = xml_get_sibling(wnode->next, "window"))
+ {
+ WindowQtConfig config;
+ config.m_size.setX(xml_get_attribute_int(wnode, "size_x", config.m_size.x()));
+ config.m_size.setY(xml_get_attribute_int(wnode, "size_y", config.m_size.y()));
+ config.m_position.setX(xml_get_attribute_int(wnode, "position_x", config.m_position.x()));
+ config.m_position.setY(xml_get_attribute_int(wnode, "position_y", config.m_position.y()));
+ config.m_type = (WindowQtConfig::WindowType)xml_get_attribute_int(wnode, "type", config.m_type);
+ xmlConfigurations.push_back(config);
+ }
+}
+
+
+static void xml_configuration_save(running_machine &machine, int config_type, xml_data_node *parentnode)
+{
+ // We only care about game files
+ if (config_type != CONFIG_TYPE_GAME)
+ return;
+
+ for (int i = 0; i < xmlConfigurations.size(); i++)
+ {
+ // Create an xml node
+ xml_data_node *debugger_node;
+ debugger_node = xml_add_child(parentnode, "window", NULL);
+ if (debugger_node == NULL)
+ continue;
+
+ xml_set_attribute_int(debugger_node, "type", xmlConfigurations[i].m_type);
+ xml_set_attribute_int(debugger_node, "position_x", xmlConfigurations[i].m_position.x());
+ xml_set_attribute_int(debugger_node, "position_y", xmlConfigurations[i].m_position.y());
+ xml_set_attribute_int(debugger_node, "size_x", xmlConfigurations[i].m_size.x());
+ xml_set_attribute_int(debugger_node, "size_y", xmlConfigurations[i].m_size.y());
+ }
+}
+
+
+static void gather_save_configurations()
+{
+ xmlConfigurations.clear();
+
+ // Loop over all the open windows
+ foreach (QWidget* widget, QApplication::topLevelWidgets())
+ {
+ if (!widget->isVisible())
+ continue;
+
+ if (!widget->isWindow() || widget->windowType() != Qt::Window)
+ continue;
+
+ // Figure out its type
+ WindowQtConfig::WindowType type = WindowQtConfig::WIN_TYPE_UNKNOWN;
+ if (dynamic_cast<MainWindow*>(widget))
+ type = WindowQtConfig::WIN_TYPE_MAIN;
+ else if (dynamic_cast<MemoryWindow*>(widget))
+ type = WindowQtConfig::WIN_TYPE_MEMORY;
+ else if (dynamic_cast<DasmWindow*>(widget))
+ type = WindowQtConfig::WIN_TYPE_DISASM;
+ else if (dynamic_cast<LogWindow*>(widget))
+ type = WindowQtConfig::WIN_TYPE_LOG;
+
+ WindowQtConfig config;
+ config.m_type = type;
+ config.m_position.setX(widget->geometry().topLeft().x());
+ config.m_position.setY(widget->geometry().topLeft().y());
+ config.m_size.setX(widget->size().width());
+ config.m_size.setY(widget->size().height());
+ xmlConfigurations.push_back(config);
+ }
+}
+
+
+//============================================================
+// Utilities
+//============================================================
+
+static void load_and_clear_main_window_config(std::vector<WindowQtConfig>& configs)
+{
+ if (configs.size() == 0)
+ return;
+
+ int i = 0;
+ for (i = 0; i < configs.size(); i++)
+ {
+ if (configs[i].m_type == WindowQtConfig::WIN_TYPE_MAIN)
+ {
+ mainQtWindow->setGeometry(configs[i].m_position.x(), configs[i].m_position.y(),
+ configs[i].m_size.x(), configs[i].m_size.y());
+ break;
+ }
+ }
+ configs.erase(configs.begin()+i);
+}
+
+
+static void setup_additional_startup_windows(running_machine& machine, std::vector<WindowQtConfig>& configs)
+{
+ for (int i = 0; i < configs.size(); i++)
+ {
+ WindowQt* foo = NULL;
+ switch (configs[i].m_type)
+ {
+ case WindowQtConfig::WIN_TYPE_MEMORY:
+ foo = new MemoryWindow(&machine); break;
+ case WindowQtConfig::WIN_TYPE_DISASM:
+ foo = new DasmWindow(&machine); break;
+ case WindowQtConfig::WIN_TYPE_LOG:
+ foo = new LogWindow(&machine); break;
+ default: break;
+ }
+ foo->setGeometry(configs[i].m_position.x(), configs[i].m_position.y(),
+ configs[i].m_size.x(), configs[i].m_size.y());
+ foo->show();
+ }
+}
+
+
+static void bring_main_window_to_front()
+{
+ foreach (QWidget* widget, QApplication::topLevelWidgets())
+ {
+ if (!dynamic_cast<MainWindow*>(widget))
+ continue;
+ widget->activateWindow();
+ widget->raise();
+ }
+}
+
+
+//============================================================
// Core functionality
//============================================================
void sdl_osd_interface::init_debugger()
{
- // QT is a magical thing
- new QApplication(qtArgc, qtArgv);
+ if (qApp == NULL)
+ {
+ // If you're starting from scratch, create a new qApp
+ new QApplication(qtArgc, qtArgv);
+ }
+ else
+ {
+ // If you're doing a hard reset, clear out existing widgets & get ready for re-init
+ foreach (QWidget* widget, QApplication::topLevelWidgets())
+ {
+ if (!widget->isWindow() || widget->windowType() != Qt::Window)
+ continue;
+ delete widget;
+ }
+ oneShot = true;
+ }
+
+ // Setup the configuration XML saving and loading
+ config_register(machine(),
+ "debugger",
+ config_saveload_delegate(FUNC(xml_configuration_load), &machine()),
+ config_saveload_delegate(FUNC(xml_configuration_save), &machine()));
}
@@ -49,14 +223,26 @@ void sdl_osd_interface::init_debugger()
void sdl_osd_interface::wait_for_debugger(device_t &device, bool firststop)
{
+ // Dialog initialization
if (oneShot)
{
- mainQtWindow = new MainWindow(&device, &machine());
+ mainQtWindow = new MainWindow(&machine());
+ load_and_clear_main_window_config(xmlConfigurations);
+ setup_additional_startup_windows(machine(), xmlConfigurations);
mainQtWindow->show();
oneShot = false;
}
- // Make sure the main window displays the proper cpu
+ // Insure all top level widgets are visible & bring main window to front
+ foreach (QWidget* widget, QApplication::topLevelWidgets())
+ {
+ if (!widget->isWindow() || widget->windowType() != Qt::Window)
+ continue;
+ widget->show();
+ }
+ bring_main_window_to_front();
+
+ // Set the main window to display the proper cpu
mainQtWindow->setProcessor(&device);
// Run our own QT event loop
@@ -73,9 +259,25 @@ void sdl_osd_interface::wait_for_debugger(device_t &device, bool firststop)
mainQtWindow->clearRefreshFlag();
}
- // Exit if the machine has been instructed to do so
- if (machine().exit_pending())
+ // Hide all top level widgets if requested
+ if (mainQtWindow->wantsHide())
+ {
+ foreach (QWidget* widget, QApplication::topLevelWidgets())
+ {
+ if (!widget->isWindow() || widget->windowType() != Qt::Window)
+ continue;
+ widget->hide();
+ }
+ mainQtWindow->clearHideFlag();
+ }
+
+ // Exit if the machine has been instructed to do so (scheduled event == exit || hard_reset)
+ if (machine().scheduled_event_pending())
{
+ // Keep a list of windows we want to save.
+ // We need to do this here because by the time xml_configuration_save gets called
+ // all the QT windows are already gone.
+ gather_save_configurations();
break;
}
}
diff --git a/src/osd/sdl/debugqtdasmwindow.c b/src/osd/sdl/debugqtdasmwindow.c
index f9b126da78d..da35ce76f4c 100644
--- a/src/osd/sdl/debugqtdasmwindow.c
+++ b/src/osd/sdl/debugqtdasmwindow.c
@@ -8,10 +8,14 @@
DasmWindow::DasmWindow(running_machine* machine, QWidget* parent) :
WindowQt(machine, parent)
{
- QPoint parentPos = parent->pos();
- setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
setWindowTitle("Debug: Disassembly View");
+ if (parent != NULL)
+ {
+ QPoint parentPos = parent->pos();
+ setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
+ }
+
//
// The main frame and its input and log widgets
//
diff --git a/src/osd/sdl/debugqtlogwindow.c b/src/osd/sdl/debugqtlogwindow.c
index 16a335a3aa2..a332188fa3d 100644
--- a/src/osd/sdl/debugqtlogwindow.c
+++ b/src/osd/sdl/debugqtlogwindow.c
@@ -8,10 +8,14 @@
LogWindow::LogWindow(running_machine* machine, QWidget* parent) :
WindowQt(machine, parent)
{
- QPoint parentPos = parent->pos();
- setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
setWindowTitle("Debug: Machine Log");
+ if (parent != NULL)
+ {
+ QPoint parentPos = parent->pos();
+ setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
+ }
+
//
// The main frame and its input and log widgets
//
diff --git a/src/osd/sdl/debugqtmainwindow.c b/src/osd/sdl/debugqtmainwindow.c
index 56ff9ed991d..58630e390e8 100644
--- a/src/osd/sdl/debugqtmainwindow.c
+++ b/src/osd/sdl/debugqtmainwindow.c
@@ -4,9 +4,7 @@
#include "debug/dvdisasm.h"
-MainWindow::MainWindow(device_t* processor,
- running_machine* machine,
- QWidget* parent) :
+MainWindow::MainWindow(running_machine* machine, QWidget* parent) :
WindowQt(machine, parent),
m_historyIndex(0),
m_inputHistory()
@@ -100,11 +98,6 @@ MainWindow::MainWindow(device_t* processor,
addDockWidget(Qt::TopDockWidgetArea, dasmDock);
dockMenu->addAction(dasmDock->toggleViewAction());
-
- // Window title
- astring title;
- title.printf("Debug: %s - %s '%s'", m_machine->system().name, processor->name(), processor->tag());
- setWindowTitle(title.cstr());
}
@@ -261,18 +254,32 @@ void MainWindow::rightBarChanged(QAction* changedTo)
void MainWindow::executeCommand(bool withClear)
{
- if (m_inputEdit->text() == "")
+ QString command = m_inputEdit->text();
+
+ // A blank command is a "silent step"
+ if (command == "")
{
debug_cpu_get_visible_cpu(*m_machine)->debug()->single_step();
return;
}
+ // If the user asked for help on a specific command, enhance the call
+ if (command.trimmed().startsWith("help", Qt::CaseInsensitive))
+ {
+ if (command.split(" ", QString::SkipEmptyParts).length() == 2)
+ {
+ const int width = m_consoleView->view()->visible_size().x;
+ command.append(QString(", %1").arg(width, 1, 16));
+ }
+ }
+
+ // Send along the command
debug_console_execute_command(*m_machine,
- m_inputEdit->text().toLocal8Bit().data(),
+ command.toLocal8Bit().data(),
true);
// Add history & set the index to be the top of the stack
- addToHistory(m_inputEdit->text());
+ addToHistory(command);
// Clear out the text and reset the history pointer only if asked
if (withClear)
@@ -288,6 +295,12 @@ void MainWindow::executeCommand(bool withClear)
}
+void MainWindow::debugActClose()
+{
+ m_machine->schedule_exit();
+}
+
+
void MainWindow::addToHistory(const QString& command)
{
if (command == "")
diff --git a/src/osd/sdl/debugqtmainwindow.h b/src/osd/sdl/debugqtmainwindow.h
index 452d8b56bcf..93ff103aac5 100644
--- a/src/osd/sdl/debugqtmainwindow.h
+++ b/src/osd/sdl/debugqtmainwindow.h
@@ -21,9 +21,7 @@ class MainWindow : public WindowQt
Q_OBJECT
public:
- MainWindow(device_t* processor,
- running_machine* machine,
- QWidget* parent=NULL);
+ MainWindow(running_machine* machine, QWidget* parent=NULL);
virtual ~MainWindow() {}
void setProcessor(device_t* processor);
@@ -44,6 +42,9 @@ private slots:
void executeCommand(bool withClear=true);
+ // Closing the main window actually exits the program
+ void debugActClose();
+
private:
// Widgets and docks
diff --git a/src/osd/sdl/debugqtmemorywindow.c b/src/osd/sdl/debugqtmemorywindow.c
index 94670051ddf..57e3794f4ac 100644
--- a/src/osd/sdl/debugqtmemorywindow.c
+++ b/src/osd/sdl/debugqtmemorywindow.c
@@ -1,7 +1,6 @@
#include "debugqtmemorywindow.h"
#include "debug/dvmemory.h"
-#include "debug/debugvw.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
@@ -9,10 +8,14 @@
MemoryWindow::MemoryWindow(running_machine* machine, QWidget* parent) :
WindowQt(machine, parent)
{
- QPoint parentPos = parent->pos();
- setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
setWindowTitle("Debug: Memory View");
+ if (parent != NULL)
+ {
+ QPoint parentPos = parent->pos();
+ setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
+ }
+
//
// The main frame and its input and log widgets
//
diff --git a/src/osd/sdl/debugqtview.c b/src/osd/sdl/debugqtview.c
index c809e5e7953..45432a41269 100644
--- a/src/osd/sdl/debugqtview.c
+++ b/src/osd/sdl/debugqtview.c
@@ -89,6 +89,10 @@ void DebuggerView::paintEvent(QPaintEvent* event)
{
bgColor.setRgb(0xff, 0xff, 0x00);
}
+ if ((textAttr & DCA_SELECTED) && (textAttr & DCA_CURRENT))
+ {
+ bgColor.setRgb(0xff,0xc0,0x80);
+ }
if(textAttr & DCA_CHANGED)
{
fgColor.setRgb(0xff, 0x00, 0x00);
diff --git a/src/osd/sdl/debugqtwindow.c b/src/osd/sdl/debugqtwindow.c
index 956035a4975..997cfe54f44 100644
--- a/src/osd/sdl/debugqtwindow.c
+++ b/src/osd/sdl/debugqtwindow.c
@@ -9,12 +9,15 @@
#include "debugqtmemorywindow.h"
bool WindowQt::s_refreshAll = false;
+bool WindowQt::s_hideAll = false;
WindowQt::WindowQt(running_machine* machine, QWidget* parent) :
QMainWindow(parent),
m_machine(machine)
{
+ //setAttribute(Qt::WA_DeleteOnClose, true);
+
// The Debug menu bar
QAction* debugActOpenMemory = new QAction("New &Memory Window", this);
debugActOpenMemory->setShortcut(QKeySequence("Ctrl+M"));
@@ -83,6 +86,7 @@ WindowQt::WindowQt(running_machine* machine, QWidget* parent) :
debugMenu->addAction(debugActOpenLog);
debugMenu->addSeparator();
debugMenu->addAction(dbgActRun);
+ debugMenu->addAction(dbgActRunAndHide);
debugMenu->addAction(dbgActRunToNextCpu);
debugMenu->addAction(dbgActRunNextInt);
debugMenu->addAction(dbgActRunNextVBlank);
@@ -137,7 +141,7 @@ void WindowQt::debugActRun()
void WindowQt::debugActRunAndHide()
{
debug_cpu_get_visible_cpu(*m_machine)->debug()->go();
- // TODO: figure out hide
+ hideAll();
}
void WindowQt::debugActRunToNextCpu()
@@ -173,13 +177,12 @@ void WindowQt::debugActStepOut()
void WindowQt::debugActSoftReset()
{
m_machine->schedule_soft_reset();
+ debug_cpu_get_visible_cpu(*m_machine)->debug()->single_step();
}
void WindowQt::debugActHardReset()
{
- // TODO: Figure out segfault
m_machine->schedule_hard_reset();
- debug_cpu_get_visible_cpu(*m_machine)->debug()->go();
}
void WindowQt::debugActClose()
@@ -190,5 +193,4 @@ void WindowQt::debugActClose()
void WindowQt::debugActQuit()
{
m_machine->schedule_exit();
- qApp->closeAllWindows();
}
diff --git a/src/osd/sdl/debugqtwindow.h b/src/osd/sdl/debugqtwindow.h
index ba6c0919236..ae87a767c05 100644
--- a/src/osd/sdl/debugqtwindow.h
+++ b/src/osd/sdl/debugqtwindow.h
@@ -22,6 +22,10 @@ public:
bool wantsRefresh() { return s_refreshAll; }
void clearRefreshFlag() { s_refreshAll = false; }
+ void hideAll() { s_hideAll = true; }
+ bool wantsHide() { return s_hideAll; }
+ void clearHideFlag() { s_hideAll = false; }
+
protected slots:
void debugActOpenMemory();
@@ -37,7 +41,7 @@ protected slots:
void debugActStepOut();
void debugActSoftReset();
void debugActHardReset();
- void debugActClose();
+ virtual void debugActClose();
void debugActQuit();
@@ -45,7 +49,37 @@ protected:
running_machine* m_machine;
static bool s_refreshAll;
+ static bool s_hideAll;
};
+//=======================================================================
+// A way to store the configuration of a window long enough to use it.
+//=======================================================================
+class WindowQtConfig
+{
+public:
+ // This is a holdover from the old debugger - TODO: remove
+ enum WindowType
+ {
+ WIN_TYPE_MAIN = 0x01,
+ WIN_TYPE_MEMORY = 0x02,
+ WIN_TYPE_DISASM = 0x04,
+ WIN_TYPE_LOG = 0x08,
+ WIN_TYPE_UNKNOWN = 0x10,
+ };
+
+public:
+ WindowQtConfig() :
+ m_type(WIN_TYPE_MAIN),
+ m_size(800, 600),
+ m_position(120, 120)
+ {}
+ ~WindowQtConfig() {}
+
+ WindowType m_type;
+ QPoint m_size;
+ QPoint m_position;
+};
+
#endif