all repos — mgba @ 969fea54946d6d0ba0153773bcebbe27c65e437a

mGBA Game Boy Advance Emulator

GBA Video: Improve sprite cycle counting (fixes #1274)
Vicki Pfau vi@endrift.com
Sat, 26 Jan 2019 22:41:24 -0800
commit

969fea54946d6d0ba0153773bcebbe27c65e437a

parent

e0c5196e91c18c5ac672b5f03ed181f649229869

M CHANGESCHANGES

@@ -1,3 +1,7 @@

+0.7.1: (Future) +Misc: + - GBA Video: Improve sprite cycle counting (fixes mgba.io/i/1274) + 0.7.0: (2019-01-26) Features: - ELF support
M src/gba/renderers/software-obj.csrc/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.csrc/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; } } }