DS GX: Improve alpha slightly
Vicki Pfau vi@endrift.com
Sat, 04 Mar 2017 21:50:58 -0800
2 files changed,
13 insertions(+),
34 deletions(-)
M
include/mgba/internal/ds/gx.h
→
include/mgba/internal/ds/gx.h
@@ -56,6 +56,7 @@ DECL_BITS(DSGXPolygonAttrs, Mode, 4, 2);
DECL_BIT(DSGXPolygonAttrs, FrontFace, 6); DECL_BIT(DSGXPolygonAttrs, BackFace, 7); // TODO +DECL_BITS(DSGXPolygonAttrs, Alpha, 16, 5); enum DSGXCommand { DS_GX_CMD_NOP = 0,
M
src/ds/gx/software.c
→
src/ds/gx/software.c
@@ -106,11 +106,11 @@ t &= poly->texH - 1;
} uint16_t texelCoord = s + t * poly->texW; - uint8_t a = 0x1F; + uint8_t a = DSGXPolygonAttrsGetAlpha(poly->poly->polyParams); switch (poly->texFormat) { case 0: default: - return _finishColor(ep->cr, ep->cg, ep->cb, 0x1F); + return _finishColor(ep->cr, ep->cg, ep->cb, a); case 1: texel = ((uint8_t*) poly->texBase)[texelCoord]; a = (texel >> 5) & 0x7;@@ -164,26 +164,6 @@ return _finishColor(wr, wg, wb, a);
} } -static int _edgeSort(const void* a, const void* b) { - const struct DSGXSoftwareEdge* ea = a; - const struct DSGXSoftwareEdge* eb = b; - - // Sort upside down - if (ea->y0 < eb->y0) { - return 1; - } - if (ea->y0 > eb->y0) { - return -1; - } - if (ea->y1 < eb->y1) { - return 1; - } - if (ea->y1 > eb->y1) { - return -1; - } - return 0; -} - static bool _edgeToSpan(struct DSGXSoftwareSpan* span, const struct DSGXSoftwareEdge* edge, int index, int32_t y) { int32_t height = edge->y1 - edge->y0; int64_t yw = (y << 12) - edge->y0;@@ -192,9 +172,9 @@ return false;
} // Clamp to bounds if (yw < 0) { - yw = 0; + return false; } else if (yw > height) { - yw = height; + return false; } yw *= 0x100000000LL / height;@@ -415,7 +395,6 @@ edge->s1 = v0->vs;
edge->t1 = v0->vt; } } - qsort(DSGXSoftwareEdgeListGetPointer(&softwareRenderer->activeEdges, 0), DSGXSoftwareEdgeListSize(&softwareRenderer->activeEdges), sizeof(struct DSGXSoftwareEdge), _edgeSort); } static void DSGXSoftwareRendererDrawScanline(struct DSGXRenderer* renderer, int y) {@@ -426,11 +405,9 @@ }
DSGXSoftwareSpanListClear(&softwareRenderer->activeSpans); memset(softwareRenderer->bucket, 0, sizeof(*softwareRenderer->bucket) * DS_GX_POLYGON_BUFFER_SIZE); size_t i; - for (i = DSGXSoftwareEdgeListSize(&softwareRenderer->activeEdges); i; --i) { - size_t idx = i - 1; - struct DSGXSoftwareEdge* edge = DSGXSoftwareEdgeListGetPointer(&softwareRenderer->activeEdges, idx); + for (i = 0; i < DSGXSoftwareEdgeListSize(&softwareRenderer->activeEdges); ++i) { + struct DSGXSoftwareEdge* edge = DSGXSoftwareEdgeListGetPointer(&softwareRenderer->activeEdges, i); if (edge->y1 >> 12 < y) { - DSGXSoftwareEdgeListShift(&softwareRenderer->activeEdges, idx, 1); continue; } else if (edge->y0 >> 12 > y) { continue;@@ -439,8 +416,9 @@
unsigned poly = edge->polyId; struct DSGXSoftwareSpan* span = softwareRenderer->bucket[poly]; if (span && !span->ep[1].w) { - _edgeToSpan(span, edge, 1, y); - softwareRenderer->bucket[poly] = NULL; + if (_edgeToSpan(span, edge, 1, y)) { + softwareRenderer->bucket[poly] = NULL; + } } else if (!span) { span = DSGXSoftwareSpanListAppend(&softwareRenderer->activeSpans); memset(&span->ep[1], 0, sizeof(span->ep[1]));@@ -475,8 +453,7 @@ struct DSGXSoftwareEndpoint ep;
_lerpEndpoint(span, &ep, x); color_t color = _lookupColor(&ep, span->poly); unsigned a = color >> 27; - if (a == 0x1F || (a && !(scanline[x] & 0xF8000000))) { - // TODO: Alpha + if (a == 0x1F || !(scanline[x] & 0xF8000000)) { if (softwareRenderer->wSort) { if (ep.w < softwareRenderer->depthBuffer[x]) { softwareRenderer->depthBuffer[x] = ep.w;@@ -495,14 +472,15 @@ 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; + scanline[x] = color; } } else { if (ep.z < softwareRenderer->depthBuffer[x]) { softwareRenderer->depthBuffer[x] = ep.z; + scanline[x] = color; } } }