rosalina: add brightness control menu
This commit is contained in:
parent
a21eee9207
commit
a564d8536a
@ -54,6 +54,9 @@
|
||||
#define GPU_TRANSFER_CNT REG32(0x10400C18)
|
||||
#define GPU_CMDLIST_CNT REG32(0x104018F0)
|
||||
|
||||
#define LCD_TOP_BRIGHTNESS REG32(0x10202240)
|
||||
#define LCD_BOT_BRIGHTNESS REG32(0x10202A40)
|
||||
|
||||
#define FB_BOTTOM_VRAM_ADDR ((void *)0x1F48F000) // cached
|
||||
#define FB_BOTTOM_VRAM_PA 0x1848F000
|
||||
#define FB_BOTTOM_SIZE (320 * 240 * 2)
|
||||
|
@ -60,6 +60,7 @@ typedef struct Menu {
|
||||
MenuItem items[0x40];
|
||||
} Menu;
|
||||
|
||||
extern bool isN3DS;
|
||||
extern bool menuShouldExit;
|
||||
extern bool preTerminationRequested;
|
||||
extern Handle preTerminationEvent;
|
||||
|
@ -33,6 +33,7 @@
|
||||
extern Menu rosalinaMenu;
|
||||
|
||||
void RosalinaMenu_TakeScreenshot(void);
|
||||
void RosalinaMenu_ChangeScreenBrightness(void);
|
||||
void RosalinaMenu_ShowCredits(void);
|
||||
void RosalinaMenu_ProcessList(void);
|
||||
void RosalinaMenu_PowerOff(void);
|
||||
|
@ -30,3 +30,4 @@
|
||||
#include "menu.h"
|
||||
|
||||
Result OpenProcessByName(const char *name, Handle *h);
|
||||
Result PatchProcessByName(const char *name, Result (*func)(u32 size));
|
||||
|
@ -151,7 +151,6 @@ MyThread *menuCreateThread(void)
|
||||
return &menuThread;
|
||||
}
|
||||
|
||||
extern bool isN3DS;
|
||||
u32 menuCombo;
|
||||
|
||||
void menuThreadMain(void)
|
||||
@ -159,7 +158,7 @@ void menuThreadMain(void)
|
||||
if(!isN3DS)
|
||||
{
|
||||
rosalinaMenu.nbItems--;
|
||||
for(u32 i = 6; i <= rosalinaMenu.nbItems; i++)
|
||||
for(u32 i = 7; i <= rosalinaMenu.nbItems; i++)
|
||||
rosalinaMenu.items[i] = rosalinaMenu.items[i+1];
|
||||
}
|
||||
else
|
||||
|
@ -38,12 +38,14 @@
|
||||
#include "ifile.h"
|
||||
#include "memory.h"
|
||||
#include "fmt.h"
|
||||
#include "process_patches.h"
|
||||
|
||||
Menu rosalinaMenu = {
|
||||
"Rosalina menu",
|
||||
.nbItems = 11,
|
||||
.nbItems = 12,
|
||||
{
|
||||
{ "Take screenshot", METHOD, .method = &RosalinaMenu_TakeScreenshot },
|
||||
{ "Change screen brightness", METHOD, .method = &RosalinaMenu_ChangeScreenBrightness },
|
||||
{ "Cheats...", METHOD, .method = &RosalinaMenu_Cheats },
|
||||
{ "Process list", METHOD, .method = &RosalinaMenu_ProcessList },
|
||||
{ "Debugger options...", MENU, .menu = &debuggerMenu },
|
||||
@ -119,6 +121,109 @@ void RosalinaMenu_Reboot(void)
|
||||
while(!menuShouldExit);
|
||||
}
|
||||
|
||||
static u32 gspPatchAddrN3ds, gspPatchValuesN3ds[2];
|
||||
static bool gspPatchDoneN3ds;
|
||||
|
||||
static Result RosalinaMenu_PatchN3dsGspForBrightness(u32 size)
|
||||
{
|
||||
u32 *off = (u32 *)0x00100000;
|
||||
u32 *end = (u32 *)(0x00100000 + size);
|
||||
|
||||
for (; off < end && (off[0] != 0xE92D4030 || off[1] != 0xE1A04000 || off[2] != 0xE2805C01 || off[3] != 0xE5D0018C); off++);
|
||||
|
||||
if (off >= end) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
gspPatchAddrN3ds = (u32)off;
|
||||
gspPatchValuesN3ds[0] = off[26];
|
||||
gspPatchValuesN3ds[1] = off[50];
|
||||
|
||||
// NOP brightness changing in GSP
|
||||
off[26] = 0xE1A00000;
|
||||
off[50] = 0xE1A00000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static Result RosalinaMenu_RevertN3dsGspPatch(u32 size)
|
||||
{
|
||||
(void)size;
|
||||
|
||||
u32 *off = (u32 *)gspPatchAddrN3ds;
|
||||
off[26] = gspPatchValuesN3ds[0];
|
||||
off[50] = gspPatchValuesN3ds[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RosalinaMenu_ChangeScreenBrightness(void)
|
||||
{
|
||||
Result patchResult = 0;
|
||||
if (isN3DS && !gspPatchDoneN3ds)
|
||||
{
|
||||
patchResult = PatchProcessByName("gsp", RosalinaMenu_PatchN3dsGspForBrightness);
|
||||
gspPatchDoneN3ds = R_SUCCEEDED(patchResult);
|
||||
}
|
||||
|
||||
Draw_Lock();
|
||||
Draw_ClearFramebuffer();
|
||||
Draw_FlushFramebuffer();
|
||||
Draw_Unlock();
|
||||
|
||||
do
|
||||
{
|
||||
// Assume the current brightness for both screens are the same.
|
||||
s32 brightness = (s32)(LCD_TOP_BRIGHTNESS & 0xFF);
|
||||
|
||||
Draw_Lock();
|
||||
Draw_DrawString(10, 10, COLOR_TITLE, "Rosalina menu");
|
||||
u32 posY = 30;
|
||||
posY = Draw_DrawFormattedString(10, posY, COLOR_WHITE, "Current brightness (0..255): %3lu\n\n", brightness);
|
||||
if (R_SUCCEEDED(patchResult))
|
||||
{
|
||||
posY = Draw_DrawString(10, posY, COLOR_WHITE, "Press Up/Down for +-1, Right/Left for +-10.\n");
|
||||
posY = Draw_DrawString(10, posY, COLOR_WHITE, "Press Y to revert the GSP patch and exit.\n\n");
|
||||
|
||||
posY = Draw_DrawString(10, posY, COLOR_RED, "WARNING: \n");
|
||||
posY = Draw_DrawString(10, posY, COLOR_WHITE, " * very high values might damage your screens\n");
|
||||
posY = Draw_DrawString(10, posY, COLOR_WHITE, " * normal brightness mngmt. is now broken on N3DS.\nYou'll need to press Y to revert");
|
||||
}
|
||||
else
|
||||
Draw_DrawFormattedString(10, posY, COLOR_WHITE, "Failed to patch GSP (0x%08lx).", (u32)patchResult);
|
||||
|
||||
Draw_FlushFramebuffer();
|
||||
Draw_Unlock();
|
||||
|
||||
u32 pressed = waitInputWithTimeout(1000);
|
||||
|
||||
if ((pressed & DIRECTIONAL_KEYS) && R_SUCCEEDED(patchResult))
|
||||
{
|
||||
if (pressed & KEY_UP)
|
||||
brightness += 1;
|
||||
else if (pressed & KEY_DOWN)
|
||||
brightness -= 1;
|
||||
else if (pressed & KEY_RIGHT)
|
||||
brightness += 10;
|
||||
else if (pressed & KEY_LEFT)
|
||||
brightness -= 10;
|
||||
|
||||
brightness = brightness < 0 ? 0 : brightness;
|
||||
brightness = brightness > 255 ? 255 : brightness;
|
||||
LCD_TOP_BRIGHTNESS = (u32)brightness;
|
||||
LCD_BOT_BRIGHTNESS = (u32)brightness;
|
||||
}
|
||||
else if ((pressed & KEY_Y) && gspPatchDoneN3ds)
|
||||
{
|
||||
patchResult = PatchProcessByName("gsp", RosalinaMenu_RevertN3dsGspPatch);
|
||||
gspPatchDoneN3ds = !R_SUCCEEDED(patchResult);
|
||||
return;
|
||||
}
|
||||
else if (pressed & KEY_B)
|
||||
return;
|
||||
}
|
||||
while (!menuShouldExit);
|
||||
}
|
||||
|
||||
void RosalinaMenu_PowerOff(void) // Soft shutdown.
|
||||
{
|
||||
Draw_Lock();
|
||||
|
@ -59,7 +59,7 @@ Result OpenProcessByName(const char *name, Handle *h)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*static u32 ProcessPatchesMenu_PatchUnpatchProcessByName(const char *name, Result (*func)(u32 size))
|
||||
Result PatchProcessByName(const char *name, Result (*func)(u32 size))
|
||||
{
|
||||
Result res;
|
||||
Handle processHandle;
|
||||
@ -75,4 +75,4 @@ Result OpenProcessByName(const char *name, Handle *h)
|
||||
|
||||
svcUnmapProcessMemoryEx(processHandle, 0x00100000, textTotalRoundedSize);
|
||||
return res;
|
||||
}*/
|
||||
}
|
||||
|
Reference in New Issue
Block a user