From d35f6ca3dbea9576ac38a834f2b3e0152f0ff9bd Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Tue, 8 Jan 2013 17:20:01 -0600 Subject: Colorize text on win32 console Text input line color based on code by "spior" Main colorize function based on Sys_AnsiColorPrint in sys_main.c --- src/sys/con_win32.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 2 deletions(-) diff --git a/src/sys/con_win32.c b/src/sys/con_win32.c index a39bd159..73f62cd1 100644 --- a/src/sys/con_win32.c +++ b/src/sys/con_win32.c @@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define QCONSOLE_HISTORY 32 static WORD qconsole_attrib; +static WORD qconsole_backgroundAttrib; // saved console status static DWORD qconsole_orig_mode; @@ -46,6 +47,38 @@ static int qconsole_linelen = 0; static HANDLE qconsole_hout; static HANDLE qconsole_hin; +/* +================== +CON_ColorCharToAttrib + +Convert Quake color character to Windows text attrib +================== +*/ +static WORD CON_ColorCharToAttrib( char color ) { + WORD attrib; + + if ( color == COLOR_WHITE ) + { + // use console's foreground and background colors + attrib = qconsole_attrib; + } + else + { + float *rgba = g_color_table[ ColorIndex( color ) ]; + + // set foreground color + attrib = ( rgba[0] >= 0.5 ? FOREGROUND_RED : 0 ) | + ( rgba[1] >= 0.5 ? FOREGROUND_GREEN : 0 ) | + ( rgba[2] >= 0.5 ? FOREGROUND_BLUE : 0 ) | + ( rgba[3] >= 0.5 ? FOREGROUND_INTENSITY : 0 ); + + // use console's background color + attrib |= qconsole_backgroundAttrib; + } + + return attrib; +} + /* ================== CON_CtrlHandler @@ -144,6 +177,7 @@ static void CON_Show( void ) SMALL_RECT writeArea = { 0, 0, 0, 0 }; int i; CHAR_INFO line[ MAX_EDIT_LINE ]; + WORD attrib; GetConsoleScreenBufferInfo( qconsole_hout, &binfo ); @@ -156,15 +190,21 @@ static void CON_Show( void ) writeArea.Bottom = binfo.dwCursorPosition.Y; writeArea.Right = MAX_EDIT_LINE; + // set color to white + attrib = CON_ColorCharToAttrib( COLOR_WHITE ); + // build a space-padded CHAR_INFO array for( i = 0; i < MAX_EDIT_LINE; i++ ) { + if( Q_IsColorString( qconsole_line + i ) ) + attrib = CON_ColorCharToAttrib( *( qconsole_line + i + 1 ) ); + if( i < qconsole_linelen ) line[ i ].Char.AsciiChar = qconsole_line[ i ]; else line[ i ].Char.AsciiChar = ' '; - line[ i ].Attributes = qconsole_attrib; + line[ i ].Attributes = attrib; } if( qconsole_linelen > binfo.srWindow.Right ) @@ -189,6 +229,7 @@ void CON_Shutdown( void ) { SetConsoleMode( qconsole_hin, qconsole_orig_mode ); SetConsoleCursorInfo( qconsole_hout, &qconsole_orig_cursorinfo ); + SetConsoleTextAttribute( qconsole_hout, qconsole_attrib ); CloseHandle( qconsole_hout ); CloseHandle( qconsole_hin ); } @@ -225,6 +266,7 @@ void CON_Init( void ) GetConsoleScreenBufferInfo( qconsole_hout, &info ); qconsole_attrib = info.wAttributes; + qconsole_backgroundAttrib = qconsole_attrib & (BACKGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_RED|BACKGROUND_INTENSITY); SetConsoleTitle("Tremulous Dedicated Server Console"); @@ -237,6 +279,9 @@ void CON_Init( void ) // initialize history for( i = 0; i < QCONSOLE_HISTORY; i++ ) qconsole_history[ i ][ 0 ] = '\0'; + + // set text color to white + SetConsoleTextAttribute( qconsole_hout, CON_ColorCharToAttrib( COLOR_WHITE ) ); } /* @@ -348,6 +393,63 @@ char *CON_Input( void ) return qconsole_line; } +/* +================= +CON_WindowsColorPrint + +Set text colors based on Q3 color codes +================= +*/ +void CON_WindowsColorPrint( const char *msg ) +{ + static char buffer[ MAXPRINTMSG ]; + int length = 0; + + while( *msg ) + { + if( Q_IsColorString( msg ) || *msg == '\n' ) + { + // First empty the buffer + if( length > 0 ) + { + buffer[ length ] = '\0'; + fputs( buffer, stderr ); + length = 0; + } + + if( *msg == '\n' ) + { + // Reset color and then add the newline + SetConsoleTextAttribute( qconsole_hout, CON_ColorCharToAttrib( COLOR_WHITE ) ); + fputs( "\n", stderr ); + msg++; + } + else + { + // Set the color + SetConsoleTextAttribute( qconsole_hout, CON_ColorCharToAttrib( *( msg + 1 ) ) ); + 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, stderr ); + } +} + /* ================== CON_Print @@ -355,7 +457,7 @@ CON_Print */ void CON_Print( const char *msg ) { - fputs( msg, stderr ); + CON_WindowsColorPrint( msg ); CON_Show( ); } -- cgit