Merge remote-tracking branch 'origin/master'

* origin/master: (98 commits)
  rosalina: fix for latest libctru changes
  pm: fix critical bugs where 1.0(?) titles not in the list have scheduling mode misconfigured
  loader: revert to use the NS patch due to a Nintendo bug: https://www.3dbrew.org/wiki/NCCH/Extended_Header#Flag1
  loader: replace NS N3DS CPU patch with exheader override, fix overriding exheader with homebrew
  rosalina: ntp: use PTMSYSM_SetRtcTime
  revert the memory map to the old one (mostly)
  fix module loading
  kext: fix outer memory cacheability on newer versions
  so bascially rosalina's image...
  rosalina: add hidden debug info menu
  rosalina: refactor menu handling
  rosalina: rephrase brightness warning
  rosalina: add brightness control menu
  rosalina/pm: remove fs patch, use pm instead
  rosalina: cleanup variable names
  rosalina: reorder menus
  Fix latest commit
  rosalina menu: add scrolling, cpad and inputredir support (note: no ZL/ZR due to technical reasons)
  stuff
  newlib...
  ...

# Conflicts:
#	k11_extension/source/main.c
#	k11_extension/source/svc/UnmapProcessMemoryEx.c
#	sysmodules/rosalina/Makefile
#	sysmodules/rosalina/include/menu.h
#	sysmodules/rosalina/include/utils.h
#	sysmodules/rosalina/source/errdisp.c
#	sysmodules/rosalina/source/main.c
#	sysmodules/rosalina/source/menu.c
#	sysmodules/rosalina/source/menus.c
This commit is contained in:
Lorenzo Dellacà
2020-07-04 02:43:27 +02:00
266 changed files with 3161 additions and 1525 deletions

View File

