diff --git a/libctru/include/3ds/gfx.h b/libctru/include/3ds/gfx.h index ca69b85..9d65b05 100644 --- a/libctru/include/3ds/gfx.h +++ b/libctru/include/3ds/gfx.h @@ -151,17 +151,26 @@ void gfxFlushBuffers(void); /** * @brief Updates the configuration of the specified screen, swapping the buffers if double buffering is enabled. * @param scr Screen ID (see \ref gfxScreen_t) - * @param immediate This parameter no longer has any effect and is thus ignored. + * @param hasStereo For the top screen in 3D mode: true if the framebuffer contains individual images + * for both eyes, or false if the left image should be duplicated to the right eye. * @note Previously rendered content will be displayed on the screen after the next VBlank. * @note This function is still useful even if double buffering is disabled, as it must be used to commit configuration changes. * @warning Only call this once per screen per frame, otherwise graphical glitches will occur * since this API does not implement triple buffering. */ -void gfxConfigScreen(gfxScreen_t scr, bool immediate); +void gfxScreenSwapBuffers(gfxScreen_t scr, bool hasStereo); + +/** + * @brief Same as \ref gfxScreenSwapBuffers, but with hasStereo set to true. + * @param scr Screen ID (see \ref gfxScreen_t) + * @param immediate This parameter no longer has any effect and is thus ignored. + * @deprecated This function has been superseded by \ref gfxScreenSwapBuffers, please use that instead. + */ +DEPRECATED void gfxConfigScreen(gfxScreen_t scr, bool immediate); /** * @brief Updates the configuration of both screens. - * @note This function is equivalent to calling \ref gfxConfigScreen for both screens. + * @note This function is equivalent to: \code gfxScreenSwapBuffers(GFX_TOP,true); gfxScreenSwapBuffers(GFX_BOTTOM,true); \endcode */ void gfxSwapBuffers(void); diff --git a/libctru/source/gfx.c b/libctru/source/gfx.c index 32a9a0c..6ace71c 100644 --- a/libctru/source/gfx.c +++ b/libctru/source/gfx.c @@ -83,7 +83,7 @@ void gfxSetDoubleBuffering(gfxScreen_t screen, bool enable) gfxIsDoubleBuf[screen] = enable ? 1 : 0; // make sure they're the integer values '1' and '0' } -static void gfxPresentFramebuffer(gfxScreen_t screen, u8 id) +static void gfxPresentFramebuffer(gfxScreen_t screen, u8 id, bool hasStereo) { u32 stride = GSP_SCREEN_WIDTH*gspGetBytesPerPixel(gfxFramebufferFormats[screen]); u32 mode = gfxFramebufferFormats[screen]; @@ -101,7 +101,7 @@ static void gfxPresentFramebuffer(gfxScreen_t screen, u8 id) break; case MODE_3D: mode |= BIT(5); - fb_b = fb_a + gfxTopFramebufferMaxSize/2; + fb_b = hasStereo ? (fb_a + gfxTopFramebufferMaxSize/2) : fb_a; break; case MODE_WIDE: fb_b = fb_a; @@ -149,8 +149,8 @@ void gfxInit(GSPGPU_FramebufferFormat topFormat, GSPGPU_FramebufferFormat bottom // Present the framebuffers gfxCurBuf[0] = gfxCurBuf[1] = 0; - gfxPresentFramebuffer(GFX_TOP, 0); - gfxPresentFramebuffer(GFX_BOTTOM, 0); + gfxPresentFramebuffer(GFX_TOP, 0, false); + gfxPresentFramebuffer(GFX_BOTTOM, 0, false); // Wait for VBlank and turn the LCD on gspWaitForVBlank(); @@ -241,20 +241,25 @@ void gfxFlushBuffers(void) GSPGPU_FlushDataCache(gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL), bottomSize); } -void gfxConfigScreen(gfxScreen_t scr, bool immediate) +void gfxScreenSwapBuffers(gfxScreen_t scr, bool hasStereo) { gfxCurBuf[scr] ^= gfxIsDoubleBuf[scr]; - gfxPresentFramebuffer(scr, gfxCurBuf[scr]); + gfxPresentFramebuffer(scr, gfxCurBuf[scr], hasStereo); +} + +void gfxConfigScreen(gfxScreen_t scr, bool immediate) +{ + gfxScreenSwapBuffers(scr, true); } void gfxSwapBuffers(void) { - gfxConfigScreen(GFX_TOP, true); - gfxConfigScreen(GFX_BOTTOM, true); + gfxScreenSwapBuffers(GFX_TOP, true); + gfxScreenSwapBuffers(GFX_BOTTOM, true); } void gfxSwapBuffersGpu(void) { - gfxConfigScreen(GFX_TOP, false); - gfxConfigScreen(GFX_BOTTOM, false); + gfxScreenSwapBuffers(GFX_TOP, true); + gfxScreenSwapBuffers(GFX_BOTTOM, true); }