PPU: Fixed sprite display when sprite interlace mode is turned on

This commit is contained in:
Sour 2020-05-26 18:58:13 -04:00
parent 2a6504c2d4
commit bdce582677
3 changed files with 6 additions and 11 deletions

View file

@ -580,7 +580,7 @@ void Ppu::EvaluateNextLineSprites()
FetchSpritePosition(_oamEvaluationIndex << 2);
} else {
//Second cycle: Check if sprite is in range, if so, keep its index
if(_currentSprite.IsVisible(_scanline)) {
if(_currentSprite.IsVisible(_scanline, _state.ObjInterlace)) {
if(_spriteCount < 32) {
_spriteIndexes[_spriteCount] = _oamEvaluationIndex;
_spriteCount++;
@ -662,9 +662,6 @@ void Ppu::FetchSpritePosition(uint16_t oamAddress)
}
uint8_t height = _oamSizes[_state.OamMode][largeSprite][1] << 3;
if(_state.ObjInterlace) {
height /= 2;
}
_currentSprite.Height = height;
}

View file

@ -273,11 +273,7 @@ void PpuTools::GetSpritePreview(GetSpritePreviewOptions options, PpuState state,
uint8_t largeSprite = (highTableValue & 0x02) >> 1;
uint8_t height = _oamSizes[state.OamMode][largeSprite][1] << 3;
if(state.ObjInterlace) {
height /= 2;
}
uint8_t endY = (y + height) & 0xFF;
uint8_t endY = (y + (state.ObjInterlace ? (height >> 1): height)) & 0xFF;
bool visible = (screenY >= y && screenY < endY) || (endY < y && screenY < endY);
if(!visible) {
@ -311,7 +307,9 @@ void PpuTools::GetSpritePreview(GetSpritePreviewOptions options, PpuState state,
int yGap = (screenY - y);
if(state.ObjInterlace) {
yGap <<= 1;
yGap |= (state.FrameCount & 0x01);
}
if(verticalMirror) {
yOffset = (height - 1 - yGap) & 0x07;
rowOffset = (height - 1 - yGap) >> 3;

View file

@ -34,7 +34,7 @@ struct SpriteInfo
uint16_t FetchAddress;
uint16_t ChrData[2];
bool IsVisible(uint16_t scanline)
bool IsVisible(uint16_t scanline, bool interlace)
{
if(X != -256 && (X + Width <= 0 || X > 255)) {
//Sprite is not visible (and must be ignored for time/range flag calculations)
@ -42,7 +42,7 @@ struct SpriteInfo
return false;
}
uint8_t endY = (Y + Height) & 0xFF;
uint8_t endY = (Y + (interlace ? (Height >> 1) : Height)) & 0xFF;
return (scanline >= Y && scanline < endY) || (endY < Y && scanline < endY);
}
};