Switch to c++ and update SDL_FontCache

This commit is contained in:
Joel16 2021-11-05 00:59:45 -04:00
parent 3c28b195c3
commit 53e3d086d7
37 changed files with 1298 additions and 1172 deletions

36
.gitignore vendored Normal file
View File

@ -0,0 +1,36 @@
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
# Switch
build/
SwitchIdent.*

View File

@ -1,35 +0,0 @@
language: c
sudo: true
#Cache devkitARM and doxygen
cache:
directories:
- /home/travis/devkitPro
before_install:
- wget https://github.com/devkitPro/pacman/releases/download/v1.0.0/devkitpro-pacman.deb
- sudo dpkg -i devkitpro-pacman.deb
install:
- sudo dkp-pacman -Syu switch-dev --noconfirm --needed
- sudo dkp-pacman -S switch-libpng --noconfirm
- sudo dkp-pacman -S switch-libjpeg-turbo --noconfirm
- sudo dkp-pacman -S switch-libwebp --noconfirm
- sudo dkp-pacman -S switch-sdl2 --noconfirm
- sudo dkp-pacman -S switch-sdl2_gfx --noconfirm
- sudo dkp-pacman -S switch-sdl2_image --noconfirm
- sudo dkp-pacman -S switch-sdl2_ttf --noconfirm
- source /etc/profile.d/devkit-env.sh
- sh .travis/.travis-deps.sh
script:
- cd $TRAVIS_BUILD_DIR
- sh .travis/.build.sh
deploy:
provider: pages
skip_cleanup: true
github_token: $GITHUB_TOKEN # Set in travis-ci.org dashboard
on:
branch: master

View File

@ -1,7 +0,0 @@
#!/bin/sh
set -e
set -x
make clean && make
rm .gitattributes .travis.yml devkitpro-pacman.deb icon.jpg LICENSE Makefile README.md
rm -rf .travis build common include romfs source SwitchIdent.elf SwitchIdent.nacp SwitchIdent.nso SwitchIdent.pfs0

View File

@ -1,12 +0,0 @@
#!/bin/sh
set -e
set -x
# Get latest libnx and overwrite bundled one
mkdir libnx-update && cd libnx-update
git clone https://github.com/switchbrew/libnx.git
cd libnx/
make
sudo make install
cd ../../
rm -rf libnx-update/

137
Makefile
View File

