1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2024-11-29 03:34:07 +00:00

Match retail PreRender_DivotFilter (#1740)

This commit is contained in:
cadmic 2024-02-10 08:38:04 -08:00 committed by GitHub
parent 097db907ca
commit 6c405b6ea3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -681,6 +681,14 @@ void PreRender_AntiAliasFilter(PreRender* this, s32 x, s32 y) {
(((a2) >= (a1)) ? (((a3) >= (a2)) ? (a2) : (((a1) >= (a3)) ? (a1) : (a3))) \ (((a2) >= (a1)) ? (((a3) >= (a2)) ? (a2) : (((a1) >= (a3)) ? (a1) : (a3))) \
: (((a2) >= (a3)) ? (a2) : (((a3) >= (a1)) ? (a1) : (a3)))) : (((a2) >= (a3)) ? (a2) : (((a3) >= (a1)) ? (a1) : (a3))))
#if OOT_DEBUG
#define R_HREG_MODE_DEBUG R_HREG_MODE
#else
#define R_HREG_MODE_DEBUG ((void)0, 0)
#endif
#define PRERENDER_DIVOT_CONTROL (R_HREG_MODE_DEBUG == HREG_MODE_PRERENDER ? R_PRERENDER_DIVOT_CONTROL : 0)
/** /**
* Applies the Video Interface divot filter to an image. * Applies the Video Interface divot filter to an image.
* *
@ -696,7 +704,7 @@ void PreRender_AntiAliasFilter(PreRender* this, s32 x, s32 y) {
void PreRender_DivotFilter(PreRender* this) { void PreRender_DivotFilter(PreRender* this) {
s32 x; s32 x;
s32 y; s32 y;
s32 pad1; s32 cvg;
u8* buffR = alloca(this->width); u8* buffR = alloca(this->width);
u8* buffG = alloca(this->width); u8* buffG = alloca(this->width);
u8* buffB = alloca(this->width); u8* buffB = alloca(this->width);
@ -704,14 +712,14 @@ void PreRender_DivotFilter(PreRender* this) {
s32 pxR; s32 pxR;
s32 pxG; s32 pxG;
s32 pxB; s32 pxB;
Color_RGBA16 pxIn;
Color_RGBA16 pxOut;
for (y = 0; y < this->height; y++) { for (y = 0; y < this->height; y++) {
// The divot filter is applied row-by-row as it only needs to use pixels that are horizontally adjacent // The divot filter is applied row-by-row as it only needs to use pixels that are horizontally adjacent
// Decompose each pixel into color channels // Decompose each pixel into color channels
for (x = 0; x < this->width; x++) { for (x = 0; x < this->width; x++) {
Color_RGBA16 pxIn;
pxIn.rgba = this->fbufSave[x + y * this->width]; pxIn.rgba = this->fbufSave[x + y * this->width];
buffR[x] = pxIn.r; buffR[x] = pxIn.r;
buffG[x] = pxIn.g; buffG[x] = pxIn.g;
@ -721,8 +729,7 @@ void PreRender_DivotFilter(PreRender* this) {
// Apply the divot filter itself. For pixels with partial coverage, the filter selects the median value from a // Apply the divot filter itself. For pixels with partial coverage, the filter selects the median value from a
// window of 3 pixels in a horizontal row and uses that as the value for the center pixel. // window of 3 pixels in a horizontal row and uses that as the value for the center pixel.
for (x = 1; x < this->width - 1; x++) { for (x = 1; x < this->width - 1; x++) {
Color_RGBA16 pxOut; cvg = this->cvgSave[x + y * this->width];
s32 cvg = this->cvgSave[x + y * this->width];
// Reject pixels with full coverage. The hardware video filter divot circuit checks if all 3 pixels in the // Reject pixels with full coverage. The hardware video filter divot circuit checks if all 3 pixels in the
// window have partial coverage, here only the center pixel is checked. // window have partial coverage, here only the center pixel is checked.
@ -732,11 +739,10 @@ void PreRender_DivotFilter(PreRender* this) {
} }
// This condition is checked before entering this function, it will always pass if it runs. // This condition is checked before entering this function, it will always pass if it runs.
if ((R_HREG_MODE == HREG_MODE_PRERENDER ? R_PRERENDER_DIVOT_CONTROL : 0) != 0) { if (PRERENDER_DIVOT_CONTROL != 0) {
if ((R_HREG_MODE == HREG_MODE_PRERENDER ? R_PRERENDER_DIVOT_CONTROL : 0) != 0) {} if (PRERENDER_DIVOT_CONTROL != 0) {}
if ((R_HREG_MODE == HREG_MODE_PRERENDER ? R_PRERENDER_DIVOT_CONTROL : 0) == if (PRERENDER_DIVOT_CONTROL == PRERENDER_DIVOT_PARTIAL_CVG_RED) {
PRERENDER_DIVOT_PARTIAL_CVG_RED) {
// Fill the pixel with full red, likely for debugging // Fill the pixel with full red, likely for debugging
pxR = 31; pxR = 31;
pxG = 0; pxG = 0;
@ -747,8 +753,7 @@ void PreRender_DivotFilter(PreRender* this) {
u8* windowG = &buffG[x - 1]; u8* windowG = &buffG[x - 1];
u8* windowB = &buffB[x - 1]; u8* windowB = &buffB[x - 1];
if ((R_HREG_MODE == HREG_MODE_PRERENDER ? R_PRERENDER_DIVOT_CONTROL : 0) == if (PRERENDER_DIVOT_CONTROL == PRERENDER_DIVOT_PRINT_COLOR) {
PRERENDER_DIVOT_PRINT_COLOR) {
PRINTF("red=%3d %3d %3d %3d grn=%3d %3d %3d %3d blu=%3d %3d %3d %3d \n", windowR[0], windowR[1], PRINTF("red=%3d %3d %3d %3d grn=%3d %3d %3d %3d blu=%3d %3d %3d %3d \n", windowR[0], windowR[1],
windowR[2], MEDIAN3(windowR[0], windowR[1], windowR[2]), windowG[0], windowG[1], windowR[2], MEDIAN3(windowR[0], windowR[1], windowR[2]), windowG[0], windowG[1],
windowG[2], MEDIAN3(windowG[0], windowG[1], windowG[2]), windowB[0], windowB[1], windowG[2], MEDIAN3(windowG[0], windowG[1], windowG[2]), windowB[0], windowB[1],
@ -758,8 +763,7 @@ void PreRender_DivotFilter(PreRender* this) {
// Sample the median value from the 3 pixel wide window // Sample the median value from the 3 pixel wide window
// (Both blocks contain the same code) // (Both blocks contain the same code)
if ((R_HREG_MODE == HREG_MODE_PRERENDER ? R_PRERENDER_DIVOT_CONTROL : 0) == if (PRERENDER_DIVOT_CONTROL == PRERENDER_DIVOT_ALTERNATE_COLOR) {
PRERENDER_DIVOT_ALTERNATE_COLOR) {
pxR = MEDIAN3(windowR[0], windowR[1], windowR[2]); pxR = MEDIAN3(windowR[0], windowR[1], windowR[2]);
pxG = MEDIAN3(windowG[0], windowG[1], windowG[2]); pxG = MEDIAN3(windowG[0], windowG[1], windowG[2]);
pxB = MEDIAN3(windowB[0], windowB[1], windowB[2]); pxB = MEDIAN3(windowB[0], windowB[1], windowB[2]);
@ -803,11 +807,9 @@ void PreRender_ApplyFilters(PreRender* this) {
} }
} }
#if OOT_DEBUG if (PRERENDER_DIVOT_CONTROL != 0) {
if ((R_HREG_MODE == HREG_MODE_PRERENDER ? R_PRERENDER_DIVOT_CONTROL : 0) != 0) {
// Apply divot filter // Apply divot filter
PreRender_DivotFilter(this); PreRender_DivotFilter(this);
} }
#endif
} }
} }