gfx.cpp: memset less memory at once for FirstSprite+Y, accelerating sprite rendering if not all lines have sprites.

This commit is contained in:
Nebuleon Fumika 2013-04-15 22:25:27 -04:00 committed by Brandon Wright
parent 8384891515
commit c64bfbf614
1 changed files with 30 additions and 16 deletions

46
gfx.cpp
View File

@ -899,8 +899,14 @@ static void SetupOBJ (void)
else // evil FirstSprite+Y case else // evil FirstSprite+Y case
{ {
// First, find out which sprites are on which lines // First, find out which sprites are on which lines
uint8 OBJOnLine[SNES_HEIGHT_EXTENDED][128]; uint8 OBJOnLine[SNES_HEIGHT_EXTENDED][128];
memset(OBJOnLine, 0, sizeof(OBJOnLine)); // memset(OBJOnLine, 0, sizeof(OBJOnLine));
/* Hold on here, that's a lot of bytes to initialise at once!
* So we only initialise them per line, as needed. [Neb]
* Bonus: We can quickly avoid looping if a line has no OBJs.
*/
bool8 AnyOBJOnLine[SNES_HEIGHT_EXTENDED];
memset(AnyOBJOnLine, FALSE, sizeof(AnyOBJOnLine)); // better
for (S = 0; S < 128; S++) for (S = 0; S < 128; S++)
{ {
@ -934,6 +940,11 @@ static void SetupOBJ (void)
if (Y >= SNES_HEIGHT_EXTENDED) if (Y >= SNES_HEIGHT_EXTENDED)
continue; continue;
if (!AnyOBJOnLine[Y]) {
memset(OBJOnLine[Y], 0, sizeof(OBJOnLine[Y]));
AnyOBJOnLine[Y] = TRUE;
}
if (PPU.OBJ[S].VFlip) if (PPU.OBJ[S].VFlip)
// Yes, Width not Height. It so happens that the // Yes, Width not Height. It so happens that the
// sprites with H=2*W flip as two WxW sprites. // sprites with H=2*W flip as two WxW sprites.
@ -955,25 +966,28 @@ static void SetupOBJ (void)
S = FirstSprite; S = FirstSprite;
j = 0; j = 0;
do if (AnyOBJOnLine[Y])
{ {
if (OBJOnLine[Y][S]) do
{ {
if (j >= 32) if (OBJOnLine[Y][S])
{ {
GFX.OBJLines[Y].RTOFlags |= 0x40; if (j >= 32)
break; {
GFX.OBJLines[Y].RTOFlags |= 0x40;
break;
}
GFX.OBJLines[Y].Tiles -= GFX.OBJVisibleTiles[S];
if (GFX.OBJLines[Y].Tiles < 0)
GFX.OBJLines[Y].RTOFlags |= 0x80;
GFX.OBJLines[Y].OBJ[j].Sprite = S;
GFX.OBJLines[Y].OBJ[j++].Line = OBJOnLine[Y][S] & ~0x80;
} }
GFX.OBJLines[Y].Tiles -= GFX.OBJVisibleTiles[S]; S = (S + 1) & 0x7f;
if (GFX.OBJLines[Y].Tiles < 0) } while (S != FirstSprite);
GFX.OBJLines[Y].RTOFlags |= 0x80; }
GFX.OBJLines[Y].OBJ[j].Sprite = S;
GFX.OBJLines[Y].OBJ[j++].Line = OBJOnLine[Y][S] & ~0x80;
}
S = (S + 1) & 0x7f;
} while (S != FirstSprite);
if (j < 32) if (j < 32)
GFX.OBJLines[Y].OBJ[j].Sprite = -1; GFX.OBJLines[Y].OBJ[j].Sprite = -1;