sysclk: rework selection method and fix translation bugs

This commit is contained in:
souldbminersmwc
2026-03-22 18:22:38 -04:00
parent 17e27ad6e9
commit ec21e47b53
4 changed files with 348 additions and 121 deletions

View File

@@ -1,79 +1,101 @@
{
"Horizon OC Zeus": "Horizon OC Zeus",
"Edit App Profile": "Edit App Profile",
"Advanced": "Advanced",
"Edit Global Profile": "Edit Global Profile",
"Temporary Overrides": "Temporary Overrides",
"Temporary Overrides Reset": "Temporary Overrides Reset",
"Settings": "Settings",
"Information": "Information",
"Enable": "Enable",
"Uncapped Clocks": "Uncapped Clocks",
"Override Boost Mode": "Override Boost Mode",
"CPU Max Display Clock": "CPU Max Display Clock",
"Thermal Throttle": "Thermal Throttle",
"Thermal Throttle Threshold": "Thermal Throttle Threshold",
"Handheld TDP": "Handheld TDP",
"Handheld TDP Limit": "Handheld TDP Limit",
"Lite TDP Limit": "Lite TDP Limit",
"Enforce Board Limit": "Enforce Board Limit",
"Battery Charge Current": "Battery Charge Current",
"Display Refresh Rate Changing": "Display Refresh Rate Changing",
"Fix CPU Volt Bug": "Fix CPU Volt Bug",
"[cfg] no enum format string": "[cfg] no enum format string",
"KIP": "KIP",
"Save KIP Settings": "Save KIP Settings",
"RAM Settings": "RAM Settings",
"CPU Settings": "CPU Settings",
"GPU Settings": "GPU Settings",
"Experimental": "Experimental",
"Charge Current Override": "Charge Current Override",
"Speedo:": "Speedo:",
"IDDQ:": "IDDQ:",
"Module: ": "Module: ",
"sys-dock status:": "sys-dock status:",
"SaltyNX status:": "SaltyNX status:",
"RR Display status:": "RR Display status:",
"Wafer Position:": "Wafer Position:",
"Credits": "Credits",
"Developers": "Developers",
"Souldbminer": "Souldbminer",
"Lightos_": "Lightos_",
"Contributors": "Contributors",
"Dom": "Dom",
"Blaise25": "Blaise25",
"Testers": "Testers",
"Samybigio2011": "Samybigio2011",
"Delta": "Delta",
"Miki1305": "Miki1305",
"Happy": "Happy",
"Flopsider": "Flopsider",
"Winnerboi77": "Winnerboi77",
"WE1ZARD": "WE1ZARD",
"Alvise": "Alvise",
"TDRR": "TDRR",
"agjeococh": "agjeococh",
"Xenshen": "Xenshen",
"Frost": "Frost",
"Special Thanks": "Special Thanks",
"ScriesM - Atmosphere CFW": "ScriesM - Atmosphere CFW",
"KazushiMe - Switch OC Suite": "KazushiMe - Switch OC Suite",
"hanai3bi - Switch OC Suite & EOS": "hanai3bi - Switch OC Suite & EOS",
"NaGaa95 - L4T-OC-Kernel": "NaGaa95 - L4T-OC-Kernel",
"B3711 - EOS": "B3711 - EOS",
"RetroNX - sys-clk": "RetroNX - sys-clk",
"b0rd2death - Ultrahand": "b0rd2death - Ultrahand",
"MasaGratoR - Status Monitor": "MasaGratoR - Status Monitor",
"Cat": "Cat",
"HB-MGCH 4GB": "HB-MGCH 4GB",
"HM-MGCH 6GB": "HM-MGCH 6GB",
"HM-MGXX 8GB": "HM-MGXX 8GB",
"NLE": "NLE",
"WT:C": "WT:C",
"NEE": "NEE",
"AM-MGCJ 4GB": "AM-MGCJ 4GB",
"AM-MGCJ 8GB": "AM-MGCJ 8GB",
"NME": "NME",
"WT:E": "WT:E",
"AA-MGCL 4GB": "AA-MGCL 4GB",
"AA-MGCL 8GB": "AA-MGCL 8GB",
"AB-MGCL 4GB": "AB-MGCL 4GB",
"WT:F": "WT:F",
"WT:B": "WT:B",
"Unknown": "Unknown",
"Installed": "Installed",
"Not Installed": "Not Installed",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "THE BEER-WARE LICENSE",
"Default": "Default",
"Governor": "Governor",
"CPU": "CPU",
"GPU": "GPU",
"VRR": "VRR",
"Do Not Override": "Do Not Override",
"Disabled": "Disabled",
"HP Mode": "HP Mode",
"EMC Max Clock": "EMC Max Clock",
"EMC VDD2 Voltage": "EMC VDD2 Voltage",
"EMC VDDQ Voltage": "EMC VDDQ Voltage",
"DVB Shift": "DVB Shift",
"Memory Timings": "Memory Timings",
"Memory Latencies": "Memory Latencies",
"t1 tRCD": "t1 tRCD",
"t2 tRP": "t2 tRP",
"t3 tRAS": "t3 tRAS",
"t4 tRRD": "t4 tRRD",
"t5 tRFC": "t5 tRFC",
"t6 tRTW": "t6 tRTW",
"t7 tWTR": "t7 tWTR",
"t8 tREFI": "t8 tREFI",
"Update RAM Timings": "Update RAM Timings",
"\uE150 This feature is EXPERIMENTAL": "\uE150 This feature is EXPERIMENTAL",
"and should only be used for testing!": "and should only be used for testing!",
"Read Latency": "Read Latency",
"Write Latency": "Write Latency",
"CPU UV": "CPU UV",
"CPU Unlock": "CPU Unlock",
"CPU VMIN": "CPU VMIN",
"CPU Max Voltage": "CPU Max Voltage",
"CPU UV Table": "CPU UV Table",
"CPU Low UV": "CPU Low UV",
"CPU High UV": "CPU High UV",
"CPU Max Clock": "CPU Max Clock",
"CPU Low VMIN": "CPU Low VMIN",
"CPU High VMIN": "CPU High VMIN",
"GPU Undervolt Table": "GPU Undervolt Table",
"Calculate GPU Vmin": "Calculate GPU Vmin",
"GPU VMIN": "GPU VMIN",
"GPU VMAX": "GPU VMAX",
"GPU Volt Offset": "GPU Volt Offset",
"GPU Custom Table": "GPU Custom Table",
"GPU Custom Table (mV)": "GPU Custom Table (mV)",
"\uE150 Setting GPU Clocks past": "\uE150 Setting GPU Clocks past",
"1075MHz without UV, 1152MHz on SLT or ": "1075MHz without UV, 1152MHz on SLT or ",
"1228MHz on HiOPT can cause ": "1228MHz on HiOPT can cause ",
"permanent damage to your Switch!": "permanent damage to your Switch!",
"Proceed at your own risk!": "Proceed at your own risk!",
"921MHz without UV and 960MHz on": "921MHz without UV and 960MHz on",
"SLT or HiOPT can cause ": "SLT or HiOPT can cause ",
"Auto": "Auto",
"Enabled": "Enabled",
" \\ue0e3 Reset": " \\ue0e3 Reset",
"Display": "Display",
"Application changed\\n\\n": "Application changed\\n\\n",
"The running application changed\\n\\n": "The running application changed\\n\\n",
"while editing was going on.": "while editing was going on.",
"Horizon OC Zeus": "Horizon OC Zeus",
"App ID": "App ID",
"Profile": "Profile",
"MEM": "MEM",
"SoC": "SoC",
"Board": "Board",
"Skin": "Skin",
"Now": "Now",
"Avg": "Avg",
"BAT": "BAT",
"PMIC": "PMIC",
"FAN": "FAN",
"DISP": "DISP",
"FPS": "FPS",
"RES": "RES",
"USB Charger": "USB Charger",
"%u.%u%u mV": "%u.%u%u mV",
"N/A": "N/A",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Could not connect to hoc-clk sysmodule.\\n\\n",
"Please make sure everything is\\n\\n": "Please make sure everything is\\n\\n",
"correctly installed and enabled.": "correctly installed and enabled.",
"Fatal error": "Fatal error",
"cpu": "cpu",
"gpu": "gpu",
"mem": "mem",
"Temporary Overrides ": "Temporary Overrides ",
"Sleep Mode": "Sleep Mode",
"Stock": "Stock",
"Dev OC": "Dev OC",
@@ -81,52 +103,138 @@
"Safe Max": "Safe Max",
"Unsafe Max": "Unsafe Max",
"Absolute Max": "Absolute Max",
"Boost Mode & Safe Max": "Boost Mode & Safe Max",
"Handheld": "Handheld",
"Handheld Safe Max": "Handheld Safe Max",
"Docked": "Docked",
"Enable": "Enable",
"Edit App Profile": "Edit App Profile",
"Edit Global Profile": "Edit Global Profile",
"Temporary Overrides": "Temporary Overrides",
"Misc": "Misc",
"Settings": "Settings",
"About": "About",
"Compiling with minimal features": "Compiling with minimal features",
"General Settings": "General Settings",
"Governor Settings": "Governor Settings",
"Safety Settings": "Safety Settings",
"KIP": "KIP",
"Save KIP Settings": "Save KIP Settings",
"RAM Settings": "RAM Settings",
"CPU Settings": "CPU Settings",
"GPU Settings": "GPU Settings",
"Display Settings": "Display Settings",
"Experimental": "Experimental",
"INI": "INI",
"NV Service": "NV Service",
"GPU Scheduling Override Method": "GPU Scheduling Override Method",
"can be dangerous and may cause": "can be dangerous and may cause",
"damage to your battery or charger!": "damage to your battery or charger!",
"Charge Current Override": "Charge Current Override",
"VDD2 + VDDQ": "VDD2 + VDDQ",
"VDD2 + Usage": "VDD2 + Usage",
"VDDQ + Usage": "VDDQ + Usage",
"RAM Voltage Display Mode": "RAM Voltage Display Mode",
"Polling Interval": "Polling Interval",
"CPU Governor Minimum Frequency": "CPU Governor Minimum Frequency",
"refresh rates may cause stress": "refresh rates may cause stress",
"or damage to your display! ": "or damage to your display! ",
"Proceed at your own risk!": "Proceed at your own risk!",
"Max Handheld Display": "Max Handheld Display",
"Display Clock": "Display Clock",
"Official Rating": "Official Rating",
"TDP Threshold": "TDP Threshold",
"Power": "Power",
"Thermal Throttle Limit": "Thermal Throttle Limit",
"Temp": "Temp",
"HP Mode": "HP Mode",
"Default (Mariko)": "Default (Mariko)",
"Default (Erista)": "Default (Erista)",
"Rating": "Rating",
"Safe Max (Mariko)": "Safe Max (Mariko)",
"Safe Max (Erista)": "Safe Max (Erista)",
"Default": "Default",
"RAM VDD2 Voltage": "RAM VDD2 Voltage",
"Voltage": "Voltage",
"RAM VDDQ Voltage": "RAM VDDQ Voltage",
"SoC DVB Shift": "SoC DVB Shift",
"RAM Frequency Editor": "RAM Frequency Editor",
"JEDEC.": "JEDEC.",
"High speedo needed!": "High speedo needed!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz (Needs extreme Speedo/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz (Needs extreme Speedo/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz (Needs extreme Speedo/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (Needs ridiculous Speedo/PLL)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz (Needs ridiculous Speedo/PLL)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz (Needs ridiculous Speedo/PLL)",
"Ram Max Clock": "Ram Max Clock",
"RAM Latency Editor": "RAM Latency Editor",
"RAM Timing Reductions": "RAM Timing Reductions",
"Memory Timings": "Memory Timings",
"t1 tRCD": "t1 tRCD",
"tRCD": "tRCD",
"t2 tRP": "t2 tRP",
"tRP": "tRP",
"t3 tRAS": "t3 tRAS",
"tRAS": "tRAS",
"t4 tRRD": "t4 tRRD",
"tRRD": "tRRD",
"t5 tRFC": "t5 tRFC",
"tRFC": "tRFC",
"t6 tRTW": "t6 tRTW",
"tRTW": "tRTW",
"t7 tWTR": "t7 tWTR",
"tWTR": "tWTR",
"t8 tREFI": "t8 tREFI",
"tREFI": "tREFI",
"Advanced": "Advanced",
"t6 tRTW Fine Tune": "t6 tRTW Fine Tune",
"tRTW Fine Tune": "tRTW Fine Tune",
"t7 tWTR Fine Tune": "t7 tWTR Fine Tune",
"tWTR Fine Tune": "tWTR Fine Tune",
"Memory Latencies": "Memory Latencies",
"1333 RL": "1333 RL",
"1600 RL": "1600 RL",
"1866 RL": "1866 RL",
"2133 RL": "2133 RL",
"Read Latency": "Read Latency",
"Write Latency": "Write Latency",
"CPU Boost Clock": "CPU Boost Clock",
"CPU UV": "CPU UV",
"CPU Unlock": "CPU Unlock",
"CPU VMIN": "CPU VMIN",
"CPU Max Voltage": "CPU Max Voltage",
"CPU Max Clock": "CPU Max Clock",
"Auto": "Auto",
"1581MHz Tbreak": "1581MHz Tbreak",
"1683MHz Tbreak": "1683MHz Tbreak",
"Extreme UV Table": "Extreme UV Table",
"No UV": "No UV",
"CPU UV Table": "CPU UV Table",
"CPU Low UV": "CPU Low UV",
"CPU High UV": "CPU High UV",
"CPU Low VMIN": "CPU Low VMIN",
"CPU High VMIN": "CPU High VMIN",
"No Undervolt": "No Undervolt",
"SLT Table": "SLT Table",
"HiOPT Table": "HiOPT Table",
"Power": "Power",
"Temp": "Temp",
"Voltage": "Voltage",
"TDP Threshold": "TDP Threshold",
"Lite TDP Threshold": "Lite TDP Threshold",
"Thermal Throttle Limit": "Thermal Throttle Limit",
"1600BL": "1600BL",
"1866BL": "1866BL",
"2133BL": "2133BL",
"BAT": "BAT",
"FAN": "FAN",
"DISP": "DISP",
"Board": "Board",
"Skin": "Skin",
"Now": "Now",
"Avg": "Avg",
"App ID": "App ID",
"Profile": "Profile",
"CPU": "CPU",
"GPU": "GPU",
"Memory": "Memory",
"Display": "Display",
"Governor": "Governor",
"SOC": "SOC",
"PCB": "PCB",
"PMIC": "PMIC",
"Docked": "Docked",
"Handheld": "Handheld",
"Charging": "Charging",
"USB Charger": "USB Charger",
"PD Charger": "PD Charger",
"VDD2": "VDD2",
"VDDQ": "VDDQ",
"GPU DVFS": "GPU DVFS"
}
"GPU Undervolt Table": "GPU Undervolt Table",
"GPU Minimum Voltage": "GPU Minimum Voltage",
"Calculate GPU Vmin": "Calculate GPU Vmin",
"GPU VMIN": "GPU VMIN",
"GPU Maximum Voltage": "GPU Maximum Voltage",
"GPU Voltage Offset": "GPU Voltage Offset",
"Do not override": "Do not override",
"Enabled (Default)": "Enabled (Default)",
"96.6% limit": "96.6% limit",
"99.7% limit": "99.7% limit",
"GPU Scheduling Override": "GPU Scheduling Override",
"PCV Hijack": "PCV Hijack",
"Official Service": "Official Service",
"GPU DVFS Mode": "GPU DVFS Mode",
"GPU DVFS Offset": "GPU DVFS Offset",
"GPU Voltage Table": "GPU Voltage Table",
"GPU Custom Table (mV)": "GPU Custom Table (mV)",
"1075MHz without UV, 1152MHz on SLT": "1075MHz without UV, 1152MHz on SLT",
"or 1228MHz on HiOPT can cause ": "or 1228MHz on HiOPT can cause ",
"permanent damage to your Switch!": "permanent damage to your Switch!",
"921MHz without UV and 960MHz on": "921MHz without UV and 960MHz on",
"SLT or HiOPT can cause ": "SLT or HiOPT can cause "
}

