#pragma once
#include <cstddef>
#include "ppsspp_config.h"
#include "CommonFuncs.h"
#define NOTICE_LEVEL 1
#define ERROR_LEVEL 2
#define WARNING_LEVEL 3
#define INFO_LEVEL 4
#define DEBUG_LEVEL 5
#define VERBOSE_LEVEL 6
enum class Log {
System = 0,
Boot,
Common,
CPU,
FileSystem,
G3D,
HLE,
JIT,
Loader,
Mpeg,
Atrac,
ME,
MemMap,
SasMix,
SaveState,
FrameBuf,
Audio,
IO,
Achievements,
HTTP,
Printf,
TexReplacement,
GeDebugger,
UI,
IAP,
sceAudio,
sceCtrl,
sceDisplay,
sceFont,
sceGe,
sceIntc,
sceIo,
sceKernel,
sceModule,
sceNet,
sceRtc,
sceSas,
sceUtility,
sceMisc,
sceReg,
NUMBER_OF_LOGS,
};
enum class LogLevel : int {
LNOTICE = NOTICE_LEVEL,
LERROR = ERROR_LEVEL,
LWARNING = WARNING_LEVEL,
LINFO = INFO_LEVEL,
LDEBUG = DEBUG_LEVEL,
LVERBOSE = VERBOSE_LEVEL,
};
struct LogChannel {
#if defined(_DEBUG)
LogLevel level = LogLevel::LDEBUG;
#else
LogLevel level = LogLevel::LDEBUG;
#endif
bool enabled = true;
bool IsEnabled(LogLevel level) const {
if (level > this->level || !this->enabled)
return false;
return true;
}
};
extern bool *g_bLogEnabledSetting;
extern LogChannel g_log[(size_t)Log::NUMBER_OF_LOGS];
inline bool GenericLogEnabled(Log type, LogLevel level) {
return g_log[(int)type].IsEnabled(level) && (*g_bLogEnabledSetting);
}
void GenericLog(Log type, LogLevel level, const char *file, int line, const char *fmt, ...)
#ifdef __GNUC__
__attribute__((format(printf, 5, 6)))
#endif
;
#define MAX_LOGLEVEL DEBUG_LEVEL
#define GENERIC_LOG(t, v, ...) \
if ((int)v <= MAX_LOGLEVEL && GenericLogEnabled(t, v)) { \
GenericLog(t, v, __FILE__, __LINE__, __VA_ARGS__); \
}
#define ERROR_LOG(t,...) do { GENERIC_LOG(t, LogLevel::LERROR, __VA_ARGS__) } while (false)
#define WARN_LOG(t,...) do { GENERIC_LOG(t, LogLevel::LWARNING, __VA_ARGS__) } while (false)
#define NOTICE_LOG(t,...) do { GENERIC_LOG(t, LogLevel::LNOTICE, __VA_ARGS__) } while (false)
#define INFO_LOG(t,...) do { GENERIC_LOG(t, LogLevel::LINFO, __VA_ARGS__) } while (false)
#define DEBUG_LOG(t,...) do { GENERIC_LOG(t, LogLevel::LDEBUG, __VA_ARGS__) } while (false)
#define VERBOSE_LOG(t,...) do { GENERIC_LOG(t, LogLevel::LVERBOSE, __VA_ARGS__) } while (false)
bool HandleAssert(const char *function, const char *file, int line, const char *expression, const char* format, ...)
#ifdef __GNUC__
__attribute__((format(printf, 5, 6)))
#endif
;
enum class DebugCounter {
APP_BOOT = 0,
GAME_BOOT = 1,
GAME_SHUTDOWN = 2,
CPUCORE_SWITCHES = 3,
};
bool HitAnyAsserts();
void ResetHitAnyAsserts();
void SetExtraAssertInfo(const char *info);
void SetDebugValue(DebugCounter counter, int value);
void IncrementDebugCounter(DebugCounter counter);
typedef void (*AssertNoCallbackFunc)(const char *message, void *userdata);
void SetAssertCancelCallback(AssertNoCallbackFunc callback, void *userdata);
void SetCleanExitOnAssert();
void BreakIntoPSPDebugger(const char *reason = "(userbreak)");
void SetAssertDialogParent(void *handle);
#if defined(__ANDROID__)
#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : (__builtin_strrchr(__FILE__, '\\') ? __builtin_strrchr(__FILE__, '\\') + 1 : __FILE__))
#else
#define __FILENAME__ __FILE__
#endif
#if defined(_DEBUG)
#define _dbg_assert_(_a_) \
if (!(_a_)) {\
if (!HandleAssert(__FUNCTION__, __FILENAME__, __LINE__, #_a_, "Assert!\n")) Crash(); \
}
#define _dbg_assert_or_log_(_a_) \
if (!(_a_)) {\
if (!HandleAssert(__FUNCTION__, __FILENAME__, __LINE__, #_a_, "Assert!\n")) Crash(); \
}
#define _dbg_assert_msg_(_a_, ...) \
if (!(_a_)) { \
if (!HandleAssert(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__)) Crash(); \
}
#define _dbg_assert_msg_or_log_(_a_, log, ...) \
if (!(_a_)) { \
if (!HandleAssert(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__)) Crash(); \
}
#else
#ifndef _dbg_assert_
#define _dbg_assert_(_a_) {}
#define _dbg_assert_or_log_(_a_) \
if (!(_a_)) { \
ERROR_LOG(Log::System, "Assert! " ## #_a_); \
}
#define _dbg_assert_msg_(_a_, _desc_, ...) {}
#define _dbg_assert_msg_or_log_(_a_, log, ...) \
if (!(_a_)) { \
ERROR_LOG(log, __VA_ARGS__); \
}
#endif
#endif
#define _assert_(_a_) \
if (!(_a_)) {\
if (!HandleAssert(__FUNCTION__, __FILENAME__, __LINE__, #_a_, "Assert!\n")) Crash(); \
}
#define _assert_msg_(_a_, ...) \
if (!(_a_)) { \
if (!HandleAssert(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__)) Crash(); \
}
void OutputDebugStringUTF8(const char *p);