all repos — mgba @ 4fecedb42a6a27a6de2fb99b60de77914c15828e

mGBA Game Boy Advance Emulator

DS GX: Start on alpha
Vicki Pfau vi@endrift.com
Sat, 04 Mar 2017 16:01:43 -0800
commit

4fecedb42a6a27a6de2fb99b60de77914c15828e

parent

1ed7db5c9cf9049142608b80705b45e435083139

1 files changed, 49 insertions(+), 1 deletions(-)

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

@@ -40,6 +40,36 @@ #error Unsupported color depth

#endif } +static unsigned _mix32(int weightA, unsigned colorA, int weightB, unsigned colorB) { + unsigned c = 0; + unsigned a, b; +#ifdef COLOR_16_BIT +#error Unsupported color depth +#else + a = colorA & 0xFF; + b = colorB & 0xFF; + c |= ((a * weightA + b * weightB) / 32) & 0x1FF; + if (c & 0x00000100) { + c = 0x000000FF; + } + + a = colorA & 0xFF00; + b = colorB & 0xFF00; + c |= ((a * weightA + b * weightB) / 32) & 0x1FF00; + if (c & 0x00010000) { + c = (c & 0x000000FF) | 0x0000FF00; + } + + a = colorA & 0xFF0000; + b = colorB & 0xFF0000; + c |= ((a * weightA + b * weightB) / 32) & 0x1FF0000; + if (c & 0x01000000) { + c = (c & 0x0000FFFF) | 0x00FF0000; + } +#endif + return c; +} + static color_t _lookupColor(struct DSGXSoftwareEndpoint* ep, struct DSGXSoftwarePolygon* poly) { // TODO: Optimize uint16_t texel;

@@ -444,7 +474,8 @@ for (; x < span->ep[1].x >> 12 && x < DS_VIDEO_HORIZONTAL_PIXELS; ++x) {

struct DSGXSoftwareEndpoint ep; _lerpEndpoint(span, &ep, x); color_t color = _lookupColor(&ep, span->poly); - if (color & 0xF8000000) { + unsigned a = color >> 27; + if (a == 0x1F || (a && !(scanline[x] & 0xF8000000))) { // TODO: Alpha if (softwareRenderer->wSort) { if (ep.w < softwareRenderer->depthBuffer[x]) {

@@ -455,6 +486,23 @@ } else {

if (ep.z < softwareRenderer->depthBuffer[x]) { softwareRenderer->depthBuffer[x] = ep.z; scanline[x] = color; + } + } + } else if (a) { + // TODO: Disable alpha? + color = _mix32(a, color, 0x1F - a, scanline[x]); + if (scanline[x] >> 27 > a) { + a = scanline[x] >> 27; + } + color |= a << 27; + scanline[x] = color; + if (softwareRenderer->wSort) { + if (ep.w < softwareRenderer->depthBuffer[x]) { + softwareRenderer->depthBuffer[x] = ep.w; + } + } else { + if (ep.z < softwareRenderer->depthBuffer[x]) { + softwareRenderer->depthBuffer[x] = ep.z; } } }