diff --git a/code/sys/con_win32.c b/code/sys/con_win32.c index 1e22dd4e..b9b2199d 100644 --- a/code/sys/con_win32.c +++ b/code/sys/con_win32.c @@ -28,6 +28,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; @@ -45,6 +46,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 @@ -143,6 +176,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 ); @@ -155,15 +189,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 ) @@ -188,6 +228,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 ); } @@ -224,6 +265,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(CLIENT_WINDOW_TITLE " Dedicated Server Console"); @@ -236,6 +278,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 ) ); } /* @@ -347,6 +392,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 @@ -354,7 +456,7 @@ CON_Print */ void CON_Print( const char *msg ) { - fputs( msg, stderr ); + CON_WindowsColorPrint( msg ); CON_Show( ); }