GB: Fixed sprites with x < 8 (e.g partially offscreen) not being shown at their correct position

+ Re-implement BG priority flag for GBC
This commit is contained in:
Sour 2020-05-21 23:55:01 -04:00
parent 134c28ed9f
commit 713d18c2d4
3 changed files with 18 additions and 11 deletions

View file

@ -205,7 +205,7 @@ void GbPpu::RunSpriteEvaluation()
uint8_t spriteIndex = (_state.Cycle >> 1) * 4;
int16_t sprY = (int16_t)_oam[spriteIndex] - 16;
if(_state.Scanline >= sprY && _state.Scanline < sprY + (_state.LargeSprites ? 16 : 8)) {
_spriteCountersX[_spriteCount] = _oam[spriteIndex + 1];
_spriteX[_spriteCount] = _oam[spriteIndex + 1];
_spriteIndexes[_spriteCount] = spriteIndex;
_spriteCount++;
}
@ -238,9 +238,10 @@ void GbPpu::ClockTileFetcher()
{
if(_fetchSprite < 0 && _fifoSize >= 8) {
for(int i = 0; i < _spriteCount; i++) {
if((int)_spriteCountersX[i] - 8 <= _drawnPixels) {
if((int)_spriteX[i] - 8 <= _drawnPixels) {
_fetchSprite = _spriteIndexes[i];
_spriteCountersX[i] = 0xFF; //prevent processing this sprite again
_fetchSpriteOffset = _spriteX[i] < 8 ? (8 - _spriteX[i]) : 0;
_spriteX[i] = 0xFF; //prevent processing this sprite again
ResetTileFetcher();
break;
}
@ -325,20 +326,25 @@ void GbPpu::PushSpriteToPixelFifo()
return;
}
uint8_t pos = _fifoPosition;
//Overlap sprite
for(int i = 0; i < 8; i++) {
for(int i = _fetchSpriteOffset; i < 8; i++) {
uint8_t shift = (_fetcherAttributes & 0x20) ? i : (7 - i);
uint8_t bits = ((_fetcherTileLowByte >> shift) & 0x01);
bits |= ((_fetcherTileHighByte >> shift) & 0x01) << 1;
if(bits > 0) {
uint8_t pos = (_fifoPosition + i) & 0x0F;
if(!(_fifoContent[pos].Attributes & 0x40) && (_fifoContent[pos].Color == 0 || !(_fetcherAttributes & 0x80))) {
//Draw pixel if the current pixel is a BG pixel, and the color is 0, or the sprite is NOT background priority
if(!(_fifoContent[pos].Attributes & 0x40) && !(_fifoContent[pos].Attributes & 0x80) && (_fifoContent[pos].Color == 0 || !(_fetcherAttributes & 0x80))) {
//Draw pixel if the current pixel:
// -Is a BG pixel, and
// -Does not have the BG priority flag turned on (CGB only)
// -Is color 0, or the sprite is NOT background priority
_fifoContent[pos].Color = bits;
_fifoContent[pos].Attributes = _fetcherAttributes;
}
}
pos = (pos + 1) & 0x0F;
}
}
@ -619,10 +625,10 @@ void GbPpu::Serialize(Serializer& s)
_fifoPosition, _fifoSize, _shiftedPixels, _drawnPixels,
_fetcherAttributes, _fetcherStep, _fetchColumn, _fetcherTileAddr,
_fetcherTileLowByte, _fetcherTileHighByte, _fetchWindow, _fetchSprite,
_spriteCount
_spriteCount, _fetchSpriteOffset
);
s.StreamArray(_spriteCountersX, 10);
s.StreamArray(_spriteX, 10);
s.StreamArray(_spriteIndexes, 10);
for(int i = 0; i < 16; i++) {

View file

@ -46,8 +46,9 @@ private:
bool _fetchWindow = false;
int16_t _fetchSprite = -1;
int16_t _fetchSpriteOffset = -1;
uint8_t _spriteCount = 0;
uint8_t _spriteCountersX[10] = {};
uint8_t _spriteX[10] = {};
uint8_t _spriteIndexes[10] = {};
void ExecCycle();

View file

@ -638,7 +638,7 @@
<Message ID="FilterAvi">Avi files (*.avi)|*.avi|All Files (*.*)|*.*</Message>
<Message ID="FilterGif">GIF files (*.gif)|*.gif|All Files (*.*)|*.*</Message>
<Message ID="FilterPalette">Palette Files (*.pal)|*.pal|All Files (*.*)|*.*</Message>
<Message ID="FilterRom">All supported formats (*.sfc, *.gb, *.bs, *.spc, *.zip, *.7z)|*.SFC;*.SMC;*.SWC;*.FIG;*.ZIP;*.7Z;*.SPC;*.BS;*.GB|SNES Roms (*.sfc)|*.SFC;*.SMC;*.SWC;*.FIG;*.BS|Gameboy Roms (*.gb)|*.GB|SPC Sound Files (*.spc)|*.SPC|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|All (*.*)|*.*</Message>
<Message ID="FilterRom">All supported formats (*.sfc, *.gb, *.gbc, *.bs, *.spc, *.zip, *.7z)|*.SFC;*.SMC;*.SWC;*.FIG;*.ZIP;*.7Z;*.SPC;*.BS;*.GB;*.GBC|SNES Roms (*.sfc)|*.SFC;*.SMC;*.SWC;*.FIG;*.BS|Gameboy Roms (*.gb, *.gbc)|*.GB;*.GBC|SPC Sound Files (*.spc)|*.SPC|ZIP Archives (*.zip)|*.ZIP|7-Zip Archives (*.7z)|*.7z|All (*.*)|*.*</Message>
<Message ID="FilterTest">Test files (*.mtp)|*.mtp|All (*.*)|*.*</Message>
<Message ID="FilterCheat">All supported formats (*.cht, *.xml)|*.cht;*.xml</Message>
<Message ID="FilterSavestate">Mesen-S Savestates (*.mss)|*.mss|All files (*.*)|*.*</Message>