all repos — mgba @ eb15e02412dc545a9da81b90778d13e51679d392

mGBA Game Boy Advance Emulator

DS GX: Proper per-pixel blending
Vicki Pfau vi@endrift.com
Thu, 09 Mar 2017 14:23:37 -0500
commit

eb15e02412dc545a9da81b90778d13e51679d392

parent

197f73cf85d8b81da9c9620881991543e9d77b5f

2 files changed, 15 insertions(+), 11 deletions(-)

jump to
M src/ds/gx/software.csrc/ds/gx/software.c

@@ -127,15 +127,16 @@ t &= poly->texH - 1;

} uint16_t texelCoord = s + t * poly->texW; - uint8_t a = DSGXPolygonAttrsGetAlpha(poly->poly->polyParams); + uint8_t ta = 0x1F; + uint8_t pa = DSGXPolygonAttrsGetAlpha(poly->poly->polyParams); switch (poly->texFormat) { case 0: default: - return _finishColor(ep->cr, ep->cg, ep->cb, a); + return _finishColor(ep->cr, ep->cg, ep->cb, pa); case 1: texel = ((uint8_t*) poly->texBase)[texelCoord]; - a = (texel >> 5) & 0x7; - a = (a << 2) + (a >> 1); + ta = (texel >> 5) & 0x7; + ta = (ta << 2) + (ta >> 1); texel &= 0x1F; break; case 2:

@@ -163,14 +164,14 @@ texel &= 3;

break; case 6: texel = ((uint8_t*) poly->texBase)[texelCoord]; - a = (texel >> 3) & 0x1F; + ta = (texel >> 3) & 0x1F; texel &= 0x7; break; case 7: - return _finishColor(0x3F, 0x3F, 0x3F, 0x1F); + return _finishColor(0x3F, 0x3F, 0x3F, pa); } uint8_t r, g, b; - unsigned wr, wg, wb; + unsigned wr, wg, wb, wa; if (poly->texFormat == 5) { // TODO: Slot 2 uses upper half uint16_t texel2 = renderer->d.tex[1][texelCoord >> 1];

@@ -234,12 +235,13 @@ switch (poly->blendFormat) {

case 1: default: // TODO: Alpha - return _finishColor(r, g, b, a); + return _finishColor(r, g, b, pa); case 0: wr = ((r + 1) * (ep->cr + 1) - 1) >> 6; wg = ((g + 1) * (ep->cg + 1) - 1) >> 6; wb = ((b + 1) * (ep->cb + 1) - 1) >> 6; - return _finishColor(wr, wg, wb, a); + wa = ((ta + 1) * (pa + 1) - 1) >> 5; + return _finishColor(wr, wg, wb, wa); } }
M src/ds/renderers/software.csrc/ds/renderers/software.c

@@ -396,13 +396,15 @@ flags |= FLAG_TARGET_1 * (softwareRenderer->bg[0].target1 && softwareRenderer->blendEffect == BLEND_ALPHA && GBAWindowControlIsBlendEnable(softwareRenderer->currentWindow.packed));

int x; for (x = softwareRenderer->start; x < softwareRenderer->end; ++x) { if (scanline[x] & 0xF8000000) { - if (flags & FLAG_TARGET_1) { + if ((flags & FLAG_TARGET_1) && (scanline[x] >> 28) != 0xF) { // TODO: More precise values softwareRenderer->alphaA[x] = (scanline[x] >> 28) + 1; - softwareRenderer->alphaB[x] = 0x10 - softwareRenderer->alphaA[x]; + softwareRenderer->alphaB[x] = 0x10; _compositeBlendNoObjwin(softwareRenderer, x, (scanline[x] & 0x00FFFFFF) | flags, softwareRenderer->row[x]); } else { _compositeNoBlendNoObjwin(softwareRenderer, x, (scanline[x] & 0x00FFFFFF) | flags, softwareRenderer->row[x]); + softwareRenderer->alphaA[x] = 0x10; + softwareRenderer->alphaB[x] = 0; } } }