From 2bbb599d7cf39dfc788d2172da0a880cfb5d3f24 Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 9 Mar 2017 21:19:17 +0300 Subject: [PATCH] Add ANSI colors option for gsc_printf() --- gsc_utils.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++- libcod.cpp | 2 ++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/gsc_utils.cpp b/gsc_utils.cpp index 08296fa..007c5f4 100644 --- a/gsc_utils.cpp +++ b/gsc_utils.cpp @@ -43,6 +43,81 @@ void gsc_utils_getarraykeys() } } +/* +================= +Sys_AnsiColorPrint +Transform Q3 colour codes to ANSI escape sequences +================= +*/ +#define MAXPRINTMSG 1024 +#define ColorIndex(c) (((c) - '0') & 0x07) +#define Q_COLOR_ESCAPE '^' +#define Q_IsColorString(p) ((p) && *(p) == Q_COLOR_ESCAPE && *((p)+1) && isalnum(*((p)+1))) // ^[0-9a-zA-Z] +void Sys_AnsiColorPrint( const char *msg ) +{ + static char buffer[ MAXPRINTMSG ]; + int length = 0; + static int q3ToAnsi[ 8 ] = + { + 30, // COLOR_BLACK + 31, // COLOR_RED + 32, // COLOR_GREEN + 33, // COLOR_YELLOW + 34, // COLOR_BLUE + 36, // COLOR_CYAN + 35, // COLOR_MAGENTA + 0 // COLOR_WHITE + }; + + while( *msg ) + { + if( Q_IsColorString( msg ) || *msg == '\n' ) + { + // First empty the buffer + if( length > 0 ) + { + buffer[ length ] = '\0'; + fputs( buffer, stdout ); + length = 0; + } + + if( *msg == '\n' ) + { + // Issue a reset and then the newline + fputs( "\033[0m\n", stdout ); + msg++; + } + else + { + // Print the color code + Com_sprintf( buffer, sizeof( buffer ), "\033[1;%dm", + q3ToAnsi[ ColorIndex( *( msg + 1 ) ) ] ); + fputs( buffer, stdout ); + msg += 2; + } + } + else + { + if( length >= MAXPRINTMSG - 1 ) + break; + + buffer[ length ] = *msg; + length++; + msg++; + } + } + + // Empty anything still left in the buffer + if( length > 0 ) + { + buffer[ length ] = '\0'; + fputs( buffer, stdout ); + // Issue a reset at the end + fputs( "\033[0m", stdout ); + } +} + +extern cvar_t *colored_prints; int stackPrintParam(int param) { if (param >= Scr_GetNumParam()) @@ -53,7 +128,10 @@ int stackPrintParam(int param) case STACK_STRING: char *str; stackGetParamString(param, &str); // no error checking, since we know it's a string - printf("%s", str); + if (colored_prints->boolean) + Sys_AnsiColorPrint(str); + else + printf("%s", str); return 1; case STACK_VECTOR: diff --git a/libcod.cpp b/libcod.cpp index 1ff4f17..ab62895 100644 --- a/libcod.cpp +++ b/libcod.cpp @@ -14,6 +14,7 @@ cvar_t *sv_allowDownload; cvar_t *sv_pure; cvar_t *developer; cvar_t *rcon_password; +cvar_t *colored_prints; #if COD_VERSION == COD2_1_2 || COD_VERSION == COD2_1_3 cvar_t *sv_wwwDownload; @@ -1222,6 +1223,7 @@ class cCallOfDuty2Pro sv_cracked = Cvar_RegisterBool("sv_cracked", 0, 0x1000u); nodeveloper_errors = Cvar_RegisterBool("nodeveloper_errors", 0, 0x1000u); nodeveloper_prints = Cvar_RegisterBool("nodeveloper_prints", 0, 0x1000u); + colored_prints = Cvar_RegisterBool("colored_prints", 1, 0x1000u); g_playerCollision = Cvar_RegisterBool("g_playerCollision", 1, 0x1000u); g_playerEject = Cvar_RegisterBool("g_playerEject", 1, 0x1000u); fs_library = Cvar_RegisterString("fs_library", "", 0x1000u);