#pragma once #include <cstdarg> #include <fstream> #ifdef __ANDROID__ #include <android/log.h> #endif namespace Log { // Our logger class template <bool enabled> class Logger { public: void log(const char* fmt, ...) { if constexpr (!enabled) return; std::va_list args; va_start(args, fmt); #ifdef __ANDROID__ __android_log_vprint(ANDROID_LOG_DEFAULT, "Panda3DS", fmt, args); #else std::vprintf(fmt, args); #endif va_end(args); } }; // Our loggers here. Enable/disable by toggling the template param static Logger<false> kernelLogger; // Enables output for the outputDebugString SVC static Logger<true> debugStringLogger; static Logger<false> errorLogger; static Logger<false> fileIOLogger; static Logger<false> svcLogger; static Logger<false> threadLogger; static Logger<false> gpuLogger; static Logger<false> rendererLogger; static Logger<false> shaderJITLogger; static Logger<false> dspLogger; // Service loggers static Logger<false> acLogger; static Logger<false> actLogger; static Logger<false> amLogger; static Logger<false> aptLogger; static Logger<false> bossLogger; static Logger<false> camLogger; static Logger<false> cecdLogger; static Logger<false> cfgLogger; static Logger<false> csndLogger; static Logger<false> dspServiceLogger; static Logger<false> dlpSrvrLogger; static Logger<false> frdLogger; static Logger<false> fsLogger; static Logger<false> hidLogger; static Logger<false> httpLogger; static Logger<false> irUserLogger; static Logger<false> gspGPULogger; static Logger<false> gspLCDLogger; static Logger<false> ldrLogger; static Logger<false> mcuLogger; static Logger<false> micLogger; static Logger<false> newsLogger; static Logger<false> nfcLogger; static Logger<false> nwmUdsLogger; static Logger<false> nimLogger; static Logger<false> ndmLogger; static Logger<false> ptmLogger; static Logger<false> socLogger; static Logger<false> sslLogger; static Logger<false> y2rLogger; static Logger<false> srvLogger; // We have 2 ways to create a log function // MAKE_LOG_FUNCTION: Creates a log function which is toggleable but always killed for user-facing builds // MAKE_LOG_FUNCTION_USER: Creates a log function which is toggleable, may be on for user builds as well // We need this because sadly due to the loggers taking variadic arguments, compilers will not properly // Kill them fully even when they're disabled. The only way they will is if the function with varargs is totally empty #define MAKE_LOG_FUNCTION_USER(functionName, logger) \ template <typename... Args> \ void functionName(const char* fmt, Args&&... args) { \ Log::logger.log(fmt, args...); \ } #ifdef PANDA3DS_USER_BUILD #define MAKE_LOG_FUNCTION(functionName, logger) \ template <typename... Args> \ void functionName(const char* fmt, Args&&... args) {} #else #define MAKE_LOG_FUNCTION(functionName, logger) MAKE_LOG_FUNCTION_USER(functionName, logger) #endif }