GBA Video: Improve sprite cycle counting (fixes #1274)
Vicki Pfau vi@endrift.com
Sat, 26 Jan 2019 22:41:24 -0800
11 files changed,
23 insertions(+),
20 deletions(-)
jump to
M
src/gba/renderers/software-obj.c
→
src/gba/renderers/software-obj.c
@@ -145,9 +145,6 @@ unsigned charBase = (GBAObjAttributesCGetTile(sprite->c) & ~align) * 0x20;
if (GBARegisterDISPCNTGetMode(renderer->dispcnt) >= 3 && GBAObjAttributesCGetTile(sprite->c) < 512) { return 0; } - if (renderer->spriteCyclesRemaining <= 0) { - return 0; - } int objwinSlowPath = GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt) && GBAWindowControlGetBlendEnable(renderer->objwin.packed) != GBAWindowControlIsBlendEnable(renderer->currentWindow.packed); int variant = renderer->target1Obj &&
M
src/gba/renderers/video-software.c
→
src/gba/renderers/video-software.c
@@ -809,7 +809,6 @@ renderer->bg[X].priority == priority)
static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) { int w; - renderer->end = 0; int spriteLayers = 0; if (GBARegisterDISPCNTIsObjEnable(renderer->dispcnt) && !renderer->d.disableOBJ) { if (renderer->oamDirty) {@@ -818,30 +817,33 @@ }
renderer->spriteCyclesRemaining = GBARegisterDISPCNTIsHblankIntervalFree(renderer->dispcnt) ? OBJ_HBLANK_FREE_LENGTH : OBJ_LENGTH; int mosaicV = GBAMosaicControlGetObjV(renderer->mosaic) + 1; int mosaicY = y - (y % mosaicV); - for (w = 0; w < renderer->nWindows; ++w) { - renderer->start = renderer->end; - renderer->end = renderer->windows[w].endX; - renderer->currentWindow = renderer->windows[w].control; - if (!GBAWindowControlIsObjEnable(renderer->currentWindow.packed) && !GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt)) { + int i; + for (i = 0; i < renderer->oamMax; ++i) { + struct GBAVideoSoftwareSprite* sprite = &renderer->sprites[i]; + int localY = y; + renderer->end = 0; + if (GBAObjAttributesAIsMosaic(sprite->obj.a)) { + localY = mosaicY; + } + if ((localY < sprite->y && (sprite->endY - 256 < 0 || localY >= sprite->endY - 256)) || localY >= sprite->endY) { continue; } - int i; - int drawn; - - for (i = 0; i < renderer->oamMax; ++i) { - int localY = y; + for (w = 0; w < renderer->nWindows; ++w) { if (renderer->spriteCyclesRemaining <= 0) { break; } - struct GBAVideoSoftwareSprite* sprite = &renderer->sprites[i]; - if (GBAObjAttributesAIsMosaic(sprite->obj.a)) { - localY = mosaicY; - } - if ((localY < sprite->y && (sprite->endY - 256 < 0 || localY >= sprite->endY - 256)) || localY >= sprite->endY) { + renderer->currentWindow = renderer->windows[w].control; + renderer->start = renderer->end; + renderer->end = renderer->windows[w].endX; + if (!GBAWindowControlIsObjEnable(renderer->currentWindow.packed) && !GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt)) { continue; } - drawn = GBAVideoSoftwareRendererPreprocessSprite(renderer, &sprite->obj, localY); + + int drawn = GBAVideoSoftwareRendererPreprocessSprite(renderer, &sprite->obj, localY); spriteLayers |= drawn << GBAObjAttributesCGetPriority(sprite->obj.c); + } + if (renderer->spriteCyclesRemaining <= 0) { + break; } } }