hocclk: improve ui

yes i did vibecode this, no i don't care
This commit is contained in:
souldbminersmwc
2026-05-26 19:05:53 -04:00
parent 13f422fa29
commit 6b26aa5574
14 changed files with 101 additions and 40 deletions

View File

@@ -1,10 +0,0 @@
{
"permissions": {
"allow": [
"PowerShell(\\(Get-Item \"c:\\\\Users\\\\sould\\\\Documents\\\\GitHub\\\\Horizon-OC\\\\Source\\\\hoc-clk\\\\assets\\\\hoc.rgba\"\\).Length)",
"PowerShell(python --version)",
"PowerShell(magick --version 2>$null)",
"PowerShell(convert --version 2>$null)"
]
}
}

View File

@@ -28,20 +28,21 @@
#pragma once
#include <tesla.hpp>
#include "../gui/base_gui.h"
class BaseGui;
static constexpr u16 HOC_HEADER_HEIGHT = 287;
// Bottom edge of the drawn box: 106 + TOP_Y_OFFSET(15) + 156 = 277
static constexpr u16 HOC_BOX_BOTTOM = 277;
class BaseFrame : public tsl::elm::HeaderOverlayFrame
{
public:
BaseFrame(BaseGui* gui) : tsl::elm::HeaderOverlayFrame(234) {
BaseFrame(BaseGui* gui, u16 headerHeight = HOC_HEADER_HEIGHT) : tsl::elm::HeaderOverlayFrame(headerHeight) {
this->gui = gui;
}
void draw(tsl::gfx::Renderer* renderer) override
{
tsl::elm::HeaderOverlayFrame::draw(renderer);
this->gui->preDraw(renderer);
}
void draw(tsl::gfx::Renderer* renderer) override;
protected:
BaseGui* gui;

View File

@@ -25,6 +25,7 @@
*/
#include "ult_ext.h"
#include "app_profile_gui.h"
#include "../format.h"

View File

@@ -25,9 +25,13 @@
*/
#include "base_gui.h"
#include "../elements/base_frame.h"
void BaseFrame::draw(tsl::gfx::Renderer* renderer) {
tsl::elm::HeaderOverlayFrame::draw(renderer);
this->gui->preDraw(renderer);
}
#include <tesla.hpp>
#include <math.h>
@@ -142,11 +146,27 @@ void BaseGui::preDraw(tsl::gfx::Renderer* renderer) {
STATIC_TEAL,
false
);
static const std::string versionStr = "Version " + getVersionString();
static constexpr tsl::Color versionColor(9, 9, 9, 15);
static constexpr s32 vx = LOGO_TEXT_X + 15;
static constexpr s32 vy = TEXT_Y + 18;
static constexpr s32 fs = 15;
static constexpr s32 skew = 3;
static constexpr s32 passes = 10;
for (s32 i = 0; i < passes; i++) {
s32 sliceY = (vy - fs) + i * fs / passes;
s32 sliceH = fs / passes + 1;
s32 xOff = skew - (skew * i / (passes - 1));
renderer->enableScissoring(0, sliceY, tsl::cfg::FramebufferWidth, sliceH);
renderer->drawString(versionStr.c_str(), false, vx + xOff, vy, fs, versionColor);
renderer->disableScissoring();
}
}
tsl::elm::Element* BaseGui::createUI()
{
BaseFrame* rootFrame = new BaseFrame(this);
BaseFrame* rootFrame = new BaseFrame(this, this->headerHeight());
rootFrame->setContent(this->baseUI());
return rootFrame;
}

View File

@@ -28,6 +28,7 @@
#pragma once
#include <tesla.hpp>
#include "../elements/base_frame.h"
#include <fstream>
#include <vector>
#include <string>
@@ -46,6 +47,7 @@ class BaseGui : public tsl::Gui
tsl::elm::Element* createUI() override;
virtual tsl::elm::Element* baseUI() = 0;
virtual void refresh() {}
virtual u16 headerHeight() const { return HOC_HEADER_HEIGHT; }
private:
};

View File

