From 988ec17ebfce513fc4589f7b12e0d6e3894ae542 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Sat, 22 Jun 2024 01:22:22 +0200 Subject: [PATCH] Screenshots: when dealing with 800px mode, produce 800x480 instead of 800x240 images for more faithful output Each line is duplicated in this case (integer scaling 2) --- sysmodules/rosalina/include/draw.h | 2 +- sysmodules/rosalina/source/draw.c | 18 +++++++++++------- sysmodules/rosalina/source/menus.c | 17 +++++++++++------ 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/sysmodules/rosalina/include/draw.h b/sysmodules/rosalina/include/draw.h index 1b77e47e2..af41027b1 100644 --- a/sysmodules/rosalina/include/draw.h +++ b/sysmodules/rosalina/include/draw.h @@ -108,4 +108,4 @@ u32 Draw_GetCurrentFramebufferAddress(bool top, bool left); void Draw_GetCurrentScreenInfo(u32 *width, bool *is3d, bool top); void Draw_CreateBitmapHeader(u8 *dst, u32 width, u32 heigth); -void Draw_ConvertFrameBufferLines(u8 *buf, u32 width, u32 startingLine, u32 numLines, bool top, bool left); +void Draw_ConvertFrameBufferLines(u8 *buf, u32 width, u32 startingLine, u32 numLines, u32 scaleFactorY, bool top, bool left); diff --git a/sysmodules/rosalina/source/draw.c b/sysmodules/rosalina/source/draw.c index 333f48a9b..ddfd58fd3 100644 --- a/sysmodules/rosalina/source/draw.c +++ b/sysmodules/rosalina/source/draw.c @@ -203,7 +203,7 @@ u32 Draw_SetupFramebuffer(void) GPU_FB_BOTTOM_ADDR_1 = GPU_FB_BOTTOM_ADDR_2 = FB_BOTTOM_VRAM_PA; GPU_FB_BOTTOM_FMT = format; GPU_FB_BOTTOM_STRIDE = 240 * 2; - + gpuSavedFillColor = LCD_BOT_FILLCOLOR; LCD_BOT_FILLCOLOR = 0; @@ -214,7 +214,7 @@ void Draw_RestoreFramebuffer(void) { memcpy(FB_BOTTOM_VRAM_ADDR, framebufferCache, FB_BOTTOM_SIZE); Draw_FlushFramebuffer(); - + LCD_BOT_FILLCOLOR = gpuSavedFillColor; GPU_FB_BOTTOM_ADDR_1 = gpuSavedFramebufferAddr1; GPU_FB_BOTTOM_ADDR_2 = gpuSavedFramebufferAddr2; @@ -350,6 +350,7 @@ typedef struct FrameBufferConvertArgs { u32 width; u8 startingLine; u8 numLines; + u8 scaleFactorY; bool top; bool left; } FrameBufferConvertArgs; @@ -367,16 +368,19 @@ static void Draw_ConvertFrameBufferLinesKernel(const FrameBufferConvertArgs *arg for (u32 y = args->startingLine; y < args->startingLine + args->numLines; y++) { - for(u32 x = 0; x < width; x++) + for (u8 i = 0; i < args->scaleFactorY; i++) { - __builtin_prefetch(addr + x * stride + y * formatSizes[fmt], 0, 3); - Draw_ConvertPixelToBGR8(args->buf + (x + width * y) * 3 , addr + x * stride + y * formatSizes[fmt], fmt); + for(u32 x = 0; x < width; x++) + { + __builtin_prefetch(addr + x * stride + y * formatSizes[fmt], 0, 3); + Draw_ConvertPixelToBGR8(args->buf + (x + width * (args->scaleFactorY * y + i)) * 3 , addr + x * stride + y * formatSizes[fmt], fmt); + } } } } -void Draw_ConvertFrameBufferLines(u8 *buf, u32 width, u32 startingLine, u32 numLines, bool top, bool left) +void Draw_ConvertFrameBufferLines(u8 *buf, u32 width, u32 startingLine, u32 numLines, u32 scaleFactorY, bool top, bool left) { - FrameBufferConvertArgs args = { buf, width, (u8)startingLine, (u8)numLines, top, left }; + FrameBufferConvertArgs args = { buf, width, (u8)startingLine, (u8)numLines, (u8)scaleFactorY, top, left }; svcCustomBackdoor(Draw_ConvertFrameBufferLinesKernel, &args); } diff --git a/sysmodules/rosalina/source/menus.c b/sysmodules/rosalina/source/menus.c index 4e23ae8f7..9b741707f 100644 --- a/sysmodules/rosalina/source/menus.c +++ b/sysmodules/rosalina/source/menus.c @@ -362,7 +362,12 @@ static Result RosalinaMenu_WriteScreenshot(IFile *file, u32 width, bool top, boo u64 total; Result res = 0; u32 lineSize = 3 * width; - u32 remaining = lineSize * 240; + + // When dealing with 800px mode (800x240 with half-width pixels), duplicate each line + // to restore aspect ratio and obtain faithful 800x480 screenshots + u32 scaleFactorY = width > 400 ? 2 : 1; + u32 numLinesScaled = 240 * scaleFactorY; + u32 remaining = lineSize * numLinesScaled; TRY(Draw_AllocateFramebufferCacheForScreenshot(remaining)); @@ -370,7 +375,7 @@ static Result RosalinaMenu_WriteScreenshot(IFile *file, u32 width, bool top, boo u8 *framebufferCacheEnd = framebufferCache + Draw_GetFramebufferCacheSize(); u8 *buf = framebufferCache; - Draw_CreateBitmapHeader(framebufferCache, width, 240); + Draw_CreateBitmapHeader(framebufferCache, width, numLinesScaled); buf += 54; u32 y = 0; @@ -380,16 +385,16 @@ static Result RosalinaMenu_WriteScreenshot(IFile *file, u32 width, bool top, boo s64 t0 = svcGetSystemTick(); u32 available = (u32)(framebufferCacheEnd - buf); u32 size = available < remaining ? available : remaining; - u32 nlines = size / lineSize; - Draw_ConvertFrameBufferLines(buf, width, y, nlines, top, left); + u32 nlines = size / (lineSize * scaleFactorY); + Draw_ConvertFrameBufferLines(buf, width, y, nlines, scaleFactorY, top, left); s64 t1 = svcGetSystemTick(); timeSpentConvertingScreenshot += t1 - t0; - TRY(IFile_Write(file, &total, framebufferCache, (y == 0 ? 54 : 0) + lineSize * nlines, 0)); // don't forget to write the header + TRY(IFile_Write(file, &total, framebufferCache, (y == 0 ? 54 : 0) + lineSize * nlines * scaleFactorY, 0)); // don't forget to write the header timeSpentWritingScreenshot += svcGetSystemTick() - t1; y += nlines; - remaining -= lineSize * nlines; + remaining -= lineSize * nlines * scaleFactorY; buf = framebufferCache; } end: