mirror of https://github.com/mgba-emu/mgba.git
DS GX: Improve alpha slightly
This commit is contained in:
parent
4fecedb42a
commit
4bde13effb
|
@ -56,6 +56,7 @@ DECL_BITS(DSGXPolygonAttrs, Mode, 4, 2);
|
||||||
DECL_BIT(DSGXPolygonAttrs, FrontFace, 6);
|
DECL_BIT(DSGXPolygonAttrs, FrontFace, 6);
|
||||||
DECL_BIT(DSGXPolygonAttrs, BackFace, 7);
|
DECL_BIT(DSGXPolygonAttrs, BackFace, 7);
|
||||||
// TODO
|
// TODO
|
||||||
|
DECL_BITS(DSGXPolygonAttrs, Alpha, 16, 5);
|
||||||
|
|
||||||
enum DSGXCommand {
|
enum DSGXCommand {
|
||||||
DS_GX_CMD_NOP = 0,
|
DS_GX_CMD_NOP = 0,
|
||||||
|
|
|
@ -106,11 +106,11 @@ static color_t _lookupColor(struct DSGXSoftwareEndpoint* ep, struct DSGXSoftware
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t texelCoord = s + t * poly->texW;
|
uint16_t texelCoord = s + t * poly->texW;
|
||||||
uint8_t a = 0x1F;
|
uint8_t a = DSGXPolygonAttrsGetAlpha(poly->poly->polyParams);
|
||||||
switch (poly->texFormat) {
|
switch (poly->texFormat) {
|
||||||
case 0:
|
case 0:
|
||||||
default:
|
default:
|
||||||
return _finishColor(ep->cr, ep->cg, ep->cb, 0x1F);
|
return _finishColor(ep->cr, ep->cg, ep->cb, a);
|
||||||
case 1:
|
case 1:
|
||||||
texel = ((uint8_t*) poly->texBase)[texelCoord];
|
texel = ((uint8_t*) poly->texBase)[texelCoord];
|
||||||
a = (texel >> 5) & 0x7;
|
a = (texel >> 5) & 0x7;
|
||||||
|
@ -164,26 +164,6 @@ static color_t _lookupColor(struct DSGXSoftwareEndpoint* ep, struct DSGXSoftware
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
static bool _edgeToSpan(struct DSGXSoftwareSpan* span, const struct DSGXSoftwareEdge* edge, int index, int32_t y) {
|
||||||
int32_t height = edge->y1 - edge->y0;
|
int32_t height = edge->y1 - edge->y0;
|
||||||
int64_t yw = (y << 12) - edge->y0;
|
int64_t yw = (y << 12) - edge->y0;
|
||||||
|
@ -192,9 +172,9 @@ static bool _edgeToSpan(struct DSGXSoftwareSpan* span, const struct DSGXSoftware
|
||||||
}
|
}
|
||||||
// Clamp to bounds
|
// Clamp to bounds
|
||||||
if (yw < 0) {
|
if (yw < 0) {
|
||||||
yw = 0;
|
return false;
|
||||||
} else if (yw > height) {
|
} else if (yw > height) {
|
||||||
yw = height;
|
return false;
|
||||||
}
|
}
|
||||||
yw *= 0x100000000LL / height;
|
yw *= 0x100000000LL / height;
|
||||||
|
|
||||||
|
@ -415,7 +395,6 @@ static void DSGXSoftwareRendererSetRAM(struct DSGXRenderer* renderer, struct DSG
|
||||||
edge->t1 = v0->vt;
|
edge->t1 = v0->vt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qsort(DSGXSoftwareEdgeListGetPointer(&softwareRenderer->activeEdges, 0), DSGXSoftwareEdgeListSize(&softwareRenderer->activeEdges), sizeof(struct DSGXSoftwareEdge), _edgeSort);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DSGXSoftwareRendererDrawScanline(struct DSGXRenderer* renderer, int y) {
|
static void DSGXSoftwareRendererDrawScanline(struct DSGXRenderer* renderer, int y) {
|
||||||
|
@ -426,11 +405,9 @@ static void DSGXSoftwareRendererDrawScanline(struct DSGXRenderer* renderer, int
|
||||||
DSGXSoftwareSpanListClear(&softwareRenderer->activeSpans);
|
DSGXSoftwareSpanListClear(&softwareRenderer->activeSpans);
|
||||||
memset(softwareRenderer->bucket, 0, sizeof(*softwareRenderer->bucket) * DS_GX_POLYGON_BUFFER_SIZE);
|
memset(softwareRenderer->bucket, 0, sizeof(*softwareRenderer->bucket) * DS_GX_POLYGON_BUFFER_SIZE);
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = DSGXSoftwareEdgeListSize(&softwareRenderer->activeEdges); i; --i) {
|
for (i = 0; i < DSGXSoftwareEdgeListSize(&softwareRenderer->activeEdges); ++i) {
|
||||||
size_t idx = i - 1;
|
struct DSGXSoftwareEdge* edge = DSGXSoftwareEdgeListGetPointer(&softwareRenderer->activeEdges, i);
|
||||||
struct DSGXSoftwareEdge* edge = DSGXSoftwareEdgeListGetPointer(&softwareRenderer->activeEdges, idx);
|
|
||||||
if (edge->y1 >> 12 < y) {
|
if (edge->y1 >> 12 < y) {
|
||||||
DSGXSoftwareEdgeListShift(&softwareRenderer->activeEdges, idx, 1);
|
|
||||||
continue;
|
continue;
|
||||||
} else if (edge->y0 >> 12 > y) {
|
} else if (edge->y0 >> 12 > y) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -439,8 +416,9 @@ static void DSGXSoftwareRendererDrawScanline(struct DSGXRenderer* renderer, int
|
||||||
unsigned poly = edge->polyId;
|
unsigned poly = edge->polyId;
|
||||||
struct DSGXSoftwareSpan* span = softwareRenderer->bucket[poly];
|
struct DSGXSoftwareSpan* span = softwareRenderer->bucket[poly];
|
||||||
if (span && !span->ep[1].w) {
|
if (span && !span->ep[1].w) {
|
||||||
_edgeToSpan(span, edge, 1, y);
|
if (_edgeToSpan(span, edge, 1, y)) {
|
||||||
softwareRenderer->bucket[poly] = NULL;
|
softwareRenderer->bucket[poly] = NULL;
|
||||||
|
}
|
||||||
} else if (!span) {
|
} else if (!span) {
|
||||||
span = DSGXSoftwareSpanListAppend(&softwareRenderer->activeSpans);
|
span = DSGXSoftwareSpanListAppend(&softwareRenderer->activeSpans);
|
||||||
memset(&span->ep[1], 0, sizeof(span->ep[1]));
|
memset(&span->ep[1], 0, sizeof(span->ep[1]));
|
||||||
|
@ -475,8 +453,7 @@ static void DSGXSoftwareRendererDrawScanline(struct DSGXRenderer* renderer, int
|
||||||
_lerpEndpoint(span, &ep, x);
|
_lerpEndpoint(span, &ep, x);
|
||||||
color_t color = _lookupColor(&ep, span->poly);
|
color_t color = _lookupColor(&ep, span->poly);
|
||||||
unsigned a = color >> 27;
|
unsigned a = color >> 27;
|
||||||
if (a == 0x1F || (a && !(scanline[x] & 0xF8000000))) {
|
if (a == 0x1F || !(scanline[x] & 0xF8000000)) {
|
||||||
// TODO: Alpha
|
|
||||||
if (softwareRenderer->wSort) {
|
if (softwareRenderer->wSort) {
|
||||||
if (ep.w < softwareRenderer->depthBuffer[x]) {
|
if (ep.w < softwareRenderer->depthBuffer[x]) {
|
||||||
softwareRenderer->depthBuffer[x] = ep.w;
|
softwareRenderer->depthBuffer[x] = ep.w;
|
||||||
|
@ -495,14 +472,15 @@ static void DSGXSoftwareRendererDrawScanline(struct DSGXRenderer* renderer, int
|
||||||
a = scanline[x] >> 27;
|
a = scanline[x] >> 27;
|
||||||
}
|
}
|
||||||
color |= a << 27;
|
color |= a << 27;
|
||||||
scanline[x] = color;
|
|
||||||
if (softwareRenderer->wSort) {
|
if (softwareRenderer->wSort) {
|
||||||
if (ep.w < softwareRenderer->depthBuffer[x]) {
|
if (ep.w < softwareRenderer->depthBuffer[x]) {
|
||||||
softwareRenderer->depthBuffer[x] = ep.w;
|
softwareRenderer->depthBuffer[x] = ep.w;
|
||||||
|
scanline[x] = color;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ep.z < softwareRenderer->depthBuffer[x]) {
|
if (ep.z < softwareRenderer->depthBuffer[x]) {
|
||||||
softwareRenderer->depthBuffer[x] = ep.z;
|
softwareRenderer->depthBuffer[x] = ep.z;
|
||||||
|
scanline[x] = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue