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)
This commit is contained in:
TuxSH 2024-06-22 01:22:22 +02:00
parent 52a1f4ae60
commit 988ec17ebf
3 changed files with 23 additions and 14 deletions

View File

@ -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);

View File

@ -350,6 +350,7 @@ typedef struct FrameBufferConvertArgs {
u32 width;
u8 startingLine;
u8 numLines;
u8 scaleFactorY;
bool top;
bool left;
} FrameBufferConvertArgs;
@ -366,17 +367,20 @@ static void Draw_ConvertFrameBufferLinesKernel(const FrameBufferConvertArgs *arg
u8 *addr = (u8 *)KERNPA2VA(pa);
for (u32 y = args->startingLine; y < args->startingLine + args->numLines; y++)
{
for (u8 i = 0; i < args->scaleFactorY; i++)
{
for(u32 x = 0; x < width; x++)
{
__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);
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);
}

View File

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