From e72f9d8e6019038aa32321fc0fd90e8352d0bac6 Mon Sep 17 00:00:00 2001 From: souldbminersmwc Date: Sun, 9 Nov 2025 16:07:13 -0500 Subject: [PATCH] hoc-sys: change stuff --- .../overlay/src/ui/gui/app_profile_gui.cpp | 4 + .../overlay/src/ui/gui/app_profile_gui.h | 4 + .../sys-clk/overlay/src/ui/gui/base_gui.cpp | 22 +- Source/sys-clk/overlay/src/ui/gui/base_gui.h | 4 + .../overlay/src/ui/gui/base_menu_gui.cpp | 616 +++++++++--------- .../overlay/src/ui/gui/base_menu_gui.h | 121 ++-- .../sys-clk/overlay/src/ui/gui/fatal_gui.cpp | 4 + Source/sys-clk/overlay/src/ui/gui/fatal_gui.h | 4 + .../overlay/src/ui/gui/freq_choice_gui.cpp | 4 + .../overlay/src/ui/gui/freq_choice_gui.h | 4 + .../src/ui/gui/global_override_gui.cpp | 4 + .../overlay/src/ui/gui/global_override_gui.h | 4 + .../sys-clk/overlay/src/ui/gui/main_gui.cpp | 4 + Source/sys-clk/overlay/src/ui/gui/main_gui.h | 4 + 14 files changed, 406 insertions(+), 397 deletions(-) diff --git a/Source/sys-clk/overlay/src/ui/gui/app_profile_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/app_profile_gui.cpp index 2f68228e..e282b669 100644 --- a/Source/sys-clk/overlay/src/ui/gui/app_profile_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/app_profile_gui.cpp @@ -1,4 +1,8 @@ /* + * Copyright (C) Switch-OC-Suite + * + * Copyright (c) 2023 hanai3Bi + * * Copyright (c) Souldbminer and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it diff --git a/Source/sys-clk/overlay/src/ui/gui/app_profile_gui.h b/Source/sys-clk/overlay/src/ui/gui/app_profile_gui.h index 5cf87d9c..23939394 100644 --- a/Source/sys-clk/overlay/src/ui/gui/app_profile_gui.h +++ b/Source/sys-clk/overlay/src/ui/gui/app_profile_gui.h @@ -1,4 +1,8 @@ /* + * Copyright (C) Switch-OC-Suite + * + * Copyright (c) 2023 hanai3Bi + * * Copyright (c) Souldbminer and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it 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 4a928403..7d38134f 100644 --- a/Source/sys-clk/overlay/src/ui/gui/base_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/base_gui.cpp @@ -1,4 +1,8 @@ /* + * Copyright (C) Switch-OC-Suite + * + * Copyright (c) 2023 hanai3Bi + * * Copyright (c) Souldbminer and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it @@ -23,13 +27,20 @@ * stuff is worth it, you can buy us a beer in return. - The sys-clk authors * -------------------------------------------------------------------------- */ + + #include "base_gui.h" + #include "../elements/base_frame.h" #include "logo_rgba_bin.h" + + + #define LOGO_X 20 #define LOGO_Y 45 #define LOGO_LABEL_FONT_SIZE 35 + #define VERSION_X (LOGO_X + 250) #define VERSION_Y LOGO_Y-40 #define VERSION_FONT_SIZE 15 @@ -45,12 +56,9 @@ std::string getVersionString() { void BaseGui::preDraw(tsl::gfx::Renderer* renderer) { - // Draw "Horizon OC " in default color - renderer->drawString("Horizon OC ", false, LOGO_X, LOGO_Y, LOGO_LABEL_FONT_SIZE, renderer->a(TEXT_COLOR)); - - // Draw "Gaea" in green - tsl::Color greenColor(40, 204, 40, 255); // Light green - renderer->drawString("Gaea", false, LOGO_X + 225, LOGO_Y, LOGO_LABEL_FONT_SIZE, greenColor); +// 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); } tsl::elm::Element* BaseGui::createUI() @@ -63,4 +71,4 @@ tsl::elm::Element* BaseGui::createUI() void BaseGui::update() { this->refresh(); -} \ No newline at end of file +} diff --git a/Source/sys-clk/overlay/src/ui/gui/base_gui.h b/Source/sys-clk/overlay/src/ui/gui/base_gui.h index eac03aee..a5a00045 100644 --- a/Source/sys-clk/overlay/src/ui/gui/base_gui.h +++ b/Source/sys-clk/overlay/src/ui/gui/base_gui.h @@ -1,4 +1,8 @@ /* + * Copyright (C) Switch-OC-Suite + * + * Copyright (c) 2023 hanai3Bi + * * Copyright (c) Souldbminer and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it diff --git a/Source/sys-clk/overlay/src/ui/gui/base_menu_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/base_menu_gui.cpp index 5d75392b..9b906bc6 100644 --- a/Source/sys-clk/overlay/src/ui/gui/base_menu_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/base_menu_gui.cpp @@ -1,14 +1,7 @@ /* - * -------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * , , - * wrote this file. As long as you retain this notice you can do whatever you - * want with this stuff. If you meet any of us some day, and you think this - * stuff is worth it, you can buy us a beer in return. - The sys-clk authors - * -------------------------------------------------------------------------- - */ - -/* + * Copyright (C) Switch-OC-Suite + * + * Copyright (c) 2023 hanai3Bi * * Copyright (c) Souldbminer and Horizon OC Contributors * @@ -23,322 +16,297 @@ * * 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): + * , , + * wrote this file. As long as you retain this notice you can do whatever you + * want with this stuff. If you meet any of us some day, and you think this + * stuff is worth it, you can buy us a beer in return. - The sys-clk authors + * -------------------------------------------------------------------------- */ - #include "base_menu_gui.h" - #include "fatal_gui.h" - - // Cache hardware model to avoid repeated syscalls - - BaseMenuGui::BaseMenuGui() - { - tsl::initializeThemeVars(); - this->context = nullptr; - this->lastContextUpdate = 0; - this->listElement = nullptr; - - // Initialize all voltages to zero once - memset(&cpuVoltageUv, 0, sizeof(u32) * 5); // Zero all 5 voltage values at once - - // Pre-cache hardware model during initialization - IsMariko(); - - // Initialize display strings - memset(displayStrings, 0, sizeof(displayStrings)); - } - - BaseMenuGui::~BaseMenuGui() { - delete this->context; // delete handles nullptr automatically - } - - // Fast preDraw - just renders pre-computed strings - void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) { - BaseGui::preDraw(renderer); - if(!this->context) [[unlikely]] return; - - // All constants pre-calculated and cached - static constexpr const char* const labels[] = { - "App ID", "Profile", "CPU", "GPU", "MEM", "SoC", "Board", "Skin", "Now", "Avg", "CPU", "GPU", "PLL", "PMIC", "BAT" - }; - - static constexpr u32 dataPositions[6] = {63-3+3, 200-1, 344-1-3, 200-1, 342-1, 321-1}; - - static u32 labelWidths[10]; - static bool positionsInitialized = false; - - if (!positionsInitialized) { - for (int i = 0; i < 10; i++) { - labelWidths[i] = renderer->getTextDimensions(labels[i], false, SMALL_TEXT_SIZE).first; - } - positionsInitialized = true; - } - static u32 positions[10] = {24-1, 310-labelWidths[1], 24-1, 192-labelWidths[3], 332-labelWidths[4], 24-1, 192 - labelWidths[6], 332-labelWidths[7], 192 - labelWidths[8], 332-labelWidths[9]}; - - static u32 maxProfileValueWidth = renderer->getTextDimensions("PD Charger", false, SMALL_TEXT_SIZE).first; // longest word - - u32 y = 91; - - // === TOP SECTION === - // renderer->drawRoundedRect(14, 70-1, 420, 30+2, 10.0f, renderer->aWithOpacity(tsl::tableBGColor)); - - // App ID - use pre-formatted string - renderer->drawString(labels[0], false, positions[0], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); - renderer->drawString(displayStrings[0], false, positions[0] + labelWidths[0] + 9, y, SMALL_TEXT_SIZE, tsl::infoTextColor); - - // Profile - use pre-formatted string - renderer->drawString(labels[1], false, 423 - maxProfileValueWidth - labelWidths[1] - 9, y, SMALL_TEXT_SIZE, tsl::sectionTextColor); - renderer->drawString(displayStrings[1], false, 423 - maxProfileValueWidth, y, SMALL_TEXT_SIZE, tsl::infoTextColor); - - y = y + 38; // Direct assignment instead of += 38 - - // === MAIN DATA SECTION === - // renderer->drawRoundedRect(14, 106, 420, 116, 10.0f, renderer->aWithOpacity(tsl::tableBGColor)); - - // === FREQUENCY SECTION === - // Labels first (better cache locality) - renderer->drawString(labels[2], false, positions[2], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); - renderer->drawString(labels[3], false, positions[3], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); - renderer->drawString(labels[4], false, positions[4], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); - - // Current frequencies - use pre-formatted strings - renderer->drawString(displayStrings[2], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU - renderer->drawString(displayStrings[3], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU - renderer->drawString(displayStrings[4], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // MEM - - y = y + 20; // Direct assignment (129 + 20) - - // === REAL FREQUENCIES === - renderer->drawString(displayStrings[5], false, positions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU real - renderer->drawString(displayStrings[6], false, positions[3], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU real - renderer->drawString(displayStrings[7], false, positions[4], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // MEM real - - y = y + 20; // Direct assignment (149 + 20) - - // === VOLTAGES === - renderer->drawString(displayStrings[8], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU voltage - renderer->drawString(displayStrings[9], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU voltage - - // Memory voltage - check if VDD is present - if (emcVoltageUv && vddVoltageUv) { - renderer->drawStringWithColoredSections(displayStrings[10], false, {""}, dataPositions[5]-16, y, SMALL_TEXT_SIZE, tsl::infoTextColor, tsl::separatorColor); - } else if (vddVoltageUv) { - renderer->drawString(displayStrings[10], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); - } else if (emcVoltageUv) { - renderer->drawString(displayStrings[10], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); - } - - // y = y + 20; // Direct assignment (169 + 22) - - - // renderer->drawString(displayStrings[17], false, dataPositions[0], y, SMALL_TEXT_SIZE, tempColors[3]); // CPU - // renderer->drawString(displayStrings[18], false, dataPositions[1], y, SMALL_TEXT_SIZE, tempColors[4]); // GPU - // renderer->drawString(displayStrings[19], false, dataPositions[2], y, SMALL_TEXT_SIZE, tempColors[5]); // PLL - - y = y + 22; // Direct assignment (149 + 20) - - // === TEMPERATURE SECTION === - // Labels - renderer->drawString(labels[5], false, positions[5], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); - renderer->drawString(labels[6], false, positions[6]-1, y, SMALL_TEXT_SIZE, tsl::sectionTextColor); - renderer->drawString(labels[7], false, positions[7], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); - - // Temperatures with color - use pre-computed colors - renderer->drawString(displayStrings[11], false, dataPositions[0], y, SMALL_TEXT_SIZE, tempColors[0]); // SOC - renderer->drawString(displayStrings[12], false, dataPositions[1], y, SMALL_TEXT_SIZE, tempColors[1]); // PCB - renderer->drawString(displayStrings[13], false, dataPositions[2], y, SMALL_TEXT_SIZE, tempColors[2]); // Skin - - y = y + 20; // Direct assignment (191 + 20) - - // === SOC VOLTAGE & POWER === - // SOC voltage (if available) - if (socVoltageUv) [[likely]] { - renderer->drawString(displayStrings[14], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); - } - - // Power labels and values - renderer->drawString(labels[8], false, positions[8]-1, y, SMALL_TEXT_SIZE, tsl::sectionTextColor); - renderer->drawString(labels[9], false, positions[9], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); - - renderer->drawString(displayStrings[15], false, dataPositions[3], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Power now - renderer->drawString(displayStrings[16], false, dataPositions[4], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Power avg - - y = y + 20; // Direct assignment (191 + 20) - renderer->drawString(displayStrings[20], false, dataPositions[0], y, SMALL_TEXT_SIZE, tempColors[4]); // BAT - renderer->drawString(displayStrings[21], false, dataPositions[1], y, SMALL_TEXT_SIZE, tempColors[5]); // PMIC +#include "base_menu_gui.h" +#include "fatal_gui.h" - y = y + 20; // Direct assignment (191 + 20) +// Cache hardware model to avoid repeated syscalls - - } - - // Optimized refresh - now does all the string formatting once per second - void BaseMenuGui::refresh() - { - - const u64 ticks = armGetSystemTick(); - // Use cached comparison - 1 billion nanoseconds - if (armTicksToNs(ticks - this->lastContextUpdate) <= 1000000000UL) [[likely]] { - return; // Early exit for most calls - } - - this->lastContextUpdate = ticks; - - // Lazy context allocation - if (!this->context) [[unlikely]] { - this->context = new SysClkContext; - } - - // === ULTRA-FAST VOLTAGE READING === - // Pre-computed domain configuration based on hardware - static const PowerDomainId domains[] = { - PcvPowerDomainId_Max77621_Cpu, // [0] CPU - PcvPowerDomainId_Max77621_Gpu, // [1] GPU - PcvPowerDomainId_Max77812_Dram, // [2] EMC/DRAM - Mariko only - PcvPowerDomainId_Max77620_Sd0, // [3] SOC - PcvPowerDomainId_Max77620_Sd1 // [4] VDD2 - }; - - // Voltage array for direct indexing - u32* voltages[] = {&cpuVoltageUv, &gpuVoltageUv, &emcVoltageUv, &socVoltageUv, &vddVoltageUv}; - - // Single regulator init/exit cycle - if (R_SUCCEEDED(rgltrInitialize())) [[likely]] { - if (IsMariko()) { - // Mariko with EOS: all 5 domains - for (int i = 0; i < 5; ++i) { - RgltrSession session; - if (R_SUCCEEDED(rgltrOpenSession(&session, domains[i]))) [[likely]] { - if (R_FAILED(rgltrGetVoltage(&session, voltages[i]))) { - *voltages[i] = 0; - } - rgltrCloseSession(&session); - } else { - *voltages[i] = 0; - } - } - } else { - // Erista - // Erista with EOS: CPU, GPU, SOC, VDD (no DRAM) - for (int i = 0; i < 5; ++i) { - if (i == 2) continue; // Skip DRAM domain - - RgltrSession session; - if (R_SUCCEEDED(rgltrOpenSession(&session, domains[i]))) [[likely]] { - if (R_FAILED(rgltrGetVoltage(&session, voltages[i]))) { - *voltages[i] = 0; - } - rgltrCloseSession(&session); - } else { - *voltages[i] = 0; - } - emcVoltageUv = 0; // Erista never supports DRAM - } - } - - rgltrExit(); - } else { - // Zero all voltages on regulator failure - memset(&cpuVoltageUv, 0, sizeof(u32) * 5); - } - - // === SYSCLK CONTEXT UPDATE === - const Result rc = sysclkIpcGetCurrentContext(this->context); - if (R_FAILED(rc)) [[unlikely]] { - FatalGui::openWithResultCode("sysclkIpcGetCurrentContext", rc); - return; - } - - // === FORMAT ALL DISPLAY STRINGS (once per second) === - // App ID (hex conversion) - sprintf(displayStrings[0], "%016lX", context->applicationId); - - // Profile - strcpy(displayStrings[1], sysclkFormatProfile(context->profile, true)); - - // Current frequencies - u32 hz = context->freqs[0]; // CPU - - sprintf(displayStrings[2], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); - - hz = context->freqs[1]; // GPU - sprintf(displayStrings[3], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); - - hz = context->freqs[2]; // MEM - sprintf(displayStrings[4], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); - - // Real frequencies - hz = context->realFreqs[0]; // CPU - sprintf(displayStrings[5], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); - - hz = context->realFreqs[1]; // GPU - sprintf(displayStrings[6], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); - - hz = context->realFreqs[2]; // MEM - sprintf(displayStrings[7], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); - - // Voltages - sprintf(displayStrings[8], "%.1f mV", cpuVoltageUv / 1000.0); - sprintf(displayStrings[9], "%.1f mV", gpuVoltageUv / 1000.0); - - // Memory voltage (handle VDD case) - if (emcVoltageUv && vddVoltageUv) { - //sprintf(displayStrings[10], "%u%u mV", vddVoltageUv / 1000U, emcVoltageUv / 1000U); - //sprintf(displayStrings[10], "%u%.1f mV", vddVoltageUv / 1000U, emcVoltageUv / 1000.0f); - sprintf(displayStrings[10], "%u.%u%u mV", vddVoltageUv / 1000U, (vddVoltageUv % 1000U) / 100U, emcVoltageUv / 1000U); - } else if (vddVoltageUv) { - //sprintf(displayStrings[10], "%u mV", vddVoltageUv / 1000U); - sprintf(displayStrings[10], "%u.%u mV", vddVoltageUv / 1000U, (vddVoltageUv % 1000U) / 100U); - } else if (emcVoltageUv) { - sprintf(displayStrings[10], "%u mV", emcVoltageUv / 1000U); - } - - - u32 millis = context->temps[SysClkThermalSensor_SOC]; // SOC - sprintf(displayStrings[11], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); - tempColors[0] = tsl::GradientColor(millis * 0.001f); - - millis = context->temps[SysClkThermalSensor_PCB]; // PCB - sprintf(displayStrings[12], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); - tempColors[1] = tsl::GradientColor(millis * 0.001f); - - millis = context->temps[SysClkThermalSensor_Skin]; // Skin - sprintf(displayStrings[13], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); - tempColors[2] = tsl::GradientColor(millis * 0.001f); - - millis = context->temps[HocClkThermalSensor_Battery]; // - sprintf(displayStrings[20], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); - tempColors[3] = tsl::GradientColor(millis * 0.001f); - - millis = context->temps[HocClkThermalSensor_PMIC]; // - sprintf(displayStrings[21], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); - tempColors[4] = tsl::GradientColor(millis * 0.001f); - - // millis = context->temps[HocClkThermalSensor_GPU]; // Skin - // sprintf(displayStrings[18], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); - // tempColors[4] = tsl::GradientColor(millis * 0.001f); - - // millis = context->temps[HocClkThermalSensor_PLL]; // Skin - // sprintf(displayStrings[19], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); - // tempColors[5] = tsl::GradientColor(millis * 0.001f); - - // SOC voltage (if available) - if (socVoltageUv) { - sprintf(displayStrings[14], "%u mV", socVoltageUv / 1000U); - } - - // Power - sprintf(displayStrings[15], "%d mW", context->power[0]); // Now - sprintf(displayStrings[16], "%d mW", context->power[1]); // Avg - - - } - - tsl::elm::Element* BaseMenuGui::baseUI() - { - auto* list = new tsl::elm::List(); - this->listElement = list; - this->listUI(); - - return list; - } \ No newline at end of file +BaseMenuGui::BaseMenuGui() : tempColors{tsl::Color(0), tsl::Color(0), tsl::Color(0)} +{ + tsl::initializeThemeVars(); + this->context = nullptr; + this->lastContextUpdate = 0; + this->listElement = nullptr; + + // Initialize all voltages to zero once + memset(&cpuVoltageUv, 0, sizeof(u32) * 5); // Zero all 5 voltage values at once + + // Pre-cache hardware model during initialization + IsMariko(); + + // Initialize display strings + memset(displayStrings, 0, sizeof(displayStrings)); +} + +BaseMenuGui::~BaseMenuGui() { + delete this->context; // delete handles nullptr automatically +} + +// Fast preDraw - just renders pre-computed strings +void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) { + BaseGui::preDraw(renderer); + if(!this->context) [[unlikely]] return; + + // All constants pre-calculated and cached + static constexpr const char* const labels[10] = { + "App ID", "Profile", "CPU", "GPU", "MEM", "SoC", "Board", "Skin", "Now", "Avg" + }; + + static constexpr u32 dataPositions[6] = {63-3+3, 200-1, 344-1-3, 200-1, 342-1, 321-1}; + + static u32 labelWidths[10]; + static bool positionsInitialized = false; + + if (!positionsInitialized) { + for (int i = 0; i < 10; i++) { + labelWidths[i] = renderer->getTextDimensions(labels[i], false, SMALL_TEXT_SIZE).first; + } + positionsInitialized = true; + } + static u32 positions[10] = {24-1, 310-labelWidths[1], 24-1, 192-labelWidths[3], 332-labelWidths[4], 24-1, 192 - labelWidths[6], 332-labelWidths[7], 192 - labelWidths[8], 332-labelWidths[9]}; + + static u32 maxProfileValueWidth = renderer->getTextDimensions("PD Charger", false, SMALL_TEXT_SIZE).first; // longest word + + u32 y = 91; + + // === TOP SECTION === + renderer->drawRoundedRect(14, 70-1, 420, 30+2, 10.0f, renderer->aWithOpacity(tsl::tableBGColor)); + + // App ID - use pre-formatted string + renderer->drawString(labels[0], false, positions[0], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); + renderer->drawString(displayStrings[0], false, positions[0] + labelWidths[0] + 9, y, SMALL_TEXT_SIZE, tsl::infoTextColor); + + // Profile - use pre-formatted string + renderer->drawString(labels[1], false, 423 - maxProfileValueWidth - labelWidths[1] - 9, y, SMALL_TEXT_SIZE, tsl::sectionTextColor); + renderer->drawString(displayStrings[1], false, 423 - maxProfileValueWidth, y, SMALL_TEXT_SIZE, tsl::infoTextColor); + + y = 129; // Direct assignment instead of += 38 + + // === MAIN DATA SECTION === + renderer->drawRoundedRect(14, 106, 420, 116, 10.0f, renderer->aWithOpacity(tsl::tableBGColor)); + + // === FREQUENCY SECTION === + // Labels first (better cache locality) + renderer->drawString(labels[2], false, positions[2], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); + renderer->drawString(labels[3], false, positions[3], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); + renderer->drawString(labels[4], false, positions[4], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); + + // Current frequencies - use pre-formatted strings + renderer->drawString(displayStrings[2], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU + renderer->drawString(displayStrings[3], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU + renderer->drawString(displayStrings[4], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // MEM + + y = 149; // Direct assignment (129 + 20) + + // === REAL FREQUENCIES === + renderer->drawString(displayStrings[5], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU real + renderer->drawString(displayStrings[6], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU real + renderer->drawString(displayStrings[7], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // MEM real + + y = 169; // Direct assignment (149 + 20) + + // === VOLTAGES === + renderer->drawString(displayStrings[8], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU voltage + renderer->drawString(displayStrings[9], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU voltage + + // Memory voltage - check if VDD is present + if (emcVoltageUv && vddVoltageUv) { + renderer->drawStringWithColoredSections(displayStrings[10], false, {""}, dataPositions[5]-16, y, SMALL_TEXT_SIZE, tsl::infoTextColor, tsl::separatorColor); + } else if (vddVoltageUv) { + renderer->drawString(displayStrings[10], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); + } else if (emcVoltageUv) { + renderer->drawString(displayStrings[10], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); + } + + y = 191; // Direct assignment (169 + 22) + + // === TEMPERATURE SECTION === + // Labels + renderer->drawString(labels[5], false, positions[5], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); + renderer->drawString(labels[6], false, positions[6]-1, y, SMALL_TEXT_SIZE, tsl::sectionTextColor); + renderer->drawString(labels[7], false, positions[7], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); + + // Temperatures with color - use pre-computed colors + renderer->drawString(displayStrings[11], false, dataPositions[0], y, SMALL_TEXT_SIZE, tempColors[0]); // SOC + renderer->drawString(displayStrings[12], false, dataPositions[1], y, SMALL_TEXT_SIZE, tempColors[1]); // PCB + renderer->drawString(displayStrings[13], false, dataPositions[2], y, SMALL_TEXT_SIZE, tempColors[2]); // Skin + + y = 211; // Direct assignment (191 + 20) + + // === SOC VOLTAGE & POWER === + // SOC voltage (if available) + if (socVoltageUv) [[likely]] { + renderer->drawString(displayStrings[14], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); + } + + // Power labels and values + renderer->drawString(labels[8], false, positions[8]-1, y, SMALL_TEXT_SIZE, tsl::sectionTextColor); + renderer->drawString(labels[9], false, positions[9], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); + + renderer->drawString(displayStrings[15], false, dataPositions[3], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Power now + renderer->drawString(displayStrings[16], false, dataPositions[4], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Power avg +} + +// Optimized refresh - now does all the string formatting once per second +void BaseMenuGui::refresh() +{ + const u64 ticks = armGetSystemTick(); + // Use cached comparison - 1 billion nanoseconds + if (armTicksToNs(ticks - this->lastContextUpdate) <= 1000000000UL) [[likely]] { + return; // Early exit for most calls + } + + this->lastContextUpdate = ticks; + + // Lazy context allocation + if (!this->context) [[unlikely]] { + this->context = new SysClkContext; + } + + // === ULTRA-FAST VOLTAGE READING === + // Pre-computed domain configuration based on hardware + static const PowerDomainId domains[] = { + PcvPowerDomainId_Max77621_Cpu, // [0] CPU + PcvPowerDomainId_Max77621_Gpu, // [1] GPU + PcvPowerDomainId_Max77812_Dram, // [2] EMC/DRAM - Mariko only + PcvPowerDomainId_Max77620_Sd0, // [3] SOC - EOS only + PcvPowerDomainId_Max77620_Sd1 // [4] VDD2 - EOS only + }; + + // Voltage array for direct indexing + u32* voltages[] = {&cpuVoltageUv, &gpuVoltageUv, &emcVoltageUv, &socVoltageUv, &vddVoltageUv}; + + // Single regulator init/exit cycle + if (R_SUCCEEDED(rgltrInitialize())) [[likely]] { + if (IsMariko()) { + // Mariko with EOS: all 5 domains + for (int i = 0; i < 5; ++i) { + RgltrSession session; + if (R_SUCCEEDED(rgltrOpenSession(&session, domains[i]))) [[likely]] { + if (R_FAILED(rgltrGetVoltage(&session, voltages[i]))) { + *voltages[i] = 0; + } + rgltrCloseSession(&session); + } else { + *voltages[i] = 0; + } + } + } else { + // Erista + // Erista with EOS: CPU, GPU, SOC, VDD (no DRAM) + for (int i = 0; i < 5; ++i) { + if (i == 2) continue; // Skip DRAM domain + + RgltrSession session; + if (R_SUCCEEDED(rgltrOpenSession(&session, domains[i]))) [[likely]] { + if (R_FAILED(rgltrGetVoltage(&session, voltages[i]))) { + *voltages[i] = 0; + } + rgltrCloseSession(&session); + } else { + *voltages[i] = 0; + } + emcVoltageUv = 0; // Erista never supports DRAM + } + } + + rgltrExit(); + } else { + // Zero all voltages on regulator failure + memset(&cpuVoltageUv, 0, sizeof(u32) * 5); + } + + // === SYSCLK CONTEXT UPDATE === + const Result rc = sysclkIpcGetCurrentContext(this->context); + if (R_FAILED(rc)) [[unlikely]] { + FatalGui::openWithResultCode("sysclkIpcGetCurrentContext", rc); + return; + } + + // === FORMAT ALL DISPLAY STRINGS (once per second) === + // App ID (hex conversion) + sprintf(displayStrings[0], "%016lX", context->applicationId); + + // Profile + strcpy(displayStrings[1], sysclkFormatProfile(context->profile, true)); + + // Current frequencies + u32 hz = context->freqs[0]; // CPU + sprintf(displayStrings[2], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); + + hz = context->freqs[1]; // GPU + sprintf(displayStrings[3], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); + + hz = context->freqs[2]; // MEM + sprintf(displayStrings[4], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); + + // Real frequencies + hz = context->realFreqs[0]; // CPU + sprintf(displayStrings[5], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); + + hz = context->realFreqs[1]; // GPU + sprintf(displayStrings[6], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); + + hz = context->realFreqs[2]; // MEM + sprintf(displayStrings[7], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U); + + // Voltages + sprintf(displayStrings[8], "%.1f mV", cpuVoltageUv / 1000.0); + sprintf(displayStrings[9], "%.1f mV", gpuVoltageUv / 1000.0); + + // Memory voltage (handle VDD case) + if (emcVoltageUv && vddVoltageUv) { + //sprintf(displayStrings[10], "%u%u mV", vddVoltageUv / 1000U, emcVoltageUv / 1000U); + //sprintf(displayStrings[10], "%u%.1f mV", vddVoltageUv / 1000U, emcVoltageUv / 1000.0f); + sprintf(displayStrings[10], "%u.%u%u mV", vddVoltageUv / 1000U, (vddVoltageUv % 1000U) / 100U, emcVoltageUv / 1000U); + } else if (vddVoltageUv) { + //sprintf(displayStrings[10], "%u mV", vddVoltageUv / 1000U); + sprintf(displayStrings[10], "%u.%u mV", vddVoltageUv / 1000U, (vddVoltageUv % 1000U) / 100U); + } else if (emcVoltageUv) { + sprintf(displayStrings[10], "%u mV", emcVoltageUv / 1000U); + } + + // Temperatures and pre-compute colors + u32 millis = context->temps[0]; // SOC + sprintf(displayStrings[11], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); + tempColors[0] = tsl::GradientColor(millis * 0.001f); + + millis = context->temps[1]; // PCB + sprintf(displayStrings[12], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); + tempColors[1] = tsl::GradientColor(millis * 0.001f); + + millis = context->temps[2]; // Skin + sprintf(displayStrings[13], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); + tempColors[2] = tsl::GradientColor(millis * 0.001f); + + // SOC voltage (if available) + if (socVoltageUv) { + sprintf(displayStrings[14], "%u mV", socVoltageUv / 1000U); + } + + // Power + sprintf(displayStrings[15], "%d mW", context->power[0]); // Now + sprintf(displayStrings[16], "%d mW", context->power[1]); // Avg +} + +tsl::elm::Element* BaseMenuGui::baseUI() +{ + auto* list = new tsl::elm::List(); + this->listElement = list; + this->listUI(); + + return list; +} \ No newline at end of file diff --git a/Source/sys-clk/overlay/src/ui/gui/base_menu_gui.h b/Source/sys-clk/overlay/src/ui/gui/base_menu_gui.h index 3ec312fd..461926c4 100644 --- a/Source/sys-clk/overlay/src/ui/gui/base_menu_gui.h +++ b/Source/sys-clk/overlay/src/ui/gui/base_menu_gui.h @@ -1,14 +1,7 @@ /* - * -------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * , , - * wrote this file. As long as you retain this notice you can do whatever you - * want with this stuff. If you meet any of us some day, and you think this - * stuff is worth it, you can buy us a beer in return. - The sys-clk authors - * -------------------------------------------------------------------------- - */ - -/* + * Copyright (C) Switch-OC-Suite + * + * Copyright (c) 2023 hanai3Bi * * Copyright (c) Souldbminer and Horizon OC Contributors * @@ -23,69 +16,65 @@ * * 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): + * , , + * wrote this file. As long as you retain this notice you can do whatever you + * want with this stuff. If you meet any of us some day, and you think this + * stuff is worth it, you can buy us a beer in return. - The sys-clk authors + * -------------------------------------------------------------------------- */ - #pragma once - #include "../../rgltr_services.h" - #include "../../ipc.h" - #include "base_gui.h" - - - class BaseMenuGui : public BaseGui - { - protected: - SysClkContext* context; - std::uint64_t lastContextUpdate; - std::uint32_t cpuVoltageUv; - std::uint32_t gpuVoltageUv; - std::uint32_t emcVoltageUv; - std::uint32_t socVoltageUv; //add soc voltage - std::uint32_t vddVoltageUv;//add vdd2 voltage - - public: - uint64_t systemtickfrequency = 19200000; - bool g_hardwareModelCached = false; - bool g_isMariko = false; - bool g_isAula = false; +#pragma once - bool IsMariko() { - if (!g_hardwareModelCached) { - SetSysProductModel model = SetSysProductModel_Invalid; - setsysGetProductModel(&model); - g_isMariko = (model == SetSysProductModel_Iowa || - model == SetSysProductModel_Hoag || - model == SetSysProductModel_Calcio || - model == SetSysProductModel_Aula); - g_hardwareModelCached = true; - } - return g_isMariko; - } +#include "../../rgltr_services.h" +#include "../../ipc.h" +#include "base_gui.h" - bool IsAula() { +class BaseMenuGui : public BaseGui +{ + protected: + SysClkContext* context; + std::uint64_t lastContextUpdate; + std::uint32_t cpuVoltageUv; + std::uint32_t gpuVoltageUv; + std::uint32_t emcVoltageUv; + std::uint32_t socVoltageUv; //add soc voltage + std::uint32_t vddVoltageUv;//add vdd2 voltage + + public: + bool g_hardwareModelCached = false; + bool g_isMariko = false; + + bool IsMariko() { if (!g_hardwareModelCached) { SetSysProductModel model = SetSysProductModel_Invalid; setsysGetProductModel(&model); - g_isMariko = (model == SetSysProductModel_Aula); + g_isMariko = (model == SetSysProductModel_Iowa || + model == SetSysProductModel_Hoag || + model == SetSysProductModel_Calcio || + model == SetSysProductModel_Aula); + g_hardwareModelCached = true; } - return g_isAula; + return g_isMariko; } - - bool IsErista() { - return !IsMariko(); - } - BaseMenuGui(); - ~BaseMenuGui(); - void preDraw(tsl::gfx::Renderer* renderer) override; - tsl::elm::List* listElement; - tsl::elm::Element* baseUI() override; - void refresh() override; - virtual void listUI() = 0; - - private: - char displayStrings[32][32]; // Pre-formatted display strings - tsl::Color tempColors[6] = { - tsl::Color(0), tsl::Color(0), tsl::Color(0), - tsl::Color(0), tsl::Color(0), tsl::Color(0) - }; - }; \ No newline at end of file + + bool IsErista() { + return !IsMariko(); + } + BaseMenuGui(); + ~BaseMenuGui(); + void preDraw(tsl::gfx::Renderer* renderer) override; + tsl::elm::List* listElement; + tsl::elm::Element* baseUI() override; + void refresh() override; + virtual void listUI() = 0; + + private: + char displayStrings[17][32]; // Pre-formatted display strings + tsl::Color tempColors[3]; // Pre-computed temperature colors +}; diff --git a/Source/sys-clk/overlay/src/ui/gui/fatal_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/fatal_gui.cpp index e2ce452e..bd5760a7 100644 --- a/Source/sys-clk/overlay/src/ui/gui/fatal_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/fatal_gui.cpp @@ -1,4 +1,8 @@ /* + * Copyright (C) Switch-OC-Suite + * + * Copyright (c) 2023 hanai3Bi + * * Copyright (c) Souldbminer and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it diff --git a/Source/sys-clk/overlay/src/ui/gui/fatal_gui.h b/Source/sys-clk/overlay/src/ui/gui/fatal_gui.h index 0c5c3784..77d04136 100644 --- a/Source/sys-clk/overlay/src/ui/gui/fatal_gui.h +++ b/Source/sys-clk/overlay/src/ui/gui/fatal_gui.h @@ -1,4 +1,8 @@ /* + * Copyright (C) Switch-OC-Suite + * + * Copyright (c) 2023 hanai3Bi + * * Copyright (c) Souldbminer and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it 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..912266ce 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 @@ -1,4 +1,8 @@ /* + * Copyright (C) Switch-OC-Suite + * + * Copyright (c) 2023 hanai3Bi + * * Copyright (c) Souldbminer and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it 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..466bb9bb 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 @@ -1,4 +1,8 @@ /* + * Copyright (C) Switch-OC-Suite + * + * Copyright (c) 2023 hanai3Bi + * * Copyright (c) Souldbminer and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it diff --git a/Source/sys-clk/overlay/src/ui/gui/global_override_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/global_override_gui.cpp index eac22cee..2e49ac6c 100644 --- a/Source/sys-clk/overlay/src/ui/gui/global_override_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/global_override_gui.cpp @@ -1,4 +1,8 @@ /* + * Copyright (C) Switch-OC-Suite + * + * Copyright (c) 2023 hanai3Bi + * * Copyright (c) Souldbminer and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it diff --git a/Source/sys-clk/overlay/src/ui/gui/global_override_gui.h b/Source/sys-clk/overlay/src/ui/gui/global_override_gui.h index 477ff7cc..bb4dcafa 100644 --- a/Source/sys-clk/overlay/src/ui/gui/global_override_gui.h +++ b/Source/sys-clk/overlay/src/ui/gui/global_override_gui.h @@ -1,4 +1,8 @@ /* + * Copyright (C) Switch-OC-Suite + * + * Copyright (c) 2023 hanai3Bi + * * Copyright (c) Souldbminer and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it diff --git a/Source/sys-clk/overlay/src/ui/gui/main_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/main_gui.cpp index d8c29923..0524f4fa 100644 --- a/Source/sys-clk/overlay/src/ui/gui/main_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/main_gui.cpp @@ -1,4 +1,8 @@ /* + * Copyright (C) Switch-OC-Suite + * + * Copyright (c) 2023 hanai3Bi + * * Copyright (c) Souldbminer and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it diff --git a/Source/sys-clk/overlay/src/ui/gui/main_gui.h b/Source/sys-clk/overlay/src/ui/gui/main_gui.h index 77b98a2e..07d3db2d 100644 --- a/Source/sys-clk/overlay/src/ui/gui/main_gui.h +++ b/Source/sys-clk/overlay/src/ui/gui/main_gui.h @@ -1,4 +1,8 @@ /* + * Copyright (C) Switch-OC-Suite + * + * Copyright (c) 2023 hanai3Bi + * * Copyright (c) Souldbminer and Horizon OC Contributors * * This program is free software; you can redistribute it and/or modify it