mirror of https://github.com/mgba-emu/mgba.git
GBA Video: Fix out of bounds sprite transforms
This commit is contained in:
parent
4085b9cdc5
commit
3415484d9d
1
CHANGES
1
CHANGES
|
@ -34,6 +34,7 @@ Bugfixes:
|
|||
- GBA: Add savegame override for Crash Bandicoot 2
|
||||
- ARM7: PSR mode bits should not get sign extended
|
||||
- GBA: Only unhalt CPU if an IRQ actually fires
|
||||
- GBA Video: Fix out of bounds sprite transforms
|
||||
Misc:
|
||||
- SDL: Remove scancode key input
|
||||
- GBA Video: Clean up unused timers
|
||||
|
|
|
@ -52,8 +52,8 @@
|
|||
renderer->spriteCyclesRemaining -= 2; \
|
||||
xAccum += mat.a; \
|
||||
yAccum += mat.c; \
|
||||
int localX = (xAccum >> 8) + (width >> 1); \
|
||||
int localY = (yAccum >> 8) + (height >> 1); \
|
||||
int localX = xAccum >> 8; \
|
||||
int localY = yAccum >> 8; \
|
||||
\
|
||||
if (localX & widthMask || localY & heightMask) { \
|
||||
break; \
|
||||
|
@ -200,24 +200,25 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
|
|||
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;
|
||||
}
|
||||
|
||||
int xAccum = mat.a * (inX - 1 - (totalWidth >> 1)) + mat.b * (inY - (totalHeight >> 1)) + (width << 7);
|
||||
int yAccum = mat.c * (inX - 1 - (totalWidth >> 1)) + mat.d * (inY - (totalHeight >> 1)) + (height << 7);
|
||||
|
||||
// Clip off early pixels
|
||||
// TODO: Transform end coordinates too
|
||||
if (mat.a) {
|
||||
if ((xAccum >> 8) < -(width >> 1)) {
|
||||
int32_t diffX = -(width << 7) - xAccum - 1;
|
||||
if ((xAccum >> 8) < 0) {
|
||||
int32_t diffX = -xAccum - 1;
|
||||
int32_t x = mat.a ? diffX / mat.a : 0;
|
||||
xAccum += mat.a * x;
|
||||
yAccum += mat.c * x;
|
||||
outX += x;
|
||||
inX += x;
|
||||
} else if ((xAccum >> 8) >= (width >> 1)) {
|
||||
int32_t diffX = (width << 7) - xAccum;
|
||||
} else if ((xAccum >> 8) >= width) {
|
||||
int32_t diffX = (width << 8) - xAccum;
|
||||
int32_t x = mat.a ? diffX / mat.a : 0;
|
||||
xAccum += mat.a * x;
|
||||
yAccum += mat.c * x;
|
||||
|
@ -226,15 +227,15 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
|
|||
}
|
||||
}
|
||||
if (mat.c) {
|
||||
if ((yAccum >> 8) < -(height >> 1)) {
|
||||
int32_t diffY = -(height << 7) - yAccum - 1;
|
||||
if ((yAccum >> 8) < 0) {
|
||||
int32_t diffY = - yAccum - 1;
|
||||
int32_t y = mat.c ? diffY / mat.c : 0;
|
||||
xAccum += mat.a * y;
|
||||
yAccum += mat.c * y;
|
||||
outX += y;
|
||||
inX += y;
|
||||
} else if ((yAccum >> 8) >= (height >> 1)) {
|
||||
int32_t diffY = (height << 7) - yAccum;
|
||||
} else if ((yAccum >> 8) >= height) {
|
||||
int32_t diffY = (height << 8) - yAccum;
|
||||
int32_t y = mat.c ? diffY / mat.c : 0;
|
||||
xAccum += mat.a * y;
|
||||
yAccum += mat.c * y;
|
||||
|
@ -243,6 +244,10 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
|
|||
}
|
||||
}
|
||||
|
||||
if (outX < start || outX >= condition) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!GBAObjAttributesAIs256Color(sprite->a)) {
|
||||
palette = &palette[GBAObjAttributesCGetPalette(sprite->c) << 4];
|
||||
if (flags & FLAG_OBJWIN) {
|
||||
|
|
Loading…
Reference in New Issue