2015-08-15 01:50:14 +00:00
# pragma once
# include "stdafx.h"
# include "PPU.h"
# include "HdNesPack.h"
2015-08-31 01:04:21 +00:00
# include "VideoDecoder.h"
2017-04-28 23:54:58 +00:00
# include "RewindManager.h"
2015-08-15 01:50:14 +00:00
class HdPpu : public PPU
{
private :
2015-08-31 01:04:21 +00:00
HdPpuPixelInfo * _screenTileBuffers [ 2 ] ;
2015-08-15 01:50:14 +00:00
HdPpuPixelInfo * _screenTiles ;
2017-06-28 23:00:08 +00:00
bool _isChrRam ;
2015-08-15 01:50:14 +00:00
protected :
void DrawPixel ( )
{
uint16_t bufferOffset = ( _scanline < < 8 ) + _cycle - 1 ;
2015-08-31 01:04:21 +00:00
uint16_t & pixel = _currentOutputBuffer [ bufferOffset ] ;
2015-08-15 01:50:14 +00:00
_lastSprite = nullptr ;
if ( IsRenderingEnabled ( ) | | ( ( _state . VideoRamAddr & 0x3F00 ) ! = 0x3F00 ) ) {
2017-04-01 02:14:16 +00:00
uint32_t color = GetPixelColor ( ) ;
pixel = ( _paletteRAM [ color & 0x03 ? color : 0 ] & _paletteRamMask ) | _intensifyColorBits ;
2015-08-15 01:50:14 +00:00
2017-06-28 23:00:08 +00: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 ) ;
}
2015-08-15 01:50:14 +00:00
HdPpuPixelInfo & tileInfo = _screenTiles [ bufferOffset ] ;
2017-03-26 13:27:41 +00:00
if ( _lastSprite & & _flags . SpritesEnabled ) {
2017-04-01 02:14:16 +00:00
tileInfo . Sprite . TileIndex = _mapper - > ToAbsoluteChrAddress ( _lastSprite - > TileAddr ) / 16 ;
2017-06-28 23:00:08 +00:00
tileInfo . Sprite . PaletteColors = ReadPaletteRAM ( _lastSprite - > PaletteOffset + 3 ) | ( ReadPaletteRAM ( _lastSprite - > PaletteOffset + 2 ) < < 8 ) | ( ReadPaletteRAM ( _lastSprite - > PaletteOffset + 1 ) < < 16 ) ;
2015-08-15 01:50:14 +00:00
tileInfo . Sprite . OffsetY = _lastSprite - > OffsetY ;
2017-06-28 23:00:08 +00:00
if ( tileInfo . Sprite . OffsetY > = 8 ) {
tileInfo . Sprite . OffsetY - = 8 ;
}
tileInfo . Sprite . IsChrRamTile = _isChrRam ;
if ( _isChrRam ) {
for ( int i = 0 ; i < 16 ; i + + ) {
tileInfo . Sprite . TileData [ i ] = _mapper - > GetMemoryValue ( DebugMemoryType : : ChrRom , _lastSprite - > AbsoluteTileAddr / 16 * 16 + i ) ;
}
}
2015-08-15 01:50:14 +00:00
tileInfo . Sprite . OffsetX = _cycle - _lastSprite - > SpriteX - 1 ;
tileInfo . Sprite . HorizontalMirroring = _lastSprite - > HorizontalMirror ;
2015-08-15 14:40:27 +00:00
tileInfo . Sprite . VerticalMirroring = _lastSprite - > VerticalMirror ;
2015-08-15 01:50:14 +00:00
tileInfo . Sprite . BackgroundPriority = _lastSprite - > BackgroundPriority ;
2017-06-28 23:00:08 +00:00
int32_t shift = ( int32_t ) _cycle - _lastSprite - > SpriteX - 1 ;
if ( _lastSprite - > HorizontalMirror ) {
tileInfo . Sprite . SpriteColorIndex = ( ( _lastSprite - > LowByte > > shift ) & 0x01 ) | ( ( _lastSprite - > HighByte > > shift ) & 0x01 ) < < 1 ;
} else {
tileInfo . Sprite . SpriteColorIndex = ( ( _lastSprite - > LowByte < < shift ) & 0x80 ) > > 7 | ( ( _lastSprite - > HighByte < < shift ) & 0x80 ) > > 6 ;
}
if ( tileInfo . Sprite . SpriteColorIndex = = 0 ) {
tileInfo . Sprite . SpriteColor = ReadPaletteRAM ( 0 ) ;
} else {
tileInfo . Sprite . SpriteColor = ReadPaletteRAM ( _lastSprite - > PaletteOffset + tileInfo . Sprite . SpriteColorIndex ) ;
2015-08-15 01:50:14 +00:00
}
2015-08-15 15:52:10 +00:00
tileInfo . Sprite . BgColorIndex = backgroundColor ;
2015-08-15 01:50:14 +00:00
if ( backgroundColor = = 0 ) {
tileInfo . Sprite . BgColor = ReadPaletteRAM ( 0 ) ;
} else {
2017-06-28 23:00:08 +00:00
tileInfo . Sprite . BgColor = ReadPaletteRAM ( lastTile - > PaletteOffset + backgroundColor ) ;
2015-08-15 01:50:14 +00:00
}
} else {
tileInfo . Sprite . TileIndex = HdPpuTileInfo : : NoTile ;
}
2017-06-28 23:00:08 +00:00
if ( _flags . BackgroundEnabled & & _cycle > _minimumDrawBgCycle ) {
tileInfo . Tile . NametableValue = ( lastTile - > TileAddr / 16 ) & 0xFF ;
2017-04-01 02:14:16 +00:00
tileInfo . Tile . TileIndex = _mapper - > ToAbsoluteChrAddress ( lastTile - > TileAddr ) / 16 ;
2017-06-28 23:00:08 +00:00
tileInfo . Tile . PaletteColors = ReadPaletteRAM ( lastTile - > PaletteOffset + 3 ) | ( ReadPaletteRAM ( lastTile - > PaletteOffset + 2 ) < < 8 ) | ( ReadPaletteRAM ( lastTile - > PaletteOffset + 1 ) < < 16 ) | ( ReadPaletteRAM ( 0 ) < < 24 ) ;
2017-03-26 13:27:41 +00:00
tileInfo . Tile . OffsetY = lastTile - > OffsetY ;
tileInfo . Tile . BackgroundPriority = false ;
2017-06-28 23:00:08 +00:00
tileInfo . Tile . IsChrRamTile = _isChrRam ;
if ( _isChrRam ) {
for ( int i = 0 ; i < 16 ; i + + ) {
tileInfo . Tile . TileData [ i ] = _mapper - > GetMemoryValue ( DebugMemoryType : : ChrRom , lastTile - > AbsoluteTileAddr / 16 * 16 + i ) ;
}
}
2017-03-26 13:27:41 +00:00
2017-06-28 23:00:08 +00:00
tileInfo . Tile . BgColorIndex = backgroundColor ;
2017-03-26 13:27:41 +00:00
tileInfo . Tile . OffsetX = ( _state . XScroll + ( ( _cycle - 1 ) & 0x07 ) ) & 0x07 ;
tileInfo . Tile . HorizontalMirroring = false ;
tileInfo . Tile . VerticalMirroring = false ;
tileInfo . Tile . BgColor = ReadPaletteRAM ( 0 ) ;
} else {
tileInfo . Tile . TileIndex = HdPpuTileInfo : : NoTile ;
}
2015-08-15 01:50:14 +00: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 ;
_screenTiles [ bufferOffset ] . Tile . TileIndex = HdPpuTileInfo : : NoTile ;
_screenTiles [ bufferOffset ] . Sprite . TileIndex = HdPpuTileInfo : : NoTile ;
}
}
public :
2017-04-01 02:14:16 +00:00
HdPpu ( BaseMapper * mapper ) : PPU ( mapper )
2015-08-15 01:50:14 +00:00
{
2015-08-31 01:04:21 +00:00
_screenTileBuffers [ 0 ] = new HdPpuPixelInfo [ 256 * 240 ] ;
_screenTileBuffers [ 1 ] = new HdPpuPixelInfo [ 256 * 240 ] ;
_screenTiles = _screenTileBuffers [ 0 ] ;
2017-06-28 23:00:08 +00:00
_isChrRam = ! _mapper - > HasChrRom ( ) ;
2015-08-15 01:50:14 +00:00
}
~ HdPpu ( )
{
2015-08-31 01:04:21 +00:00
delete [ ] _screenTileBuffers [ 0 ] ;
delete [ ] _screenTileBuffers [ 1 ] ;
2015-08-15 01:50:14 +00:00
}
void SendFrame ( )
{
2017-04-28 23:54:58 +00:00
MessageManager : : SendNotification ( ConsoleNotificationType : : PpuFrameDone , _currentOutputBuffer ) ;
if ( RewindManager : : IsRewinding ( ) ) {
VideoDecoder : : GetInstance ( ) - > UpdateFrameSync ( _currentOutputBuffer , _screenTiles ) ;
} else {
VideoDecoder : : GetInstance ( ) - > UpdateFrame ( _currentOutputBuffer , _screenTiles ) ;
}
2016-01-13 00:42:28 +00:00
_currentOutputBuffer = ( _currentOutputBuffer = = _outputBuffers [ 0 ] ) ? _outputBuffers [ 1 ] : _outputBuffers [ 0 ] ;
_screenTiles = ( _screenTiles = = _screenTileBuffers [ 0 ] ) ? _screenTileBuffers [ 1 ] : _screenTileBuffers [ 0 ] ;
2015-08-15 01:50:14 +00:00
}
} ;