Merge pull request #178 from mjbudd77/master

Added PPU Viewer Feature to Qt/SDL GUI
This commit is contained in:
mjbudd77 2020-10-05 00:42:15 -04:00 committed by GitHub
commit 717967c4d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 756 additions and 7 deletions

View File

@ -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 |

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -0,0 +1,609 @@
// ppuViewer.cpp
//
#include <stdio.h>
#include <stdint.h>
#include <QDir>
#include <QPainter>
#include <QInputDialog>
#include <QMessageBox>
#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"
#include "Qt/input.h"
#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 = 1;
static bool PPUView_maskUnusedGraphics = true;
static bool PPUView_invertTheMask = false;
static int PPUView_sprite16Mode[2] = { 0, 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
static void initPPUViewer(void);
static ppuPatternTable_t pattern0;
static ppuPatternTable_t pattern1;
//----------------------------------------------------
int openPPUViewWindow( QWidget *parent )
{
if ( ppuViewWindow != NULL )
{
return -1;
}
initPPUViewer();
ppuViewWindow = new ppuViewerDialog_t(parent);
ppuViewWindow->show();
return 0;
}
//----------------------------------------------------
ppuViewerDialog_t::ppuViewerDialog_t(QWidget *parent)
: QDialog( parent )
{
QVBoxLayout *mainLayout, *vbox;
QVBoxLayout *patternVbox[2];
QHBoxLayout *hbox;
QGridLayout *grid;
char stmp[64];
ppuViewWindow = this;
setWindowTitle( tr("PPU Viewer") );
mainLayout = new QVBoxLayout();
setLayout( mainLayout );
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("Tile:") );
tileLabel[1] = new QLabel( tr("Tile:") );
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 );
maskUnusedCbox = new QCheckBox( tr("Mask unused Graphics (Code/Data Logger)") );
invertMaskCbox = new QCheckBox( tr("Invert the Mask (Code/Data Logger)") );
maskUnusedCbox->setChecked( PPUView_maskUnusedGraphics );
invertMaskCbox->setChecked( PPUView_invertTheMask );
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 );
hbox->addWidget( new QLabel( tr("Refresh: More") ) );
hbox->addWidget( refreshSlider );
hbox->addWidget( new QLabel( tr("Less") ) );
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, 1, 1, Qt::AlignRight );
vbox = new QVBoxLayout();
paletteFrame = new QGroupBox( tr("Palettes:") );
paletteView = new ppuPalatteView_t(this);
vbox->addWidget( paletteView, 1 );
paletteFrame->setLayout( vbox );
mainLayout->addWidget( paletteFrame, 1 );
patternView[0]->setPattern( &pattern0 );
patternView[1]->setPattern( &pattern1 );
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);
connect( refreshSlider, SIGNAL(valueChanged(int)), this, SLOT(refreshSliderChanged(int)));
FCEUD_UpdatePPUView( -1, 1 );
}
//----------------------------------------------------
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();
}
//----------------------------------------------------
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;
}
//----------------------------------------------------
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)
{
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 )
{
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::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)
{
int i,j,x,y,w,h,xx,yy,ii,jj,rr;
QPainter painter(this);
viewWidth = event->rect().width();
viewHeight = event->rect().height();
//printf("PPU PatternView %ix%i \n", viewWidth, viewHeight );
w = viewWidth / 128;
h = viewHeight / 128;
pattern->w = w;
pattern->h = h;
xx = 0; yy = 0;
if ( PPUView_sprite16Mode[ patternIndex ] )
{
for (i=0; i<16; i++) //Columns
{
for (j=0; j<16; j++) //Rows
{
rr = (j%2);
jj = j;
if ( rr )
{
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;
}
}
}
}
}
//----------------------------------------------------
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;
int p=0,tmp;
uint8_t chr0,chr1,logs,shift;
pal <<= 2;
for (i = 0; i < 16; i++) //Columns
{
for (j = 0; j < 16; j++) //Rows
{
//printf("Tile: %X%X index:%04X %04X\n", j,i,index, (i<<4)|(j<<8));
//-----------------------------------------------
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++)
{
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++;
}
index+=8;
//------------------------------------------------
}
}
}
//----------------------------------------------------
void FCEUD_UpdatePPUView(int scanline, int refreshchr)
{
if ( ppuViewWindow == NULL )
{
return;
}
if ( (scanline != -1) && (scanline != PPUViewScanline) )
{
return;
}
int x,y,i;
if (refreshchr)
{
for (i = 0, x=0x1000; i < 0x1000; i++, x++)
{
chrcache0[i] = VPage[i>>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)
{
PPUViewSkip++;
return;
}
PPUViewSkip = 0;
// 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,pindex[0]);
DrawPatternTable( &pattern1,chrcache1,logcache1,pindex[1]);
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.fillRect( xx, yy, w, h, ppuv_palette[y][x] );
xx += w;
}
yy += h;
}
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 );
}
}
//----------------------------------------------------

114
src/drivers/Qt/ppuViewer.h Normal file
View File

@ -0,0 +1,114 @@
// ppuViewer.h
//
#pragma once
#include <QWidget>
#include <QDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QComboBox>
#include <QCheckBox>
#include <QPushButton>
#include <QLabel>
#include <QFrame>
#include <QTimer>
#include <QSlider>
#include <QLineEdit>
#include <QGroupBox>
#include <QCloseEvent>
#include "Qt/main.h"
struct ppuPatternTable_t
{
struct
{
struct
{
QColor color;
} pixel[8][8];
int x;
int y;
} tile[16][16];
int w;
int h;
};
class ppuPatternView_t : public QWidget
{
Q_OBJECT
public:
ppuPatternView_t( int patternIndex, QWidget *parent = 0);
~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);
void mousePressEvent(QMouseEvent * event);
int patternIndex;
int viewWidth;
int viewHeight;
QLabel *tileLabel;
ppuPatternTable_t *pattern;
};
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
public:
ppuViewerDialog_t(QWidget *parent = 0);
~ppuViewerDialog_t(void);
protected:
//QTimer *inputTimer;
ppuPatternView_t *patternView[2];
ppuPalatteView_t *paletteView;
void closeEvent(QCloseEvent *bar);
private:
QGroupBox *patternFrame[2];
QGroupBox *paletteFrame;
QLabel *tileLabel[2];
QCheckBox *sprite8x16Cbox[2];
QCheckBox *maskUnusedCbox;
QCheckBox *invertMaskCbox;
QSlider *refreshSlider;
QLineEdit *scanLineEdit;
public slots:
void closeWindow(void);
private slots:
//void updatePeriodic(void);
void sprite8x16Changed0(int state);
void sprite8x16Changed1(int state);
void refreshSliderChanged(int value);
void scanLineChanged( const QString &s );
};
int openPPUViewWindow( QWidget *parent );

View File

@ -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;

View File

@ -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),\

View File

@ -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
}