@@ -1,6 +1,6 @@
/*
* This file is part of Luma3DS
* Copyright (C) 2016-2019 Aurora Wright, TuxSH
* Copyright (C) 2016-2020 Aurora Wright, TuxSH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,16 +33,11 @@
#include "utils.h"
#include "fmt.h"
#include "ifile.h"
#include "pmdbgext.h"
#define MAKE_QWORD(hi,low) \
((u64) ((((u64)(hi)) << 32) | (low)))
typedef struct CheatProcessInfo
{
u32 pid;
u64 titleId;
} CheatProcessInfo;
typedef struct CheatDescription
{
struct {
@@ -70,36 +65,6 @@ CheatDescription* cheats[1024] = { 0 };
u8 cheatBuffer[32768] = { 0 };
u8 cheatPage[0x1000] = { 0 };
static CheatProcessInfo cheatinfo[0x40] = { 0 };
static s32 Cheats_FetchProcessInfo(void)
{
u32 pidList[0x40];
s32 processAmount;
s64 sa, textTotalRoundedSize, rodataTotalRoundedSize, dataTotalRoundedSize;
svcGetProcessList(&processAmount, pidList, 0x40);
for (s32 i = 0; i < processAmount; i++)
{
Handle processHandle;
Result res = svcOpenProcess(&processHandle, pidList[i]);
if (R_FAILED(res)) continue;
cheatinfo[i].pid = pidList[i];
svcGetProcessInfo((s64 *) &cheatinfo[i].titleId, processHandle, 0x10001);
svcGetProcessInfo(&textTotalRoundedSize, processHandle, 0x10002);
svcGetProcessInfo(&rodataTotalRoundedSize, processHandle, 0x10003);
svcGetProcessInfo(&dataTotalRoundedSize, processHandle, 0x10004);
svcGetProcessInfo(&sa, processHandle, 0x10005);
svcCloseHandle(processHandle);
}
return processAmount;
}
typedef struct CheatState
{
u32 index;
@@ -131,6 +96,7 @@ typedef struct CheatState
CheatState cheat_state = { 0 };
u8 cheatCount = 0;
u64 cheatTitleInfo = -1ULL;
u64 cheatRngState = 0;
static inline u32* activeOffset()
{
@@ -149,6 +115,12 @@ static inline u32* activeStorage(CheatDescription* desc)
char failureReason[64];
static u32 Cheat_GetRandomNumber(void)
{
cheatRngState = 0x5D588B656C078965ULL * cheatRngState + 0x0000000000269EC3ULL;
return (u32)(cheatRngState >> 32);
}
static bool Cheat_IsValidAddress(const Handle processHandle, u32 address, u32 size)
{
MemInfo info;
@@ -168,7 +140,7 @@ static u8 ReadWriteBuffer8 = 0;
static bool Cheat_Write8(const Handle processHandle, u32 offset, u8 value)
{
u32 addr = *activeOffset() + offset;
if (addr >= 0x01E81000 && addr + 1 < 0x01E82000)
if (addr >= 0x01E81000 && addr < 0x01E82000)
{
cheatPage[addr - 0x01E81000] = value;
return true;
@@ -184,7 +156,7 @@ static bool Cheat_Write8(const Handle processHandle, u32 offset, u8 value)
static bool Cheat_Write16(const Handle processHandle, u32 offset, u16 value)
{
u32 addr = *activeOffset() + offset;
if (addr >= 0x01E81000 && addr + 2 < 0x01E82000)
if (addr >= 0x01E81000 && addr + 1 < 0x01E82000)
{
*(u16*)(cheatPage + addr - 0x01E81000) = value;
return true;
@@ -200,7 +172,7 @@ static bool Cheat_Write16(const Handle processHandle, u32 offset, u16 value)
static bool Cheat_Write32(const Handle processHandle, u32 offset, u32 value)
{
u32 addr = *activeOffset() + offset;
if (addr >= 0x01E81000 && addr + 4 < 0x01E82000)
if (addr >= 0x01E81000 && addr + 3 < 0x01E82000)
{
*(u32*)(cheatPage + addr - 0x01E81000) = value;
return true;
@@ -216,7 +188,7 @@ static bool Cheat_Write32(const Handle processHandle, u32 offset, u32 value)
static bool Cheat_Read8(const Handle processHandle, u32 offset, u8* retValue)
{
u32 addr = *activeOffset() + offset;
if (addr >= 0x01E81000 && addr + 1 < 0x01E82000)
if (addr >= 0x01E81000 && addr < 0x01E82000)
{
*retValue = cheatPage[addr - 0x01E81000];
return true;
@@ -233,7 +205,7 @@ static bool Cheat_Read8(const Handle processHandle, u32 offset, u8* retValue)
static bool Cheat_Read16(const Handle processHandle, u32 offset, u16* retValue)
{
u32 addr = *activeOffset() + offset;
if (addr >= 0x01E81000 && addr + 2 < 0x01E82000)
if (addr >= 0x01E81000 && addr + 1 < 0x01E82000)
{
*retValue = *(u16*)(cheatPage + addr - 0x01E81000);
return true;
@@ -250,7 +222,7 @@ static bool Cheat_Read16(const Handle processHandle, u32 offset, u16* retValue)
static bool Cheat_Read32(const Handle processHandle, u32 offset, u32* retValue)
{
u32 addr = *activeOffset() + offset;
if (addr >= 0x01E81000 && addr + 4 < 0x01E82000)
if (addr >= 0x01E81000 && addr + 3 < 0x01E82000)
{
*retValue = *(u32*)(cheatPage + addr - 0x01E81000);
return true;
@@ -1512,7 +1484,7 @@ static u32 Cheat_ApplyCheat(const Handle processHandle, CheatDescription* const
case 0xF:
{
u32 range = arg1 - (arg0 & 0xFFFFFF);
u32 number = rand() % range;
u32 number = Cheat_GetRandomNumber() % range;
*activeData() = (arg0 & 0xFFFFFF) + number;
}
break;
@@ -1886,33 +1858,24 @@ static void Cheat_LoadCheatsIntoMemory(u64 titleId)
memset(cheatPage, 0, 0x1000);
}
static u32 Cheat_GetCurrentPID(u64* titleId)
static u32 Cheat_GetCurrentProcessAndTitleId(u64* titleId)
{
s32 processAmount = Cheats_FetchProcessInfo();
s32 index = -1;
for (s32 i = 0; i < processAmount; i++)
{
if (((u32) (cheatinfo[i].titleId >> 32)) == 0x00040010 || ((u32) (cheatinfo[i].titleId >> 32) == 0x00040000))
{
index = i;
break;
}
}
if (index != -1)
{
*titleId = cheatinfo[index].titleId;
return cheatinfo[index].pid;
}
else
{
FS_ProgramInfo programInfo;
u32 pid;
u32 launchFlags;
Result res = PMDBG_GetCurrentAppInfo(&programInfo, &pid, &launchFlags);
if (R_FAILED(res)) {
*titleId = 0;
return 0xFFFFFFFF;
}
*titleId = programInfo.programId;
return pid;
}
void Cheat_SeedRng(u64 seed)
{
cheatRngState = seed;
}
void Cheat_ApplyCheats(void)
@@ -1923,7 +1886,7 @@ void Cheat_ApplyCheats(void)
}
u64 titleId = 0;
u32 pid = Cheat_GetCurrentPID(&titleId);
u32 pid = Cheat_GetCurrentProcessAndTitleId(&titleId);
if (!titleId)
{
@@ -1949,7 +1912,7 @@ void Cheat_ApplyCheats(void)
void RosalinaMenu_Cheats(void)
{
u64 titleId = 0;
u32 pid = Cheat_GetCurrentPID(&titleId);
u32 pid = Cheat_GetCurrentProcessAndTitleId(&titleId);
if (titleId != 0)
{
@@ -1981,7 +1944,7 @@ void RosalinaMenu_Cheats(void)
Draw_FlushFramebuffer();
Draw_Unlock();
} while (!(waitInput() & BUTTON_B) && !terminationRequest);
} while (!(waitInput() & KEY_B) && !menuShouldExit);
}
else
{
@@ -2019,18 +1982,18 @@ void RosalinaMenu_Cheats(void)
Draw_FlushFramebuffer();
Draw_Unlock();
if (terminationRequest) break;
if (menuShouldExit) break;
u32 pressed;
do
{
pressed = waitInputWithTimeout(50);
if (pressed != 0) break;
} while (pressed == 0 && !terminationRequest);
} while (pressed == 0 && !menuShouldExit);
if (pressed & BUTTON_B)
if (pressed & KEY_B)
break;
else if ((pressed & BUTTON_A) && R_SUCCEEDED(r))
else if ((pressed & KEY_A) && R_SUCCEEDED(r))
{
if (cheats[selected]->active)
{
@@ -2041,13 +2004,13 @@ void RosalinaMenu_Cheats(void)
r = Cheat_MapMemoryAndApplyCheat(pid, cheats[selected]);
}
}
else if (pressed & BUTTON_DOWN)
else if (pressed & KEY_DOWN)
selected++;
else if (pressed & BUTTON_UP)
else if (pressed & KEY_UP)
selected--;
else if (pressed & BUTTON_LEFT)
else if (pressed & KEY_LEFT)
selected -= CHEATS_PER_MENU_PAGE;
else if (pressed & BUTTON_RIGHT)
else if (pressed & KEY_RIGHT)
{
if (selected + CHEATS_PER_MENU_PAGE < cheatCount)
selected += CHEATS_PER_MENU_PAGE;
@@ -2062,7 +2025,7 @@ void RosalinaMenu_Cheats(void)
pagePrev = page;
page = selected / CHEATS_PER_MENU_PAGE;
} while (!terminationRequest);
} while (!menuShouldExit);
}
}

View File

@@ -1,6 +1,6 @@
/*
* This file is part of Luma3DS
* Copyright (C) 2016-2019 Aurora Wright, TuxSH
* Copyright (C) 2016-2020 Aurora Wright, TuxSH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -38,11 +38,11 @@
Menu debuggerMenu = {
"Debugger options menu",
.nbItems = 3,
{
{ "Enable debugger", METHOD, .method = &DebuggerMenu_EnableDebugger },
{ "Disable debugger", METHOD, .method = &DebuggerMenu_DisableDebugger },
{ "Force-debug next application at launch", METHOD, .method = &DebuggerMenu_DebugNextApplicationByForce },
{},
}
};
@@ -84,6 +84,30 @@ void debuggerFetchAndSetNextApplicationDebugHandleTask(void *argdata)
GDB_UnlockAllContexts(&gdbServer);
}
Result debuggerDisable(s64 timeout)
{
Result res = 0;
bool initialized = gdbServer.referenceCount != 0;
if(initialized)
{
svcSignalEvent(gdbServer.super.shall_terminate_event);
server_kill_connections(&gdbServer.super);
res = MyThread_Join(&debuggerDebugThread, timeout);
if(res == 0)
res = MyThread_Join(&debuggerSocketThread, timeout);
Handle dummy = 0;
PMDBG_RunQueuedProcess(&dummy);
svcCloseHandle(dummy);
PMDBG_DebugNextApplicationByForce(false);
nextApplicationGdbCtx = NULL;
svcKernelSetState(0x10000, 2);
}
return res;
}
void DebuggerMenu_EnableDebugger(void)
{
bool done = false, alreadyEnabled = gdbServer.super.running;
@@ -115,16 +139,18 @@ void DebuggerMenu_EnableDebugger(void)
if(!done)
{
res = GDB_InitializeServer(&gdbServer);
Handle handles[3] = { gdbServer.super.started_event, gdbServer.super.shall_terminate_event, preTerminationEvent };
s32 idx;
if(R_SUCCEEDED(res))
{
debuggerCreateSocketThread();
debuggerCreateDebugThread();
res = svcWaitSynchronization(gdbServer.super.started_event, 10 * 1000 * 1000 * 1000LL);
res = svcWaitSynchronizationN(&idx, handles, 3, false, 5 * 1000 * 1000 * 1000LL);
if(res == 0) res = gdbServer.super.init_result;
}
if(res != 0)
sprintf(buf, "Starting debugger... failed (0x%08lx).", (u32)res);
done = true;
}
if(res == 0)
@@ -136,33 +162,16 @@ void DebuggerMenu_EnableDebugger(void)
Draw_FlushFramebuffer();
Draw_Unlock();
}
while(!(waitInput() & BUTTON_B) && !terminationRequest);
while(!(waitInput() & KEY_B) && !menuShouldExit);
}
void DebuggerMenu_DisableDebugger(void)
{
bool initialized = gdbServer.referenceCount != 0;
Result res = 0;
Result res = initialized ? debuggerDisable(2 * 1000 * 1000 * 1000LL) : 0;
char buf[65];
if(initialized)
{
svcSignalEvent(gdbServer.super.shall_terminate_event);
server_kill_connections(&gdbServer.super);
//server_set_should_close_all(&gdbServer.super);
res = MyThread_Join(&debuggerDebugThread, 2 * 1000 * 1000 * 1000LL);
if(res == 0)
res = MyThread_Join(&debuggerSocketThread, 2 * 1000 * 1000 * 1000LL);
Handle dummy = 0;
PMDBG_RunQueuedProcess(&dummy);
svcCloseHandle(dummy);
PMDBG_DebugNextApplicationByForce(false);
nextApplicationGdbCtx = NULL;
svcKernelSetState(0x10000, 2);
}
if(res != 0)
sprintf(buf, "Failed to disable debugger (0x%08lx).", (u32)res);
@@ -174,7 +183,7 @@ void DebuggerMenu_DisableDebugger(void)
Draw_FlushFramebuffer();
Draw_Unlock();
}
while(!(waitInput() & BUTTON_B) && !terminationRequest);
while(!(waitInput() & KEY_B) && !menuShouldExit);
}
void DebuggerMenu_DebugNextApplicationByForce(void)
@@ -223,7 +232,7 @@ void DebuggerMenu_DebugNextApplicationByForce(void)
Draw_FlushFramebuffer();
Draw_Unlock();
}
while(!(waitInput() & BUTTON_B) && !terminationRequest);
while(!(waitInput() & KEY_B) && !menuShouldExit);
}
void debuggerSocketThreadMain(void)

View File

@@ -1,6 +1,6 @@
/*
* This file is part of Luma3DS
* Copyright (C) 2016-2019 Aurora Wright, TuxSH
* Copyright (C) 2016-2020 Aurora Wright, TuxSH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,36 +33,37 @@
#include "hbloader.h"
#include "plgloader.h"
#include "fmt.h"
#include "utils.h" // for makeARMBranch
#include "utils.h" // for makeArmBranch
#include "minisoc.h"
#include "ifile.h"
#include "pmdbgext.h"
Menu miscellaneousMenu = {
"Miscellaneous options menu",
.nbItems = 5,
{
{ "Switch the hb. title to the current app.", METHOD, .method = &MiscellaneousMenu_SwitchBoot3dsxTargetTitle },
{ "Change the menu combo", METHOD, .method = &MiscellaneousMenu_ChangeMenuCombo },
{ "Start InputRedirection", METHOD, .method = &MiscellaneousMenu_InputRedirection },
{ "Sync time and date via NTP", METHOD, .method = &MiscellaneousMenu_SyncTimeDate },
{ "Save settings", METHOD, .method = &MiscellaneousMenu_SaveSettings },
{},
}
};
void MiscellaneousMenu_SwitchBoot3dsxTargetTitle(void)
{
Result res;
u64 titleId = 0;
char failureReason[64];
if(HBLDR_3DSX_TID == HBLDR_DEFAULT_3DSX_TID)
{
FS_ProgramInfo progInfo;
u32 pid;
res = PMDBG_GetCurrentAppTitleIdAndPid(&titleId, &pid);
u32 launchFlags;
res = PMDBG_GetCurrentAppInfo(&progInfo, &pid, &launchFlags);
if(R_SUCCEEDED(res))
{
HBLDR_3DSX_TID = titleId;
HBLDR_3DSX_TID = progInfo.programId;
miscellaneousMenu.items[0].title = "Switch the hb. title to hblauncher_loader";
}
else
@@ -95,13 +96,25 @@ void MiscellaneousMenu_SwitchBoot3dsxTargetTitle(void)
Draw_FlushFramebuffer();
Draw_Unlock();
}
while(!(waitInput() & BUTTON_B) && !terminationRequest);
while(!(waitInput() & KEY_B) && !menuShouldExit);
}
static void MiscellaneousMenu_ConvertComboToString(char *out, u32 combo)
{
static const char *keys[] = { "A", "B", "Select", "Start", "Right", "Left", "Up", "Down", "R", "L", "X", "Y" };
for(s32 i = 11; i >= 0; i--)
static const char *keys[] = {
"A", "B", "Select", "Start", "Right", "Left", "Up", "Down", "R", "L", "X", "Y",
"?", "?",
"ZL", "ZR",
"?", "?", "?", "?",
"Touch",
"?", "?", "?",
"CStick Right", "CStick Left", "CStick Up", "CStick Down",
"CPad Right", "CPad Left", "CPad Up", "CPad Down",
};
char *outOrig = out;
out[0] = 0;
for(s32 i = 31; i >= 0; i--)
{
if(combo & (1 << i))
{
@@ -111,12 +124,13 @@ static void MiscellaneousMenu_ConvertComboToString(char *out, u32 combo)
}
}
out[-1] = 0;
if (out != outOrig)
out[-1] = 0;
}
void MiscellaneousMenu_ChangeMenuCombo(void)
{
char comboStrOrig[64], comboStr[64];
char comboStrOrig[128], comboStr[128];
u32 posY;
Draw_Lock();
@@ -132,9 +146,6 @@ void MiscellaneousMenu_ChangeMenuCombo(void)
posY = Draw_DrawFormattedString(10, 30, COLOR_WHITE, "The current menu combo is: %s", comboStrOrig);
posY = Draw_DrawString(10, posY + SPACING_Y, COLOR_WHITE, "Please enter the new combo:");
Draw_FlushFramebuffer();
Draw_Unlock();
menuCombo = waitCombo();
MiscellaneousMenu_ConvertComboToString(comboStr, menuCombo);
@@ -151,7 +162,7 @@ void MiscellaneousMenu_ChangeMenuCombo(void)
Draw_FlushFramebuffer();
Draw_Unlock();
}
while(!(waitInput() & BUTTON_B) && !terminationRequest);
while(!(waitInput() & KEY_B) && !menuShouldExit);
}
Result SaveSettings(void)
@@ -228,12 +239,11 @@ void MiscellaneousMenu_SaveSettings(void)
Draw_FlushFramebuffer();
Draw_Unlock();
}
while(!(waitInput() & BUTTON_B) && !terminationRequest);
while(!(waitInput() & KEY_B) && !menuShouldExit);
}
void MiscellaneousMenu_InputRedirection(void)
{
static MyThread *inputRedirectionThread = NULL;
bool done = false;
Result res;
@@ -243,11 +253,7 @@ void MiscellaneousMenu_InputRedirection(void)
if(wasEnabled)
{
res = InputRedirection_DoOrUndoPatches();
inputRedirectionEnabled = false;
res = MyThread_Join(inputRedirectionThread, 5 * 1000 * 1000 * 1000LL);
svcCloseHandle(inputRedirectionThreadStartedEvent);
res = InputRedirection_Disable(5 * 1000 * 1000 * 1000LL);
if(res != 0)
sprintf(buf, "Failed to stop InputRedirection (0x%08lx).", (u32)res);
else
@@ -294,13 +300,18 @@ void MiscellaneousMenu_InputRedirection(void)
res = svcCreateEvent(&inputRedirectionThreadStartedEvent, RESET_STICKY);
if(R_SUCCEEDED(res))
{
inputRedirectionThread = inputRedirectionCreateThread();
inputRedirectionCreateThread();
res = svcWaitSynchronization(inputRedirectionThreadStartedEvent, 10 * 1000 * 1000 * 1000LL);
if(res == 0)
res = (Result)inputRedirectionStartResult;
if(res != 0)
{
svcCloseHandle(inputRedirectionThreadStartedEvent);
InputRedirection_DoOrUndoPatches();
inputRedirectionEnabled = false;
}
inputRedirectionStartResult = 0;
}
}
@@ -328,7 +339,7 @@ void MiscellaneousMenu_InputRedirection(void)
Draw_FlushFramebuffer();
Draw_Unlock();
}
while(!(waitInput() & BUTTON_B) && !terminationRequest);
while(!(waitInput() & KEY_B) && !menuShouldExit);
}
void MiscellaneousMenu_SyncTimeDate(void)
@@ -342,12 +353,12 @@ void MiscellaneousMenu_SyncTimeDate(void)
bool isSocURegistered;
time_t t;
struct tm localt = {0};
res = srvIsServiceRegistered(&isSocURegistered, "soc:U");
cantStart = R_FAILED(res) || !isSocURegistered;
int utcOffset = 12;
int utcOffsetMinute = 0;
int absOffset;
do
{
@@ -356,20 +367,21 @@ void MiscellaneousMenu_SyncTimeDate(void)
absOffset = utcOffset - 12;
absOffset = absOffset < 0 ? -absOffset : absOffset;
posY = Draw_DrawFormattedString(10, 30, COLOR_WHITE, "Current UTC offset: %c%02d", utcOffset < 12 ? '-' : '+', absOffset);
posY = Draw_DrawFormattedString(10, posY + SPACING_Y, COLOR_WHITE, "Use DPAD Left/Right to change offset.\nPress A when done.") + SPACING_Y;
posY = Draw_DrawFormattedString(10, 30, COLOR_WHITE, "Current UTC offset: %c%02d%02d", utcOffset < 12 ? '-' : '+', absOffset, utcOffsetMinute);
posY = Draw_DrawFormattedString(10, posY + SPACING_Y, COLOR_WHITE, "Use DPAD Left/Right to change hour offset.\nUse DPAD Up/Down to change minute offset.\nPress A when done.") + SPACING_Y;
input = waitInput();
if(input & BUTTON_LEFT) utcOffset = (24 + utcOffset - 1) % 24; // ensure utcOffset >= 0
if(input & BUTTON_RIGHT) utcOffset = (utcOffset + 1) % 24;
if(input & KEY_LEFT) utcOffset = (24 + utcOffset - 1) % 24; // ensure utcOffset >= 0
if(input & KEY_RIGHT) utcOffset = (utcOffset + 1) % 24;
if(input & KEY_UP) utcOffsetMinute = (utcOffsetMinute + 1) % 60;
if(input & KEY_DOWN) utcOffsetMinute = (60 + utcOffsetMinute - 1) % 60;
Draw_FlushFramebuffer();
Draw_Unlock();
}
while(!(input & (BUTTON_A | BUTTON_B)) && !terminationRequest);
while(!(input & (KEY_A | KEY_B)) && !menuShouldExit);
if (input & BUTTON_B)
if (input & KEY_B)
return;
utcOffset -= 12;
@@ -383,8 +395,8 @@ void MiscellaneousMenu_SyncTimeDate(void)
if(R_SUCCEEDED(res))
{
t += 3600 * utcOffset;
gmtime_r(&t, &localt);
res = ntpSetTimeDate(&localt);
t += 60 * utcOffsetMinute;
res = ntpSetTimeDate(t);
}
}
@@ -408,6 +420,6 @@ void MiscellaneousMenu_SyncTimeDate(void)
Draw_FlushFramebuffer();
Draw_Unlock();
}
while(!(input & BUTTON_B) && !terminationRequest);
while(!(input & KEY_B) && !menuShouldExit);
}
}

View File

@@ -1,6 +1,6 @@
/*
* This file is part of Luma3DS
* Copyright (C) 2016-2019 Aurora Wright, TuxSH
* Copyright (C) 2016-2020 Aurora Wright, TuxSH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,10 +34,10 @@ static char clkRateBuf[128 + 1];
Menu N3DSMenu = {
"New 3DS menu",
.nbItems = 2,
{
{ "Enable L2 cache", METHOD, .method = &N3DSMenu_EnableDisableL2Cache },
{ clkRateBuf, METHOD, .method = &N3DSMenu_ChangeClockRate }
{ clkRateBuf, METHOD, .method = &N3DSMenu_ChangeClockRate },
{},
}
};

View File

@@ -1,6 +1,6 @@
/*
* This file is part of Luma3DS
* Copyright (C) 2016-2019 Aurora Wright, TuxSH
* Copyright (C) 2016-2020 Aurora Wright, TuxSH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@
#include <3ds.h>
#include "menus/process_list.h"
#include "process_patches.h"
#include "memory.h"
#include "csvc.h"
#include "draw.h"
@@ -104,7 +105,7 @@ static void ProcessListMenu_DumpMemory(const char *name, void *start, u32 size)
IFile file;
Result res;
char filename[64] = {0};
char filename[100] = {0};
FS_Archive archive;
FS_ArchiveID archiveId;
@@ -197,7 +198,7 @@ end:
Draw_FlushFramebuffer();
Draw_Unlock();
}
while(!(waitInput() & BUTTON_B) && !terminationRequest);
while(!(waitInput() & KEY_B) && !menuShouldExit);
#undef TRY
}
@@ -493,21 +494,21 @@ static void ProcessListMenu_MemoryViewer(const ProcessInfo *info)
u32 pressed = waitInputWithTimeout(1000);
if(pressed & BUTTON_A)
if(pressed & KEY_A)
editing = !editing;
else if(pressed & BUTTON_X)
else if(pressed & KEY_X)
{
if(checkMode(MENU_MODE_GOTO))
finishJumping();
else
gotoAddress = __builtin_bswap32(((u32)menus[MENU_MODE_NORMAL].buf) + menus[MENU_MODE_NORMAL].selected);
}
else if(pressed & BUTTON_Y)
else if(pressed & KEY_Y)
{
if(checkMode(MENU_MODE_SEARCH))
finishSearching();
}
else if(pressed & BUTTON_SELECT)
else if(pressed & KEY_SELECT)
{
clearMenu();
ProcessListMenu_DumpMemory(info->name, menus[MENU_MODE_NORMAL].buf, menus[MENU_MODE_NORMAL].max);
@@ -517,35 +518,35 @@ static void ProcessListMenu_MemoryViewer(const ProcessInfo *info)
if(editing)
{
// Edit the highlighted byte
if(pressed & BUTTON_LEFT)
if(pressed & KEY_LEFT)
selectedByteAdd0x10();
else if(pressed & BUTTON_RIGHT)
else if(pressed & KEY_RIGHT)
selectedByteSub0x10();
else if(pressed & BUTTON_UP)
else if(pressed & KEY_UP)
selectedByteIncrement();
else if(pressed & BUTTON_DOWN)
else if(pressed & KEY_DOWN)
selectedByteDecrement();
}
else
{
// Move the cursor
if(pressed & BUTTON_LEFT)
if(pressed & KEY_LEFT)
selectedMoveLeft();
else if(pressed & BUTTON_RIGHT)
else if(pressed & KEY_RIGHT)
selectedMoveRight();
else if(pressed & BUTTON_UP)
else if(pressed & KEY_UP)
selectedMoveUp();
else if(pressed & BUTTON_DOWN)
else if(pressed & KEY_DOWN)
selectedMoveDown();
else if(pressed & BUTTON_L1)
else if(pressed & KEY_L)
{
if(menuMode == MENU_MODE_NORMAL)
viewHeap();
else if(menuMode == MENU_MODE_SEARCH)
searchPatternReduce();
}
else if(pressed & BUTTON_R1)
else if(pressed & KEY_R)
{
if(menuMode == MENU_MODE_NORMAL)
viewCode();
@@ -554,7 +555,7 @@ static void ProcessListMenu_MemoryViewer(const ProcessInfo *info)
}
}
if(pressed & BUTTON_B) // go back to the list, or the simple viewer
if(pressed & KEY_B) // go back to the list, or the simple viewer
{
if(menuMode != MENU_MODE_NORMAL)
{
@@ -568,7 +569,7 @@ static void ProcessListMenu_MemoryViewer(const ProcessInfo *info)
if(menus[menuMode].selected >= menus[menuMode].max)
menus[menuMode].selected = menus[menuMode].max - 1;
}
while(!terminationRequest);
while(!menuShouldExit);
clearMenu();
}
@@ -666,7 +667,7 @@ void RosalinaMenu_ProcessList(void)
if(gdbServer.super.running)
{
char ipBuffer[17];
u32 ip = gethostid();
u32 ip = socGethostid();
u8 *addr = (u8 *)&ip;
int n = sprintf(ipBuffer, "%hhu.%hhu.%hhu.%hhu", addr[0], addr[1], addr[2], addr[3]);
Draw_DrawString(SCREEN_BOT_WIDTH - 10 - SPACING_X * n, 10, COLOR_WHITE, ipBuffer);
@@ -685,7 +686,7 @@ void RosalinaMenu_ProcessList(void)
Draw_FlushFramebuffer();
Draw_Unlock();
if(terminationRequest)
if(menuShouldExit)
break;
u32 pressed;
@@ -698,19 +699,19 @@ void RosalinaMenu_ProcessList(void)
if(memcmp(infos, infosPrev, sizeof(infos)) != 0)
break;
}
while(pressed == 0 && !terminationRequest);
while(pressed == 0 && !menuShouldExit);
if(pressed & BUTTON_B)
if(pressed & KEY_B)
break;
else if(pressed & BUTTON_A)
else if(pressed & KEY_A)
ProcessListMenu_HandleSelected(&infos[selected]);
else if(pressed & BUTTON_DOWN)
else if(pressed & KEY_DOWN)
selected++;
else if(pressed & BUTTON_UP)
else if(pressed & KEY_UP)
selected--;
else if(pressed & BUTTON_LEFT)
else if(pressed & KEY_LEFT)
selected -= PROCESSES_PER_MENU_PAGE;
else if(pressed & BUTTON_RIGHT)
else if(pressed & KEY_RIGHT)
{
if(selected + PROCESSES_PER_MENU_PAGE < processAmount)
selected += PROCESSES_PER_MENU_PAGE;
@@ -728,5 +729,5 @@ void RosalinaMenu_ProcessList(void)
pagePrev = page;
page = selected / PROCESSES_PER_MENU_PAGE;
}
while(!terminationRequest);
while(!menuShouldExit);
}

View File

@@ -1,120 +0,0 @@
/*
* This file is part of Luma3DS
* Copyright (C) 2016-2019 Aurora Wright, TuxSH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include <3ds.h>
#include "csvc.h"
#include "menus/process_patches.h"
#include "memory.h"
#include "draw.h"
#include "hbloader.h"
#include "fmt.h"
#include "utils.h"
static Result ProcessPatchesMenu_DoPatchUnpatchFS(u32 textTotalRoundedSize)
{
static bool patched = false;
static u16 *off;
static u16 origData[2];
static const u16 pattern[2] = {
0x7401, // strb r1, [r0, #16]
0x2000, // movs r0, #0
};
if(patched)
{
memcpy(off, &origData, sizeof(origData));
patched = false;
}
else
{
off = (u16 *)memsearch((u8 *)0x00100000, &pattern, textTotalRoundedSize, sizeof(pattern));
if(off == NULL)
return -1;
for(; (*off & 0xFF00) != 0xB500; off++); // Find function start
memcpy(origData, off, 4);
off[0] = 0x2001; // mov r0, #1
off[1] = 0x4770; // bx lr
patched = true;
}
//processPatchesMenu.items[1].title = patched ? "Unpatch FS for the archive checks" : "Patch FS for the archive checks";
return 0;
}
Result OpenProcessByName(const char *name, Handle *h)
{
u32 pidList[0x40];
s32 processCount;
svcGetProcessList(&processCount, pidList, 0x40);
Handle dstProcessHandle = 0;
for(s32 i = 0; i < processCount; i++)
{
Handle processHandle;
Result res = svcOpenProcess(&processHandle, pidList[i]);
if(R_FAILED(res))
continue;
char procName[8] = {0};
svcGetProcessInfo((s64 *)procName, processHandle, 0x10000);
if(strncmp(procName, name, 8) == 0)
dstProcessHandle = processHandle;
else
svcCloseHandle(processHandle);
}
if(dstProcessHandle == 0)
return -1;
*h = dstProcessHandle;
return 0;
}
static u32 ProcessPatchesMenu_PatchUnpatchProcessByName(const char *name, Result (*func)(u32 size))
{
Result res;
Handle processHandle;
OpenProcessByName(name, &processHandle);
s64 textTotalRoundedSize = 0, startAddress = 0;
svcGetProcessInfo(&textTotalRoundedSize, processHandle, 0x10002); // only patch .text
svcGetProcessInfo(&startAddress, processHandle, 0x10005);
if(R_FAILED(res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, textTotalRoundedSize)))
return res;
res = func(textTotalRoundedSize);
svcUnmapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, textTotalRoundedSize);
return res;
}
void ProcessPatchesMenu_PatchUnpatchFSDirectly(void)
{
ProcessPatchesMenu_PatchUnpatchProcessByName("fs", &ProcessPatchesMenu_DoPatchUnpatchFS);
}

View File

@@ -55,42 +55,42 @@ typedef struct {
u8 z;
} Pixel;
static u16 g_c[0x600];
static Pixel g_px[0x400];
void applyColorSettings(color_setting_t* cs)
{
u16 c[0x600];
Pixel px[0x400];
u8 i = 0;
memset(c, 0, sizeof(c));
memset(px, 0, sizeof(px));
memset(g_c, 0, sizeof(g_c));
memset(g_px, 0, sizeof(g_px));
do {
px[i].r = i;
px[i].g = i;
px[i].b = i;
px[i].z = 0;
g_px[i].r = i;
g_px[i].g = i;
g_px[i].b = i;
g_px[i].z = 0;
} while(++i);
do {
*(c + i + 0x000) = px[i].r | (px[i].r << 8);
*(c + i + 0x100) = px[i].g | (px[i].g << 8);
*(c + i + 0x200) = px[i].b | (px[i].b << 8);
*(g_c + i + 0x000) = g_px[i].r | (g_px[i].r << 8);
*(g_c + i + 0x100) = g_px[i].g | (g_px[i].g << 8);
*(g_c + i + 0x200) = g_px[i].b | (g_px[i].b << 8);
} while(++i);
colorramp_fill(c + 0x000, c + 0x100, c + 0x200, 0x100, cs);
colorramp_fill(g_c + 0x000, g_c + 0x100, g_c + 0x200, 0x100, cs);
do {
px[i].r = *(c + i + 0x000) >> 8;
px[i].g = *(c + i + 0x100) >> 8;
px[i].b = *(c + i + 0x200) >> 8;
g_px[i].r = *(g_c + i + 0x000) >> 8;
g_px[i].g = *(g_c + i + 0x100) >> 8;
g_px[i].b = *(g_c + i + 0x200) >> 8;
} while(++i);
writeLut((u32*)px);
writeLut((u32*)g_px);
}
Menu screenFiltersMenu = {
"Screen filters menu",
.nbItems = 6,
{
{ "Disable", METHOD, .method = &screenFiltersSetDisabled },
{ "Reduce blue light (level 1)", METHOD, .method = &screenFiltersReduceBlueLevel1 },
@@ -98,6 +98,7 @@ Menu screenFiltersMenu = {
{ "Reduce blue light (level 3)", METHOD, .method = &screenFiltersReduceBlueLevel3 },
{ "Reduce blue light (level 4)", METHOD, .method = &screenFiltersReduceBlueLevel4 },
{ "Reduce blue light (level 5)", METHOD, .method = &screenFiltersReduceBlueLevel5 },
{},
}
};
@@ -143,10 +144,10 @@ void screenFiltersSetTemperature(int temperature)
memset(&cs, 0, sizeof(cs));
cs.temperature = temperature;
cs.gamma[0] = 1.0F;
/*cs.gamma[0] = 1.0F;
cs.gamma[1] = 1.0F;
cs.gamma[2] = 1.0F;
cs.brightness = 1.0F;
cs.brightness = 1.0F;*/
applyColorSettings(&cs);
}

