diff --git a/Makefile b/Makefile index 54c3153..086818f 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ boot.firm: $(SUBFOLDERS) @echo built... $(notdir $@) boot.3dsx: - @curl -sSL "https://github.com/fincs/new-hbmenu/releases/latest/download/boot.3dsx" -o "$@" + @curl -sSfLO "https://github.com/fincs/new-hbmenu/releases/latest/download/$@" @echo downloaded... $(notdir $@) $(SUBFOLDERS): diff --git a/arm9/source/crypto.c b/arm9/source/crypto.c index ea23570..ce90847 100755 --- a/arm9/source/crypto.c +++ b/arm9/source/crypto.c @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2021 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 @@ -348,7 +348,7 @@ int ctrNandInit(void) u8 __attribute__((aligned(4))) temp[0x200]; //Read NCSD header - result = firmSource == FIRMWARE_SYSNAND ? sdmmc_nand_readsectors(0, 1, temp) : sdmmc_sdcard_readsectors(emuHeader, 1, temp); + result = firmSource == FIRMWARE_SYSNAND ? sdmmc_nand_readsectors(0, 1, temp) : sdmmc_sdcard_readsectors(emuOffset + emuHeader, 1, temp); if(!result) { diff --git a/arm9/source/emunand.c b/arm9/source/emunand.c index 1f9bd76..fa0f380 100644 --- a/arm9/source/emunand.c +++ b/arm9/source/emunand.c @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2021 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 @@ -77,7 +77,7 @@ void locateEmuNand(FirmwareSource *nandType) if(!sdmmc_sdcard_readsectors(nandOffset + 1, 1, temp) && memcmp(temp + 0x100, "NCSD", 4) == 0) { emuOffset = nandOffset + 1; - emuHeader = nandOffset + 1; + emuHeader = 0; return; } @@ -85,7 +85,7 @@ void locateEmuNand(FirmwareSource *nandType) else if(i != 2 && !sdmmc_sdcard_readsectors(nandOffset + nandSize, 1, temp) && memcmp(temp + 0x100, "NCSD", 4) == 0) { emuOffset = nandOffset; - emuHeader = nandOffset + nandSize; + emuHeader = nandSize; return; } } diff --git a/arm9/source/firm.c b/arm9/source/firm.c index ce44d7e..6088bbe 100755 --- a/arm9/source/firm.c +++ b/arm9/source/firm.c @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2021 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 diff --git a/arm9/source/fs.c b/arm9/source/fs.c index b0e8742..17a6b1b 100644 --- a/arm9/source/fs.c +++ b/arm9/source/fs.c @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2021 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 diff --git a/arm9/source/fs.h b/arm9/source/fs.h index f9ab0e4..db83b2a 100644 --- a/arm9/source/fs.h +++ b/arm9/source/fs.h @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2021 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 diff --git a/sysmodules/loader/source/ifile.h b/sysmodules/loader/source/ifile.h index e184777..cd0d35e 100644 --- a/sysmodules/loader/source/ifile.h +++ b/sysmodules/loader/source/ifile.h @@ -1,6 +1,6 @@ #pragma once -#include <3ds/types.h> +#include <3ds/services/fs.h> #define PATH_MAX 255 diff --git a/sysmodules/loader/source/patcher.c b/sysmodules/loader/source/patcher.c index 24a4d50..75a1e72 100644 --- a/sysmodules/loader/source/patcher.c +++ b/sysmodules/loader/source/patcher.c @@ -548,12 +548,14 @@ static inline bool patchLayeredFs(u64 progId, u8 *code, u32 size, u32 textSize, void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 textSize, u32 roSize, u32 dataSize, u32 roAddress, u32 dataAddress) { - if(progId == 0x0004003000008F02LL || //USA Home Menu - progId == 0x0004003000008202LL || //JPN Home Menu - progId == 0x0004003000009802LL || //EUR Home Menu - progId == 0x000400300000A902LL || //KOR Home Menu - progId == 0x000400300000A102LL || //CHN Home Menu - progId == 0x000400300000B102LL) //TWN Home Menu + bool isHomeMenu = progId == 0x0004003000008F02LL || //USA Home Menu + progId == 0x0004003000008202LL || //JPN Home Menu + progId == 0x0004003000009802LL || //EUR Home Menu + progId == 0x000400300000A902LL || //KOR Home Menu + progId == 0x000400300000A102LL || //CHN Home Menu + progId == 0x000400300000B102LL; //TWN Home Menu + + if(isHomeMenu) { bool applyRegionFreePatch = true; @@ -864,7 +866,7 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 textSize, u32 ro if(!patcherApplyCodeBpsPatch(progId, code, size)) goto error; if(!applyCodeIpsPatch(progId, code, size)) goto error; - if((u32)((progId >> 0x20) & 0xFFFFFFEDULL) == 0x00040000) + if((u32)((progId >> 0x20) & 0xFFFFFFEDULL) == 0x00040000 || isHomeMenu) { u8 mask, regionId, diff --git a/sysmodules/rosalina/include/ifile.h b/sysmodules/rosalina/include/ifile.h index 515296b..a164660 100644 --- a/sysmodules/rosalina/include/ifile.h +++ b/sysmodules/rosalina/include/ifile.h @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2022 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,7 +26,7 @@ #pragma once -#include <3ds/types.h> +#include <3ds/services/fs.h> #define PATH_MAX 255 diff --git a/sysmodules/rosalina/include/menu.h b/sysmodules/rosalina/include/menu.h index 3068769..22d369e 100644 --- a/sysmodules/rosalina/include/menu.h +++ b/sysmodules/rosalina/include/menu.h @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2021 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 diff --git a/sysmodules/rosalina/include/menus/miscellaneous.h b/sysmodules/rosalina/include/menus/miscellaneous.h index 8efab34..4ecb914 100644 --- a/sysmodules/rosalina/include/menus/miscellaneous.h +++ b/sysmodules/rosalina/include/menus/miscellaneous.h @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2021 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 diff --git a/sysmodules/rosalina/include/ntp.h b/sysmodules/rosalina/include/ntp.h index 242e20f..cd2a0bb 100644 --- a/sysmodules/rosalina/include/ntp.h +++ b/sysmodules/rosalina/include/ntp.h @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2021 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 @@ -29,6 +29,6 @@ #include <3ds/types.h> #include -Result ntpGetTimeStamp(time_t *outTimestamp); -Result ntpSetTimeDate(time_t timestamp); +Result ntpGetTimeStamp(u64 *msSince1900, u64 *samplingTick); +Result ntpSetTimeDate(u64 msSince1900, u64 samplingTick); Result ntpNullifyUserTimeOffset(void); // not actually used for NTP diff --git a/sysmodules/rosalina/include/process_patches.h b/sysmodules/rosalina/include/process_patches.h index 2bd0e9c..e25512f 100644 --- a/sysmodules/rosalina/include/process_patches.h +++ b/sysmodules/rosalina/include/process_patches.h @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2021 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 diff --git a/sysmodules/rosalina/source/ifile.c b/sysmodules/rosalina/source/ifile.c index 515fa91..65164d3 100644 --- a/sysmodules/rosalina/source/ifile.c +++ b/sysmodules/rosalina/source/ifile.c @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2021 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 diff --git a/sysmodules/rosalina/source/main.c b/sysmodules/rosalina/source/main.c index 645093a..db0128b 100644 --- a/sysmodules/rosalina/source/main.c +++ b/sysmodules/rosalina/source/main.c @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2021 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 diff --git a/sysmodules/rosalina/source/menu.c b/sysmodules/rosalina/source/menu.c index 2e061ab..8e031da 100644 --- a/sysmodules/rosalina/source/menu.c +++ b/sysmodules/rosalina/source/menu.c @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2022 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 @@ -444,6 +444,8 @@ void menuShow(Menu *root) } else if(pressed & KEY_B) { + while (nbPreviousMenus == 0 && (scanHeldKeys() & KEY_B)); // wait a bit before exiting rosalina + Draw_Lock(); Draw_ClearFramebuffer(); Draw_FlushFramebuffer(); diff --git a/sysmodules/rosalina/source/menus.c b/sysmodules/rosalina/source/menus.c index b749eee..992f80e 100644 --- a/sysmodules/rosalina/source/menus.c +++ b/sysmodules/rosalina/source/menus.c @@ -143,7 +143,7 @@ void RosalinaMenu_ShowCredits(void) Draw_Lock(); Draw_DrawString(10, 10, COLOR_TITLE, "Rosalina -- Luma3DS credits"); - u32 posY = Draw_DrawString(10, 30, COLOR_WHITE, "Luma3DS (c) 2016-2020 AuroraWright, TuxSH") + SPACING_Y; + u32 posY = Draw_DrawString(10, 30, COLOR_WHITE, "Luma3DS (c) 2016-2022 AuroraWright, TuxSH") + SPACING_Y; posY = Draw_DrawString(10, posY + SPACING_Y, COLOR_WHITE, "3DSX loading code by fincs"); posY = Draw_DrawString(10, posY + SPACING_Y, COLOR_WHITE, "Networking code & basic GDB functionality by Stary"); diff --git a/sysmodules/rosalina/source/menus/cheats.c b/sysmodules/rosalina/source/menus/cheats.c index 0b085f8..e1515c4 100755 --- a/sysmodules/rosalina/source/menus/cheats.c +++ b/sysmodules/rosalina/source/menus/cheats.c @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS - * Copyright (C) 2016-2020 Aurora Wright, TuxSH + * Copyright (C) 2016-2021 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 @@ -322,18 +322,32 @@ static u32 Cheat_ApplyCheat(const Handle processHandle, CheatDescription* const // Simple: If the value at address 0XXXXXXX is less than the value YYYYYYYY. // Example: 323D6B28 10000000 { + bool newSkip; u32 value = 0; - if (!Cheat_Read32(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; - - cheat_state.ifStack <<= 1; - if (value < arg1) - { - cheat_state.ifStack |= skipExecution ? 1 : 0; - } - else + switch (cheat_state.conditionalMode) { - cheat_state.ifStack |= 1; + case 0x0: + if (!Cheat_Read32(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; + newSkip = !(value < arg1); + break; + case 0x1: + if (!Cheat_Read32(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; + newSkip = !(value < *activeData()); + break; + case 0x2: + newSkip = !(*activeData() < arg1); + break; + case 0x3: + newSkip = !(*activeStorage(cheat) < arg1); + break; + case 0x4: + newSkip = !(*activeData() < *activeStorage(cheat)); + break; + default: + return 0; } + cheat_state.ifStack <<= 1; + cheat_state.ifStack |= (newSkip || skipExecution) ? 1 : 0; cheat_state.ifCount++; } break; @@ -344,18 +358,32 @@ static u32 Cheat_ApplyCheat(const Handle processHandle, CheatDescription* const // Simple: If the value at address 0XXXXXXX is greater than the value YYYYYYYY. // Example: 423D6B28 10000000 { + bool newSkip; u32 value = 0; - if (!Cheat_Read32(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; - - cheat_state.ifStack <<= 1; - if (value > arg1) - { - cheat_state.ifStack |= skipExecution ? 1 : 0; - } - else + switch (cheat_state.conditionalMode) { - cheat_state.ifStack |= 1; + case 0x0: + if (!Cheat_Read32(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; + newSkip = !(value > arg1); + break; + case 0x1: + if (!Cheat_Read32(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; + newSkip = !(value > *activeData()); + break; + case 0x2: + newSkip = !(*activeData() > arg1); + break; + case 0x3: + newSkip = !(*activeStorage(cheat) > arg1); + break; + case 0x4: + newSkip = !(*activeData() > *activeStorage(cheat)); + break; + default: + return 0; } + cheat_state.ifStack <<= 1; + cheat_state.ifStack |= (newSkip || skipExecution) ? 1 : 0; cheat_state.ifCount++; } break; @@ -366,18 +394,32 @@ static u32 Cheat_ApplyCheat(const Handle processHandle, CheatDescription* const // Simple: If the value at address 0XXXXXXX is equal to the value YYYYYYYY. // Example: 523D6B28 10000000 { + bool newSkip; u32 value = 0; - if (!Cheat_Read32(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; - - cheat_state.ifStack <<= 1; - if (value == arg1) - { - cheat_state.ifStack |= skipExecution ? 1 : 0; - } - else + switch (cheat_state.conditionalMode) { - cheat_state.ifStack |= 1; + case 0x0: + if (!Cheat_Read32(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; + newSkip = !(value == arg1); + break; + case 0x1: + if (!Cheat_Read32(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; + newSkip = !(value == *activeData()); + break; + case 0x2: + newSkip = !(*activeData() == arg1); + break; + case 0x3: + newSkip = !(*activeStorage(cheat) == arg1); + break; + case 0x4: + newSkip = !(*activeData() == *activeStorage(cheat)); + break; + default: + return 0; } + cheat_state.ifStack <<= 1; + cheat_state.ifStack |= (newSkip || skipExecution) ? 1 : 0; cheat_state.ifCount++; } break; @@ -388,18 +430,32 @@ static u32 Cheat_ApplyCheat(const Handle processHandle, CheatDescription* const // Simple: If the value at address 0XXXXXXX is not equal to the value YYYYYYYY. // Example: 623D6B28 10000000 { + bool newSkip; u32 value = 0; - if (!Cheat_Read32(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; - - cheat_state.ifStack <<= 1; - if (value != arg1) - { - cheat_state.ifStack |= skipExecution ? 1 : 0; - } - else + switch (cheat_state.conditionalMode) { - cheat_state.ifStack |= 1; + case 0x0: + if (!Cheat_Read32(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; + newSkip = !(value != arg1); + break; + case 0x1: + if (!Cheat_Read32(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; + newSkip = !(value != *activeData()); + break; + case 0x2: + newSkip = !(*activeData() != arg1); + break; + case 0x3: + newSkip = !(*activeStorage(cheat) != arg1); + break; + case 0x4: + newSkip = !(*activeData() != *activeStorage(cheat)); + break; + default: + return 0; } + cheat_state.ifStack <<= 1; + cheat_state.ifStack |= (newSkip || skipExecution) ? 1 : 0; cheat_state.ifCount++; } break; @@ -413,13 +469,14 @@ static u32 Cheat_ApplyCheat(const Handle processHandle, CheatDescription* const bool newSkip; u16 mask = (u16) ((arg1 >> 16) & 0xFFFF); u16 value = 0; - if (!Cheat_Read16(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; switch (cheat_state.conditionalMode) { case 0x0: + if (!Cheat_Read16(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; newSkip = !((value & (~mask)) < (arg1 & 0xFFFF)); break; case 0x1: + if (!Cheat_Read16(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; newSkip = !((value & (~mask)) < (*activeData() & (~mask))); break; case 0x2: @@ -449,13 +506,14 @@ static u32 Cheat_ApplyCheat(const Handle processHandle, CheatDescription* const bool newSkip; u16 mask = (u16) ((arg1 >> 16) & 0xFFFF); u16 value = 0; - if (!Cheat_Read16(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; switch (cheat_state.conditionalMode) { case 0x0: + if (!Cheat_Read16(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; newSkip = !((value & (~mask)) > (arg1 & 0xFFFF)); break; case 0x1: + if (!Cheat_Read16(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; newSkip = !((value & (~mask)) > (*activeData() & (~mask))); break; case 0x2: @@ -486,13 +544,14 @@ static u32 Cheat_ApplyCheat(const Handle processHandle, CheatDescription* const bool newSkip; u16 mask = (u16) ((arg1 >> 16) & 0xFFFF); u16 value = 0; - if (!Cheat_Read16(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; switch (cheat_state.conditionalMode) { case 0x0: + if (!Cheat_Read16(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; newSkip = !((value & (~mask)) == (arg1 & 0xFFFF)); break; case 0x1: + if (!Cheat_Read16(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; newSkip = !((value & (~mask)) == (*activeData() & (~mask))); break; case 0x2: @@ -523,13 +582,14 @@ static u32 Cheat_ApplyCheat(const Handle processHandle, CheatDescription* const bool newSkip; u16 mask = (u16) ((arg1 >> 16) & 0xFFFF); u16 value = 0; - if (!Cheat_Read16(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; switch (cheat_state.conditionalMode) { case 0x0: + if (!Cheat_Read16(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; newSkip = !((value & (~mask)) != (arg1 & 0xFFFF)); break; case 0x1: + if (!Cheat_Read16(processHandle, arg0 & 0x0FFFFFFF, &value)) return 0; newSkip = !((value & (~mask)) != (*activeData() & (~mask))); break; case 0x2: @@ -1251,186 +1311,235 @@ static u32 Cheat_ApplyCheat(const Handle processHandle, CheatDescription* const { case 0x0: { - cheat_state.floatMode = arg1 & 0x1; + if(!skipExecution) + { + cheat_state.floatMode = arg1 & 0x1; + } } break; case 0x1: { - if (cheat_state.floatMode) + if (!skipExecution) { - u32 tmp; - if (!Cheat_Read32(processHandle, arg0 & 0x00FFFFFF, &tmp)) + if (cheat_state.floatMode) { - return 0; - } - float value; - memcpy(&value, &tmp, sizeof(float)); - value += arg1; - memcpy(&tmp, &value, sizeof(u32)); - if (!Cheat_Write32(processHandle, arg0 & 0x00FFFFFF, tmp)) - { - return 0; - } - } - else - { - u32 tmp; - if (!Cheat_Read32(processHandle, arg0 & 0x00FFFFFF, &tmp)) - { - return 0; + float flarg1; + memcpy(&flarg1, &arg1, sizeof(float)); + u32 tmp; + if (!Cheat_Read32(processHandle, arg0 & 0x00FFFFFF, &tmp)) + { + return 0; + } + float value; + memcpy(&value, &tmp, sizeof(float)); + value += flarg1; + memcpy(&tmp, &value, sizeof(u32)); + if (!Cheat_Write32(processHandle, arg0 & 0x00FFFFFF, tmp)) + { + return 0; + } } - tmp += arg1; - if (!Cheat_Write32(processHandle, arg0 & 0x00FFFFFF, tmp)) + else { - return 0; + u32 tmp; + if (!Cheat_Read32(processHandle, arg0 & 0x00FFFFFF, &tmp)) + { + return 0; + } + tmp += arg1; + if (!Cheat_Write32(processHandle, arg0 & 0x00FFFFFF, tmp)) + { + return 0; + } } } } break; case 0x2: { - if (cheat_state.floatMode) + if (!skipExecution) { - u32 tmp; - if (!Cheat_Read32(processHandle, arg0 & 0x00FFFFFF, &tmp)) + if (cheat_state.floatMode) { - return 0; + float flarg1; + memcpy(&flarg1, &arg1, sizeof(float)); + u32 tmp; + if (!Cheat_Read32(processHandle, arg0 & 0x00FFFFFF, &tmp)) + { + return 0; + } + float value; + memcpy(&value, &tmp, sizeof(float)); + value *= flarg1; + memcpy(&tmp, &value, sizeof(u32)); + if (!Cheat_Write32(processHandle, arg0 & 0x00FFFFFF, tmp)) + { + return 0; + } } - float value; - memcpy(&value, &tmp, sizeof(float)); - value *= arg1; - memcpy(&tmp, &value, sizeof(u32)); - if (!Cheat_Write32(processHandle, arg0 & 0x00FFFFFF, tmp)) + else { - return 0; + u32 tmp; + if (!Cheat_Read32(processHandle, arg0 & 0x00FFFFFF, &tmp)) + { + return 0; + } + tmp *= arg1; + if (!Cheat_Write32(processHandle, arg0 & 0x00FFFFFF, tmp)) + { + return 0; + } } } - else + } + break; + case 0x3: + { + if (!skipExecution) { - u32 tmp; - if (!Cheat_Read32(processHandle, arg0 & 0x00FFFFFF, &tmp)) + if (cheat_state.floatMode) { - return 0; + float flarg1; + memcpy(&flarg1, &arg1, sizeof(float)); + u32 tmp; + if (!Cheat_Read32(processHandle, arg0 & 0x00FFFFFF, &tmp)) + { + return 0; + } + float value; + memcpy(&value, &tmp, sizeof(float)); + value /= flarg1; + memcpy(&tmp, &value, sizeof(u32)); + if (!Cheat_Write32(processHandle, arg0 & 0x00FFFFFF, tmp)) + { + return 0; + } } - tmp *= arg1; - if (!Cheat_Write32(processHandle, arg0 & 0x00FFFFFF, tmp)) + else { - return 0; + u32 tmp; + if (!Cheat_Read32(processHandle, arg0 & 0x00FFFFFF, &tmp)) + { + return 0; + } + tmp /= arg1; + if (!Cheat_Write32(processHandle, arg0 & 0x00FFFFFF, tmp)) + { + return 0; + } } } } break; - case 0x3: + case 0x4: { - if (cheat_state.floatMode) + if (!skipExecution) { - u32 tmp; - if (!Cheat_Read32(processHandle, arg0 & 0x00FFFFFF, &tmp)) + if (cheat_state.data1Mode) { - return 0; + float flarg1; + memcpy(&flarg1, &arg1, sizeof(float)); + float value; + memcpy(&value, activeData(), sizeof(float)); + value *= flarg1; + memcpy(activeData(), &value, sizeof(float)); } - float value; - memcpy(&value, &tmp, sizeof(float)); - value /= arg1; - memcpy(&tmp, &value, sizeof(u32)); - if (!Cheat_Write32(processHandle, arg0 & 0x00FFFFFF, tmp)) + else { - return 0; + *activeData() *= arg1; } } - else + } + break; + case 0x5: + { + if (!skipExecution) { - u32 tmp; - if (!Cheat_Read32(processHandle, arg0 & 0x00FFFFFF, &tmp)) + if (cheat_state.data1Mode) { - return 0; + float flarg1; + memcpy(&flarg1, &arg1, sizeof(float)); + float value; + memcpy(&value, activeData(), sizeof(float)); + value /= flarg1; + memcpy(activeData(), &value, sizeof(float)); } - tmp /= arg1; - if (!Cheat_Write32(processHandle, arg0 & 0x00FFFFFF, tmp)) + else { - return 0; + *activeData() /= arg1; } } } break; - case 0x4: + case 0x6: { - if (cheat_state.data1Mode) + if (!skipExecution) { - float value; - memcpy(&value, activeData(), sizeof(float)); - value *= arg1; - memcpy(activeData(), &value, sizeof(float)); - } - else - { - *activeData() *= arg1; + *activeData() &= arg1; } } break; - case 0x5: + case 0x7: { - if (cheat_state.data1Mode) + if (!skipExecution) { - float value; - memcpy(&value, activeData(), sizeof(float)); - value /= arg1; - memcpy(activeData(), &value, sizeof(float)); + *activeData() |= arg1; } - else - { - *activeData() /= arg1; - } - } - break; - case 0x6: - { - *activeData() &= arg1; - } - break; - case 0x7: - { - *activeData() |= arg1; } break; case 0x8: { - *activeData() ^= arg1; + if (!skipExecution) + { + *activeData() ^= arg1; + } } break; case 0x9: { - *activeData() = ~*activeData(); + if (!skipExecution) + { + *activeData() = ~*activeData(); + } } break; case 0xA: { - *activeData() <<= arg1; + if (!skipExecution) + { + *activeData() <<= arg1; + } } break; case 0xB: { - *activeData() >>= arg1; + if (!skipExecution) + { + *activeData() >>= arg1; + } } break; case 0xC: { - u8 origActiveOffset = cheat_state.activeOffset; - for (size_t i = 0; i < arg1; i++) + if (!skipExecution) { - u8 data; - cheat_state.activeOffset = 1; - if (!Cheat_Read8(processHandle, 0, &data)) - { - return 0; - } - cheat_state.activeOffset = 0; - if (!Cheat_Write8(processHandle, 0, data)) + u8 origActiveOffset = cheat_state.activeOffset; + for (size_t i = 0; i < arg1; i++) { - return 0; + u8 data; + cheat_state.activeOffset = 1; + if (!Cheat_Read8(processHandle, 0, &data)) + { + return 0; + } + cheat_state.activeOffset = 0; + if (!Cheat_Write8(processHandle, 0, data)) + { + return 0; + } } + cheat_state.activeOffset = origActiveOffset; } - cheat_state.activeOffset = origActiveOffset; } break; // Search for pattern @@ -1483,9 +1592,12 @@ static u32 Cheat_ApplyCheat(const Handle processHandle, CheatDescription* const break; case 0xF: { - u32 range = arg1 - (arg0 & 0xFFFFFF); - u32 number = Cheat_GetRandomNumber() % range; - *activeData() = (arg0 & 0xFFFFFF) + number; + if (!skipExecution) + { + u32 range = arg1 - (arg0 & 0xFFFFFF); + u32 number = Cheat_GetRandomNumber() % range; + *activeData() = (arg0 & 0xFFFFFF) + number; + } } break; default: diff --git a/sysmodules/rosalina/source/menus/miscellaneous.c b/sysmodules/rosalina/source/menus/miscellaneous.c index 1d5b2f1..b166fdb 100644 --- a/sysmodules/rosalina/source/menus/miscellaneous.c +++ b/sysmodules/rosalina/source/menus/miscellaneous.c @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2021 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 @@ -397,7 +397,7 @@ void MiscellaneousMenu_UpdateTimeDateNtp(void) bool isSocURegistered; - time_t t; + u64 msSince1900, samplingTick; res = srvIsServiceRegistered(&isSocURegistered, "soc:U"); cantStart = R_FAILED(res) || !isSocURegistered; @@ -436,12 +436,11 @@ void MiscellaneousMenu_UpdateTimeDateNtp(void) res = 0; if(!cantStart) { - res = ntpGetTimeStamp(&t); + res = ntpGetTimeStamp(&msSince1900, &samplingTick); if(R_SUCCEEDED(res)) { - t += 3600 * utcOffset; - t += 60 * utcOffsetMinute; - res = ntpSetTimeDate(t); + msSince1900 += 1000 * (3600 * utcOffset + 60 * utcOffsetMinute); + res = ntpSetTimeDate(msSince1900, samplingTick); } } diff --git a/sysmodules/rosalina/source/menus/process_list.c b/sysmodules/rosalina/source/menus/process_list.c index afd7eda..d0de864 100644 --- a/sysmodules/rosalina/source/menus/process_list.c +++ b/sysmodules/rosalina/source/menus/process_list.c @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2022 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 @@ -50,6 +50,8 @@ typedef struct ProcessInfo static ProcessInfo infos[0x40] = {0}, infosPrev[0x40] = {0}; extern GDBServer gdbServer; +bool ascii = false; + static inline int ProcessListMenu_FormatInfoLine(char *out, const ProcessInfo *info) { const char *checkbox; @@ -382,6 +384,11 @@ static void ProcessListMenu_MemoryViewer(const ProcessInfo *info) menus[MENU_MODE_SEARCH].buf = searchPattern; menus[MENU_MODE_SEARCH].max = 1; // ------------------------------------------ + char u8ToChar(u8 val) { + if(val < 32 || val > 126) + return '-'; + return val; + } void drawMenu(void) { @@ -412,16 +419,22 @@ static void ProcessListMenu_MemoryViewer(const ProcessInfo *info) // ------------------------------------------ // Location + const u32 infoY = instructionsY + SPACING_Y; + viewerY += SPACING_Y; if(codeAvailable && heapAvailable) - { - const u32 infoY = instructionsY + SPACING_Y; - viewerY += SPACING_Y; + { Draw_DrawString(10, infoY, COLOR_WHITE, "Press L or R to switch between heap and code."); if((u32)menus[MENU_MODE_NORMAL].buf == heapDestAddress) Draw_DrawString(10 + SPACING_X * 31, infoY, COLOR_GREEN, "heap"); if((u32)menus[MENU_MODE_NORMAL].buf == codeDestAddress) Draw_DrawString(10 + SPACING_X * 40, infoY, COLOR_GREEN, "code"); } + else + { + Draw_DrawString(10, infoY, COLOR_WHITE, "SELECT to dump memory, START to toggle ASCII view."); + if(ascii) + Draw_DrawString(10 + SPACING_X * 39, infoY, COLOR_GREEN, "ASCII"); + } // ------------------------------------------ for(u32 row = menus[menuMode].starti; row < (menus[menuMode].starti + ROWS_PER_SCREEN); row++) @@ -438,10 +451,23 @@ static void ProcessListMenu_MemoryViewer(const ProcessInfo *info) if(address < menus[menuMode].max) { - Draw_DrawFormattedString(x, y, - address == menus[menuMode].selected ? (editing ? COLOR_RED : COLOR_GREEN) : COLOR_WHITE, - "%.2x", - menus[menuMode].buf[address]); + u32 color; + if(address == menus[menuMode].selected) + { + if(editing) + color = COLOR_RED; + else + color = COLOR_GREEN; + } + else + color = COLOR_WHITE; + + u8 val = menus[menuMode].buf[address]; + + if(ascii) + Draw_DrawFormattedString(x, y, color, "%c ", u8ToChar(val)); + else + Draw_DrawFormattedString(x, y, color, "%.2x", val); } else Draw_DrawString(x, y, COLOR_WHITE, " "); @@ -514,6 +540,8 @@ static void ProcessListMenu_MemoryViewer(const ProcessInfo *info) ProcessListMenu_DumpMemory(info->name, menus[MENU_MODE_NORMAL].buf, menus[MENU_MODE_NORMAL].max); clearMenu(); } + else if(pressed & KEY_START) + ascii = !ascii; if(editing) { diff --git a/sysmodules/rosalina/source/menus/sysconfig.c b/sysmodules/rosalina/source/menus/sysconfig.c index 46f1373..e6c8714 100644 --- a/sysmodules/rosalina/source/menus/sysconfig.c +++ b/sysmodules/rosalina/source/menus/sysconfig.c @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2021 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 diff --git a/sysmodules/rosalina/source/ntp.c b/sysmodules/rosalina/source/ntp.c index 548ebb2..6e136d0 100644 --- a/sysmodules/rosalina/source/ntp.c +++ b/sysmodules/rosalina/source/ntp.c @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2021 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,7 +33,9 @@ #define NUM2BCD(n) ((n<99) ? (((n/10)*0x10)|(n%10)) : 0x99) -#define NTP_TIMESTAMP_DELTA 2208988800ull +//#define NTP_TIMESTAMP_DELTA 2208988800ull + +#define MSEC_DELTA_1900_2000 3155673600000ull #define MAKE_IPV4(a,b,c,d) ((a) << 24 | (b) << 16 | (c) << 8 | (d)) @@ -73,10 +75,13 @@ typedef struct NtpPacket } NtpPacket; // Total: 384 bits or 48 bytes. -Result ntpGetTimeStamp(time_t *outTimestamp) +Result ntpGetTimeStamp(u64 *msSince1900, u64 *samplingTick) { Result res = 0; struct linger linger; + *msSince1900 = 0; + *samplingTick = 0; + res = miniSocInit(); if(R_FAILED(res)) return res; @@ -108,12 +113,14 @@ Result ntpGetTimeStamp(time_t *outTimestamp) if(socConnect(sock, (struct sockaddr *)&servAddr, sizeof(struct sockaddr_in)) < 0) goto cleanup; + u64 roundTripTicks = svcGetSystemTick(); if(socSend(sock, &packet, sizeof(NtpPacket), 0) < 0) goto cleanup; if(socRecv(sock, &packet, sizeof(NtpPacket), 0) < 0) goto cleanup; - + roundTripTicks = svcGetSystemTick() - roundTripTicks; + u64 dt = 1000 * 1000 * roundTripTicks / (2 * SYSCLOCK_ARM11); // avg = round trip time / 2 res = 0; // These two fields contain the time-stamp seconds as the packet left the NTP server. @@ -121,13 +128,11 @@ Result ntpGetTimeStamp(time_t *outTimestamp) // ntohl() converts the bit/byte order from the network's to host's "endianness". packet.txTm_s = ntohl(packet.txTm_s); // Time-stamp seconds. - packet.txTm_f = ntohl(packet.txTm_f); // Time-stamp fraction of a second. - - // Extract the 32 bits that represent the time-stamp seconds (since NTP epoch) from when the packet left the server. - // Subtract 70 years worth of seconds from the seconds since 1900. - // This leaves the seconds since the UNIX epoch of 1970. - // (1900)------------------(1970)**************************************(Time Packet Left the Server) - *outTimestamp = (time_t)(packet.txTm_s - NTP_TIMESTAMP_DELTA); + packet.txTm_f = ntohl(packet.txTm_f); // Time-stamp fraction of a second. txTm is 32.32 fixed point. + u64 txTmUsec = (1000 * 1000 * (u64)packet.txTm_f) >> 32; // convert txTm to usec (truncate; end result is in ms anyway) + txTmUsec += 1000 * 1000 * (u64)packet.txTm_s; + *msSince1900 = (txTmUsec + dt + 500u) / 1000u; + *samplingTick = svcGetSystemTick(); cleanup: linger.l_onoff = 1; @@ -140,54 +145,70 @@ Result ntpGetTimeStamp(time_t *outTimestamp) return res; } -Result ntpSetTimeDate(time_t timestamp) +static Result ntpSetTimeDateImpl(u64 msSince1900, u64 samplingTick, bool syncRtc) { Result res = ptmSysmInit(); if (R_FAILED(res)) return res; - - // Update the user time offset - // 946684800 is the timestamp of 01/01/2000 00:00 relative to the Unix Epoch - s64 msY2k = (timestamp - 946684800) * 1000; - res = PTMSYSM_SetUserTime(msY2k); - - ptmSysmExit(); - return res; -} - -// Not actually used for NTP, but... -Result ntpNullifyUserTimeOffset(void) -{ - Result res = ptmSysmInit(); - if (R_FAILED(res)) return res; - + res = ptmSetsInit(); + if (R_FAILED(res)) + { + ptmSysmExit(); + return res; + } res = cfguInit(); if (R_FAILED(res)) { + ptmSetsExit(); ptmSysmExit(); return res; } - // First, set the user time offset to 0 (user time = rtc time + user time offset) - s64 userTimeOff = 0; - res = CFG_SetConfigInfoBlk4(8, 0x30001, &userTimeOff); - if (R_FAILED(res)) goto cleanup; - - // Get the user time from shared data... there might be up to 0.5s drift from {mcu+offset} but we don't care here - s64 userTime = osGetTime() - 3155673600000LL; // 1900 -> 2000 time base + u64 dt = 1000 * (svcGetSystemTick() - samplingTick) / SYSCLOCK_ARM11; + s64 msY2k = msSince1900 + dt - MSEC_DELTA_1900_2000; - // Apply user time to RTC - res = PTMSYSM_SetRtcTime(userTime); - if (R_FAILED(res)) goto cleanup; - - // Invalidate system (absolute, server) time, which gets fixed on "friends" login anyway -- don't care if we fail here. - // It has become invalid because we changed the RTC time - PTMSYSM_InvalidateSystemTime(); + if (syncRtc) + { + u64 samplingTick2 = svcGetSystemTick(); + + s64 timeOff = 0; + res = CFG_SetConfigInfoBlk4(8, 0x30001, &timeOff); + if (R_SUCCEEDED(res)) res = CFG_SetConfigInfoBlk4(8, 0x30002, &timeOff); + + // Save the config changes + if (R_SUCCEEDED(res)) res = CFG_UpdateConfigSavegame(); + + // Wait till next second + msY2k += 1000 * (svcGetSystemTick() - samplingTick2) / SYSCLOCK_ARM11; + if (msY2k % 1000u != 0) + { + u64 dt2 = 1000u - msY2k % 1000u; + svcSleepThread(dt2); + msY2k += dt2; + } + if (R_SUCCEEDED(res)) res = PTMSYSM_SetRtcTime(msY2k); + } + else + { + if (R_SUCCEEDED(res)) res = PTMSYSM_SetUserTime(msY2k); + if (R_SUCCEEDED(res)) res = PTMSETS_SetSystemTime(msY2k); + } - // Save the config changes - res = CFG_UpdateConfigSavegame(); - cleanup: - ptmSysmExit(); cfguExit(); + ptmSetsExit(); + ptmSysmExit(); return res; } + +Result ntpSetTimeDate(u64 msSince1900, u64 samplingTick) +{ + return ntpSetTimeDateImpl(msSince1900, samplingTick, false); +} + +// Not actually used for NTP, but... +Result ntpNullifyUserTimeOffset(void) +{ + u64 msSince1900 = osGetTime(); + u64 samplingTick = svcGetSystemTick(); + return ntpSetTimeDateImpl(msSince1900, samplingTick, true); +} diff --git a/sysmodules/rosalina/source/process_patches.c b/sysmodules/rosalina/source/process_patches.c index 6b1ed8d..e72ecf6 100644 --- a/sysmodules/rosalina/source/process_patches.c +++ b/sysmodules/rosalina/source/process_patches.c @@ -1,6 +1,6 @@ /* * This file is part of Luma3DS -* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* Copyright (C) 2016-2021 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