mirror of
https://github.com/LumaTeam/Luma3DS.git
synced 2026-02-22 01:44:38 +00:00
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:
parent
52a1f4ae60
commit
988ec17ebf
@ -108,4 +108,4 @@ u32 Draw_GetCurrentFramebufferAddress(bool top, bool left);
|
|||||||
void Draw_GetCurrentScreenInfo(u32 *width, bool *is3d, bool top);
|
void Draw_GetCurrentScreenInfo(u32 *width, bool *is3d, bool top);
|
||||||
|
|
||||||
void Draw_CreateBitmapHeader(u8 *dst, u32 width, u32 heigth);
|
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);
|
||||||
|
|||||||
@ -350,6 +350,7 @@ typedef struct FrameBufferConvertArgs {
|
|||||||
u32 width;
|
u32 width;
|
||||||
u8 startingLine;
|
u8 startingLine;
|
||||||
u8 numLines;
|
u8 numLines;
|
||||||
|
u8 scaleFactorY;
|
||||||
bool top;
|
bool top;
|
||||||
bool left;
|
bool left;
|
||||||
} FrameBufferConvertArgs;
|
} FrameBufferConvertArgs;
|
||||||
@ -366,17 +367,20 @@ static void Draw_ConvertFrameBufferLinesKernel(const FrameBufferConvertArgs *arg
|
|||||||
u8 *addr = (u8 *)KERNPA2VA(pa);
|
u8 *addr = (u8 *)KERNPA2VA(pa);
|
||||||
|
|
||||||
for (u32 y = args->startingLine; y < args->startingLine + args->numLines; y++)
|
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++)
|
for(u32 x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
__builtin_prefetch(addr + x * stride + y * formatSizes[fmt], 0, 3);
|
__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);
|
svcCustomBackdoor(Draw_ConvertFrameBufferLinesKernel, &args);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -362,7 +362,12 @@ static Result RosalinaMenu_WriteScreenshot(IFile *file, u32 width, bool top, boo
|
|||||||
u64 total;
|
u64 total;
|
||||||
Result res = 0;
|
Result res = 0;
|
||||||
u32 lineSize = 3 * width;
|
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));
|
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 *framebufferCacheEnd = framebufferCache + Draw_GetFramebufferCacheSize();
|
||||||
|
|
||||||
u8 *buf = framebufferCache;
|
u8 *buf = framebufferCache;
|
||||||
Draw_CreateBitmapHeader(framebufferCache, width, 240);
|
Draw_CreateBitmapHeader(framebufferCache, width, numLinesScaled);
|
||||||
buf += 54;
|
buf += 54;
|
||||||
|
|
||||||
u32 y = 0;
|
u32 y = 0;
|
||||||
@ -380,16 +385,16 @@ static Result RosalinaMenu_WriteScreenshot(IFile *file, u32 width, bool top, boo
|
|||||||
s64 t0 = svcGetSystemTick();
|
s64 t0 = svcGetSystemTick();
|
||||||
u32 available = (u32)(framebufferCacheEnd - buf);
|
u32 available = (u32)(framebufferCacheEnd - buf);
|
||||||
u32 size = available < remaining ? available : remaining;
|
u32 size = available < remaining ? available : remaining;
|
||||||
u32 nlines = size / lineSize;
|
u32 nlines = size / (lineSize * scaleFactorY);
|
||||||
Draw_ConvertFrameBufferLines(buf, width, y, nlines, top, left);
|
Draw_ConvertFrameBufferLines(buf, width, y, nlines, scaleFactorY, top, left);
|
||||||
|
|
||||||
s64 t1 = svcGetSystemTick();
|
s64 t1 = svcGetSystemTick();
|
||||||
timeSpentConvertingScreenshot += t1 - t0;
|
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;
|
timeSpentWritingScreenshot += svcGetSystemTick() - t1;
|
||||||
|
|
||||||
y += nlines;
|
y += nlines;
|
||||||
remaining -= lineSize * nlines;
|
remaining -= lineSize * nlines * scaleFactorY;
|
||||||
buf = framebufferCache;
|
buf = framebufferCache;
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user