@ -1,3 +1,4 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
@ -15,7 +16,7 @@ include $(DEVKITPRO)/libnx/switch_rules
# 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".
# ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional)
#
# NO_ICON: if set to anything, do not use icon.
# NO_NACP: if set to anything, no .nacp file is generated.
@ -28,42 +29,47 @@ include $(DEVKITPRO)/libnx/switch_rules
# - <Project name>.jpg
# - icon.jpg
# - <libnx folder>/default_icon.jpg
#
# CONFIG_JSON is the filename of the NPDM config file (.json), relative to the project folder.
# If not set, it attempts to use one of the following (in this order):
# - <Project name>.json
# - config.json
# If a JSON file is provided or autodetected, an ExeFS PFS0 (.nsp) is built instead
# of a homebrew executable (.nro). This is intended to be used for sysmodules.
# NACP building is skipped as well.
#---------------------------------------------------------------------------------
TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := source common
DATA := data
INCLUDES := include common
EXEFS_SRC := exefs_src
ROMFS := romfs
TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := source
DATA := data
INCLUDES := include
ROMFS := romfs
VERSION_MAJOR := 0
VERSION_MINOR := 3
VERSION_MICRO := 0
VERSION_MAJOR := 0
VERSION_MINOR := 3
VERSION_MICRO := 0
APP_TITLE := SwitchIdent
APP_AUTHOR := Joel16
APP_VERSION := ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_MICRO}
APP_TITLE := SwitchIdent
APP_AUTHOR := Joel16
APP_VERSION := ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_MICRO}
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
CFLAGS := -g -Wall -O3 -ffunction-sections \
-DVERSION_MAJOR=$(VERSION_MAJOR) -DVERSION_MINOR=$(VERSION_MINOR) -DVERSION_MICRO=$(VERSION_MICRO) \
-DAPP_TITLE="\"$(APP_TITLE)\"" \
-DGITVERSION="\"${GITVERSION}\"" \
$(ARCH) $(DEFINES)
CFLAGS := `$(PREFIX)pkg-config --cflags sdl2 SDL2_image` -Wall -O2 -ffunction-sections \
$(ARCH) $(DEFINES)
CFLAGS += -D__SWITCH__ $(INCLUDE) `freetype-config --cflags` `sdl2-config --cflags`
CFLAGS += $(INCLUDE) -D__SWITCH__
CFLAGS += -DVERSION_MAJOR=$(VERSION_MAJOR) -DVERSION_MINOR=$(VERSION_MINOR) -DVERSION_MICRO=$(VERSION_MICRO)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) -L$(PWD)/$(BUILD)
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS := -lSDL2_ttf -lSDL2_image -lwebp -lpng -lturbojpeg `sdl2-config --libs` `freetype-config --libs` -lnx
LIBS := `$(PREFIX)pkg-config --libs sdl2 SDL2_image SDL2_ttf` -lnx
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
@ -79,36 +85,47 @@ LIBDIRS := $(PORTLIBS) $(LIBNX)
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export TOPDIR := $(CURDIR)
export OUTPUT := $(CURDIR)/$(TARGET)
export TOPDIR := $(CURDIR)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
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)/*.*)))
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
# use CXX for linking C++ and libEGL dependent projects
#---------------------------------------------------------------------------------
export LD := $(CXX)
export LD := $(CXX)
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_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
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_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
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 LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC)
ifeq ($(strip $(CONFIG_JSON)),)
jsons := $(wildcard *.json)
ifneq (,$(findstring $(TARGET).json,$(jsons)))
export APP_JSON := $(TOPDIR)/$(TARGET).json
else
ifneq (,$(findstring config.json,$(jsons)))
export APP_JSON := $(TOPDIR)/config.json
endif
endif
else
export APP_JSON := $(TOPDIR)/$(CONFIG_JSON)
endif
ifeq ($(strip $(ICON)),)
icons := $(wildcard *.jpg)
@ -151,7 +168,11 @@ $(BUILD):
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(TARGET).pfs0 $(TARGET).nso $(TARGET).nro $(TARGET).nacp $(TARGET).elf
ifeq ($(strip $(APP_JSON)),)
@rm -fr $(BUILD) $(TARGET).nro $(TARGET).nacp $(TARGET).elf
else
@rm -fr $(BUILD) $(TARGET).nsp $(TARGET).nso $(TARGET).npdm $(TARGET).elf
endif
#---------------------------------------------------------------------------------
@ -163,21 +184,29 @@ DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
all : $(OUTPUT).pfs0 $(OUTPUT).nro
ifeq ($(strip $(APP_JSON)),)
$(OUTPUT).pfs0 : $(OUTPUT).nso
$(OUTPUT).nso : $(OUTPUT).elf
all : $(OUTPUT).nro
ifeq ($(strip $(NO_NACP)),)
$(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp
$(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp
else
$(OUTPUT).nro : $(OUTPUT).elf
$(OUTPUT).nro : $(OUTPUT).elf
endif
$(OUTPUT).elf : $(OFILES)
else
$(OFILES_SRC) : $(HFILES_BIN)
all : $(OUTPUT).nsp
$(OUTPUT).nsp : $(OUTPUT).nso $(OUTPUT).npdm
$(OUTPUT).nso : $(OUTPUT).elf
endif
$(OUTPUT).elf : $(OFILES)
$(OFILES_SRC) : $(HFILES_BIN)
#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data

View File

@ -1,9 +1,7 @@
# SwitchIdent [![Travis](https://img.shields.io/travis/joel16/SwitchIdent.svg?style=flat-square)](https://github.com/joel16/SwitchIdent/tree/gh-pages)
# SwitchIdent ![Github latest downloads](https://img.shields.io/github/downloads/joel16/SwitchIdent/total.svg)
This is yet another identity tool that is continuing the series of <*device name here*>ident. This tool allows users to get various bits of information from your Nintendo Switch device, hence the name 'ident' as in identifying your Nintendo Switch.
Bleeding edge builds can be found in the [gh-pages branch](https://github.com/joel16/SwitchIdent/tree/gh-pages).
# Features:
- Displays system firmware version.
- Displays hardware type and unit.
@ -27,5 +25,6 @@ Bleeding edge builds can be found in the [gh-pages branch](https://github.com/jo
- Displays WiFi and Bluetooth MAC address.
# Credits:
- shchmue: Added missing DRAM descriptors and fix compatibility with libnx v4.2.0+
- Eve/Hikari/Junko, Klodeckel and hopperplaysmc: Beta testing
- preetisketch: Banner

View File

@ -1,152 +0,0 @@
#include <stdio.h>
#include <switch.h>
char *SwitchIdent_GetDramDesc(void) {
Result ret = 0;
u64 id = 0;
char *dram_desc[] = {
"EristaIcosaSamsung4gb",
"EristaIcosaHynix4gb",
"EristaIcosaMicron4gb",
"MarikoIowaHynix1y4gb",
"EristaIcosaSamsung6gb",
"MarikoHoagHynix1y4gb",
"MarikoAulaHynix1y4gb",
"MarikoIowax1x2Samsung4gb",
"MarikoIowaSamsung4gb",
"MarikoIowaSamsung8gb",
"MarikoIowaHynix4gb",
"MarikoIowaMicron4gb",
"MarikoHoagSamsung4gb",
"MarikoHoagSamsung8gb",
"MarikoHoagSamsung8gb",
"MarikoHoagHynix4gb",
"MarikoHoagMicron4gb",
"MarikoIowaSamsung4gbY",
"MarikoIowaSamsung1y4gbX",
"MarikoIowaSamsung1y8gbX",
"MarikoHoagSamsung1y4gbX",
"MarikoIowaSamsung1y4gbY",
"MarikoIowaSamsung1y8gbY",
"MarikoAulaSamsung1y4gb",
"MarikoHoagSamsung1y8gbX",
"MarikoAulaSamsung1y4gbX",
"MarikoIowaMicron1y4gb",
"MarikoHoagMicron1y4gb",
"MarikoAulaMicron1y4gb",
"MarikoAulaSamsung1y8gbX",
"Unknown"
};
if (R_FAILED(ret = splGetConfig(SplConfigItem_DramId, &id)))
printf("splGetConfig(SplConfigItem_DramId) failed: 0x%x.\n\n", ret);
if (id >= 30)
return dram_desc[30];
return dram_desc[id];
}
char *SwitchIdent_GetFirmwareVersion(void) {
Result ret = 0;
SetSysFirmwareVersion ver;
if (R_FAILED(ret = setsysGetFirmwareVersion(&ver))) {
printf("setsysGetFirmwareVersion() failed: 0x%x.\n\n", ret);
return NULL;
}
static char buf[9];
snprintf(buf, 19, "%u.%u.%u-%u%u", ver.major, ver.minor, ver.micro, ver.revision_major, ver.revision_minor);
return buf;
}
char *SwitchIdent_GetHardwareType(void) {
Result ret = 0;
u64 hardware_type;
char *hardware_string[] = {
"Icosa",
"Copper",
"Hoag",
"Iowa",
"Calcio",
"Aula",
"Unknown"
};
if (R_FAILED(ret = splGetConfig(SplConfigItem_HardwareType, &hardware_type)))
printf("splGetConfig(SplConfigItem_HardwareType) failed: 0x%x.\n\n", ret);
if (hardware_type >= 6)
return hardware_string[6];
return hardware_string[hardware_type];
}
// [4.0.0+] Kiosk mode (0 = retail; 1 = kiosk)
bool SwitchIdent_IsKiosk(void) {
u64 isKiosk = 0;
Result ret = 0;
if (R_FAILED(ret = splGetConfig(SplConfigItem_IsKiosk , &isKiosk)))
printf("splGetConfig(SplConfigItem_IsKiosk) failed: 0x%x.\n\n", ret);
if (isKiosk) // if bit 10 returns (1)
return true;
return false;
}
char *SwitchIdent_GetUnit(void) {
Result ret = 0;
u64 isRetail = 0;
char *unit[] = {
"Debug",
"Retail",
"Unknown"
};
if (R_FAILED(ret = splGetConfig(SplConfigItem_IsRetail, &isRetail))) {
printf("splGetConfig(SplConfigItem_IsRetail) failed: 0x%x.\n\n", ret);
return unit[2];
}
return unit[isRetail];
}
bool SwitchIdent_IsSafeMode(void) {
Result ret = 0;
u64 safemode = 0;
if (R_FAILED(ret = splGetConfig(SplConfigItem_IsRecoveryBoot, &safemode)))
printf("splGetConfig(SplConfigItem_IsRecoveryBoot) failed: 0x%x.\n\n", ret);
if (safemode)
return true;
return false;
}
u64 SwitchIdent_GetDeviceID(void) {
Result ret = 0;
u64 deviceID = 0;
if (R_FAILED(ret = splGetConfig(SplConfigItem_DeviceId, &deviceID)))
printf("splGetConfig(SplConfigItem_DeviceId) failed: 0x%x.\n\n", ret);
return deviceID;
}
char *SwitchIdent_GetSerialNumber(void) {
Result ret = 0;
static SetSysSerialNumber serial;
if (R_FAILED(ret = setsysGetSerialNumber(&serial)))
printf("setsysGetSerialNumber() failed: 0x%x.\n\n", ret);
return serial.number;
}

View File

@ -1,12 +0,0 @@
#ifndef _SWITCHIDENT_KERNEL_H_
#define _SWITCHIDENT_KERNEL_H_
char *SwitchIdent_GetDramDesc(void);
char *SwitchIdent_GetFirmwareVersion(void);
char *SwitchIdent_GetHardwareType(void);
char *SwitchIdent_GetUnit(void);
bool SwitchIdent_IsSafeMode(void);
u64 SwitchIdent_GetDeviceID(void);
char *SwitchIdent_GetSerialNumber(void);
#endif

View File

@ -1,79 +0,0 @@
#include <stdio.h>
#include <switch.h>
char *SwitchIdent_GetOperationMode(void) {
if (appletGetOperationMode() == AppletOperationMode_Handheld)
return "Handheld";
return "Docked";
}
bool SwitchIdent_GetWirelessLanEnableFlag() {
Result ret = 0;
bool out = false;
if (R_FAILED(ret = setsysGetWirelessLanEnableFlag(&out)))
printf("setsysGetWirelessLanEnableFlag() failed: 0x%x.\n\n", ret);
return out;
}
bool SwitchIdent_GetBluetoothEnableFlag() {
Result ret = 0;
bool out = false;
if (R_FAILED(ret = setsysGetBluetoothEnableFlag(&out)))
printf("setsysGetBluetoothEnableFlag() failed: 0x%x.\n\n", ret);
return out;
}
bool SwitchIdent_GetNfcEnableFlag() {
Result ret = 0;
bool out = false;
if (R_FAILED(ret = setsysGetNfcEnableFlag(&out)))
printf("setsysGetNfcEnableFlag() failed: 0x%x.\n\n", ret);
return out;
}
bool SwitchIdent_GetAutoUpdateEnableFlag() {
Result ret = 0;
bool out = false;
if (R_FAILED(ret = setsysGetAutoUpdateEnableFlag(&out)))
printf("setsysGetAutoUpdateEnableFlag() failed: 0x%x.\n\n", ret);
return out;
}
bool SwitchIdent_GetConsoleInformationUploadFlag() {
Result ret = 0;
bool out = false;
if (R_FAILED(ret = setsysGetConsoleInformationUploadFlag(&out)))
printf("setsysGetConsoleInformationUploadFlag() failed: 0x%x.\n\n", ret);
return out;
}
bool SwitchIdent_IsSDCardInserted(FsDeviceOperator *fsDeviceOperator) {
Result ret = 0;
bool out = false;
if (R_FAILED(ret = fsDeviceOperatorIsSdCardInserted(fsDeviceOperator, &out)))
printf("fsDeviceOperatorIsSdCardInserted() failed: 0x%x.\n\n", ret);
return out;
}
bool SwitchIdent_IsGameCardInserted(FsDeviceOperator *fsDeviceOperator) {
Result ret = 0;
bool out = false;
if (R_FAILED(ret = fsDeviceOperatorIsGameCardInserted(fsDeviceOperator, &out)))
printf("fsDeviceOperatorIsGameCardInserted() failed: 0x%x.\n\n", ret);
return out;
}

View File

@ -1,13 +0,0 @@
#ifndef _SWITCHIDENT_MISC_H_
#define _SWITCHIDENT_MISC_H_
char *SwitchIdent_GetOperationMode(void);
bool SwitchIdent_GetWirelessLanEnableFlag();
bool SwitchIdent_GetBluetoothEnableFlag();
bool SwitchIdent_GetNfcEnableFlag();
bool SwitchIdent_GetAutoUpdateEnableFlag();
bool SwitchIdent_GetConsoleInformationUploadFlag();
bool SwitchIdent_IsSDCardInserted(FsDeviceOperator *fsDeviceOperator);
bool SwitchIdent_IsGameCardInserted(FsDeviceOperator *fsDeviceOperator);
#endif

View File

@ -1,126 +0,0 @@
#include <stdio.h>
#include <switch.h>
static Result _psmCmdNoInOutBool(Service* srv, bool *out, u32 cmd_id) {
u8 outval = 0;
Result rc = serviceDispatchOut(srv, cmd_id, outval);
if (R_SUCCEEDED(rc)) {
if (out) *out = outval & 1;
}
return rc;
}
static Result psmIsBatteryChargingEnabled(bool *out) {
return _psmCmdNoInOutBool(psmGetServiceSession(), out, 4);
}
u32 SwitchIdent_GetBatteryPercent(void) {
Result ret = 0;
u32 out = 0;
if (R_FAILED(ret = psmGetBatteryChargePercentage(&out)))
return -1;
return out;
}
char *SwitchIdent_GetChargerType(void) {
Result ret = 0;
PsmChargerType charger_type;
if (R_FAILED(ret = psmGetChargerType(&charger_type)))
return NULL;
if (charger_type == PsmChargerType_EnoughPower)
return "Official charger or dock";
else if (charger_type == PsmChargerType_LowPower)
return "USB-C charger";
else
return "No charger connected";
return NULL;
}
bool SwitchIdent_IsCharging(void) {
Result ret = 0;
PsmChargerType charger_type;
if (R_FAILED(ret = psmGetChargerType(&charger_type)))
return false;
return charger_type != PsmChargerType_Unconnected;
}
bool SwitchIdent_IsChargingEnabled(void) {
Result ret = 0;
bool out = 0;
if (R_FAILED(ret = psmIsBatteryChargingEnabled(&out)))
return -1;
return out;
}
char *SwitchIdent_GetVoltageState(void) {
Result ret = 0;
u32 out = 0;
char *states[]=
{
"Power state needs shutdown",
"Power state needs sleep",
"Performance boost cannot be entered",
"Normal",
"Unknown"
};
if (R_SUCCEEDED(ret = psmGetBatteryVoltageState(&out))) {
if (out < 4)
return states[out];
}
printf("psmGetBatteryVoltageState() failed: 0x%x.\n\n", ret);
return states[4];
}
double SwitchIdent_GetRawBatteryChargePercentage(void) {
Result ret = 0;
double out = 0;
if (R_FAILED(ret = psmGetRawBatteryChargePercentage(&out)))
return -1;
return out;
}
bool SwitchIdent_IsEnoughPowerSupplied(void) {
Result ret = 0;
bool out = 0;
if (R_FAILED(ret = psmIsEnoughPowerSupplied(&out)))
return -1;
return out;
}
double SwitchIdent_GetBatteryAgePercent(void) {
Result ret = 0;
double out = 0;
if (R_FAILED(ret = psmGetBatteryAgePercentage(&out)))
return -1;
return out;
}
char *SwitchIdent_GetBatteryLot(void) {
Result ret = 0;
static SetBatteryLot battery_lot;
if (R_FAILED(ret = setcalGetBatteryLot(&battery_lot))) {
printf("setcalGetBatteryLot() failed: 0x%x.\n\n", ret);
return NULL;
}
return battery_lot.lot;
}

View File

@ -1,14 +0,0 @@
#ifndef _SWITCHIDENT_POWER_H_
#define _SWITCHIDENT_POWER_H_
u32 SwitchIdent_GetBatteryPercent(void);
char *SwitchIdent_GetChargerType(void);
bool SwitchIdent_IsCharging(void);
bool SwitchIdent_IsChargingEnabled(void);
char *SwitchIdent_GetVoltageState(void);
double SwitchIdent_GetRawBatteryChargePercentage(void);
bool SwitchIdent_IsEnoughPowerSupplied(void);
double SwitchIdent_GetBatteryAgePercent(void);
char *SwitchIdent_GetBatteryLot(void);
#endif

View File

@ -1,27 +0,0 @@
#include <stdio.h>
#include "storage.h"
s64 SwitchIdent_GetTotalStorage(NcmStorageId storage_id) {
Result ret = 0;
s64 total = 0;
if (R_FAILED(ret = nsGetTotalSpaceSize(storage_id, &total)))
printf("nsGetFreeSpaceSize() failed: 0x%x.\n\n", ret);
return total;
}
s64 SwitchIdent_GetFreeStorage(NcmStorageId storage_id) {
Result ret = 0;
s64 free = 0;
if (R_FAILED(ret = nsGetFreeSpaceSize(storage_id, &free)))
printf("nsGetFreeSpaceSize() failed: 0x%x.\n\n", ret);
return free;
}
s64 SwitchIdent_GetUsedStorage(NcmStorageId storage_id) {
return (SwitchIdent_GetTotalStorage(storage_id) - SwitchIdent_GetFreeStorage(storage_id));
}

View File

@ -1,10 +0,0 @@
#ifndef _SWITCHIDENT_STORAGE_H_
#define _SWITCHIDENT_STORAGE_H_
#include <switch.h>
s64 SwitchIdent_GetTotalStorage(NcmStorageId storage_id);
s64 SwitchIdent_GetFreeStorage(NcmStorageId storage_id);
s64 SwitchIdent_GetUsedStorage(NcmStorageId storage_id);
#endif

View File

@ -1,94 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <switch.h>
#include "misc.h"
char *SwitchIdent_GetLanguage(void) {
Result ret = 0;
u64 language = 0;
if (R_FAILED(ret = setGetSystemLanguage(&language)))
printf("setGetSystemLanguage() failed: 0x%x.\n\n", ret);
return strupr((char*)&language);
}
char *SwitchIdent_GetRegion(void) {
Result ret = 0;
char *regions[] = {
"JPN",
"USA",
"EUR",
"AUS",
"CHN",
"KOR",
"TWN",
"Unknown"
};
SetRegion regionCode = 0;
if (R_FAILED(ret = setGetRegionCode(&regionCode))) {
printf("setGetRegionCode() failed: 0x%x.\n\n", ret);
return regions[7];
}
return regions[regionCode];
}
u32 SwitchIdent_GetClock(PcvModule module) {
Result ret = 0;
u32 out = 0;
if (hosversionAtLeast(8, 0, 0)) {
ClkrstSession session = {0};
PcvModuleId module_id;
if (R_FAILED(ret = pcvGetModuleId(&module_id, module)))
printf("pcvGetModuleId() failed: 0x%x.\n\n", ret);
else if (R_FAILED(ret = clkrstOpenSession(&session, module_id, 3)))
printf("clkrstOpenSession() failed: 0x%x.\n\n", ret);
else if (R_FAILED(ret = clkrstGetClockRate(&session, &out)))
printf("clkrstGetClockRate() failed: 0x%x.\n\n", ret);
else
clkrstCloseSession(&session);
} else {
if (R_FAILED(ret = pcvGetClockRate(module, &out)))
printf("pcvGetClockRate() failed: 0x%x.\n\n", ret);
}
return out/1000000;
}
char *SwitchIdent_GetBluetoothBdAddress(void) {
Result ret = 0;
static char bd_addr_string[0x13];
SetCalBdAddress bd_addr;
if (R_FAILED(ret = setcalGetBdAddress(&bd_addr))) {
printf("setcalGetBdAddress() failed: 0x%x.\n\n", ret);
return NULL;
}
snprintf(bd_addr_string, 0x12, "%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]);
return bd_addr_string;
}
char *SwitchIdent_GetWirelessLanMacAddress(void) {
Result ret = 0;
static char mac_addr_string[0x13];
SetCalMacAddress mac_addr;
if (R_FAILED(ret = setcalGetWirelessLanMacAddress(&mac_addr))) {
printf("setcalGetWirelessLanMacAddress() failed: 0x%x.\n\n", ret);
return NULL;
}
snprintf(mac_addr_string, 0x12, "%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]);
return mac_addr_string;
}

View File

@ -1,10 +0,0 @@
#ifndef _SWITCHIDENT_SYSTEM_H_
#define _SWITCHIDENT_SYSTEM_H_
char *SwitchIdent_GetLanguage(void);
char *SwitchIdent_GetRegion(void);
u32 SwitchIdent_GetClock(PcvModule module);
char *SwitchIdent_GetBluetoothBdAddress(void);
char *SwitchIdent_GetWirelessLanMacAddress(void);
#endif

View File

@ -1,16 +0,0 @@
#include <stdio.h>
#include <switch.h>
void Utils_GetSizeString(char *string, u64 size) {
double double_size = (double)size;
int i = 0;
static char *units[] = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
while (double_size >= 1024.0f) {
double_size /= 1024.0f;
i++;
}
sprintf(string, "%.*f %s", (i == 0) ? 0 : 2, double_size, units[i]);
}

View File

@ -1,6 +0,0 @@
#ifndef _SWITCHIDENT_UTILS_H_
#define _SWITCHIDENT_UTILS_H_
void Utils_GetSizeString(char *string, u64 size);
#endif

View File

@ -1,34 +0,0 @@
#include <switch.h>
u32 SwitchIdent_GetWlanState(void) {
Result ret = 0;
u32 out = 0;
if (R_FAILED(ret = wlaninfGetState(&out)))
return -1;
return out;
}
u32 SwitchIdent_GetWlanQuality(u32 dBm) {
u32 quality = 0;
if (dBm <= -100)
quality = 0;
else if (dBm >= -50)
quality = 100;
else
quality = 2 * (dBm + 100);
return quality;
}
u32 SwitchIdent_GetWlanRSSI(void) {
Result ret = 0;
s32 out = 0;
if (R_FAILED(ret = wlaninfGetRSSI(&out)))
return -1;
return out;
}

View File

@ -1,8 +0,0 @@
#ifndef _SWITCHIDENT_WLAN_H_
#define _SWITCHIDENT_WLAN_H_
u32 SwitchIdent_GetWlanState(void);
u32 SwitchIdent_GetWlanQuality(u32 dBm);
u32 SwitchIdent_GetWlanRSSI(void);
#endif

View File

@ -221,6 +221,12 @@ unsigned int FC_GetBufferSize(void);
/*! Changes the size of the internal buffer which is used for unpacking variadic text data. This buffer is shared by all FC_Fonts. */
void FC_SetBufferSize(unsigned int size);
/*! Returns the width of a single horizontal tab in multiples of the width of a space (default: 4) */
unsigned int FC_GetTabWidth(void);
/*! Changes the width of a horizontal tab in multiples of the width of a space (default: 4) */
void FC_SetTabWidth(unsigned int width_in_spaces);
void FC_SetRenderCallback(FC_Rect (*callback)(FC_Image* src, FC_Rect* srcrect, FC_Target* dest, float x, float y, float xscale, float yscale));
FC_Rect FC_DefaultRenderCallback(FC_Image* src, FC_Rect* srcrect, FC_Target* dest, float x, float y, float xscale, float yscale);

58
include/common.hpp Normal file
View File

@ -0,0 +1,58 @@
#ifndef _SWITCHIDENT_COMMON_H_
#define _SWITCHIDENT_COMMON_H_
#include <switch.h>
namespace SwitchIdent {
// Kernel
const char *GetDramDesc(void);
SetSysFirmwareVersion GetFirmwareVersion(void);
const char *GetHardwareType(void);
bool IsKiosk(void);
const char *GetUnit(void);
bool IsSafeMode(void);
u64 GetDeviceID(void);
SetSysSerialNumber GetSerialNumber(void);
// Misc
const char *GetOperationMode(void);
bool GetWirelessLanEnableFlag(void);
bool GetBluetoothEnableFlag(void);
bool GetNfcEnableFlag(void);
bool GetAutoUpdateEnableFlag(void);
bool GetConsoleInformationUploadFlag(void);
bool IsSDCardInserted(FsDeviceOperator *fsDeviceOperator);
bool IsGameCardInserted(FsDeviceOperator *fsDeviceOperator);
// Power
u32 GetBatteryPercentage(void);
const char *GetChargerType(void);
bool IsCharging(void);
bool IsChargingEnabled(void);
const char *GetVoltageState(void);
double GetRawBatteryChargePercentage(void);
bool IsEnoughPowerSupplied(void);
double GetBatteryAgePercentage(void);
SetBatteryLot GetBatteryLot(void);
// Storage
s64 GetTotalStorage(NcmStorageId storage_id);
s64 GetFreeStorage(NcmStorageId storage_id);
s64 GetUsedStorage(NcmStorageId storage_id);
void GetSizeString(char *string, double size);
// System
u64 GetLanguage(void);
const char *GetRegion(void);
u32 GetClock(PcvModule module);
SetCalBdAddress GetBluetoothBdAddress(void);
SetCalMacAddress GetWirelessLanMacAddress(void);
// Wlan
u32 GetWlanState(void);
s32 GetWlanQuality(s32 dBm);
u32 GetWlanRSSI(void);
}
#endif

View File

@ -1,5 +1,5 @@
#ifndef _SWITCHIDENT_SDL_HELPER_H_
#define _SWITCHIDENT_SDL_HELPER_H_
#ifndef _SWITCHIDENT_GUI_H_
#define _SWITCHIDENT_GUI_H_
#include <switch.h>
#include <SDL2/SDL.h>
@ -15,15 +15,17 @@
#define MENU_INFO_TITLE_COLOUR FC_MakeColor(144, 137, 129, 255)
#define MENU_INFO_DESC_COLOUR FC_MakeColor(51, 51, 51, 255)
int SDL_HelperInit(void);
void SDL_HelperTerm(void);
void SDL_ClearScreen(SDL_Color colour);
void SDL_DrawRect(int x, int y, int w, int h, SDL_Color colour);
void SDL_DrawText(int x, int y, int size, SDL_Color colour, const char *text);
void SDL_DrawTextf(int x, int y, int size, SDL_Color colour, const char* text, ...);
void SDL_GetTextDimensions(int size, const char *text, u32 *width, u32 *height);
void SDL_DrawBanner(int x, int y);
void SDL_DrawDriveIcon(int x, int y);
void SDL_Renderdisplay(void);
namespace GUI {
int Init(void);
void Exit(void);
void ClearScreen(SDL_Color colour);
void DrawRect(int x, int y, int w, int h, SDL_Color colour);
void DrawText(int x, int y, int size, SDL_Color colour, const char *text);
void DrawTextf(int x, int y, int size, SDL_Color colour, const char* text, ...);
void GetTextDimensions(int size, const char *text, u32 *width, u32 *height);
void DrawBanner(int x, int y);
void DrawDriveIcon(int x, int y);
void Render(void);
}
#endif

View File

@ -1,6 +1,8 @@
#ifndef _SWITCHIDENT_MENUS_H_
#define _SWITCHIDENT_MENUS_H_
void Menu_Main(void);
namespace Menus {
void Main(void);
}
#endif
#endif

View File

@ -153,8 +153,8 @@ static char* replace_concat(char** a, const char* b)
}
// Width of a tab in units of the space width (sorry, no tab alignment!)
static unsigned int fc_tab_width = 4;
// Shared buffer for variadic text
static char* fc_buffer = NULL;
@ -162,44 +162,50 @@ static unsigned int fc_buffer_size = 1024;
static Uint8 fc_has_render_target_support = 0;
// The number of fonts that has been created but not freed
static int NUM_EXISTING_FONTS = 0;
// Globals for GetString functions
static char* ASCII_STRING = NULL;
static char* LATIN_1_STRING = NULL;
static char* ASCII_LATIN_1_STRING = NULL;
char* FC_GetStringASCII(void)
{
static char* buffer = NULL;
if(buffer == NULL)
if(ASCII_STRING == NULL)
{
int i;
char c;
buffer = (char*)malloc(512);
memset(buffer, 0, 512);
ASCII_STRING = (char*)malloc(512);
memset(ASCII_STRING, 0, 512);
i = 0;
c = 32;
while(1)
{
buffer[i] = c;
ASCII_STRING[i] = c;
if(c == 126)
break;
++i;
++c;
}
}
return U8_strdup(buffer);
return U8_strdup(ASCII_STRING);
}
char* FC_GetStringLatin1(void)
{
static char* buffer = NULL;
if(buffer == NULL)
if(LATIN_1_STRING == NULL)
{
int i;
unsigned char c;
buffer = (char*)malloc(512);
memset(buffer, 0, 512);
LATIN_1_STRING = (char*)malloc(512);
memset(LATIN_1_STRING, 0, 512);
i = 0;
c = 0xA0;
while(1)
{
buffer[i] = 0xC2;
buffer[i+1] = c;
LATIN_1_STRING[i] = 0xC2;
LATIN_1_STRING[i+1] = c;
if(c == 0xBF)
break;
i += 2;
@ -209,24 +215,23 @@ char* FC_GetStringLatin1(void)
c = 0x80;
while(1)
{
buffer[i] = 0xC3;
buffer[i+1] = c;
LATIN_1_STRING[i] = 0xC3;
LATIN_1_STRING[i+1] = c;
if(c == 0xBF)
break;
i += 2;
++c;
}
}
return U8_strdup(buffer);
return U8_strdup(LATIN_1_STRING);
}
char* FC_GetStringASCII_Latin1(void)
{
static char* buffer = NULL;
if(buffer == NULL)
buffer = new_concat(FC_GetStringASCII(), FC_GetStringLatin1());
if(ASCII_LATIN_1_STRING == NULL)
ASCII_LATIN_1_STRING = new_concat(FC_GetStringASCII(), FC_GetStringLatin1());
return U8_strdup(buffer);
return U8_strdup(ASCII_LATIN_1_STRING);
}
FC_Rect FC_MakeRect(float x, float y, float w, float h)
@ -829,6 +834,17 @@ void FC_SetBufferSize(unsigned int size)
}
unsigned int FC_GetTabWidth(void)
{
return fc_tab_width;
}
void FC_SetTabWidth(unsigned int width_in_spaces)
{
fc_tab_width = width_in_spaces;
}
@ -973,7 +989,10 @@ Uint8 FC_UploadGlyphCache(FC_Font* font, int cache_level, SDL_Surface* data_surf
// Set filter mode for new texture
char old_filter_mode[16]; // Save it so we can change the hint value in the meantime
snprintf(old_filter_mode, 16, "%s", SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY));
const char* old_filter_hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
if(!old_filter_hint)
old_filter_hint = "nearest";
snprintf(old_filter_mode, 16, "%s", old_filter_hint);
if(FC_GetFilterMode(font) == FC_FILTER_LINEAR)
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
@ -1051,6 +1070,14 @@ static FC_GlyphData* FC_PackGlyphData(FC_Font* font, Uint32 codepoint, Uint16 wi
FC_GlyphData* last_glyph = &font->last_glyph;
Uint16 height = font->height + FC_CACHE_PADDING;
// TAB is special!
if(codepoint == '\t')
{
FC_GlyphData spaceGlyph;
FC_GetGlyphData(font, &spaceGlyph, ' ');
width = fc_tab_width * spaceGlyph.rect.w;
}
if(last_glyph->rect.x + last_glyph->rect.w + width >= maxWidth - FC_CACHE_PADDING)
{
if(last_glyph->rect.y + height + height >= maxHeight - FC_CACHE_PADDING)
@ -1130,6 +1157,7 @@ FC_Font* FC_CreateFont(void)
memset(font, 0, sizeof(FC_Font));
FC_Init(font);
++NUM_EXISTING_FONTS;
return font;
}
@ -1171,7 +1199,7 @@ Uint8 FC_LoadFontFromTTF(FC_Font* font, SDL_Renderer* renderer, TTF_Font* ttf, S
font->height = TTF_FontHeight(ttf);
font->ascent = TTF_FontAscent(ttf);
font->descent = -TTF_FontDescent(ttf);
// Some bug for certain fonts can result in an incorrect height.
if(font->height < font->ascent - font->descent)
font->height = font->ascent - font->descent;
@ -1437,6 +1465,22 @@ void FC_FreeFont(FC_Font* font)
free(font->loading_string);
free(font);
// If the last font has been freed; assume shutdown and free the global variables
if (--NUM_EXISTING_FONTS <= 0)
{
free(ASCII_STRING);
ASCII_STRING = NULL;
free(LATIN_1_STRING);
LATIN_1_STRING = NULL;
free(ASCII_LATIN_1_STRING);
ASCII_LATIN_1_STRING = NULL;
free(fc_buffer);
fc_buffer = NULL;
}
}
int FC_GetNumCacheLevels(FC_Font* font)
@ -1755,9 +1799,9 @@ FC_StringList** FC_StringListPushBack(FC_StringList** node, char* value, Uint8 c
{
if(node == NULL)
{
return node;
return NULL;
}
// Get to the last node
while(*node != NULL)
{
@ -1772,6 +1816,29 @@ FC_StringList** FC_StringListPushBack(FC_StringList** node, char* value, Uint8 c
return node;
}
FC_StringList** FC_StringListPushBackBytes(FC_StringList** node, const char* data, int num_bytes)
{
if(node == NULL)
{
return node;
}
// Get to the last node
while(*node != NULL)
{
node = &(*node)->next;
}
*node = (FC_StringList*)malloc(sizeof(FC_StringList));
(*node)->value = (char*)malloc(num_bytes + 1);
memcpy((*node)->value, data, num_bytes);
(*node)->value[num_bytes] = '\0';
(*node)->next = NULL;
return node;
}
static FC_StringList* FC_Explode(const char* text, char delimiter)
{
FC_StringList* head;
@ -1818,10 +1885,52 @@ static FC_StringList* FC_Explode(const char* text, char delimiter)
return head;
}
static FC_StringList* FC_ExplodeBreakingSpace(const char* text, FC_StringList** spaces)
{
FC_StringList* head;
FC_StringList** node;
const char* start;
const char* end;
unsigned int size;
if(text == NULL)
return NULL;
head = NULL;
node = &head;
// Warning: spaces must not be initialized before this function
*spaces = NULL;
// Doesn't technically support UTF-8, but it's probably fine, right?
size = 0;
start = end = text;
while(1)
{
// Add any characters here that should make separate words (except for \n?)
if(*end == ' ' || *end == '\t' || *end == '\0')
{
FC_StringListPushBackBytes(node, start, size);
FC_StringListPushBackBytes(spaces, end, 1);
if(*end == '\0')
break;
node = &((*node)->next);
start = end+1;
size = 0;
}
else
++size;
++end;
}
return head;
}
static FC_StringList* FC_ExplodeAndKeep(const char* text, char delimiter)
{
FC_StringList* head;
FC_StringList* new_node;
FC_StringList** node;
const char* start;
const char* end;
@ -1839,14 +1948,7 @@ static FC_StringList* FC_ExplodeAndKeep(const char* text, char delimiter)
{
if(*end == delimiter || *end == '\0')
{
*node = (FC_StringList*)malloc(sizeof(FC_StringList));
new_node = *node;
new_node->value = (char*)malloc(size + 1);
memcpy(new_node->value, start, size);
new_node->value[size] = '\0';
new_node->next = NULL;
FC_StringListPushBackBytes(node, start, size);
if(*end == '\0')
break;
@ -1895,15 +1997,15 @@ static FC_StringList* FC_GetBufferFitToColumn(FC_Font* font, int width, FC_Scale
// If line is too long, then add words one at a time until we go over.
if(width > 0 && FC_GetWidth(font, "%s", line) > width)
{
FC_StringList *words, *word_iter;
FC_StringList *words, *word_iter, *spaces, *spaces_iter;
words = FC_Explode(line, ' ');
words = FC_ExplodeBreakingSpace(line, &spaces);
// Skip the first word for the iterator, so there will always be at least one word per line
line = new_concat(words->value, " ");
for(word_iter = words->next; word_iter != NULL; word_iter = word_iter->next)
line = new_concat(words->value, spaces->value);
for(word_iter = words->next, spaces_iter = spaces->next; word_iter != NULL && spaces_iter != NULL; word_iter = word_iter->next, spaces_iter = spaces_iter->next)
{
char* line_plus_word = new_concat(line, word_iter->value);
char* word_plus_space = new_concat(word_iter->value, " ");
char* word_plus_space = new_concat(word_iter->value, spaces_iter->value);
if(FC_GetWidth(font, "%s", line_plus_word) > width)
{
current = FC_StringListPushBack(current, line, 0);
@ -1919,6 +2021,7 @@ static FC_StringList* FC_GetBufferFitToColumn(FC_Font* font, int width, FC_Scale
}
current = FC_StringListPushBack(current, line, 0);
FC_StringListFree(words);
FC_StringListFree(spaces);
}
else
{
@ -2644,17 +2747,17 @@ SDL_Color FC_GetDefaultColor(FC_Font* font)
FC_Rect FC_GetBounds(FC_Font* font, float x, float y, FC_AlignEnum align, FC_Scale scale, const char* formatted_text, ...)
{
FC_Rect result = {x, y, 0, 0};
if(formatted_text == NULL)
return result;
// Create a temp buffer while GetWidth and GetHeight use fc_buffer.
char* temp = (char*)malloc(fc_buffer_size);
FC_EXTRACT_VARARGS(temp, formatted_text);
result.w = FC_GetWidth(font, "%s", temp) * scale.x;
result.h = FC_GetHeight(font, "%s", temp) * scale.y;
switch(align)
{
case FC_ALIGN_LEFT:
@ -2668,9 +2771,9 @@ FC_Rect FC_GetBounds(FC_Font* font, float x, float y, FC_AlignEnum align, FC_Sca
default:
break;
}
free(temp);
return result;
}
@ -2749,7 +2852,7 @@ int FC_GetWrappedText(FC_Font* font, char* result, int max_result_size, Uint16 w
int num_bytes = FC_MIN(len, size_remaining);
memcpy(&result[size_so_far], iter->value, num_bytes);
size_so_far += num_bytes;
// If there's another line, add newline character
if(size_remaining > 0 && iter->next != NULL)
{
@ -2759,7 +2862,7 @@ int FC_GetWrappedText(FC_Font* font, char* result, int max_result_size, Uint16 w
}
}
FC_StringListFree(ls);
result[size_so_far] = '\0';
return size_so_far;

View File

@ -1,108 +0,0 @@
#include <SDL2/SDL_image.h>
#include "SDL_helper.h"
#define FC_USE_SDL_GPU 1
static SDL_Window *WINDOW;
static SDL_Renderer *RENDERER;
static FC_Font *font;
static SDL_Texture *banner, *drive;
static void SDL_LoadImage(SDL_Texture **texture, char *path) {
SDL_Surface *image = NULL;
image = IMG_Load(path);
if (!image)
return;
SDL_ConvertSurfaceFormat(image, SDL_PIXELFORMAT_RGBA8888, 0);
*texture = SDL_CreateTextureFromSurface(RENDERER, image);
SDL_FreeSurface(image);
}
int SDL_HelperInit(void) {
if (SDL_Init(SDL_INIT_VIDEO) != 0)
return -1;
WINDOW = SDL_CreateWindow("SwitchIdent", 0, 0, 1280, 720, SDL_WINDOW_FULLSCREEN);
if (WINDOW == NULL)
return -1;
RENDERER = SDL_CreateRenderer(WINDOW, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");
int flags = IMG_INIT_PNG;
if ((IMG_Init(flags) & flags) != flags)
return -1;
SDL_LoadImage(&banner, "romfs:/banner.png");
SDL_LoadImage(&drive, "romfs:/drive.png");
font = FC_CreateFont();
FC_LoadFont(font, RENDERER, "romfs:/Ubuntu-R.ttf", 25, FC_MakeColor(0, 0, 0, 255), TTF_STYLE_NORMAL);
return 0;
}
void SDL_HelperTerm(void) {
FC_FreeFont(font);
TTF_Quit();
IMG_Quit();
SDL_DestroyRenderer(RENDERER);
SDL_DestroyWindow(WINDOW);
SDL_Quit();
}
void SDL_ClearScreen(SDL_Color colour) {
SDL_SetRenderDrawColor(RENDERER, colour.r, colour.g, colour.b, colour.a);
SDL_RenderClear(RENDERER);
}
void SDL_DrawRect(int x, int y, int w, int h, SDL_Color colour) {
SDL_Rect rect;
rect.x = x; rect.y = y; rect.w = w; rect.h = h;
SDL_SetRenderDrawColor(RENDERER, colour.r, colour.g, colour.b, colour.a);
SDL_RenderFillRect(RENDERER, &rect);
}
void SDL_DrawText(int x, int y, int size, SDL_Color colour, const char *text) {
FC_DrawColor(font, RENDERER, x, y, colour, text);
}
void SDL_DrawTextf(int x, int y, int size, SDL_Color colour, const char* text, ...) {
char buffer[256];
va_list args;
va_start(args, text);
vsnprintf(buffer, 256, text, args);
SDL_DrawText(x, y, size, colour, buffer);
va_end(args);
}
void SDL_GetTextDimensions(int size, const char *text, u32 *width, u32 *height) {
if (width != NULL)
*width = FC_GetWidth(font, text);
if (height != NULL)
*height = FC_GetHeight(font, text);
}
static void SDL_DrawImage(SDL_Texture *texture, int x, int y) {
SDL_Rect position;
position.x = x; position.y = y;
SDL_QueryTexture(texture, NULL, NULL, &position.w, &position.h);
SDL_RenderCopy(RENDERER, texture, NULL, &position);
}
void SDL_DrawBanner(int x, int y) {
SDL_DrawImage(banner, x, y);
}
void SDL_DrawDriveIcon(int x, int y) {
SDL_DrawImage(drive, x, y);
}
void SDL_Renderdisplay(void) {
SDL_RenderPresent(RENDERER);
}

106
source/gui.cpp Normal file
View File

@ -0,0 +1,106 @@
#include <cstdio>
#include <SDL2/SDL_image.h>
#include "gui.hpp"
namespace GUI {
static SDL_Window *g_window = nullptr;
static SDL_Renderer *g_renderer = nullptr;
static FC_Font *g_font = nullptr;
static SDL_Texture *banner = nullptr, *drive = nullptr;
static void LoadImage(SDL_Texture **texture, const char *path) {
SDL_Surface *image = nullptr;
image = IMG_Load(path);
if (!image)
return;
SDL_ConvertSurfaceFormat(image, SDL_PIXELFORMAT_RGBA8888, 0);
*texture = SDL_CreateTextureFromSurface(g_renderer, image);
SDL_FreeSurface(image);
}
int Init(void) {
if (SDL_Init(SDL_INIT_VIDEO) != 0)
return -1;
g_window = SDL_CreateWindow("SwitchIdent", 0, 0, 1280, 720, SDL_WINDOW_FULLSCREEN);
if (g_window == nullptr)
return -1;
g_renderer = SDL_CreateRenderer(g_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");
int flags = IMG_INIT_PNG;
if ((IMG_Init(flags) & flags) != flags)
return -1;
GUI::LoadImage(&banner, "romfs:/banner.png");
GUI::LoadImage(&drive, "romfs:/drive.png");
g_font = FC_CreateFont();
FC_LoadFont(g_font, g_renderer, "romfs:/Ubuntu-R.ttf", 25, FC_MakeColor(0, 0, 0, 255), TTF_STYLE_NORMAL);
return 0;
}
void Exit(void) {
FC_FreeFont(g_font);
TTF_Quit();
IMG_Quit();
SDL_DestroyRenderer(g_renderer);
SDL_DestroyWindow(g_window);
SDL_Quit();
}
void ClearScreen(SDL_Color colour) {
SDL_SetRenderDrawColor(g_renderer, colour.r, colour.g, colour.b, colour.a);
SDL_RenderClear(g_renderer);
}
void DrawRect(int x, int y, int w, int h, SDL_Color colour) {
SDL_Rect rect;
rect.x = x; rect.y = y; rect.w = w; rect.h = h;
SDL_SetRenderDrawColor(g_renderer, colour.r, colour.g, colour.b, colour.a);
SDL_RenderFillRect(g_renderer, &rect);
}
void DrawText(int x, int y, int size, SDL_Color colour, const char *text) {
FC_DrawColor(g_font, g_renderer, x, y, colour, text);
}
void DrawTextf(int x, int y, int size, SDL_Color colour, const char* text, ...) {
char buffer[256];
va_list args;
va_start(args, text);
std::vsnprintf(buffer, 256, text, args);
GUI::DrawText(x, y, size, colour, buffer);
va_end(args);
}
void GetTextDimensions(int size, const char *text, u32 *width, u32 *height) {
if (width != nullptr)
*width = FC_GetWidth(g_font, text);
if (height != nullptr)
*height = FC_GetHeight(g_font, text);
}
static void DrawImage(SDL_Texture *texture, int x, int y) {
SDL_Rect position;
position.x = x; position.y = y;
SDL_QueryTexture(texture, nullptr, nullptr, &position.w, &position.h);
SDL_RenderCopy(g_renderer, texture, nullptr, &position);
}
void DrawBanner(int x, int y) {
GUI::DrawImage(banner, x, y);
}
void DrawDriveIcon(int x, int y) {
GUI::DrawImage(drive, x, y);
}
void Render(void) {
SDL_RenderPresent(g_renderer);
}
}

147
source/kernel.cpp Normal file
View File

@ -0,0 +1,147 @@
#include <cstdio>
#include "common.hpp"
namespace SwitchIdent {
const char *GetDramDesc(void) {
Result ret = 0;
u64 id = 0;
const char *dram_desc[] = {
"EristaIcosaSamsung4gb",
"EristaIcosaHynix4gb",
"EristaIcosaMicron4gb",
"MarikoIowaHynix1y4gb",
"EristaIcosaSamsung6gb",
"MarikoHoagHynix1y4gb",
"MarikoAulaHynix1y4gb",
"MarikoIowax1x2Samsung4gb",
"MarikoIowaSamsung4gb",
"MarikoIowaSamsung8gb",
"MarikoIowaHynix4gb",
"MarikoIowaMicron4gb",
"MarikoHoagSamsung4gb",
"MarikoHoagSamsung8gb",
"MarikoHoagSamsung8gb",
"MarikoHoagHynix4gb",
"MarikoHoagMicron4gb",
"MarikoIowaSamsung4gbY",
"MarikoIowaSamsung1y4gbX",
"MarikoIowaSamsung1y8gbX",
"MarikoHoagSamsung1y4gbX",
"MarikoIowaSamsung1y4gbY",
"MarikoIowaSamsung1y8gbY",
"MarikoAulaSamsung1y4gb",
"MarikoHoagSamsung1y8gbX",
"MarikoAulaSamsung1y4gbX",
"MarikoIowaMicron1y4gb",
"MarikoHoagMicron1y4gb",
"MarikoAulaMicron1y4gb",
"MarikoAulaSamsung1y8gbX",
"Unknown"
};
if (R_FAILED(ret = splGetConfig(SplConfigItem_DramId, &id)))
std::printf("splGetConfig(SplConfigItem_DramId) failed: 0x%x.\n\n", ret);
if (id >= 30)
return dram_desc[30];
return dram_desc[id];
}
SetSysFirmwareVersion GetFirmwareVersion(void) {
Result ret = 0;
SetSysFirmwareVersion version;
if (R_FAILED(ret = setsysGetFirmwareVersion(&version)))
std::printf("setsysGetFirmwareVersion() failed: 0x%x.\n\n", ret);
return version;
}
const char *GetHardwareType(void) {
Result ret = 0;
u64 hardware_type;
const char *hardware_string[] = {
"Icosa",
"Copper",
"Hoag",
"Iowa",
"Calcio",
"Aula",
"Unknown"
};
if (R_FAILED(ret = splGetConfig(SplConfigItem_HardwareType, &hardware_type)))
std::printf("splGetConfig(SplConfigItem_HardwareType) failed: 0x%x.\n\n", ret);
if (hardware_type >= 6)
return hardware_string[6];
return hardware_string[hardware_type];
}
// [4.0.0+] Kiosk mode (0 = retail; 1 = kiosk)
bool IsKiosk(void) {
u64 is_kiosk_mode = 0;
Result ret = 0;
if (R_FAILED(ret = splGetConfig(SplConfigItem_IsKiosk , &is_kiosk_mode)))
std::printf("splGetConfig(SplConfigItem_IsKiosk) failed: 0x%x.\n\n", ret);
return is_kiosk_mode? true : false;
}
const char *GetUnit(void) {
Result ret = 0;
u64 is_retail_mode = 0;
const char *unit[] = {
"Debug",
"Retail",
"Unknown"
};
if (R_FAILED(ret = splGetConfig(SplConfigItem_IsRetail, &is_retail_mode))) {
std::printf("splGetConfig(SplConfigItem_IsRetail) failed: 0x%x.\n\n", ret);
return unit[2];
}
return unit[is_retail_mode];
}
bool IsSafeMode(void) {
Result ret = 0;
u64 safemode = 0;
if (R_FAILED(ret = splGetConfig(SplConfigItem_IsRecoveryBoot, &safemode)))
std::printf("splGetConfig(SplConfigItem_IsRecoveryBoot) failed: 0x%x.\n\n", ret);
if (safemode)
return true;
return false;
}
u64 GetDeviceID(void) {
Result ret = 0;
u64 id = 0;
if (R_FAILED(ret = splGetConfig(SplConfigItem_DeviceId, &id)))
std::printf("splGetConfig(SplConfigItem_DeviceId) failed: 0x%x.\n\n", ret);
return id;
}
SetSysSerialNumber GetSerialNumber(void) {
Result ret = 0;
SetSysSerialNumber serial;
if (R_FAILED(ret = setsysGetSerialNumber(&serial)))
std::printf("setsysGetSerialNumber() failed: 0x%x.\n\n", ret);
return serial;
}
}

View File

@ -1,82 +0,0 @@
#include <switch.h>
#include "menus.h"
#include "power.h"
#include "SDL_helper.h"
#include "wlan.h"
static void Term_Services(void) {
wlaninfExit();
if (hosversionAtLeast(8, 0, 0))
clkrstExit();
else
pcvExit();
psmExit();
nsExit();
apmExit();
appletExit();
socketExit();
nifmExit();
splExit();
setcalExit();
setsysExit();
setExit();
SDL_HelperTerm();
romfsExit();
}
static void Init_Services(void) {
Result ret = 0;
if (R_FAILED(ret = romfsInit()))
printf("romfsInit() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = setInitialize()))
printf("setInitialize() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = setsysInitialize()))
printf("setsysInitialize() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = setcalInitialize()))
printf("setcalInitialize() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = splInitialize()))
printf("splInitialize() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = nifmInitialize(NifmServiceType_User)))
printf("nifmInitialize() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = socketInitializeDefault()))
printf("socketInitializeDefault() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = appletInitialize()))
printf("appletInitialize() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = apmInitialize()))
printf("apmInitialize() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = nsInitialize()))
printf("nsInitialize() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = psmInitialize()))
printf("psmInitialize() failed: 0x%x.\n\n", ret);
if (hosversionAtLeast(8, 0, 0)) {
if (R_FAILED(ret = clkrstInitialize()))
printf("clkrstInitialize() failed: 0x%x.\n\n", ret);
} else {
if (R_FAILED(ret = pcvInitialize()))
printf("pcvInitialize() failed: 0x%x.\n\n", ret);
}
if (R_FAILED(ret = wlaninfInitialize()))
printf("wlaninfInitialize() failed: 0x%x.\n\n", ret);
SDL_HelperInit();
}
int main(int argc, char **argv) {
Init_Services();
Menu_Main();
Term_Services();
}

85
source/main.cpp Normal file
View File

@ -0,0 +1,85 @@
#include <cstdio>
#include "common.hpp"
#include "gui.hpp"
#include "menus.hpp"
namespace Services {
void Exit(void) {
wlaninfExit();
if (hosversionAtLeast(8, 0, 0))
clkrstExit();
else
pcvExit();
psmExit();
nsExit();
apmExit();
appletExit();
socketExit();
nifmExit();
splExit();
setcalExit();
setsysExit();
setExit();
GUI::Exit();
romfsExit();
}
void Init(void) {
Result ret = 0;
if (R_FAILED(ret = romfsInit()))
std::printf("romfsInit() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = setInitialize()))
std::printf("setInitialize() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = setsysInitialize()))
std::printf("setsysInitialize() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = setcalInitialize()))
std::printf("setcalInitialize() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = splInitialize()))
std::printf("splInitialize() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = nifmInitialize(NifmServiceType_User)))
std::printf("nifmInitialize() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = socketInitializeDefault()))
std::printf("socketInitializeDefault() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = appletInitialize()))
std::printf("appletInitialize() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = apmInitialize()))
std::printf("apmInitialize() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = nsInitialize()))
std::printf("nsInitialize() failed: 0x%x.\n\n", ret);
if (R_FAILED(ret = psmInitialize()))
std::printf("psmInitialize() failed: 0x%x.\n\n", ret);
if (hosversionAtLeast(8, 0, 0)) {
if (R_FAILED(ret = clkrstInitialize()))
std::printf("clkrstInitialize() failed: 0x%x.\n\n", ret);
} else {
if (R_FAILED(ret = pcvInitialize()))
std::printf("pcvInitialize() failed: 0x%x.\n\n", ret);
}
if (R_FAILED(ret = wlaninfInitialize()))
std::printf("wlaninfInitialize() failed: 0x%x.\n\n", ret);
GUI::Init();
}
}
int main(int argc, char **argv) {
Services::Init();
Menus::Main();
Services::Exit();
}

View File

@ -1,209 +0,0 @@
#include <unistd.h>
#include <switch.h>
#include "kernel.h"
#include "menus.h"
#include "misc.h"
#include "power.h"
#include "SDL_helper.h"
#include "storage.h"
#include "system.h"
#include "utils.h"
#include "wlan.h"
#define MENU_Y_DIST 67
#define MAX_MENU_ITEMS 5
static u32 item_height = 0;
static bool isSDInserted = false, isGameCardInserted = false;
static void Menu_DrawItem(int x, int y, char *item_title, const char *text, ...) {
u32 title_width = 0;
SDL_GetTextDimensions(25, item_title, &title_width, NULL);
SDL_DrawText(x, y, 25, MENU_INFO_TITLE_COLOUR, item_title);
char buffer[256];
va_list args;
va_start(args, text);
vsnprintf(buffer, 256, text, args);
SDL_DrawText(x + title_width + 20, y, 25, MENU_INFO_DESC_COLOUR, buffer);
va_end(args);
}
static void Menu_Kernel(void) {
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 50, "Firmware version:", SwitchIdent_GetFirmwareVersion());
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 100, "Hardware:", SwitchIdent_GetHardwareType());
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 150, "Unit:", SwitchIdent_GetUnit());
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 200, "Serial:", SwitchIdent_GetSerialNumber());
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 250, "DRAM ID:", SwitchIdent_GetDramDesc());
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 300, "Device ID:", "%llu", SwitchIdent_GetDeviceID());
}
static void Menu_System(void) {
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 50, "Region:", SwitchIdent_GetRegion());
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 100, "CPU clock:", "%lu MHz", SwitchIdent_GetClock(PcvModule_CpuBus));
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 150, "GPU clock:", "%lu MHz", SwitchIdent_GetClock(PcvModule_GPU));
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 200, "EMC clock:", "%lu MHz", SwitchIdent_GetClock(PcvModule_EMC));
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 250, "Wireless LAN:", "%s (RSSI: %d) (Quality: %lu)", SwitchIdent_GetWirelessLanEnableFlag()? "Enabled" : "Disabled", SwitchIdent_GetWlanRSSI(), SwitchIdent_GetWlanQuality(SwitchIdent_GetWlanRSSI()));
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 300, "Bluetooth:", "%s", SwitchIdent_GetBluetoothEnableFlag()? "Enabled" : "Disabled");
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 350, "NFC:", SwitchIdent_GetNfcEnableFlag()? "Enabled" : "Disabled");
}
static void Menu_Power(void) {
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 50, "Battery percentage:", "%lu %% (%s)", SwitchIdent_GetBatteryPercent(), SwitchIdent_IsCharging()? "charging" : "not charging");
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 100, "Battery voltage state:", SwitchIdent_GetVoltageState());
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 150, "Battery charger type:", SwitchIdent_GetChargerType());
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 200, "Battery charging enabled:", SwitchIdent_IsChargingEnabled()? "Yes" : "No");
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 250, "Battery ample power supplied:", SwitchIdent_IsEnoughPowerSupplied()? "Yes" : "No");
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 300, "Battery lot number:", SwitchIdent_GetBatteryLot());
}
static void Menu_Storage(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];
Utils_GetSizeString(sd_total_str, sd_total);
Utils_GetSizeString(sd_free_str, SwitchIdent_GetFreeStorage(NcmStorageId_SdCard));
Utils_GetSizeString(sd_used_str, sd_used);
char nand_u_total_str[16], nand_u_free_str[16], nand_u_used_str[16];
Utils_GetSizeString(nand_u_total_str, nand_u_total);
Utils_GetSizeString(nand_u_free_str, SwitchIdent_GetFreeStorage(NcmStorageId_BuiltInUser));
Utils_GetSizeString(nand_u_used_str, nand_u_used);
char nand_s_total_str[16], nand_s_free_str[16], nand_s_used_str[16];
Utils_GetSizeString(nand_s_total_str, nand_s_total);
Utils_GetSizeString(nand_s_free_str, SwitchIdent_GetFreeStorage(NcmStorageId_BuiltInSystem));
Utils_GetSizeString(nand_s_used_str, nand_s_used);
SDL_DrawRect(400, 50, 880, 670, BACKGROUND_COLOUR);
SDL_DrawDriveIcon(450, 88);
SDL_DrawRect(450, 226, 128, 25, STATUS_BAR_COLOUR);
SDL_DrawRect(452, 228, 124, 21, BACKGROUND_COLOUR);
SDL_DrawRect(452, 228, (((double)sd_used / (double)sd_total) * 124.0), 21, MENU_SELECTOR_COLOUR);
SDL_DrawDriveIcon(450, 296);
SDL_DrawRect(450, 434, 128, 25, STATUS_BAR_COLOUR);
SDL_DrawRect(452, 436, 124, 21, BACKGROUND_COLOUR);
SDL_DrawRect(452, 436, (((double)nand_u_used / (double)nand_u_total) * 124.0), 21, MENU_SELECTOR_COLOUR);
SDL_DrawDriveIcon(450, 504);
SDL_DrawRect(450, 642, 128, 25, STATUS_BAR_COLOUR);
SDL_DrawRect(452, 644, 124, 21, BACKGROUND_COLOUR);
SDL_DrawRect(452, 644, (((double)nand_s_used / (double)nand_s_total) * 124.0), 21, MENU_SELECTOR_COLOUR);
SDL_DrawText(600, 38 + ((MENU_Y_DIST - item_height) / 2) + 50, 25, MENU_INFO_DESC_COLOUR, "SD");
Menu_DrawItem(600, 38 + ((MENU_Y_DIST - item_height) / 2) + 88, "Total storage capacity:", sd_total_str);
Menu_DrawItem(600, 38 + ((MENU_Y_DIST - item_height) / 2) + 126, "Free storage capacity:", sd_free_str);
Menu_DrawItem(600, 38 + ((MENU_Y_DIST - item_height) / 2) + 164, "Used storage capacity:", sd_used_str);
SDL_DrawText(600, 246 + ((MENU_Y_DIST - item_height) / 2) + 50, 25, MENU_INFO_DESC_COLOUR, "NAND User");
Menu_DrawItem(600, 246 + ((MENU_Y_DIST - item_height) / 2) + 88, "Total storage capacity:", nand_u_total_str);
Menu_DrawItem(600, 246 + ((MENU_Y_DIST - item_height) / 2) + 126, "Free storage capacity:", nand_u_free_str);
Menu_DrawItem(600, 246 + ((MENU_Y_DIST - item_height) / 2) + 164, "Used storage capacity:", nand_u_used_str);
SDL_DrawText(600, 454 + ((MENU_Y_DIST - item_height) / 2) + 50, 25, MENU_INFO_DESC_COLOUR, "NAND System");
Menu_DrawItem(600, 454 + ((MENU_Y_DIST - item_height) / 2) + 88, "Total storage capacity:", nand_s_total_str);
Menu_DrawItem(600, 454 + ((MENU_Y_DIST - item_height) / 2) + 126, "Free storage capacity:", nand_s_free_str);
Menu_DrawItem(600, 454 + ((MENU_Y_DIST - item_height) / 2) + 164, "Used storage capacity:", nand_s_used_str);
}
static void Menu_Misc(void) {
char hostname[128];
Result ret = gethostname(hostname, sizeof(hostname));
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 50, "IP:", R_SUCCEEDED(ret)? hostname : NULL);
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 100, "State:", SwitchIdent_GetOperationMode());
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 150, "Automatic update:", SwitchIdent_GetAutoUpdateEnableFlag()? "Enabled" : "Disabled");
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 200, "Console information upload:", SwitchIdent_GetConsoleInformationUploadFlag()? "Enabled" : "Disabled");
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 250, "SD card status:", isSDInserted? "Inserted" : "Not inserted");
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 300, "Game card status:", isGameCardInserted? "Inserted" : "Not inserted");
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 350, "BT address:", SwitchIdent_GetBluetoothBdAddress());
Menu_DrawItem(450, 250 + ((MENU_Y_DIST - item_height) / 2) + 400, "WLAN address:", SwitchIdent_GetWirelessLanMacAddress());
}
void Menu_Main(void) {
u32 title_height = 0;
SDL_GetTextDimensions(25, "SwitchIdent", NULL, &title_height);
SDL_GetTextDimensions(25, "Test", NULL, &item_height);
int banner_width = 200;
int selection = 0;
Result ret = 0;
FsDeviceOperator fsDeviceOperator;
if (R_FAILED(ret = fsOpenDeviceOperator(&fsDeviceOperator)))
printf("fsOpenDeviceOperator() failed: 0x%x.\n\n", ret);
isSDInserted = SwitchIdent_IsSDCardInserted(&fsDeviceOperator);
isGameCardInserted = SwitchIdent_IsGameCardInserted(&fsDeviceOperator);
fsDeviceOperatorClose(&fsDeviceOperator);
padConfigureInput(1, HidNpadStyleSet_NpadStandard);
PadState pad;
padInitializeDefault(&pad);
while(appletMainLoop()) {
SDL_ClearScreen(BACKGROUND_COLOUR);
SDL_DrawRect(0, 0, 1280, 50, STATUS_BAR_COLOUR);
SDL_DrawRect(0, 50, 400, 670, MENU_BAR_COLOUR);
SDL_DrawTextf(30, ((50 - title_height) / 2), 25, BACKGROUND_COLOUR, "SwitchIdent v%d.%d", VERSION_MAJOR, VERSION_MINOR);// 0x%lx 0x%lx", connect, disconnect);
SDL_DrawBanner(400 + ((880 - (banner_width)) / 2), 80);
SDL_DrawRect(0, 50 + (MENU_Y_DIST * selection), 400, MENU_Y_DIST, MENU_SELECTOR_COLOUR);
SDL_DrawText(30, 50 + ((MENU_Y_DIST - item_height) / 2), 25, selection == 0? ITEM_SELECTED_COLOUR : ITEM_COLOUR, "Kernel");
SDL_DrawText(30, 50 + ((MENU_Y_DIST - item_height) / 2) + (MENU_Y_DIST * 1), 25, selection == 1? ITEM_SELECTED_COLOUR : ITEM_COLOUR, "System");
SDL_DrawText(30, 50 + ((MENU_Y_DIST - item_height) / 2) + (MENU_Y_DIST * 2), 25, selection == 2? ITEM_SELECTED_COLOUR : ITEM_COLOUR, "Power");
SDL_DrawText(30, 50 + ((MENU_Y_DIST - item_height) / 2) + (MENU_Y_DIST * 3), 25, selection == 3? ITEM_SELECTED_COLOUR : ITEM_COLOUR, "Storage");
SDL_DrawText(30, 50 + ((MENU_Y_DIST - item_height) / 2) + (MENU_Y_DIST * 4), 25, selection == 4? ITEM_SELECTED_COLOUR : ITEM_COLOUR, "Misc");
SDL_DrawText(30, 50 + ((MENU_Y_DIST - item_height) / 2) + (MENU_Y_DIST * 5), 25, selection == 5? ITEM_SELECTED_COLOUR : ITEM_COLOUR, "Exit");
padUpdate(&pad);
u32 kDown = padGetButtonsDown(&pad);
if (kDown & HidNpadButton_AnyDown)
selection++;
else if (kDown & HidNpadButton_AnyUp)
selection--;
if (selection > MAX_MENU_ITEMS)
selection = 0;
if (selection < 0)
selection = MAX_MENU_ITEMS;
switch (selection) {
case 0:
Menu_Kernel();
break;
case 1:
Menu_System();
break;
case 2:
Menu_Power();
break;
case 3:
Menu_Storage();
break;
case 4:
Menu_Misc();
break;
}
SDL_Renderdisplay();
if ((kDown & HidNpadButton_Plus) || ((kDown & HidNpadButton_A) && (selection == MAX_MENU_ITEMS)))
break;
}
}

239
source/menus.cpp Normal file
View File

@ -0,0 +1,239 @@
#include <cstdio>
#include <unistd.h>
#include "common.hpp"
#include "gui.hpp"
#include "menus.hpp"
namespace Menus {
static u32 g_item_height = 0;
static bool g_is_sd_inserted = false, g_is_gamecard_inserted = false;
static const int g_item_dist = 67;
static const int g_start_x = 450;
static const int g_start_y = 250;
enum MenuState {
STATE_KERNEL_INFO = 0,
STATE_SYSTEM_INFO,
STATE_POWER_INFO,
STATE_STORAGE_INFO,
STATE_MISC_INFO,
MAX_ITEMS
};
static void DrawItem(int x, int y, const char *title, const char *text) {
u32 title_width = 0;
GUI::GetTextDimensions(25, title, &title_width, nullptr);
GUI::DrawText(x, y, 25, MENU_INFO_TITLE_COLOUR, title);
GUI::DrawText(x + title_width + 20, y, 25, MENU_INFO_DESC_COLOUR, text);
}
static void DrawItemf(int x, int y, const char *title, const char *text, ...) {
u32 title_width = 0;
GUI::GetTextDimensions(25, title, &title_width, nullptr);
GUI::DrawText(x, y, 25, MENU_INFO_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, MENU_INFO_DESC_COLOUR, buffer);
va_end(args);
}
void KernelInfo(void) {
SetSysFirmwareVersion ver = SwitchIdent::GetFirmwareVersion();
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 50, "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) + 100, "Hardware:", SwitchIdent::GetHardwareType());
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 150, "Unit:", SwitchIdent::GetUnit());
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 200, "Serial:", SwitchIdent::GetSerialNumber().number);
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 250, "DRAM ID:", SwitchIdent::GetDramDesc());
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 300, "Device ID:", "%llu", SwitchIdent::GetDeviceID());
}
void SystemInfo(void) {
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 50, "Region:", SwitchIdent::GetRegion());
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 100, "CPU clock:", "%lu MHz", SwitchIdent::GetClock(PcvModule_CpuBus));
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 150, "GPU clock:", "%lu MHz", SwitchIdent::GetClock(PcvModule_GPU));
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 200, "EMC clock:", "%lu MHz", SwitchIdent::GetClock(PcvModule_EMC));
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 250, "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) + 300, "Bluetooth:", SwitchIdent::GetBluetoothEnableFlag()? "Enabled" : "Disabled");
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 350, "NFC:", SwitchIdent::GetNfcEnableFlag()? "Enabled" : "Disabled");
}
void PowerInfo(void) {
Menus::DrawItemf(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 50, "Battery percentage:", "%lu %% (%s)", SwitchIdent::GetBatteryPercentage(), SwitchIdent::IsCharging()? "charging" : "not charging");
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 100, "Battery voltage state:", SwitchIdent::GetVoltageState());
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 150, "Battery charger type:", SwitchIdent::GetChargerType());
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 200, "Battery charging enabled:", SwitchIdent::IsChargingEnabled()? "Yes" : "No");
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 250, "Battery ample power supplied:", SwitchIdent::IsEnoughPowerSupplied()? "Yes" : "No");
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 300, "Battery lot number:", SwitchIdent::GetBatteryLot().lot);
}
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, BACKGROUND_COLOUR);
GUI::DrawDriveIcon(450, 88);
GUI::DrawRect(450, 226, 128, 25, STATUS_BAR_COLOUR);
GUI::DrawRect(452, 228, 124, 21, BACKGROUND_COLOUR);
GUI::DrawRect(452, 228, (((double)sd_used / (double)sd_total) * 124.0), 21, MENU_SELECTOR_COLOUR);
GUI::DrawDriveIcon(450, 296);
GUI::DrawRect(450, 434, 128, 25, STATUS_BAR_COLOUR);
GUI::DrawRect(452, 436, 124, 21, BACKGROUND_COLOUR);
GUI::DrawRect(452, 436, (((double)nand_u_used / (double)nand_u_total) * 124.0), 21, MENU_SELECTOR_COLOUR);
GUI::DrawDriveIcon(450, 504);
GUI::DrawRect(450, 642, 128, 25, STATUS_BAR_COLOUR);
GUI::DrawRect(452, 644, 124, 21, BACKGROUND_COLOUR);
GUI::DrawRect(452, 644, (((double)nand_s_used / (double)nand_s_total) * 124.0), 21, MENU_SELECTOR_COLOUR);
GUI::DrawText(600, 38 + ((g_item_dist - g_item_height) / 2) + 50, 25, MENU_INFO_DESC_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, MENU_INFO_DESC_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, MENU_INFO_DESC_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 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) + 50, "IP:", R_SUCCEEDED(ret)? hostname : nullptr);
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 100, "State:", SwitchIdent::GetOperationMode());
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 150, "Automatic update:", SwitchIdent::GetAutoUpdateEnableFlag()? "Enabled" : "Disabled");
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 200, "Console information upload:", SwitchIdent::GetConsoleInformationUploadFlag()? "Enabled" : "Disabled");
Menus::DrawItem(g_start_x, g_start_y + ((g_item_dist - g_item_height) / 2) + 250, "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) + 300, "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) + 350, "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) + 400, "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) {
u32 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);
PadState pad;
padInitializeDefault(&pad);
const char *items[] = {
"Kernel",
"System",
"Power",
"Storage",
"Misc",
"Exit"
};
while(appletMainLoop()) {
GUI::ClearScreen(BACKGROUND_COLOUR);
GUI::DrawRect(0, 0, 1280, 50, STATUS_BAR_COLOUR);
GUI::DrawRect(0, 50, 400, 670, MENU_BAR_COLOUR);
GUI::DrawTextf(30, ((50 - title_height) / 2), 25, BACKGROUND_COLOUR, "SwitchIdent v%d.%d", VERSION_MAJOR, VERSION_MINOR);
GUI::DrawBanner(400 + ((880 - (banner_width)) / 2), 80);
GUI::DrawRect(0, 50 + (g_item_dist * selection), 400, g_item_dist, MENU_SELECTOR_COLOUR);
for (int i = 0; i < MAX_ITEMS + 1; i++)
GUI::DrawText(30, 50 + ((g_item_dist - g_item_height) / 2) + (g_item_dist * i), 25, selection == i? ITEM_SELECTED_COLOUR : ITEM_COLOUR, items[i]);
padUpdate(&pad);
u32 kDown = padGetButtonsDown(&pad);
if (kDown & HidNpadButton_AnyDown)
selection++;
else if (kDown & HidNpadButton_AnyUp)
selection--;
if (selection > MAX_ITEMS)
selection = 0;
if (selection < 0)
selection = MAX_ITEMS;
switch (selection) {
case STATE_KERNEL_INFO:
Menus::KernelInfo();
break;
case STATE_SYSTEM_INFO:
Menus::SystemInfo();
break;
case STATE_POWER_INFO:
Menus::PowerInfo();
break;
case STATE_STORAGE_INFO:
Menus::StorageInfo();
break;
case STATE_MISC_INFO:
Menus::MiscInfo();
break;
default:
break;
}
GUI::Render();
if ((kDown & HidNpadButton_Plus) || ((kDown & HidNpadButton_A) && (selection == MAX_ITEMS)))
break;
}
}
}

82
source/misc.cpp Normal file
View File

@ -0,0 +1,82 @@
#include <cstdio>
#include "common.hpp"
namespace SwitchIdent {
const char *GetOperationMode(void) {
if (appletGetOperationMode() == AppletOperationMode_Handheld)
return "Handheld";
return "Docked";
}
bool GetWirelessLanEnableFlag(void) {
Result ret = 0;
bool out = false;
if (R_FAILED(ret = setsysGetWirelessLanEnableFlag(&out)))
std::printf("setsysGetWirelessLanEnableFlag() failed: 0x%x.\n\n", ret);
return out;
}
bool GetBluetoothEnableFlag(void) {
Result ret = 0;
bool out = false;
if (R_FAILED(ret = setsysGetBluetoothEnableFlag(&out)))
std::printf("setsysGetBluetoothEnableFlag() failed: 0x%x.\n\n", ret);
return out;
}
bool GetNfcEnableFlag(void) {
Result ret = 0;
bool out = false;
if (R_FAILED(ret = setsysGetNfcEnableFlag(&out)))
std::printf("setsysGetNfcEnableFlag() failed: 0x%x.\n\n", ret);
return out;
}
bool GetAutoUpdateEnableFlag(void) {
Result ret = 0;
bool out = false;
if (R_FAILED(ret = setsysGetAutoUpdateEnableFlag(&out)))
std::printf("setsysGetAutoUpdateEnableFlag() failed: 0x%x.\n\n", ret);
return out;
}
bool GetConsoleInformationUploadFlag(void) {
Result ret = 0;
bool out = false;
if (R_FAILED(ret = setsysGetConsoleInformationUploadFlag(&out)))
std::printf("setsysGetConsoleInformationUploadFlag() failed: 0x%x.\n\n", ret);
return out;
}
bool IsSDCardInserted(FsDeviceOperator *fsDeviceOperator) {
Result ret = 0;
bool out = false;
if (R_FAILED(ret = fsDeviceOperatorIsSdCardInserted(fsDeviceOperator, &out)))
std::printf("fsDeviceOperatorIsSdCardInserted() failed: 0x%x.\n\n", ret);
return out;
}
bool IsGameCardInserted(FsDeviceOperator *fsDeviceOperator) {
Result ret = 0;
bool out = false;
if (R_FAILED(ret = fsDeviceOperatorIsGameCardInserted(fsDeviceOperator, &out)))
std::printf("fsDeviceOperatorIsGameCardInserted() failed: 0x%x.\n\n", ret);
return out;
}
}

