mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-11-22 18:26:39 +00:00
Some changes. Read full commit message.
* title: implemented titleGetNcmStorageIdName(). * nxdt_log: implemented log verbosity levels (debug, info, warning, error, none) and helper macros for each level. The rest of the codebase still needs to be updated to take advantange of this change. * nxdt_log: implemented auxiliary logging via nxlink, if available. * nxdt_utils: system CPU/MEM overclocking is now only applied through utilsSetLongRunningProcessState(), as it should have been from the beginning. * nxdt_utils: nxlink initialization is now carried out without redirecting stdout and/or stderr, entirely removing the need for utilsRestoreConsoleOutput(). utilsGetNxLinkFileDescriptor() is used to send data to the nxlink host via dprintf() in log functions.
This commit is contained in:
parent
243080f1a6
commit
a9b5f7211c
12 changed files with 255 additions and 115 deletions
23
Makefile
23
Makefile
|
@ -6,6 +6,9 @@ ifeq ($(strip $(DEVKITPRO)),)
|
||||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Uncomment to enable verbose output.
|
||||||
|
#V:=1
|
||||||
|
|
||||||
TOPDIR ?= $(CURDIR)
|
TOPDIR ?= $(CURDIR)
|
||||||
include $(DEVKITPRO)/libnx/switch_rules
|
include $(DEVKITPRO)/libnx/switch_rules
|
||||||
|
|
||||||
|
@ -38,11 +41,13 @@ include $(DEVKITPRO)/libnx/switch_rules
|
||||||
# NACP building is skipped as well.
|
# NACP building is skipped as well.
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ROOTDIR ?= $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
|
||||||
|
|
||||||
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
|
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
|
||||||
GIT_COMMIT := $(shell git rev-parse --short HEAD)
|
GIT_COMMIT := $(shell git rev-parse --short HEAD)
|
||||||
GIT_REV := ${GIT_BRANCH}-${GIT_COMMIT}
|
GIT_REV := ${GIT_BRANCH}-${GIT_COMMIT}
|
||||||
|
|
||||||
ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
ifneq (,$(strip $(shell git status --porcelain 2>/dev/null)))
|
||||||
GIT_REV := $(GIT_REV)-dirty
|
GIT_REV := $(GIT_REV)-dirty
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -72,7 +77,7 @@ ROMFS := romfs
|
||||||
BOREALIS_PATH := libs/borealis
|
BOREALIS_PATH := libs/borealis
|
||||||
BOREALIS_RESOURCES := romfs:/
|
BOREALIS_RESOURCES := romfs:/
|
||||||
|
|
||||||
USBHSFS_PATH := $(TOPDIR)/libs/libusbhsfs
|
USBHSFS_PATH := $(ROOTDIR)/libs/libusbhsfs
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
|
@ -98,7 +103,7 @@ LIBS := -lcurl -lmbedtls -lmbedx509 -lmbedcrypto -lxml2 -ljson-c -lz -lusbhsfs
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
LIBDIRS := $(PORTLIBS) $(LIBNX) $(USBHSFS_PATH)
|
LIBDIRS := $(PORTLIBS) $(LIBNX) $(USBHSFS_PATH)
|
||||||
|
|
||||||
include $(TOPDIR)/$(BOREALIS_PATH)/library/borealis.mk
|
include $(ROOTDIR)/$(BOREALIS_PATH)/library/borealis.mk
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# no real need to edit anything past this point unless you need to add additional
|
# no real need to edit anything past this point unless you need to add additional
|
||||||
|
@ -244,6 +249,18 @@ $(OUTPUT).elf : $(OFILES)
|
||||||
|
|
||||||
$(OFILES_SRC) : $(HFILES_BIN)
|
$(OFILES_SRC) : $(HFILES_BIN)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# Overrides for devkitA64/base_rules targets.
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
%.o: %.cpp
|
||||||
|
$(SILENTMSG) $(notdir $<)
|
||||||
|
$(SILENTCMD)$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -D__FILENAME__="\"$(subst $(ROOTDIR),,$(realpath $<))\"" -c $< -o $@ $(ERROR_FILTER)
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(SILENTMSG) $(notdir $<)
|
||||||
|
$(SILENTCMD)$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) -D__FILENAME__="\"$(subst $(ROOTDIR),,$(realpath $<))\"" -c $< -o $@ $(ERROR_FILTER)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# you need a rule like this for each extension you use as binary data
|
# you need a rule like this for each extension you use as binary data
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|
|
@ -956,7 +956,7 @@ static void nspDump(TitleInfo *title_info)
|
||||||
consolePrint("publisher: %s\n", app_metadata->lang_entry.author);
|
consolePrint("publisher: %s\n", app_metadata->lang_entry.author);
|
||||||
}
|
}
|
||||||
|
|
||||||
consolePrint("source storage: %s\n", title_info->storage_id == NcmStorageId_GameCard ? "gamecard" : (title_info->storage_id == NcmStorageId_BuiltInUser ? "emmc" : "sd card"));
|
consolePrint("source storage: %s\n", titleGetNcmStorageIdName(title_info->storage_id));
|
||||||
consolePrint("title id: %016lX\n", title_info->meta_key.id);
|
consolePrint("title id: %016lX\n", title_info->meta_key.id);
|
||||||
consolePrint("version: %u (%u.%u.%u-%u.%u)\n", title_info->version.value, title_info->version.system_version.major, title_info->version.system_version.minor, title_info->version.system_version.micro, title_info->version.system_version.major_relstep, \
|
consolePrint("version: %u (%u.%u.%u-%u.%u)\n", title_info->version.value, title_info->version.system_version.major, title_info->version.system_version.minor, title_info->version.system_version.micro, title_info->version.system_version.major_relstep, \
|
||||||
title_info->version.system_version.minor_relstep);
|
title_info->version.system_version.minor_relstep);
|
||||||
|
@ -1168,10 +1168,10 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
consolePrint("selected %s info:\n\n", title_info->meta_key.type == NcmContentMetaType_Application ? "base application" : \
|
consolePrint("selected %s info:\n\n", title_info->meta_key.type == NcmContentMetaType_Application ? "base application" : \
|
||||||
(title_info->meta_key.type == NcmContentMetaType_Patch ? "update" : "dlc"));
|
(title_info->meta_key.type == NcmContentMetaType_Patch ? "update" : "dlc"));
|
||||||
consolePrint("source storage: %s\n", title_info->storage_id == NcmStorageId_GameCard ? "gamecard" : (title_info->storage_id == NcmStorageId_BuiltInUser ? "emmc" : "sd card"));
|
consolePrint("source storage: %s\n", titleGetNcmStorageIdName(title_info->storage_id));
|
||||||
if (title_info->meta_key.type != NcmContentMetaType_Application) consolePrint("title id: %016lX\n", title_info->meta_key.id);
|
if (title_info->meta_key.type != NcmContentMetaType_Application) consolePrint("title id: %016lX\n", title_info->meta_key.id);
|
||||||
consolePrint("version: %u (%u.%u.%u-%u.%u)\n", title_info->version.value, title_info->version.system_version.major, title_info->version.system_version.minor, title_info->version.system_version.micro, title_info->version.system_version.major_relstep, \
|
consolePrint("version: %u (%u.%u.%u-%u.%u)\n", title_info->version.value, title_info->version.system_version.major, title_info->version.system_version.minor, \
|
||||||
title_info->version.system_version.minor_relstep);
|
title_info->version.system_version.micro, title_info->version.system_version.major_relstep, title_info->version.system_version.minor_relstep);
|
||||||
consolePrint("content count: %u\n", title_info->content_count);
|
consolePrint("content count: %u\n", title_info->content_count);
|
||||||
consolePrint("size: %s\n", title_info->size_str);
|
consolePrint("size: %s\n", title_info->size_str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,9 @@
|
||||||
/* libnx header. */
|
/* libnx header. */
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
|
||||||
|
/* Internet operations. */
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
/* Global defines. */
|
/* Global defines. */
|
||||||
#include "../defines.h"
|
#include "../defines.h"
|
||||||
|
|
||||||
|
|
|
@ -28,28 +28,85 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// Used to control logfile verbosity.
|
||||||
|
#define LOG_LEVEL_DEBUG 0
|
||||||
|
#define LOG_LEVEL_INFO 1
|
||||||
|
#define LOG_LEVEL_WARNING 2
|
||||||
|
#define LOG_LEVEL_ERROR 3
|
||||||
|
#define LOG_LEVEL_NONE 4
|
||||||
|
|
||||||
|
/// Defines the log level used throughout the application.
|
||||||
|
/// Log messages with a log value lower than this one won't be compiled into the binary.
|
||||||
|
/// If a value lower than LOG_LEVEL_DEBUG or equal to/greater than LOG_LEVEL_NONE is used, logfile output will be entirely disabled.
|
||||||
|
#define LOG_LEVEL LOG_LEVEL_DEBUG /* TODO: change before release. */
|
||||||
|
|
||||||
|
#if (LOG_LEVEL >= LOG_LEVEL_DEBUG) && (LOG_LEVEL < LOG_LEVEL_NONE)
|
||||||
|
|
||||||
/// Helper macros.
|
/// Helper macros.
|
||||||
#define LOG_MSG(fmt, ...) logWriteFormattedStringToLogFile(__func__, fmt, ##__VA_ARGS__)
|
|
||||||
#define LOG_MSG_BUF(dst, dst_size, fmt, ...) logWriteFormattedStringToBuffer(dst, dst_size, __func__, fmt, ##__VA_ARGS__)
|
#define LOG_MSG_GENERIC(level, fmt, ...) logWriteFormattedStringToLogFile(level, __FILENAME__, __LINE__, __func__, fmt, ##__VA_ARGS__)
|
||||||
#define LOG_DATA(data, data_size, fmt, ...) logWriteBinaryDataToLogFile(data, data_size, __func__, fmt, ##__VA_ARGS__)
|
#define LOG_MSG_BUF_GENERIC(dst, dst_size, level, fmt, ...) logWriteFormattedStringToBuffer(dst, dst_size, level, __FILENAME__, __LINE__, __func__, fmt, ##__VA_ARGS__)
|
||||||
|
#define LOG_DATA_GENERIC(data, data_size, level, fmt, ...) logWriteBinaryDataToLogFile(data, data_size, level, __FILENAME__, __LINE__, __func__, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define LOG_MSG_DEBUG(fmt, ...) LOG_MSG_GENERIC(LOG_LEVEL_DEBUG, fmt, ##__VA_ARGS__)
|
||||||
|
#define LOG_MSG_BUF_DEBUG(dst, dst_size, fmt, ...) LOG_MSG_BUF_GENERIC(dst, dst_size, LOG_LEVEL_DEBUG, fmt, ##__VA_ARGS__)
|
||||||
|
#define LOG_DATA_DEBUG(data, data_size, fmt, ...) LOG_DATA_GENERIC(data, data_size, LOG_LEVEL_DEBUG, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
/* TODO: delete these macros after migrating all log calls to the new verbosity-level-based system. */
|
||||||
|
#define LOG_MSG(fmt, ...) LOG_MSG_DEBUG(fmt, ##__VA_ARGS__)
|
||||||
|
#define LOG_MSG_BUF(dst, dst_size, fmt, ...) LOG_MSG_BUF_DEBUG(dst, dst_size, fmt, ##__VA_ARGS__)
|
||||||
|
#define LOG_DATA(data, data_size, fmt, ...) LOG_DATA_DEBUG(data, data_size, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#if LOG_LEVEL >= LOG_LEVEL_INFO
|
||||||
|
#define LOG_MSG_INFO(fmt, ...) LOG_MSG_GENERIC(LOG_LEVEL_INFO, fmt, ##__VA_ARGS__)
|
||||||
|
#define LOG_MSG_BUF_INFO(dst, dst_size, fmt, ...) LOG_MSG_BUF_GENERIC(dst, dst_size, LOG_LEVEL_INFO, fmt, ##__VA_ARGS__)
|
||||||
|
#define LOG_DATA_INFO(data, data_size, fmt, ...) LOG_DATA_GENERIC(data, data_size, LOG_LEVEL_INFO, fmt, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define LOG_MSG_INFO(fmt, ...) do {} while(0)
|
||||||
|
#define LOG_MSG_BUF_INFO(dst, dst_size, fmt, ...) do {} while(0)
|
||||||
|
#define LOG_DATA_INFO(data, data_size, fmt, ...) do {} while(0)
|
||||||
|
#endif /* LOG_LEVEL >= LOG_LEVEL_INFO */
|
||||||
|
|
||||||
|
#if LOG_LEVEL >= LOG_LEVEL_WARNING
|
||||||
|
#define LOG_MSG_WARNING(fmt, ...) LOG_MSG_GENERIC(LOG_LEVEL_WARNING, fmt, ##__VA_ARGS__)
|
||||||
|
#define LOG_MSG_BUF_WARNING(dst, dst_size, fmt, ...) LOG_MSG_BUF_GENERIC(dst, dst_size, LOG_LEVEL_WARNING, fmt, ##__VA_ARGS__)
|
||||||
|
#define LOG_DATA_WARNING(data, data_size, fmt, ...) LOG_DATA_GENERIC(data, data_size, LOG_LEVEL_WARNING, fmt, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define LOG_MSG_WARNING(fmt, ...) do {} while(0)
|
||||||
|
#define LOG_MSG_BUF_WARNING(dst, dst_size, fmt, ...) do {} while(0)
|
||||||
|
#define LOG_DATA_WARNING(data, data_size, fmt, ...) do {} while(0)
|
||||||
|
#endif /* LOG_LEVEL >= LOG_LEVEL_WARNING */
|
||||||
|
|
||||||
|
#if LOG_LEVEL >= LOG_LEVEL_ERROR
|
||||||
|
#define LOG_MSG_ERROR(fmt, ...) LOG_MSG_GENERIC(LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__)
|
||||||
|
#define LOG_MSG_BUF_ERROR(dst, dst_size, fmt, ...) LOG_MSG_BUF_GENERIC(dst, dst_size, LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__)
|
||||||
|
#define LOG_DATA_ERROR(data, data_size, fmt, ...) LOG_DATA_GENERIC(data, data_size, LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define LOG_MSG_ERROR(fmt, ...) do {} while(0)
|
||||||
|
#define LOG_MSG_BUF_ERROR(dst, dst_size, fmt, ...) do {} while(0)
|
||||||
|
#define LOG_DATA_ERROR(data, data_size, fmt, ...) do {} while(0)
|
||||||
|
#endif /* LOG_LEVEL >= LOG_LEVEL_ERROR */
|
||||||
|
|
||||||
/// Writes the provided string to the logfile.
|
/// Writes the provided string to the logfile.
|
||||||
|
/// If the logfile hasn't been created and/or opened, this function takes care of it.
|
||||||
void logWriteStringToLogFile(const char *src);
|
void logWriteStringToLogFile(const char *src);
|
||||||
|
|
||||||
/// Writes a formatted log string to the logfile.
|
/// Writes a formatted log string to the logfile.
|
||||||
__attribute__((format(printf, 2, 3))) void logWriteFormattedStringToLogFile(const char *func_name, const char *fmt, ...);
|
/// If the logfile hasn't been created and/or opened, this function takes care of it.
|
||||||
|
__attribute__((format(printf, 5, 6))) void logWriteFormattedStringToLogFile(u8 level, const char *file_name, int line, const char *func_name, const char *fmt, ...);
|
||||||
|
|
||||||
/// Writes a formatted log string to the provided buffer.
|
/// Writes a formatted log string to the provided buffer.
|
||||||
/// If the buffer isn't big enough to hold both its current contents and the new formatted string, it will be resized.
|
/// If the buffer isn't big enough to hold both its current contents and the new formatted string, it will be resized.
|
||||||
__attribute__((format(printf, 4, 5))) void logWriteFormattedStringToBuffer(char **dst, size_t *dst_size, const char *func_name, const char *fmt, ...);
|
__attribute__((format(printf, 7, 8))) void logWriteFormattedStringToBuffer(char **dst, size_t *dst_size, u8 level, const char *file_name, int line, const char *func_name, const char *fmt, ...);
|
||||||
|
|
||||||
/// Writes a formatted log string + a hex string representation of the provided binary data to the logfile.
|
/// Writes a formatted log string + a hex string representation of the provided binary data to the logfile.
|
||||||
__attribute__((format(printf, 4, 5))) void logWriteBinaryDataToLogFile(const void *data, size_t data_size, const char *func_name, const char *fmt, ...);
|
/// If the logfile hasn't been created and/or opened, this function takes care of it.
|
||||||
|
__attribute__((format(printf, 7, 8))) void logWriteBinaryDataToLogFile(const void *data, size_t data_size, u8 level, const char *file_name, int line, const char *func_name, const char *fmt, ...);
|
||||||
|
|
||||||
/// Forces a flush operation on the logfile.
|
/// Forces a flush operation on the logfile.
|
||||||
void logFlushLogFile(void);
|
void logFlushLogFile(void);
|
||||||
|
|
||||||
/// Closes the logfile.
|
/// Write any pending data to the logfile, flushes it and then closes it.
|
||||||
void logCloseLogFile(void);
|
void logCloseLogFile(void);
|
||||||
|
|
||||||
/// Stores the last log message in the provided buffer.
|
/// Stores the last log message in the provided buffer.
|
||||||
|
@ -59,6 +116,33 @@ void logGetLastMessage(char *dst, size_t dst_size);
|
||||||
/// Use with caution.
|
/// Use with caution.
|
||||||
void logControlMutex(bool lock);
|
void logControlMutex(bool lock);
|
||||||
|
|
||||||
|
#else /* (LOG_LEVEL >= LOG_LEVEL_DEBUG) && (LOG_LEVEL < LOG_LEVEL_NONE) */
|
||||||
|
|
||||||
|
/// Helper macros.
|
||||||
|
|
||||||
|
#define LOG_STR(src) do {} while(0)
|
||||||
|
#define LOG_MSG_GENERIC(level, fmt, ...) do {} while(0)
|
||||||
|
#define LOG_MSG_BUF_GENERIC(dst, dst_size, level, fmt, ...) do {} while(0)
|
||||||
|
#define LOG_DATA_GENERIC(data, data_size, level, fmt, ...) do {} while(0)
|
||||||
|
|
||||||
|
#define LOG_MSG_DEBUG(fmt, ...) do {} while(0)
|
||||||
|
#define LOG_MSG_BUF_DEBUG(dst, dst_size, fmt, ...) do {} while(0)
|
||||||
|
#define LOG_DATA_DEBUG(data, data_size, fmt, ...) do {} while(0)
|
||||||
|
|
||||||
|
#define LOG_MSG_INFO(fmt, ...) do {} while(0)
|
||||||
|
#define LOG_MSG_BUF_INFO(dst, dst_size, fmt, ...) do {} while(0)
|
||||||
|
#define LOG_DATA_INFO(data, data_size, fmt, ...) do {} while(0)
|
||||||
|
|
||||||
|
#define LOG_MSG_WARNING(fmt, ...) do {} while(0)
|
||||||
|
#define LOG_MSG_BUF_WARNING(dst, dst_size, fmt, ...) do {} while(0)
|
||||||
|
#define LOG_DATA_WARNING(data, data_size, fmt, ...) do {} while(0)
|
||||||
|
|
||||||
|
#define LOG_MSG_ERROR(fmt, ...) do {} while(0)
|
||||||
|
#define LOG_MSG_BUF_ERROR(dst, dst_size, fmt, ...) do {} while(0)
|
||||||
|
#define LOG_DATA_ERROR(data, data_size, fmt, ...) do {} while(0)
|
||||||
|
|
||||||
|
#endif /* (LOG_LEVEL >= LOG_LEVEL_DEBUG) && (LOG_LEVEL < LOG_LEVEL_NONE) */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -74,6 +74,9 @@ void utilsCloseResources(void);
|
||||||
/// Returns a pointer to the application launch path.
|
/// Returns a pointer to the application launch path.
|
||||||
const char *utilsGetLaunchPath(void);
|
const char *utilsGetLaunchPath(void);
|
||||||
|
|
||||||
|
/// Returns the nxlink socket descriptor, or -1 if an nxlink connection couldn't be established.
|
||||||
|
int utilsGetNxLinkFileDescriptor(void);
|
||||||
|
|
||||||
/// Returns a pointer to the FsFileSystem object for the SD card.
|
/// Returns a pointer to the FsFileSystem object for the SD card.
|
||||||
FsFileSystem *utilsGetSdCardFileSystemObject(void);
|
FsFileSystem *utilsGetSdCardFileSystemObject(void);
|
||||||
|
|
||||||
|
@ -93,11 +96,9 @@ bool utilsAppletModeCheck(void);
|
||||||
/// Returns a pointer to the FsStorage object for the eMMC BIS System partition.
|
/// Returns a pointer to the FsStorage object for the eMMC BIS System partition.
|
||||||
FsStorage *utilsGetEmmcBisSystemPartitionStorage(void);
|
FsStorage *utilsGetEmmcBisSystemPartitionStorage(void);
|
||||||
|
|
||||||
/// Enables/disables CPU/MEM overclocking.
|
/// Blocks HOME button presses, disables screen dimming and auto sleep and overclocks system CPU/MEM.
|
||||||
void utilsOverclockSystem(bool overclock);
|
|
||||||
|
|
||||||
/// (Un)blocks HOME button presses and (un)sets screen dimming and auto sleep.
|
|
||||||
/// Must be called before starting long-running processes.
|
/// Must be called before starting long-running processes.
|
||||||
|
/// If state is set to false, regular system behavior is restored.
|
||||||
void utilsSetLongRunningProcessState(bool state);
|
void utilsSetLongRunningProcessState(bool state);
|
||||||
|
|
||||||
/// Thread management functions.
|
/// Thread management functions.
|
||||||
|
|
|
@ -137,6 +137,9 @@ char *titleGenerateFileName(TitleInfo *title_info, u8 naming_convention, u8 ille
|
||||||
/// A valid gamecard must be inserted, and title info must have been loaded from it accordingly.
|
/// A valid gamecard must be inserted, and title info must have been loaded from it accordingly.
|
||||||
char *titleGenerateGameCardFileName(u8 naming_convention, u8 illegal_char_replace_type);
|
char *titleGenerateGameCardFileName(u8 naming_convention, u8 illegal_char_replace_type);
|
||||||
|
|
||||||
|
/// Returns a pointer to a string holding a user-friendly name for the provided NcmStorageId value. Returns NULL if the provided value is invalid.
|
||||||
|
const char *titleGetNcmStorageIdName(u8 storage_id);
|
||||||
|
|
||||||
/// Returns a pointer to a string holding the name of the provided NcmContentType value. Returns NULL if the provided value is invalid.
|
/// Returns a pointer to a string holding the name of the provided NcmContentType value. Returns NULL if the provided value is invalid.
|
||||||
const char *titleGetNcmContentTypeName(u8 content_type);
|
const char *titleGetNcmContentTypeName(u8 content_type);
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
#include "nxdt_utils.h"
|
#include "nxdt_utils.h"
|
||||||
|
|
||||||
|
#if (LOG_LEVEL >= LOG_LEVEL_DEBUG) && (LOG_LEVEL < LOG_LEVEL_NONE)
|
||||||
|
|
||||||
/* Global variables. */
|
/* Global variables. */
|
||||||
|
|
||||||
static Mutex g_logMutex = 0;
|
static Mutex g_logMutex = 0;
|
||||||
|
@ -33,34 +35,44 @@ static s64 g_logFileOffset = 0;
|
||||||
static char *g_logBuffer = NULL;
|
static char *g_logBuffer = NULL;
|
||||||
static size_t g_logBufferLength = 0;
|
static size_t g_logBufferLength = 0;
|
||||||
|
|
||||||
static const char *g_logStrFormat = "[%d-%02d-%02d %02d:%02d:%02d.%09lu] %s -> ";
|
static const char *g_logStrFormat = "[%d-%02d-%02d %02d:%02d:%02d.%09lu] [%s] %s:%d:%s -> ";
|
||||||
|
static const char *g_logSessionSeparator = "________________________________________________________________\r\n";
|
||||||
|
|
||||||
|
static const char *g_logLevelNames[] = {
|
||||||
|
[LOG_LEVEL_DEBUG] = "DEBUG",
|
||||||
|
[LOG_LEVEL_INFO] = "INFO",
|
||||||
|
[LOG_LEVEL_WARNING] = "WARNING",
|
||||||
|
[LOG_LEVEL_ERROR] = "ERROR"
|
||||||
|
};
|
||||||
|
|
||||||
/* Function prototypes. */
|
/* Function prototypes. */
|
||||||
|
|
||||||
static void _logWriteStringToLogFile(const char *src);
|
static void _logWriteStringToLogFile(const char *src);
|
||||||
static void _logWriteFormattedStringToLogFile(bool save, const char *func_name, const char *fmt, va_list args);
|
static void _logWriteFormattedStringToLogFile(bool save, u8 level, const char *file_name, int line, const char *func_name, const char *fmt, va_list args);
|
||||||
|
|
||||||
static void _logFlushLogFile(void);
|
static void _logFlushLogFile(void);
|
||||||
|
|
||||||
static bool logAllocateLogBuffer(void);
|
static bool logAllocateLogBuffer(void);
|
||||||
static bool logOpenLogFile(void);
|
static bool logOpenLogFile(void);
|
||||||
|
|
||||||
|
static void logWriteStringToNxLink(const char *str);
|
||||||
|
|
||||||
void logWriteStringToLogFile(const char *src)
|
void logWriteStringToLogFile(const char *src)
|
||||||
{
|
{
|
||||||
SCOPED_LOCK(&g_logMutex) _logWriteStringToLogFile(src);
|
SCOPED_LOCK(&g_logMutex) _logWriteStringToLogFile(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((format(printf, 2, 3))) void logWriteFormattedStringToLogFile(const char *func_name, const char *fmt, ...)
|
__attribute__((format(printf, 5, 6))) void logWriteFormattedStringToLogFile(u8 level, const char *file_name, int line, const char *func_name, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
SCOPED_LOCK(&g_logMutex) _logWriteFormattedStringToLogFile(true, func_name, fmt, args);
|
SCOPED_LOCK(&g_logMutex) _logWriteFormattedStringToLogFile(true, level, file_name, line, func_name, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((format(printf, 4, 5))) void logWriteFormattedStringToBuffer(char **dst, size_t *dst_size, const char *func_name, const char *fmt, ...)
|
__attribute__((format(printf, 7, 8))) void logWriteFormattedStringToBuffer(char **dst, size_t *dst_size, u8 level, const char *file_name, int line, const char *func_name, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
if (!dst || !dst_size || (!*dst && *dst_size) || (*dst && !*dst_size) || !func_name || !*func_name || !fmt || !*fmt) return;
|
if (!dst || !dst_size || (!*dst && *dst_size) || (*dst && !*dst_size) || level > LOG_LEVEL || !file_name || !*file_name || !func_name || !*func_name || !fmt || !*fmt) return;
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
|
@ -86,7 +98,7 @@ __attribute__((format(printf, 4, 5))) void logWriteFormattedStringToBuffer(char
|
||||||
ts.tm_mon++;
|
ts.tm_mon++;
|
||||||
|
|
||||||
/* Get formatted string length. */
|
/* Get formatted string length. */
|
||||||
str1_len = snprintf(NULL, 0, g_logStrFormat, ts.tm_year, ts.tm_mon, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec, now.tv_nsec, func_name);
|
str1_len = snprintf(NULL, 0, g_logStrFormat, ts.tm_year, ts.tm_mon, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec, now.tv_nsec, g_logLevelNames[level], file_name, line, func_name);
|
||||||
if (str1_len <= 0) goto end;
|
if (str1_len <= 0) goto end;
|
||||||
|
|
||||||
str2_len = vsnprintf(NULL, 0, fmt, args);
|
str2_len = vsnprintf(NULL, 0, fmt, args);
|
||||||
|
@ -115,7 +127,7 @@ __attribute__((format(printf, 4, 5))) void logWriteFormattedStringToBuffer(char
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate formatted string. */
|
/* Generate formatted string. */
|
||||||
sprintf(dst_ptr + dst_str_len, g_logStrFormat, ts.tm_year, ts.tm_mon, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec, now.tv_nsec, func_name);
|
sprintf(dst_ptr + dst_str_len, g_logStrFormat, ts.tm_year, ts.tm_mon, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec, now.tv_nsec, g_logLevelNames[level], file_name, line, func_name);
|
||||||
vsprintf(dst_ptr + dst_str_len + (size_t)str1_len, fmt, args);
|
vsprintf(dst_ptr + dst_str_len + (size_t)str1_len, fmt, args);
|
||||||
strcat(dst_ptr, CRLF);
|
strcat(dst_ptr, CRLF);
|
||||||
|
|
||||||
|
@ -123,9 +135,9 @@ end:
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((format(printf, 4, 5))) void logWriteBinaryDataToLogFile(const void *data, size_t data_size, const char *func_name, const char *fmt, ...)
|
__attribute__((format(printf, 7, 8))) void logWriteBinaryDataToLogFile(const void *data, size_t data_size, u8 level, const char *file_name, int line, const char *func_name, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
if (!data || !data_size || !func_name || !*func_name || !fmt || !*fmt) return;
|
if (!data || !data_size || level > LOG_LEVEL || !file_name || !*file_name || !func_name || !*func_name || !fmt || !*fmt) return;
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
size_t data_str_size = ((data_size * 2) + 3);
|
size_t data_str_size = ((data_size * 2) + 3);
|
||||||
|
@ -143,7 +155,7 @@ __attribute__((format(printf, 4, 5))) void logWriteBinaryDataToLogFile(const voi
|
||||||
{
|
{
|
||||||
/* Write formatted string. */
|
/* Write formatted string. */
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
_logWriteFormattedStringToLogFile(false, func_name, fmt, args);
|
_logWriteFormattedStringToLogFile(false, level, file_name, line, func_name, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
/* Write hex string representation. */
|
/* Write hex string representation. */
|
||||||
|
@ -255,16 +267,19 @@ static void _logWriteStringToLogFile(const char *src)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write data to nxlink. */
|
||||||
|
logWriteStringToNxLink(src);
|
||||||
|
|
||||||
#if LOG_FORCE_FLUSH == 1
|
#if LOG_FORCE_FLUSH == 1
|
||||||
/* Flush log buffer. */
|
/* Flush log buffer. */
|
||||||
_logFlushLogFile();
|
_logFlushLogFile();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _logWriteFormattedStringToLogFile(bool save, const char *func_name, const char *fmt, va_list args)
|
static void _logWriteFormattedStringToLogFile(bool save, u8 level, const char *file_name, int line, const char *func_name, const char *fmt, va_list args)
|
||||||
{
|
{
|
||||||
/* Make sure we have allocated memory for the log buffer and opened the logfile. */
|
/* Make sure we have allocated memory for the log buffer and opened the logfile. */
|
||||||
if (!func_name || !*func_name || !fmt || !*fmt || !logAllocateLogBuffer() || !logOpenLogFile()) return;
|
if (level > LOG_LEVEL || !file_name || !*file_name || !func_name || !*func_name || !fmt || !*fmt || !logAllocateLogBuffer() || !logOpenLogFile()) return;
|
||||||
|
|
||||||
Result rc = 0;
|
Result rc = 0;
|
||||||
|
|
||||||
|
@ -286,7 +301,7 @@ static void _logWriteFormattedStringToLogFile(bool save, const char *func_name,
|
||||||
ts.tm_mon++;
|
ts.tm_mon++;
|
||||||
|
|
||||||
/* Get formatted string length. */
|
/* Get formatted string length. */
|
||||||
str1_len = snprintf(NULL, 0, g_logStrFormat, ts.tm_year, ts.tm_mon, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec, now.tv_nsec, func_name);
|
str1_len = snprintf(NULL, 0, g_logStrFormat, ts.tm_year, ts.tm_mon, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec, now.tv_nsec, g_logLevelNames[level], file_name, line, func_name);
|
||||||
if (str1_len <= 0) return;
|
if (str1_len <= 0) return;
|
||||||
|
|
||||||
str2_len = vsnprintf(NULL, 0, fmt, args);
|
str2_len = vsnprintf(NULL, 0, fmt, args);
|
||||||
|
@ -318,9 +333,14 @@ static void _logWriteFormattedStringToLogFile(bool save, const char *func_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nice and easy string formatting using the log buffer. */
|
/* Nice and easy string formatting using the log buffer. */
|
||||||
sprintf(g_logBuffer + g_logBufferLength, g_logStrFormat, ts.tm_year, ts.tm_mon, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec, now.tv_nsec, func_name);
|
sprintf(g_logBuffer + g_logBufferLength, g_logStrFormat, ts.tm_year, ts.tm_mon, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec, now.tv_nsec, g_logLevelNames[level], file_name, line, func_name);
|
||||||
vsprintf(g_logBuffer + g_logBufferLength + (size_t)str1_len, fmt, args);
|
vsprintf(g_logBuffer + g_logBufferLength + (size_t)str1_len, fmt, args);
|
||||||
strcat(g_logBuffer, CRLF);
|
strcat(g_logBuffer, CRLF);
|
||||||
|
|
||||||
|
/* Write data to nxlink. */
|
||||||
|
logWriteStringToNxLink(g_logBuffer + g_logBufferLength);
|
||||||
|
|
||||||
|
/* Update log buffer length. */
|
||||||
g_logBufferLength += log_str_len;
|
g_logBufferLength += log_str_len;
|
||||||
} else {
|
} else {
|
||||||
/* Flush log buffer. */
|
/* Flush log buffer. */
|
||||||
|
@ -332,10 +352,13 @@ static void _logWriteFormattedStringToLogFile(bool save, const char *func_name,
|
||||||
if (!tmp_str) return;
|
if (!tmp_str) return;
|
||||||
|
|
||||||
/* Generate formatted string. */
|
/* Generate formatted string. */
|
||||||
sprintf(tmp_str, g_logStrFormat, ts.tm_year, ts.tm_mon, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec, now.tv_nsec, func_name);
|
sprintf(tmp_str, g_logStrFormat, ts.tm_year, ts.tm_mon, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec, now.tv_nsec, g_logLevelNames[level], file_name, line, func_name);
|
||||||
vsprintf(tmp_str + (size_t)str1_len, fmt, args);
|
vsprintf(tmp_str + (size_t)str1_len, fmt, args);
|
||||||
strcat(tmp_str, CRLF);
|
strcat(tmp_str, CRLF);
|
||||||
|
|
||||||
|
/* Write data to nxlink. */
|
||||||
|
logWriteStringToNxLink(tmp_str);
|
||||||
|
|
||||||
/* Write formatted string data until it no longer exceeds the log buffer size. */
|
/* Write formatted string data until it no longer exceeds the log buffer size. */
|
||||||
while(log_str_len >= LOG_BUF_SIZE)
|
while(log_str_len >= LOG_BUF_SIZE)
|
||||||
{
|
{
|
||||||
|
@ -427,17 +450,41 @@ static bool logOpenLogFile(void)
|
||||||
rc = fsFileGetSize(&g_logFile, &g_logFileOffset);
|
rc = fsFileGetSize(&g_logFile, &g_logFileOffset);
|
||||||
if (R_SUCCEEDED(rc))
|
if (R_SUCCEEDED(rc))
|
||||||
{
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
/* Write UTF-8 BOM right away (if needed). */
|
/* Write UTF-8 BOM right away (if needed). */
|
||||||
if (!g_logFileOffset)
|
if (!g_logFileOffset)
|
||||||
{
|
{
|
||||||
size_t utf8_bom_len = strlen(UTF8_BOM);
|
len = strlen(UTF8_BOM);
|
||||||
fsFileWrite(&g_logFile, g_logFileOffset, UTF8_BOM, utf8_bom_len, FsWriteOption_Flush);
|
fsFileWrite(&g_logFile, g_logFileOffset, UTF8_BOM, len, FsWriteOption_Flush);
|
||||||
g_logFileOffset += (s64)utf8_bom_len;
|
g_logFileOffset += (s64)len;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
fsFileClose(&g_logFile);
|
/* Write session separator right away. */
|
||||||
|
len = strlen(g_logSessionSeparator);
|
||||||
|
rc = fsFileWrite(&g_logFile, g_logFileOffset, g_logSessionSeparator, len, FsWriteOption_Flush);
|
||||||
|
if (R_SUCCEEDED(rc)) g_logFileOffset += (s64)len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Close file if we successfully opened it, but an error occurred afterwards. */
|
||||||
|
if (R_FAILED(rc) && serviceIsActive(&(g_logFile.s)))
|
||||||
|
{
|
||||||
|
fsFileClose(&g_logFile);
|
||||||
|
memset(&g_logFile, 0, sizeof(FsFile));
|
||||||
|
}
|
||||||
|
|
||||||
return R_SUCCEEDED(rc);
|
return R_SUCCEEDED(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void logWriteStringToNxLink(const char *str)
|
||||||
|
{
|
||||||
|
int fd = utilsGetNxLinkFileDescriptor();
|
||||||
|
if (fd >= 0)
|
||||||
|
{
|
||||||
|
dprintf(fd, "%s", str);
|
||||||
|
fsync(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (LOG_LEVEL >= LOG_LEVEL_DEBUG) && (LOG_LEVEL < LOG_LEVEL_NONE) */
|
||||||
|
|
|
@ -48,9 +48,11 @@ typedef struct {
|
||||||
static bool g_resourcesInit = false;
|
static bool g_resourcesInit = false;
|
||||||
static Mutex g_resourcesMutex = 0;
|
static Mutex g_resourcesMutex = 0;
|
||||||
|
|
||||||
|
static const char *g_appLaunchPath = NULL;
|
||||||
|
|
||||||
static FsFileSystem *g_sdCardFileSystem = NULL;
|
static FsFileSystem *g_sdCardFileSystem = NULL;
|
||||||
|
|
||||||
static const char *g_appLaunchPath = NULL;
|
static int g_nxLinkSocketFd = -1;
|
||||||
|
|
||||||
static u8 g_customFirmwareType = UtilsCustomFirmwareType_Unknown;
|
static u8 g_customFirmwareType = UtilsCustomFirmwareType_Unknown;
|
||||||
|
|
||||||
|
@ -65,8 +67,6 @@ static AppletHookCookie g_systemOverclockCookie = {0};
|
||||||
|
|
||||||
static bool g_longRunningProcess = false;
|
static bool g_longRunningProcess = false;
|
||||||
|
|
||||||
static int g_stdoutFd = -1, g_stderrFd = -1, g_nxLinkSocketFd = -1;
|
|
||||||
|
|
||||||
static const char *g_sizeSuffixes[] = { "B", "KiB", "MiB", "GiB" };
|
static const char *g_sizeSuffixes[] = { "B", "KiB", "MiB", "GiB" };
|
||||||
static const u32 g_sizeSuffixesCount = MAX_ELEMENTS(g_sizeSuffixes);
|
static const u32 g_sizeSuffixesCount = MAX_ELEMENTS(g_sizeSuffixes);
|
||||||
|
|
||||||
|
@ -102,13 +102,11 @@ static bool _utilsAppletModeCheck(void);
|
||||||
static bool utilsMountEmmcBisSystemPartitionStorage(void);
|
static bool utilsMountEmmcBisSystemPartitionStorage(void);
|
||||||
static void utilsUnmountEmmcBisSystemPartitionStorage(void);
|
static void utilsUnmountEmmcBisSystemPartitionStorage(void);
|
||||||
|
|
||||||
|
static void utilsOverclockSystem(bool overclock);
|
||||||
static void utilsOverclockSystemAppletHook(AppletHookType hook, void *param);
|
static void utilsOverclockSystemAppletHook(AppletHookType hook, void *param);
|
||||||
|
|
||||||
static void utilsChangeHomeButtonBlockStatus(bool block);
|
static void utilsChangeHomeButtonBlockStatus(bool block);
|
||||||
|
|
||||||
NX_INLINE void utilsCloseFileDescriptor(int *fd);
|
|
||||||
static void utilsRestoreConsoleOutput(void);
|
|
||||||
|
|
||||||
static size_t utilsGetUtf8CodepointCount(const char *str, size_t str_size, size_t cp_limit, size_t *last_cp_pos);
|
static size_t utilsGetUtf8CodepointCount(const char *str, size_t str_size, size_t cp_limit, size_t *last_cp_pos);
|
||||||
|
|
||||||
bool utilsInitializeResources(const int program_argc, const char **program_argv)
|
bool utilsInitializeResources(const int program_argc, const char **program_argv)
|
||||||
|
@ -134,17 +132,19 @@ bool utilsInitializeResources(const int program_argc, const char **program_argv)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create logfile. */
|
|
||||||
logWriteStringToLogFile("________________________________________________________________\r\n");
|
|
||||||
LOG_MSG(APP_TITLE " v" APP_VERSION " starting (" GIT_REV "). Built on " BUILD_TIMESTAMP ".");
|
|
||||||
|
|
||||||
/* Log Horizon OS version. */
|
|
||||||
u32 hos_version = hosversionGet();
|
|
||||||
LOG_MSG("Horizon OS version: %u.%u.%u.", HOSVER_MAJOR(hos_version), HOSVER_MINOR(hos_version), HOSVER_MICRO(hos_version));
|
|
||||||
|
|
||||||
/* Initialize needed services. */
|
/* Initialize needed services. */
|
||||||
if (!servicesInitialize()) break;
|
if (!servicesInitialize()) break;
|
||||||
|
|
||||||
|
/* Check if a valid nxlink host IP address was set by libnx. */
|
||||||
|
/* If so, initialize nxlink connection without redirecting stdout and/or stderr. */
|
||||||
|
if (__nxlink_host.s_addr != 0 && __nxlink_host.s_addr != INADDR_NONE) g_nxLinkSocketFd = nxlinkConnectToHost(false, false);
|
||||||
|
|
||||||
|
/* Log info messages. */
|
||||||
|
u32 hos_version = hosversionGet();
|
||||||
|
LOG_MSG(APP_TITLE " v" APP_VERSION " starting (" GIT_REV "). Built on " BUILD_TIMESTAMP ".");
|
||||||
|
if (g_nxLinkSocketFd >= 0) LOG_MSG("nxlink enabled! Host IP address: %s.", inet_ntoa(__nxlink_host));
|
||||||
|
LOG_MSG("Horizon OS version: %u.%u.%u.", HOSVER_MAJOR(hos_version), HOSVER_MINOR(hos_version), HOSVER_MICRO(hos_version));
|
||||||
|
|
||||||
/* Retrieve custom firmware type. */
|
/* Retrieve custom firmware type. */
|
||||||
_utilsGetCustomFirmwareType();
|
_utilsGetCustomFirmwareType();
|
||||||
if (g_customFirmwareType != UtilsCustomFirmwareType_Unknown) LOG_MSG("Detected %s CFW.", (g_customFirmwareType == UtilsCustomFirmwareType_Atmosphere ? "Atmosphère" : \
|
if (g_customFirmwareType != UtilsCustomFirmwareType_Unknown) LOG_MSG("Detected %s CFW.", (g_customFirmwareType == UtilsCustomFirmwareType_Atmosphere ? "Atmosphère" : \
|
||||||
|
@ -228,9 +228,6 @@ bool utilsInitializeResources(const int program_argc, const char **program_argv)
|
||||||
/* Initialize configuration interface. */
|
/* Initialize configuration interface. */
|
||||||
if (!configInitialize()) break;
|
if (!configInitialize()) break;
|
||||||
|
|
||||||
/* Overclock system. */
|
|
||||||
utilsOverclockSystem(configGetBoolean("overclock"));
|
|
||||||
|
|
||||||
/* Setup an applet hook to change the hardware clocks after a system mode change (docked <-> undocked). */
|
/* Setup an applet hook to change the hardware clocks after a system mode change (docked <-> undocked). */
|
||||||
appletHook(&g_systemOverclockCookie, utilsOverclockSystemAppletHook, NULL);
|
appletHook(&g_systemOverclockCookie, utilsOverclockSystemAppletHook, NULL);
|
||||||
|
|
||||||
|
@ -242,11 +239,6 @@ bool utilsInitializeResources(const int program_argc, const char **program_argv)
|
||||||
if (R_SUCCEEDED(rc) && flag) appletInitializeGamePlayRecording();
|
if (R_SUCCEEDED(rc) && flag) appletInitializeGamePlayRecording();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Duplicate the stdout and stderr file handles, then redirect stdout and stderr over network to nxlink. */
|
|
||||||
g_stdoutFd = dup(STDOUT_FILENO);
|
|
||||||
g_stderrFd = dup(STDERR_FILENO);
|
|
||||||
g_nxLinkSocketFd = nxlinkConnectToHost(true, true);
|
|
||||||
|
|
||||||
/* Update flags. */
|
/* Update flags. */
|
||||||
ret = g_resourcesInit = true;
|
ret = g_resourcesInit = true;
|
||||||
}
|
}
|
||||||
|
@ -277,18 +269,12 @@ void utilsCloseResources(void)
|
||||||
{
|
{
|
||||||
SCOPED_LOCK(&g_resourcesMutex)
|
SCOPED_LOCK(&g_resourcesMutex)
|
||||||
{
|
{
|
||||||
/* Restore console output. */
|
|
||||||
utilsRestoreConsoleOutput();
|
|
||||||
|
|
||||||
/* Unset long running process state. */
|
/* Unset long running process state. */
|
||||||
utilsSetLongRunningProcessState(false);
|
utilsSetLongRunningProcessState(false);
|
||||||
|
|
||||||
/* Unset our overclock applet hook. */
|
/* Unset our overclock applet hook. */
|
||||||
appletUnhook(&g_systemOverclockCookie);
|
appletUnhook(&g_systemOverclockCookie);
|
||||||
|
|
||||||
/* Restore hardware clocks. */
|
|
||||||
utilsOverclockSystem(false);
|
|
||||||
|
|
||||||
/* Close configuration interface. */
|
/* Close configuration interface. */
|
||||||
configExit();
|
configExit();
|
||||||
|
|
||||||
|
@ -322,6 +308,13 @@ void utilsCloseResources(void)
|
||||||
/* Close HTTP interface. */
|
/* Close HTTP interface. */
|
||||||
httpExit();
|
httpExit();
|
||||||
|
|
||||||
|
/* Close nxlink socket. */
|
||||||
|
if (g_nxLinkSocketFd >= 0)
|
||||||
|
{
|
||||||
|
close(g_nxLinkSocketFd);
|
||||||
|
g_nxLinkSocketFd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Close initialized services. */
|
/* Close initialized services. */
|
||||||
servicesClose();
|
servicesClose();
|
||||||
|
|
||||||
|
@ -348,6 +341,11 @@ const char *utilsGetLaunchPath(void)
|
||||||
return g_appLaunchPath;
|
return g_appLaunchPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int utilsGetNxLinkFileDescriptor(void)
|
||||||
|
{
|
||||||
|
return g_nxLinkSocketFd;
|
||||||
|
}
|
||||||
|
|
||||||
FsFileSystem *utilsGetSdCardFileSystemObject(void)
|
FsFileSystem *utilsGetSdCardFileSystemObject(void)
|
||||||
{
|
{
|
||||||
return g_sdCardFileSystem;
|
return g_sdCardFileSystem;
|
||||||
|
@ -378,26 +376,22 @@ FsStorage *utilsGetEmmcBisSystemPartitionStorage(void)
|
||||||
return &g_emmcBisSystemPartitionStorage;
|
return &g_emmcBisSystemPartitionStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void utilsOverclockSystem(bool overclock)
|
|
||||||
{
|
|
||||||
u32 cpu_rate = ((overclock ? CPU_CLKRT_OVERCLOCKED : CPU_CLKRT_NORMAL) * 1000000);
|
|
||||||
u32 mem_rate = ((overclock ? MEM_CLKRT_OVERCLOCKED : MEM_CLKRT_NORMAL) * 1000000);
|
|
||||||
servicesChangeHardwareClockRates(cpu_rate, mem_rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
void utilsSetLongRunningProcessState(bool state)
|
void utilsSetLongRunningProcessState(bool state)
|
||||||
{
|
{
|
||||||
SCOPED_LOCK(&g_resourcesMutex)
|
SCOPED_LOCK(&g_resourcesMutex)
|
||||||
{
|
{
|
||||||
/* Don't proceed if the requested state matches the current one. */
|
/* Don't proceed if resources haven't been initialized, or if the requested state matches the current one. */
|
||||||
if (state == g_longRunningProcess) break;
|
if (!g_resourcesInit || state == g_longRunningProcess) break;
|
||||||
|
|
||||||
/* Change HOME button block status. */
|
/* Change HOME button block status. */
|
||||||
utilsChangeHomeButtonBlockStatus(state);
|
utilsChangeHomeButtonBlockStatus(state);
|
||||||
|
|
||||||
/* (Un)set screen dimming and auto sleep. */
|
/* Enable/disable screen dimming and auto sleep. */
|
||||||
appletSetMediaPlaybackState(state);
|
appletSetMediaPlaybackState(state);
|
||||||
|
|
||||||
|
/* Enable/disable system overclock. */
|
||||||
|
utilsOverclockSystem(configGetBoolean("overclock") & state);
|
||||||
|
|
||||||
/* Update flag. */
|
/* Update flag. */
|
||||||
g_longRunningProcess = state;
|
g_longRunningProcess = state;
|
||||||
}
|
}
|
||||||
|
@ -870,9 +864,6 @@ void utilsPrintConsoleError(const char *msg)
|
||||||
padConfigureInput(8, HidNpadStyleSet_NpadFullCtrl);
|
padConfigureInput(8, HidNpadStyleSet_NpadFullCtrl);
|
||||||
padInitializeWithMask(&pad, 0x1000000FFUL);
|
padInitializeWithMask(&pad, 0x1000000FFUL);
|
||||||
|
|
||||||
/* Restore console output. */
|
|
||||||
utilsRestoreConsoleOutput();
|
|
||||||
|
|
||||||
/* Initialize console output. */
|
/* Initialize console output. */
|
||||||
consoleInit(NULL);
|
consoleInit(NULL);
|
||||||
|
|
||||||
|
@ -1118,13 +1109,22 @@ static void utilsUnmountEmmcBisSystemPartitionStorage(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void utilsOverclockSystem(bool overclock)
|
||||||
|
{
|
||||||
|
u32 cpu_rate = ((overclock ? CPU_CLKRT_OVERCLOCKED : CPU_CLKRT_NORMAL) * 1000000);
|
||||||
|
u32 mem_rate = ((overclock ? MEM_CLKRT_OVERCLOCKED : MEM_CLKRT_NORMAL) * 1000000);
|
||||||
|
servicesChangeHardwareClockRates(cpu_rate, mem_rate);
|
||||||
|
}
|
||||||
|
|
||||||
static void utilsOverclockSystemAppletHook(AppletHookType hook, void *param)
|
static void utilsOverclockSystemAppletHook(AppletHookType hook, void *param)
|
||||||
{
|
{
|
||||||
(void)param;
|
(void)param;
|
||||||
|
|
||||||
|
/* Don't proceed if we're not dealing with a desired hook type. */
|
||||||
if (hook != AppletHookType_OnOperationMode && hook != AppletHookType_OnPerformanceMode) return;
|
if (hook != AppletHookType_OnOperationMode && hook != AppletHookType_OnPerformanceMode) return;
|
||||||
|
|
||||||
utilsOverclockSystem(configGetBoolean("overclock"));
|
/* Overclock the system based on the overclock setting and the current long running state value. */
|
||||||
|
SCOPED_LOCK(&g_resourcesMutex) utilsOverclockSystem(configGetBoolean("overclock") & g_longRunningProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void utilsChangeHomeButtonBlockStatus(bool block)
|
static void utilsChangeHomeButtonBlockStatus(bool block)
|
||||||
|
@ -1147,26 +1147,6 @@ NX_INLINE void utilsCloseFileDescriptor(int *fd)
|
||||||
*fd = -1;
|
*fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void utilsRestoreConsoleOutput(void)
|
|
||||||
{
|
|
||||||
SCOPED_LOCK(&g_resourcesMutex)
|
|
||||||
{
|
|
||||||
if (g_nxLinkSocketFd >= 0) utilsCloseFileDescriptor(&g_nxLinkSocketFd);
|
|
||||||
|
|
||||||
if (g_stdoutFd >= 0)
|
|
||||||
{
|
|
||||||
dup2(g_stdoutFd, STDOUT_FILENO);
|
|
||||||
utilsCloseFileDescriptor(&g_stdoutFd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_stderrFd >= 0)
|
|
||||||
{
|
|
||||||
dup2(g_stderrFd, STDERR_FILENO);
|
|
||||||
utilsCloseFileDescriptor(&g_stderrFd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t utilsGetUtf8CodepointCount(const char *str, size_t str_size, size_t cp_limit, size_t *last_cp_pos)
|
static size_t utilsGetUtf8CodepointCount(const char *str, size_t str_size, size_t cp_limit, size_t *last_cp_pos)
|
||||||
{
|
{
|
||||||
if (!str || !*str || !str_size || (!cp_limit && last_cp_pos) || (cp_limit && !last_cp_pos)) return 0;
|
if (!str || !*str || !str_size || (!cp_limit && last_cp_pos) || (cp_limit && !last_cp_pos)) return 0;
|
||||||
|
|
|
@ -62,6 +62,16 @@ static TitleStorage g_titleStorage[TITLE_STORAGE_COUNT] = {0};
|
||||||
static TitleInfo **g_orphanTitleInfo = NULL;
|
static TitleInfo **g_orphanTitleInfo = NULL;
|
||||||
static u32 g_orphanTitleInfoCount = 0;
|
static u32 g_orphanTitleInfoCount = 0;
|
||||||
|
|
||||||
|
static const char *g_titleNcmStorageIdNames[] = {
|
||||||
|
[NcmStorageId_None] = "None",
|
||||||
|
[NcmStorageId_Host] = "Host",
|
||||||
|
[NcmStorageId_GameCard] = "Gamecard",
|
||||||
|
[NcmStorageId_BuiltInSystem] = "eMMC (system)",
|
||||||
|
[NcmStorageId_BuiltInUser] = "eMMC (user)",
|
||||||
|
[NcmStorageId_SdCard] = "SD card",
|
||||||
|
[NcmStorageId_Any] = "Any"
|
||||||
|
};
|
||||||
|
|
||||||
static const char *g_titleNcmContentTypeNames[] = {
|
static const char *g_titleNcmContentTypeNames[] = {
|
||||||
[NcmContentType_Meta] = "Meta",
|
[NcmContentType_Meta] = "Meta",
|
||||||
[NcmContentType_Program] = "Program",
|
[NcmContentType_Program] = "Program",
|
||||||
|
@ -1090,6 +1100,11 @@ fallback:
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *titleGetNcmStorageIdName(u8 storage_id)
|
||||||
|
{
|
||||||
|
return (storage_id <= NcmStorageId_Any ? g_titleNcmStorageIdNames[storage_id] : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
const char *titleGetNcmContentTypeName(u8 content_type)
|
const char *titleGetNcmContentTypeName(u8 content_type)
|
||||||
{
|
{
|
||||||
return (content_type <= NcmContentType_DeltaFragment ? g_titleNcmContentTypeNames[content_type] : NULL);
|
return (content_type <= NcmContentType_DeltaFragment ? g_titleNcmContentTypeNames[content_type] : NULL);
|
||||||
|
@ -1264,7 +1279,7 @@ static bool titleInitializeTitleStorage(u8 storage_id)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_MSG("Loaded %u title info %s from storage ID %u.", title_storage->title_count, (title_storage->title_count == 1 ? "entry" : "entries"), storage_id);
|
LOG_MSG("Loaded %u title info %s from %s.", title_storage->title_count, (title_storage->title_count == 1 ? "entry" : "entries"), titleGetNcmStorageIdName(storage_id));
|
||||||
|
|
||||||
/* Update flag. */
|
/* Update flag. */
|
||||||
success = true;
|
success = true;
|
||||||
|
|
|
@ -414,14 +414,10 @@ namespace nxdt::views
|
||||||
"options_tab/overclock/value_disabled"_i18n);
|
"options_tab/overclock/value_disabled"_i18n);
|
||||||
|
|
||||||
overclock->getClickEvent()->subscribe([](brls::View* view) {
|
overclock->getClickEvent()->subscribe([](brls::View* view) {
|
||||||
brls::ToggleListItem *item = static_cast<brls::ToggleListItem*>(view);
|
|
||||||
|
|
||||||
/* Get current value. */
|
/* Get current value. */
|
||||||
|
brls::ToggleListItem *item = static_cast<brls::ToggleListItem*>(view);
|
||||||
bool value = item->getToggleState();
|
bool value = item->getToggleState();
|
||||||
|
|
||||||
/* Change hardware clocks based on the current value. */
|
|
||||||
utilsOverclockSystem(value);
|
|
||||||
|
|
||||||
/* Update configuration. */
|
/* Update configuration. */
|
||||||
configSetBoolean("overclock", value);
|
configSetBoolean("overclock", value);
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
|
|
||||||
#include <nxdt_includes.h>
|
#include <nxdt_includes.h>
|
||||||
#include <tasks.hpp>
|
#include <tasks.hpp>
|
||||||
#include <arpa/inet.h>
|
|
||||||
|
|
||||||
#define NXDT_TASK_INTERVAL 250 /* 250 ms. */
|
#define NXDT_TASK_INTERVAL 250 /* 250 ms. */
|
||||||
|
|
||||||
|
@ -70,9 +69,9 @@ namespace nxdt::tasks
|
||||||
{
|
{
|
||||||
if (status_info_data->connection_type && connection_status == NifmInternetConnectionStatus_Connected)
|
if (status_info_data->connection_type && connection_status == NifmInternetConnectionStatus_Connected)
|
||||||
{
|
{
|
||||||
struct in_addr addr = { .s_addr = 0 };
|
struct in_addr addr = { .s_addr = INADDR_NONE };
|
||||||
nifmGetCurrentIpAddress(&(addr.s_addr));
|
nifmGetCurrentIpAddress(&(addr.s_addr));
|
||||||
status_info_data->ip_addr = inet_ntoa(addr);
|
status_info_data->ip_addr = (addr.s_addr != INADDR_NONE ? inet_ntoa(addr) : NULL);
|
||||||
} else {
|
} else {
|
||||||
status_info_data->ip_addr = NULL;
|
status_info_data->ip_addr = NULL;
|
||||||
}
|
}
|
||||||
|
|
5
todo.txt
5
todo.txt
|
@ -1,10 +1,5 @@
|
||||||
todo:
|
todo:
|
||||||
|
|
||||||
nca: add function to retrieve a pointer to a nca fs ctx based on section type? (e.g. like titleGetContentInfoByTypeAndIdOffset)
|
|
||||||
|
|
||||||
log: verbosity levels
|
|
||||||
log: nxlink output for advanced users
|
|
||||||
|
|
||||||
title: always retrieve names from unpacked nacps? (e.g. if an update changes the name of a title, like deltarune)
|
title: always retrieve names from unpacked nacps? (e.g. if an update changes the name of a title, like deltarune)
|
||||||
title: use dlc index as part of the output dump filename?
|
title: use dlc index as part of the output dump filename?
|
||||||
title: more functions for title lookup? (filters, patches / aoc, etc.)
|
title: more functions for title lookup? (filters, patches / aoc, etc.)
|
||||||
|
|
Loading…
Reference in a new issue