Wii: Interframe blending

This commit is contained in:
Vicki Pfau 2019-05-29 12:08:00 -07:00
parent b6f8ff7569
commit 14b3bdf414
1 changed files with 42 additions and 3 deletions

View File

@ -87,6 +87,7 @@ static void _setup(struct mGUIRunner* runner);
static void _gameLoaded(struct mGUIRunner* runner);
static void _gameUnloaded(struct mGUIRunner* runner);
static void _unpaused(struct mGUIRunner* runner);
static void _prepareForFrame(struct mGUIRunner* runner);
static void _drawFrame(struct mGUIRunner* runner, bool faded);
static uint16_t _pollGameInput(struct mGUIRunner* runner);
static void _setFrameLimiter(struct mGUIRunner* runner, bool limit);
@ -110,6 +111,8 @@ static uint16_t* texmem;
static GXTexObj tex;
static uint16_t* rescaleTexmem;
static GXTexObj rescaleTex;
static uint16_t* interframeTexmem;
static GXTexObj interframeTex;
static int32_t tiltX;
static int32_t tiltY;
static int32_t gyroZ;
@ -118,6 +121,7 @@ static uint32_t referenceRetraceCount;
static bool frameLimiter = true;
static int scaleFactor;
static unsigned corew, coreh;
static bool interframeBlending = true;
uint32_t* romBuffer;
size_t romBufferSize;
@ -277,10 +281,16 @@ int main(int argc, char* argv[]) {
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
GX_SetNumTevStages(1);
GX_SetNumChans(1);
GX_SetNumTexGens(1);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
GX_SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, GX_TEXMAP1, GX_COLOR0A0);
GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
GX_SetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_DIVIDE_2, GX_TRUE, GX_TEVPREV);
GX_SetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
GX_SetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_TEXC, GX_CC_ONE, GX_CC_CPREV);
GX_SetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV);
GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
GX_InvVtxCache();
@ -298,6 +308,8 @@ int main(int argc, char* argv[]) {
texmem = memalign(32, TEX_W * TEX_H * BYTES_PER_PIXEL);
GX_InitTexObj(&tex, texmem, TEX_W, TEX_H, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
interframeTexmem = memalign(32, TEX_W * TEX_H * BYTES_PER_PIXEL);
GX_InitTexObj(&interframeTex, interframeTexmem, TEX_W, TEX_H, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
rescaleTexmem = memalign(32, TEX_W * TEX_H * 4 * BYTES_PER_PIXEL);
GX_InitTexObj(&rescaleTex, rescaleTexmem, TEX_W * 2, TEX_H * 2, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObjFilterMode(&rescaleTex, GX_LINEAR, GX_LINEAR);
@ -519,7 +531,7 @@ int main(int argc, char* argv[]) {
.teardown = 0,
.gameLoaded = _gameLoaded,
.gameUnloaded = _gameUnloaded,
.prepareForFrame = 0,
.prepareForFrame = _prepareForFrame,
.drawFrame = _drawFrame,
.paused = _gameUnloaded,
.unpaused = _unpaused,
@ -584,6 +596,7 @@ int main(int argc, char* argv[]) {
free(fifo);
free(texmem);
free(rescaleTexmem);
free(interframeTexmem);
free(outputBuffer);
GUIFontDestroy(font);
@ -728,6 +741,7 @@ void _reproj2(int w, int h) {
}
void _guiPrepare(void) {
GX_SetNumTevStages(1);
_reproj2(vmode->fbWidth * guiScale * wAdjust, vmode->efbHeight * guiScale * hAdjust);
}
@ -811,6 +825,7 @@ void _gameLoaded(struct mGUIRunner* runner) {
}
}
memset(texmem, 0, TEX_W * TEX_H * BYTES_PER_PIXEL);
memset(interframeTexmem, 0, TEX_W * TEX_H * BYTES_PER_PIXEL);
_unpaused(runner);
}
@ -843,6 +858,10 @@ void _unpaused(struct mGUIRunner* runner) {
break;
}
}
int fakeBool;
mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool);
interframeBlending = fakeBool;
float stretch;
if (mCoreConfigGetFloatValue(&runner->config, "stretchWidth", &stretch)) {
wStretch = fminf(1.0f, fmaxf(0.5f, stretch));
@ -852,6 +871,12 @@ void _unpaused(struct mGUIRunner* runner) {
}
}
void _prepareForFrame(struct mGUIRunner* runner) {
if (interframeBlending) {
memcpy(interframeTexmem, texmem, TEX_W * TEX_H * BYTES_PER_PIXEL);
}
}
void _drawFrame(struct mGUIRunner* runner, bool faded) {
runner->core->desiredVideoDimensions(runner->core, &corew, &coreh);
uint32_t color = 0xFFFFFF3F;
@ -870,14 +895,24 @@ void _drawFrame(struct mGUIRunner* runner, bool faded) {
}
}
DCFlushRange(texdest, TEX_W * TEX_H * BYTES_PER_PIXEL);
if (interframeBlending) {
DCFlushRange(interframeTexmem, TEX_W * TEX_H * BYTES_PER_PIXEL);
}
if (faded) {
if (faded || interframeBlending) {
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP);
} else {
GX_SetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_NOOP);
}
GX_InvalidateTexAll();
GX_LoadTexObj(&tex, GX_TEXMAP0);
if (interframeBlending) {
GX_LoadTexObj(&interframeTex, GX_TEXMAP0);
GX_LoadTexObj(&tex, GX_TEXMAP1);
GX_SetNumTevStages(2);
} else {
GX_LoadTexObj(&tex, GX_TEXMAP0);
GX_SetNumTevStages(1);
}
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
s16 vertWidth = corew;
@ -910,6 +945,10 @@ void _drawFrame(struct mGUIRunner* runner, bool faded) {
GX_SetTexCopyDst(TEX_W * 2, TEX_H * 2, GX_TF_RGB565, GX_FALSE);
GX_CopyTex(rescaleTexmem, GX_TRUE);
GX_LoadTexObj(&rescaleTex, GX_TEXMAP0);
GX_SetNumTevStages(1);
if (!faded) {
GX_SetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_NOOP);
}
}
int hfactor = (vmode->fbWidth * wStretch) / (corew * wAdjust);