mirror of https://github.com/mgba-emu/mgba.git
3DS: Interframe blending
This commit is contained in:
parent
252b9409b6
commit
456dbc482f
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue