gfx: Add support for the top screen's 800px high resolution mode (!!!)
This commit is contained in:
parent
09d629aa85
commit
d521c99769
@ -5,6 +5,10 @@
|
|||||||
* This API provides basic functionality needed to bring up framebuffers for both screens,
|
* This API provides basic functionality needed to bring up framebuffers for both screens,
|
||||||
* as well as managing display mode (stereoscopic 3D) and double buffering.
|
* as well as managing display mode (stereoscopic 3D) and double buffering.
|
||||||
* It is mainly an abstraction over the gsp service.
|
* It is mainly an abstraction over the gsp service.
|
||||||
|
*
|
||||||
|
* Please note that the 3DS uses *portrait* screens rotated 90 degrees counterclockwise.
|
||||||
|
* Width/height refer to the physical dimensions of the screen; that is, the top screen
|
||||||
|
* is 240 pixels wide and 400 pixels tall; while the bottom screen is 240x320.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
@ -80,6 +84,22 @@ void gfxSet3D(bool enable);
|
|||||||
*/
|
*/
|
||||||
bool gfxIs3D(void);
|
bool gfxIs3D(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves the status of the 800px (double-height) high resolution display mode of the top screen.
|
||||||
|
* @return true if wide mode enabled, false otherwise.
|
||||||
|
*/
|
||||||
|
bool gfxIsWide(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables or disables the 800px (double-height) high resolution display mode of the top screen.
|
||||||
|
* @param enable Pass true to enable, false to disable.
|
||||||
|
* @note Wide mode is disabled by default.
|
||||||
|
* @note Wide and stereoscopic 3D modes are mutually exclusive.
|
||||||
|
* @note In wide mode pixels are not square, since scanlines are half as tall as they normally are.
|
||||||
|
* @warning Wide mode does not work on Old 2DS consoles (however it does work on New 2DS XL consoles).
|
||||||
|
*/
|
||||||
|
void gfxSetWide(bool enable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Changes the pixel format of a screen.
|
* @brief Changes the pixel format of a screen.
|
||||||
* @param screen Screen ID (see \ref gfxScreen_t)
|
* @param screen Screen ID (see \ref gfxScreen_t)
|
||||||
|
@ -10,7 +10,12 @@ static u32 gfxTopFramebufferMaxSize;
|
|||||||
static u32 gfxBottomFramebufferMaxSize;
|
static u32 gfxBottomFramebufferMaxSize;
|
||||||
static GSPGPU_FramebufferFormat gfxFramebufferFormats[2];
|
static GSPGPU_FramebufferFormat gfxFramebufferFormats[2];
|
||||||
|
|
||||||
static bool gfxEnable3D, gfxIsVram;
|
static enum {
|
||||||
|
MODE_2D = 0,
|
||||||
|
MODE_3D = 1,
|
||||||
|
MODE_WIDE = 2,
|
||||||
|
} gfxTopMode;
|
||||||
|
static bool gfxIsVram;
|
||||||
static u8 gfxCurBuf[2];
|
static u8 gfxCurBuf[2];
|
||||||
static u8 gfxIsDoubleBuf[2];
|
static u8 gfxIsDoubleBuf[2];
|
||||||
|
|
||||||
@ -19,12 +24,22 @@ static void *(*screenAlloc)(size_t);
|
|||||||
|
|
||||||
void gfxSet3D(bool enable)
|
void gfxSet3D(bool enable)
|
||||||
{
|
{
|
||||||
gfxEnable3D = enable;
|
gfxTopMode = enable ? MODE_3D : MODE_2D;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gfxIs3D(void)
|
bool gfxIs3D(void)
|
||||||
{
|
{
|
||||||
return gfxEnable3D;
|
return gfxTopMode == MODE_3D;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfxSetWide(bool enable)
|
||||||
|
{
|
||||||
|
gfxTopMode = enable ? MODE_WIDE : MODE_2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gfxIsWide(void)
|
||||||
|
{
|
||||||
|
return gfxTopMode == MODE_WIDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfxSetScreenFormat(gfxScreen_t screen, GSPGPU_FramebufferFormat format)
|
void gfxSetScreenFormat(gfxScreen_t screen, GSPGPU_FramebufferFormat format)
|
||||||
@ -77,15 +92,20 @@ static void gfxPresentFramebuffer(gfxScreen_t screen, u8 id)
|
|||||||
if (screen == GFX_TOP)
|
if (screen == GFX_TOP)
|
||||||
{
|
{
|
||||||
fb_a = gfxTopFramebuffers[id];
|
fb_a = gfxTopFramebuffers[id];
|
||||||
if (gfxEnable3D)
|
switch (gfxTopMode)
|
||||||
{
|
|
||||||
mode |= BIT(5);
|
|
||||||
fb_b = fb_a + gfxTopFramebufferMaxSize/2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
default:
|
||||||
|
case MODE_2D:
|
||||||
mode |= BIT(6);
|
mode |= BIT(6);
|
||||||
fb_b = fb_a;
|
fb_b = fb_a;
|
||||||
|
break;
|
||||||
|
case MODE_3D:
|
||||||
|
mode |= BIT(5);
|
||||||
|
fb_b = fb_a + gfxTopFramebufferMaxSize/2;
|
||||||
|
break;
|
||||||
|
case MODE_WIDE:
|
||||||
|
fb_b = fb_a;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -173,8 +193,19 @@ u8* gfxGetFramebuffer(gfxScreen_t screen, gfx3dSide_t side, u16* width, u16* hei
|
|||||||
{
|
{
|
||||||
fb = gfxTopFramebuffers[id];
|
fb = gfxTopFramebuffers[id];
|
||||||
scr_height = GSP_SCREEN_HEIGHT_TOP;
|
scr_height = GSP_SCREEN_HEIGHT_TOP;
|
||||||
if (gfxEnable3D && side != GFX_LEFT)
|
switch (gfxTopMode)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case MODE_2D:
|
||||||
|
break;
|
||||||
|
case MODE_3D:
|
||||||
|
if (side != GFX_LEFT)
|
||||||
fb += gfxTopFramebufferMaxSize/2;
|
fb += gfxTopFramebufferMaxSize/2;
|
||||||
|
break;
|
||||||
|
case MODE_WIDE:
|
||||||
|
scr_height = GSP_SCREEN_HEIGHT_TOP_2X;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else // GFX_BOTTOM
|
else // GFX_BOTTOM
|
||||||
{
|
{
|
||||||
@ -194,10 +225,12 @@ void gfxFlushBuffers(void)
|
|||||||
{
|
{
|
||||||
const u32 baseSize = GSP_SCREEN_WIDTH * gspGetBytesPerPixel(gfxGetScreenFormat(GFX_TOP));
|
const u32 baseSize = GSP_SCREEN_WIDTH * gspGetBytesPerPixel(gfxGetScreenFormat(GFX_TOP));
|
||||||
const u32 topSize = GSP_SCREEN_HEIGHT_TOP * baseSize;
|
const u32 topSize = GSP_SCREEN_HEIGHT_TOP * baseSize;
|
||||||
|
const u32 topSize2x = GSP_SCREEN_HEIGHT_TOP_2X * baseSize;
|
||||||
const u32 bottomSize = GSP_SCREEN_HEIGHT_BOTTOM * baseSize;
|
const u32 bottomSize = GSP_SCREEN_HEIGHT_BOTTOM * baseSize;
|
||||||
|
|
||||||
GSPGPU_FlushDataCache(gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), topSize);
|
GSPGPU_FlushDataCache(gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), gfxTopMode == MODE_WIDE ? topSize2x : topSize);
|
||||||
if(gfxEnable3D)GSPGPU_FlushDataCache(gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, NULL, NULL), topSize);
|
if (gfxTopMode == MODE_3D)
|
||||||
|
GSPGPU_FlushDataCache(gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, NULL, NULL), topSize);
|
||||||
GSPGPU_FlushDataCache(gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL), bottomSize);
|
GSPGPU_FlushDataCache(gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL), bottomSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user