all repos — mgba @ ee5c9c8a91ed94dd0a3858f3d265ba12f57714ca

mGBA Game Boy Advance Emulator

GBA Video: Fix regressions from sprite cycle counting
Jeffrey Pfau jeffrey@endrift.com
Wed, 06 Jan 2016 20:43:36 -0800
commit

ee5c9c8a91ed94dd0a3858f3d265ba12f57714ca

parent

95d77f76e242b28e2afb5fb1d8f79c95cb26cfc4

1 files changed, 19 insertions(+), 9 deletions(-)

jump to
M src/gba/renderers/software-obj.csrc/gba/renderers/software-obj.c

@@ -12,6 +12,7 @@ for (; outX < condition; ++outX, inX += xOffset) { \

if (!(renderer->row[outX] & FLAG_UNWRITTEN)) { \ continue; \ } \ + renderer->spriteCyclesRemaining -= 1; \ SPRITE_XBASE_ ## DEPTH(inX); \ SPRITE_DRAW_PIXEL_ ## DEPTH ## _ ## TYPE(inX); \ }

@@ -44,10 +45,11 @@ #define SPRITE_TRANSFORMED_LOOP(DEPTH, TYPE) \

unsigned tileData; \ unsigned widthMask = ~(width - 1); \ unsigned heightMask = ~(height - 1); \ - for (; outX < x + totalWidth && outX < end; ++outX, ++inX) { \ + for (; outX < condition; ++outX, ++inX) { \ if (!(renderer->row[outX] & FLAG_UNWRITTEN)) { \ continue; \ } \ + renderer->spriteCyclesRemaining -= 2; \ xAccum += mat.a; \ yAccum += mat.c; \ int localX = (xAccum >> 8) + (width >> 1); \

@@ -147,6 +149,10 @@ unsigned charBase = GBAObjAttributesCGetTile(sprite->c) * 0x20;

if (GBARegisterDISPCNTGetMode(renderer->dispcnt) >= 3 && GBAObjAttributesCGetTile(sprite->c) < 512) { return 0; } + if (renderer->spriteCyclesRemaining <= 0) { + return 0; + } + int variant = renderer->target1Obj && GBAWindowControlIsBlendEnable(renderer->currentWindow.packed) && (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN);

@@ -178,10 +184,7 @@ uint32_t current;

if (GBAObjAttributesAIsTransformed(sprite->a)) { int totalWidth = width << GBAObjAttributesAGetDoubleSize(sprite->a); int totalHeight = height << GBAObjAttributesAGetDoubleSize(sprite->a); - renderer->spriteCyclesRemaining -= 10 + totalWidth * 2; - if (renderer->spriteCyclesRemaining <= 0) { - return 0; - } + renderer->spriteCyclesRemaining -= 10; struct GBAOAMMatrix mat; LOAD_16(mat.a, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].a); LOAD_16(mat.b, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].b);

@@ -192,10 +195,15 @@ if (inY < 0) {

inY += 256; } int outX = x >= start ? x : start; + int condition = x + totalWidth; int inX = outX - x; int xAccum = mat.a * (inX - 1 - (totalWidth >> 1)) + mat.b * (inY - (totalHeight >> 1)); int yAccum = mat.c * (inX - 1 - (totalWidth >> 1)) + mat.d * (inY - (totalHeight >> 1)); + if (end < condition) { + condition = end; + } + if (!GBAObjAttributesAIs256Color(sprite->a)) { palette = &palette[GBAObjAttributesCGetPalette(sprite->c) << 4]; if (flags & FLAG_OBJWIN) {

@@ -215,11 +223,10 @@ } else {

SPRITE_TRANSFORMED_LOOP(256, NORMAL); } } + if (x + totalWidth > VIDEO_HORIZONTAL_PIXELS) { + renderer->spriteCyclesRemaining -= (x + totalWidth - VIDEO_HORIZONTAL_PIXELS) * 2; + } } else { - renderer->spriteCyclesRemaining -= width; - if (renderer->spriteCyclesRemaining <= 0) { - return 0; - } int outX = x >= start ? x : start; int condition = x + width; int mosaicH = 1;

@@ -276,6 +283,9 @@ SPRITE_NORMAL_LOOP(256, NORMAL_OBJWIN);

} else { SPRITE_NORMAL_LOOP(256, NORMAL); } + } + if (x + width > VIDEO_HORIZONTAL_PIXELS) { + renderer->spriteCyclesRemaining -= x + width - VIDEO_HORIZONTAL_PIXELS; } } return 1;