mirror of
https://github.com/joel16/SwitchIdent.git
synced 2024-11-27 05:30:37 +00:00
316 lines
18 KiB
C++
316 lines
18 KiB
C++
#include <cstdio>
|
|
#include <unistd.h>
|
|
|
|
#include "common.hpp"
|
|
#include "gui.hpp"
|
|
#include "menus.hpp"
|
|
|
|
namespace Menus {
|
|
// Globals
|
|
static int g_item_height = 0;
|
|
static bool g_is_sd_inserted = false, g_is_gamecard_inserted = false;
|
|
static PadState g_pad;
|
|
static const int g_item_dist = 67;
|
|
static const int g_start_x = 450;
|
|
static const int g_start_y = 260;
|
|
|
|
// Colours
|
|
static const SDL_Color bg_colour = { 62, 62, 62 };
|
|
static const SDL_Color status_bar_colour = { 44, 44, 44 };
|
|
static const SDL_Color menu_bar_colour = { 52, 52, 52 };
|
|
static const SDL_Color selector_colour = { 223, 74, 22 };
|
|
static const SDL_Color title_colour = { 252, 252, 252 };
|
|
static const SDL_Color descr_colour = { 182, 182, 182 };
|
|
|
|
enum MenuState {
|
|
STATE_KERNEL_INFO = 0,
|
|
STATE_SYSTEM_INFO,
|
|
STATE_BATTERY_INFO,
|
|
STATE_STORAGE_INFO,
|
|
STATE_JOYCON_INFO,
|
|
STATE_MISC_INFO,
|
|
STATE_EXIT,
|
|
MAX_ITEMS
|
|
};
|
|
|
|
static void DrawItem(int x, int y, const char *title, const char *text) {
|
|
int title_width = 0;
|
|
GUI::GetTextDimensions(25, title, &title_width, nullptr);
|
|
GUI::DrawText(x, y, 25, title_colour, title);
|
|
GUI::DrawText(x + title_width + 20, y, 25, descr_colour, text);
|
|
}
|
|
|
|
static void DrawItemf(int x, int y, const char *title, const char *text, ...) {
|
|
int title_width = 0;
|
|
GUI::GetTextDimensions(25, title, &title_width, nullptr);
|
|
GUI::DrawText(x, y, 25, title_colour, title);
|
|
|
|
char buffer[256];
|
|
va_list args;
|
|
va_start(args, text);
|
|
std::vsnprintf(buffer, 256, text, args);
|
|
GUI::DrawText(x + title_width + 20, y, 25, descr_colour, buffer);
|
|
va_end(args);
|
|
}
|
|
|
|
void KernelInfo(void) {
|
|
SetSysFirmwareVersion ver = SwitchIdent::GetFirmwareVersion();
|
|
//DockFirmwareVersion dock_ver = SwitchIdent::GetDockFirmware();
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 60, "Firmware version:",
|
|
"%u.%u.%u-%u%u", ver.major, ver.minor, ver.micro, ver.revision_major, ver.revision_minor);
|
|
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 120, "Hardware:", SwitchIdent::GetHardwareType());
|
|
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 180, "Unit:", SwitchIdent::GetUnit());
|
|
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 240, "Serial:", SwitchIdent::GetSerialNumber().number);
|
|
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 300, "DRAM ID:", SwitchIdent::GetDramDesc());
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 360, "Device ID:", "%llu", SwitchIdent::GetDeviceID());
|
|
|
|
// if (hosversionAtLeast(2, 0, 0) && appletGetOperationMode() == AppletOperationMode_Console) {
|
|
// Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 420, "Dock firmware:", "%d.%d.%d.%d", dock_ver.major, dock_ver.minor, dock_ver.micro, dock_ver.rev);
|
|
// }
|
|
}
|
|
|
|
void SystemInfo(void) {
|
|
s32 int_temp = SwitchIdent::GetBatteryTemperature(TsLocation_Internal);
|
|
s32 ext_temp = SwitchIdent::GetBatteryTemperature(TsLocation_External);
|
|
|
|
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 60, "Region:", SwitchIdent::GetRegion());
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 120, "CPU clock:", "%lu MHz", SwitchIdent::GetClock(PcvModule_CpuBus));
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 180, "GPU clock:", "%lu MHz", SwitchIdent::GetClock(PcvModule_GPU));
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 240, "EMC clock:", "%lu MHz", SwitchIdent::GetClock(PcvModule_EMC));
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 300, "Wireless LAN:",
|
|
"%s (RSSI: %d) (Quality: %lu)", SwitchIdent::GetWirelessLanEnableFlag()? "Enabled" : "Disabled", SwitchIdent::GetWlanRSSI(), SwitchIdent::GetWlanQuality(SwitchIdent::GetWlanRSSI()));
|
|
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 360, "Bluetooth:", SwitchIdent::GetBluetoothEnableFlag()? "Enabled" : "Disabled");
|
|
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 420, "NFC:", SwitchIdent::GetNfcEnableFlag()? "Enabled" : "Disabled");
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 480, "Internal (PCB) temperature:", "%d °C (%d °F)", int_temp, ((int_temp * 9/5) + 32));
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 540, "External (SoC) temperature:", "%d °C (%d °F)", ext_temp, ((ext_temp * 9/5) + 32));
|
|
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 600, "Headphone Status:", SwitchIdent::GetHeadphoneStatus());
|
|
}
|
|
|
|
void BatteryInfo(void) {
|
|
const char *chargers[] = {
|
|
"Unknown",
|
|
"PD",
|
|
"Type-C 1.5A",
|
|
"Type-C 3.0A"
|
|
"DCP",
|
|
"CDP",
|
|
"SDP",
|
|
"Apple 500mA",
|
|
"Apple 1000mA",
|
|
"Apple 2000mA"
|
|
};
|
|
|
|
BatteryChargeInfoFields batteryChargeInfoFields = { 0 };
|
|
SwitchIdent::GetBatteryChargeInfoFields(&batteryChargeInfoFields);
|
|
|
|
u32 battery_temp = batteryChargeInfoFields.battery_temp * 0.001;
|
|
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 60, "Battery Percentage:", "%lu %% (%s)", SwitchIdent::GetBatteryPercentage(), SwitchIdent::IsCharging()? "charging" : "not charging");
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 120, "Battery age percentage:", "%.2f %%", SwitchIdent::GetBatteryAgePercentage());
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 180, "Battery temperature", "%d °C (%d °F)", battery_temp, ((battery_temp * 9/5) + 32));
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 240, "Battery voltage state:", "%s (Avg: %d mV)", SwitchIdent::GetVoltageState(), batteryChargeInfoFields.voltage_avg);
|
|
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 300, "Battery lot number:", SwitchIdent::GetBatteryLot().lot);
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 360, "Charger current limit:", "(In: %d mA) (Out: %d mA)", batteryChargeInfoFields.in_curr_limit, batteryChargeInfoFields.out_curr_limit);
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 420, "Battery charging current limit:", "%d mA", batteryChargeInfoFields.charge_curr_limit);
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 480, "Battery charging voltage limit:", "%d mV", batteryChargeInfoFields.charge_volt_limit);
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 540, "Battery capacity:", "%d pcm (Age: %d pcm)", batteryChargeInfoFields.capacity, batteryChargeInfoFields.battery_age);
|
|
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 600, "Charger:", chargers[batteryChargeInfoFields.charger]);
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 660, "Charger voltage limit:", "%d mV", batteryChargeInfoFields.charger_volt_limit);
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 720, "Charger current limit:", "%d mA", batteryChargeInfoFields.charger_curr_limit);
|
|
}
|
|
|
|
void StorageInfo(void) {
|
|
u64 sd_used = SwitchIdent::GetUsedStorage(NcmStorageId_SdCard);
|
|
u64 sd_total = SwitchIdent::GetTotalStorage(NcmStorageId_SdCard);
|
|
|
|
u64 nand_u_used = SwitchIdent::GetUsedStorage(NcmStorageId_BuiltInUser);
|
|
u64 nand_u_total = SwitchIdent::GetTotalStorage(NcmStorageId_BuiltInUser);
|
|
|
|
u64 nand_s_used = SwitchIdent::GetUsedStorage(NcmStorageId_BuiltInSystem);
|
|
u64 nand_s_total = SwitchIdent::GetTotalStorage(NcmStorageId_BuiltInSystem);
|
|
|
|
char sd_total_str[16], sd_free_str[16], sd_used_str[16];
|
|
SwitchIdent::GetSizeString(sd_total_str, sd_total);
|
|
SwitchIdent::GetSizeString(sd_free_str, SwitchIdent::GetFreeStorage(NcmStorageId_SdCard));
|
|
SwitchIdent::GetSizeString(sd_used_str, sd_used);
|
|
|
|
char nand_u_total_str[16], nand_u_free_str[16], nand_u_used_str[16];
|
|
SwitchIdent::GetSizeString(nand_u_total_str, nand_u_total);
|
|
SwitchIdent::GetSizeString(nand_u_free_str, SwitchIdent::GetFreeStorage(NcmStorageId_BuiltInUser));
|
|
SwitchIdent::GetSizeString(nand_u_used_str, nand_u_used);
|
|
|
|
char nand_s_total_str[16], nand_s_free_str[16], nand_s_used_str[16];
|
|
SwitchIdent::GetSizeString(nand_s_total_str, nand_s_total);
|
|
SwitchIdent::GetSizeString(nand_s_free_str, SwitchIdent::GetFreeStorage(NcmStorageId_BuiltInSystem));
|
|
SwitchIdent::GetSizeString(nand_s_used_str, nand_s_used);
|
|
|
|
GUI::DrawRect(400, 50, 880, 670, bg_colour);
|
|
|
|
GUI::DrawImage(drive, 450, 88);
|
|
GUI::DrawRect(450, 226, 128, 25, descr_colour);
|
|
GUI::DrawRect(452, 228, 124, 21, bg_colour);
|
|
GUI::DrawRect(452, 228, (((double)sd_used / (double)sd_total) * 124.0), 21, selector_colour);
|
|
|
|
GUI::DrawImage(drive, 450, 296);
|
|
GUI::DrawRect(450, 434, 128, 25, descr_colour);
|
|
GUI::DrawRect(452, 436, 124, 21, bg_colour);
|
|
GUI::DrawRect(452, 436, (((double)nand_u_used / (double)nand_u_total) * 124.0), 21, selector_colour);
|
|
|
|
GUI::DrawImage(drive, 450, 504);
|
|
GUI::DrawRect(450, 642, 128, 25, descr_colour);
|
|
GUI::DrawRect(452, 644, 124, 21, bg_colour);
|
|
GUI::DrawRect(452, 644, (((double)nand_s_used / (double)nand_s_total) * 124.0), 21, selector_colour);
|
|
|
|
GUI::DrawText(600, 38 + ((g_item_dist - g_item_height) / 2) + 50, 25, descr_colour, "SD");
|
|
Menus::DrawItem(600, 38 + ((g_item_dist - g_item_height) / 2) + 88, "Total storage capacity:", sd_total_str);
|
|
Menus::DrawItem(600, 38 + ((g_item_dist - g_item_height) / 2) + 126, "Free storage capacity:", sd_free_str);
|
|
Menus::DrawItem(600, 38 + ((g_item_dist - g_item_height) / 2) + 164, "Used storage capacity:", sd_used_str);
|
|
|
|
GUI::DrawText(600, 246 + ((g_item_dist - g_item_height) / 2) + 50, 25, descr_colour, "NAND User");
|
|
Menus::DrawItem(600, 246 + ((g_item_dist - g_item_height) / 2) + 88, "Total storage capacity:", nand_u_total_str);
|
|
Menus::DrawItem(600, 246 + ((g_item_dist - g_item_height) / 2) + 126, "Free storage capacity:", nand_u_free_str);
|
|
Menus::DrawItem(600, 246 + ((g_item_dist - g_item_height) / 2) + 164, "Used storage capacity:", nand_u_used_str);
|
|
|
|
GUI::DrawText(600, 454 + ((g_item_dist - g_item_height) / 2) + 50, 25, descr_colour, "NAND System");
|
|
Menus::DrawItem(600, 454 + ((g_item_dist - g_item_height) / 2) + 88, "Total storage capacity:", nand_s_total_str);
|
|
Menus::DrawItem(600, 454 + ((g_item_dist - g_item_height) / 2) + 126, "Free storage capacity:", nand_s_free_str);
|
|
Menus::DrawItem(600, 454 + ((g_item_dist - g_item_height) / 2) + 164, "Used storage capacity:", nand_s_used_str);
|
|
}
|
|
|
|
void JoyconInfo(void) {
|
|
// TODO: Get info on other connected controllers
|
|
HidPowerInfo info_left = SwitchIdent::GetJoyconPowerInfoL(padIsHandheld(&g_pad) ? HidNpadIdType_Handheld : HidNpadIdType_No1);
|
|
HidPowerInfo info_right = SwitchIdent::GetJoyconPowerInfoR(padIsHandheld(&g_pad) ? HidNpadIdType_Handheld : HidNpadIdType_No1);
|
|
|
|
HIDFirmwareVersion version_left;
|
|
HIDFirmwareVersion version_right;
|
|
SwitchIdent::GetJoyconFirmwareVersion(padIsHandheld(&g_pad) ? HidDeviceTypeBits_HandheldLeft : HidDeviceTypeBits_JoyLeft, &version_left);
|
|
SwitchIdent::GetJoyconFirmwareVersion(padIsHandheld(&g_pad) ? HidDeviceTypeBits_HandheldRight : HidDeviceTypeBits_JoyRight, &version_right);
|
|
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 60, "Left Joy-con battery:", "%lu %% (%s)", (info_left.battery_level * 25), info_left.is_charging? "charging" : "not charging");
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 120, "Right Joy-con battery:", "%lu %% (%s)", (info_right.battery_level * 25), info_right.is_charging? "charging" : "not charging");
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 180, "Left Joy-con firmware:", "%d.%d.%d", version_left.major, version_left.minor, version_left.micro);
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 240, "Right Joy-con firmware:", "%d.%d.%d", version_right.major, version_right.minor, version_right.micro);
|
|
}
|
|
|
|
void MiscInfo(void) {
|
|
char hostname[128];
|
|
Result ret = gethostname(hostname, sizeof(hostname));
|
|
|
|
SetCalBdAddress bd_addr = SwitchIdent::GetBluetoothBdAddress();
|
|
SetCalMacAddress mac_addr = SwitchIdent::GetWirelessLanMacAddress();
|
|
|
|
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 60, "IP:", R_SUCCEEDED(ret)? hostname : nullptr);
|
|
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 120, "State:", SwitchIdent::GetOperationMode());
|
|
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 180, "Automatic update:", SwitchIdent::GetAutoUpdateEnableFlag()? "Enabled" : "Disabled");
|
|
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 240, "Console information upload:", SwitchIdent::GetConsoleInformationUploadFlag()? "Enabled" : "Disabled");
|
|
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 300, "SD card status:", g_is_sd_inserted? "Inserted" : "Not inserted");
|
|
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 360, "Game card status:", g_is_gamecard_inserted? "Inserted" : "Not inserted");
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 420, "BT address:",
|
|
"%02X:%02X:%02X:%02X:%02X:%02X", bd_addr.bd_addr[0], bd_addr.bd_addr[1], bd_addr.bd_addr[2], bd_addr.bd_addr[3], bd_addr.bd_addr[4], bd_addr.bd_addr[5]);
|
|
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 480, "WLAN address:",
|
|
"%02X:%02X:%02X:%02X:%02X:%02X", mac_addr.addr[0], mac_addr.addr[1], mac_addr.addr[2], mac_addr.addr[3], mac_addr.addr[4], mac_addr.addr[5]);
|
|
}
|
|
|
|
void Main(void) {
|
|
int title_height = 0;
|
|
GUI::GetTextDimensions(25, "SwitchIdent", nullptr, &title_height);
|
|
GUI::GetTextDimensions(25, "Item", nullptr, &g_item_height);
|
|
|
|
int banner_width = 200;
|
|
int selection = STATE_KERNEL_INFO;
|
|
Result ret = 0;
|
|
|
|
FsDeviceOperator fsDeviceOperator;
|
|
if (R_FAILED(ret = fsOpenDeviceOperator(&fsDeviceOperator))) {
|
|
std::printf("fsOpenDeviceOperator() failed: 0x%x.\n\n", ret);
|
|
}
|
|
|
|
g_is_sd_inserted = SwitchIdent::IsSDCardInserted(&fsDeviceOperator);
|
|
g_is_gamecard_inserted = SwitchIdent::IsGameCardInserted(&fsDeviceOperator);
|
|
fsDeviceOperatorClose(&fsDeviceOperator);
|
|
|
|
padConfigureInput(1, HidNpadStyleSet_NpadStandard);
|
|
padInitializeDefault(&g_pad);
|
|
padUpdate(&g_pad);
|
|
|
|
const char *items[] = {
|
|
"Kernel",
|
|
"System",
|
|
"Battery",
|
|
"Storage",
|
|
"Joy-con",
|
|
"Misc",
|
|
"Exit"
|
|
};
|
|
|
|
while(appletMainLoop()) {
|
|
GUI::ClearScreen(bg_colour);
|
|
GUI::DrawRect(0, 0, 1920, 50, status_bar_colour);
|
|
GUI::DrawRect(0, 50, 400, 1030, menu_bar_colour);
|
|
|
|
GUI::DrawTextf(30, ((50 - title_height) / 2), 25, title_colour, "SwitchIdent Test v%d.%d", VERSION_MAJOR, VERSION_MINOR);
|
|
GUI::DrawImage(banner, 400 + ((1320 - (banner_width)) / 2), 80);
|
|
|
|
GUI::DrawRect(0, 50 + (g_item_dist * selection), 400, g_item_dist, selector_colour);
|
|
|
|
for (int i = 0; i < MAX_ITEMS; i++) {
|
|
GUI::DrawImage(menu_icons[i], 20, 52 + ((g_item_dist - g_item_height) / 2) + (g_item_dist * i));
|
|
GUI::DrawText(75, 45 + ((g_item_dist - g_item_height) / 2) + (g_item_dist * i), 25, title_colour, items[i]);
|
|
}
|
|
|
|
padUpdate(&g_pad);
|
|
u32 kDown = padGetButtonsDown(&g_pad);
|
|
|
|
if (kDown & HidNpadButton_AnyDown) {
|
|
selection++;
|
|
}
|
|
else if (kDown & HidNpadButton_AnyUp) {
|
|
selection--;
|
|
}
|
|
|
|
if (selection > STATE_EXIT) {
|
|
selection = 0;
|
|
}
|
|
if (selection < 0) {
|
|
selection = STATE_EXIT;
|
|
}
|
|
|
|
switch (selection) {
|
|
case STATE_KERNEL_INFO:
|
|
Menus::KernelInfo();
|
|
break;
|
|
|
|
case STATE_SYSTEM_INFO:
|
|
Menus::SystemInfo();
|
|
break;
|
|
|
|
case STATE_BATTERY_INFO:
|
|
Menus::BatteryInfo();
|
|
break;
|
|
|
|
case STATE_STORAGE_INFO:
|
|
Menus::StorageInfo();
|
|
break;
|
|
|
|
case STATE_JOYCON_INFO:
|
|
Menus::JoyconInfo();
|
|
break;
|
|
|
|
case STATE_MISC_INFO:
|
|
Menus::MiscInfo();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
GUI::Render();
|
|
|
|
if ((kDown & HidNpadButton_Plus) || ((kDown & HidNpadButton_A) && (selection == STATE_EXIT))) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|