diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp index c4a7a549..9257e3e3 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp @@ -23,6 +23,7 @@ #define ENABLED 1 #define DISABLED 0 #define CPU_MAX_MAX_VOLT 1375000 + namespace ams::ldr::oc { //volatile EristaMtcTable EristaMtcTablePlaceholder = { .rev = ERISTA_MTC_MAGIC, }; @@ -199,8 +200,8 @@ volatile CustomizeTable C = { .marikoCpuDvfsTableSLT = { // { 204000, { 732856, -17335, 113 }, { } }, // { 306000, { 760024, -18195, 113 }, { } }, - { 408000, { 789258, -19055, 113 }, { } }, - { 510000, { 789258, -19915, 113 }, { } }, + // { 408000, { 789258, -19055, 113 }, { } }, + // { 510000, { 789258, -19915, 113 }, { } }, { 612000, { 789258, -19055, 113 }, { } }, { 714000, { 820558, -19915, 113 }, { } }, { 816000, { 853926, -20775, 113 }, { } }, @@ -223,8 +224,8 @@ volatile CustomizeTable C = { { 2601000, { 1702903, -36675, 113 }, { CPU_MAX_MAX_VOLT } }, { 2703000, { 1748360, -37535, 113 }, { CPU_MAX_MAX_VOLT } }, { 2805000, { 1793817, -38395, 113 }, { CPU_MAX_MAX_VOLT } }, - // { 2907000, { 1839274, -39255, 113 }, { CPU_MAX_MAX_VOLT } }, - // { 3009000, { 1884731, -40115, 113 }, { CPU_MAX_MAX_VOLT } }, + { 2907000, { 1839274, -39255, 113 }, { CPU_MAX_MAX_VOLT } }, + { 3009000, { 1884731, -40115, 113 }, { CPU_MAX_MAX_VOLT } }, }, /* - Erista GPU DVFS Table: diff --git a/Source/Configurator/dist/hocconfig.exe b/Source/Configurator/dist/hocconfig.exe index 262289a4..64bf345f 100644 Binary files a/Source/Configurator/dist/hocconfig.exe and b/Source/Configurator/dist/hocconfig.exe differ diff --git a/Source/Configurator/loader_edit.kip b/Source/Configurator/loader_edit.kip new file mode 100644 index 00000000..d2022b50 Binary files /dev/null and b/Source/Configurator/loader_edit.kip differ diff --git a/Source/Configurator/run.bat b/Source/Configurator/run.bat index 4c4e7796..b3642477 100644 --- a/Source/Configurator/run.bat +++ b/Source/Configurator/run.bat @@ -1 +1 @@ -python3 src/main.py \ No newline at end of file +python src/main.py \ No newline at end of file diff --git a/Source/Configurator/src/main.py b/Source/Configurator/src/main.py index 63479a54..a05c3d70 100644 --- a/Source/Configurator/src/main.py +++ b/Source/Configurator/src/main.py @@ -44,10 +44,10 @@ import misc true = True false = False -# if getattr(sys, 'frozen', False): -assets_path = os.path.join(sys._MEIPASS, 'assets/') -# else: - # assets_path = os.path.join(os.path.dirname(__file__), '../assets/') +if getattr(sys, 'frozen', False): + assets_path = os.path.join(sys._MEIPASS, 'assets/') +else: + assets_path = os.path.join(os.path.dirname(__file__), '../assets/') cooler_image_path = assets_path + "coolerhd.png" # coolerHD Emoji from OC server cooler_image = Image.open(cooler_image_path).convert("RGBA") diff --git a/Source/Configurator/src/settings.py b/Source/Configurator/src/settings.py index 9044af21..3f48b8b9 100644 --- a/Source/Configurator/src/settings.py +++ b/Source/Configurator/src/settings.py @@ -60,6 +60,7 @@ freqs_mhz_cpu = [ variables = [ ("custRev", "u32"), ("mtcConf", "u32"), + ("hpMode", "u32"), ("commonCpuBoostClock", "u32"), ("commonEmcMemVolt", "u32"), ("eristaCpuMaxVolt", "u32"), diff --git a/Source/sys-clk/common/include/sysclk/board.h b/Source/sys-clk/common/include/sysclk/board.h index 04dbbe2c..9fa6c625 100644 --- a/Source/sys-clk/common/include/sysclk/board.h +++ b/Source/sys-clk/common/include/sysclk/board.h @@ -74,10 +74,11 @@ typedef enum typedef enum { - SysClkRamLoad_All = 0, - SysClkRamLoad_Cpu, - SysClkRamLoad_EnumMax -} SysClkRamLoad; + SysClkPartLoad_EMC = 0, + SysClkPartLoad_EMCCpu, + HocClkPartLoad_GPU, + SysClkPartLoad_EnumMax +} SysClkPartLoad; typedef enum { diff --git a/Source/sys-clk/common/include/sysclk/clock_manager.h b/Source/sys-clk/common/include/sysclk/clock_manager.h index d3ba7b51..72bd830a 100644 --- a/Source/sys-clk/common/include/sysclk/clock_manager.h +++ b/Source/sys-clk/common/include/sysclk/clock_manager.h @@ -40,7 +40,7 @@ typedef struct uint32_t overrideFreqs[SysClkModule_EnumMax]; uint32_t temps[SysClkThermalSensor_EnumMax]; int32_t power[SysClkPowerSensor_EnumMax]; - uint32_t ramLoad[SysClkRamLoad_EnumMax]; + uint32_t partLoad[SysClkPartLoad_EnumMax]; // uint32_t perfConfId; } SysClkContext; diff --git a/Source/sys-clk/common/include/sysclk/ipc.h b/Source/sys-clk/common/include/sysclk/ipc.h index 51474458..260f2b87 100644 --- a/Source/sys-clk/common/include/sysclk/ipc.h +++ b/Source/sys-clk/common/include/sysclk/ipc.h @@ -32,7 +32,7 @@ #include "clock_manager.h" #define SYSCLK_IPC_API_VERSION 4 -#define SYSCLK_IPC_SERVICE_NAME "sys:clk" +#define SYSCLK_IPC_SERVICE_NAME "horizon:oc" enum SysClkIpcCmd { diff --git a/Source/sys-clk/overlay/Makefile b/Source/sys-clk/overlay/Makefile index 901a7b5c..d5bab04f 100644 --- a/Source/sys-clk/overlay/Makefile +++ b/Source/sys-clk/overlay/Makefile @@ -37,7 +37,7 @@ include ${TOPDIR}/lib/libultrahand/ultrahand.mk # version control constants #--------------------------------------------------------------------------------- #TARGET_VERSION := $(shell git describe --dirty --always --tags) -APP_VERSION := 1.0.1 +APP_VERSION := 0.0.4 TARGET_VERSION := $(APP_VERSION) #--------------------------------------------------------------------------------- diff --git a/Source/sys-clk/overlay/src/main.cpp b/Source/sys-clk/overlay/src/main.cpp index 60f39028..f2085057 100644 --- a/Source/sys-clk/overlay/src/main.cpp +++ b/Source/sys-clk/overlay/src/main.cpp @@ -57,7 +57,7 @@ class AppOverlay : public tsl::Overlay if(!sysclkIpcRunning()) { return initially( - "sys-clk is not running.\n\n" + "Horizon OC is not running.\n\n" "\n" "Please make sure it is correctly\n\n" "installed and enabled.", @@ -68,7 +68,7 @@ class AppOverlay : public tsl::Overlay if(R_FAILED(sysclkIpcInitialize()) || R_FAILED(sysclkIpcGetAPIVersion(&apiVersion))) { return initially( - "Could not connect to sys-clk.\n\n" + "Could not connect to Horizon OC.\n\n" "\n" "Please make sure it is correctly\n\n" "installed and enabled.", @@ -80,7 +80,7 @@ class AppOverlay : public tsl::Overlay { return initially( "Overlay not compatible with\n\n" - "the running sys-clk version.\n\n" + "the running Horizon OC version.\n\n" "\n" "Please make sure everything is\n\n" "installed and up to date.", diff --git a/Source/sys-clk/overlay/src/ui/gui/base_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/base_gui.cpp index 545f402a..8513d2e2 100644 --- a/Source/sys-clk/overlay/src/ui/gui/base_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/base_gui.cpp @@ -7,14 +7,14 @@ * * This program is distributed in the hope 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. + * 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 . * */ - + /* -------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): * , , @@ -24,37 +24,124 @@ * -------------------------------------------------------------------------- */ - #include "base_gui.h" #include "../elements/base_frame.h" #include "logo_rgba_bin.h" +#include +#include - +// ------------------------------------------------------------- +// Layout constants +// ------------------------------------------------------------- #define LOGO_X 20 -#define LOGO_Y 45 -#define LOGO_LABEL_FONT_SIZE 35 +#define LOGO_Y 50 +#define LOGO_LABEL_FONT_SIZE 45 #define VERSION_X (LOGO_X + 250) -#define VERSION_Y LOGO_Y-40 +#define VERSION_Y (LOGO_Y - 40) #define VERSION_FONT_SIZE 15 +// ------------------------------------------------------------- +// Version string getter +// ------------------------------------------------------------- + std::string getVersionString() { - char buf[0x100] = ""; // 256 bytes — safe for any expected version string + char buf[0x100] = ""; Result rc = sysclkIpcGetVersionString(buf, sizeof(buf)); if (R_FAILED(rc) || buf[0] == '\0') { - return "unknown"; + return "HorizonOC-Misc"; } return std::string(buf); } +// ------------------------------------------------------------- +// Animated Ultra Text +// ------------------------------------------------------------- + +// Your animated wave colors (example placeholders) +static constexpr tsl::Color dynamicLogoRGB1 = tsl::Color(40, 255, 80, 255); +static constexpr tsl::Color dynamicLogoRGB2 = tsl::Color(120, 255, 160, 255); + +// Your project name rendered letter-by-letter +static constexpr const char* PROJECT_NAME = "Horizon OC Gaea"; + +// Fully corrected function signature +static s32 drawDynamicUltraText( + tsl::gfx::Renderer* renderer, + s32 startX, + s32 y, + u32 fontSize, + const tsl::Color& staticColor, + bool useNotificationMethod = false) +{ + static constexpr double cycleDuration = 1.6; + + const std::string name = "Horizon OC Gaea"; + s32 currentX = startX; + + const u64 currentTime_ns = armTicksToNs(armGetSystemTick()); + const double timeNow = static_cast(currentTime_ns) / 1e9; + const double timeBase = fmod(timeNow, cycleDuration); + + // Controls wave spacing + const double waveScale = 2.0 * M_PI / cycleDuration; + + // Every character has its own index offset + for (size_t i = 0; i < name.size(); i++) + { + char letter = name[i]; + if (letter == '\0') break; + + // phase shift per character → THIS CREATES THE WAVE + double phase = waveScale * (timeBase + i * 0.12); + + double raw = cos(phase); + double n = (raw + 1.0) * 0.5; + + // Smoothstep ×2 (ultra smooth) + double s1 = n * n * (3.0 - 2.0 * n); + double s2 = s1 * s1 * (3.0 - 2.0 * s1); + + double blend = std::clamp(s2, 0.0, 1.0); + + tsl::Color color = { + static_cast(staticColor.r + (dynamicLogoRGB2.r - staticColor.r) * blend), + static_cast(staticColor.g + (dynamicLogoRGB2.g - staticColor.g) * blend), + static_cast(staticColor.b + (dynamicLogoRGB2.b - staticColor.b) * blend), + 255 + }; + + std::string ls(1, letter); + + if (useNotificationMethod) + currentX += renderer->drawNotificationString(ls, false, currentX, y, fontSize, color).first; + else + currentX += renderer->drawString(ls, false, currentX, y, fontSize, color).first; + } + + return currentX; +} + + +// ------------------------------------------------------------- +// Rendering functions +// ------------------------------------------------------------- + void BaseGui::preDraw(tsl::gfx::Renderer* renderer) { -// renderer->drawBitmap(LOGO_X, LOGO_Y, LOGO_WIDTH, LOGO_HEIGHT, logo_rgba_bin); - renderer->drawString("Horizon OC overlay", false, LOGO_X, LOGO_Y, LOGO_LABEL_FONT_SIZE, renderer->a(TEXT_COLOR)); -// renderer->drawString(TARGET_VERSION, false, VERSION_X, VERSION_Y, VERSION_FONT_SIZE, tsl::bannerVersionTextColor); + static constexpr tsl::Color STATIC_GREEN = tsl::Color(80, 255, 120, 255); + + drawDynamicUltraText( + renderer, + LOGO_X, + LOGO_Y, + LOGO_LABEL_FONT_SIZE, + STATIC_GREEN, + false + ); } tsl::elm::Element* BaseGui::createUI() diff --git a/Source/sys-clk/overlay/src/ui/gui/freq_choice_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/freq_choice_gui.cpp index 0adfc561..79b6418b 100644 --- a/Source/sys-clk/overlay/src/ui/gui/freq_choice_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/freq_choice_gui.cpp @@ -25,154 +25,184 @@ */ - #include "freq_choice_gui.h" +#include "freq_choice_gui.h" + +#include "../format.h" +#include "fatal_gui.h" + +FreqChoiceGui::FreqChoiceGui(std::uint32_t selectedHz, + std::uint32_t* hzList, + std::uint32_t hzCount, + SysClkModule module, + FreqChoiceListener listener, + bool checkMax, + std::map labels) +{ + this->selectedHz = selectedHz; + this->hzList = hzList; + this->hzCount = hzCount; + this->module = module; + this->listener = listener; + this->checkMax = checkMax; + this->labels = labels; // NEW + this->configList = new SysClkConfigValueList {}; +} - #include "../format.h" - #include "fatal_gui.h" - - FreqChoiceGui::FreqChoiceGui(std::uint32_t selectedHz, std::uint32_t *hzList, std::uint32_t hzCount, SysClkModule module, FreqChoiceListener listener, bool checkMax) - { - this->selectedHz = selectedHz; - this->hzList = hzList; - this->hzCount = hzCount; - this->module = module; - this->listener = listener; - this->checkMax = checkMax; - this->configList = new SysClkConfigValueList {}; - } FreqChoiceGui::~FreqChoiceGui() { delete this->configList; } - tsl::elm::ListItem* FreqChoiceGui::createFreqListItem(std::uint32_t hz, bool selected, int safety) - { - std::string text = formatListFreqHz(hz); - if (selected) text += " \uE14B"; - - tsl::elm::ListItem* listItem = new tsl::elm::ListItem(text, "", false); - - switch (safety) - { - case 0: - listItem->setTextColor(tsl::Color(255, 255, 255, 255)); - listItem->setValueColor(tsl::Color(255, 255, 255, 255)); - break; - case 1: - listItem->setTextColor(tsl::Color(255, 165, 0, 255)); - listItem->setValueColor(tsl::Color(255, 165, 0, 255)); - break; - case 2: - listItem->setTextColor(tsl::Color(255, 0, 0, 255)); - listItem->setValueColor(tsl::Color(255, 0, 0, 255)); - break; - } - - listItem->setClickListener([this, hz](u64 keys) - { - if ((keys & HidNpadButton_A) == HidNpadButton_A && this->listener) { - if (this->listener(hz)) { - tsl::goBack(); - } - return true; - } - return false; - }); - - return listItem; - } - - void FreqChoiceGui::listUI() - { - sysclkIpcGetConfigValues(this->configList); - // Add CategoryHeader based on module - std::string moduleName = sysclkFormatModule(this->module, false); - this->listElement->addItem(new tsl::elm::CategoryHeader(moduleName)); - - this->listElement->addItem(this->createFreqListItem(0, this->selectedHz == 0, false)); - std::uint32_t hz; - for (std::uint32_t i = 0; i < this->hzCount; i++) - { - hz = this->hzList[i]; - uint32_t mhz = hz / 1000000; - // Skip 204 MHz exactly - if(checkMax && IsMariko()) { - if (this->configList->values[HocClkConfigValue_MarikoMaxCpuClock] < mhz && moduleName == "cpu") { - continue; - } - - if (this->configList->values[HocClkConfigValue_MarikoMaxGpuClock] < mhz && moduleName == "gpu") { - continue; - } - if (this->configList->values[HocClkConfigValue_MarikoMaxMemClock] < mhz && moduleName == "mem") { - continue; - } - } else if (checkMax && IsErista()) { - if (this->configList->values[HocClkConfigValue_EristaMaxCpuClock] < mhz && moduleName == "cpu") { - continue; - } - - if (this->configList->values[HocClkConfigValue_EristaMaxGpuClock] < mhz && moduleName == "gpu") { - continue; - } - if (this->configList->values[HocClkConfigValue_EristaMaxMemClock] < mhz && moduleName == "mem") { - continue; - } - } - if (moduleName == "mem" && mhz <= 600) - { - continue; - } - uint32_t unsafe_cpu; - uint32_t unsafe_gpu; - uint32_t danger_cpu; - uint32_t danger_gpu; - if (IsMariko()) - { - unsafe_cpu = 1964; - unsafe_gpu = 1076; - danger_cpu = 2398; - danger_gpu = 1306; - } - else - { - unsafe_cpu = 1786; - unsafe_gpu = 922; - danger_cpu = 2092; - danger_gpu = 999; - } +tsl::elm::ListItem* FreqChoiceGui::createFreqListItem(std::uint32_t hz, bool selected, int safety) +{ + std::string text = formatListFreqHz(hz); + if (selected) + text += " \uE14B"; - if (moduleName == "cpu") { - if (mhz >= danger_cpu) { - this->listElement->addItem(this->createFreqListItem(hz, mhz == this->selectedHz / 1000000, 2)); - continue; - } - if (mhz >= unsafe_cpu) { - this->listElement->addItem(this->createFreqListItem(hz, mhz == this->selectedHz / 1000000, 1)); - continue; - } - if (mhz <= unsafe_cpu) { - this->listElement->addItem(this->createFreqListItem(hz, mhz == this->selectedHz / 1000000, 0)); + // NEW: Right-side label + std::string rightText = ""; + auto it = labels.find(hz); + if (it != labels.end()) + rightText = it->second; + + tsl::elm::ListItem* listItem = + new tsl::elm::ListItem(text, rightText, false); + + switch (safety) + { + case 0: + listItem->setTextColor(tsl::Color(255, 255, 255, 255)); + listItem->setValueColor(tsl::Color(255, 255, 255, 255)); + break; + case 1: + listItem->setTextColor(tsl::Color(255, 165, 0, 255)); + listItem->setValueColor(tsl::Color(255, 165, 0, 255)); + break; + case 2: + listItem->setTextColor(tsl::Color(255, 0, 0, 255)); + listItem->setValueColor(tsl::Color(255, 0, 0, 255)); + break; + } + + // Make annotation grey + if (!rightText.empty()) + listItem->setValueColor(tsl::Color(180, 180, 180, 255)); + + listItem->setClickListener([this, hz](u64 keys) + { + if ((keys & HidNpadButton_A) == HidNpadButton_A && this->listener) { + if (this->listener(hz)) { + tsl::goBack(); + } + return true; + } + return false; + }); + + return listItem; +} + +void FreqChoiceGui::listUI() +{ + sysclkIpcGetConfigValues(this->configList); + + // Header based on CPU/GPU/MEM module + std::string moduleName = sysclkFormatModule(this->module, false); + this->listElement->addItem(new tsl::elm::CategoryHeader(moduleName)); + + // Default option + this->listElement->addItem( + this->createFreqListItem(0, this->selectedHz == 0, 0)); + + for (std::uint32_t i = 0; i < this->hzCount; i++) + { + std::uint32_t hz = this->hzList[i]; + uint32_t mhz = hz / 1000000; + + if (checkMax && IsMariko()) { + if (moduleName == "cpu" && + this->configList->values[HocClkConfigValue_MarikoMaxCpuClock] < mhz) continue; - } - } else if (moduleName == "gpu") { - if (mhz >= danger_gpu) { - this->listElement->addItem(this->createFreqListItem(hz, mhz == this->selectedHz / 1000000, 2)); - continue; - } - if (mhz >= unsafe_gpu) { - this->listElement->addItem(this->createFreqListItem(hz, mhz == this->selectedHz / 1000000, 1)); - continue; - } - if (mhz <= unsafe_gpu) { - this->listElement->addItem(this->createFreqListItem(hz, mhz == this->selectedHz / 1000000, 0)); + + if (moduleName == "gpu" && + this->configList->values[HocClkConfigValue_MarikoMaxGpuClock] < mhz) continue; - } - } else if (moduleName == "mem") { - this->listElement->addItem(this->createFreqListItem(hz, mhz == this->selectedHz / 1000000, 0)); + + if (moduleName == "mem" && + this->configList->values[HocClkConfigValue_MarikoMaxMemClock] < mhz) + continue; + + } else if (checkMax && IsErista()) { + if (moduleName == "cpu" && + this->configList->values[HocClkConfigValue_EristaMaxCpuClock] < mhz) + continue; + + if (moduleName == "gpu" && + this->configList->values[HocClkConfigValue_EristaMaxGpuClock] < mhz) + continue; + + if (moduleName == "mem" && + this->configList->values[HocClkConfigValue_EristaMaxMemClock] < mhz) + continue; + } + + if (moduleName == "mem" && mhz <= 600) continue; - } - - } - this->listElement->jumpToItem("", ""); - } \ No newline at end of file + + uint32_t unsafe_cpu; + uint32_t unsafe_gpu; + uint32_t danger_cpu; + uint32_t danger_gpu; + + if (IsMariko()) + { + unsafe_cpu = 1964; + unsafe_gpu = 1076; + danger_cpu = 2398; + danger_gpu = 1306; + } + else + { + unsafe_cpu = 1786; + unsafe_gpu = 922; + danger_cpu = 2092; + danger_gpu = 999; + } + + int safety = 0; + + if (moduleName == "cpu") { + + if (mhz >= danger_cpu) + safety = 2; + else if (mhz >= unsafe_cpu) + safety = 1; + else + safety = 0; + + } else if (moduleName == "gpu") { + + if (mhz >= danger_gpu) + safety = 2; + else if (mhz >= unsafe_gpu) + safety = 1; + else + safety = 0; + + } else if (moduleName == "mem") { + + safety = 0; + + } + + this->listElement->addItem( + this->createFreqListItem( + hz, + (mhz == this->selectedHz / 1000000), + safety + ) + ); + } + + this->listElement->jumpToItem("", ""); +} \ No newline at end of file diff --git a/Source/sys-clk/overlay/src/ui/gui/freq_choice_gui.h b/Source/sys-clk/overlay/src/ui/gui/freq_choice_gui.h index cc13e2e9..cf18095c 100644 --- a/Source/sys-clk/overlay/src/ui/gui/freq_choice_gui.h +++ b/Source/sys-clk/overlay/src/ui/gui/freq_choice_gui.h @@ -29,6 +29,7 @@ #include #include +#include #include "base_menu_gui.h" using FreqChoiceListener = std::function; @@ -42,19 +43,24 @@ protected: std::uint32_t selectedHz; std::uint32_t* hzList; std::uint32_t hzCount; - SysClkModule module; // added module + SysClkModule module; FreqChoiceListener listener; - bool checkMax; // new member + bool checkMax; + + // NEW: Optional annotation labels + std::map labels; + tsl::elm::ListItem* createFreqListItem(std::uint32_t hz, bool selected, int safety); public: - // Updated constructor with checkMaxValue FreqChoiceGui(std::uint32_t selectedHz, std::uint32_t* hzList, std::uint32_t hzCount, SysClkModule module, FreqChoiceListener listener, - bool checkMax = true); + bool checkMax = true, + std::map labels = {}); // NEW ARG + ~FreqChoiceGui(); void listUI() override; diff --git a/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp index 7ec20065..3aacd96d 100644 --- a/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp @@ -59,7 +59,8 @@ void MiscGui::addConfigButton(SysClkConfigValue configVal, const char* altName, const ValueRange& range, const std::string& categoryName, - const ValueThresholds* thresholds) + const ValueThresholds* thresholds, + const std::map& labels) { const char* configName = altName ? altName : sysclkFormatConfigValue(configVal, true); @@ -82,7 +83,7 @@ void MiscGui::addConfigButton(SysClkConfigValue configVal, ValueThresholds thresholdsCopy = (thresholds ? *thresholds : ValueThresholds{}); listItem->setClickListener( - [this, configVal, range, categoryName, thresholdsCopy](u64 keys) + [this, configVal, range, categoryName, thresholdsCopy, labels](u64 keys) { if ((keys & HidNpadButton_A) == 0) return false; @@ -106,7 +107,8 @@ void MiscGui::addConfigButton(SysClkConfigValue configVal, return true; }, thresholdsCopy, - true + true, + labels // <── NEW ); } else { @@ -123,7 +125,10 @@ void MiscGui::addConfigButton(SysClkConfigValue configVal, } this->lastContextUpdate = armGetSystemTick(); return true; - } + }, + ValueThresholds(), + false, + labels // <── NEW ); } @@ -135,7 +140,11 @@ void MiscGui::addConfigButton(SysClkConfigValue configVal, this->configRanges[configVal] = range; } -void MiscGui::addFreqButton(SysClkConfigValue configVal, const char* altName, SysClkModule module) { +void MiscGui::addFreqButton(SysClkConfigValue configVal, + const char* altName, + SysClkModule module, + const std::map& labels) +{ const char* configName = altName ? altName : sysclkFormatConfigValue(configVal, true); tsl::elm::ListItem* listItem = new tsl::elm::ListItem(configName); @@ -145,45 +154,48 @@ void MiscGui::addFreqButton(SysClkConfigValue configVal, const char* altName, Sy snprintf(valueText, sizeof(valueText), "%lu MHz", currentMHz); listItem->setValue(valueText); - listItem->setClickListener([this, configVal, module](u64 keys) { - if ((keys & HidNpadButton_A) == 0) - return false; + listItem->setClickListener( + [this, configVal, module, labels](u64 keys) + { + if ((keys & HidNpadButton_A) == 0) + return false; - std::uint32_t hzList[SYSCLK_FREQ_LIST_MAX]; - std::uint32_t hzCount; + std::uint32_t hzList[SYSCLK_FREQ_LIST_MAX]; + std::uint32_t hzCount; - Result rc = sysclkIpcGetFreqList(module, hzList, SYSCLK_FREQ_LIST_MAX, &hzCount); - if (R_FAILED(rc)) { - FatalGui::openWithResultCode("sysclkIpcGetFreqList", rc); - return false; - } + Result rc = sysclkIpcGetFreqList(module, hzList, SYSCLK_FREQ_LIST_MAX, &hzCount); + if (R_FAILED(rc)) { + FatalGui::openWithResultCode("sysclkIpcGetFreqList", rc); + return false; + } - std::uint32_t currentHz = this->configList->values[configVal] * 1'000'000; + std::uint32_t currentHz = this->configList->values[configVal] * 1'000'000; - tsl::changeTo( - currentHz, - hzList, - hzCount, - module, - [this, configVal](std::uint32_t hz) { + tsl::changeTo( + currentHz, + hzList, + hzCount, + module, + [this, configVal](std::uint32_t hz) + { + uint64_t mhz = hz / 1'000'000; + this->configList->values[configVal] = mhz; - uint64_t mhz = hz / 1'000'000; - this->configList->values[configVal] = mhz; + Result rc = sysclkIpcSetConfigValues(this->configList); + if (R_FAILED(rc)) { + FatalGui::openWithResultCode("sysclkIpcSetConfigValues", rc); + return false; + } - Result rc = sysclkIpcSetConfigValues(this->configList); - if (R_FAILED(rc)) { - FatalGui::openWithResultCode("sysclkIpcSetConfigValues", rc); - return false; - } + this->lastContextUpdate = armGetSystemTick(); + return true; + }, + false, + labels + ); - this->lastContextUpdate = armGetSystemTick(); - return true; - }, - false - ); - - return true; - }); + return true; + }); this->listElement->addItem(listItem); this->configButtons[configVal] = listItem; @@ -204,18 +216,24 @@ void MiscGui::listUI() addConfigToggle(HocClkConfigValue_UncappedClocks, nullptr); addConfigToggle(HocClkConfigValue_OverwriteBoostMode, nullptr); - this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental")); + // this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental")); addConfigToggle(HocClkConfigValue_ThermalThrottle, nullptr); addConfigToggle(HocClkConfigValue_HandheldTDP, nullptr); addConfigToggle(HocClkConfigValue_EnforceBoardLimit, nullptr); - + std::map labels_pwr_r = { + {8600, "Official Rating"} + }; + std::map labels_pwr_l = { + {6400, "Official Rating"} + }; ValueThresholds tdpThresholds(8600, 9500); addConfigButton( HocClkConfigValue_HandheldTDPLimit, "TDP Threshold", ValueRange(5000, 10000, 200, "mW", 1), "Power", - &tdpThresholds + &tdpThresholds, + labels_pwr_r ); ValueThresholds tdpThresholdsLite(6400, 7500); @@ -224,7 +242,8 @@ void MiscGui::listUI() "Lite TDP Threshold", ValueRange(4000, 8000, 200, "mW", 1), "Power", - &tdpThresholdsLite + &tdpThresholdsLite, + labels_pwr_l ); ValueThresholds throttleThresholds(70, 80); @@ -235,45 +254,130 @@ void MiscGui::listUI() "Temp", &throttleThresholds ); - this->listElement->addItem(new tsl::elm::CategoryHeader("Max Clocks")); + std::map cpu_freq_label_m = { + {612000000, "Sleep Mode"}, + {1020000000, "Stock"}, + {1224000000, "Dev OC"}, + {1785000000, "Boost Mode"}, + {1963000000, "Safe Max"}, + {2397000000, "Unsafe Max"}, + {2805000000, "Aboslute Max"}, + }; + + std::map cpu_freq_label_e = { + {612000000, "Sleep Mode"}, + {1020000000, "Stock"}, + {1224000000, "Dev OC"}, + {1785000000, "Boost Mode & Safe Max"}, + {2091000000, "Unsafe Max"}, + {2295000000, "Aboslute Max"}, + }; + + std::map gpu_freq_label_e = { + {76800000, "Boost Mode"}, + {307200000, "Handheld"}, + {384000000, "Handheld"}, + {460800000, "Handheld Safe Max"}, + {768000000, "Docked"}, + {844000000, "Safe Max"}, + {998400000, "Unsafe Max"}, + {1075200000, "Aboslute Max"}, + }; + + std::map gpu_freq_label_m = { + {76800000, "Boost Mode"}, + {307200000, "Handheld"}, + {384000000, "Handheld"}, + {460800000, "Handheld"}, + {614400000, "Handheld Safe Max"}, + {768000000, "Docked"}, + {1152200000, "Safe Max"}, + {1305600000, "Unsafe Max"}, + {1536000000, "Aboslute Max"}, + }; + + std::map emc_freq_label_e = { + {133120000, "Handheld"}, + {160000000, "Docked & Safe Max"}, + {213100000, "JEDEC Max"}, + {236000000, "Absolute Max"}, + }; + + + std::map emc_freq_label_m = { + {133120000, "Handheld"}, + {160000000, "Docked"}, + {186600000, "Safe Max (3733MT/s)"}, + {213300000, "Safe Max (4266MT/s)"}, + {320000000, "Absolute Max"}, + }; + + + this->listElement->addItem(new tsl::elm::CategoryHeader("Clocks")); if(IsMariko()) { - addFreqButton(HocClkConfigValue_MarikoMaxCpuClock, nullptr, SysClkModule_CPU); - addFreqButton(HocClkConfigValue_MarikoMaxGpuClock, nullptr, SysClkModule_GPU); - addFreqButton(HocClkConfigValue_MarikoMaxMemClock, nullptr, SysClkModule_MEM); + addFreqButton(HocClkConfigValue_MarikoMaxCpuClock, nullptr, SysClkModule_CPU, cpu_freq_label_m); + addFreqButton(HocClkConfigValue_MarikoMaxGpuClock, nullptr, SysClkModule_GPU, gpu_freq_label_m); + addFreqButton(HocClkConfigValue_MarikoMaxMemClock, nullptr, SysClkModule_MEM, emc_freq_label_m); } else { - addFreqButton(HocClkConfigValue_EristaMaxCpuClock, nullptr, SysClkModule_CPU); - addFreqButton(HocClkConfigValue_EristaMaxGpuClock, nullptr, SysClkModule_GPU); - addFreqButton(HocClkConfigValue_EristaMaxMemClock, nullptr, SysClkModule_MEM); + addFreqButton(HocClkConfigValue_EristaMaxCpuClock, nullptr, SysClkModule_CPU, cpu_freq_label_e); + addFreqButton(HocClkConfigValue_EristaMaxGpuClock, nullptr, SysClkModule_GPU, gpu_freq_label_e); + addFreqButton(HocClkConfigValue_EristaMaxMemClock, nullptr, SysClkModule_MEM, emc_freq_label_e); } + this->listElement->addItem(new tsl::elm::CategoryHeader("EMC")); + addConfigToggle(HocClkConfigValue_EMCDVFS, nullptr); - ValueThresholds emcUvThresholds(1212500, 1250000); - addConfigButton( - HocClkConfigValue_EMCVdd2VoltageUV, - "EMC VDD2 Voltage", - ValueRange(1100000, 1237500, 12500, "mV", 1000, 1), - "EMC VDD2 Voltage", - &emcUvThresholds - ); + std::map emc_voltage_label_m = { + {1100000, "Default"}, + {1175000, "Rating"}, + {1212500, "Safe Max"}, + }; - // if(IsMariko()) { - // addConfigButton( - // HocClkConfigValue_EMCVdd2VoltageUVStockMariko, - // "EMC Stock VDD2 Voltage", - // ValueRange(912500, 1175000, 12500, "mV", 1000, 1), - // "EMC Stock VDD2 Voltage", - // &emcUvThresholds - // ); - // } else { + std::map emc_voltage_label_e = { + {1125000, "Default"}, + {1175000, "Rating"}, + {1237500, "Safe Max"}, + }; + + + if(IsMariko()) { + ValueThresholds emcUvThresholds(1212500, 1250000); + addConfigButton( + HocClkConfigValue_EMCVdd2VoltageUV, + "EMC VDD2 Voltage", + ValueRange(1100000, 1237500, 12500, "mV", 1000, 1), + "EMC VDD2 Voltage", + &emcUvThresholds, + emc_voltage_label_m + ); + addConfigButton( + HocClkConfigValue_EMCVdd2VoltageUVStockMariko, + "EMC Stock VDD2 Voltage", + ValueRange(912500, 1175000, 12500, "mV", 1000, 1), + "EMC Stock VDD2 Voltage", + &emcUvThresholds, + emc_voltage_label_m + ); + } else { + ValueThresholds emcUvThresholds(1237500, 1300000); + addConfigButton( + HocClkConfigValue_EMCVdd2VoltageUV, + "EMC VDD2 Voltage", + ValueRange(1100000, 1237500, 12500, "mV", 1000, 1), + "EMC VDD2 Voltage", + &emcUvThresholds, + emc_voltage_label_e + ); addConfigButton( HocClkConfigValue_EMCVdd2VoltageUVStockErista, "EMC Stock VDD2 Voltage", ValueRange(1000000, 1175000, 12500, "mV", 1000, 1), "EMC Stock VDD2 Voltage", - &emcUvThresholds + &emcUvThresholds, + emc_voltage_label_e ); - // } + } tsl::elm::ListItem* applyBtn = new tsl::elm::ListItem("Apply EMC Regs"); applyBtn->setClickListener([](u64 keys) { diff --git a/Source/sys-clk/overlay/src/ui/gui/misc_gui.h b/Source/sys-clk/overlay/src/ui/gui/misc_gui.h index 0192b888..d60fc617 100644 --- a/Source/sys-clk/overlay/src/ui/gui/misc_gui.h +++ b/Source/sys-clk/overlay/src/ui/gui/misc_gui.h @@ -27,8 +27,12 @@ protected: const char* altName, const ValueRange& range, const std::string& categoryName, - const ValueThresholds* thresholds = nullptr); - void addFreqButton(SysClkConfigValue configVal, const char* altName, SysClkModule module); + const ValueThresholds* thresholds, + const std::map& labels = {}); + void addFreqButton(SysClkConfigValue configVal, + const char* altName, + SysClkModule module, + const std::map& labels = {}); void updateConfigToggles(); tsl::elm::ToggleListItem* enabledToggle; diff --git a/Source/sys-clk/overlay/src/ui/gui/value_choice_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/value_choice_gui.cpp index 7856d150..07074d51 100644 --- a/Source/sys-clk/overlay/src/ui/gui/value_choice_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/value_choice_gui.cpp @@ -9,13 +9,15 @@ ValueChoiceGui::ValueChoiceGui(std::uint32_t selectedValue, const std::string& categoryName, ValueChoiceListener listener, const ValueThresholds& thresholds, - bool enableThresholds) + bool enableThresholds, + std::map labels) : selectedValue(selectedValue), range(range), categoryName(categoryName), listener(listener), thresholds(thresholds), - enableThresholds(enableThresholds) + enableThresholds(enableThresholds), + labels(labels) { } @@ -31,12 +33,10 @@ std::string ValueChoiceGui::formatValue(std::uint32_t value) return VALUE_DEFAULT_TEXT; } - // Convert to floating point for division double displayValue = static_cast(value) / static_cast(range.divisor); - // Set precision and formatting oss << std::fixed << std::setprecision(range.decimalPlaces) << displayValue; - + if (!range.suffix.empty()) { oss << " " << range.suffix; } @@ -45,12 +45,6 @@ std::string ValueChoiceGui::formatValue(std::uint32_t value) int ValueChoiceGui::getSafetyLevel(std::uint32_t value) { - // if (!enableThresholds) { - // return 0; - // } - - std::uint32_t scaledValue = value / range.divisor; - if (value > thresholds.danger) { return 2; } @@ -67,7 +61,13 @@ tsl::elm::ListItem* ValueChoiceGui::createValueListItem(std::uint32_t value, boo text += " \uE14B"; } - tsl::elm::ListItem* listItem = new tsl::elm::ListItem(text, "", false); + std::string rightText = ""; + auto it = labels.find(value); + if (it != labels.end()) { + rightText = it->second; + } + + tsl::elm::ListItem* listItem = new tsl::elm::ListItem(text, rightText, false); switch (safety) { @@ -85,6 +85,9 @@ tsl::elm::ListItem* ValueChoiceGui::createValueListItem(std::uint32_t value, boo break; } + if (!rightText.empty()) + listItem->setValueColor(tsl::Color(180, 180, 180, 255)); + listItem->setClickListener([this, value](u64 keys) { if ((keys & HidNpadButton_A) == HidNpadButton_A && this->listener) { @@ -115,4 +118,4 @@ void ValueChoiceGui::listUI() } this->listElement->jumpToItem("", "\uE14B"); -} \ No newline at end of file +} diff --git a/Source/sys-clk/overlay/src/ui/gui/value_choice_gui.h b/Source/sys-clk/overlay/src/ui/gui/value_choice_gui.h index 2c9b122e..278c8144 100644 --- a/Source/sys-clk/overlay/src/ui/gui/value_choice_gui.h +++ b/Source/sys-clk/overlay/src/ui/gui/value_choice_gui.h @@ -25,62 +25,69 @@ */ - #pragma once +#pragma once - #include - #include - #include - #include "base_menu_gui.h" - - using ValueChoiceListener = std::function; - - #define VALUE_DEFAULT_TEXT "Default" - - struct ValueRange { +#include +#include +#include +#include +#include "base_menu_gui.h" + +using ValueChoiceListener = std::function; + +#define VALUE_DEFAULT_TEXT "Default" + +struct ValueRange { std::uint32_t min; std::uint32_t max; std::uint32_t step; std::string suffix; - std::uint32_t divisor; // Divide input values by this for display - int decimalPlaces; // Number of decimal places to display (0-6) - - ValueRange() : min(0), max(0), step(1), suffix(""), divisor(1), decimalPlaces(0) {} - - ValueRange(std::uint32_t min, std::uint32_t max, std::uint32_t step, + std::uint32_t divisor; + int decimalPlaces; + + ValueRange() + : min(0), max(0), step(1), suffix(""), divisor(1), decimalPlaces(0) {} + + ValueRange(std::uint32_t min, std::uint32_t max, std::uint32_t step, const std::string& suffix = "", std::uint32_t divisor = 1, int decimalPlaces = 0) - : min(min), max(max), step(step), suffix(suffix), divisor(divisor), decimalPlaces(decimalPlaces) {} + : min(min), max(max), step(step), suffix(suffix), + divisor(divisor), decimalPlaces(decimalPlaces) {} }; - struct ValueThresholds { - std::uint32_t warning; // Values >= this show orange - std::uint32_t danger; // Values >= this show red - - ValueThresholds(std::uint32_t warning = 0, std::uint32_t danger = 0) - : warning(warning), danger(danger) {} - }; - - class ValueChoiceGui : public BaseMenuGui - { - protected: - std::uint32_t selectedValue; - ValueRange range; - std::string categoryName; - ValueChoiceListener listener; - ValueThresholds thresholds; - bool enableThresholds; - - tsl::elm::ListItem* createValueListItem(std::uint32_t value, bool selected, int safety); - std::string formatValue(std::uint32_t value); - int getSafetyLevel(std::uint32_t value); - - public: - ValueChoiceGui(std::uint32_t selectedValue, - const ValueRange& range, - const std::string& categoryName, - ValueChoiceListener listener, - const ValueThresholds& thresholds = ValueThresholds(), - bool enableThresholds = false); - ~ValueChoiceGui(); - - void listUI() override; - }; \ No newline at end of file +struct ValueThresholds { + std::uint32_t warning; + std::uint32_t danger; + + ValueThresholds(std::uint32_t warning = 0, std::uint32_t danger = 0) + : warning(warning), danger(danger) {} +}; + +class ValueChoiceGui : public BaseMenuGui +{ +protected: + std::uint32_t selectedValue; + ValueRange range; + std::string categoryName; + ValueChoiceListener listener; + ValueThresholds thresholds; + bool enableThresholds; + + // NEW — map of value → right-side text (like version numbers) + std::map labels; + + tsl::elm::ListItem* createValueListItem(std::uint32_t value, bool selected, int safety); + std::string formatValue(std::uint32_t value); + int getSafetyLevel(std::uint32_t value); + +public: + ValueChoiceGui(std::uint32_t selectedValue, + const ValueRange& range, + const std::string& categoryName, + ValueChoiceListener listener, + const ValueThresholds& thresholds = ValueThresholds(), + bool enableThresholds = false, + std::map labels = {}); + ~ValueChoiceGui(); + + void listUI() override; +}; diff --git a/Source/sys-clk/sysmodule/Makefile b/Source/sys-clk/sysmodule/Makefile index c5bd564a..ae8bfa66 100644 --- a/Source/sys-clk/sysmodule/Makefile +++ b/Source/sys-clk/sysmodule/Makefile @@ -39,7 +39,7 @@ DEFINES := -DDISABLE_IPC -DTARGET="\"$(TARGET)\"" -DTARGET_VERSION="\"$(TARGET_V ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE -CFLAGS := -g -Wall -O2 -ffunction-sections \ +CFLAGS := -g -Wall -Os -ffunction-sections \ $(ARCH) $(DEFINES) CFLAGS += $(INCLUDE) -D__SWITCH__ diff --git a/Source/sys-clk/sysmodule/perms.json b/Source/sys-clk/sysmodule/perms.json index a57e28e4..67ca8fe3 100644 --- a/Source/sys-clk/sysmodule/perms.json +++ b/Source/sys-clk/sysmodule/perms.json @@ -1,5 +1,5 @@ { - "name": "sys:clk", + "name": "horizon:oc", "title_id": "0x00FF0000636C6BFF", "title_id_range_min": "0x00FF0000636C6BFF", "title_id_range_max": "0x00FF0000636C6BFF", @@ -18,7 +18,7 @@ "*" ], "service_host": [ - "sys:clk" + "horizon:oc" ], "kernel_capabilities": [ { diff --git a/Source/sys-clk/sysmodule/src/board.cpp b/Source/sys-clk/sysmodule/src/board.cpp index be51247d..700af72f 100644 --- a/Source/sys-clk/sysmodule/src/board.cpp +++ b/Source/sys-clk/sysmodule/src/board.cpp @@ -31,6 +31,10 @@ #define HOSSVC_HAS_CLKRST (hosversionAtLeast(8,0,0)) #define HOSSVC_HAS_TC (hosversionAtLeast(5,0,0)) +#define NVGPU_GPU_IOCTL_PMU_GET_GPU_LOAD 0x80044715 + +Result nvCheck = 1; +u32 fd = 0; static SysClkSocType g_socType = SysClkSocType_Erista; @@ -117,6 +121,11 @@ void Board::Initialize() rc = tmp451Initialize(); ASSERT_RESULT_OK(rc, "tmp451Initialize"); + // u32 fd = 0; + + // if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu"); + + FetchHardwareInfos(); } @@ -141,6 +150,7 @@ void Board::Exit() max17050Exit(); tmp451Exit(); + nvExit(); } SysClkProfile Board::GetProfile() @@ -463,16 +473,23 @@ std::int32_t Board::GetPowerMw(SysClkPowerSensor sensor) return 0; } -std::uint32_t Board::GetRamLoad(SysClkRamLoad loadSource) +std::uint32_t Board::GetPartLoad(SysClkPartLoad loadSource) { + // u32 temp, GPU_Load_u = 0; + switch(loadSource) { - case SysClkRamLoad_All: + case SysClkPartLoad_EMC: return t210EmcLoadAll(); - case SysClkRamLoad_Cpu: + case SysClkPartLoad_EMCCpu: return t210EmcLoadCpu(); + // case HocClkPartLoad_GPU: + // #define gpu_samples_average 10 + // // nvIoctl(fd, NVGPU_GPU_IOCTL_PMU_GET_GPU_LOAD, &temp); + // GPU_Load_u = ((GPU_Load_u * (gpu_samples_average-1)) + temp) / gpu_samples_average; + // return GPU_Load_u / 10; default: - ASSERT_ENUM_VALID(SysClkRamLoad, loadSource); + ASSERT_ENUM_VALID(SysClkPartLoad, loadSource); } return 0; @@ -502,4 +519,4 @@ void Board::FetchHardwareInfos() default: g_socType = SysClkSocType_Erista; } -} \ No newline at end of file +} diff --git a/Source/sys-clk/sysmodule/src/board.h b/Source/sys-clk/sysmodule/src/board.h index 21b9c227..ae654d2f 100644 --- a/Source/sys-clk/sysmodule/src/board.h +++ b/Source/sys-clk/sysmodule/src/board.h @@ -51,7 +51,7 @@ class Board static void GetFreqList(SysClkModule module, std::uint32_t* outList, std::uint32_t maxCount, std::uint32_t* outCount); static std::uint32_t GetTemperatureMilli(SysClkThermalSensor sensor); static std::int32_t GetPowerMw(SysClkPowerSensor sensor); - static std::uint32_t GetRamLoad(SysClkRamLoad load); + static std::uint32_t GetPartLoad(SysClkPartLoad load); static SysClkSocType GetSocType(); protected: diff --git a/Source/sys-clk/sysmodule/src/clock_manager.cpp b/Source/sys-clk/sysmodule/src/clock_manager.cpp index b712f489..bb338d7d 100644 --- a/Source/sys-clk/sysmodule/src/clock_manager.cpp +++ b/Source/sys-clk/sysmodule/src/clock_manager.cpp @@ -24,6 +24,7 @@ * -------------------------------------------------------------------------- */ +#include "notification.h" #include "clock_manager.h" #include @@ -35,6 +36,10 @@ #define HOSPPC_HAS_BOOST (hosversionAtLeast(7,0,0)) +bool HAS_TDP_BEEN_FIRED = false; +bool HAS_EBL_BEEN_FIRED = false; +bool HAS_TT_BEEN_FIRED = false; + ClockManager *ClockManager::instance = NULL; ClockManager *ClockManager::GetInstance() @@ -228,6 +233,7 @@ void ClockManager::RefreshFreqTableRow(SysClkModule module) void ClockManager::Tick() { + std::uint32_t mode = 0; AppletOperationMode opMode = appletGetOperationMode(); Result rc = apmExtGetCurrentPerformanceConfiguration(&mode); @@ -257,25 +263,47 @@ void ClockManager::Tick() if(this->config->GetConfigValue(HocClkConfigValue_HandheldTDP) && opMode == AppletOperationMode_Handheld) { if(Board::GetSocType() == SysClkSocType_MarikoLite) { if(Board::GetPowerMw(SysClkPowerSensor_Avg) < -(int)this->config->GetConfigValue(HocClkConfigValue_LiteTDPLimit)) { + if(!HAS_TDP_BEEN_FIRED) + writeNotification("Horizon OC\nTDP has been activated"); + HAS_TDP_BEEN_FIRED = true; ResetToStockClocks(); return; + } else { + HAS_TDP_BEEN_FIRED = false; } } else { if(Board::GetPowerMw(SysClkPowerSensor_Avg) < -(int)this->config->GetConfigValue(HocClkConfigValue_HandheldTDPLimit)) { + if(!HAS_TDP_BEEN_FIRED) + writeNotification("Horizon OC\nTDP has been activated"); + HAS_TDP_BEEN_FIRED = true; ResetToStockClocks(); return; + } else { + HAS_TDP_BEEN_FIRED = false; } } } else if(opMode == AppletOperationMode_Console && this->config->GetConfigValue(HocClkConfigValue_EnforceBoardLimit)) { if(Board::GetPowerMw(SysClkPowerSensor_Avg) < 0) { + if(!HAS_EBL_BEEN_FIRED) + writeNotification("Horizon OC\nBoard Limit has been exeeded"); + HAS_EBL_BEEN_FIRED = true; ResetToStockClocks(); return; + } else { + HAS_EBL_BEEN_FIRED = false; } } - if(((tmp451TempSoc() / 1000) > (int)this->config->GetConfigValue(HocClkConfigValue_ThermalThrottleThreshold)) && this->config->GetConfigValue(HocClkConfigValue_ThermalThrottle)) { - ResetToStockClocks(); - return; + if(this->config->GetConfigValue(HocClkConfigValue_ThermalThrottle)) { + if(tmp451TempSoc() / 1000 > (int)this->config->GetConfigValue(HocClkConfigValue_ThermalThrottleThreshold)) { + if(!HAS_TT_BEEN_FIRED) + writeNotification("Horizon OC\nThermal Throttle has started"); + HAS_TT_BEEN_FIRED = true; + ResetToStockClocks(); + return; + } else { + HAS_TT_BEEN_FIRED = false; + } } std::scoped_lock lock{this->contextMutex}; @@ -454,9 +482,9 @@ bool ClockManager::RefreshContext() } // ram load do not and should not force a refresh, hasChanged untouched - for (unsigned int loadSource = 0; loadSource < SysClkRamLoad_EnumMax; loadSource++) + for (unsigned int loadSource = 0; loadSource < SysClkPartLoad_EnumMax; loadSource++) { - this->context->ramLoad[loadSource] = Board::GetRamLoad((SysClkRamLoad)loadSource); + this->context->partLoad[loadSource] = Board::GetPartLoad((SysClkPartLoad)loadSource); } if (this->ConfigIntervalTimeout(SysClkConfigValue_CsvWriteIntervalMs, ns, &this->lastCsvWriteNs)) @@ -481,31 +509,29 @@ void ClockManager::set_sd1_voltage(uint32_t voltage_uv) const u8 volt_addr = 0x17; // MAX77620_REG_SD1 const u8 volt_mask = 0x7F; // MAX77620_SD1_VOLT_MASK - // Validate input voltage if (voltage_uv < uv_min || voltage_uv > uv_max) return; - // Calculate voltage multiplier u32 mult = (voltage_uv + uv_step - 1 - uv_min) / uv_step; mult = mult & volt_mask; - // Open I2C session to MAX77620 PMIC I2cSession session; Result res = i2cOpenSession(&session, I2cDevice_Max77620Pmic); if (R_FAILED(res)) { return; } - // Read current register value u8 current_val = 0; res = i2csessionSendAuto(&session, &volt_addr, 1, I2cTransactionOption_Start); if (R_FAILED(res)) { + writeNotification("I2C write failed. This may be a hardware issue"); i2csessionClose(&session); return; } res = i2csessionReceiveAuto(&session, ¤t_val, 1, I2cTransactionOption_Stop); if (R_FAILED(res)) { + writeNotification("I2C write failed. This may be a hardware issue"); i2csessionClose(&session); return; } diff --git a/Source/sys-clk/sysmodule/src/main.cpp b/Source/sys-clk/sysmodule/src/main.cpp index 44d89fc7..d9e71919 100644 --- a/Source/sys-clk/sysmodule/src/main.cpp +++ b/Source/sys-clk/sysmodule/src/main.cpp @@ -40,7 +40,7 @@ #include "fancontrol.h" #include "emc_patcher.h" -#define INNER_HEAP_SIZE 0xFFFFF +#define INNER_HEAP_SIZE 0x50000 extern "C" { @@ -92,7 +92,7 @@ extern "C" hosversionSet(MAKEHOSVERSION(fw.major, fw.minor, fw.micro)); setsysExit(); } - + } void __appExit(void) @@ -124,7 +124,7 @@ int main(int argc, char** argv) ClockManager* clockMgr = new ClockManager(); IpcService* ipcSrv = new IpcService(clockMgr); - + FileUtils::LogLine("Starting Horizon OC Sysmodule"); clockMgr->SetRunning(true); diff --git a/Source/sys-clk/sysmodule/src/notification.h b/Source/sys-clk/sysmodule/src/notification.h new file mode 100644 index 00000000..4000df1a --- /dev/null +++ b/Source/sys-clk/sysmodule/src/notification.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include + +static void writeNotification(const std::string& message) { + const char* flagPath = "sdmc:/config/ultrahand/flags/NOTIFICATIONS.flag"; + + // Check if flag file exists + FILE* flagFile = fopen(flagPath, "r"); + if (!flagFile) { + // Flag file does not exist, do nothing + return; + } + fclose(flagFile); + + // Generate filename with timestamp + std::string filename = "Horzon OC -" + std::to_string(std::time(nullptr)) + ".notify"; + std::string fullPath = "sdmc:/config/ultrahand/notifications/" + filename; + + // Write JSON manually + FILE* file = fopen(fullPath.c_str(), "w"); + if (file) { + fprintf(file, "{\n"); + fprintf(file, " \"text\": \"%s\",\n", message.c_str()); + fprintf(file, " \"fontSize\": 28\n"); + fprintf(file, "}\n"); + fclose(file); + } + } diff --git a/Source/sys-clk/sysmodule/toolbox.json b/Source/sys-clk/sysmodule/toolbox.json index 83ac964c..4874c6c7 100644 --- a/Source/sys-clk/sysmodule/toolbox.json +++ b/Source/sys-clk/sysmodule/toolbox.json @@ -1,5 +1,5 @@ { - "name" : "hoc-clk", + "name" : "Horizon OC", "tid" : "00FF0000636C6BFF", "requires_reboot": false } \ No newline at end of file