diff --git a/nx/include/switch/gfx/gfx.h b/nx/include/switch/gfx/gfx.h index f8968b6c..f1c93e64 100644 --- a/nx/include/switch/gfx/gfx.h +++ b/nx/include/switch/gfx/gfx.h @@ -41,6 +41,7 @@ void gfxExit(void); * @note The default resolution is 720p. * @note This can only be used before calling \ref gfxInitDefault, this will use \ref fatalSimple otherwise. If the input is 0, the default resolution will be used during \ref gfxInitDefault. This sets the maximum resolution for the framebuffer, used during \ref gfxInitDefault. This is also used as the current resolution when crop isn't set. The width/height are reset to the default when \ref gfxExit is used. * @note Normally you should only use this when you need a maximum resolution larger than the default, see above. + * @note The width and height are aligned to 4. */ void gfxInitResolution(u32 width, u32 height); @@ -52,6 +53,7 @@ void gfxInitResolutionDefault(void); /// This will update the display width/height returned by \ref gfxGetFramebuffer, with that width/height being reset to the default when required. /// \ref gfxGetFramebufferDisplayOffset uses absolute x/y, it will not adjust for non-zero crop left/top. /// The new crop config will not take affect with double-buffering disabled. When used during frame-drawing, this should be called before \ref gfxGetFramebuffer. +/// The right and bottom params are aligned to 4. void gfxConfigureCrop(s32 left, s32 top, s32 right, s32 bottom); /// Wrapper for \ref gfxConfigureCrop. Use this to set the resolution, within the bounds of the maximum resolution. Use all-zero input to reset to default. diff --git a/nx/source/gfx/gfx.c b/nx/source/gfx/gfx.c index 8f7165a6..23aeda92 100644 --- a/nx/source/gfx/gfx.c +++ b/nx/source/gfx/gfx.c @@ -397,8 +397,8 @@ void gfxExit(void) void gfxInitResolution(u32 width, u32 height) { if (g_gfxInitialized) fatalSimple(MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized)); - g_gfx_framebuf_width = width; - g_gfx_framebuf_height = height; + g_gfx_framebuf_width = (width+3) & ~3; + g_gfx_framebuf_height = (height+3) & ~3; } void gfxInitResolutionDefault(void) { @@ -412,6 +412,10 @@ void gfxConfigureCrop(s32 left, s32 top, s32 right, s32 bottom) { } if (left < 0 || top < 0 || right < 0 || bottom < 0) return; + + right = (right+3) & ~3; + bottom = (bottom+3) & ~3; + if (right < left || bottom < top) return; if (left > g_gfx_framebuf_width || top > g_gfx_framebuf_height) return; if (right > g_gfx_framebuf_width || bottom > g_gfx_framebuf_height) return; @@ -540,26 +544,14 @@ void gfxFlushBuffers(void) { u32 *actual_framebuf = (u32*)&g_gfxFramebuf[g_gfxCurrentBuffer*g_gfx_singleframebuf_size]; if (g_gfxMode == GfxMode_LinearDouble) { - //TODO: Implement block-linear here without re-calculating the entire offset with gfxGetFramebufferDisplayOffset(). - - size_t x, y, j, tmpoff; + size_t x, y; size_t width = g_gfx_framebuf_display_width; size_t height = g_gfx_framebuf_display_height; u32 *in_framebuf = (u32*)g_gfxFramebufLinear; for (y=0; y= width) - break; - actual_framebuf[tmpoff+j] = in_framebuf[y * width + x+j]; - } - } - else { - *((u128*)&actual_framebuf[tmpoff]) = *((u128*)&in_framebuf[y * width + x]); - } + *((u128*)&actual_framebuf[gfxGetFramebufferDisplayOffset(x, y)]) = *((u128*)&in_framebuf[y * width + x]); } } }