all repos — mgba @ 1e60a3011467aad08307bf3245789e8f1df93302

mGBA Game Boy Advance Emulator

GBA Video: Fix sprite mis-ordering behavior in some cases (fixes #168)
Jeffrey Pfau jeffrey@endrift.com
Mon, 29 Dec 2014 23:33:12 -0800
commit

1e60a3011467aad08307bf3245789e8f1df93302

parent

38cb3eeaa857e744917d3ed57263f7585bf74233

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

jump to
M CHANGESCHANGES

@@ -32,6 +32,7 @@ - Video: Fix uncompressed PCM audio recording

- GBA Video: Fix windows not disabling target 1 appropriately (fixes #161) - Debugger: Align PC-relative loads in Thumb - Debugger: Fix watchpoints triggering too late + - GBA Video: Fix sprite mis-ordering behavior in some cases (fixes #168) Misc: - Qt: Disable sync to video by default - GBA: Exit cleanly on FATAL if the port supports it
M src/gba/renderers/video-software.csrc/gba/renderers/video-software.c

@@ -1584,8 +1584,13 @@

#define SPRITE_DRAW_PIXEL_16_NORMAL(localX) \ LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFF), vramBase); \ tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \ - if (tileData && (renderer->spriteLayer[outX] & FLAG_ORDER_MASK) > flags) { \ - renderer->spriteLayer[outX] = palette[tileData] | flags; \ + current = renderer->spriteLayer[outX]; \ + if ((current & FLAG_ORDER_MASK) > flags) { \ + if (tileData) { \ + renderer->spriteLayer[outX] = palette[tileData] | flags; \ + } else if (current != FLAG_UNWRITTEN) { \ + renderer->spriteLayer[outX] = (current & ~FLAG_ORDER_MASK) | GBAObjAttributesCGetPriority(sprite->c) << OFFSET_PRIORITY; \ + } \ } #define SPRITE_DRAW_PIXEL_16_OBJWIN(localX) \

@@ -1601,8 +1606,13 @@

#define SPRITE_DRAW_PIXEL_256_NORMAL(localX) \ LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFF), vramBase); \ tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \ - if (tileData && (renderer->spriteLayer[outX] & FLAG_ORDER_MASK) > flags) { \ - renderer->spriteLayer[outX] = palette[tileData] | flags; \ + current = renderer->spriteLayer[outX]; \ + if ((current & FLAG_ORDER_MASK) > flags) { \ + if (tileData) { \ + renderer->spriteLayer[outX] = palette[tileData] | flags; \ + } else if (current != FLAG_UNWRITTEN) { \ + renderer->spriteLayer[outX] = (current & ~FLAG_ORDER_MASK) | GBAObjAttributesCGetPriority(sprite->c) << OFFSET_PRIORITY; \ + } \ } #define SPRITE_DRAW_PIXEL_256_OBJWIN(localX) \

@@ -1636,6 +1646,7 @@ }

int inY = y - (int) GBAObjAttributesAGetY(sprite->a); + uint32_t current; if (GBAObjAttributesAIsTransformed(sprite->a)) { int totalWidth = width << GBAObjAttributesAGetDoubleSize(sprite->a); int totalHeight = height << GBAObjAttributesAGetDoubleSize(sprite->a);