Merge branch 'master' into 3gx-master

* master:
  Change screen filters presets (adding more) menu & print CCT. Fixes #1442.
  rosalina: implement 800px top-screen screenshot, etc. Fixes #1443

# Conflicts:
#	sysmodules/rosalina/source/draw.c
This commit is contained in:
Bea 2020-07-06 20:20:27 +02:00
commit 1176fa8f28
6 changed files with 145 additions and 105 deletions

View File

@ -91,7 +91,8 @@ u32 Draw_DrawFormattedString(u32 posX, u32 posY, u32 color, const char *fmt, ...
void Draw_FillFramebuffer(u32 value);
void Draw_ClearFramebuffer(void);
u32 Draw_AllocateFramebufferCache(void);
Result Draw_AllocateFramebufferCache(u32 size);
Result Draw_AllocateFramebufferCacheForScreenshot(u32 size);
void Draw_FreeFramebufferCache(void);
void *Draw_GetFramebufferCache(void);
u32 Draw_GetFramebufferCacheSize(void);
@ -99,6 +100,8 @@ u32 Draw_SetupFramebuffer(void);
void Draw_RestoreFramebuffer(void);
void Draw_FlushFramebuffer(void);
u32 Draw_GetCurrentFramebufferAddress(bool top, bool left);
// Width is actually height as the 3ds screen is rotated 90 degrees
void Draw_GetCurrentScreenInfo(u32 *width, bool *is3d, bool top);
void Draw_CreateBitmapHeader(u8 *dst, u32 width, u32 heigth);
void Draw_ConvertFrameBufferLines(u8 *buf, u32 startingLine, u32 numLines, bool top, bool left);
void Draw_ConvertFrameBufferLines(u8 *buf, u32 width, u32 startingLine, u32 numLines, bool top, bool left);

View File

@ -32,10 +32,14 @@ extern Menu screenFiltersMenu;
extern int screenFiltersCurrentTemperature;
void screenFiltersSetDisabled(void);
void screenFiltersReduceBlueLevel1(void);
void screenFiltersReduceBlueLevel2(void);
void screenFiltersReduceBlueLevel3(void);
void screenFiltersReduceBlueLevel4(void);
void screenFiltersReduceBlueLevel5(void);
void screenFiltersSetTemperature(int temperature);
void ScreenFiltersMenu_SetDefault(void); // 6500K (default)
void ScreenFiltersMenu_SetAquarium(void); // 10000K
void ScreenFiltersMenu_SetOvercastSky(void); // 7500K
void ScreenFiltersMenu_SetDaylight(void); // 5500K
void ScreenFiltersMenu_SetFluorescent(void); // 4200K
void ScreenFiltersMenu_SetHalogen(void); // 3400K
void ScreenFiltersMenu_SetIncandescent(void); // 2700K
void ScreenFiltersMenu_SetWarmIncandescent(void); // 2300K
void ScreenFiltersMenu_SetCandle(void); // 1900K
void ScreenFiltersMenu_SetEmber(void); // 1200K

View File

@ -129,18 +129,19 @@ void Draw_ClearFramebuffer(void)
Draw_FillFramebuffer(0);
}
u32 Draw_AllocateFramebufferCache(void)
Result Draw_AllocateFramebufferCache(u32 size)
{
// Try to see how much we can allocate...
// Can't use fbs in FCRAM when Home Menu is active (AXI config related maybe?)
u32 addr = 0x0D000000;
u32 tmp;
u32 minSize = (FB_BOTTOM_SIZE + 0xFFF) & ~0xFFF;
u32 maxSize = (FB_SCREENSHOT_SIZE + 0xFFF) & ~0xFFF;
u32 remaining = (u32)osGetMemRegionFree(MEMREGION_SYSTEM);
u32 size = remaining < maxSize ? remaining : maxSize;
if (size < minSize || R_FAILED(svcControlMemoryEx(&tmp, addr, 0, size, MEMOP_ALLOC, MEMREGION_SYSTEM | MEMPERM_READ | MEMPERM_WRITE, true)))
size = (size + 0xFFF) >> 12 << 12; // round-up
if (framebufferCache != NULL)
__builtin_trap();
Result res = svcControlMemoryEx(&tmp, addr, 0, size, MEMOP_ALLOC, MEMREGION_SYSTEM | MEMPERM_READWRITE, true);
if (R_FAILED(res))
{
framebufferCache = NULL;
framebufferCacheSize = 0;
@ -151,13 +152,21 @@ u32 Draw_AllocateFramebufferCache(void)
framebufferCacheSize = size;
}
return framebufferCacheSize;
return res;
}
Result Draw_AllocateFramebufferCacheForScreenshot(u32 size)
{
u32 remaining = (u32)osGetMemRegionFree(MEMREGION_SYSTEM);
u32 sz = remaining < size ? remaining : size;
return Draw_AllocateFramebufferCache(sz);
}
void Draw_FreeFramebufferCache(void)
{
u32 tmp;
svcControlMemory(&tmp, (u32)framebufferCache, 0, framebufferCacheSize, MEMOP_FREE, 0);
if (framebufferCache != NULL)
svcControlMemory(&tmp, (u32)framebufferCache, 0, framebufferCacheSize, MEMOP_FREE, 0);
framebufferCacheSize = 0;
framebufferCache = NULL;
}
@ -180,13 +189,19 @@ u32 Draw_SetupFramebuffer(void)
memcpy(framebufferCache, FB_BOTTOM_VRAM_ADDR, FB_BOTTOM_SIZE);
Draw_ClearFramebuffer();
Draw_FlushFramebuffer();
u32 format = GPU_FB_BOTTOM_FMT;
gpuSavedFramebufferAddr1 = GPU_FB_BOTTOM_ADDR_1;
gpuSavedFramebufferAddr2 = GPU_FB_BOTTOM_ADDR_2;
gpuSavedFramebufferFormat = GPU_FB_BOTTOM_FMT;
gpuSavedFramebufferFormat = format;
gpuSavedFramebufferStride = GPU_FB_BOTTOM_STRIDE;
format = (format & ~7) | GSP_RGB565_OES;
format |= 3 << 8; // set VRAM bits
GPU_FB_BOTTOM_ADDR_1 = GPU_FB_BOTTOM_ADDR_2 = FB_BOTTOM_VRAM_PA;
GPU_FB_BOTTOM_FMT = (GPU_FB_BOTTOM_FMT & ~7) | GSP_RGB565_OES;
GPU_FB_BOTTOM_FMT = format;
GPU_FB_BOTTOM_STRIDE = 240 * 2;
return framebufferCacheSize;
@ -205,7 +220,7 @@ void Draw_RestoreFramebuffer(void)
void Draw_FlushFramebuffer(void)
{
svcFlushProcessDataCache(CUR_PROCESS_HANDLE, FB_BOTTOM_VRAM_ADDR, FB_BOTTOM_SIZE);
svcFlushProcessDataCache(CUR_PROCESS_HANDLE, (u32)FB_BOTTOM_VRAM_ADDR, FB_BOTTOM_SIZE);
}
u32 Draw_GetCurrentFramebufferAddress(bool top, bool left)
@ -226,6 +241,21 @@ u32 Draw_GetCurrentFramebufferAddress(bool top, bool left)
}
}
void Draw_GetCurrentScreenInfo(u32 *width, bool *is3d, bool top)
{
if (top)
{
bool isNormal2d = (GPU_FB_TOP_FMT & BIT(6)) != 0;
*is3d = (GPU_FB_TOP_FMT & BIT(5)) != 0;
*width = !(*is3d) && !isNormal2d ? 800 : 400;
}
else
{
*is3d = false;
*width = 320;
}
}
static inline void Draw_WriteUnaligned(u8 *dst, u32 tmp, u32 size)
{
memcpy(dst, &tmp, size);
@ -313,6 +343,7 @@ static inline void Draw_ConvertPixelToBGR8(u8 *dst, const u8 *src, GSPGPU_Frameb
typedef struct FrameBufferConvertArgs {
u8 *buf;
u32 width;
u8 startingLine;
u8 numLines;
bool top;
@ -324,7 +355,7 @@ static void Draw_ConvertFrameBufferLinesKernel(const FrameBufferConvertArgs *arg
static const u8 formatSizes[] = { 4, 3, 2, 2, 2 };
GSPGPU_FramebufferFormats fmt = args->top ? (GSPGPU_FramebufferFormats)(GPU_FB_TOP_FMT & 7) : (GSPGPU_FramebufferFormats)(GPU_FB_BOTTOM_FMT & 7);
u32 width = args->top ? 400 : 320;
u32 width = args->width;
u32 stride = args->top ? GPU_FB_TOP_STRIDE : GPU_FB_BOTTOM_STRIDE;
u32 pa = Draw_GetCurrentFramebufferAddress(args->top, args->left);
@ -340,8 +371,8 @@ static void Draw_ConvertFrameBufferLinesKernel(const FrameBufferConvertArgs *arg
}
}
void Draw_ConvertFrameBufferLines(u8 *buf, u32 startingLine, u32 numLines, bool top, bool left)
void Draw_ConvertFrameBufferLines(u8 *buf, u32 width, u32 startingLine, u32 numLines, bool top, bool left)
{
FrameBufferConvertArgs args = { buf, (u8)startingLine, (u8)numLines, top, left };
FrameBufferConvertArgs args = { buf, width, (u8)startingLine, (u8)numLines, top, left };
svcCustomBackdoor(Draw_ConvertFrameBufferLinesKernel, &args);
}

View File

@ -228,15 +228,15 @@ void menuEnter(void)
menuRefCount++;
svcKernelSetState(0x10000, 1);
svcSleepThread(5 * 1000 * 100LL);
if (Draw_AllocateFramebufferCache() == 0)
if (R_FAILED(Draw_AllocateFramebufferCache(FB_BOTTOM_SIZE)))
{
// Oops
menuRefCount = 0;
svcKernelSetState(0x10000, 1);
svcSleepThread(5 * 1000 * 100LL);
}
Draw_SetupFramebuffer();
else
Draw_SetupFramebuffer();
}
Draw_Unlock();
}

View File

@ -296,18 +296,20 @@ void RosalinaMenu_PowerOff(void) // Soft shutdown.
static s64 timeSpentConvertingScreenshot = 0;
static s64 timeSpentWritingScreenshot = 0;
static Result RosalinaMenu_WriteScreenshot(IFile *file, bool top, bool left)
static Result RosalinaMenu_WriteScreenshot(IFile *file, u32 width, bool top, bool left)
{
u64 total;
Result res = 0;
u32 dimX = top ? 400 : 320;
u32 lineSize = 3 * dimX;
u32 lineSize = 3 * width;
u32 remaining = lineSize * 240;
TRY(Draw_AllocateFramebufferCacheForScreenshot(remaining));
u8 *framebufferCache = (u8 *)Draw_GetFramebufferCache();
u8 *framebufferCacheEnd = framebufferCache + Draw_GetFramebufferCacheSize();
u8 *buf = framebufferCache;
Draw_CreateBitmapHeader(framebufferCache, dimX, 240);
Draw_CreateBitmapHeader(framebufferCache, width, 240);
buf += 54;
u32 y = 0;
@ -318,7 +320,7 @@ static Result RosalinaMenu_WriteScreenshot(IFile *file, bool top, bool left)
u32 available = (u32)(framebufferCacheEnd - buf);
u32 size = available < remaining ? available : remaining;
u32 nlines = size / lineSize;
Draw_ConvertFrameBufferLines(buf, y, nlines, top, left);
Draw_ConvertFrameBufferLines(buf, width, y, nlines, top, left);
s64 t1 = svcGetSystemTick();
timeSpentConvertingScreenshot += t1 - t0;
@ -329,7 +331,10 @@ static Result RosalinaMenu_WriteScreenshot(IFile *file, bool top, bool left)
remaining -= lineSize * nlines;
buf = framebufferCache;
}
end: return res;
end:
Draw_FreeFramebufferCache();
return res;
}
void RosalinaMenu_TakeScreenshot(void)
@ -353,9 +358,16 @@ void RosalinaMenu_TakeScreenshot(void)
archiveId = isSdMode ? ARCHIVE_SDMC : ARCHIVE_NAND_RW;
Draw_Lock();
Draw_RestoreFramebuffer();
Draw_FreeFramebufferCache();
svcFlushEntireDataCache();
bool is3d;
u32 topWidth, bottomWidth; // actually Y-dim
Draw_GetCurrentScreenInfo(&bottomWidth, &is3d, false);
Draw_GetCurrentScreenInfo(&topWidth, &is3d, true);
res = FSUSER_OpenArchive(&archive, archiveId, fsMakePath(PATH_EMPTY, ""));
if(R_SUCCEEDED(res))
{
@ -410,24 +422,28 @@ void RosalinaMenu_TakeScreenshot(void)
sprintf(filename, "/luma/screenshots/%04lu-%02lu-%02lu_%02lu-%02lu-%02lu.%03llu_top.bmp", year, month, days, hours, minutes, seconds, milliseconds);
TRY(IFile_Open(&file, archiveId, fsMakePath(PATH_EMPTY, ""), fsMakePath(PATH_ASCII, filename), FS_OPEN_CREATE | FS_OPEN_WRITE));
TRY(RosalinaMenu_WriteScreenshot(&file, true, true));
TRY(RosalinaMenu_WriteScreenshot(&file, topWidth, true, true));
TRY(IFile_Close(&file));
sprintf(filename, "/luma/screenshots/%04lu-%02lu-%02lu_%02lu-%02lu-%02lu.%03llu_bot.bmp", year, month, days, hours, minutes, seconds, milliseconds);
TRY(IFile_Open(&file, archiveId, fsMakePath(PATH_EMPTY, ""), fsMakePath(PATH_ASCII, filename), FS_OPEN_CREATE | FS_OPEN_WRITE));
TRY(RosalinaMenu_WriteScreenshot(&file, false, true));
TRY(RosalinaMenu_WriteScreenshot(&file, bottomWidth, false, true));
TRY(IFile_Close(&file));
if((GPU_FB_TOP_FMT & 0x20) && (Draw_GetCurrentFramebufferAddress(true, true) != Draw_GetCurrentFramebufferAddress(true, false)))
if(is3d && (Draw_GetCurrentFramebufferAddress(true, true) != Draw_GetCurrentFramebufferAddress(true, false)))
{
sprintf(filename, "/luma/screenshots/%04lu-%02lu-%02lu_%02lu-%02lu-%02lu.%03llu_top_right.bmp", year, month, days, hours, minutes, seconds, milliseconds);
TRY(IFile_Open(&file, archiveId, fsMakePath(PATH_EMPTY, ""), fsMakePath(PATH_ASCII, filename), FS_OPEN_CREATE | FS_OPEN_WRITE));
TRY(RosalinaMenu_WriteScreenshot(&file, true, false));
TRY(RosalinaMenu_WriteScreenshot(&file, topWidth, true, false));
TRY(IFile_Close(&file));
}
end:
IFile_Close(&file);
if (R_FAILED(Draw_AllocateFramebufferCache(FB_BOTTOM_SIZE)))
__builtin_trap(); // We're f***ed if this happens
svcFlushEntireDataCache();
Draw_SetupFramebuffer();
Draw_Unlock();

View File

@ -32,11 +32,19 @@
#include "redshift/redshift.h"
#include "redshift/colorramp.h"
#define TEMP_DEFAULT NEUTRAL_TEMP
typedef struct {
u8 r;
u8 g;
u8 b;
u8 z;
} Pixel;
int screenFiltersCurrentTemperature = TEMP_DEFAULT;
static u16 g_c[0x600];
static Pixel g_px[0x400];
void writeLut(u32* lut)
int screenFiltersCurrentTemperature = 6500;
static void ScreenFiltersMenu_WriteLut(const u32* lut)
{
GPU_FB_TOP_COL_LUT_INDEX = 0;
GPU_FB_BOTTOM_COL_LUT_INDEX = 0;
@ -48,17 +56,7 @@ void writeLut(u32* lut)
}
}
typedef struct {
u8 r;
u8 g;
u8 b;
u8 z;
} Pixel;
static u16 g_c[0x600];
static Pixel g_px[0x400];
void applyColorSettings(color_setting_t* cs)
static void ScreenFiltersMenu_ApplyColorSettings(color_setting_t* cs)
{
u8 i = 0;
@ -86,68 +84,56 @@ void applyColorSettings(color_setting_t* cs)
g_px[i].b = *(g_c + i + 0x200) >> 8;
} while(++i);
writeLut((u32*)g_px);
ScreenFiltersMenu_WriteLut((u32*)g_px);
}
Menu screenFiltersMenu = {
"Screen filters menu",
{
{ "Disable", METHOD, .method = &screenFiltersSetDisabled },
{ "Reduce blue light (level 1)", METHOD, .method = &screenFiltersReduceBlueLevel1 },
{ "Reduce blue light (level 2)", METHOD, .method = &screenFiltersReduceBlueLevel2 },
{ "Reduce blue light (level 3)", METHOD, .method = &screenFiltersReduceBlueLevel3 },
{ "Reduce blue light (level 4)", METHOD, .method = &screenFiltersReduceBlueLevel4 },
{ "Reduce blue light (level 5)", METHOD, .method = &screenFiltersReduceBlueLevel5 },
{},
}
};
void screenFiltersSetDisabled(void)
{
screenFiltersCurrentTemperature = TEMP_DEFAULT;
screenFiltersSetTemperature(screenFiltersCurrentTemperature);
}
void screenFiltersReduceBlueLevel1(void)
{
screenFiltersCurrentTemperature = 4300;
screenFiltersSetTemperature(screenFiltersCurrentTemperature);
}
void screenFiltersReduceBlueLevel2(void)
{
screenFiltersCurrentTemperature = 3200;
screenFiltersSetTemperature(screenFiltersCurrentTemperature);
}
void screenFiltersReduceBlueLevel3(void)
{
screenFiltersCurrentTemperature = 2100;
screenFiltersSetTemperature(screenFiltersCurrentTemperature);
}
void screenFiltersReduceBlueLevel4(void)
{
screenFiltersCurrentTemperature = 1550;
screenFiltersSetTemperature(screenFiltersCurrentTemperature);
}
void screenFiltersReduceBlueLevel5(void)
{
screenFiltersCurrentTemperature = 1000;
screenFiltersSetTemperature(screenFiltersCurrentTemperature);
}
void screenFiltersSetTemperature(int temperature)
static void ScreenFiltersMenu_SetCct(int cct)
{
color_setting_t cs;
memset(&cs, 0, sizeof(cs));
cs.temperature = temperature;
cs.temperature = cct;
/*cs.gamma[0] = 1.0F;
cs.gamma[1] = 1.0F;
cs.gamma[2] = 1.0F;
cs.brightness = 1.0F;*/
applyColorSettings(&cs);
ScreenFiltersMenu_ApplyColorSettings(&cs);
}
Menu screenFiltersMenu = {
"Screen filters menu",
{
{ "[6500K] Default", METHOD, .method = &ScreenFiltersMenu_SetDefault },
{ "[10000K] Aquarium", METHOD, .method = &ScreenFiltersMenu_SetAquarium },
{ "[7500K] Overcast Sky", METHOD, .method = &ScreenFiltersMenu_SetOvercastSky },
{ "[5500K] Daylight", METHOD, .method = &ScreenFiltersMenu_SetDaylight },
{ "[4200K] Fluorescent", METHOD, .method = &ScreenFiltersMenu_SetFluorescent },
{ "[3400K] Halogen", METHOD, .method = &ScreenFiltersMenu_SetHalogen },
{ "[2700K] Incandescent", METHOD, .method = &ScreenFiltersMenu_SetIncandescent },
{ "[2300K] Warm Incandescent", METHOD, .method = &ScreenFiltersMenu_SetWarmIncandescent },
{ "[1900K] Candle", METHOD, .method = &ScreenFiltersMenu_SetCandle },
{ "[2700K] Ember", METHOD, .method = &ScreenFiltersMenu_SetEmber },
{},
}
};
#define DEF_CCT_SETTER(temp, name)\
void ScreenFiltersMenu_Set##name(void)\
{\
screenFiltersCurrentTemperature = temp;\
ScreenFiltersMenu_SetCct(temp);\
}
DEF_CCT_SETTER(6500, Default)
DEF_CCT_SETTER(10000, Aquarium)
DEF_CCT_SETTER(7500, OvercastSky)
DEF_CCT_SETTER(5500, Daylight)
DEF_CCT_SETTER(4200, Fluorescent)
DEF_CCT_SETTER(3400, Halogen)
DEF_CCT_SETTER(2700, Incandescent)
DEF_CCT_SETTER(2300, WarmIncandescent)
DEF_CCT_SETTER(1900, Candle)
DEF_CCT_SETTER(1200, Ember)