hoc-sys: add extra features to overlay
This commit is contained in:
@@ -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:
|
||||
|
||||
BIN
Source/Configurator/dist/hocconfig.exe
vendored
BIN
Source/Configurator/dist/hocconfig.exe
vendored
Binary file not shown.
BIN
Source/Configurator/loader_edit.kip
Normal file
BIN
Source/Configurator/loader_edit.kip
Normal file
Binary file not shown.
@@ -1 +1 @@
|
||||
python3 src/main.py
|
||||
python 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")
|
||||
|
||||
@@ -60,6 +60,7 @@ freqs_mhz_cpu = [
|
||||
variables = [
|
||||
("custRev", "u32"),
|
||||
("mtcConf", "u32"),
|
||||
("hpMode", "u32"),
|
||||
("commonCpuBoostClock", "u32"),
|
||||
("commonEmcMemVolt", "u32"),
|
||||
("eristaCpuMaxVolt", "u32"),
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
@@ -57,7 +57,7 @@ class AppOverlay : public tsl::Overlay
|
||||
if(!sysclkIpcRunning())
|
||||
{
|
||||
return initially<FatalGui>(
|
||||
"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<FatalGui>(
|
||||
"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<FatalGui>(
|
||||
"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.",
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
|
||||
@@ -24,37 +24,124 @@
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "base_gui.h"
|
||||
|
||||
#include "../elements/base_frame.h"
|
||||
#include "logo_rgba_bin.h"
|
||||
|
||||
#include <tesla.hpp>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// 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<double>(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<u8>(staticColor.r + (dynamicLogoRGB2.r - staticColor.r) * blend),
|
||||
static_cast<u8>(staticColor.g + (dynamicLogoRGB2.g - staticColor.g) * blend),
|
||||
static_cast<u8>(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()
|
||||
|
||||
@@ -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<uint32_t, std::string> 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("", "");
|
||||
}
|
||||
|
||||
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("", "");
|
||||
}
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include <list>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include "base_menu_gui.h"
|
||||
|
||||
using FreqChoiceListener = std::function<bool(std::uint32_t hz)>;
|
||||
@@ -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<uint32_t, std::string> 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<uint32_t, std::string> labels = {}); // NEW ARG
|
||||
|
||||
~FreqChoiceGui();
|
||||
|
||||
void listUI() override;
|
||||
|
||||
@@ -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<uint32_t, std::string>& 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<uint32_t, std::string>& 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<FreqChoiceGui>(
|
||||
currentHz,
|
||||
hzList,
|
||||
hzCount,
|
||||
module,
|
||||
[this, configVal](std::uint32_t hz) {
|
||||
tsl::changeTo<FreqChoiceGui>(
|
||||
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<uint32_t, std::string> labels_pwr_r = {
|
||||
{8600, "Official Rating"}
|
||||
};
|
||||
std::map<uint32_t, std::string> 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<uint32_t, std::string> 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<uint32_t, std::string> 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<uint32_t, std::string> 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<uint32_t, std::string> 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<uint32_t, std::string> emc_freq_label_e = {
|
||||
{133120000, "Handheld"},
|
||||
{160000000, "Docked & Safe Max"},
|
||||
{213100000, "JEDEC Max"},
|
||||
{236000000, "Absolute Max"},
|
||||
};
|
||||
|
||||
|
||||
std::map<uint32_t, std::string> 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<uint32_t, std::string> 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<uint32_t, std::string> 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) {
|
||||
|
||||
@@ -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<uint32_t, std::string>& labels = {});
|
||||
void addFreqButton(SysClkConfigValue configVal,
|
||||
const char* altName,
|
||||
SysClkModule module,
|
||||
const std::map<uint32_t, std::string>& labels = {});
|
||||
void updateConfigToggles();
|
||||
|
||||
tsl::elm::ToggleListItem* enabledToggle;
|
||||
|
||||
@@ -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<std::uint32_t, std::string> 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<double>(value) / static_cast<double>(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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,62 +25,69 @@
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include "base_menu_gui.h"
|
||||
|
||||
using ValueChoiceListener = std::function<bool(std::uint32_t value)>;
|
||||
|
||||
#define VALUE_DEFAULT_TEXT "Default"
|
||||
|
||||
struct ValueRange {
|
||||
#include <list>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "base_menu_gui.h"
|
||||
|
||||
using ValueChoiceListener = std::function<bool(std::uint32_t value)>;
|
||||
|
||||
#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;
|
||||
};
|
||||
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<std::uint32_t, std::string> 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<std::uint32_t, std::string> labels = {});
|
||||
~ValueChoiceGui();
|
||||
|
||||
void listUI() override;
|
||||
};
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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": [
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "notification.h"
|
||||
|
||||
#include "clock_manager.h"
|
||||
#include <cstring>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
31
Source/sys-clk/sysmodule/src/notification.h
Normal file
31
Source/sys-clk/sysmodule/src/notification.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
#include <cstdio>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name" : "hoc-clk",
|
||||
"name" : "Horizon OC",
|
||||
"tid" : "00FF0000636C6BFF",
|
||||
"requires_reboot": false
|
||||
}
|
||||
Reference in New Issue
Block a user