diff options
author | Nebuleon Fumika | 2012-12-30 14:34:12 -0500 |
---|---|---|
committer | Nebuleon Fumika | 2012-12-30 14:34:12 -0500 |
commit | b7867f01cc9bc4fbcec6281afcfecbbc3304b861 (patch) | |
tree | 221b9ebcff6989b4cd17981dca24e40642adfff0 | |
parent | d1d0c81af89dc0d54e9d16a64af4a0597b4be90a (diff) | |
download | snes9x2005-b7867f01cc9bc4fbcec6281afcfecbbc3304b861.tar.gz snes9x2005-b7867f01cc9bc4fbcec6281afcfecbbc3304b861.tar.bz2 snes9x2005-b7867f01cc9bc4fbcec6281afcfecbbc3304b861.zip |
Memory access optimisations in sprite rendering.
-rw-r--r-- | source/gfx.cpp | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/source/gfx.cpp b/source/gfx.cpp index 3303fb9..611ec0a 100644 --- a/source/gfx.cpp +++ b/source/gfx.cpp @@ -981,7 +981,6 @@ void S9xSetupOBJ () for(int i=0; i<SNES_HEIGHT_EXTENDED; i++){ GFX.OBJLines[i].RTOFlags=0; GFX.OBJLines[i].Tiles=34; - for(int j=0; j<32; j++){ GFX.OBJLines[i].OBJ[j].Sprite=-1; } } uint8 FirstSprite=PPU.FirstSprite; S=FirstSprite; @@ -1026,6 +1025,10 @@ void S9xSetupOBJ () S=(S+1)&0x7F; } while(S!=FirstSprite); + for (int Y = 0; Y < SNES_HEIGHT_EXTENDED; Y++) { + if (LineOBJ[Y] < 32) // Add the sentinel + GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Sprite = -1; + } for(int Y=1; Y<SNES_HEIGHT_EXTENDED; Y++){ GFX.OBJLines[Y].RTOFlags |= GFX.OBJLines[Y-1].RTOFlags; } @@ -1037,7 +1040,13 @@ void S9xSetupOBJ () /* First, find out which sprites are on which lines */ 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++){ if(PPU.OBJ[S].Size){ @@ -1057,6 +1066,10 @@ void S9xSetupOBJ () } for(uint8 line=0, Y=(uint8)(PPU.OBJ[S].VPos&0xff); line<Height; Y++, line++){ if(Y>=SNES_HEIGHT_EXTENDED) continue; + if (!AnyOBJOnLine[Y]) { + memset(OBJOnLine[Y], 0, 128); + AnyOBJOnLine[Y] = TRUE; + } if(PPU.OBJ[S].VFlip){ // Yes, Width not Height. It so happens that the // sprites with H=2*W flip as two WxW sprites. @@ -1074,24 +1087,27 @@ void S9xSetupOBJ () GFX.OBJLines[Y].RTOFlags=Y?0:GFX.OBJLines[Y-1].RTOFlags; GFX.OBJLines[Y].Tiles=34; - uint8 FirstSprite=(PPU.FirstSprite+Y)&0x7F; - S=FirstSprite; j=0; - do { - if(OBJOnLine[Y][S]){ - if(j>=32){ - GFX.OBJLines[Y].RTOFlags|=0x40; -#ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "%d: OBJ %02x ranged over\n", Y, S); -#endif - break; + j=0; + if (AnyOBJOnLine[Y]) { + uint8 FirstSprite=(PPU.FirstSprite+Y)&0x7F; + S=FirstSprite; + do { + if(OBJOnLine[Y][S]){ + if(j>=32){ + GFX.OBJLines[Y].RTOFlags|=0x40; + #ifdef MK_DEBUG_RTO + if(Settings.BGLayering) fprintf(stderr, "%d: OBJ %02x ranged over\n", Y, S); + #endif + 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]; - 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; - } - S=(S+1)&0x7F; - } while(S!=FirstSprite); + S=(S+1)&0x7F; + } while(S!=FirstSprite); + } if(j<32) GFX.OBJLines[Y].OBJ[j].Sprite=-1; } } |