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
2017-11-20 04:08:23 +00:00
class ControlManager ;
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 ;
2017-07-25 23:46:25 +00:00
uint32_t _version ;
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-07-25 23:46:25 +00: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 ) ;
}
2017-03-26 13:27:41 +00:00
if ( _lastSprite & & _flags . SpritesEnabled ) {
2017-07-25 23:46:25 +00: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 ;
if ( _version > = 100 ) {
tileInfo . Sprite [ j ] . PaletteColors = 0xFF000000 | ReadPaletteRAM ( sprite . PaletteOffset + 3 ) | ( ReadPaletteRAM ( sprite . PaletteOffset + 2 ) < < 8 ) | ( ReadPaletteRAM ( sprite . PaletteOffset + 1 ) < < 16 ) ;
} else {
tileInfo . Sprite [ j ] . PaletteColors = ReadPaletteRAM ( sprite . PaletteOffset + 3 ) | ( ReadPaletteRAM ( sprite . PaletteOffset + 2 ) < < 8 ) | ( ReadPaletteRAM ( sprite . PaletteOffset + 1 ) < < 16 ) ;
}
tileInfo . Sprite [ j ] . OffsetY = sprite . OffsetY ;
if ( tileInfo . Sprite [ j ] . OffsetY > = 8 ) {
tileInfo . Sprite [ j ] . OffsetY - = 8 ;
}
tileInfo . Sprite [ j ] . IsChrRamTile = _isChrRam ;
if ( _isChrRam ) {
for ( int k = 0 ; k < 16 ; k + + ) {
tileInfo . Sprite [ j ] . TileData [ k ] = _mapper - > GetMemoryValue ( DebugMemoryType : : ChrRom , sprite . AbsoluteTileAddr / 16 * 16 + k ) ;
}
}
2015-08-15 01:50:14 +00:00
2017-07-25 23:46:25 +00: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-15 01:50:14 +00:00
2017-07-25 23:46:25 +00: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 23:00:08 +00:00
2017-07-25 23:46:25 +00: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-15 01:50:14 +00:00
2017-07-25 23:46:25 +00:00
tileInfo . Sprite [ j ] . PpuBackgroundColor = tileInfo . Tile . PpuBackgroundColor ;
tileInfo . Sprite [ j ] . BgColorIndex = tileInfo . Tile . BgColorIndex ;
j + + ;
if ( j > = 4 ) {
break ;
}
}
2015-08-15 01:50:14 +00:00
}
2017-07-25 23:46:25 +00:00
tileInfo . SpriteCount = j ;
2015-08-15 01:50:14 +00:00
} else {
2017-07-25 23:46:25 +00:00
tileInfo . SpriteCount = 0 ;
2015-08-15 01:50:14 +00:00
}
2017-06-28 23:00:08 +00:00
if ( _flags . BackgroundEnabled & & _cycle > _minimumDrawBgCycle ) {
2017-07-25 23:46:25 +00:00
tileInfo . Tile . TileIndex = lastTile - > AbsoluteTileAddr / 16 ;
if ( _version > = 100 ) {
tileInfo . Tile . PaletteColors = ReadPaletteRAM ( lastTile - > PaletteOffset + 3 ) | ( ReadPaletteRAM ( lastTile - > PaletteOffset + 2 ) < < 8 ) | ( ReadPaletteRAM ( lastTile - > PaletteOffset + 1 ) < < 16 ) | ( ReadPaletteRAM ( 0 ) < < 24 ) ;
} else {
tileInfo . Tile . PaletteColors = ReadPaletteRAM ( lastTile - > PaletteOffset + 3 ) | ( ReadPaletteRAM ( lastTile - > PaletteOffset + 2 ) < < 8 ) | ( ReadPaletteRAM ( lastTile - > PaletteOffset + 1 ) < < 16 ) ;
}
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
tileInfo . Tile . OffsetX = ( _state . XScroll + ( ( _cycle - 1 ) & 0x07 ) ) & 0x07 ;
tileInfo . Tile . HorizontalMirroring = false ;
tileInfo . Tile . VerticalMirroring = false ;
} 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 ;
2017-07-25 23:46:25 +00:00
_screenTiles [ bufferOffset ] . SpriteCount = 0 ;
2015-08-15 01:50:14 +00:00
}
}
public :
2017-11-20 04:08:23 +00:00
HdPpu ( BaseMapper * mapper , ControlManager * controlManager , uint32_t version ) : PPU ( mapper , controlManager )
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 ( ) ;
2017-07-25 23:46:25 +00:00
_version = version ;
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
}
} ;