View File

@@ -1,6 +1,6 @@
/*
* This file is part of Luma3DS
* Copyright (C) 2016-2019 Aurora Wright, TuxSH
* Copyright (C) 2016-2020 Aurora Wright, TuxSH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,13 +34,17 @@
Menu sysconfigMenu = {
"System configuration menu",
.nbItems = 2,
{
{ "Toggle LEDs", METHOD, .method = &SysConfigMenu_ToggleLEDs },
{ "Toggle Wireless", METHOD, .method = &SysConfigMenu_ToggleWireless },
{ "Toggle Power Button", METHOD, .method=&SysConfigMenu_TogglePowerButton },
{ "Control Wireless connection", METHOD, .method = &SysConfigMenu_ControlWifi },
{},
}
};
bool isConnectionForced = false;
void SysConfigMenu_ToggleLEDs(void)
{
Draw_Lock();
@@ -62,7 +66,7 @@ void SysConfigMenu_ToggleLEDs(void)
u32 pressed = waitInputWithTimeout(1000);
if(pressed & BUTTON_A)
if(pressed & KEY_A)
{
mcuHwcInit();
u8 result;
@@ -71,10 +75,10 @@ void SysConfigMenu_ToggleLEDs(void)
MCUHWC_WriteRegister(0x28, &result, 1);
mcuHwcExit();
}
else if(pressed & BUTTON_B)
else if(pressed & KEY_B)
return;
}
while(!terminationRequest);
while(!menuShouldExit);
}
void SysConfigMenu_ToggleWireless(void)
@@ -135,14 +139,221 @@ void SysConfigMenu_ToggleWireless(void)
u32 pressed = waitInputWithTimeout(1000);
if(pressed & BUTTON_A && nwmRunning)
if(pressed & KEY_A && nwmRunning)
{
nwmExtInit();
NWMEXT_ControlWirelessEnabled(!wireless);
nwmExtExit();
}
else if(pressed & BUTTON_B)
else if(pressed & KEY_B)
return;
}
while(!terminationRequest);
while(!menuShouldExit);
}
void SysConfigMenu_UpdateStatus(bool control)
{
MenuItem *item = &sysconfigMenu.items[3];
if(control)
{
item->title = "Control Wireless connection";
item->method = &SysConfigMenu_ControlWifi;
}
else
{
item->title = "Disable forced wireless connection";
item->method = &SysConfigMenu_DisableForcedWifiConnection;
}
}
static bool SysConfigMenu_ForceWifiConnection(int slot)
{
char ssid[0x20 + 1] = {0};
isConnectionForced = false;
if(R_FAILED(acInit()))
return false;
acuConfig config = {0};
ACU_CreateDefaultConfig(&config);
ACU_SetNetworkArea(&config, 2);
ACU_SetAllowApType(&config, 1 << slot);
ACU_SetRequestEulaVersion(&config);
Handle connectEvent = 0;
svcCreateEvent(&connectEvent, RESET_ONESHOT);
bool forcedConnection = false;
if(R_SUCCEEDED(ACU_ConnectAsync(&config, connectEvent)))
{
if(R_SUCCEEDED(svcWaitSynchronization(connectEvent, -1)) && R_SUCCEEDED(ACU_GetSSID(ssid)))
forcedConnection = true;
}
svcCloseHandle(connectEvent);
if(forcedConnection)
{
isConnectionForced = true;
SysConfigMenu_UpdateStatus(false);
}
else
acExit();
char infoString[80] = {0};
u32 infoStringColor = forcedConnection ? COLOR_GREEN : COLOR_RED;
if(forcedConnection)
sprintf(infoString, "Succesfully forced a connection to: %s", ssid);
else
sprintf(infoString, "Failed to connect to slot %d", slot + 1);
Draw_Lock();
Draw_ClearFramebuffer();
Draw_FlushFramebuffer();
Draw_Unlock();
do
{
Draw_Lock();
Draw_DrawString(10, 10, COLOR_TITLE, "System configuration menu");
Draw_DrawString(10, 30, infoStringColor, infoString);
Draw_DrawString(10, 40, COLOR_WHITE, "Press B to go back.");
Draw_FlushFramebuffer();
Draw_Unlock();
u32 pressed = waitInputWithTimeout(1000);
if(pressed & KEY_B)
break;
}
while(!menuShouldExit);
return forcedConnection;
}
void SysConfigMenu_TogglePowerButton(void)
{
u32 mcuIRQMask;
Draw_Lock();
Draw_ClearFramebuffer();
Draw_FlushFramebuffer();
Draw_Unlock();
mcuHwcInit();
MCUHWC_ReadRegister(0x18, (u8*)&mcuIRQMask, 4);
mcuHwcExit();
do
{
Draw_Lock();
Draw_DrawString(10, 10, COLOR_TITLE, "System configuration menu");
Draw_DrawString(10, 30, COLOR_WHITE, "Press A to toggle, press B to go back.");
Draw_DrawString(10, 50, COLOR_WHITE, "Current status:");
Draw_DrawString(100, 50, (((mcuIRQMask & 0x00000001) == 0x00000001) ? COLOR_RED : COLOR_GREEN), (((mcuIRQMask & 0x00000001) == 0x00000001) ? " DISABLED" : " ENABLED "));
Draw_FlushFramebuffer();
Draw_Unlock();
u32 pressed = waitInputWithTimeout(1000);
if(pressed & KEY_A)
{
mcuHwcInit();
MCUHWC_ReadRegister(0x18, (u8*)&mcuIRQMask, 4);
mcuIRQMask ^= 0x00000001;
MCUHWC_WriteRegister(0x18, (u8*)&mcuIRQMask, 4);
mcuHwcExit();
}
else if(pressed & KEY_B)
return;
}
while(!menuShouldExit);
}
void SysConfigMenu_ControlWifi(void)
{
Draw_Lock();
Draw_ClearFramebuffer();
Draw_FlushFramebuffer();
Draw_Unlock();
int slot = 0;
char slotString[12] = {0};
sprintf(slotString, ">1< 2 3 ");
do
{
Draw_Lock();
Draw_DrawString(10, 10, COLOR_TITLE, "System configuration menu");
Draw_DrawString(10, 30, COLOR_WHITE, "Press A to force a connection to slot:");
Draw_DrawString(10, 40, COLOR_WHITE, slotString);
Draw_DrawString(10, 60, COLOR_WHITE, "Press B to go back.");
Draw_FlushFramebuffer();
Draw_Unlock();
u32 pressed = waitInputWithTimeout(1000);
if(pressed & KEY_A)
{
if(SysConfigMenu_ForceWifiConnection(slot))
{
// Connection successfully forced, return from this menu to prevent ac handle refcount leakage.
break;
}
Draw_Lock();
Draw_ClearFramebuffer();
Draw_FlushFramebuffer();
Draw_Unlock();
}
else if(pressed & KEY_LEFT)
{
slotString[slot * 4] = ' ';
slotString[(slot * 4) + 2] = ' ';
slot--;
if(slot == -1)
slot = 2;
slotString[slot * 4] = '>';
slotString[(slot * 4) + 2] = '<';
}
else if(pressed & KEY_RIGHT)
{
slotString[slot * 4] = ' ';
slotString[(slot * 4) + 2] = ' ';
slot++;
if(slot == 3)
slot = 0;
slotString[slot * 4] = '>';
slotString[(slot * 4) + 2] = '<';
}
else if(pressed & KEY_B)
return;
}
while(!menuShouldExit);
}
void SysConfigMenu_DisableForcedWifiConnection(void)
{
Draw_Lock();
Draw_ClearFramebuffer();
Draw_FlushFramebuffer();
Draw_Unlock();
acExit();
SysConfigMenu_UpdateStatus(true);
do
{
Draw_Lock();
Draw_DrawString(10, 10, COLOR_TITLE, "System configuration menu");
Draw_DrawString(10, 30, COLOR_WHITE, "Forced connection successfully disabled.\nNote: auto-connection may remain broken.");
u32 pressed = waitInputWithTimeout(1000);
if(pressed & KEY_B)
return;
}
while(!menuShouldExit);
}