all repos — mgba @ 2bc23e7aa26a554cb13e737d03404f6e2546548d

mGBA Game Boy Advance Emulator

Redo compositing and sprite blending
Jeffrey Pfau jeffrey@endrift.com
Sat, 27 Apr 2013 01:36:06 -0700
commit

2bc23e7aa26a554cb13e737d03404f6e2546548d

parent

b3e1aa785326fafab1806bc76fa0f08fa9da78f7

2 files changed, 20 insertions(+), 23 deletions(-)

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

@@ -296,30 +296,28 @@ }

} static void _composite(struct GBAVideoSoftwareRenderer* renderer, int offset, uint16_t color, struct PixelFlags flags) { - if (renderer->flags[offset].isSprite && flags.priority >= renderer->flags[offset].priority) { - if (renderer->flags[offset].target1) { - if (flags.target2) { - renderer->row[offset] = _mix(renderer->bldb, color, renderer->blda, renderer->row[offset]); + struct PixelFlags currentFlags = renderer->flags[offset]; + if (currentFlags.isSprite && flags.priority >= currentFlags.priority) { + if (currentFlags.target1) { + if (currentFlags.written && currentFlags.target2) { + renderer->row[offset] = _mix(renderer->blda, renderer->row[offset], renderer->bldb, renderer->spriteLayer[offset]); + } else if (flags.target2) { + renderer->row[offset] = _mix(renderer->bldb, color, renderer->blda, renderer->spriteLayer[offset]); } + } else if (!currentFlags.written) { + renderer->row[offset] = renderer->spriteLayer[offset]; } renderer->flags[offset].finalized = 1; - renderer->flags[offset].written = 1; return; } - if (renderer->blendEffect == BLEND_NONE || (!flags.target1 && !flags.target2)) { - renderer->row[offset] = color; - renderer->flags[offset].finalized = 1; - } else if (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN) { + if (renderer->blendEffect != BLEND_ALPHA || (!flags.target1 && !flags.target2)) { renderer->row[offset] = color; renderer->flags[offset].finalized = 1; } else if (renderer->blendEffect == BLEND_ALPHA) { - if (renderer->flags[offset].written) { - if (renderer->flags[offset].target1 && flags.target2) { + if (currentFlags.written) { + if (currentFlags.target1 && flags.target2) { renderer->row[offset] = _mix(renderer->bldb, color, renderer->blda, renderer->row[offset]); } - renderer->flags[offset].finalized = 1; - } else if (renderer->flags[offset].isSprite && renderer->flags[offset].target2 && flags.target1) { - renderer->row[offset] = _mix(renderer->blda, color, renderer->bldb, renderer->row[offset]); renderer->flags[offset].finalized = 1; } else { renderer->row[offset] = color;

@@ -412,7 +410,7 @@

uint32_t screenBase; uint32_t charBase; struct PixelFlags flags = { - .target1 = background->target1, + .target1 = background->target1 && renderer->blendEffect == BLEND_ALPHA, .target2 = background->target2, .priority = background->priority };

@@ -457,11 +455,10 @@ int height = _objSizes[sprite->shape * 8 + sprite->size * 2 + 1];

if ((y < sprite->y && (sprite->y + height - 256 < 0 || y >= sprite->y + height - 256)) || y >= sprite->y + height) { return; } - (void)(renderer); struct PixelFlags flags = { .priority = sprite->priority, .isSprite = 1, - .target1 = renderer->target1Obj || sprite->mode == OBJ_MODE_SEMITRANSPARENT, + .target1 = (renderer->target1Obj && renderer->blendEffect == BLEND_ALPHA) || sprite->mode == OBJ_MODE_SEMITRANSPARENT, .target2 = renderer->target2Obj }; int x = sprite->x;

@@ -487,9 +484,9 @@ uint16_t tileData = renderer->d.vram[(yBase + charBase + xBase) >> 1];

tileData = (tileData >> ((inX & 3) << 2)) & 0xF; if (tileData) { if (!renderer->target1Obj) { - renderer->row[outX] = renderer->d.palette[0x100 | tileData | (sprite->palette << 4)]; + renderer->spriteLayer[outX] = renderer->d.palette[0x100 | tileData | (sprite->palette << 4)]; } else { - renderer->row[outX] = renderer->variantPalette[0x100 | tileData | (sprite->palette << 4)]; + renderer->spriteLayer[outX] = renderer->variantPalette[0x100 | tileData | (sprite->palette << 4)]; } renderer->flags[outX] = flags; }

@@ -504,11 +501,10 @@ int totalHeight = height << sprite->doublesize;

if ((y < sprite->y && (sprite->y + totalHeight - 256 < 0 || y >= sprite->y + totalHeight - 256)) || y >= sprite->y + totalHeight) { return; } - (void)(renderer); struct PixelFlags flags = { .priority = sprite->priority, .isSprite = 1, - .target1 = renderer->target1Obj || sprite->mode == OBJ_MODE_SEMITRANSPARENT, + .target1 = (renderer->target1Obj && renderer->blendEffect == BLEND_ALPHA) || sprite->mode == OBJ_MODE_SEMITRANSPARENT, .target2 = renderer->target2Obj }; int x = sprite->x;

@@ -533,9 +529,9 @@ uint16_t tileData = renderer->d.vram[(yBase + charBase + xBase) >> 1];

tileData = (tileData >> ((localX & 3) << 2)) & 0xF; if (tileData) { if (!renderer->target1Obj) { - renderer->row[outX] = renderer->d.palette[0x100 | tileData | (sprite->palette << 4)]; + renderer->spriteLayer[outX] = renderer->d.palette[0x100 | tileData | (sprite->palette << 4)]; } else { - renderer->row[outX] = renderer->variantPalette[0x100 | tileData | (sprite->palette << 4)]; + renderer->spriteLayer[outX] = renderer->variantPalette[0x100 | tileData | (sprite->palette << 4)]; } renderer->flags[outX] = flags; }
M src/gba/renderers/video-software.hsrc/gba/renderers/video-software.h

@@ -53,6 +53,7 @@ unsigned outputBufferStride;

union GBARegisterDISPCNT dispcnt; + uint16_t spriteLayer[VIDEO_HORIZONTAL_PIXELS]; struct PixelFlags flags[VIDEO_HORIZONTAL_PIXELS]; // BLDCNT