diff options
Diffstat (limited to 'src/osd')
-rw-r--r-- | src/osd/sdl/debugqtmainwindow.c | 510 | ||||
-rw-r--r-- | src/osd/sdl/debugqtview.c | 382 | ||||
-rw-r--r-- | src/osd/sdl/debugqtview.h | 35 | ||||
-rw-r--r-- | src/osd/sdl/sdl.mak | 1 |
4 files changed, 492 insertions, 436 deletions
diff --git a/src/osd/sdl/debugqtmainwindow.c b/src/osd/sdl/debugqtmainwindow.c index d92bed9c88c..56ff9ed991d 100644 --- a/src/osd/sdl/debugqtmainwindow.c +++ b/src/osd/sdl/debugqtmainwindow.c @@ -4,299 +4,305 @@ #include "debug/dvdisasm.h" -MainWindow::MainWindow(device_t* processor, - running_machine* machine, - QWidget* parent) : - WindowQt(machine, parent), - m_historyIndex(0), - m_inputHistory() +MainWindow::MainWindow(device_t* processor, + running_machine* machine, + QWidget* parent) : + WindowQt(machine, parent), + m_historyIndex(0), + m_inputHistory() { - setGeometry(300, 300, 1000, 600); - - // - // The main frame and its input and log widgets - // - QFrame* mainWindowFrame = new QFrame(this); - - // The input line - m_inputEdit = new QLineEdit(mainWindowFrame); - connect(m_inputEdit, SIGNAL(returnPressed()), this, SLOT(executeCommand())); - m_inputEdit->installEventFilter(this); - - - // The log view - m_consoleView = new DebuggerView(DVT_CONSOLE, - m_machine, - mainWindowFrame); - m_consoleView->setFocusPolicy(Qt::NoFocus); - m_consoleView->setPreferBottom(true); - - QVBoxLayout* vLayout = new QVBoxLayout(mainWindowFrame); - vLayout->addWidget(m_consoleView); - vLayout->addWidget(m_inputEdit); - vLayout->setSpacing(3); - vLayout->setContentsMargins(4,0,4,2); - - setCentralWidget(mainWindowFrame); - - // - // Menu bars - // - // Create two commands - QAction* breakpointSetAct = new QAction("Toggle Breakpoint At Cursor", this); - QAction* runToCursorAct = new QAction("Run To Cursor", this); - breakpointSetAct->setShortcut(Qt::Key_F9); - runToCursorAct->setShortcut(Qt::Key_F4); - connect(breakpointSetAct, SIGNAL(triggered(bool)), this, SLOT(toggleBreakpointAtCursor(bool))); - connect(runToCursorAct, SIGNAL(triggered(bool)), this, SLOT(runToCursor(bool))); - - // Right bar options - QActionGroup* rightBarGroup = new QActionGroup(this); - QAction* rightActRaw = new QAction("Raw Opcodes", this); - QAction* rightActEncrypted = new QAction("Encrypted Opcodes", this); - QAction* rightActComments = new QAction("Comments", this); - rightActRaw->setCheckable(true); - rightActEncrypted->setCheckable(true); - rightActComments->setCheckable(true); - rightActRaw->setActionGroup(rightBarGroup); - rightActEncrypted->setActionGroup(rightBarGroup); - rightActComments->setActionGroup(rightBarGroup); - rightActRaw->setShortcut(QKeySequence("Ctrl+R")); - rightActEncrypted->setShortcut(QKeySequence("Ctrl+E")); - rightActComments->setShortcut(QKeySequence("Ctrl+C")); - rightActRaw->setChecked(true); - connect(rightBarGroup, SIGNAL(triggered(QAction*)), this, SLOT(rightBarChanged(QAction*))); - - // Assemble the options menu - QMenu* optionsMenu = menuBar()->addMenu("&Options"); - optionsMenu->addAction(breakpointSetAct); - optionsMenu->addAction(runToCursorAct); - optionsMenu->addSeparator(); - optionsMenu->addActions(rightBarGroup->actions()); - - - // - // Dock windows - // - QMenu* dockMenu = menuBar()->addMenu("Doc&ks"); - - setCorner(Qt::TopRightCorner, Qt::TopDockWidgetArea); - setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); - - // The processor dock - QDockWidget* cpuDock = new QDockWidget("processor", this); - cpuDock->setAllowedAreas(Qt::LeftDockWidgetArea); - m_procFrame = new ProcessorDockWidget(m_machine, cpuDock); - cpuDock->setWidget(dynamic_cast<QWidget*>(m_procFrame)); - - addDockWidget(Qt::LeftDockWidgetArea, cpuDock); - dockMenu->addAction(cpuDock->toggleViewAction()); - - // The disassembly dock - QDockWidget* dasmDock = new QDockWidget("dasm", this); - dasmDock->setAllowedAreas(Qt::TopDockWidgetArea); - m_dasmFrame = new DasmDockWidget(m_machine, dasmDock); - dasmDock->setWidget(m_dasmFrame); - - 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()); + setGeometry(300, 300, 1000, 600); + + // + // The main frame and its input and log widgets + // + QFrame* mainWindowFrame = new QFrame(this); + + // The input line + m_inputEdit = new QLineEdit(mainWindowFrame); + connect(m_inputEdit, SIGNAL(returnPressed()), this, SLOT(executeCommand())); + m_inputEdit->installEventFilter(this); + + + // The log view + m_consoleView = new DebuggerView(DVT_CONSOLE, + m_machine, + mainWindowFrame); + m_consoleView->setFocusPolicy(Qt::NoFocus); + m_consoleView->setPreferBottom(true); + + QVBoxLayout* vLayout = new QVBoxLayout(mainWindowFrame); + vLayout->addWidget(m_consoleView); + vLayout->addWidget(m_inputEdit); + vLayout->setSpacing(3); + vLayout->setContentsMargins(4,0,4,2); + + setCentralWidget(mainWindowFrame); + + // + // Menu bars + // + // Create two commands + QAction* breakpointSetAct = new QAction("Toggle Breakpoint At Cursor", this); + QAction* runToCursorAct = new QAction("Run To Cursor", this); + breakpointSetAct->setShortcut(Qt::Key_F9); + runToCursorAct->setShortcut(Qt::Key_F4); + connect(breakpointSetAct, SIGNAL(triggered(bool)), this, SLOT(toggleBreakpointAtCursor(bool))); + connect(runToCursorAct, SIGNAL(triggered(bool)), this, SLOT(runToCursor(bool))); + + // Right bar options + QActionGroup* rightBarGroup = new QActionGroup(this); + QAction* rightActRaw = new QAction("Raw Opcodes", this); + QAction* rightActEncrypted = new QAction("Encrypted Opcodes", this); + QAction* rightActComments = new QAction("Comments", this); + rightActRaw->setCheckable(true); + rightActEncrypted->setCheckable(true); + rightActComments->setCheckable(true); + rightActRaw->setActionGroup(rightBarGroup); + rightActEncrypted->setActionGroup(rightBarGroup); + rightActComments->setActionGroup(rightBarGroup); + rightActRaw->setShortcut(QKeySequence("Ctrl+R")); + rightActEncrypted->setShortcut(QKeySequence("Ctrl+E")); + rightActComments->setShortcut(QKeySequence("Ctrl+C")); + rightActRaw->setChecked(true); + connect(rightBarGroup, SIGNAL(triggered(QAction*)), this, SLOT(rightBarChanged(QAction*))); + + // Assemble the options menu + QMenu* optionsMenu = menuBar()->addMenu("&Options"); + optionsMenu->addAction(breakpointSetAct); + optionsMenu->addAction(runToCursorAct); + optionsMenu->addSeparator(); + optionsMenu->addActions(rightBarGroup->actions()); + + + // + // Dock windows + // + QMenu* dockMenu = menuBar()->addMenu("Doc&ks"); + + setCorner(Qt::TopRightCorner, Qt::TopDockWidgetArea); + setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); + + // The processor dock + QDockWidget* cpuDock = new QDockWidget("processor", this); + cpuDock->setAllowedAreas(Qt::LeftDockWidgetArea); + m_procFrame = new ProcessorDockWidget(m_machine, cpuDock); + cpuDock->setWidget(dynamic_cast<QWidget*>(m_procFrame)); + + addDockWidget(Qt::LeftDockWidgetArea, cpuDock); + dockMenu->addAction(cpuDock->toggleViewAction()); + + // The disassembly dock + QDockWidget* dasmDock = new QDockWidget("dasm", this); + dasmDock->setAllowedAreas(Qt::TopDockWidgetArea); + m_dasmFrame = new DasmDockWidget(m_machine, dasmDock); + dasmDock->setWidget(m_dasmFrame); + + 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()); } void MainWindow::setProcessor(device_t* processor) { - // Cpu swap - m_procFrame->view()->view()->set_source(*m_procFrame->view()->view()->source_list().match_device(processor)); - m_dasmFrame->view()->view()->set_source(*m_dasmFrame->view()->view()->source_list().match_device(processor)); - - // Scrollbar refresh - seems I should be able to do in the DebuggerView - m_dasmFrame->view()->verticalScrollBar()->setValue(m_dasmFrame->view()->view()->visible_position().y); - m_dasmFrame->view()->verticalScrollBar()->setValue(m_dasmFrame->view()->view()->visible_position().y); - - // Window title - astring title; - title.printf("Debug: %s - %s '%s'", m_machine->system().name, processor->name(), processor->tag()); - setWindowTitle(title.cstr()); + // Cpu swap + m_procFrame->view()->view()->set_source(*m_procFrame->view()->view()->source_list().match_device(processor)); + m_dasmFrame->view()->view()->set_source(*m_dasmFrame->view()->view()->source_list().match_device(processor)); + + // Scrollbar refresh - seems I should be able to do in the DebuggerView + m_dasmFrame->view()->verticalScrollBar()->setValue(m_dasmFrame->view()->view()->visible_position().y); + m_dasmFrame->view()->verticalScrollBar()->setValue(m_dasmFrame->view()->view()->visible_position().y); + + // Window title + astring title; + title.printf("Debug: %s - %s '%s'", m_machine->system().name, processor->name(), processor->tag()); + setWindowTitle(title.cstr()); } // Used to intercept the user clicking 'X' in the upper corner void MainWindow::closeEvent(QCloseEvent* event) { - debugActQuit(); + debugActQuit(); } // Used to intercept the user hitting the up arrow in the input widget bool MainWindow::eventFilter(QObject* obj, QEvent* event) { - // Only filter keypresses - QKeyEvent* keyEvent = NULL; - 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) - { - if (keyEvent->key() == Qt::Key_Up) - { - if (m_historyIndex > 0) - m_historyIndex--; - } - else if (keyEvent->key() == Qt::Key_Down) - { - if (m_historyIndex < m_inputHistory.size()) - m_historyIndex++; - } - - // Populate the input edit or clear it if you're at the end - if (m_historyIndex == m_inputHistory.size()) - { - m_inputEdit->setText(""); - } - else - { - m_inputEdit->setText(m_inputHistory[m_historyIndex]); - } - } - else if (keyEvent->key() == Qt::Key_Enter) - { - executeCommand(false); - } - else - { - return QObject::eventFilter(obj, event); - } - - return true; + // Only filter keypresses + QKeyEvent* keyEvent = NULL; + 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) + { + if (keyEvent->key() == Qt::Key_Up) + { + if (m_historyIndex > 0) + m_historyIndex--; + } + else if (keyEvent->key() == Qt::Key_Down) + { + if (m_historyIndex < m_inputHistory.size()) + m_historyIndex++; + } + + // Populate the input edit or clear it if you're at the end + if (m_historyIndex == m_inputHistory.size()) + { + m_inputEdit->setText(""); + } + else + { + m_inputEdit->setText(m_inputHistory[m_historyIndex]); + } + } + else if (keyEvent->key() == Qt::Key_Enter) + { + executeCommand(false); + } + else + { + return QObject::eventFilter(obj, event); + } + + return true; } void MainWindow::toggleBreakpointAtCursor(bool changedTo) { - debug_view_disasm* dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view()); - if (dasmView->cursor_visible()) - { - if (debug_cpu_get_visible_cpu(*m_machine) == dasmView->source()->device()) - { - offs_t address = downcast<debug_view_disasm *>(dasmView)->selected_address(); - device_debug *cpuinfo = dasmView->source()->device()->debug(); - - // Find an existing breakpoint at this address - INT32 bpindex = -1; - for (device_debug::breakpoint* bp = cpuinfo->breakpoint_first(); - bp != NULL; - bp = bp->next()) - { - if (address == bp->address()) - { - bpindex = bp->index(); - break; - } - } - - // If none exists, add a new one - astring command; - if (bpindex == -1) - { - command.printf("bpset 0x%X", address); - } - else - { - command.printf("bpclear 0x%X", bpindex); - } - debug_console_execute_command(*m_machine, command, 1); - } - } - - refreshAll(); + debug_view_disasm* dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view()); + if (dasmView->cursor_visible()) + { + if (debug_cpu_get_visible_cpu(*m_machine) == dasmView->source()->device()) + { + offs_t address = downcast<debug_view_disasm *>(dasmView)->selected_address(); + device_debug *cpuinfo = dasmView->source()->device()->debug(); + + // Find an existing breakpoint at this address + INT32 bpindex = -1; + for (device_debug::breakpoint* bp = cpuinfo->breakpoint_first(); + bp != NULL; + bp = bp->next()) + { + if (address == bp->address()) + { + bpindex = bp->index(); + break; + } + } + + // If none exists, add a new one + astring command; + if (bpindex == -1) + { + command.printf("bpset 0x%X", address); + } + else + { + command.printf("bpclear 0x%X", bpindex); + } + debug_console_execute_command(*m_machine, command, 1); + } + } + + refreshAll(); } void MainWindow::runToCursor(bool changedTo) { - debug_view_disasm* dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view()); - if (dasmView->cursor_visible()) - { - if (debug_cpu_get_visible_cpu(*m_machine) == dasmView->source()->device()) - { - offs_t address = downcast<debug_view_disasm*>(dasmView)->selected_address(); - astring command; - command.printf("go 0x%X", address); - debug_console_execute_command(*m_machine, command, 1); - } - } + debug_view_disasm* dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view()); + if (dasmView->cursor_visible()) + { + if (debug_cpu_get_visible_cpu(*m_machine) == dasmView->source()->device()) + { + offs_t address = downcast<debug_view_disasm*>(dasmView)->selected_address(); + astring command; + command.printf("go 0x%X", address); + debug_console_execute_command(*m_machine, command, 1); + } + } } 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(); + 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(); } void MainWindow::executeCommand(bool withClear) { - debug_console_execute_command(*m_machine, - m_inputEdit->text().toLocal8Bit().data(), - true); - - // Add history & set the index to be the top of the stack - addToHistory(m_inputEdit->text()); - - // Clear out the text and reset the history pointer only if asked - if (withClear) - { - m_inputEdit->clear(); - m_historyIndex = m_inputHistory.size(); - } - - // Refresh - m_consoleView->viewport()->update(); - m_procFrame->view()->update(); - m_dasmFrame->view()->update(); + if (m_inputEdit->text() == "") + { + debug_cpu_get_visible_cpu(*m_machine)->debug()->single_step(); + return; + } + + debug_console_execute_command(*m_machine, + m_inputEdit->text().toLocal8Bit().data(), + true); + + // Add history & set the index to be the top of the stack + addToHistory(m_inputEdit->text()); + + // Clear out the text and reset the history pointer only if asked + if (withClear) + { + m_inputEdit->clear(); + m_historyIndex = m_inputHistory.size(); + } + + // Refresh + m_consoleView->viewport()->update(); + m_procFrame->view()->update(); + m_dasmFrame->view()->update(); } void MainWindow::addToHistory(const QString& command) { - if (command == "") - return; - - // Always push back when there is no previous history - if (m_inputHistory.size() == 0) - { - m_inputHistory.push_back(m_inputEdit->text()); - return; - } - - // 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()); - } + if (command == "") + return; + + // Always push back when there is no previous history + if (m_inputHistory.size() == 0) + { + m_inputHistory.push_back(m_inputEdit->text()); + return; + } + + // 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()); + } } diff --git a/src/osd/sdl/debugqtview.c b/src/osd/sdl/debugqtview.c index 9e0a072085f..c809e5e7953 100644 --- a/src/osd/sdl/debugqtview.c +++ b/src/osd/sdl/debugqtview.c @@ -3,197 +3,239 @@ #include "debugqtview.h" -DebuggerView::DebuggerView(const debug_view_type& type, - running_machine* machine, - QWidget* parent) : - QAbstractScrollArea(parent), - m_preferBottom(false), - m_view(NULL), - m_machine(machine) +DebuggerView::DebuggerView(const debug_view_type& type, + running_machine* machine, + QWidget* parent) : + QAbstractScrollArea(parent), + m_preferBottom(false), + m_view(NULL), + m_machine(machine) { - QFont viewFontRequest("Courier"); - viewFontRequest.setFixedPitch(true); - viewFontRequest.setPointSize(12); - setFont(viewFontRequest); - - m_view = m_machine->debug_view().alloc_view(type, - DebuggerView::debuggerViewUpdate, - this); + // I like setting the font per-view since it doesn't override the menuing fonts. + QFont viewFontRequest("Courier New"); + viewFontRequest.setFixedPitch(true); + viewFontRequest.setPointSize(11); + setFont(viewFontRequest); + + m_view = m_machine->debug_view().alloc_view(type, + DebuggerView::debuggerViewUpdate, + this); + + connect(verticalScrollBar(), SIGNAL(valueChanged(int)), + this, SLOT(verticalScrollSlot(int))); + connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), + this, SLOT(horizontalScrollSlot(int))); } void DebuggerView::paintEvent(QPaintEvent* event) { - // Tell the MAME debug view how much real estate is available - QFontMetrics actualFont = fontMetrics(); - const int fontWidth = MAX(1, actualFont.maxWidth()); - const int fontHeight = MAX(1, actualFont.height()); - m_view->set_visible_size(debug_view_xy(width()/fontWidth, height()/fontHeight)); - - - // Handle the scroll bars - const int verticalScrollCharDiff = m_view->total_size().y - m_view->visible_size().y; - const int scrollSize = verticalScrollCharDiff < 0 ? 0 : verticalScrollCharDiff; - bool atEnd = false; - if (verticalScrollBar()->value() == verticalScrollBar()->maximum()) - { - atEnd = true; - } - verticalScrollBar()->setRange(0, scrollSize); - if (m_preferBottom && atEnd) - { - verticalScrollBar()->setValue(scrollSize); - } - m_view->set_visible_position(debug_view_xy(0, verticalScrollBar()->value())); - - - // Draw the viewport widget - QPainter painter(viewport()); - painter.fillRect(0, 0, width(), height(), QBrush(Qt::white)); - painter.setBackgroundMode(Qt::OpaqueMode); - painter.setBackground(QColor(255,255,255)); - - // Background control - QBrush bgBrush; - bgBrush.setStyle(Qt::SolidPattern); - painter.setPen(QPen(QColor(0,0,0))); - - size_t viewDataOffset = 0; - const debug_view_xy& visibleCharDims = m_view->visible_size(); - for (int y = 0; y < visibleCharDims.y; y++) - { - for (int x = 0; x < visibleCharDims.x; x++) - { - const unsigned char textAttr = m_view->viewdata()[viewDataOffset].attrib; - - if (x == 0 || textAttr != m_view->viewdata()[viewDataOffset-1].attrib) - { - // Text color handling - QColor fgColor(0,0,0); - QColor bgColor(255,255,255); - - 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_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.green() + bgColor.green()) >> 1, - (fgColor.blue() + bgColor.blue()) >> 1); - } - if(textAttr & DCA_COMMENT) - { - fgColor.setRgb(0x00, 0x80, 0x00); - } - - bgBrush.setColor(bgColor); - painter.setBackground(bgBrush); - painter.setPen(QPen(fgColor)); - } - - // There is a touchy interplay between font height, drawing difference, visible position, etc - // To test, set the bgcolor to something crazy and see where stuff gets drawn - painter.drawText(x*fontWidth, - y*fontHeight + fontHeight, - QString(m_view->viewdata()[viewDataOffset].byte)); - viewDataOffset++; - } - } + // Tell the MAME debug view how much real estate is available + QFontMetrics actualFont = fontMetrics(); + const int fontWidth = MAX(1, actualFont.maxWidth()); + const int fontHeight = MAX(1, actualFont.height()); + m_view->set_visible_size(debug_view_xy(width()/fontWidth, height()/fontHeight)); + + + // Handle the scroll bars + const int verticalScrollCharDiff = m_view->total_size().y - m_view->visible_size().y; + const int scrollSize = verticalScrollCharDiff < 0 ? 0 : verticalScrollCharDiff; + bool atEnd = false; + if (verticalScrollBar()->value() == verticalScrollBar()->maximum()) + { + atEnd = true; + } + verticalScrollBar()->setRange(0, scrollSize); + if (m_preferBottom && atEnd) + { + verticalScrollBar()->setValue(scrollSize); + } + + + // Draw the viewport widget + QPainter painter(viewport()); + painter.fillRect(0, 0, width(), height(), QBrush(Qt::white)); + painter.setBackgroundMode(Qt::OpaqueMode); + painter.setBackground(QColor(255,255,255)); + + // Background control + QBrush bgBrush; + bgBrush.setStyle(Qt::SolidPattern); + painter.setPen(QPen(QColor(0,0,0))); + + size_t viewDataOffset = 0; + const debug_view_xy& visibleCharDims = m_view->visible_size(); + for (int y = 0; y < visibleCharDims.y; y++) + { + for (int x = 0; x < visibleCharDims.x; x++) + { + const unsigned char textAttr = m_view->viewdata()[viewDataOffset].attrib; + + if (x == 0 || textAttr != m_view->viewdata()[viewDataOffset-1].attrib) + { + // Text color handling + QColor fgColor(0,0,0); + QColor bgColor(255,255,255); + + 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_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.green() + bgColor.green()) >> 1, + (fgColor.blue() + bgColor.blue()) >> 1); + } + if(textAttr & DCA_COMMENT) + { + fgColor.setRgb(0x00, 0x80, 0x00); + } + + bgBrush.setColor(bgColor); + painter.setBackground(bgBrush); + painter.setPen(QPen(fgColor)); + } + + // Your character is not guaranteed to take up the entire fontWidth x fontHeight, so fill before. + painter.fillRect(x*fontWidth, y*fontHeight, fontWidth, fontHeight, bgBrush); + + // There is a touchy interplay between font height, drawing difference, visible position, etc + // Fonts don't get drawn "down and to the left" like boxes, so some wiggling is needed. + painter.drawText(x*fontWidth, + (y*fontHeight + (fontHeight*0.80)), + QString(m_view->viewdata()[viewDataOffset].byte)); + viewDataOffset++; + } + } } void DebuggerView::keyPressEvent(QKeyEvent* event) { - if (m_view == NULL) - return QWidget::keyPressEvent(event); + if (m_view == NULL) + return QWidget::keyPressEvent(event); + + Qt::KeyboardModifiers keyMods = QApplication::keyboardModifiers(); + const bool ctrlDown = keyMods.testFlag(Qt::ControlModifier); + + int keyPress = -1; + switch (event->key()) + { + case Qt::Key_Up: + keyPress = DCH_UP; + break; + case Qt::Key_Down: + keyPress = DCH_DOWN; + break; + case Qt::Key_Left: + keyPress = DCH_LEFT; + if (ctrlDown) keyPress = DCH_CTRLLEFT; + break; + case Qt::Key_Right: + keyPress = DCH_RIGHT; + if (ctrlDown) keyPress = DCH_CTRLRIGHT; + break; + case Qt::Key_PageUp: + keyPress = DCH_PUP; + break; + case Qt::Key_PageDown: + keyPress = DCH_PDOWN; + break; + case Qt::Key_Home: + keyPress = DCH_HOME; + if (ctrlDown) keyPress = DCH_CTRLHOME; + break; + case Qt::Key_End: + keyPress = DCH_END; + if (ctrlDown) keyPress = DCH_CTRLEND; + break; + case Qt::Key_0: keyPress = '0'; break; + case Qt::Key_1: keyPress = '1'; break; + case Qt::Key_2: keyPress = '2'; break; + case Qt::Key_3: keyPress = '3'; break; + case Qt::Key_4: keyPress = '4'; break; + case Qt::Key_5: keyPress = '5'; break; + case Qt::Key_6: keyPress = '6'; break; + case Qt::Key_7: keyPress = '7'; break; + case Qt::Key_8: keyPress = '8'; break; + case Qt::Key_9: keyPress = '9'; break; + case Qt::Key_A: keyPress = 'a'; break; + case Qt::Key_B: keyPress = 'b'; break; + case Qt::Key_C: keyPress = 'c'; break; + case Qt::Key_D: keyPress = 'd'; break; + case Qt::Key_E: keyPress = 'e'; break; + case Qt::Key_F: keyPress = 'f'; break; + default: + return QWidget::keyPressEvent(event); + } + + m_view->set_cursor_visible(true); + m_view->process_char(keyPress); + + // Catch the view up with the cursor + verticalScrollBar()->setValue(m_view->visible_position().y); + + viewport()->update(); + update(); +} - Qt::KeyboardModifiers keyMods = QApplication::keyboardModifiers(); - bool ctrlDown = keyMods.testFlag(Qt::ControlModifier); - int keyPress = -1; - switch (event->key()) +void DebuggerView::mousePressEvent(QMouseEvent* event) +{ + if (event->button() == Qt::LeftButton) { - case Qt::Key_Up: - keyPress = DCH_UP; - break; - case Qt::Key_Down: - keyPress = DCH_DOWN; - break; - case Qt::Key_Left: - keyPress = DCH_LEFT; - if (ctrlDown) keyPress = DCH_CTRLLEFT; - break; - case Qt::Key_Right: - keyPress = DCH_RIGHT; - if (ctrlDown) keyPress = DCH_CTRLRIGHT; - break; - case Qt::Key_PageUp: - keyPress = DCH_PUP; - break; - case Qt::Key_PageDown: - keyPress = DCH_PDOWN; - break; - case Qt::Key_Home: - keyPress = DCH_HOME; - if (ctrlDown) keyPress = DCH_CTRLHOME; - break; - case Qt::Key_End: - keyPress = DCH_END; - if (ctrlDown) keyPress = DCH_CTRLEND; - break; - case Qt::Key_0: keyPress = '0'; break; - case Qt::Key_1: keyPress = '1'; break; - case Qt::Key_2: keyPress = '2'; break; - case Qt::Key_3: keyPress = '3'; break; - case Qt::Key_4: keyPress = '4'; break; - case Qt::Key_5: keyPress = '5'; break; - case Qt::Key_6: keyPress = '6'; break; - case Qt::Key_7: keyPress = '7'; break; - case Qt::Key_8: keyPress = '8'; break; - case Qt::Key_9: keyPress = '9'; break; - case Qt::Key_A: keyPress = 'a'; break; - case Qt::Key_B: keyPress = 'b'; break; - case Qt::Key_C: keyPress = 'c'; break; - case Qt::Key_D: keyPress = 'd'; break; - case Qt::Key_E: keyPress = 'e'; break; - case Qt::Key_F: keyPress = 'f'; break; - default: - return QWidget::keyPressEvent(event); + QFontMetrics actualFont = fontMetrics(); + const int fontWidth = MAX(1, actualFont.maxWidth()); + const int fontHeight = MAX(1, actualFont.height()); + + debug_view_xy topLeft = m_view->visible_position(); + debug_view_xy clickViewPosition; + clickViewPosition.x = topLeft.x + (event->x() / fontWidth); + clickViewPosition.y = topLeft.y + (event->y() / fontHeight); + m_view->process_click(DCK_LEFT_CLICK, clickViewPosition); + + viewport()->update(); + update(); } +} - m_view->set_cursor_visible(true); - m_view->process_char(keyPress); - // Catch the view up with the cursor - verticalScrollBar()->setValue(m_view->visible_position().y); +void DebuggerView::verticalScrollSlot(int value) +{ + m_view->set_visible_position(debug_view_xy(horizontalScrollBar()->value(), value)); +} - viewport()->update(); - update(); + +void DebuggerView::horizontalScrollSlot(int value) +{ + m_view->set_visible_position(debug_view_xy(value, verticalScrollBar()->value())); } void DebuggerView::debuggerViewUpdate(debug_view& debugView, void* osdPrivate) { - // Get a handle to the DebuggerView being updated & redraw - DebuggerView* dView = (DebuggerView*)osdPrivate; - dView->verticalScrollBar()->setValue(dView->view()->visible_position().y); - dView->viewport()->update(); - dView->update(); + // Get a handle to the DebuggerView being updated & redraw + DebuggerView* dView = (DebuggerView*)osdPrivate; + dView->verticalScrollBar()->setValue(dView->view()->visible_position().y); + dView->viewport()->update(); + dView->update(); } + + diff --git a/src/osd/sdl/debugqtview.h b/src/osd/sdl/debugqtview.h index 5deab206dc7..1e926949114 100644 --- a/src/osd/sdl/debugqtview.h +++ b/src/osd/sdl/debugqtview.h @@ -8,31 +8,38 @@ class DebuggerView : public QAbstractScrollArea { + Q_OBJECT + public: - DebuggerView(const debug_view_type& type, - running_machine* machine, - QWidget* parent=NULL); - virtual ~DebuggerView() {} + DebuggerView(const debug_view_type& type, + running_machine* machine, + QWidget* parent=NULL); + virtual ~DebuggerView() {} - void paintEvent(QPaintEvent* event); + void paintEvent(QPaintEvent* event); - // Callback to allow MAME to refresh the view - static void debuggerViewUpdate(debug_view& debugView, void* osdPrivate); + // Callback to allow MAME to refresh the view + static void debuggerViewUpdate(debug_view& debugView, void* osdPrivate); - // Setters and accessors - void setPreferBottom(bool pb) { m_preferBottom = pb; } - debug_view* view() { return m_view; } + // Setters and accessors + void setPreferBottom(bool pb) { m_preferBottom = pb; } + debug_view* view() { return m_view; } protected: - void keyPressEvent(QKeyEvent* event); + void keyPressEvent(QKeyEvent* event); + void mousePressEvent(QMouseEvent* event); + +private slots: + void verticalScrollSlot(int value); + void horizontalScrollSlot(int value); private: - bool m_preferBottom; + bool m_preferBottom; - debug_view* m_view; - running_machine* m_machine; + debug_view* m_view; + running_machine* m_machine; }; diff --git a/src/osd/sdl/sdl.mak b/src/osd/sdl/sdl.mak index 831022a1ee3..b899cb97329 100644 --- a/src/osd/sdl/sdl.mak +++ b/src/osd/sdl/sdl.mak @@ -635,6 +635,7 @@ DEBUGOBJS = \ $(SDLOBJ)/debugqtdasmwindow.o \ $(SDLOBJ)/debugqtmainwindow.o \ $(SDLOBJ)/debugqtmemorywindow.o \ + $(SDLOBJ)/debugqtview.moc.o \ $(SDLOBJ)/debugqtwindow.moc.o \ $(SDLOBJ)/debugqtlogwindow.moc.o \ $(SDLOBJ)/debugqtdasmwindow.moc.o \ |