GBA Video: Improve sprite cycle counting (fixes #1274)

This commit is contained in:
Vicki Pfau 2019-01-26 22:41:24 -08:00
parent e0c5196e91
commit 969fea5494
11 changed files with 23 additions and 20 deletions

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

View File

@ -145,9 +145,6 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
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 &&

View File

@ -809,7 +809,6 @@ static void GBAVideoSoftwareRendererWriteBLDCNT(struct GBAVideoSoftwareRenderer*
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,31 +817,34 @@ static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) {
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;
}
}
}