From 21a23b3a7a862180dd057321c5fb317c7d9865c4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 31 Jul 2020 22:01:11 -0700 Subject: [PATCH] 3DS: Use "wide mode" where applicable for slightly better filtering --- CHANGES | 1 + src/platform/3ds/main.c | 43 ++++++++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/CHANGES b/CHANGES index 938ba84d4..90ae34920 100644 --- a/CHANGES +++ b/CHANGES @@ -56,6 +56,7 @@ Other fixes: - SM83: Simplify register pair access on big endian - Wii: Fix pixelated filtering on interframe blending (fixes mgba.io/i/1830) Misc: + - 3DS: Use "wide mode" where applicable for slightly better filtering - GB: Allow pausing event loop while CPU is blocked - GBA: Allow pausing event loop while CPU is blocked - Debugger: Keep track of global cycle count diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index 2f26c49d1..6ffe46da2 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -114,8 +115,13 @@ static bool _initGpu(void) { return false; } - topScreen[0] = C3D_RenderTargetCreate(240, 400, GPU_RB_RGB8, 0); - topScreen[1] = C3D_RenderTargetCreate(240, 400, GPU_RB_RGB8, 0); + if (gfxIsWide()) { + topScreen[0] = C3D_RenderTargetCreate(240, 800, GPU_RB_RGB8, 0); + topScreen[1] = C3D_RenderTargetCreate(240, 800, GPU_RB_RGB8, 0); + } else { + topScreen[0] = C3D_RenderTargetCreate(240, 400, GPU_RB_RGB8, 0); + topScreen[1] = C3D_RenderTargetCreate(240, 400, GPU_RB_RGB8, 0); + } bottomScreen[0] = C3D_RenderTargetCreate(240, 320, GPU_RB_RGB8, 0); bottomScreen[1] = C3D_RenderTargetCreate(240, 320, GPU_RB_RGB8, 0); if (!topScreen[0] || !topScreen[1] || !bottomScreen[0] || !bottomScreen[1]) { @@ -470,6 +476,7 @@ static u32 _setupTex(int out, bool faded) { static void _drawTex(struct mCore* core, bool faded, bool both) { unsigned screen_w, screen_h; + bool isWide = screenMode >= SM_PA_TOP && gfxIsWide(); switch (screenMode) { case SM_PA_BOTTOM: C3D_FrameDrawOn(bottomScreen[doubleBuffer]); @@ -478,7 +485,7 @@ static void _drawTex(struct mCore* core, bool faded, bool both) { break; case SM_PA_TOP: C3D_FrameDrawOn(topScreen[doubleBuffer]); - screen_w = 400; + screen_w = isWide ? 800 : 400; screen_h = 240; break; default: @@ -487,6 +494,7 @@ static void _drawTex(struct mCore* core, bool faded, bool both) { screen_h = 512; break; } + int wide = isWide ? 2 : 1; unsigned corew, coreh; core->desiredVideoDimensions(core, &corew, &coreh); @@ -497,24 +505,16 @@ static void _drawTex(struct mCore* core, bool faded, bool both) { w = GB_VIDEO_HORIZONTAL_PIXELS; h = GB_VIDEO_VERTICAL_PIXELS; } - int innerw = w; - int innerh = h; - // Get greatest common divisor - while (w != 0) { - int temp = h % w; - h = w; - w = temp; - } - int gcd = h; - unsigned aspectw = innerw / gcd; - unsigned aspecth = innerh / gcd; + int aspectw = w; + int aspecth = h; + int gcd = reduceFraction(&aspecth, &aspectw); int x = 0; int y = 0; switch (screenMode) { case SM_PA_TOP: case SM_PA_BOTTOM: - w = corew; + w = corew * wide; h = coreh; x = (screen_w - w) / 2; y = (screen_h - h) / 2; @@ -544,8 +544,8 @@ static void _drawTex(struct mCore* core, bool faded, bool both) { } ctrFlushBatch(); - innerw = corew; - innerh = coreh; + int innerw = corew; + int innerh = coreh; corew = w; coreh = h; screen_h = 240; @@ -554,7 +554,7 @@ static void _drawTex(struct mCore* core, bool faded, bool both) { screen_w = 320; } else { C3D_FrameDrawOn(topScreen[doubleBuffer]); - screen_w = 400; + screen_w = isWide ? 800 : 400; } ctrSetViewportSize(screen_w, screen_h, true); @@ -566,6 +566,7 @@ static void _drawTex(struct mCore* core, bool faded, bool both) { case SM_AF_BOTTOM: afw = screen_w / (float) aspectw; afh = screen_h / (float) aspecth; + innerw *= wide; if (afw * aspecth > screen_h) { w = innerw * afh / gcd; h = innerh * afh / gcd; @@ -846,6 +847,12 @@ int main() { gfxInit(GSP_BGR8_OES, GSP_BGR8_OES, true); + u8 model = 0; + CFGU_GetSystemModel(&model); + if (model != 3 /* o2DS */) { + gfxSetWide(true); + } + if (!_initGpu()) { outputTexture[0].data = 0; _cleanup();