mirror of https://github.com/mgba-emu/mgba.git
GBA Video: Simplify sprite cycle counting (fixes #1279)
This commit is contained in:
parent
d61d9ef6a6
commit
031049cd06
1
CHANGES
1
CHANGES
|
@ -27,6 +27,7 @@ Emulation fixes:
|
|||
- GBA Video: Fix disabling OBJWIN in GL renderer (fixes mgba.io/i/1759)
|
||||
- GBA Video: Add missing parts of 256-color mode 0 mosaic (fixes mgba.io/i/1701)
|
||||
- GBA Video: Fix double-size OBJ wrapping in GL renderer (fixes mgba.io/i/1712)
|
||||
- GBA Video: Simplify sprite cycle counting (fixes mgba.io/i/1279)
|
||||
- SM83: Emulate HALT bug
|
||||
Other fixes:
|
||||
- 3DS: Fix framelimiter on newer citro3d (fixes mgba.io/i/1771)
|
||||
|
|
|
@ -16,6 +16,7 @@ struct GBAVideoRendererSprite {
|
|||
struct GBAObj obj;
|
||||
int16_t y;
|
||||
int16_t endY;
|
||||
int16_t cycles;
|
||||
int8_t index;
|
||||
};
|
||||
|
||||
|
|
|
@ -16,14 +16,19 @@ int GBAVideoRendererCleanOAM(struct GBAObj* oam, struct GBAVideoRendererSprite*
|
|||
LOAD_16LE(obj.b, 0, &oam[i].b);
|
||||
LOAD_16LE(obj.c, 0, &oam[i].c);
|
||||
if (GBAObjAttributesAIsTransformed(obj.a) || !GBAObjAttributesAIsDisable(obj.a)) {
|
||||
int width = GBAVideoObjSizes[GBAObjAttributesAGetShape(obj.a) * 4 + GBAObjAttributesBGetSize(obj.b)][0];
|
||||
int height = GBAVideoObjSizes[GBAObjAttributesAGetShape(obj.a) * 4 + GBAObjAttributesBGetSize(obj.b)][1];
|
||||
int cycles = width;
|
||||
if (GBAObjAttributesAIsTransformed(obj.a)) {
|
||||
height <<= GBAObjAttributesAGetDoubleSize(obj.a);
|
||||
width <<= GBAObjAttributesAGetDoubleSize(obj.a);
|
||||
cycles = 10 + width * 2;
|
||||
}
|
||||
if (GBAObjAttributesAGetY(obj.a) < GBA_VIDEO_VERTICAL_PIXELS || GBAObjAttributesAGetY(obj.a) + height >= VIDEO_VERTICAL_TOTAL_PIXELS) {
|
||||
int y = GBAObjAttributesAGetY(obj.a) + offsetY;
|
||||
sprites[oamMax].y = y;
|
||||
sprites[oamMax].endY = y + height;
|
||||
sprites[oamMax].cycles = cycles;
|
||||
sprites[oamMax].obj = obj;
|
||||
sprites[oamMax].index = i;
|
||||
++oamMax;
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
SPRITE_YBASE_ ## DEPTH(inY); \
|
||||
unsigned tileData; \
|
||||
for (; outX < condition; ++outX, inX += xOffset) { \
|
||||
renderer->spriteCyclesRemaining -= 1; \
|
||||
SPRITE_XBASE_ ## DEPTH(inX); \
|
||||
SPRITE_DRAW_PIXEL_ ## DEPTH ## _ ## TYPE(inX); \
|
||||
}
|
||||
|
@ -33,7 +32,6 @@
|
|||
unsigned widthMask = ~(width - 1); \
|
||||
unsigned heightMask = ~(height - 1); \
|
||||
for (; outX < condition; ++outX, ++inX) { \
|
||||
renderer->spriteCyclesRemaining -= 2; \
|
||||
xAccum += mat.a; \
|
||||
yAccum += mat.c; \
|
||||
int localX = xAccum >> 8; \
|
||||
|
@ -55,7 +53,6 @@
|
|||
int localX = xAccum >> 8; \
|
||||
int localY = yAccum >> 8; \
|
||||
for (; outX < condition; ++outX, ++inX) { \
|
||||
renderer->spriteCyclesRemaining -= 2; \
|
||||
xAccum += mat.a; \
|
||||
yAccum += mat.c; \
|
||||
\
|
||||
|
@ -272,7 +269,6 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
|
|||
if (outX < start || outX >= condition) {
|
||||
return 0;
|
||||
}
|
||||
renderer->spriteCyclesRemaining -= 10;
|
||||
|
||||
if (!GBAObjAttributesAIs256Color(sprite->a)) {
|
||||
palette = &palette[GBAObjAttributesCGetPalette(sprite->c) << 4];
|
||||
|
@ -306,9 +302,6 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
|
|||
SPRITE_TRANSFORMED_LOOP(256, NORMAL);
|
||||
}
|
||||
}
|
||||
if (end == GBA_VIDEO_HORIZONTAL_PIXELS && x + totalWidth > GBA_VIDEO_HORIZONTAL_PIXELS) {
|
||||
renderer->spriteCyclesRemaining -= (x + totalWidth - GBA_VIDEO_HORIZONTAL_PIXELS) * 2;
|
||||
}
|
||||
} else {
|
||||
int outX = x >= start ? x : start;
|
||||
int condition = x + width;
|
||||
|
@ -366,9 +359,6 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
|
|||
SPRITE_NORMAL_LOOP(256, NORMAL);
|
||||
}
|
||||
}
|
||||
if (end == GBA_VIDEO_HORIZONTAL_PIXELS && x + width > GBA_VIDEO_HORIZONTAL_PIXELS) {
|
||||
renderer->spriteCyclesRemaining -= x + width - GBA_VIDEO_HORIZONTAL_PIXELS;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -845,12 +845,10 @@ static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) {
|
|||
}
|
||||
}
|
||||
for (w = 0; w < renderer->nWindows; ++w) {
|
||||
if (renderer->spriteCyclesRemaining <= 0) {
|
||||
break;
|
||||
}
|
||||
renderer->currentWindow = renderer->windows[w].control;
|
||||
renderer->start = renderer->end;
|
||||
renderer->end = renderer->windows[w].endX;
|
||||
// TODO: partial sprite drawing
|
||||
if (!GBAWindowControlIsObjEnable(renderer->currentWindow.packed) && !GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -858,6 +856,7 @@ static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) {
|
|||
int drawn = GBAVideoSoftwareRendererPreprocessSprite(renderer, &sprite->obj, sprite->index, localY);
|
||||
spriteLayers |= drawn << GBAObjAttributesCGetPriority(sprite->obj.c);
|
||||
}
|
||||
renderer->spriteCyclesRemaining -= sprite->cycles;
|
||||
if (renderer->spriteCyclesRemaining <= 0) {
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue