diff --git a/3ds/include/util.hpp b/3ds/include/util.hpp index 0b8bfd7..0782c58 100644 --- a/3ds/include/util.hpp +++ b/3ds/include/util.hpp @@ -31,6 +31,7 @@ #include "common.hpp" #include "configuration.hpp" #include "gui.hpp" +#include "logger.hpp" #include <3ds.h> #include #include diff --git a/3ds/source/util.cpp b/3ds/source/util.cpp index 05c2bce..5ad85bb 100644 --- a/3ds/source/util.cpp +++ b/3ds/source/util.cpp @@ -47,18 +47,22 @@ static Result consoleDisplayError(const std::string& message, Result res) Result servicesInit(void) { + sdmcInit(); + ATEXIT(sdmcExit); + + Logger::getInstance().info("Checkpoint loading started..."); + Result res = 0; Handle hbldrHandle; - if (R_FAILED(res = svcConnectToPort(&hbldrHandle, "hb:ldr"))) + if (R_FAILED(res = svcConnectToPort(&hbldrHandle, "hb:ldr"))) { + Logger::getInstance().error("Error during startup with result %llX. Rosalina not found on this system", res); return consoleDisplayError("Rosalina not found on this system.\nAn updated CFW is required to launch Checkpoint.", res); + } romfsInit(); ATEXIT(romfsExit); - sdmcInit(); - ATEXIT(sdmcExit); - srvInit(); ATEXIT(srvExit); @@ -68,8 +72,10 @@ Result servicesInit(void) pxiDevInit(); ATEXIT(pxiDevExit); - if (R_FAILED(res = Archive::init())) + if (R_FAILED(res = Archive::init())) { + Logger::getInstance().error("Archive::init failed with result %llX", res); return consoleDisplayError("Archive::init failed.", res); + } ATEXIT(Archive::exit); mkdir("sdmc:/3ds", 777); @@ -87,6 +93,8 @@ Result servicesInit(void) Configuration::getInstance(); + Logger::getInstance().info("Checkpoint loading finished!"); + return 0; } diff --git a/common/common.cpp b/common/common.cpp index cb9f82b..935fb97 100644 --- a/common/common.cpp +++ b/common/common.cpp @@ -45,6 +45,16 @@ std::string DateTime::dateTimeStr(void) timeStruct.tm_min, timeStruct.tm_sec); } +std::string DateTime::logDateTime(void) +{ + time_t unixTime; + struct tm timeStruct; + time(&unixTime); + localtime_r(&unixTime, &timeStruct); + return StringUtils::format("%04i-%02i-%02i %02i:%02i:%02i", timeStruct.tm_year + 1900, timeStruct.tm_mon + 1, timeStruct.tm_mday, + timeStruct.tm_hour, timeStruct.tm_min, timeStruct.tm_sec); +} + std::string StringUtils::UTF16toUTF8(const std::u16string& src) { static std::wstring_convert, char16_t> convert; diff --git a/common/common.hpp b/common/common.hpp index ba0e118..92b6b74 100644 --- a/common/common.hpp +++ b/common/common.hpp @@ -46,6 +46,7 @@ namespace DateTime { std::string timeStr(void); std::string dateTimeStr(void); + std::string logDateTime(void); } namespace StringUtils { diff --git a/common/logger.hpp b/common/logger.hpp index d028f63..7a9bf21 100644 --- a/common/logger.hpp +++ b/common/logger.hpp @@ -40,13 +40,27 @@ public: } template - void log(const std::string& format, Args... args) + void info(const std::string& format, Args... args) { - if (mFile != NULL) { - fprintf(mFile, (DateUtils::logDateTime() + format + "\n").c_str(), args...); - } + log(format, args...); } + template + void error(const std::string& format, Args... args) + { + log(ERROR, format, args...); + } + + template + void debug(const std::string& format, Args... args) + { + log(DEBUG, format, args...); + } + + inline static const std::string INFO = "[ INFO]"; + inline static const std::string DEBUG = "[DEBUG]"; + inline static const std::string ERROR = "[ERROR]"; + private: Logger(void) { mFile = fopen(mPath.c_str(), "a"); } ~Logger(void) { fclose(mFile); } @@ -54,6 +68,14 @@ private: Logger(Logger const&) = delete; void operator=(Logger const&) = delete; + template + void log(const std::string& level = INFO, const std::string& format = {}, Args... args) + { + if (mFile != NULL) { + fprintf(mFile, ("[" + DateTime::logDateTime() + "] " + level + " " + format + "\n").c_str(), args...); + } + } + #if defined(_3DS) const std::string mPath = "/3ds/Checkpoint/checkpoint.log"; #elif defined(__SWITCH__) diff --git a/switch/source/util.cpp b/switch/source/util.cpp index 8b1eccd..10ab994 100644 --- a/switch/source/util.cpp +++ b/switch/source/util.cpp @@ -26,6 +26,24 @@ #include "util.hpp" +static Result consoleDisplayError(const std::string& message, Result res) +{ + consoleInit(NULL); + + printf("\x1b[2;29HCheckpoint v%d.%d.%d-%s", VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO, GIT_REV); + printf("\x1b[5;2HError during startup: \x1b[31m0x%08X\x1b[0m", res); + printf("\x1b[8;2HDescription: \x1b[33m%s\x1b[0m", message.c_str()); + printf("\x1b[45;32HPress PLUS to exit."); + consoleUpdate(NULL); + while (appletMainLoop() && !(hidKeysDown(CONTROLLER_P1_AUTO) & KEY_PLUS)) { + hidScanInput(); + } + + consoleExit(NULL); + + return res; +} + void servicesExit(void) { ftp_exit(); @@ -46,6 +64,10 @@ void servicesExit(void) Result servicesInit(void) { + if (appletGetAppletType() != AppletType_Application) { + return consoleDisplayError("Please run Checkpoint under Atmosphere title takeover.", -1); + } + // debug Result socinit = 0; if ((socinit = socketInitializeDefault()) == 0) {