Previous 199869 Revisions Next

r20436 Thursday 24th January, 2013 at 17:06:42 UTC by Andrew Gardner
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.
[src/emu/debug]debugcmd.c
[src/osd/sdl]debugqt.c debugqtdasmwindow.c debugqtlogwindow.c debugqtmainwindow.c debugqtmainwindow.h debugqtmemorywindow.c debugqtview.c debugqtwindow.c debugqtwindow.h

trunk/src/osd/sdl/debugqt.c
r20435r20436
1616
1717#include "emu.h"
1818#include "osdsdl.h"
19#include "config.h"
1920#include "debugger.h"
2021
2122#include "debugqtmainwindow.h"
23#include "debugqtmemorywindow.h"
24#include "debugqtdasmwindow.h"
25#include "debugqtlogwindow.h"
2226
2327
2428//============================================================
r20435r20436
3337
3438
3539//============================================================
40//  XML configuration save/load
41//============================================================
42
43// Global variable used to feed the xml configuration callbacks
44std::vector<WindowQtConfig> xmlConfigurations;
45
46static void xml_configuration_load(running_machine &machine, int config_type, xml_data_node *parentnode)
47{
48   xml_data_node *wnode;
49
50   // We only care about game files
51   if (config_type != CONFIG_TYPE_GAME)
52      return;
53
54   // Might not have any data
55   if (parentnode == NULL)
56      return;
57
58   xmlConfigurations.clear();
59
60   // Configuration load
61   for (wnode = xml_get_sibling(parentnode->child, "window"); wnode != NULL; wnode = xml_get_sibling(wnode->next, "window"))
62   {
63      WindowQtConfig config;
64      config.m_size.setX(xml_get_attribute_int(wnode, "size_x", config.m_size.x()));
65      config.m_size.setY(xml_get_attribute_int(wnode, "size_y", config.m_size.y()));
66      config.m_position.setX(xml_get_attribute_int(wnode, "position_x", config.m_position.x()));
67      config.m_position.setY(xml_get_attribute_int(wnode, "position_y", config.m_position.y()));
68      config.m_type = (WindowQtConfig::WindowType)xml_get_attribute_int(wnode, "type", config.m_type);
69      xmlConfigurations.push_back(config);
70   }
71}
72
73
74static void xml_configuration_save(running_machine &machine, int config_type, xml_data_node *parentnode)
75{
76   // We only care about game files
77   if (config_type != CONFIG_TYPE_GAME)
78      return;
79
80   for (int i = 0; i < xmlConfigurations.size(); i++)
81   {
82      // Create an xml node
83      xml_data_node *debugger_node;
84      debugger_node = xml_add_child(parentnode, "window", NULL);
85      if (debugger_node == NULL)
86         continue;
87
88      xml_set_attribute_int(debugger_node, "type", xmlConfigurations[i].m_type);
89      xml_set_attribute_int(debugger_node, "position_x", xmlConfigurations[i].m_position.x());
90      xml_set_attribute_int(debugger_node, "position_y", xmlConfigurations[i].m_position.y());
91      xml_set_attribute_int(debugger_node, "size_x", xmlConfigurations[i].m_size.x());
92      xml_set_attribute_int(debugger_node, "size_y", xmlConfigurations[i].m_size.y());
93   }
94}
95
96
97static void gather_save_configurations()
98{
99   xmlConfigurations.clear();
100
101   // Loop over all the open windows
102   foreach (QWidget* widget, QApplication::topLevelWidgets())
103   {
104      if (!widget->isVisible())
105         continue;
106
107      if (!widget->isWindow() || widget->windowType() != Qt::Window)
108         continue;
109
110      // Figure out its type
111      WindowQtConfig::WindowType type = WindowQtConfig::WIN_TYPE_UNKNOWN;
112      if (dynamic_cast<MainWindow*>(widget))
113         type = WindowQtConfig::WIN_TYPE_MAIN;
114      else if (dynamic_cast<MemoryWindow*>(widget))
115         type = WindowQtConfig::WIN_TYPE_MEMORY;
116      else if (dynamic_cast<DasmWindow*>(widget))
117         type = WindowQtConfig::WIN_TYPE_DISASM;
118      else if (dynamic_cast<LogWindow*>(widget))
119         type = WindowQtConfig::WIN_TYPE_LOG;
120
121      WindowQtConfig config;
122      config.m_type = type;
123      config.m_position.setX(widget->geometry().topLeft().x());
124      config.m_position.setY(widget->geometry().topLeft().y());
125      config.m_size.setX(widget->size().width());
126      config.m_size.setY(widget->size().height());
127      xmlConfigurations.push_back(config);
128   }
129}
130
131
132//============================================================
133//  Utilities
134//============================================================
135
136static void load_and_clear_main_window_config(std::vector<WindowQtConfig>& configs)
137{
138   if (configs.size() == 0)
139      return;
140
141   int i = 0;
142   for (i = 0; i < configs.size(); i++)
143   {
144      if (configs[i].m_type == WindowQtConfig::WIN_TYPE_MAIN)
145      {
146         mainQtWindow->setGeometry(configs[i].m_position.x(), configs[i].m_position.y(),
147                             configs[i].m_size.x(), configs[i].m_size.y());
148         break;
149      }
150   }
151   configs.erase(configs.begin()+i);
152}
153
154
155static void setup_additional_startup_windows(running_machine& machine, std::vector<WindowQtConfig>& configs)
156{
157   for (int i = 0; i < configs.size(); i++)
158   {
159      WindowQt* foo = NULL;
160      switch (configs[i].m_type)
161      {
162         case WindowQtConfig::WIN_TYPE_MEMORY:
163            foo = new MemoryWindow(&machine); break;
164         case WindowQtConfig::WIN_TYPE_DISASM:
165            foo = new DasmWindow(&machine); break;
166         case WindowQtConfig::WIN_TYPE_LOG:
167            foo = new LogWindow(&machine); break;
168         default: break;
169      }
170      foo->setGeometry(configs[i].m_position.x(), configs[i].m_position.y(),
171                   configs[i].m_size.x(), configs[i].m_size.y());
172      foo->show();
173   }
174}
175
176
177static void bring_main_window_to_front()
178{
179   foreach (QWidget* widget, QApplication::topLevelWidgets())
180   {
181      if (!dynamic_cast<MainWindow*>(widget))
182         continue;
183      widget->activateWindow();
184      widget->raise();
185   }
186}
187
188
189//============================================================
36190//  Core functionality
37191//============================================================
38192
39193void sdl_osd_interface::init_debugger()
40194{
41   // QT is a magical thing
42   new QApplication(qtArgc, qtArgv);
195   if (qApp == NULL)
196   {
197      // If you're starting from scratch, create a new qApp
198      new QApplication(qtArgc, qtArgv);
199   }
200   else
201   {
202      // If you're doing a hard reset, clear out existing widgets & get ready for re-init
203      foreach (QWidget* widget, QApplication::topLevelWidgets())
204      {
205         if (!widget->isWindow() || widget->windowType() != Qt::Window)
206            continue;
207         delete widget;
208      }
209      oneShot = true;
210   }
211
212   // Setup the configuration XML saving and loading
213   config_register(machine(),
214               "debugger",
215               config_saveload_delegate(FUNC(xml_configuration_load), &machine()),
216               config_saveload_delegate(FUNC(xml_configuration_save), &machine()));
43217}
44218
45219
r20435r20436
49223
50224void sdl_osd_interface::wait_for_debugger(device_t &device, bool firststop)
51225{
226   // Dialog initialization
52227   if (oneShot)
53228   {
54      mainQtWindow = new MainWindow(&device, &machine());
229      mainQtWindow = new MainWindow(&machine());
230      load_and_clear_main_window_config(xmlConfigurations);
231      setup_additional_startup_windows(machine(), xmlConfigurations);
55232      mainQtWindow->show();
56233      oneShot = false;
57234   }
58235
59   // Make sure the main window displays the proper cpu
236   // Insure all top level widgets are visible & bring main window to front
237   foreach (QWidget* widget, QApplication::topLevelWidgets())
238   {
239      if (!widget->isWindow() || widget->windowType() != Qt::Window)
240         continue;
241      widget->show();
242   }
243   bring_main_window_to_front();
244
245   // Set the main window to display the proper cpu
60246   mainQtWindow->setProcessor(&device);
61247
62248   // Run our own QT event loop
r20435r20436
73259         mainQtWindow->clearRefreshFlag();
74260      }
75261
76      // Exit if the machine has been instructed to do so
77      if (machine().exit_pending())
262      // Hide all top level widgets if requested
263      if (mainQtWindow->wantsHide())
78264      {
265         foreach (QWidget* widget, QApplication::topLevelWidgets())
266         {
267            if (!widget->isWindow() || widget->windowType() != Qt::Window)
268               continue;
269            widget->hide();
270         }
271         mainQtWindow->clearHideFlag();
272      }
273
274      // Exit if the machine has been instructed to do so (scheduled event == exit || hard_reset)
275      if (machine().scheduled_event_pending())
276      {
277         // Keep a list of windows we want to save.
278         // We need to do this here because by the time xml_configuration_save gets called
279         // all the QT windows are already gone.
280         gather_save_configurations();
79281         break;
80282      }
81283   }
trunk/src/osd/sdl/debugqtlogwindow.c
r20435r20436
88LogWindow::LogWindow(running_machine* machine, QWidget* parent) :
99   WindowQt(machine, parent)
1010{
11   QPoint parentPos = parent->pos();
12   setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
1311   setWindowTitle("Debug: Machine Log");
1412
13   if (parent != NULL)
14   {
15      QPoint parentPos = parent->pos();
16      setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
17   }
18
1519   //
1620   // The main frame and its input and log widgets
1721   //
trunk/src/osd/sdl/debugqtview.c
r20435r20436
8989                {
9090                    bgColor.setRgb(0xff, 0xff, 0x00);
9191                }
92                if ((textAttr & DCA_SELECTED) && (textAttr & DCA_CURRENT))
93                {
94                    bgColor.setRgb(0xff,0xc0,0x80);
95                }
9296                if(textAttr & DCA_CHANGED)
9397                {
9498                    fgColor.setRgb(0xff, 0x00, 0x00);
trunk/src/osd/sdl/debugqtdasmwindow.c
r20435r20436
88DasmWindow::DasmWindow(running_machine* machine, QWidget* parent) :
99   WindowQt(machine, parent)
1010{
11   QPoint parentPos = parent->pos();
12   setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
1311   setWindowTitle("Debug: Disassembly View");
1412
13   if (parent != NULL)
14   {
15      QPoint parentPos = parent->pos();
16      setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
17   }
18
1519   //
1620   // The main frame and its input and log widgets
1721   //
trunk/src/osd/sdl/debugqtmemorywindow.c
r20435r20436
11#include "debugqtmemorywindow.h"
22
33#include "debug/dvmemory.h"
4#include "debug/debugvw.h"
54#include "debug/debugcon.h"
65#include "debug/debugcpu.h"
76
r20435r20436
98MemoryWindow::MemoryWindow(running_machine* machine, QWidget* parent) :
109   WindowQt(machine, parent)
1110{
12   QPoint parentPos = parent->pos();
13   setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
1411   setWindowTitle("Debug: Memory View");
1512
13   if (parent != NULL)
14   {
15      QPoint parentPos = parent->pos();
16      setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
17   }
18
1619   //
1720   // The main frame and its input and log widgets
1821   //
trunk/src/osd/sdl/debugqtmainwindow.c
r20435r20436
44#include "debug/dvdisasm.h"
55
66
7MainWindow::MainWindow(device_t* processor,
8                       running_machine* machine,
9                       QWidget* parent) :
7MainWindow::MainWindow(running_machine* machine, QWidget* parent) :
108    WindowQt(machine, parent),
119    m_historyIndex(0),
1210    m_inputHistory()
r20435r20436
10098
10199    addDockWidget(Qt::TopDockWidgetArea, dasmDock);
102100    dockMenu->addAction(dasmDock->toggleViewAction());
103
104    // Window title
105    astring title;
106    title.printf("Debug: %s - %s '%s'", m_machine->system().name, processor->name(), processor->tag());
107    setWindowTitle(title.cstr());
108101}
109102
110103
r20435r20436
261254
262255void MainWindow::executeCommand(bool withClear)
263256{
264    if (m_inputEdit->text() == "")
257    QString command = m_inputEdit->text();
258   
259    // A blank command is a "silent step"
260    if (command == "")
265261    {
266262        debug_cpu_get_visible_cpu(*m_machine)->debug()->single_step();
267263        return;
268264    }
269265   
266    // If the user asked for help on a specific command, enhance the call
267    if (command.trimmed().startsWith("help", Qt::CaseInsensitive))
268    {
269        if (command.split(" ", QString::SkipEmptyParts).length() == 2)
270        {
271            const int width = m_consoleView->view()->visible_size().x;
272            command.append(QString(", %1").arg(width, 1, 16));
273        }
274    }
275   
276    // Send along the command
270277    debug_console_execute_command(*m_machine,
271                                  m_inputEdit->text().toLocal8Bit().data(),
278                                  command.toLocal8Bit().data(),
272279                                  true);
273280
274281    // Add history & set the index to be the top of the stack
275    addToHistory(m_inputEdit->text());
282    addToHistory(command);
276283
277284    // Clear out the text and reset the history pointer only if asked
278285    if (withClear)
r20435r20436
288295}
289296
290297
298void MainWindow::debugActClose()
299{
300    m_machine->schedule_exit();
301}
302
303
291304void MainWindow::addToHistory(const QString& command)
292305{
293306    if (command == "")
trunk/src/osd/sdl/debugqtmainwindow.h
r20435r20436
2121   Q_OBJECT
2222
2323public:
24   MainWindow(device_t* processor,
25            running_machine* machine,
26            QWidget* parent=NULL);
24   MainWindow(running_machine* machine, QWidget* parent=NULL);
2725   virtual ~MainWindow() {}
2826
2927   void setProcessor(device_t* processor);
r20435r20436
4442
4543   void executeCommand(bool withClear=true);
4644
45   // Closing the main window actually exits the program
46   void debugActClose();
4747
48
4849private:
4950   // Widgets and docks
5051   QLineEdit* m_inputEdit;
trunk/src/osd/sdl/debugqtwindow.c
r20435r20436
99#include "debugqtmemorywindow.h"
1010
1111bool WindowQt::s_refreshAll = false;
12bool WindowQt::s_hideAll = false;
1213
1314
1415WindowQt::WindowQt(running_machine* machine, QWidget* parent) :
1516   QMainWindow(parent),
1617   m_machine(machine)
1718{
19   //setAttribute(Qt::WA_DeleteOnClose, true);
20
1821   // The Debug menu bar
1922   QAction* debugActOpenMemory = new QAction("New &Memory Window", this);
2023   debugActOpenMemory->setShortcut(QKeySequence("Ctrl+M"));
r20435r20436
8386   debugMenu->addAction(debugActOpenLog);
8487   debugMenu->addSeparator();
8588   debugMenu->addAction(dbgActRun);
89   debugMenu->addAction(dbgActRunAndHide);
8690   debugMenu->addAction(dbgActRunToNextCpu);
8791   debugMenu->addAction(dbgActRunNextInt);
8892   debugMenu->addAction(dbgActRunNextVBlank);
r20435r20436
137141void WindowQt::debugActRunAndHide()
138142{
139143   debug_cpu_get_visible_cpu(*m_machine)->debug()->go();
140   // TODO: figure out hide
144   hideAll();
141145}
142146
143147void WindowQt::debugActRunToNextCpu()
r20435r20436
173177void WindowQt::debugActSoftReset()
174178{
175179   m_machine->schedule_soft_reset();
180   debug_cpu_get_visible_cpu(*m_machine)->debug()->single_step();
176181}
177182
178183void WindowQt::debugActHardReset()
179184{
180   // TODO: Figure out segfault
181185   m_machine->schedule_hard_reset();
182   debug_cpu_get_visible_cpu(*m_machine)->debug()->go();
183186}
184187
185188void WindowQt::debugActClose()
r20435r20436
190193void WindowQt::debugActQuit()
191194{
192195   m_machine->schedule_exit();
193   qApp->closeAllWindows();
194196}
trunk/src/osd/sdl/debugqtwindow.h
r20435r20436
2222   bool wantsRefresh() { return s_refreshAll; }
2323   void clearRefreshFlag() { s_refreshAll = false; }
2424
25   void hideAll() { s_hideAll = true; }
26   bool wantsHide() { return s_hideAll; }
27   void clearHideFlag() { s_hideAll = false; }
2528
29
2630protected slots:
2731   void debugActOpenMemory();
2832   void debugActOpenDasm();
r20435r20436
3741   void debugActStepOut();
3842   void debugActSoftReset();
3943   void debugActHardReset();
40   void debugActClose();
44   virtual void debugActClose();
4145   void debugActQuit();
4246
4347
r20435r20436
4549   running_machine* m_machine;
4650
4751   static bool s_refreshAll;
52   static bool s_hideAll;
4853};
4954
5055
56//=======================================================================
57//  A way to store the configuration of a window long enough to use it.
58//=======================================================================
59class WindowQtConfig
60{
61public:
62   // This is a holdover from the old debugger - TODO: remove
63   enum WindowType
64   {
65      WIN_TYPE_MAIN       = 0x01,
66      WIN_TYPE_MEMORY     = 0x02,
67      WIN_TYPE_DISASM     = 0x04,
68      WIN_TYPE_LOG        = 0x08,
69      WIN_TYPE_UNKNOWN    = 0x10,
70   };
71
72public:
73   WindowQtConfig() :
74      m_type(WIN_TYPE_MAIN),
75      m_size(800, 600),
76      m_position(120, 120)
77   {}
78   ~WindowQtConfig() {}
79
80   WindowType m_type;
81   QPoint m_size;
82   QPoint m_position;
83};
84
5185#endif
trunk/src/emu/debug/debugcmd.c
r20435r20436
258258   }
259259
260260   /* add all the commands */
261   debug_console_register_command(machine, "help",      CMDFLAG_NONE, 0, 0, 1, execute_help);
261   debug_console_register_command(machine, "help",      CMDFLAG_NONE, 0, 0, 2, execute_help);
262262   debug_console_register_command(machine, "print",     CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, execute_print);
263263   debug_console_register_command(machine, "printf",    CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, execute_printf);
264264   debug_console_register_command(machine, "logerror",  CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, execute_logerror);
r20435r20436
643643{
644644   if (params == 0)
645645      debug_console_printf_wrap(machine, 80, "%s\n", debug_get_help(""));
646   else
646   else if (params == 1)
647647      debug_console_printf_wrap(machine, 80, "%s\n", debug_get_help(param[0]));
648   else if (params == 2)
649   {
650      UINT64 width;
651      debug_command_parameter_number(machine, param[1], &width);
652      debug_console_printf_wrap(machine, (int)width, "%s\n", debug_get_help(param[0]));
653   }
648654}
649655
650656

Previous 199869 Revisions Next


© 1997-2024 The MAME Team