all repos — mgba @ 88ba6ee0b0e9872a1598a815d06c35529ee5d12f

mGBA Game Boy Advance Emulator

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

88ba6ee0b0e9872a1598a815d06c35529ee5d12f

parent

6fecc6d379a14da301606b463ce027e16f2706c6

2 files changed, 20 insertions(+), 16 deletions(-)

jump to
M CHANGESCHANGES

@@ -8,6 +8,7 @@ - GBA Savedata: EEPROM performance fixes

- GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash - GB Memory: Support running from blocked memory - Qt: Don't unload ROM immediately if it crashes + - GBA Video: Improve sprite cycle counting (fixes mgba.io/i/1274) 0.7.0: (Future) Features:
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,34 @@ }

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; + if (!GBAWindowControlIsObjEnable(renderer->currentWindow.packed) && !GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt)) { continue; } + + int drawn; + renderer->start = renderer->end; + renderer->end = renderer->windows[w].endX; drawn = GBAVideoSoftwareRendererPreprocessSprite(renderer, &sprite->obj, localY); spriteLayers |= drawn << GBAObjAttributesCGetPriority(sprite->obj.c); + } + if (renderer->spriteCyclesRemaining <= 0) { + break; } } }