2015-08-14 21:50:14 -04:00
# pragma once
# include "stdafx.h"
# include "PPU.h"
2018-02-17 23:44:25 -05:00
# include "CPU.h"
2015-08-14 21:50:14 -04:00
# include "HdNesPack.h"
2015-08-30 21:04:21 -04:00
# include "VideoDecoder.h"
2017-04-28 19:54:58 -04:00
# include "RewindManager.h"
2018-03-14 23:25:06 -04:00
# include "HdPackConditions.h"
2015-08-14 21:50:14 -04:00
2017-11-19 23:08:23 -05:00
class ControlManager ;
2015-08-14 21:50:14 -04:00
class HdPpu : public PPU
{
private :
2018-02-17 23:44:25 -05:00
HdScreenInfo * _screenInfo [ 2 ] ;
HdScreenInfo * _info ;
2017-07-25 19:46:25 -04:00
uint32_t _version ;
2018-02-17 23:44:25 -05:00
HdPackData * _hdData = nullptr ;
2015-08-14 21:50:14 -04:00
protected :
void DrawPixel ( )
{
uint16_t bufferOffset = ( _scanline < < 8 ) + _cycle - 1 ;
2015-08-30 21:04:21 -04:00
uint16_t & pixel = _currentOutputBuffer [ bufferOffset ] ;
2015-08-14 21:50:14 -04:00
_lastSprite = nullptr ;
if ( IsRenderingEnabled ( ) | | ( ( _state . VideoRamAddr & 0x3F00 ) ! = 0x3F00 ) ) {
2018-07-01 15:21:05 -04:00
bool isChrRam = ! _console - > GetMapper ( ) - > HasChrRom ( ) ;
BaseMapper * mapper = _console - > GetMapper ( ) ;
2017-03-31 22:14:16 -04:00
uint32_t color = GetPixelColor ( ) ;
pixel = ( _paletteRAM [ color & 0x03 ? color : 0 ] & _paletteRamMask ) | _intensifyColorBits ;
2015-08-14 21:50:14 -04:00
2017-06-28 19:00:08 -04:00
TileInfo * lastTile = & ( ( _state . XScroll + ( ( _cycle - 1 ) & 0x07 ) < 8 ) ? _previousTile : _currentTile ) ;
uint32_t backgroundColor = 0 ;
if ( _flags . BackgroundEnabled & & _cycle > _minimumDrawBgCycle ) {
backgroundColor = ( ( ( _state . LowBitShift < < _state . XScroll ) & 0x8000 ) > > 15 ) | ( ( ( _state . HighBitShift < < _state . XScroll ) & 0x8000 ) > > 14 ) ;
}
2018-02-17 23:44:25 -05:00
HdPpuPixelInfo & tileInfo = _info - > ScreenTiles [ bufferOffset ] ;
2017-07-25 19:46:25 -04:00
2018-03-11 22:42:32 -04:00
tileInfo . Grayscale = _paletteRamMask = = 0x30 ;
tileInfo . EmphasisBits = _intensifyColorBits > > 6 ;
2017-07-25 19:46:25 -04:00
tileInfo . Tile . PpuBackgroundColor = ReadPaletteRAM ( 0 ) ;
tileInfo . Tile . BgColorIndex = backgroundColor ;
if ( backgroundColor = = 0 ) {
tileInfo . Tile . BgColor = tileInfo . Tile . PpuBackgroundColor ;
} else {
tileInfo . Tile . BgColor = ReadPaletteRAM ( lastTile - > PaletteOffset + backgroundColor ) ;
}
2018-02-17 23:44:25 -05:00
tileInfo . XScroll = _state . XScroll ;
tileInfo . TmpVideoRamAddr = _state . TmpVideoRamAddr ;
2017-03-26 09:27:41 -04:00
if ( _lastSprite & & _flags . SpritesEnabled ) {
2017-07-25 19:46:25 -04:00
int j = 0 ;
for ( uint8_t i = 0 ; i < _spriteCount ; i + + ) {
int32_t shift = ( int32_t ) _cycle - _spriteTiles [ i ] . SpriteX - 1 ;
SpriteInfo & sprite = _spriteTiles [ i ] ;
if ( shift > = 0 & & shift < 8 ) {
tileInfo . Sprite [ j ] . TileIndex = sprite . AbsoluteTileAddr / 16 ;
2018-07-01 15:21:05 -04:00
if ( isChrRam ) {
mapper - > CopyChrRamTile ( sprite . AbsoluteTileAddr & 0xFFFFFFF0 , tileInfo . Sprite [ j ] . TileData ) ;
2017-12-18 20:02:25 -05:00
}
2017-07-25 19:46:25 -04:00
if ( _version > = 100 ) {
2017-12-18 20:02:25 -05:00
tileInfo . Sprite [ j ] . PaletteColors = 0xFF000000 | _paletteRAM [ sprite . PaletteOffset + 3 ] | ( _paletteRAM [ sprite . PaletteOffset + 2 ] < < 8 ) | ( _paletteRAM [ sprite . PaletteOffset + 1 ] < < 16 ) ;
2017-07-25 19:46:25 -04:00
} else {
2017-12-18 20:02:25 -05:00
tileInfo . Sprite [ j ] . PaletteColors = _paletteRAM [ sprite . PaletteOffset + 3 ] | ( _paletteRAM [ sprite . PaletteOffset + 2 ] < < 8 ) | ( _paletteRAM [ sprite . PaletteOffset + 1 ] < < 16 ) ;
2017-07-25 19:46:25 -04:00
}
2017-12-18 20:02:25 -05:00
if ( sprite . OffsetY > = 8 ) {
tileInfo . Sprite [ j ] . OffsetY = sprite . OffsetY - 8 ;
} else {
tileInfo . Sprite [ j ] . OffsetY = sprite . OffsetY ;
2017-07-25 19:46:25 -04:00
}
2018-02-17 23:44:25 -05:00
2017-07-25 19:46:25 -04:00
tileInfo . Sprite [ j ] . OffsetX = shift ;
tileInfo . Sprite [ j ] . HorizontalMirroring = sprite . HorizontalMirror ;
tileInfo . Sprite [ j ] . VerticalMirroring = sprite . VerticalMirror ;
tileInfo . Sprite [ j ] . BackgroundPriority = sprite . BackgroundPriority ;
2015-08-14 21:50:14 -04:00
2017-07-25 19:46:25 -04:00
int32_t shift = ( int32_t ) _cycle - sprite . SpriteX - 1 ;
if ( sprite . HorizontalMirror ) {
tileInfo . Sprite [ j ] . SpriteColorIndex = ( ( sprite . LowByte > > shift ) & 0x01 ) | ( ( sprite . HighByte > > shift ) & 0x01 ) < < 1 ;
} else {
tileInfo . Sprite [ j ] . SpriteColorIndex = ( ( sprite . LowByte < < shift ) & 0x80 ) > > 7 | ( ( sprite . HighByte < < shift ) & 0x80 ) > > 6 ;
}
2017-06-28 19:00:08 -04:00
2017-07-25 19:46:25 -04:00
if ( tileInfo . Sprite [ j ] . SpriteColorIndex = = 0 ) {
tileInfo . Sprite [ j ] . SpriteColor = ReadPaletteRAM ( 0 ) ;
} else {
tileInfo . Sprite [ j ] . SpriteColor = ReadPaletteRAM ( sprite . PaletteOffset + tileInfo . Sprite [ j ] . SpriteColorIndex ) ;
}
2015-08-14 21:50:14 -04:00
2017-07-25 19:46:25 -04:00
tileInfo . Sprite [ j ] . PpuBackgroundColor = tileInfo . Tile . PpuBackgroundColor ;
tileInfo . Sprite [ j ] . BgColorIndex = tileInfo . Tile . BgColorIndex ;
j + + ;
if ( j > = 4 ) {
break ;
}
}
2015-08-14 21:50:14 -04:00
}
2017-07-25 19:46:25 -04:00
tileInfo . SpriteCount = j ;
2015-08-14 21:50:14 -04:00
} else {
2017-07-25 19:46:25 -04:00
tileInfo . SpriteCount = 0 ;
2015-08-14 21:50:14 -04:00
}
2017-06-28 19:00:08 -04:00
if ( _flags . BackgroundEnabled & & _cycle > _minimumDrawBgCycle ) {
2017-07-25 19:46:25 -04:00
tileInfo . Tile . TileIndex = lastTile - > AbsoluteTileAddr / 16 ;
2018-07-01 15:21:05 -04:00
if ( isChrRam ) {
mapper - > CopyChrRamTile ( lastTile - > AbsoluteTileAddr & 0xFFFFFFF0 , tileInfo . Tile . TileData ) ;
2017-12-18 20:02:25 -05:00
}
2017-07-25 19:46:25 -04:00
if ( _version > = 100 ) {
2017-12-18 20:02:25 -05:00
tileInfo . Tile . PaletteColors = _paletteRAM [ lastTile - > PaletteOffset + 3 ] | ( _paletteRAM [ lastTile - > PaletteOffset + 2 ] < < 8 ) | ( _paletteRAM [ lastTile - > PaletteOffset + 1 ] < < 16 ) | ( _paletteRAM [ 0 ] < < 24 ) ;
2017-07-25 19:46:25 -04:00
} else {
2017-12-18 20:02:25 -05:00
tileInfo . Tile . PaletteColors = _paletteRAM [ lastTile - > PaletteOffset + 3 ] | ( _paletteRAM [ lastTile - > PaletteOffset + 2 ] < < 8 ) | ( _paletteRAM [ lastTile - > PaletteOffset + 1 ] < < 16 ) ;
2017-07-25 19:46:25 -04:00
}
2017-03-26 09:27:41 -04:00
tileInfo . Tile . OffsetY = lastTile - > OffsetY ;
tileInfo . Tile . OffsetX = ( _state . XScroll + ( ( _cycle - 1 ) & 0x07 ) ) & 0x07 ;
} else {
tileInfo . Tile . TileIndex = HdPpuTileInfo : : NoTile ;
}
2015-08-14 21:50:14 -04:00
} else {
//"If the current VRAM address points in the range $3F00-$3FFF during forced blanking, the color indicated by this palette location will be shown on screen instead of the backdrop color."
pixel = ReadPaletteRAM ( _state . VideoRamAddr ) | _intensifyColorBits ;
2018-02-17 23:44:25 -05:00
_info - > ScreenTiles [ bufferOffset ] . Tile . TileIndex = HdPpuTileInfo : : NoTile ;
_info - > ScreenTiles [ bufferOffset ] . SpriteCount = 0 ;
2015-08-14 21:50:14 -04:00
}
}
public :
2018-07-01 15:21:05 -04:00
HdPpu ( shared_ptr < Console > console , HdPackData * hdData ) : PPU ( console )
2015-08-14 21:50:14 -04:00
{
2018-02-17 23:44:25 -05:00
_hdData = hdData ;
_version = _hdData - > Version ;
2018-07-01 15:21:05 -04:00
_screenInfo [ 0 ] = new HdScreenInfo ( ) ;
_screenInfo [ 1 ] = new HdScreenInfo ( ) ;
2018-02-17 23:44:25 -05:00
_info = _screenInfo [ 0 ] ;
2015-08-14 21:50:14 -04:00
}
~ HdPpu ( )
{
2018-02-17 23:44:25 -05:00
delete _screenInfo [ 0 ] ;
delete _screenInfo [ 1 ] ;
2015-08-14 21:50:14 -04:00
}
void SendFrame ( )
{
2017-04-28 19:54:58 -04:00
MessageManager : : SendNotification ( ConsoleNotificationType : : PpuFrameDone , _currentOutputBuffer ) ;
2018-02-17 23:44:25 -05:00
_info - > FrameNumber = _frameCount ;
_info - > WatchedAddressValues . clear ( ) ;
2018-03-14 23:25:06 -04:00
for ( uint32_t address : _hdData - > WatchedMemoryAddresses ) {
if ( address & HdPackBaseMemoryCondition : : PpuMemoryMarker ) {
if ( ( address & 0x3FFF ) > = 0x3F00 ) {
_info - > WatchedAddressValues [ address ] = ReadPaletteRAM ( address ) ;
} else {
2018-07-01 15:21:05 -04:00
_info - > WatchedAddressValues [ address ] = _console - > GetMapper ( ) - > DebugReadVRAM ( address & 0x3FFF , true ) ;
2018-03-14 23:25:06 -04:00
}
} else {
2018-07-01 15:21:05 -04:00
_info - > WatchedAddressValues [ address ] = _console - > GetMemoryManager ( ) - > DebugRead ( address ) ;
2018-03-14 23:25:06 -04:00
}
2018-02-17 23:44:25 -05:00
}
2018-01-04 19:03:47 -05:00
# ifdef LIBRETRO
2018-07-01 15:21:05 -04:00
_console - > GetVideoDecoder ( ) - > UpdateFrameSync ( _currentOutputBuffer , _info ) ;
2018-01-04 19:03:47 -05:00
# else
2018-07-01 15:21:05 -04:00
if ( _console - > GetRewindManager ( ) - > IsRewinding ( ) ) {
_console - > GetVideoDecoder ( ) - > UpdateFrameSync ( _currentOutputBuffer , _info ) ;
2017-04-28 19:54:58 -04:00
} else {
2018-07-01 15:21:05 -04:00
_console - > GetVideoDecoder ( ) - > UpdateFrame ( _currentOutputBuffer , _info ) ;
2017-04-28 19:54:58 -04:00
}
2016-01-12 19:42:28 -05:00
_currentOutputBuffer = ( _currentOutputBuffer = = _outputBuffers [ 0 ] ) ? _outputBuffers [ 1 ] : _outputBuffers [ 0 ] ;
2018-02-17 23:44:25 -05:00
_info = ( _info = = _screenInfo [ 0 ] ) ? _screenInfo [ 1 ] : _screenInfo [ 0 ] ;
2018-01-04 19:03:47 -05:00
# endif
2015-08-14 21:50:14 -04:00
}
} ;