HD Packs: Fixed issues with background priority sprites
This commit is contained in:
parent
5f47b402b5
commit
fef31e6749
6 changed files with 65 additions and 50 deletions
|
@ -25,6 +25,10 @@ protected:
|
|||
_lastSprite = nullptr;
|
||||
uint32_t color = GetPixelColor();
|
||||
_currentOutputBuffer[(_scanline << 8) + _cycle - 1] = _paletteRAM[color & 0x03 ? color : 0];
|
||||
uint32_t backgroundColor = 0;
|
||||
if(_flags.BackgroundEnabled && _cycle > _minimumDrawBgCycle) {
|
||||
backgroundColor = (((_state.LowBitShift << _state.XScroll) & 0x8000) >> 15) | (((_state.HighBitShift << _state.XScroll) & 0x8000) >> 14);
|
||||
}
|
||||
|
||||
if(_needChrHash) {
|
||||
uint16_t addr = 0;
|
||||
|
@ -41,7 +45,17 @@ protected:
|
|||
_needChrHash = false;
|
||||
}
|
||||
|
||||
bool hasBgSprite = false;
|
||||
if(_lastSprite && _flags.SpritesEnabled) {
|
||||
if(backgroundColor == 0) {
|
||||
for(uint8_t i = 0; i < _spriteCount; i++) {
|
||||
if(_spriteTiles[i].BackgroundPriority) {
|
||||
hasBgSprite = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(_lastSprite->AbsoluteTileAddr >= 0) {
|
||||
sprite.TileIndex = (_isChrRam ? (_lastSprite->TileAddr & _chrRamIndexMask) : _lastSprite->AbsoluteTileAddr) / 16;
|
||||
sprite.PaletteColors = ReadPaletteRAM(_lastSprite->PaletteOffset + 3) | (ReadPaletteRAM(_lastSprite->PaletteOffset + 2) << 8) | (ReadPaletteRAM(_lastSprite->PaletteOffset + 1) << 16) | 0xFF000000;
|
||||
|
@ -50,7 +64,7 @@ protected:
|
|||
sprite.TileData[i] = _mapper->GetMemoryValue(DebugMemoryType::ChrRom, _lastSprite->AbsoluteTileAddr / 16 * 16 + i);
|
||||
}
|
||||
|
||||
_hdPackBuilder->ProcessTile(_cycle - 1, _scanline, _lastSprite->AbsoluteTileAddr, sprite, _mapper, false, _bankHashes[_lastSprite->TileAddr / _chrRamBankSize]);
|
||||
_hdPackBuilder->ProcessTile(_cycle - 1, _scanline, _lastSprite->AbsoluteTileAddr, sprite, _mapper, false, _bankHashes[_lastSprite->TileAddr / _chrRamBankSize], false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +78,7 @@ protected:
|
|||
tile.TileData[i] = _mapper->GetMemoryValue(DebugMemoryType::ChrRom, lastTile->AbsoluteTileAddr / 16 * 16 + i);
|
||||
}
|
||||
|
||||
_hdPackBuilder->ProcessTile(_cycle - 1, _scanline, lastTile->AbsoluteTileAddr, tile, _mapper, false, _bankHashes[lastTile->TileAddr / _chrRamBankSize]);
|
||||
_hdPackBuilder->ProcessTile(_cycle - 1, _scanline, lastTile->AbsoluteTileAddr, tile, _mapper, false, _bankHashes[lastTile->TileAddr / _chrRamBankSize], hasBgSprite);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -226,6 +226,7 @@ struct HdPackTileInfo : public HdTileKey
|
|||
bool DefaultTile;
|
||||
bool Blank;
|
||||
bool HasTransparentPixels;
|
||||
bool TransparencyRequired;
|
||||
bool IsFullyTransparent;
|
||||
vector<uint32_t> HdTileData;
|
||||
uint32_t ChrBankId;
|
||||
|
@ -252,7 +253,7 @@ struct HdPackTileInfo : public HdTileKey
|
|||
for(uint8_t j = 0; j < 8; j++) {
|
||||
uint8_t color = ((lowByte >> (7 - j)) & 0x01) | (((highByte >> (7 - j)) & 0x01) << 1);
|
||||
uint32_t rgbColor;
|
||||
if(IsSpriteTile()) {
|
||||
if(IsSpriteTile() || TransparencyRequired) {
|
||||
rgbColor = color == 0 ? 0x00FFFFFF : palette[(PaletteColors >> ((3 - color) * 8)) & 0x3F];
|
||||
} else {
|
||||
rgbColor = palette[(PaletteColors >> ((3 - color) * 8)) & 0x3F];
|
||||
|
|
|
@ -64,22 +64,14 @@ void HdNesPack::DrawCustomBackground(uint32_t *outputBuffer, uint32_t x, uint32_
|
|||
}
|
||||
}
|
||||
|
||||
bool HdNesPack::DrawTile(HdPpuTileInfo &tileInfo, HdPackTileInfo &hdPackTileInfo, uint32_t *outputBuffer, uint32_t screenWidth, bool drawBackground)
|
||||
void HdNesPack::DrawTile(HdPpuTileInfo &tileInfo, HdPackTileInfo &hdPackTileInfo, uint32_t *outputBuffer, uint32_t screenWidth)
|
||||
{
|
||||
if(tileInfo.BackgroundPriority && tileInfo.BgColorIndex != 0) {
|
||||
//Nothing to draw, tile is hidden
|
||||
return false;
|
||||
if(hdPackTileInfo.IsFullyTransparent) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t bgColor = _palette[tileInfo.PpuBackgroundColor];
|
||||
uint32_t scale = GetScale();
|
||||
if(hdPackTileInfo.IsFullyTransparent) {
|
||||
if(drawBackground) {
|
||||
DrawColor(bgColor, outputBuffer, scale, screenWidth);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t *bitmapData = hdPackTileInfo.HdTileData.data();
|
||||
uint32_t tileWidth = 8 * scale;
|
||||
uint8_t tileOffsetX = tileInfo.HorizontalMirroring ? 7 - tileInfo.OffsetX : tileInfo.OffsetX;
|
||||
|
@ -96,7 +88,6 @@ bool HdNesPack::DrawTile(HdPpuTileInfo &tileInfo, HdPackTileInfo &hdPackTileInfo
|
|||
bitmapLargeInc = (tileInfo.HorizontalMirroring ? (int32_t)scale : -(int32_t)scale) - (int32_t)tileWidth;
|
||||
}
|
||||
|
||||
bool pixelDrawn = false;
|
||||
uint32_t rgbValue;
|
||||
if(hdPackTileInfo.HasTransparentPixels || hdPackTileInfo.Brightness < 255) {
|
||||
for(uint32_t y = 0; y < scale; y++) {
|
||||
|
@ -109,14 +100,9 @@ bool HdNesPack::DrawTile(HdPpuTileInfo &tileInfo, HdPackTileInfo &hdPackTileInfo
|
|||
|
||||
if(!hdPackTileInfo.HasTransparentPixels || (bitmapData[bitmapOffset] & 0xFF000000) == 0xFF000000) {
|
||||
*outputBuffer = rgbValue;
|
||||
pixelDrawn = true;
|
||||
} else {
|
||||
if(drawBackground) {
|
||||
*outputBuffer = bgColor;
|
||||
}
|
||||
if(bitmapData[bitmapOffset] & 0xFF000000) {
|
||||
BlendColors((uint8_t*)outputBuffer, (uint8_t*)&rgbValue);
|
||||
pixelDrawn = true;
|
||||
}
|
||||
}
|
||||
outputBuffer++;
|
||||
|
@ -135,10 +121,7 @@ bool HdNesPack::DrawTile(HdPpuTileInfo &tileInfo, HdPackTileInfo &hdPackTileInfo
|
|||
bitmapOffset += bitmapLargeInc;
|
||||
outputBuffer += screenWidth - scale;
|
||||
}
|
||||
pixelDrawn = true;
|
||||
}
|
||||
|
||||
return pixelDrawn;
|
||||
}
|
||||
|
||||
uint32_t HdNesPack::GetScale()
|
||||
|
@ -210,7 +193,15 @@ bool HdNesPack::IsNextToSprite(HdPpuPixelInfo *screenTiles, uint32_t x, uint32_t
|
|||
}
|
||||
};
|
||||
for(int i = -1; i <= 1; i++) {
|
||||
if(y + i < 0 || y + i >= PPU::ScreenHeight) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for(int j = -1; j <= 1; j++) {
|
||||
if(x + j < 0 || x + j >= PPU::ScreenWidth) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!hasNonBackgroundSurrounding) {
|
||||
processAdjacentTile(screenTiles[(i + y) * 256 + j + x]);
|
||||
}
|
||||
|
@ -244,21 +235,20 @@ void HdNesPack::GetPixels(HdPpuPixelInfo *screenTiles, uint32_t x, uint32_t y, H
|
|||
|
||||
bool hasBgSprite = false;
|
||||
int lowestBgSprite = 999;
|
||||
bool needBg = true;
|
||||
|
||||
DrawColor(_palette[pixelInfo.Tile.PpuBackgroundColor], outputBuffer, hdData->Scale, screenWidth);
|
||||
|
||||
if(hasSprite) {
|
||||
for(int k = pixelInfo.SpriteCount - 1; k >= 0; k--) {
|
||||
if(pixelInfo.Sprite[k].BackgroundPriority) {
|
||||
hasBgSprite = true;
|
||||
lowestBgSprite = k;
|
||||
|
||||
if(pixelInfo.Tile.BgColorIndex == 0) {
|
||||
hdPackSpriteInfo = GetMatchingTile(screenTiles, x, y, pixelInfo.Sprite[k]);
|
||||
if(hdPackSpriteInfo) {
|
||||
needBg &= !DrawTile(pixelInfo.Sprite[k], *hdPackSpriteInfo, outputBuffer, screenWidth, needBg);
|
||||
} else if(pixelInfo.Sprite[k].SpriteColorIndex != 0) {
|
||||
DrawColor(_palette[pixelInfo.Sprite[k].SpriteColor], outputBuffer, hdData->Scale, screenWidth);
|
||||
needBg = false;
|
||||
}
|
||||
hdPackSpriteInfo = GetMatchingTile(screenTiles, x, y, pixelInfo.Sprite[k]);
|
||||
if(hdPackSpriteInfo) {
|
||||
DrawTile(pixelInfo.Sprite[k], *hdPackSpriteInfo, outputBuffer, screenWidth);
|
||||
} else if(pixelInfo.Sprite[k].SpriteColorIndex != 0) {
|
||||
DrawColor(_palette[pixelInfo.Sprite[k].SpriteColor], outputBuffer, hdData->Scale, screenWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -270,18 +260,15 @@ void HdNesPack::GetPixels(HdPpuPixelInfo *screenTiles, uint32_t x, uint32_t y, H
|
|||
DrawCustomBackground(outputBuffer, x, y, hdData->Scale, screenWidth);
|
||||
}
|
||||
|
||||
bool drawBg = !hasBgSprite || pixelInfo.Tile.BgColorIndex != 0 || needBg;
|
||||
if(drawBg) {
|
||||
if(hdPackTileInfo) {
|
||||
DrawTile(pixelInfo.Tile, *hdPackTileInfo, outputBuffer, screenWidth, true);
|
||||
} else {
|
||||
//Draw regular SD background tile
|
||||
bool useCustomBackground = !hasNonBackgroundSurrounding && hasCustomBackground && pixelInfo.Tile.BgColorIndex == 0;
|
||||
if(useCustomBackground) {
|
||||
DrawCustomBackground(outputBuffer, x, y, hdData->Scale, screenWidth);
|
||||
} else {
|
||||
DrawColor(_palette[pixelInfo.Tile.BgColor], outputBuffer, hdData->Scale, screenWidth);
|
||||
}
|
||||
if(hdPackTileInfo) {
|
||||
DrawTile(pixelInfo.Tile, *hdPackTileInfo, outputBuffer, screenWidth);
|
||||
} else {
|
||||
//Draw regular SD background tile
|
||||
bool useCustomBackground = !hasNonBackgroundSurrounding && hasCustomBackground && pixelInfo.Tile.BgColorIndex == 0;
|
||||
if(useCustomBackground) {
|
||||
DrawCustomBackground(outputBuffer, x, y, hdData->Scale, screenWidth);
|
||||
} else if(pixelInfo.Tile.BgColorIndex != 0 || hasNonBackgroundSurrounding) {
|
||||
DrawColor(_palette[pixelInfo.Tile.BgColor], outputBuffer, hdData->Scale, screenWidth);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,7 +277,7 @@ void HdNesPack::GetPixels(HdPpuPixelInfo *screenTiles, uint32_t x, uint32_t y, H
|
|||
if(!pixelInfo.Sprite[k].BackgroundPriority && lowestBgSprite > k) {
|
||||
hdPackSpriteInfo = GetMatchingTile(screenTiles, x, y, pixelInfo.Sprite[k]);
|
||||
if(hdPackSpriteInfo) {
|
||||
DrawTile(pixelInfo.Sprite[k], *hdPackSpriteInfo, outputBuffer, screenWidth, false);
|
||||
DrawTile(pixelInfo.Sprite[k], *hdPackSpriteInfo, outputBuffer, screenWidth);
|
||||
} else if(pixelInfo.Sprite[k].SpriteColorIndex != 0) {
|
||||
DrawColor(_palette[pixelInfo.Sprite[k].SpriteColor], outputBuffer, hdData->Scale, screenWidth);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ private:
|
|||
__forceinline void BlendColors(uint8_t output[4], uint8_t input[4]);
|
||||
__forceinline uint32_t AdjustBrightness(uint8_t input[4], uint16_t brightness);
|
||||
__forceinline void DrawColor(uint32_t color, uint32_t* outputBuffer, uint32_t scale, uint32_t screenWidth);
|
||||
__forceinline bool DrawTile(HdPpuTileInfo &tileInfo, HdPackTileInfo &hdPackTileInfo, uint32_t* outputBuffer, uint32_t screenWidth, bool drawBackground);
|
||||
__forceinline void DrawTile(HdPpuTileInfo &tileInfo, HdPackTileInfo &hdPackTileInfo, uint32_t* outputBuffer, uint32_t screenWidth);
|
||||
__forceinline HdPackTileInfo* GetMatchingTile(HdPpuPixelInfo *screenTiles, uint32_t x, uint32_t y, HdTileKey& key);
|
||||
|
||||
__forceinline bool IsNextToSprite(HdPpuPixelInfo *screenTiles, uint32_t x, uint32_t y);
|
||||
|
|
|
@ -76,10 +76,11 @@ void HdPackBuilder::AddTile(HdPackTileInfo *tile, uint32_t usageCount)
|
|||
paletteMap[palette][tile->TileIndex % 256] = tile;
|
||||
}
|
||||
|
||||
_tilesByKey[tile->GetKey(false)] = tile;
|
||||
_tileUsageCount[tile->GetKey(false)] = usageCount;
|
||||
}
|
||||
|
||||
void HdPackBuilder::ProcessTile(uint32_t x, uint32_t y, uint16_t tileAddr, HdPpuTileInfo &tile, BaseMapper *mapper, bool isSprite, uint32_t chrBankHash)
|
||||
void HdPackBuilder::ProcessTile(uint32_t x, uint32_t y, uint16_t tileAddr, HdPpuTileInfo &tile, BaseMapper *mapper, bool isSprite, uint32_t chrBankHash, bool transparencyRequired)
|
||||
{
|
||||
if(_flags & HdPackRecordFlags::IgnoreOverscan) {
|
||||
OverscanDimensions overscan = EmulationSettings::GetOverscanDimensions();
|
||||
|
@ -104,14 +105,20 @@ void HdPackBuilder::ProcessTile(uint32_t x, uint32_t y, uint16_t tileAddr, HdPpu
|
|||
hdTile->IsChrRamTile = _isChrRam;
|
||||
hdTile->Brightness = 255;
|
||||
hdTile->ChrBankId = _isChrRam ? chrBankHash : (tileAddr / 16 / 256);
|
||||
hdTile->TransparencyRequired = transparencyRequired;
|
||||
|
||||
memcpy(hdTile->TileData, tile.TileData, 16);
|
||||
GenerateHdTile(hdTile);
|
||||
hdTile->UpdateFlags();
|
||||
|
||||
_hdData.Tiles.push_back(unique_ptr<HdPackTileInfo>(hdTile));
|
||||
AddTile(hdTile, 1);
|
||||
} else {
|
||||
if(transparencyRequired) {
|
||||
auto existingTile = _tilesByKey.find(tile.GetKey(false));
|
||||
if(existingTile != _tilesByKey.end()) {
|
||||
existingTile->second->TransparencyRequired = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(result->second < 0x7FFFFFFF) {
|
||||
//Increase usage count
|
||||
result->second++;
|
||||
|
@ -166,6 +173,11 @@ void HdPackBuilder::GenerateHdTile(HdPackTileInfo *tile)
|
|||
|
||||
void HdPackBuilder::DrawTile(HdPackTileInfo *tile, int tileNumber, uint32_t *pngBuffer, int pageNumber, bool containsSpritesOnly)
|
||||
{
|
||||
if(tile->HdTileData.empty()) {
|
||||
GenerateHdTile(tile);
|
||||
tile->UpdateFlags();
|
||||
}
|
||||
|
||||
if(containsSpritesOnly && (_flags & HdPackRecordFlags::UseLargeSprites)) {
|
||||
int row = tileNumber / 16;
|
||||
int column = tileNumber % 16;
|
||||
|
|
|
@ -21,6 +21,7 @@ private:
|
|||
|
||||
HdPackData _hdData;
|
||||
std::unordered_map<HdTileKey, uint32_t> _tileUsageCount;
|
||||
std::unordered_map<HdTileKey, HdPackTileInfo*> _tilesByKey;
|
||||
std::map<uint32_t, std::map<uint32_t, vector<HdPackTileInfo*>>> _tilesByChrBankByPalette;
|
||||
bool _isChrRam;
|
||||
uint32_t _chrRamBankSize;
|
||||
|
@ -41,7 +42,7 @@ public:
|
|||
HdPackBuilder(string saveFolder, ScaleFilterType filterType, uint32_t scale, uint32_t flags, uint32_t chrRamBankSize, bool isChrRam);
|
||||
~HdPackBuilder();
|
||||
|
||||
void ProcessTile(uint32_t x, uint32_t y, uint16_t tileAddr, HdPpuTileInfo& tile, BaseMapper* mapper, bool isSprite, uint32_t chrBankHash);
|
||||
void ProcessTile(uint32_t x, uint32_t y, uint16_t tileAddr, HdPpuTileInfo& tile, BaseMapper* mapper, bool isSprite, uint32_t chrBankHash, bool transparencyRequired);
|
||||
void SaveHdPack();
|
||||
|
||||
static void GetChrBankList(uint32_t *banks);
|
||||
|
|
Loading…
Add table
Reference in a new issue