3DS: Interframe blending

This commit is contained in:
Vicki Pfau 2019-05-29 15:13:30 -07:00
parent 252b9409b6
commit 456dbc482f
1 changed files with 43 additions and 22 deletions

View File

@ -89,7 +89,8 @@ static color_t* screenshotBuffer = NULL;
static struct mAVStream stream; static struct mAVStream stream;
static int16_t* audioLeft = 0; static int16_t* audioLeft = 0;
static size_t audioPos = 0; static size_t audioPos = 0;
static C3D_Tex outputTexture; static C3D_Tex outputTexture[2];
static int activeOutputTexture = 0;
static ndspWaveBuf dspBuffer[DSP_BUFFERS]; static ndspWaveBuf dspBuffer[DSP_BUFFERS];
static int bufferId = 0; static int bufferId = 0;
static bool frameLimiter = true; static bool frameLimiter = true;
@ -102,6 +103,7 @@ static bool frameStarted = false;
static C3D_RenderTarget* upscaleBuffer; static C3D_RenderTarget* upscaleBuffer;
static C3D_Tex upscaleBufferTex; static C3D_Tex upscaleBufferTex;
static bool interframeBlending = false;
static aptHookCookie cookie; static aptHookCookie cookie;
static bool core2; static bool core2;
@ -150,7 +152,8 @@ static void _cleanup(void) {
C3D_RenderTargetDelete(bottomScreen[1]); C3D_RenderTargetDelete(bottomScreen[1]);
C3D_RenderTargetDelete(upscaleBuffer); C3D_RenderTargetDelete(upscaleBuffer);
C3D_TexDelete(&upscaleBufferTex); C3D_TexDelete(&upscaleBufferTex);
C3D_TexDelete(&outputTexture); C3D_TexDelete(&outputTexture[0]);
C3D_TexDelete(&outputTexture[1]);
C3D_Fini(); C3D_Fini();
gfxExit(); gfxExit();
@ -374,6 +377,11 @@ static void _gameLoaded(struct mGUIRunner* runner) {
} }
} }
} }
int fakeBool;
if (mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool)) {
interframeBlending = fakeBool;
}
} }
static void _gameUnloaded(struct mGUIRunner* runner) { static void _gameUnloaded(struct mGUIRunner* runner) {
@ -404,7 +412,7 @@ static void _gameUnloaded(struct mGUIRunner* runner) {
} }
} }
static void _drawTex(struct mCore* core, bool faded) { static void _drawTex(struct mCore* core, bool faded, bool both) {
unsigned screen_w, screen_h; unsigned screen_w, screen_h;
switch (screenMode) { switch (screenMode) {
case SM_PA_BOTTOM: case SM_PA_BOTTOM:
@ -466,7 +474,6 @@ static void _drawTex(struct mCore* core, bool faded) {
break; break;
} }
ctrActivateTexture(&outputTexture);
u32 color; u32 color;
if (!faded) { if (!faded) {
color = 0xFFFFFFFF; color = 0xFFFFFFFF;
@ -502,7 +509,12 @@ static void _drawTex(struct mCore* core, bool faded) {
} }
} }
ctrActivateTexture(&outputTexture[activeOutputTexture]);
ctrAddRectEx(color, x, y, w, h, 0, 0, corew, coreh, 0); ctrAddRectEx(color, x, y, w, h, 0, 0, corew, coreh, 0);
if (both) {
ctrActivateTexture(&outputTexture[activeOutputTexture ^ 1]);
ctrAddRectEx(color & 0x7FFFFFFF, x, y, w, h, 0, 0, corew, coreh, 0);
}
ctrFlushBatch(); ctrFlushBatch();
corew = w; corew = w;
@ -546,9 +558,14 @@ static void _drawTex(struct mCore* core, bool faded) {
ctrFlushBatch(); ctrFlushBatch();
} }
static void _prepareForFrame(struct mGUIRunner* runner) {
UNUSED(runner);
activeOutputTexture ^= 1;
}
static void _drawFrame(struct mGUIRunner* runner, bool faded) { static void _drawFrame(struct mGUIRunner* runner, bool faded) {
UNUSED(runner); UNUSED(runner);
C3D_Tex* tex = &outputTexture; C3D_Tex* tex = &outputTexture[activeOutputTexture];
GSPGPU_FlushDataCache(outputBuffer, 256 * GBA_VIDEO_VERTICAL_PIXELS * 2); GSPGPU_FlushDataCache(outputBuffer, 256 * GBA_VIDEO_VERTICAL_PIXELS * 2);
C3D_SyncDisplayTransfer( C3D_SyncDisplayTransfer(
@ -563,11 +580,11 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) {
blip_clear(runner->core->getAudioChannel(runner->core, 1)); blip_clear(runner->core->getAudioChannel(runner->core, 1));
} }
_drawTex(runner->core, faded); _drawTex(runner->core, faded, interframeBlending);
} }
static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded) { static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded) {
C3D_Tex* tex = &outputTexture; C3D_Tex* tex = &outputTexture[activeOutputTexture];
if (!screenshotBuffer) { if (!screenshotBuffer) {
screenshotBuffer = linearMemAlign(256 * 224 * sizeof(color_t), 0x80); screenshotBuffer = linearMemAlign(256 * 224 * sizeof(color_t), 0x80);
@ -586,7 +603,7 @@ static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, un
GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB565) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB565) |
GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_FLIP_VERT(1)); GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_FLIP_VERT(1));
_drawTex(runner->core, faded); _drawTex(runner->core, faded, false);
} }
static uint16_t _pollGameInput(struct mGUIRunner* runner) { static uint16_t _pollGameInput(struct mGUIRunner* runner) {
@ -804,25 +821,29 @@ int main() {
gfxInit(GSP_BGR8_OES, GSP_BGR8_OES, true); gfxInit(GSP_BGR8_OES, GSP_BGR8_OES, true);
if (!_initGpu()) { if (!_initGpu()) {
outputTexture.data = 0; outputTexture[0].data = 0;
_cleanup(); _cleanup();
return 1; return 1;
} }
if (!C3D_TexInitVRAM(&outputTexture, 256, 256, GPU_RGB565)) {
_cleanup();
return 1;
}
C3D_TexSetWrap(&outputTexture, GPU_CLAMP_TO_EDGE, GPU_CLAMP_TO_EDGE);
C3D_TexSetFilter(&outputTexture, GPU_NEAREST, GPU_NEAREST);
C3D_TexSetFilter(&upscaleBufferTex, GPU_LINEAR, GPU_LINEAR); C3D_TexSetFilter(&upscaleBufferTex, GPU_LINEAR, GPU_LINEAR);
void* outputTextureEnd = (u8*)outputTexture.data + 256 * 256 * 2;
// Zero texture data to make sure no garbage around the border interferes with filtering int i;
GX_MemoryFill( for (i = 0; i < 2; ++i) {
outputTexture.data, 0x0000, outputTextureEnd, GX_FILL_16BIT_DEPTH | GX_FILL_TRIGGER, if (!C3D_TexInitVRAM(&outputTexture[i], 256, 256, GPU_RGB565)) {
NULL, 0, NULL, 0); _cleanup();
gspWaitForPSC0(); return 1;
}
C3D_TexSetWrap(&outputTexture[i], GPU_CLAMP_TO_EDGE, GPU_CLAMP_TO_EDGE);
C3D_TexSetFilter(&outputTexture[i], GPU_NEAREST, GPU_NEAREST);
void* outputTextureEnd = (u8*)outputTexture[i].data + 256 * 256 * 2;
// Zero texture data to make sure no garbage around the border interferes with filtering
GX_MemoryFill(
outputTexture[i].data, 0x0000, outputTextureEnd, GX_FILL_16BIT_DEPTH | GX_FILL_TRIGGER,
NULL, 0, NULL, 0);
gspWaitForPSC0();
}
struct GUIFont* font = GUIFontCreate(); struct GUIFont* font = GUIFontCreate();
@ -937,7 +958,7 @@ int main() {
.teardown = 0, .teardown = 0,
.gameLoaded = _gameLoaded, .gameLoaded = _gameLoaded,
.gameUnloaded = _gameUnloaded, .gameUnloaded = _gameUnloaded,
.prepareForFrame = 0, .prepareForFrame = _prepareForFrame,
.drawFrame = _drawFrame, .drawFrame = _drawFrame,
.drawScreenshot = _drawScreenshot, .drawScreenshot = _drawScreenshot,
.paused = _gameUnloaded, .paused = _gameUnloaded,