Using idTech 5 fonts for gui and console.

This commit is contained in:
Justin Marshall
2026-05-28 19:17:27 -07:00
parent e4c87fd5a4
commit 0591e0b5c1
28 changed files with 459 additions and 1019 deletions
+165 -93
View File
@@ -29,6 +29,8 @@ If you have questions concerning this license or the applicable additional terms
#include "precompiled.h"
#pragma hdrstop
#include "ConsoleHistory.h"
void SCR_DrawTextLeftAlign( float &y, const char *text, ... ) id_attribute((format(printf,2,3)));
void SCR_DrawTextRightAlign( float &y, const char *text, ... ) id_attribute((format(printf,2,3)));
extern int QD3D12_GetActiveFrameGenerationMultiplier( void );
@@ -36,14 +38,14 @@ extern const char *QD3D12_GetAdapterName( void );
extern int QD3D12_GetVideoMemoryInfo( uint64_t *usageBytes, uint64_t *budgetBytes, uint64_t *dedicatedBytes );
extern glconfig_t glConfig;
#define LINE_WIDTH 78
#define LINE_WIDTH 160
#define NUM_CON_TIMES 4
#define CON_TEXTSIZE 0x30000
#define TOTAL_LINES (CON_TEXTSIZE / LINE_WIDTH)
#define CONSOLE_FIRSTREPEAT 200
#define CONSOLE_REPEAT 100
#define COMMAND_HISTORY 64
static const char *CONSOLE_FONT_NAME = "editor";
// the console will query the cvar and command systems for
// command completion information
@@ -65,8 +67,6 @@ public:
//============================
const idMaterial * charSetShader;
private:
void KeyDownEvent( int key );
@@ -106,12 +106,6 @@ private:
// for transparent notify lines
idVec4 color;
idEditField historyEditLines[COMMAND_HISTORY];
int nextHistoryLine;// the last line in the history buffer, not masked
int historyLine; // the line being displayed from history buffer
// will be <= nextHistoryLine
idEditField consoleField;
static idCVar con_speed;
@@ -154,7 +148,7 @@ void SCR_DrawTextLeftAlign( float &y, const char *text, ... ) {
va_start( argptr, text );
idStr::vsnPrintf( string, sizeof( string ), text, argptr );
va_end( argptr );
renderSystem->DrawSmallStringExt( 0, y + 2, string, colorWhite, true, localConsole.charSetShader );
renderSystem->DrawSmallStringExt( 0, y + 2, string, colorWhite, true, NULL );
y += SMALLCHAR_HEIGHT + 4;
}
@@ -169,7 +163,7 @@ void SCR_DrawTextRightAlign( float &y, const char *text, ... ) {
va_start( argptr, text );
int i = idStr::vsnPrintf( string, sizeof( string ), text, argptr );
va_end( argptr );
renderSystem->DrawSmallStringExt( 635 - i * SMALLCHAR_WIDTH, y + 2, string, colorWhite, true, localConsole.charSetShader );
renderSystem->DrawSmallStringExt( 635 - i * SMALLCHAR_WIDTH, y + 2, string, colorWhite, true, NULL );
y += SMALLCHAR_HEIGHT + 4;
}
@@ -192,9 +186,130 @@ static const idVec4 &SCR_FrameTimeColor( int msec ) {
return colorRed;
}
static int SCR_ConsoleSmallStringWidth( const char *text );
static void SCR_DrawSmallStringRightAlign( float y, const idVec4 &color, const char *text ) {
const int w = strlen( text ) * SMALLCHAR_WIDTH;
renderSystem->DrawSmallStringExt( ( SCREEN_WIDTH - 5.0f ) - w, idMath::FtoiFast( y ) + 2, text, color, true, localConsole.charSetShader );
const int w = SCR_ConsoleSmallStringWidth( text );
renderSystem->DrawSmallStringExt( ( SCREEN_WIDTH - 5.0f ) - w, idMath::FtoiFast( y ) + 2, text, color, true, NULL );
}
static const float SCR_CONSOLE_SMALL_FONT_SCALE = 0.255f;
static const float SCR_CONSOLE_SMALL_CHAR_PAD = 0.75f;
static const float SCR_CONSOLE_BIG_FONT_SCALE = 0.33f;
static const float SCR_CONSOLE_BIG_CHAR_PAD = 0.75f;
static const idVec4 CONSOLE_COLOR_TEXT( 0.78f, 0.78f, 0.74f, 1.0f );
static const idVec4 CONSOLE_COLOR_DIM_TEXT( 0.48f, 0.48f, 0.45f, 1.0f );
static const idVec4 CONSOLE_COLOR_WARNING( 0.92f, 0.86f, 0.08f, 1.0f );
static const idVec4 CONSOLE_COLOR_ERROR( 0.95f, 0.06f, 0.02f, 1.0f );
static const idVec4 CONSOLE_COLOR_ORANGE( 1.0f, 0.34f, 0.02f, 1.0f );
static const idVec4 CONSOLE_COLOR_GREEN( 0.55f, 0.82f, 0.12f, 1.0f );
static const idVec4 CONSOLE_COLOR_COMPLETE( 0.95f, 0.18f, 0.02f, 0.35f );
static const idVec4 &SCR_ConsoleColorForIndex( int colorIndex ) {
switch ( colorIndex ) {
case ( C_COLOR_RED & 15 ):
case ( C_COLOR_MAGENTA & 15 ):
return CONSOLE_COLOR_ERROR;
case ( C_COLOR_GREEN & 15 ):
return CONSOLE_COLOR_GREEN;
case ( C_COLOR_YELLOW & 15 ):
return CONSOLE_COLOR_WARNING;
case ( C_COLOR_GRAY & 15 ):
return CONSOLE_COLOR_DIM_TEXT;
case ( C_COLOR_BLACK & 15 ):
return colorBlack;
case ( C_COLOR_DEFAULT & 15 ):
case ( C_COLOR_WHITE & 15 ):
case ( C_COLOR_CYAN & 15 ):
case ( C_COLOR_BLUE & 15 ):
default:
return CONSOLE_COLOR_TEXT;
}
}
static int SCR_ConsoleSmallStringWidth( const char *text ) {
if ( text == NULL ) {
return 0;
}
idFont *font = renderSystem->RegisterFont( CONSOLE_FONT_NAME );
if ( font == NULL ) {
return strlen( text ) * SMALLCHAR_WIDTH;
}
int width = 0;
for ( const unsigned char *s = (const unsigned char *)text; *s != '\0'; s++ ) {
if ( idStr::IsColor( (const char *)s ) ) {
s++;
continue;
}
float advance = font->GetGlyphWidth( SCR_CONSOLE_SMALL_FONT_SCALE, *s );
if ( advance <= 0.0f ) {
advance = SMALLCHAR_WIDTH;
}
width += idMath::FtoiFast( advance + SCR_CONSOLE_SMALL_CHAR_PAD );
}
return width;
}
static int SCR_ConsoleBigStringWidth( const char *text ) {
if ( text == NULL ) {
return 0;
}
idFont *font = renderSystem->RegisterFont( CONSOLE_FONT_NAME );
if ( font == NULL ) {
return strlen( text ) * BIGCHAR_WIDTH;
}
int width = 0;
for ( const unsigned char *s = (const unsigned char *)text; *s != '\0'; s++ ) {
if ( idStr::IsColor( (const char *)s ) ) {
s++;
continue;
}
float advance = font->GetGlyphWidth( SCR_CONSOLE_BIG_FONT_SCALE, *s );
if ( advance <= 0.0f ) {
advance = BIGCHAR_WIDTH;
}
width += idMath::FtoiFast( advance + SCR_CONSOLE_BIG_CHAR_PAD );
}
return width;
}
static void SCR_DrawConsoleTextLine( const short *text_p, int y ) {
char run[LINE_WIDTH + 1];
int runLen = 0;
int runColor = idStr::ColorIndex( C_COLOR_WHITE );
int last = LINE_WIDTH - 1;
int penX = SMALLCHAR_WIDTH;
while ( last >= 0 && ( text_p[last] & 0xff ) == ' ' ) {
last--;
}
for ( int x = 0; x <= last; x++ ) {
const int ch = text_p[x] & 0xff;
const int color = idStr::ColorIndex( text_p[x] >> 8 );
if ( runLen > 0 && color != runColor ) {
run[runLen] = '\0';
renderSystem->DrawSmallStringExt( penX, y, run, SCR_ConsoleColorForIndex( runColor ), true, NULL );
penX += SCR_ConsoleSmallStringWidth( run );
runLen = 0;
}
runColor = color;
run[runLen++] = ch;
}
if ( runLen > 0 ) {
run[runLen] = '\0';
renderSystem->DrawSmallStringExt( penX, y, run, SCR_ConsoleColorForIndex( runColor ), true, NULL );
}
}
static uint64_t SCR_BytesToMiB( uint64_t bytes ) {
@@ -243,9 +358,9 @@ float SCR_DrawFPS( float y ) {
} else {
s = va( "%ifps %dms", fps, averageFrameTime );
}
w = strlen( s ) * BIGCHAR_WIDTH;
w = SCR_ConsoleBigStringWidth( s );
renderSystem->DrawBigStringExt( (SCREEN_WIDTH - 5.0f) - w, idMath::FtoiFast(y) + 2, s, frameColor, true, localConsole.charSetShader);
renderSystem->DrawBigStringExt( (SCREEN_WIDTH - 5.0f) - w, idMath::FtoiFast(y) + 2, s, frameColor, true, NULL);
y += BIGCHAR_HEIGHT + 4;
s = va( "game cpu:%4.1fms render cpu:%4.1fms pt gpu:%4.1fms", com_lastGameFrameMsec, com_lastRenderFrameMsec, com_pathTracingGpuMsec );
@@ -416,8 +531,6 @@ idConsoleLocal::Init
==============
*/
void idConsoleLocal::Init( void ) {
int i;
keyCatching = false;
lastKeyEvent = -1;
@@ -427,13 +540,9 @@ void idConsoleLocal::Init( void ) {
consoleField.SetWidthInChars( LINE_WIDTH );
for ( i = 0 ; i < COMMAND_HISTORY ; i++ ) {
historyEditLines[i].Clear();
historyEditLines[i].SetWidthInChars( LINE_WIDTH );
}
cmdSystem->AddCommand( "clear", Con_Clear_f, CMD_FL_SYSTEM, "clears the console" );
cmdSystem->AddCommand( "conDump", Con_Dump_f, CMD_FL_SYSTEM, "dumps the console text to a file" );
ConsoleHistory_RegisterCommands();
}
/*
@@ -444,6 +553,7 @@ idConsoleLocal::Shutdown
void idConsoleLocal::Shutdown( void ) {
cmdSystem->RemoveCommand( "clear" );
cmdSystem->RemoveCommand( "conDump" );
ConsoleHistory_UnregisterCommands();
}
/*
@@ -455,13 +565,8 @@ the renderSystem is initialized
==============
*/
void idConsoleLocal::LoadGraphics() {
#ifdef QUAKE4
// jmarshall
charSetShader = declManager->FindMaterial("fonts/english/bigchars");
// jmarshall end
#else
charSetShader = declManager->FindMaterial( "textures/bigchars" );
#endif
consoleHistory.LoadHistoryFile();
renderSystem->RegisterFont( CONSOLE_FONT_NAME );
whiteShader = declManager->FindMaterial( "_white" );
consoleShader = declManager->FindMaterial( "console" );
}
@@ -651,10 +756,7 @@ void idConsoleLocal::KeyDownEvent( int key ) {
cmdSystem->BufferCommandText( CMD_EXEC_APPEND, consoleField.GetBuffer() ); // valid command
cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "\n" );
// copy line to history buffer
historyEditLines[nextHistoryLine % COMMAND_HISTORY] = consoleField;
nextHistoryLine++;
historyLine = nextHistoryLine;
consoleHistory.AddToHistory( consoleField.GetBuffer() );
consoleField.Clear();
consoleField.SetWidthInChars( LINE_WIDTH );
@@ -675,20 +777,19 @@ void idConsoleLocal::KeyDownEvent( int key ) {
if ( ( key == K_UPARROW ) ||
( ( tolower(key) == 'p' ) && idKeyInput::IsDown( K_CTRL ) ) ) {
if ( nextHistoryLine - historyLine < COMMAND_HISTORY && historyLine > 0 ) {
historyLine--;
idStr history = consoleHistory.RetrieveFromHistory( true );
if ( !history.IsEmpty() ) {
consoleField.SetBuffer( history.c_str() );
}
consoleField = historyEditLines[ historyLine % COMMAND_HISTORY ];
return;
}
if ( ( key == K_DOWNARROW ) ||
( ( tolower( key ) == 'n' ) && idKeyInput::IsDown( K_CTRL ) ) ) {
if ( historyLine == nextHistoryLine ) {
return;
idStr history = consoleHistory.RetrieveFromHistory( false );
if ( !history.IsEmpty() ) {
consoleField.SetBuffer( history.c_str() );
}
historyLine++;
consoleField = historyEditLines[ historyLine % COMMAND_HISTORY ];
return;
}
@@ -1019,7 +1120,7 @@ void idConsoleLocal::DrawInput() {
autoCompleteLength = strlen( consoleField.GetBuffer() ) - consoleField.GetAutoCompleteLength();
if ( autoCompleteLength > 0 ) {
renderSystem->SetColor4( .8f, .2f, .2f, .45f );
renderSystem->SetColor( CONSOLE_COLOR_COMPLETE );
renderSystem->DrawStretchPic( 2 * SMALLCHAR_WIDTH + consoleField.GetAutoCompleteLength() * SMALLCHAR_WIDTH,
y + 2, autoCompleteLength * SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT - 2, 0, 0, 0, 0, whiteShader );
@@ -1027,11 +1128,11 @@ void idConsoleLocal::DrawInput() {
}
}
renderSystem->SetColor( idStr::ColorForIndex( C_COLOR_CYAN ) );
renderSystem->SetColor( CONSOLE_COLOR_ORANGE );
renderSystem->DrawSmallChar( 1 * SMALLCHAR_WIDTH, y, ']', localConsole.charSetShader );
renderSystem->DrawSmallChar( 1 * SMALLCHAR_WIDTH, y, ']', NULL );
consoleField.Draw(2 * SMALLCHAR_WIDTH, y, SCREEN_WIDTH - 3 * SMALLCHAR_WIDTH, true, charSetShader );
consoleField.Draw(2 * SMALLCHAR_WIDTH, y, SCREEN_WIDTH - 3 * SMALLCHAR_WIDTH, true, NULL );
}
@@ -1043,19 +1144,15 @@ Draws the last few lines of output transparently over the game top
================
*/
void idConsoleLocal::DrawNotify() {
int x, v;
int v;
short *text_p;
int i;
int time;
int currentColor;
if ( con_noPrint.GetBool() ) {
return;
}
currentColor = idStr::ColorIndex( C_COLOR_WHITE );
renderSystem->SetColor( idStr::ColorForIndex( currentColor ) );
v = 0;
for ( i = current-NUM_CON_TIMES+1; i <= current; i++ ) {
if ( i < 0 ) {
@@ -1070,22 +1167,12 @@ void idConsoleLocal::DrawNotify() {
continue;
}
text_p = text + (i % TOTAL_LINES)*LINE_WIDTH;
for ( x = 0; x < LINE_WIDTH; x++ ) {
if ( ( text_p[x] & 0xff ) == ' ' ) {
continue;
}
if ( idStr::ColorIndex(text_p[x]>>8) != currentColor ) {
currentColor = idStr::ColorIndex(text_p[x]>>8);
renderSystem->SetColor( idStr::ColorForIndex( currentColor ) );
}
renderSystem->DrawSmallChar( (x+1)*SMALLCHAR_WIDTH, v, text_p[x] & 0xff, localConsole.charSetShader );
}
SCR_DrawConsoleTextLine( text_p, v );
v += SMALLCHAR_HEIGHT;
}
renderSystem->SetColor( colorCyan );
renderSystem->SetColor( CONSOLE_COLOR_TEXT );
}
/*
@@ -1096,13 +1183,12 @@ Draws the console with the solid background
================
*/
void idConsoleLocal::DrawSolidConsole( float frac ) {
int i, x;
int i, x = 0;
float y;
int rows;
short *text_p;
int row;
int lines;
int currentColor;
lines = idMath::FtoiFast( SCREEN_HEIGHT * frac );
if ( lines <= 0 ) {
@@ -1115,29 +1201,29 @@ void idConsoleLocal::DrawSolidConsole( float frac ) {
// draw the background
y = frac * SCREEN_HEIGHT - 2;
renderSystem->SetColor( colorWhite );
if ( y < 1.0f ) {
y = 0.0f;
} else {
renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, y, 0, 1.0f - displayFrac, 1, 1, consoleShader );
}
renderSystem->SetColor( colorCyan );
renderSystem->SetColor( CONSOLE_COLOR_ORANGE );
renderSystem->DrawStretchPic( 0, y, SCREEN_WIDTH, 2, 0, 0, 0, 0, whiteShader );
renderSystem->SetColor( colorWhite );
// draw the version number
renderSystem->SetColor( idStr::ColorForIndex( C_COLOR_CYAN ) );
idStr version = va("%s.%i", ENGINE_VERSION, BUILD_NUMBER);
i = version.Length();
for ( x = 0; x < i; x++ ) {
renderSystem->DrawSmallChar( SCREEN_WIDTH - ( i - x ) * SMALLCHAR_WIDTH,
(lines-(SMALLCHAR_HEIGHT+SMALLCHAR_HEIGHT/2)), version[x], localConsole.charSetShader );
y = lines - ( SMALLCHAR_HEIGHT * 2 ) - 6;
if ( y < SMALLCHAR_HEIGHT ) {
y = SMALLCHAR_HEIGHT;
}
idStr compileVersion = COMPILE_VERSION;
compileVersion.StripLeading( ' ' );
SCR_DrawSmallStringRightAlign( y, CONSOLE_COLOR_ERROR, GAME_NAME );
SCR_DrawSmallStringRightAlign( y + SMALLCHAR_HEIGHT, CONSOLE_COLOR_ERROR, va( "Date: %s", compileVersion.c_str() ) );
// draw the text
vislines = lines;
@@ -1148,9 +1234,9 @@ void idConsoleLocal::DrawSolidConsole( float frac ) {
// draw from the bottom up
if ( display != current ) {
// draw arrows to show the buffer is backscrolled
renderSystem->SetColor( idStr::ColorForIndex( C_COLOR_CYAN ) );
renderSystem->SetColor( CONSOLE_COLOR_ORANGE );
for ( x = 0; x < LINE_WIDTH; x += 4 ) {
renderSystem->DrawSmallChar( (x+1)*SMALLCHAR_WIDTH, idMath::FtoiFast( y ), '^', localConsole.charSetShader );
renderSystem->DrawSmallChar( (x+1)*SMALLCHAR_WIDTH, idMath::FtoiFast( y ), '^', NULL );
}
y -= SMALLCHAR_HEIGHT;
rows--;
@@ -1162,9 +1248,6 @@ void idConsoleLocal::DrawSolidConsole( float frac ) {
row--;
}
currentColor = idStr::ColorIndex( C_COLOR_WHITE );
renderSystem->SetColor( idStr::ColorForIndex( currentColor ) );
for ( i = 0; i < rows; i++, y -= SMALLCHAR_HEIGHT, row-- ) {
if ( row < 0 ) {
break;
@@ -1175,24 +1258,13 @@ void idConsoleLocal::DrawSolidConsole( float frac ) {
}
text_p = text + (row % TOTAL_LINES)*LINE_WIDTH;
for ( x = 0; x < LINE_WIDTH; x++ ) {
if ( ( text_p[x] & 0xff ) == ' ' ) {
continue;
}
if ( idStr::ColorIndex(text_p[x]>>8) != currentColor ) {
currentColor = idStr::ColorIndex(text_p[x]>>8);
renderSystem->SetColor( idStr::ColorForIndex( currentColor ) );
}
renderSystem->DrawSmallChar( (x+1)*SMALLCHAR_WIDTH, idMath::FtoiFast( y ), text_p[x] & 0xff, localConsole.charSetShader );
}
SCR_DrawConsoleTextLine( text_p, idMath::FtoiFast( y ) );
}
// draw the input prompt, user text, and cursor if desired
DrawInput();
renderSystem->SetColor( colorCyan );
renderSystem->SetColor( CONSOLE_COLOR_TEXT );
}
@@ -1206,7 +1278,7 @@ ForceFullScreen is used by the editor
void idConsoleLocal::Draw( bool forceFullScreen ) {
float y = 0.0f;
if ( !charSetShader ) {
if ( !whiteShader || !consoleShader ) {
return;
}