First successful viewing of pattern and palatte colors on Qt PPU Viewer.
This commit is contained in:
parent
c21041e26e
commit
cf2b43f31a
|
@ -1,11 +1,20 @@
|
||||||
// ppuViewer.cpp
|
// ppuViewer.cpp
|
||||||
//
|
//
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QPainter>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QMessageBox>
|
#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/ppuViewer.h"
|
||||||
#include "Qt/main.h"
|
#include "Qt/main.h"
|
||||||
#include "Qt/dface.h"
|
#include "Qt/dface.h"
|
||||||
|
@ -13,7 +22,40 @@
|
||||||
#include "Qt/config.h"
|
#include "Qt/config.h"
|
||||||
#include "Qt/fceuWrapper.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 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 )
|
int openPPUViewWindow( QWidget *parent )
|
||||||
{
|
{
|
||||||
|
@ -31,11 +73,23 @@ int openPPUViewWindow( QWidget *parent )
|
||||||
ppuViewerDialog_t::ppuViewerDialog_t(QWidget *parent)
|
ppuViewerDialog_t::ppuViewerDialog_t(QWidget *parent)
|
||||||
: QDialog( parent )
|
: QDialog( parent )
|
||||||
{
|
{
|
||||||
|
QVBoxLayout *mainLayout;
|
||||||
|
|
||||||
ppuViewWindow = this;
|
ppuViewWindow = this;
|
||||||
|
|
||||||
setWindowTitle( tr("PPU Viewer") );
|
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();
|
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<<PPUView_sprite16Mode)-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------------------------------------
|
||||||
|
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)
|
||||||
|
//{
|
||||||
|
// 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 );
|
||||||
|
}
|
||||||
|
//----------------------------------------------------
|
||||||
|
|
|
@ -18,6 +18,30 @@
|
||||||
|
|
||||||
#include "Qt/main.h"
|
#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
|
class ppuViewerDialog_t : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -29,6 +53,9 @@ class ppuViewerDialog_t : public QDialog
|
||||||
protected:
|
protected:
|
||||||
//QTimer *inputTimer;
|
//QTimer *inputTimer;
|
||||||
|
|
||||||
|
ppuPatternView_t *patternView;
|
||||||
|
ppuPalatteView_t *paletteView;
|
||||||
|
|
||||||
void closeEvent(QCloseEvent *bar);
|
void closeEvent(QCloseEvent *bar);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ static void ChoosePalette(void);
|
||||||
static void WritePalette(void);
|
static void WritePalette(void);
|
||||||
|
|
||||||
//points to the actually selected current palette
|
//points to the actually selected current palette
|
||||||
pal *palo;
|
pal *palo = NULL;
|
||||||
|
|
||||||
#define RGB_TO_YIQ( r, g, b, y, i ) (\
|
#define RGB_TO_YIQ( r, g, b, y, i ) (\
|
||||||
(y = (r) * 0.299f + (g) * 0.587f + (b) * 0.114f),\
|
(y = (r) * 0.299f + (g) * 0.587f + (b) * 0.114f),\
|
||||||
|
|
12
src/ppu.cpp
12
src/ppu.cpp
|
@ -1853,10 +1853,10 @@ int FCEUPPU_Loop(int skip) {
|
||||||
|
|
||||||
for (scanline = 0; scanline < totalscanlines; ) { //scanline is incremented in DoLine. Evil. :/
|
for (scanline = 0; scanline < totalscanlines; ) { //scanline is incremented in DoLine. Evil. :/
|
||||||
deempcnt[deemp]++;
|
deempcnt[deemp]++;
|
||||||
#ifdef WIN32
|
|
||||||
if (scanline < 240)
|
if (scanline < 240)
|
||||||
DEBUG(FCEUD_UpdatePPUView(scanline, 1));
|
DEBUG(FCEUD_UpdatePPUView(scanline, 1));
|
||||||
#endif
|
|
||||||
DoLine();
|
DoLine();
|
||||||
|
|
||||||
if (scanline < normalscanlines || scanline == totalscanlines)
|
if (scanline < normalscanlines || scanline == totalscanlines)
|
||||||
|
@ -2137,7 +2137,8 @@ int FCEUX_PPU_Loop(int skip) {
|
||||||
//int xscroll = ppur.fh;
|
//int xscroll = ppur.fh;
|
||||||
//render 241/291 scanlines (1 dummy at beginning, dendy's 50 at the end)
|
//render 241/291 scanlines (1 dummy at beginning, dendy's 50 at the end)
|
||||||
//ignore overclocking!
|
//ignore overclocking!
|
||||||
for (int sl = 0; sl < normalscanlines; sl++) {
|
for (int sl = 0; sl < normalscanlines; sl++)
|
||||||
|
{
|
||||||
spr_read.start_scanline();
|
spr_read.start_scanline();
|
||||||
|
|
||||||
g_rasterpos = 0;
|
g_rasterpos = 0;
|
||||||
|
@ -2148,9 +2149,10 @@ int FCEUX_PPU_Loop(int skip) {
|
||||||
const int yp = sl - 1;
|
const int yp = sl - 1;
|
||||||
ppuphase = PPUPHASE_BG;
|
ppuphase = PPUPHASE_BG;
|
||||||
|
|
||||||
if (sl != 0 && sl < 241) { // ignore the invisible
|
if (sl != 0 && sl < 241) // ignore the invisible
|
||||||
#ifdef WIN32
|
{
|
||||||
DEBUG(FCEUD_UpdatePPUView(scanline = yp, 1));
|
DEBUG(FCEUD_UpdatePPUView(scanline = yp, 1));
|
||||||
|
#ifdef WIN32
|
||||||
DEBUG(FCEUD_UpdateNTView(scanline = yp, 1));
|
DEBUG(FCEUD_UpdateNTView(scanline = yp, 1));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue