-Qt debugger updates:

* Added context menu with Copy Visible and Paste commands to debug views (partially addresses #6066).
* Made memory view last PC display a context menu item.
* Fixed crash on right-clicking a memory view showing something other than an address space.

-debugger: Fixed commas in dumpkbd output.
This commit is contained in:
Vas Crabb 2021-01-28 02:59:43 +11:00
parent 832acf5731
commit 83c9637635
20 changed files with 746 additions and 768 deletions

View File

@ -1015,7 +1015,6 @@ void natural_keyboard::dump(std::ostream &str) const
firstdev = false;
// loop through all codes
bool firstkey(true);
for (auto &code : devinfo.codemap)
{
// describe the character code
@ -1027,12 +1026,15 @@ void natural_keyboard::dump(std::ostream &str) const
for (auto &entry : code.second)
{
// identify the keys used
bool firstkey(true);
for (std::size_t field = 0; (entry.field.size() > field) && entry.field[field]; ++field)
{
util::stream_format(str, "%s'%s'", firstkey ? "" : ", ", entry.field[field]->name());
firstkey = false;
}
// carriage return
str << '\n';
firstkey = false;
}
}
}

View File

@ -38,9 +38,7 @@ class debug_qt : public osd_module, public debug_module
#endif
{
public:
debug_qt()
: osd_module(OSD_DEBUG_PROVIDER, "qt"), debug_module(),
m_machine(nullptr)
debug_qt() : osd_module(OSD_DEBUG_PROVIDER, "qt"), debug_module(), m_machine(nullptr)
{
}
@ -78,7 +76,7 @@ MainWindow *mainQtWindow = nullptr;
//============================================================
// Global variable used to feed the xml configuration callbacks
std::vector<WindowQtConfig*> xmlConfigurations;
std::vector<std::unique_ptr<WindowQtConfig> > xmlConfigurations;
void xml_configuration_load(running_machine &machine, config_type cfg_type, util::xml::data_node const *parentnode)
@ -88,11 +86,9 @@ std::vector<WindowQtConfig*> xmlConfigurations;
return;
// Might not have any data
if (parentnode == nullptr)
if (!parentnode)
return;
for (int i = 0; i < xmlConfigurations.size(); i++)
delete xmlConfigurations[i];
xmlConfigurations.clear();
// Configuration load
@ -102,13 +98,13 @@ std::vector<WindowQtConfig*> xmlConfigurations;
WindowQtConfig::WindowType type = (WindowQtConfig::WindowType)wnode->get_attribute_int("type", WindowQtConfig::WIN_TYPE_UNKNOWN);
switch (type)
{
case WindowQtConfig::WIN_TYPE_MAIN: xmlConfigurations.push_back(new MainWindowQtConfig()); break;
case WindowQtConfig::WIN_TYPE_MEMORY: xmlConfigurations.push_back(new MemoryWindowQtConfig()); break;
case WindowQtConfig::WIN_TYPE_DASM: xmlConfigurations.push_back(new DasmWindowQtConfig()); break;
case WindowQtConfig::WIN_TYPE_LOG: xmlConfigurations.push_back(new LogWindowQtConfig()); break;
case WindowQtConfig::WIN_TYPE_BREAK_POINTS: xmlConfigurations.push_back(new BreakpointsWindowQtConfig()); break;
case WindowQtConfig::WIN_TYPE_DEVICES: xmlConfigurations.push_back(new DevicesWindowQtConfig()); break;
case WindowQtConfig::WIN_TYPE_DEVICE_INFORMATION: xmlConfigurations.push_back(new DeviceInformationWindowQtConfig()); break;
case WindowQtConfig::WIN_TYPE_MAIN: xmlConfigurations.push_back(std::make_unique<MainWindowQtConfig>()); break;
case WindowQtConfig::WIN_TYPE_MEMORY: xmlConfigurations.push_back(std::make_unique<MemoryWindowQtConfig>()); break;
case WindowQtConfig::WIN_TYPE_DASM: xmlConfigurations.push_back(std::make_unique<DasmWindowQtConfig>()); break;
case WindowQtConfig::WIN_TYPE_LOG: xmlConfigurations.push_back(std::make_unique<LogWindowQtConfig>()); break;
case WindowQtConfig::WIN_TYPE_BREAK_POINTS: xmlConfigurations.push_back(std::make_unique<BreakpointsWindowQtConfig>()); break;
case WindowQtConfig::WIN_TYPE_DEVICES: xmlConfigurations.push_back(std::make_unique<DevicesWindowQtConfig>()); break;
case WindowQtConfig::WIN_TYPE_DEVICE_INFORMATION: xmlConfigurations.push_back(std::make_unique<DeviceInformationWindowQtConfig>()); break;
default: continue;
}
xmlConfigurations.back()->recoverFromXmlNode(*wnode);
@ -124,23 +120,20 @@ void xml_configuration_save(running_machine &machine, config_type cfg_type, util
for (int i = 0; i < xmlConfigurations.size(); i++)
{
WindowQtConfig* config = xmlConfigurations[i];
WindowQtConfig &config = *xmlConfigurations[i];
// Create an xml node
util::xml::data_node *const debugger_node = parentnode->add_child("window", nullptr);
if (debugger_node == nullptr)
continue;
// Insert the appropriate information
config->addToXmlDataNode(*debugger_node);
if (debugger_node)
config.addToXmlDataNode(*debugger_node);
}
}
void gather_save_configurations()
{
for (int i = 0; i < xmlConfigurations.size(); i++)
delete xmlConfigurations[i];
xmlConfigurations.clear();
// Loop over all the open windows
@ -154,19 +147,19 @@ void gather_save_configurations()
// Figure out its type
if (dynamic_cast<MainWindow *>(widget))
xmlConfigurations.push_back(new MainWindowQtConfig());
xmlConfigurations.push_back(std::make_unique<MainWindowQtConfig>());
else if (dynamic_cast<MemoryWindow *>(widget))
xmlConfigurations.push_back(new MemoryWindowQtConfig());
xmlConfigurations.push_back(std::make_unique<MemoryWindowQtConfig>());
else if (dynamic_cast<DasmWindow *>(widget))
xmlConfigurations.push_back(new DasmWindowQtConfig());
xmlConfigurations.push_back(std::make_unique<DasmWindowQtConfig>());
else if (dynamic_cast<LogWindow *>(widget))
xmlConfigurations.push_back(new LogWindowQtConfig());
xmlConfigurations.push_back(std::make_unique<LogWindowQtConfig>());
else if (dynamic_cast<BreakpointsWindow *>(widget))
xmlConfigurations.push_back(new BreakpointsWindowQtConfig());
xmlConfigurations.push_back(std::make_unique<BreakpointsWindowQtConfig>());
else if (dynamic_cast<DevicesWindow *>(widget))
xmlConfigurations.push_back(new DevicesWindowQtConfig());
xmlConfigurations.push_back(std::make_unique<DevicesWindowQtConfig>());
else if (dynamic_cast<DeviceInformationWindow *>(widget))
xmlConfigurations.push_back(new DeviceInformationWindowQtConfig());
xmlConfigurations.push_back(std::make_unique<DeviceInformationWindowQtConfig>());
xmlConfigurations.back()->buildFromQWidget(widget);
}
@ -177,14 +170,14 @@ void gather_save_configurations()
// Utilities
//============================================================
void load_and_clear_main_window_config(std::vector<WindowQtConfig*>& configList)
void load_and_clear_main_window_config(std::vector<std::unique_ptr<WindowQtConfig> > &configList)
{
for (int i = 0; i < configList.size(); i++)
{
WindowQtConfig* config = configList[i];
if (config->m_type == WindowQtConfig::WIN_TYPE_MAIN)
WindowQtConfig &config = *configList[i];
if (config.m_type == WindowQtConfig::WIN_TYPE_MAIN)
{
config->applyToQWidget(mainQtWindow);
config.applyToQWidget(mainQtWindow);
configList.erase(configList.begin() + i);
break;
}
@ -192,30 +185,31 @@ void load_and_clear_main_window_config(std::vector<WindowQtConfig*>& configList)
}
void setup_additional_startup_windows(running_machine& machine, std::vector<WindowQtConfig*>& configList)
void setup_additional_startup_windows(running_machine &machine, std::vector<std::unique_ptr<WindowQtConfig> > &configList)
{
for (int i = 0; i < configList.size(); i++)
{
WindowQtConfig* config = configList[i];
WindowQtConfig &config = *configList[i];
WindowQt *foo = nullptr;
switch (config->m_type)
switch (config.m_type)
{
case WindowQtConfig::WIN_TYPE_MEMORY:
foo = new MemoryWindow(&machine); break;
foo = new MemoryWindow(machine); break;
case WindowQtConfig::WIN_TYPE_DASM:
foo = new DasmWindow(&machine); break;
foo = new DasmWindow(machine); break;
case WindowQtConfig::WIN_TYPE_LOG:
foo = new LogWindow(&machine); break;
foo = new LogWindow(machine); break;
case WindowQtConfig::WIN_TYPE_BREAK_POINTS:
foo = new BreakpointsWindow(&machine); break;
foo = new BreakpointsWindow(machine); break;
case WindowQtConfig::WIN_TYPE_DEVICES:
foo = new DevicesWindow(&machine); break;
foo = new DevicesWindow(machine); break;
case WindowQtConfig::WIN_TYPE_DEVICE_INFORMATION:
foo = new DeviceInformationWindow(&machine); break;
default: break;
foo = new DeviceInformationWindow(machine); break;
default:
break;
}
config->applyToQWidget(foo);
config.applyToQWidget(foo);
foo->show();
}
}
@ -225,12 +219,13 @@ void bring_main_window_to_front()
{
foreach (QWidget *widget, QApplication::topLevelWidgets())
{
if (!dynamic_cast<MainWindow*>(widget))
continue;
if (dynamic_cast<MainWindow *>(widget))
{
widget->activateWindow();
widget->raise();
}
}
}
} // anonymous namespace
@ -251,7 +246,7 @@ bool debug_qt::nativeEventFilter(const QByteArray &eventType, void *message, lon
void debug_qt::init_debugger(running_machine &machine)
{
if (qApp == nullptr)
if (!qApp)
{
// If you're starting from scratch, create a new qApp
new QApplication(qtArgc, qtArgv);
@ -298,14 +293,14 @@ void debug_qt::wait_for_debugger(device_t &device, bool firststop)
// Dialog initialization
if (oneShot)
{
mainQtWindow = new MainWindow(m_machine);
mainQtWindow = new MainWindow(*m_machine);
load_and_clear_main_window_config(xmlConfigurations);
setup_additional_startup_windows(*m_machine, xmlConfigurations);
mainQtWindow->show();
oneShot = false;
}
// Insure all top level widgets are visible & bring main window to front
// Ensure all top level widgets are visible & bring main window to front
foreach (QWidget *widget, QApplication::topLevelWidgets())
{
if (!widget->isWindow() || widget->windowType() != Qt::Window)
@ -314,9 +309,7 @@ void debug_qt::wait_for_debugger(device_t &device, bool firststop)
}
if (firststop)
{
bring_main_window_to_front();
}
// Set the main window to display the proper cpu
mainQtWindow->setProcessor(&device);
@ -369,8 +362,10 @@ void debug_qt::debugger_update()
qApp->processEvents(QEventLoop::AllEvents, 1);
}
#else /* SDLMAME_UNIX */
#else // USE_QTDEBUG
MODULE_NOT_SUPPORTED(debug_qt, OSD_DEBUG_PROVIDER, "qt")
#endif
MODULE_DEFINITION(DEBUG_QT, debug_qt)

View File

@ -1,12 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#include "emu.h"
#include <QtWidgets/QActionGroup>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QVBoxLayout>
#include "breakpointswindow.h"
#include "debug/debugcon.h"
@ -14,13 +8,19 @@
#include "debug/dvbpoints.h"
#include "debug/dvwpoints.h"
#include <QtWidgets/QActionGroup>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QVBoxLayout>
BreakpointsWindow::BreakpointsWindow(running_machine* machine, QWidget* parent) :
BreakpointsWindow::BreakpointsWindow(running_machine &machine, QWidget *parent) :
WindowQt(machine, nullptr)
{
setWindowTitle("Debug: All Breakpoints");
if (parent != nullptr)
if (parent)
{
QPoint parentPos = parent->pos();
setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);

View File

@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#ifndef __DEBUG_QT_BREAK_POINTS_WINDOW_H__
#define __DEBUG_QT_BREAK_POINTS_WINDOW_H__
#ifndef MAME_DEBUGGER_QT_BREAKPOINTSWINDOW_H
#define MAME_DEBUGGER_QT_BREAKPOINTSWINDOW_H
#include "debuggerview.h"
#include "windowqt.h"
@ -15,14 +15,12 @@ class BreakpointsWindow : public WindowQt
Q_OBJECT
public:
BreakpointsWindow(running_machine* machine, QWidget* parent=nullptr);
BreakpointsWindow(running_machine &machine, QWidget *parent = nullptr);
virtual ~BreakpointsWindow();
private slots:
void typeChanged(QAction *changedTo);
private:
// Widgets
DebuggerView *m_breakpointsView;
@ -52,5 +50,4 @@ public:
void recoverFromXmlNode(util::xml::data_node const &node);
};
#endif
#endif // MAME_DEBUGGER_QT_BREAKPOINTSWINDOW_H

View File

@ -1,12 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#include "emu.h"
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QAction>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
#include "dasmwindow.h"
#include "debug/debugcon.h"
@ -14,13 +8,19 @@
#include "debug/dvdisasm.h"
#include "debug/points.h"
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QAction>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
DasmWindow::DasmWindow(running_machine* machine, QWidget* parent) :
DasmWindow::DasmWindow(running_machine &machine, QWidget *parent) :
WindowQt(machine, nullptr)
{
setWindowTitle("Debug: Disassembly View");
if (parent != nullptr)
if (parent)
{
QPoint parentPos = parent->pos();
setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
@ -51,11 +51,10 @@ DasmWindow::DasmWindow(running_machine* machine, QWidget* parent) :
// Force a recompute of the disassembly region
downcast<debug_view_disasm *>(m_dasmView->view())->set_expression("curpc");
// Populate the combo box & set the proper cpu
// Populate the combo box & set the proper CPU
populateComboBox();
setToCurrentCpu();
// Layout
QHBoxLayout *subLayout = new QHBoxLayout(topSubFrame);
subLayout->addWidget(m_inputEdit);
@ -145,19 +144,19 @@ void DasmWindow::toggleBreakpointAtCursor(bool changedTo)
const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
// If none exists, add a new one
if (bp == nullptr)
if (!bp)
{
int32_t bpindex = cpuinfo->breakpoint_set(address, nullptr, nullptr);
m_machine->debugger().console().printf("Breakpoint %X set\n", bpindex);
m_machine.debugger().console().printf("Breakpoint %X set\n", bpindex);
}
else
{
int32_t bpindex = bp->index();
cpuinfo->breakpoint_clear(bpindex);
m_machine->debugger().console().printf("Breakpoint %X cleared\n", bpindex);
m_machine.debugger().console().printf("Breakpoint %X cleared\n", bpindex);
}
m_machine->debug_view().update_all();
m_machine->debugger().refresh_display();
m_machine.debug_view().update_all();
m_machine.debugger().refresh_display();
}
refreshAll();
@ -175,12 +174,12 @@ void DasmWindow::enableBreakpointAtCursor(bool changedTo)
// Find an existing breakpoint at this address
const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
if (bp != nullptr)
if (bp)
{
cpuinfo->breakpoint_enable(bp->index(), !bp->enabled());
m_machine->debugger().console().printf("Breakpoint %X %s\n", (uint32_t)bp->index(), bp->enabled() ? "enabled" : "disabled");
m_machine->debug_view().update_all();
m_machine->debugger().refresh_display();
m_machine.debugger().console().printf("Breakpoint %X %s\n", (uint32_t)bp->index(), bp->enabled() ? "enabled" : "disabled");
m_machine.debug_view().update_all();
m_machine.debugger().refresh_display();
}
}
@ -231,7 +230,7 @@ void DasmWindow::dasmViewUpdated()
// Find an existing breakpoint at this address
const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
if (bp != nullptr)
if (bp)
{
haveBreakpoint = true;
breakpointEnabled = bp->enabled();
@ -248,7 +247,7 @@ void DasmWindow::dasmViewUpdated()
void DasmWindow::populateComboBox()
{
if (m_dasmView == nullptr)
if (!m_dasmView)
return;
m_cpuComboBox->clear();
@ -261,7 +260,7 @@ void DasmWindow::populateComboBox()
void DasmWindow::setToCurrentCpu()
{
device_t* curCpu = m_machine->debugger().console().get_visible_cpu();
device_t *curCpu = m_machine.debugger().console().get_visible_cpu();
if (curCpu)
{
const debug_view_source *source = m_dasmView->view()->source_for_device(curCpu);

View File

@ -1,14 +1,14 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#ifndef __DEBUG_QT_DASM_WINDOW_H__
#define __DEBUG_QT_DASM_WINDOW_H__
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QComboBox>
#ifndef MAME_DEBUGGER_QT_DASMWINDOW_H
#define MAME_DEBUGGER_QT_DASMWINDOW_H
#include "debuggerview.h"
#include "windowqt.h"
#include <QtWidgets/QComboBox>
#include <QtWidgets/QLineEdit>
//============================================================
// The Disassembly Window.
@ -18,10 +18,9 @@ class DasmWindow : public WindowQt
Q_OBJECT
public:
DasmWindow(running_machine* machine, QWidget* parent=nullptr);
DasmWindow(running_machine &machine, QWidget *parent = nullptr);
virtual ~DasmWindow();
private slots:
void cpuChanged(int index);
void expressionSubmitted();
@ -33,12 +32,10 @@ private slots:
void dasmViewUpdated();
private:
void populateComboBox();
void setToCurrentCpu();
// Widgets
QLineEdit *m_inputEdit;
QComboBox *m_cpuComboBox;
@ -77,4 +74,4 @@ public:
};
#endif
#endif // MAME_DEBUGGER_QT_DASMWINDOW_H

View File

@ -1,51 +1,53 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#include "emu.h"
#include <QtWidgets/QScrollBar>
#include <QtWidgets/QApplication>
#include <QtGui/QPainter>
#include <QtGui/QKeyEvent>
#include "debuggerview.h"
#include "modules/lib/osdobj_common.h"
#include <QtCore/QMimeData>
#include <QtGui/QClipboard>
#include <QtGui/QKeyEvent>
#include <QtGui/QPainter>
#include <QtWidgets/QApplication>
#include <QtWidgets/QScrollBar>
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
#define horizontalAdvance width
#endif
DebuggerView::DebuggerView(const debug_view_type& type,
running_machine* machine,
DebuggerView::DebuggerView(
debug_view_type type,
running_machine &machine,
QWidget *parent) :
QAbstractScrollArea(parent),
m_preferBottom(false),
m_machine(machine),
m_view(nullptr),
m_machine(machine)
m_preferBottom(false)
{
// I like setting the font per-view since it doesn't override the menuing fonts.
const char *const selectedFont(downcast<osd_options &>(m_machine->options()).debugger_font());
const float selectedFontSize(downcast<osd_options &>(m_machine->options()).debugger_font_size());
// I like setting the font per-view since it doesn't override the menu fonts.
const char *const selectedFont(downcast<osd_options &>(m_machine.options()).debugger_font());
const float selectedFontSize(downcast<osd_options &>(m_machine.options()).debugger_font_size());
QFont viewFontRequest((!*selectedFont || !strcmp(selectedFont, OSDOPTVAL_AUTO)) ? "Courier New" : selectedFont);
viewFontRequest.setFixedPitch(true);
viewFontRequest.setStyleHint(QFont::TypeWriter);
viewFontRequest.setPointSize((selectedFontSize <= 0) ? 11 : selectedFontSize);
setFont(viewFontRequest);
m_view = m_machine->debug_view().alloc_view(type,
m_view = m_machine.debug_view().alloc_view(
type,
DebuggerView::debuggerViewUpdate,
this);
connect(verticalScrollBar(), &QScrollBar::valueChanged,
this, &DebuggerView::verticalScrollSlot);
connect(horizontalScrollBar(), &QScrollBar::valueChanged,
this, &DebuggerView::horizontalScrollSlot);
connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &DebuggerView::verticalScrollSlot);
connect(horizontalScrollBar(), &QScrollBar::valueChanged, this, &DebuggerView::horizontalScrollSlot);
}
DebuggerView::~DebuggerView()
{
if (m_machine && m_view)
m_machine->debug_view().free_view(*m_view);
if (m_view)
m_machine.debug_view().free_view(*m_view);
}
void DebuggerView::paintEvent(QPaintEvent *event)
@ -67,17 +69,10 @@ void DebuggerView::paintEvent(QPaintEvent* event)
const int verticalScrollCharDiff = m_view->total_size().y - m_view->visible_size().y;
const int verticalScrollSize = verticalScrollCharDiff < 0 ? 0 : verticalScrollCharDiff+verticalScrollAdjust;
bool atEnd = false;
if (verticalScrollBar()->value() == verticalScrollBar()->maximum())
{
atEnd = true;
}
const bool atEnd = verticalScrollBar()->value() == verticalScrollBar()->maximum();
verticalScrollBar()->setRange(0, verticalScrollSize);
if (m_preferBottom && atEnd)
{
verticalScrollBar()->setValue(verticalScrollSize);
}
// Draw the viewport widget
QPainter painter(viewport());
@ -105,43 +100,36 @@ void DebuggerView::paintEvent(QPaintEvent* event)
QColor bgColor(255,255,255);
if (textAttr & DCA_VISITED)
{
bgColor.setRgb(0xc6, 0xe2, 0xff);
}
if (textAttr & DCA_ANCILLARY)
{
bgColor.setRgb(0xe0, 0xe0, 0xe0);
}
if (textAttr & DCA_SELECTED)
{
bgColor.setRgb(0xff, 0x80, 0x80);
}
if (textAttr & DCA_CURRENT)
{
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);
}
if (textAttr & DCA_INVALID)
{
fgColor.setRgb(0x00, 0x00, 0xff);
}
if (textAttr & DCA_DISABLED)
{
fgColor.setRgb((fgColor.red() + bgColor.red()) >> 1,
fgColor.setRgb(
(fgColor.red() + bgColor.red()) >> 1,
(fgColor.green() + bgColor.green()) >> 1,
(fgColor.blue() + bgColor.blue()) >> 1);
}
if(textAttr & DCA_COMMENT)
{
fgColor.setRgb(0x00, 0x80, 0x00);
}
bgBrush.setColor(bgColor);
painter.setBackground(bgBrush);
@ -184,11 +172,13 @@ void DebuggerView::keyPressEvent(QKeyEvent* event)
break;
case Qt::Key_Left:
keyPress = DCH_LEFT;
if (ctrlDown) keyPress = DCH_CTRLLEFT;
if (ctrlDown)
keyPress = DCH_CTRLLEFT;
break;
case Qt::Key_Right:
keyPress = DCH_RIGHT;
if (ctrlDown) keyPress = DCH_CTRLRIGHT;
if (ctrlDown)
keyPress = DCH_CTRLRIGHT;
break;
case Qt::Key_PageUp:
keyPress = DCH_PUP;
@ -237,11 +227,9 @@ void DebuggerView::keyPressEvent(QKeyEvent* event)
void DebuggerView::mousePressEvent(QMouseEvent *event)
{
if (m_view == nullptr)
if (!m_view)
return;
if (event->button() == Qt::LeftButton)
{
QFontMetrics actualFont = fontMetrics();
const double fontWidth = actualFont.horizontalAdvance(QString(100, '_')) / 100.;
const int fontHeight = std::max(1, actualFont.lineSpacing());
@ -250,11 +238,46 @@ void DebuggerView::mousePressEvent(QMouseEvent* event)
debug_view_xy clickViewPosition;
clickViewPosition.x = topLeft.x + (event->x() / fontWidth);
clickViewPosition.y = topLeft.y + (event->y() / fontHeight);
if (event->button() == Qt::LeftButton)
{
m_view->process_click(DCK_LEFT_CLICK, clickViewPosition);
}
else if (event->button() == Qt::MiddleButton)
{
m_view->process_click(DCK_MIDDLE_CLICK, clickViewPosition);
}
else if (event->button() == Qt::RightButton)
{
if (m_view->cursor_supported())
{
m_view->set_cursor_position(clickViewPosition);
m_view->set_cursor_visible(true);
}
}
viewport()->update();
update();
}
void DebuggerView::contextMenuEvent(QContextMenuEvent *event)
{
QMenu *const menu = new QMenu(this);
addItemsToContextMenu(menu);
menu->popup(event->globalPos());
}
void DebuggerView::addItemsToContextMenu(QMenu *menu)
{
QAction *const copyAct = new QAction("Copy Visible", menu);
QAction *const pasteAct = new QAction("Paste", menu);
pasteAct->setEnabled(QApplication::clipboard()->mimeData()->hasText());
connect(copyAct, &QAction::triggered, this, &DebuggerView::copyVisibleSlot);
connect(pasteAct, &QAction::triggered, this, &DebuggerView::pasteSlot);
menu->addAction(copyAct);
menu->addAction(pasteAct);
}
@ -270,10 +293,46 @@ void DebuggerView::horizontalScrollSlot(int value)
}
void DebuggerView::copyVisibleSlot()
{
// get visible text
debug_view_xy const visarea = m_view->visible_size();
debug_view_char const *viewdata = m_view->viewdata();
if (!viewdata)
return;
// turn into a plain string, trimming trailing whitespace
std::string text;
for (uint32_t row = 0; row < visarea.y; row++, viewdata += visarea.x)
{
std::string::size_type const start = text.length();
for (uint32_t col = 0; col < visarea.x; ++col)
text += wchar_t(viewdata[col].byte);
std::string::size_type const nonblank = text.find_last_not_of("\t\n\v\r ");
if ((nonblank != std::string::npos) && (nonblank >= start))
text.resize(nonblank + 1);
text += "\n";
}
// copy to the clipboard
QApplication::clipboard()->setText(text.c_str());
}
void DebuggerView::pasteSlot()
{
for (QChar ch : QApplication::clipboard()->text())
{
if ((32 <= ch.unicode()) && (127 >= ch.unicode()))
m_view->process_char(ch.unicode());
}
}
void DebuggerView::debuggerViewUpdate(debug_view &debugView, void *osdPrivate)
{
// Get a handle to the DebuggerView being updated & redraw
DebuggerView* dView = (DebuggerView*)osdPrivate;
// Get a handle to the DebuggerView being updated and redraw
DebuggerView *dView = reinterpret_cast<DebuggerView *>(osdPrivate);
dView->verticalScrollBar()->setValue(dView->view()->visible_position().y);
dView->horizontalScrollBar()->setValue(dView->view()->visible_position().x);
dView->viewport()->update();

View File

@ -1,21 +1,20 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#ifndef __DEBUG_QT_DEBUGGER_VIEW_H__
#define __DEBUG_QT_DEBUGGER_VIEW_H__
#include <QtWidgets/QAbstractScrollArea>
#ifndef MAME_DEBUGGER_QT_DEBUGGERVIEW_H
#define MAME_DEBUGGER_QT_DEBUGGERVIEW_H
#include "debug/debugvw.h"
#include <QtWidgets/QAbstractScrollArea>
#include <QtWidgets/QMenu>
class DebuggerView : public QAbstractScrollArea
{
Q_OBJECT
public:
DebuggerView(const debug_view_type& type,
running_machine* machine,
QWidget* parent=nullptr);
DebuggerView(debug_view_type type, running_machine &machine, QWidget *parent = nullptr);
virtual ~DebuggerView();
void paintEvent(QPaintEvent *event);
@ -28,23 +27,26 @@ signals:
void updated();
protected:
void keyPressEvent(QKeyEvent* event);
void mousePressEvent(QMouseEvent* event);
void keyPressEvent(QKeyEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void contextMenuEvent(QContextMenuEvent *event) override;
virtual void addItemsToContextMenu(QMenu *menu);
private slots:
void verticalScrollSlot(int value);
void horizontalScrollSlot(int value);
void copyVisibleSlot();
void pasteSlot();
private:
// Callback to allow MAME to refresh the view
static void debuggerViewUpdate(debug_view &debugView, void *osdPrivate);
bool m_preferBottom;
running_machine &m_machine;
debug_view *m_view;
running_machine* m_machine;
bool m_preferBottom;
};
#endif
#endif // MAME_DEBUGGER_QT_DEBUGGERVIEW_H

View File

@ -8,12 +8,11 @@
#include "deviceinformationwindow.h"
DeviceInformationWindow::DeviceInformationWindow(running_machine* machine, device_t* device, QWidget* parent) :
WindowQt(machine, nullptr)
DeviceInformationWindow::DeviceInformationWindow(running_machine &machine, device_t *device, QWidget *parent) :
WindowQt(machine, nullptr),
m_device(device)
{
m_device = device;
if (parent != nullptr)
if (parent)
{
QPoint parentPos = parent->pos();
setGeometry(parentPos.x()+100, parentPos.y()+100, 600, 400);
@ -30,10 +29,7 @@ DeviceInformationWindow::~DeviceInformationWindow()
void DeviceInformationWindow::fill_device_information()
{
char title[4069];
sprintf(title, "Debug: Device %s", m_device->tag());
setWindowTitle(title);
setWindowTitle(util::string_format("Debug: Device %s", m_device->tag()).c_str());
QFrame *mainWindowFrame = new QFrame(this);
QVBoxLayout *vLayout = new QVBoxLayout(mainWindowFrame);
@ -53,9 +49,11 @@ void DeviceInformationWindow::fill_device_information()
int cpos = 3;
device_interface *intf = m_device->interfaces().first();
if(intf) {
if (intf)
{
gl1->addWidget(new QLabel(QString("Interfaces"), primaryFrame), cpos, 0);
while(intf) {
while(intf)
{
gl1->addWidget(new QLabel(QString(intf->interface_type()), primaryFrame), cpos, 1);
cpos++;
intf = intf->interface_next();
@ -65,16 +63,19 @@ void DeviceInformationWindow::fill_device_information()
vLayout->addWidget(primaryFrame);
device_memory_interface *d_memory;
if(m_device->interface(d_memory)) {
if (m_device->interface(d_memory))
{
QFrame *f = new QFrame(mainWindowFrame);
f->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
QVBoxLayout *vb = new QVBoxLayout(f);
bool first = true;
for (int i=0; i<d_memory->max_space_count(); i++)
if(d_memory->has_space(i)) {
if (d_memory->has_space(i))
{
QFrame *ff = new QFrame(f);
QHBoxLayout *hb = new QHBoxLayout(ff);
if(first) {
if (first)
{
hb->addWidget(new QLabel("Memory maps"));
first = false;
}
@ -92,9 +93,9 @@ void DeviceInformationWindow::fill_device_information()
void DeviceInformationWindow::set_device(const char *tag)
{
m_device = m_machine->root_device().subdevice(tag);
m_device = m_machine.root_device().subdevice(tag);
if (!m_device)
m_device = &m_machine->root_device();
m_device = &m_machine.root_device();
fill_device_information();
}

View File

@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#ifndef __DEBUG_QT_DEVICE_INFORMATION_WINDOW_H__
#define __DEBUG_QT_DEVICE_INFORMATION_WINDOW_H__
#ifndef MAME_DEBUGGER_QT_DEVICEINFORMATIONWINDOW_H
#define MAME_DEBUGGER_QT_DEVICEINFORMATIONWINDOW_H
#include "windowqt.h"
@ -13,7 +13,7 @@ class DeviceInformationWindow : public WindowQt
Q_OBJECT
public:
DeviceInformationWindow(running_machine* machine, device_t* device = nullptr, QWidget* parent=nullptr);
DeviceInformationWindow(running_machine &machine, device_t *device = nullptr, QWidget* parent=nullptr);
virtual ~DeviceInformationWindow();
void set_device(const char *tag);
@ -50,4 +50,4 @@ public:
};
#endif
#endif // MAME_DEBUGGER_QT_DEVICEINFORMATIONWINDOW_H

View File

@ -4,9 +4,9 @@
#include "deviceswindow.h"
#include "deviceinformationwindow.h"
DevicesWindowModel::DevicesWindowModel(running_machine *machine, QObject *parent)
DevicesWindowModel::DevicesWindowModel(running_machine &machine, QObject *parent) :
m_machine(machine)
{
m_machine = machine;
}
DevicesWindowModel::~DevicesWindowModel()
@ -19,8 +19,9 @@ QVariant DevicesWindowModel::data(const QModelIndex &index, int role) const
return QVariant();
device_t *dev = static_cast<device_t *>(index.internalPointer());
switch(index.column()) {
case 0: return dev == &m_machine->root_device() ? QString("<root>") : QString(dev->basetag());
switch (index.column())
{
case 0: return (dev == &m_machine.root_device()) ? QString("<root>") : QString(dev->basetag());
case 1: return QString(dev->name());
}
@ -49,11 +50,14 @@ QModelIndex DevicesWindowModel::index(int row, int column, const QModelIndex &pa
device_t *target = nullptr;
if(!parent.isValid()) {
if (!parent.isValid())
{
if (row == 0)
target = &m_machine->root_device();
target = &m_machine.root_device();
} else {
}
else
{
device_t *dparent = static_cast<device_t *>(parent.internalPointer());
int count = row;
for(target = dparent->subdevices().first(); count && target; target = target->next())
@ -79,7 +83,8 @@ QModelIndex DevicesWindowModel::parent(const QModelIndex &index) const
device_t *dpp = dparent->owner();
int row = 0;
if(dpp) {
if (dpp)
{
for (device_t *child = dpp->subdevices().first(); child && child != dparent; child = child->next())
row++;
}
@ -102,7 +107,7 @@ int DevicesWindowModel::columnCount(const QModelIndex &parent) const
DevicesWindow::DevicesWindow(running_machine* machine, QWidget* parent) :
DevicesWindow::DevicesWindow(running_machine &machine, QWidget *parent) :
WindowQt(machine, nullptr),
m_devices_model(machine)
{

View File

@ -1,12 +1,12 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#ifndef __DEBUG_QT_DEVICES_WINDOW_H__
#define __DEBUG_QT_DEVICES_WINDOW_H__
#include <QtWidgets/QTreeView>
#ifndef MAME_DEBUGGER_QT_DEVICESWINDOW_H
#define MAME_DEBUGGER_QT_DEVICESWINDOW_H
#include "windowqt.h"
#include <QtWidgets/QTreeView>
//============================================================
// The model for the treeview
@ -17,21 +17,19 @@ class DevicesWindowModel : public QAbstractItemModel
Q_OBJECT
public:
explicit DevicesWindowModel(running_machine *machine, QObject *parent = 0);
explicit DevicesWindowModel(running_machine &machine, QObject *parent = nullptr);
~DevicesWindowModel();
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &index) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
private:
running_machine *m_machine;
running_machine &m_machine;
};
//============================================================
@ -42,7 +40,7 @@ class DevicesWindow : public WindowQt
Q_OBJECT
public:
DevicesWindow(running_machine* machine, QWidget* parent=nullptr);
DevicesWindow(running_machine &machine, QWidget *parent = nullptr);
virtual ~DevicesWindow();
public slots:
@ -78,4 +76,4 @@ public:
};
#endif
#endif // MAME_DEBUGGER_QT_DEVICESWINDOW_H

View File

@ -10,12 +10,12 @@
#include "debug/dvdisasm.h"
LogWindow::LogWindow(running_machine* machine, QWidget* parent) :
LogWindow::LogWindow(running_machine &machine, QWidget *parent) :
WindowQt(machine, nullptr)
{
setWindowTitle("Debug: Machine Log");
if (parent != nullptr)
if (parent)
{
QPoint parentPos = parent->pos();
setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
@ -27,9 +27,7 @@ LogWindow::LogWindow(running_machine* machine, QWidget* parent) :
QFrame *mainWindowFrame = new QFrame(this);
// The main log view
m_logView = new DebuggerView(DVT_LOG,
m_machine,
this);
m_logView = new DebuggerView(DVT_LOG, m_machine, this);
// Layout
QVBoxLayout* vLayout = new QVBoxLayout(mainWindowFrame);

View File

@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#ifndef __DEBUG_QT_LOG_WINDOW_H__
#define __DEBUG_QT_LOG_WINDOW_H__
#ifndef MAME_DEBUGGER_QT_LOGWINDOW_H
#define MAME_DEBUGGER_QT_LOGWINDOW_H
#include "debuggerview.h"
#include "windowqt.h"
@ -15,10 +15,9 @@ class LogWindow : public WindowQt
Q_OBJECT
public:
LogWindow(running_machine* machine, QWidget* parent=nullptr);
LogWindow(running_machine &machine, QWidget *parent = nullptr);
virtual ~LogWindow();
private:
// Widgets
DebuggerView *m_logView;
@ -45,4 +44,4 @@ public:
};
#endif
#endif // MAME_DEBUGGER_QT_LOGWINDOW_H

View File

@ -1,14 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#include "emu.h"
#include <QtWidgets/QAction>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QDockWidget>
#include <QtWidgets/QScrollBar>
#include <QtWidgets/QFileDialog>
#include <QtGui/QCloseEvent>
#include "mainwindow.h"
#include "debug/debugcon.h"
@ -16,8 +8,16 @@
#include "debug/dvdisasm.h"
#include "debug/points.h"
#include <QtGui/QCloseEvent>
#include <QtWidgets/QAction>
#include <QtWidgets/QDockWidget>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QScrollBar>
MainWindow::MainWindow(running_machine* machine, QWidget* parent) :
MainWindow::MainWindow(running_machine &machine, QWidget *parent) :
WindowQt(machine, nullptr),
m_historyIndex(0),
m_inputHistory()
@ -36,9 +36,7 @@ MainWindow::MainWindow(running_machine* machine, QWidget* parent) :
// The log view
m_consoleView = new DebuggerView(DVT_CONSOLE,
m_machine,
mainWindowFrame);
m_consoleView = new DebuggerView(DVT_CONSOLE, m_machine, mainWindowFrame);
m_consoleView->setFocusPolicy(Qt::NoFocus);
m_consoleView->setPreferBottom(true);
@ -93,11 +91,9 @@ MainWindow::MainWindow(running_machine* machine, QWidget* parent) :
//
// Images menu
//
image_interface_enumerator imageIterTest(m_machine->root_device());
if (imageIterTest.first() != nullptr)
{
image_interface_enumerator imageIterTest(m_machine.root_device());
if (imageIterTest.first())
createImagesMenu();
}
//
// Dock window menu
@ -146,8 +142,7 @@ void MainWindow::setProcessor(device_t* processor)
m_dasmFrame->view()->verticalScrollBar()->setValue(m_dasmFrame->view()->view()->visible_position().y);
// Window title
string_format("Debug: %s - %s '%s'", m_machine->system().name, processor->name(), processor->tag());
setWindowTitle(string_format("Debug: %s - %s '%s'", m_machine->system().name, processor->name(), processor->tag()).c_str());
setWindowTitle(string_format("Debug: %s - %s '%s'", m_machine.system().name, processor->name(), processor->tag()).c_str());
}
@ -167,13 +162,9 @@ bool MainWindow::eventFilter(QObject* obj, QEvent* event)
// Only filter keypresses
QKeyEvent *keyEvent = nullptr;
if (event->type() == QEvent::KeyPress)
{
keyEvent = static_cast<QKeyEvent*>(event);
}
else
{
return QObject::eventFilter(obj, event);
}
// Catch up & down keys
if (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down)
@ -215,7 +206,7 @@ bool MainWindow::eventFilter(QObject* obj, QEvent* event)
void MainWindow::toggleBreakpointAtCursor(bool changedTo)
{
debug_view_disasm *const dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
if (dasmView->cursor_visible() && (m_machine->debugger().console().get_visible_cpu() == dasmView->source()->device()))
if (dasmView->cursor_visible() && (m_machine.debugger().console().get_visible_cpu() == dasmView->source()->device()))
{
offs_t const address = downcast<debug_view_disasm *>(dasmView)->selected_address();
device_debug *const cpuinfo = dasmView->source()->device()->debug();
@ -225,15 +216,11 @@ void MainWindow::toggleBreakpointAtCursor(bool changedTo)
// If none exists, add a new one
std::string command;
if (bp == nullptr)
{
if (!bp)
command = string_format("bpset 0x%X", address);
}
else
{
command = string_format("bpclear 0x%X", bp->index());
}
m_machine->debugger().console().execute_command(command.c_str(), true);
m_machine.debugger().console().execute_command(command.c_str(), true);
}
refreshAll();
@ -243,7 +230,7 @@ void MainWindow::toggleBreakpointAtCursor(bool changedTo)
void MainWindow::enableBreakpointAtCursor(bool changedTo)
{
debug_view_disasm *const dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
if (dasmView->cursor_visible() && (m_machine->debugger().console().get_visible_cpu() == dasmView->source()->device()))
if (dasmView->cursor_visible() && (m_machine.debugger().console().get_visible_cpu() == dasmView->source()->device()))
{
offs_t const address = dasmView->selected_address();
device_debug *const cpuinfo = dasmView->source()->device()->debug();
@ -251,11 +238,11 @@ void MainWindow::enableBreakpointAtCursor(bool changedTo)
// Find an existing breakpoint at this address
const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
if (bp != nullptr)
if (bp)
{
int32_t const bpindex = bp->index();
std::string command = string_format(bp->enabled() ? "bpdisable 0x%X" : "bpenable 0x%X", bpindex);
m_machine->debugger().console().execute_command(command.c_str(), true);
m_machine.debugger().console().execute_command(command.c_str(), true);
}
}
@ -266,11 +253,11 @@ void MainWindow::enableBreakpointAtCursor(bool changedTo)
void MainWindow::runToCursor(bool changedTo)
{
debug_view_disasm *dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
if (dasmView->cursor_visible() && (m_machine->debugger().console().get_visible_cpu() == dasmView->source()->device()))
if (dasmView->cursor_visible() && (m_machine.debugger().console().get_visible_cpu() == dasmView->source()->device()))
{
offs_t address = downcast<debug_view_disasm*>(dasmView)->selected_address();
std::string command = string_format("go 0x%X", address);
m_machine->debugger().console().execute_command(command.c_str(), true);
m_machine.debugger().console().execute_command(command.c_str(), true);
}
}
@ -278,18 +265,14 @@ void MainWindow::runToCursor(bool changedTo)
void MainWindow::rightBarChanged(QAction *changedTo)
{
debug_view_disasm *dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
if (changedTo->text() == "Raw Opcodes")
{
dasmView->set_right_column(DASM_RIGHTCOL_RAW);
}
else if (changedTo->text() == "Encrypted Opcodes")
{
dasmView->set_right_column(DASM_RIGHTCOL_ENCRYPTED);
}
else if (changedTo->text() == "Comments")
{
dasmView->set_right_column(DASM_RIGHTCOL_COMMENTS);
}
m_dasmFrame->view()->viewport()->update();
}
@ -305,12 +288,12 @@ void MainWindow::executeCommand(bool withClear)
// A blank command is a "silent step"
if (command == "")
{
m_machine->debugger().console().get_visible_cpu()->debug()->single_step();
m_machine.debugger().console().get_visible_cpu()->debug()->single_step();
return;
}
// Send along the command
m_machine->debugger().console().execute_command(command.toLocal8Bit().data(), true);
m_machine.debugger().console().execute_command(command.toLocal8Bit().data(), true);
// Add history & set the index to be the top of the stack
addToHistory(command);
@ -332,24 +315,25 @@ void MainWindow::mountImage(bool changedTo)
{
// The image interface index was assigned to the QAction's data memeber
const int imageIndex = dynamic_cast<QAction*>(sender())->data().toInt();
image_interface_enumerator iter(m_machine->root_device());
image_interface_enumerator iter(m_machine.root_device());
device_image_interface *img = iter.byindex(imageIndex);
if (img == nullptr)
if (!img)
{
m_machine->debugger().console().printf("Something is wrong with the mount menu.\n");
m_machine.debugger().console().printf("Something is wrong with the mount menu.\n");
refreshAll();
return;
}
// File dialog
QString filename = QFileDialog::getOpenFileName(this,
QString filename = QFileDialog::getOpenFileName(
this,
"Select an image file",
QDir::currentPath(),
tr("All files (*.*)"));
if (img->load(filename.toUtf8().data()) != image_init_result::PASS)
{
m_machine->debugger().console().printf("Image could not be mounted.\n");
m_machine.debugger().console().printf("Image could not be mounted.\n");
refreshAll();
return;
}
@ -365,7 +349,7 @@ void MainWindow::mountImage(bool changedTo)
const QString newTitle = baseString + QString(" : ") + QString(img->filename());
parentMenuItem->setTitle(newTitle);
m_machine->debugger().console().printf("Image %s mounted successfully.\n", filename.toUtf8().data());
m_machine.debugger().console().printf("Image %s mounted successfully.\n", filename.toUtf8().data());
refreshAll();
}
@ -374,7 +358,7 @@ void MainWindow::unmountImage(bool changedTo)
{
// The image interface index was assigned to the QAction's data memeber
const int imageIndex = dynamic_cast<QAction *>(sender())->data().toInt();
image_interface_enumerator iter(m_machine->root_device());
image_interface_enumerator iter(m_machine.root_device());
device_image_interface *img = iter.byindex(imageIndex);
img->unload();
@ -389,7 +373,7 @@ void MainWindow::unmountImage(bool changedTo)
const QString newTitle = baseString + QString(" : ") + QString("[empty slot]");
parentMenuItem->setTitle(newTitle);
m_machine->debugger().console().printf("Image successfully unmounted.\n");
m_machine.debugger().console().printf("Image successfully unmounted.\n");
refreshAll();
}
@ -397,7 +381,7 @@ void MainWindow::unmountImage(bool changedTo)
void MainWindow::dasmViewUpdated()
{
debug_view_disasm *const dasmView = downcast<debug_view_disasm *>(m_dasmFrame->view()->view());
bool const haveCursor = dasmView->cursor_visible() && (m_machine->debugger().console().get_visible_cpu() == dasmView->source()->device());
bool const haveCursor = dasmView->cursor_visible() && (m_machine.debugger().console().get_visible_cpu() == dasmView->source()->device());
bool haveBreakpoint = false;
bool breakpointEnabled = false;
if (haveCursor)
@ -409,7 +393,7 @@ void MainWindow::dasmViewUpdated()
// Find an existing breakpoint at this address
const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
if (bp != nullptr)
if (bp)
{
haveBreakpoint = true;
breakpointEnabled = bp->enabled();
@ -426,7 +410,7 @@ void MainWindow::dasmViewUpdated()
void MainWindow::debugActClose()
{
m_machine->schedule_exit();
m_machine.schedule_exit();
}
@ -436,7 +420,7 @@ void MainWindow::addToHistory(const QString& command)
return;
// Always push back when there is no previous history
if (m_inputHistory.size() == 0)
if (m_inputHistory.empty())
{
m_inputHistory.push_back(m_inputEdit->text());
return;
@ -444,10 +428,8 @@ void MainWindow::addToHistory(const QString& command)
// If there is previous history, make sure it's not what you just executed
if (m_inputHistory.back() != m_inputEdit->text())
{
m_inputHistory.push_back(m_inputEdit->text());
}
}
void MainWindow::createImagesMenu()
@ -455,7 +437,7 @@ void MainWindow::createImagesMenu()
QMenu *imagesMenu = menuBar()->addMenu("&Images");
int interfaceIndex = 0;
for (device_image_interface &img : image_interface_enumerator(m_machine->root_device()))
for (device_image_interface &img : image_interface_enumerator(m_machine.root_device()))
{
std::string menuName = string_format("%s : %s", img.device().name(), img.exists() ? img.filename() : "[empty slot]");

View File

@ -1,18 +1,19 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#ifndef __DEBUG_QT_MAIN_WINDOW_H__
#define __DEBUG_QT_MAIN_WINDOW_H__
#ifndef MAME_DEBUGGER_QT_MAINWINDOW_H
#define MAME_DEBUGGER_QT_MAINWINDOW_H
#include <vector>
#include "debuggerview.h"
#include "windowqt.h"
#include "debug/dvdisasm.h"
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QComboBox>
#include "debug/dvdisasm.h"
#include <vector>
#include "debuggerview.h"
#include "windowqt.h"
class DasmDockWidget;
class ProcessorDockWidget;
@ -26,7 +27,7 @@ class MainWindow : public WindowQt
Q_OBJECT
public:
MainWindow(running_machine* machine, QWidget* parent=nullptr);
MainWindow(running_machine &machine, QWidget *parent = nullptr);
virtual ~MainWindow();
void setProcessor(device_t *processor);
@ -39,7 +40,6 @@ protected:
// Used to intercept the user hitting the up arrow in the input widget
bool eventFilter(QObject *obj, QEvent *event);
private slots:
void toggleBreakpointAtCursor(bool changedTo);
void enableBreakpointAtCursor(bool changedTo);
@ -87,13 +87,11 @@ class DasmDockWidget : public QWidget
Q_OBJECT
public:
DasmDockWidget(running_machine* machine, QWidget* parent=nullptr) :
DasmDockWidget(running_machine &machine, QWidget *parent = nullptr) :
QWidget(parent),
m_machine(machine)
{
m_dasmView = new DebuggerView(DVT_DISASSEMBLY,
m_machine,
this);
m_dasmView = new DebuggerView(DVT_DISASSEMBLY, m_machine, this);
// Force a recompute of the disassembly region
downcast<debug_view_disasm*>(m_dasmView->view())->set_expression("curpc");
@ -103,29 +101,17 @@ public:
dvLayout->setContentsMargins(4,0,4,0);
}
virtual ~DasmDockWidget();
DebuggerView *view() { return m_dasmView; }
QSize minimumSizeHint() const
{
return QSize(150,150);
}
QSize sizeHint() const
{
return QSize(150,200);
}
QSize minimumSizeHint() const { return QSize(150, 150); }
QSize sizeHint() const { return QSize(150, 200); }
private:
DebuggerView* m_dasmView;
running_machine &m_machine;
running_machine* m_machine;
DebuggerView *m_dasmView;
};
@ -137,15 +123,12 @@ class ProcessorDockWidget : public QWidget
Q_OBJECT
public:
ProcessorDockWidget(running_machine* machine,
QWidget* parent=nullptr) :
ProcessorDockWidget(running_machine &machine, QWidget *parent = nullptr) :
QWidget(parent),
m_processorView(nullptr),
m_machine(machine)
m_machine(machine),
m_processorView(nullptr)
{
m_processorView = new DebuggerView(DVT_STATE,
m_machine,
this);
m_processorView = new DebuggerView(DVT_STATE, m_machine, this);
m_processorView->setFocusPolicy(Qt::NoFocus);
QVBoxLayout *cvLayout = new QVBoxLayout(this);
@ -153,29 +136,17 @@ public:
cvLayout->setContentsMargins(4,0,4,2);
}
virtual ~ProcessorDockWidget();
DebuggerView *view() { return m_processorView; }
QSize minimumSizeHint() const
{
return QSize(150,300);
}
QSize sizeHint() const
{
return QSize(200,300);
}
QSize minimumSizeHint() const { return QSize(150, 300); }
QSize sizeHint() const { return QSize(200, 300); }
private:
DebuggerView* m_processorView;
running_machine &m_machine;
running_machine* m_machine;
DebuggerView *m_processorView;
};
@ -204,5 +175,4 @@ public:
};
#endif
#endif // MAME_DEBUGGER_QT_MAINWINDOW_H

View File

@ -1,6 +1,12 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#include "emu.h"
#include "memorywindow.h"
#include "debug/dvmemory.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include <QtGui/QClipboard>
#include <QtGui/QMouseEvent>
#include <QtWidgets/QActionGroup>
@ -12,22 +18,16 @@
#include <QtWidgets/QToolTip>
#include <QtWidgets/QVBoxLayout>
#include "memorywindow.h"
#include "debug/dvmemory.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
#define horizontalAdvance width
#endif
MemoryWindow::MemoryWindow(running_machine* machine, QWidget* parent) :
MemoryWindow::MemoryWindow(running_machine &machine, QWidget *parent) :
WindowQt(machine, nullptr)
{
setWindowTitle("Debug: Memory View");
if (parent != nullptr)
if (parent)
{
QPoint parentPos = parent->pos();
setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
@ -209,34 +209,22 @@ void MemoryWindow::expressionSubmitted()
void MemoryWindow::formatChanged(QAction* changedTo)
{
debug_view_memory *memView = downcast<debug_view_memory*>(m_memTable->view());
if (changedTo->text() == "1-byte chunks")
{
memView->set_data_format(1);
}
else if (changedTo->text() == "2-byte chunks")
{
memView->set_data_format(2);
}
else if (changedTo->text() == "4-byte chunks")
{
memView->set_data_format(4);
}
else if (changedTo->text() == "8-byte chunks")
{
memView->set_data_format(8);
}
else if (changedTo->text() == "32 bit floating point")
{
memView->set_data_format(9);
}
else if (changedTo->text() == "64 bit floating point")
{
memView->set_data_format(10);
}
else if (changedTo->text() == "80 bit floating point")
{
memView->set_data_format(11);
}
m_memTable->viewport()->update();
}
@ -244,14 +232,12 @@ void MemoryWindow::formatChanged(QAction* changedTo)
void MemoryWindow::addressChanged(QAction* changedTo)
{
debug_view_memory *memView = downcast<debug_view_memory *>(m_memTable->view());
if (changedTo->text() == "Logical Addresses")
{
memView->set_physical(false);
}
else if (changedTo->text() == "Physical Addresses")
{
memView->set_physical(true);
}
m_memTable->viewport()->update();
}
@ -282,20 +268,18 @@ void MemoryWindow::decreaseBytesPerLine(bool checked)
void MemoryWindow::populateComboBox()
{
if (m_memTable == nullptr)
if (!m_memTable)
return;
m_memoryComboBox->clear();
for (auto &source : m_memTable->view()->source_list())
{
m_memoryComboBox->addItem(source->name());
}
}
void MemoryWindow::setToCurrentCpu()
{
device_t* curCpu = m_machine->debugger().console().get_visible_cpu();
device_t *curCpu = m_machine.debugger().console().get_visible_cpu();
if (curCpu)
{
const debug_view_source *source = m_memTable->view()->source_for_device(curCpu);
@ -314,7 +298,8 @@ QAction* MemoryWindow::dataFormatMenuItem(const QString& itemName)
QList<QMenu *> menus = menuBar()->findChildren<QMenu *>();
for (int i = 0; i < menus.length(); i++)
{
if (menus[i]->title() != "&Options") continue;
if (menus[i]->title() != "&Options")
continue;
QList<QAction *> actions = menus[i]->actions();
for (int j = 0; j < actions.length(); j++)
{
@ -329,36 +314,25 @@ QAction* MemoryWindow::dataFormatMenuItem(const QString& itemName)
//=========================================================================
// DebuggerMemView
//=========================================================================
void DebuggerMemView::mousePressEvent(QMouseEvent* event)
void DebuggerMemView::addItemsToContextMenu(QMenu *menu)
{
const bool leftClick = event->button() == Qt::LeftButton;
const bool rightClick = event->button() == Qt::RightButton;
DebuggerView::addItemsToContextMenu(menu);
if (leftClick || rightClick)
if (view()->cursor_visible())
{
QFontMetrics actualFont = fontMetrics();
const double fontWidth = actualFont.horizontalAdvance(QString(100, '_')) / 100.;
const int fontHeight = std::max(1, actualFont.lineSpacing());
debug_view_xy topLeft = view()->visible_position();
debug_view_xy clickViewPosition;
clickViewPosition.x = topLeft.x + (event->x() / fontWidth);
clickViewPosition.y = topLeft.y + (event->y() / fontHeight);
if (leftClick)
debug_view_memory &memView = downcast<debug_view_memory &>(*view());
debug_view_memory_source const &source = downcast<debug_view_memory_source const &>(*memView.source());
address_space *const addressSpace = source.space();
if (addressSpace)
{
view()->process_click(DCK_LEFT_CLICK, clickViewPosition);
}
else if (rightClick)
{
// Display the last known PC to write to this memory location & copy it onto the clipboard
debug_view_memory* memView = downcast<debug_view_memory*>(view());
const offs_t address = memView->addressAtCursorPosition(clickViewPosition);
const debug_view_memory_source* source = downcast<const debug_view_memory_source*>(memView->source());
address_space* addressSpace = source->space();
// get the last known PC to write to this memory location
debug_view_xy const pos = view()->cursor_position();
offs_t const address = memView.addressAtCursorPosition(pos);
offs_t a = address & addressSpace->logaddrmask();
bool good = false;
if (!addressSpace->device().memory().translate(addressSpace->spacenum(), TRANSLATE_READ_DEBUG, a))
{
QToolTip::showText(QCursor::pos(), "Bad address", nullptr);
m_lastPc = "Bad address";
}
else
{
@ -366,46 +340,41 @@ void DebuggerMemView::mousePressEvent(QMouseEvent* event)
auto dis = addressSpace->device().machine().disable_side_effects();
switch (addressSpace->data_width())
{
case 8:
memValue = addressSpace->read_byte(a);
break;
case 16:
memValue = addressSpace->read_word_unaligned(a);
break;
case 32:
memValue = addressSpace->read_dword_unaligned(a);
break;
case 64:
memValue = addressSpace->read_qword_unaligned(a);
break;
case 8: memValue = addressSpace->read_byte(a); break;
case 16: memValue = addressSpace->read_word_unaligned(a); break;
case 32: memValue = addressSpace->read_dword_unaligned(a); break;
case 64: memValue = addressSpace->read_qword_unaligned(a); break;
}
const offs_t pc = source->device()->debug()->track_mem_pc_from_space_address_data(addressSpace->spacenum(),
offs_t const pc = source.device()->debug()->track_mem_pc_from_space_address_data(
addressSpace->spacenum(),
address,
memValue);
if (pc != (offs_t)(-1))
if (pc != offs_t(-1))
{
// TODO: You can specify a box that the tooltip stays alive within - might be good?
const QString addressAndPc = QString("Address %1 written at PC=%2").arg(address, 2, 16).arg(pc, 2, 16);
QToolTip::showText(QCursor::pos(), addressAndPc, nullptr);
// Copy the PC into the clipboard as well
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(QString("%1").arg(pc, 2, 16));
m_lastPc = QString("Address %1 written at PC=%2").arg(address, 2, 16).arg(pc, 2, 16);
good = true;
}
else
{
QToolTip::showText(QCursor::pos(), "UNKNOWN PC", nullptr);
m_lastPc = "Unknown PC";
}
}
if (!menu->isEmpty())
menu->addSeparator();
QAction *const act = new QAction(m_lastPc, menu);
act->setEnabled(good);
connect(act, &QAction::triggered, this, &DebuggerMemView::copyLastPc);
menu->addAction(act);
}
}
}
viewport()->update();
update();
}
void DebuggerMemView::copyLastPc()
{
QApplication::clipboard()->setText(m_lastPc);
}
@ -454,7 +423,8 @@ void MemoryWindowQtConfig::applyToQWidget(QWidget* widget)
memoryRegion->setCurrentIndex(m_memoryRegion);
QAction *reverse = window->findChild<QAction *>("reverse");
if (m_reverse) reverse->trigger();
if (m_reverse)
reverse->trigger();
QActionGroup *addressGroup = window->findChild<QActionGroup*>("addressgroup");
addressGroup->actions()[m_addressMode]->trigger();

View File

@ -1,14 +1,14 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#ifndef __DEBUG_QT_MEMORY_WINDOW_H__
#define __DEBUG_QT_MEMORY_WINDOW_H__
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QComboBox>
#ifndef MAME_DEBUGGER_QT_MEMORYWINDOW_H
#define MAME_DEBUGGER_QT_MEMORYWINDOW_H
#include "debuggerview.h"
#include "windowqt.h"
#include <QtWidgets/QComboBox>
#include <QtWidgets/QLineEdit>
class DebuggerMemView;
@ -20,10 +20,9 @@ class MemoryWindow : public WindowQt
Q_OBJECT
public:
MemoryWindow(running_machine* machine, QWidget* parent=nullptr);
MemoryWindow(running_machine &machine, QWidget *parent = nullptr);
virtual ~MemoryWindow();
private slots:
void memoryRegionChanged(int index);
void expressionSubmitted();
@ -33,14 +32,11 @@ private slots:
void increaseBytesPerLine(bool changedTo);
void decreaseBytesPerLine(bool checked = false);
private:
void populateComboBox();
void setToCurrentCpu();
QAction *dataFormatMenuItem(const QString &itemName);
private:
// Widgets
QLineEdit *m_inputEdit;
QComboBox *m_memoryComboBox;
@ -53,16 +49,23 @@ private:
//=========================================================================
class DebuggerMemView : public DebuggerView
{
Q_OBJECT
public:
DebuggerMemView(const debug_view_type& type,
running_machine* machine,
QWidget* parent=nullptr)
DebuggerMemView(const debug_view_type& type, running_machine &machine, QWidget *parent = nullptr)
: DebuggerView(type, machine, parent)
{}
virtual ~DebuggerMemView() {}
protected:
void mousePressEvent(QMouseEvent* event);
virtual void addItemsToContextMenu(QMenu *menu) override;
private slots:
void copyLastPc();
private:
QString m_lastPc;
};
@ -96,4 +99,4 @@ public:
};
#endif
#endif // MAME_DEBUGGER_QT_MEMORYWINDOW_H

View File

@ -1,19 +1,20 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#include "emu.h"
#include "windowqt.h"
#include "breakpointswindow.h"
#include "dasmwindow.h"
#include "deviceswindow.h"
#include "logwindow.h"
#include "memorywindow.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
#include "windowqt.h"
#include "logwindow.h"
#include "dasmwindow.h"
#include "memorywindow.h"
#include "breakpointswindow.h"
#include "deviceswindow.h"
#include "debug/debugcpu.h"
#include "debug/debugcon.h"
bool WindowQt::s_refreshAll = false;
bool WindowQt::s_hideAll = false;
@ -23,7 +24,7 @@ bool WindowQt::s_hideAll = false;
// however, is often used to place each child window & the code to do this can
// be found in most of the inherited classes.
WindowQt::WindowQt(running_machine* machine, QWidget* parent) :
WindowQt::WindowQt(running_machine &machine, QWidget *parent) :
QMainWindow(parent),
m_machine(machine)
{
@ -180,54 +181,54 @@ void WindowQt::debugActOpenDevices()
void WindowQt::debugActRun()
{
m_machine->debugger().console().get_visible_cpu()->debug()->go();
m_machine.debugger().console().get_visible_cpu()->debug()->go();
}
void WindowQt::debugActRunAndHide()
{
m_machine->debugger().console().get_visible_cpu()->debug()->go();
m_machine.debugger().console().get_visible_cpu()->debug()->go();
hideAll();
}
void WindowQt::debugActRunToNextCpu()
{
m_machine->debugger().console().get_visible_cpu()->debug()->go_next_device();
m_machine.debugger().console().get_visible_cpu()->debug()->go_next_device();
}
void WindowQt::debugActRunNextInt()
{
m_machine->debugger().console().get_visible_cpu()->debug()->go_interrupt();
m_machine.debugger().console().get_visible_cpu()->debug()->go_interrupt();
}
void WindowQt::debugActRunNextVBlank()
{
m_machine->debugger().console().get_visible_cpu()->debug()->go_vblank();
m_machine.debugger().console().get_visible_cpu()->debug()->go_vblank();
}
void WindowQt::debugActStepInto()
{
m_machine->debugger().console().get_visible_cpu()->debug()->single_step();
m_machine.debugger().console().get_visible_cpu()->debug()->single_step();
}
void WindowQt::debugActStepOver()
{
m_machine->debugger().console().get_visible_cpu()->debug()->single_step_over();
m_machine.debugger().console().get_visible_cpu()->debug()->single_step_over();
}
void WindowQt::debugActStepOut()
{
m_machine->debugger().console().get_visible_cpu()->debug()->single_step_out();
m_machine.debugger().console().get_visible_cpu()->debug()->single_step_out();
}
void WindowQt::debugActSoftReset()
{
m_machine->schedule_soft_reset();
m_machine->debugger().console().get_visible_cpu()->debug()->single_step();
m_machine.schedule_soft_reset();
m_machine.debugger().console().get_visible_cpu()->debug()->single_step();
}
void WindowQt::debugActHardReset()
{
m_machine->schedule_hard_reset();
m_machine.schedule_hard_reset();
}
void WindowQt::debugActClose()
@ -237,7 +238,7 @@ void WindowQt::debugActClose()
void WindowQt::debugActQuit()
{
m_machine->schedule_exit();
m_machine.schedule_exit();
}

View File

@ -1,13 +1,13 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#ifndef __DEBUG_QT_WINDOW_QT_H__
#define __DEBUG_QT_WINDOW_QT_H__
#include <QtWidgets/QMainWindow>
#ifndef MAME_DEBUGGER_QT_WINDOWQT_H
#define MAME_DEBUGGER_QT_WINDOWQT_H
#include "config.h"
#include "debugger.h"
#include <QtWidgets/QMainWindow>
//============================================================
// The Qt window that everyone derives from.
@ -17,7 +17,7 @@ class WindowQt : public QMainWindow
Q_OBJECT
public:
WindowQt(running_machine* machine, QWidget* parent=nullptr);
WindowQt(running_machine &machine, QWidget *parent = nullptr);
virtual ~WindowQt();
// The interface to an all-window refresh
@ -51,7 +51,7 @@ protected slots:
protected:
running_machine* m_machine;
running_machine &m_machine;
static bool s_refreshAll;
static bool s_hideAll;
@ -96,4 +96,4 @@ public:
};
#endif
#endif // MAME_DEBUGGER_QT_WINDOWQT_H