mirror of https://github.com/mgba-emu/mgba.git
Redo compositing and sprite blending
This commit is contained in:
parent
b3e1aa7853
commit
2bc23e7aa2
|
@ -296,31 +296,29 @@ static void GBAVideoSoftwareRendererWriteBLDCNT(struct GBAVideoSoftwareRenderer*
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _composite(struct GBAVideoSoftwareRenderer* renderer, int offset, uint16_t color, struct PixelFlags flags) {
|
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) {
|
struct PixelFlags currentFlags = renderer->flags[offset];
|
||||||
if (renderer->flags[offset].target1) {
|
if (currentFlags.isSprite && flags.priority >= currentFlags.priority) {
|
||||||
if (flags.target2) {
|
if (currentFlags.target1) {
|
||||||
renderer->row[offset] = _mix(renderer->bldb, color, renderer->blda, renderer->row[offset]);
|
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].finalized = 1;
|
||||||
renderer->flags[offset].written = 1;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (renderer->blendEffect == BLEND_NONE || (!flags.target1 && !flags.target2)) {
|
if (renderer->blendEffect != BLEND_ALPHA || (!flags.target1 && !flags.target2)) {
|
||||||
renderer->row[offset] = color;
|
|
||||||
renderer->flags[offset].finalized = 1;
|
|
||||||
} else if (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN) {
|
|
||||||
renderer->row[offset] = color;
|
renderer->row[offset] = color;
|
||||||
renderer->flags[offset].finalized = 1;
|
renderer->flags[offset].finalized = 1;
|
||||||
} else if (renderer->blendEffect == BLEND_ALPHA) {
|
} else if (renderer->blendEffect == BLEND_ALPHA) {
|
||||||
if (renderer->flags[offset].written) {
|
if (currentFlags.written) {
|
||||||
if (renderer->flags[offset].target1 && flags.target2) {
|
if (currentFlags.target1 && flags.target2) {
|
||||||
renderer->row[offset] = _mix(renderer->bldb, color, renderer->blda, renderer->row[offset]);
|
renderer->row[offset] = _mix(renderer->bldb, color, renderer->blda, renderer->row[offset]);
|
||||||
}
|
}
|
||||||
renderer->flags[offset].finalized = 1;
|
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 {
|
} else {
|
||||||
renderer->row[offset] = color;
|
renderer->row[offset] = color;
|
||||||
renderer->flags[offset].target1 = flags.target1;
|
renderer->flags[offset].target1 = flags.target1;
|
||||||
|
@ -412,7 +410,7 @@ static void _drawBackgroundMode0(struct GBAVideoSoftwareRenderer* renderer, stru
|
||||||
uint32_t screenBase;
|
uint32_t screenBase;
|
||||||
uint32_t charBase;
|
uint32_t charBase;
|
||||||
struct PixelFlags flags = {
|
struct PixelFlags flags = {
|
||||||
.target1 = background->target1,
|
.target1 = background->target1 && renderer->blendEffect == BLEND_ALPHA,
|
||||||
.target2 = background->target2,
|
.target2 = background->target2,
|
||||||
.priority = background->priority
|
.priority = background->priority
|
||||||
};
|
};
|
||||||
|
@ -457,11 +455,10 @@ static void _drawSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBAObj
|
||||||
if ((y < sprite->y && (sprite->y + height - 256 < 0 || y >= sprite->y + height - 256)) || y >= sprite->y + height) {
|
if ((y < sprite->y && (sprite->y + height - 256 < 0 || y >= sprite->y + height - 256)) || y >= sprite->y + height) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(void)(renderer);
|
|
||||||
struct PixelFlags flags = {
|
struct PixelFlags flags = {
|
||||||
.priority = sprite->priority,
|
.priority = sprite->priority,
|
||||||
.isSprite = 1,
|
.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
|
.target2 = renderer->target2Obj
|
||||||
};
|
};
|
||||||
int x = sprite->x;
|
int x = sprite->x;
|
||||||
|
@ -487,9 +484,9 @@ static void _drawSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBAObj
|
||||||
tileData = (tileData >> ((inX & 3) << 2)) & 0xF;
|
tileData = (tileData >> ((inX & 3) << 2)) & 0xF;
|
||||||
if (tileData) {
|
if (tileData) {
|
||||||
if (!renderer->target1Obj) {
|
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 {
|
} 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;
|
renderer->flags[outX] = flags;
|
||||||
}
|
}
|
||||||
|
@ -504,11 +501,10 @@ static void _drawTransformedSprite(struct GBAVideoSoftwareRenderer* renderer, st
|
||||||
if ((y < sprite->y && (sprite->y + totalHeight - 256 < 0 || y >= sprite->y + totalHeight - 256)) || y >= sprite->y + totalHeight) {
|
if ((y < sprite->y && (sprite->y + totalHeight - 256 < 0 || y >= sprite->y + totalHeight - 256)) || y >= sprite->y + totalHeight) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(void)(renderer);
|
|
||||||
struct PixelFlags flags = {
|
struct PixelFlags flags = {
|
||||||
.priority = sprite->priority,
|
.priority = sprite->priority,
|
||||||
.isSprite = 1,
|
.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
|
.target2 = renderer->target2Obj
|
||||||
};
|
};
|
||||||
int x = sprite->x;
|
int x = sprite->x;
|
||||||
|
@ -533,9 +529,9 @@ static void _drawTransformedSprite(struct GBAVideoSoftwareRenderer* renderer, st
|
||||||
tileData = (tileData >> ((localX & 3) << 2)) & 0xF;
|
tileData = (tileData >> ((localX & 3) << 2)) & 0xF;
|
||||||
if (tileData) {
|
if (tileData) {
|
||||||
if (!renderer->target1Obj) {
|
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 {
|
} 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;
|
renderer->flags[outX] = flags;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ struct GBAVideoSoftwareRenderer {
|
||||||
|
|
||||||
union GBARegisterDISPCNT dispcnt;
|
union GBARegisterDISPCNT dispcnt;
|
||||||
|
|
||||||
|
uint16_t spriteLayer[VIDEO_HORIZONTAL_PIXELS];
|
||||||
struct PixelFlags flags[VIDEO_HORIZONTAL_PIXELS];
|
struct PixelFlags flags[VIDEO_HORIZONTAL_PIXELS];
|
||||||
|
|
||||||
// BLDCNT
|
// BLDCNT
|
||||||
|
|
Loading…
Reference in New Issue