From c21041e26e9341ff500725fcbea2a6fffc21b873 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 3 Oct 2020 11:46:14 -0400 Subject: [PATCH 01/10] Setup initial menu options and window open for Qt GUI PPU Viewer. --- src/CMakeLists.txt | 1 + src/drivers/Qt/ConsoleWindow.cpp | 16 ++++++++ src/drivers/Qt/ConsoleWindow.h | 2 + src/drivers/Qt/ppuViewer.cpp | 63 ++++++++++++++++++++++++++++++++ src/drivers/Qt/ppuViewer.h | 43 ++++++++++++++++++++++ 5 files changed, 125 insertions(+) create mode 100644 src/drivers/Qt/ppuViewer.cpp create mode 100644 src/drivers/Qt/ppuViewer.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 41036c60..fcf5be14 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -441,6 +441,7 @@ set(SRC_DRIVERS_SDL ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/TraceLogger.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/AboutWindow.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/fceuWrapper.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ppuViewer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/config.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/input.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/nes_shm.cpp diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index d4f7e723..490566c4 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -33,6 +33,7 @@ #include "Qt/ConsoleVideoConf.h" #include "Qt/AboutWindow.h" #include "Qt/fceuWrapper.h" +#include "Qt/ppuViewer.h" #include "Qt/keyscan.h" #include "Qt/nes_shm.h" @@ -501,6 +502,14 @@ void consoleWin_t::createMainMenu(void) debugMenu->addAction(hexEditAct); + // Debug -> PPU Viewer + ppuViewAct = new QAction(tr("PPU Viewer..."), this); + //ppuViewAct->setShortcut( QKeySequence(tr("Shift+F7"))); + ppuViewAct->setStatusTip(tr("Open PPU Viewer")); + connect(ppuViewAct, SIGNAL(triggered()), this, SLOT(openPPUViewer(void)) ); + + debugMenu->addAction(ppuViewAct); + // Debug -> Trace Logger traceLogAct = new QAction(tr("Trace Logger..."), this); //traceLogAct->setShortcut( QKeySequence(tr("Shift+F7"))); @@ -1021,6 +1030,13 @@ void consoleWin_t::openHexEditor(void) hexEditWin->show(); } +void consoleWin_t::openPPUViewer(void) +{ + //printf("Open GUI PPU Viewer Window\n"); + + openPPUViewWindow(this); +} + void consoleWin_t::openCodeDataLogger(void) { CodeDataLoggerDialog_t *cdlWin; diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index a8d74264..7699b3ed 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -93,6 +93,7 @@ class consoleWin_t : public QMainWindow QAction *codeDataLogAct; QAction *traceLogAct; QAction *hexEditAct; + QAction *ppuViewAct; QAction *openMovAct; QAction *stopMovAct; QAction *recMovAct; @@ -162,6 +163,7 @@ class consoleWin_t : public QMainWindow void fdsSwitchDisk(void); void fdsEjectDisk(void); void fdsLoadBiosFile(void); + void openPPUViewer(void); void openCheats(void); void openMovie(void); void stopMovie(void); diff --git a/src/drivers/Qt/ppuViewer.cpp b/src/drivers/Qt/ppuViewer.cpp new file mode 100644 index 00000000..b1e75bb6 --- /dev/null +++ b/src/drivers/Qt/ppuViewer.cpp @@ -0,0 +1,63 @@ +// ppuViewer.cpp +// +#include + +#include +#include +#include + +#include "Qt/ppuViewer.h" +#include "Qt/main.h" +#include "Qt/dface.h" +#include "Qt/input.h" +#include "Qt/config.h" +#include "Qt/fceuWrapper.h" + +static ppuViewerDialog_t *ppuViewWindow = NULL; +//---------------------------------------------------- +int openPPUViewWindow( QWidget *parent ) +{ + if ( ppuViewWindow != NULL ) + { + return -1; + } + ppuViewWindow = new ppuViewerDialog_t(parent); + + ppuViewWindow->show(); + + return 0; +} +//---------------------------------------------------- +ppuViewerDialog_t::ppuViewerDialog_t(QWidget *parent) + : QDialog( parent ) +{ + ppuViewWindow = this; + + setWindowTitle( tr("PPU Viewer") ); + + //setLayout( mainLayout ); +} + +//---------------------------------------------------- +ppuViewerDialog_t::~ppuViewerDialog_t(void) +{ + ppuViewWindow = NULL; + + printf("PPU Viewer Window Deleted\n"); +} +//---------------------------------------------------- +void ppuViewerDialog_t::closeEvent(QCloseEvent *event) +{ + printf("PPU Viewer Close Window Event\n"); + done(0); + deleteLater(); + event->accept(); +} +//---------------------------------------------------- +void ppuViewerDialog_t::closeWindow(void) +{ + printf("Close Window\n"); + done(0); + deleteLater(); +} +//---------------------------------------------------- diff --git a/src/drivers/Qt/ppuViewer.h b/src/drivers/Qt/ppuViewer.h new file mode 100644 index 00000000..f8734424 --- /dev/null +++ b/src/drivers/Qt/ppuViewer.h @@ -0,0 +1,43 @@ +// ppuViewer.h +// + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Qt/main.h" + +class ppuViewerDialog_t : public QDialog +{ + Q_OBJECT + + public: + ppuViewerDialog_t(QWidget *parent = 0); + ~ppuViewerDialog_t(void); + + protected: + //QTimer *inputTimer; + + void closeEvent(QCloseEvent *bar); + private: + + public slots: + void closeWindow(void); + private slots: + //void updatePeriodic(void); + +}; + +int openPPUViewWindow( QWidget *parent ); + From cf2b43f31a2da9b582fa532d12fb36c263bdb906 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 4 Oct 2020 09:54:51 -0400 Subject: [PATCH 02/10] First successful viewing of pattern and palatte colors on Qt PPU Viewer. --- src/drivers/Qt/ppuViewer.cpp | 302 ++++++++++++++++++++++++++++++++++- src/drivers/Qt/ppuViewer.h | 27 ++++ src/palette.cpp | 2 +- src/ppu.cpp | 12 +- 4 files changed, 336 insertions(+), 7 deletions(-) diff --git a/src/drivers/Qt/ppuViewer.cpp b/src/drivers/Qt/ppuViewer.cpp index b1e75bb6..35b110f9 100644 --- a/src/drivers/Qt/ppuViewer.cpp +++ b/src/drivers/Qt/ppuViewer.cpp @@ -1,11 +1,20 @@ // ppuViewer.cpp // #include +#include #include +#include #include #include +#include "../../types.h" +#include "../../fceu.h" +#include "../../cart.h" +#include "../../ppu.h" +#include "../../debug.h" +#include "../../palette.h" + #include "Qt/ppuViewer.h" #include "Qt/main.h" #include "Qt/dface.h" @@ -13,7 +22,40 @@ #include "Qt/config.h" #include "Qt/fceuWrapper.h" +#define PATTERNWIDTH 128 +#define PATTERNHEIGHT 128 +#define PATTERNBITWIDTH PATTERNWIDTH*3 + +#define PALETTEWIDTH 16 +#define PALETTEHEIGHT 2 +#define PALETTEBITWIDTH PALETTEWIDTH*3 + static ppuViewerDialog_t *ppuViewWindow = NULL; +static int PPUViewScanline = 0; +//static int PPUViewSkip = 0; +//static int PPUViewRefresh = 0; +static bool PPUView_maskUnusedGraphics = true; +static bool PPUView_invertTheMask = false; +static int PPUView_sprite16Mode = 0; +static int pindex0 = 0, pindex1 = 0; +static QColor ppuv_palette[PALETTEHEIGHT][PALETTEWIDTH]; +static uint8_t pallast[32+3] = { 0 }; // palette cache for change comparison +static uint8_t palcache[36] = { 0 }; //palette cache for drawing +static uint8_t chrcache0[0x1000] = {0}, chrcache1[0x1000] = {0}, logcache0[0x1000] = {0}, logcache1[0x1000] = {0}; //cache CHR, fixes a refresh problem when right-clicking +//pattern table bitmap arrays + +struct patternTable_t +{ + struct + { + struct + { + QColor color; + } pixel[16][8]; + } tile[16][16]; +}; +static patternTable_t pattern0; +static patternTable_t pattern1; //---------------------------------------------------- int openPPUViewWindow( QWidget *parent ) { @@ -31,11 +73,23 @@ int openPPUViewWindow( QWidget *parent ) ppuViewerDialog_t::ppuViewerDialog_t(QWidget *parent) : QDialog( parent ) { + QVBoxLayout *mainLayout; + ppuViewWindow = this; setWindowTitle( tr("PPU Viewer") ); - //setLayout( mainLayout ); + mainLayout = new QVBoxLayout(); + + setLayout( mainLayout ); + + patternView = new ppuPatternView_t(this); + paletteView = new ppuPalatteView_t(this); + + mainLayout->addWidget( patternView, 10 ); + mainLayout->addWidget( paletteView, 1 ); + + FCEUD_UpdatePPUView( -1, 1 ); } //---------------------------------------------------- @@ -61,3 +115,249 @@ void ppuViewerDialog_t::closeWindow(void) deleteLater(); } //---------------------------------------------------- +ppuPatternView_t::ppuPatternView_t(QWidget *parent) + : QWidget(parent) +{ + setMinimumWidth( 512 ); + setMinimumHeight( 256 ); + +} +//---------------------------------------------------- +ppuPatternView_t::~ppuPatternView_t(void) +{ + +} +//---------------------------------------------------- +void ppuPatternView_t::paintEvent(QPaintEvent *event) +{ + int i,j,x,y,w,h,w2,xx,yy; + QPainter painter(this); + int viewWidth = event->rect().width(); + int viewHeight = event->rect().height(); + + //printf("PPU PatternView %ix%i \n", viewWidth, viewHeight ); + + w = viewWidth / 256; + h = viewHeight / 128; + w2= viewWidth / 2; + + xx = 0; yy = 0; + + for (i=0; i<16; i++) //Columns + { + for (j=0; j<16; j++) //Rows + { + xx = (i*8)*w; + + for (x=0; x < 8; x++) + { + yy = (j*8)*h; + + for (y=0; y < 8; y++) + { + painter.fillRect( xx, yy, w, h, pattern0.tile[j][i].pixel[y][x].color ); + yy += h; + } + xx += w; + } + } + } + + xx = w2; yy = 0; + + for (i=0; i<16; i++) //Columns + { + for (j=0; j<16; j++) //Rows + { + xx = w2 + (i*8)*w; + + for (x=0; x < 8; x++) + { + yy = (j*8)*h; + + for (y=0; y < 8; y++) + { + painter.fillRect( xx, yy, w, h, pattern1.tile[j][i].pixel[y][x].color ); + yy += h; + } + xx += w; + } + } + } +} +//---------------------------------------------------- +static void DrawPatternTable( patternTable_t *pattern, uint8_t *table, uint8_t *log, uint8_t pal) +{ + int i,j,k,x,y,index=0; + int p=0,tmp; + uint8_t chr0,chr1,logs,shift; + + pal <<= 2; + for (i = 0; i < (16 >> PPUView_sprite16Mode); i++) //Columns + { + for (j = 0; j < 16; j++) //Rows + { + //index = (i<<4)|(j<<8); + //printf("Tile: %X%X index:%04X %04X\n", j,i,index, (i<<4)|(j<<8)); + //----------------------------------------------- + for (k = 0; k < (PPUView_sprite16Mode + 1); k++) + { + for (y = 0; y < 8; y++) + { + chr0 = table[index]; + chr1 = table[index + 8]; + logs = log[index] & log[index + 8]; + tmp = 7; + //shift=(PPUView_maskUnusedGraphics && debug_loggingCD && (((logs & 3) != 0) == PPUView_invertTheMask))?3:0; + shift=0; + for (x = 0; x < 8; x++) + { + p = (chr0 >> tmp) & 1; + p |= ((chr1 >> tmp) & 1) << 1; + p = palcache[p | pal]; + tmp--; + pattern->tile[i][j].pixel[y][x].color.setBlue( palo[p].b >> shift ); + pattern->tile[i][j].pixel[y][x].color.setGreen( palo[p].g >> shift ); + pattern->tile[i][j].pixel[y][x].color.setRed( palo[p].r >> shift ); + + //printf("Tile: %X%X Pixel: (%i,%i) P:%i RGB: (%i,%i,%i)\n", j, i, x, y, p, + // pattern->tile[j][i].pixel[y][x].color.red(), + // pattern->tile[j][i].pixel[y][x].color.green(), + // pattern->tile[j][i].pixel[y][x].color.blue() ); + } + index++; + //pbitmap += (PATTERNBITWIDTH-24); + } + index+=8; + } + //pbitmap -= ((PATTERNBITWIDTH<<(3+PPUView_sprite16Mode))-24); + //------------------------------------------------ + } + //pbitmap += (PATTERNBITWIDTH*((8<>10][i]; + chrcache1[i] = VPage[x>>10][x]; + if (debug_loggingCD) + { + if (cdloggerVideoDataSize) + { + int addr; + addr = &VPage[i >> 10][i] - CHRptr[0]; + if ((addr >= 0) && (addr < (int)cdloggerVideoDataSize)) + logcache0[i] = cdloggervdata[addr]; + addr = &VPage[x >> 10][x] - CHRptr[0]; + if ((addr >= 0) && (addr < (int)cdloggerVideoDataSize)) + logcache1[i] = cdloggervdata[addr]; + } + else + { + logcache0[i] = cdloggervdata[i]; + logcache1[i] = cdloggervdata[x]; + } + } + } + } + + //if (PPUViewSkip < PPUViewRefresh) + //{ + // return; + //} + + // update palette only if required + if ((memcmp(pallast, PALRAM, 32) != 0) || (memcmp(pallast+32, UPALRAM, 3) != 0)) + { + //printf("Updated PPU View Palette\n"); + memcpy(pallast, PALRAM, 32); + memcpy(pallast+32, UPALRAM, 3); + + // cache palette content + memcpy(palcache,PALRAM,32); + palcache[0x10] = palcache[0x00]; + palcache[0x04] = palcache[0x14] = UPALRAM[0]; + palcache[0x08] = palcache[0x18] = UPALRAM[1]; + palcache[0x0C] = palcache[0x1C] = UPALRAM[2]; + + //draw palettes + for (y = 0; y < PALETTEHEIGHT; y++) + { + for (x = 0; x < PALETTEWIDTH; x++) + { + i = (y*PALETTEWIDTH) + x; + + ppuv_palette[y][x].setBlue( palo[palcache[i]].b ); + ppuv_palette[y][x].setGreen( palo[palcache[i]].g ); + ppuv_palette[y][x].setRed( palo[palcache[i]].r ); + } + } + } + + DrawPatternTable( &pattern0,chrcache0,logcache0,pindex0); + DrawPatternTable( &pattern1,chrcache1,logcache1,pindex1); + + if ( ppuViewWindow ) + { + ppuViewWindow->update(); + } +} +//---------------------------------------------------- +ppuPalatteView_t::ppuPalatteView_t(QWidget *parent) + : QWidget(parent) +{ + setMinimumWidth( 32 * PALETTEHEIGHT ); + setMinimumHeight( 32 * PALETTEHEIGHT ); + +} +//---------------------------------------------------- +ppuPalatteView_t::~ppuPalatteView_t(void) +{ + +} +//---------------------------------------------------- +void ppuPalatteView_t::paintEvent(QPaintEvent *event) +{ + int x,y,w,h,xx,yy; + QPainter painter(this); + int viewWidth = event->rect().width(); + int viewHeight = event->rect().height(); + + //printf("PPU PatternView %ix%i \n", viewWidth, viewHeight ); + + w = viewWidth / PALETTEWIDTH; + h = viewHeight / PALETTEHEIGHT; + + yy = 0; + for (y=0; y < PALETTEHEIGHT; y++) + { + xx = 0; + + for (x=0; x < PALETTEWIDTH; x++) + { + + //painter.setPen( pattern0.tile[j][i].pixel[y][x].color ); + painter.fillRect( xx, yy, w, h, ppuv_palette[y][x] ); + xx += w; + } + yy += h; + } + painter.drawLine( 0, viewHeight / 2, viewWidth, viewHeight / 2 ); +} +//---------------------------------------------------- diff --git a/src/drivers/Qt/ppuViewer.h b/src/drivers/Qt/ppuViewer.h index f8734424..b62f48d9 100644 --- a/src/drivers/Qt/ppuViewer.h +++ b/src/drivers/Qt/ppuViewer.h @@ -18,6 +18,30 @@ #include "Qt/main.h" +class ppuPatternView_t : public QWidget +{ + Q_OBJECT + + public: + ppuPatternView_t(QWidget *parent = 0); + ~ppuPatternView_t(void); + + protected: + void paintEvent(QPaintEvent *event); +}; + +class ppuPalatteView_t : public QWidget +{ + Q_OBJECT + + public: + ppuPalatteView_t(QWidget *parent = 0); + ~ppuPalatteView_t(void); + + protected: + void paintEvent(QPaintEvent *event); +}; + class ppuViewerDialog_t : public QDialog { Q_OBJECT @@ -29,6 +53,9 @@ class ppuViewerDialog_t : public QDialog protected: //QTimer *inputTimer; + ppuPatternView_t *patternView; + ppuPalatteView_t *paletteView; + void closeEvent(QCloseEvent *bar); private: diff --git a/src/palette.cpp b/src/palette.cpp index 5a9c2709..361d9671 100644 --- a/src/palette.cpp +++ b/src/palette.cpp @@ -72,7 +72,7 @@ static void ChoosePalette(void); static void WritePalette(void); //points to the actually selected current palette -pal *palo; +pal *palo = NULL; #define RGB_TO_YIQ( r, g, b, y, i ) (\ (y = (r) * 0.299f + (g) * 0.587f + (b) * 0.114f),\ diff --git a/src/ppu.cpp b/src/ppu.cpp index 0e667a43..712e72ee 100644 --- a/src/ppu.cpp +++ b/src/ppu.cpp @@ -1853,10 +1853,10 @@ int FCEUPPU_Loop(int skip) { for (scanline = 0; scanline < totalscanlines; ) { //scanline is incremented in DoLine. Evil. :/ deempcnt[deemp]++; -#ifdef WIN32 + if (scanline < 240) DEBUG(FCEUD_UpdatePPUView(scanline, 1)); -#endif + DoLine(); if (scanline < normalscanlines || scanline == totalscanlines) @@ -2137,7 +2137,8 @@ int FCEUX_PPU_Loop(int skip) { //int xscroll = ppur.fh; //render 241/291 scanlines (1 dummy at beginning, dendy's 50 at the end) //ignore overclocking! - for (int sl = 0; sl < normalscanlines; sl++) { + for (int sl = 0; sl < normalscanlines; sl++) + { spr_read.start_scanline(); g_rasterpos = 0; @@ -2148,9 +2149,10 @@ int FCEUX_PPU_Loop(int skip) { const int yp = sl - 1; ppuphase = PPUPHASE_BG; - if (sl != 0 && sl < 241) { // ignore the invisible -#ifdef WIN32 + if (sl != 0 && sl < 241) // ignore the invisible + { DEBUG(FCEUD_UpdatePPUView(scanline = yp, 1)); +#ifdef WIN32 DEBUG(FCEUD_UpdateNTView(scanline = yp, 1)); #endif } From fa55d6024befa354d86d91ffd5b7b16c54d67fbe Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 4 Oct 2020 19:17:11 -0400 Subject: [PATCH 03/10] Added PPU Viewer control widgets to window. Still TODO, write logic. --- src/drivers/Qt/ppuViewer.cpp | 114 ++++++++++++++++++++++++----------- src/drivers/Qt/ppuViewer.h | 11 ++++ 2 files changed, 90 insertions(+), 35 deletions(-) diff --git a/src/drivers/Qt/ppuViewer.cpp b/src/drivers/Qt/ppuViewer.cpp index 35b110f9..9d45bd3a 100644 --- a/src/drivers/Qt/ppuViewer.cpp +++ b/src/drivers/Qt/ppuViewer.cpp @@ -73,7 +73,10 @@ int openPPUViewWindow( QWidget *parent ) ppuViewerDialog_t::ppuViewerDialog_t(QWidget *parent) : QDialog( parent ) { - QVBoxLayout *mainLayout; + QVBoxLayout *mainLayout, *vbox; + QHBoxLayout *hbox; + QGroupBox *frame; + QGridLayout *grid; ppuViewWindow = this; @@ -83,11 +86,56 @@ ppuViewerDialog_t::ppuViewerDialog_t(QWidget *parent) setLayout( mainLayout ); + vbox = new QVBoxLayout(); + frame = new QGroupBox( tr("Pattern Tables") ); patternView = new ppuPatternView_t(this); - paletteView = new ppuPalatteView_t(this); + grid = new QGridLayout; - mainLayout->addWidget( patternView, 10 ); - mainLayout->addWidget( paletteView, 1 ); + vbox->addWidget( patternView, 10 ); + vbox->addLayout( grid, 1 ); + frame->setLayout( vbox ); + + tileLabel[0] = new QLabel( tr("Pattern 0 Tile:") ); + tileLabel[1] = new QLabel( tr("Pattern 1 Tile:") ); + sprite8x16Cbox = new QCheckBox( tr("Sprites 8x16 Mode") ); + maskUnusedCbox = new QCheckBox( tr("Mask unused Graphics (Code/Data Logger)") ); + invertMaskCbox = new QCheckBox( tr("Invert the Mask (Code/Data Logger)") ); + + sprite8x16Cbox->setChecked( PPUView_sprite16Mode ); + maskUnusedCbox->setChecked( PPUView_maskUnusedGraphics ); + invertMaskCbox->setChecked( PPUView_invertTheMask ); + + connect( sprite8x16Cbox, SIGNAL(stateChanged(int)), this, SLOT(sprite8x16Changed(int))); + + hbox = new QHBoxLayout(); + refreshSlider = new QSlider( Qt::Horizontal ); + hbox->addWidget( new QLabel( tr("Refresh: More") ) ); + hbox->addWidget( refreshSlider ); + hbox->addWidget( new QLabel( tr("Less") ) ); + + grid->addWidget( tileLabel[0], 0, 0, Qt::AlignLeft ); + grid->addWidget( tileLabel[1], 0, 1, Qt::AlignLeft ); + grid->addWidget( sprite8x16Cbox, 1, 0, Qt::AlignLeft ); + grid->addWidget( maskUnusedCbox, 2, 0, Qt::AlignLeft ); + grid->addWidget( invertMaskCbox, 3, 0, Qt::AlignLeft ); + grid->addLayout( hbox, 1, 1, Qt::AlignRight ); + + hbox = new QHBoxLayout(); + scanLineEdit = new QLineEdit(); + hbox->addWidget( new QLabel( tr("Display on Scanline:") ) ); + hbox->addWidget( scanLineEdit ); + grid->addLayout( hbox, 2, 1, Qt::AlignRight ); + + mainLayout->addWidget( frame, 10 ); + + vbox = new QVBoxLayout(); + paletteFrame = new QGroupBox( tr("Palettes:") ); + paletteView = new ppuPalatteView_t(this); + + vbox->addWidget( paletteView, 1 ); + paletteFrame->setLayout( vbox ); + + mainLayout->addWidget( paletteFrame, 1 ); FCEUD_UpdatePPUView( -1, 1 ); } @@ -115,12 +163,16 @@ void ppuViewerDialog_t::closeWindow(void) deleteLater(); } //---------------------------------------------------- +void ppuViewerDialog_t::sprite8x16Changed(int state) +{ + PPUView_sprite16Mode = (state == Qt::Unchecked) ? 0 : 1; +} +//---------------------------------------------------- ppuPatternView_t::ppuPatternView_t(QWidget *parent) : QWidget(parent) { setMinimumWidth( 512 ); setMinimumHeight( 256 ); - } //---------------------------------------------------- ppuPatternView_t::~ppuPatternView_t(void) @@ -188,52 +240,44 @@ void ppuPatternView_t::paintEvent(QPaintEvent *event) //---------------------------------------------------- static void DrawPatternTable( patternTable_t *pattern, uint8_t *table, uint8_t *log, uint8_t pal) { - int i,j,k,x,y,index=0; + int i,j,x,y,index=0; int p=0,tmp; uint8_t chr0,chr1,logs,shift; pal <<= 2; - for (i = 0; i < (16 >> PPUView_sprite16Mode); i++) //Columns + for (i = 0; i < 16; i++) //Columns { for (j = 0; j < 16; j++) //Rows { - //index = (i<<4)|(j<<8); //printf("Tile: %X%X index:%04X %04X\n", j,i,index, (i<<4)|(j<<8)); //----------------------------------------------- - for (k = 0; k < (PPUView_sprite16Mode + 1); k++) + for (y = 0; y < 8; y++) { - for (y = 0; y < 8; y++) + chr0 = table[index]; + chr1 = table[index + 8]; + logs = log[index] & log[index + 8]; + tmp = 7; + shift=(PPUView_maskUnusedGraphics && debug_loggingCD && (((logs & 3) != 0) == PPUView_invertTheMask))?3:0; + for (x = 0; x < 8; x++) { - chr0 = table[index]; - chr1 = table[index + 8]; - logs = log[index] & log[index + 8]; - tmp = 7; - //shift=(PPUView_maskUnusedGraphics && debug_loggingCD && (((logs & 3) != 0) == PPUView_invertTheMask))?3:0; - shift=0; - for (x = 0; x < 8; x++) - { - p = (chr0 >> tmp) & 1; - p |= ((chr1 >> tmp) & 1) << 1; - p = palcache[p | pal]; - tmp--; - pattern->tile[i][j].pixel[y][x].color.setBlue( palo[p].b >> shift ); - pattern->tile[i][j].pixel[y][x].color.setGreen( palo[p].g >> shift ); - pattern->tile[i][j].pixel[y][x].color.setRed( palo[p].r >> shift ); + p = (chr0 >> tmp) & 1; + p |= ((chr1 >> tmp) & 1) << 1; + p = palcache[p | pal]; + tmp--; + pattern->tile[i][j].pixel[y][x].color.setBlue( palo[p].b >> shift ); + pattern->tile[i][j].pixel[y][x].color.setGreen( palo[p].g >> shift ); + pattern->tile[i][j].pixel[y][x].color.setRed( palo[p].r >> shift ); - //printf("Tile: %X%X Pixel: (%i,%i) P:%i RGB: (%i,%i,%i)\n", j, i, x, y, p, - // pattern->tile[j][i].pixel[y][x].color.red(), - // pattern->tile[j][i].pixel[y][x].color.green(), - // pattern->tile[j][i].pixel[y][x].color.blue() ); - } - index++; - //pbitmap += (PATTERNBITWIDTH-24); + //printf("Tile: %X%X Pixel: (%i,%i) P:%i RGB: (%i,%i,%i)\n", j, i, x, y, p, + // pattern->tile[j][i].pixel[y][x].color.red(), + // pattern->tile[j][i].pixel[y][x].color.green(), + // pattern->tile[j][i].pixel[y][x].color.blue() ); } - index+=8; + index++; } - //pbitmap -= ((PATTERNBITWIDTH<<(3+PPUView_sprite16Mode))-24); + index+=8; //------------------------------------------------ } - //pbitmap += (PATTERNBITWIDTH*((8< #include #include +#include +#include #include #include @@ -59,10 +61,19 @@ class ppuViewerDialog_t : public QDialog void closeEvent(QCloseEvent *bar); private: + QGroupBox *paletteFrame; + QLabel *tileLabel[2]; + QCheckBox *sprite8x16Cbox; + QCheckBox *maskUnusedCbox; + QCheckBox *invertMaskCbox; + QSlider *refreshSlider; + QLineEdit *scanLineEdit; + public slots: void closeWindow(void); private slots: //void updatePeriodic(void); + void sprite8x16Changed(int state); }; From ccb8b63282bef607d59a6764c8d533a3758552c6 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 4 Oct 2020 20:36:33 -0400 Subject: [PATCH 04/10] Re-organized Qt PPU viewer to have each pattern table in its own frame. --- src/drivers/Qt/ppuViewer.cpp | 129 +++++++++++++++++------------------ src/drivers/Qt/ppuViewer.h | 25 +++++-- 2 files changed, 84 insertions(+), 70 deletions(-) diff --git a/src/drivers/Qt/ppuViewer.cpp b/src/drivers/Qt/ppuViewer.cpp index 9d45bd3a..37d18073 100644 --- a/src/drivers/Qt/ppuViewer.cpp +++ b/src/drivers/Qt/ppuViewer.cpp @@ -36,7 +36,7 @@ static int PPUViewScanline = 0; //static int PPUViewRefresh = 0; static bool PPUView_maskUnusedGraphics = true; static bool PPUView_invertTheMask = false; -static int PPUView_sprite16Mode = 0; +static int PPUView_sprite16Mode[2] = { 0, 0 }; static int pindex0 = 0, pindex1 = 0; static QColor ppuv_palette[PALETTEHEIGHT][PALETTEWIDTH]; static uint8_t pallast[32+3] = { 0 }; // palette cache for change comparison @@ -44,18 +44,8 @@ static uint8_t palcache[36] = { 0 }; //palette cache for drawing static uint8_t chrcache0[0x1000] = {0}, chrcache1[0x1000] = {0}, logcache0[0x1000] = {0}, logcache1[0x1000] = {0}; //cache CHR, fixes a refresh problem when right-clicking //pattern table bitmap arrays -struct patternTable_t -{ - struct - { - struct - { - QColor color; - } pixel[16][8]; - } tile[16][16]; -}; -static patternTable_t pattern0; -static patternTable_t pattern1; +static ppuPatternTable_t pattern0; +static ppuPatternTable_t pattern1; //---------------------------------------------------- int openPPUViewWindow( QWidget *parent ) { @@ -74,8 +64,8 @@ ppuViewerDialog_t::ppuViewerDialog_t(QWidget *parent) : QDialog( parent ) { QVBoxLayout *mainLayout, *vbox; + QVBoxLayout *patternVbox[2]; QHBoxLayout *hbox; - QGroupBox *frame; QGridLayout *grid; ppuViewWindow = this; @@ -86,26 +76,47 @@ ppuViewerDialog_t::ppuViewerDialog_t(QWidget *parent) setLayout( mainLayout ); - vbox = new QVBoxLayout(); - frame = new QGroupBox( tr("Pattern Tables") ); - patternView = new ppuPatternView_t(this); - grid = new QGridLayout; + vbox = new QVBoxLayout(); + hbox = new QHBoxLayout(); + grid = new QGridLayout; + patternVbox[0] = new QVBoxLayout(); + patternVbox[1] = new QVBoxLayout(); + patternFrame[0] = new QGroupBox( tr("Pattern Table 0") ); + patternFrame[1] = new QGroupBox( tr("Pattern Table 1") ); + patternView[0] = new ppuPatternView_t( 0, this); + patternView[1] = new ppuPatternView_t( 1, this); + sprite8x16Cbox[0] = new QCheckBox( tr("Sprites 8x16 Mode") ); + sprite8x16Cbox[1] = new QCheckBox( tr("Sprites 8x16 Mode") ); + tileLabel[0] = new QLabel( tr("Pattern 0 Tile:") ); + tileLabel[1] = new QLabel( tr("Pattern 1 Tile:") ); - vbox->addWidget( patternView, 10 ); - vbox->addLayout( grid, 1 ); - frame->setLayout( vbox ); + sprite8x16Cbox[0]->setChecked( PPUView_sprite16Mode[0] ); + sprite8x16Cbox[1]->setChecked( PPUView_sprite16Mode[1] ); + + patternVbox[0]->addWidget( patternView[0], 10 ); + patternVbox[0]->addWidget( tileLabel[0], 1 ); + patternVbox[0]->addWidget( sprite8x16Cbox[0], 1 ); + patternVbox[1]->addWidget( patternView[1], 10 ); + patternVbox[1]->addWidget( tileLabel[1], 1 ); + patternVbox[1]->addWidget( sprite8x16Cbox[1], 1 ); + + patternFrame[0]->setLayout( patternVbox[0] ); + patternFrame[1]->setLayout( patternVbox[1] ); + + hbox->addWidget( patternFrame[0] ); + hbox->addWidget( patternFrame[1] ); + + mainLayout->addLayout( hbox, 10 ); + mainLayout->addLayout( grid, 1 ); - tileLabel[0] = new QLabel( tr("Pattern 0 Tile:") ); - tileLabel[1] = new QLabel( tr("Pattern 1 Tile:") ); - sprite8x16Cbox = new QCheckBox( tr("Sprites 8x16 Mode") ); maskUnusedCbox = new QCheckBox( tr("Mask unused Graphics (Code/Data Logger)") ); invertMaskCbox = new QCheckBox( tr("Invert the Mask (Code/Data Logger)") ); - sprite8x16Cbox->setChecked( PPUView_sprite16Mode ); maskUnusedCbox->setChecked( PPUView_maskUnusedGraphics ); invertMaskCbox->setChecked( PPUView_invertTheMask ); - connect( sprite8x16Cbox, SIGNAL(stateChanged(int)), this, SLOT(sprite8x16Changed(int))); + connect( sprite8x16Cbox[0], SIGNAL(stateChanged(int)), this, SLOT(sprite8x16Changed0(int))); + connect( sprite8x16Cbox[1], SIGNAL(stateChanged(int)), this, SLOT(sprite8x16Changed1(int))); hbox = new QHBoxLayout(); refreshSlider = new QSlider( Qt::Horizontal ); @@ -113,20 +124,15 @@ ppuViewerDialog_t::ppuViewerDialog_t(QWidget *parent) hbox->addWidget( refreshSlider ); hbox->addWidget( new QLabel( tr("Less") ) ); - grid->addWidget( tileLabel[0], 0, 0, Qt::AlignLeft ); - grid->addWidget( tileLabel[1], 0, 1, Qt::AlignLeft ); - grid->addWidget( sprite8x16Cbox, 1, 0, Qt::AlignLeft ); - grid->addWidget( maskUnusedCbox, 2, 0, Qt::AlignLeft ); - grid->addWidget( invertMaskCbox, 3, 0, Qt::AlignLeft ); - grid->addLayout( hbox, 1, 1, Qt::AlignRight ); + grid->addWidget( maskUnusedCbox, 0, 0, Qt::AlignLeft ); + grid->addWidget( invertMaskCbox, 1, 0, Qt::AlignLeft ); + grid->addLayout( hbox, 0, 1, Qt::AlignRight ); hbox = new QHBoxLayout(); scanLineEdit = new QLineEdit(); hbox->addWidget( new QLabel( tr("Display on Scanline:") ) ); hbox->addWidget( scanLineEdit ); - grid->addLayout( hbox, 2, 1, Qt::AlignRight ); - - mainLayout->addWidget( frame, 10 ); + grid->addLayout( hbox, 1, 1, Qt::AlignRight ); vbox = new QVBoxLayout(); paletteFrame = new QGroupBox( tr("Palettes:") ); @@ -137,6 +143,9 @@ ppuViewerDialog_t::ppuViewerDialog_t(QWidget *parent) mainLayout->addWidget( paletteFrame, 1 ); + patternView[0]->setPattern( &pattern0 ); + patternView[1]->setPattern( &pattern1 ); + FCEUD_UpdatePPUView( -1, 1 ); } @@ -163,18 +172,29 @@ void ppuViewerDialog_t::closeWindow(void) deleteLater(); } //---------------------------------------------------- -void ppuViewerDialog_t::sprite8x16Changed(int state) +void ppuViewerDialog_t::sprite8x16Changed0(int state) { - PPUView_sprite16Mode = (state == Qt::Unchecked) ? 0 : 1; + PPUView_sprite16Mode[0] = (state == Qt::Unchecked) ? 0 : 1; } //---------------------------------------------------- -ppuPatternView_t::ppuPatternView_t(QWidget *parent) +void ppuViewerDialog_t::sprite8x16Changed1(int state) +{ + PPUView_sprite16Mode[1] = (state == Qt::Unchecked) ? 0 : 1; +} +//---------------------------------------------------- +ppuPatternView_t::ppuPatternView_t( int patternIndexID, QWidget *parent) : QWidget(parent) { - setMinimumWidth( 512 ); + patternIndex = patternIndexID; + setMinimumWidth( 256 ); setMinimumHeight( 256 ); } //---------------------------------------------------- +void ppuPatternView_t::setPattern( ppuPatternTable_t *p ) +{ + pattern = p; +} +//---------------------------------------------------- ppuPatternView_t::~ppuPatternView_t(void) { @@ -182,16 +202,15 @@ ppuPatternView_t::~ppuPatternView_t(void) //---------------------------------------------------- void ppuPatternView_t::paintEvent(QPaintEvent *event) { - int i,j,x,y,w,h,w2,xx,yy; + int i,j,x,y,w,h,xx,yy; QPainter painter(this); int viewWidth = event->rect().width(); int viewHeight = event->rect().height(); //printf("PPU PatternView %ix%i \n", viewWidth, viewHeight ); - w = viewWidth / 256; + w = viewWidth / 128; h = viewHeight / 128; - w2= viewWidth / 2; xx = 0; yy = 0; @@ -207,29 +226,7 @@ void ppuPatternView_t::paintEvent(QPaintEvent *event) for (y=0; y < 8; y++) { - painter.fillRect( xx, yy, w, h, pattern0.tile[j][i].pixel[y][x].color ); - yy += h; - } - xx += w; - } - } - } - - xx = w2; yy = 0; - - for (i=0; i<16; i++) //Columns - { - for (j=0; j<16; j++) //Rows - { - xx = w2 + (i*8)*w; - - for (x=0; x < 8; x++) - { - yy = (j*8)*h; - - for (y=0; y < 8; y++) - { - painter.fillRect( xx, yy, w, h, pattern1.tile[j][i].pixel[y][x].color ); + painter.fillRect( xx, yy, w, h, pattern->tile[j][i].pixel[y][x].color ); yy += h; } xx += w; @@ -238,7 +235,7 @@ void ppuPatternView_t::paintEvent(QPaintEvent *event) } } //---------------------------------------------------- -static void DrawPatternTable( patternTable_t *pattern, uint8_t *table, uint8_t *log, uint8_t pal) +static void DrawPatternTable( ppuPatternTable_t *pattern, uint8_t *table, uint8_t *log, uint8_t pal) { int i,j,x,y,index=0; int p=0,tmp; diff --git a/src/drivers/Qt/ppuViewer.h b/src/drivers/Qt/ppuViewer.h index 5ff8a59d..53b788f0 100644 --- a/src/drivers/Qt/ppuViewer.h +++ b/src/drivers/Qt/ppuViewer.h @@ -20,16 +20,31 @@ #include "Qt/main.h" +struct ppuPatternTable_t +{ + struct + { + struct + { + QColor color; + } pixel[8][8]; + } tile[16][16]; +}; + class ppuPatternView_t : public QWidget { Q_OBJECT public: - ppuPatternView_t(QWidget *parent = 0); + ppuPatternView_t( int patternIndex, QWidget *parent = 0); ~ppuPatternView_t(void); + void setPattern( ppuPatternTable_t *p ); protected: void paintEvent(QPaintEvent *event); + + int patternIndex; + ppuPatternTable_t *pattern; }; class ppuPalatteView_t : public QWidget @@ -55,15 +70,16 @@ class ppuViewerDialog_t : public QDialog protected: //QTimer *inputTimer; - ppuPatternView_t *patternView; + ppuPatternView_t *patternView[2]; ppuPalatteView_t *paletteView; void closeEvent(QCloseEvent *bar); private: + QGroupBox *patternFrame[2]; QGroupBox *paletteFrame; QLabel *tileLabel[2]; - QCheckBox *sprite8x16Cbox; + QCheckBox *sprite8x16Cbox[2]; QCheckBox *maskUnusedCbox; QCheckBox *invertMaskCbox; QSlider *refreshSlider; @@ -73,7 +89,8 @@ class ppuViewerDialog_t : public QDialog void closeWindow(void); private slots: //void updatePeriodic(void); - void sprite8x16Changed(int state); + void sprite8x16Changed0(int state); + void sprite8x16Changed1(int state); }; From ec6a6e06e7027da80fc1efdedf89b60c6a921143 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 4 Oct 2020 22:07:33 -0400 Subject: [PATCH 05/10] Added logic to display sprite 8x16 on Qt PPU viewer --- src/drivers/Qt/ppuViewer.cpp | 72 +++++++++++++++++++++++++++++------- src/drivers/Qt/ppuViewer.h | 7 ++++ 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/src/drivers/Qt/ppuViewer.cpp b/src/drivers/Qt/ppuViewer.cpp index 37d18073..2ad6a424 100644 --- a/src/drivers/Qt/ppuViewer.cpp +++ b/src/drivers/Qt/ppuViewer.cpp @@ -202,7 +202,7 @@ ppuPatternView_t::~ppuPatternView_t(void) //---------------------------------------------------- void ppuPatternView_t::paintEvent(QPaintEvent *event) { - int i,j,x,y,w,h,xx,yy; + int i,j,x,y,w,h,xx,yy,ii,jj,rr; QPainter painter(this); int viewWidth = event->rect().width(); int viewHeight = event->rect().height(); @@ -212,24 +212,72 @@ void ppuPatternView_t::paintEvent(QPaintEvent *event) w = viewWidth / 128; h = viewHeight / 128; + pattern->w = w; + pattern->h = h; + xx = 0; yy = 0; - for (i=0; i<16; i++) //Columns + if ( PPUView_sprite16Mode[ patternIndex ] ) { - for (j=0; j<16; j++) //Rows + for (i=0; i<16; i++) //Columns { - xx = (i*8)*w; - - for (x=0; x < 8; x++) + for (j=0; j<16; j++) //Rows { - yy = (j*8)*h; + rr = (j%2); + jj = j; - for (y=0; y < 8; y++) + if ( rr ) { - painter.fillRect( xx, yy, w, h, pattern->tile[j][i].pixel[y][x].color ); - yy += h; + jj--; + } + + ii = (i*2)+rr; + + if ( ii >= 16 ) + { + ii = ii % 16; + jj++; + } + + xx = (i*8)*w; + + for (x=0; x < 8; x++) + { + yy = (j*8)*h; + + for (y=0; y < 8; y++) + { + pattern->tile[jj][ii].x = xx; + pattern->tile[jj][ii].y = yy; + painter.fillRect( xx, yy, w, h, pattern->tile[jj][ii].pixel[y][x].color ); + yy += h; + } + xx += w; + } + } + } + } + else + { + for (i=0; i<16; i++) //Columns + { + for (j=0; j<16; j++) //Rows + { + xx = (i*8)*w; + + for (x=0; x < 8; x++) + { + yy = (j*8)*h; + + for (y=0; y < 8; y++) + { + pattern->tile[j][i].x = xx; + pattern->tile[j][i].y = yy; + painter.fillRect( xx, yy, w, h, pattern->tile[j][i].pixel[y][x].color ); + yy += h; + } + xx += w; } - xx += w; } } } @@ -392,8 +440,6 @@ void ppuPalatteView_t::paintEvent(QPaintEvent *event) for (x=0; x < PALETTEWIDTH; x++) { - - //painter.setPen( pattern0.tile[j][i].pixel[y][x].color ); painter.fillRect( xx, yy, w, h, ppuv_palette[y][x] ); xx += w; } diff --git a/src/drivers/Qt/ppuViewer.h b/src/drivers/Qt/ppuViewer.h index 53b788f0..98b927a5 100644 --- a/src/drivers/Qt/ppuViewer.h +++ b/src/drivers/Qt/ppuViewer.h @@ -28,7 +28,14 @@ struct ppuPatternTable_t { QColor color; } pixel[8][8]; + + int x; + int y; + } tile[16][16]; + + int w; + int h; }; class ppuPatternView_t : public QWidget From 202bbc0b15cd3ed4618b2dfa38f7869132fdccb9 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 4 Oct 2020 22:44:30 -0400 Subject: [PATCH 06/10] Added logic to fill out PPU selected tile label --- src/drivers/Qt/ppuViewer.cpp | 82 ++++++++++++++++++++++++++++++++++-- src/drivers/Qt/ppuViewer.h | 7 +++ 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/src/drivers/Qt/ppuViewer.cpp b/src/drivers/Qt/ppuViewer.cpp index 2ad6a424..c2158929 100644 --- a/src/drivers/Qt/ppuViewer.cpp +++ b/src/drivers/Qt/ppuViewer.cpp @@ -87,8 +87,8 @@ ppuViewerDialog_t::ppuViewerDialog_t(QWidget *parent) patternView[1] = new ppuPatternView_t( 1, this); sprite8x16Cbox[0] = new QCheckBox( tr("Sprites 8x16 Mode") ); sprite8x16Cbox[1] = new QCheckBox( tr("Sprites 8x16 Mode") ); - tileLabel[0] = new QLabel( tr("Pattern 0 Tile:") ); - tileLabel[1] = new QLabel( tr("Pattern 1 Tile:") ); + tileLabel[0] = new QLabel( tr("Tile:") ); + tileLabel[1] = new QLabel( tr("Tile:") ); sprite8x16Cbox[0]->setChecked( PPUView_sprite16Mode[0] ); sprite8x16Cbox[1]->setChecked( PPUView_sprite16Mode[1] ); @@ -145,6 +145,8 @@ ppuViewerDialog_t::ppuViewerDialog_t(QWidget *parent) patternView[0]->setPattern( &pattern0 ); patternView[1]->setPattern( &pattern1 ); + patternView[0]->setTileLabel( tileLabel[0] ); + patternView[1]->setTileLabel( tileLabel[1] ); FCEUD_UpdatePPUView( -1, 1 ); } @@ -185,9 +187,14 @@ void ppuViewerDialog_t::sprite8x16Changed1(int state) ppuPatternView_t::ppuPatternView_t( int patternIndexID, QWidget *parent) : QWidget(parent) { + this->setFocusPolicy(Qt::StrongFocus); + this->setMouseTracking(true); patternIndex = patternIndexID; setMinimumWidth( 256 ); setMinimumHeight( 256 ); + viewWidth = 256; + viewHeight = 256; + tileLabel = NULL; } //---------------------------------------------------- void ppuPatternView_t::setPattern( ppuPatternTable_t *p ) @@ -195,17 +202,84 @@ void ppuPatternView_t::setPattern( ppuPatternTable_t *p ) pattern = p; } //---------------------------------------------------- +void ppuPatternView_t::setTileLabel( QLabel *l ) +{ + tileLabel = l; +} +//---------------------------------------------------- ppuPatternView_t::~ppuPatternView_t(void) { +} +//---------------------------------------------------- +QPoint ppuPatternView_t::convPixToTile( QPoint p ) +{ + QPoint t(0,0); + int x,y,w,h,i,j,ii,jj,rr; + + x = p.x(); y = p.y(); + + w = pattern->w; + h = pattern->h; + + i = x / (w*8); + j = y / (h*8); + + if ( PPUView_sprite16Mode[ patternIndex ] ) + { + rr = (j%2); + jj = j; + + if ( rr ) + { + jj--; + } + + ii = (i*2)+rr; + + if ( ii >= 16 ) + { + ii = ii % 16; + jj++; + } + } + else + { + ii = i; jj = j; + } + //printf("(x,y) = (%i,%i) w=%i h=%i $%X%X \n", x, y, w, h, jj, ii ); + + t.setX(ii); + t.setY(jj); + + return t; +} +//---------------------------------------------------- +void ppuPatternView_t::resizeEvent(QResizeEvent *event) +{ + viewWidth = event->size().width(); + viewHeight = event->size().height(); + + pattern->w = viewWidth / 128; + pattern->h = viewHeight / 128; +} +//---------------------------------------------------- +void ppuPatternView_t::mouseMoveEvent(QMouseEvent *event) +{ + char stmp[64]; + QPoint tile = convPixToTile( event->pos() ); + + sprintf( stmp, "Tile: $%X%X", tile.y(), tile.x() ); + + tileLabel->setText( tr(stmp) ); } //---------------------------------------------------- void ppuPatternView_t::paintEvent(QPaintEvent *event) { int i,j,x,y,w,h,xx,yy,ii,jj,rr; QPainter painter(this); - int viewWidth = event->rect().width(); - int viewHeight = event->rect().height(); + viewWidth = event->rect().width(); + viewHeight = event->rect().height(); //printf("PPU PatternView %ix%i \n", viewWidth, viewHeight ); diff --git a/src/drivers/Qt/ppuViewer.h b/src/drivers/Qt/ppuViewer.h index 98b927a5..c75094a9 100644 --- a/src/drivers/Qt/ppuViewer.h +++ b/src/drivers/Qt/ppuViewer.h @@ -47,10 +47,17 @@ class ppuPatternView_t : public QWidget ~ppuPatternView_t(void); void setPattern( ppuPatternTable_t *p ); + void setTileLabel( QLabel *l ); + QPoint convPixToTile( QPoint p ); protected: void paintEvent(QPaintEvent *event); + void resizeEvent(QResizeEvent *event); + void mouseMoveEvent(QMouseEvent *event); int patternIndex; + int viewWidth; + int viewHeight; + QLabel *tileLabel; ppuPatternTable_t *pattern; }; From b19c86bc103edb728262e34cd81b164ba4d7d5f6 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 4 Oct 2020 23:23:27 -0400 Subject: [PATCH 07/10] Minor display updates to Qt PPU viewer. --- src/drivers/Qt/ppuViewer.cpp | 86 +++++++++++++++++++++++++++++++----- src/drivers/Qt/ppuViewer.h | 2 + 2 files changed, 77 insertions(+), 11 deletions(-) diff --git a/src/drivers/Qt/ppuViewer.cpp b/src/drivers/Qt/ppuViewer.cpp index c2158929..118a4ec1 100644 --- a/src/drivers/Qt/ppuViewer.cpp +++ b/src/drivers/Qt/ppuViewer.cpp @@ -32,18 +32,18 @@ static ppuViewerDialog_t *ppuViewWindow = NULL; static int PPUViewScanline = 0; -//static int PPUViewSkip = 0; -//static int PPUViewRefresh = 0; +static int PPUViewSkip = 0; +static int PPUViewRefresh = 1; static bool PPUView_maskUnusedGraphics = true; static bool PPUView_invertTheMask = false; static int PPUView_sprite16Mode[2] = { 0, 0 }; -static int pindex0 = 0, pindex1 = 0; +static int pindex[2] = { 0, 0 }; static QColor ppuv_palette[PALETTEHEIGHT][PALETTEWIDTH]; static uint8_t pallast[32+3] = { 0 }; // palette cache for change comparison static uint8_t palcache[36] = { 0 }; //palette cache for drawing static uint8_t chrcache0[0x1000] = {0}, chrcache1[0x1000] = {0}, logcache0[0x1000] = {0}, logcache1[0x1000] = {0}; //cache CHR, fixes a refresh problem when right-clicking -//pattern table bitmap arrays +static void initPPUViewer(void); static ppuPatternTable_t pattern0; static ppuPatternTable_t pattern1; //---------------------------------------------------- @@ -53,6 +53,8 @@ int openPPUViewWindow( QWidget *parent ) { return -1; } + initPPUViewer(); + ppuViewWindow = new ppuViewerDialog_t(parent); ppuViewWindow->show(); @@ -148,6 +150,12 @@ ppuViewerDialog_t::ppuViewerDialog_t(QWidget *parent) patternView[0]->setTileLabel( tileLabel[0] ); patternView[1]->setTileLabel( tileLabel[1] ); + refreshSlider->setMinimum( 0); + refreshSlider->setMaximum(25); + refreshSlider->setValue(PPUViewRefresh); + + connect( refreshSlider, SIGNAL(valueChanged(int)), this, SLOT(refreshSliderChanged(int))); + FCEUD_UpdatePPUView( -1, 1 ); } @@ -184,6 +192,11 @@ void ppuViewerDialog_t::sprite8x16Changed1(int state) PPUView_sprite16Mode[1] = (state == Qt::Unchecked) ? 0 : 1; } //---------------------------------------------------- +void ppuViewerDialog_t::refreshSliderChanged(int value) +{ + PPUViewRefresh = value; +} +//---------------------------------------------------- ppuPatternView_t::ppuPatternView_t( int patternIndexID, QWidget *parent) : QWidget(parent) { @@ -273,6 +286,21 @@ void ppuPatternView_t::mouseMoveEvent(QMouseEvent *event) tileLabel->setText( tr(stmp) ); } +//---------------------------------------------------------------------------- +void ppuPatternView_t::mousePressEvent(QMouseEvent * event) +{ + //QPoint tile = convPixToTile( event->pos() ); + + if ( event->button() == Qt::LeftButton ) + { + // TODO Load Tile Viewport + } + else if ( event->button() == Qt::RightButton ) + { + pindex[ patternIndex ] = (pindex[ patternIndex ] + 1) % 9; + PPUViewSkip = 100; + } +} //---------------------------------------------------- void ppuPatternView_t::paintEvent(QPaintEvent *event) { @@ -357,6 +385,26 @@ void ppuPatternView_t::paintEvent(QPaintEvent *event) } } //---------------------------------------------------- +static void initPPUViewer(void) +{ + memset( pallast , 0, sizeof(pallast) ); + memset( palcache , 0, sizeof(palcache) ); + memset( chrcache0, 0, sizeof(chrcache0) ); + memset( chrcache1, 0, sizeof(chrcache1) ); + memset( logcache0, 0, sizeof(logcache0) ); + memset( logcache1, 0, sizeof(logcache1) ); + + // forced palette (e.g. for debugging CHR when palettes are all-black) + palcache[(8*4)+0] = 0x0F; + palcache[(8*4)+1] = 0x00; + palcache[(8*4)+2] = 0x10; + palcache[(8*4)+3] = 0x20; + + pindex[0] = 0; + pindex[1] = 0; + +} +//---------------------------------------------------- static void DrawPatternTable( ppuPatternTable_t *pattern, uint8_t *table, uint8_t *log, uint8_t pal) { int i,j,x,y,index=0; @@ -440,10 +488,12 @@ void FCEUD_UpdatePPUView(int scanline, int refreshchr) } } - //if (PPUViewSkip < PPUViewRefresh) - //{ - // return; - //} + if (PPUViewSkip < PPUViewRefresh) + { + PPUViewSkip++; + return; + } + PPUViewSkip = 0; // update palette only if required if ((memcmp(pallast, PALRAM, 32) != 0) || (memcmp(pallast+32, UPALRAM, 3) != 0)) @@ -473,8 +523,8 @@ void FCEUD_UpdatePPUView(int scanline, int refreshchr) } } - DrawPatternTable( &pattern0,chrcache0,logcache0,pindex0); - DrawPatternTable( &pattern1,chrcache1,logcache1,pindex1); + DrawPatternTable( &pattern0,chrcache0,logcache0,pindex[0]); + DrawPatternTable( &pattern1,chrcache1,logcache1,pindex[1]); if ( ppuViewWindow ) { @@ -519,6 +569,20 @@ void ppuPalatteView_t::paintEvent(QPaintEvent *event) } yy += h; } - painter.drawLine( 0, viewHeight / 2, viewWidth, viewHeight / 2 ); + + y = PALETTEHEIGHT*h; + for (int i=0; i<=PALETTEWIDTH; i++) + { + x = i*w; + painter.drawLine( x, 0 , x, y ); + } + + + x = PALETTEWIDTH*w; + for (int i=0; i<=PALETTEHEIGHT; i++) + { + y = i*h; + painter.drawLine( 0, y, x, y ); + } } //---------------------------------------------------- diff --git a/src/drivers/Qt/ppuViewer.h b/src/drivers/Qt/ppuViewer.h index c75094a9..b9ec9316 100644 --- a/src/drivers/Qt/ppuViewer.h +++ b/src/drivers/Qt/ppuViewer.h @@ -53,6 +53,7 @@ class ppuPatternView_t : public QWidget void paintEvent(QPaintEvent *event); void resizeEvent(QResizeEvent *event); void mouseMoveEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent * event); int patternIndex; int viewWidth; @@ -105,6 +106,7 @@ class ppuViewerDialog_t : public QDialog //void updatePeriodic(void); void sprite8x16Changed0(int state); void sprite8x16Changed1(int state); + void refreshSliderChanged(int value); }; From 59d726230d452212e07a4d788c37bb1627271a14 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 4 Oct 2020 23:38:10 -0400 Subject: [PATCH 08/10] Added logic for Qt PPU Viewer scanline entry box. --- src/drivers/Qt/ppuViewer.cpp | 21 +++++++++++++++++++++ src/drivers/Qt/ppuViewer.h | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/drivers/Qt/ppuViewer.cpp b/src/drivers/Qt/ppuViewer.cpp index 118a4ec1..8ba27639 100644 --- a/src/drivers/Qt/ppuViewer.cpp +++ b/src/drivers/Qt/ppuViewer.cpp @@ -69,6 +69,7 @@ ppuViewerDialog_t::ppuViewerDialog_t(QWidget *parent) QVBoxLayout *patternVbox[2]; QHBoxLayout *hbox; QGridLayout *grid; + char stmp[64]; ppuViewWindow = this; @@ -150,6 +151,13 @@ ppuViewerDialog_t::ppuViewerDialog_t(QWidget *parent) patternView[0]->setTileLabel( tileLabel[0] ); patternView[1]->setTileLabel( tileLabel[1] ); + scanLineEdit->setMaxLength( 3 ); + scanLineEdit->setInputMask( ">900;" ); + sprintf( stmp, "%i", PPUViewScanline ); + scanLineEdit->setText( tr(stmp) ); + + connect( scanLineEdit, SIGNAL(textEdited(const QString &)), this, SLOT(scanLineChanged(const QString &))); + refreshSlider->setMinimum( 0); refreshSlider->setMaximum(25); refreshSlider->setValue(PPUViewRefresh); @@ -182,6 +190,19 @@ void ppuViewerDialog_t::closeWindow(void) deleteLater(); } //---------------------------------------------------- +void ppuViewerDialog_t::scanLineChanged( const QString &txt ) +{ + std::string s; + + s = txt.toStdString(); + + if ( s.size() > 0 ) + { + PPUViewScanline = strtoul( s.c_str(), NULL, 10 ); + } + //printf("ScanLine: '%s' %i\n", s.c_str(), PPUViewScanline ); +} +//---------------------------------------------------- void ppuViewerDialog_t::sprite8x16Changed0(int state) { PPUView_sprite16Mode[0] = (state == Qt::Unchecked) ? 0 : 1; diff --git a/src/drivers/Qt/ppuViewer.h b/src/drivers/Qt/ppuViewer.h index b9ec9316..f73246bd 100644 --- a/src/drivers/Qt/ppuViewer.h +++ b/src/drivers/Qt/ppuViewer.h @@ -107,7 +107,7 @@ class ppuViewerDialog_t : public QDialog void sprite8x16Changed0(int state); void sprite8x16Changed1(int state); void refreshSliderChanged(int value); - + void scanLineChanged( const QString &s ); }; int openPPUViewWindow( QWidget *parent ); From 9241c33c221b3f38f6db23e755ee891b470f1a89 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 4 Oct 2020 23:42:49 -0400 Subject: [PATCH 09/10] Added place holder function for FCEUD_UpdatePPUView in the GTK/SDL GUI. This fixes GTK GUI build issue that occurred when Qt/SDL PPU Viewer feature was added. GTK GUI will not support the PPU Viewer feature at this time. --- src/drivers/sdl/debugger.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/drivers/sdl/debugger.cpp b/src/drivers/sdl/debugger.cpp index ea23deea..54d348cc 100644 --- a/src/drivers/sdl/debugger.cpp +++ b/src/drivers/sdl/debugger.cpp @@ -1714,6 +1714,11 @@ void FCEUD_TraceInstruction(uint8 *opcode, int size) // Place holder to allow for compiling. GTK GUI doesn't support this. Qt Does. } +void FCEUD_UpdatePPUView(int scanline, int refreshchr) +{ + // Place holder to allow for compiling. GTK GUI doesn't support this. Qt Does. +} + static void closeDebuggerWindow (GtkWidget * w, GdkEvent * e, debuggerWin_t * dw) { std::list < debuggerWin_t * >::iterator it; From bf2018493711e8999f23e7ecd79317cf7d8ce79c Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 4 Oct 2020 23:48:33 -0400 Subject: [PATCH 10/10] Updated TODO-SDL file to show that Qt5 GUI now has PPU Viewer capability. --- TODO-SDL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO-SDL b/TODO-SDL index 83f91b5c..335f41c3 100644 --- a/TODO-SDL +++ b/TODO-SDL @@ -43,7 +43,7 @@ RAM Watch Window | NO | YES Memory Watch Window | NO | NO | TAS Editor | NO | NO | 6502 Debugger Window | YES | YES | -PPU Viewer | NO | NO | +PPU Viewer | YES | NO | Name Table Viewer | NO | NO | Memory Hex Editor | YES | YES | Trace Logger | YES | NO |