SMS: improve rendering accuracy of left-column blanking. I have to say I never thought that would be a thing that needed improved rendering. Also fix issue with when Sprite Overflow fires.

This commit is contained in:
beirich 2014-03-18 00:50:08 +00:00
parent cbc4d925be
commit 3b66e61c82
2 changed files with 72 additions and 71 deletions

View File

@ -133,15 +133,6 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
int SpritesDrawnThisScanline = 0;
for (int i = 0; i < 64; i++)
{
if (SpritesDrawnThisScanline >= 8)
{
collisionHappens = false; // technically the VDP stops processing sprite past this so we would never set the collision bit for sprites past this
if (overflowHappens)
StatusByte |= 0x40; // Set Overflow bit
if (SpriteLimit)
renderHappens = false; // should be able to break/return, but to ensure this has no effect on sync we keep processing and disable rendering
}
int x = VRAM[SpriteBase + 0x80 + (i * 2)];
if (ShiftSpritesLeft8Pixels)
x -= 8;
@ -155,6 +146,15 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
if (y + SpriteHeight <= ScanLine || y > ScanLine)
continue;
if (SpritesDrawnThisScanline >= 8)
{
collisionHappens = false; // technically the VDP stops processing sprite past this so we would never set the collision bit for sprites past this
if (overflowHappens)
StatusByte |= 0x40; // Set Overflow bit
if (SpriteLimit)
renderHappens = false; // should be able to break/return, but to ensure this has no effect on sync we keep processing and disable rendering
}
int tileNo = VRAM[SpriteBase + 0x80 + (i * 2) + 1];
if (EnableLargeSprites)
tileNo &= 0xFE;
@ -210,15 +210,6 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
int SpritesDrawnThisScanline = 0;
for (int i = 0; i < 64; i++)
{
if (SpritesDrawnThisScanline >= 8)
{
collisionHappens = false; // technically the VDP stops processing sprite past this so we would never set the collision bit for sprites past this
if (overflowHappens)
StatusByte |= 0x40; // Set Overflow bit
if (SpriteLimit)
renderHappens = false; // should be able to break/return, but to ensure this has no effect on sync we keep processing and disable rendering
}
int x = VRAM[SpriteBase + 0x80 + (i * 2)];
if (ShiftSpritesLeft8Pixels)
x -= 8;
@ -232,6 +223,15 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
if (y + (SpriteHeight * 2) <= ScanLine || y > ScanLine)
continue;
if (SpritesDrawnThisScanline >= 8)
{
collisionHappens = false; // technically the VDP stops processing sprite past this so we would never set the collision bit for sprites past this
if (overflowHappens)
StatusByte |= 0x40; // Set Overflow bit
if (SpriteLimit)
renderHappens = false; // should be able to break/return, but to ensure this has no effect on sync we keep processing and disable rendering
}
int tileNo = VRAM[SpriteBase + 0x80 + (i * 2) + 1];
if (EnableLargeSprites)
tileNo &= 0xFE;
@ -260,75 +260,74 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
}
}
// Performs render buffer blanking. This includes the left-column blanking as well as Game Gear blanking if requested.
// Should be called at the end of the frame.
internal void RenderBlankingRegions()
// Renders left-blanking. Should be done per scanline, not per-frame.
internal void RenderLineBlanking(bool render)
{
int blankingColor = Palette[BackdropColor];
if (!LeftBlanking || ScanLine >= FrameHeight || !render)
return;
if (LeftBlanking)
int ofs = ScanLine * 256;
for (int x = 0; x < 8; x++)
FrameBuffer[ofs++] = Palette[BackdropColor];
}
// Handles GG clipping or highlighting
internal void ProcessGGScreen()
{
if (mode != VdpMode.GameGear)
return;
if (Sms.Settings.ShowClippedRegions == false)
{
for (int y = 0; y < FrameHeight; y++)
{
for (int x = 0; x < 8; x++)
FrameBuffer[(y * 256) + x] = blankingColor;
}
int yStart = (FrameHeight - 144) / 2;
for (int y = 0; y < 144; y++)
for (int x = 0; x < 160; x++)
GameGearFrameBuffer[(y * 160) + x] = FrameBuffer[((y + yStart) * 256) + x + 48];
}
if (mode == VdpMode.GameGear)
if (Sms.Settings.HighlightActiveDisplayRegion && Sms.Settings.ShowClippedRegions)
{
if (Sms.Settings.ShowClippedRegions == false)
// Top 24 scanlines
for (int y = 0; y < 24; y++)
{
int yStart = (FrameHeight - 144) / 2;
for (int y = 0; y < 144; y++)
for (int x = 0; x < 160; x++)
GameGearFrameBuffer[(y * 160) + x] = FrameBuffer[((y + yStart) * 256) + x + 48];
for (int x = 0; x < 256; x++)
{
int frameOffset = (y * 256) + x;
int p = (FrameBuffer[frameOffset] >> 1) & 0x7F7F7F7F;
FrameBuffer[frameOffset] = (int)((uint)p | 0x80000000);
}
}
if (Sms.Settings.HighlightActiveDisplayRegion && Sms.Settings.ShowClippedRegions)
// Bottom 24 scanlines
for (int y = 168; y < 192; y++)
{
// Top 24 scanlines
for (int y = 0; y < 24; y++)
for (int x = 0; x < 256; x++)
{
for (int x = 0; x < 256; x++)
{
int frameOffset = (y * 256) + x;
int p = (FrameBuffer[frameOffset] >> 1) & 0x7F7F7F7F;
FrameBuffer[frameOffset] = (int)((uint)p | 0x80000000);
}
int frameOffset = (y * 256) + x;
int p = (FrameBuffer[frameOffset] >> 1) & 0x7F7F7F7F;
FrameBuffer[frameOffset] = (int)((uint)p | 0x80000000);
}
}
// Bottom 24 scanlines
for (int y = 168; y < 192; y++)
// Left 48 pixels
for (int y = 24; y < 168; y++)
{
for (int x = 0; x < 48; x++)
{
for (int x = 0; x < 256; x++)
{
int frameOffset = (y * 256) + x;
int p = (FrameBuffer[frameOffset] >> 1) & 0x7F7F7F7F;
FrameBuffer[frameOffset] = (int)((uint)p | 0x80000000);
}
int frameOffset = (y * 256) + x;
int p = (FrameBuffer[frameOffset] >> 1) & 0x7F7F7F7F;
FrameBuffer[frameOffset] = (int)((uint)p | 0x80000000);
}
}
// Left 48 pixels
for (int y = 24; y < 168; y++)
// Right 48 pixels
for (int y = 24; y < 168; y++)
{
for (int x = 208; x < 256; x++)
{
for (int x = 0; x < 48; x++)
{
int frameOffset = (y * 256) + x;
int p = (FrameBuffer[frameOffset] >> 1) & 0x7F7F7F7F;
FrameBuffer[frameOffset] = (int)((uint)p | 0x80000000);
}
}
// Right 48 pixels
for (int y = 24; y < 168; y++)
{
for (int x = 208; x < 256; x++)
{
int frameOffset = (y * 256) + x;
int p = (FrameBuffer[frameOffset] >> 1) & 0x7F7F7F7F;
FrameBuffer[frameOffset] = (int)((uint)p | 0x80000000);
}
int frameOffset = (y * 256) + x;
int p = (FrameBuffer[frameOffset] >> 1) & 0x7F7F7F7F;
FrameBuffer[frameOffset] = (int)((uint)p | 0x80000000);
}
}
}

View File

@ -364,7 +364,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
Cpu.ExecuteCycles(IPeriod);
if (ScanLine == scanlinesPerFrame - 1)
RenderBlankingRegions();
ProcessGGScreen();
}
}
@ -380,6 +380,8 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
RenderSpritesCurrentLineDoubleSize(Sms.Settings.DispOBJ & render);
else
RenderSpritesCurrentLine(Sms.Settings.DispOBJ & render);
RenderLineBlanking(render);
}
else if (TmsMode == 2)
{