sysclk: remove old hocclk, bump version

This commit is contained in:
souldbminersmwc
2026-04-01 15:58:40 -04:00
parent 80fa802e88
commit e20bafd6ab
199 changed files with 13967 additions and 657 deletions

5
Source/hoc-clk/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
/dist
.DS_Store
Thumbs.db
desktop.ini
.vscode

View File

@@ -0,0 +1,17 @@
image: $CI_SERVER_HOST:4567/libretro/infrastructure/libretro-build-libnx-devkitpro:latest
variables:
PACKAGE_FOLDER: "sys-clk"
stages:
- package
nightly:
stage: package
script:
- bash build.sh $PACKAGE_FOLDER
artifacts:
name: $PACKAGE_FOLDER
expire_in: 24 hours
paths:
- $PACKAGE_FOLDER

3
Source/hoc-clk/.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "overlay/lib/libultrahand"]
path = overlay/lib/libultrahand
url = https://github.com/ppkantorski/libultrahand

7
Source/hoc-clk/LICENSE Normal file
View File

@@ -0,0 +1,7 @@
--------------------------------------------------------------------------
"THE BEER-WARE LICENSE" (Revision 42):
<p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
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
--------------------------------------------------------------------------

6
Source/hoc-clk/README.md Normal file
View File

@@ -0,0 +1,6 @@
# hoc-clk
Switch sysmodule allowing you to set cpu/gpu/mem clocks according to the running application and docked state.
Modified for Horizon OC
Support is only provided for FW 16.0.0+. This MAY work on older firmwares but support is NOT guaranteed

53
Source/hoc-clk/bitmap.py Normal file
View File

@@ -0,0 +1,53 @@
from PIL import Image
import argparse
import os
def image_to_rgba8888_array(image_path, output_path):
# Open and convert to RGBA
img = Image.open(image_path).convert('RGBA')
width, height = img.size
# Get pixel data
pixels = img.tobytes()
# Write as C header file
with open(output_path, 'w') as f:
f.write('// This is a automatically generated file, do not edit manually.\n')
f.write(f'// {os.path.basename(image_path)} - {width}x{height}\n')
f.write(f'const unsigned int IMG_WIDTH = {width};\n')
f.write(f'const unsigned int IMG_HEIGHT = {height};\n')
f.write('const unsigned char IMG_DATA[] = {\n ')
for i, byte in enumerate(pixels):
f.write(f'0x{byte:02X}')
if i < len(pixels) - 1:
f.write(', ')
if (i + 1) % 12 == 0:
f.write('\n ')
f.write('\n};\n')
print(f'Converted: {width}x{height} -> {len(pixels)} bytes')
print(f'Output: {output_path}')
def main():
parser = argparse.ArgumentParser(
description='PNG to RGB8888 script'
)
parser.add_argument('input', help='Input image file (e.g. cat.png)')
parser.add_argument(
'-o', '--output',
help='Output header file (default: <input>.h)'
)
args = parser.parse_args()
output_path = args.output
if not output_path:
base, _ = os.path.splitext(args.input)
output_path = base + '.h'
image_to_rgba8888_array(args.input, output_path)
if __name__ == '__main__':
main()

41
Source/hoc-clk/build.sh Normal file
View File

@@ -0,0 +1,41 @@
#!/bin/bash
set -e
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
DIST_DIR="$ROOT_DIR/dist"
CORES="$(nproc --all)"
if [[ -n "$1" ]]; then
DIST_DIR="$1"
fi
echo "DIST_DIR: $DIST_DIR"
echo "CORES: $CORES"
echo "*** sysmodule ***"
TITLE_ID="$(grep -oP '"title_id":\s*"0x\K(\w+)' "$ROOT_DIR/sysmodule/perms.json")"
pushd "$ROOT_DIR/sysmodule"
make -j$CORES
popd > /dev/null
mkdir -p "$DIST_DIR/atmosphere/contents/$TITLE_ID/flags"
cp -vf "$ROOT_DIR/sysmodule/out/horizon-oc.nsp" "$DIST_DIR/atmosphere/contents/$TITLE_ID/exefs.nsp"
>"$DIST_DIR/atmosphere/contents/$TITLE_ID/flags/boot2.flag"
cp -vf "$ROOT_DIR/sysmodule/toolbox.json" "$DIST_DIR/atmosphere/contents/$TITLE_ID/toolbox.json"
echo "*** overlay ***"
pushd "$ROOT_DIR/overlay"
make -j$CORES
popd > /dev/null
mkdir -p "$DIST_DIR/switch/.overlays"
cp -vf "$ROOT_DIR/overlay/out/horizon-oc-overlay.ovl" "$DIST_DIR/switch/.overlays/horizon-oc-overlay.ovl"
echo "*** assets ***"
mkdir -p "$DIST_DIR/config/horizon-oc"
cp -vf "$ROOT_DIR/config.ini.template" "$DIST_DIR/config/horizon-oc/config.ini.template"
cp -vf "$ROOT_DIR/../../README.md" "$DIST_DIR/README.md"
echo "*** lang ***"
cp -r "$ROOT_DIR/overlay/lang/" "$DIST_DIR/config/horizon-oc/lang/"

View File

@@ -0,0 +1,248 @@
/*
* Copyright (c) MasaGratoR
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "ipc.h"
Handle saltysd_orig;
Result SaltySD_Connect() {
for (int i = 0; i < 200; i++) {
if (!svcConnectToNamedPort(&saltysd_orig, "SaltySD"))
return 0;
svcSleepThread(1000*1000);
}
return 1;
}
Result SaltySD_Term()
{
Result ret;
IpcCommand c;
ipcInitialize(&c);
ipcSendPid(&c);
struct input
{
u64 magic;
u64 cmd_id;
u64 zero;
u64 reserved[2];
} *raw;
raw = (input*)ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 0;
raw->zero = 0;
ret = ipcDispatch(saltysd_orig);
if (R_SUCCEEDED(ret))
{
IpcParsedCommand r;
ipcParse(&r);
struct output {
u64 magic;
u64 result;
} *resp = (output*)r.Raw;
ret = resp->result;
}
// Session terminated works too.
svcCloseHandle(saltysd_orig);
if (ret == 0xf601) return 0;
return ret;
}
Result SaltySD_CheckIfSharedMemoryAvailable(ptrdiff_t *offset, u64 size)
{
Result ret = 0;
// Send a command
IpcCommand c;
ipcInitialize(&c);
ipcSendPid(&c);
struct input {
u64 magic;
u64 cmd_id;
u64 size;
u32 reserved[2];
} *raw;
raw = (input*)ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 6;
raw->size = size;
ret = ipcDispatch(saltysd_orig);
if (R_SUCCEEDED(ret)) {
IpcParsedCommand r;
ipcParse(&r);
struct output {
u64 magic;
u64 result;
u64 offset;
} *resp = (output*)r.Raw;
ret = resp->result;
if (!ret)
{
*offset = resp->offset;
}
}
return ret;
}
Result SaltySD_GetSharedMemoryHandle(Handle *retrieve)
{
Result ret = 0;
// Send a command
IpcCommand c;
ipcInitialize(&c);
ipcSendPid(&c);
struct input {
u64 magic;
u64 cmd_id;
u32 reserved[4];
} *raw;
raw = (input*)ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 7;
ret = ipcDispatch(saltysd_orig);
if (R_SUCCEEDED(ret)) {
IpcParsedCommand r;
ipcParse(&r);
struct output {
u64 magic;
u64 result;
u64 reserved[2];
} *resp = (output*)r.Raw;
ret = resp->result;
if (!ret)
{
*retrieve = r.Handles[0];
}
}
return ret;
}
Result SaltySD_GetDisplayRefreshRate(uint8_t* refreshRate)
{
Result ret = 0;
// Send a command
IpcCommand c;
ipcInitialize(&c);
ipcSendPid(&c);
struct input {
u64 magic;
u64 cmd_id;
u64 zero;
u64 reserved;
} *raw;
raw = (input*)ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 10;
raw->zero = 0;
ret = ipcDispatch(saltysd_orig);
if (R_SUCCEEDED(ret)) {
IpcParsedCommand r;
ipcParse(&r);
struct output {
u64 magic;
u64 result;
u64 refreshRate;
u64 reserved;
} *resp = (output*)r.Raw;
ret = resp->result;
if (!ret)
{
*refreshRate = (uint8_t)(resp->refreshRate);
}
}
return ret;
}
Result SaltySD_SetDisplayRefreshRate(uint8_t refreshRate)
{
Result ret = 0;
// Send a command
IpcCommand c;
ipcInitialize(&c);
ipcSendPid(&c);
struct input {
u64 magic;
u64 cmd_id;
u64 refreshRate;
u64 reserved;
} *raw;
raw = (input*)ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 11;
raw->refreshRate = refreshRate;
ret = ipcDispatch(saltysd_orig);
if (R_SUCCEEDED(ret)) {
IpcParsedCommand r;
ipcParse(&r);
struct output {
u64 magic;
u64 result;
u64 reserved[2];
} *resp = (output*)r.Raw;
ret = resp->result;
}
return ret;
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <switch.h>
#include <inttypes.h>
#include <string.h>
typedef enum {
BatteryFlag_NoHub = BIT(0), // Hub is disconnected
BatteryFlag_Rail = BIT(8), // At least one Joy-con is charging from rail
BatteryFlag_SPDSRC = BIT(12), // OTG
BatteryFlag_ACC = BIT(16) // Accessory
} BatteryChargeFlags;
typedef enum {
PDState_NewPDO = 1, // Received new Power Data Object
PDState_NoPD = 2, // No Power Delivery source is detected
PDState_AcceptedRDO = 3 // Received and accepted Request Data Object
} BatteryPDControllerState;
// Charger type detection
typedef enum {
ChargerType_None = 0,
ChargerType_PD = 1,
ChargerType_TypeC_1500mA = 2,
ChargerType_TypeC_3000mA = 3,
ChargerType_DCP = 4, // Dedicated Charging Port
ChargerType_CDP = 5, // Charging Downstream Port
ChargerType_SDP = 6, // Standard Downstream Port
ChargerType_Apple_500mA = 7,
ChargerType_Apple_1000mA = 8,
ChargerType_Apple_2000mA = 9
} BatteryChargerType;
typedef enum {
PowerRole_Sink = 1, // Device is receiving power
PowerRole_Source = 2 // Device is providing power
} BatteryPowerRole;
typedef struct {
int32_t InputCurrentLimit; // Input (Sink) current limit in mA
int32_t VBUSCurrentLimit; // Output (Source/VBUS/OTG) current limit in mA
int32_t ChargeCurrentLimit; // Battery charging current limit in mA
int32_t ChargeVoltageLimit; // Battery charging voltage limit in mV
int32_t unk_x10; // Unknown field (possibly enum)
int32_t unk_x14; // Unknown field (possibly flags)
BatteryPDControllerState PDControllerState; // PD Controller State
int32_t BatteryTemperature; // Battery temperature in milli-Celsius
int32_t RawBatteryCharge; // Battery charge in percentmille
int32_t VoltageAvg; // Average voltage in mV
int32_t BatteryAge; // Battery health (capacity full/design) in pcm
BatteryPowerRole PowerRole; // Current power role
BatteryChargerType ChargerType; // Type of charger connected
int32_t ChargerVoltageLimit; // Charger voltage limit in mV
int32_t ChargerCurrentLimit; // Charger current limit in mA
BatteryChargeFlags Flags; // Various status flags
} BatteryChargeInfo;
#define IS_BATTERY_CHARGING_ENABLED(info) (((info)->unk_x14 >> 8) & 1)
static inline int batteryInfoGetTemperatureMiliCelsius(BatteryChargeInfo *info) {
return info->BatteryTemperature;
}
static inline float batteryInfoGetChargePercent(BatteryChargeInfo *info) {
return (float)info->RawBatteryCharge / 1000.0f;
}
static inline float batteryInfoGetBatteryHealthPercent(BatteryChargeInfo *info) {
return (float)info->BatteryAge / 1000.0f;
}
static inline bool batteryInfoIsCharging(BatteryChargeInfo *info) {
return IS_BATTERY_CHARGING_ENABLED(info);
}
Result batteryInfoInitialize(void);
void batteryInfoExit(void);
Result batteryInfoGetChargeInfo(BatteryChargeInfo *out);
Result batteryInfoGetChargePercentage(u32 *out);
Result batteryInfoIsEnoughPowerSupplied(bool *out);
Result batteryInfoEnableCharging(void);
Result batteryInfoDisableCharging(void);
Result batteryInfoEnableFastCharging(void);
Result batteryInfoDisableFastCharging(void);
const char* batteryInfoGetChargerTypeString(BatteryChargerType type);
const char* batteryInfoGetPowerRoleString(BatteryPowerRole role);
const char* batteryInfoGetPDStateString(BatteryPDControllerState state);

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) meha3945 (hanai3bi)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <utility>
template<typename F>
class ScopeGuard {
public:
ScopeGuard(F&& f)
: f(f), engaged(true) {};
~ScopeGuard() {
if (engaged)
f();
};
ScopeGuard(ScopeGuard&& rhs)
: f(std::move(rhs.f)) {};
void dismiss() { engaged = false; }
private:
F f;
bool engaged;
};
struct MakeScopeExit {
template<typename F>
ScopeGuard<F> operator+=(F&& f) {
return ScopeGuard<F>(std::move(f));
};
};
#define STRING_CAT2(x, y) x##y
#define STRING_CAT(x, y) STRING_CAT2(x, y)
#define SCOPE_GUARD MakeScopeExit() += [&]() __attribute__((always_inline))
#define SCOPE_EXIT auto STRING_CAT(scope_exit_, __LINE__) = SCOPE_GUARD

View File

@@ -0,0 +1,24 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <stdio.h>
#include <stdint.h>
namespace crc32 {
uint32_t crc32(const uint8_t *data, size_t length);
uint32_t checksum_file(const char *filename);
}

View File

@@ -0,0 +1,314 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 shuffle2
* Copyright (c) 2018 balika011
* Copyright (c) 2019-2025 CTCaer
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _FUSE_H_
#define _FUSE_H_
#ifndef BIT
#define BIT(n) (1U<<(n))
#endif
/*! Fuse registers. */
#define FUSE_CTRL 0x0
#define FUSE_ADDR 0x4
#define FUSE_RDATA 0x8
#define FUSE_WDATA 0xC
#define FUSE_TIME_RD1 0x10
#define FUSE_TIME_RD2 0x14
#define FUSE_TIME_PGM1 0x18
#define FUSE_TIME_PGM2 0x1C
#define FUSE_PRIV2INTFC 0x20
#define FUSE_PRIV2INTFC_START_DATA BIT(0)
#define FUSE_PRIV2INTFC_SKIP_RECORDS BIT(1)
#define FUSE_FUSEBYPASS 0x24
#define FUSE_PRIVATEKEYDISABLE 0x28
#define FUSE_PRIVKEY_DISABLE BIT(0)
#define FUSE_PRIVKEY_TZ_STICKY_BIT BIT(4)
#define FUSE_DISABLEREGPROGRAM 0x2C
#define FUSE_WRITE_ACCESS_SW 0x30
#define FUSE_PWR_GOOD_SW 0x34
#define FUSE_PRIV2RESHIFT 0x3C
#define FUSE_FUSETIME_RD0 0x40
#define FUSE_FUSETIME_RD1 0x44
#define FUSE_FUSETIME_RD2 0x48
#define FUSE_FUSETIME_RD3 0x4C
#define FUSE_PRIVATE_KEY0_NONZERO 0x80
#define FUSE_PRIVATE_KEY1_NONZERO 0x84
#define FUSE_PRIVATE_KEY2_NONZERO 0x88
#define FUSE_PRIVATE_KEY3_NONZERO 0x8C
#define FUSE_PRIVATE_KEY4_NONZERO 0x90
/*! Fuse Cached registers */
#define FUSE_RESERVED_ODM8_B01 0x98 // FUSE_READ_TZ Group 0.
#define FUSE_RESERVED_ODM9_B01 0x9C // FUSE_READ_TZ Group 0.
#define FUSE_RESERVED_ODM10_B01 0xA0 // FUSE_READ_TZ Group 0.
#define FUSE_RESERVED_ODM11_B01 0xA4 // FUSE_READ_TZ Group 0.
#define FUSE_RESERVED_ODM12_B01 0xA8 // FUSE_READ_TZ Group 1? Is value -1?
#define FUSE_RESERVED_ODM13_B01 0xAC // FUSE_READ_TZ Group 1? Is value -1?
#define FUSE_RESERVED_ODM14_B01 0xB0 // FUSE_READ_TZ Group 1? Is value -1?
#define FUSE_RESERVED_ODM15_B01 0xB4 // FUSE_READ_TZ Group 1? Is value -1?
#define FUSE_RESERVED_ODM16_B01 0xB8 // FUSE_READ_TZ Group 2? Is value -1?
#define FUSE_RESERVED_ODM17_B01 0xBC // FUSE_READ_TZ Group 2? Is value -1?
#define FUSE_RESERVED_ODM18_B01 0xC0 // FUSE_READ_TZ Group 2.
#define FUSE_RESERVED_ODM19_B01 0xC4 // FUSE_READ_TZ Group 2.
#define FUSE_RESERVED_ODM20_B01 0xC8 // FUSE_READ_TZ Group 3.
#define FUSE_RESERVED_ODM21_B01 0xCC // FUSE_READ_TZ Group 3.
#define FUSE_KEK00_B01 0xD0
#define FUSE_KEK01_B01 0xD4
#define FUSE_KEK02_B01 0xD8
#define FUSE_KEK03_B01 0xDC
#define FUSE_BEK00_B01 0xE0
#define FUSE_BEK01_B01 0xE4
#define FUSE_BEK02_B01 0xE8
#define FUSE_BEK03_B01 0xEC
#define FUSE_OPT_RAM_RTSEL_TSMCSP_PO4SVT_B01 0xF0
#define FUSE_OPT_RAM_WTSEL_TSMCSP_PO4SVT_B01 0xF4
#define FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4SVT_B01 0xF8
#define FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4SVT_B01 0xFC
#define FUSE_PRODUCTION_MODE 0x100
#define FUSE_JTAG_SECUREID_VALID 0x104
#define FUSE_ODM_LOCK 0x108
#define FUSE_OPT_OPENGL_EN 0x10C
#define FUSE_SKU_INFO 0x110
#define FUSE_CPU_SPEEDO_0_CALIB 0x114
#define FUSE_CPU_IDDQ_CALIB 0x118
#define FUSE_RESERVED_ODM22_B01 0x11C // FUSE_READ_TZ Group 3.
#define FUSE_RESERVED_ODM23_B01 0x120 // FUSE_READ_TZ Group 3.
#define FUSE_RESERVED_ODM24_B01 0x124 // FUSE_READ_TZ Group 4.
#define FUSE_OPT_FT_REV 0x128
#define FUSE_CPU_SPEEDO_1_CALIB 0x12C
#define FUSE_CPU_SPEEDO_2_CALIB 0x130
#define FUSE_SOC_SPEEDO_0_CALIB 0x134
#define FUSE_SOC_SPEEDO_1_CALIB 0x138
#define FUSE_SOC_SPEEDO_2_CALIB 0x13C
#define FUSE_SOC_IDDQ_CALIB 0x140
#define FUSE_RESERVED_ODM25_B01 0x144 // FUSE_READ_TZ Group 4.
#define FUSE_FA 0x148
#define FUSE_RESERVED_PRODUCTION 0x14C
#define FUSE_HDMI_LANE0_CALIB 0x150
#define FUSE_HDMI_LANE1_CALIB 0x154
#define FUSE_HDMI_LANE2_CALIB 0x158
#define FUSE_HDMI_LANE3_CALIB 0x15C
#define FUSE_ENCRYPTION_RATE 0x160
#define FUSE_PUBLIC_KEY0 0x164
#define FUSE_PUBLIC_KEY1 0x168
#define FUSE_PUBLIC_KEY2 0x16C
#define FUSE_PUBLIC_KEY3 0x170
#define FUSE_PUBLIC_KEY4 0x174
#define FUSE_PUBLIC_KEY5 0x178
#define FUSE_PUBLIC_KEY6 0x17C
#define FUSE_PUBLIC_KEY7 0x180
#define FUSE_TSENSOR1_CALIB 0x184 // CPU1.
#define FUSE_TSENSOR2_CALIB 0x188 // CPU2.
#define FUSE_OPT_SECURE_SCC_DIS_B01 0x18C
#define FUSE_OPT_CP_REV 0x190 // FUSE style revision - ATE. 0x101 0x100
#define FUSE_OPT_PFG 0x194
#define FUSE_TSENSOR0_CALIB 0x198 // CPU0.
#define FUSE_FIRST_BOOTROM_PATCH_SIZE 0x19C
#define FUSE_SECURITY_MODE 0x1A0
#define FUSE_PRIVATE_KEY0 0x1A4
#define FUSE_PRIVATE_KEY1 0x1A8
#define FUSE_PRIVATE_KEY2 0x1AC
#define FUSE_PRIVATE_KEY3 0x1B0
#define FUSE_PRIVATE_KEY4 0x1B4
#define FUSE_ARM_JTAG_DIS 0x1B8
#define FUSE_BOOT_DEVICE_INFO 0x1BC
#define FUSE_RESERVED_SW 0x1C0
#define FUSE_OPT_VP9_DISABLE 0x1C4
#define FUSE_RESERVED_ODM0 0x1C8
#define FUSE_RESERVED_ODM1 0x1CC
#define FUSE_RESERVED_ODM2 0x1D0
#define FUSE_RESERVED_ODM3 0x1D4
#define FUSE_RESERVED_ODM4 0x1D8
#define FUSE_RESERVED_ODM5 0x1DC
#define FUSE_RESERVED_ODM6 0x1E0
#define FUSE_RESERVED_ODM7 0x1E4
#define FUSE_OBS_DIS 0x1E8
#define FUSE_OPT_NVJTAG_PROTECTION_ENABLE_B01 0x1EC
#define FUSE_USB_CALIB 0x1F0
#define FUSE_SKU_DIRECT_CONFIG 0x1F4
#define FUSE_KFUSE_PRIVKEY_CTRL 0x1F8
#define FUSE_PACKAGE_INFO 0x1FC // 1: MID, 2: DSC.
#define FUSE_OPT_VENDOR_CODE 0x200
#define FUSE_OPT_FAB_CODE 0x204
#define FUSE_OPT_LOT_CODE_0 0x208
#define FUSE_OPT_LOT_CODE_1 0x20C
#define FUSE_OPT_WAFER_ID 0x210
#define FUSE_OPT_X_COORDINATE 0x214
#define FUSE_OPT_Y_COORDINATE 0x218
#define FUSE_OPT_SEC_DEBUG_EN 0x21C
#define FUSE_OPT_OPS_RESERVED 0x220
#define FUSE_SATA_CALIB 0x224
#define FUSE_SPARE_REGISTER_ODM_B01 0x224
#define FUSE_GPU_IDDQ_CALIB 0x228
#define FUSE_TSENSOR3_CALIB 0x22C // CPU3.
#define FUSE_CLOCK_BONDOUT0 0x230
#define FUSE_CLOCK_BONDOUT1 0x234
#define FUSE_RESERVED_ODM26_B01 0x238 // FUSE_READ_TZ Group 4.
#define FUSE_RESERVED_ODM27_B01 0x23C // FUSE_READ_TZ Group 4.
#define FUSE_RESERVED_ODM28_B01 0x240 // MAX77812 phase configuration. FUSE_READ_TZ Group 5.
#define FUSE_OPT_SAMPLE_TYPE 0x244
#define FUSE_OPT_SUBREVISION 0x248 // "", "p", "q", "r". e.g: A01p.
#define FUSE_OPT_SW_RESERVED_0 0x24C
#define FUSE_OPT_SW_RESERVED_1 0x250
#define FUSE_TSENSOR4_CALIB 0x254 // GPU.
#define FUSE_TSENSOR5_CALIB 0x258 // MEM0.
#define FUSE_TSENSOR6_CALIB 0x25C // MEM1.
#define FUSE_TSENSOR7_CALIB 0x260 // PLLX.
#define FUSE_OPT_PRIV_SEC_DIS 0x264
#define FUSE_PKC_DISABLE 0x268
#define FUSE_BOOT_SECURITY_INFO_B01 0x268
#define FUSE_OPT_RAM_RTSEL_TSMCSP_PO4HVT_B01 0x26C
#define FUSE_OPT_RAM_WTSEL_TSMCSP_PO4HVT_B01 0x270
#define FUSE_OPT_RAM_RTSEL_TSMCPDP_PO4HVT_B01 0x274
#define FUSE_OPT_RAM_MTSEL_TSMCPDP_PO4HVT_B01 0x278
#define FUSE_FUSE2TSEC_DEBUG_DISABLE 0x27C
#define FUSE_TSENSOR_COMMON 0x280
#define FUSE_OPT_CP_BIN 0x284
#define FUSE_OPT_GPU_DISABLE 0x288
#define FUSE_OPT_FT_BIN 0x28C
#define FUSE_OPT_DONE_MAP 0x290
#define FUSE_RESERVED_ODM29_B01 0x294 // FUSE_READ_TZ Group 5? Is value -1?
#define FUSE_APB2JTAG_DISABLE 0x298
#define FUSE_ODM_INFO 0x29C // Debug features disable.
#define FUSE_ARM_CRYPT_DE_FEATURE 0x2A8
#define FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4SVT_B01 0x2B0
#define FUSE_OPT_RAM_RCT_TSMCDP_PO4SVT_B01 0x2B4
#define FUSE_OPT_RAM_WCT_TSMCDP_PO4SVT_B01 0x2B8
#define FUSE_OPT_RAM_KP_TSMCDP_PO4SVT_B01 0x2BC
#define FUSE_WOA_SKU_FLAG 0x2C0
#define FUSE_ECO_RESERVE_1 0x2C4
#define FUSE_GCPLEX_CONFIG_FUSE 0x2C8
#define FUSE_GPU_VPR_AUTO_FETCH_DIS BIT(0)
#define FUSE_GPU_VPR_ENABLED BIT(1)
#define FUSE_GPU_WPR_ENABLED BIT(2)
#define FUSE_PRODUCTION_MONTH 0x2CC
#define FUSE_RAM_REPAIR_INDICATOR 0x2D0
#define FUSE_TSENSOR9_CALIB 0x2D4 // AOTAG.
#define FUSE_VMIN_CALIBRATION 0x2DC
#define FUSE_AGING_SENSOR_CALIBRATION 0x2E0
#define FUSE_DEBUG_AUTHENTICATION 0x2E4
#define FUSE_SECURE_PROVISION_INDEX 0x2E8
#define FUSE_SECURE_PROVISION_INFO 0x2EC
#define FUSE_OPT_GPU_DISABLE_CP1 0x2F0
#define FUSE_SPARE_ENDIS 0x2F4
#define FUSE_ECO_RESERVE_0 0x2F8 // AID.
#define FUSE_RESERVED_CALIB0 0x304 // GPCPLL ADC Calibration.
#define FUSE_RESERVED_CALIB1 0x308
#define FUSE_OPT_GPU_TPC0_DISABLE 0x30C
#define FUSE_OPT_GPU_TPC0_DISABLE_CP1 0x310
#define FUSE_OPT_CPU_DISABLE 0x314
#define FUSE_OPT_CPU_DISABLE_CP1 0x318
#define FUSE_TSENSOR10_CALIB 0x31C
#define FUSE_TSENSOR10_CALIB_AUX 0x320
#define FUSE_OPT_RAM_SVOP_DP 0x324
#define FUSE_OPT_RAM_SVOP_PDP 0x328
#define FUSE_OPT_RAM_SVOP_REG 0x32C
#define FUSE_OPT_RAM_SVOP_SP 0x330
#define FUSE_OPT_RAM_SVOP_SMPDP 0x334
#define FUSE_OPT_RAM_WTSEL_TSMCPDP_PO4HVT_B01 0x324
#define FUSE_OPT_RAM_RCT_TSMCDP_PO4HVT_B01 0x328
#define FUSE_OPT_RAM_WCT_TSMCDP_PO4HVT_B01 0x32c
#define FUSE_OPT_RAM_KP_TSMCDP_PO4HVT_B01 0x330
#define FUSE_OPT_RAM_SVOP_SP_B01 0x334
#define FUSE_OPT_GPU_TPC0_DISABLE_CP2 0x338
#define FUSE_OPT_GPU_TPC1_DISABLE 0x33C
#define FUSE_OPT_GPU_TPC1_DISABLE_CP1 0x340
#define FUSE_OPT_GPU_TPC1_DISABLE_CP2 0x344
#define FUSE_OPT_CPU_DISABLE_CP2 0x348
#define FUSE_OPT_GPU_DISABLE_CP2 0x34C
#define FUSE_USB_CALIB_EXT 0x350
#define FUSE_RESERVED_FIELD 0x354 // RMA.
#define FUSE_SPARE_REALIGNMENT_REG 0x37C
#define FUSE_SPARE_BIT_0 0x380
//...
#define FUSE_SPARE_BIT_31 0x3FC
/*! Fuse commands. */
#define FUSE_IDLE 0x0
#define FUSE_READ 0x1
#define FUSE_WRITE 0x2
#define FUSE_SENSE 0x3
#define FUSE_CMD_MASK 0x3
/*! Fuse status. */
#define FUSE_STATUS_RESET 0
#define FUSE_STATUS_POST_RESET 1
#define FUSE_STATUS_LOAD_ROW0 2
#define FUSE_STATUS_LOAD_ROW1 3
#define FUSE_STATUS_IDLE 4
#define FUSE_STATUS_READ_SETUP 5
#define FUSE_STATUS_READ_STROBE 6
#define FUSE_STATUS_SAMPLE_FUSES 7
#define FUSE_STATUS_READ_HOLD 8
#define FUSE_STATUS_FUSE_SRC_SETUP 9
#define FUSE_STATUS_WRITE_SETUP 10
#define FUSE_STATUS_WRITE_ADDR_SETUP 11
#define FUSE_STATUS_WRITE_PROGRAM 12
#define FUSE_STATUS_WRITE_ADDR_HOLD 13
#define FUSE_STATUS_FUSE_SRC_HOLD 14
#define FUSE_STATUS_LOAD_RIR 15
#define FUSE_STATUS_READ_BEFORE_WRITE_SETUP 16
#define FUSE_STATUS_READ_DEASSERT_PD 17
/*! Fuse cache registers. */
#define FUSE_RESERVED_ODMX(x) (0x1C8 + 4 * (x))
#define FUSE_ARRAY_WORDS_NUM 192
#define FUSE_ARRAY_WORDS_NUM_B01 256
enum
{
FUSE_NX_HW_TYPE_ICOSA,
FUSE_NX_HW_TYPE_IOWA,
FUSE_NX_HW_TYPE_HOAG,
FUSE_NX_HW_TYPE_AULA
};
enum
{
FUSE_NX_HW_STATE_PROD,
FUSE_NX_HW_STATE_DEV
};
#endif

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2023 KazushiMe
* Licensed under the GPLv2
*/
#pragma once
#include <switch.h>
// To use i2c service, sm and i2c should be intialized via smInitialize() and i2cInitialize().
Result I2cSet_U8(I2cDevice dev, u8 reg, u8 val);
Result I2cRead_OutU8(I2cDevice dev, u8 reg, u8 *out);
Result I2cRead_OutU16(I2cDevice dev, u8 reg, u16 *out);
// Max17050 fuel gauge
float I2c_Max17050_GetBatteryCurrent();
const u8 MAX17050_CURRENT_REG = 0x0A;
// Buck Converter
typedef enum I2c_BuckConverter_Reg {
I2c_Max77620_SD1VOLT_REG = 0x17, // Used for Erista DDR VDDQ+VDD2 / Mariko VDD2
I2c_Max77621_VOLT_REG = 0x00,
I2c_Max77812_CPUVOLT_REG = 0x26,
I2c_Max77812_GPUVOLT_REG = 0x23,
I2c_Max77812_MEMVOLT_REG = 0x25, // Master 3 (GPU 1 + 2, DRAM 3, CPU 4), used for Mariko VDDQ
} I2c_BuckConverter_Reg;
typedef struct I2c_BuckConverter_Domain {
I2cDevice device;
I2c_BuckConverter_Reg reg;
u8 volt_mask;
u32 uv_step;
u32 uv_min;
u32 uv_max;
u8 por_val;
} I2c_BuckConverter_Domain;
const I2c_BuckConverter_Domain I2c_Erista_CPU = { I2cDevice_Max77621Cpu, I2c_Max77621_VOLT_REG, 0x7F, 6250, 606250, 1400000, };
const I2c_BuckConverter_Domain I2c_Erista_GPU = { I2cDevice_Max77621Gpu, I2c_Max77621_VOLT_REG, 0x7F, 6250, 606250, 1400000, };
const I2c_BuckConverter_Domain I2c_Erista_DRAM = { I2cDevice_Max77620Pmic, I2c_Max77620_SD1VOLT_REG, 0x7F, 12500, 600000, 1250000, };
const I2c_BuckConverter_Domain I2c_Mariko_CPU = { I2cDevice_Max77812_2, I2c_Max77812_CPUVOLT_REG, 0xFF, 5000, 250000, 1525000, 0x78 };
const I2c_BuckConverter_Domain I2c_Mariko_GPU = { I2cDevice_Max77812_2, I2c_Max77812_GPUVOLT_REG, 0xFF, 5000, 250000, 1525000, 0x78 };
const I2c_BuckConverter_Domain I2c_Mariko_DRAM_VDDQ = { I2cDevice_Max77812_2, I2c_Max77812_MEMVOLT_REG, 0xFF, 5000, 250000, 700000, 0x78 };
const I2c_BuckConverter_Domain I2c_Mariko_DRAM_VDD2 = { I2cDevice_Max77620Pmic, I2c_Max77620_SD1VOLT_REG, 0x7F, 12500, 600000, 1250000, };
u32 I2c_BuckConverter_GetMvOut(const I2c_BuckConverter_Domain* domain);
Result I2c_BuckConverter_SetMvOut(const I2c_BuckConverter_Domain* domain, u32 mvolt);
// Bq24193 Battery management
u32 I2c_Bq24193_Convert_Raw_mA(u8 raw);
u8 I2c_Bq24193_Convert_mA_Raw(u32 ma);
Result I2c_Bq24193_GetFastChargeCurrentLimit(u32 *ma);
Result I2c_Bq24193_SetFastChargeCurrentLimit(u32 ma);
const u32 MA_RANGE_MIN = 512;
const u32 MA_RANGE_MAX = 4544;
const u8 BQ24193_CHARGE_CURRENT_CONTROL_REG = 0x2;

View File

@@ -0,0 +1,756 @@
/**
* @file ipc.h
* @brief Inter-process communication handling
* @author plutoo
* @copyright libnx Authors (ISC License)
*/
#pragma once
#include <switch.h>
/// IPC input header magic
#define SFCI_MAGIC 0x49434653
/// IPC output header magic
#define SFCO_MAGIC 0x4f434653
/// IPC invalid object ID
#define IPC_INVALID_OBJECT_ID UINT32_MAX
///@name IPC request building
///@{
/// IPC command (request) structure.
#define IPC_MAX_BUFFERS 8
#define IPC_MAX_OBJECTS 8
typedef enum {
BufferType_Normal=0, ///< Regular buffer.
BufferType_Type1=1, ///< Allows ProcessMemory and shared TransferMemory.
BufferType_Invalid=2,
BufferType_Type3=3 ///< Same as Type1 except remote process is not allowed to use device-mapping.
} BufferType;
typedef enum {
BufferDirection_Send=0,
BufferDirection_Recv=1,
BufferDirection_Exch=2,
} BufferDirection;
typedef enum {
IpcCommandType_Invalid = 0,
IpcCommandType_LegacyRequest = 1,
IpcCommandType_Close = 2,
IpcCommandType_LegacyControl = 3,
IpcCommandType_Request = 4,
IpcCommandType_Control = 5,
IpcCommandType_RequestWithContext = 6,
IpcCommandType_ControlWithContext = 7,
} IpcCommandType;
typedef enum {
DomainMessageType_Invalid = 0,
DomainMessageType_SendMessage = 1,
DomainMessageType_Close = 2,
} DomainMessageType;
/// IPC domain message header.
typedef struct {
u8 Type;
u8 NumObjectIds;
u16 Length;
u32 ThisObjectId;
u32 Pad[2];
} DomainMessageHeader;
/// IPC domain response header.
typedef struct {
u32 NumObjectIds;
u32 Pad[3];
} DomainResponseHeader;
typedef struct {
size_t NumSend; // A
size_t NumRecv; // B
size_t NumExch; // W
const void* Buffers[IPC_MAX_BUFFERS];
size_t BufferSizes[IPC_MAX_BUFFERS];
BufferType BufferTypes[IPC_MAX_BUFFERS];
size_t NumStaticIn; // X
size_t NumStaticOut; // C
const void* Statics[IPC_MAX_BUFFERS];
size_t StaticSizes[IPC_MAX_BUFFERS];
u8 StaticIndices[IPC_MAX_BUFFERS];
bool SendPid;
size_t NumHandlesCopy;
size_t NumHandlesMove;
Handle Handles[IPC_MAX_OBJECTS];
size_t NumObjectIds;
u32 ObjectIds[IPC_MAX_OBJECTS];
} IpcCommand;
/**
* @brief Initializes an IPC command structure.
* @param cmd IPC command structure.
*/
static inline void ipcInitialize(IpcCommand* cmd) {
*cmd = (IpcCommand){};
}
/// IPC buffer descriptor.
typedef struct {
u32 Size; ///< Size of the buffer.
u32 Addr; ///< Lower 32-bits of the address of the buffer
u32 Packed; ///< Packed data (including higher bits of the address)
} IpcBufferDescriptor;
/// IPC static send-buffer descriptor.
typedef struct {
u32 Packed; ///< Packed data (including higher bits of the address)
u32 Addr; ///< Lower 32-bits of the address
} IpcStaticSendDescriptor;
/// IPC static receive-buffer descriptor.
typedef struct {
u32 Addr; ///< Lower 32-bits of the address of the buffer
u32 Packed; ///< Packed data (including higher bits of the address)
} IpcStaticRecvDescriptor;
/**
* @brief Adds a buffer to an IPC command structure.
* @param cmd IPC command structure.
* @param buffer Address of the buffer.
* @param size Size of the buffer.
* @param type Buffer type.
*/
static inline void ipcAddSendBuffer(IpcCommand* cmd, const void* buffer, size_t size, BufferType type) {
size_t off = cmd->NumSend;
cmd->Buffers[off] = buffer;
cmd->BufferSizes[off] = size;
cmd->BufferTypes[off] = type;
cmd->NumSend++;
}
/**
* @brief Adds a receive-buffer to an IPC command structure.
* @param cmd IPC command structure.
* @param buffer Address of the buffer.
* @param size Size of the buffer.
* @param type Buffer type.
*/
static inline void ipcAddRecvBuffer(IpcCommand* cmd, void* buffer, size_t size, BufferType type) {
size_t off = cmd->NumSend + cmd->NumRecv;
cmd->Buffers[off] = buffer;
cmd->BufferSizes[off] = size;
cmd->BufferTypes[off] = type;
cmd->NumRecv++;
}
/**
* @brief Adds an exchange-buffer to an IPC command structure.
* @param cmd IPC command structure.
* @param buffer Address of the buffer.
* @param size Size of the buffer.
* @param type Buffer type.
*/
static inline void ipcAddExchBuffer(IpcCommand* cmd, void* buffer, size_t size, BufferType type) {
size_t off = cmd->NumSend + cmd->NumRecv + cmd->NumExch;
cmd->Buffers[off] = buffer;
cmd->BufferSizes[off] = size;
cmd->BufferTypes[off] = type;
cmd->NumExch++;
}
/**
* @brief Adds a static-buffer to an IPC command structure.
* @param cmd IPC command structure.
* @param buffer Address of the buffer.
* @param size Size of the buffer.
* @param index Index of buffer.
*/
static inline void ipcAddSendStatic(IpcCommand* cmd, const void* buffer, size_t size, u8 index) {
size_t off = cmd->NumStaticIn;
cmd->Statics[off] = buffer;
cmd->StaticSizes[off] = size;
cmd->StaticIndices[off] = index;
cmd->NumStaticIn++;
}
/**
* @brief Adds a static-receive-buffer to an IPC command structure.
* @param cmd IPC command structure.
* @param buffer Address of the buffer.
* @param size Size of the buffer.
* @param index Index of buffer.
*/
static inline void ipcAddRecvStatic(IpcCommand* cmd, void* buffer, size_t size, u8 index) {
size_t off = cmd->NumStaticIn + cmd->NumStaticOut;
cmd->Statics[off] = buffer;
cmd->StaticSizes[off] = size;
cmd->StaticIndices[off] = index;
cmd->NumStaticOut++;
}
/**
* @brief Adds a smart-buffer (buffer + static-buffer pair) to an IPC command structure.
* @param cmd IPC command structure.
* @param pointer_buffer_size Pointer buffer size.
* @param buffer Address of the buffer.
* @param size Size of the buffer.
* @param index Index of buffer.
*/
static inline void ipcAddSendSmart(IpcCommand* cmd, size_t pointer_buffer_size, const void* buffer, size_t size, u8 index) {
if (pointer_buffer_size != 0 && size <= pointer_buffer_size) {
ipcAddSendBuffer(cmd, NULL, 0, BufferType_Normal);
ipcAddSendStatic(cmd, buffer, size, index);
} else {
ipcAddSendBuffer(cmd, buffer, size, BufferType_Normal);
ipcAddSendStatic(cmd, NULL, 0, index);
}
}
/**
* @brief Adds a smart-receive-buffer (buffer + static-receive-buffer pair) to an IPC command structure.
* @param cmd IPC command structure.
* @param pointer_buffer_size Pointer buffer size.
* @param buffer Address of the buffer.
* @param size Size of the buffer.
* @param index Index of buffer.
*/
static inline void ipcAddRecvSmart(IpcCommand* cmd, size_t pointer_buffer_size, void* buffer, size_t size, u8 index) {
if (pointer_buffer_size != 0 && size <= pointer_buffer_size) {
ipcAddRecvBuffer(cmd, NULL, 0, BufferType_Normal);
ipcAddRecvStatic(cmd, buffer, size, index);
} else {
ipcAddRecvBuffer(cmd, buffer, size, BufferType_Normal);
ipcAddRecvStatic(cmd, NULL, 0, index);
}
}
/**
* @brief Tags an IPC command structure to send the PID.
* @param cmd IPC command structure.
*/
static inline void ipcSendPid(IpcCommand* cmd) {
cmd->SendPid = true;
}
/**
* @brief Adds a copy-handle to be sent through an IPC command structure.
* @param cmd IPC command structure.
* @param h Handle to send.
* @remark The receiving process gets a copy of the handle.
*/
static inline void ipcSendHandleCopy(IpcCommand* cmd, Handle h) {
cmd->Handles[cmd->NumHandlesCopy++] = h;
}
/**
* @brief Adds a move-handle to be sent through an IPC command structure.
* @param cmd IPC command structure.
* @param h Handle to send.
* @remark The sending process loses ownership of the handle, which is transferred to the receiving process.
*/
static inline void ipcSendHandleMove(IpcCommand* cmd, Handle h) {
cmd->Handles[cmd->NumHandlesCopy + cmd->NumHandlesMove++] = h;
}
/**
* @brief Prepares the header of an IPC command structure.
* @param cmd IPC command structure.
* @param sizeof_raw Size in bytes of the raw data structure to embed inside the IPC request
* @return Pointer to the raw embedded data structure in the request, ready to be filled out.
*/
static inline void* ipcPrepareHeader(IpcCommand* cmd, size_t sizeof_raw) {
u32* buf = (u32*)armGetTls();
size_t i;
*buf++ = IpcCommandType_Request | (cmd->NumStaticIn << 16) | (cmd->NumSend << 20) | (cmd->NumRecv << 24) | (cmd->NumExch << 28);
u32* fill_in_size_later = buf;
if (cmd->NumStaticOut > 0) {
*buf = (cmd->NumStaticOut + 2) << 10;
}
else {
*buf = 0;
}
if (cmd->SendPid || cmd->NumHandlesCopy > 0 || cmd->NumHandlesMove > 0) {
*buf++ |= 0x80000000;
*buf++ = (!!cmd->SendPid) | (cmd->NumHandlesCopy << 1) | (cmd->NumHandlesMove << 5);
if (cmd->SendPid)
buf += 2;
for (i=0; i<(cmd->NumHandlesCopy + cmd->NumHandlesMove); i++)
*buf++ = cmd->Handles[i];
}
else {
buf++;
}
for (i=0; i<cmd->NumStaticIn; i++, buf+=2) {
IpcStaticSendDescriptor* desc = (IpcStaticSendDescriptor*) buf;
uintptr_t ptr = (uintptr_t) cmd->Statics[i];
desc->Addr = ptr;
desc->Packed = cmd->StaticIndices[i] | (cmd->StaticSizes[i] << 16) |
(((ptr >> 32) & 15) << 12) | (((ptr >> 36) & 15) << 6);
}
for (i=0; i<(cmd->NumSend + cmd->NumRecv + cmd->NumExch); i++, buf+=3) {
IpcBufferDescriptor* desc = (IpcBufferDescriptor*) buf;
desc->Size = cmd->BufferSizes[i];
uintptr_t ptr = (uintptr_t) cmd->Buffers[i];
desc->Addr = ptr;
desc->Packed = cmd->BufferTypes[i] |
(((ptr >> 32) & 15) << 28) | ((ptr >> 36) << 2);
}
u32 padding = ((16 - (((uintptr_t) buf) & 15)) & 15) / 4;
u32* raw = (u32*) (buf + padding);
size_t raw_size = (sizeof_raw/4) + 4;
buf += raw_size;
u16* buf_u16 = (u16*) buf;
for (i=0; i<cmd->NumStaticOut; i++) {
size_t off = cmd->NumStaticIn + i;
size_t sz = (uintptr_t) cmd->StaticSizes[off];
buf_u16[i] = (sz > 0xFFFF) ? 0 : sz;
}
size_t u16s_size = ((2*cmd->NumStaticOut) + 3)/4;
buf += u16s_size;
raw_size += u16s_size;
*fill_in_size_later |= raw_size;
for (i=0; i<cmd->NumStaticOut; i++, buf+=2) {
IpcStaticRecvDescriptor* desc = (IpcStaticRecvDescriptor*) buf;
size_t off = cmd->NumStaticIn + i;
uintptr_t ptr = (uintptr_t) cmd->Statics[off];
desc->Addr = ptr;
desc->Packed = (ptr >> 32) | (cmd->StaticSizes[off] << 16);
}
return (void*) raw;
}
/**
* @brief Dispatches an IPC request.
* @param session IPC session handle.
* @return Result code.
*/
static inline Result ipcDispatch(Handle session) {
return svcSendSyncRequest(session);
}
///@}
///@name IPC response parsing
///@{
/// IPC parsed command (response) structure.
typedef struct {
IpcCommandType CommandType; ///< Type of the command
bool HasPid; ///< true if the 'Pid' field is filled out.
u64 Pid; ///< PID included in the response (only if HasPid is true)
size_t NumHandles; ///< Number of handles copied.
Handle Handles[IPC_MAX_OBJECTS]; ///< Handles.
bool WasHandleCopied[IPC_MAX_OBJECTS]; ///< true if the handle was moved, false if it was copied.
bool IsDomainRequest; ///< true if the the message is a Domain message.
DomainMessageType InMessageType; ///< Type of the domain message.
u32 InMessageLength; ///< Size of rawdata (for domain messages).
u32 InThisObjectId; ///< Object ID to call the command on (for domain messages).
size_t InNumObjectIds; ///< Number of object IDs (for domain messages).
u32 InObjectIds[IPC_MAX_OBJECTS]; ///< Object IDs (for domain messages).
bool IsDomainResponse; ///< true if the the message is a Domain response.
size_t OutNumObjectIds; ///< Number of object IDs (for domain responses).
u32 OutObjectIds[IPC_MAX_OBJECTS]; ///< Object IDs (for domain responses).
size_t NumBuffers; ///< Number of buffers in the response.
void* Buffers[IPC_MAX_BUFFERS]; ///< Pointers to the buffers.
size_t BufferSizes[IPC_MAX_BUFFERS]; ///< Sizes of the buffers.
BufferType BufferTypes[IPC_MAX_BUFFERS]; ///< Types of the buffers.
BufferDirection BufferDirections[IPC_MAX_BUFFERS]; ///< Direction of each buffer.
size_t NumStatics; ///< Number of statics in the response.
void* Statics[IPC_MAX_BUFFERS]; ///< Pointers to the statics.
size_t StaticSizes[IPC_MAX_BUFFERS]; ///< Sizes of the statics.
u8 StaticIndices[IPC_MAX_BUFFERS]; ///< Indices of the statics.
size_t NumStaticsOut; ///< Number of output statics available in the response.
void* Raw; ///< Pointer to the raw embedded data structure in the response.
void* RawWithoutPadding; ///< Pointer to the raw embedded data structure, without padding.
size_t RawSize; ///< Size of the raw embedded data.
} IpcParsedCommand;
/**
* @brief Parse an IPC command response into an IPC parsed command structure.
* @param r IPC parsed command structure to fill in.
* @return Result code.
*/
static inline Result ipcParse(IpcParsedCommand* r) {
u32* buf = (u32*)armGetTls();
u32 ctrl0 = *buf++;
u32 ctrl1 = *buf++;
size_t i;
r->IsDomainRequest = false;
r->IsDomainResponse = false;
r->CommandType = (IpcCommandType) (ctrl0 & 0xffff);
r->HasPid = false;
r->RawSize = (ctrl1 & 0x1ff) * 4;
r->NumHandles = 0;
r->NumStaticsOut = (ctrl1 >> 10) & 15;
if (r->NumStaticsOut >> 1) r->NumStaticsOut--; // Value 2 -> Single descriptor
if (r->NumStaticsOut >> 1) r->NumStaticsOut--; // Value 3+ -> (Value - 2) descriptors
if (ctrl1 & 0x80000000) {
u32 ctrl2 = *buf++;
if (ctrl2 & 1) {
r->HasPid = true;
r->Pid = *buf++;
r->Pid |= ((u64)(*buf++)) << 32;
}
size_t num_handles_copy = ((ctrl2 >> 1) & 15);
size_t num_handles_move = ((ctrl2 >> 5) & 15);
size_t num_handles = num_handles_copy + num_handles_move;
u32* buf_after_handles = buf + num_handles;
if (num_handles > IPC_MAX_OBJECTS)
num_handles = IPC_MAX_OBJECTS;
for (i=0; i<num_handles; i++)
{
r->Handles[i] = *(buf+i);
r->WasHandleCopied[i] = (i < num_handles_copy);
}
r->NumHandles = num_handles;
buf = buf_after_handles;
}
size_t num_statics = (ctrl0 >> 16) & 15;
u32* buf_after_statics = buf + num_statics*2;
if (num_statics > IPC_MAX_BUFFERS)
num_statics = IPC_MAX_BUFFERS;
for (i=0; i<num_statics; i++, buf+=2) {
IpcStaticSendDescriptor* desc = (IpcStaticSendDescriptor*) buf;
u64 packed = (u64) desc->Packed;
r->Statics[i] = (void*) (desc->Addr | (((packed >> 12) & 15) << 32) | (((packed >> 6) & 15) << 36));
r->StaticSizes[i] = packed >> 16;
r->StaticIndices[i] = packed & 63;
}
r->NumStatics = num_statics;
buf = buf_after_statics;
size_t num_bufs_send = (ctrl0 >> 20) & 15;
size_t num_bufs_recv = (ctrl0 >> 24) & 15;
size_t num_bufs_exch = (ctrl0 >> 28) & 15;
size_t num_bufs = num_bufs_send + num_bufs_recv + num_bufs_exch;
r->Raw = (void*)(((uintptr_t)(buf + num_bufs*3) + 15) &~ 15);
r->RawWithoutPadding = (void*)((uintptr_t)(buf + num_bufs*3));
if (num_bufs > IPC_MAX_BUFFERS)
num_bufs = IPC_MAX_BUFFERS;
for (i=0; i<num_bufs; i++, buf+=3) {
IpcBufferDescriptor* desc = (IpcBufferDescriptor*) buf;
u64 packed = (u64) desc->Packed;
r->Buffers[i] = (void*) (desc->Addr | ((packed >> 28) << 32) | (((packed >> 2) & 15) << 36));
r->BufferSizes[i] = desc->Size;
r->BufferTypes[i] = (BufferType) (packed & 3);
if (i < num_bufs_send)
r->BufferDirections[i] = BufferDirection_Send;
else if (i < (num_bufs_send + num_bufs_recv))
r->BufferDirections[i] = BufferDirection_Recv;
else
r->BufferDirections[i] = BufferDirection_Exch;
}
r->NumBuffers = num_bufs;
return 0;
}
/**
* @brief Queries the size of an IPC pointer buffer.
* @param session IPC session handle.
* @param size Output variable in which to store the size.
* @return Result code.
*/
static inline Result ipcQueryPointerBufferSize(Handle session, size_t *size) {
u32* buf = (u32*)armGetTls();
buf[0] = IpcCommandType_Control;
buf[1] = 8;
buf[2] = 0;
buf[3] = 0;
buf[4] = SFCI_MAGIC;
buf[5] = 0;
buf[6] = 3;
buf[7] = 0;
Result rc = ipcDispatch(session);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct ipcQueryPointerBufferSizeResponse {
u64 magic;
u64 result;
u32 size;
} *raw = (struct ipcQueryPointerBufferSizeResponse*)r.Raw;
rc = raw->result;
if (R_SUCCEEDED(rc)) {
*size = raw->size & 0xffff;
}
}
return rc;
}
/**
* @brief Closes the IPC session with proper clean up.
* @param session IPC session handle.
* @return Result code.
*/
static inline Result ipcCloseSession(Handle session) {
u32* buf = (u32*)armGetTls();
buf[0] = IpcCommandType_Close;
buf[1] = 0;
return ipcDispatch(session);
}
/**
* @brief Clones an IPC session.
* @param session IPC session handle.
* @param unk Unknown.
* @param new_session_out Output cloned IPC session handle.
* @return Result code.
*/
static inline Result ipcCloneSession(Handle session, u32 unk, Handle* new_session_out) {
u32* buf = (u32*)armGetTls();
buf[0] = IpcCommandType_Control;
buf[1] = 9;
buf[2] = 0;
buf[3] = 0;
buf[4] = SFCI_MAGIC;
buf[5] = 0;
buf[6] = 4;
buf[7] = 0;
buf[8] = unk;
Result rc = ipcDispatch(session);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct ipcCloneSessionResponse {
u64 magic;
u64 result;
} *raw = (struct ipcCloneSessionResponse*)r.Raw;
rc = raw->result;
if (R_SUCCEEDED(rc) && new_session_out) {
*new_session_out = r.Handles[0];
}
}
return rc;
}
///@}
///@name IPC domain handling
///@{
/**
* @brief Converts an IPC session handle into a domain.
* @param session IPC session handle.
* @param object_id_out Output variable in which to store the object ID.
* @return Result code.
*/
static inline Result ipcConvertSessionToDomain(Handle session, u32* object_id_out) {
u32* buf = (u32*)armGetTls();
buf[0] = IpcCommandType_Control;
buf[1] = 8;
buf[4] = SFCI_MAGIC;
buf[5] = 0;
buf[6] = 0;
buf[7] = 0;
Result rc = ipcDispatch(session);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct ipcConvertSessionToDomainResponse {
u64 magic;
u64 result;
u32 object_id;
} *raw = (struct ipcConvertSessionToDomainResponse*)r.Raw;
rc = raw->result;
if (R_SUCCEEDED(rc)) {
*object_id_out = raw->object_id;
}
}
return rc;
}
/**
* @brief Adds an object ID to be sent through an IPC domain command structure.
* @param cmd IPC domain command structure.
* @param object_id Object ID to send.
*/
static inline void ipcSendObjectId(IpcCommand* cmd, u32 object_id) {
cmd->ObjectIds[cmd->NumObjectIds++] = object_id;
}
/**
* @brief Prepares the header of an IPC command structure (domain version).
* @param cmd IPC command structure.
* @param sizeof_raw Size in bytes of the raw data structure to embed inside the IPC request
* @param object_id Domain object ID.
* @return Pointer to the raw embedded data structure in the request, ready to be filled out.
*/
static inline void* ipcPrepareHeaderForDomain(IpcCommand* cmd, size_t sizeof_raw, u32 object_id) {
void* raw = ipcPrepareHeader(cmd, sizeof_raw + sizeof(DomainMessageHeader) + cmd->NumObjectIds*sizeof(u32));
DomainMessageHeader* hdr = (DomainMessageHeader*) raw;
u32 *object_ids = (u32*)(((uintptr_t) raw) + sizeof(DomainMessageHeader) + sizeof_raw);
hdr->Type = DomainMessageType_SendMessage;
hdr->NumObjectIds = (u8)cmd->NumObjectIds;
hdr->Length = sizeof_raw;
hdr->ThisObjectId = object_id;
hdr->Pad[0] = hdr->Pad[1] = 0;
for(size_t i = 0; i < cmd->NumObjectIds; i++)
object_ids[i] = cmd->ObjectIds[i];
return (void*)(((uintptr_t) raw) + sizeof(DomainMessageHeader));
}
/**
* @brief Parse an IPC command request into an IPC parsed command structure (domain version).
* @param r IPC parsed command structure to fill in.
* @return Result code.
*/
static inline Result ipcParseDomainRequest(IpcParsedCommand* r) {
Result rc = ipcParse(r);
DomainMessageHeader *hdr;
u32 *object_ids;
if(R_FAILED(rc))
return rc;
hdr = (DomainMessageHeader*) r->Raw;
object_ids = (u32*)(((uintptr_t) hdr) + sizeof(DomainMessageHeader) + hdr->Length);
r->Raw = (void*)(((uintptr_t) r->Raw) + sizeof(DomainMessageHeader));
r->IsDomainRequest = true;
r->InMessageType = (DomainMessageType)(hdr->Type);
switch (r->InMessageType) {
case DomainMessageType_SendMessage:
case DomainMessageType_Close:
break;
default:
return MAKERESULT(Module_Libnx, LibnxError_DomainMessageUnknownType);
}
r->InThisObjectId = hdr->ThisObjectId;
r->InNumObjectIds = hdr->NumObjectIds > 8 ? 8 : hdr->NumObjectIds;
if ((uintptr_t)object_ids + sizeof(u32) * r->InNumObjectIds - (uintptr_t)armGetTls() >= 0x100) {
return MAKERESULT(Module_Libnx, LibnxError_DomainMessageTooManyObjectIds);
}
for(size_t i = 0; i < r->InNumObjectIds; i++)
r->InObjectIds[i] = object_ids[i];
return rc;
}
/**
* @brief Parse an IPC command response into an IPC parsed command structure (domain version).
* @param r IPC parsed command structure to fill in.
* @param sizeof_raw Size in bytes of the raw data structure.
* @return Result code.
*/
static inline Result ipcParseDomainResponse(IpcParsedCommand* r, size_t sizeof_raw) {
Result rc = ipcParse(r);
DomainResponseHeader *hdr;
u32 *object_ids;
if(R_FAILED(rc))
return rc;
hdr = (DomainResponseHeader*) r->Raw;
r->Raw = (void*)(((uintptr_t) r->Raw) + sizeof(DomainResponseHeader));
object_ids = (u32*)(((uintptr_t) r->Raw) + sizeof_raw);//Official sw doesn't align this.
r->IsDomainResponse = true;
r->OutNumObjectIds = hdr->NumObjectIds > 8 ? 8 : hdr->NumObjectIds;
if ((uintptr_t)object_ids + sizeof(u32) * r->OutNumObjectIds - (uintptr_t)armGetTls() >= 0x100) {
return MAKERESULT(Module_Libnx, LibnxError_DomainMessageTooManyObjectIds);
}
for(size_t i = 0; i < r->OutNumObjectIds; i++)
r->OutObjectIds[i] = object_ids[i];
return rc;
}
/**
* @brief Closes a domain object by ID.
* @param session IPC session handle.
* @param object_id ID of the object to close.
* @return Result code.
*/
static inline Result ipcCloseObjectById(Handle session, u32 object_id) {
IpcCommand c;
DomainMessageHeader* hdr;
ipcInitialize(&c);
hdr = (DomainMessageHeader*)ipcPrepareHeader(&c, sizeof(DomainMessageHeader));
hdr->Type = DomainMessageType_Close;
hdr->NumObjectIds = 0;
hdr->Length = 0;
hdr->ThisObjectId = object_id;
hdr->Pad[0] = hdr->Pad[1] = 0;
return ipcDispatch(session); // this command has no associated response
}
///@}

View File

@@ -0,0 +1,41 @@
/*
MIT License
Copyright (c) 2024 Roy Merkel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef MEMMEM_IMPL_H
#define MEMMEM_IMPL_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
void *memmem_impl(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,25 @@
/*
* Copyright (c) ppkantorski (bord2death)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <string>
#include <ctime>
#include <cstdio>
namespace notification {
void writeNotification(const std::string& message);
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright (c) ppkantorski (bord2death)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/*
* SDx actual min is 625 mV. Multipliers 0/1 reserved.
* SD0 max is 1400 mV
* SD1 max is 1550 mV
* SD2 max is 3787.5 mV
* SD3 max is 3787.5 mV
*/
/*
* Switch Power domains (max77620):
* Name | Usage | uV step | uV min | uV default | uV max | Init
*-------+---------------+---------+--------+------------+---------+------------------
* sd0 | SoC | 12500 | 600000 | 625000 | 1400000 | 1.125V (pkg1.1)
* sd1 | SDRAM | 12500 | 600000 | 1125000 | 1125000 | 1.1V (pkg1.1)
* sd2 | ldo{0-1, 7-8} | 12500 | 600000 | 1325000 | 1350000 | 1.325V (pcv)
* sd3 | 1.8V general | 12500 | 600000 | 1800000 | 1800000 |
* ldo0 | Display Panel | 25000 | 800000 | 1200000 | 1200000 | 1.2V (pkg1.1)
* ldo1 | XUSB, PCIE | 25000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
* ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 |
* ldo3 | GC ASIC | 50000 | 800000 | 3100000 | 3100000 | 3.1V (pcv)
* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 | 0.85V (AO, pcv)
* ldo5 | GC Card | 50000 | 800000 | 1800000 | 1800000 | 1.8V (pcv)
* ldo6 | Touch, ALS | 50000 | 800000 | 2900000 | 2900000 | 2.9V (pcv)
* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 | 1.05V (pcv)
* ldo8 | XUSB, DP, MCU | 50000 | 800000 | 1050000 | 2800000 | 1.05V/2.8V (pcv)
*/
// GPIOs T210: 3: 3.3V, 5: CPU PMIC, 6: GPU PMIC, 7: DSI/VI 1.2V powered by ldo0.
/*
* OTP: T210 - T210B01:
* SD0: 1.0V 1.05V - SoC. EN Based on FPSSRC.
* SD1: 1.15V 1.1V - DRAM for T210. EN Based on FPSSRC.
* SD2: 1.35V 1.35V
* SD3: 1.8V 1.8V
* All powered off?
* LDO0: -- -- - Display
* LDO1: 1.05V 1.05V
* LDO2: -- -- - SD
* LDO3: 3.1V 3.1V - GC ASIC
* LDO4: 1.0V 0.8V - Needed for RTC domain on T210.
* LDO5: 3.1V 3.1V
* LDO6: 2.8V 2.9V - Touch.
* LDO7: 1.05V 1.0V
* LDO8: 1.05V 1.0V
*/
/*
* MAX77620_AME_GPIO: control GPIO modes (bits 0 - 7 correspond to GPIO0 - GPIO7); 0 -> GPIO, 1 -> alt-mode
* MAX77620_REG_GPIOx: 0x9 sets output and enable
*/
typedef enum {
PcvPowerDomain_Max77620_Sd0 = 0,
PcvPowerDomain_Max77620_Sd1 = 1,
PcvPowerDomain_Max77620_Sd2 = 2,
PcvPowerDomain_Max77620_Sd3 = 3,
PcvPowerDomain_Max77620_Ldo0 = 4,
PcvPowerDomain_Max77620_Ldo1 = 5,
PcvPowerDomain_Max77620_Ldo2 = 6,
PcvPowerDomain_Max77620_Ldo3 = 7,
PcvPowerDomain_Max77620_Ldo4 = 8,
PcvPowerDomain_Max77620_Ldo5 = 9,
PcvPowerDomain_Max77620_Ldo6 = 10,
PcvPowerDomain_Max77620_Ldo7 = 11,
PcvPowerDomain_Max77620_Ldo8 = 12,
PcvPowerDomain_Max77621_Cpu = 13,
PcvPowerDomain_Max77621_Gpu = 14,
PcvPowerDomain_Max77812_Cpu = 15,
PcvPowerDomain_Max77812_Gpu = 16,
PcvPowerDomain_Max77812_Dram = 17,
} PowerDomain;
typedef enum {
PcvPowerDomainId_Max77620_Sd0 = 0x3A000080,
PcvPowerDomainId_Max77620_Sd1 = 0x3A000081, // vdd2
PcvPowerDomainId_Max77620_Sd2 = 0x3A000082,
PcvPowerDomainId_Max77620_Sd3 = 0x3A000083,
PcvPowerDomainId_Max77620_Ldo0 = 0x3A0000A0,
PcvPowerDomainId_Max77620_Ldo1 = 0x3A0000A1,
PcvPowerDomainId_Max77620_Ldo2 = 0x3A0000A2,
PcvPowerDomainId_Max77620_Ldo3 = 0x3A0000A3,
PcvPowerDomainId_Max77620_Ldo4 = 0x3A0000A4,
PcvPowerDomainId_Max77620_Ldo5 = 0x3A0000A5,
PcvPowerDomainId_Max77620_Ldo6 = 0x3A0000A6,
PcvPowerDomainId_Max77620_Ldo7 = 0x3A0000A7,
PcvPowerDomainId_Max77620_Ldo8 = 0x3A0000A8,
PcvPowerDomainId_Max77621_Cpu = 0x3A000003,
PcvPowerDomainId_Max77621_Gpu = 0x3A000004,
PcvPowerDomainId_Max77812_Cpu = 0x3A000003,
PcvPowerDomainId_Max77812_Gpu = 0x3A000004,
PcvPowerDomainId_Max77812_Dram = 0x3A000005, // vddq
} PowerDomainId;

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) MasaGratoR
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <switch.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
Service s;
} PwmChannelSession;
Result pwmInitialize(void);
void pwmExit(void);
Service* pwmGetServiceSession(void);
Result pwmOpenSession2(PwmChannelSession *out, u32 device_code);
Result pwmChannelSessionGetDutyCycle(PwmChannelSession *c, double* out);
void pwmChannelSessionClose(PwmChannelSession *c);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -0,0 +1,527 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* Copyright (c) Linux 4 Tegra & Linux 4 Switch contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#define EMC_INTSTATUS_0 0x0
#define EMC_INTMASK_0 0x4
#define EMC_DBG_0 0x8
#define EMC_CFG_0 0xC
#define EMC_ADR_CFG_0 0x10
#define EMC_REFCTRL_0 0x20
#define EMC_PIN_0 0x24
#define EMC_TIMING_CONTROL_0 0x28
#define EMC_RC_0 0x2C
#define EMC_RFC_0 0x30
#define EMC_RAS_0 0x34
#define EMC_RP_0 0x38
#define EMC_R2W_0 0x3C
#define EMC_W2R_0 0x40
#define EMC_R2P_0 0x44
#define EMC_W2P_0 0x48
#define EMC_RD_RCD_0 0x4C
#define EMC_WR_RCD_0 0x50
#define EMC_RRD_0 0x54
#define EMC_REXT_0 0x58
#define EMC_WDV_0 0x5C
#define EMC_QUSE_0 0x60
#define EMC_QRST_0 0x64
#define EMC_QSAFE_0 0x68
#define EMC_RDV_0 0x6C
#define EMC_REFRESH_0 0x70
#define EMC_BURST_REFRESH_NUM_0 0x74
#define EMC_PDEX2WR_0 0x78
#define EMC_PDEX2RD_0 0x7C
#define EMC_PCHG2PDEN_0 0x80
#define EMC_ACT2PDEN_0 0x84
#define EMC_AR2PDEN_0 0x88
#define EMC_RW2PDEN_0 0x8C
#define EMC_TXSR_0 0x90
#define EMC_TCKE_0 0x94
#define EMC_TFAW_0 0x98
#define EMC_TRPAB_0 0x9C
#define EMC_TCLKSTABLE_0 0xA0
#define EMC_TCLKSTOP_0 0xA4
#define EMC_TREFBW_0 0xA8
#define EMC_TPPD_0 0xAC
#define EMC_ODT_WRITE_0 0xB0
#define EMC_PDEX2MRR_0 0xB4
#define EMC_WEXT_0 0xB8
#define EMC_RFC_SLR_0 0xC0
#define EMC_MRS_WAIT_CNT2_0 0xC4
#define EMC_MRS_WAIT_CNT_0 0xC8
#define EMC_MRS_0 0xCC
#define EMC_EMRS_0 0xD0
#define EMC_REF_0 0xD4
#define EMC_PRE_0 0xD8
#define EMC_NOP_0 0xDC
#define EMC_SELF_REF_0 0xE0
#define EMC_DPD_0 0xE4
#define EMC_MRW_0 0xE8
#define EMC_MRR_0 0xEC
#define EMC_CMDQ_0 0xF0
#define EMC_MC2EMCQ_0 0xF4
#define EMC_FBIO_SPARE_0 0x100
#define EMC_FBIO_CFG5_0 0x104
#define EMC_FBIO_CFG6_0 0x114
#define EMC_PDEX2CKE_0 0x118
#define EMC_CKE2PDEN_0 0x11C
#define EMC_CFG_RSV_0 0x120
#define EMC_ACPD_CONTROL_0 0x124
#define EMC_MPC_0 0x128
#define EMC_EMRS2_0 0x12C
#define EMC_EMRS3_0 0x130
#define EMC_MRW2_0 0x134
#define EMC_MRW3_0 0x138
#define EMC_MRW4_0 0x13C
#define EMC_CLKEN_OVERRIDE_0 0x140
#define EMC_R2R_0 0x144
#define EMC_W2W_0 0x148
#define EMC_EINPUT_0 0x14C
#define EMC_EINPUT_DURATION_0 0x150
#define EMC_PUTERM_EXTRA_0 0x154
#define EMC_TCKESR_0 0x158
#define EMC_TPD_0 0x15C
#define EMC_AUTO_CAL_CONFIG_0 0x2A4
#define EMC_AUTO_CAL_INTERVAL_0 0x2A8
#define EMC_AUTO_CAL_STATUS_0 0x2AC
#define EMC_REQ_CTRL_0 0x2B0
#define EMC_EMC_STATUS_0 0x2B4
#define EMC_CFG_2_0 0x2B8
#define EMC_CFG_DIG_DLL_0 0x2BC
#define EMC_CFG_DIG_DLL_PERIOD_0 0x2C0
#define EMC_DIG_DLL_STATUS_0 0x2C4
#define EMC_CFG_DIG_DLL_1_0 0x2C8
#define EMC_RDV_MASK_0 0x2CC
#define EMC_WDV_MASK_0 0x2D0
#define EMC_RDV_EARLY_MASK_0 0x2D4
#define EMC_RDV_EARLY_0 0x2D8
#define EMC_AUTO_CAL_CONFIG8_0 0x2DC
#define EMC_ZCAL_INTERVAL_0 0x2E0
#define EMC_ZCAL_WAIT_CNT_0 0x2E4
#define EMC_ZCAL_MRW_CMD_0 0x2E8
#define EMC_ZQ_CAL_0 0x2EC
#define EMC_XM2COMPPADCTRL3_0 0x2F4
#define EMC_AUTO_CAL_VREF_SEL_0_0 0x2F8
#define EMC_AUTO_CAL_VREF_SEL_1_0 0x300
#define EMC_XM2COMPPADCTRL_0 0x30C
#define EMC_FDPD_CTRL_DQ_0 0x310
#define EMC_FDPD_CTRL_CMD_0 0x314
#define EMC_PMACRO_CMD_BRICK_CTRL_FDPD_0 0x318
#define EMC_PMACRO_DATA_BRICK_CTRL_FDPD_0 0x31C
#define EMC_SCRATCH0_0 0x324
#define EMC_PMACRO_BRICK_CTRL_RFU1_0 0x330
#define EMC_PMACRO_BRICK_CTRL_RFU2_0 0x334
#define EMC_CMD_MAPPING_CMD0_0_0 0x380
#define EMC_CMD_MAPPING_CMD0_1_0 0x384
#define EMC_CMD_MAPPING_CMD0_2_0 0x388
#define EMC_CMD_MAPPING_CMD1_0_0 0x38C
#define EMC_CMD_MAPPING_CMD1_1_0 0x390
#define EMC_CMD_MAPPING_CMD1_2_0 0x394
#define EMC_CMD_MAPPING_CMD2_0_0 0x398
#define EMC_CMD_MAPPING_CMD2_1_0 0x39C
#define EMC_CMD_MAPPING_CMD2_2_0 0x3A0
#define EMC_CMD_MAPPING_CMD3_0_0 0x3A4
#define EMC_CMD_MAPPING_CMD3_1_0 0x3A8
#define EMC_CMD_MAPPING_CMD3_2_0 0x3AC
#define EMC_CMD_MAPPING_BYTE_0 0x3B0
#define EMC_TR_TIMING_0_0 0x3B4
#define EMC_TR_CTRL_0_0 0x3B8
#define EMC_TR_CTRL_1_0 0x3BC
#define EMC_SWITCH_BACK_CTRL_0 0x3C0
#define EMC_TR_RDV_0 0x3C4
#define EMC_STALL_THEN_EXE_BEFORE_CLKCHANGE_0 0x3C8
#define EMC_STALL_THEN_EXE_AFTER_CLKCHANGE_0 0x3CC
#define EMC_UNSTALL_RW_AFTER_CLKCHANGE_0 0x3D0
#define EMC_AUTO_CAL_ 0x3D4
#define EMC_SEL_DPD_CTRL_0 0x3D8
#define EMC_PRE_REFRESH_REQ_CNT_0 0x3DC
#define EMC_DYN_SELF_REF_CONTROL_0 0x3E0
#define EMC_TXSRDLL_0 0x3E4
#define EMC_CCFIFO_ADDR_0 0x3E8
#define EMC_CCFIFO_DATA_0 0x3EC
#define EMC_CCFIFO_STATUS_0 0x3F0
#define EMC_TR_QPOP_0 0x3F4
#define EMC_TR_RDV_MASK_0 0x3F8
#define EMC_TR_QSAFE_0 0x3FC
#define EMC_TR_QRST_0 0x400
#define EMC_SWIZZLE_RANK0_BYTE0_0 0x404
#define EMC_SWIZZLE_RANK0_BYTE1_0 0x408
#define EMC_SWIZZLE_RANK0_BYTE2_0 0x40C
#define EMC_SWIZZLE_RANK0_BYTE3_0 0x410
#define EMC_SWIZZLE_RANK1_BYTE0_0 0x418
#define EMC_SWIZZLE_RANK1_BYTE1_0 0x41C
#define EMC_SWIZZLE_RANK1_BYTE2_0 0x420
#define EMC_SWIZZLE_RANK1_BYTE3_0 0x424
#define EMC_ISSUE_QRST_0 0x428
#define EMC_PMC_SCRATCH1_0 0x440
#define EMC_PMC_SCRATCH2_0 0x444
#define EMC_PMC_SCRATCH3_0 0x448
#define EMC_AUTO_CAL_CONFIG2_0 0x458
#define EMC_AUTO_CAL_CONFIG3_0 0x45C
#define EMC_TR_DVFS_0 0x460
#define EMC_AUTO_CAL_CHANNEL_0 0x464
#define EMC_IBDLY_0 0x468
#define EMC_OBDLY_0 0x46C
#define EMC_TXDSRVTTGEN_0 0x480
#define EMC_WE_DURATION_0 0x48C
#define EMC_WS_DURATION_0 0x490
#define EMC_WEV_0 0x494
#define EMC_WSV_0 0x498
#define EMC_CFG_3_0 0x49C
#define EMC_MRW5_0 0x4A0
#define EMC_MRW6_0 0x4A4
#define EMC_MRW7_0 0x4A8
#define EMC_MRW8_0 0x4AC
#define EMC_MRW9_0 0x4B0
#define EMC_MRW10_0 0x4B4
#define EMC_MRW11_0 0x4B8
#define EMC_MRW12_0 0x4BC
#define EMC_MRW13_0 0x4C0
#define EMC_MRW14_0 0x4C4
#define EMC_MRW15_0 0x4D0
#define EMC_CFG_SYNC_0 0x4D4
#define EMC_FDPD_CTRL_CMD_NO_RAMP_0 0x4D8
#define EMC_WDV_CHK_0 0x4E0
#define EMC_CFG_PIPE_2_0 0x554
#define EMC_CFG_PIPE_CLK_0 0x558
#define EMC_CFG_PIPE_1_0 0x55C
#define EMC_CFG_PIPE_0 0x560
#define EMC_QPOP_0 0x564
#define EMC_QUSE_WIDTH_0 0x568
#define EMC_PUTERM_WIDTH_0 0x56C
#define EMC_BGBIAS_CTL0_0 0x570
#define EMC_AUTO_CAL_CONFIG7_0 0x574
#define EMC_XM2COMPPADCTRL2_0 0x578
#define EMC_COMP_PAD_SW_CTRL_0 0x57C
#define EMC_REFCTRL2_0 0x580
#define EMC_FBIO_CFG7_0 0x584
#define EMC_DATA_BRLSHFT_0_0 0x588
#define EMC_DATA_BRLSHFT_1_0 0x58C
#define EMC_RFCPB_0 0x590
#define EMC_DQS_BRLSHFT_0_0 0x594
#define EMC_DQS_BRLSHFT_1_0 0x598
#define EMC_CMD_BRLSHFT_0_0 0x59C
#define EMC_CMD_BRLSHFT_1_0 0x5A0
#define EMC_CMD_BRLSHFT_2_0 0x5A4
#define EMC_CMD_BRLSHFT_3_0 0x5A8
#define EMC_QUSE_BRLSHFT_0_0 0x5AC
#define EMC_AUTO_CAL_CONFIG4_0 0x5B0
#define EMC_AUTO_CAL_CONFIG5_0 0x5B4
#define EMC_QUSE_BRLSHFT_1_0 0x5B8
#define EMC_QUSE_BRLSHFT_2_0 0x5BC
#define EMC_CCDMW_0 0x5C0
#define EMC_QUSE_BRLSHFT_3_0 0x5C4
#define EMC_FBIO_CFG8_0 0x5C8
#define EMC_AUTO_CAL_CONFIG6_0 0x5CC
#define EMC_PROTOBIST_CONFIG_ADR_1_0 0x5D0
#define EMC_PROTOBIST_CONFIG_ADR_2_0 0x5D4
#define EMC_PROTOBIST_MISC_0 0x5D8
#define EMC_PROTOBIST_WDATA_LOWER_0 0x5DC
#define EMC_PROTOBIST_WDATA_UPPER_0 0x5E0
#define EMC_PROTOBIST_RDATA_0 0x5EC
#define EMC_DLL_CFG_0_0 0x5E4
#define EMC_DLL_CFG_1_0 0x5E8
#define EMC_CONFIG_SAMPLE_DELAY_0 0x5F0
#define EMC_CFG_UPDATE_0 0x5F4
#define EMC_PMACRO_QUSE_DDLL_RANK0_0_0 0x600
#define EMC_PMACRO_QUSE_DDLL_RANK0_1_0 0x604
#define EMC_PMACRO_QUSE_DDLL_RANK0_2_0 0x608
#define EMC_PMACRO_QUSE_DDLL_RANK0_3_0 0x60C
#define EMC_PMACRO_QUSE_DDLL_RANK0_4_0 0x610
#define EMC_PMACRO_QUSE_DDLL_RANK0_5_0 0x614
#define EMC_PMACRO_QUSE_DDLL_RANK1_0_0 0x620
#define EMC_PMACRO_QUSE_DDLL_RANK1_1_0 0x624
#define EMC_PMACRO_QUSE_DDLL_RANK1_2_0 0x628
#define EMC_PMACRO_QUSE_DDLL_RANK1_3_0 0x62C
#define EMC_PMACRO_QUSE_DDLL_RANK1_4_0 0x630
#define EMC_PMACRO_QUSE_DDLL_RANK1_5_0 0x634
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0_0 0x640
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1_0 0x644
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2_0 0x648
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3_0 0x64C
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4_0 0x650
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5_0 0x654
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0_0 0x660
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1_0 0x664
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2_0 0x668
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3_0 0x66C
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4_0 0x670
#define EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5_0 0x674
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0_0 0x680
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1_0 0x684
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2_0 0x688
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3_0 0x68C
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4_0 0x690
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5_0 0x694
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0_0 0x6A0
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1_0 0x6A4
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2_0 0x6A8
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3_0 0x6AC
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4_0 0x6B0
#define EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5_0 0x6B4
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0_0 0x6C0
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1_0 0x6C4
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2_0 0x6C8
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3_0 0x6CC
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_4_0 0x6D0
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_5_0 0x6D4
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0_0 0x6E0
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1_0 0x6E4
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2_0 0x6E8
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3_0 0x6EC
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_4_0 0x6F0
#define EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_5_0 0x6F4
#define EMC_PMACRO_AUTOCAL_CFG_0_0 0x700
#define EMC_PMACRO_AUTOCAL_CFG_1_0 0x704
#define EMC_PMACRO_AUTOCAL_CFG_2_0 0x708
#define EMC_PMACRO_TX_PWRD_0_0 0x720
#define EMC_PMACRO_TX_PWRD_1_0 0x724
#define EMC_PMACRO_TX_PWRD_2_0 0x728
#define EMC_PMACRO_TX_PWRD_3_0 0x72C
#define EMC_PMACRO_TX_PWRD_4_0 0x730
#define EMC_PMACRO_TX_PWRD_5_0 0x734
#define EMC_PMACRO_TX_SEL_CLK_SRC_0_0 0x740
#define EMC_PMACRO_TX_SEL_CLK_SRC_1_0 0x744
#define EMC_PMACRO_TX_SEL_CLK_SRC_2_0 0x748
#define EMC_PMACRO_TX_SEL_CLK_SRC_3_0 0x74C
#define EMC_PMACRO_TX_SEL_CLK_SRC_4_0 0x750
#define EMC_PMACRO_TX_SEL_CLK_SRC_5_0 0x754
#define EMC_PMACRO_DDLL_BYPASS_0 0x760
#define EMC_PMACRO_DDLL_PWRD_0_0 0x770
#define EMC_PMACRO_DDLL_PWRD_1_0 0x774
#define EMC_PMACRO_DDLL_PWRD_2_0 0x778
#define EMC_PMACRO_CMD_CTRL_0_0 0x780
#define EMC_PMACRO_CMD_CTRL_1_0 0x784
#define EMC_PMACRO_CMD_CTRL_2_0 0x788
#define MC_REGISTER_BASE 0x70019000
#define MC_REGISTER_REGION_SIZE 0x1000
#define MC_INTSTATUS_0 0x000
#define MC_INTMASK_0 0x004
#define MC_ERR_STATUS_0 0x008
#define MC_ERR_ADR_0 0x00C
#define MC_SMMU_CONFIG_0 0x010
#define MC_SMMU_PTB_ASID_0 0x01C
#define MC_SMMU_PTB_DATA_0 0x020
#define MC_SMMU_TLB_FLUSH_0 0x030
#define MC_SMMU_PTC_FLUSH_0_0 0x034
#define MC_EMEM_CFG_0 0x050
#define MC_EMEM_ADR_CFG_0 0x054
#define MC_EMEM_ARB_CFG_0 0x090
#define MC_EMEM_ARB_OUTSTANDING_REQ_0 0x094
#define MC_EMEM_ARB_TIMING_RCD_0 0x098
#define MC_EMEM_ARB_TIMING_RP_0 0x09C
#define MC_EMEM_ARB_TIMING_RC_0 0x0A0
#define MC_EMEM_ARB_TIMING_RAS_0 0x0A4
#define MC_EMEM_ARB_TIMING_FAW_0 0x0A8
#define MC_EMEM_ARB_TIMING_RRD_0 0x0AC
#define MC_EMEM_ARB_TIMING_RAP2PRE_0 0x0B0
#define MC_EMEM_ARB_TIMING_WAP2PRE_0 0x0B4
#define MC_EMEM_ARB_TIMING_R2R_0 0x0B8
#define MC_EMEM_ARB_TIMING_W2W_0 0x0BC
#define MC_EMEM_ARB_TIMING_R2W_0 0x0C0
#define MC_EMEM_ARB_TIMING_W2R_0 0x0C4
#define MC_EMEM_ARB_MISC2_0 0x0C8
#define MC_EMEM_ARB_DA_TURNS_0 0x0D0
#define MC_EMEM_ARB_DA_COVERS_0 0x0D4
#define MC_EMEM_ARB_MISC0_0 0x0D8
#define MC_EMEM_ARB_MISC1_0 0x0DC
#define MC_TIMING_CONTROL_0 0xFC
#define MC_EMEM_ARB_RING1_THROTTLE_0 0x0E0
#define MC_CLIENT_HOTRESET_CTRL_0 0x200
#define MC_CLIENT_HOTRESET_STATUS_0 0x204
#define MC_SMMU_AFI_ASID_0 0x238
#define MC_SMMU_DC_ASID_0 0x240
#define MC_SMMU_DCB_ASID_0 0x244
#define MC_SMMU_HC_ASID_0 0x250
#define MC_SMMU_HDA_ASID_0 0x254
#define MC_SMMU_ISP2_ASID_0 0x258
#define MC_SMMU_MSENC_NVENC_ASID_0 0x264
#define MC_SMMU_NV_ASID_0 0x268
#define MC_SMMU_NV2_ASID_0 0x26C
#define MC_SMMU_PPCS_ASID_0 0x270
#define MC_SMMU_SATA_ASID_0 0x274
#define MC_SMMU_VI_ASID_0 0x280
#define MC_SMMU_VIC_ASID_0 0x284
#define MC_SMMU_XUSB_HOST_ASID_0 0x288
#define MC_SMMU_XUSB_DEV_ASID_0 0x28C
#define MC_SMMU_TSEC_ASID_0 0x294
#define MC_LATENCY_ALLOWANCE_AVPC_0 0x2E4
#define MC_LATENCY_ALLOWANCE_DC_0 0x2E8
#define MC_LATENCY_ALLOWANCE_DC_1 0x2EC
#define MC_LATENCY_ALLOWANCE_DCB_0 0x2F4
#define MC_LATENCY_ALLOWANCE_DCB_1 0x2F8
#define MC_LATENCY_ALLOWANCE_HC_0 0x310
#define MC_LATENCY_ALLOWANCE_HC_1 0x314
#define MC_LATENCY_ALLOWANCE_MPCORE_0 0x320
#define MC_LATENCY_ALLOWANCE_NVENC_0 0x328
#define MC_LATENCY_ALLOWANCE_PPCS_0 0x344
#define MC_LATENCY_ALLOWANCE_PPCS_1 0x348
#define MC_LATENCY_ALLOWANCE_ISP2_0 0x370
#define MC_LATENCY_ALLOWANCE_ISP2_1 0x374
#define MC_LATENCY_ALLOWANCE_XUSB_0 0x37C
#define MC_LATENCY_ALLOWANCE_XUSB_1 0x380
#define MC_LATENCY_ALLOWANCE_TSEC_0 0x390
#define MC_LATENCY_ALLOWANCE_VIC_0 0x394
#define MC_LATENCY_ALLOWANCE_VI2_0 0x398
#define MC_LATENCY_ALLOWANCE_GPU_0 0x3AC
#define MC_LATENCY_ALLOWANCE_SDMMCA_0 0x3B8
#define MC_LATENCY_ALLOWANCE_SDMMCAA_0 0x3BC
#define MC_LATENCY_ALLOWANCE_SDMMC_0 0x3C0
#define MC_LATENCY_ALLOWANCE_SDMMCAB_0 0x3C4
#define MC_LATENCY_ALLOWANCE_NVDEC_0 0x3D8
#define MC_LATENCY_ALLOWANCE_GPU2_0 0x3E8
#define MC_DIS_PTSA_RATE_0 0x41C
#define MC_DIS_PTSA_MIN_0 0x420
#define MC_DIS_PTSA_MAX_0 0x424
#define MC_DISB_PTSA_RATE_0 0x428
#define MC_DISB_PTSA_MIN_0 0x42C
#define MC_DISB_PTSA_MAX_0 0x430
#define MC_VE_PTSA_RATE_0 0x434
#define MC_VE_PTSA_MIN_0 0x438
#define MC_VE_PTSA_MAX_0 0x43C
#define MC_MLL_MPCORER_PTSA_RATE_0 0x44C
#define MC_RING1_PTSA_RATE_0 0x47C
#define MC_RING1_PTSA_MIN_0 0x480
#define MC_RING1_PTSA_MAX_0 0x484
#define MC_PCX_PTSA_RATE_0 0x4AC
#define MC_PCX_PTSA_MIN_0 0x4B0
#define MC_PCX_PTSA_MAX_0 0x4B4
#define MC_MSE_PTSA_RATE_0 0x4C4
#define MC_MSE_PTSA_MIN_0 0x4C8
#define MC_MSE_PTSA_MAX_0 0x4CC
#define MC_AHB_PTSA_RATE_0 0x4DC
#define MC_AHB_PTSA_MIN_0 0x4E0
#define MC_AHB_PTSA_MAX_0 0x4E4
#define MC_APB_PTSA_RATE_0 0x4E8
#define MC_APB_PTSA_MIN_0 0x4EC
#define MC_APB_PTSA_MAX_0 0x4F0
#define MC_FTOP_PTSA_RATE_0 0x50C
#define MC_HOST_PTSA_RATE_0 0x518
#define MC_HOST_PTSA_MIN_0 0x51C
#define MC_HOST_PTSA_MAX_0 0x520
#define MC_USBX_PTSA_RATE_0 0x524
#define MC_USBX_PTSA_MIN_0 0x528
#define MC_USBX_PTSA_MAX_0 0x52C
#define MC_USBD_PTSA_RATE_0 0x530
#define MC_USBD_PTSA_MIN_0 0x534
#define MC_USBD_PTSA_MAX_0 0x538
#define MC_GK_PTSA_RATE_0 0x53C
#define MC_GK_PTSA_MIN_0 0x540
#define MC_GK_PTSA_MAX_0 0x544
#define MC_AUD_PTSA_RATE_0 0x548
#define MC_AUD_PTSA_MIN_0 0x54C
#define MC_AUD_PTSA_MAX_0 0x550
#define MC_VICPC_PTSA_RATE_0 0x554
#define MC_VICPC_PTSA_MIN_0 0x558
#define MC_VICPC_PTSA_MAX_0 0x55C
#define MC_JPG_PTSA_RATE_0 0x584
#define MC_JPG_PTSA_MIN_0 0x588
#define MC_JPG_PTSA_MAX_0 0x58C
#define MC_GK2_PTSA_RATE_0 0x610
#define MC_GK2_PTSA_MIN_0 0x614
#define MC_GK2_PTSA_MAX_0 0x618
#define MC_SDM_PTSA_RATE_0 0x61C
#define MC_SDM_PTSA_MIN_0 0x620
#define MC_SDM_PTSA_MAX_0 0x624
#define MC_HDAPC_PTSA_RATE_0 0x628
#define MC_HDAPC_PTSA_MIN_0 0x62C
#define MC_HDAPC_PTSA_MAX_0 0x630
#define MC_SEC_CARVEOUT_BOM_0 0x670
#define MC_SEC_CARVEOUT_SIZE_MB_0 0x674
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0A_0 0x690
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0AB_0 0x694
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0B_0 0x698
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0BB_0 0x69C
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0C_0 0x6A0
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0CB_0 0x6A4
#define MC_EMEM_ARB_TIMING_RFCPB_0 0x6C0
#define MC_EMEM_ARB_TIMING_CCDMW_0 0x6C4
#define MC_EMEM_ARB_REFPB_HP_CTRL_0 0x6F0
#define MC_EMEM_ARB_REFPB_BANK_CTRL_0 0x6F4
#define MC_PTSA_GRANT_DECREMENT_0 0x960
#define MC_CLIENT_HOTRESET_CTRL_1 0x970
#define MC_CLIENT_HOTRESET_STATUS_1 0x974
#define MC_SMMU_PTC_FLUSH_1 0x9B8
#define MC_SMMU_DC1_ASID_0 0xA88
#define MC_SMMU_SDMMC1A_ASID_0 0xA94
#define MC_SMMU_SDMMC2A_ASID_0 0xA98
#define MC_SMMU_SDMMC3A_ASID_0 0xA9C
#define MC_SMMU_SDMMC4A_ASID_0 0xAA0
#define MC_SMMU_ISP2B_ASID_0 0xAA4
#define MC_SMMU_GPU_ASID_0 0xAA8
#define MC_SMMU_GPUB_ASID_0 0xAAC
#define MC_SMMU_PPCS2_ASID_0 0xAB0
#define MC_SMMU_NVDEC_ASID_0 0xAB4
#define MC_SMMU_APE_ASID_0 0xAB8
#define MC_SMMU_SE_ASID_0 0xABC
#define MC_SMMU_NVJPG_ASID_0 0xAC0
#define MC_SMMU_HC1_ASID_0 0xAC4
#define MC_SMMU_SE1_ASID_0 0xAC8
#define MC_SMMU_AXIAP_ASID_0 0xACC
#define MC_SMMU_ETR_ASID_0 0xAD0
#define MC_SMMU_TSECB_ASID_0 0xAD4
#define MC_SMMU_TSEC1_ASID_0 0xAD8
#define MC_SMMU_TSECB1_ASID_0 0xADC
#define MC_SMMU_NVDEC1_ASID_0 0xAE0
#define MC_EMEM_ARB_DHYST_CTRL_0 0xBCC
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0 0xBD0
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1 0xBD4
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2 0xBD8
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3 0xBDC
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4 0xBE0
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5 0xBE4
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6 0xBE8
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7 0xBEC
#define MC_ERR_GENERALIZED_CARVEOUT_STATUS_0 0xC00
#define MC_SECURITY_CARVEOUT2_BOM_0 0xC5C
#define MC_SECURITY_CARVEOUT3_BOM_0 0xCAC
#define CLDVFS_REGION_BASE 0x70110000
#define CLDVFS_REGION_SIZE 0x1000
#define CL_DVFS_CTRL_0 0x0
#define CL_DVFS_CONFIG_0 0x4
#define CL_DVFS_PARAMS_0 0x8
#define CL_DVFS_TUNE0_0 0xC
#define CL_DVFS_TUNE1_0 0x10
#define CL_DVFS_FREQ_REQ_0 0x14
#define CL_DVFS_SCALE_RAMP_0 0x18
#define CL_DVFS_DROOP_CTRL_0 0x1C
#define CL_DVFS_OUTPUT_CFG_0 0x20
#define CL_DVFS_OUTPUT_FORCE_0 0x24
#define CL_DVFS_MONITOR_CTRL_0 0x28
#define CL_DVFS_MONITOR_DATA_0 0x2C
#define CL_DVFS_I2C_CFG_0 0x40
#define CL_DVFS_I2C_VDD_REG_ADDR_0 0x44
#define CL_DVFS_I2C_STS_0 0x48
#define CL_DVFS_INTR_STS_0 0x5C
#define CL_DVFS_INTR_EN_0 0x60
#define DVFS_DFLL_THROTTLE_CTRL_0 0x64
#define DVFS_DFLL_THROTTLE_LIGHT_0 0x68
#define DVFS_DFLL_THROTTLE_MEDIUM_0 0x6C
#define DVFS_DFLL_THROTTLE_HEAVY_0 0x70
#define DVFS_CC4_HVC_0 0x74
#define CL_DVFS_MONITOR_DATA_0 0x2C
#define CL_DVFS_I2C_CFG_0 0x40
#define CL_DVFS_I2C_VDD_REG_ADDR_0 0x44
#define CL_DVFS_I2C_STS_0 0x48
#define CL_DVFS_INTR_STS_0 0x5C
#define CL_DVFS_I2C_CLK_DIVISOR_REGISTER_0 0x16C

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) ppkantorski (bord2death)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <switch.h>
#include "pcv_types.h"
typedef struct {
Service s;
} RgltrSession;
Result rgltrInitialize(void);
void rgltrExit(void);
Service* rgltrGetServiceSession(void);
Result rgltrOpenSession(RgltrSession* session_out, PowerDomainId module_id);
void rgltrCloseSession(RgltrSession* session);
Result rgltrGetVoltage(RgltrSession* session, u32 *out_volt);
Result rgltrGetPowerModuleNumLimit(u32 *out);
Result rgltrGetVoltageEnabled(RgltrSession* session, u32 *out);
Result rgltrRequestVoltage(RgltrSession* session, u32 microvolt);
Result rgltrCancelVoltageRequest(RgltrSession* session);

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) ppkantorski (bord2death)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <switch.h> // for Service, Result, hosversionBefore(), smGetService(), serviceClose(), etc.
#include "rgltr.h" // for RgltrSession, PowerDomainId, etc.
extern Service g_rgltrSrv;
Result rgltrInitialize(void);
void rgltrExit(void);
Result rgltrOpenSession(RgltrSession* session_out, PowerDomainId module_id);
Result rgltrGetVoltage(RgltrSession* session, u32* out_volt);
void rgltrCloseSession(RgltrSession* session);

View File

@@ -0,0 +1,82 @@
/*
* Copyright (c) MasaGratoR
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <switch/types.h>
#include <switch/result.h>
#include <switch/kernel/mutex.h>
#include <switch/sf/service.h>
#include <switch/services/sm.h>
typedef struct ServiceGuard {
Mutex mutex;
u32 refCount;
} ServiceGuard;
NX_INLINE bool serviceGuardBeginInit(ServiceGuard* g)
{
mutexLock(&g->mutex);
return (g->refCount++) == 0;
}
NX_INLINE Result serviceGuardEndInit(ServiceGuard* g, Result rc, void (*cleanupFunc)(void))
{
if (R_FAILED(rc)) {
cleanupFunc();
--g->refCount;
}
mutexUnlock(&g->mutex);
return rc;
}
NX_INLINE void serviceGuardExit(ServiceGuard* g, void (*cleanupFunc)(void))
{
mutexLock(&g->mutex);
if (g->refCount && (--g->refCount) == 0)
cleanupFunc();
mutexUnlock(&g->mutex);
}
#define NX_GENERATE_SERVICE_GUARD_PARAMS(name, _paramdecl, _parampass) \
\
static ServiceGuard g_##name##Guard; \
NX_INLINE Result _##name##Initialize _paramdecl; \
static void _##name##Cleanup(void); \
\
Result name##Initialize _paramdecl \
{ \
Result rc = 0; \
if (serviceGuardBeginInit(&g_##name##Guard)) \
rc = _##name##Initialize _parampass; \
return serviceGuardEndInit(&g_##name##Guard, rc, _##name##Cleanup); \
} \
\
void name##Exit(void) \
{ \
serviceGuardExit(&g_##name##Guard, _##name##Cleanup); \
}
#define NX_GENERATE_SERVICE_GUARD(name) NX_GENERATE_SERVICE_GUARD_PARAMS(name, (void), ())
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 <cstdint>
#include <switch.h> // include libnx
#ifdef __cplusplus
#include "cpp_util.hpp"
extern "C" {
#endif
// typedef std::uint32_t Result;
// typedef std::uint32_t u32;
// typedef std::int32_t s32;
// typedef std::uint64_t u64;
// typedef std::int64_t s64;
// typedef std::uint8_t u8;
// typedef std::int16_t s16;
// typedef std::uint16_t u16;
#include "sysclk/ipc.h"
#include "sysclk/board.h"
#include "sysclk/clock_manager.h"
#include "sysclk/apm.h"
#include "sysclk/config.h"
#include "sysclk/errors.h"
#include "sysclk/psm_ext.h"
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 "board.h"
typedef struct {
uint32_t id;
uint32_t cpu_hz;
uint32_t gpu_hz;
uint32_t mem_hz;
} SysClkApmConfiguration;
extern SysClkApmConfiguration sysclk_g_apm_configurations[];

View File

@@ -0,0 +1,279 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <switch/types.h>
typedef enum
{
SysClkSocType_Erista = 0,
SysClkSocType_Mariko,
SysClkSocType_EnumMax
} SysClkSocType;
typedef enum
{
HorizonOCConsoleType_Icosa = 0,
HorizonOCConsoleType_Copper,
HorizonOCConsoleType_Hoag,
HorizonOCConsoleType_Iowa,
HorizonOCConsoleType_Calcio,
HorizonOCConsoleType_Aula,
HorizonOCConsoleType_EnumMax,
} HorizonOCConsoleType;
typedef enum {
HocClkVoltage_SOC = 0,
HocClkVoltage_EMCVDD2,
HocClkVoltage_CPU,
HocClkVoltage_GPU,
HocClkVoltage_EMCVDDQ_MarikoOnly,
HocClkVoltage_Display,
HocClkVoltage_Battery,
HocClkVoltage_EnumMax,
} HocClkVoltage;
typedef enum
{
SysClkProfile_Handheld = 0,
SysClkProfile_HandheldCharging,
SysClkProfile_HandheldChargingUSB,
SysClkProfile_HandheldChargingOfficial,
SysClkProfile_Docked,
SysClkProfile_EnumMax
} SysClkProfile;
typedef enum
{
SysClkModule_CPU = 0,
SysClkModule_GPU,
SysClkModule_MEM,
HorizonOCModule_Governor,
HorizonOCModule_Display,
SysClkModule_EnumMax,
} SysClkModule;
typedef enum
{
SysClkThermalSensor_SOC = 0,
SysClkThermalSensor_PCB,
SysClkThermalSensor_Skin,
HorizonOCThermalSensor_Battery,
HorizonOCThermalSensor_PMIC,
HorizonOCThermalSensor_CPU,
HorizonOCThermalSensor_GPU,
HorizonOCThermalSensor_MEM,
HorizonOCThermalSensor_PLLX,
SysClkThermalSensor_EnumMax
} SysClkThermalSensor;
typedef enum
{
SysClkPowerSensor_Now = 0,
SysClkPowerSensor_Avg,
SysClkPowerSensor_EnumMax
} SysClkPowerSensor;
typedef enum
{
SysClkPartLoad_EMC = 0,
SysClkPartLoad_EMCCpu,
HocClkPartLoad_GPU,
HocClkPartLoad_CPUMax,
HocClkPartLoad_BAT,
HocClkPartLoad_FAN,
SysClkPartLoad_EnumMax
} SysClkPartLoad;
typedef enum {
HorizonOCSpeedo_CPU = 0,
HorizonOCSpeedo_GPU,
HorizonOCSpeedo_SOC,
HorizonOCSpeedo_EnumMax,
} HorizonOCSpeedo;
typedef enum {
GPUUVLevel_NoUV = 0,
GPUUVLevel_SLT,
GPUUVLevel_HiOPT,
GPUUVLevel_EnumMax,
} GPUUndervoltLevel;
enum {
DVFSMode_Disabled = 0,
DVFSMode_Hijack,
// DVFSMode_OfficialService,
// DVFSMode_Hack,
DVFSMode_EnumMax,
};
typedef enum {
GpuSchedulingMode_DoNotOverride = 0,
GpuSchedulingMode_Enabled,
GpuSchedulingMode_Disabled,
GpuSchedulingMode_EnumMax,
} GpuSchedulingMode;
typedef enum {
GpuSchedulingOverrideMethod_Ini = 0,
GpuSchedulingOverrideMethod_NvService,
GpuSchedulingOverrideMethod_EnumMax,
} GpuSchedulingOverrideMethod;
typedef enum {
ComponentGovernor_DoNotOverride = 0,
ComponentGovernor_Disabled = 1,
ComponentGovernor_Enabled = 2,
ComponentGovernor_EnumMax,
} ComponentGovernorState;
typedef enum {
RamDisplayMode_VDD2VDDQ = 0,
RamDisplayMode_VDD2Usage,
RamDisplayMode_VDDQUsage,
RamDisplayMode_EnumMax,
} RamDisplayMode;
#define SYSCLK_ENUM_VALID(n, v) ((v) < n##_EnumMax)
// Packed u32
// Bits 0-7 - CPU
// Bits 8-15 - GPU
// Bits 16-23 - VRR
// Bits 24-32 - unused
inline u32 GovernorStatePack(u8 cpu, u8 gpu, u8 vrr) {
return (u32)cpu | ((u32)gpu << 8) | ((u32)vrr << 16);
}
inline u8 GovernorStateCpu(u32 p) {
return (u8)(p & 0xFF);
}
inline u8 GovernorStateGpu(u32 p) {
return (u8)((p >> 8) & 0xFF);
}
inline u8 GovernorStateVrr(u32 p) {
return (u8)((p >> 16) & 0xFF);
}
static inline const char* sysclkFormatModule(SysClkModule module, bool pretty)
{
switch(module)
{
case SysClkModule_CPU:
return pretty ? "CPU" : "cpu";
case SysClkModule_GPU:
return pretty ? "GPU" : "gpu";
case SysClkModule_MEM:
return pretty ? "Memory" : "mem";
case HorizonOCModule_Display:
return pretty ? "Display" : "display";
case HorizonOCModule_Governor:
return pretty ? "Governor" : "governor";
default:
return "null";
}
}
static inline const char* sysclkFormatThermalSensor(SysClkThermalSensor thermSensor, bool pretty)
{
switch(thermSensor)
{
case SysClkThermalSensor_SOC:
return pretty ? "SOC" : "soc";
case SysClkThermalSensor_PCB:
return pretty ? "PCB" : "pcb";
case SysClkThermalSensor_Skin:
return pretty ? "Skin" : "skin";
case HorizonOCThermalSensor_Battery:
return pretty ? "BAT" : "battery";
case HorizonOCThermalSensor_PMIC:
return pretty ? "PMIC" : "pmic";
case HorizonOCThermalSensor_CPU:
return pretty ? "CPU" : "cpu";
case HorizonOCThermalSensor_GPU:
return pretty ? "GPU" : "gpu";
case HorizonOCThermalSensor_MEM:
return pretty ? "MEM" : "mem";
default:
return NULL;
}
}
static inline const char* sysclkFormatPowerSensor(SysClkPowerSensor powSensor, bool pretty)
{
switch(powSensor)
{
case SysClkPowerSensor_Now:
return pretty ? "Now" : "now";
case SysClkPowerSensor_Avg:
return pretty ? "Avg" : "avg";
default:
return NULL;
}
}
static inline const char* sysclkFormatProfile(SysClkProfile profile, bool pretty)
{
switch(profile)
{
case SysClkProfile_Docked:
return pretty ? "Docked" : "docked";
case SysClkProfile_Handheld:
return pretty ? "Handheld" : "handheld";
case SysClkProfile_HandheldCharging:
return pretty ? "Charging" : "handheld_charging";
case SysClkProfile_HandheldChargingUSB:
return pretty ? "USB Charger" : "handheld_charging_usb";
case SysClkProfile_HandheldChargingOfficial:
return pretty ? "PD Charger" : "handheld_charging_official";
default:
return NULL;
}
}
static inline const char* hocClkFormatVoltage(HocClkVoltage voltage, bool pretty)
{
switch(voltage)
{
case HocClkVoltage_CPU:
return pretty ? "CPU" : "cpu";
case HocClkVoltage_GPU:
return pretty ? "GPU" : "gpu";
case HocClkVoltage_EMCVDD2:
return pretty ? "VDD2" : "emcvdd2";
case HocClkVoltage_EMCVDDQ_MarikoOnly:
return pretty ? "VDDQ" : "vddq";
case HocClkVoltage_SOC:
return pretty ? "SOC" : "soc";
case HocClkVoltage_Display:
return pretty ? "Display" : "display";
default:
return NULL;
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 "types.h"
#include "../config.h"
#include "../board.h"
#include "../ipc.h"
bool sysclkIpcRunning();
Result sysclkIpcInitialize(void);
void sysclkIpcExit(void);
Result sysclkIpcGetAPIVersion(u32* out_ver);
Result sysclkIpcGetVersionString(char* out, size_t len);
Result sysclkIpcGetCurrentContext(SysClkContext* out_context);
Result sysclkIpcGetProfileCount(u64 tid, u8* out_count);
Result sysclkIpcSetEnabled(bool enabled);
Result sysclkIpcExitCmd();
Result sysclkIpcSetOverride(SysClkModule module, u32 hz);
Result sysclkIpcGetProfiles(u64 tid, SysClkTitleProfileList* out_profiles);
Result sysclkIpcSetProfiles(u64 tid, SysClkTitleProfileList* profiles);
Result sysclkIpcGetConfigValues(SysClkConfigValueList* out_configValues);
Result sysclkIpcSetConfigValues(SysClkConfigValueList* configValues);
Result sysclkIpcGetFreqList(SysClkModule module, u32* list, u32 maxCount, u32* outCount);
Result hocClkIpcSetKipData();
Result hocClkIpcGetKipData();
static inline Result sysclkIpcRemoveOverride(SysClkModule module)
{
return sysclkIpcSetOverride(module, 0);
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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
#ifdef __SWITCH__
#include <switch/types.h>
#include <switch/result.h>
#else
#define R_FAILED(res) ((res) != 0)
#define R_SUCCEEDED(res) ((res) == 0)
typedef std::uint32_t Result;
typedef std::uint32_t u32;
typedef std::int32_t s32;
typedef std::uint64_t u64;
typedef std::uint8_t u8;
#endif

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 <stdint.h>
#include "board.h"
typedef struct
{
uint64_t applicationId;
SysClkProfile profile;
uint32_t freqs[SysClkModule_EnumMax];
uint32_t realFreqs[SysClkModule_EnumMax];
uint32_t overrideFreqs[SysClkModule_EnumMax];
uint32_t temps[SysClkThermalSensor_EnumMax];
int32_t power[SysClkPowerSensor_EnumMax];
uint32_t partLoad[SysClkPartLoad_EnumMax];
uint32_t voltages[HocClkVoltage_EnumMax];
u16 speedos[HorizonOCSpeedo_EnumMax];
u16 iddq[HorizonOCSpeedo_EnumMax];
u16 waferX;
u16 waferY;
// Misc stuff
GpuSchedulingMode gpuSchedulingMode;
bool isSysDockInstalled;
bool isSaltyNXInstalled;
bool isUsingRetroSuper;
u8 maxDisplayFreq;
u8 dramID;
bool isDram8GB;
// FPS / Resolution
u8 fps;
u16 resolutionHeight;
} SysClkContext;
typedef struct
{
union {
uint32_t mhz[+SysClkProfile_EnumMax * +SysClkModule_EnumMax];
uint32_t mhzMap[+SysClkProfile_EnumMax][+SysClkModule_EnumMax];
};
} SysClkTitleProfileList;
#define SYSCLK_FREQ_LIST_MAX 32
#define GLOBAL_PROFILE_ID 0xA111111111111111

View File

@@ -0,0 +1,594 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 <stdint.h>
#include <stddef.h>
typedef enum {
SysClkConfigValue_PollingIntervalMs = 0,
SysClkConfigValue_TempLogIntervalMs,
SysClkConfigValue_FreqLogIntervalMs,
SysClkConfigValue_PowerLogIntervalMs,
SysClkConfigValue_CsvWriteIntervalMs,
HocClkConfigValue_UncappedClocks,
HocClkConfigValue_OverwriteBoostMode,
HocClkConfigValue_EristaMaxCpuClock,
HocClkConfigValue_MarikoMaxCpuClock,
HocClkConfigValue_ThermalThrottle,
HocClkConfigValue_ThermalThrottleThreshold,
HocClkConfigValue_HandheldTDP,
HocClkConfigValue_HandheldTDPLimit,
HocClkConfigValue_LiteTDPLimit,
HorizonOCConfigValue_BatteryChargeCurrent,
HorizonOCConfigValue_OverwriteRefreshRate,
HorizonOCConfigValue_MaxDisplayClockH,
HorizonOCConfigValue_DVFSMode,
HorizonOCConfigValue_DVFSOffset,
HorizonOCConfigValue_LiveCpuUv,
HorizonOCConfigValue_EnableExperimentalSettings,
HorizonOCConfigValue_GPUScheduling,
HorizonOCConfigValue_GPUSchedulingMethod,
HorizonOCConfigValue_RAMVoltUsageDisplayMode,
HorizonOCConfigValue_CpuGovernorMinimumFreq,
KipConfigValue_custRev,
// KipConfigValue_mtcConf,
KipConfigValue_hpMode,
KipConfigValue_commonEmcMemVolt,
KipConfigValue_eristaEmcMaxClock,
KipConfigValue_eristaEmcMaxClock1,
KipConfigValue_eristaEmcMaxClock2,
KipConfigValue_marikoEmcMaxClock,
KipConfigValue_marikoEmcVddqVolt,
KipConfigValue_emcDvbShift,
KipConfigValue_t1_tRCD,
KipConfigValue_t2_tRP,
KipConfigValue_t3_tRAS,
KipConfigValue_t4_tRRD,
KipConfigValue_t5_tRFC,
KipConfigValue_t6_tRTW,
KipConfigValue_t7_tWTR,
KipConfigValue_t8_tREFI,
KipConfigValue_mem_burst_read_latency,
KipConfigValue_mem_burst_write_latency,
KipConfigValue_eristaCpuUV,
KipConfigValue_eristaCpuVmin,
KipConfigValue_eristaCpuMaxVolt,
KipConfigValue_eristaCpuUnlock,
KipConfigValue_marikoCpuUVLow,
KipConfigValue_marikoCpuUVHigh,
KipConfigValue_tableConf,
KipConfigValue_marikoCpuLowVmin,
KipConfigValue_marikoCpuHighVmin,
KipConfigValue_marikoCpuMaxVolt,
KipConfigValue_marikoCpuMaxClock,
KipConfigValue_eristaCpuBoostClock,
KipConfigValue_marikoCpuBoostClock,
KipConfigValue_eristaGpuUV,
KipConfigValue_eristaGpuVmin,
KipConfigValue_marikoGpuUV,
KipConfigValue_marikoGpuVmin,
KipConfigValue_marikoGpuVmax,
KipConfigValue_commonGpuVoltOffset,
KipConfigValue_gpuSpeedo,
KipConfigValue_g_volt_76800,
KipConfigValue_g_volt_153600,
KipConfigValue_g_volt_230400,
KipConfigValue_g_volt_307200,
KipConfigValue_g_volt_384000,
KipConfigValue_g_volt_460800,
KipConfigValue_g_volt_537600,
KipConfigValue_g_volt_614400,
KipConfigValue_g_volt_691200,
KipConfigValue_g_volt_768000,
KipConfigValue_g_volt_844800,
KipConfigValue_g_volt_921600,
KipConfigValue_g_volt_998400,
KipConfigValue_g_volt_1075200,
KipConfigValue_g_volt_1152000,
KipConfigValue_g_volt_1228800,
KipConfigValue_g_volt_1267200,
KipConfigValue_g_volt_1305600,
KipConfigValue_g_volt_1344000,
KipConfigValue_g_volt_1382400,
KipConfigValue_g_volt_1420800,
KipConfigValue_g_volt_1459200,
KipConfigValue_g_volt_1497600,
KipConfigValue_g_volt_1536000,
KipConfigValue_g_volt_e_76800,
KipConfigValue_g_volt_e_115200,
KipConfigValue_g_volt_e_153600,
KipConfigValue_g_volt_e_192000,
KipConfigValue_g_volt_e_230400,
KipConfigValue_g_volt_e_268800,
KipConfigValue_g_volt_e_307200,
KipConfigValue_g_volt_e_345600,
KipConfigValue_g_volt_e_384000,
KipConfigValue_g_volt_e_422400,
KipConfigValue_g_volt_e_460800,
KipConfigValue_g_volt_e_499200,
KipConfigValue_g_volt_e_537600,
KipConfigValue_g_volt_e_576000,
KipConfigValue_g_volt_e_614400,
KipConfigValue_g_volt_e_652800,
KipConfigValue_g_volt_e_691200,
KipConfigValue_g_volt_e_729600,
KipConfigValue_g_volt_e_768000,
KipConfigValue_g_volt_e_806400,
KipConfigValue_g_volt_e_844800,
KipConfigValue_g_volt_e_883200,
KipConfigValue_g_volt_e_921600,
KipConfigValue_g_volt_e_960000,
KipConfigValue_g_volt_e_998400,
KipConfigValue_g_volt_e_1036800,
KipConfigValue_g_volt_e_1075200,
KipConfigValue_t6_tRTW_fine_tune,
KipConfigValue_t7_tWTR_fine_tune,
KipCrc32,
HocClkConfigValue_IsFirstLoad,
SysClkConfigValue_EnumMax,
} SysClkConfigValue;
typedef struct {
uint64_t values[SysClkConfigValue_EnumMax];
} SysClkConfigValueList;
static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pretty)
{
switch(val)
{
case SysClkConfigValue_PollingIntervalMs:
return pretty ? "Polling Interval (ms)" : "poll_interval_ms";
case SysClkConfigValue_TempLogIntervalMs:
return pretty ? "Temperature logging interval (ms)" : "temp_log_interval_ms";
case SysClkConfigValue_FreqLogIntervalMs:
return pretty ? "Frequency logging interval (ms)" : "freq_log_interval_ms";
case SysClkConfigValue_PowerLogIntervalMs:
return pretty ? "Power logging interval (ms)" : "power_log_interval_ms";
case SysClkConfigValue_CsvWriteIntervalMs:
return pretty ? "CSV write interval (ms)" : "csv_write_interval_ms";
case HocClkConfigValue_UncappedClocks:
return pretty ? "Uncapped Clocks" : "uncapped_clocks";
case HocClkConfigValue_OverwriteBoostMode:
return pretty ? "Overwrite Boost Mode" : "ow_boost";
case HocClkConfigValue_EristaMaxCpuClock:
return pretty ? "CPU Max Clock" : "cpu_max_e";
case HocClkConfigValue_MarikoMaxCpuClock:
return pretty ? "CPU Max Display Clock" : "cpu_max_m";
case HocClkConfigValue_ThermalThrottle:
return pretty ? "Thermal Throttle" : "thermal_throttle";
case HocClkConfigValue_ThermalThrottleThreshold:
return pretty ? "Thermal Throttle Threshold" : "thermal_throttle_threshold";
case HocClkConfigValue_HandheldTDP:
return pretty ? "Handheld TDP" : "handheld_tdp";
case HocClkConfigValue_HandheldTDPLimit:
return pretty ? "Handheld TDP Limit" : "tdp_limit";
case HocClkConfigValue_LiteTDPLimit:
return pretty ? "Handheld TDP Limit" : "tdp_limit_l";
case HorizonOCConfigValue_BatteryChargeCurrent:
return pretty ? "Battery Charge Current" : "bat_charge_current";
case HorizonOCConfigValue_OverwriteRefreshRate:
return pretty ? "Display Refresh Rate Changing" : "drr_changing";
case HorizonOCConfigValue_MaxDisplayClockH:
return pretty ? "Max Display Clock (Handheld)" : "drr_max_clock";
case HorizonOCConfigValue_DVFSMode:
return pretty ? "DVFS Mode" : "dvfs_mode";
case HorizonOCConfigValue_DVFSOffset:
return pretty ? "DVFS Offset" : "dvfs_offset";
case HorizonOCConfigValue_GPUScheduling:
return pretty ? "GPU Scheduling" : "gpu_scheduling";
case HorizonOCConfigValue_GPUSchedulingMethod:
return pretty ? "GPU Scheduling Method" : "gpu_sched_method";
case HorizonOCConfigValue_LiveCpuUv:
return pretty ? "Live CPU Undervolt" : "live_cpu_uv";
case HorizonOCConfigValue_EnableExperimentalSettings:
return pretty ? "Enable Experimental Settings" : "enable_experimental_settings";
case HorizonOCConfigValue_RAMVoltUsageDisplayMode:
return pretty ? "RAM Voltage / Usage Display Mode" : "ram_volt_usage_display_mode";
case HorizonOCConfigValue_CpuGovernorMinimumFreq:
return pretty ? "CPU Governor Minimum Frequency" : "cpu_gov_min_freq";
// KIP config values
case KipConfigValue_custRev:
return pretty ? "Custom Revision" : "kip_cust_rev";
// case KipConfigValue_mtcConf:
// return pretty ? "MTC Config" : "kip_mtc_conf";
case KipConfigValue_hpMode:
return pretty ? "HP Mode" : "kip_hp_mode";
// EMC
case KipConfigValue_commonEmcMemVolt:
return pretty ? "Common EMC/MEM Voltage" : "common_emc_mem_volt";
case KipConfigValue_eristaEmcMaxClock:
return pretty ? "Erista EMC Max Clock 1" : "erista_emc_max_clock";
case KipConfigValue_eristaEmcMaxClock1:
return pretty ? "Erista EMC Max Clock 2" : "erista_emc_max_clock1";
case KipConfigValue_eristaEmcMaxClock2:
return pretty ? "Erista EMC Max Clock 3" : "erista_emc_max_clock2";
case KipConfigValue_marikoEmcMaxClock:
return pretty ? "Mariko EMC Max Clock" : "mariko_emc_max_clock";
case KipConfigValue_marikoEmcVddqVolt:
return pretty ? "Mariko EMC VDDQ Voltage" : "mariko_emc_vddq_volt";
case KipConfigValue_emcDvbShift:
return pretty ? "EMC DVB Shift" : "emc_dvb_shift";
// Memory timings
case KipConfigValue_t1_tRCD:
return pretty ? "t1 - tRCD" : "t1_trcd";
case KipConfigValue_t2_tRP:
return pretty ? "t2 - tRP" : "t2_trp";
case KipConfigValue_t3_tRAS:
return pretty ? "t3 - tRAS" : "t3_tras";
case KipConfigValue_t4_tRRD:
return pretty ? "t4 - tRRD" : "t4_trrd";
case KipConfigValue_t5_tRFC:
return pretty ? "t5 - tRFC" : "t5_trfc";
case KipConfigValue_t6_tRTW:
return pretty ? "t6 - tRTW" : "t6_trtw";
case KipConfigValue_t7_tWTR:
return pretty ? "t7 - tWTR" : "t7_twtr";
case KipConfigValue_t8_tREFI:
return pretty ? "t8 - tREFI" : "t8_trefi";
case KipConfigValue_mem_burst_read_latency:
return pretty ? "Memory Burst Read Latency" : "mem_burst_read_latency";
case KipConfigValue_mem_burst_write_latency:
return pretty ? "Memory Burst Write Latency" : "mem_burst_write_latency";
// CPU Erista
case KipConfigValue_eristaCpuUV:
return pretty ? "Erista CPU Undervolt" : "erista_cpu_uv";
case KipConfigValue_eristaCpuVmin:
return pretty ? "Erista CPU vMin" : "erista_cpu_vmin";
case KipConfigValue_eristaCpuMaxVolt:
return pretty ? "Erista CPU Max Voltage" : "erista_cpu_max_volt";
case KipConfigValue_eristaCpuUnlock:
return pretty ? "Erista CPU Unlock" : "erista_cpu_unlock";
// CPU Mariko
case KipConfigValue_marikoCpuUVLow:
return pretty ? "Mariko CPU Undervolt (Low)" : "mariko_cpu_uv_low";
case KipConfigValue_marikoCpuUVHigh:
return pretty ? "Mariko CPU Undervolt (High)" : "mariko_cpu_uv_high";
case KipConfigValue_tableConf:
return pretty ? "Table Config" : "kip_table_conf";
case KipConfigValue_marikoCpuLowVmin:
return pretty ? "Mariko CPU Low Vmin" : "mariko_cpu_low_vmin";
case KipConfigValue_marikoCpuHighVmin:
return pretty ? "Mariko CPU High Vmin" : "mariko_cpu_high_vmin";
case KipConfigValue_marikoCpuMaxVolt:
return pretty ? "Mariko CPU Max Voltage" : "mariko_cpu_max_volt";
case KipConfigValue_eristaCpuBoostClock:
return pretty ? "Erista CPU Boost Clock" : "erista_cpu_boost_clock";
case KipConfigValue_marikoCpuBoostClock:
return pretty ? "Mariko CPU Boost Clock" : "mariko_cpu_boost_clock";
case KipConfigValue_marikoCpuMaxClock:
return pretty ? "Mariko CPU Max Clock" : "mariko_cpu_max_clock";
// GPU Erista
case KipConfigValue_eristaGpuUV:
return pretty ? "Erista GPU Undervolt" : "erista_gpu_uv";
case KipConfigValue_eristaGpuVmin:
return pretty ? "Erista GPU Vmin" : "erista_gpu_vmin";
// GPU Mariko
case KipConfigValue_marikoGpuUV:
return pretty ? "Mariko GPU Undervolt" : "mariko_gpu_uv";
case KipConfigValue_marikoGpuVmin:
return pretty ? "Mariko GPU Vmin" : "mariko_gpu_vmin";
case KipConfigValue_marikoGpuVmax:
return pretty ? "Mariko GPU Vmax" : "mariko_gpu_vmax";
case KipConfigValue_commonGpuVoltOffset:
return pretty ? "Common GPU Voltage Offset" : "common_gpu_volt_offset";
case KipConfigValue_gpuSpeedo:
return pretty ? "GPU Speedo" : "gpu_speedo";
// Mariko GPU voltages (24)
case KipConfigValue_g_volt_76800: return pretty ? "Mariko GPU Volt 76 MHz" : "g_volt_76800";
case KipConfigValue_g_volt_153600: return pretty ? "Mariko GPU Volt 153 MHz" : "g_volt_153600";
case KipConfigValue_g_volt_230400: return pretty ? "Mariko GPU Volt 230 MHz" : "g_volt_230400";
case KipConfigValue_g_volt_307200: return pretty ? "Mariko GPU Volt 307 MHz" : "g_volt_307200";
case KipConfigValue_g_volt_384000: return pretty ? "Mariko GPU Volt 384 MHz" : "g_volt_384000";
case KipConfigValue_g_volt_460800: return pretty ? "Mariko GPU Volt 460 MHz" : "g_volt_460800";
case KipConfigValue_g_volt_537600: return pretty ? "Mariko GPU Volt 537 MHz" : "g_volt_537600";
case KipConfigValue_g_volt_614400: return pretty ? "Mariko GPU Volt 614 MHz" : "g_volt_614400";
case KipConfigValue_g_volt_691200: return pretty ? "Mariko GPU Volt 691 MHz" : "g_volt_691200";
case KipConfigValue_g_volt_768000: return pretty ? "Mariko GPU Volt 768 MHz" : "g_volt_768000";
case KipConfigValue_g_volt_844800: return pretty ? "Mariko GPU Volt 844 MHz" : "g_volt_844800";
case KipConfigValue_g_volt_921600: return pretty ? "Mariko GPU Volt 921 MHz" : "g_volt_921600";
case KipConfigValue_g_volt_998400: return pretty ? "Mariko GPU Volt 998 MHz" : "g_volt_998400";
case KipConfigValue_g_volt_1075200: return pretty ? "Mariko GPU Volt 1075 MHz" : "g_volt_1075200";
case KipConfigValue_g_volt_1152000: return pretty ? "Mariko GPU Volt 1152 MHz" : "g_volt_1152000";
case KipConfigValue_g_volt_1228800: return pretty ? "Mariko GPU Volt 1228 MHz" : "g_volt_1228800";
case KipConfigValue_g_volt_1267200: return pretty ? "Mariko GPU Volt 1267 MHz" : "g_volt_1267200";
case KipConfigValue_g_volt_1305600: return pretty ? "Mariko GPU Volt 1305 MHz" : "g_volt_1305600";
case KipConfigValue_g_volt_1344000: return pretty ? "Mariko GPU Volt 1344 MHz" : "g_volt_1344000";
case KipConfigValue_g_volt_1382400: return pretty ? "Mariko GPU Volt 1382 MHz" : "g_volt_1382400";
case KipConfigValue_g_volt_1420800: return pretty ? "Mariko GPU Volt 1420 MHz" : "g_volt_1420800";
case KipConfigValue_g_volt_1459200: return pretty ? "Mariko GPU Volt 1459 MHz" : "g_volt_1459200";
case KipConfigValue_g_volt_1497600: return pretty ? "Mariko GPU Volt 1497 MHz" : "g_volt_1497600";
case KipConfigValue_g_volt_1536000: return pretty ? "Mariko GPU Volt 1536 MHz" : "g_volt_1536000";
// Erista GPU voltages (27)
case KipConfigValue_g_volt_e_76800: return pretty ? "Erista GPU Volt 76 MHz" : "g_volt_e_76800";
case KipConfigValue_g_volt_e_115200: return pretty ? "Erista GPU Volt 115 MHz" : "g_volt_e_115200";
case KipConfigValue_g_volt_e_153600: return pretty ? "Erista GPU Volt 153 MHz" : "g_volt_e_153600";
case KipConfigValue_g_volt_e_192000: return pretty ? "Erista GPU Volt 192 MHz" : "g_volt_e_192000";
case KipConfigValue_g_volt_e_230400: return pretty ? "Erista GPU Volt 230 MHz" : "g_volt_e_230400";
case KipConfigValue_g_volt_e_268800: return pretty ? "Erista GPU Volt 268 MHz" : "g_volt_e_268800";
case KipConfigValue_g_volt_e_307200: return pretty ? "Erista GPU Volt 307 MHz" : "g_volt_e_307200";
case KipConfigValue_g_volt_e_345600: return pretty ? "Erista GPU Volt 345 MHz" : "g_volt_e_345600";
case KipConfigValue_g_volt_e_384000: return pretty ? "Erista GPU Volt 384 MHz" : "g_volt_e_384000";
case KipConfigValue_g_volt_e_422400: return pretty ? "Erista GPU Volt 422 MHz" : "g_volt_e_422400";
case KipConfigValue_g_volt_e_460800: return pretty ? "Erista GPU Volt 460 MHz" : "g_volt_e_460800";
case KipConfigValue_g_volt_e_499200: return pretty ? "Erista GPU Volt 499 MHz" : "g_volt_e_499200";
case KipConfigValue_g_volt_e_537600: return pretty ? "Erista GPU Volt 537 MHz" : "g_volt_e_537600";
case KipConfigValue_g_volt_e_576000: return pretty ? "Erista GPU Volt 576 MHz" : "g_volt_e_576000";
case KipConfigValue_g_volt_e_614400: return pretty ? "Erista GPU Volt 614 MHz" : "g_volt_e_614400";
case KipConfigValue_g_volt_e_652800: return pretty ? "Erista GPU Volt 652 MHz" : "g_volt_e_652800";
case KipConfigValue_g_volt_e_691200: return pretty ? "Erista GPU Volt 691 MHz" : "g_volt_e_691200";
case KipConfigValue_g_volt_e_729600: return pretty ? "Erista GPU Volt 729 MHz" : "g_volt_e_729600";
case KipConfigValue_g_volt_e_768000: return pretty ? "Erista GPU Volt 768 MHz" : "g_volt_e_768000";
case KipConfigValue_g_volt_e_806400: return pretty ? "Erista GPU Volt 806 MHz" : "g_volt_e_806400";
case KipConfigValue_g_volt_e_844800: return pretty ? "Erista GPU Volt 844 MHz" : "g_volt_e_844800";
case KipConfigValue_g_volt_e_883200: return pretty ? "Erista GPU Volt 883 MHz" : "g_volt_e_883200";
case KipConfigValue_g_volt_e_921600: return pretty ? "Erista GPU Volt 921 MHz" : "g_volt_e_921600";
case KipConfigValue_g_volt_e_960000: return pretty ? "Erista GPU Volt 960 MHz" : "g_volt_e_960000";
case KipConfigValue_g_volt_e_998400: return pretty ? "Erista GPU Volt 998 MHz" : "g_volt_e_998400";
case KipConfigValue_g_volt_e_1036800: return pretty ? "Erista GPU Volt 1036 MHz" : "g_volt_e_1036800";
case KipConfigValue_g_volt_e_1075200: return pretty ? "Erista GPU Volt 1075 MHz" : "g_volt_e_1075200";
case KipConfigValue_t6_tRTW_fine_tune: return pretty ? "t6 - tRTW Fine Tune" : "t6_tRTW_fine_fune";
case KipConfigValue_t7_tWTR_fine_tune: return pretty ? "t7 - tWTR Fine Tune" : "t7_tWTR_fine_tune";
case KipCrc32:
return pretty ? "CRC32" : "crc32";
case HocClkConfigValue_IsFirstLoad:
return pretty ? "Is First Load" : "is_first_load";
default:
return pretty ? "[cfg] no enum format string" : "err_no_format_string";
}
}
static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val)
{
switch(val)
{
case SysClkConfigValue_PollingIntervalMs:
return 300ULL;
case SysClkConfigValue_TempLogIntervalMs:
case SysClkConfigValue_FreqLogIntervalMs:
case SysClkConfigValue_PowerLogIntervalMs:
case SysClkConfigValue_CsvWriteIntervalMs:
case HocClkConfigValue_UncappedClocks:
case HocClkConfigValue_OverwriteBoostMode:
case HorizonOCConfigValue_BatteryChargeCurrent:
case HorizonOCConfigValue_OverwriteRefreshRate:
case HorizonOCConfigValue_GPUScheduling:
case HorizonOCConfigValue_LiveCpuUv:
case HorizonOCConfigValue_GPUSchedulingMethod:
return 0ULL;
case HocClkConfigValue_EristaMaxCpuClock:
return 1785ULL;
case HocClkConfigValue_MarikoMaxCpuClock:
return 1963ULL;
case HocClkConfigValue_ThermalThrottle:
case HocClkConfigValue_HandheldTDP:
case HocClkConfigValue_IsFirstLoad:
case HorizonOCConfigValue_DVFSMode:
return 1ULL;
case HocClkConfigValue_ThermalThrottleThreshold:
return 70ULL;
case HocClkConfigValue_HandheldTDPLimit:
return 9600ULL; // 8600mW will trigger on erista stock, so raise it a bit
case HocClkConfigValue_LiteTDPLimit:
return 6400ULL; // 0.5C
case HorizonOCConfigValue_CpuGovernorMinimumFreq:
return 612000000ULL; // 612MHz
case HorizonOCConfigValue_MaxDisplayClockH:
return 60ULL;
default:
return 0ULL;
}
}
static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t input)
{
switch(val)
{
case HocClkConfigValue_EristaMaxCpuClock:
case HocClkConfigValue_MarikoMaxCpuClock:
case HocClkConfigValue_ThermalThrottleThreshold:
case HocClkConfigValue_HandheldTDPLimit:
case HocClkConfigValue_LiteTDPLimit:
case SysClkConfigValue_PollingIntervalMs:
case HorizonOCConfigValue_MaxDisplayClockH:
return input > 0;
case SysClkConfigValue_TempLogIntervalMs:
case SysClkConfigValue_FreqLogIntervalMs:
case SysClkConfigValue_PowerLogIntervalMs:
case SysClkConfigValue_CsvWriteIntervalMs:
case HocClkConfigValue_UncappedClocks:
case HocClkConfigValue_OverwriteBoostMode:
case HocClkConfigValue_ThermalThrottle:
case HocClkConfigValue_HandheldTDP:
case HorizonOCConfigValue_OverwriteRefreshRate:
case HocClkConfigValue_IsFirstLoad:
case HorizonOCConfigValue_EnableExperimentalSettings:
case HorizonOCConfigValue_LiveCpuUv:
case HorizonOCConfigValue_GPUSchedulingMethod:
return (input & 0x1) == input;
case KipConfigValue_custRev:
// case KipConfigValue_mtcConf:
case KipConfigValue_hpMode:
case KipConfigValue_commonEmcMemVolt:
case KipConfigValue_eristaEmcMaxClock:
case KipConfigValue_eristaEmcMaxClock1:
case KipConfigValue_eristaEmcMaxClock2:
case KipConfigValue_marikoEmcMaxClock:
case KipConfigValue_marikoEmcVddqVolt:
case KipConfigValue_emcDvbShift:
case KipConfigValue_t1_tRCD:
case KipConfigValue_t2_tRP:
case KipConfigValue_t3_tRAS:
case KipConfigValue_t4_tRRD:
case KipConfigValue_t5_tRFC:
case KipConfigValue_t6_tRTW:
case KipConfigValue_t7_tWTR:
case KipConfigValue_t8_tREFI:
case KipConfigValue_mem_burst_read_latency:
case KipConfigValue_mem_burst_write_latency:
case KipConfigValue_eristaCpuUV:
case KipConfigValue_eristaCpuMaxVolt:
case KipConfigValue_marikoCpuUVLow:
case KipConfigValue_marikoCpuUVHigh:
case KipConfigValue_tableConf:
case KipConfigValue_marikoCpuLowVmin:
case KipConfigValue_marikoCpuHighVmin:
case KipConfigValue_marikoCpuMaxVolt:
case KipConfigValue_eristaCpuBoostClock:
case KipConfigValue_marikoCpuBoostClock:
case KipConfigValue_marikoCpuMaxClock:
case KipConfigValue_eristaGpuUV:
case KipConfigValue_eristaGpuVmin:
case KipConfigValue_marikoGpuUV:
case KipConfigValue_marikoGpuVmin:
case KipConfigValue_marikoGpuVmax:
case KipConfigValue_commonGpuVoltOffset:
case KipConfigValue_gpuSpeedo:
case KipConfigValue_g_volt_76800:
case KipConfigValue_g_volt_153600:
case KipConfigValue_g_volt_230400:
case KipConfigValue_g_volt_307200:
case KipConfigValue_g_volt_384000:
case KipConfigValue_g_volt_460800:
case KipConfigValue_g_volt_537600:
case KipConfigValue_g_volt_614400:
case KipConfigValue_g_volt_691200:
case KipConfigValue_g_volt_768000:
case KipConfigValue_g_volt_844800:
case KipConfigValue_g_volt_921600:
case KipConfigValue_g_volt_998400:
case KipConfigValue_g_volt_1075200:
case KipConfigValue_g_volt_1152000:
case KipConfigValue_g_volt_1228800:
case KipConfigValue_g_volt_1267200:
case KipConfigValue_g_volt_1305600:
case KipConfigValue_g_volt_1344000:
case KipConfigValue_g_volt_1382400:
case KipConfigValue_g_volt_1420800:
case KipConfigValue_g_volt_1459200:
case KipConfigValue_g_volt_1497600:
case KipConfigValue_g_volt_1536000:
case KipConfigValue_g_volt_e_76800:
case KipConfigValue_g_volt_e_115200:
case KipConfigValue_g_volt_e_153600:
case KipConfigValue_g_volt_e_192000:
case KipConfigValue_g_volt_e_230400:
case KipConfigValue_g_volt_e_268800:
case KipConfigValue_g_volt_e_307200:
case KipConfigValue_g_volt_e_345600:
case KipConfigValue_g_volt_e_384000:
case KipConfigValue_g_volt_e_422400:
case KipConfigValue_g_volt_e_460800:
case KipConfigValue_g_volt_e_499200:
case KipConfigValue_g_volt_e_537600:
case KipConfigValue_g_volt_e_576000:
case KipConfigValue_g_volt_e_614400:
case KipConfigValue_g_volt_e_652800:
case KipConfigValue_g_volt_e_691200:
case KipConfigValue_g_volt_e_729600:
case KipConfigValue_g_volt_e_768000:
case KipConfigValue_g_volt_e_806400:
case KipConfigValue_g_volt_e_844800:
case KipConfigValue_g_volt_e_883200:
case KipConfigValue_g_volt_e_921600:
case KipConfigValue_g_volt_e_960000:
case KipConfigValue_g_volt_e_998400:
case KipConfigValue_g_volt_e_1036800:
case KipConfigValue_g_volt_e_1075200:
case KipConfigValue_eristaCpuVmin:
case KipConfigValue_eristaCpuUnlock:
case KipConfigValue_t6_tRTW_fine_tune:
case KipConfigValue_t7_tWTR_fine_tune:
case KipCrc32:
case HorizonOCConfigValue_DVFSMode:
case HorizonOCConfigValue_DVFSOffset:
case HorizonOCConfigValue_GPUScheduling:
case HorizonOCConfigValue_RAMVoltUsageDisplayMode:
case HorizonOCConfigValue_CpuGovernorMinimumFreq:
return true;
case HorizonOCConfigValue_BatteryChargeCurrent:
return ((input >= 1024) && (input <= 3072)) || !input;
default:
return false;
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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
#define SYSCLK_ERROR_MODULE 388
#define SYSCLK_ERROR(desc) ((SYSCLK_ERROR_MODULE & 0x1FF) | (SysClkError_##desc & 0x1FFF)<<9)
typedef enum
{
SysClkError_Generic = 0,
SysClkError_ConfigNotLoaded = 1,
SysClkError_ConfigSaveFailed = 2,
// HocClkError_SocThermFail = 3,
} SysClkError;

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 <stdint.h>
#include "board.h"
#include "clock_manager.h"
#define SYSCLK_IPC_API_VERSION 1
#define SYSCLK_IPC_SERVICE_NAME "hoc:clk"
enum SysClkIpcCmd
{
SysClkIpcCmd_GetApiVersion = 0,
SysClkIpcCmd_GetVersionString = 1,
SysClkIpcCmd_GetCurrentContext = 2,
SysClkIpcCmd_Exit = 3,
SysClkIpcCmd_GetProfileCount = 4,
SysClkIpcCmd_GetProfiles = 5,
SysClkIpcCmd_SetProfiles = 6,
SysClkIpcCmd_SetEnabled = 7,
SysClkIpcCmd_SetOverride = 8,
SysClkIpcCmd_GetConfigValues = 9,
SysClkIpcCmd_SetConfigValues = 10,
SysClkIpcCmd_GetFreqList = 11,
HocClkIpcCmd_SetKipData = 12,
HocClkIpcCmd_GetKipData = 13,
};
typedef struct
{
uint64_t tid;
SysClkTitleProfileList profiles;
} SysClkIpc_SetProfiles_Args;
typedef struct
{
SysClkModule module;
uint32_t hz;
} SysClkIpc_SetOverride_Args;
typedef struct
{
SysClkModule module;
uint32_t maxCount;
} SysClkIpc_GetFreqList_Args;

View File

@@ -0,0 +1,94 @@
/*
* Copyright (c) KazushiMe
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <switch.h>
typedef enum {
PsmPDC_NewPDO = 1, //Received new Power Data Object
PsmPDC_NoPD = 2, //No Power Delivery source is detected
PsmPDC_AcceptedRDO = 3 //Received and accepted Request Data Object
} PsmChargeInfoPDC; //BM92T series
typedef enum {
PsmPowerRole_Sink = 1,
PsmPowerRole_Source = 2
} PsmPowerRole;
const char* PsmPowerRoleToStr(PsmPowerRole role);
typedef enum {
PsmInfoChargerType_None = 0,
PsmInfoChargerType_PD = 1,
PsmInfoChargerType_TypeC_1500mA = 2,
PsmInfoChargerType_TypeC_3000mA = 3,
PsmInfoChargerType_DCP = 4,
PsmInfoChargerType_CDP = 5,
PsmInfoChargerType_SDP = 6,
PsmInfoChargerType_Apple_500mA = 7,
PsmInfoChargerType_Apple_1000mA = 8,
PsmInfoChargerType_Apple_2000mA = 9
} PsmInfoChargerType;
const char* PsmInfoChargerTypeToStr(PsmInfoChargerType type);
typedef enum {
PsmFlags_NoHub = BIT(0), //If hub is disconnected
PsmFlags_Rail = BIT(8), //At least one Joy-con is charging from rail
PsmFlags_SPDSRC = BIT(12), //OTG
PsmFlags_ACC = BIT(16) //Accessory
} PsmChargeInfoFlags;
typedef struct {
int32_t InputCurrentLimit; //Input (Sink) current limit in mA
int32_t VBUSCurrentLimit; //Output (Source/VBUS/OTG) current limit in mA
int32_t ChargeCurrentLimit; //Battery charging current limit in mA (512mA when Docked, 768mA when BatteryTemperature < 17.0 C)
int32_t ChargeVoltageLimit; //Battery charging voltage limit in mV (3952mV when BatteryTemperature >= 51.0 C)
int32_t unk_x10; //Possibly an emum, getting the same value as PowerRole in all tested cases
int32_t unk_x14; //Possibly flags
PsmChargeInfoPDC PDCState; //Power Delivery Controller State
int32_t BatteryTemperature; //Battery temperature in milli C
int32_t RawBatteryCharge; //Raw battery charged capacity per cent-mille (i.e. 100% = 100000 pcm)
int32_t VoltageAvg; //Voltage avg in mV (more in Notes)
int32_t BatteryAge; //Battery age (capacity full / capacity design) per cent-mille (i.e. 100% = 100000 pcm)
PsmPowerRole PowerRole;
PsmInfoChargerType ChargerType;
int32_t ChargerVoltageLimit; //Charger and external device voltage limit in mV
int32_t ChargerCurrentLimit; //Charger and external device current limit in mA
PsmChargeInfoFlags Flags; //Unknown flags
} PsmChargeInfo;
typedef enum {
Psm_EnableBatteryCharging = 2,
Psm_DisableBatteryCharging = 3,
Psm_EnableFastBatteryCharging = 10,
Psm_DisableFastBatteryCharging = 11,
Psm_GetBatteryChargeInfoFields = 17,
} IPsmServerCmd;
bool PsmIsChargerConnected(const PsmChargeInfo* info);
bool PsmIsCharging(const PsmChargeInfo* info);
typedef enum {
PsmBatteryState_Discharging,
PsmBatteryState_ChargingPaused,
PsmBatteryState_FastCharging
} PsmBatteryState;
PsmBatteryState PsmGetBatteryState(const PsmChargeInfo* info);
const char* PsmGetBatteryStateIcon(const PsmChargeInfo* info);

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 <sysclk/apm.h>
SysClkApmConfiguration sysclk_g_apm_configurations[] = {
{0x00010000, 1020000000, 384000000, 1600000000},
{0x00010001, 1020000000, 768000000, 1600000000},
{0x00010002, 1224000000, 691200000, 1600000000},
{0x00020000, 1020000000, 230400000, 1600000000},
{0x00020001, 1020000000, 307200000, 1600000000},
{0x00020002, 1224000000, 230400000, 1600000000},
{0x00020003, 1020000000, 307200000, 1331200000},
{0x00020004, 1020000000, 384000000, 1331200000},
{0x00020005, 1020000000, 307200000, 1065600000},
{0x00020006, 1020000000, 384000000, 1065600000},
{0x92220007, 1020000000, 460800000, 1600000000},
{0x92220008, 1020000000, 460800000, 1331200000},
{0x92220009, 1785000000, 76800000, 1600000000},
{0x9222000A, 1785000000, 76800000, 1331200000},
{0x9222000B, 1020000000, 76800000, 1600000000},
{0x9222000C, 1020000000, 76800000, 1331200000},
{0, 0, 0, 0},
};

View File

@@ -0,0 +1,165 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <switch.h>
#include <cstring>
#include "battery.h"
// Internal PSM service handle
static Service g_psmService = {0};
static bool g_batteryInfoInitialized = false;
static const char* s_chargerTypeStrings[] = {
"None",
"Power Delivery",
"USB-C @ 1.5A",
"USB-C @ 3.0A",
"USB-DCP",
"USB-CDP",
"USB-SDP",
"Apple @ 0.5A",
"Apple @ 1.0A",
"Apple @ 2.0A",
};
static const char* s_powerRoleStrings[] = {
"Unknown",
"Sink",
"Source",
};
static const char* s_pdStateStrings[] = {
"Unknown",
"New PDO Received",
"No PD Source",
"RDO Accepted"
};
// Internal PSM command implementations
static Result psmGetBatteryChargeInfoFields(BatteryChargeInfo *out) {
if (!g_batteryInfoInitialized)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return serviceDispatchOut(&g_psmService, 17, *out);
}
static Result psmEnableBatteryCharging_internal(void) {
if (!g_batteryInfoInitialized)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return serviceDispatch(&g_psmService, 2);
}
static Result psmDisableBatteryCharging_internal(void) {
if (!g_batteryInfoInitialized)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return serviceDispatch(&g_psmService, 3);
}
static Result psmEnableFastBatteryCharging_internal(void) {
if (!g_batteryInfoInitialized)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return serviceDispatch(&g_psmService, 10);
}
static Result psmDisableFastBatteryCharging_internal(void) {
if (!g_batteryInfoInitialized)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return serviceDispatch(&g_psmService, 11);
}
Result batteryInfoInitialize(void) {
if (g_batteryInfoInitialized)
return 0;
Result rc = psmInitialize();
if (R_SUCCEEDED(rc)) {
memcpy(&g_psmService, psmGetServiceSession(), sizeof(Service));
g_batteryInfoInitialized = true;
}
return rc;
}
void batteryInfoExit(void) {
if (g_batteryInfoInitialized) {
psmExit();
memset(&g_psmService, 0, sizeof(Service));
g_batteryInfoInitialized = false;
}
}
Result batteryInfoGetChargeInfo(BatteryChargeInfo *out) {
if (!out)
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
return psmGetBatteryChargeInfoFields(out);
}
Result batteryInfoGetChargePercentage(u32 *out) {
if (!g_batteryInfoInitialized)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return psmGetBatteryChargePercentage(out);
}
Result batteryInfoIsEnoughPowerSupplied(bool *out) {
if (!g_batteryInfoInitialized)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
return psmIsEnoughPowerSupplied(out);
}
Result batteryInfoEnableCharging(void) {
return psmEnableBatteryCharging_internal();
}
Result batteryInfoDisableCharging(void) {
return psmDisableBatteryCharging_internal();
}
Result batteryInfoEnableFastCharging(void) {
return psmEnableFastBatteryCharging_internal();
}
Result batteryInfoDisableFastCharging(void) {
return psmDisableFastBatteryCharging_internal();
}
const char* batteryInfoGetChargerTypeString(BatteryChargerType type) {
if (type < 0 || type > ChargerType_Apple_2000mA)
return "Unknown";
return s_chargerTypeStrings[type];
}
const char* batteryInfoGetPowerRoleString(BatteryPowerRole role) {
if (role < PowerRole_Sink || role > PowerRole_Source)
return s_powerRoleStrings[0];
return s_powerRoleStrings[role];
}
const char* batteryInfoGetPDStateString(BatteryPDControllerState state) {
if (state < PDState_NewPDO || state > PDState_AcceptedRDO)
return s_pdStateStrings[0];
return s_pdStateStrings[state];
}

View File

@@ -0,0 +1,169 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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
* --------------------------------------------------------------------------
*/
#define NX_SERVICE_ASSUME_NON_DOMAIN
#include <switch.h>
#include <string.h>
#include <stdatomic.h>
#include <sysclk/client/ipc.h>
static Service g_sysclkSrv;
static atomic_size_t g_refCnt;
bool sysclkIpcRunning()
{
Handle handle;
bool running = R_FAILED(smRegisterService(&handle, smEncodeName(SYSCLK_IPC_SERVICE_NAME), false, 1));
if (!running)
{
smUnregisterService(smEncodeName(SYSCLK_IPC_SERVICE_NAME));
}
return running;
}
Result sysclkIpcInitialize(void)
{
Result rc = 0;
g_refCnt++;
if (serviceIsActive(&g_sysclkSrv))
return 0;
rc = smGetService(&g_sysclkSrv, SYSCLK_IPC_SERVICE_NAME);
if (R_FAILED(rc)) sysclkIpcExit();
return rc;
}
void sysclkIpcExit(void)
{
if (--g_refCnt == 0)
{
serviceClose(&g_sysclkSrv);
}
}
Result sysclkIpcGetAPIVersion(u32* out_ver)
{
return serviceDispatchOut(&g_sysclkSrv, SysClkIpcCmd_GetApiVersion, *out_ver);
}
Result sysclkIpcGetVersionString(char* out, size_t len)
{
return serviceDispatch(&g_sysclkSrv, SysClkIpcCmd_GetVersionString,
.buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out },
.buffers = {{out, len}},
);
}
Result sysclkIpcGetCurrentContext(SysClkContext* out_context)
{
return serviceDispatch(&g_sysclkSrv, SysClkIpcCmd_GetCurrentContext,
.buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out },
.buffers = {{out_context, sizeof(SysClkContext)}},
);
}
Result sysclkIpcGetProfileCount(u64 tid, u8* out_count)
{
return serviceDispatchInOut(&g_sysclkSrv, SysClkIpcCmd_GetProfileCount, tid, *out_count);
}
Result sysclkIpcSetEnabled(bool enabled)
{
u8 enabledRaw = (u8)enabled;
return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_SetEnabled, enabledRaw);
}
Result sysclkIpcSetOverride(SysClkModule module, u32 hz)
{
SysClkIpc_SetOverride_Args args = {
.module = module,
.hz = hz
};
return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_SetOverride, args);
}
Result sysclkIpcGetProfiles(u64 tid, SysClkTitleProfileList* out_profiles)
{
return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_GetProfiles, tid,
.buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out },
.buffers = {{out_profiles, sizeof(SysClkTitleProfileList)}},
);
}
Result sysclkIpcSetProfiles(u64 tid, SysClkTitleProfileList* profiles)
{
SysClkIpc_SetProfiles_Args args;
args.tid = tid;
memcpy(&args.profiles, profiles, sizeof(SysClkTitleProfileList));
return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_SetProfiles, args);
}
Result sysclkIpcGetConfigValues(SysClkConfigValueList* out_configValues)
{
return serviceDispatch(&g_sysclkSrv, SysClkIpcCmd_GetConfigValues,
.buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out },
.buffers = {{out_configValues, sizeof(SysClkConfigValueList)}},
);
}
Result sysclkIpcSetConfigValues(SysClkConfigValueList* configValues)
{
return serviceDispatch(&g_sysclkSrv, SysClkIpcCmd_SetConfigValues,
.buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_In },
.buffers = {{configValues, sizeof(SysClkConfigValueList)}},
);
}
Result sysclkIpcGetFreqList(SysClkModule module, u32* list, u32 maxCount, u32* outCount)
{
SysClkIpc_GetFreqList_Args args = {
.module = module,
.maxCount = maxCount
};
return serviceDispatchInOut(&g_sysclkSrv, SysClkIpcCmd_GetFreqList, args, *outCount,
.buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out },
.buffers = {{list, maxCount * sizeof(u32)}},
);
}
Result hocClkIpcSetKipData()
{
u32 temp = 0;
return serviceDispatchIn(&g_sysclkSrv, HocClkIpcCmd_SetKipData, temp);
}
Result hocClkIpcGetKipData()
{
u32 temp = 0;
return serviceDispatchIn(&g_sysclkSrv, HocClkIpcCmd_GetKipData, temp);
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <crc32.h>
namespace crc32 {
uint32_t crc32(const uint8_t *data, size_t length) {
uint32_t crc = 0xFFFFFFFF;
for (size_t i = 0; i < length; i++) {
crc ^= data[i];
for (int j = 0; j < 8; j++) {
crc = (crc >> 1) ^ (0xEDB88320 & -(crc & 1));
}
}
return ~crc;
}
uint32_t checksum_file(const char *filename) {
FILE *file = fopen(filename, "rb");
if (!file) {
perror("[crc32] Error opening file");
return 0;
}
uint8_t buffer[1024];
uint32_t crc = 0xFFFFFFFF;
size_t bytes_read;
while ((bytes_read = fread(buffer, 1, sizeof(buffer), file)) > 0) {
for (size_t i = 0; i < bytes_read; i++) {
crc ^= buffer[i];
for (int j = 0; j < 8; j++) {
crc = (crc >> 1) ^ (0xEDB88320 & -(crc & 1));
}
}
}
fclose(file);
return ~crc;
}
}

View File

@@ -0,0 +1,202 @@
/*
* Copyright (c) KazushiMe
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "i2c.h"
Result I2cSet_U8(I2cDevice dev, u8 reg, u8 val) {
// ams::fatal::srv::StopSoundTask::StopSound()
// I2C Bus Communication Reference: https://www.ti.com/lit/an/slva704/slva704.pdf
struct {
u8 reg;
u8 val;
} __attribute__((packed)) cmd;
I2cSession _session;
Result res = i2cOpenSession(&_session, dev);
if (res)
return res;
cmd.reg = reg;
cmd.val = val;
res = i2csessionSendAuto(&_session, &cmd, sizeof(cmd), I2cTransactionOption_All);
i2csessionClose(&_session);
return res;
}
Result I2cRead_OutU8(I2cDevice dev, u8 reg, u8 *out) {
struct { u8 reg; } __attribute__((packed)) cmd;
struct { u8 val; } __attribute__((packed)) rec;
I2cSession _session;
Result res = i2cOpenSession(&_session, dev);
if (res)
return res;
cmd.reg = reg;
res = i2csessionSendAuto(&_session, &cmd, sizeof(cmd), I2cTransactionOption_All);
if (res) {
i2csessionClose(&_session);
return res;
}
res = i2csessionReceiveAuto(&_session, &rec, sizeof(rec), I2cTransactionOption_All);
i2csessionClose(&_session);
if (res) {
return res;
}
*out = rec.val;
return 0;
}
Result I2cRead_OutU16(I2cDevice dev, u8 reg, u16 *out) {
struct { u8 reg; } __attribute__((packed)) cmd;
struct { u16 val; } __attribute__((packed)) rec;
I2cSession _session;
Result res = i2cOpenSession(&_session, dev);
if (res)
return res;
cmd.reg = reg;
res = i2csessionSendAuto(&_session, &cmd, sizeof(cmd), I2cTransactionOption_All);
if (res) {
i2csessionClose(&_session);
return res;
}
res = i2csessionReceiveAuto(&_session, &rec, sizeof(rec), I2cTransactionOption_All);
i2csessionClose(&_session);
if (res) {
return res;
}
*out = rec.val;
return 0;
}
float I2c_Max17050_GetBatteryCurrent() {
u16 val;
Result res = I2cRead_OutU16(I2cDevice_Max17050, MAX17050_CURRENT_REG, &val);
if (res)
return 0.f;
const float SenseResistor = 5.; // in uOhm
const float CGain = 1.99993;
return (s16)val * (1.5625 / (SenseResistor * CGain));
}
u32 I2c_BuckConverter_MultiplierToMvOut(const I2c_BuckConverter_Domain* domain, u8 multiplier) {
return (domain->uv_min + domain->uv_step * multiplier) / 1000;
}
u8 I2c_BuckConverter_MvOutToMultiplier(const I2c_BuckConverter_Domain* domain, u32 mvolt) {
u32 uvolt = mvolt * 1000;
if (uvolt < domain->uv_min)
uvolt = domain->uv_min;
if (uvolt > domain->uv_max)
uvolt = domain->uv_max;
return (uvolt - domain->uv_min) / domain->uv_step;
}
u32 I2c_BuckConverter_GetMvOut(const I2c_BuckConverter_Domain* domain) {
u8 val;
// Retry 5 times if received POR value
for (int i = 0; i < 5; i++) {
if (R_FAILED(I2cRead_OutU8(domain->device, domain->reg, &val)))
return 0u;
// Wait 1us
svcSleepThread(1E3);
if (!domain->por_val || val != domain->por_val)
break;
}
return I2c_BuckConverter_MultiplierToMvOut(domain, val & domain->volt_mask);
}
Result I2c_BuckConverter_SetMvOut(const I2c_BuckConverter_Domain* domain, u32 mvolt) {
u8 val;
Result res = I2cRead_OutU8(domain->device, domain->reg, &val);
if (R_FAILED(res))
return res;
u8 multiplier = I2c_BuckConverter_MvOutToMultiplier(domain, mvolt);
val &= ~domain->volt_mask;
val |= multiplier & domain->volt_mask;
res = I2cSet_U8(domain->device, domain->reg, val);
if (R_FAILED(res))
return res;
// 5ms Ramp delay
svcSleepThread(5E6);
u8 new_val;
res = I2cRead_OutU8(domain->device, domain->reg, &new_val);
if (R_FAILED(res))
return res;
if (new_val != val)
return -1;
return 0;
}
u8 I2c_Bq24193_Convert_mA_Raw(u32 ma) {
// Adjustment is required
u8 raw = 0;
if (ma > MA_RANGE_MAX) // capping
ma = MA_RANGE_MAX;
bool pct20 = ma <= (MA_RANGE_MIN - 64);
if (pct20) {
ma = ma * 5;
raw |= 0x1;
}
ma -= ma % 100; // round to 100
ma -= (MA_RANGE_MIN - 64); // ceiling
raw |= (ma >> 6) << 2;
return raw;
};
u32 I2c_Bq24193_Convert_Raw_mA(u8 raw) {
// No adjustment is allowed
u32 ma = (((raw >> 2)) << 6) + MA_RANGE_MIN;
bool pct20 = raw & 1;
if (pct20)
ma = ma * 20 / 100;
return ma;
};
Result I2c_Bq24193_GetFastChargeCurrentLimit(u32 *ma) {
u8 raw;
Result res = I2cRead_OutU8(I2cDevice_Bq24193, BQ24193_CHARGE_CURRENT_CONTROL_REG, &raw);
if (res)
return res;
*ma = I2c_Bq24193_Convert_Raw_mA(raw);
return 0;
}
Result I2c_Bq24193_SetFastChargeCurrentLimit(u32 ma) {
u8 raw = I2c_Bq24193_Convert_mA_Raw(ma);
return I2cSet_U8(I2cDevice_Bq24193, BQ24193_CHARGE_CURRENT_CONTROL_REG, raw);
}

View File

@@ -0,0 +1,83 @@
/*
MIT License
Copyright (c) 2024 Roy Merkel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "memmem.h"
void *memmem_impl(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen)
{
const unsigned char *cmpp;
const unsigned char *p;
const unsigned char *endp;
const unsigned char *q;
const unsigned char *endq;
unsigned char found;
if(haystack == NULL)
{
return NULL;
}
if(needle == NULL)
{
return (void*)haystack;
}
if(haystacklen == 0)
{
return NULL;
}
if(needlelen == 0)
{
return (void*)haystack;
}
if(needlelen > haystacklen)
{
return NULL;
}
endp = haystack + haystacklen - needlelen;
endq = needle + needlelen;
for(p = haystack; p <= endp; p++)
{
found = 1;
cmpp = p;
for(q = needle; q < endq; q++)
{
if(*cmpp != *q)
{
found = 0;
break;
}
else
{
cmpp++;
}
}
if(found)
{
return (void*)p;
}
}
return NULL;
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) ppkantorski (bord2death)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "notification.h"
namespace notification {
void writeNotification(const std::string& message) {
static const char* flagPath = "sdmc:/config/ultrahand/flags/NOTIFICATIONS.flag";
FILE* flagFile = fopen(flagPath, "r");
if (!flagFile) {
return;
}
fclose(flagFile);
std::string filename = "Horizon OC -" + std::to_string(std::time(nullptr)) + ".notify";
std::string fullPath = "sdmc:/config/ultrahand/notifications/" + filename;
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);
}
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) KazushiMe
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <sysclk/psm_ext.h>
const char* PsmPowerRoleToStr(PsmPowerRole role) {
switch (role) {
case PsmPowerRole_Sink: return "Sink";
case PsmPowerRole_Source: return "Source";
default: return "Unknown";
}
}
const char* PsmInfoChargerTypeToStr(PsmInfoChargerType type) {
switch (type) {
case PsmInfoChargerType_None: return "None";
case PsmInfoChargerType_PD: return "USB-C PD";
case PsmInfoChargerType_TypeC_1500mA:
case PsmInfoChargerType_TypeC_3000mA: return "USB-C";
case PsmInfoChargerType_DCP: return "USB DCP";
case PsmInfoChargerType_CDP: return "USB CDP";
case PsmInfoChargerType_SDP: return "USB SDP";
case PsmInfoChargerType_Apple_500mA:
case PsmInfoChargerType_Apple_1000mA:
case PsmInfoChargerType_Apple_2000mA: return "Apple";
default: return "Unknown";
}
}
bool PsmIsChargerConnected(const PsmChargeInfo* info) {
return info->ChargerType != PsmInfoChargerType_None;
}
bool PsmIsCharging(const PsmChargeInfo* info) {
return PsmIsChargerConnected(info) && ((info->unk_x14 >> 8) & 1);
}
PsmBatteryState PsmGetBatteryState(const PsmChargeInfo* info) {
if (!PsmIsChargerConnected(info))
return PsmBatteryState_Discharging;
if (!PsmIsCharging(info))
return PsmBatteryState_ChargingPaused;
return PsmBatteryState_FastCharging;
}
const char* PsmGetBatteryStateIcon(const PsmChargeInfo* info) {
switch (PsmGetBatteryState(info)) {
case PsmBatteryState_Discharging: return "\u25c0"; // ◀
case PsmBatteryState_ChargingPaused:return "| |";
case PsmBatteryState_FastCharging: return "\u25b6"; // ▶
default: return "?";
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) MasaGratoR
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define NX_SERVICE_ASSUME_NON_DOMAIN
#include <switch.h>
#include "service_guard.h"
#include "pwm.h"
static Service g_pwmSrv;
NX_GENERATE_SERVICE_GUARD(pwm);
Result _pwmInitialize(void) {
return smGetService(&g_pwmSrv, "pwm");
}
void _pwmCleanup(void) {
serviceClose(&g_pwmSrv);
}
Service* pwmGetServiceSession(void) {
return &g_pwmSrv;
}
Result pwmOpenSession2(PwmChannelSession *out, u32 device_code) {
return serviceDispatchIn(&g_pwmSrv, 2, device_code,
.out_num_objects = 1,
.out_objects = &out->s,
);
}
Result pwmChannelSessionGetDutyCycle(PwmChannelSession *c, double* out) {
return serviceDispatchOut(&c->s, 7, *out);
}
void pwmChannelSessionClose(PwmChannelSession *controller) {
serviceClose(&controller->s);
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) ppkantorski (bord2death)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <switch.h>
#include "rgltr.h"
#include "rgltr_services.h" // for extern Service g_rgltrSrv, etc.
// Global service handle
Service g_rgltrSrv;
Result rgltrInitialize(void) {
if (hosversionBefore(8, 0, 0)) {
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
}
return smGetService(&g_rgltrSrv, "rgltr");
}
void rgltrExit(void) {
serviceClose(&g_rgltrSrv);
}
Result rgltrOpenSession(RgltrSession* session_out, PowerDomainId module_id) {
const u32 in = (u32)module_id;
return serviceDispatchIn(
&g_rgltrSrv,
0,
in,
.out_num_objects = 1,
.out_objects = &session_out->s
);
}
Result rgltrGetVoltage(RgltrSession* session, u32* out_volt) {
u32 temp = 0;
Result rc = serviceDispatchOut(&session->s, 4, temp);
if (R_SUCCEEDED(rc)) {
*out_volt = temp;
}
return rc;
}
Result rgltrRequestVoltage(RgltrSession* session, u32 microvolt) {
return serviceDispatchIn(&session->s, 5, microvolt);
}
Result rgltrCancelVoltageRequest(RgltrSession* session) {
return serviceDispatch(&session->s, 6);
}
void rgltrCloseSession(RgltrSession* session) {
serviceClose(&session->s);
}

View File

@@ -0,0 +1,19 @@
[values]
; Defines how often sys-clk log temperatures, in milliseconds (set 0 to disable)
temp_log_interval_ms=0
; Defines how often sys-clk writes to the CSV, in milliseconds (set 0 to disable)
csv_write_interval_ms=0
; Example #1: BOTW
; Overclock CPU when docked
; Overclock MEM to docked clocks when handheld
;[01007EF00011E000]
;docked_cpu=1224
;handheld_mem=1600
; Example #2: Picross
; Underclock to save battery
;[0100BA0003EEA000]
;handheld_cpu=816
;handheld_gpu=153
;handheld_mem=800

2
Source/hoc-clk/overlay/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/out
/build

View File

@@ -0,0 +1,173 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
endif
TOPDIR ?= $(CURDIR)
include $(DEVKITPRO)/libnx/switch_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# DATA is a list of directories containing data files
# INCLUDES is a list of directories containing header files
# EXEFS_SRC is the optional input directory containing data copied into exefs, if anything this normally should only contain "main.npdm".
#---------------------------------------------------------------------------------
TARGET := horizon-oc-overlay
BUILD := build
OUTDIR := out
RESOURCES := res
SOURCES := src src/ui/gui src/ui/elements ../common/src ../common/src/client
DATA := data
INCLUDES := ../common/include
EXEFS_SRC := exefs_src
IS_MINIMAL := 0
APP_TITLE := Horizon OC Zeus
NO_ICON := 1
# This location should reflect where you place the libultrahand directory (lib can vary between projects).
include ${TOPDIR}/lib/libultrahand/ultrahand.mk
#---------------------------------------------------------------------------------
# version control constants
#---------------------------------------------------------------------------------
#TARGET_VERSION := $(shell git describe --dirty --always --tags)
APP_VERSION := 1.1.0
TARGET_VERSION := $(APP_VERSION)
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
DEFINES := -DDISABLE_IPC -DTARGET="\"$(TARGET)\"" -DTARGET_VERSION="\"$(TARGET_VERSION)\"" -DIS_MINIMAL=$(IS_MINIMAL)
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
CFLAGS := -O2 -Wall -flto -fdata-sections -ffunction-sections -fno-rtti -fno-common \
$(ARCH) $(DEFINES)
CFLAGS += $(INCLUDE) -D__SWITCH__
# Enable appearance overriding
export MSYS2_ARG_CONV_EXCL := -DUI_OVERRIDE_PATH
UI_OVERRIDE_PATH := /config/horizon-oc/
CFLAGS += -DUI_OVERRIDE_PATH="\"$(UI_OVERRIDE_PATH)\""
# Disable fstream
#NO_FSTREAM_DIRECTIVE := 1
#CFLAGS += -DNO_FSTREAM_DIRECTIVE=$(NO_FSTREAM_DIRECTIVE)
CXXFLAGS := $(CFLAGS) -fno-exceptions -std=gnu++20
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS := -lcurl -lz -lzzip -lmbedtls -lmbedx509 -lmbedcrypto -ljansson -lnx
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(PORTLIBS) $(LIBNX)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(OUTDIR)/$(TARGET)
export TOPDIR := $(CURDIR)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC)
.PHONY: $(BUILD) clean all
#---------------------------------------------------------------------------------
all: $(BUILD)
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@[ -d $(OUTDIR) ] || mkdir -p $(OUTDIR)
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(TARGET).ovl $(TARGET).nacp $(TARGET).nso $(TARGET).elf $(OUTDIR)
#---------------------------------------------------------------------------------
else
.PHONY: all
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
all: $(OUTPUT).ovl
$(OUTPUT).ovl: $(OUTPUT).elf $(OUTPUT).nacp
@elf2nro $< $@ --nacp=$(OUTPUT).nacp
@echo "built ... $(notdir $(OUTPUT).ovl)"
@printf 'ULTR' >> $@
@printf "Ultrahand signature has been added.\n"
$(OUTPUT).elf: $(OFILES)
#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#---------------------------------------------------------------------------------
%.bin.o : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

Binary file not shown.

View File

@@ -0,0 +1,141 @@
{
"Information": "Informationen",
"IDDQ:": "IDDQ:",
"Module: ": "Modul:",
"sys-dock status:": "Sys-Dock-Status:",
"SaltyNX status:": "SaltyNX-Status:",
"RR Display status:": "RR Anzeigestatus:",
"Wafer Position:": "Waferposition:",
"Credits": "Credits",
"Developers": "Entwickler",
"Contributors": "Mitwirkende",
"Testers": "Tester",
"Special Thanks": "Besonderer Dank",
"Unknown": "Unbekannt",
"Installed": "Installiert",
"Not Installed": "Nicht installiert",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "DIE BIERWAREN-LIZENZ",
"Default": "Standard",
"Do Not Override": "Nicht überschreiben",
"Disabled": "Deaktiviert",
"Enabled": "Aktiviert",
" \\ue0e3 Reset": "\\ue0e3 Zurücksetzen",
"Display": "Anzeige",
"Application changed\\n\\n": "Anwendung geändert\\n\\n",
"The running application changed\\n\\n": "Die laufende Anwendung hat sich geändert\\n\\n",
"while editing was going on.": "während die Bearbeitung im Gange war.",
"Board": "Vorstand",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Es konnte keine Verbindung zum hoc-clk-Systemmodul hergestellt werden.\\n\\n",
"Please make sure everything is\\n\\n": "Bitte stellen Sie sicher, dass alles in Ordnung ist\\n\\n",
"correctly installed and enabled.": "korrekt installiert und aktiviert.",
"Fatal error": "Fataler Fehler",
"Temporary Overrides ": "Temporäre Überschreibungen",
"Sleep Mode": "Schlafmodus",
"Stock": "Lager",
"Dev OC": "Entwickler OC",
"Boost Mode": "Boost-Modus",
"Safe Max": "Sicher max",
"Unsafe Max": "Unsicher max",
"Absolute Max": "Absolutes Maximum",
"Handheld Safe Max": "Handsafe max",
"Enable": "Aktivieren",
"Edit App Profile": "App-Profil bearbeiten",
"Edit Global Profile": "Globales Profil bearbeiten",
"Temporary Overrides": "Temporäre Überschreibungen",
"Settings": "Einstellungen",
"About": "Über",
"Compiling with minimal features": "Kompilieren mit minimalen Funktionen",
"General Settings": "Allgemeine Einstellungen",
"Governor Settings": "Gouverneurseinstellungen",
"Safety Settings": "Sicherheitseinstellungen",
"Save KIP Settings": "Speichern Sie die KIP-Einstellungen",
"RAM Settings": "RAM-Einstellungen",
"CPU Settings": "CPU-Einstellungen",
"GPU Settings": "GPU-Einstellungen",
"Display Settings": "Anzeigeeinstellungen",
"Experimental": "Experimentell",
"GPU Scheduling Override Method": "GPU-Planungsüberschreibungsmethode",
"can be dangerous and may cause": "kann gefährlich sein und verursachen",
"damage to your battery or charger!": "Schäden an Ihrem Akku oder Ladegerät!",
"Charge Current Override": "Ladestrom-Überbrückung",
"RAM Voltage Display Mode": "RAM-Spannungsanzeigemodus",
"Polling Interval": "Abfrageintervall",
"CPU Governor Minimum Frequency": "Mindestfrequenz des CPU-Reglers",
"refresh rates may cause stress": "Bildwiederholraten können Stress verursachen",
"or damage to your display! ": "oder Schäden an Ihrem Display!",
"Proceed at your own risk!": "Das Vorgehen erfolgt auf eigene Gefahr!",
"Max Handheld Display": "Max Handheld-Display",
"Display Clock": "Uhr anzeigen",
"Official Rating": "Offizielle Bewertung",
"TDP Threshold": "TDP-Schwellenwert",
"Power": "Macht",
"Thermal Throttle Limit": "Thermische Drosselgrenze",
"HP Mode": "HP-Modus",
"Default (Mariko)": "Standard (Mariko)",
"Default (Erista)": "Standard (Erista)",
"Rating": "Bewertung",
"Safe Max (Mariko)": "Safe Max (Mariko)",
"Safe Max (Erista)": "Safe Max (Erista)",
"RAM VDD2 Voltage": "RAM VDD2 Spannung",
"Voltage": "Spannung",
"RAM VDDQ Voltage": "RAM-VDDQ-Spannung",
"RAM Frequency Editor": "RAM-Frequenzeditor",
"JEDEC.": "JEDEC.",
"High speedo needed!": "Hoher Tacho erforderlich!",
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (Benötigt extremen Tacho/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (Benötigt extremen Tacho/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (Benötigt extremen Tacho/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 MHz (Benötigt lächerlichen Tacho/PLL)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (Benötigt lächerlichen Tacho/PLL)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (Benötigt lächerlichen Tacho/PLL)",
"Ram Max Clock": "Ram Max Uhr",
"RAM Latency Editor": "RAM-Latenz-Editor",
"RAM Timing Reductions": "Reduzierung des RAM-Timings",
"Memory Timings": "Speicherzeiten",
"Advanced": "Fortgeschritten",
"t6 tRTW Fine Tune": "t6 tRTW Feinabstimmung",
"tRTW Fine Tune": "tRTW-Feinabstimmung",
"t7 tWTR Fine Tune": "t7 tWTR Feinabstimmung",
"tWTR Fine Tune": "tWTR-Feinabstimmung",
"Memory Latencies": "Speicherlatenzen",
"Read Latency": "Leselatenz",
"Write Latency": "Schreiblatenz",
"CPU Boost Clock": "CPU-Boost-Takt",
"CPU UV": "CPU-UV",
"CPU Unlock": "CPU-Entsperrung",
"CPU VMIN": "CPU-VMIN",
"CPU Max Voltage": "Maximale CPU-Spannung",
"CPU Max Clock": "Maximaler CPU-Takt",
"Extreme UV Table": "Extremer UV-Tisch",
"CPU UV Table": "CPU-UV-Tisch",
"CPU Low UV": "CPU-niedrige UV-Strahlung",
"CPU High UV": "CPU Hohe UV-Strahlung",
"CPU Low VMIN": "CPU niedrig VMIN",
"CPU High VMIN": "CPU hoch VMIN",
"No Undervolt": "Kein Undervolt",
"SLT Table": "SLT-Tisch",
"HiOPT Table": "HiOPT-Tabelle",
"GPU Undervolt Table": "GPU-Unterspannungstabelle",
"GPU Minimum Voltage": "GPU-Mindestspannung",
"Calculate GPU Vmin": "Berechnen Sie die GPU-Vmin",
"GPU VMIN": "GPU-VMIN",
"GPU Maximum Voltage": "Maximale GPU-Spannung",
"GPU Voltage Offset": "GPU-Spannungsoffset",
"Do not override": "Nicht überschreiben",
"Enabled (Default)": "Aktiviert (Standard)",
"96.6% limit": "96,6 %-Grenze",
"99.7% limit": "99,7 %-Grenze",
"GPU Scheduling Override": "GPU-Planungsüberschreibung",
"Official Service": "Offizieller Dienst",
"GPU DVFS Mode": "GPU-DVFS-Modus",
"GPU DVFS Offset": "GPU-DVFS-Offset",
"GPU Voltage Table": "GPU-Spannungstabelle",
"GPU Custom Table (mV)": "Benutzerdefinierte GPU-Tabelle (mV)",
"1075MHz without UV, 1152MHz on SLT": "1075 MHz ohne UV, 1152 MHz auf SLT",
"or 1228MHz on HiOPT can cause ": "oder 1228 MHz auf HiOPT kann dazu führen",
"permanent damage to your Switch!": "Dauerhafter Schaden an Ihrem Switch!",
"921MHz without UV and 960MHz on": "921 MHz ohne UV und 960 MHz eingeschaltet",
"SLT or HiOPT can cause ": "SLT oder HiOPT können dazu führen"
}

View File

@@ -0,0 +1,141 @@
{
"Information": "Information",
"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",
"Contributors": "Contributors",
"Testers": "Testers",
"Special Thanks": "Special Thanks",
"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",
"Do Not Override": "Do Not Override",
"Disabled": "Disabled",
"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.",
"Board": "Board",
"%u.%u%u mV": "%u.%u%u mV",
"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",
"Temporary Overrides ": "Temporary Overrides ",
"Sleep Mode": "Sleep Mode",
"Stock": "Stock",
"Dev OC": "Dev OC",
"Boost Mode": "Boost Mode",
"Safe Max": "Safe Max",
"Unsafe Max": "Unsafe Max",
"Absolute Max": "Absolute Max",
"Handheld Safe Max": "Handheld Safe Max",
"Enable": "Enable",
"Edit App Profile": "Edit App Profile",
"Edit Global Profile": "Edit Global Profile",
"Temporary Overrides": "Temporary Overrides",
"Settings": "Settings",
"About": "About",
"Compiling with minimal features": "Compiling with minimal features",
"General Settings": "General Settings",
"Governor Settings": "Governor Settings",
"Safety Settings": "Safety Settings",
"Save KIP Settings": "Save KIP Settings",
"RAM Settings": "RAM Settings",
"CPU Settings": "CPU Settings",
"GPU Settings": "GPU Settings",
"Display Settings": "Display Settings",
"Experimental": "Experimental",
"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",
"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",
"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)",
"RAM VDD2 Voltage": "RAM VDD2 Voltage",
"Voltage": "Voltage",
"RAM VDDQ Voltage": "RAM VDDQ Voltage",
"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",
"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",
"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",
"Extreme UV Table": "Extreme UV Table",
"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",
"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",
"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

@@ -0,0 +1,141 @@
{
"Information": "Información",
"IDDQ:": "IDDQ:",
"Module: ": "Módulo:",
"sys-dock status:": "estado del sys-dock:",
"SaltyNX status:": "Estado de SaltyNX:",
"RR Display status:": "Estado de visualización RR:",
"Wafer Position:": "Posición de la oblea:",
"Credits": "Créditos",
"Developers": "Desarrolladores",
"Contributors": "Colaboradores",
"Testers": "Probadores",
"Special Thanks": "agradecimiento especial",
"Unknown": "Desconocido",
"Installed": "Instalado",
"Not Installed": "No instalado",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "LA LICENCIA DE CERVEZA",
"Default": "Predeterminado",
"Do Not Override": "No anular",
"Disabled": "Discapacitado",
"Enabled": "Habilitado",
" \\ue0e3 Reset": "\\ue0e3 Restablecer",
"Display": "Pantalla",
"Application changed\\n\\n": "Aplicación modificada\\n\\n",
"The running application changed\\n\\n": "La aplicación en ejecución cambió\\n\\n",
"while editing was going on.": "mientras se realizaba la edición.",
"Board": "tablero",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "No se pudo conectar al módulo del sistema hoc-clk.\\n\\n",
"Please make sure everything is\\n\\n": "Por favor asegúrese de que todo esté\\n\\n",
"correctly installed and enabled.": "correctamente instalado y habilitado.",
"Fatal error": "error fatal",
"Temporary Overrides ": "Anulaciones temporales",
"Sleep Mode": "Modo de suspensión",
"Stock": "Valores",
"Dev OC": "Desarrollador OC",
"Boost Mode": "Modo de impulso",
"Safe Max": "Máximo seguro",
"Unsafe Max": "Máximo inseguro",
"Absolute Max": "Máximo absoluto",
"Handheld Safe Max": "Caja fuerte de mano máx.",
"Enable": "Habilitar",
"Edit App Profile": "Editar perfil de aplicación",
"Edit Global Profile": "Editar perfil global",
"Temporary Overrides": "Anulaciones temporales",
"Settings": "Configuración",
"About": "Acerca de",
"Compiling with minimal features": "Compilando con características mínimas",
"General Settings": "Configuraciones generales",
"Governor Settings": "Configuración del gobernador",
"Safety Settings": "Configuraciones de seguridad",
"Save KIP Settings": "Guardar configuración de KIP",
"RAM Settings": "Configuración de RAM",
"CPU Settings": "Configuración de la CPU",
"GPU Settings": "Configuración de GPU",
"Display Settings": "Configuración de pantalla",
"Experimental": "Experimental",
"GPU Scheduling Override Method": "Método de anulación de programación de GPU",
"can be dangerous and may cause": "puede ser peligroso y puede causar",
"damage to your battery or charger!": "¡Daños a su batería o cargador!",
"Charge Current Override": "Anulación de corriente de carga",
"RAM Voltage Display Mode": "Modo de visualización de voltaje de RAM",
"Polling Interval": "Intervalo de sondeo",
"CPU Governor Minimum Frequency": "Frecuencia mínima del gobernador de CPU",
"refresh rates may cause stress": "Las frecuencias de actualización pueden causar estrés.",
"or damage to your display! ": "o daños a su pantalla!",
"Proceed at your own risk!": "¡Continúe bajo su propio riesgo!",
"Max Handheld Display": "Pantalla portátil máxima",
"Display Clock": "Reloj de pantalla",
"Official Rating": "Calificación oficial",
"TDP Threshold": "Umbral de TDP",
"Power": "poder",
"Thermal Throttle Limit": "Límite del acelerador térmico",
"HP Mode": "Modo HP",
"Default (Mariko)": "Predeterminado (Mariko)",
"Default (Erista)": "Predeterminado (Erista)",
"Rating": "Calificación",
"Safe Max (Mariko)": "Max seguro (Mariko)",
"Safe Max (Erista)": "Safe Max (Erista)",
"RAM VDD2 Voltage": "Voltaje RAM VDD2",
"Voltage": "voltaje",
"RAM VDDQ Voltage": "Voltaje RAM VDDQ",
"RAM Frequency Editor": "Editor de frecuencia RAM",
"JEDEC.": "JEDEC.",
"High speedo needed!": "¡Se necesita alta velocidad!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz (Necesita Speedo/PLL extremo)",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz (Necesita Speedo/PLL extremo)",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz (Necesita Speedo/PLL extremo)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (Necesita Speedo/PLL ridículo)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz (Necesita Speedo/PLL ridículo)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz (Necesita Speedo/PLL ridículo)",
"Ram Max Clock": "Ram Max Reloj",
"RAM Latency Editor": "Editor de latencia de RAM",
"RAM Timing Reductions": "Reducciones de tiempo de RAM",
"Memory Timings": "Tiempos de memoria",
"Advanced": "Avanzado",
"t6 tRTW Fine Tune": "t6 tRTW Ajuste fino",
"tRTW Fine Tune": "Ajuste fino tRTW",
"t7 tWTR Fine Tune": "t7 tWTR Ajuste fino",
"tWTR Fine Tune": "Ajuste fino de tWTR",
"Memory Latencies": "Latencias de la memoria",
"Read Latency": "Leer latencia",
"Write Latency": "Latencia de escritura",
"CPU Boost Clock": "Reloj de aumento de CPU",
"CPU UV": "procesador ultravioleta",
"CPU Unlock": "Desbloqueo de CPU",
"CPU VMIN": "CPU VMIN",
"CPU Max Voltage": "Voltaje máximo de la CPU",
"CPU Max Clock": "Reloj máximo de CPU",
"Extreme UV Table": "Mesa UV extrema",
"CPU UV Table": "Tabla UV de CPU",
"CPU Low UV": "CPU baja radiación ultravioleta",
"CPU High UV": "CPU alta UV",
"CPU Low VMIN": "VMIN bajo de CPU",
"CPU High VMIN": "VMIN alto de CPU",
"No Undervolt": "Sin subvoltaje",
"SLT Table": "Mesa TR",
"HiOPT Table": "Tabla HiOPT",
"GPU Undervolt Table": "Tabla de subvoltaje de GPU",
"GPU Minimum Voltage": "Voltaje mínimo de GPU",
"Calculate GPU Vmin": "Calcular GPU Vmin",
"GPU VMIN": "GPU VMIN",
"GPU Maximum Voltage": "Voltaje máximo de GPU",
"GPU Voltage Offset": "Compensación de voltaje de GPU",
"Do not override": "no anular",
"Enabled (Default)": "Habilitado (predeterminado)",
"96.6% limit": "límite del 96,6%",
"99.7% limit": "límite del 99,7%",
"GPU Scheduling Override": "Anulación de programación de GPU",
"Official Service": "Servicio Oficial",
"GPU DVFS Mode": "Modo GPU DVFS",
"GPU DVFS Offset": "Compensación DVFS de GPU",
"GPU Voltage Table": "Tabla de voltaje de GPU",
"GPU Custom Table (mV)": "Tabla personalizada de GPU (mV)",
"1075MHz without UV, 1152MHz on SLT": "1075MHz sin UV, 1152MHz en SLT",
"or 1228MHz on HiOPT can cause ": "o 1228MHz en HiOPT pueden causar",
"permanent damage to your Switch!": "¡Daño permanente a tu Switch!",
"921MHz without UV and 960MHz on": "921MHz sin UV y 960MHz encendido",
"SLT or HiOPT can cause ": "SLT o HiOPT pueden causar"
}

View File

@@ -0,0 +1,141 @@
{
"Information": "Informations",
"IDDQ:": "IDDQ :",
"Module: ": "Module :",
"sys-dock status:": "état du dock système :",
"SaltyNX status:": "Statut SaltyNX :",
"RR Display status:": "Etat d'affichage RR :",
"Wafer Position:": "Position de la plaquette :",
"Credits": "Crédits",
"Developers": "Développeurs",
"Contributors": "Contributeurs",
"Testers": "Testeurs",
"Special Thanks": "Remerciements spéciaux",
"Unknown": "Inconnu",
"Installed": "Installé",
"Not Installed": "Non installé",
"X: %u Y: %u": "X : %u Y : %u",
"THE BEER-WARE LICENSE": "LA LICENCE DE LA BIÈRE",
"Default": "Par défaut",
"Do Not Override": "Ne pas remplacer",
"Disabled": "Désactivé",
"Enabled": "Activé",
" \\ue0e3 Reset": "\\ue0e3 Réinitialiser",
"Display": "Affichage",
"Application changed\\n\\n": "Application modifiée\\n\\n",
"The running application changed\\n\\n": "L'application en cours d'exécution a changé\\n\\n",
"while editing was going on.": "pendant le montage.",
"Board": "Conseil",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Impossible de se connecter au module système hoc-clk.\\n\\n",
"Please make sure everything is\\n\\n": "Veuillez vous assurer que tout est\\n\\n",
"correctly installed and enabled.": "correctement installé et activé.",
"Fatal error": "Erreur fatale",
"Temporary Overrides ": "Remplacements temporaires",
"Sleep Mode": "Mode veille",
"Stock": "Actions",
"Dev OC": "Développeur OC",
"Boost Mode": "Mode Boost",
"Safe Max": "Coffre-fort maximum",
"Unsafe Max": "Dangereux Max",
"Absolute Max": "Max absolu",
"Handheld Safe Max": "Coffre-fort portatif Max",
"Enable": "Activer",
"Edit App Profile": "Modifier le profil de l'application",
"Edit Global Profile": "Modifier le profil global",
"Temporary Overrides": "Remplacements temporaires",
"Settings": "Paramètres",
"About": "À propos",
"Compiling with minimal features": "Compilation avec des fonctionnalités minimales",
"General Settings": "Paramètres généraux",
"Governor Settings": "Paramètres du gouverneur",
"Safety Settings": "Paramètres de sécurité",
"Save KIP Settings": "Enregistrer les paramètres KIP",
"RAM Settings": "Paramètres de la RAM",
"CPU Settings": "Paramètres du processeur",
"GPU Settings": "Paramètres du processeur graphique",
"Display Settings": "Paramètres d'affichage",
"Experimental": "Expérimental",
"GPU Scheduling Override Method": "Méthode de remplacement de la planification GPU",
"can be dangerous and may cause": "peut être dangereux et provoquer",
"damage to your battery or charger!": "dommages à votre batterie ou à votre chargeur !",
"Charge Current Override": "Remplacement du courant de charge",
"RAM Voltage Display Mode": "Mode d'affichage de la tension de la RAM",
"Polling Interval": "Intervalle d'interrogation",
"CPU Governor Minimum Frequency": "Fréquence minimale du gouverneur du processeur",
"refresh rates may cause stress": "les taux de rafraîchissement peuvent causer du stress",
"or damage to your display! ": "ou endommager votre écran !",
"Proceed at your own risk!": "Procédez à vos propres risques !",
"Max Handheld Display": "Affichage portable maximum",
"Display Clock": "Affichage de l'horloge",
"Official Rating": "Classement officiel",
"TDP Threshold": "Seuil TDP",
"Power": "Puissance",
"Thermal Throttle Limit": "Limite d'accélérateur thermique",
"HP Mode": "Mode HP",
"Default (Mariko)": "Par défaut (Mariko)",
"Default (Erista)": "Par défaut (Erista)",
"Rating": "Note",
"Safe Max (Mariko)": "Coffre-fort Max (Mariko)",
"Safe Max (Erista)": "Coffre-fort Max (Erista)",
"RAM VDD2 Voltage": "Tension de la RAM VDD2",
"Voltage": "Tension",
"RAM VDDQ Voltage": "Tension VDDQ de la RAM",
"RAM Frequency Editor": "Éditeur de fréquence RAM",
"JEDEC.": "JEDEC.",
"High speedo needed!": "Besoin d'un speedo haut !",
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (nécessite un Speedo/PLL extrême)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (nécessite un Speedo/PLL extrême)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (nécessite un Speedo/PLL extrême)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 MHz (nécessite un Speedo/PLL ridicule)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (nécessite un Speedo/PLL ridicule)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (nécessite un Speedo/PLL ridicule)",
"Ram Max Clock": "Ram Max Horloge",
"RAM Latency Editor": "Éditeur de latence RAM",
"RAM Timing Reductions": "Réductions de synchronisation de la RAM",
"Memory Timings": "Horaires de mémoire",
"Advanced": "Avancé",
"t6 tRTW Fine Tune": "t6 tRTW réglage fin",
"tRTW Fine Tune": "tRTW Réglage fin",
"t7 tWTR Fine Tune": "t7 tWTR réglage fin",
"tWTR Fine Tune": "Réglage fin du tWTR",
"Memory Latencies": "Latences de mémoire",
"Read Latency": "Latence de lecture",
"Write Latency": "Latence d'écriture",
"CPU Boost Clock": "Horloge d'augmentation du processeur",
"CPU UV": "UV du processeur",
"CPU Unlock": "Déverrouillage du processeur",
"CPU VMIN": "CPU VMIN",
"CPU Max Voltage": "Tension maximale du processeur",
"CPU Max Clock": "Horloge maximale du processeur",
"Extreme UV Table": "Table UV Extrême",
"CPU UV Table": "Tableau UV du processeur",
"CPU Low UV": "CPU faible UV",
"CPU High UV": "CPU UV élevé",
"CPU Low VMIN": "CPU faible VMIN",
"CPU High VMIN": "Processeur VMIN élevé",
"No Undervolt": "Pas de sous-tension",
"SLT Table": "Tableau SLT",
"HiOPT Table": "Tableau HiOPT",
"GPU Undervolt Table": "Tableau de sous-tension GPU",
"GPU Minimum Voltage": "Tension minimale du GPU",
"Calculate GPU Vmin": "Calculer la Vmin du GPU",
"GPU VMIN": "GPU VMIN",
"GPU Maximum Voltage": "Tension maximale du GPU",
"GPU Voltage Offset": "Décalage de tension du GPU",
"Do not override": "Ne remplacez pas",
"Enabled (Default)": "Activé (par défaut)",
"96.6% limit": "Limite de 96,6 %",
"99.7% limit": "Limite de 99,7 %",
"GPU Scheduling Override": "Remplacement de la planification GPU",
"Official Service": "Service officiel",
"GPU DVFS Mode": "Mode GPU DVFS",
"GPU DVFS Offset": "Décalage GPU DVFS",
"GPU Voltage Table": "Tableau de tension du GPU",
"GPU Custom Table (mV)": "Tableau personnalisé GPU (mV)",
"1075MHz without UV, 1152MHz on SLT": "1075 MHz sans UV, 1152 MHz sur SLT",
"or 1228MHz on HiOPT can cause ": "ou 1228 MHz sur HiOPT peut provoquer",
"permanent damage to your Switch!": "dommages permanents à votre Switch !",
"921MHz without UV and 960MHz on": "921 MHz sans UV et 960 MHz activé",
"SLT or HiOPT can cause ": "SLT ou HiOPT peuvent provoquer"
}

View File

@@ -0,0 +1,141 @@
{
"Information": "Informazioni",
"IDDQ:": "IDDQ:",
"Module: ": "Modulo:",
"sys-dock status:": "stato del dock di sistema:",
"SaltyNX status:": "Stato di SaltyNX:",
"RR Display status:": "Stato di visualizzazione RR:",
"Wafer Position:": "Posizione del wafer:",
"Credits": "Crediti",
"Developers": "Sviluppatori",
"Contributors": "Collaboratori",
"Testers": "Tester",
"Special Thanks": "Un ringraziamento speciale",
"Unknown": "Sconosciuto",
"Installed": "Installato",
"Not Installed": "Non installato",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "LA LICENZA PER GLI ARTICOLI DI BIRRA",
"Default": "Predefinito",
"Do Not Override": "Non sovrascrivere",
"Disabled": "Disabilitato",
"Enabled": "Abilitato",
" \\ue0e3 Reset": "\\ue0e3 Ripristina",
"Display": "Visualizzazione",
"Application changed\\n\\n": "Applicazione modificata\\n\\n",
"The running application changed\\n\\n": "L'applicazione in esecuzione è cambiata\\n\\n",
"while editing was going on.": "mentre era in corso la modifica.",
"Board": "Consiglio",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Impossibile connettersi al modulo di sistema hoc-clk.\\n\\n",
"Please make sure everything is\\n\\n": "Assicurati che tutto sia\\n\\n",
"correctly installed and enabled.": "correttamente installato e abilitato.",
"Fatal error": "Errore fatale",
"Temporary Overrides ": "Sostituzioni temporanee",
"Sleep Mode": "Modalità di sospensione",
"Stock": "Magazzino",
"Dev OC": "OC di sviluppo",
"Boost Mode": "Modalità potenziamento",
"Safe Max": "Sicuro massimo",
"Unsafe Max": "Non sicuro Max",
"Absolute Max": "Massimo assoluto",
"Handheld Safe Max": "Cassaforte portatile max",
"Enable": "Abilita",
"Edit App Profile": "Modifica profilo dell'app",
"Edit Global Profile": "Modifica profilo globale",
"Temporary Overrides": "Sostituzioni temporanee",
"Settings": "Impostazioni",
"About": "Circa",
"Compiling with minimal features": "Compilazione con funzionalità minime",
"General Settings": "Impostazioni generali",
"Governor Settings": "Impostazioni del governatore",
"Safety Settings": "Impostazioni di sicurezza",
"Save KIP Settings": "Salva le impostazioni KIP",
"RAM Settings": "Impostazioni della RAM",
"CPU Settings": "Impostazioni della CPU",
"GPU Settings": "Impostazioni della GPU",
"Display Settings": "Impostazioni di visualizzazione",
"Experimental": "Sperimentale",
"GPU Scheduling Override Method": "Metodo di override della pianificazione GPU",
"can be dangerous and may cause": "può essere pericoloso e può causare",
"damage to your battery or charger!": "danni alla batteria o al caricabatterie!",
"Charge Current Override": "Override della corrente di carica",
"RAM Voltage Display Mode": "Modalità di visualizzazione della tensione RAM",
"Polling Interval": "Intervallo di polling",
"CPU Governor Minimum Frequency": "Frequenza minima del governatore della CPU",
"refresh rates may cause stress": "le frequenze di aggiornamento possono causare stress",
"or damage to your display! ": "o danni al display!",
"Proceed at your own risk!": "Procedi a tuo rischio e pericolo!",
"Max Handheld Display": "Display portatile massimo",
"Display Clock": "Visualizza orologio",
"Official Rating": "Valutazione ufficiale",
"TDP Threshold": "Soglia TDP",
"Power": "Potenza",
"Thermal Throttle Limit": "Limite della valvola termica",
"HP Mode": "Modalità HP",
"Default (Mariko)": "Predefinito (Mariko)",
"Default (Erista)": "Predefinito (Erista)",
"Rating": "Valutazione",
"Safe Max (Mariko)": "Safe Max (Mariko)",
"Safe Max (Erista)": "Safe Max (Erista)",
"RAM VDD2 Voltage": "Tensione RAM VDD2",
"Voltage": "Voltaggio",
"RAM VDDQ Voltage": "Voltaggio VDDQ della RAM",
"RAM Frequency Editor": "Editor della frequenza RAM",
"JEDEC.": "JEDEC.",
"High speedo needed!": "È necessaria l'alta velocità!",
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (richiede Speedo/PLL estremo)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (richiede Speedo/PLL estremo)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (richiede Speedo/PLL estremo)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 MHz (è necessario un ridicolo Speedo/PLL)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (è necessario un ridicolo Speedo/PLL)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (è necessario un ridicolo Speedo/PLL)",
"Ram Max Clock": "Orologio Ram Max",
"RAM Latency Editor": "Editor della latenza RAM",
"RAM Timing Reductions": "Riduzioni della temporizzazione della RAM",
"Memory Timings": "Tempi di memoria",
"Advanced": "Avanzato",
"t6 tRTW Fine Tune": "t6 tRTW Sintonia fine",
"tRTW Fine Tune": "tRTW Sintonia fine",
"t7 tWTR Fine Tune": "t7 tWTR Sintonia fine",
"tWTR Fine Tune": "tWTR Sintonia fine",
"Memory Latencies": "Latenza della memoria",
"Read Latency": "Leggi latenza",
"Write Latency": "Scrivi latenza",
"CPU Boost Clock": "Orologio di potenziamento della CPU",
"CPU UV": "UV della CPU",
"CPU Unlock": "Sblocco della CPU",
"CPU VMIN": "CPUVMIN",
"CPU Max Voltage": "Voltaggio massimo della CPU",
"CPU Max Clock": "Orologio massimo della CPU",
"Extreme UV Table": "Tavolo UV estremo",
"CPU UV Table": "Tabella UV della CPU",
"CPU Low UV": "CPU con raggi UV bassi",
"CPU High UV": "UV elevato della CPU",
"CPU Low VMIN": "VMIN CPU basso",
"CPU High VMIN": "CPU alta VMIN",
"No Undervolt": "Nessuna sottotensione",
"SLT Table": "Tabella SLT",
"HiOPT Table": "Tabella HiOPT",
"GPU Undervolt Table": "Tabella di sottotensione GPU",
"GPU Minimum Voltage": "Voltaggio minimo della GPU",
"Calculate GPU Vmin": "Calcola GPU Vmin",
"GPU VMIN": "GPUVMIN",
"GPU Maximum Voltage": "Voltaggio massimo della GPU",
"GPU Voltage Offset": "Offset di tensione della GPU",
"Do not override": "Non sovrascrivere",
"Enabled (Default)": "Abilitato (impostazione predefinita)",
"96.6% limit": "Limite del 96,6%.",
"99.7% limit": "Limite del 99,7%.",
"GPU Scheduling Override": "Override della pianificazione GPU",
"Official Service": "Servizio ufficiale",
"GPU DVFS Mode": "Modalità DVFS GPU",
"GPU DVFS Offset": "Offset DVFS della GPU",
"GPU Voltage Table": "Tabella delle tensioni della GPU",
"GPU Custom Table (mV)": "Tabella personalizzata GPU (mV)",
"1075MHz without UV, 1152MHz on SLT": "1075 MHz senza UV, 1152 MHz su SLT",
"or 1228MHz on HiOPT can cause ": "o 1228 MHz su HiOPT possono causare",
"permanent damage to your Switch!": "danni permanenti al tuo Switch!",
"921MHz without UV and 960MHz on": "921 MHz senza UV e 960 MHz attivi",
"SLT or HiOPT can cause ": "SLT o HiOPT possono causare"
}

View File

@@ -0,0 +1,141 @@
{
"Information": "情報",
"IDDQ:": "IDQ:",
"Module: ": "モジュール:",
"sys-dock status:": "システムドックのステータス:",
"SaltyNX status:": "SaltyNX ステータス:",
"RR Display status:": "RR 表示ステータス:",
"Wafer Position:": "ウェーハの位置:",
"Credits": "クレジット",
"Developers": "開発者",
"Contributors": "貢献者",
"Testers": "テスター",
"Special Thanks": "特別な感謝の気持ち",
"Unknown": "不明",
"Installed": "インストール済み",
"Not Installed": "インストールされていません",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "ビール製品ライセンス",
"Default": "デフォルト",
"Do Not Override": "上書きしないでください",
"Disabled": "障害者",
"Enabled": "有効",
" \\ue0e3 Reset": "\\ue0e3 リセット",
"Display": "ディスプレイ",
"Application changed\\n\\n": "アプリケーションが変更されました\\n\\n",
"The running application changed\\n\\n": "実行中のアプリケーションが変更されました\\n\\n",
"while editing was going on.": "編集を進めている最中でした。",
"Board": "理事会",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "hoc-clk sysmodule に接続できませんでした。\\n\\n",
"Please make sure everything is\\n\\n": "すべてが正しいことを確認してください\\n\\n",
"correctly installed and enabled.": "正しくインストールされ、有効になっています。",
"Fatal error": "致命的なエラー",
"Temporary Overrides ": "一時的なオーバーライド",
"Sleep Mode": "スリープモード",
"Stock": "在庫",
"Dev OC": "開発OC",
"Boost Mode": "ブーストモード",
"Safe Max": "セーフマックス",
"Unsafe Max": "危険なマックス",
"Absolute Max": "絶対最大値",
"Handheld Safe Max": "手持ち金庫マックス",
"Enable": "有効にする",
"Edit App Profile": "アプリプロファイルの編集",
"Edit Global Profile": "グローバルプロファイルの編集",
"Temporary Overrides": "一時的なオーバーライド",
"Settings": "設定",
"About": "について",
"Compiling with minimal features": "最小限の機能でコンパイルする",
"General Settings": "一般設定",
"Governor Settings": "ガバナーの設定",
"Safety Settings": "安全設定",
"Save KIP Settings": "KIP 設定の保存",
"RAM Settings": "RAM設定",
"CPU Settings": "CPUの設定",
"GPU Settings": "GPU設定",
"Display Settings": "表示設定",
"Experimental": "実験的",
"GPU Scheduling Override Method": "GPU スケジューリング オーバーライド メソッド",
"can be dangerous and may cause": "危険であり、原因となる可能性があります",
"damage to your battery or charger!": "バッテリーまたは充電器が損傷します。",
"Charge Current Override": "充電電流オーバーライド",
"RAM Voltage Display Mode": "RAM電圧表示モード",
"Polling Interval": "ポーリング間隔",
"CPU Governor Minimum Frequency": "CPU ガバナの最小周波数",
"refresh rates may cause stress": "リフレッシュレートがストレスを引き起こす可能性がある",
"or damage to your display! ": "ディスプレイに損傷を与えてしまいます。",
"Proceed at your own risk!": "自己責任で進めてください!",
"Max Handheld Display": "最大ハンドヘルドディスプレイ",
"Display Clock": "時計の表示",
"Official Rating": "公式評価",
"TDP Threshold": "TDP しきい値",
"Power": "パワー",
"Thermal Throttle Limit": "サーマルスロットル制限",
"HP Mode": "HPモード",
"Default (Mariko)": "デフォルト(マリコ)",
"Default (Erista)": "デフォルト(エリスタ)",
"Rating": "評価",
"Safe Max (Mariko)": "セーフマックス(マリコ)",
"Safe Max (Erista)": "セーフマックス(エリスタ)",
"RAM VDD2 Voltage": "RAM VDD2 電圧",
"Voltage": "電圧",
"RAM VDDQ Voltage": "RAM VDDQ 電圧",
"RAM Frequency Editor": "RAM周波数エディター",
"JEDEC.": "JEDEC。",
"High speedo needed!": "ハイスピードが必要です!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz (エクストリーム Speedo/PLL が必要)",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz (エクストリーム Speedo/PLL が必要)",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz (エクストリーム Speedo/PLL が必要)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (とんでもない Speedo/PLL が必要)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz (とんでもない Speedo/PLL が必要)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz (とんでもない Speedo/PLL が必要)",
"Ram Max Clock": "ラムマックスクロック",
"RAM Latency Editor": "RAM レイテンシ エディター",
"RAM Timing Reductions": "RAM タイミングの削減",
"Memory Timings": "メモリタイミング",
"Advanced": "上級者向け",
"t6 tRTW Fine Tune": "t6 tRTW 微調整",
"tRTW Fine Tune": "tRTW 微調整",
"t7 tWTR Fine Tune": "t7 tWTR ファインチューン",
"tWTR Fine Tune": "tWTR ファインチューン",
"Memory Latencies": "メモリレイテンシ",
"Read Latency": "読み取りレイテンシー",
"Write Latency": "書き込みレイテンシ",
"CPU Boost Clock": "CPUブーストクロック",
"CPU UV": "CPU UV",
"CPU Unlock": "CPUロック解除",
"CPU VMIN": "CPU VMIN",
"CPU Max Voltage": "CPU最大電圧",
"CPU Max Clock": "CPU最大クロック",
"Extreme UV Table": "エクストリーム UV テーブル",
"CPU UV Table": "CPU UV テーブル",
"CPU Low UV": "CPU 低 UV",
"CPU High UV": "CPU 高紫外線",
"CPU Low VMIN": "CPU 低 VMIN",
"CPU High VMIN": "CPU の高い VMIN",
"No Undervolt": "不足電圧なし",
"SLT Table": "SLTテーブル",
"HiOPT Table": "HiOPT テーブル",
"GPU Undervolt Table": "GPUアンダーボルトテーブル",
"GPU Minimum Voltage": "GPUの最小電圧",
"Calculate GPU Vmin": "GPU Vmin を計算する",
"GPU VMIN": "GPU VMIN",
"GPU Maximum Voltage": "GPU最大電圧",
"GPU Voltage Offset": "GPU電圧オフセット",
"Do not override": "上書きしないでください",
"Enabled (Default)": "有効 (デフォルト)",
"96.6% limit": "96.6%制限",
"99.7% limit": "99.7%制限",
"GPU Scheduling Override": "GPU スケジュールのオーバーライド",
"Official Service": "正式サービス",
"GPU DVFS Mode": "GPU DVFS モード",
"GPU DVFS Offset": "GPU DVFS オフセット",
"GPU Voltage Table": "GPU電圧テーブル",
"GPU Custom Table (mV)": "GPUカスタムテーブル(mV)",
"1075MHz without UV, 1152MHz on SLT": "UVなしで1075MHz、SLTで1152MHz",
"or 1228MHz on HiOPT can cause ": "HiOPT で 1228MHz を使用すると、次のような問題が発生する可能性があります。",
"permanent damage to your Switch!": "Switch に永久的なダメージを与えます!",
"921MHz without UV and 960MHz on": "921MHzUVなし、960MHzUVあり",
"SLT or HiOPT can cause ": "SLT または HiOPT が原因となる可能性があります"
}

View File

@@ -0,0 +1,146 @@
{
"Information": "Information",
"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",
"Contributors": "Contributors",
"Testers": "Testers",
"Special Thanks": "Special Thanks",
"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",
"Do Not Override": "Do Not Override",
"Disabled": "Disabled",
"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.",
"App ID": "App ID",
"Profile": "Profile",
"Board": "Board",
"USB Charger": "USB Charger",
"%u.%u%u mV": "%u.%u%u mV",
"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",
"Temporary Overrides ": "Temporary Overrides",
"Sleep Mode": "Sleep Mode",
"Stock": "Stock",
"Dev OC": "Dev OC",
"Boost Mode": "Boost Mode",
"Safe Max": "Safe Max",
"Unsafe Max": "Unsafe Max",
"Absolute Max": "Absolute 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",
"Settings": "Settings",
"About": "About",
"Compiling with minimal features": "Compiling with minimal features",
"General Settings": "General Settings",
"Governor Settings": "Governor Settings",
"Safety Settings": "Safety Settings",
"Save KIP Settings": "Save KIP Settings",
"RAM Settings": "RAM Settings",
"CPU Settings": "CPU Settings",
"GPU Settings": "GPU Settings",
"Display Settings": "Display Settings",
"Experimental": "Experimental",
"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",
"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",
"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)",
"RAM VDD2 Voltage": "RAM VDD2 Voltage",
"Voltage": "Voltage",
"RAM VDDQ Voltage": "RAM VDDQ Voltage",
"RAM Frequency Editor": "RAM Frequency Editor",
"JEDEC.": "JEDEC.",
"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",
"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",
"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",
"Extreme UV Table": "Extreme UV Table",
"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",
"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",
"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

@@ -0,0 +1,141 @@
{
"Information": "정보",
"IDDQ:": "IDDQ:",
"Module: ": "모듈:",
"sys-dock status:": "sys-dock 상태:",
"SaltyNX status:": "SaltyNX 상태:",
"RR Display status:": "RR 표시 상태:",
"Wafer Position:": "웨이퍼 위치:",
"Credits": "크레딧",
"Developers": "개발자",
"Contributors": "기여자",
"Testers": "테스터",
"Special Thanks": "특별한 분",
"Unknown": "알 수 없음",
"Installed": "설치됨",
"Not Installed": "설치되지 않음",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "맥주 제품 라이센스",
"Default": "기본값",
"Do Not Override": "재정의하지 마십시오",
"Disabled": "비활성화",
"Enabled": "활성화됨",
" \\ue0e3 Reset": "\\ue0e3 재설정",
"Display": "디스플레이",
"Application changed\\n\\n": "애플리케이션이 변경되었습니다.\\n\\n",
"The running application changed\\n\\n": "실행 중인 애플리케이션이 변경되었습니다.\\n\\n",
"while editing was going on.": "편집이 진행되는 동안.",
"Board": "보드",
"%u.%u%u mV": "%u.%u%umV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "hoc-clk 시스템 모듈에 연결할 수 없습니다.\\n\\n",
"Please make sure everything is\\n\\n": "모든 것이 올바른지 확인하십시오.\\n\\n",
"correctly installed and enabled.": "올바르게 설치되고 활성화되었습니다.",
"Fatal error": "치명적인 오류",
"Temporary Overrides ": "임시 재정의",
"Sleep Mode": "절전 모드",
"Stock": "주식",
"Dev OC": "개발 OC",
"Overwrite Boost Mode": "부스트 모드 덮어쓰기",
"Safe Max": "안전함 최대값",
"Unsafe Max": "불안정 최대값",
"Absolute Max": "절대 최대값",
"Handheld Safe Max": "휴대모드 안전함 최대값",
"Enable": "활성화",
"Edit App Profile": "앱 프로필 편집",
"Edit Global Profile": "글로벌 프로필 편집",
"Temporary Overrides": "임시 재정의",
"Settings": "설정",
"About": "소개",
"Compiling with minimal features": "최소한의 기능으로 컴파일하기",
"General Settings": "일반 설정",
"Governor Settings": "거버너 설정",
"Safety Settings": "안전 설정",
"Save KIP Settings": "KIP 설정 저장",
"RAM Settings": "RAM 설정",
"CPU Settings": "CPU 설정",
"GPU Settings": "GPU 설정",
"Display Settings": "디스플레이 설정",
"Experimental": "실험적",
"GPU Scheduling Override Method": "GPU 스케줄링 재정의 방법",
"can be dangerous and may cause": "위험할 수 있고 원인이 될 수 있습니다.",
"damage to your battery or charger!": "배터리나 충전기가 손상되었습니다!",
"Charge Current Override": "충전 전류 오버라이드",
"RAM Voltage Display Mode": "RAM 전압 표시 모드",
"Polling Interval": "폴링 간격",
"CPU Governor Minimum Frequency": "CPU 거버너 최소 주파수",
"refresh rates may cause stress": "디스플레이 주사율 빈도 변경은",
"or damage to your display! ": "기기에 손상이 발생될 수 있습니다!",
"Proceed at your own risk!": "책임하에 주의해서 사용하십시오!",
"Max Handheld Display": "최대 휴대용 디스플레이",
"Display Clock": "디스플레이 클럭",
"Official Rating": "공식 등급",
"TDP Threshold": "TDP 임계값",
"Power": "힘",
"Thermal Throttle Limit": "열 스로틀 한계",
"HP Mode": "HP 모드",
"Default (Mariko)": "기본값(마리코)",
"Default (Erista)": "기본값(에리스타)",
"Rating": "표준값",
"Safe Max (Mariko)": "안전함 최대치(마리코)",
"Safe Max (Erista)": "안전함 최대치(에리스타)",
"RAM VDD2 Voltage": "RAM VDD2 전압",
"Voltage": "전압",
"RAM VDDQ Voltage": "RAM VDDQ 전압",
"RAM Frequency Editor": "RAM 주파수 편집기",
"JEDEC.": "JEDEC.",
"High speedo needed!": "높은 스피도값이 필요합니다!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz(극단적인 Speedo/PLL 필요)",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz(극단적인 Speedo/PLL 필요)",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz(극단적인 Speedo/PLL 필요)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (말도 안 되는 Speedo/PLL 필요)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz(터무니없는 Speedo/PLL 필요)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz(터무니없는 Speedo/PLL 필요)",
"Ram Max Clock": "RAM 최대 클럭",
"RAM Latency Editor": "RAM 지연 시간 편집기",
"RAM Timing Reductions": "RAM 타이밍 편집기",
"Memory Timings": "메모리 타이밍",
"Advanced": "고급",
"t6 tRTW Fine Tune": "t6 tRTW 미세 조정",
"tRTW Fine Tune": "tRTW 미세 조정",
"t7 tWTR Fine Tune": "t7 tWTR 미세 조정",
"tWTR Fine Tune": "tWTR 미세 조정",
"Memory Latencies": "메모리 지연 시간",
"Read Latency": "읽기 지연 시간",
"Write Latency": "쓰기 지연 시간",
"CPU Boost Clock": "CPU 부스트 클럭",
"CPU UV": "CPU 언더볼트",
"CPU Unlock": "CPU 잠금 해제",
"CPU VMIN": "CPU VMIN",
"CPU Max Voltage": "CPU 최대 전압",
"CPU Max Clock": "CPU 최대 클럭",
"Extreme UV Table": "익스트림 테이블",
"CPU UV Table": "CPU 언더볼트 테이블",
"CPU Low UV": "CPU 저주파 언더볼트",
"CPU High UV": "CPU 고주파 언더볼트",
"CPU Low VMIN": "CPU 저주파 최소 전압",
"CPU High VMIN": "CPU 고주파 최소 전압",
"No Undervolt": "언더볼트 없음",
"SLT Table": "SLT 테이블",
"HiOPT Table": "HiOPT 테이블",
"GPU Undervolt Table": "GPU 언더볼트 테이블",
"GPU Minimum Voltage": "GPU 최소 전압",
"Calculate GPU Vmin": "GPU Vmin 계산",
"GPU VMIN": "GPU VMIN",
"GPU Maximum Voltage": "GPU 최대 전압",
"GPU Voltage Offset": "GPU 전압 오프셋",
"Do not override": "재정의하지 않음",
"Enabled (Default)": "활성화됨(기본값)",
"96.6% limit": "96.6% 한도",
"99.7% limit": "99.7% 한도",
"GPU Scheduling Override": "GPU 스케줄링 재정의",
"Official Service": "공식 서비스",
"GPU DVFS Mode": "GPU DVFS 모드",
"GPU DVFS Offset": "GPU DVFS 오프셋",
"GPU Voltage Table": "GPU 전압 테이블",
"GPU Custom Table (mV)": "GPU 사용자 정의 테이블(mV)",
"1075MHz without UV, 1152MHz on SLT": "UV 없이 1075MHz, SLT에서 1152MHz",
"or 1228MHz on HiOPT can cause ": "또는 HiOPT에서 1228MHz를 사용하면",
"permanent damage to your Switch!": "스위치가 영구적으로 손상될 수 있습니다!",
"921MHz without UV and 960MHz on": "UV가 없는 경우 921MHz, 켜진 경우에는 960MHz",
"SLT or HiOPT can cause ": "SLT 또는 HiOPT는 다음을 유발할 수 있습니다."
}

View File

@@ -0,0 +1,141 @@
{
"Information": "Informatie",
"IDDQ:": "IDDQ:",
"Module: ": "module:",
"sys-dock status:": "sys-dock-status:",
"SaltyNX status:": "SaltyNX-status:",
"RR Display status:": "RR Weergavestatus:",
"Wafer Position:": "Waferpositie:",
"Credits": "Kredieten",
"Developers": "Ontwikkelaars",
"Contributors": "Bijdragers",
"Testers": "Testers",
"Special Thanks": "Speciale dank",
"Unknown": "Onbekend",
"Installed": "Geïnstalleerd",
"Not Installed": "Niet geïnstalleerd",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "DE LICENTIE VOOR BIERWAREN",
"Default": "Standaard",
"Do Not Override": "Niet overschrijven",
"Disabled": "Uitgeschakeld",
"Enabled": "Ingeschakeld",
" \\ue0e3 Reset": "\\ue0e3 Opnieuw instellen",
"Display": "Weergave",
"Application changed\\n\\n": "Applicatie gewijzigd\\n\\n",
"The running application changed\\n\\n": "De actieve applicatie is gewijzigd\\n\\n",
"while editing was going on.": "terwijl er werd bewerkt.",
"Board": "Bord",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Kan geen verbinding maken met hoc-clk sysmodule.\\n\\n",
"Please make sure everything is\\n\\n": "Zorg ervoor dat alles in orde is\\n\\n",
"correctly installed and enabled.": "correct geïnstalleerd en ingeschakeld.",
"Fatal error": "Fatale fout",
"Temporary Overrides ": "Tijdelijke overschrijvingen",
"Sleep Mode": "Slaapmodus",
"Stock": "Voorraad",
"Dev OC": "Ontwikkelaar OC",
"Boost Mode": "Boost-modus",
"Safe Max": "Veilig Max",
"Unsafe Max": "OnveiligMax",
"Absolute Max": "Absoluut Max",
"Handheld Safe Max": "Handkluis Max",
"Enable": "Inschakelen",
"Edit App Profile": "App-profiel bewerken",
"Edit Global Profile": "Globaal profiel bewerken",
"Temporary Overrides": "Tijdelijke overschrijvingen",
"Settings": "Instellingen",
"About": "Over",
"Compiling with minimal features": "Compileren met minimale functies",
"General Settings": "Algemene instellingen",
"Governor Settings": "Gouverneur instellingen",
"Safety Settings": "Veiligheidsinstellingen",
"Save KIP Settings": "Sla KIP-instellingen op",
"RAM Settings": "RAM-instellingen",
"CPU Settings": "CPU-instellingen",
"GPU Settings": "GPU-instellingen",
"Display Settings": "Weergave-instellingen",
"Experimental": "Experimenteel",
"GPU Scheduling Override Method": "Methode voor het overschrijven van GPU-planning",
"can be dangerous and may cause": "kan gevaarlijk zijn en kan veroorzaken",
"damage to your battery or charger!": "schade aan uw accu of lader!",
"Charge Current Override": "Laadstroom overschrijven",
"RAM Voltage Display Mode": "Weergavemodus RAM-spanning",
"Polling Interval": "Polling-interval",
"CPU Governor Minimum Frequency": "Minimale frequentie CPU-regelaar",
"refresh rates may cause stress": "vernieuwingsfrequenties kunnen stress veroorzaken",
"or damage to your display! ": "of schade aan uw display!",
"Proceed at your own risk!": "Ga verder op eigen risico!",
"Max Handheld Display": "Maximaal handheld-display",
"Display Clock": "Klok weergeven",
"Official Rating": "Officiële beoordeling",
"TDP Threshold": "TDP-drempel",
"Power": "Macht",
"Thermal Throttle Limit": "Thermische gaslimiet",
"HP Mode": "HP-modus",
"Default (Mariko)": "Standaard (Mariko)",
"Default (Erista)": "Standaard (Erista)",
"Rating": "Beoordeling",
"Safe Max (Mariko)": "Veilig Max (Mariko)",
"Safe Max (Erista)": "Veilige Max (Erista)",
"RAM VDD2 Voltage": "RAM VDD2-spanning",
"Voltage": "Spanning",
"RAM VDDQ Voltage": "RAM VDDQ-spanning",
"RAM Frequency Editor": "RAM-frequentie-editor",
"JEDEC.": "JEDEC.",
"High speedo needed!": "Hoge snelheid nodig!",
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (vereist extreme snelheidsmeter/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (vereist extreme snelheidsmeter/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (vereist extreme snelheidsmeter/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (heeft een belachelijke snelheidsmeter/PLL nodig)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz (heeft een belachelijke snelheidsmeter/PLL nodig)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (heeft een belachelijke snelheidsmeter/PLL nodig)",
"Ram Max Clock": "Ram Max-klok",
"RAM Latency Editor": "RAM-latentie-editor",
"RAM Timing Reductions": "RAM-timingreducties",
"Memory Timings": "Geheugentijden",
"Advanced": "Geavanceerd",
"t6 tRTW Fine Tune": "t6 tRTW Fijnafstemming",
"tRTW Fine Tune": "tRTW Fijnafstemming",
"t7 tWTR Fine Tune": "t7 tWTR Fijnafstemming",
"tWTR Fine Tune": "tWTR Fijnafstemming",
"Memory Latencies": "Geheugenlatenties",
"Read Latency": "Lees Latentie",
"Write Latency": "Schrijf latentie",
"CPU Boost Clock": "CPU-boostklok",
"CPU UV": "CPU-UV",
"CPU Unlock": "CPU-ontgrendeling",
"CPU VMIN": "CPU-VMIN",
"CPU Max Voltage": "Maximale CPU-spanning",
"CPU Max Clock": "CPU maximale klok",
"Extreme UV Table": "Extreme UV-tafel",
"CPU UV Table": "CPU UV-tabel",
"CPU Low UV": "CPU Lage UV",
"CPU High UV": "CPU Hoge UV",
"CPU Low VMIN": "CPU Lage VMIN",
"CPU High VMIN": "CPU Hoge VMIN",
"No Undervolt": "Geen ondervolt",
"SLT Table": "SLT-tabel",
"HiOPT Table": "HiOPT-tabel",
"GPU Undervolt Table": "GPU-undervolttabel",
"GPU Minimum Voltage": "GPU-minimale spanning",
"Calculate GPU Vmin": "Bereken GPU Vmin",
"GPU VMIN": "GPU-VMIN",
"GPU Maximum Voltage": "GPU maximale spanning",
"GPU Voltage Offset": "GPU-spanningsoffset",
"Do not override": "Niet overschrijven",
"Enabled (Default)": "Ingeschakeld (standaard)",
"96.6% limit": "96,6% limiet",
"99.7% limit": "99,7% limiet",
"GPU Scheduling Override": "GPU-planning negeren",
"Official Service": "Officiële dienst",
"GPU DVFS Mode": "GPU DVFS-modus",
"GPU DVFS Offset": "GPU DVFS-offset",
"GPU Voltage Table": "GPU-spanningstabel",
"GPU Custom Table (mV)": "Aangepaste GPU-tabel (mV)",
"1075MHz without UV, 1152MHz on SLT": "1075MHz zonder UV, 1152MHz op SLT",
"or 1228MHz on HiOPT can cause ": "of 1228MHz op HiOPT kan dit veroorzaken",
"permanent damage to your Switch!": "blijvende schade aan uw Switch!",
"921MHz without UV and 960MHz on": "921MHz zonder UV en 960MHz aan",
"SLT or HiOPT can cause ": "SLT of HiOPT kunnen dit veroorzaken"
}

View File

@@ -0,0 +1,141 @@
{
"Information": "Informacje",
"IDDQ:": "IDDQ:",
"Module: ": "Moduł:",
"sys-dock status:": "stan sys-dock:",
"SaltyNX status:": "Stan SaltyNX:",
"RR Display status:": "Stan wyświetlacza:",
"Wafer Position:": "Pozycja wafla:",
"Credits": "Kredyty",
"Developers": "Deweloperzy",
"Contributors": "Współautorzy",
"Testers": "Testery",
"Special Thanks": "Specjalne podziękowania",
"Unknown": "Nieznany",
"Installed": "Zainstalowany",
"Not Installed": "Nie zainstalowano",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "LICENCJA NA WYROBY PIWNE",
"Default": "Domyślne",
"Do Not Override": "Nie zastępuj",
"Disabled": "Niepełnosprawny",
"Enabled": "Włączone",
" \\ue0e3 Reset": "\\ue0e3 Zresetuj",
"Display": "Wyświetlacz",
"Application changed\\n\\n": "Aplikacja została zmieniona\\n\\n",
"The running application changed\\n\\n": "Działająca aplikacja została zmieniona\\n\\n",
"while editing was going on.": "podczas gdy edycja była w toku.",
"Board": "Deska",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Nie można połączyć się z modułem sysmodule hoc-clk.\\n\\n",
"Please make sure everything is\\n\\n": "Upewnij się, że wszystko jest\\n\\n",
"correctly installed and enabled.": "poprawnie zainstalowany i włączony.",
"Fatal error": "Fatalny błąd",
"Temporary Overrides ": "Tymczasowe nadpisania",
"Sleep Mode": "Tryb uśpienia",
"Stock": "Zapas",
"Dev OC": "Dev OC",
"Boost Mode": "Tryb wzmocnienia",
"Safe Max": "Bezpieczny maks",
"Unsafe Max": "Niebezpieczny maks",
"Absolute Max": "Absolutny maks",
"Handheld Safe Max": "Sejf ręczny Max",
"Enable": "Włącz",
"Edit App Profile": "Edytuj profil aplikacji",
"Edit Global Profile": "Edytuj profil globalny",
"Temporary Overrides": "Tymczasowe nadpisania",
"Settings": "Ustawienia",
"About": "O",
"Compiling with minimal features": "Kompilacja z minimalnymi funkcjami",
"General Settings": "Ustawienia ogólne",
"Governor Settings": "Ustawienia gubernatora",
"Safety Settings": "Ustawienia bezpieczeństwa",
"Save KIP Settings": "Zapisz ustawienia KIP",
"RAM Settings": "Ustawienia pamięci RAM",
"CPU Settings": "Ustawienia procesora",
"GPU Settings": "Ustawienia GPU",
"Display Settings": "Ustawienia wyświetlania",
"Experimental": "Eksperymentalny",
"GPU Scheduling Override Method": "Metoda obejścia harmonogramu GPU",
"can be dangerous and may cause": "może być niebezpieczne i powodować",
"damage to your battery or charger!": "uszkodzenie akumulatora lub ładowarki!",
"Charge Current Override": "Obejście prądu ładowania",
"RAM Voltage Display Mode": "Tryb wyświetlania napięcia RAM",
"Polling Interval": "Interwał odpytywania",
"CPU Governor Minimum Frequency": "Minimalna częstotliwość regulatora procesora",
"refresh rates may cause stress": "częstotliwości odświeżania mogą powodować stres",
"or damage to your display! ": "lub uszkodzenie wyświetlacza!",
"Proceed at your own risk!": "Postępuj na własne ryzyko!",
"Max Handheld Display": "Maksymalny wyświetlacz ręczny",
"Display Clock": "Wyświetl zegar",
"Official Rating": "Oficjalna ocena",
"TDP Threshold": "Próg TDP",
"Power": "Moc",
"Thermal Throttle Limit": "Limit przepustnicy termicznej",
"HP Mode": "Tryb HP",
"Default (Mariko)": "Domyślny (Mariko)",
"Default (Erista)": "Domyślny (Erista)",
"Rating": "Ocena",
"Safe Max (Mariko)": "Bezpieczny Max (Mariko)",
"Safe Max (Erista)": "Bezpieczny Max (Erista)",
"RAM VDD2 Voltage": "Napięcie pamięci RAM VDD2",
"Voltage": "Napięcie",
"RAM VDDQ Voltage": "Napięcie RAM VDDQ",
"RAM Frequency Editor": "Edytor częstotliwości RAM",
"JEDEC.": "JEDEC.",
"High speedo needed!": "Potrzebna duża prędkość!",
"3333MHz (Needs extreme Speedo/PLL)": "3333 MHz (wymaga ekstremalnego Speedo/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (wymaga ekstremalnego Speedo/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (wymaga ekstremalnego Speedo/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 MHz (potrzebuje śmiesznego Speedo/PLL)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (potrzebuje śmiesznego Speedo/PLL)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (potrzebuje śmiesznego Speedo/PLL)",
"Ram Max Clock": "Zegar Ram Max",
"RAM Latency Editor": "Edytor opóźnień pamięci RAM",
"RAM Timing Reductions": "Zmniejszenie taktowania pamięci RAM",
"Memory Timings": "Taktowanie pamięci",
"Advanced": "Zaawansowane",
"t6 tRTW Fine Tune": "t6 tRTW Dostrój",
"tRTW Fine Tune": "tRTW Dostosuj",
"t7 tWTR Fine Tune": "t7 tWTR Dostosuj",
"tWTR Fine Tune": "tWTR Dostosuj",
"Memory Latencies": "Opóźnienia pamięci",
"Read Latency": "Przeczytaj Opóźnienie",
"Write Latency": "Opóźnienie zapisu",
"CPU Boost Clock": "Zegar wzmocnienia procesora",
"CPU UV": "Procesor UV",
"CPU Unlock": "Odblokowanie procesora",
"CPU VMIN": "Procesor VMIN",
"CPU Max Voltage": "Maksymalne napięcie procesora",
"CPU Max Clock": "Maks. zegar procesora",
"Extreme UV Table": "Ekstremalny stół UV",
"CPU UV Table": "Tabela UV procesora",
"CPU Low UV": "Niskie promieniowanie UV procesora",
"CPU High UV": "Wysokie promieniowanie UV procesora",
"CPU Low VMIN": "Niski poziom VMIN procesora",
"CPU High VMIN": "Wysoki poziom VMIN procesora",
"No Undervolt": "Brak Undervolta",
"SLT Table": "Stół SLT",
"HiOPT Table": "Stół HiOPT",
"GPU Undervolt Table": "Tabela niedoboru napięcia GPU",
"GPU Minimum Voltage": "Minimalne napięcie procesora graficznego",
"Calculate GPU Vmin": "Oblicz Vmin GPU",
"GPU VMIN": "VMIN GPU",
"GPU Maximum Voltage": "Maksymalne napięcie procesora graficznego",
"GPU Voltage Offset": "Przesunięcie napięcia GPU",
"Do not override": "Nie zastępuj",
"Enabled (Default)": "Włączone (domyślnie)",
"96.6% limit": "Limit 96,6%.",
"99.7% limit": "Limit 99,7%.",
"GPU Scheduling Override": "Zastąpienie harmonogramu GPU",
"Official Service": "Oficjalny serwis",
"GPU DVFS Mode": "Tryb DVFS procesora graficznego",
"GPU DVFS Offset": "Przesunięcie DVFS GPU",
"GPU Voltage Table": "Tabela napięć GPU",
"GPU Custom Table (mV)": "Tabela niestandardowa GPU (mV)",
"1075MHz without UV, 1152MHz on SLT": "1075 MHz bez UV, 1152 MHz na SLT",
"or 1228MHz on HiOPT can cause ": "lub 1228 MHz na HiOPT może powodować",
"permanent damage to your Switch!": "trwałe uszkodzenie Switcha!",
"921MHz without UV and 960MHz on": "921 MHz bez UV i 960 MHz włączone",
"SLT or HiOPT can cause ": "Przyczyną mogą być SLT lub HiOPT"
}

View File

@@ -0,0 +1,141 @@
{
"Information": "Informação",
"IDDQ:": "IDDQ:",
"Module: ": "Módulo:",
"sys-dock status:": "status do dock do sistema:",
"SaltyNX status:": "Status do SaltyNX:",
"RR Display status:": "Status de exibição do RR:",
"Wafer Position:": "Posição da bolacha:",
"Credits": "Créditos",
"Developers": "Desenvolvedores",
"Contributors": "Colaboradores",
"Testers": "Testadores",
"Special Thanks": "Agradecimentos especiais",
"Unknown": "Desconhecido",
"Installed": "Instalado",
"Not Installed": "Não instalado",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "A LICENÇA DE CERVEJA",
"Default": "Padrão",
"Do Not Override": "Não substituir",
"Disabled": "Desativado",
"Enabled": "Habilitado",
" \\ue0e3 Reset": "\\ue0e3 Redefinir",
"Display": "Exibição",
"Application changed\\n\\n": "Aplicativo alterado\\n\\n",
"The running application changed\\n\\n": "O aplicativo em execução foi alterado\\n\\n",
"while editing was going on.": "enquanto a edição estava acontecendo.",
"Board": "Conselho",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Não foi possível conectar-se ao sysmodule hoc-clk.\\n\\n",
"Please make sure everything is\\n\\n": "Verifique se tudo está\\n\\n",
"correctly installed and enabled.": "corretamente instalado e ativado.",
"Fatal error": "Erro fatal",
"Temporary Overrides ": "Substituições temporárias",
"Sleep Mode": "Modo de suspensão",
"Stock": "Estoque",
"Dev OC": "Desenvolvedor OC",
"Boost Mode": "Modo de reforço",
"Safe Max": "Máx. Seguro",
"Unsafe Max": "Máximo inseguro",
"Absolute Max": "Máximo absoluto",
"Handheld Safe Max": "Portátil Seguro Máx.",
"Enable": "Habilitar",
"Edit App Profile": "Editar perfil do aplicativo",
"Edit Global Profile": "Editar perfil global",
"Temporary Overrides": "Substituições temporárias",
"Settings": "Configurações",
"About": "Sobre",
"Compiling with minimal features": "Compilando com recursos mínimos",
"General Settings": "Configurações Gerais",
"Governor Settings": "Configurações do Governador",
"Safety Settings": "Configurações de segurança",
"Save KIP Settings": "Salvar configurações KIP",
"RAM Settings": "Configurações de RAM",
"CPU Settings": "Configurações de CPU",
"GPU Settings": "Configurações de GPU",
"Display Settings": "Configurações de exibição",
"Experimental": "Experimental",
"GPU Scheduling Override Method": "Método de substituição de agendamento de GPU",
"can be dangerous and may cause": "pode ser perigoso e causar",
"damage to your battery or charger!": "danos à sua bateria ou carregador!",
"Charge Current Override": "Substituição de corrente de carga",
"RAM Voltage Display Mode": "Modo de exibição de tensão RAM",
"Polling Interval": "Intervalo de votação",
"CPU Governor Minimum Frequency": "Frequência Mínima do Governador da CPU",
"refresh rates may cause stress": "taxas de atualização podem causar estresse",
"or damage to your display! ": "ou danos ao seu monitor!",
"Proceed at your own risk!": "Prossiga por sua conta e risco!",
"Max Handheld Display": "Visor portátil máximo",
"Display Clock": "Exibir relógio",
"Official Rating": "Classificação Oficial",
"TDP Threshold": "Limite de TDP",
"Power": "Poder",
"Thermal Throttle Limit": "Limite de aceleração térmica",
"HP Mode": "Modo HP",
"Default (Mariko)": "Padrão (Mariko)",
"Default (Erista)": "Padrão (Erista)",
"Rating": "Avaliação",
"Safe Max (Mariko)": "Máximo Seguro (Mariko)",
"Safe Max (Erista)": "Seguro Max (Erista)",
"RAM VDD2 Voltage": "Tensão RAM VDD2",
"Voltage": "Tensão",
"RAM VDDQ Voltage": "Tensão RAM VDDQ",
"RAM Frequency Editor": "Editor de frequência RAM",
"JEDEC.": "JEDEC.",
"High speedo needed!": "Alta velocidade necessária!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz (precisa de Speedo/PLL extremo)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 MHz (precisa de Speedo/PLL extremo)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 MHz (precisa de Speedo/PLL extremo)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (precisa de Speedo/PLL ridículo)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 MHz (precisa de Speedo/PLL ridículo)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 MHz (precisa de Speedo/PLL ridículo)",
"Ram Max Clock": "Relógio máximo de Ram",
"RAM Latency Editor": "Editor de latência de RAM",
"RAM Timing Reductions": "Reduções de tempo de RAM",
"Memory Timings": "Tempos de memória",
"Advanced": "Avançado",
"t6 tRTW Fine Tune": "t6 tRTW Ajuste fino",
"tRTW Fine Tune": "Ajuste fino tRTW",
"t7 tWTR Fine Tune": "t7 tWTR Ajuste fino",
"tWTR Fine Tune": "Ajuste fino tWTR",
"Memory Latencies": "Latências de memória",
"Read Latency": "Latência de leitura",
"Write Latency": "Latência de gravação",
"CPU Boost Clock": "Relógio de aumento da CPU",
"CPU UV": "UV da CPU",
"CPU Unlock": "Desbloqueio da CPU",
"CPU VMIN": "CPU VMIN",
"CPU Max Voltage": "Tensão máxima da CPU",
"CPU Max Clock": "Relógio máximo da CPU",
"Extreme UV Table": "Mesa UV Extrema",
"CPU UV Table": "Tabela UV da CPU",
"CPU Low UV": "UV baixo da CPU",
"CPU High UV": "CPU alta UV",
"CPU Low VMIN": "CPU baixa VMIN",
"CPU High VMIN": "VMIN alto da CPU",
"No Undervolt": "Sem subtensão",
"SLT Table": "Tabela SLT",
"HiOPT Table": "Tabela HiOPT",
"GPU Undervolt Table": "Tabela de subtensão da GPU",
"GPU Minimum Voltage": "Tensão mínima da GPU",
"Calculate GPU Vmin": "Calcular Vmin da GPU",
"GPU VMIN": "GPU VMIN",
"GPU Maximum Voltage": "Tensão máxima da GPU",
"GPU Voltage Offset": "Compensação de tensão da GPU",
"Do not override": "Não substitua",
"Enabled (Default)": "Habilitado (padrão)",
"96.6% limit": "Limite de 96,6%",
"99.7% limit": "Limite de 99,7%",
"GPU Scheduling Override": "Substituição de agendamento de GPU",
"Official Service": "Serviço Oficial",
"GPU DVFS Mode": "Modo GPU DVFS",
"GPU DVFS Offset": "Deslocamento DVFS da GPU",
"GPU Voltage Table": "Tabela de tensão da GPU",
"GPU Custom Table (mV)": "Tabela personalizada de GPU (mV)",
"1075MHz without UV, 1152MHz on SLT": "1075 MHz sem UV, 1152 MHz em SLT",
"or 1228MHz on HiOPT can cause ": "ou 1228 MHz em HiOPT pode causar",
"permanent damage to your Switch!": "danos permanentes ao seu Switch!",
"921MHz without UV and 960MHz on": "921 MHz sem UV e 960 MHz ativado",
"SLT or HiOPT can cause ": "SLT ou HiOPT podem causar"
}

View File

@@ -0,0 +1,141 @@
{
"Information": "Информация",
"IDDQ:": "ИДДК:",
"Module: ": "Модуль:",
"sys-dock status:": "Статус системной док-станции:",
"SaltyNX status:": "Статус SaltyNX:",
"RR Display status:": "Статус отображения RR:",
"Wafer Position:": "Позиция вафли:",
"Credits": "Кредиты",
"Developers": "Разработчики",
"Contributors": "Авторы",
"Testers": "Тестеры",
"Special Thanks": "Особая благодарность",
"Unknown": "Неизвестно",
"Installed": "Установлено",
"Not Installed": "Не установлено",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "ЛИЦЕНЗИЯ НА ПРОДАЖУ ПИВА",
"Default": "По умолчанию",
"Do Not Override": "Не переопределять",
"Disabled": "Отключено",
"Enabled": "Включено",
" \\ue0e3 Reset": "\\ue0e3 Сброс",
"Display": "Дисплей",
"Application changed\\n\\n": "Приложение изменено\\n\\n",
"The running application changed\\n\\n": "Запущенное приложение изменилось\\n\\n",
"while editing was going on.": "пока шло редактирование.",
"Board": "Совет",
"%u.%u%u mV": "%u.%u%u мВ",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Не удалось подключиться к системному модулю hoc-clk.\\n\\n",
"Please make sure everything is\\n\\n": "Пожалуйста, убедитесь, что все в порядке\\n\\n",
"correctly installed and enabled.": "правильно установлен и включен.",
"Fatal error": "Неустранимая ошибка",
"Temporary Overrides ": "Временные переопределения",
"Sleep Mode": "Спящий режим",
"Stock": "Акции",
"Dev OC": "Разработчик OC",
"Boost Mode": "Режим повышения",
"Safe Max": "Сейф Макс",
"Unsafe Max": "Небезопасный Макс",
"Absolute Max": "Абсолютный Макс",
"Handheld Safe Max": "Ручной сейф Макс",
"Enable": "Включить",
"Edit App Profile": "Редактировать профиль приложения",
"Edit Global Profile": "Редактировать глобальный профиль",
"Temporary Overrides": "Временные переопределения",
"Settings": "Настройки",
"About": "О",
"Compiling with minimal features": "Компиляция с минимальными возможностями",
"General Settings": "Общие настройки",
"Governor Settings": "Настройки губернатора",
"Safety Settings": "Настройки безопасности",
"Save KIP Settings": "Сохранить настройки КИП",
"RAM Settings": "Настройки ОЗУ",
"CPU Settings": "Настройки процессора",
"GPU Settings": "Настройки графического процессора",
"Display Settings": "Настройки дисплея",
"Experimental": "Экспериментальный",
"GPU Scheduling Override Method": "Метод переопределения планирования графического процессора",
"can be dangerous and may cause": "может быть опасным и может вызвать",
"damage to your battery or charger!": "повреждение аккумулятора или зарядного устройства!",
"Charge Current Override": "Блокировка зарядного тока",
"RAM Voltage Display Mode": "Режим отображения напряжения ОЗУ",
"Polling Interval": "Интервал опроса",
"CPU Governor Minimum Frequency": "Минимальная частота регулятора ЦП",
"refresh rates may cause stress": "частота обновления может вызвать стресс",
"or damage to your display! ": "или повреждение дисплея!",
"Proceed at your own risk!": "Действуйте на свой страх и риск!",
"Max Handheld Display": "Макс. портативный дисплей",
"Display Clock": "Дисплей Часы",
"Official Rating": "Официальный рейтинг",
"TDP Threshold": "Порог TDP",
"Power": "Мощность",
"Thermal Throttle Limit": "Температурный предел дроссельной заслонки",
"HP Mode": "Режим HP",
"Default (Mariko)": "По умолчанию (Марико)",
"Default (Erista)": "По умолчанию (Эриста)",
"Rating": "Рейтинг",
"Safe Max (Mariko)": "Сейф Макс (Марико)",
"Safe Max (Erista)": "Сейф Макс (Эриста)",
"RAM VDD2 Voltage": "Напряжение ОЗУ VDD2",
"Voltage": "Напряжение",
"RAM VDDQ Voltage": "Напряжение ОЗУ VDDQ",
"RAM Frequency Editor": "Редактор частоты оперативной памяти",
"JEDEC.": "ДЖЕДЕК.",
"High speedo needed!": "Нужен высокий спидометр!",
"3333MHz (Needs extreme Speedo/PLL)": "3333 МГц (требуется экстремальный спидометр/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 МГц (требуется экстремальный спидометр/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 МГц (требуется экстремальный спидометр/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 МГц (нужен нелепый спидометр/PLL)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 МГц (нужен нелепый спидометр/PLL)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 МГц (нужен нелепый спидометр/PLL)",
"Ram Max Clock": "Рам Макс Часы",
"RAM Latency Editor": "Редактор задержки оперативной памяти",
"RAM Timing Reductions": "Сокращение таймингов ОЗУ",
"Memory Timings": "Тайминги памяти",
"Advanced": "Расширенный",
"t6 tRTW Fine Tune": "t6 tRTW Точная настройка",
"tRTW Fine Tune": "tRTW Точная настройка",
"t7 tWTR Fine Tune": "t7 tWTR Тонкая настройка",
"tWTR Fine Tune": "tWTR Тонкая настройка",
"Memory Latencies": "Задержки памяти",
"Read Latency": "Задержка чтения",
"Write Latency": "Задержка записи",
"CPU Boost Clock": "Тактовая частота процессора",
"CPU UV": "УФ процессора",
"CPU Unlock": "Разблокировка процессора",
"CPU VMIN": "ЦП VMIN",
"CPU Max Voltage": "Максимальное напряжение процессора",
"CPU Max Clock": "Максимальная частота процессора",
"Extreme UV Table": "Стол для экстремального УФ-излучения",
"CPU UV Table": "UV-таблица процессора",
"CPU Low UV": "ЦП с низким УФ-излучением",
"CPU High UV": "Процессор с высоким УФ",
"CPU Low VMIN": "Низкий VMIN процессора",
"CPU High VMIN": "Высокий VMIN процессора",
"No Undervolt": "Нет Андервольта",
"SLT Table": "Таблица ТА",
"HiOPT Table": "Таблица HiOPT",
"GPU Undervolt Table": "Таблица пониженного напряжения графического процессора",
"GPU Minimum Voltage": "Минимальное напряжение графического процессора",
"Calculate GPU Vmin": "Рассчитать Vmin графического процессора",
"GPU VMIN": "Вмин графического процессора",
"GPU Maximum Voltage": "Максимальное напряжение графического процессора",
"GPU Voltage Offset": "Смещение напряжения графического процессора",
"Do not override": "Не переопределять",
"Enabled (Default)": "Включено (по умолчанию)",
"96.6% limit": "Предел 96,6%",
"99.7% limit": "лимит 99,7%",
"GPU Scheduling Override": "Переопределение планирования графического процессора",
"Official Service": "Официальная служба",
"GPU DVFS Mode": "Режим графического процессора DVFS",
"GPU DVFS Offset": "Смещение DVFS графического процессора",
"GPU Voltage Table": "Таблица напряжений графического процессора",
"GPU Custom Table (mV)": "Пользовательская таблица графического процессора (мВ)",
"1075MHz without UV, 1152MHz on SLT": "1075 МГц без УФ, 1152 МГц на SLT",
"or 1228MHz on HiOPT can cause ": "или 1228 МГц на HiOPT может привести к",
"permanent damage to your Switch!": "необратимое повреждение вашего коммутатора!",
"921MHz without UV and 960MHz on": "921 МГц без УФ и 960 МГц с включенным",
"SLT or HiOPT can cause ": "SLT или HiOPT могут вызвать"
}

View File

@@ -0,0 +1,141 @@
{
"Information": "Інформація",
"IDDQ:": "IDDQ:",
"Module: ": "Модуль:",
"sys-dock status:": "стан sys-dock:",
"SaltyNX status:": "Статус SaltyNX:",
"RR Display status:": "Статус дисплея RR:",
"Wafer Position:": "Позиція пластини:",
"Credits": "Кредити",
"Developers": "Розробники",
"Contributors": "Дописувачі",
"Testers": "Тестери",
"Special Thanks": "Особлива подяка",
"Unknown": "Невідомий",
"Installed": "встановлено",
"Not Installed": "Не встановлено",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "ЛІЦЕНЗІЯ НА ПИВНИЙ ПОСУД",
"Default": "За замовчуванням",
"Do Not Override": "Не перевизначати",
"Disabled": "Вимкнено",
"Enabled": "Увімкнено",
" \\ue0e3 Reset": "\\ue0e3 Скидання",
"Display": "Дисплей",
"Application changed\\n\\n": "Додаток змінено\\n\\n",
"The running application changed\\n\\n": "Запущена програма змінена\\n\\n",
"while editing was going on.": "поки йшло редагування.",
"Board": "дошка",
"%u.%u%u mV": "%u.%u%u мВ",
"Could not connect to hoc-clk sysmodule.\\n\\n": "Не вдалося підключитися до системного модуля hoc-clk.\\n\\n",
"Please make sure everything is\\n\\n": "Переконайтеся, що все\\n\\n",
"correctly installed and enabled.": "правильно встановлено та включено.",
"Fatal error": "Фатальна помилка",
"Temporary Overrides ": "Тимчасові перевизначення",
"Sleep Mode": "Режим сну",
"Stock": "Запас",
"Dev OC": "Розробник OC",
"Boost Mode": "Режим посилення",
"Safe Max": "Безпечний макс",
"Unsafe Max": "Небезпечний макс",
"Absolute Max": "Абсолютний макс",
"Handheld Safe Max": "Портативний сейф Макс",
"Enable": "Увімкнути",
"Edit App Profile": "Редагувати профіль програми",
"Edit Global Profile": "Редагувати глобальний профіль",
"Temporary Overrides": "Тимчасові перевизначення",
"Settings": "Налаштування",
"About": "про",
"Compiling with minimal features": "Компіляція з мінімальними можливостями",
"General Settings": "Загальні налаштування",
"Governor Settings": "Налаштування губернатора",
"Safety Settings": "Налаштування безпеки",
"Save KIP Settings": "Зберегти налаштування KIP",
"RAM Settings": "Налаштування оперативної пам'яті",
"CPU Settings": "Налаштування ЦП",
"GPU Settings": "Налаштування GPU",
"Display Settings": "Налаштування дисплея",
"Experimental": "Експериментальний",
"GPU Scheduling Override Method": "Метод перевизначення планування GPU",
"can be dangerous and may cause": "може бути небезпечним і може спричинити",
"damage to your battery or charger!": "пошкодження акумулятора або зарядного пристрою!",
"Charge Current Override": "Перевизначення струму заряду",
"RAM Voltage Display Mode": "Режим відображення напруги RAM",
"Polling Interval": "Інтервал опитування",
"CPU Governor Minimum Frequency": "Мінімальна частота регулятора ЦП",
"refresh rates may cause stress": "частоти оновлення можуть викликати стрес",
"or damage to your display! ": "або пошкодження дисплея!",
"Proceed at your own risk!": "Продовжуйте на свій страх і ризик!",
"Max Handheld Display": "Максимальний портативний дисплей",
"Display Clock": "Відображення годинника",
"Official Rating": "Офіційний рейтинг",
"TDP Threshold": "Поріг TDP",
"Power": "потужність",
"Thermal Throttle Limit": "Термічний дросельний ліміт",
"HP Mode": "Режим HP",
"Default (Mariko)": "За замовчуванням (Маріко)",
"Default (Erista)": "За замовчуванням (Erista)",
"Rating": "Рейтинг",
"Safe Max (Mariko)": "Сейф Макс (Маріко)",
"Safe Max (Erista)": "Сейф Макс (Еріста)",
"RAM VDD2 Voltage": "Напруга RAM VDD2",
"Voltage": "Напруга",
"RAM VDDQ Voltage": "Напруга RAM VDDQ",
"RAM Frequency Editor": "Редактор частоти оперативної пам'яті",
"JEDEC.": "JEDEC.",
"High speedo needed!": "Потрібна висока швидкість!",
"3333MHz (Needs extreme Speedo/PLL)": "3333 МГц (потрібна екстремальна швидкість/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366 МГц (потрібна екстремальна швидкість/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400 МГц (потрібна екстремальна швидкість/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433 МГц (потрібен смішний Speedo/PLL)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466 МГц (потрібен смішний Speedo/PLL)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500 МГц (потрібен смішний Speedo/PLL)",
"Ram Max Clock": "Годинник Ram Max",
"RAM Latency Editor": "Редактор затримки оперативної пам'яті",
"RAM Timing Reductions": "Скорочення оперативної пам'яті",
"Memory Timings": "Таймінг пам'яті",
"Advanced": "Просунутий",
"t6 tRTW Fine Tune": "t6 tRTW Точне налаштування",
"tRTW Fine Tune": "Точне налаштування tRTW",
"t7 tWTR Fine Tune": "t7 tWTR Точне налаштування",
"tWTR Fine Tune": "Точна настройка tWTR",
"Memory Latencies": "Затримки пам'яті",
"Read Latency": "Прочитати затримку",
"Write Latency": "Затримка запису",
"CPU Boost Clock": "CPU Boost Clock",
"CPU UV": "CPU UV",
"CPU Unlock": "Розблокування ЦП",
"CPU VMIN": "CPU VMIN",
"CPU Max Voltage": "Максимальна напруга ЦП",
"CPU Max Clock": "Максимальна частота ЦП",
"Extreme UV Table": "Екстремальний ультрафіолетовий стіл",
"CPU UV Table": "CPU UV Таблиця",
"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": "Без андервольта",
"SLT Table": "Таблиця SLT",
"HiOPT Table": "Таблиця HiOPT",
"GPU Undervolt Table": "Таблиця зниження напруги GPU",
"GPU Minimum Voltage": "Мінімальна напруга GPU",
"Calculate GPU Vmin": "Розрахувати GPU Vmin",
"GPU VMIN": "GPU VMIN",
"GPU Maximum Voltage": "Максимальна напруга GPU",
"GPU Voltage Offset": "Зсув напруги GPU",
"Do not override": "Не перевизначати",
"Enabled (Default)": "Увімкнено (за замовчуванням)",
"96.6% limit": "96,6% обмеження",
"99.7% limit": "Обмеження 99,7%.",
"GPU Scheduling Override": "Перевизначення планування GPU",
"Official Service": "Офіційний сервіс",
"GPU DVFS Mode": "Режим GPU DVFS",
"GPU DVFS Offset": "GPU DVFS Offset",
"GPU Voltage Table": "Таблиця напруги GPU",
"GPU Custom Table (mV)": "Спеціальна таблиця GPU (мВ)",
"1075MHz without UV, 1152MHz on SLT": "1075 МГц без УФ, 1152 МГц на SLT",
"or 1228MHz on HiOPT can cause ": "або 1228 МГц на HiOPT може спричинити",
"permanent damage to your Switch!": "незворотне пошкодження вашого комутатора!",
"921MHz without UV and 960MHz on": "921 МГц без УФ і 960 МГц увімкнено",
"SLT or HiOPT can cause ": "SLT або HiOPT можуть спричинити"
}

View File

@@ -0,0 +1,157 @@
{
"Information": "信息",
"IDDQ:": "IDDQ:",
"Module: ": "模块: ",
"sys-dock status:": "sys-dock 状态:",
"SaltyNX status:": "SaltyNX 状态:",
"RR Display status:": "RR 显示状态:",
"Wafer Position:": "晶圆位置:",
"Credits": "致谢",
"Developers": "开发者",
"Contributors": "贡献者",
"Testers": "测试者",
"Special Thanks": "特别感谢",
"Unknown": "未知",
"Installed": "已安装",
"Not Installed": "未安装",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "啤酒软件许可协议",
"Default": "默认",
"Do Not Override": "不修改",
"Disabled": "已禁用",
"Enabled": "已启用",
" \\ue0e3 Reset": " \\ue0e3 重置",
"Display": "显示",
"Application changed\\n\\n": "应用已变更\\n\\n",
"The running application changed\\n\\n": "正在运行的应用已变更\\n\\n",
"while editing was going on.": "编辑过程中发生变更。",
"Board": "主板",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "无法连接到 hoc-clk 系统模块。\\n\\n",
"Please make sure everything is\\n\\n": "请确保所有内容均已\\n\\n",
"correctly installed and enabled.": "正确安装并启用。",
"Fatal error": "致命错误",
"Temporary Overrides ": "临时配置 ",
"Sleep Mode": "睡眠模式",
"Stock": "原厂默认",
"Dev OC": "开发者超频",
"Boost Mode": "加速模式",
"Safe Max": "安全最大值",
"Unsafe Max": "危险最大值",
"Absolute Max": "绝对最大值",
"Handheld Safe Max": "掌机模式安全最大值",
"Enable": "启用",
"Edit App Profile": "编辑应用配置",
"Edit Global Profile": "编辑全局配置",
"Temporary Overrides": "临时配置",
"Settings": "设置",
"About": "关于",
"Compiling with minimal features": "以最小功能编译",
"General Settings": "通用设置",
"Governor Settings": "调频器设置",
"Safety Settings": "安全设置",
"Save KIP Settings": "保存 KIP 设置",
"RAM Settings": "内存设置",
"CPU Settings": "CPU 设置",
"GPU Settings": "GPU 设置",
"Display Settings": "显示设置",
"Experimental": "实验性功能",
"GPU Scheduling Override Method": "GPU 调度覆盖方式",
"can be dangerous and may cause": "存在风险,可能导致",
"damage to your battery or charger!": "电池或充电器损坏!",
"Charge Current Override": "充电电流修改",
"RAM Voltage Display Mode": "内存电压显示模式",
"Polling Interval": "刷新间隔",
"CPU Governor Minimum Frequency": "CPU 调频器最低频率",
"\uE150 Usage of unsafe display": "\uE150 不安全的显示屏",
"refresh rates may cause stress": "刷新率可能会对",
"or damage to your display! ": "显示屏造成压力或损坏! ",
"Proceed at your own risk!": "操作风险自负!",
"Max Handheld Display": "掌机模式最大显示率",
"Display Clock": "显示时钟",
"Official Rating": "官方额定值",
"TDP Threshold": "TDP 阈值",
"Power": "电源",
"Thermal Throttle Limit": "温控设置",
"HP Mode": "高性能模式",
"Default (Mariko)": "默认 (Mariko)",
"Default (Erista)": "默认 (Erista)",
"Rating": "额定值",
"Safe Max (Mariko)": "安全最大值 (Mariko)",
"Safe Max (Erista)": "安全最大值 (Erista)",
"RAM VDD2 Voltage": "内存 VDD2 电压",
"Voltage": "电压",
"RAM VDDQ Voltage": "内存 VDDQ 电压",
"RAM Frequency Editor": "内存频率编辑器",
"JEDEC.": "JEDEC 标准。",
"High speedo needed!": "需要高 Speedo 配置!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz (需要极限 Speedo/PLL)",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz (需要极限 Speedo/PLL)",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz (需要极限 Speedo/PLL)",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz (需要极端 Speedo/PLL)",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz (需要极端 Speedo/PLL)",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz (需要极端 Speedo/PLL)",
"Ram Max Clock": "内存最大频率",
"RAM Latency Editor": "内存延迟编辑器",
"RAM Timing Reductions": "内存时序优化",
"Memory Timings": "内存时序",
"Memory": "内存",
"mem": "内存",
"Governor": "调频器",
"Advanced": "高级",
"Docked": "底座模式",
"Handheld": "掌机模式",
"Charging": "充电中",
"USB Charger": "USB 充电器",
"PD Charger": "PD 充电器",
"Handheld TDP": "掌机模式功耗限制",
"Thermal Throttle": "温度控制",
"Uncapped Clocks": "解除频率上限",
"Soc DVB Shift": "SoC DVB偏移",
"Overwrite Boost Mode": "接管官方CPU调度",
"Display Refresh Rate Changing": "显示刷新率变更",
"t6 tRTW Fine Tune": "t6 tRTW 微调",
"tRTW Fine Tune": "tRTW 微调",
"t7 tWTR Fine Tune": "t7 tWTR 微调",
"tWTR Fine Tune": "tWTR 微调",
"Memory Latencies": "内存延迟",
"Read Latency": "读取延迟",
"Write Latency": "写入延迟",
"CPU Boost Clock": "CPU 超频频率",
"CPU UV": "CPU 降压",
"CPU Unlock": "CPU 解锁",
"CPU VMIN": "CPU 最低电压",
"CPU Max Voltage": "CPU 最大电压",
"CPU Max Clock": "CPU 最大频率",
"Extreme UV Table": "极限降压表",
"CPU UV Table": "CPU 降压表",
"CPU Low UV": "CPU 低压降压",
"CPU High UV": "CPU 高压降压",
"CPU Low VMIN": "CPU 低压最低电压",
"CPU High VMIN": "CPU 高压最低电压",
"No Undervolt": "不降压",
"SLT Table": "SLT 表",
"HiOPT Table": "HiOPT 表",
"GPU Undervolt Table": "GPU 降压表",
"GPU Minimum Voltage": "GPU 最低电压",
"Calculate GPU Vmin": "计算 GPU 最低电压",
"GPU VMIN": "GPU 最低电压",
"GPU Maximum Voltage": "GPU 最大电压",
"GPU Voltage Offset": "GPU 电压偏移",
"Do not override": "不修改",
"Enabled (Default)": "已启用 (默认)",
"96.6% limit": "96.6% 限制",
"99.7% limit": "99.7% 限制",
"GPU Scheduling Override": "GPU 调度修改",
"Official Service": "官方服务",
"GPU DVFS Mode": "GPU DVFS 模式",
"GPU DVFS Offset": "GPU DVFS 偏移",
"GPU Voltage Table": "GPU 电压表",
"GPU Custom Table (mV)": "GPU 自定义表 (mV)",
"\uE150 Setting GPU Clocks past": "\uE150 将 GPU 频率设置超过",
"1075MHz without UV, 1152MHz on SLT": "1075MHz 无降压SLT 表下 1152MHz",
"or 1228MHz on HiOPT can cause ": "或 HiOPT 表下 1228MHz 可能导致 ",
"permanent damage to your Switch!": "Switch 永久损坏!",
"921MHz without UV and 960MHz on": "921MHz 无降压SLT/HiOPT 表下 960MHz",
"SLT or HiOPT can cause ": "可能导致 "
}

View File

@@ -0,0 +1,141 @@
{
"Information": "資訊",
"IDDQ:": "國際電話號碼:",
"Module: ": "模組:",
"sys-dock status:": "系統塢站狀態:",
"SaltyNX status:": "SaltyNX 狀態:",
"RR Display status:": "RR 顯示狀態:",
"Wafer Position:": "晶圓位置:",
"Credits": "製作人員",
"Developers": "開發商",
"Contributors": "貢獻者",
"Testers": "測試人員",
"Special Thanks": "特別感謝",
"Unknown": "未知",
"Installed": "已安裝",
"Not Installed": "未安裝",
"X: %u Y: %u": "X: %u Y: %u",
"THE BEER-WARE LICENSE": "啤酒製品許可證",
"Default": "預設",
"Do Not Override": "不要覆蓋",
"Disabled": "殘障人士",
"Enabled": "啟用",
" \\ue0e3 Reset": "\\ue0e3 重設",
"Display": "顯示",
"Application changed\\n\\n": "應用程式已更改\\n\\n",
"The running application changed\\n\\n": "正在運行的應用程式已更改\\n\\n",
"while editing was going on.": "當編輯正在進行時。",
"Board": "董事會",
"%u.%u%u mV": "%u.%u%u mV",
"Could not connect to hoc-clk sysmodule.\\n\\n": "無法連接到 hoc-clk 系統模組。 \\n\\n",
"Please make sure everything is\\n\\n": "請確保一切正常\\n\\n",
"correctly installed and enabled.": "正確安裝並啟用。",
"Fatal error": "致命錯誤",
"Temporary Overrides ": "臨時覆蓋",
"Sleep Mode": "睡眠模式",
"Stock": "庫存",
"Dev OC": "開發OC",
"Boost Mode": "升壓模式",
"Safe Max": "安全最大值",
"Unsafe Max": "不安全最大值",
"Absolute Max": "絕對最大值",
"Handheld Safe Max": "手持式安全最大",
"Enable": "啟用",
"Edit App Profile": "編輯應用程式設定檔",
"Edit Global Profile": "編輯全域設定檔",
"Temporary Overrides": "臨時覆蓋",
"Settings": "設定",
"About": "關於",
"Compiling with minimal features": "使用最少的功能進行編譯",
"General Settings": "常規設定",
"Governor Settings": "調速器設定",
"Safety Settings": "安全設定",
"Save KIP Settings": "儲存 KIP 設定",
"RAM Settings": "記憶體設定",
"CPU Settings": "中央處理器設定",
"GPU Settings": "GPU設定",
"Display Settings": "顯示設定",
"Experimental": "實驗性的",
"GPU Scheduling Override Method": "GPU調度覆蓋方法",
"can be dangerous and may cause": "可能很危險並可能導致",
"damage to your battery or charger!": "損壞電池或充電器!",
"Charge Current Override": "充電電流覆蓋",
"RAM Voltage Display Mode": "RAM電壓顯示模式",
"Polling Interval": "輪詢間隔",
"CPU Governor Minimum Frequency": "CPU調速器最低頻率",
"refresh rates may cause stress": "刷新率可能會造成壓力",
"or damage to your display! ": "或損壞您的顯示器!",
"Proceed at your own risk!": "請自行承擔風險!",
"Max Handheld Display": "最大手持顯示器",
"Display Clock": "顯示時鐘",
"Official Rating": "官方評級",
"TDP Threshold": "TDP閾值",
"Power": "電源",
"Thermal Throttle Limit": "熱油門限制",
"HP Mode": "惠普模式",
"Default (Mariko)": "預設(真理子)",
"Default (Erista)": "預設(埃里斯塔)",
"Rating": "評級",
"Safe Max (Mariko)": "安全最大(真理子)",
"Safe Max (Erista)": "安全最大(埃里斯塔)",
"RAM VDD2 Voltage": "RAM VDD2 電壓",
"Voltage": "電壓",
"RAM VDDQ Voltage": "RAM VDDQ 電壓",
"RAM Frequency Editor": "RAM頻率編輯器",
"JEDEC.": "JEDEC。",
"High speedo needed!": "需要高速!",
"3333MHz (Needs extreme Speedo/PLL)": "3333MHz需要極高的 Speedo/PLL",
"3366MHz (Needs extreme Speedo/PLL)": "3366MHz需要極高的 Speedo/PLL",
"3400MHz (Needs extreme Speedo/PLL)": "3400MHz需要極高的 Speedo/PLL",
"3433MHz (Needs ridiculous Speedo/PLL)": "3433MHz需要荒謬的 Speedo/PLL",
"3466MHz (Needs ridiculous Speedo/PLL)": "3466MHz需要荒謬的 Speedo/PLL",
"3500MHz (Needs ridiculous Speedo/PLL)": "3500MHz需要荒謬的 Speedo/PLL",
"Ram Max Clock": "記憶體最大時鐘",
"RAM Latency Editor": "RAM 延遲編輯器",
"RAM Timing Reductions": "RAM 時序減少",
"Memory Timings": "記憶體時序",
"Advanced": "進階",
"t6 tRTW Fine Tune": "t6 tRTW 微調",
"tRTW Fine Tune": "tRTW 微調",
"t7 tWTR Fine Tune": "t7 tWTR 微調",
"tWTR Fine Tune": "tWTR 微調",
"Memory Latencies": "記憶體延遲",
"Read Latency": "讀取延遲",
"Write Latency": "寫入延遲",
"CPU Boost Clock": "CPU 升壓時鐘",
"CPU UV": "中央處理器紫外線",
"CPU Unlock": "CPU解鎖",
"CPU VMIN": "CPU最低電壓",
"CPU Max Voltage": "CPU最大電壓",
"CPU Max Clock": "CPU 最大時脈",
"Extreme UV Table": "極端紫外線表",
"CPU UV Table": "CPU UV表",
"CPU Low UV": "CPU低紫外線",
"CPU High UV": "CPU高紫外線",
"CPU Low VMIN": "CPU 低 VMIN",
"CPU High VMIN": "CPU 高 VMIN",
"No Undervolt": "無欠壓",
"SLT Table": "SLT表",
"HiOPT Table": "HiOPT表",
"GPU Undervolt Table": "GPU 欠壓表",
"GPU Minimum Voltage": "GPU最低電壓",
"Calculate GPU Vmin": "計算 GPU Vmin",
"GPU VMIN": "GPU VMIN",
"GPU Maximum Voltage": "GPU最大電壓",
"GPU Voltage Offset": "GPU電壓偏移",
"Do not override": "不要覆蓋",
"Enabled (Default)": "啟用(預設)",
"96.6% limit": "96.6%限制",
"99.7% limit": "99.7%限制",
"GPU Scheduling Override": "GPU 調度覆蓋",
"Official Service": "官方服務",
"GPU DVFS Mode": "GPU DVFS 模式",
"GPU DVFS Offset": "GPU DVFS 偏移",
"GPU Voltage Table": "GPU電壓表",
"GPU Custom Table (mV)": "GPU 自訂表 (mV)",
"1075MHz without UV, 1152MHz on SLT": "無 UV 時為 1075MHzSLT 時為 1152MHz",
"or 1228MHz on HiOPT can cause ": "或 HiOPT 上的 1228MHz 可能會導致",
"permanent damage to your Switch!": "對您的 Switch 造成永久性損壞!",
"921MHz without UV and 960MHz on": "無 UV 時為 921MHz開啟時為 960MHz",
"SLT or HiOPT can cause ": "SLT 或 HiOPT 可能會導致"
}

View File

@@ -0,0 +1,16 @@
#!/bin/bash
set -e
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
DEST="$CURRENT_DIR/../data/logo_rgba.bin"
FONT="$CURRENT_DIR/../../manager/resources/fira/FiraSans-Medium-rnx.ttf"
FONT_SIZE="30.5"
TEXT="sys-clk"
function render() {
convert -background transparent -colorspace RGB -depth 8 -fill white -font "$1" -pointsize "$2" "label:$3" "$4"
}
render "$FONT" "$FONT_SIZE" "$TEXT" info:
render "$FONT" "$FONT_SIZE" "$TEXT" "RGBA:$DEST"

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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
#if defined(__cplusplus)
#include "cpp_util.hpp"
extern "C"
{
#endif
#include <sysclk.h>
#include <sysclk/client/ipc.h>
#if defined(__cplusplus)
}
#endif

View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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
* --------------------------------------------------------------------------
*/
#define TESLA_INIT_IMPL
#include <tesla.hpp>
#include "ui/gui/fatal_gui.h"
#include "ui/gui/main_gui.h"
#include "rgltr_services.h" // for extern Service g_rgltrSrv, etc.
class AppOverlay : public tsl::Overlay
{
public:
AppOverlay() {}
~AppOverlay() {}
//virtual void initServices() override {
// rgltrInitialize();
//}
virtual void exitServices() override {
rgltrExit();
sysclkIpcExit();
}
virtual std::unique_ptr<tsl::Gui> loadInitialGui() override
{
uint32_t apiVersion;
smInitialize();
tsl::hlp::ScopeGuard smGuard([] { smExit(); });
if(!sysclkIpcRunning())
{
return initially<FatalGui>(
"hoc-clk is not running.\n\n"
"\n"
"Please make sure it is correctly\n\n"
"installed and enabled.",
""
);
}
if(R_FAILED(sysclkIpcInitialize()) || R_FAILED(sysclkIpcGetAPIVersion(&apiVersion)))
{
return initially<FatalGui>(
"Could not connect to hoc-clk.\n\n"
"\n"
"Please make sure it is correctly\n\n"
"installed and enabled.",
""
);
}
if(SYSCLK_IPC_API_VERSION != apiVersion)
{
return initially<FatalGui>(
"Overlay not compatible with\n\n"
"the running hoc-clk version.\n\n"
"\n"
"Please make sure everything is\n\n"
"installed and up to date.",
""
);
}
return initially<MainGui>();
}
};
int main(int argc, char **argv)
{
return tsl::loop<AppOverlay>(argc, argv);
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 <tesla.hpp>
#include "../gui/base_gui.h"
class BaseFrame : public tsl::elm::HeaderOverlayFrame
{
public:
BaseFrame(BaseGui* gui) : tsl::elm::HeaderOverlayFrame(234) {
this->gui = gui;
}
void draw(tsl::gfx::Renderer* renderer) override
{
tsl::elm::HeaderOverlayFrame::draw(renderer);
this->gui->preDraw(renderer);
}
protected:
BaseGui* gui;
};

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 <cstdio>
#include <string>
#include <cstdint>
#define FREQ_DEFAULT_TEXT "Do not override"
static inline std::string formatListFreqMHz(std::uint32_t mhz)
{
if(mhz == 0)
{
return FREQ_DEFAULT_TEXT;
}
char buf[10];
return std::string(buf, snprintf(buf, sizeof(buf), "%u MHz", mhz));
}
static inline std::string formatListFreqHz(std::uint32_t hz) { return formatListFreqMHz(hz / 1000000); }

View File

@@ -0,0 +1,309 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "about_gui.h"
#include "../format.h"
#include <tesla.hpp>
#include <string>
#include "cat.h"
#include "ult_ext.h"
tsl::elm::ListItem* SpeedoItem = NULL;
tsl::elm::ListItem* IddqItem = NULL;
tsl::elm::ListItem* DramModule = NULL;
tsl::elm::ListItem* sysdockStatusItem = NULL;
tsl::elm::ListItem* saltyNXStatusItem = NULL;
tsl::elm::ListItem* RETROStatusItem = NULL;
tsl::elm::ListItem* waferCordsItem = NULL;
ImageElement* CatImage = NULL;
HideableCategoryHeader* CatHeader = NULL;
HideableCustomDrawer* CatSpacer = NULL;
int lightosClickCount = 0;
AboutGui::AboutGui()
{
memset(strings, 0, sizeof(strings));
}
AboutGui::~AboutGui()
{
}
void AboutGui::listUI()
{
this->listElement->addItem(
new tsl::elm::CategoryHeader("Information")
);
SpeedoItem =
new tsl::elm::ListItem("Speedo:");
this->listElement->addItem(SpeedoItem);
IddqItem =
new tsl::elm::ListItem("IDDQ:");
this->listElement->addItem(IddqItem);
DramModule =
new tsl::elm::ListItem("Module: ");
this->listElement->addItem(DramModule);
if(!IsHoag()) {
sysdockStatusItem =
new tsl::elm::ListItem("sys-dock status:");
this->listElement->addItem(sysdockStatusItem);
}
saltyNXStatusItem =
new tsl::elm::ListItem("SaltyNX status:");
this->listElement->addItem(saltyNXStatusItem);
if(IsHoag()) {
RETROStatusItem =
new tsl::elm::ListItem("RR Display status:");
this->listElement->addItem(RETROStatusItem);
}
waferCordsItem =
new tsl::elm::ListItem("Wafer Position:");
this->listElement->addItem(waferCordsItem);
this->listElement->addItem(
new tsl::elm::CategoryHeader("Credits")
);
this->listElement->addItem(
new tsl::elm::CategoryHeader("Developers")
);
this->listElement->addItem(
new tsl::elm::ListItem("Souldbminer")
);
// Create special clickable item for Lightos
auto lightosItem = new tsl::elm::ListItem("Lightos_");
lightosItem->setClickListener([this](u64 keys) -> bool {
if (keys & HidNpadButton_A) {
lightosClickCount++;
if (lightosClickCount >= 10) {
if (CatImage != NULL) CatImage->setVisible(true);
if (CatHeader != NULL) CatHeader->setVisible(true);
if (CatSpacer != NULL) CatSpacer->setVisible(true);
}
return true;
}
return false;
});
this->listElement->addItem(lightosItem);
// ---- Contributors ----
this->listElement->addItem(
new tsl::elm::CategoryHeader("Contributors")
);
this->listElement->addItem(
new tsl::elm::ListItem("Dom")
);
this->listElement->addItem(
new tsl::elm::ListItem("Blaise25")
);
// ---- Testers ----
this->listElement->addItem(
new tsl::elm::CategoryHeader("Testers")
);
this->listElement->addItem(
new tsl::elm::ListItem("Dom")
);
this->listElement->addItem(
new tsl::elm::ListItem("Samybigio2011")
);
this->listElement->addItem(
new tsl::elm::ListItem("Delta")
);
this->listElement->addItem(
new tsl::elm::ListItem("Miki1305")
);
this->listElement->addItem(
new tsl::elm::ListItem("Happy")
);
this->listElement->addItem(
new tsl::elm::ListItem("Flopsider")
);
this->listElement->addItem(
new tsl::elm::ListItem("Winnerboi77")
);
this->listElement->addItem(
new tsl::elm::ListItem("Blaise25")
);
this->listElement->addItem(
new tsl::elm::ListItem("WE1ZARD")
);
this->listElement->addItem(
new tsl::elm::ListItem("Alvise")
);
this->listElement->addItem(
new tsl::elm::ListItem("TDRR")
);
this->listElement->addItem(
new tsl::elm::ListItem("agjeococh")
);
this->listElement->addItem(
new tsl::elm::ListItem("Xenshen")
);
this->listElement->addItem(
new tsl::elm::ListItem("Frost")
);
// ---- Special Thanks ----
this->listElement->addItem(
new tsl::elm::CategoryHeader("Special Thanks")
);
this->listElement->addItem(
new tsl::elm::ListItem("ScriesM - Atmosphere CFW")
);
this->listElement->addItem(
new tsl::elm::ListItem("KazushiMe - Switch OC Suite")
);
this->listElement->addItem(
new tsl::elm::ListItem("hanai3bi - Switch OC Suite & EOS")
);
this->listElement->addItem(
new tsl::elm::ListItem("NaGaa95 - L4T-OC-Kernel")
);
this->listElement->addItem(
new tsl::elm::ListItem("B3711 - EOS")
);
this->listElement->addItem(
new tsl::elm::ListItem("RetroNX - sys-clk")
);
this->listElement->addItem(
new tsl::elm::ListItem("b0rd2death - Ultrahand")
);
this->listElement->addItem(
new tsl::elm::ListItem("MasaGratoR - Status Monitor")
);
// Create cat elements but hide them initially
CatHeader = new HideableCategoryHeader("Cat");
CatHeader->setVisible(false);
this->listElement->addItem(CatHeader);
CatImage = new ImageElement(CAT_DATA, CAT_WIDTH, CAT_HEIGHT);
CatImage->setVisible(false);
this->listElement->addItem(CatImage);
CatSpacer = new HideableCustomDrawer(75);
CatSpacer->setVisible(false);
this->listElement->addItem(CatSpacer);
}
std::string AboutGui::formatRamModule() {
switch (this->context->dramID) {
case 0: return "HB-MGCH 4GB";
case 4: return "HM-MGCH 6GB";
case 7: return "HM-MGXX 8GB";
case 1: return "NLE 4GB";
case 2: return "WT:C 4GB";
case 3:
case 5 ... 6: return "NEE 4GB";
case 8:
case 12: return "AM-MGCJ 4GB";
case 9:
case 13: return "AM-MGCJ 8GB";
case 10:
case 14: return "NME 4GB";
case 11:
case 15: return "WT:E 4GB";
case 17:
case 19:
case 24: return "AA-MGCL 4GB";
case 18:
case 23:
case 28: return "AA-MGCL 8GB";
case 20 ... 22: return "AB-MGCL 4GB";
case 25 ... 27: return "WT:F 4GB";
case 29 ... 31: return "x267 4GB";
case 32 ... 34: return "WT:B 4GB";
default: return "Unknown";
}
}
void AboutGui::update()
{
BaseMenuGui::update();
}
void AboutGui::refresh()
{
BaseMenuGui::refresh();
if (!this->context)
return;
// Format strings once per refresh
sprintf(strings[0], "%u/%u/%u", this->context->speedos[HorizonOCSpeedo_CPU], this->context->speedos[HorizonOCSpeedo_GPU], this->context->speedos[HorizonOCSpeedo_SOC]);
// This is how hekate does it
sprintf(strings[1], "%u/%u/%u", this->context->iddq[HorizonOCSpeedo_CPU], this->context->iddq[HorizonOCSpeedo_GPU], this->context->iddq[HorizonOCSpeedo_SOC]);
SpeedoItem->setValue(strings[0]);
IddqItem->setValue(strings[1]);
DramModule->setValue(formatRamModule());
if(!IsHoag())
sysdockStatusItem->setValue(this->context->isSysDockInstalled ? "Installed" : "Not Installed");
saltyNXStatusItem->setValue(this->context->isSaltyNXInstalled ? "Installed" : "Not Installed");
if(IsHoag())
RETROStatusItem->setValue(this->context->isUsingRetroSuper ? "Installed" : "Not Installed");
sprintf(strings[2], "X: %u Y: %u", this->context->waferX, this->context->waferY);
waferCordsItem->setValue(strings[2]);
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "../../ipc.h"
#include "base_menu_gui.h"
#include "freq_choice_gui.h"
#include "value_choice_gui.h"
#include "fatal_gui.h"
#include <map>
#include <vector>
class AboutGui : public BaseMenuGui
{
protected:
char strings[32][32];
public:
AboutGui();
~AboutGui();
void listUI() override;
void update() override;
void refresh() override;
private:
std::string formatRamModule();
};

View File

@@ -0,0 +1,468 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 "app_profile_gui.h"
#include "../format.h"
#include "fatal_gui.h"
#include "labels.h"
AppProfileGui::AppProfileGui(std::uint64_t applicationId, SysClkTitleProfileList* profileList)
{
this->applicationId = applicationId;
this->profileList = profileList;
}
AppProfileGui::~AppProfileGui()
{
delete this->profileList;
}
void AppProfileGui::openFreqChoiceGui(tsl::elm::ListItem* listItem, SysClkProfile profile, SysClkModule module)
{
std::uint32_t hzList[SYSCLK_FREQ_LIST_MAX];
std::uint32_t hzCount;
Result rc = sysclkIpcGetFreqList(module, &hzList[0], SYSCLK_FREQ_LIST_MAX, &hzCount);
if(R_FAILED(rc))
{
FatalGui::openWithResultCode("sysclkIpcGetFreqList", rc);
return;
}
std::map<uint32_t, std::string> labels = {};
if (module == SysClkModule_CPU) {
bool isUsingUv = IsMariko() ? configList.values[KipConfigValue_marikoCpuUVHigh] : configList.values[KipConfigValue_eristaCpuUV];
labels = IsMariko() ? (isUsingUv ? cpu_freq_label_m_uv : cpu_freq_label_m) : (isUsingUv ? cpu_freq_label_e_uv : cpu_freq_label_e);
} else if (module == SysClkModule_GPU) {
labels = IsMariko() ? *(marikoUV[configList.values[KipConfigValue_marikoGpuUV]]) : *(eristaUV[configList.values[KipConfigValue_eristaGpuUV]]);
}
tsl::changeTo<FreqChoiceGui>(this->profileList->mhzMap[profile][module] * 1000000, hzList, hzCount, module, [this, listItem, profile, module](std::uint32_t hz) {
this->profileList->mhzMap[profile][module] = hz / 1000000;
listItem->setValue(formatListFreqMHz(this->profileList->mhzMap[profile][module]));
Result rc = sysclkIpcSetProfiles(this->applicationId, this->profileList);
if(R_FAILED(rc))
{
FatalGui::openWithResultCode("sysclkIpcSetProfiles", rc);
return false;
}
return true;
}, true, labels
);
}
void AppProfileGui::openValueChoiceGui(
tsl::elm::ListItem* listItem,
std::uint32_t currentValue,
const ValueRange& range,
const std::string& categoryName,
ValueChoiceListener listener,
const ValueThresholds& thresholds,
bool enableThresholds,
const std::map<std::uint32_t, std::string>& labels,
const std::vector<NamedValue>& namedValues,
bool showDefaultValue
)
{
tsl::changeTo<ValueChoiceGui>(
currentValue,
range,
categoryName,
listener,
thresholds,
enableThresholds,
labels,
namedValues,
showDefaultValue,
true
);
}
void AppProfileGui::addModuleListItem(SysClkProfile profile, SysClkModule module)
{
tsl::elm::ListItem* listItem = new tsl::elm::ListItem(sysclkFormatModule(module, true));
listItem->setValue(formatListFreqMHz(this->profileList->mhzMap[profile][module]));
listItem->setClickListener([this, listItem, profile, module](u64 keys) {
if((keys & HidNpadButton_A) == HidNpadButton_A)
{
this->openFreqChoiceGui(listItem, profile, module);
return true;
}
else if((keys & HidNpadButton_Y) == HidNpadButton_Y)
{
// Reset to "Default" (0 MHz)
this->profileList->mhzMap[profile][module] = 0;
listItem->setValue(formatListFreqMHz(0));
Result rc = sysclkIpcSetProfiles(this->applicationId, this->profileList);
if(R_FAILED(rc))
{
FatalGui::openWithResultCode("sysclkIpcSetProfiles", rc);
return false;
}
return true;
}
return false;
});
this->listElement->addItem(listItem);
}
void AppProfileGui::addModuleListItemToggle(SysClkProfile profile, SysClkModule module)
{
const char* moduleName = sysclkFormatModule(module, true);
std::uint32_t currentValue = this->profileList->mhzMap[profile][module];
tsl::elm::ToggleListItem* toggle = new tsl::elm::ToggleListItem(moduleName, currentValue != 0);
toggle->setStateChangedListener([this, profile, module](bool state) {
this->profileList->mhzMap[profile][module] = state ? 1 : 0;
Result rc = sysclkIpcSetProfiles(this->applicationId, this->profileList);
if(R_FAILED(rc))
{
FatalGui::openWithResultCode("sysclkIpcSetProfiles", rc);
}
});
this->listElement->addItem(toggle);
}
std::string AppProfileGui::formatValueDisplay(
std::uint32_t value,
const std::vector<NamedValue>& namedValues,
const std::string& suffix,
std::uint32_t divisor,
int decimalPlaces
)
{
if (value == 0) {
return FREQ_DEFAULT_TEXT;
}
if (!namedValues.empty()) {
for (const auto& namedValue : namedValues) {
if (namedValue.value == value) {
return namedValue.name;
}
}
}
char buf[32];
if (decimalPlaces > 0) {
double displayValue = (double)value / divisor;
snprintf(buf, sizeof(buf), "%.*f%s", decimalPlaces, displayValue, suffix.c_str());
} else {
snprintf(buf, sizeof(buf), "%u%s", value / divisor, suffix.c_str());
}
return std::string(buf);
}
void AppProfileGui::addModuleListItemValue(
SysClkProfile profile,
SysClkModule module,
const std::string& categoryName,
std::uint32_t min,
std::uint32_t max,
std::uint32_t step,
const std::string& suffix,
std::uint32_t divisor,
int decimalPlaces,
ValueThresholds thresholds,
std::vector<NamedValue> namedValues,
bool showDefaultValue
)
{
tsl::elm::ListItem* listItem =
new tsl::elm::ListItem(sysclkFormatModule(module, true));
std::uint32_t storedValue = this->profileList->mhzMap[profile][module];
listItem->setValue(this->formatValueDisplay(storedValue, namedValues, suffix, divisor, decimalPlaces));
listItem->setClickListener(
[this,
listItem,
profile,
module,
categoryName,
min,
max,
step,
suffix,
divisor,
decimalPlaces,
thresholds,
namedValues,
showDefaultValue](u64 keys)
{
if ((keys & HidNpadButton_A) == HidNpadButton_A)
{
std::uint32_t currentValue =
this->profileList->mhzMap[profile][module] * divisor;
ValueRange range(
min,
max,
step,
suffix,
divisor,
decimalPlaces
);
this->openValueChoiceGui(
listItem,
currentValue,
range,
categoryName,
[this, listItem, profile, module, divisor, suffix, decimalPlaces, thresholds, namedValues](std::uint32_t value) -> bool
{
this->profileList->mhzMap[profile][module] = value / divisor;
listItem->setValue(this->formatValueDisplay(value / divisor, namedValues, suffix, divisor, decimalPlaces));
Result rc =
sysclkIpcSetProfiles(this->applicationId,
this->profileList);
if (R_FAILED(rc))
{
FatalGui::openWithResultCode(
"sysclkIpcSetProfiles", rc);
return false;
}
return true;
},
thresholds,
false,
{},
namedValues,
showDefaultValue
);
return true;
}
else if ((keys & HidNpadButton_Y) == HidNpadButton_Y)
{
this->profileList->mhzMap[profile][module] = 0;
listItem->setValue(FREQ_DEFAULT_TEXT);
Result rc =
sysclkIpcSetProfiles(this->applicationId,
this->profileList);
if (R_FAILED(rc))
{
FatalGui::openWithResultCode("sysclkIpcSetProfiles", rc);
return false;
}
return true;
}
return false;
});
this->listElement->addItem(listItem);
}
class GovernorProfileSubMenuGui : public BaseMenuGui {
uint64_t applicationId;
SysClkTitleProfileList* profileList;
SysClkProfile profile;
public:
GovernorProfileSubMenuGui(uint64_t appId, SysClkTitleProfileList* pList, SysClkProfile prof)
: applicationId(appId), profileList(pList), profile(prof) {}
void listUI() override {
Result rc = sysclkIpcGetConfigValues(&configList);
if (R_FAILED(rc)) [[unlikely]] {
FatalGui::openWithResultCode("sysclkIpcGetConfigValues", rc);
return;
}
this->listElement->addItem(new tsl::elm::CategoryHeader("Governor"));
static constexpr struct { const char* label; int shift; } kAll[] = {
{"CPU", 0}, {"GPU", 8}, {"VRR", 16}
};
int count = configList.values[HorizonOCConfigValue_OverwriteRefreshRate] ? 3 : 2;
for (int i = 0; i < count; i++) {
u8 cur = (this->profileList->mhzMap[this->profile][HorizonOCModule_Governor] >> kAll[i].shift) & 0xFF;
auto* bar = new tsl::elm::NamedStepTrackBar(
"", {"Do Not Override", "Disabled", "Enabled"},
true, kAll[i].label
);
bar->setProgress(cur);
int shift = kAll[i].shift;
bar->setValueChangedListener([this, shift](u8 value) {
u32& packed = this->profileList->mhzMap[this->profile][HorizonOCModule_Governor];
packed = (packed & ~(0xFFu << shift)) | ((u32)value << shift);
Result rc = sysclkIpcSetProfiles(this->applicationId, this->profileList);
if (R_FAILED(rc)) FatalGui::openWithResultCode("sysclkIpcSetProfiles", rc);
});
this->listElement->addItem(bar);
}
}
};
void AppProfileGui::addGovernorSection(SysClkProfile profile) {
auto* item = new tsl::elm::ListItem("Governor");
item->setValue("\u2192"); // Right arrow
item->setClickListener([this, profile](u64 keys) {
if (keys & HidNpadButton_A) {
tsl::changeTo<GovernorProfileSubMenuGui>(
this->applicationId, this->profileList, profile
);
return true;
}
return false;
});
this->listElement->addItem(item);
}
void AppProfileGui::addProfileUI(SysClkProfile profile)
{
BaseMenuGui::refresh();
if(!this->context)
return;
Result rc = sysclkIpcGetConfigValues(&configList);
if (R_FAILED(rc)) [[unlikely]] {
FatalGui::openWithResultCode("sysclkIpcGetConfigValues", rc);
return;
}
if((profile == SysClkProfile_Docked && IsHoag()) || profile == SysClkProfile_HandheldCharging)
return;
this->listElement->addItem(new tsl::elm::CategoryHeader(sysclkFormatProfile(profile, true) + std::string(" ") + ult::DIVIDER_SYMBOL + " \ue0e3 Reset"));
this->addModuleListItem(profile, SysClkModule_CPU);
this->addModuleListItem(profile, SysClkModule_GPU);
this->addModuleListItem(profile, SysClkModule_MEM);
#if IS_MINIMAL == 0
ValueThresholds lcdThresholds(60, 65);
ValueThresholds DThresholdsOLED(120, 500); // nothing is dangerous, past 120hz you can get applet crashes
if(configList.values[HorizonOCConfigValue_OverwriteRefreshRate]) {
if(profile != SysClkProfile_Docked) {
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", IsAula() ? 45 : 40, configList.values[HorizonOCConfigValue_MaxDisplayClockH], this->context->isUsingRetroSuper ? 5 : 1, " Hz", 1, 0, lcdThresholds);
} else {
if(IsAula() && this->context->isSysDockInstalled) {
std::vector<NamedValue> dockedFreqs = {
NamedValue("40 Hz", 40),
NamedValue("45 Hz", 45),
NamedValue("50 Hz", 50),
NamedValue("55 Hz", 55),
NamedValue("60 Hz", 60),
NamedValue("70 Hz", 70),
NamedValue("72 Hz", 72),
NamedValue("75 Hz", 75),
NamedValue("80 Hz", 80),
NamedValue("90 Hz", 90),
NamedValue("95 Hz", 95),
NamedValue("100 Hz", 100),
NamedValue("110 Hz", 110),
NamedValue("120 Hz", 120),
NamedValue("130 Hz", 130),
NamedValue("140 Hz", 140),
NamedValue("144 Hz", 144),
NamedValue("150 Hz", 150),
NamedValue("160 Hz", 160),
NamedValue("165 Hz", 165),
NamedValue("170 Hz", 170),
NamedValue("180 Hz", 180),
NamedValue("190 Hz", 190),
NamedValue("200 Hz", 200),
NamedValue("210 Hz", 210),
NamedValue("220 Hz", 220),
NamedValue("230 Hz", 230),
NamedValue("240 Hz", 240)
};
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 40, 240, 1, " Hz", 1, 0, DThresholdsOLED, dockedFreqs);
} else if (IsAula() && !this->context->isSysDockInstalled) {
std::vector<NamedValue> dockedFreqsLimited = {
NamedValue("50 Hz", 50),
NamedValue("55 Hz", 55),
NamedValue("60 Hz", 60),
NamedValue("65 Hz", 65),
NamedValue("70 Hz", 70),
NamedValue("72 Hz", 72),
NamedValue("75 Hz", 75)
};
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 50, 75, 1, " Hz", 1, 0, DThresholdsOLED, dockedFreqsLimited);
} else {
std::vector<NamedValue> dockedFreqsStandard = {
NamedValue("50 Hz", 50),
NamedValue("55 Hz", 55),
NamedValue("60 Hz", 60),
NamedValue("65 Hz", 65),
NamedValue("70 Hz", 70),
NamedValue("72 Hz", 72),
NamedValue("75 Hz", 75),
NamedValue("80 Hz", 80),
NamedValue("85 Hz", 85),
NamedValue("90 Hz", 90),
NamedValue("95 Hz", 95),
NamedValue("100 Hz", 100),
NamedValue("105 Hz", 105),
NamedValue("110 Hz", 110),
NamedValue("115 Hz", 115),
NamedValue("120 Hz", 120)
};
this->addModuleListItemValue(profile, HorizonOCModule_Display, "Display", 50, 120, 1, " Hz", 1, 0, ValueThresholds(), dockedFreqsStandard);
}
}
}
#endif
this->addGovernorSection(profile);
}
void AppProfileGui::listUI()
{
this->addProfileUI(SysClkProfile_Docked);
this->addProfileUI(SysClkProfile_Handheld);
this->addProfileUI(SysClkProfile_HandheldCharging);
this->addProfileUI(SysClkProfile_HandheldChargingOfficial);
this->addProfileUI(SysClkProfile_HandheldChargingUSB);
}
void AppProfileGui::changeTo(std::uint64_t applicationId)
{
SysClkTitleProfileList* profileList = new SysClkTitleProfileList;
Result rc = sysclkIpcGetProfiles(applicationId, profileList);
if(R_FAILED(rc))
{
delete profileList;
FatalGui::openWithResultCode("sysclkIpcGetProfiles", rc);
return;
}
tsl::changeTo<AppProfileGui>(applicationId, profileList);
}
void AppProfileGui::update()
{
BaseMenuGui::update();
if((this->context && this->applicationId != this->context->applicationId) && this->applicationId != SYSCLK_GLOBAL_PROFILE_TID)
{
tsl::changeTo<FatalGui>(
"Application changed\n\n"
"\n"
"The running application changed\n\n"
"while editing was going on.",
""
);
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 "../../ipc.h"
#include "base_menu_gui.h"
#include "freq_choice_gui.h"
#include "value_choice_gui.h"
#define SYSCLK_GLOBAL_PROFILE_TID 0xA111111111111111
class AppProfileGui : public BaseMenuGui
{
protected:
std::uint64_t applicationId;
SysClkTitleProfileList* profileList;
void openFreqChoiceGui(tsl::elm::ListItem* listItem, SysClkProfile profile, SysClkModule module);
void addModuleListItem(SysClkProfile profile, SysClkModule module);
void addModuleListItemToggle(SysClkProfile profile, SysClkModule module);
void openValueChoiceGui(
tsl::elm::ListItem* listItem,
std::uint32_t currentValue,
const ValueRange& range,
const std::string& categoryName,
ValueChoiceListener listener,
const ValueThresholds& thresholds = ValueThresholds(),
bool enableThresholds = false,
const std::map<std::uint32_t, std::string>& labels = {},
const std::vector<NamedValue>& namedValues = {},
bool showDefaultValue = true
);
std::string formatValueDisplay(
std::uint32_t value,
const std::vector<NamedValue>& namedValues,
const std::string& suffix,
std::uint32_t divisor,
int decimalPlaces
);
void addModuleListItemValue(
SysClkProfile profile,
SysClkModule module,
const std::string& categoryName,
std::uint32_t min,
std::uint32_t max,
std::uint32_t step,
const std::string& suffix,
std::uint32_t divisor,
int decimalPlaces,
ValueThresholds thresholds,
std::vector<NamedValue> namedValues = {},
bool showDefaultValue = true
);
void addGovernorSection(SysClkProfile profile);
void addProfileUI(SysClkProfile profile);
public:
AppProfileGui(std::uint64_t applicationId, SysClkTitleProfileList* profileList);
~AppProfileGui();
void listUI() override;
static void changeTo(std::uint64_t applicationId);
void update() override;
};

View File

@@ -0,0 +1,144 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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_gui.h"
#include "../elements/base_frame.h"
#include <tesla.hpp>
#include <math.h>
#define LOGO_X 20
#define LOGO_Y 50
#define LOGO_LABEL_FONT_SIZE 45
#define VERSION_X (LOGO_X + 250)
#define VERSION_Y (LOGO_Y - 40)
#define VERSION_FONT_SIZE 15
std::string getVersionString() {
char buf[0x100] = "";
Result rc = sysclkIpcGetVersionString(buf, sizeof(buf));
if (R_FAILED(rc) || buf[0] == '\0') {
return "Unknown";
}
return std::string(buf);
}
static constexpr tsl::Color dynamicLogoRGB1 = tsl::Color(0, 4, 8, 15);
static constexpr tsl::Color dynamicLogoRGB2 = tsl::Color(7, 15, 15, 15);
static constexpr tsl::Color STATIC_AQUA = tsl::Color(2, 10, 12, 15);
const std::string name = "Horizon OC Zeus";
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;
s32 currentX = startX;
const u64 currentTime_ns = armTicksToNs(armGetSystemTick());
const double timeNow = static_cast<double>(currentTime_ns) / 1e9;
const double timeBase = fmod(timeNow, cycleDuration);
const double waveScale = 2.0 * M_PI / cycleDuration;
for (size_t i = 0; i < name.size(); i++)
{
char letter = name[i];
if (letter == '\0') break;
double phase = waveScale * (timeBase + i * 0.12);
double raw = cos(phase);
double n = (raw + 1.0) * 0.5;
double s1 = n * n * (3.0 - 2.0 * n);
double blend = std::clamp(s1, 0.0, 1.0);
double glow = (cos(phase * 1.5) + 1.0) * 0.5;
double brightness = 0.75 + glow * 0.25;
u8 r = static_cast<u8>(
(dynamicLogoRGB1.r + (dynamicLogoRGB2.r - dynamicLogoRGB1.r) * blend) * brightness
);
u8 g = static_cast<u8>(
(dynamicLogoRGB1.g + (dynamicLogoRGB2.g - dynamicLogoRGB1.g) * blend) * brightness
);
u8 b = static_cast<u8>(
(dynamicLogoRGB1.b + (dynamicLogoRGB2.b - dynamicLogoRGB1.b) * blend) * brightness
);
r = std::clamp<u8>(r, 0, 15);
g = std::clamp<u8>(g, 0, 15);
b = std::clamp<u8>(b, 0, 15);
bool lightning = (fmod(timeNow, 5.0) < 0.15);
if (lightning) {
r = std::min<u8>(r + 4, 15);
g = std::min<u8>(g + 4, 15);
b = std::min<u8>(b + 15, 15);
}
tsl::Color color(r, g, b, 15);
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;
}
void BaseGui::preDraw(tsl::gfx::Renderer* renderer) {
drawDynamicUltraText(
renderer,
LOGO_X,
LOGO_Y,
LOGO_LABEL_FONT_SIZE,
STATIC_AQUA,
false
);
}
tsl::elm::Element* BaseGui::createUI()
{
BaseFrame* rootFrame = new BaseFrame(this);
rootFrame->setContent(this->baseUI());
return rootFrame;
}
void BaseGui::update()
{
this->refresh();
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 <tesla.hpp>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include "../style.h"
#include "../../ipc.h"
class BaseGui : public tsl::Gui
{
public:
BaseGui() {}
~BaseGui() {}
virtual void preDraw(tsl::gfx::Renderer* renderer);
void update() override;
tsl::elm::Element* createUI() override;
virtual tsl::elm::Element* baseUI() = 0;
virtual void refresh() {}
private:
};
extern std::string getVersionString();

View File

@@ -0,0 +1,323 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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() : tempColors{ tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), }
{
tsl::initializeThemeVars();
this->context = nullptr;
this->lastContextUpdate = 0;
this->listElement = nullptr;
// Pre-cache hardware model during initialization
IsAula();
IsMariko();
IsHoag();
// 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", "BAT", "PMIC", "FAN", "DISP", "FPS", "RES"
};
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("USB Charger", false, SMALL_TEXT_SIZE).first; // longest word
u32 y = 91;
// === TOP SECTION ===
renderer->drawRoundedRect(14, 70-1, 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);
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 += 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, 420, 136, 12.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);
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
// 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 += 20; // Direct assignment (129 + 20)
renderer->drawString(displayStrings[19], false, positions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU Usage
renderer->drawString(displayStrings[17], false, positions[3], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU Usage
if(configList.values[HorizonOCConfigValue_RAMVoltUsageDisplayMode] == RamDisplayMode_VDD2Usage || configList.values[HorizonOCConfigValue_RAMVoltUsageDisplayMode] == RamDisplayMode_VDDQUsage)
renderer->drawString(displayStrings[18], false, positions[4], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // RAM Usage
// === REAL FREQUENCIES ===
// 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
renderer->drawStringWithColoredSections(displayStrings[10], false, {""}, configList.values[HorizonOCConfigValue_RAMVoltUsageDisplayMode] == RamDisplayMode_VDD2VDDQ ? dataPositions[5]-16 : dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor, tsl::separatorColor);
y += 22; // 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[SysClkThermalSensor_SOC]); // SOC
renderer->drawString(displayStrings[12], false, dataPositions[1], y, SMALL_TEXT_SIZE, tempColors[SysClkThermalSensor_PCB]); // PCB
renderer->drawString(displayStrings[13], false, dataPositions[2], y, SMALL_TEXT_SIZE, tempColors[SysClkThermalSensor_Skin]); // Skin
y += 20; // Direct assignment (191 + 20)
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+=20;
renderer->drawString(labels[10], false, positions[2], y, SMALL_TEXT_SIZE, tsl::sectionTextColor);
renderer->drawString(displayStrings[20], false, dataPositions[0], y, SMALL_TEXT_SIZE, tempColors[HorizonOCThermalSensor_Battery]); // Battery
renderer->drawString(labels[13], false, positions[4], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // disp label
renderer->drawString(displayStrings[25], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // disp freq
renderer->drawString(labels[12], false, positions[3], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // fan label
renderer->drawString(displayStrings[24], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // fan speed
y+=20;
renderer->drawString(displayStrings[21], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Bat voltage
renderer->drawString(displayStrings[23], false, positions[2] - 2, y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Bat Age
if(this->context->isSaltyNXInstalled) {
renderer->drawString(labels[15], false, positions[3], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // RES label
renderer->drawString(displayStrings[27], false, dataPositions[1], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // RES
renderer->drawString(labels[14], false, positions[4], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // FPS label
renderer->drawString(displayStrings[26], false, dataPositions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // FPS
}
y+=20;
}
// 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;
}
// === SYSCLK CONTEXT UPDATE ===
Result rc = sysclkIpcGetCurrentContext(this->context);
if (R_FAILED(rc)) [[unlikely]] {
FatalGui::openWithResultCode("sysclkIpcGetCurrentContext", rc);
return;
}
rc = sysclkIpcGetConfigValues(&configList);
if (R_FAILED(rc)) [[unlikely]] {
FatalGui::openWithResultCode("sysclkIpcGetConfigValues", rc);
return;
}
// dockedHighestAllowedRefreshRate = this->context->maxDisplayFreq;
// === 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[SysClkModule_CPU]; // CPU
sprintf(displayStrings[2], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
hz = context->freqs[SysClkModule_GPU]; // GPU
sprintf(displayStrings[3], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
hz = context->freqs[SysClkModule_MEM]; // MEM
sprintf(displayStrings[4], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
// Real frequencies
hz = context->realFreqs[SysClkModule_CPU]; // CPU
sprintf(displayStrings[5], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
hz = context->realFreqs[SysClkModule_GPU]; // GPU
sprintf(displayStrings[6], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
hz = context->realFreqs[SysClkModule_MEM]; // MEM
sprintf(displayStrings[7], "%u.%u MHz", hz / 1000000U, (hz / 100000U) % 10U);
// Voltages
sprintf(displayStrings[8], "%.1f mV", context->voltages[HocClkVoltage_CPU] / 1000.0);
sprintf(displayStrings[9], "%.1f mV", context->voltages[HocClkVoltage_GPU] / 1000.0);
switch(configList.values[HorizonOCConfigValue_RAMVoltUsageDisplayMode]) {
case RamDisplayMode_VDD2VDDQ:
sprintf(displayStrings[10], "%u.%u%u mV", context->voltages[HocClkVoltage_EMCVDD2] / 1000U, (context->voltages[HocClkVoltage_EMCVDD2] % 1000U) / 100U, context->voltages[HocClkVoltage_EMCVDDQ_MarikoOnly] / 1000U);
break;
case RamDisplayMode_VDD2Usage:
sprintf(displayStrings[10], "%u.%u mV", context->voltages[HocClkVoltage_EMCVDD2] / 1000U, (context->voltages[HocClkVoltage_EMCVDD2] % 1000U) / 100U);
break;
case RamDisplayMode_VDDQUsage:
sprintf(displayStrings[10], "%u.%u mV", context->voltages[HocClkVoltage_EMCVDDQ_MarikoOnly] / 1000U, (context->voltages[HocClkVoltage_EMCVDDQ_MarikoOnly] % 1000U) / 100U);
break;
default:
strcpy(displayStrings[10], "N/A");
break;
}
// Temperatures and pre-compute colors
u32 millis = context->temps[SysClkThermalSensor_SOC]; // SOC
sprintf(displayStrings[11], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U);
tempColors[SysClkThermalSensor_SOC] = tsl::GradientColor(millis * 0.001f);
millis = context->temps[SysClkThermalSensor_PCB]; // PCB
sprintf(displayStrings[12], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U);
tempColors[SysClkThermalSensor_PCB] = tsl::GradientColor(millis * 0.001f);
millis = context->temps[SysClkThermalSensor_Skin]; // Skin
sprintf(displayStrings[13], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U);
tempColors[SysClkThermalSensor_Skin] = tsl::GradientColor(millis * 0.001f);
// SOC voltage (if available)
sprintf(displayStrings[14], "%u mV", context->voltages[HocClkVoltage_SOC] / 1000U);
// Power
sprintf(displayStrings[15], "%d mW", context->power[0]); // Now
sprintf(displayStrings[16], "%d mW", context->power[1]); // Avg
sprintf(displayStrings[17], "%u%%", context->partLoad[HocClkPartLoad_GPU] / 10);
sprintf(displayStrings[18], "%u%%", context->partLoad[SysClkPartLoad_EMC] / 10);
sprintf(displayStrings[19], "%u%%", context->partLoad[HocClkPartLoad_CPUMax] / 10);
millis = context->temps[HorizonOCThermalSensor_Battery]; // Battery
sprintf(displayStrings[20], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U);
tempColors[HorizonOCThermalSensor_Battery] = tsl::GradientColor(millis * 0.001f);
sprintf(displayStrings[21], "%d mV", context->voltages[HocClkVoltage_Battery]); // BAT AVG
sprintf(displayStrings[23], "%u%%", context->partLoad[HocClkPartLoad_BAT] / 1000);
sprintf(displayStrings[24], "%u%%", context->partLoad[HocClkPartLoad_FAN]);
sprintf(displayStrings[25], "%u Hz", context->realFreqs[HorizonOCModule_Display]);
if(this->context->isSaltyNXInstalled) {
if(context->fps == 254) {
strcpy(displayStrings[26], "N/A");
} else {
memset(displayStrings[26], 0, sizeof(displayStrings[26]));
sprintf(displayStrings[26], "%u", context->fps);
}
}
if(this->context->isSaltyNXInstalled) {
if(context->resolutionHeight == 0) {
strcpy(displayStrings[27], "N/A");
} else {
memset(displayStrings[27], 0, sizeof(displayStrings[27]));
sprintf(displayStrings[27], "%up", context->resolutionHeight);
}
}
}
tsl::elm::Element* BaseMenuGui::baseUI()
{
auto* list = new tsl::elm::List();
list->addItem(new tsl::elm::CustomDrawer([](tsl::gfx::Renderer*, s32, s32, s32, s32) {}), 10); // add a bit of space
this->listElement = list;
this->listUI();
return list;
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 "../../ipc.h"
#include "base_gui.h"
class BaseMenuGui : public BaseGui
{
protected:
public:
// u8 dockedHighestAllowedRefreshRate = 60;
SysClkContext* context;
std::uint64_t lastContextUpdate;
SysClkConfigValueList configList;
bool g_hardwareModelCached = false;
bool g_isMariko = false;
bool g_isAula = false;
bool g_isHoag = false;
SetSysProductModel HWmodel = SetSysProductModel_Invalid;
bool IsAula() {
if (!g_hardwareModelCached) {
setsysGetProductModel(&HWmodel);
g_hardwareModelCached = true;
}
g_isAula = (HWmodel == SetSysProductModel_Aula);
return g_isAula;
}
bool IsHoag() {
if (!g_hardwareModelCached) {
setsysGetProductModel(&HWmodel);
g_hardwareModelCached = true;
}
g_isHoag = (HWmodel == SetSysProductModel_Hoag);
return g_isHoag;
}
bool IsMariko() {
if (!g_hardwareModelCached) {
setsysGetProductModel(&HWmodel);
g_hardwareModelCached = true;
}
g_isMariko = (HWmodel == SetSysProductModel_Iowa ||
HWmodel == SetSysProductModel_Hoag ||
HWmodel == SetSysProductModel_Calcio ||
HWmodel == SetSysProductModel_Aula);
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[7]; // Pre-computed temperature colors
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,84 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 "fatal_gui.h"
FatalGui::FatalGui(const std::string message, const std::string info)
{
this->message = message;
this->info = info;
}
void FatalGui::openWithResultCode(std::string tag, Result rc)
{
char rcStr[32];
std::string info = tag;
info.append(rcStr, snprintf(rcStr, sizeof(rcStr), "\n\n[0x%x] %04d-%04d", rc, R_MODULE(rc), R_DESCRIPTION(rc)));
tsl::changeTo<FatalGui>(
"Could not connect to hoc-clk sysmodule.\n\n"
"\n"
"Please make sure everything is\n\n"
"correctly installed and enabled.",
info
);
}
tsl::elm::Element* FatalGui::baseUI()
{
tsl::elm::CustomDrawer* drawer = new tsl::elm::CustomDrawer([this](tsl::gfx::Renderer* renderer, u16 x, u16 y, u16 w, u16 h) {
renderer->drawString("\uE150", false, 40, 210, 40, TEXT_COLOR);
renderer->drawString("Fatal error", false, 100, 210, 30, TEXT_COLOR);
std::uint32_t txtY = 255;
if(!this->message.empty())
{
txtY += renderer->drawString(this->message.c_str(), false, 40, txtY, 23, TEXT_COLOR).second;
txtY += 55;
}
if(!this->info.empty())
{
renderer->drawString(this->info.c_str(), false, 40, txtY, 18, DESC_COLOR);
}
});
return drawer;
}
bool FatalGui::handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight)
{
if((keysDown & HidNpadButton_A) == HidNpadButton_A || (keysDown & HidNpadButton_B) == HidNpadButton_B)
{
while(tsl::Overlay::get()->getCurrentGui() != nullptr) {
tsl::goBack();
}
return true;
}
return false;
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 <list>
#include "base_gui.h"
class FatalGui : public BaseGui
{
protected:
std::string message;
std::string info;
public:
FatalGui(const std::string message, const std::string info);
~FatalGui() {}
tsl::elm::Element* baseUI() override;
bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight);
static void openWithResultCode(std::string tag, Result rc);
};

View File

@@ -0,0 +1,219 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 "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;
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);
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);
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() && !selected)
listItem->setValueColor(tsl::Color(180, 180, 180, 255));
else if(selected)
listItem->setValueColor(tsl::infoTextColor);
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;
// // if (moduleName == "gpu" &&
// // this->configList->values[HocClkConfigValue_MarikoMaxGpuClock] < mhz)
// // continue;
// // if (moduleName == "mem" &&
// // this->configList->values[HocClkConfigValue_MarikoMaxMemClock] < mhz)
// // continue;
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;
uint32_t unsafe_cpu;
uint32_t unsafe_gpu;
uint32_t danger_cpu;
uint32_t danger_gpu;
if (IsMariko())
{
unsafe_cpu = this->configList->values[KipConfigValue_marikoCpuUVHigh] ? 2398 : 1964;
if(this->configList->values[KipConfigValue_marikoGpuUV] == 0) {
unsafe_gpu = 1076;
} else if (this->configList->values[KipConfigValue_marikoGpuUV] == 1) {
unsafe_gpu = 1153;
} else {
unsafe_gpu = 1229;
}
danger_cpu = this->configList->values[KipConfigValue_marikoCpuUVHigh] ? 2500 : 2398;
danger_gpu = 1306;
}
else
{
unsafe_cpu = this->configList->values[KipConfigValue_eristaCpuUV] ? 2092 : 1786;
if(this->configList->values[KipConfigValue_eristaGpuUV] == 0) {
unsafe_gpu = 922;
} else {
unsafe_gpu = 961;
}
danger_cpu = this->configList->values[KipConfigValue_eristaCpuUV] ? 2194 : 1964;
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("", "");
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 <list>
#include <functional>
#include <map>
#include "base_menu_gui.h"
using FreqChoiceListener = std::function<bool(std::uint32_t hz)>;
class FreqChoiceGui : public BaseMenuGui
{
protected:
SysClkConfigValueList* configList;
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;
tsl::elm::ListItem* createFreqListItem(std::uint32_t hz, bool selected, int safety);
public:
FreqChoiceGui(std::uint32_t selectedHz,
std::uint32_t* hzList,
std::uint32_t hzCount,
SysClkModule module,
FreqChoiceListener listener,
bool checkMax = true,
std::map<uint32_t, std::string> labels = {});
~FreqChoiceGui();
void listUI() override;
};

View File

@@ -0,0 +1,418 @@
/*
*
* Copyright (c) Souldbminer and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "../format.h"
#include "fatal_gui.h"
#include "global_override_gui.h"
#include "value_choice_gui.h"
#include "labels.h"
GlobalOverrideGui::GlobalOverrideGui()
{
for (std::uint16_t m = 0; m < SysClkModule_EnumMax; m++) {
this->listItems[m] = nullptr;
this->listHz[m] = 0;
}
}
void GlobalOverrideGui::openFreqChoiceGui(SysClkModule module)
{
std::uint32_t hzList[SYSCLK_FREQ_LIST_MAX];
std::uint32_t hzCount;
Result rc =
sysclkIpcGetFreqList(module, &hzList[0], SYSCLK_FREQ_LIST_MAX, &hzCount);
if (R_FAILED(rc)) {
FatalGui::openWithResultCode("sysclkIpcGetFreqList", rc);
return;
}
std::map<uint32_t, std::string> labels = {};
if (module == SysClkModule_CPU) {
bool isUsingUv = IsMariko() ? configList.values[KipConfigValue_marikoCpuUVHigh] : configList.values[KipConfigValue_eristaCpuUV];
labels = IsMariko() ? (isUsingUv ? cpu_freq_label_m_uv : cpu_freq_label_m) : (isUsingUv ? cpu_freq_label_e_uv : cpu_freq_label_e);
} else if (module == SysClkModule_GPU) {
labels = IsMariko() ? *(marikoUV[configList.values[KipConfigValue_marikoGpuUV]]) : *(eristaUV[configList.values[KipConfigValue_eristaGpuUV]]);
}
tsl::changeTo<FreqChoiceGui>(
this->context->overrideFreqs[module], hzList, hzCount, module,
[this, module](std::uint32_t hz) {
Result rc = sysclkIpcSetOverride(module, hz);
if (R_FAILED(rc)) {
FatalGui::openWithResultCode("sysclkIpcSetOverride", rc);
return false;
}
this->lastContextUpdate = armGetSystemTick();
this->context->overrideFreqs[module] = hz;
return true;
},
true, labels
);
}
void GlobalOverrideGui::openValueChoiceGui(
tsl::elm::ListItem* listItem,
std::uint32_t currentValue,
const ValueRange& range,
const std::string& categoryName,
ValueChoiceListener listener,
const ValueThresholds& thresholds,
bool enableThresholds,
const std::map<std::uint32_t, std::string>& labels,
const std::vector<NamedValue>& namedValues,
bool showDefaultValue
)
{
tsl::changeTo<ValueChoiceGui>(
currentValue,
range,
categoryName,
listener,
thresholds,
enableThresholds,
labels,
namedValues,
showDefaultValue,
true
);
}
void GlobalOverrideGui::addModuleListItemValue(
SysClkModule module,
const std::string& categoryName,
std::uint32_t min,
std::uint32_t max,
std::uint32_t step,
const std::string& suffix,
std::uint32_t divisor,
int decimalPlaces,
ValueThresholds thresholds,
const std::vector<NamedValue>& namedValues,
bool showDefaultValue
)
{
bool hasNamedValues = !namedValues.empty();
if (!hasNamedValues) {
this->customFormatModules[module] = std::make_tuple(suffix, divisor, decimalPlaces);
}
tsl::elm::ListItem* listItem =
new tsl::elm::ListItem(sysclkFormatModule(module, true));
listItem->setValue(FREQ_DEFAULT_TEXT);
listItem->setClickListener(
[this,
listItem,
module,
categoryName,
min,
max,
step,
suffix,
divisor,
decimalPlaces,
thresholds,
namedValues,
hasNamedValues,
showDefaultValue](u64 keys)
{
if ((keys & HidNpadButton_A) == HidNpadButton_A)
{
if (!this->context) {
return false;
}
std::uint32_t currentValue =
this->context->overrideFreqs[module] * divisor;
ValueRange range(
min,
max,
step,
suffix,
divisor,
decimalPlaces
);
this->openValueChoiceGui(
listItem,
currentValue,
range,
categoryName,
[this, listItem, module, divisor, suffix, decimalPlaces, thresholds, namedValues, hasNamedValues, showDefaultValue](std::uint32_t value) -> bool
{
if (!this->context) {
return false;
}
this->context->overrideFreqs[module] = value / divisor;
this->listHz[module] = value / divisor;
if (value == 0) {
listItem->setValue(FREQ_DEFAULT_TEXT);
} else if (hasNamedValues) {
for (const auto& namedValue : namedValues) {
if (namedValue.value == value / divisor) {
listItem->setValue(namedValue.name);
break;
}
}
} else {
char buf[32];
if (decimalPlaces > 0) {
double displayValue = (double)value / divisor;
snprintf(buf, sizeof(buf), "%.*f%s",
decimalPlaces, displayValue, suffix.c_str());
} else {
snprintf(buf, sizeof(buf), "%u%s",
value / divisor, suffix.c_str());
}
listItem->setValue(buf);
}
Result rc =
sysclkIpcSetOverride(module, this->context->overrideFreqs[module]);
if (R_FAILED(rc))
{
FatalGui::openWithResultCode(
"sysclkIpcSetOverride", rc);
return false;
}
this->lastContextUpdate = armGetSystemTick();
return true;
},
thresholds,
false,
std::map<std::uint32_t, std::string>(),
namedValues,
showDefaultValue
);
return true;
}
else if ((keys & HidNpadButton_Y) == HidNpadButton_Y)
{
if (!this->context) {
return false;
}
this->context->overrideFreqs[module] = 0;
this->listHz[module] = 0;
listItem->setValue(FREQ_DEFAULT_TEXT);
Result rc = sysclkIpcSetOverride(module, 0);
if (R_FAILED(rc))
{
FatalGui::openWithResultCode("sysclkIpcSetOverride", rc);
return false;
}
this->lastContextUpdate = armGetSystemTick();
return true;
}
return false;
});
this->listElement->addItem(listItem);
this->listItems[module] = listItem;
}
void GlobalOverrideGui::addModuleListItem(SysClkModule module)
{
tsl::elm::ListItem *listItem =
new tsl::elm::ListItem(sysclkFormatModule(module, true));
listItem->setValue(formatListFreqMHz(0));
listItem->setClickListener([this, module](u64 keys) {
if ((keys & HidNpadButton_A) == HidNpadButton_A) {
this->openFreqChoiceGui(module);
return true;
} else if ((keys & HidNpadButton_Y) == HidNpadButton_Y) {
Result rc = sysclkIpcSetOverride(module, 0);
if (R_FAILED(rc)) {
FatalGui::openWithResultCode("sysclkIpcSetOverride", rc);
return false;
}
this->lastContextUpdate = armGetSystemTick();
this->context->overrideFreqs[module] = 0;
this->listHz[module] = 0;
this->listItems[module]->setValue(formatListFreqHz(0));
return true;
}
return false;
});
this->listElement->addItem(listItem);
this->listItems[module] = listItem;
}
void GlobalOverrideGui::addModuleToggleItem(SysClkModule module)
{
const char *moduleName = sysclkFormatModule(module, true);
bool isOn = this->listHz[module];
tsl::elm::ToggleListItem *toggle =
new tsl::elm::ToggleListItem(moduleName, isOn);
toggle->setStateChangedListener([this, module, toggle](bool state) {
Result rc = sysclkIpcSetOverride(module, state ? 1 : 0);
if (R_FAILED(rc)) {
FatalGui::openWithResultCode("sysclkIpcSetProfiles", rc);
}
this->lastContextUpdate = armGetSystemTick();
this->context->overrideFreqs[module] = 0;
this->listHz[module] = 0;
});
this->listElement->addItem(toggle);
this->listItems[module] = toggle;
}
class GovernorOverrideSubMenuGui : public BaseMenuGui {
u32 packed;
public:
GovernorOverrideSubMenuGui(u32 initialPacked) : packed(initialPacked) {}
void listUI() override {
Result rc = sysclkIpcGetConfigValues(&configList); // idk why this is needed, probably some refreshing issue
if (R_FAILED(rc)) [[unlikely]] {
FatalGui::openWithResultCode("sysclkIpcGetConfigValues", rc);
return;
}
this->listElement->addItem(new tsl::elm::CategoryHeader("Governor"));
static constexpr struct { const char* label; int shift; } kAll[] = {
{"CPU", 0}, {"GPU", 8}, {"VRR", 16}
};
int count = configList.values[HorizonOCConfigValue_OverwriteRefreshRate] ? 3 : 2;
for (int i = 0; i < count; i++) {
u8 cur = (this->packed >> kAll[i].shift) & 0xFF;
auto* bar = new tsl::elm::NamedStepTrackBar(
"", {"Do Not Override", "Disabled", "Enabled"},
true, kAll[i].label
);
bar->setProgress(cur);
int shift = kAll[i].shift;
bar->setValueChangedListener([this, shift](u8 value) {
this->packed = (this->packed & ~(0xFFu << shift)) | ((u32)value << shift);
Result rc = sysclkIpcSetOverride(HorizonOCModule_Governor, this->packed);
if (R_FAILED(rc)) FatalGui::openWithResultCode("sysclkIpcSetOverride", rc);
this->lastContextUpdate = armGetSystemTick();
});
this->listElement->addItem(bar);
}
}
};
void GlobalOverrideGui::addGovernorSection() {
auto* item = new tsl::elm::ListItem("Governor");
item->setValue("\u2192"); // right arrow
item->setClickListener([this](u64 keys) {
if (keys & HidNpadButton_A) {
u32 packed = this->context ? this->context->overrideFreqs[HorizonOCModule_Governor] : 0;
tsl::changeTo<GovernorOverrideSubMenuGui>(packed);
return true;
}
return false;
});
this->listElement->addItem(item);
}
void GlobalOverrideGui::listUI()
{
BaseMenuGui::refresh(); // get latest context
if(!this->context)
return;
Result rc = sysclkIpcGetConfigValues(&configList); // idk why this is needed, probably some refreshing issue
if (R_FAILED(rc)) [[unlikely]] {
FatalGui::openWithResultCode("sysclkIpcGetConfigValues", rc);
return;
}
this->listElement->addItem(new tsl::elm::CategoryHeader(
"Temporary Overrides " + ult::DIVIDER_SYMBOL + " \ue0e3 Reset"));
this->addModuleListItem(SysClkModule_CPU);
this->addModuleListItem(SysClkModule_GPU);
this->addModuleListItem(SysClkModule_MEM);
#if IS_MINIMAL == 0
ValueThresholds lcdThresholds(60, 65);
if(configList.values[HorizonOCConfigValue_OverwriteRefreshRate])
this->addModuleListItemValue(HorizonOCModule_Display, "Display", IsAula() ? 45 : 40, configList.values[HorizonOCConfigValue_MaxDisplayClockH], this->context->isUsingRetroSuper ? 5 : 1, " Hz", 1, 0, lcdThresholds);
#endif
this->addGovernorSection();
}
void GlobalOverrideGui::refresh()
{
BaseMenuGui::refresh();
if (!this->context)
return;
for (std::uint16_t m = 0; m < SysClkModule_EnumMax; m++) {
if (m == HorizonOCModule_Governor) {
this->listHz[m] = this->context->overrideFreqs[m];
continue;
}
if (this->listItems[m] != nullptr &&
this->listHz[m] != this->context->overrideFreqs[m]) {
auto it = this->customFormatModules.find((SysClkModule)m);
if (it != this->customFormatModules.end()) {
std::string suffix = std::get<0>(it->second);
std::uint32_t divisor = std::get<1>(it->second);
int decimalPlaces = std::get<2>(it->second);
if (this->context->overrideFreqs[m] == 0) {
this->listItems[m]->setValue(FREQ_DEFAULT_TEXT);
} else {
char buf[32];
if (decimalPlaces > 0) {
double displayValue = (double)this->context->overrideFreqs[m] / divisor;
snprintf(buf, sizeof(buf), "%.*f%s",
decimalPlaces, displayValue, suffix.c_str());
} else {
snprintf(buf, sizeof(buf), "%u%s",
this->context->overrideFreqs[m] / divisor, suffix.c_str());
}
this->listItems[m]->setValue(buf);
}
} else {
this->listItems[m]->setValue(
formatListFreqHz(this->context->overrideFreqs[m]));
}
this->listHz[m] = this->context->overrideFreqs[m];
}
}
}

View File

@@ -0,0 +1,74 @@
/*
*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 "../../ipc.h"
#include "base_menu_gui.h"
#include "freq_choice_gui.h"
#include <string>
#include "value_choice_gui.h"
class GlobalOverrideGui : public BaseMenuGui
{
protected:
std::map<SysClkModule, std::tuple<std::string, std::uint32_t, int>> customFormatModules;
tsl::elm::ListItem* listItems[SysClkModule_EnumMax];
std::uint32_t listHz[SysClkModule_EnumMax];
void openFreqChoiceGui(SysClkModule module);
void addGovernorSection();
void addModuleListItem(SysClkModule module);
void addModuleToggleItem(SysClkModule module);
void openValueChoiceGui(
tsl::elm::ListItem* listItem,
std::uint32_t currentValue,
const ValueRange& range,
const std::string& categoryName,
ValueChoiceListener listener,
const ValueThresholds& thresholds,
bool enableThresholds,
const std::map<std::uint32_t, std::string>& labels,
const std::vector<NamedValue>& namedValues,
bool showDefaultValue
);
void addModuleListItemValue(
SysClkModule module,
const std::string& categoryName,
std::uint32_t min,
std::uint32_t max,
std::uint32_t step,
const std::string& suffix,
std::uint32_t divisor,
int decimalPlaces,
ValueThresholds thresholds = {},
const std::vector<NamedValue>& namedValues = {},
bool showDefaultValue = true
);
public:
GlobalOverrideGui();
~GlobalOverrideGui() {}
void listUI() override;
void refresh() override;
void setModuleCustomFormat(SysClkModule module, const std::string& suffix, std::uint32_t divisor, int decimalPlaces);
};

View File

@@ -0,0 +1,134 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <map>
#include <cstdint>
#include <string>
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"},
{2703000000, "Absolute Max"},
};
std::map<uint32_t, std::string> cpu_freq_label_m_uv = {
{612000000, "Sleep Mode"},
{1020000000, "Stock"},
{1224000000, "Dev OC"},
{1785000000, "Boost Mode"},
{2397000000, "Safe Max"},
{2499000000, "Unsafe Max"},
{2703000000, "Absolute Max"},
};
std::map<uint32_t, std::string> cpu_freq_label_e = {
{612000000, "Sleep Mode"},
{1020000000, "Stock"},
{1224000000, "Dev OC"},
{1785000000, "Safe Max"},
{2091000000, "Unsafe Max"},
{2397000000, "Absolute Max"},
};
std::map<uint32_t, std::string> cpu_freq_label_e_uv = {
{612000000, "Sleep Mode"},
{1020000000, "Stock"},
{1224000000, "Dev OC"},
{1785000000, "Boost Mode"},
{2091000000, "Safe Max"},
{2193000000, "Unsafe Max"},
{2397000000, "Absolute Max"},
};
std::map<uint32_t, std::string> gpu_freq_label_e = {
{76800000, "Boost Mode"},
{307200000, "Handheld"},
{345600000, "Handheld"},
{384000000, "Handheld"},
{422400000, "Handheld"},
{460800000, "Handheld Safe Max"},
{768000000, "Docked"},
{921600000, "Safe Max"},
{960000000, "Unsafe Max"},
{1075200000, "Absolute Max"},
};
std::map<uint32_t, std::string> gpu_freq_label_e_uv = {
{76800000, "Boost Mode"},
{307200000, "Handheld"},
{345600000, "Handheld"},
{384000000, "Handheld"},
{422400000, "Handheld"},
{460800000, "Handheld Safe Max"},
{768000000, "Docked"},
{960000000, "Safe Max"},
{1075200000, "Absolute 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"},
{1075200000, "Safe Max"},
{1305600000, "Unsafe Max"},
{1536000000, "Absolute Max"},
};
std::map<uint32_t, std::string> gpu_freq_label_m_slt = {
{76800000, "Boost Mode"},
{307200000, "Handheld"},
{384000000, "Handheld"},
{460800000, "Handheld"},
{614400000, "Handheld Safe Max"},
{768000000, "Docked"},
{1152200000, "Safe Max"},
{1305600000, "Unsafe Max"},
{1536000000, "Absolute Max"},
};
std::map<uint32_t, std::string> gpu_freq_label_m_hiopt = {
{76800000, "Boost Mode"},
{307200000, "Handheld"},
{384000000, "Handheld"},
{460800000, "Handheld"},
{614400000, "Handheld Safe Max"},
{768000000, "Docked"},
{1228800000, "Safe Max"},
{1305600000, "Unsafe Max"},
{1536000000, "Absolute Max"},
};
std::map<uint32_t, std::string>* marikoUV[3] {
&gpu_freq_label_m,
&gpu_freq_label_m_slt,
&gpu_freq_label_m_hiopt,
};
std::map<uint32_t, std::string>* eristaUV[3] {
&gpu_freq_label_e,
&gpu_freq_label_e_uv,
&gpu_freq_label_e_uv,
};

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <map>
#include <cstdint>
#include <string>
extern std::map<uint32_t, std::string> cpu_freq_label_m;
extern std::map<uint32_t, std::string> cpu_freq_label_m_uv;
extern std::map<uint32_t, std::string> cpu_freq_label_e;
extern std::map<uint32_t, std::string> cpu_freq_label_e_uv;
extern std::map<uint32_t, std::string> gpu_freq_label_m;
extern std::map<uint32_t, std::string> gpu_freq_label_m_slt;
extern std::map<uint32_t, std::string> gpu_freq_label_m_hiopt;
extern std::map<uint32_t, std::string> gpu_freq_label_e;
extern std::map<uint32_t, std::string> gpu_freq_label_e_uv;
extern std::map<uint32_t, std::string>* marikoUV[3];
extern std::map<uint32_t, std::string>* eristaUV[3];

View File

@@ -0,0 +1,123 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 "main_gui.h"
#include "fatal_gui.h"
#include "app_profile_gui.h"
#include "global_override_gui.h"
#include "misc_gui.h"
#include "about_gui.h"
void MainGui::listUI()
{
// this->enabledToggle = new tsl::elm::ToggleListItem("Enable", false);
// enabledToggle->setStateChangedListener([this](bool state) {
// Result rc = sysclkIpcSetEnabled(state);
// if(R_FAILED(rc))
// {
// FatalGui::openWithResultCode("sysclkIpcSetEnabled", rc);
// }
// this->lastContextUpdate = armGetSystemTick();
// this->context->enabled = state;
// });
// this->listElement->addItem(this->enabledToggle);
tsl::elm::ListItem* appProfileItem = new tsl::elm::ListItem("Edit App Profile");
appProfileItem->setClickListener([this](u64 keys) {
if((keys & HidNpadButton_A) == HidNpadButton_A && this->context)
{
AppProfileGui::changeTo(this->context->applicationId);
return true;
}
return false;
});
this->listElement->addItem(appProfileItem);
tsl::elm::ListItem* globalProfileItem = new tsl::elm::ListItem("Edit Global Profile");
globalProfileItem->setClickListener([this](u64 keys) {
if((keys & HidNpadButton_A) == HidNpadButton_A && this->context)
{
AppProfileGui::changeTo(SYSCLK_GLOBAL_PROFILE_TID);
return true;
}
return false;
});
this->listElement->addItem(globalProfileItem);
tsl::elm::ListItem* globalOverrideItem = new tsl::elm::ListItem("Temporary Overrides");
globalOverrideItem->setClickListener([this](u64 keys) {
if((keys & HidNpadButton_A) == HidNpadButton_A && this->context)
{
tsl::changeTo<GlobalOverrideGui>();
return true;
}
return false;
});
this->listElement->addItem(globalOverrideItem);
//this->listElement->addItem(new tsl::elm::CategoryHeader("Misc"));
tsl::elm::ListItem* miscItem = new tsl::elm::ListItem("Settings");
miscItem->setClickListener([this](u64 keys) {
if((keys & HidNpadButton_A) == HidNpadButton_A && this->context)
{
tsl::changeTo<MiscGui>();
return true;
}
return false;
});
this->listElement->addItem(miscItem);
tsl::elm::ListItem* aboutItem = new tsl::elm::ListItem("About");
aboutItem->setClickListener([this](u64 keys) {
if((keys & HidNpadButton_A) == HidNpadButton_A && this->context)
{
tsl::changeTo<AboutGui>();
return true;
}
return false;
});
this->listElement->addItem(aboutItem);
}
void MainGui::refresh()
{
BaseMenuGui::refresh();
//if(this->context)
//{
// this->enabledToggle->setState(this->context->enabled);
//}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 "base_menu_gui.h"
class MainGui : public BaseMenuGui
{
public:
MainGui() {}
~MainGui() {}
void listUI() override;
void refresh() override;
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,72 @@
/*
*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../../ipc.h"
#include "base_menu_gui.h"
#include <set>
#include <unordered_map>
#include <string>
#include <vector>
#include "freq_choice_gui.h"
#include "value_choice_gui.h"
class MiscGui : public BaseMenuGui
{
public:
MiscGui();
~MiscGui();
void listUI() override;
void refresh() override;
protected:
SysClkConfigValueList* configList;
std::map<SysClkConfigValue, tsl::elm::ListItem*> configButtons;
std::map<SysClkConfigValue, ValueRange> configRanges;
std::map<SysClkConfigValue, std::vector<NamedValue>> configNamedValues;
std::map<SysClkConfigValue, tsl::elm::ToggleListItem*> configToggles;
std::map<SysClkConfigValue, std::tuple<tsl::elm::TrackBar*, tsl::elm::ListItem*, std::vector<uint64_t>>> configTrackbars;
std::set<SysClkConfigValue> configButtonSKeys;
std::map<SysClkConfigValue, std::string> configButtonSSubtext;
void addConfigToggle(SysClkConfigValue configVal, const char* altName);
void addConfigButton(SysClkConfigValue configVal,
const char* altName,
const ValueRange& range,
const std::string& categoryName,
const ValueThresholds* thresholds,
const std::map<uint32_t, std::string>& labels = {},
const std::vector<NamedValue>& namedValues = {},
bool showDefaultValue = true);
void addConfigButtonS(SysClkConfigValue configVal,
const char* altName,
const ValueRange& range,
const std::string& categoryName,
const ValueThresholds* thresholds,
const std::map<uint32_t, std::string>& labels = {},
const std::vector<NamedValue>& namedValues = {},
bool showDefaultValue = true,
const char* subText = nullptr);
void addFreqButton(SysClkConfigValue configVal,
const char* altName,
SysClkModule module,
const std::map<uint32_t, std::string>& labels = {});
void updateConfigToggles();
tsl::elm::ToggleListItem* enabledToggle;
u8 frameCounter = 60;
};

View File

@@ -0,0 +1,126 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <tesla.hpp>
class ImageElement : public tsl::elm::ListItem {
private:
const uint8_t* imgData;
uint32_t imgWidth, imgHeight;
bool visible;
public:
ImageElement(const uint8_t* data, uint32_t w, uint32_t h)
: tsl::elm::ListItem(""), imgData(data), imgWidth(w), imgHeight(h), visible(true) {}
void setVisible(bool v) {
visible = v;
}
virtual void draw(tsl::gfx::Renderer *renderer) override {
if (!visible) return;
// Draw image centered horizontally
u16 centerX = this->getX() + (this->getWidth() - imgWidth) / 2;
renderer->drawBitmap(
centerX,
this->getY() + 10,
imgWidth,
imgHeight,
imgData
);
}
virtual void layout(u16 parentX, u16 parentY, u16 parentWidth, u16 parentHeight) override {
if (!visible) {
// Take up no space when hidden
this->setBoundaries(parentX, parentY, 0, 0);
} else {
// Normal layout when visible
tsl::elm::ListItem::layout(parentX, parentY, parentWidth, parentHeight);
}
}
virtual void drawHighlight(tsl::gfx::Renderer *renderer) override {
// Do nothing - no highlight
}
virtual bool onClick(u64 keys) override {
return false; // Non-clickable
}
virtual Element* requestFocus(Element *oldFocus, tsl::FocusDirection direction) override {
return nullptr; // Make it non-focusable
}
};
class HideableCategoryHeader : public tsl::elm::CategoryHeader {
private:
bool visible;
public:
HideableCategoryHeader(const std::string& title)
: tsl::elm::CategoryHeader(title), visible(true) {}
void setVisible(bool v) {
visible = v;
}
virtual void draw(tsl::gfx::Renderer *renderer) override {
if (!visible) return;
tsl::elm::CategoryHeader::draw(renderer);
}
virtual void layout(u16 parentX, u16 parentY, u16 parentWidth, u16 parentHeight) override {
if (!visible) {
this->setBoundaries(parentX, parentY, 0, 0);
} else {
tsl::elm::CategoryHeader::layout(parentX, parentY, parentWidth, parentHeight);
}
}
};
class HideableCustomDrawer : public tsl::elm::Element {
private:
bool visible;
u32 height;
public:
HideableCustomDrawer(u32 h)
: Element(), visible(true), height(h) {}
void setVisible(bool v) {
visible = v;
}
virtual void draw(tsl::gfx::Renderer *renderer) override {
// Empty drawer - just for spacing
}
virtual void layout(u16 parentX, u16 parentY, u16 parentWidth, u16 parentHeight) override {
if (!visible) {
this->setBoundaries(parentX, parentY, 0, 0);
} else {
this->setBoundaries(parentX, parentY, parentWidth, height);
}
}
virtual Element* requestFocus(Element *oldFocus, tsl::FocusDirection direction) override {
return nullptr;
}
};

View File

@@ -0,0 +1,200 @@
/*
*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "value_choice_gui.h"
#include "../format.h"
#include "fatal_gui.h"
#include <sstream>
#include <iomanip>
ValueChoiceGui::ValueChoiceGui(std::uint32_t selectedValue,
const ValueRange& range,
const std::string& categoryName,
ValueChoiceListener listener,
const ValueThresholds& thresholds,
bool enableThresholds,
std::map<std::uint32_t, std::string> labels,
std::vector<NamedValue> namedValues,
bool showDefaultValue,
bool showDNO)
: selectedValue(selectedValue),
range(range),
categoryName(categoryName),
listener(listener),
thresholds(thresholds),
enableThresholds(enableThresholds),
labels(labels),
namedValues(namedValues),
showDefaultValue(showDefaultValue),
showDNO(showDNO)
{
}
ValueChoiceGui::~ValueChoiceGui()
{
}
std::string ValueChoiceGui::formatValue(std::uint32_t value)
{
std::ostringstream oss;
if(showDefaultValue) {
if (value == 0) {
return this->showDNO ? FREQ_DEFAULT_TEXT : VALUE_DEFAULT_TEXT;
}
}
double displayValue = static_cast<double>(value) / static_cast<double>(range.divisor);
oss << std::fixed << std::setprecision(range.decimalPlaces) << displayValue;
if (!range.suffix.empty()) {
oss << " " << range.suffix;
}
return oss.str();
}
int ValueChoiceGui::getSafetyLevel(std::uint32_t value)
{
if(thresholds.warning == 0 && thresholds.danger == 0) {
return 0;
}
if (value > thresholds.danger) {
return 2;
}
if (value > thresholds.warning) {
return 1;
}
return 0;
}
tsl::elm::ListItem* ValueChoiceGui::createValueListItem(std::uint32_t value, bool selected, int safety)
{
std::string text = formatValue(value);
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)
{
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() && !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) {
if (this->listener(value)) {
tsl::goBack();
}
return true;
}
return false;
});
return listItem;
}
tsl::elm::ListItem* ValueChoiceGui::createNamedValueListItem(const NamedValue& namedValue, bool selected, int safety)
{
std::string text = namedValue.name;
if (selected) {
const_cast<std::string&>(namedValue.rightText) = "\uE14B";
}
tsl::elm::ListItem* listItem = new tsl::elm::ListItem(text, namedValue.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;
}
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) {
if (this->listener(value)) {
tsl::goBack();
}
return true;
}
return false;
});
return listItem;
}
void ValueChoiceGui::listUI()
{
if (!categoryName.empty()) {
this->listElement->addItem(new tsl::elm::CategoryHeader(categoryName));
}
if (showDefaultValue) {
this->listElement->addItem(this->createValueListItem(0, this->selectedValue == 0, 0));
}
for (const auto& namedValue : namedValues) {
int safety = enableThresholds ? getSafetyLevel(namedValue.value) : 0;
bool selected = (namedValue.value == this->selectedValue);
this->listElement->addItem(this->createNamedValueListItem(namedValue, selected, safety));
}
if (namedValues.empty()) {
for (std::uint32_t value = range.min; value <= range.max; value += range.step)
{
int safety = getSafetyLevel(value);
bool selected = (value == this->selectedValue);
this->listElement->addItem(this->createValueListItem(value, selected, safety));
}
}
this->listElement->jumpToItem("", "\uE14B");
}

View File

@@ -0,0 +1,114 @@
/*
*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <list>
#include <functional>
#include <string>
#include <map>
#include <vector>
#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;
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) {}
};
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) {}
};
struct NamedValue {
std::string name;
std::uint32_t value;
std::string rightText;
NamedValue(const std::string& name, std::uint32_t value, const std::string& rightText = "")
: name(name), value(value), rightText(rightText) {}
};
class ValueChoiceGui : public BaseMenuGui
{
protected:
std::uint32_t selectedValue;
ValueRange range;
std::string categoryName;
ValueChoiceListener listener;
ValueThresholds thresholds;
bool enableThresholds;
std::map<std::uint32_t, std::string> labels;
std::vector<NamedValue> namedValues;
bool showDefaultValue = true;
bool showDNO = false;
tsl::elm::ListItem* createValueListItem(std::uint32_t value, bool selected, int safety);
tsl::elm::ListItem* createNamedValueListItem(const NamedValue& namedValue, 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 = {},
std::vector<NamedValue> namedValues = {},
bool showDefaultValue = true,
bool showDNO = false);
~ValueChoiceGui();
void addNamedValue(const std::string& name, std::uint32_t value, const std::string& rightText = "")
{
namedValues.emplace_back(name, value, rightText);
}
void addNamedValues(const std::vector<NamedValue>& values)
{
namedValues.insert(namedValues.end(), values.begin(), values.end());
}
void clearNamedValues()
{
namedValues.clear();
}
void setShowDefaultValue(bool show)
{
showDefaultValue = show;
}
void listUI() override;
};

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* 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>
* 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 <tesla.hpp>
#define TEXT_COLOR tsl::gfx::Renderer::a(0xFFFF)
#define DESC_COLOR tsl::gfx::Renderer::a({ 0xC, 0xC, 0xC, 0xF })
#define VALUE_COLOR tsl::gfx::Renderer::a({ 0x5, 0xC, 0xA, 0xF })
#define SMALL_TEXT_SIZE 15
#define LABEL_SPACING 7
#define LABEL_FONT_SIZE 15

2
Source/hoc-clk/sysmodule/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/out
/build

View File

@@ -0,0 +1,164 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
endif
TOPDIR ?= $(CURDIR)
include $(DEVKITPRO)/libnx/switch_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# DATA is a list of directories containing data files
# INCLUDES is a list of directories containing header files
# EXEFS_SRC is the optional input directory containing data copied into exefs, if anything this normally should only contain "main.npdm".
#---------------------------------------------------------------------------------
TARGET := horizon-oc
BUILD := build
OUTDIR := out
RESOURCES := res
SOURCES := src src/nx/ipc ../common/src src/board
DATA := data
INCLUDES := ../common/include
EXEFS_SRC := exefs_src
LIBNAMES := minIni nxExt
#---------------------------------------------------------------------------------
# version control constants
#---------------------------------------------------------------------------------
TARGET_VERSION := $(shell git describe --dirty --always --tags)
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
DEFINES := -DDISABLE_IPC -DTARGET="\"$(TARGET)\"" -DTARGET_VERSION="\"$(TARGET_VERSION)\""
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
CFLAGS := -g -Wall -Os -ffunction-sections \
$(ARCH) $(DEFINES)
CFLAGS += $(INCLUDE) -D__SWITCH__
CXXFLAGS := $(CFLAGS) -fno-rtti -std=gnu++17
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS := $(foreach lib,$(LIBNAMES),-l$(lib)) -lnx
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(PORTLIBS) $(LIBNX) $(foreach lib,$(LIBNAMES),$(TOPDIR)/lib/$(lib))
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(OUTDIR)/$(TARGET)
export TOPDIR := $(CURDIR)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC)
export APP_JSON := $(TOPDIR)/perms.json
.PHONY: $(BUILD) clean clean-libs clean-build all libs
#---------------------------------------------------------------------------------
all: $(BUILD)
libs:
@$(foreach lib,$(LIBNAMES),$(MAKE) --no-print-directory -C $(TOPDIR)/lib/$(lib) && ) true
$(LIBNAMES):
@echo $@
$(BUILD): libs
@[ -d $@ ] || mkdir -p $@
@[ -d $(OUTDIR) ] || mkdir -p $(OUTDIR)
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean-libs:
@echo clean libs $(LIBNAMES) ...
@$(foreach lib,$(LIBNAMES),$(MAKE) -C $(TOPDIR)/lib/$(lib) clean && ) true
clean-build:
@echo clean build ...
@rm -fr $(BUILD) $(TARGET).kip $(TARGET).nsp $(TARGET).npdm $(TARGET).nso $(TARGET).elf $(OUTDIR)
clean: clean-libs clean-build
#---------------------------------------------------------------------------------
else
.PHONY: all $(LIBFILES)
LIBFILES := $(foreach lib,$(LIBNAMES),$(TOPDIR)/lib/$(lib)/lib/lib$(lib).a)
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
all: $(OUTPUT).nsp
$(OUTPUT).nsp: $(OUTPUT).nso $(OUTPUT).npdm
$(OUTPUT).elf: $(OFILES) $(LIBFILES)
#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#---------------------------------------------------------------------------------
%.bin.o : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

View File

@@ -0,0 +1,13 @@
# Editor files
*.swp
*~
# Objects
*.o
*.a
*.so
# Lib
lib
release
debug

View File

@@ -0,0 +1,12 @@
; DO NOT EDIT (unless you know what you are doing)
;
; This subdirectory is a git "subrepo", and this file is maintained by the
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
;
[subrepo]
remote = https://github.com/compuphase/minIni
branch = master
commit = 8ce144c3c287fa4e59f8ed4c405cd8b7e29f189b
parent = f32c0b1bca87a6d7e55fb341f8db9ef33b13819f
method = merge
cmdver = 0.4.0

View File

@@ -0,0 +1,189 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
EXCEPTION TO THE APACHE 2.0 LICENSE
As a special exception to the Apache License 2.0 (and referring to the
definitions in Section 1 of this license), you may link, statically or
dynamically, the "Work" to other modules to produce an executable file
containing portions of the "Work", and distribute that executable file
in "Object" form under the terms of your choice, without any of the
additional requirements listed in Section 4 of the Apache License 2.0.
This exception applies only to redistributions in "Object" form (not
"Source" form) and only if no modifications have been made to the "Work".
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.

View File

@@ -0,0 +1,133 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
endif
include $(DEVKITPRO)/libnx/switch_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# SOURCES is a list of directories containing source code
# DATA is a list of directories containing data files
# INCLUDES is a list of directories containing header files
#---------------------------------------------------------------------------------
TARGET := $(notdir $(CURDIR))
SOURCES := dev
DATA := data
INCLUDES := dev
SRC_H_FILES :=
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIC -ftls-model=local-exec
CFLAGS := -g -Wall -Werror \
-ffunction-sections \
-fdata-sections \
$(ARCH) \
$(BUILD_CFLAGS)
CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH)
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(PORTLIBS) $(LIBNX)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
CFILES := minIni.c
CPPFILES :=
SFILES :=
BINFILES :=
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
.PHONY: clean all lib/lib$(TARGET).a
#---------------------------------------------------------------------------------
all: lib/lib$(TARGET).a
lib:
@[ -d $@ ] || mkdir -p $@
release:
@[ -d $@ ] || mkdir -p $@
debug:
@[ -d $@ ] || mkdir -p $@
lib/lib$(TARGET).a : lib release $(SOURCES) $(INCLUDES)
@$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \
BUILD_CFLAGS="-DNDEBUG=1 -O2" \
DEPSDIR=$(CURDIR)/release \
--no-print-directory -C release \
-f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr release debug lib
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT) : $(OFILES)
$(OFILES_SRC) : $(HFILES)
#---------------------------------------------------------------------------------
%_bin.h %.bin.o : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

View File

@@ -0,0 +1,12 @@
minIni is a programmer's library to read and write "INI" files in embedded
systems. The library takes little resources and can be configured for various
kinds of file I/O libraries.
The method for portable INI file management in minIni is, in part based, on the
article "Multiplatform .INI Files" by Joseph J. Graf in the March 1994 issue of
Dr. Dobb's Journal.
The C++ class in minIni.h was contributed by Steven Van Ingelgem.
The option to compile minIni as a read-only library was contributed by Luca
Bassanello.

View File

@@ -0,0 +1,170 @@
# minIni
minIni is a portable and configurable library for reading and writing ".INI" files. At 830 lines of commented source
code
(version 1.2), minIni truly is a "mini" INI file parser, especially considering its features.
The library does not require the file I/O functions from the standard C/C++ library, but instead lets you configure
the file I/O interface to use via macros. minIni uses limited stack space and does not use dynamic memory (malloc and
friends) at all.
Some minor variations on standard INI files are supported too, notably minIni supports INI files that lack sections.
# Acknowledgement
minIni is derived from an earlier INI file parser (which I wrote) for desktop systems.
In turn, that earlier parser was a re-write of the code from the article "Multiplatform .INI Files" by Joseph J. Graf
in the March 1994 issue of Dr. Dobb's Journal. In other words, minIni has its roots in the work of Joseph Graf (even
though the code has been almost completely re-written).
# Features
minIni is a programmer's library to read and write "INI" files in embedded systems. minIni takes little resources,
can be configured for various kinds of file I/O libraries and provides functionality for reading, writing and
deleting keys from an INI file.
Although the main feature of minIni is that it is small and minimal, it has a few other features:
* minIni supports reading keys that are outside a section, and it thereby supports configuration files that do not use sections (but that are otherwise compatible with INI files).
* You may use a colon to separate key and value; the colon is equivalent to the equal sign. That is, the strings "Name: Value" and "Name=Value" have the same meaning.
* The hash character ("#") is an alternative for the semicolon to start a comment. Trailing comments (i.e. behind a key/value pair on a line) are allowed.
* Leading and trailing white space around key names and values is ignored.
* When writing a value that contains a comment character (";" or "#"), that value will automatically be put between double quotes; when reading the value, these quotes are removed. When a double-quote itself appears in the setting, these characters are escaped.
* Section and key enumeration are supported.
* You can optionally set the line termination (for text files) that minIni will use. (This is a compile-time setting, not a run-time setting.)
* Since writing speed is much lower than reading speed in Flash memory (SD/MMC cards, USB memory sticks), minIni minimizes "file writes" at the expense of double "file reads".
* The memory footprint is deterministic. There is no dynamic memory allocation.
## INI file reading paradigms
There are two approaches to reading settings from an INI file. One way is to call a function, such as
GetProfileString() for every section and key that you need. This is especially convenient if there is a large
INI file, but you only need a few settings from that file at any time &mdash;especially if the INI file can also
change while your program runs. This is the approach that the Microsoft Windows API uses.
The above procedure is quite inefficient, however, when you need to retrieve quite a few settings in a row from
the INI file &mdash;especially if the INI file is not cached in memory (which it isn't, in minIni). A different approach
to getting settings from an INI file is to call a "parsing" function and let that function call the application
back with the section and key names plus the associated data. XML parsing libraries often use this approach; see
for example the Expat library.
minIni supports both approaches. For reading a single setting, use functions like ini_gets(). For the callback
approach, implement a callback and call ini_browse(). See the minIni manual for details.
# INI file syntax
INI files are best known from Microsoft Windows, but they are also used with applications that run on other
platforms (although their file extension is sometimes ".cfg" instead of ".ini").
INI files have a simple syntax with name/value pairs in a plain text file. The name must be unique (per section)
and the value must fit on a single line. INI files are commonly separated into sections &mdash;in minIni, this is
optional. A section is a name between square brackets, like "[Network]" in the example below.
```
[Network]
hostname=My Computer
address=dhcp
dns = 192.168.1.1
```
In the API and in this documentation, the "name" for a setting is denoted as the key for the setting. The key
and the value are separated by an equal sign ("="). minIni supports the colon (":") as an alternative to the
equal sign for the key/value delimiter.
Leading a trailing spaces around values or key names are removed. If you need to include leading and/or trailing
spaces in a value, put the value between double quotes. The ini_gets() function (from the minIni library, see the
minIni manual) strips off the double quotes from the returned value. Function ini_puts() adds double quotes if
the value to write contains trailing white space (or special characters).
minIni ignores spaces around the "=" or ":" delimiters, but it does not ignore spaces between the brackets in a
section name. In other words, it is best not to put spaces behind the opening bracket "[" or before the closing
bracket "]" of a section name.
Comments in the INI must start with a semicolon (";") or a hash character ("#"), and run to the end of the line.
A comment can be a line of its own, or it may follow a key/value pair (the "#" character and trailing comments
are extensions of minIni).
For more details on the format, please see http://en.wikipedia.org/wiki/INI_file.
# Adapting minIni to a file system
The minIni library must be configured for a platform with the help of a so- called "glue file". This glue file
contains macros (and possibly functions) that map file reading and writing functions used by the minIni library
to those provided by the operating system. The glue file must be called "minGlue.h".
To get you started, the minIni distribution comes with the following example glue files:
* a glue file that maps to the standard C/C++ library (specifically the file I/O functions from the "stdio" package),
* a glue file for Microchip's "Memory Disk Drive File System Library" (see http://www.microchip.com/),
* a glue file for the FAT library provided with the CCS PIC compiler (see http://www.ccsinfo.com/)
* a glue file for the EFS Library (EFSL, http://www.efsl.be/),
* and a glue file for the FatFs and Petit-FatFs libraries (http://elm-chan.org/fsw/ff/00index_e.html).
The minIni library does not rely on the availability of a standard C library, because embedded operating systems
may have limited support for file I/O. Even on full operating systems, separating the file I/O from the INI format
parsing carries advantages, because it allows you to cache the INI file and thereby enhance performance.
The glue file must specify the type that identifies a file, whether it is a handle or a pointer. For the standard
C/C++ file I/O library, this would be:
```C
#define INI_FILETYPE FILE*
```
If you are not using the standard C/C++ file I/O library, chances are that you need a different handle or
"structure" to identify the storage than the ubiquitous "FILE*" type. For example, the glue file for the FatFs
library uses the following declaration:
```C
#define INI_FILETYPE FIL
```
The minIni functions declare variables of this INI_FILETYPE type and pass these variables to sub-functions
(including the glue interface functions) by reference.
For "write support", another type that must be defined is for variables that hold the "current position" in a
file. For the standard C/C++ I/O library, this is "fpos_t".
Another item that needs to be configured is the buffer size. The functions in the minIni library allocate this
buffer on the stack, so the buffer size is directly related to the stack usage. In addition, the buffer size
determines the maximum line length that is supported in the INI file and the maximum path name length for the
temporary file. For example, minGlue.h could contain the definition:
```C
#define INI_BUFFERSIZE 512
```
The above macro limits the line length of the INI files supported by minIni to 512 characters.
The temporary file is only used when writing to INI files. The minIni routines copy/change the INI file to a
temporary file and then rename that temporary file to the original file. This approach uses the least amount of
memory. The path name of the temporary file is the same as the input file, but with the last character set to a
tilde ("~").
Below is an example of a glue file (this is the one that maps to the C/C++ "stdio" library).
```C
#include <stdio.h>
#define INI_FILETYPE FILE*
#define ini_openread(filename,file) ((*(file) = fopen((filename),"r")) != NULL)
#define ini_openwrite(filename,file) ((*(file) = fopen((filename),"w")) != NULL)
#define ini_close(file) (fclose(*(file)) == 0)
#define ini_read(buffer,size,file) (fgets((buffer),(size),*(file)) != NULL)
#define ini_write(buffer,file) (fputs((buffer),*(file)) >= 0)
#define ini_rename(source,dest) (rename((source), (dest)) == 0)
#define ini_remove(filename) (remove(filename) == 0)
#define INI_FILEPOS fpos_t
#define ini_tell(file,pos) (fgetpos(*(file), (pos)) == 0)
#define ini_seek(file,pos) (fsetpos(*(file), (pos)) == 0)
```
As you can see, a glue file is mostly a set of macros that wraps one function definition around another.
The glue file may contain more settings, for support of rational numbers, to explicitly set the line termination
character(s), or to disable write support (for example). See the manual that comes with the archive for the details.

View File

@@ -0,0 +1,37 @@
/* Glue functions for the minIni library, based on the FatFs and Petit-FatFs
* libraries, see http://elm-chan.org/fsw/ff/00index_e.html
*
* By CompuPhase, 2008-2012
* This "glue file" is in the public domain. It is distributed without
* warranties or conditions of any kind, either express or implied.
*
* (The FatFs and Petit-FatFs libraries are copyright by ChaN and licensed at
* its own terms.)
*/
#define INI_BUFFERSIZE 256 /* maximum line length, maximum path length */
/* You must set _USE_STRFUNC to 1 or 2 in the include file ff.h (or tff.h)
* to enable the "string functions" fgets() and fputs().
*/
#include "ff.h" /* include tff.h for Tiny-FatFs */
#define INI_FILETYPE FIL
#define ini_openread(filename,file) (f_open((file), (filename), FA_READ+FA_OPEN_EXISTING) == FR_OK)
#define ini_openwrite(filename,file) (f_open((file), (filename), FA_WRITE+FA_CREATE_ALWAYS) == FR_OK)
#define ini_close(file) (f_close(file) == FR_OK)
#define ini_read(buffer,size,file) f_gets((buffer), (size),(file))
#define ini_write(buffer,file) f_puts((buffer), (file))
#define ini_remove(filename) (f_unlink(filename) == FR_OK)
#define INI_FILEPOS DWORD
#define ini_tell(file,pos) (*(pos) = f_tell((file)))
#define ini_seek(file,pos) (f_lseek((file), *(pos)) == FR_OK)
static int ini_rename(TCHAR *source, const TCHAR *dest)
{
/* Function f_rename() does not allow drive letters in the destination file */
char *drive = strchr(dest, ':');
drive = (drive == NULL) ? dest : drive + 1;
return (f_rename(source, drive) == FR_OK);
}

Some files were not shown because too many files have changed in this diff Show More