diff --git a/Makefile b/Makefile
index c1993bb9..4ab95c62 100755
--- a/Makefile
+++ b/Makefile
@@ -37,8 +37,8 @@ include $(DEVKITPRO)/libnx/switch_rules
# of a homebrew executable (.nro). This is intended to be used for sysmodules.
# NACP building is skipped as well.
#---------------------------------------------------------------------------------
-APP_TITLE := Ultra Monitor
-APP_VERSION := 1.0.1
+APP_TITLE := Status Monitor
+APP_VERSION := 1.0.3
TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := source
diff --git a/config/status-monitor/config.ini.template b/config/status-monitor/config.ini.template
index f5220354..c143e078 100644
--- a/config/status-monitor/config.ini.template
+++ b/config/status-monitor/config.ini.template
@@ -1,5 +1,7 @@
[status-monitor]
key_combo=L+R+DUP
+battery_avg_iir_filter=false
+battery_time_left_refreshrate=60
[full]
refresh_rate=1
@@ -51,5 +53,5 @@ fps_counter_color=#4444
border_color=#F77F
dashed_line_color=#8888
main_line_color=#FFFF
-rounded_line_color=#0C0F
-perfect_line_color=#F0FF
\ No newline at end of file
+rounded_line_color=#F0FF
+perfect_line_color=#0C0F
diff --git a/docs/config.md b/docs/config.md
index 13c04f97..31aaa557 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -12,6 +12,9 @@ Colors are provided in RGBA4444 format, which means that each character represen
| Key | Explanation | Possible values | Default Value |
|-----|-------------|-----------------|---------------|
| `key_combo` | Buttons combination that allows exiting Full, Mini and Micro modes; max 4 buttons, otherwise next buttons will be ignored. Combine different buttons with `+` | `A`, `B`, `X`, `Y`, `L`, `R`, `ZL`, `ZR`, `PLUS`, `MINUS`, `DUP`, `DDOWN`, `DLEFT`, `DRIGHT`, `SL`, `SR`, `LSTICK`, `RSTICK`, `UP`, `DOWN`, `LEFT`, `RIGHT` | `L+DDOWN+RSTICK` |
+| `battery_avg_iir_filter` | Read voltage + current averages directly from fuel gauge, that uses infinite impulse response filter | `true`, `false` | `false` |
+| `battery_time_left_refreshrate` | How many seconds must pass to refresh Battery Remaining Time | from `1` to `60` | `60` |
+
> [full]
diff --git a/docs/modes.md b/docs/modes.md
index df446801..aed63caf 100755
--- a/docs/modes.md
+++ b/docs/modes.md
@@ -9,15 +9,27 @@ For additional functions you need to install:
This mode you can know from older releases of Status Monitor. It contains all informations properly described and supported with high precision.
-| Category | Format | Explanation |
-|-----------|-------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| CPU Usage | Frequency: %.1f (Δ%+.1f)
Core #0: %.2f
Core #1: %.2f
Core #2: %.2f
Core #3: %.2f | Targete clockrate of all CPU cores in MHz (^1)
Load of CPU Core #0 calculated from IdleTickCount to percent value
Load of CPU Core #1 calculated from IdleTickCount to percent value
Load of CPU Core #2 calculated from IdleTickCount to percent value
Load of CPU Core #3 calculated from IdleTickCount to percent value |
-| GPU Usage | Frequency: %.1f (Δ%+.1f)
Load: %.1f | Target clockrate of GPU in MHz (^1)
GPU Load provided by PMU in percent |
-| RAM Usage | - Real Frequency: %.1f (Δ%+.1f)
- Target Frequency: %.1f
- Load: %.1f (CPU %.1f \| GPU %.1f)`^1`
- %s: %.2f/%.2f | - Real clockrate of EMC in MHz `(^1)`
- Target clockrate of EMC in MHz
- RAM Load in % (Which part of that are CPU and GPU (with other hardware, but their impact on GPU readings is negligible) `(^1)`
- %s memory used/%s memory available in MB (not working with FW <5.0.0) |
-| Board | Battery Power Flow: %+.2f[h:mm]
Temperatures:
- SoC: %.1f
- PCB: %.1f
- Skin: %.1f
Fan Rotation Level: %.1f | How much power in watts is discharged from or charged to the battery [time left before shutdown]
SoC temperature in Celsius degrees
PCB temperature in Celsius degrees
Skin temperature in Celsius degrees (^2)
Fan rotation level in percent |
-
-- ^1 - This shows only when sys-clk 2.0.0_rc4+ is installed.
-- ^2 - Explanation provided at the end of file
+- CPU Usage
+ - Real Frequency: `%.1f` = Real clockrate of all CPU cores in MHz (This shows only when sys-clk 2.0.0_4c+ is installed)
+ - Target Frequency: `%.1f` = Target clockrate of all CPU cores in MHz
+ - Core #0-#3: `%.2f` = Load of CPU Cores calculated from IdleTickCount to percent value
+
+- GPU Usage
+ - Real Frequency: `%.1f` = Real clockrate of GPU in MHz (This shows only when sys-clk 2.0.0_rc4+ is installed)
+ - Target Frequency: `%.1f` = Target clockrate of GPU in MHz
+ - Load: `%.1f` = GPU Load provided by PMU in percent
+
+- RAM Usage
+ - Real Frequency: `%.1f` = Real clockrate of EMC in MHz (This shows only when sys-clk 2.0.0_rc4+ is installed)
+ - Target Frequency: `%.1f` = Target clockrate of EMC in MHz
+ - Load: `%.1f` (CPU `%.1f` | GPU `%.1f`) = RAM Load in % (Which part of that are CPU and GPU (with other hardware, but their impact on GPU readings is negligible))
+ - `%s`: `%.2f`/`%.2f` = %s memory used/%s memory available in MB (not working with FW <5.0.0)
+
+- Board
+ - Battery Power Flow: `%+.2f`[h:mm] = How much power in watts is discharged from or charged to the battery [time left before shutdown]
+ - Temperatures: SoC: `%.1f` / PCB: `%.1f` / Skin: `%.1f` = SoC / PCB / Skin temperature in Celsius degrees (Explanation provided at the end of file)
+ - Fan Rotation Level: `%.1f` = Fan rotation level in percent
+
```Optional (shows only when SaltyNX is installed and game is running)```
@@ -102,14 +114,15 @@ Mode available only with SaltyNX installed.
> Battery
-| Category | Format | Explanation |
-|---------------------------------|-----------|-----------------------------------------------------------------------------------------------|
-| Battery Temperature | %.2f | Battery temperature in Celsius |
-| Battery Raw Charge | %.2f | Raw battery charged capacity in percent |
-| Battery Voltage (AVG of 5) | %.2f | Battery average voltage in mV taken from 5 readings in period of 5 seconds |
-| Battery Current Flow (AVG of 5) | %+.2f | Battery average current flow in mA taken from 5 readings in period of 5 seconds |
-| Battery Power Flow (AVG of 5) | %+.3f | Battery average power flow in W calciulated from Battery Voltage and Battery Current Flow |
-| Battery Remaining Time | h:mm | How much time is left before shutdown |
+- Battery Actual Capacity: `%d` = Battery Designed Capacity multiplied by Battery Age in mAh
+- Battery Designed Capacity: `%d` = Battery capacity targeted by manufacturer in mAh
+- Battery Temperature: `%.1f` = Battery temperature in Celsius
+- Battery Raw Charge: `%.1f` = Raw battery charged capacity in percent
+- Battery Age: `%.1f` = How much of designed capacity was charged last time battery was charged completely in percent
+- Battery Voltage: `%.0f` = Battery average voltage in mV (time period: 5s, or with `battery_avg_iir_filter` enabled: 45s)
+- Battery Current Flow: `%+.0f` = Battery average current flow in mA (time period: 5s, or with `battery_avg_iir_filter` enabled: 11.25s)
+- Battery Power Flow: `%+.3f` = Battery average power flow in W calculated from Battery Voltage and Battery Current Flow
+- Battery Remaining Time: h:mm - How much time is left before shutdown
Shows only if charger is connected:
| Category | Format | Explanation |
diff --git a/include/i2c.h b/include/i2c.h
index 762d841b..32a21e43 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -10,9 +10,13 @@ constexpr float max17050CGain = 1.99993;
Result I2cReadRegHandler(u8 reg, I2cDevice dev, u16 *out)
{
- // I2C Bus Communication Reference: https://www.ti.com/lit/an/slva704/slva704.pdf
- struct { u8 reg; } __attribute__((packed)) cmd;
- struct { u16 val; } __attribute__((packed)) rec;
+ struct readReg {
+ u8 send;
+ u8 sendLength;
+ u8 sendData;
+ u8 receive;
+ u8 receiveLength;
+ };
I2cSession _session;
@@ -20,37 +24,38 @@ Result I2cReadRegHandler(u8 reg, I2cDevice dev, u16 *out)
if (res)
return res;
- cmd.reg = reg;
- res = i2csessionSendAuto(&_session, &cmd, sizeof(cmd), I2cTransactionOption_All);
- if (res)
- {
- i2csessionClose(&_session);
- return res;
- }
+ u16 val;
- res = i2csessionReceiveAuto(&_session, &rec, sizeof(rec), I2cTransactionOption_All);
+ struct readReg readRegister = {
+ .send = 0 | (I2cTransactionOption_Start << 6),
+ .sendLength = sizeof(reg),
+ .sendData = reg,
+ .receive = 1 | (I2cTransactionOption_All << 6),
+ .receiveLength = sizeof(val),
+ };
+
+ res = i2csessionExecuteCommandList(&_session, &val, sizeof(val), &readRegister, sizeof(readRegister));
if (res)
{
i2csessionClose(&_session);
return res;
}
- *out = rec.val;
+ *out = val;
i2csessionClose(&_session);
return 0;
}
-bool Max17050ReadReg(u8 reg, u16 *out)
+Result Max17050ReadReg(u8 reg, u16 *out)
{
u16 data = 0;
Result res = I2cReadRegHandler(reg, I2cDevice_Max17050, &data);
- if (res)
+ if (R_FAILED(res))
{
- *out = res;
- return false;
+ return res;
}
*out = data;
- return true;
-}
\ No newline at end of file
+ return res;
+}
diff --git a/include/max17050.h b/include/max17050.h
index 07e42136..c56ab9ba 100644
--- a/include/max17050.h
+++ b/include/max17050.h
@@ -42,6 +42,8 @@
#define MAXIM17050_I2C_ADDR 0x36
*/
+#define MAX17050_WAIT_NS 1175800000
+
enum MAX17050_reg {
MAX17050_STATUS = 0x00,
diff --git a/source/Utils.hpp b/source/Utils.hpp
index c9446904..8ec4d3b4 100644
--- a/source/Utils.hpp
+++ b/source/Utils.hpp
@@ -33,7 +33,7 @@ Thread t3;
Thread t4;
Thread t6;
Thread t7;
-uint64_t systemtickfrequency = 19200000;
+const uint64_t systemtickfrequency = 19200000;
bool threadexit = false;
bool threadexit2 = false;
FanController g_ICon;
@@ -89,6 +89,8 @@ float PowerConsumption = 0;
int16_t batTimeEstimate = -1;
float actualFullBatCapacity = 0;
float designedFullBatCapacity = 0;
+bool batteryFiltered = false;
+uint8_t batteryTimeLeftRefreshRate = 60;
//Temperatures
float SOC_temperatureF = 0;
@@ -239,133 +241,124 @@ void CheckIfGameRunning(void*) {
}
}
+Mutex mutex_BatteryChecker = {0};
void BatteryChecker(void*) {
- if (R_SUCCEEDED(psmCheck)){
- uint16_t data = 0;
- float tempV = 0;
- float tempA = 0;
- size_t ArraySize = 10;
- size_t CommonPowerAvgHistorySize = 3; // last 3 min history
- size_t TmpPowerHistoryArraySize = 120; // last 60 sec history
- float readingsAmp[ArraySize] = {0};
- float readingsVolt[ArraySize] = {0};
- std::vector commonAvgPowerHistory; // common avg history
- float tmpPowerHistory[TmpPowerHistoryArraySize] = {0};
-
- if (Max17050ReadReg(MAX17050_Current, &data)) {
- tempA = (1.5625 / (max17050SenseResistor * max17050CGain)) * (s16)data;
- for (size_t i = 0; i < ArraySize; i++) {
- readingsAmp[i] = tempA;
- }
- }
- svcSleepThread(1000000);
- if (Max17050ReadReg(MAX17050_VCELL, &data)) {
- tempV = 0.625 * (data >> 3);
- for (size_t i = 0; i < ArraySize; i++) {
- readingsVolt[i] = tempV;
- }
- }
- svcSleepThread(1000000);
- if (!actualFullBatCapacity && Max17050ReadReg(MAX17050_FullCAP, &data)) {
- actualFullBatCapacity = data * (BASE_SNS_UOHM / MAX17050_BOARD_SNS_RESISTOR_UOHM) / MAX17050_BOARD_CGAIN;
- }
- svcSleepThread(1000000);
- if (!designedFullBatCapacity && Max17050ReadReg(MAX17050_DesignCap, &data)) {
- designedFullBatCapacity = data * (BASE_SNS_UOHM / MAX17050_BOARD_SNS_RESISTOR_UOHM) / MAX17050_BOARD_CGAIN;
- }
- svcSleepThread(1000000);
- size_t i = 0;
- size_t powerHistoryIteration = 0;
- int tempChargerType = 0;
- if (!Max17050ReadReg(MAX17050_AvgCurrent, &data) && (s16)data > 0) {
- float tmpCurrentAvg = (1.5625 / (max17050SenseResistor * max17050CGain)) * (s16)data;
- while (powerHistoryIteration < 20)
- tmpPowerHistory[powerHistoryIteration++] = tmpCurrentAvg;
+ if (R_FAILED(psmCheck)){
+ return;
+ }
+ uint16_t data = 0;
+ float tempV = 0.0;
+ float tempA = 0.0;
+ size_t ArraySize = 10;
+ if (batteryFiltered) {
+ ArraySize = 1;
+ }
+ float* readingsAmp = new float[ArraySize];
+ float* readingsVolt = new float[ArraySize];
+
+ Max17050ReadReg(MAX17050_AvgCurrent, &data);
+ tempA = (1.5625 / (max17050SenseResistor * max17050CGain)) * (s16)data;
+ for (size_t i = 0; i < ArraySize; i++) {
+ readingsAmp[i] = tempA;
+ }
+ Max17050ReadReg(MAX17050_AvgVCELL, &data);
+ tempV = 0.625 * (data >> 3);
+ for (size_t i = 0; i < ArraySize; i++) {
+ readingsVolt[i] = tempV;
+ }
+ if (!actualFullBatCapacity) {
+ Max17050ReadReg(MAX17050_FullCAP, &data);
+ actualFullBatCapacity = data * (BASE_SNS_UOHM / MAX17050_BOARD_SNS_RESISTOR_UOHM) / MAX17050_BOARD_CGAIN;
+ }
+ if (!designedFullBatCapacity) {
+ Max17050ReadReg(MAX17050_DesignCap, &data);
+ designedFullBatCapacity = data * (BASE_SNS_UOHM / MAX17050_BOARD_SNS_RESISTOR_UOHM) / MAX17050_BOARD_CGAIN;
+ }
+ if (readingsAmp[0] >= 0) {
+ batTimeEstimate = -1;
+ }
+ else {
+ Max17050ReadReg(MAX17050_TTE, &data);
+ float batteryTimeEstimateInMinutes = (5.625 * data) / 60;
+ if (batteryTimeEstimateInMinutes > (99.0*60.0)+59.0) {
+ batTimeEstimate = (99*60)+59;
}
+ else batTimeEstimate = (int16_t)batteryTimeEstimateInMinutes;
+ }
+
+ size_t counter = 0;
+ uint64_t tick_TTE = svcGetSystemTick();
+ while (!threadexit) {
+ mutexLock(&mutex_BatteryChecker);
+ uint64_t startTick = svcGetSystemTick();
- while (!threadexit) {
- svcSleepThread(1000000);
- psmGetBatteryChargeInfoFields(psmService, &_batteryChargeInfoFields);
- // Calculation is based on Hekate's max17050.c
- // Source: https://github.com/CTCaer/hekate/blob/master/bdk/power/max17050.c
- if (!Max17050ReadReg(MAX17050_Current, &data))
- continue;
- svcSleepThread(1000000);
+ psmGetBatteryChargeInfoFields(psmService, &_batteryChargeInfoFields);
+
+ // Calculation is based on Hekate's max17050.c
+ // Source: https://github.com/CTCaer/hekate/blob/master/bdk/power/max17050.c
+
+ if (!batteryFiltered) {
+ Max17050ReadReg(MAX17050_Current, &data);
+ tempA = (1.5625 / (max17050SenseResistor * max17050CGain)) * (s16)data;
+ Max17050ReadReg(MAX17050_VCELL, &data);
+ tempV = 0.625 * (data >> 3);
+ } else {
+ Max17050ReadReg(MAX17050_AvgCurrent, &data);
tempA = (1.5625 / (max17050SenseResistor * max17050CGain)) * (s16)data;
- if (!Max17050ReadReg(MAX17050_VCELL, &data))
- continue;
- svcSleepThread(1000000);
+ Max17050ReadReg(MAX17050_AvgVCELL, &data);
tempV = 0.625 * (data >> 3);
+ }
- readingsAmp[i] = tempA;
- readingsVolt[i] = tempV;
- if (i+1 < ArraySize) {
- i++;
- }
- else i = 0;
-
- float batCurrent = readingsAmp[0];
- float batVoltage = readingsVolt[0];
- float batPowerAvg = (readingsAmp[0] * readingsVolt[0]) / 1'000;
- for (size_t x = 1; x < ArraySize; x++) {
- batCurrent += readingsAmp[x];
- batVoltage += readingsVolt[x];
- batPowerAvg += (readingsAmp[x] * readingsVolt[x]) / 1'000;
- }
- float actualCapacity = actualFullBatCapacity / 100 * (float)_batteryChargeInfoFields.RawBatteryCharge / 1000;
- batCurrent /= ArraySize;
- batVoltage /= ArraySize;
- batCurrentAvg = batCurrent;
- batVoltageAvg = batVoltage;
- batPowerAvg /= ArraySize * 1000;
- PowerConsumption = batPowerAvg;
- bool chargerTypeDifferent = (tempChargerType != _batteryChargeInfoFields.ChargerType);
- if (hosversionAtLeast(17,0,0)) {
- chargerTypeDifferent = (tempChargerType != ((BatteryChargeInfoFields17*)&_batteryChargeInfoFields) -> ChargerType);
- }
- if (chargerTypeDifferent) {
- powerHistoryIteration = 0;
- batTimeEstimate = -1;
- tempChargerType = _batteryChargeInfoFields.ChargerType;
- if (hosversionAtLeast(17,0,0)) {
- tempChargerType = ((BatteryChargeInfoFields17*)&_batteryChargeInfoFields) -> ChargerType;
- }
- commonAvgPowerHistory.clear();
- commonAvgPowerHistory.shrink_to_fit();
- }
- else if (batCurrentAvg < 0) {
- tmpPowerHistory[powerHistoryIteration++] = batCurrentAvg; // add currentAvg to tmp array
- if (powerHistoryIteration == TmpPowerHistoryArraySize) {
- if (commonAvgPowerHistory.size() == CommonPowerAvgHistorySize) {
- commonAvgPowerHistory.erase(commonAvgPowerHistory.begin());
- }
- float tmpPowerSum = std::accumulate(tmpPowerHistory, tmpPowerHistory+TmpPowerHistoryArraySize, 0);
- commonAvgPowerHistory.push_back(tmpPowerSum / TmpPowerHistoryArraySize);
- float commonPowerSum = std::accumulate(commonAvgPowerHistory.begin(), commonAvgPowerHistory.end(), 0);
- float commonAvg = -commonPowerSum / commonAvgPowerHistory.size();
- batTimeEstimate = (int)(actualCapacity / (commonAvg / 60));
- if (batTimeEstimate > (99*60)+59)
- batTimeEstimate = (99*60)+59;
- powerHistoryIteration = 0;
- }
- else if (commonAvgPowerHistory.size() == 0 && powerHistoryIteration < TmpPowerHistoryArraySize) {
- float PowerSum = std::accumulate(tmpPowerHistory, tmpPowerHistory+powerHistoryIteration, 0);
- float commonAvg = -PowerSum / powerHistoryIteration;
- batTimeEstimate = (int)(actualCapacity / (commonAvg / 60));
- if (batTimeEstimate > (99*60)+59)
- batTimeEstimate = (99*60)+59;
- }
+ if (tempA && tempV) {
+ readingsAmp[counter % ArraySize] = tempA;
+ readingsVolt[counter % ArraySize] = tempV;
+ counter++;
+ }
+
+ float batCurrent = 0.0;
+ float batVoltage = 0.0;
+ float batPowerAvg = 0.0;
+ for (size_t x = 0; x < ArraySize; x++) {
+ batCurrent += readingsAmp[x];
+ batVoltage += readingsVolt[x];
+ batPowerAvg += (readingsAmp[x] * readingsVolt[x]) / 1'000;
+ }
+ batCurrent /= ArraySize;
+ batVoltage /= ArraySize;
+ batCurrentAvg = batCurrent;
+ batVoltageAvg = batVoltage;
+ batPowerAvg /= ArraySize * 1000;
+ PowerConsumption = batPowerAvg;
+
+ if (batCurrentAvg >= 0) {
+ batTimeEstimate = -1;
+ }
+ else {
+ static float batteryTimeEstimateInMinutes = 0;
+ Max17050ReadReg(MAX17050_TTE, &data);
+ batteryTimeEstimateInMinutes = (5.625 * data) / 60;
+ if (batteryTimeEstimateInMinutes > (99.0*60.0)+59.0) {
+ batteryTimeEstimateInMinutes = (99.0*60.0)+59.0;
}
- else {
- powerHistoryIteration = 0;
- batTimeEstimate = -1;
+ uint64_t new_tick_TTE = svcGetSystemTick();
+ if (armTicksToNs(new_tick_TTE - tick_TTE) / 1'000'000'000 >= batteryTimeLeftRefreshRate) {
+ batTimeEstimate = (int16_t)batteryTimeEstimateInMinutes;
+ tick_TTE = new_tick_TTE;
}
- svcSleepThread(499'000'000);
}
- _batteryChargeInfoFields = {0};
- commonAvgPowerHistory.clear();
- commonAvgPowerHistory.shrink_to_fit();
+
+ mutexUnlock(&mutex_BatteryChecker);
+ uint64_t nanosecondsPassed = armTicksToNs(svcGetSystemTick() - startTick);
+ if (nanosecondsPassed < 1'000'000'000 / 2) {
+ svcSleepThread((1'000'000'000 / 2) - nanosecondsPassed);
+ } else {
+ svcSleepThread(1'000);
+ }
}
+ batTimeEstimate = -1;
+ _batteryChargeInfoFields = {0};
+ delete[] readingsAmp;
+ delete[] readingsVolt;
}
void StartBatteryThread() {
@@ -373,10 +366,11 @@ void StartBatteryThread() {
threadStart(&t7);
}
+Mutex mutex_Misc = {0};
//Stuff that doesn't need multithreading
void Misc(void*) {
while (!threadexit) {
-
+ mutexLock(&mutex_Misc);
// CPU, GPU and RAM Frequency
if (R_SUCCEEDED(clkrstCheck)) {
ClkrstSession clkSession;
@@ -468,6 +462,7 @@ void Misc(void*) {
FPSmax = 0;
}
// Interval
+ mutexUnlock(&mutex_Misc);
svcSleepThread(100'000'000);
}
}
@@ -494,10 +489,12 @@ void Misc2(void*) {
}
//Check each core for idled ticks in intervals, they cannot read info about other core than they are assigned
+//In case of getting more than systemtickfrequency in idle, make it equal to systemtickfrequency to get 0% as output and nothing less
+//This is because making each loop also takes time, which is not considered because this will take also additional time
void CheckCore0(void*) {
while (!threadexit) {
- static uint64_t idletick_a0 = 0;
- static uint64_t idletick_b0 = 0;
+ uint64_t idletick_a0 = 0;
+ uint64_t idletick_b0 = 0;
svcGetInfo(&idletick_b0, InfoType_IdleTickCount, INVALID_HANDLE, 0);
svcSleepThread(1'000'000'000 / TeslaFPS);
svcGetInfo(&idletick_a0, InfoType_IdleTickCount, INVALID_HANDLE, 0);
@@ -507,8 +504,8 @@ void CheckCore0(void*) {
void CheckCore1(void*) {
while (!threadexit) {
- static uint64_t idletick_a1 = 0;
- static uint64_t idletick_b1 = 0;
+ uint64_t idletick_a1 = 0;
+ uint64_t idletick_b1 = 0;
svcGetInfo(&idletick_b1, InfoType_IdleTickCount, INVALID_HANDLE, 1);
svcSleepThread(1'000'000'000 / TeslaFPS);
svcGetInfo(&idletick_a1, InfoType_IdleTickCount, INVALID_HANDLE, 1);
@@ -518,8 +515,8 @@ void CheckCore1(void*) {
void CheckCore2(void*) {
while (!threadexit) {
- static uint64_t idletick_a2 = 0;
- static uint64_t idletick_b2 = 0;
+ uint64_t idletick_a2 = 0;
+ uint64_t idletick_b2 = 0;
svcGetInfo(&idletick_b2, InfoType_IdleTickCount, INVALID_HANDLE, 2);
svcSleepThread(1'000'000'000 / TeslaFPS);
svcGetInfo(&idletick_a2, InfoType_IdleTickCount, INVALID_HANDLE, 2);
@@ -529,13 +526,12 @@ void CheckCore2(void*) {
void CheckCore3(void*) {
while (!threadexit) {
- static uint64_t idletick_a3 = 0;
- static uint64_t idletick_b3 = 0;
+ uint64_t idletick_a3 = 0;
+ uint64_t idletick_b3 = 0;
svcGetInfo(&idletick_b3, InfoType_IdleTickCount, INVALID_HANDLE, 3);
svcSleepThread(1'000'000'000 / TeslaFPS);
svcGetInfo(&idletick_a3, InfoType_IdleTickCount, INVALID_HANDLE, 3);
idletick3 = idletick_a3 - idletick_b3;
-
}
}
@@ -692,65 +688,58 @@ void formatButtonCombination(std::string& line) {
}
}
+uint64_t MapButtons(const std::string& buttonCombo) {
+ std::map buttonMap = {
+ {"A", HidNpadButton_A},
+ {"B", HidNpadButton_B},
+ {"X", HidNpadButton_X},
+ {"Y", HidNpadButton_Y},
+ {"L", HidNpadButton_L},
+ {"R", HidNpadButton_R},
+ {"ZL", HidNpadButton_ZL},
+ {"ZR", HidNpadButton_ZR},
+ {"PLUS", HidNpadButton_Plus},
+ {"MINUS", HidNpadButton_Minus},
+ {"DUP", HidNpadButton_Up},
+ {"DDOWN", HidNpadButton_Down},
+ {"DLEFT", HidNpadButton_Left},
+ {"DRIGHT", HidNpadButton_Right},
+ {"SL", HidNpadButton_AnySL},
+ {"SR", HidNpadButton_AnySR},
+ {"LSTICK", HidNpadButton_StickL},
+ {"RSTICK", HidNpadButton_StickR},
+ {"UP", HidNpadButton_Up},
+ {"DOWN", HidNpadButton_Down},
+ {"LEFT", HidNpadButton_Left},
+ {"RIGHT", HidNpadButton_Right}
+ };
-// Base class with virtual function
-class ButtonMapper {
-public:
- virtual std::list MapButtons(const std::string& buttonCombo) = 0;
-};
+ uint64_t comboBitmask = 0;
+ std::string comboCopy = buttonCombo; // Make a copy of buttonCombo
-// Derived class implementing the virtual function
-class ButtonMapperImpl : public ButtonMapper {
-public:
- std::list MapButtons(const std::string& buttonCombo) override {
- std::map buttonMap = {
- {"A", static_cast(HidNpadButton_A)},
- {"B", static_cast(HidNpadButton_B)},
- {"X", static_cast(HidNpadButton_X)},
- {"Y", static_cast(HidNpadButton_Y)},
- {"L", static_cast(HidNpadButton_L)},
- {"R", static_cast(HidNpadButton_R)},
- {"ZL", static_cast(HidNpadButton_ZL)},
- {"ZR", static_cast(HidNpadButton_ZR)},
- {"PLUS", static_cast(HidNpadButton_Plus)},
- {"MINUS", static_cast(HidNpadButton_Minus)},
- {"DUP", static_cast(HidNpadButton_Up)},
- {"DDOWN", static_cast(HidNpadButton_Down)},
- {"DLEFT", static_cast(HidNpadButton_Left)},
- {"DRIGHT", static_cast(HidNpadButton_Right)},
- {"SL", static_cast(HidNpadButton_AnySL)},
- {"SR", static_cast(HidNpadButton_AnySR)},
- {"LSTICK", static_cast(HidNpadButton_StickL)},
- {"RSTICK", static_cast(HidNpadButton_StickR)},
- {"UP", static_cast(HidNpadButton_Up | HidNpadButton_StickLUp | HidNpadButton_StickRUp)},
- {"DOWN", static_cast(HidNpadButton_Down | HidNpadButton_StickLDown | HidNpadButton_StickRDown)},
- {"LEFT", static_cast(HidNpadButton_Left | HidNpadButton_StickLLeft | HidNpadButton_StickRLeft)},
- {"RIGHT", static_cast(HidNpadButton_Right | HidNpadButton_StickLRight | HidNpadButton_StickRRight)}
- };
-
- std::list mappedButtons;
- std::string comboCopy = buttonCombo; // Make a copy of buttonCombo
-
- std::string delimiter = "+";
- size_t pos = 0;
- std::string button;
- size_t max_delimiters = 4;
- while ((pos = comboCopy.find(delimiter)) != std::string::npos) {
- button = comboCopy.substr(0, pos);
- if (buttonMap.find(button) != buttonMap.end()) {
- mappedButtons.push_back(buttonMap[button]);
- }
- comboCopy.erase(0, pos + delimiter.length());
- if(!--max_delimiters) {
- return mappedButtons;
- }
+ std::string delimiter = "+";
+ size_t pos = 0;
+ std::string button;
+ size_t max_delimiters = 4;
+ while ((pos = comboCopy.find(delimiter)) != std::string::npos) {
+ button = comboCopy.substr(0, pos);
+ if (buttonMap.find(button) != buttonMap.end()) {
+ comboBitmask |= buttonMap[button];
}
- if (buttonMap.find(comboCopy) != buttonMap.end()) {
- mappedButtons.push_back(buttonMap[comboCopy]);
+ comboCopy.erase(0, pos + delimiter.length());
+ if (!--max_delimiters) {
+ return comboBitmask;
}
- return mappedButtons;
}
-};
+ if (buttonMap.find(comboCopy) != buttonMap.end()) {
+ comboBitmask |= buttonMap[comboCopy];
+ }
+ return comboBitmask;
+}
+
+static inline bool isKeyComboPressed(uint64_t keysHeld, uint64_t keysDown, uint64_t comboBitmask) {
+ return (keysDown == comboBitmask) || (keysHeld == comboBitmask);
+}
// Custom utility function for parsing an ini file
void ParseIniFile() {
@@ -778,26 +767,44 @@ void ParseIniFile() {
long fileSize = ftell(configFileIn);
rewind(configFileIn);
- // Read the contents of the INI file
- char* fileData = new char[fileSize + 1];
- fread(fileData, sizeof(char), fileSize, configFileIn);
- fileData[fileSize] = '\0'; // Add null-terminator to create a C-string
- fclose(configFileIn);
-
// Parse the INI data
- std::string fileDataString(fileData, fileSize);
+ std::string fileDataString(fileSize, '\0');
+ fread(&fileDataString[0], sizeof(char), fileSize, configFileIn);
+ fclose(configFileIn);
+
parsedData = tsl::hlp::ini::parseIni(fileDataString);
- delete[] fileData;
// Access and use the parsed data as needed
// For example, print the value of a specific section and key
- if (parsedData.find("status-monitor") != parsedData.end() &&
- parsedData["status-monitor"].find("key_combo") != parsedData["status-monitor"].end()) {
- keyCombo = parsedData["status-monitor"]["key_combo"]; // load keyCombo variable
- removeSpaces(keyCombo); // format combo
- convertToUpper(keyCombo);
- } else {
- readExternalCombo = true;
+ if (parsedData.find("status-monitor") != parsedData.end()) {
+ if (parsedData["status-monitor"].find("key_combo") != parsedData["status-monitor"].end()) {
+ keyCombo = parsedData["status-monitor"]["key_combo"]; // load keyCombo variable
+ removeSpaces(keyCombo); // format combo
+ convertToUpper(keyCombo);
+ }
+ else {
+ readExternalCombo = true;
+ }
+ if (parsedData["status-monitor"].find("battery_avg_iir_filter") != parsedData["status-monitor"].end()) {
+ auto key = parsedData["status-monitor"]["battery_avg_iir_filter"];
+ convertToUpper(key);
+ batteryFiltered = !key.compare("TRUE");
+ }
+ if (parsedData["status-monitor"].find("battery_time_left_refreshrate") != parsedData["status-monitor"].end()) {
+ auto key = parsedData["status-monitor"]["battery_time_left_refreshrate"];
+ long maxSeconds = 60;
+ long minSeconds = 1;
+
+ long rate = atol(key.c_str());
+
+ if (rate > maxSeconds) {
+ rate = maxSeconds;
+ }
+ else if (rate < minSeconds) {
+ rate = minSeconds;
+ }
+ batteryTimeLeftRefreshRate = rate;
+ }
}
} else {
@@ -978,10 +985,10 @@ void GetConfigSettings(MiniSettings* settings) {
convertToUpper(key);
settings -> realFrequencies = !(key.compare("TRUE"));
}
- if (parsedData["mini"].find("real_volts") != parsedData["mini"].end()) {
- key = parsedData["mini"]["real_volts"];
- convertToUpper(key);
- settings -> realVolts = !(key.compare("TRUE"));
+ if (parsedData["mini"].find("real_volts") != parsedData["mini"].end()) {
+ key = parsedData["mini"]["real_volts"];
+ convertToUpper(key);
+ settings -> realVolts = !(key.compare("TRUE"));
}
long maxFontSize = 32;
@@ -1056,7 +1063,7 @@ void GetConfigSettings(MiniSettings* settings) {
void GetConfigSettings(MicroSettings* settings) {
settings -> realFrequencies = false;
- settings -> realVolts = false;
+ settings -> realVolts = false;
settings -> handheldFontSize = 18;
settings -> dockedFontSize = 18;
settings -> alignTo = 1;
@@ -1102,11 +1109,11 @@ void GetConfigSettings(MicroSettings* settings) {
convertToUpper(key);
settings -> realFrequencies = !(key.compare("TRUE"));
}
- if (parsedData["micro"].find("real_volts") != parsedData["micro"].end()) {
- key = parsedData["micro"]["real_volts"];
- convertToUpper(key);
- settings -> realVolts = !(key.compare("TRUE"));
- }
+ if (parsedData["micro"].find("real_volts") != parsedData["micro"].end()) {
+ key = parsedData["micro"]["real_volts"];
+ convertToUpper(key);
+ settings -> realVolts = !(key.compare("TRUE"));
+ }
if (parsedData["micro"].find("text_align") != parsedData["micro"].end()) {
key = parsedData["micro"]["text_align"];
convertToUpper(key);
@@ -1262,8 +1269,8 @@ void GetConfigSettings(FpsGraphSettings* settings) {
convertStrToRGBA4444("#FFFF", &(settings -> maxFPSTextColor));
convertStrToRGBA4444("#FFFF", &(settings -> minFPSTextColor));
convertStrToRGBA4444("#FFFF", &(settings -> mainLineColor));
- convertStrToRGBA4444("#0C0F", &(settings -> roundedLineColor));
- convertStrToRGBA4444("#F0FF", &(settings -> perfectLineColor));
+ convertStrToRGBA4444("#F0FF", &(settings -> roundedLineColor));
+ convertStrToRGBA4444("#0C0F", &(settings -> perfectLineColor));
settings -> refreshRate = 31;
FILE* configFileIn = fopen("sdmc:/config/status-monitor/config.ini", "r");
@@ -1414,4 +1421,4 @@ void GetConfigSettings(FullSettings* settings) {
convertToUpper(key);
settings -> showTargetFreqs = key.compare("FALSE");
}
-}
\ No newline at end of file
+}
diff --git a/source/audsnoop.c b/source/audsnoop.c
index 18308773..bb69fcd0 100644
--- a/source/audsnoop.c
+++ b/source/audsnoop.c
@@ -27,7 +27,7 @@ Result audsnoopDisableDspUsageMeasurement(void) {
}
Result audsnoopGetDspUsage(u32 *usage) {
- u32 tmp;
+ u32 tmp = 0;
Result rc = serviceDispatchOut(&g_audsnoopSrv, 6, tmp);
if (R_SUCCEEDED(rc) && usage)
*usage = tmp;
diff --git a/source/main.cpp b/source/main.cpp
index 116d20a7..b17fcaff 100755
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -2,13 +2,16 @@
#include
#include "Utils.hpp"
-#include "FullOverlay.hpp"
-#include "MiniOverlay.hpp"
-#include "MicroOverlay.hpp"
-#include "FPSCounterOverlay.hpp"
-#include "FPSGraphOverlay.hpp"
-#include "BatteryOverlay.hpp"
-#include "MiscOverlay.hpp"
+static tsl::elm::OverlayFrame* rootFrame = nullptr;
+static bool skipMain = false;
+
+#include "modes/FPS_Counter.hpp"
+#include "modes/FPS_Graph.hpp"
+#include "modes/Full.hpp"
+#include "modes/Mini.hpp"
+#include "modes/Micro.hpp"
+#include "modes/Battery.hpp"
+#include "modes/Misc.hpp"
//Graphs
class GraphsMenu : public tsl::Gui {
@@ -16,7 +19,7 @@ class GraphsMenu : public tsl::Gui {
GraphsMenu() {}
virtual tsl::elm::Element* createUI() override {
- rootFrame = new tsl::elm::OverlayFrame("Ultra Monitor", "FPS");
+ rootFrame = new tsl::elm::OverlayFrame("Status Monitor", "FPS");
auto list = new tsl::elm::List();
auto comFPSGraph = new tsl::elm::ListItem("Graph");
@@ -47,8 +50,7 @@ class GraphsMenu : public tsl::Gui {
virtual void update() override {}
virtual bool handleInput(uint64_t keysDown, uint64_t keysHeld, touchPosition touchInput, JoystickPosition leftJoyStick, JoystickPosition rightJoyStick) override {
- if (keysHeld & KEY_B) {
- returningFromSelection = true;
+ if (keysDown & KEY_B) {
tsl::goBack();
return true;
}
@@ -93,17 +95,10 @@ class OtherMenu : public tsl::Gui {
virtual void update() override {}
virtual bool handleInput(uint64_t keysDown, uint64_t keysHeld, touchPosition touchInput, JoystickPosition leftJoyStick, JoystickPosition rightJoyStick) override {
- if (!returningFromSelection && (keysHeld & KEY_B)) {
- returningFromSelection = true;
+ if (keysDown & KEY_B) {
tsl::goBack();
return true;
}
- if (returningFromSelection && !(keysHeld & KEY_B)) {
- returningFromSelection = false;
- }
- if (keysHeld & KEY_B) {
- return false;
- }
return false;
}
};
@@ -196,16 +191,10 @@ class MainMenu : public tsl::Gui {
}
virtual bool handleInput(uint64_t keysDown, uint64_t keysHeld, touchPosition touchInput, JoystickPosition leftJoyStick, JoystickPosition rightJoyStick) override {
- if (!returningFromSelection && (keysHeld & KEY_B)) {
+ if (keysDown & KEY_B) {
tsl::goBack();
return true;
}
- if (returningFromSelection && !(keysHeld & KEY_B)) {
- returningFromSelection = false;
- }
- if (keysHeld & KEY_B) {
- return false;
- }
return false;
}
};
@@ -216,11 +205,11 @@ class MonitorOverlay : public tsl::Overlay {
virtual void initServices() override {
//Initialize services
tsl::hlp::doWithSmSession([this]{
-
+
apmInitialize();
if (hosversionAtLeast(8,0,0)) clkrstCheck = clkrstInitialize();
else pcvCheck = pcvInitialize();
-
+
tsCheck = tsInitialize();
if (hosversionAtLeast(5,0,0)) tcCheck = tcInitialize();
@@ -234,18 +223,18 @@ class MonitorOverlay : public tsl::Overlay {
psmCheck = psmInitialize();
if (R_SUCCEEDED(psmCheck)) {
psmService = psmGetServiceSession();
- i2cInitialize();
}
-
+ i2cInitialize();
+
SaltySD = CheckPort();
-
+
if (SaltySD) {
LoadSharedMemory();
}
if (sysclkIpcRunning() && R_SUCCEEDED(sysclkIpcInitialize())) {
uint32_t sysClkApiVer = 0;
sysclkIpcGetAPIVersion(&sysClkApiVer);
- if (sysClkApiVer != 4) {
+ if (sysClkApiVer < 4) {
sysclkIpcExit();
}
else sysclkCheck = 0;
@@ -267,11 +256,10 @@ class MonitorOverlay : public tsl::Overlay {
tcExit();
fanControllerClose(&g_ICon);
fanExit();
- nvMapExit();
nvClose(fd);
nvExit();
- i2cExit();
psmExit();
+ i2cExit();
apmExit();
}
@@ -289,11 +277,10 @@ class MicroMode : public tsl::Overlay {
virtual void initServices() override {
//Initialize services
tsl::hlp::doWithSmSession([this]{
-
apmInitialize();
if (hosversionAtLeast(8,0,0)) clkrstCheck = clkrstInitialize();
else pcvCheck = pcvInitialize();
-
+
if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu");
tsCheck = tsInitialize();
@@ -304,21 +291,22 @@ class MicroMode : public tsl::Overlay {
else fanCheck = fanOpenController(&g_ICon, 1);
}
+ i2cInitialize();
+
psmCheck = psmInitialize();
if (R_SUCCEEDED(psmCheck)) {
psmService = psmGetServiceSession();
- i2cInitialize();
}
-
+
SaltySD = CheckPort();
-
+
if (SaltySD) {
LoadSharedMemory();
}
if (sysclkIpcRunning() && R_SUCCEEDED(sysclkIpcInitialize())) {
uint32_t sysClkApiVer = 0;
sysclkIpcGetAPIVersion(&sysClkApiVer);
- if (sysClkApiVer != 4) {
+ if (sysClkApiVer < 4) {
sysclkIpcExit();
}
else sysclkCheck = 0;
@@ -330,6 +318,9 @@ class MicroMode : public tsl::Overlay {
virtual void exitServices() override {
CloseThreads();
shmemClose(&_sharedmemory);
+ if (R_SUCCEEDED(sysclkCheck)) {
+ sysclkIpcExit();
+ }
//Exit services
clkrstExit();
pcvExit();
diff --git a/source/modes/Battery.hpp b/source/modes/Battery.hpp
index e2f835aa..a766f4a9 100644
--- a/source/modes/Battery.hpp
+++ b/source/modes/Battery.hpp
@@ -1,13 +1,9 @@
-#pragma once
-#include
-#include "common.hpp"
-
-//Battery
class BatteryOverlay : public tsl::Gui {
private:
char Battery_c[512];
public:
BatteryOverlay() {
+ mutexInit(&mutex_BatteryChecker);
StartBatteryThread();
}
~BatteryOverlay() {
@@ -15,16 +11,11 @@ class BatteryOverlay : public tsl::Gui {
}
virtual tsl::elm::Element* createUI() override {
- rootFrame = new tsl::elm::OverlayFrame("Ultra Monitor", APP_VERSION);
+ rootFrame = new tsl::elm::OverlayFrame("Status Monitor", APP_VERSION);
auto Status = new tsl::elm::CustomDrawer([this](tsl::gfx::Renderer *renderer, u16 x, u16 y, u16 w, u16 h) {
-
- if (R_SUCCEEDED(psmCheck)) {
-
- renderer->drawString("Battery/Charger Stats:", false, 20, 120, 20, renderer->a(0xFFFF));
- renderer->drawString(Battery_c, false, 20, 155, 18, renderer->a(0xFFFF));
- }
-
+ renderer->drawString("Battery/Charger Stats:", false, 20, 120, 20, renderer->a(0xFFFF));
+ renderer->drawString(Battery_c, false, 20, 155, 18, renderer->a(0xFFFF));
});
rootFrame->setContent(Status);
@@ -36,6 +27,7 @@ class BatteryOverlay : public tsl::Gui {
///Battery
+ mutexLock(&mutex_BatteryChecker);
char tempBatTimeEstimate[8] = "-:--";
if (batTimeEstimate >= 0) {
snprintf(&tempBatTimeEstimate[0], sizeof(tempBatTimeEstimate), "%d:%02d", batTimeEstimate / 60, batTimeEstimate % 60);
@@ -44,11 +36,13 @@ class BatteryOverlay : public tsl::Gui {
BatteryChargeInfoFieldsChargerType ChargerConnected = _batteryChargeInfoFields.ChargerType;
int32_t ChargerVoltageLimit = _batteryChargeInfoFields.ChargerVoltageLimit;
int32_t ChargerCurrentLimit = _batteryChargeInfoFields.ChargerCurrentLimit;
+
if (hosversionAtLeast(17,0,0)) {
ChargerConnected = ((BatteryChargeInfoFields17*)&_batteryChargeInfoFields) -> ChargerType;
ChargerVoltageLimit = ((BatteryChargeInfoFields17*)&_batteryChargeInfoFields) -> ChargerVoltageLimit;
ChargerCurrentLimit = ((BatteryChargeInfoFields17*)&_batteryChargeInfoFields) -> ChargerCurrentLimit;
}
+
if (ChargerConnected)
snprintf(Battery_c, sizeof Battery_c,
"Battery Actual Capacity: %.0f mAh\n"
@@ -56,9 +50,9 @@ class BatteryOverlay : public tsl::Gui {
"Battery Temperature: %.1f\u00B0C\n"
"Battery Raw Charge: %.1f%%\n"
"Battery Age: %.1f%%\n"
- "Battery Voltage (5s AVG): %.0f mV\n"
- "Battery Current Flow (5s AVG): %+.0f mA\n"
- "Battery Power Flow (5s AVG): %+.3f W\n"
+ "Battery Voltage (%ds AVG): %.0f mV\n"
+ "Battery Current Flow (%ss AVG): %+.0f mA\n"
+ "Battery Power Flow%s: %+.3f W\n"
"Battery Remaining Time: %s\n"
"Charger Type: %u\n"
"Charger Max Voltage: %u mV\n"
@@ -68,9 +62,9 @@ class BatteryOverlay : public tsl::Gui {
(float)_batteryChargeInfoFields.BatteryTemperature / 1000,
(float)_batteryChargeInfoFields.RawBatteryCharge / 1000,
(float)_batteryChargeInfoFields.BatteryAge / 1000,
- batVoltageAvg,
- batCurrentAvg,
- PowerConsumption,
+ batteryFiltered ? 45 : 5, batVoltageAvg,
+ batteryFiltered ? "11.25" : "5", batCurrentAvg,
+ batteryFiltered ? "" : " (5s AVG)", PowerConsumption,
tempBatTimeEstimate,
ChargerConnected,
ChargerVoltageLimit,
@@ -83,28 +77,28 @@ class BatteryOverlay : public tsl::Gui {
"Battery Temperature: %.1f\u00B0C\n"
"Battery Raw Charge: %.1f%%\n"
"Battery Age: %.1f%%\n"
- "Battery Voltage (5s AVG): %.0f mV\n"
- "Battery Current Flow (5s AVG): %.0f mA\n"
- "Battery Power Flow (5s AVG): %+.3f W\n"
+ "Battery Voltage (%ds AVG): %.0f mV\n"
+ "Battery Current Flow (%ss AVG): %+.0f mA\n"
+ "Battery Power Flow%s: %+.3f W\n"
"Battery Remaining Time: %s",
actualFullBatCapacity,
designedFullBatCapacity,
(float)_batteryChargeInfoFields.BatteryTemperature / 1000,
(float)_batteryChargeInfoFields.RawBatteryCharge / 1000,
(float)_batteryChargeInfoFields.BatteryAge / 1000,
- batVoltageAvg,
- batCurrentAvg,
- PowerConsumption,
+ batteryFiltered ? 45 : 5, batVoltageAvg,
+ batteryFiltered ? "11.25" : "5", batCurrentAvg,
+ batteryFiltered ? "" : " (5s AVG)", PowerConsumption,
tempBatTimeEstimate
);
+ mutexUnlock(&mutex_BatteryChecker);
}
virtual bool handleInput(uint64_t keysDown, uint64_t keysHeld, touchPosition touchInput, JoystickPosition leftJoyStick, JoystickPosition rightJoyStick) override {
- if (keysHeld & KEY_B) {
- returningFromSelection = true;
+ if (keysDown & KEY_B) {
tsl::goBack();
return true;
}
return false;
}
-};
\ No newline at end of file
+};
diff --git a/source/modes/FPS_Counter.hpp b/source/modes/FPS_Counter.hpp
index 2e3222b9..70889db6 100644
--- a/source/modes/FPS_Counter.hpp
+++ b/source/modes/FPS_Counter.hpp
@@ -1,11 +1,6 @@
-#pragma once
-#include
-#include "common.hpp"
-
-//FPS Counter mode
class com_FPS : public tsl::Gui {
private:
- std::list mappedButtons = buttonMapper.MapButtons(keyCombo); // map buttons
+ uint64_t mappedButtons = MapButtons(keyCombo); // map buttons
char FPSavg_c[8];
FpsCounterSettings settings;
size_t fontsize = 0;
@@ -104,17 +99,7 @@ class com_FPS : public tsl::Gui {
}
virtual bool handleInput(uint64_t keysDown, uint64_t keysHeld, touchPosition touchInput, JoystickPosition leftJoyStick, JoystickPosition rightJoyStick) override {
-
- bool allButtonsHeld = true;
- for (const HidNpadButton& button : mappedButtons) {
- if (!(keysHeld & static_cast(button))) {
- allButtonsHeld = false;
- break;
- }
- }
-
- if (allButtonsHeld) {
- returningFromSelection = true;
+ if (isKeyComboPressed(keysHeld, keysDown, mappedButtons)) {
tsl::goBack();
return true;
}
diff --git a/source/modes/FPS_Graph.hpp b/source/modes/FPS_Graph.hpp
index 8b9a07e9..1470d9ad 100644
--- a/source/modes/FPS_Graph.hpp
+++ b/source/modes/FPS_Graph.hpp
@@ -1,11 +1,6 @@
-#pragma once
-#include
-#include "common.hpp"
-
-//FPS Graph mode
class com_FPSGraph : public tsl::Gui {
private:
- std::list mappedButtons = buttonMapper.MapButtons(keyCombo); // map buttons
+ uint64_t mappedButtons = MapButtons(keyCombo); // map buttons
char FPSavg_c[8];
FpsGraphSettings settings;
public:
@@ -184,17 +179,7 @@ class com_FPSGraph : public tsl::Gui {
}
virtual bool handleInput(uint64_t keysDown, uint64_t keysHeld, touchPosition touchInput, JoystickPosition leftJoyStick, JoystickPosition rightJoyStick) override {
-
- bool allButtonsHeld = true;
- for (const HidNpadButton& button : mappedButtons) {
- if (!(keysHeld & static_cast(button))) {
- allButtonsHeld = false;
- break;
- }
- }
-
- if (allButtonsHeld) {
- returningFromSelection = true;
+ if (isKeyComboPressed(keysHeld, keysDown, mappedButtons)) {
TeslaFPS = 60;
tsl::goBack();
return true;
diff --git a/source/modes/Full.hpp b/source/modes/Full.hpp
index 86a4ecb8..1c947236 100644
--- a/source/modes/Full.hpp
+++ b/source/modes/Full.hpp
@@ -1,55 +1,52 @@
-#pragma once
-#include
-#include "common.hpp"
-
-//Full mode
class FullOverlay : public tsl::Gui {
private:
- std::list mappedButtons = buttonMapper.MapButtons(keyCombo); // map buttons
- char RealCPU_Hz_c[32];
- char DeltaCPU_c[12];
- char DeltaGPU_c[12];
- char DeltaRAM_c[12];
- char RealGPU_Hz_c[32];
- char RealRAM_Hz_c[32];
- char GPU_Load_c[32];
- char Rotation_SpeedLevel_c[64];
- char RAM_compressed_c[64];
- char RAM_var_compressed_c[128];
- char CPU_Hz_c[64];
- char GPU_Hz_c[64];
- char RAM_Hz_c[64];
- char CPU_compressed_c[160];
- char CPU_Usage0[32];
- char CPU_Usage1[32];
- char CPU_Usage2[32];
- char CPU_Usage3[32];
- char SoCPCB_temperature_c[64];
- char skin_temperature_c[32];
- char BatteryDraw_c[64];
- char FPS_var_compressed_c[64];
- char RAM_load_c[64];
+ uint64_t mappedButtons = MapButtons(keyCombo); // map buttons
+ char RealCPU_Hz_c[32] = "";
+ char DeltaCPU_c[12] = "";
+ char DeltaGPU_c[12] = "";
+ char DeltaRAM_c[12] = "";
+ char RealGPU_Hz_c[32] = "";
+ char RealRAM_Hz_c[32] = "";
+ char GPU_Load_c[32] = "";
+ char Rotation_SpeedLevel_c[64] = "";
+ char RAM_compressed_c[64] = "";
+ char RAM_var_compressed_c[128] = "";
+ char CPU_Hz_c[64] = "";
+ char GPU_Hz_c[64] = "";
+ char RAM_Hz_c[64] = "";
+ char CPU_compressed_c[160] = "";
+ char CPU_Usage0[32] = "";
+ char CPU_Usage1[32] = "";
+ char CPU_Usage2[32] = "";
+ char CPU_Usage3[32] = "";
+ char SoCPCB_temperature_c[64] = "";
+ char skin_temperature_c[32] = "";
+ char BatteryDraw_c[64] = "";
+ char FPS_var_compressed_c[64] = "";
+ char RAM_load_c[64] = "";
uint8_t COMMON_MARGIN = 20;
FullSettings settings;
+ uint64_t systemtickfrequency_impl = systemtickfrequency;
public:
FullOverlay() {
GetConfigSettings(&settings);
- StartThreads();
+ mutexInit(&mutex_BatteryChecker);
+ mutexInit(&mutex_Misc);
tsl::hlp::requestForeground(false);
TeslaFPS = settings.refreshRate;
- systemtickfrequency /= settings.refreshRate;
+ systemtickfrequency_impl /= settings.refreshRate;
if (settings.setPosRight) {
tsl::gfx::Renderer::getRenderer().setLayerPos(1248, 0);
}
deactivateOriginalFooter = true;
+ StartThreads();
}
~FullOverlay() {
CloseThreads();
FullMode = true;
tsl::hlp::requestForeground(true);
alphabackground = 0xD;
- systemtickfrequency = 19200000;
if (settings.setPosRight) {
tsl::gfx::Renderer::getRenderer().setLayerPos(0, 0);
}
@@ -57,7 +54,7 @@ class FullOverlay : public tsl::Gui {
}
virtual tsl::elm::Element* createUI() override {
- rootFrame = new tsl::elm::OverlayFrame("Ultra Monitor", APP_VERSION);
+ rootFrame = new tsl::elm::OverlayFrame("Status Monitor", APP_VERSION);
auto Status = new tsl::elm::CustomDrawer([this](tsl::gfx::Renderer *renderer, u16 x, u16 y, u16 w, u16 h) {
@@ -206,26 +203,30 @@ class FullOverlay : public tsl::Gui {
}
virtual void update() override {
- //In case of getting more than systemtickfrequency in idle, make it equal to systemtickfrequency to get 0% as output and nothing less
- //This is because making each loop also takes time, which is not considered because this will take also additional time
- if (idletick0 > systemtickfrequency) idletick0 = systemtickfrequency;
- if (idletick1 > systemtickfrequency) idletick1 = systemtickfrequency;
- if (idletick2 > systemtickfrequency) idletick2 = systemtickfrequency;
- if (idletick3 > systemtickfrequency) idletick3 = systemtickfrequency;
-
//Make stuff ready to print
///CPU
+ if (idletick0 > systemtickfrequency_impl)
+ strcpy(CPU_Usage0, "Core #0: 0.00%");
+ else snprintf(CPU_Usage0, sizeof CPU_Usage0, "Core #0: %.2f%%", (1.d - ((double)idletick0 / systemtickfrequency_impl)) * 100);
+ if (idletick1 > systemtickfrequency_impl)
+ strcpy(CPU_Usage1, "Core #1: 0.00%");
+ else snprintf(CPU_Usage1, sizeof CPU_Usage1, "Core #1: %.2f%%", (1.d - ((double)idletick1 / systemtickfrequency_impl)) * 100);
+ if (idletick2 > systemtickfrequency_impl)
+ strcpy(CPU_Usage2, "Core #2: 0.00%");
+ else snprintf(CPU_Usage2, sizeof CPU_Usage2, "Core #2: %.2f%%", (1.d - ((double)idletick2 / systemtickfrequency_impl)) * 100);
+ if (idletick3 > systemtickfrequency_impl)
+ strcpy(CPU_Usage3, "Core #3: 0.00%");
+ else snprintf(CPU_Usage3, sizeof CPU_Usage3, "Core #3: %.2f%%", (1.d - ((double)idletick3 / systemtickfrequency_impl)) * 100);
+
+ snprintf(CPU_compressed_c, sizeof CPU_compressed_c, "%s\n%s\n%s\n%s", CPU_Usage0, CPU_Usage1, CPU_Usage2, CPU_Usage3);
+
+ mutexLock(&mutex_Misc);
snprintf(CPU_Hz_c, sizeof(CPU_Hz_c), "%u.%u MHz", CPU_Hz / 1000000, (CPU_Hz / 100000) % 10);
if (realCPU_Hz) {
snprintf(RealCPU_Hz_c, sizeof(RealCPU_Hz_c), "%u.%u MHz", realCPU_Hz / 1000000, (realCPU_Hz / 100000) % 10);
int32_t deltaCPU = (int32_t)(realCPU_Hz / 1000) - (CPU_Hz / 1000);
snprintf(DeltaCPU_c, sizeof(DeltaCPU_c), "Δ %d.%u", deltaCPU / 1000, abs(deltaCPU / 100) % 10);
}
- snprintf(CPU_Usage0, sizeof CPU_Usage0, "Core #0: %.2f%%", (1.d - ((double)idletick0 / systemtickfrequency)) * 100);
- snprintf(CPU_Usage1, sizeof CPU_Usage1, "Core #1: %.2f%%", (1.d - ((double)idletick1 / systemtickfrequency)) * 100);
- snprintf(CPU_Usage2, sizeof CPU_Usage2, "Core #2: %.2f%%", (1.d - ((double)idletick2 / systemtickfrequency)) * 100);
- snprintf(CPU_Usage3, sizeof CPU_Usage3, "Core #3: %.2f%%", (1.d - ((double)idletick3 / systemtickfrequency)) * 100);
- snprintf(CPU_compressed_c, sizeof CPU_compressed_c, "%s\n%s\n%s\n%s", CPU_Usage0, CPU_Usage1, CPU_Usage2, CPU_Usage3);
///GPU
snprintf(GPU_Hz_c, sizeof GPU_Hz_c, "%u.%u MHz", GPU_Hz / 1000000, (GPU_Hz / 100000) % 10);
@@ -274,12 +275,6 @@ class FullOverlay : public tsl::Gui {
RAM_GPU_Load / 10, RAM_GPU_Load % 10);
}
///Thermal
- char remainingBatteryLife[8];
- if (batTimeEstimate >= 0) {
- snprintf(remainingBatteryLife, sizeof remainingBatteryLife, "%d:%02d", batTimeEstimate / 60, batTimeEstimate % 60);
- }
- else snprintf(remainingBatteryLife, sizeof remainingBatteryLife, "-:--");
- snprintf(BatteryDraw_c, sizeof BatteryDraw_c, "Battery Power Flow: %+.2fW[%s]", PowerConsumption, remainingBatteryLife);
if (hosversionAtLeast(10,0,0)) {
snprintf(SoCPCB_temperature_c, sizeof SoCPCB_temperature_c,
"%2.1f\u00B0C\n%2.1f\u00B0C\n%2d.%d\u00B0C",
@@ -296,27 +291,26 @@ class FullOverlay : public tsl::Gui {
///FPS
snprintf(FPS_var_compressed_c, sizeof FPS_var_compressed_c, "%u\n%2.1f", FPS, FPSavg);
+
+ mutexUnlock(&mutex_Misc);
+
+ //Battery Power Flow
+ char remainingBatteryLife[8];
+ mutexLock(&mutex_BatteryChecker);
+ if (batTimeEstimate >= 0) {
+ snprintf(remainingBatteryLife, sizeof remainingBatteryLife, "%d:%02d", batTimeEstimate / 60, batTimeEstimate % 60);
+ }
+ else snprintf(remainingBatteryLife, sizeof remainingBatteryLife, "-:--");
+ snprintf(BatteryDraw_c, sizeof BatteryDraw_c, "Battery Power Flow: %+.2fW[%s]", PowerConsumption, remainingBatteryLife);
+ mutexUnlock(&mutex_BatteryChecker);
}
virtual bool handleInput(uint64_t keysDown, uint64_t keysHeld, touchPosition touchInput, JoystickPosition leftJoyStick, JoystickPosition rightJoyStick) override {
-
- bool allButtonsHeld = true;
- for (const HidNpadButton& button : mappedButtons) {
- if (!(keysHeld & static_cast(button))) {
- allButtonsHeld = false;
- break;
- }
- }
-
- if (allButtonsHeld) {
- returningFromSelection = true;
+ if (isKeyComboPressed(keysHeld, keysDown, mappedButtons)) {
TeslaFPS = 60;
tsl::goBack();
return true;
}
- if (keysHeld & KEY_B) {
- return false;
- }
return false;
}
};
\ No newline at end of file
diff --git a/source/modes/Micro.hpp b/source/modes/Micro.hpp
index 17fdefb9..b21aaeba 100644
--- a/source/modes/Micro.hpp
+++ b/source/modes/Micro.hpp
@@ -1,27 +1,22 @@
-#pragma once
-#include
-#include "common.hpp"
-
-//Micro mode
class MicroOverlay : public tsl::Gui {
private:
- std::list mappedButtons = buttonMapper.MapButtons(keyCombo); // map buttons
- char GPU_Load_c[32];
- char Rotation_SpeedLevel_c[64];
- char Power_c[64];
- char RAM_var_compressed_c[128];
- char CPU_compressed_c[160];
- char CPUS_compressed_c[160];
- char CPU_Usage[32];
- char CPU_Usage0[32];
- char CPU_Usage1[32];
- char CPU_Usage2[32];
- char CPU_Usage3[32];
- char skin_temperature_c[48];
- char skin_temperatureB_c[48];
- char skin_temperatureS_c[48];
- char batteryCharge[10]; // Declare the batteryCharge variable
- char FPS_var_compressed_c[64];
+ uint64_t mappedButtons = MapButtons(keyCombo); // map buttons
+ char GPU_Load_c[32] = "";
+ char Rotation_SpeedLevel_c[64] = "";
+ char RAM_var_compressed_c[128] = "";
+ char Power_c[64] = "";
+ char CPU_compressed_c[160] = "";
+ char CPUS_compressed_c[160] = "";
+ char CPU_Usage[32] = "";
+ char CPU_Usage0[32] = "";
+ char CPU_Usage1[32] = "";
+ char CPU_Usage2[32] = "";
+ char CPU_Usage3[32] = "";
+ char skin_temperature_c[48] = "";
+ char skin_temperatureB_c[48] = "";
+ char skin_temperatureS_c[48] = "";
+ char batteryCharge[10] = ""; // Declare the batteryCharge variable
+ char FPS_var_compressed_c[64] = "";
char Battery_c[32];
char BatteryS_c[32];
char CPU_volt_c[10];
@@ -51,6 +46,7 @@ class MicroOverlay : public tsl::Gui {
ApmPerformanceMode performanceMode = ApmPerformanceMode_Invalid;
size_t fontsize = 0;
bool showFPS = false;
+ uint64_t systemtickfrequency_impl = systemtickfrequency;
public:
MicroOverlay() {
GetConfigSettings(&settings);
@@ -64,11 +60,13 @@ class MicroOverlay : public tsl::Gui {
if (settings.setPosBottom) {
tsl::gfx::Renderer::getRenderer().setLayerPos(0, 1038);
}
- StartThreads();
+ mutexInit(&mutex_BatteryChecker);
+ mutexInit(&mutex_Misc);
TeslaFPS = settings.refreshRate;
- systemtickfrequency /= settings.refreshRate;
+ systemtickfrequency_impl /= settings.refreshRate;
alphabackground = 0x0;
deactivateOriginalFooter = true;
+ StartThreads();
}
~MicroOverlay() {
CloseThreads();
@@ -343,16 +341,30 @@ class MicroOverlay : public tsl::Gui {
fontsize = settings.dockedFontSize;
}
}
- //In case of getting more than systemtickfrequency in idle, make it equal to systemtickfrequency to get 0% as output and nothing less
- //This is because making each loop also takes time, which is not considered because this will take also additional time
- if (idletick0 > systemtickfrequency) idletick0 = systemtickfrequency;
- if (idletick1 > systemtickfrequency) idletick1 = systemtickfrequency;
- if (idletick2 > systemtickfrequency) idletick2 = systemtickfrequency;
- if (idletick3 > systemtickfrequency) idletick3 = systemtickfrequency;
- double cpu_usage0 = (1.d - ((double)idletick0 / systemtickfrequency)) * 100;
- double cpu_usage1 = (1.d - ((double)idletick1 / systemtickfrequency)) * 100;
- double cpu_usage2 = (1.d - ((double)idletick2 / systemtickfrequency)) * 100;
- double cpu_usage3 = (1.d - ((double)idletick3 / systemtickfrequency)) * 100;
+
+ //Make stuff ready to print
+ ///CPU
+ /* if (idletick0 > systemtickfrequency_impl)
+ strcpy(CPU_Usage0, "0%");
+ else snprintf(CPU_Usage0, sizeof CPU_Usage0, "%.0f%%", (1.d - ((double)idletick0 / systemtickfrequency_impl)) * 100);
+ if (idletick1 > systemtickfrequency_impl)
+ strcpy(CPU_Usage1, "0%");
+ else snprintf(CPU_Usage1, sizeof CPU_Usage1, "%.0f%%", (1.d - ((double)idletick1 / systemtickfrequency_impl)) * 100);
+ if (idletick2 > systemtickfrequency_impl)
+ strcpy(CPU_Usage2, "0%");
+ else snprintf(CPU_Usage2, sizeof CPU_Usage2, "%.0f%%", (1.d - ((double)idletick2 / systemtickfrequency_impl)) * 100);
+ if (idletick3 > systemtickfrequency_impl)
+ strcpy(CPU_Usage3, "0%");
+ else snprintf(CPU_Usage3, sizeof CPU_Usage3, "%.0f%%", (1.d - ((double)idletick3 / systemtickfrequency_impl)) * 100); */
+
+ if (idletick0 > systemtickfrequency_impl) idletick0 = systemtickfrequency_impl;
+ if (idletick1 > systemtickfrequency_impl) idletick1 = systemtickfrequency_impl;
+ if (idletick2 > systemtickfrequency_impl) idletick2 = systemtickfrequency_impl;
+ if (idletick3 > systemtickfrequency_impl) idletick3 = systemtickfrequency_impl;
+ double cpu_usage0 = (1.d - ((double)idletick0 / systemtickfrequency_impl)) * 100;
+ double cpu_usage1 = (1.d - ((double)idletick1 / systemtickfrequency_impl)) * 100;
+ double cpu_usage2 = (1.d - ((double)idletick2 / systemtickfrequency_impl)) * 100;
+ double cpu_usage3 = (1.d - ((double)idletick3 / systemtickfrequency_impl)) * 100;
double cpu_usageM = 0;
if (cpu_usage0 > cpu_usageM) cpu_usageM = cpu_usage0;
if (cpu_usage1 > cpu_usageM) cpu_usageM = cpu_usage1;
@@ -367,6 +379,7 @@ class MicroOverlay : public tsl::Gui {
snprintf(CPU_Usage2, sizeof CPU_Usage2, "%.0f%%", (1.d - ((double)idletick2 / systemtickfrequency)) * 100);
snprintf(CPU_Usage3, sizeof CPU_Usage3, "%.0f%%", (1.d - ((double)idletick3 / systemtickfrequency)) * 100);
+ mutexLock(&mutex_Misc);
char difference[5] = "@";
if (realCPU_Hz) {
int32_t deltaCPU = (int32_t)(realCPU_Hz / 1000) - (CPU_Hz / 1000);
@@ -380,7 +393,6 @@ class MicroOverlay : public tsl::Gui {
strcpy(difference, "▽");
}
}
-
if (settings.realVolts) {
if (settings.realFrequencies && realCPU_Hz) {
snprintf(CPU_compressed_c, sizeof CPU_compressed_c,
@@ -542,6 +554,7 @@ class MicroOverlay : public tsl::Gui {
///Battery
char remainingBatteryLife[8];
+ mutexLock(&mutex_BatteryChecker);
if (batTimeEstimate >= 0) {
snprintf(remainingBatteryLife, sizeof remainingBatteryLife, "%d:%02d", batTimeEstimate / 60, batTimeEstimate % 60);
}
@@ -639,31 +652,21 @@ class MicroOverlay : public tsl::Gui {
Rotation_SpeedLevel_f * 100);
}
}
+ mutexUnlock(&mutex_BatteryChecker);
snprintf(Rotation_SpeedLevel_c, sizeof Rotation_SpeedLevel_c, "%2.1f%%", Rotation_SpeedLevel_f * 100);
///FPS
snprintf(FPS_var_compressed_c, sizeof FPS_var_compressed_c, "%2.1f", FPSavg);
+
+ mutexUnlock(&mutex_Misc);
}
virtual bool handleInput(uint64_t keysDown, uint64_t keysHeld, touchPosition touchInput, JoystickPosition leftJoyStick, JoystickPosition rightJoyStick) override {
- //std::list mappedButtons;
- //ButtonMapperImpl buttonMapper; // Create an instance of the ButtonMapperImpl class
- //mappedButtons = buttonMapper.MapButtons(keyCombo); // map buttons
-
- bool allButtonsHeld = true;
- for (const HidNpadButton& button : mappedButtons) {
- if (!(keysHeld & static_cast(button))) {
- allButtonsHeld = false;
- break;
- }
- }
-
- if (allButtonsHeld) {
- returningFromSelection = true;
+ if (isKeyComboPressed(keysHeld, keysDown, mappedButtons)) {
TeslaFPS = 60;
if (skipMain)
tsl::goBack();
@@ -673,9 +676,6 @@ class MicroOverlay : public tsl::Gui {
}
return true;
}
- if (keysHeld & KEY_B) {
- return false;
- }
return false;
}
};
\ No newline at end of file
diff --git a/source/modes/Mini.hpp b/source/modes/Mini.hpp
index 400d70e4..33ea0cc8 100644
--- a/source/modes/Mini.hpp
+++ b/source/modes/Mini.hpp
@@ -1,23 +1,19 @@
-#pragma once
-#include
-#include "common.hpp"
-
-//Mini mode
class MiniOverlay : public tsl::Gui {
private:
- std::list mappedButtons = buttonMapper.MapButtons(keyCombo); // map buttons
- char GPU_Load_c[32];
- char Rotation_SpeedLevel_c[64];
- char RAM_var_compressed_c[128];
- char SoCPCB_temperature_c[64];
- char skin_temperature_c[32];
+ uint64_t mappedButtons = MapButtons(keyCombo); // map buttons
+ char GPU_Load_c[32] = "";
+ char Rotation_SpeedLevel_c[64] = "";
+ char RAM_var_compressed_c[128] = "";
+ char SoCPCB_temperature_c[64] = "";
+ char skin_temperature_c[32] = "";
uint32_t rectangleWidth = 0;
- char Variables[512];
+ char Variables[512] = "";
size_t fontsize = 0;
MiniSettings settings;
bool Initialized = false;
ApmPerformanceMode performanceMode = ApmPerformanceMode_Invalid;
+ uint64_t systemtickfrequency_impl = systemtickfrequency;
public:
MiniOverlay() {
GetConfigSettings(&settings);
@@ -25,9 +21,7 @@ class MiniOverlay : public tsl::Gui {
if (performanceMode == ApmPerformanceMode_Normal) {
fontsize = settings.handheldFontSize;
}
- else if (performanceMode == ApmPerformanceMode_Boost) {
- fontsize = settings.dockedFontSize;
- }
+ else fontsize = settings.dockedFontSize;
switch(settings.setPos) {
case 1:
case 4:
@@ -40,20 +34,21 @@ class MiniOverlay : public tsl::Gui {
tsl::gfx::Renderer::getRenderer().setLayerPos(1248, 0);
break;
}
- StartThreads();
+ mutexInit(&mutex_BatteryChecker);
+ mutexInit(&mutex_Misc);
alphabackground = 0x0;
tsl::hlp::requestForeground(false);
FullMode = false;
TeslaFPS = settings.refreshRate;
- systemtickfrequency /= settings.refreshRate;
+ systemtickfrequency_impl /= settings.refreshRate;
deactivateOriginalFooter = true;
+ StartThreads();
}
~MiniOverlay() {
CloseThreads();
FullMode = true;
tsl::hlp::requestForeground(true);
alphabackground = 0xD;
- systemtickfrequency = 19200000;
deactivateOriginalFooter = false;
}
@@ -114,50 +109,50 @@ class MiniOverlay : public tsl::Gui {
if (print_text[0])
strcat(print_text, "\n");
strcat(print_text, "CPU");
- if (settings.realVolts)
- strcat(print_text, "\n");
entry_count++;
- if (settings.realVolts)
+ if (settings.realVolts) {
+ strcat(print_text, "\n");
entry_count++;
+ }
flags |= (1 << 0);
}
else if (!key.compare("GPU") && !(flags & 1 << 1)) {
if (print_text[0])
strcat(print_text, "\n");
strcat(print_text, "GPU");
- if (settings.realVolts)
- strcat(print_text, "\n");
entry_count++;
- if (settings.realVolts)
+ if (settings.realVolts) {
+ strcat(print_text, "\n");
entry_count++;
+ }
flags |= (1 << 1);
}
else if (!key.compare("RAM") && !(flags & 1 << 2)) {
if (print_text[0])
strcat(print_text, "\n");
strcat(print_text, "RAM");
- if (settings.realVolts)
- strcat(print_text, "\n");
entry_count++;
- if (settings.realVolts)
+ if (settings.realVolts) {
+ strcat(print_text, "\n");
entry_count++;
+ }
flags |= (1 << 2);
}
- else if (!key.compare("DRAW") && !(flags & 1 << 3)) {
+ else if (!key.compare("TEMP") && !(flags & 1 << 3)) {
if (print_text[0])
strcat(print_text, "\n");
- strcat(print_text, "DRAW");
- if (settings.realVolts)
- strcat(print_text, "\n");
+ strcat(print_text, "TEMP");
entry_count++;
- if (settings.realVolts)
+ if (settings.realVolts) {
+ strcat(print_text, "\n");
entry_count++;
+ }
flags |= (1 << 3);
}
- else if (!key.compare("TEMP") && !(flags & 1 << 4)) {
+ else if (!key.compare("DRAW") && !(flags & 1 << 4)) {
if (print_text[0])
strcat(print_text, "\n");
- strcat(print_text, "TEMP");
+ strcat(print_text, "DRAW");
entry_count++;
flags |= (1 << 4);
}
@@ -209,8 +204,9 @@ class MiniOverlay : public tsl::Gui {
}
renderer->drawRect(base_x, base_y, margin + rectangleWidth + (fontsize / 3), height, a(settings.backgroundColor));
-
renderer->drawString(print_text, false, base_x, base_y + fontsize, fontsize, renderer->a(settings.catColor));
+
+ ///GPU
renderer->drawString(Variables, false, base_x + margin, base_y + fontsize, fontsize, renderer->a(settings.textColor));
});
@@ -233,13 +229,7 @@ class MiniOverlay : public tsl::Gui {
fontsize = settings.dockedFontSize;
}
}
- //In case of getting more than systemtickfrequency in idle, make it equal to systemtickfrequency to get 0% as output and nothing less
- //This is because making each loop also takes time, which is not considered because this will take also additional time
- if (idletick0 > systemtickfrequency) idletick0 = systemtickfrequency;
- if (idletick1 > systemtickfrequency) idletick1 = systemtickfrequency;
- if (idletick2 > systemtickfrequency) idletick2 = systemtickfrequency;
- if (idletick3 > systemtickfrequency) idletick3 = systemtickfrequency;
-
+
//Make stuff ready to print
///CPU
char MINI_CPU_Usage0[7] = "";
@@ -247,13 +237,23 @@ class MiniOverlay : public tsl::Gui {
char MINI_CPU_Usage2[7] = "";
char MINI_CPU_Usage3[7] = "";
- snprintf(MINI_CPU_Usage0, sizeof(MINI_CPU_Usage0), "%.0f%%", (1.d - ((double)idletick0 / systemtickfrequency)) * 100);
- snprintf(MINI_CPU_Usage1, sizeof(MINI_CPU_Usage1), "%.0f%%", (1.d - ((double)idletick1 / systemtickfrequency)) * 100);
- snprintf(MINI_CPU_Usage2, sizeof(MINI_CPU_Usage2), "%.0f%%", (1.d - ((double)idletick2 / systemtickfrequency)) * 100);
- snprintf(MINI_CPU_Usage3, sizeof(MINI_CPU_Usage3), "%.0f%%", (1.d - ((double)idletick3 / systemtickfrequency)) * 100);
+ if (idletick0 > systemtickfrequency_impl)
+ strcpy(MINI_CPU_Usage0, "0%");
+ else snprintf(MINI_CPU_Usage0, sizeof(MINI_CPU_Usage0), "%.0f%%", (1.d - ((double)idletick0 / systemtickfrequency_impl)) * 100);
+ if (idletick1 > systemtickfrequency_impl)
+ strcpy(MINI_CPU_Usage1, "0%");
+ else snprintf(MINI_CPU_Usage1, sizeof(MINI_CPU_Usage1), "%.0f%%", (1.d - ((double)idletick1 / systemtickfrequency_impl)) * 100);
+ if (idletick2 > systemtickfrequency_impl)
+ strcpy(MINI_CPU_Usage2, "0%");
+ else snprintf(MINI_CPU_Usage2, sizeof(MINI_CPU_Usage2), "%.0f%%", (1.d - ((double)idletick2 / systemtickfrequency_impl)) * 100);
+ if (idletick3 > systemtickfrequency_impl)
+ strcpy(MINI_CPU_Usage3, "0%");
+ else snprintf(MINI_CPU_Usage3, sizeof(MINI_CPU_Usage3), "%.0f%%", (1.d - ((double)idletick3 / systemtickfrequency_impl)) * 100);
+
+ mutexLock(&mutex_Misc);
char MINI_CPU_compressed_c[42] = "";
- char MINI_CPU_volt_c[7] = "";
+ char MINI_CPU_volt_c[7] = "";
if (settings.realFrequencies && realCPU_Hz) {
snprintf(MINI_CPU_compressed_c, sizeof(MINI_CPU_compressed_c),
"[%s,%s,%s,%s]@%hu.%hhu",
@@ -270,7 +270,6 @@ class MiniOverlay : public tsl::Gui {
snprintf(MINI_CPU_volt_c, sizeof(MINI_CPU_volt_c), "%umV", realCPU_mV);
}
- ///GPU
char MINI_GPU_Load_c[14];
char MINI_GPU_volt_c[7] = "";
if (settings.realFrequencies && realGPU_Hz) {
@@ -335,14 +334,6 @@ class MiniOverlay : public tsl::Gui {
}
///Thermal
- char MINI_SOC_volt_c[7] = "";
- char remainingBatteryLife[8];
- if (batTimeEstimate >= 0) {
- snprintf(remainingBatteryLife, sizeof remainingBatteryLife, "%d:%02d", batTimeEstimate / 60, batTimeEstimate % 60);
- }
- else snprintf(remainingBatteryLife, sizeof remainingBatteryLife, "--:--");
-
- snprintf(SoCPCB_temperature_c, sizeof SoCPCB_temperature_c, "%0.2fW[%s]", PowerConsumption, remainingBatteryLife);
if (hosversionAtLeast(10,0,0)) {
snprintf(skin_temperature_c, sizeof skin_temperature_c,
"%2.1f\u00B0C/%2.1f\u00B0C/%hu.%hhu\u00B0C",
@@ -356,6 +347,7 @@ class MiniOverlay : public tsl::Gui {
PCB_temperatureC / 1000, (PCB_temperatureC / 100) % 10,
skin_temperaturemiliC / 1000, (skin_temperaturemiliC / 100) % 10);
}
+ char MINI_SOC_volt_c[7] = "";
snprintf(Rotation_SpeedLevel_c, sizeof Rotation_SpeedLevel_c, "%2.1f%%", Rotation_SpeedLevel_f * 100);
if (settings.realVolts) {
snprintf(MINI_SOC_volt_c, sizeof(MINI_SOC_volt_c), "%umV", realSOC_mV);
@@ -398,29 +390,29 @@ class MiniOverlay : public tsl::Gui {
}
flags |= 1 << 2;
}
- else if (!key.compare("DRAW") && !(flags & 1 << 3)) {
+ else if (!key.compare("TEMP") && !(flags & 1 << 3)) {
if (Temp[0]) {
strcat(Temp, "\n");
}
- strcat(Temp, SoCPCB_temperature_c);
+ strcat(Temp, skin_temperature_c);
if (settings.realVolts) {
strcat(Temp, "\n");
strcat(Temp, MINI_SOC_volt_c);
}
flags |= 1 << 3;
}
- else if (!key.compare("TEMP") && !(flags & 1 << 4)) {
+ else if (!key.compare("FAN") && !(flags & 1 << 4)) {
if (Temp[0]) {
strcat(Temp, "\n");
}
- strcat(Temp, skin_temperature_c);
+ strcat(Temp, Rotation_SpeedLevel_c);
flags |= 1 << 4;
}
- else if (!key.compare("FAN") && !(flags & 1 << 5)) {
+ else if (!key.compare("DRAW") && !(flags & 1 << 5)) {
if (Temp[0]) {
strcat(Temp, "\n");
}
- strcat(Temp, Rotation_SpeedLevel_c);
+ strcat(Temp, SoCPCB_temperature_c);
flags |= 1 << 5;
}
else if (!key.compare("FPS") && !(flags & 1 << 6) && GameRunning) {
@@ -436,21 +428,22 @@ class MiniOverlay : public tsl::Gui {
flags |= 1 << 6;
}
}
+ mutexUnlock(&mutex_Misc);
strcpy(Variables, Temp);
- }
- virtual bool handleInput(uint64_t keysDown, uint64_t keysHeld, touchPosition touchInput, JoystickPosition leftJoyStick, JoystickPosition rightJoyStick) override {
-
- bool allButtonsHeld = true;
- for (const HidNpadButton& button : mappedButtons) {
- if (!(keysHeld & static_cast(button))) {
- allButtonsHeld = false;
- break;
- }
+ char remainingBatteryLife[8];
+ mutexLock(&mutex_BatteryChecker);
+ if (batTimeEstimate >= 0) {
+ snprintf(remainingBatteryLife, sizeof remainingBatteryLife, "%d:%02d", batTimeEstimate / 60, batTimeEstimate % 60);
}
+ else snprintf(remainingBatteryLife, sizeof remainingBatteryLife, "--:--");
+
+ snprintf(SoCPCB_temperature_c, sizeof SoCPCB_temperature_c, "%0.2fW[%s]", PowerConsumption, remainingBatteryLife);
+ mutexUnlock(&mutex_BatteryChecker);
- if (allButtonsHeld) {
- returningFromSelection = true;
+ }
+ virtual bool handleInput(uint64_t keysDown, uint64_t keysHeld, touchPosition touchInput, JoystickPosition leftJoyStick, JoystickPosition rightJoyStick) override {
+ if (isKeyComboPressed(keysHeld, keysDown, mappedButtons)) {
TeslaFPS = 60;
tsl::goBack();
return true;
@@ -459,9 +452,6 @@ class MiniOverlay : public tsl::Gui {
FPSmin = 254;
FPSmax = 0;
}
- if (keysHeld & KEY_B) {
- return false;
- }
return false;
}
};
\ No newline at end of file
diff --git a/source/modes/Misc.hpp b/source/modes/Misc.hpp
index 9652ceb2..814fd373 100644
--- a/source/modes/Misc.hpp
+++ b/source/modes/Misc.hpp
@@ -1,7 +1,3 @@
-#pragma once
-#include
-#include "common.hpp"
-
void StartMiscThread() {
threadCreate(&t0, Misc2, NULL, NULL, 0x1000, 0x3F, 3);
threadStart(&t0);
@@ -23,7 +19,7 @@ class MiscOverlay : public tsl::Gui {
char Nifm_pass[96];
char Nifm_ipaddr[16];
public:
- MiscOverlay() {
+ MiscOverlay() {
smInitialize();
nifmCheck = nifmInitialize(NifmServiceType_Admin);
if (R_SUCCEEDED(mmuInitialize())) {
@@ -52,8 +48,8 @@ class MiscOverlay : public tsl::Gui {
audsnoopExit();
}
- virtual tsl::elm::Element* createUI() override {
- rootFrame = new tsl::elm::OverlayFrame("Ultra Monitor", APP_VERSION);
+ virtual tsl::elm::Element* createUI() override {
+ rootFrame = new tsl::elm::OverlayFrame("Status Monitor", APP_VERSION);
auto Status = new tsl::elm::CustomDrawer([this](tsl::gfx::Renderer *renderer, u16 x, u16 y, u16 w, u16 h) {
@@ -91,7 +87,6 @@ class MiscOverlay : public tsl::Gui {
renderer->drawString("IP Address:", false, 20, 320, 15, renderer->a(0xFFFF));
renderer->drawString(Nifm_ipaddr, false, 104, 320, 15, renderer->a(0xFFFF));
}
-
else
renderer->drawString("Type: Not connected", false, 20, 280, 18, renderer->a(0xFFFF));
}
@@ -126,7 +121,7 @@ class MiscOverlay : public tsl::Gui {
else {
memcpy(&pass_temp1, &(Nifm_profile.wireless_setting_data.passphrase[0]), 24);
}
- snprintf(Nifm_pass, sizeof Nifm_pass, "%s\n%s\n%s", pass_temp1, pass_temp2, pass_temp3);
+ snprintf(Nifm_pass, sizeof Nifm_pass, "%s\n%s\n%s", pass_temp1, pass_temp2, pass_temp3);
if (!ipaddr_value || ipaddr[0] == '\0') {
nifmGetCurrentIpAddress(&ipaddr_value);
ipaddr[0] = (ipaddr_value >> 24) & 0xFF;
@@ -134,7 +129,7 @@ class MiscOverlay : public tsl::Gui {
ipaddr[2] = (ipaddr_value >> 8) & 0xFF;
ipaddr[3] = ipaddr_value & 0xFF;
}
- snprintf(Nifm_ipaddr, sizeof Nifm_ipaddr, "%u.%u.%u.%u", ipaddr[3], ipaddr[2], ipaddr[1], ipaddr[0]);
+ snprintf(Nifm_ipaddr, sizeof Nifm_ipaddr, "%u.%u.%u.%u", ipaddr[3], ipaddr[2], ipaddr[1], ipaddr[0]);
}
virtual bool handleInput(uint64_t keysDown, uint64_t keysHeld, touchPosition touchInput, JoystickPosition leftJoyStick, JoystickPosition rightJoyStick) override {
@@ -143,14 +138,10 @@ class MiscOverlay : public tsl::Gui {
}
else Nifm_showpass = false;
- if (keysHeld & KEY_B) {
- returningFromSelection = true;
+ if (keysDown & KEY_B) {
tsl::goBack();
return true;
}
- if (keysHeld & KEY_B) {
- return false;
- }
return false;
}
};
\ No newline at end of file