all repos — mgba @ f6e0239cd339da24e04b30e394f84cffd4197a79

mGBA Game Boy Advance Emulator

GBA Video: Fix objwin and blending interaction on sprites
Jeffrey Pfau jeffrey@endrift.com
Wed, 16 Sep 2015 21:03:42 -0700
commit

f6e0239cd339da24e04b30e394f84cffd4197a79

parent

ea1f87d745a4b686ecb0b74a2303a71a5a27dda2

2 files changed, 43 insertions(+), 0 deletions(-)

jump to
M CHANGESCHANGES

@@ -13,6 +13,7 @@ - GBA Audio: Fix audio channels being silenced at the wrong time

- VFS: Fix return values of VFileFILE.read and .write - Util: Fix PowerPC PNG read/write pixel order - GBA Video: Fix edge case with sprite blend modes and semitransparency + - GBA Video: Fix objwin and blending interaction on sprites Misc: - Qt: Window size command line options are now supported - Qt: Increase usability of key mapper
M src/gba/renderers/software-obj.csrc/gba/renderers/software-obj.c

@@ -75,6 +75,19 @@ renderer->spriteLayer[outX] = (current & ~FLAG_ORDER_MASK) | GBAObjAttributesCGetPriority(sprite->c) << OFFSET_PRIORITY; \

} \ } +#define SPRITE_DRAW_PIXEL_16_NORMAL_OBJWIN(localX) \ + LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \ + tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \ + current = renderer->spriteLayer[outX]; \ + if ((current & FLAG_ORDER_MASK) > flags) { \ + if (tileData) { \ + unsigned color = (renderer->row[outX] & FLAG_OBJWIN) ? objwinPalette[tileData] : palette[tileData]; \ + renderer->spriteLayer[outX] = color | 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) \ LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \ tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \

@@ -97,6 +110,19 @@ renderer->spriteLayer[outX] = (current & ~FLAG_ORDER_MASK) | GBAObjAttributesCGetPriority(sprite->c) << OFFSET_PRIORITY; \

} \ } +#define SPRITE_DRAW_PIXEL_256_NORMAL_OBJWIN(localX) \ + LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \ + tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \ + current = renderer->spriteLayer[outX]; \ + if ((current & FLAG_ORDER_MASK) > flags) { \ + if (tileData) { \ + unsigned color = (renderer->row[outX] & FLAG_OBJWIN) ? objwinPalette[tileData] : palette[tileData]; \ + renderer->spriteLayer[outX] = color | 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) \ LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \ tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \

@@ -131,8 +157,14 @@ variant = 0;

} } color_t* palette = &renderer->normalPalette[0x100]; + color_t* objwinPalette = palette; + int objwinSlowPath = GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt) && GBAWindowControlGetBlendEnable(renderer->objwin.packed) != GBAWindowControlIsBlendEnable(renderer->currentWindow.packed); + if (variant) { palette = &renderer->variantPalette[0x100]; + if (GBAWindowControlIsBlendEnable(renderer->objwin.packed)) { + objwinPalette = palette; + } } int inY = y - (int) GBAObjAttributesAGetY(sprite->a);

@@ -159,12 +191,17 @@ if (!GBAObjAttributesAIs256Color(sprite->a)) {

palette = &palette[GBAObjAttributesCGetPalette(sprite->c) << 4]; if (flags & FLAG_OBJWIN) { SPRITE_TRANSFORMED_LOOP(16, OBJWIN); + } else if (objwinSlowPath) { + objwinPalette = &objwinPalette[GBAObjAttributesCGetPalette(sprite->c) << 4]; + SPRITE_TRANSFORMED_LOOP(16, NORMAL_OBJWIN); } else { SPRITE_TRANSFORMED_LOOP(16, NORMAL); } } else { if (flags & FLAG_OBJWIN) { SPRITE_TRANSFORMED_LOOP(256, OBJWIN); + } else if (objwinSlowPath) { + SPRITE_TRANSFORMED_LOOP(256, NORMAL_OBJWIN); } else { SPRITE_TRANSFORMED_LOOP(256, NORMAL); }

@@ -200,6 +237,9 @@ if (flags & FLAG_OBJWIN) {

SPRITE_NORMAL_LOOP(16, OBJWIN); } else if (GBAObjAttributesAIsMosaic(sprite->a)) { SPRITE_MOSAIC_LOOP(16, NORMAL); + } else if (objwinSlowPath) { + objwinPalette = &objwinPalette[GBAObjAttributesCGetPalette(sprite->c) << 4]; + SPRITE_NORMAL_LOOP(16, NORMAL_OBJWIN); } else { SPRITE_NORMAL_LOOP(16, NORMAL); }

@@ -208,6 +248,8 @@ if (flags & FLAG_OBJWIN) {

SPRITE_NORMAL_LOOP(256, OBJWIN); } else if (GBAObjAttributesAIsMosaic(sprite->a)) { SPRITE_MOSAIC_LOOP(256, NORMAL); + } else if (objwinSlowPath) { + SPRITE_NORMAL_LOOP(256, NORMAL_OBJWIN); } else { SPRITE_NORMAL_LOOP(256, NORMAL); }