mirror of https://github.com/mgba-emu/mgba.git
Wii: Interframe blending
This commit is contained in:
parent
b6f8ff7569
commit
14b3bdf414
|
@ -87,6 +87,7 @@ static void _setup(struct mGUIRunner* runner);
|
||||||
static void _gameLoaded(struct mGUIRunner* runner);
|
static void _gameLoaded(struct mGUIRunner* runner);
|
||||||
static void _gameUnloaded(struct mGUIRunner* runner);
|
static void _gameUnloaded(struct mGUIRunner* runner);
|
||||||
static void _unpaused(struct mGUIRunner* runner);
|
static void _unpaused(struct mGUIRunner* runner);
|
||||||
|
static void _prepareForFrame(struct mGUIRunner* runner);
|
||||||
static void _drawFrame(struct mGUIRunner* runner, bool faded);
|
static void _drawFrame(struct mGUIRunner* runner, bool faded);
|
||||||
static uint16_t _pollGameInput(struct mGUIRunner* runner);
|
static uint16_t _pollGameInput(struct mGUIRunner* runner);
|
||||||
static void _setFrameLimiter(struct mGUIRunner* runner, bool limit);
|
static void _setFrameLimiter(struct mGUIRunner* runner, bool limit);
|
||||||
|
@ -110,6 +111,8 @@ static uint16_t* texmem;
|
||||||
static GXTexObj tex;
|
static GXTexObj tex;
|
||||||
static uint16_t* rescaleTexmem;
|
static uint16_t* rescaleTexmem;
|
||||||
static GXTexObj rescaleTex;
|
static GXTexObj rescaleTex;
|
||||||
|
static uint16_t* interframeTexmem;
|
||||||
|
static GXTexObj interframeTex;
|
||||||
static int32_t tiltX;
|
static int32_t tiltX;
|
||||||
static int32_t tiltY;
|
static int32_t tiltY;
|
||||||
static int32_t gyroZ;
|
static int32_t gyroZ;
|
||||||
|
@ -118,6 +121,7 @@ static uint32_t referenceRetraceCount;
|
||||||
static bool frameLimiter = true;
|
static bool frameLimiter = true;
|
||||||
static int scaleFactor;
|
static int scaleFactor;
|
||||||
static unsigned corew, coreh;
|
static unsigned corew, coreh;
|
||||||
|
static bool interframeBlending = true;
|
||||||
|
|
||||||
uint32_t* romBuffer;
|
uint32_t* romBuffer;
|
||||||
size_t romBufferSize;
|
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_TEX0, GX_TEX_ST, GX_S16, 0);
|
||||||
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||||
|
|
||||||
|
GX_SetNumTevStages(1);
|
||||||
GX_SetNumChans(1);
|
GX_SetNumChans(1);
|
||||||
GX_SetNumTexGens(1);
|
GX_SetNumTexGens(1);
|
||||||
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
|
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_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_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
||||||
GX_InvVtxCache();
|
GX_InvVtxCache();
|
||||||
|
@ -298,6 +308,8 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
texmem = memalign(32, TEX_W * TEX_H * BYTES_PER_PIXEL);
|
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);
|
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);
|
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_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);
|
GX_InitTexObjFilterMode(&rescaleTex, GX_LINEAR, GX_LINEAR);
|
||||||
|
@ -519,7 +531,7 @@ int main(int argc, char* argv[]) {
|
||||||
.teardown = 0,
|
.teardown = 0,
|
||||||
.gameLoaded = _gameLoaded,
|
.gameLoaded = _gameLoaded,
|
||||||
.gameUnloaded = _gameUnloaded,
|
.gameUnloaded = _gameUnloaded,
|
||||||
.prepareForFrame = 0,
|
.prepareForFrame = _prepareForFrame,
|
||||||
.drawFrame = _drawFrame,
|
.drawFrame = _drawFrame,
|
||||||
.paused = _gameUnloaded,
|
.paused = _gameUnloaded,
|
||||||
.unpaused = _unpaused,
|
.unpaused = _unpaused,
|
||||||
|
@ -584,6 +596,7 @@ int main(int argc, char* argv[]) {
|
||||||
free(fifo);
|
free(fifo);
|
||||||
free(texmem);
|
free(texmem);
|
||||||
free(rescaleTexmem);
|
free(rescaleTexmem);
|
||||||
|
free(interframeTexmem);
|
||||||
|
|
||||||
free(outputBuffer);
|
free(outputBuffer);
|
||||||
GUIFontDestroy(font);
|
GUIFontDestroy(font);
|
||||||
|
@ -728,6 +741,7 @@ void _reproj2(int w, int h) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _guiPrepare(void) {
|
void _guiPrepare(void) {
|
||||||
|
GX_SetNumTevStages(1);
|
||||||
_reproj2(vmode->fbWidth * guiScale * wAdjust, vmode->efbHeight * guiScale * hAdjust);
|
_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(texmem, 0, TEX_W * TEX_H * BYTES_PER_PIXEL);
|
||||||
|
memset(interframeTexmem, 0, TEX_W * TEX_H * BYTES_PER_PIXEL);
|
||||||
_unpaused(runner);
|
_unpaused(runner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -843,6 +858,10 @@ void _unpaused(struct mGUIRunner* runner) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int fakeBool;
|
||||||
|
mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool);
|
||||||
|
interframeBlending = fakeBool;
|
||||||
|
|
||||||
float stretch;
|
float stretch;
|
||||||
if (mCoreConfigGetFloatValue(&runner->config, "stretchWidth", &stretch)) {
|
if (mCoreConfigGetFloatValue(&runner->config, "stretchWidth", &stretch)) {
|
||||||
wStretch = fminf(1.0f, fmaxf(0.5f, 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) {
|
void _drawFrame(struct mGUIRunner* runner, bool faded) {
|
||||||
runner->core->desiredVideoDimensions(runner->core, &corew, &coreh);
|
runner->core->desiredVideoDimensions(runner->core, &corew, &coreh);
|
||||||
uint32_t color = 0xFFFFFF3F;
|
uint32_t color = 0xFFFFFF3F;
|
||||||
|
@ -870,14 +895,24 @@ void _drawFrame(struct mGUIRunner* runner, bool faded) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DCFlushRange(texdest, TEX_W * TEX_H * BYTES_PER_PIXEL);
|
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);
|
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP);
|
||||||
} else {
|
} else {
|
||||||
GX_SetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_NOOP);
|
GX_SetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_NOOP);
|
||||||
}
|
}
|
||||||
GX_InvalidateTexAll();
|
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);
|
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
||||||
s16 vertWidth = corew;
|
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_SetTexCopyDst(TEX_W * 2, TEX_H * 2, GX_TF_RGB565, GX_FALSE);
|
||||||
GX_CopyTex(rescaleTexmem, GX_TRUE);
|
GX_CopyTex(rescaleTexmem, GX_TRUE);
|
||||||
GX_LoadTexObj(&rescaleTex, GX_TEXMAP0);
|
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);
|
int hfactor = (vmode->fbWidth * wStretch) / (corew * wAdjust);
|
||||||
|
|
Loading…
Reference in New Issue