127
source/power.cpp Normal file
View File

@ -0,0 +1,127 @@
#include <cstdio>
#include "common.hpp"
namespace SwitchIdent {
static Result _psmCmdNoInOutBool(Service* srv, bool *out, u32 cmd_id) {
u8 outval = 0;
Result ret = serviceDispatchOut(srv, cmd_id, outval);
if (R_SUCCEEDED(ret)) {
if (out)
*out = outval & 1;
}
return ret;
}
static Result psmIsBatteryChargingEnabled(bool *out) {
return _psmCmdNoInOutBool(psmGetServiceSession(), out, 4);
}
u32 GetBatteryPercentage(void) {
Result ret = 0;
u32 percentage = 0;
if (R_FAILED(ret = psmGetBatteryChargePercentage(&percentage)))
return -1;
return percentage;
}
const char *GetChargerType(void) {
Result ret = 0;
PsmChargerType charger_type;
if (R_FAILED(ret = psmGetChargerType(&charger_type)))
return nullptr;
if (charger_type == PsmChargerType_EnoughPower)
return "Official charger or dock";
else if (charger_type == PsmChargerType_LowPower)
return "USB-C charger";
else
return "No charger connected";
return nullptr;
}
bool IsCharging(void) {
Result ret = 0;
PsmChargerType charger_type;
if (R_FAILED(ret = psmGetChargerType(&charger_type)))
return false;
return charger_type != PsmChargerType_Unconnected;
}
bool IsChargingEnabled(void) {
Result ret = 0;
bool is_charing_enabled = 0;
if (R_FAILED(ret = psmIsBatteryChargingEnabled(&is_charing_enabled)))
return -1;
return is_charing_enabled;
}
const char *GetVoltageState(void) {
Result ret = 0;
PsmBatteryVoltageState voltage_state;
const char *states[] = {
"Power state needs shutdown",
"Power state needs sleep",
"Performance boost cannot be entered",
"Normal",
"Unknown"
};
if (R_SUCCEEDED(ret = psmGetBatteryVoltageState(&voltage_state))) {
if (voltage_state < 4)
return states[voltage_state];
}
std::printf("psmGetBatteryVoltageState() failed: 0x%x.\n\n", ret);
return states[4];
}
double GetRawBatteryChargePercentage(void) {
Result ret = 0;
double raw_percentage = 0;
if (R_FAILED(ret = psmGetRawBatteryChargePercentage(&raw_percentage)))
return -1;
return raw_percentage;
}
bool IsEnoughPowerSupplied(void) {
Result ret = 0;
bool is_power_supplied = 0;
if (R_FAILED(ret = psmIsEnoughPowerSupplied(&is_power_supplied)))
return -1;
return is_power_supplied;
}
double GetBatteryAgePercentage(void) {
Result ret = 0;
double age_percentage = 0;
if (R_FAILED(ret = psmGetBatteryAgePercentage(&age_percentage)))
return -1;
return age_percentage;
}
SetBatteryLot GetBatteryLot(void) {
Result ret = 0;
SetBatteryLot battery_lot;
if (R_FAILED(ret = setcalGetBatteryLot(&battery_lot)))
std::printf("setcalGetBatteryLot() failed: 0x%x.\n\n", ret);
return battery_lot;
}
}

