2020-10-03 15:46:14 +00:00
// ppuViewer.cpp
//
# include <stdio.h>
2020-10-04 13:54:51 +00:00
# include <stdint.h>
2020-10-03 15:46:14 +00:00
# include <QDir>
2020-10-20 03:21:00 +00:00
# include <QMenu>
# include <QAction>
2020-10-04 13:54:51 +00:00
# include <QPainter>
2020-10-03 15:46:14 +00:00
# include <QInputDialog>
# include <QMessageBox>
2020-10-04 13:54:51 +00:00
# include "../../types.h"
# include "../../fceu.h"
# include "../../cart.h"
# include "../../ppu.h"
# include "../../debug.h"
# include "../../palette.h"
2020-10-03 15:46:14 +00:00
# include "Qt/ppuViewer.h"
# include "Qt/main.h"
# include "Qt/dface.h"
# include "Qt/input.h"
# include "Qt/config.h"
# include "Qt/fceuWrapper.h"
2020-10-04 13:54:51 +00:00
# define PATTERNWIDTH 128
# define PATTERNHEIGHT 128
# define PATTERNBITWIDTH PATTERNWIDTH*3
# define PALETTEWIDTH 16
# define PALETTEHEIGHT 2
# define PALETTEBITWIDTH PALETTEWIDTH*3
2020-10-03 15:46:14 +00:00
static ppuViewerDialog_t * ppuViewWindow = NULL ;
2020-10-04 13:54:51 +00:00
static int PPUViewScanline = 0 ;
2020-10-05 03:23:27 +00:00
static int PPUViewSkip = 0 ;
static int PPUViewRefresh = 1 ;
2020-10-04 13:54:51 +00:00
static bool PPUView_maskUnusedGraphics = true ;
static bool PPUView_invertTheMask = false ;
2020-10-05 00:36:33 +00:00
static int PPUView_sprite16Mode [ 2 ] = { 0 , 0 } ;
2020-10-05 03:23:27 +00:00
static int pindex [ 2 ] = { 0 , 0 } ;
2020-10-04 13:54:51 +00:00
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
2020-10-06 22:40:14 +00:00
static bool redrawWindow = true ;
2020-10-04 13:54:51 +00:00
2020-10-05 03:23:27 +00:00
static void initPPUViewer ( void ) ;
2020-10-05 00:36:33 +00:00
static ppuPatternTable_t pattern0 ;
static ppuPatternTable_t pattern1 ;
2020-10-03 15:46:14 +00:00
//----------------------------------------------------
int openPPUViewWindow ( QWidget * parent )
{
if ( ppuViewWindow ! = NULL )
{
return - 1 ;
}
2020-10-05 03:23:27 +00:00
initPPUViewer ( ) ;
2020-10-03 15:46:14 +00:00
ppuViewWindow = new ppuViewerDialog_t ( parent ) ;
ppuViewWindow - > show ( ) ;
return 0 ;
}
//----------------------------------------------------
ppuViewerDialog_t : : ppuViewerDialog_t ( QWidget * parent )
2020-10-28 02:26:58 +00:00
: QDialog ( parent , Qt : : Window )
2020-10-03 15:46:14 +00:00
{
2020-10-04 23:17:11 +00:00
QVBoxLayout * mainLayout , * vbox ;
2020-10-05 00:36:33 +00:00
QVBoxLayout * patternVbox [ 2 ] ;
2020-10-04 23:17:11 +00:00
QHBoxLayout * hbox ;
QGridLayout * grid ;
2020-10-05 03:38:10 +00:00
char stmp [ 64 ] ;
2020-10-04 13:54:51 +00:00
2020-10-03 15:46:14 +00:00
ppuViewWindow = this ;
setWindowTitle ( tr ( " PPU Viewer " ) ) ;
2020-10-04 13:54:51 +00:00
mainLayout = new QVBoxLayout ( ) ;
setLayout ( mainLayout ) ;
2020-10-05 00:36:33 +00:00
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 " ) ) ;
2020-10-05 02:44:30 +00:00
tileLabel [ 0 ] = new QLabel ( tr ( " Tile: " ) ) ;
tileLabel [ 1 ] = new QLabel ( tr ( " Tile: " ) ) ;
2020-10-05 00:36:33 +00:00
sprite8x16Cbox [ 0 ] - > setChecked ( PPUView_sprite16Mode [ 0 ] ) ;
sprite8x16Cbox [ 1 ] - > setChecked ( PPUView_sprite16Mode [ 1 ] ) ;
2020-10-05 23:35:14 +00:00
patternVbox [ 0 ] - > addWidget ( patternView [ 0 ] , 100 ) ;
2020-10-05 00:36:33 +00:00
patternVbox [ 0 ] - > addWidget ( tileLabel [ 0 ] , 1 ) ;
patternVbox [ 0 ] - > addWidget ( sprite8x16Cbox [ 0 ] , 1 ) ;
2020-10-05 23:35:14 +00:00
patternVbox [ 1 ] - > addWidget ( patternView [ 1 ] , 100 ) ;
2020-10-05 00:36:33 +00:00
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 ) ;
2020-10-04 13:54:51 +00:00
2020-10-04 23:17:11 +00:00
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 ) ;
2020-10-05 00:36:33 +00:00
connect ( sprite8x16Cbox [ 0 ] , SIGNAL ( stateChanged ( int ) ) , this , SLOT ( sprite8x16Changed0 ( int ) ) ) ;
connect ( sprite8x16Cbox [ 1 ] , SIGNAL ( stateChanged ( int ) ) , this , SLOT ( sprite8x16Changed1 ( int ) ) ) ;
2020-10-04 23:17:11 +00:00
hbox = new QHBoxLayout ( ) ;
refreshSlider = new QSlider ( Qt : : Horizontal ) ;
hbox - > addWidget ( new QLabel ( tr ( " Refresh: More " ) ) ) ;
hbox - > addWidget ( refreshSlider ) ;
hbox - > addWidget ( new QLabel ( tr ( " Less " ) ) ) ;
2020-10-05 00:36:33 +00:00
grid - > addWidget ( maskUnusedCbox , 0 , 0 , Qt : : AlignLeft ) ;
grid - > addWidget ( invertMaskCbox , 1 , 0 , Qt : : AlignLeft ) ;
grid - > addLayout ( hbox , 0 , 1 , Qt : : AlignRight ) ;
2020-10-04 23:17:11 +00:00
hbox = new QHBoxLayout ( ) ;
scanLineEdit = new QLineEdit ( ) ;
hbox - > addWidget ( new QLabel ( tr ( " Display on Scanline: " ) ) ) ;
hbox - > addWidget ( scanLineEdit ) ;
2020-10-05 00:36:33 +00:00
grid - > addLayout ( hbox , 1 , 1 , Qt : : AlignRight ) ;
2020-10-04 23:17:11 +00:00
vbox = new QVBoxLayout ( ) ;
paletteFrame = new QGroupBox ( tr ( " Palettes: " ) ) ;
paletteView = new ppuPalatteView_t ( this ) ;
vbox - > addWidget ( paletteView , 1 ) ;
paletteFrame - > setLayout ( vbox ) ;
mainLayout - > addWidget ( paletteFrame , 1 ) ;
2020-10-04 13:54:51 +00:00
2020-10-05 00:36:33 +00:00
patternView [ 0 ] - > setPattern ( & pattern0 ) ;
patternView [ 1 ] - > setPattern ( & pattern1 ) ;
2020-10-05 02:44:30 +00:00
patternView [ 0 ] - > setTileLabel ( tileLabel [ 0 ] ) ;
patternView [ 1 ] - > setTileLabel ( tileLabel [ 1 ] ) ;
2020-10-06 00:02:16 +00:00
paletteView - > setTileLabel ( paletteFrame ) ;
2020-10-05 00:36:33 +00:00
2020-10-05 03:38:10 +00:00
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 & ) ) ) ;
2020-10-05 03:23:27 +00:00
refreshSlider - > setMinimum ( 0 ) ;
refreshSlider - > setMaximum ( 25 ) ;
refreshSlider - > setValue ( PPUViewRefresh ) ;
connect ( refreshSlider , SIGNAL ( valueChanged ( int ) ) , this , SLOT ( refreshSliderChanged ( int ) ) ) ;
2020-10-04 13:54:51 +00:00
FCEUD_UpdatePPUView ( - 1 , 1 ) ;
2020-10-06 22:40:14 +00:00
updateTimer = new QTimer ( this ) ;
connect ( updateTimer , & QTimer : : timeout , this , & ppuViewerDialog_t : : periodicUpdate ) ;
updateTimer - > start ( 33 ) ; // 30hz
2020-10-03 15:46:14 +00:00
}
//----------------------------------------------------
ppuViewerDialog_t : : ~ ppuViewerDialog_t ( void )
{
2020-10-06 22:40:14 +00:00
updateTimer - > stop ( ) ;
2020-10-03 15:46:14 +00:00
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 ( ) ;
}
//----------------------------------------------------
2020-10-06 22:40:14 +00:00
void ppuViewerDialog_t : : periodicUpdate ( void )
{
if ( redrawWindow )
{
this - > update ( ) ;
redrawWindow = false ;
}
}
//----------------------------------------------------
2020-10-05 03:38:10 +00:00
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 );
}
//----------------------------------------------------
2020-10-05 00:36:33 +00:00
void ppuViewerDialog_t : : sprite8x16Changed0 ( int state )
2020-10-04 23:17:11 +00:00
{
2020-10-05 00:36:33 +00:00
PPUView_sprite16Mode [ 0 ] = ( state = = Qt : : Unchecked ) ? 0 : 1 ;
2020-10-04 23:17:11 +00:00
}
//----------------------------------------------------
2020-10-05 00:36:33 +00:00
void ppuViewerDialog_t : : sprite8x16Changed1 ( int state )
{
PPUView_sprite16Mode [ 1 ] = ( state = = Qt : : Unchecked ) ? 0 : 1 ;
}
//----------------------------------------------------
2020-10-05 03:23:27 +00:00
void ppuViewerDialog_t : : refreshSliderChanged ( int value )
{
PPUViewRefresh = value ;
}
//----------------------------------------------------
2020-10-05 00:36:33 +00:00
ppuPatternView_t : : ppuPatternView_t ( int patternIndexID , QWidget * parent )
2020-10-04 13:54:51 +00:00
: QWidget ( parent )
{
2020-10-05 02:44:30 +00:00
this - > setFocusPolicy ( Qt : : StrongFocus ) ;
this - > setMouseTracking ( true ) ;
2020-10-05 00:36:33 +00:00
patternIndex = patternIndexID ;
setMinimumWidth ( 256 ) ;
2020-10-04 13:54:51 +00:00
setMinimumHeight ( 256 ) ;
2020-10-05 02:44:30 +00:00
viewWidth = 256 ;
viewHeight = 256 ;
tileLabel = NULL ;
2020-10-20 03:21:00 +00:00
mode = 0 ;
drawTileGrid = true ;
2020-10-04 13:54:51 +00:00
}
//----------------------------------------------------
2020-10-05 00:36:33 +00:00
void ppuPatternView_t : : setPattern ( ppuPatternTable_t * p )
{
pattern = p ;
}
//----------------------------------------------------
2020-10-05 02:44:30 +00:00
void ppuPatternView_t : : setTileLabel ( QLabel * l )
{
tileLabel = l ;
}
//----------------------------------------------------
2020-10-04 13:54:51 +00:00
ppuPatternView_t : : ~ ppuPatternView_t ( void )
{
2020-10-05 02:44:30 +00:00
}
//----------------------------------------------------
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 ;
}
//----------------------------------------------------
2020-10-20 03:21:00 +00:00
void ppuPatternView_t : : keyPressEvent ( QKeyEvent * event )
2020-10-05 02:44:30 +00:00
{
2020-10-20 03:21:00 +00:00
//printf("Pattern View Key Press: 0x%x \n", event->key() );
if ( event - > key ( ) = = Qt : : Key_Z )
{
mode = ! mode ;
}
else if ( event - > key ( ) = = Qt : : Key_G )
{
if ( mode )
{
drawTileGrid = ! drawTileGrid ;
}
}
else if ( event - > key ( ) = = Qt : : Key_P )
{
pindex [ patternIndex ] = ( pindex [ patternIndex ] + 1 ) % 9 ;
2020-10-05 02:44:30 +00:00
2020-10-20 03:21:00 +00:00
PPUViewSkip = 100 ;
FCEUD_UpdatePPUView ( - 1 , 0 ) ;
}
}
//----------------------------------------------------
void ppuPatternView_t : : mouseMoveEvent ( QMouseEvent * event )
{
if ( mode = = 0 )
{
QPoint tile = convPixToTile ( event - > pos ( ) ) ;
if ( ( tile . x ( ) < 16 ) & & ( tile . y ( ) < 16 ) )
{
char stmp [ 64 ] ;
sprintf ( stmp , " Tile: $%X%X " , tile . y ( ) , tile . x ( ) ) ;
tileLabel - > setText ( tr ( stmp ) ) ;
selTile = tile ;
}
2020-10-05 23:35:14 +00:00
}
2020-10-04 13:54:51 +00:00
}
2020-10-05 03:23:27 +00:00
//----------------------------------------------------------------------------
void ppuPatternView_t : : mousePressEvent ( QMouseEvent * event )
{
//QPoint tile = convPixToTile( event->pos() );
if ( event - > button ( ) = = Qt : : LeftButton )
{
2020-10-06 00:02:16 +00:00
// Load Tile Viewport
PPUViewSkip = 100 ;
FCEUD_UpdatePPUView ( - 1 , 0 ) ;
2020-10-05 03:23:27 +00:00
}
2020-10-20 03:21:00 +00:00
}
//----------------------------------------------------
void ppuPatternView_t : : contextMenuEvent ( QContextMenuEvent * event )
{
QAction * act ;
QMenu menu ( this ) ;
QMenu * subMenu ;
QActionGroup * group ;
QAction * paletteAct [ 9 ] ;
char stmp [ 64 ] ;
if ( mode )
{
sprintf ( stmp , " Exit Tile View: %X%X " , selTile . y ( ) , selTile . x ( ) ) ;
act = new QAction ( tr ( stmp ) , & menu ) ;
2020-10-20 03:34:28 +00:00
act - > setShortcut ( QKeySequence ( tr ( " Z " ) ) ) ;
2020-10-20 03:21:00 +00:00
connect ( act , SIGNAL ( triggered ( void ) ) , this , SLOT ( exitTileMode ( void ) ) ) ;
menu . addAction ( act ) ;
act = new QAction ( tr ( " Draw Tile Grid Lines " ) , & menu ) ;
act - > setCheckable ( true ) ;
act - > setChecked ( drawTileGrid ) ;
2020-10-20 03:34:28 +00:00
act - > setShortcut ( QKeySequence ( tr ( " G " ) ) ) ;
2020-10-20 03:21:00 +00:00
connect ( act , SIGNAL ( triggered ( void ) ) , this , SLOT ( toggleTileGridLines ( void ) ) ) ;
menu . addAction ( act ) ;
}
else
{
sprintf ( stmp , " View Tile: %X%X " , selTile . y ( ) , selTile . x ( ) ) ;
act = new QAction ( tr ( stmp ) , & menu ) ;
2020-10-20 03:34:28 +00:00
act - > setShortcut ( QKeySequence ( tr ( " Z " ) ) ) ;
2020-10-20 03:21:00 +00:00
connect ( act , SIGNAL ( triggered ( void ) ) , this , SLOT ( showTileMode ( void ) ) ) ;
menu . addAction ( act ) ;
}
2020-10-20 03:34:28 +00:00
act = new QAction ( tr ( " Next Palette " ) , & menu ) ;
act - > setShortcut ( QKeySequence ( tr ( " P " ) ) ) ;
connect ( act , SIGNAL ( triggered ( void ) ) , this , SLOT ( cycleNextPalette ( void ) ) ) ;
menu . addAction ( act ) ;
2020-10-20 03:21:00 +00:00
subMenu = menu . addMenu ( tr ( " Palette Select " ) ) ;
2020-10-22 00:31:39 +00:00
group = new QActionGroup ( & menu ) ;
2020-10-20 03:21:00 +00:00
group - > setExclusive ( true ) ;
for ( int i = 0 ; i < 9 ; i + + )
2020-10-05 03:23:27 +00:00
{
2020-10-20 03:21:00 +00:00
char stmp [ 8 ] ;
2020-10-06 00:02:16 +00:00
2020-10-20 03:21:00 +00:00
sprintf ( stmp , " %i " , i + 1 ) ;
2020-10-06 00:02:16 +00:00
2020-10-20 03:21:00 +00:00
paletteAct [ i ] = new QAction ( tr ( stmp ) , & menu ) ;
paletteAct [ i ] - > setCheckable ( true ) ;
group - > addAction ( paletteAct [ i ] ) ;
subMenu - > addAction ( paletteAct [ i ] ) ;
paletteAct [ i ] - > setChecked ( pindex [ patternIndex ] = = i ) ;
2020-10-05 03:23:27 +00:00
}
2020-10-20 03:21:00 +00:00
connect ( paletteAct [ 0 ] , SIGNAL ( triggered ( void ) ) , this , SLOT ( selPalette0 ( void ) ) ) ;
connect ( paletteAct [ 1 ] , SIGNAL ( triggered ( void ) ) , this , SLOT ( selPalette1 ( void ) ) ) ;
connect ( paletteAct [ 2 ] , SIGNAL ( triggered ( void ) ) , this , SLOT ( selPalette2 ( void ) ) ) ;
connect ( paletteAct [ 3 ] , SIGNAL ( triggered ( void ) ) , this , SLOT ( selPalette3 ( void ) ) ) ;
connect ( paletteAct [ 4 ] , SIGNAL ( triggered ( void ) ) , this , SLOT ( selPalette4 ( void ) ) ) ;
connect ( paletteAct [ 5 ] , SIGNAL ( triggered ( void ) ) , this , SLOT ( selPalette5 ( void ) ) ) ;
connect ( paletteAct [ 6 ] , SIGNAL ( triggered ( void ) ) , this , SLOT ( selPalette6 ( void ) ) ) ;
connect ( paletteAct [ 7 ] , SIGNAL ( triggered ( void ) ) , this , SLOT ( selPalette7 ( void ) ) ) ;
connect ( paletteAct [ 8 ] , SIGNAL ( triggered ( void ) ) , this , SLOT ( selPalette8 ( void ) ) ) ;
menu . exec ( event - > globalPos ( ) ) ;
}
//----------------------------------------------------
void ppuPatternView_t : : toggleTileGridLines ( void )
{
drawTileGrid = ! drawTileGrid ;
}
//----------------------------------------------------
void ppuPatternView_t : : showTileMode ( void )
{
mode = 1 ;
}
//----------------------------------------------------
void ppuPatternView_t : : exitTileMode ( void )
{
mode = 0 ;
}
//----------------------------------------------------
2020-10-20 03:34:28 +00:00
void ppuPatternView_t : : cycleNextPalette ( void )
{
pindex [ patternIndex ] = ( pindex [ patternIndex ] + 1 ) % 9 ;
PPUViewSkip = 100 ;
FCEUD_UpdatePPUView ( - 1 , 0 ) ;
}
//----------------------------------------------------
2020-10-20 03:21:00 +00:00
void ppuPatternView_t : : selPalette0 ( void )
{
pindex [ patternIndex ] = 0 ;
}
//----------------------------------------------------
void ppuPatternView_t : : selPalette1 ( void )
{
pindex [ patternIndex ] = 1 ;
}
//----------------------------------------------------
void ppuPatternView_t : : selPalette2 ( void )
{
pindex [ patternIndex ] = 2 ;
}
//----------------------------------------------------
void ppuPatternView_t : : selPalette3 ( void )
{
pindex [ patternIndex ] = 3 ;
}
//----------------------------------------------------
void ppuPatternView_t : : selPalette4 ( void )
{
pindex [ patternIndex ] = 4 ;
}
//----------------------------------------------------
void ppuPatternView_t : : selPalette5 ( void )
{
pindex [ patternIndex ] = 5 ;
}
//----------------------------------------------------
void ppuPatternView_t : : selPalette6 ( void )
{
pindex [ patternIndex ] = 6 ;
}
//----------------------------------------------------
void ppuPatternView_t : : selPalette7 ( void )
{
pindex [ patternIndex ] = 7 ;
}
//----------------------------------------------------
void ppuPatternView_t : : selPalette8 ( void )
{
pindex [ patternIndex ] = 8 ;
2020-10-05 03:23:27 +00:00
}
2020-10-04 13:54:51 +00:00
//----------------------------------------------------
void ppuPatternView_t : : paintEvent ( QPaintEvent * event )
{
2020-10-05 02:07:33 +00:00
int i , j , x , y , w , h , xx , yy , ii , jj , rr ;
2020-10-04 13:54:51 +00:00
QPainter painter ( this ) ;
2020-10-05 02:44:30 +00:00
viewWidth = event - > rect ( ) . width ( ) ;
viewHeight = event - > rect ( ) . height ( ) ;
2020-10-04 13:54:51 +00:00
//printf("PPU PatternView %ix%i \n", viewWidth, viewHeight );
2020-10-05 00:36:33 +00:00
w = viewWidth / 128 ;
2020-10-04 13:54:51 +00:00
h = viewHeight / 128 ;
2020-10-05 02:07:33 +00:00
pattern - > w = w ;
pattern - > h = h ;
2020-10-04 13:54:51 +00:00
xx = 0 ; yy = 0 ;
2020-10-20 03:21:00 +00:00
if ( mode = = 1 )
{
w = viewWidth / 8 ;
h = viewHeight / 8 ;
if ( w < h )
{
h = w ;
}
else
{
w = h ;
}
ii = selTile . x ( ) ;
jj = selTile . y ( ) ;
// Draw Tile Pixels as rectangles
for ( x = 0 ; x < 8 ; x + + )
{
yy = 0 ;
for ( y = 0 ; y < 8 ; y + + )
{
painter . fillRect ( xx , yy , w , h , pattern - > tile [ jj ] [ ii ] . pixel [ y ] [ x ] . color ) ;
yy + = h ;
}
xx + = w ;
}
if ( drawTileGrid )
{
// Draw Tile Pixel grid lines
xx = 0 ; y = 8 * h ;
for ( x = 0 ; x < 9 ; x + + )
{
painter . drawLine ( xx , 0 , xx , y ) ; xx + = w ;
}
yy = 0 ; x = 8 * w ;
for ( y = 0 ; y < 9 ; y + + )
{
painter . drawLine ( 0 , yy , x , yy ) ; yy + = h ;
}
}
}
else if ( PPUView_sprite16Mode [ patternIndex ] )
2020-10-04 13:54:51 +00:00
{
2020-10-05 02:07:33 +00:00
for ( i = 0 ; i < 16 ; i + + ) //Columns
2020-10-04 13:54:51 +00:00
{
2020-10-05 02:07:33 +00:00
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 + + ;
}
2020-10-04 13:54:51 +00:00
2020-10-05 02:07:33 +00:00
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
2020-10-04 13:54:51 +00:00
{
2020-10-05 02:07:33 +00:00
xx = ( i * 8 ) * w ;
2020-10-04 13:54:51 +00:00
2020-10-05 02:07:33 +00:00
for ( x = 0 ; x < 8 ; x + + )
2020-10-04 13:54:51 +00:00
{
2020-10-05 02:07:33 +00:00
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 ;
2020-10-04 13:54:51 +00:00
}
}
}
}
}
//----------------------------------------------------
2020-10-05 03:23:27 +00:00
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 ;
}
//----------------------------------------------------
2020-10-05 00:36:33 +00:00
static void DrawPatternTable ( ppuPatternTable_t * pattern , uint8_t * table , uint8_t * log , uint8_t pal )
2020-10-04 13:54:51 +00:00
{
2020-10-04 23:17:11 +00:00
int i , j , x , y , index = 0 ;
2020-10-04 13:54:51 +00:00
int p = 0 , tmp ;
uint8_t chr0 , chr1 , logs , shift ;
pal < < = 2 ;
2020-10-04 23:17:11 +00:00
for ( i = 0 ; i < 16 ; i + + ) //Columns
2020-10-04 13:54:51 +00:00
{
for ( j = 0 ; j < 16 ; j + + ) //Rows
{
//printf("Tile: %X%X index:%04X %04X\n", j,i,index, (i<<4)|(j<<8));
//-----------------------------------------------
2020-10-04 23:17:11 +00:00
for ( y = 0 ; y < 8 ; y + + )
2020-10-04 13:54:51 +00:00
{
2020-10-04 23:17:11 +00:00
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 + + )
2020-10-04 13:54:51 +00:00
{
2020-10-04 23:17:11 +00:00
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() );
2020-10-04 13:54:51 +00:00
}
2020-10-04 23:17:11 +00:00
index + + ;
2020-10-04 13:54:51 +00:00
}
2020-10-04 23:17:11 +00:00
index + = 8 ;
2020-10-04 13:54:51 +00:00
//------------------------------------------------
}
}
}
//----------------------------------------------------
void FCEUD_UpdatePPUView ( int scanline , int refreshchr )
{
if ( ppuViewWindow = = NULL )
{
return ;
}
if ( ( scanline ! = - 1 ) & & ( scanline ! = PPUViewScanline ) )
{
return ;
}
int x , y , i ;
if ( refreshchr )
{
2020-10-07 00:08:17 +00:00
int i10 , x10 ;
2020-10-04 13:54:51 +00:00
for ( i = 0 , x = 0x1000 ; i < 0x1000 ; i + + , x + + )
{
2020-10-07 00:08:17 +00:00
i10 = i > > 10 ;
x10 = x > > 10 ;
if ( VPage [ i10 ] = = NULL )
{
continue ;
}
chrcache0 [ i ] = VPage [ i10 ] [ i ] ;
chrcache1 [ i ] = VPage [ x10 ] [ x ] ;
2020-10-04 13:54:51 +00:00
if ( debug_loggingCD )
{
if ( cdloggerVideoDataSize )
{
int addr ;
2020-10-07 00:08:17 +00:00
addr = & VPage [ i10 ] [ i ] - CHRptr [ 0 ] ;
2020-10-04 13:54:51 +00:00
if ( ( addr > = 0 ) & & ( addr < ( int ) cdloggerVideoDataSize ) )
logcache0 [ i ] = cdloggervdata [ addr ] ;
2020-10-07 00:08:17 +00:00
addr = & VPage [ x10 ] [ x ] - CHRptr [ 0 ] ;
2020-10-04 13:54:51 +00:00
if ( ( addr > = 0 ) & & ( addr < ( int ) cdloggerVideoDataSize ) )
logcache1 [ i ] = cdloggervdata [ addr ] ;
}
else
{
logcache0 [ i ] = cdloggervdata [ i ] ;
logcache1 [ i ] = cdloggervdata [ x ] ;
}
}
}
}
2020-10-05 03:23:27 +00:00
if ( PPUViewSkip < PPUViewRefresh )
{
PPUViewSkip + + ;
return ;
}
PPUViewSkip = 0 ;
2020-10-04 13:54:51 +00:00
// 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 ) ;
}
}
}
2020-10-05 03:23:27 +00:00
DrawPatternTable ( & pattern0 , chrcache0 , logcache0 , pindex [ 0 ] ) ;
DrawPatternTable ( & pattern1 , chrcache1 , logcache1 , pindex [ 1 ] ) ;
2020-10-04 13:54:51 +00:00
2020-10-06 22:40:14 +00:00
redrawWindow = true ;
2020-10-04 13:54:51 +00:00
}
//----------------------------------------------------
ppuPalatteView_t : : ppuPalatteView_t ( QWidget * parent )
: QWidget ( parent )
{
2020-10-06 00:02:16 +00:00
this - > setFocusPolicy ( Qt : : StrongFocus ) ;
this - > setMouseTracking ( true ) ;
setMinimumWidth ( 32 * PALETTEWIDTH ) ;
2020-10-04 13:54:51 +00:00
setMinimumHeight ( 32 * PALETTEHEIGHT ) ;
2020-10-06 00:02:16 +00:00
viewWidth = 32 * PALETTEWIDTH ;
viewHeight = 32 * PALETTEHEIGHT ;
boxWidth = viewWidth / PALETTEWIDTH ;
boxHeight = viewHeight / PALETTEHEIGHT ;
frame = NULL ;
2020-10-04 13:54:51 +00:00
}
//----------------------------------------------------
ppuPalatteView_t : : ~ ppuPalatteView_t ( void )
{
2020-10-06 00:02:16 +00:00
}
//----------------------------------------------------
void ppuPalatteView_t : : setTileLabel ( QGroupBox * l )
{
frame = l ;
}
//----------------------------------------------------
QPoint ppuPalatteView_t : : convPixToTile ( QPoint p )
{
QPoint t ( 0 , 0 ) ;
t . setX ( p . x ( ) / boxWidth ) ;
t . setY ( p . y ( ) / boxHeight ) ;
return t ;
}
//----------------------------------------------------
void ppuPalatteView_t : : resizeEvent ( QResizeEvent * event )
{
viewWidth = event - > size ( ) . width ( ) ;
viewHeight = event - > size ( ) . height ( ) ;
boxWidth = viewWidth / PALETTEWIDTH ;
boxHeight = viewHeight / PALETTEHEIGHT ;
}
//----------------------------------------------------
void ppuPalatteView_t : : mouseMoveEvent ( QMouseEvent * event )
{
QPoint tile = convPixToTile ( event - > pos ( ) ) ;
if ( ( tile . x ( ) < PALETTEWIDTH ) & & ( tile . y ( ) < PALETTEHEIGHT ) )
{
char stmp [ 64 ] ;
int ix = ( tile . y ( ) < < 4 ) | tile . x ( ) ;
sprintf ( stmp , " Palette: $%02X " , palcache [ ix ] ) ;
frame - > setTitle ( tr ( stmp ) ) ;
}
}
//----------------------------------------------------------------------------
void ppuPalatteView_t : : mousePressEvent ( QMouseEvent * event )
{
//QPoint tile = convPixToTile( event->pos() );
//if ( event->button() == Qt::LeftButton )
//{
//}
//else if ( event->button() == Qt::RightButton )
//{
//}
2020-10-04 13:54:51 +00:00
}
//----------------------------------------------------
void ppuPalatteView_t : : paintEvent ( QPaintEvent * event )
{
int x , y , w , h , xx , yy ;
QPainter painter ( this ) ;
2020-10-06 00:02:16 +00:00
viewWidth = event - > rect ( ) . width ( ) ;
viewHeight = event - > rect ( ) . height ( ) ;
2020-10-04 13:54:51 +00:00
//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 ;
}
2020-10-05 03:23:27 +00:00
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 ) ;
}
2020-10-04 13:54:51 +00:00
}
//----------------------------------------------------