From 7dab1976f643b1f5f3ae740da0331d1150978c53 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 13 Nov 2020 10:44:09 -0500 Subject: [PATCH 1/4] Added text copy/paste functionality via Qt clipboard to Qt debugger ASM viewer. --- src/drivers/Qt/ConsoleDebugger.cpp | 247 ++++++++++++++++++++++++++++- src/drivers/Qt/ConsoleDebugger.h | 15 ++ 2 files changed, 256 insertions(+), 6 deletions(-) diff --git a/src/drivers/Qt/ConsoleDebugger.cpp b/src/drivers/Qt/ConsoleDebugger.cpp index 8aa2deb0..fe02da9d 100644 --- a/src/drivers/Qt/ConsoleDebugger.cpp +++ b/src/drivers/Qt/ConsoleDebugger.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "../../types.h" #include "../../fceu.h" @@ -2817,6 +2818,13 @@ QAsmView::QAsmView(QWidget *parent) maxLineOffset = 0; ctxMenuAddr = -1; + mouseLeftBtnDown = false; + txtHlgtStartChar = -1; + txtHlgtStartLine = -1; + txtHlgtEndChar = -1; + txtHlgtEndLine = -1; + + selAddrLine = -1; selAddrChar = 0; selAddrWidth = 0; @@ -2825,6 +2833,12 @@ QAsmView::QAsmView(QWidget *parent) //setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Expanding ); setFocusPolicy(Qt::StrongFocus); + + clipboard = QGuiApplication::clipboard(); + + //printf("clipboard->supportsSelection() : '%i' \n", clipboard->supportsSelection() ); + //printf("clipboard->supportsFindBuffer(): '%i' \n", clipboard->supportsFindBuffer() ); + } //---------------------------------------------------------------------------- QAsmView::~QAsmView(void) @@ -3015,15 +3029,78 @@ QPoint QAsmView::convPixToCursor( QPoint p ) return c; } //---------------------------------------------------------------------------- +bool QAsmView::textIsHighlighted(void) +{ + bool set = false; + + if ( txtHlgtStartLine == txtHlgtEndLine ) + { + set = (txtHlgtStartChar != txtHlgtEndChar); + } + else + { + set = true; + } + return set; +} +//---------------------------------------------------------------------------- +void QAsmView::setHighlightEndCoord( int x, int y ) +{ + + if ( txtHlgtAnchorLine < y ) + { + txtHlgtStartLine = txtHlgtAnchorLine; + txtHlgtStartChar = txtHlgtAnchorChar; + txtHlgtEndLine = y; + txtHlgtEndChar = x; + } + else if ( txtHlgtAnchorLine > y ) + { + txtHlgtStartLine = y; + txtHlgtStartChar = x; + txtHlgtEndLine = txtHlgtAnchorLine; + txtHlgtEndChar = txtHlgtAnchorChar; + } + else + { + txtHlgtStartLine = txtHlgtAnchorLine; + txtHlgtEndLine = txtHlgtAnchorLine; + + if ( txtHlgtAnchorChar < x ) + { + txtHlgtStartChar = txtHlgtAnchorChar; + txtHlgtEndChar = x; + } + else if ( txtHlgtAnchorChar > x ) + { + txtHlgtStartChar = x; + txtHlgtEndChar = txtHlgtAnchorChar; + } + else + { + txtHlgtStartChar = txtHlgtAnchorChar; + txtHlgtEndChar = txtHlgtAnchorChar; + } + } + return; +} +//---------------------------------------------------------------------------- void QAsmView::mouseMoveEvent(QMouseEvent * event) { int line; - QPoint c = convPixToCursor( event->pos() ); char txt[256]; std::string s; + QPoint c = convPixToCursor( event->pos() ); + line = lineOffset + c.y(); + if ( mouseLeftBtnDown ) + { + //printf("Left Button Move: (%i,%i)\n", c.x(), c.y() ); + setHighlightEndCoord( c.x(), line ); + } + //printf("c (%i,%i) : Line %i : %04X \n", c.x(), c.y(), line, asmEntry[line]->addr ); if ( line < asmEntry.size() ) @@ -3071,12 +3148,112 @@ void QAsmView::mouseMoveEvent(QMouseEvent * event) } } //---------------------------------------------------------------------------- +void QAsmView::loadClipboard( const char *txt ) +{ + clipboard->setText( tr(txt), QClipboard::Clipboard ); + + if ( clipboard->supportsSelection() ) + { + clipboard->setText( tr(txt), QClipboard::Selection ); + } +} +//---------------------------------------------------------------------------- +void QAsmView::loadHighlightToClipboard(void) +{ + if ( !textIsHighlighted() ) + { + return; + } + int l, row, nrow; + std::string txt; + + nrow = (viewHeight / pxLineSpacing) + 1; + + if ( nrow < 1 ) nrow = 1; + + for (row=0; row < nrow; row++) + { + l = lineOffset + row; + + if ( (l >= txtHlgtStartLine) && (l <= txtHlgtEndLine) ) + { + int hlgtXs, hlgtXe, hlgtXd; + std::string s; + bool addNewLine; + + if ( l == txtHlgtStartLine ) + { + hlgtXs = txtHlgtStartChar; + } + else + { + hlgtXs = 0; + } + + if ( l == txtHlgtEndLine ) + { + hlgtXe = txtHlgtEndChar; + addNewLine = false; + } + else + { + hlgtXe = (viewWidth / pxCharWidth) + 1; + addNewLine = true; + } + hlgtXd = (hlgtXe - hlgtXs); + + if ( hlgtXs < asmEntry[l]->text.size() ) + { + s = asmEntry[l]->text.substr( hlgtXs, hlgtXd ); + } + txt.append(s); + + if ( addNewLine ) + { + txt.append("\n"); + } + } + } + + //printf("Load Text to Clipboard:\n%s\n", txt.c_str() ); + + loadClipboard( txt.c_str() ); + +} +//---------------------------------------------------------------------------- +void QAsmView::mouseReleaseEvent(QMouseEvent * event) +{ + int line; + QPoint c = convPixToCursor( event->pos() ); + + line = lineOffset + c.y(); + + if ( event->button() == Qt::LeftButton ) + { + //printf("Left Button Release: (%i,%i)\n", c.x(), c.y() ); + mouseLeftBtnDown = false; + setHighlightEndCoord( c.x(), line ); + + loadHighlightToClipboard(); + } +} +//---------------------------------------------------------------------------- void QAsmView::mousePressEvent(QMouseEvent * event) { int line; QPoint c = convPixToCursor( event->pos() ); line = lineOffset + c.y(); + + if ( event->button() == Qt::LeftButton ) + { + //printf("Left Button Pressed: (%i,%i)\n", c.x(), c.y() ); + mouseLeftBtnDown = true; + txtHlgtAnchorChar = c.x(); + txtHlgtAnchorLine = line; + + setHighlightEndCoord( c.x(), line ); + } selAddrLine = -1; selAddrChar = 0; @@ -3209,6 +3386,10 @@ void QAsmView::mousePressEvent(QMouseEvent * event) parent->setBookmarkSelectedAddress( addr ); } + if ( selAddrText[0] != 0 ) + { + loadClipboard( selAddrText ); + } } } //---------------------------------------------------------------------------- @@ -3264,8 +3445,10 @@ void QAsmView::paintEvent(QPaintEvent *event) { int x,y,l, row, nrow, selAddr; QPainter painter(this); - QColor black("black"); + QColor white("white"), black("black"), blue("blue"); + QColor hlgtFG("white"), hlgtBG("blue"); bool forceDarkColor = false; + bool txtHlgtSet = false; painter.setFont(font); viewWidth = event->rect().width(); @@ -3302,6 +3485,8 @@ void QAsmView::paintEvent(QPaintEvent *event) y = pxLineSpacing; + txtHlgtSet = textIsHighlighted(); + for (row=0; row < nrow; row++) { x = -pxLineXScroll; @@ -3338,17 +3523,17 @@ void QAsmView::paintEvent(QPaintEvent *event) if ( (selAddrLine == l) ) { // Highlight ASM line for selected address. - if ( (selAddr == selAddrValue) && + if ( !txtHlgtSet && (selAddr == selAddrValue) && (asmEntry[l]->text.size() >= (selAddrChar + selAddrWidth) ) && ( asmEntry[l]->text.compare( selAddrChar, selAddrWidth, selAddrText ) == 0 ) ) { int ax; - ax = selAddrChar*pxCharWidth; + ax = x + selAddrChar*pxCharWidth; - painter.fillRect( ax, y - pxLineSpacing + pxLineLead, selAddrWidth*pxCharWidth, pxLineSpacing, QColor("blue") ); + painter.fillRect( ax, y - pxLineSpacing + pxLineLead, selAddrWidth*pxCharWidth, pxLineSpacing, blue ); - painter.setPen( QColor("white")); + painter.setPen( white ); painter.drawText( ax, y, tr(selAddrText) ); @@ -3358,6 +3543,56 @@ void QAsmView::paintEvent(QPaintEvent *event) } y += pxLineSpacing; } + + y = pxLineSpacing; + + painter.setPen( hlgtFG ); + + if ( txtHlgtSet ) + { + for (row=0; row < nrow; row++) + { + x = -pxLineXScroll; + l = lineOffset + row; + + if ( (l >= txtHlgtStartLine) && (l <= txtHlgtEndLine) ) + { + int ax, hlgtXs, hlgtXe, hlgtXd; + std::string s; + + if ( l == txtHlgtStartLine ) + { + hlgtXs = txtHlgtStartChar; + } + else + { + hlgtXs = 0; + } + + if ( l == txtHlgtEndLine ) + { + hlgtXe = txtHlgtEndChar; + } + else + { + hlgtXe = (viewWidth / pxCharWidth) + 1; + } + hlgtXd = (hlgtXe - hlgtXs); + + if ( hlgtXs < asmEntry[l]->text.size() ) + { + s = asmEntry[l]->text.substr( hlgtXs, hlgtXd ); + } + + ax = x + (hlgtXs * pxCharWidth); + + painter.fillRect( ax, y - pxLineSpacing + pxLineLead, hlgtXd * pxCharWidth, pxLineSpacing, hlgtBG ); + + painter.drawText( ax, y, tr(s.c_str()) ); + } + y += pxLineSpacing; + } + } } //---------------------------------------------------------------------------- // Bookmark Manager Methods diff --git a/src/drivers/Qt/ConsoleDebugger.h b/src/drivers/Qt/ConsoleDebugger.h index d7c99d75..73e4bd84 100644 --- a/src/drivers/Qt/ConsoleDebugger.h +++ b/src/drivers/Qt/ConsoleDebugger.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "Qt/main.h" @@ -116,18 +117,24 @@ class QAsmView : public QWidget void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *event); void mousePressEvent(QMouseEvent * event); + void mouseReleaseEvent(QMouseEvent * event); void mouseMoveEvent(QMouseEvent * event); void resizeEvent(QResizeEvent *event); void contextMenuEvent(QContextMenuEvent *event); + void loadHighlightToClipboard(void); void calcFontData(void); QPoint convPixToCursor( QPoint p ); + bool textIsHighlighted(void); + void setHighlightEndCoord( int x, int y ); + void loadClipboard( const char *txt ); private: ConsoleDebugger *parent; QFont font; QScrollBar *vbar; QScrollBar *hbar; + QClipboard *clipboard; int ctxMenuAddr; int maxLineLen; @@ -152,6 +159,13 @@ class QAsmView : public QWidget int selAddrValue; char selAddrText[128]; + int txtHlgtAnchorChar; + int txtHlgtAnchorLine; + int txtHlgtStartChar; + int txtHlgtStartLine; + int txtHlgtEndChar; + int txtHlgtEndLine; + dbg_asm_entry_t *asmPC; std::vector asmEntry; @@ -159,6 +173,7 @@ class QAsmView : public QWidget bool displayROMoffsets; bool symbolicDebugEnable; bool registerNameEnable; + bool mouseLeftBtnDown; }; class DebuggerStackDisplay : public QPlainTextEdit From 58a1d76e2cb030b36a21cb9b1961cfa3b226243e Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Fri, 13 Nov 2020 11:17:35 -0500 Subject: [PATCH 2/4] Changed shared memory allocation to a standard malloc to prevent crash on systems that do not allow large shm sizes. --- src/drivers/Qt/nes_shm.cpp | 43 ++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/drivers/Qt/nes_shm.cpp b/src/drivers/Qt/nes_shm.cpp index 55f164f2..2058d052 100644 --- a/src/drivers/Qt/nes_shm.cpp +++ b/src/drivers/Qt/nes_shm.cpp @@ -16,32 +16,35 @@ nes_shm_t *nes_shm = NULL; //************************************************************************ nes_shm_t *open_nes_shm(void) { - int shmId; nes_shm_t *vaddr; - struct shmid_ds ds; - shmId = shmget( IPC_PRIVATE, sizeof(struct nes_shm_t), IPC_CREAT | S_IRWXU | S_IRWXG ); + vaddr = (nes_shm_t*)malloc( sizeof(struct nes_shm_t) ); - if ( shmId == -1 ) - { - perror("Error: GL shmget Failed:"); - return NULL; - } - printf("Created ShmID: %i \n", shmId ); + //int shmId; + //struct shmid_ds ds; - vaddr = (nes_shm_t*)shmat( shmId, NULL, 0); + //shmId = shmget( IPC_PRIVATE, sizeof(struct nes_shm_t), IPC_CREAT | S_IRWXU | S_IRWXG ); - if ( vaddr == (nes_shm_t*)-1 ) - { - perror("Error: NES shmat Failed:"); - return NULL; - } - memset( vaddr, 0, sizeof(struct nes_shm_t)); + //if ( shmId == -1 ) + //{ + // perror("Error: GL shmget Failed:"); + // return NULL; + //} + //printf("Created ShmID: %i \n", shmId ); - if ( shmctl( shmId, IPC_RMID, &ds ) != 0 ) - { - perror("Error: GLX shmctl IPC_RMID Failed:"); - } + //vaddr = (nes_shm_t*)shmat( shmId, NULL, 0); + + //if ( vaddr == (nes_shm_t*)-1 ) + //{ + // perror("Error: NES shmat Failed:"); + // return NULL; + //} + //memset( vaddr, 0, sizeof(struct nes_shm_t)); + + //if ( shmctl( shmId, IPC_RMID, &ds ) != 0 ) + //{ + // perror("Error: GLX shmctl IPC_RMID Failed:"); + //} //sem_init( &vaddr->sem, 1, 1 ); From 836127afd02f55e49a0c960a20211db0dcfce741 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 13 Nov 2020 11:27:55 -0500 Subject: [PATCH 3/4] Changed Qt debugger ASM viewer to render text a single character at a time to have better control of horizontal char advance. Mac OS seems to not always draw characters with the same spacing if not done this way. --- src/drivers/Qt/ConsoleDebugger.cpp | 21 ++++++++++++++++++--- src/drivers/Qt/ConsoleDebugger.h | 1 + 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/drivers/Qt/ConsoleDebugger.cpp b/src/drivers/Qt/ConsoleDebugger.cpp index fe02da9d..26686ee7 100644 --- a/src/drivers/Qt/ConsoleDebugger.cpp +++ b/src/drivers/Qt/ConsoleDebugger.cpp @@ -3441,6 +3441,21 @@ void QAsmView::contextMenuEvent(QContextMenuEvent *event) } } //---------------------------------------------------------------------------- +void QAsmView::drawText( QPainter *painter, int x, int y, const char *txt ) +{ + int i=0; + char c[2]; + + c[0] = 0; c[1] = 0; + + while ( txt[i] != 0 ) + { + c[0] = txt[i]; + painter->drawText( x, y, tr(c) ); + i++; x += pxCharWidth; + } +} +//---------------------------------------------------------------------------- void QAsmView::paintEvent(QPaintEvent *event) { int x,y,l, row, nrow, selAddr; @@ -3519,7 +3534,7 @@ void QAsmView::paintEvent(QPaintEvent *event) { painter.setPen( this->palette().color(QPalette::WindowText)); } - painter.drawText( x, y, tr(asmEntry[l]->text.c_str()) ); + drawText( &painter, x, y, asmEntry[l]->text.c_str() ); if ( (selAddrLine == l) ) { // Highlight ASM line for selected address. @@ -3535,7 +3550,7 @@ void QAsmView::paintEvent(QPaintEvent *event) painter.setPen( white ); - painter.drawText( ax, y, tr(selAddrText) ); + drawText( &painter, ax, y, selAddrText ); painter.setPen( this->palette().color(QPalette::WindowText)); } @@ -3588,7 +3603,7 @@ void QAsmView::paintEvent(QPaintEvent *event) painter.fillRect( ax, y - pxLineSpacing + pxLineLead, hlgtXd * pxCharWidth, pxLineSpacing, hlgtBG ); - painter.drawText( ax, y, tr(s.c_str()) ); + drawText( &painter, ax, y, s.c_str() ); } y += pxLineSpacing; } diff --git a/src/drivers/Qt/ConsoleDebugger.h b/src/drivers/Qt/ConsoleDebugger.h index 73e4bd84..f8b51a07 100644 --- a/src/drivers/Qt/ConsoleDebugger.h +++ b/src/drivers/Qt/ConsoleDebugger.h @@ -128,6 +128,7 @@ class QAsmView : public QWidget bool textIsHighlighted(void); void setHighlightEndCoord( int x, int y ); void loadClipboard( const char *txt ); + void drawText( QPainter *painter, int x, int y, const char *txt ); private: ConsoleDebugger *parent; From bfa70c1f258188648f124a9bc7a4c8baf0e4ba67 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 13 Nov 2020 11:47:55 -0500 Subject: [PATCH 4/4] Bug fix for Qt debugger attempting to save symbol/bookmarks at window close with no game loaded. --- src/drivers/Qt/ConsoleDebugger.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/drivers/Qt/ConsoleDebugger.cpp b/src/drivers/Qt/ConsoleDebugger.cpp index 26686ee7..ddb28ba1 100644 --- a/src/drivers/Qt/ConsoleDebugger.cpp +++ b/src/drivers/Qt/ConsoleDebugger.cpp @@ -2480,7 +2480,10 @@ void saveGameDebugBreakpoints(void) { return; } - getGameDebugBreakpointFileName( stmp ); + if ( getGameDebugBreakpointFileName( stmp ) ) + { + return; + } //printf("Debug Save File: '%s' \n", stmp ); @@ -2616,7 +2619,10 @@ void loadGameDebugBreakpoints(void) printf("No Debug Windows Open: Skipping loading of breakpoint data\n"); return; } - getGameDebugBreakpointFileName( stmp ); + if ( getGameDebugBreakpointFileName( stmp ) ) + { + return; + } //printf("Debug Load File: '%s' \n", stmp );