40
source/storage.cpp Normal file
View File

@ -0,0 +1,40 @@
#include <cstdio>
#include "common.hpp"
namespace SwitchIdent {
s64 GetTotalStorage(NcmStorageId storage_id) {
Result ret = 0;
s64 total = 0;
if (R_FAILED(ret = nsGetTotalSpaceSize(storage_id, &total)))
std::printf("nsGetFreeSpaceSize() failed: 0x%x.\n\n", ret);
return total;
}
s64 GetFreeStorage(NcmStorageId storage_id) {
Result ret = 0;
s64 free = 0;
if (R_FAILED(ret = nsGetFreeSpaceSize(storage_id, &free)))
std::printf("nsGetFreeSpaceSize() failed: 0x%x.\n\n", ret);
return free;
}
s64 GetUsedStorage(NcmStorageId storage_id) {
return (SwitchIdent::GetTotalStorage(storage_id) - SwitchIdent::GetFreeStorage(storage_id));
}
void GetSizeString(char *string, double size) {
int i = 0;
const char *units[] = {"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
while (size >= 1024.0f) {
size /= 1024.0f;
i++;
}
std::sprintf(string, "%.*f %s", (i == 0) ? 0 : 2, size, units[i]);
}
}

82
source/system.cpp Normal file
View File

@ -0,0 +1,82 @@
#include <cstdio>
#include "common.hpp"
namespace SwitchIdent {
u64 GetLanguage(void) {
Result ret = 0;
u64 language = 0;
if (R_FAILED(ret = setGetSystemLanguage(&language)))
std::printf("setGetSystemLanguage() failed: 0x%x.\n\n", ret);
return language;
}
const char *GetRegion(void) {
Result ret = 0;
SetRegion region;
const char *regions[] = {
"JPN",
"USA",
"EUR",
"AUS",
"CHN",
"KOR",
"TWN",
"Unknown"
};
if (R_FAILED(ret = setGetRegionCode(&region))) {
std::printf("setGetRegionCode() failed: 0x%x.\n\n", ret);
return regions[7];
}
return regions[region];
}
u32 GetClock(PcvModule module) {
Result ret = 0;
u32 out = 0;
if (hosversionAtLeast(8, 0, 0)) {
ClkrstSession session = {0};
PcvModuleId module_id;
if (R_FAILED(ret = pcvGetModuleId(&module_id, module)))
std::printf("pcvGetModuleId() failed: 0x%x.\n\n", ret);
else if (R_FAILED(ret = clkrstOpenSession(&session, module_id, 3)))
std::printf("clkrstOpenSession() failed: 0x%x.\n\n", ret);
else if (R_FAILED(ret = clkrstGetClockRate(&session, &out)))
std::printf("clkrstGetClockRate() failed: 0x%x.\n\n", ret);
else
clkrstCloseSession(&session);
}
else {
if (R_FAILED(ret = pcvGetClockRate(module, &out)))
std::printf("pcvGetClockRate() failed: 0x%x.\n\n", ret);
}
return out/1000000;
}
SetCalBdAddress GetBluetoothBdAddress(void) {
Result ret = 0;
SetCalBdAddress bd_addr;
if (R_FAILED(ret = setcalGetBdAddress(&bd_addr)))
std::printf("setcalGetBdAddress() failed: 0x%x.\n\n", ret);
return bd_addr;
}
SetCalMacAddress GetWirelessLanMacAddress(void) {
Result ret = 0;
SetCalMacAddress mac_addr;
if (R_FAILED(ret = setcalGetWirelessLanMacAddress(&mac_addr)))
std::printf("setcalGetWirelessLanMacAddress() failed: 0x%x.\n\n", ret);
return mac_addr;
}
}

37
source/wlan.cpp Normal file
View File

@ -0,0 +1,37 @@
#include <cstdio>
#include "common.hpp"
namespace SwitchIdent {
u32 GetWlanState(void) {
Result ret = 0;
WlanInfState state;
if (R_FAILED(ret = wlaninfGetState(&state)))
return -1;
return state;
}
s32 GetWlanQuality(s32 dBm) {
u32 quality = 0;
if (dBm <= -100)
quality = 0;
else if (dBm >= -50)
quality = 100;
else
quality = 2 * (dBm + 100);
return quality;
}
u32 GetWlanRSSI(void) {
Result ret = 0;
s32 rssi = 0;
if (R_FAILED(ret = wlaninfGetRSSI(&rssi)))
return -1;
return rssi;
}
}