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
- 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

View File

@ -20,6 +20,7 @@
#include <mgba-util/gui/file-select.h>
#include <mgba-util/gui/font.h>
#include <mgba-util/gui/menu.h>
#include <mgba-util/math.h>
#include <mgba-util/memory.h>
#include <mgba-util/platform/3ds/3ds-vfs.h>
@ -114,8 +115,13 @@ static bool _initGpu(void) {
return false;
}
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();