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_TRANSFER_CNT REG32(0x10400C18)
|
||||||
#define GPU_CMDLIST_CNT REG32(0x104018F0)
|
#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_ADDR ((void *)0x1F48F000) // cached
|
||||||
#define FB_BOTTOM_VRAM_PA 0x1848F000
|
#define FB_BOTTOM_VRAM_PA 0x1848F000
|
||||||
#define FB_BOTTOM_SIZE (320 * 240 * 2)
|
#define FB_BOTTOM_SIZE (320 * 240 * 2)
|
||||||
|
@ -60,6 +60,7 @@ typedef struct Menu {
|
|||||||
MenuItem items[0x40];
|
MenuItem items[0x40];
|
||||||
} Menu;
|
} Menu;
|
||||||
|
|
||||||
|
extern bool isN3DS;
|
||||||
extern bool menuShouldExit;
|
extern bool menuShouldExit;
|
||||||
extern bool preTerminationRequested;
|
extern bool preTerminationRequested;
|
||||||
extern Handle preTerminationEvent;
|
extern Handle preTerminationEvent;
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
extern Menu rosalinaMenu;
|
extern Menu rosalinaMenu;
|
||||||
|
|
||||||
void RosalinaMenu_TakeScreenshot(void);
|
void RosalinaMenu_TakeScreenshot(void);
|
||||||
|
void RosalinaMenu_ChangeScreenBrightness(void);
|
||||||
void RosalinaMenu_ShowCredits(void);
|
void RosalinaMenu_ShowCredits(void);
|
||||||
void RosalinaMenu_ProcessList(void);
|
void RosalinaMenu_ProcessList(void);
|
||||||
void RosalinaMenu_PowerOff(void);
|
void RosalinaMenu_PowerOff(void);
|
||||||
|
@ -30,3 +30,4 @@
|
|||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
|
||||||
Result OpenProcessByName(const char *name, Handle *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;
|
return &menuThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern bool isN3DS;
|
|
||||||
u32 menuCombo;
|
u32 menuCombo;
|
||||||
|
|
||||||
void menuThreadMain(void)
|
void menuThreadMain(void)
|
||||||
@ -159,7 +158,7 @@ void menuThreadMain(void)
|
|||||||
if(!isN3DS)
|
if(!isN3DS)
|
||||||
{
|
{
|
||||||
rosalinaMenu.nbItems--;
|
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];
|
rosalinaMenu.items[i] = rosalinaMenu.items[i+1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -38,12 +38,14 @@
|
|||||||
#include "ifile.h"
|
#include "ifile.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
|
#include "process_patches.h"
|
||||||
|
|
||||||
Menu rosalinaMenu = {
|
Menu rosalinaMenu = {
|
||||||
"Rosalina menu",
|
"Rosalina menu",
|
||||||
.nbItems = 11,
|
.nbItems = 12,
|
||||||
{
|
{
|
||||||
{ "Take screenshot", METHOD, .method = &RosalinaMenu_TakeScreenshot },
|
{ "Take screenshot", METHOD, .method = &RosalinaMenu_TakeScreenshot },
|
||||||
|
{ "Change screen brightness", METHOD, .method = &RosalinaMenu_ChangeScreenBrightness },
|
||||||
{ "Cheats...", METHOD, .method = &RosalinaMenu_Cheats },
|
{ "Cheats...", METHOD, .method = &RosalinaMenu_Cheats },
|
||||||
{ "Process list", METHOD, .method = &RosalinaMenu_ProcessList },
|
{ "Process list", METHOD, .method = &RosalinaMenu_ProcessList },
|
||||||
{ "Debugger options...", MENU, .menu = &debuggerMenu },
|
{ "Debugger options...", MENU, .menu = &debuggerMenu },
|
||||||
@ -119,6 +121,109 @@ void RosalinaMenu_Reboot(void)
|
|||||||
while(!menuShouldExit);
|
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.
|
void RosalinaMenu_PowerOff(void) // Soft shutdown.
|
||||||
{
|
{
|
||||||
Draw_Lock();
|
Draw_Lock();
|
||||||
|
@ -59,7 +59,7 @@ Result OpenProcessByName(const char *name, Handle *h)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static u32 ProcessPatchesMenu_PatchUnpatchProcessByName(const char *name, Result (*func)(u32 size))
|
Result PatchProcessByName(const char *name, Result (*func)(u32 size))
|
||||||
{
|
{
|
||||||
Result res;
|
Result res;
|
||||||
Handle processHandle;
|
Handle processHandle;
|
||||||
@ -75,4 +75,4 @@ Result OpenProcessByName(const char *name, Handle *h)
|
|||||||
|
|
||||||
svcUnmapProcessMemoryEx(processHandle, 0x00100000, textTotalRoundedSize);
|
svcUnmapProcessMemoryEx(processHandle, 0x00100000, textTotalRoundedSize);
|
||||||
return res;
|
return res;
|
||||||
}*/
|
}
|
||||||
|
Reference in New Issue
Block a user