diff --git a/src/debug/log.c b/src/debug/log.c index 974858476..6daf278b5 100644 --- a/src/debug/log.c +++ b/src/debug/log.c @@ -171,6 +171,9 @@ static flagname_t TraceFlags[] = { uint64_t LogTraceFlags = TRACE_NONE; FILE *TraceFile = NULL; +/* We are using a function pointer for the printing code so that the + * libretro code can replace this with a libretro-specific handler. */ +void (*log_print)(LOGTYPE nType, const char *psFormat, va_list args); /* SDL GUI Alerts can show 4*50 chars at max. Use that also * as initial message buffer size (must be longer than log prefixes) @@ -198,7 +201,9 @@ static FILE *hLogFile = NULL; static LOGTYPE TextLogLevel; static LOGTYPE AlertDlgLogLevel; -/*-----------------------------------------------------------------------*/ +static void Log_VPrintf(LOGTYPE nType, const char *psFormat, va_list args); + + /** * Set default files to stderr (used at the very start, before parsing options) */ @@ -235,6 +240,9 @@ void Log_SetLevels(void) */ int Log_Init(void) { + if (!log_print) + log_print = Log_VPrintf; + Log_SetLevels(); /* Flush pending msg & drop cached prev msg FILE pointer @@ -274,8 +282,20 @@ void Log_UnInit(void) hLogFile = File_Close(hLogFile); TraceFile = File_Close(TraceFile); + + log_print = NULL; } + +/** + * Set alternative logger printing function + */ +void Log_SetPrintFunction(void (*func)(LOGTYPE nType, const char *psFormat, va_list args)) +{ + log_print = func; +} + + /*----------------------------------------------------------------------- * log/trace message repeat suppression handling */ @@ -482,7 +502,10 @@ void Log_Printf(LOGTYPE nType, const char *psFormat, ...) va_list argptr; va_start(argptr, psFormat); - Log_VPrintf(nType, psFormat, argptr); + if (log_print) + log_print(nType, psFormat, argptr); + else + Log_VPrintf(nType, psFormat, argptr); va_end(argptr); } @@ -499,7 +522,10 @@ void Log_AlertDlg(LOGTYPE nType, const char *psFormat, ...) if (hLogFile && nType <= TextLogLevel) { va_start(argptr, psFormat); - Log_VPrintf(nType, psFormat, argptr); + if (log_print) + log_print(nType, psFormat, argptr); + else + Log_VPrintf(nType, psFormat, argptr); va_end(argptr); } diff --git a/src/debug/log.h b/src/debug/log.h index b94767b0f..1075e50da 100644 --- a/src/debug/log.h +++ b/src/debug/log.h @@ -77,6 +77,7 @@ extern void Log_SetLevels(void); extern int Log_Init(void); extern int Log_SetAlertLevel(int level); extern void Log_UnInit(void); +void Log_SetPrintFunction(void (*func)(LOGTYPE nType, const char *psFormat, va_list args)); extern void Log_Printf(LOGTYPE nType, const char *psFormat, ...) __attribute__ ((format (printf, 2, 3))); extern void Log_AlertDlg(LOGTYPE nType, const char *psFormat, ...) diff --git a/src/retro/main_retro.c b/src/retro/main_retro.c index 1896ccc72..34c0030fe 100644 --- a/src/retro/main_retro.c +++ b/src/retro/main_retro.c @@ -14,6 +14,7 @@ #include "file.h" #include "floppy.h" #include "harddisk.h" +#include "log.h" #include "memorySnapShot.h" #include "m68000.h" #include "options.h" @@ -33,6 +34,7 @@ retro_environment_t environment_cb; retro_video_refresh_t video_refresh_cb; retro_input_poll_t input_poll_cb; retro_input_state_t input_state_cb; +static retro_log_printf_t log_cb = NULL; #define SAVESTATE_TMP_NAME "hatari_savestate.tmp" static char scratch_path[FILENAME_MAX]; @@ -96,6 +98,34 @@ static void Retro_LogFrontend(const char *msg, int level) } } +static void Retro_Log(LOGTYPE nType, const char *psFormat, va_list args) +{ + char logbuf[512]; + unsigned int len; + int rlevel; + + if (!log_cb) + return; + + switch (nType) + { + case LOG_DEBUG: rlevel = RETRO_LOG_DEBUG; break; + case LOG_WARN: rlevel = RETRO_LOG_WARN; break; + case LOG_ERROR: rlevel = RETRO_LOG_ERROR; break; + default: rlevel = RETRO_LOG_INFO; + } + + len = vsnprintf(logbuf, sizeof(logbuf), psFormat, args); + if (len > 0 && len < sizeof(logbuf) - 1 && logbuf[len - 1] != '\n') + { + /* Log message might not end with \n, so add one here */ + logbuf[len] = '\n'; + logbuf[len + 1] = 0; + } + log_cb(rlevel, "%s", logbuf); +} + + RETRO_API void retro_set_environment(retro_environment_t cb) { static enum retro_pixel_format pixelformat = RETRO_PIXEL_FORMAT_XRGB8888; @@ -142,6 +172,14 @@ RETRO_API void retro_init(void) char *argv[4]; const char *save_dir = NULL; const char *system_dir = NULL; + struct retro_log_callback logging; + + /* Register log call back */ + if (environment_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &logging)) + { + log_cb = logging.log; + Log_SetPrintFunction(Retro_Log); + } /* Register disk control */ DiskControl_Init();