@@ -29,6 +29,8 @@
#include "fatal_gui.h"
#include "../format.h"
#define TOP_Y_OFFSET 15
// Cache hardware model to avoid repeated syscalls
BaseMenuGui::BaseMenuGui() : tempColors{ tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), }
@@ -77,10 +79,10 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
static u32 maxProfileValueWidth = renderer->getTextDimensions("USB Charger", false, SMALL_TEXT_SIZE).first; // longest word
u32 y = 91;
u32 y = 91 + TOP_Y_OFFSET;
// === TOP SECTION ===
renderer->drawRoundedRect(14, 70-1, 420, 30+2, 12.0f, renderer->aWithOpacity(tsl::tableBGColor));
renderer->drawRoundedRect(14, 70-1 + TOP_Y_OFFSET, 420, 30+2, 12.0f, renderer->aWithOpacity(tsl::tableBGColor));
// App ID - use pre-formatted string
renderer->drawString(labels[0], false, positions[0], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
@@ -93,7 +95,7 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) {
y += 38; // Direct assignment instead of += 38
// === MAIN DATA SECTION ===
renderer->drawRoundedRect(14, 106, 420, 156, 10.0f, renderer->aWithOpacity(tsl::tableBGColor));
renderer->drawRoundedRect(14, 106 + TOP_Y_OFFSET, 420, 156, 10.0f, renderer->aWithOpacity(tsl::tableBGColor));
// === FREQUENCY SECTION ===
// Labels first (better cache locality)
@@ -348,7 +350,6 @@ void BaseMenuGui::refresh()
tsl::elm::Element* BaseMenuGui::baseUI()
{
auto* list = new tsl::elm::List();
list->addItem(new tsl::elm::CustomDrawer([](tsl::gfx::Renderer*, s32, s32, s32, s32) {}), 35); // add a bit of space
this->listElement = list;
this->listUI();

View File

@@ -84,6 +84,7 @@ class BaseMenuGui : public BaseGui
tsl::elm::Element* baseUI() override;
void refresh() override;
virtual void listUI() = 0;
u16 headerHeight() const override { return HOC_BOX_BOTTOM + 9; }
private:
char displayStrings[48][32]; // Pre-formatted display strings

View File

@@ -25,6 +25,7 @@
*/
#include "ult_ext.h"
#include "freq_choice_gui.h"
#include "../format.h"

View File

@@ -16,6 +16,7 @@
*
*/
#include "ult_ext.h"
#include "../format.h"
#include "fatal_gui.h"
#include "global_override_gui.h"

View File

@@ -32,6 +32,14 @@
#include "global_override_gui.h"
#include "misc_gui.h"
#include "about_gui.h"
#include "ult_ext.h"
tsl::elm::Element* MainGui::baseUI() {
auto* list = new BoxClippedList();
this->listElement = list;
this->listUI();
return list;
}
void MainGui::listUI()
{

View File

@@ -34,6 +34,8 @@ class MainGui : public BaseMenuGui
public:
MainGui() {}
~MainGui() {}
tsl::elm::Element* baseUI() override;
void listUI() override;
void refresh() override;
u16 headerHeight() const override { return HOC_HEADER_HEIGHT - 25; }
};

View File

@@ -17,6 +17,7 @@
*/
#include "misc_gui.h"
#include "ult_ext.h"
#include "fatal_gui.h"
#include "config_info_strings.h"
#include "../format.h"
@@ -547,7 +548,7 @@ void MiscGui::listUI()
ValueThresholds thresholdsDisabled(0, 0);
std::vector<NamedValue> noNamedValues = {};
this->listElement->addItem(new tsl::elm::CategoryHeader("Settings"));
this->listElement->addItem(new CompactCategoryHeader("Settings"));
tsl::elm::CustomDrawer* rebootSetWarning = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) {
renderer->drawString("\uE150 Settings marked in blue", false, x + 20, y + 30, 18, tsl::style::color::ColorText);
@@ -659,7 +660,7 @@ protected:
void listUI() override {
Result rc = hocclkIpcGetConfigValues(this->configList);
if (R_FAILED(rc)) [[unlikely]] { FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc); return; }
this->listElement->addItem(new tsl::elm::CategoryHeader("General Settings"));
this->listElement->addItem(new CompactCategoryHeader("General Settings"));
ValueThresholds thresholdsDisabled(0, 0);
std::vector<NamedValue> ramVoltDispModes = {
@@ -719,7 +720,7 @@ protected:
void listUI() override {
Result rc = hocclkIpcGetConfigValues(this->configList);
if (R_FAILED(rc)) [[unlikely]] { FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc); return; }
this->listElement->addItem(new tsl::elm::CategoryHeader("Experimental Settings"));
this->listElement->addItem(new CompactCategoryHeader("Experimental Settings"));
ValueThresholds thresholdsDisabled(0, 0);
if(IsMariko()) {
addConfigToggle(HocClkConfigValue_MarikoMiddleFreqs, nullptr, true);
@@ -855,7 +856,7 @@ protected:
void listUI() override {
Result rc = hocclkIpcGetConfigValues(this->configList);
if (R_FAILED(rc)) [[unlikely]] { FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc); return; }
this->listElement->addItem(new tsl::elm::CategoryHeader("Governor Settings"));
this->listElement->addItem(new CompactCategoryHeader("Governor Settings"));
ValueThresholds thresholdsDisabled(0, 0);
std::vector<NamedValue> GovernorMinHz = {
@@ -896,7 +897,7 @@ protected:
if(!this->context)
return;
this->listElement->addItem(new tsl::elm::CategoryHeader("Display Settings"));
this->listElement->addItem(new CompactCategoryHeader("Display Settings"));
addConfigToggle(HocClkConfigValue_OverwriteRefreshRate, nullptr);
if(!this->context->isUsingRetroSuper) {
tsl::elm::CustomDrawer* warningText = new tsl::elm::CustomDrawer([](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) {
@@ -951,7 +952,7 @@ protected:
void listUI() override {
Result rc = hocclkIpcGetConfigValues(this->configList);
if (R_FAILED(rc)) [[unlikely]] { FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc); return; }
this->listElement->addItem(new tsl::elm::CategoryHeader("Safety Settings"));
this->listElement->addItem(new CompactCategoryHeader("Safety Settings"));
addConfigToggle(HocClkConfigValue_UncappedClocks, nullptr);
addConfigToggle(HocClkConfigValue_ThermalThrottle, nullptr);
addConfigToggle(HocClkConfigValue_HandheldTDP, nullptr);
@@ -1011,7 +1012,7 @@ protected:
this->listElement->addItem(new tsl::elm::CategoryHeader("RAM Settings"));
this->listElement->addItem(new CompactCategoryHeader("RAM Settings"));
addMappedConfigTrackbar(KipConfigValue_emcDvbShift, "DVB Shift",
{0xFFFFFFFCu, 0xFFFFFFFDu, 0xFFFFFFFEu, 0xFFFFFFFFu, 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u},
@@ -1251,7 +1252,7 @@ protected:
void listUI() override {
Result rc = hocclkIpcGetConfigValues(this->configList);
if (R_FAILED(rc)) [[unlikely]] { FatalGui::openWithResultCode("hocclkIpcGetConfigValues", rc); return; }
this->listElement->addItem(new tsl::elm::CategoryHeader("Memory Timings"));
this->listElement->addItem(new CompactCategoryHeader("Memory Timings"));
addConfigTrackbar(KipConfigValue_t1_tRCD, "t1 tRCD", ValueRange(0, 7, 1));
addConfigTrackbar(KipConfigValue_t2_tRP, "t2 tRP", ValueRange(0, 7, 1));
@@ -1332,7 +1333,7 @@ protected:
}
ValueThresholds thresholdsDisabled(0, 0);
this->listElement->addItem(new tsl::elm::CategoryHeader("Advanced"));
this->listElement->addItem(new CompactCategoryHeader("Advanced"));
if(IsMariko()) {
// tBreak / low-high timing graph (live, reads config each frame)
{
@@ -1483,6 +1484,13 @@ class RamLatenciesSubmenuGui : public MiscGui {
public:
RamLatenciesSubmenuGui() { }
tsl::elm::Element* baseUI() override {
auto* list = new TopAnchoredList();
this->listElement = list;
this->listUI();
return list;
}
protected:
void normalizeLatencies(const HocClkConfigValue keysArr[4]) {
@@ -1729,6 +1737,8 @@ protected:
this->configNamedValues[thisKey] = buildNamedValues(tierIdx);
};
this->listElement->addItem(new CompactCategoryHeader("Latency Graph"));
{
HocClkConfigValueList* cfgPtr = this->configList;
bool mariko = IsMariko();
@@ -1764,7 +1774,7 @@ protected:
const s32 gx = x + 52;
const s32 gw = w - 64;
const s32 gy = y + 14;
const s32 gh = 72;
const s32 gh = 54;
const s32 th = gh / 3;
const s32 axisY = gy + gh;
@@ -1916,7 +1926,7 @@ protected:
}
}
s32 ly = y + h - 14;
const s32 ly = axisY + 46;
renderer->drawRect(gx, ly, 14, 3, cRead);
renderer->drawString("Read", false, gx + 17, ly + 5, 12, cRead);
renderer->drawRect(gx + 60, ly, 14, 3, cWrite);
@@ -1925,15 +1935,15 @@ protected:
renderer->drawString("Same", false, gx + 142, ly + 5, 12, cMerge);
}
);
graph->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 165);
graph->setBoundaries(0, 0, tsl::cfg::FramebufferWidth, 150);
this->listElement->addItem(graph);
}
this->listElement->addItem(new tsl::elm::CategoryHeader("Read Latency"));
this->listElement->addItem(new CompactCategoryHeader("Read Latency"));
for (int i = 0; i < 4; i++)
addLatencyRow(kTierLabels[i], i, kLatencyRKeys);
this->listElement->addItem(new tsl::elm::CategoryHeader("Write Latency"));
this->listElement->addItem(new CompactCategoryHeader("Write Latency"));
for (int i = 0; i < 4; i++)
addLatencyRow(kTierLabels[i], i, kLatencyWKeys);
}
@@ -1957,7 +1967,7 @@ protected:
ValueThresholds eCpuClockThresholds(1785000, 2091000);
ValueThresholds eCpuClockThresholdsUV(2091000, 2193000);
this->listElement->addItem(new tsl::elm::CategoryHeader("CPU Settings"));
this->listElement->addItem(new CompactCategoryHeader("CPU Settings"));
if(IsMariko()) {
addConfigTrackbar(KipConfigValue_marikoCpuUVLow, "CPU Low UV", ValueRange(0, 8, 1));
addConfigTrackbar(KipConfigValue_marikoCpuUVHigh, "CPU High UV", ValueRange(0, 12, 1));
@@ -2152,7 +2162,7 @@ protected:
ValueThresholds thresholdsDisabled(0, 0);
std::vector<NamedValue> noNamedValues = {};
this->listElement->addItem(new tsl::elm::CategoryHeader("GPU Settings"));
this->listElement->addItem(new CompactCategoryHeader("GPU Settings"));
std::vector<NamedValue> gpuUvConf = {
NamedValue("HiOPT", 0),
@@ -2363,7 +2373,7 @@ protected:
return;
}
this->listElement->addItem(new tsl::elm::CategoryHeader("GPU Custom Table (mV)"));
this->listElement->addItem(new CompactCategoryHeader("GPU Custom Table (mV)"));
ValueThresholds MgpuVmaxThresholds(800, 850);
ValueThresholds EgpuVmaxThresholds(950, 975);

View File

@@ -17,6 +17,28 @@
#pragma once
#include <tesla.hpp>
#include "../elements/base_frame.h"
class TopAnchoredList : public tsl::elm::List {
public:
TopAnchoredList() { m_hasSetInitialFocusHack = true; }
};
class BoxClippedList : public tsl::elm::List {
public:
void draw(tsl::gfx::Renderer* renderer) override {
renderer->enableScissoring(0, HOC_BOX_BOTTOM, tsl::cfg::FramebufferWidth, tsl::cfg::FramebufferHeight - HOC_BOX_BOTTOM);
tsl::elm::List::draw(renderer);
renderer->disableScissoring();
}
};
class CompactCategoryHeader : public tsl::elm::CategoryHeader {
public:
CompactCategoryHeader(const std::string& text) : tsl::elm::CategoryHeader(text) {}
void layout(u16 parentX, u16 parentY, u16 parentWidth, u16 parentHeight) override {
this->setBoundaries(this->getX(), this->getY(), this->getWidth(), 33);
}
};
class ImageElement : public tsl::elm::ListItem {
private:

View File

@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ult_ext.h"
#include "value_choice_gui.h"
#include "../format.h"
#include "fatal_gui.h"