3DS: Use "wide mode" where applicable for slightly better filtering

This commit is contained in:
Vicki Pfau 2020-07-31 22:01:11 -07:00
parent cc06e177bb
commit 21a23b3a7a
2 changed files with 26 additions and 18 deletions

View File

@ -56,6 +56,7 @@ Other fixes:
- SM83: Simplify register pair access on big endian - SM83: Simplify register pair access on big endian
- Wii: Fix pixelated filtering on interframe blending (fixes mgba.io/i/1830) - Wii: Fix pixelated filtering on interframe blending (fixes mgba.io/i/1830)
Misc: Misc:
- 3DS: Use "wide mode" where applicable for slightly better filtering
- GB: Allow pausing event loop while CPU is blocked - GB: Allow pausing event loop while CPU is blocked
- GBA: Allow pausing event loop while CPU is blocked - GBA: Allow pausing event loop while CPU is blocked
- Debugger: Keep track of global cycle count - Debugger: Keep track of global cycle count

View File

@ -20,6 +20,7 @@
#include <mgba-util/gui/file-select.h> #include <mgba-util/gui/file-select.h>
#include <mgba-util/gui/font.h> #include <mgba-util/gui/font.h>
#include <mgba-util/gui/menu.h> #include <mgba-util/gui/menu.h>
#include <mgba-util/math.h>
#include <mgba-util/memory.h> #include <mgba-util/memory.h>
#include <mgba-util/platform/3ds/3ds-vfs.h> #include <mgba-util/platform/3ds/3ds-vfs.h>
@ -114,8 +115,13 @@ static bool _initGpu(void) {
return false; return false;
} }
topScreen[0] = C3D_RenderTargetCreate(240, 400, GPU_RB_RGB8, 0); if (gfxIsWide()) {
topScreen[1] = C3D_RenderTargetCreate(240, 400, GPU_RB_RGB8, 0); 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[0] = C3D_RenderTargetCreate(240, 320, GPU_RB_RGB8, 0);
bottomScreen[1] = 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]) { 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) { static void _drawTex(struct mCore* core, bool faded, bool both) {
unsigned screen_w, screen_h; unsigned screen_w, screen_h;
bool isWide = screenMode >= SM_PA_TOP && gfxIsWide();
switch (screenMode) { switch (screenMode) {
case SM_PA_BOTTOM: case SM_PA_BOTTOM:
C3D_FrameDrawOn(bottomScreen[doubleBuffer]); C3D_FrameDrawOn(bottomScreen[doubleBuffer]);
@ -478,7 +485,7 @@ static void _drawTex(struct mCore* core, bool faded, bool both) {
break; break;
case SM_PA_TOP: case SM_PA_TOP:
C3D_FrameDrawOn(topScreen[doubleBuffer]); C3D_FrameDrawOn(topScreen[doubleBuffer]);
screen_w = 400; screen_w = isWide ? 800 : 400;
screen_h = 240; screen_h = 240;
break; break;
default: default:
@ -487,6 +494,7 @@ static void _drawTex(struct mCore* core, bool faded, bool both) {
screen_h = 512; screen_h = 512;
break; break;
} }
int wide = isWide ? 2 : 1;
unsigned corew, coreh; unsigned corew, coreh;
core->desiredVideoDimensions(core, &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; w = GB_VIDEO_HORIZONTAL_PIXELS;
h = GB_VIDEO_VERTICAL_PIXELS; h = GB_VIDEO_VERTICAL_PIXELS;
} }
int innerw = w; int aspectw = w;
int innerh = h; int aspecth = h;
// Get greatest common divisor int gcd = reduceFraction(&aspecth, &aspectw);
while (w != 0) {
int temp = h % w;
h = w;
w = temp;
}
int gcd = h;
unsigned aspectw = innerw / gcd;
unsigned aspecth = innerh / gcd;
int x = 0; int x = 0;
int y = 0; int y = 0;
switch (screenMode) { switch (screenMode) {
case SM_PA_TOP: case SM_PA_TOP:
case SM_PA_BOTTOM: case SM_PA_BOTTOM:
w = corew; w = corew * wide;
h = coreh; h = coreh;
x = (screen_w - w) / 2; x = (screen_w - w) / 2;
y = (screen_h - h) / 2; y = (screen_h - h) / 2;
@ -544,8 +544,8 @@ static void _drawTex(struct mCore* core, bool faded, bool both) {
} }
ctrFlushBatch(); ctrFlushBatch();
innerw = corew; int innerw = corew;
innerh = coreh; int innerh = coreh;
corew = w; corew = w;
coreh = h; coreh = h;
screen_h = 240; screen_h = 240;
@ -554,7 +554,7 @@ static void _drawTex(struct mCore* core, bool faded, bool both) {
screen_w = 320; screen_w = 320;
} else { } else {
C3D_FrameDrawOn(topScreen[doubleBuffer]); C3D_FrameDrawOn(topScreen[doubleBuffer]);
screen_w = 400; screen_w = isWide ? 800 : 400;
} }
ctrSetViewportSize(screen_w, screen_h, true); ctrSetViewportSize(screen_w, screen_h, true);
@ -566,6 +566,7 @@ static void _drawTex(struct mCore* core, bool faded, bool both) {
case SM_AF_BOTTOM: case SM_AF_BOTTOM:
afw = screen_w / (float) aspectw; afw = screen_w / (float) aspectw;
afh = screen_h / (float) aspecth; afh = screen_h / (float) aspecth;
innerw *= wide;
if (afw * aspecth > screen_h) { if (afw * aspecth > screen_h) {
w = innerw * afh / gcd; w = innerw * afh / gcd;
h = innerh * afh / gcd; h = innerh * afh / gcd;
@ -846,6 +847,12 @@ int main() {
gfxInit(GSP_BGR8_OES, GSP_BGR8_OES, true); gfxInit(GSP_BGR8_OES, GSP_BGR8_OES, true);
u8 model = 0;
CFGU_GetSystemModel(&model);
if (model != 3 /* o2DS */) {
gfxSetWide(true);
}
if (!_initGpu()) { if (!_initGpu()) {
outputTexture[0].data = 0; outputTexture[0].data = 0;
_cleanup(); _cleanup();