Skip to content

Commit

Permalink
Screenshots: when dealing with 800px mode, produce 800x480 instead of…
Browse files Browse the repository at this point in the history
… 800x240 images for more faithful output

Each line is duplicated in this case (integer scaling 2)
  • Loading branch information
TuxSH committed Jun 21, 2024
1 parent 52a1f4a commit 988ec17
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 14 deletions.
2 changes: 1 addition & 1 deletion sysmodules/rosalina/include/draw.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
18 changes: 11 additions & 7 deletions sysmodules/rosalina/source/draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -350,6 +350,7 @@ typedef struct FrameBufferConvertArgs {
u32 width;
u8 startingLine;
u8 numLines;
u8 scaleFactorY;
bool top;
bool left;
} FrameBufferConvertArgs;
Expand All @@ -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);
}
17 changes: 11 additions & 6 deletions sysmodules/rosalina/source/menus.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,15 +362,20 @@ 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));

u8 *framebufferCache = (u8 *)Draw_GetFramebufferCache();
u8 *framebufferCacheEnd = framebufferCache + Draw_GetFramebufferCacheSize();

u8 *buf = framebufferCache;
Draw_CreateBitmapHeader(framebufferCache, width, 240);
Draw_CreateBitmapHeader(framebufferCache, width, numLinesScaled);
buf += 54;

u32 y = 0;
Expand All @@ -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:
Expand Down

0 comments on commit 988ec17

Please sign in to comment.