View File

@@ -56,14 +56,15 @@ FreqChoiceGui::~FreqChoiceGui()
tsl::elm::ListItem* FreqChoiceGui::createFreqListItem(std::uint32_t hz, bool selected, int safety)
{
std::string text = formatListFreqHz(hz);
if (selected)
text += " \uE14B";
std::string rightText = "";
auto it = labels.find(hz);
if (it != labels.end())
rightText = it->second;
if (selected)
const_cast<std::string&>(rightText) = "\uE14B";
tsl::elm::ListItem* listItem =
new tsl::elm::ListItem(text, rightText, false);
@@ -84,8 +85,10 @@ tsl::elm::ListItem* FreqChoiceGui::createFreqListItem(std::uint32_t hz, bool sel
}
// Make annotation grey
if (!rightText.empty())
if (!rightText.empty() && !selected)
listItem->setValueColor(tsl::Color(180, 180, 180, 255));
else if(selected)
listItem->setValueColor(tsl::infoTextColor);
listItem->setClickListener([this, hz](u64 keys)
{

View File

@@ -83,14 +83,17 @@ int ValueChoiceGui::getSafetyLevel(std::uint32_t value)
tsl::elm::ListItem* ValueChoiceGui::createValueListItem(std::uint32_t value, bool selected, int safety)
{
std::string text = formatValue(value);
if (selected) {
text += " \uE14B";
}
std::string rightText = "";
auto it = labels.find(value);
if (it != labels.end()) {
rightText = it->second;
}
if (selected) {
const_cast<std::string&>(rightText) = "\uE14B";
}
tsl::elm::ListItem* listItem = new tsl::elm::ListItem(text, rightText, false);
switch (safety)
{
@@ -107,8 +110,13 @@ tsl::elm::ListItem* ValueChoiceGui::createValueListItem(std::uint32_t value, boo
listItem->setValueColor(tsl::Color(255, 0, 0, 255));
break;
}
if (!rightText.empty())
// Make annotation grey
if (!rightText.empty() && !selected)
listItem->setValueColor(tsl::Color(180, 180, 180, 255));
else if(selected)
listItem->setValueColor(tsl::infoTextColor);
listItem->setClickListener([this, value](u64 keys)
{
if ((keys & HidNpadButton_A) == HidNpadButton_A && this->listener) {
@@ -126,7 +134,7 @@ tsl::elm::ListItem* ValueChoiceGui::createNamedValueListItem(const NamedValue& n
{
std::string text = namedValue.name;
if (selected) {
text += " \uE14B";
const_cast<std::string&>(namedValue.rightText) = "\uE14B";
}
tsl::elm::ListItem* listItem = new tsl::elm::ListItem(text, namedValue.rightText, false);
@@ -145,9 +153,12 @@ tsl::elm::ListItem* ValueChoiceGui::createNamedValueListItem(const NamedValue& n
listItem->setValueColor(tsl::Color(255, 0, 0, 255));
break;
}
if (!namedValue.rightText.empty())
if (!namedValue.rightText.empty() && !selected)
listItem->setValueColor(tsl::Color(180, 180, 180, 255));
else if(selected)
listItem->setValueColor(tsl::infoTextColor);
listItem->setClickListener([this, value = namedValue.value](u64 keys)
{
if ((keys & HidNpadButton_A) == HidNpadButton_A && this->listener) {

View File

@@ -0,0 +1,105 @@
#!/usr/bin/env python3
import os
import re
import json
SOURCE_DIR = os.path.join("src", "ui", "gui")
OUTPUT_FILE = os.path.join("lang", "en.json")
IGNORED_PREFIXES = (
"/", "\\",
"sysclk", "hocclk", "horizonoc",
"\\u",
)
def extract_strings_from_file(filepath: str) -> list[str]:
with open(filepath, "r", encoding="utf-8", errors="ignore") as f:
content = f.read()
pattern = r'"((?:[^"\\]|\\.)*)"'
return re.findall(pattern, content)
def should_include(s: str) -> bool:
if not s or s.isspace():
return False
stripped = s.strip()
lower = stripped.lower()
for prefix in IGNORED_PREFIXES:
if s.startswith(prefix):
return False
if re.match(r"^\\u[0-9a-fA-F]", s):
return False
if re.fullmatch(r"[a-zA-Z0-9_./\\-]+\.(h|hpp|cpp|c)", stripped):
return False
if re.fullmatch(r"[%\d.*\-+lfdsuxXpLh ]*", stripped) and "%" in stripped:
return False
if re.fullmatch(r"[\\nt ]*", stripped):
return False
if re.fullmatch(r"[+\- ]*\d+\.?\d*\s*(MHz|mV|mA|mW|Hz|ms|°C|%%|p)?", stripped):
return False
if re.fullmatch(r"[%\d./*+\-ufdsxXlLhp ,°CM:HzWmVA\\n]+", stripped):
return False
if re.match(r"^hocClkIpc", stripped):
return False
if len(stripped) <= 2 and not stripped.isalpha():
return False
if re.fullmatch(r"(\\[nt])+", stripped):
return False
if re.fullmatch(r"[\s]*(\\u[0-9a-fA-F]{4}[\s]*)+", stripped):
return False
return True
def main():
seen: set[str] = set()
strings: list[str] = []
if not os.path.isdir(SOURCE_DIR):
print(f"Error: directory '{SOURCE_DIR}' not found.")
return
for filename in sorted(os.listdir(SOURCE_DIR)):
if not filename.endswith((".cpp", ".h")):
continue
filepath = os.path.join(SOURCE_DIR, filename)
for s in extract_strings_from_file(filepath):
if s not in seen and should_include(s):
seen.add(s)
strings.append(s)
translations = {s: s for s in strings}
os.makedirs(os.path.dirname(OUTPUT_FILE), exist_ok=True)
with open(OUTPUT_FILE, "w", encoding="utf-8") as f:
f.write("{\n")
items = list(translations.items())
for i, (key, val) in enumerate(items):
k = json.dumps(key, ensure_ascii=False)
v = json.dumps(val, ensure_ascii=False)
comma = "," if i < len(items) - 1 else ""
f.write(f" {k}: {v}{comma}\n")
f.write("}\n")
print(f"Extracted {len(translations)} unique strings from {SOURCE_DIR}")
print(f"Written to {OUTPUT_FILE}")
if __name__ == "__main__":
main()