diff --git a/base/maps/game/mars_city1/textures/objective1.tga b/base/maps/game/mars_city1/textures/objective1.tga
index cc177961..87280f32 100644
Binary files a/base/maps/game/mars_city1/textures/objective1.tga and b/base/maps/game/mars_city1/textures/objective1.tga differ
diff --git a/base/maps/game/mars_city1/textures/objective2.tga b/base/maps/game/mars_city1/textures/objective2.tga
index fd9d7504..edbb61be 100644
Binary files a/base/maps/game/mars_city1/textures/objective2.tga and b/base/maps/game/mars_city1/textures/objective2.tga differ
diff --git a/base/maps/game/mars_city2/textures/objective1.tga b/base/maps/game/mars_city2/textures/objective1.tga
index 22f3ee12..f37d6e40 100644
Binary files a/base/maps/game/mars_city2/textures/objective1.tga and b/base/maps/game/mars_city2/textures/objective1.tga differ
diff --git a/base/maps/game/mars_city2/textures/objective2.tga b/base/maps/game/mars_city2/textures/objective2.tga
index 74d62ae7..2730baa0 100644
Binary files a/base/maps/game/mars_city2/textures/objective2.tga and b/base/maps/game/mars_city2/textures/objective2.tga differ
diff --git a/base/maps/game/mars_city2/textures/objective3.tga b/base/maps/game/mars_city2/textures/objective3.tga
index 097ba507..72dcebe5 100644
Binary files a/base/maps/game/mars_city2/textures/objective3.tga and b/base/maps/game/mars_city2/textures/objective3.tga differ
diff --git a/base/newfonts/Gothic821_Cn_BT/48.dat b/base/newfonts/Gothic821_Cn_BT/48.dat
new file mode 100644
index 00000000..918028ec
Binary files /dev/null and b/base/newfonts/Gothic821_Cn_BT/48.dat differ
diff --git a/base/newfonts/Gothic821_Cn_BT/48.tga b/base/newfonts/Gothic821_Cn_BT/48.tga
new file mode 100644
index 00000000..b960687c
Binary files /dev/null and b/base/newfonts/Gothic821_Cn_BT/48.tga differ
diff --git a/base/newfonts/TT0807M_.TTF b/base/newfonts/TT0807M_.TTF
new file mode 100644
index 00000000..68444764
Binary files /dev/null and b/base/newfonts/TT0807M_.TTF differ
diff --git a/base/newfonts/editor/48.dat b/base/newfonts/editor/48.dat
new file mode 100644
index 00000000..25cdc445
Binary files /dev/null and b/base/newfonts/editor/48.dat differ
diff --git a/base/newfonts/editor/48.tga b/base/newfonts/editor/48.tga
new file mode 100644
index 00000000..c0f7020f
Binary files /dev/null and b/base/newfonts/editor/48.tga differ
diff --git a/base/newfonts/english.ttf b/base/newfonts/english.ttf
new file mode 100644
index 00000000..8d3342e0
Binary files /dev/null and b/base/newfonts/english.ttf differ
diff --git a/base/newfonts/idFont.exe b/base/newfonts/idFont.exe
new file mode 100644
index 00000000..9286ad51
Binary files /dev/null and b/base/newfonts/idFont.exe differ
diff --git a/neo/doom3/game/gamesys/TypeInfoGen.h b/neo/doom3/game/gamesys/TypeInfoGen.h
index 26498f7f..0ffe4060 100644
--- a/neo/doom3/game/gamesys/TypeInfoGen.h
+++ b/neo/doom3/game/gamesys/TypeInfoGen.h
@@ -7,9 +7,9 @@
This file has been generated with the Type Info Generator v1.1 (c) 2004 id Software
- 1204 constants
+ 1199 constants
135 enums
- 622 classes/structs/unions
+ 624 classes/structs/unions
38 templates
7 max inheritance level for 'idAI_Vagary'
@@ -569,11 +569,6 @@ static constantInfo_t constantInfo[] = {
{ "int", "DXR_MATERIAL_PREVIEW", "3" },
{ "int", "DXR_WIDGET_0", "4" },
{ "int", "DXR_WORLD_NUM", "5" },
- { "const int", "GLYPH_START", "0" },
- { "const int", "GLYPH_END", "255" },
- { "const int", "GLYPH_CHARSTART", "32" },
- { "const int", "GLYPH_CHAREND", "127" },
- { "const int", "GLYPHS_PER_FONT", "255-0+1" },
{ "const int", "SMALLCHAR_WIDTH", "8" },
{ "const int", "SMALLCHAR_HEIGHT", "16" },
{ "const int", "BIGCHAR_WIDTH", "16" },
@@ -4499,43 +4494,55 @@ static classVariableInfo_t glconfig_t_typeInfo[] = {
{ NULL, 0 }
};
-static classVariableInfo_t glyphInfo_t_typeInfo[] = {
- { "int", "height", (intptr_t)(&((glyphInfo_t *)0)->height), sizeof( ((glyphInfo_t *)0)->height ) },
- { "int", "top", (intptr_t)(&((glyphInfo_t *)0)->top), sizeof( ((glyphInfo_t *)0)->top ) },
- { "int", "bottom", (intptr_t)(&((glyphInfo_t *)0)->bottom), sizeof( ((glyphInfo_t *)0)->bottom ) },
- { "int", "pitch", (intptr_t)(&((glyphInfo_t *)0)->pitch), sizeof( ((glyphInfo_t *)0)->pitch ) },
- { "int", "xSkip", (intptr_t)(&((glyphInfo_t *)0)->xSkip), sizeof( ((glyphInfo_t *)0)->xSkip ) },
- { "int", "imageWidth", (intptr_t)(&((glyphInfo_t *)0)->imageWidth), sizeof( ((glyphInfo_t *)0)->imageWidth ) },
- { "int", "imageHeight", (intptr_t)(&((glyphInfo_t *)0)->imageHeight), sizeof( ((glyphInfo_t *)0)->imageHeight ) },
- { "float", "s", (intptr_t)(&((glyphInfo_t *)0)->s), sizeof( ((glyphInfo_t *)0)->s ) },
- { "float", "t", (intptr_t)(&((glyphInfo_t *)0)->t), sizeof( ((glyphInfo_t *)0)->t ) },
- { "float", "s2", (intptr_t)(&((glyphInfo_t *)0)->s2), sizeof( ((glyphInfo_t *)0)->s2 ) },
- { "float", "t2", (intptr_t)(&((glyphInfo_t *)0)->t2), sizeof( ((glyphInfo_t *)0)->t2 ) },
- { "const idMaterial *", "glyph", (intptr_t)(&((glyphInfo_t *)0)->glyph), sizeof( ((glyphInfo_t *)0)->glyph ) },
- { "char[32]", "shaderName", (intptr_t)(&((glyphInfo_t *)0)->shaderName), sizeof( ((glyphInfo_t *)0)->shaderName ) },
+static classVariableInfo_t scaledGlyphInfo_t_typeInfo[] = {
+ { "float", "top", (intptr_t)(&((scaledGlyphInfo_t *)0)->top), sizeof( ((scaledGlyphInfo_t *)0)->top ) },
+ { "float", "left", (intptr_t)(&((scaledGlyphInfo_t *)0)->left), sizeof( ((scaledGlyphInfo_t *)0)->left ) },
+ { "float", "width", (intptr_t)(&((scaledGlyphInfo_t *)0)->width), sizeof( ((scaledGlyphInfo_t *)0)->width ) },
+ { "float", "height", (intptr_t)(&((scaledGlyphInfo_t *)0)->height), sizeof( ((scaledGlyphInfo_t *)0)->height ) },
+ { "float", "xSkip", (intptr_t)(&((scaledGlyphInfo_t *)0)->xSkip), sizeof( ((scaledGlyphInfo_t *)0)->xSkip ) },
+ { "float", "s1", (intptr_t)(&((scaledGlyphInfo_t *)0)->s1), sizeof( ((scaledGlyphInfo_t *)0)->s1 ) },
+ { "float", "t1", (intptr_t)(&((scaledGlyphInfo_t *)0)->t1), sizeof( ((scaledGlyphInfo_t *)0)->t1 ) },
+ { "float", "s2", (intptr_t)(&((scaledGlyphInfo_t *)0)->s2), sizeof( ((scaledGlyphInfo_t *)0)->s2 ) },
+ { "float", "t2", (intptr_t)(&((scaledGlyphInfo_t *)0)->t2), sizeof( ((scaledGlyphInfo_t *)0)->t2 ) },
+ { "const idMaterial *", "material", (intptr_t)(&((scaledGlyphInfo_t *)0)->material), sizeof( ((scaledGlyphInfo_t *)0)->material ) },
{ NULL, 0 }
};
-static classVariableInfo_t fontInfo_t_typeInfo[] = {
- { "glyphInfo_t[256]", "glyphs", (intptr_t)(&((fontInfo_t *)0)->glyphs), sizeof( ((fontInfo_t *)0)->glyphs ) },
- { "float", "glyphScale", (intptr_t)(&((fontInfo_t *)0)->glyphScale), sizeof( ((fontInfo_t *)0)->glyphScale ) },
- { "char[64]", "name", (intptr_t)(&((fontInfo_t *)0)->name), sizeof( ((fontInfo_t *)0)->name ) },
+static classVariableInfo_t idFont_glyphInfo_t_typeInfo[] = {
+ { "byte", "width", (intptr_t)(&((idFont::glyphInfo_t *)0)->width), sizeof( ((idFont::glyphInfo_t *)0)->width ) },
+ { "byte", "height", (intptr_t)(&((idFont::glyphInfo_t *)0)->height), sizeof( ((idFont::glyphInfo_t *)0)->height ) },
+ { "char", "top", (intptr_t)(&((idFont::glyphInfo_t *)0)->top), sizeof( ((idFont::glyphInfo_t *)0)->top ) },
+ { "char", "left", (intptr_t)(&((idFont::glyphInfo_t *)0)->left), sizeof( ((idFont::glyphInfo_t *)0)->left ) },
+ { "byte", "xSkip", (intptr_t)(&((idFont::glyphInfo_t *)0)->xSkip), sizeof( ((idFont::glyphInfo_t *)0)->xSkip ) },
+ { "uint16_t", "s", (intptr_t)(&((idFont::glyphInfo_t *)0)->s), sizeof( ((idFont::glyphInfo_t *)0)->s ) },
+ { "uint16_t", "t", (intptr_t)(&((idFont::glyphInfo_t *)0)->t), sizeof( ((idFont::glyphInfo_t *)0)->t ) },
{ NULL, 0 }
};
-static classVariableInfo_t fontInfoEx_t_typeInfo[] = {
- { "fontInfo_t", "fontInfoSmall", (intptr_t)(&((fontInfoEx_t *)0)->fontInfoSmall), sizeof( ((fontInfoEx_t *)0)->fontInfoSmall ) },
- { "fontInfo_t", "fontInfoMedium", (intptr_t)(&((fontInfoEx_t *)0)->fontInfoMedium), sizeof( ((fontInfoEx_t *)0)->fontInfoMedium ) },
- { "fontInfo_t", "fontInfoLarge", (intptr_t)(&((fontInfoEx_t *)0)->fontInfoLarge), sizeof( ((fontInfoEx_t *)0)->fontInfoLarge ) },
- { "int", "maxHeight", (intptr_t)(&((fontInfoEx_t *)0)->maxHeight), sizeof( ((fontInfoEx_t *)0)->maxHeight ) },
- { "int", "maxWidth", (intptr_t)(&((fontInfoEx_t *)0)->maxWidth), sizeof( ((fontInfoEx_t *)0)->maxWidth ) },
- { "int", "maxHeightSmall", (intptr_t)(&((fontInfoEx_t *)0)->maxHeightSmall), sizeof( ((fontInfoEx_t *)0)->maxHeightSmall ) },
- { "int", "maxWidthSmall", (intptr_t)(&((fontInfoEx_t *)0)->maxWidthSmall), sizeof( ((fontInfoEx_t *)0)->maxWidthSmall ) },
- { "int", "maxHeightMedium", (intptr_t)(&((fontInfoEx_t *)0)->maxHeightMedium), sizeof( ((fontInfoEx_t *)0)->maxHeightMedium ) },
- { "int", "maxWidthMedium", (intptr_t)(&((fontInfoEx_t *)0)->maxWidthMedium), sizeof( ((fontInfoEx_t *)0)->maxWidthMedium ) },
- { "int", "maxHeightLarge", (intptr_t)(&((fontInfoEx_t *)0)->maxHeightLarge), sizeof( ((fontInfoEx_t *)0)->maxHeightLarge ) },
- { "int", "maxWidthLarge", (intptr_t)(&((fontInfoEx_t *)0)->maxWidthLarge), sizeof( ((fontInfoEx_t *)0)->maxWidthLarge ) },
- { "char[64]", "name", (intptr_t)(&((fontInfoEx_t *)0)->name), sizeof( ((fontInfoEx_t *)0)->name ) },
+static classVariableInfo_t idFont_fontInfo_t_oldInfo_t_typeInfo[] = {
+ { "float", "maxWidth", (intptr_t)(&((idFont::fontInfo_t::oldInfo_t *)0)->maxWidth), sizeof( ((idFont::fontInfo_t::oldInfo_t *)0)->maxWidth ) },
+ { "float", "maxHeight", (intptr_t)(&((idFont::fontInfo_t::oldInfo_t *)0)->maxHeight), sizeof( ((idFont::fontInfo_t::oldInfo_t *)0)->maxHeight ) },
+ { NULL, 0 }
+};
+
+static classVariableInfo_t idFont_fontInfo_t_typeInfo[] = {
+ { "idFont::fontInfo_t::oldInfo_t[3]", "oldInfo", (intptr_t)(&((idFont::fontInfo_t *)0)->oldInfo), sizeof( ((idFont::fontInfo_t *)0)->oldInfo ) },
+ { "short", "ascender", (intptr_t)(&((idFont::fontInfo_t *)0)->ascender), sizeof( ((idFont::fontInfo_t *)0)->ascender ) },
+ { "short", "descender", (intptr_t)(&((idFont::fontInfo_t *)0)->descender), sizeof( ((idFont::fontInfo_t *)0)->descender ) },
+ { "short", "numGlyphs", (intptr_t)(&((idFont::fontInfo_t *)0)->numGlyphs), sizeof( ((idFont::fontInfo_t *)0)->numGlyphs ) },
+ { "glyphInfo_t *", "glyphData", (intptr_t)(&((idFont::fontInfo_t *)0)->glyphData), sizeof( ((idFont::fontInfo_t *)0)->glyphData ) },
+ { "uint32_t *", "charIndex", (intptr_t)(&((idFont::fontInfo_t *)0)->charIndex), sizeof( ((idFont::fontInfo_t *)0)->charIndex ) },
+ { "char[128]", "ascii", (intptr_t)(&((idFont::fontInfo_t *)0)->ascii), sizeof( ((idFont::fontInfo_t *)0)->ascii ) },
+ { "int", "materialWidth", (intptr_t)(&((idFont::fontInfo_t *)0)->materialWidth), sizeof( ((idFont::fontInfo_t *)0)->materialWidth ) },
+ { "int", "materialHeight", (intptr_t)(&((idFont::fontInfo_t *)0)->materialHeight), sizeof( ((idFont::fontInfo_t *)0)->materialHeight ) },
+ { "const idMaterial *", "material", (intptr_t)(&((idFont::fontInfo_t *)0)->material), sizeof( ((idFont::fontInfo_t *)0)->material ) },
+ { NULL, 0 }
+};
+
+static classVariableInfo_t idFont_typeInfo[] = {
+ { "idStr", "name", (intptr_t)(&((idFont *)0)->name), sizeof( ((idFont *)0)->name ) },
+ { "idFont *", "alias", (intptr_t)(&((idFont *)0)->alias), sizeof( ((idFont *)0)->alias ) },
+ { "fontInfo_t *", "fontInfo", (intptr_t)(&((idFont *)0)->fontInfo), sizeof( ((idFont *)0)->fontInfo ) },
{ NULL, 0 }
};
@@ -4677,8 +4684,7 @@ static classVariableInfo_t idDeviceContext_typeInfo[] = {
{ "const idMaterial *[2]", "cursorImages", (intptr_t)(&((idDeviceContext *)0)->cursorImages), sizeof( ((idDeviceContext *)0)->cursorImages ) },
{ "const idMaterial *[7]", "scrollBarImages", (intptr_t)(&((idDeviceContext *)0)->scrollBarImages), sizeof( ((idDeviceContext *)0)->scrollBarImages ) },
{ "const idMaterial *", "whiteImage", (intptr_t)(&((idDeviceContext *)0)->whiteImage), sizeof( ((idDeviceContext *)0)->whiteImage ) },
- { "fontInfoEx_t *", "activeFont", (intptr_t)(&((idDeviceContext *)0)->activeFont), sizeof( ((idDeviceContext *)0)->activeFont ) },
- { "fontInfo_t *", "useFont", (intptr_t)(&((idDeviceContext *)0)->useFont), sizeof( ((idDeviceContext *)0)->useFont ) },
+ { "idFont *", "activeFont", (intptr_t)(&((idDeviceContext *)0)->activeFont), sizeof( ((idDeviceContext *)0)->activeFont ) },
{ "idStr", "fontName", (intptr_t)(&((idDeviceContext *)0)->fontName), sizeof( ((idDeviceContext *)0)->fontName ) },
{ "float", "xScale", (intptr_t)(&((idDeviceContext *)0)->xScale), sizeof( ((idDeviceContext *)0)->xScale ) },
{ "float", "yScale", (intptr_t)(&((idDeviceContext *)0)->yScale), sizeof( ((idDeviceContext *)0)->yScale ) },
@@ -5312,11 +5318,11 @@ static classVariableInfo_t frameLookup_t_typeInfo[] = {
{ NULL, 0 }
};
-static classVariableInfo_t class_290_class_290_typeInfo[] = {
-// { "const idSoundShader *", "soundShader", (intptr_t)(&((class_290::class_290 *)0)->soundShader), sizeof( ((class_290::class_290 *)0)->soundShader ) },
-// { "const function_t *", "function", (intptr_t)(&((class_290::class_290 *)0)->function), sizeof( ((class_290::class_290 *)0)->function ) },
-// { "const idDeclSkin *", "skin", (intptr_t)(&((class_290::class_290 *)0)->skin), sizeof( ((class_290::class_290 *)0)->skin ) },
-// { "int", "index", (intptr_t)(&((class_290::class_290 *)0)->index), sizeof( ((class_290::class_290 *)0)->index ) },
+static classVariableInfo_t class_292_class_292_typeInfo[] = {
+// { "const idSoundShader *", "soundShader", (intptr_t)(&((class_292::class_292 *)0)->soundShader), sizeof( ((class_292::class_292 *)0)->soundShader ) },
+// { "const function_t *", "function", (intptr_t)(&((class_292::class_292 *)0)->function), sizeof( ((class_292::class_292 *)0)->function ) },
+// { "const idDeclSkin *", "skin", (intptr_t)(&((class_292::class_292 *)0)->skin), sizeof( ((class_292::class_292 *)0)->skin ) },
+// { "int", "index", (intptr_t)(&((class_292::class_292 *)0)->index), sizeof( ((class_292::class_292 *)0)->index ) },
{ NULL, 0 }
};
@@ -9264,9 +9270,11 @@ static classTypeInfo_t classTypeInfo[] = {
{ "idRenderModel", "", sizeof(idRenderModel), idRenderModel_typeInfo },
{ "idRenderModelManager", "", sizeof(idRenderModelManager), idRenderModelManager_typeInfo },
{ "glconfig_t", "", sizeof(glconfig_t), glconfig_t_typeInfo },
- { "glyphInfo_t", "", sizeof(glyphInfo_t), glyphInfo_t_typeInfo },
- { "fontInfo_t", "", sizeof(fontInfo_t), fontInfo_t_typeInfo },
- { "fontInfoEx_t", "", sizeof(fontInfoEx_t), fontInfoEx_t_typeInfo },
+ { "scaledGlyphInfo_t", "", sizeof(scaledGlyphInfo_t), scaledGlyphInfo_t_typeInfo },
+ { "idFont::glyphInfo_t", "", sizeof(idFont::glyphInfo_t), idFont_glyphInfo_t_typeInfo },
+ { "idFont::fontInfo_t::oldInfo_t", "", sizeof(idFont::fontInfo_t::oldInfo_t), idFont_fontInfo_t_oldInfo_t_typeInfo },
+ { "idFont::fontInfo_t", "", sizeof(idFont::fontInfo_t), idFont_fontInfo_t_typeInfo },
+ { "idFont", "", sizeof(idFont), idFont_typeInfo },
{ "idRenderSystem", "", sizeof(idRenderSystem), idRenderSystem_typeInfo },
{ "renderGlobalFog_t", "", sizeof(renderGlobalFog_t), renderGlobalFog_t_typeInfo },
{ "renderEntity_t", "", sizeof(renderEntity_t), renderEntity_t_typeInfo },
@@ -9351,7 +9359,7 @@ static classTypeInfo_t classTypeInfo[] = {
{ "jointAnimInfo_t", "", sizeof(jointAnimInfo_t), jointAnimInfo_t_typeInfo },
{ "jointMod_t", "", sizeof(jointMod_t), jointMod_t_typeInfo },
{ "frameLookup_t", "", sizeof(frameLookup_t), frameLookup_t_typeInfo },
-// { "class_290::class_290", "", sizeof(class_290::class_290), class_290_class_290_typeInfo },
+// { "class_292::class_292", "", sizeof(class_292::class_292), class_292_class_292_typeInfo },
{ "frameCommand_t", "", sizeof(frameCommand_t), frameCommand_t_typeInfo },
{ "animFlags_t", "", sizeof(animFlags_t), animFlags_t_typeInfo },
{ "idModelExport", "", sizeof(idModelExport), idModelExport_typeInfo },
diff --git a/neo/engine/doomdll.vcxproj b/neo/engine/doomdll.vcxproj
index 05466f4c..1bc8d9e5 100644
--- a/neo/engine/doomdll.vcxproj
+++ b/neo/engine/doomdll.vcxproj
@@ -358,6 +358,7 @@
+
@@ -389,6 +390,7 @@
+
@@ -1550,6 +1552,7 @@
+
@@ -1620,9 +1623,9 @@
+
-
diff --git a/neo/engine/doomdll.vcxproj.filters b/neo/engine/doomdll.vcxproj.filters
index 1d1be098..4a1a7f8f 100644
--- a/neo/engine/doomdll.vcxproj.filters
+++ b/neo/engine/doomdll.vcxproj.filters
@@ -156,6 +156,9 @@
Framework
+
+ Framework
+
Framework
@@ -576,6 +579,9 @@
Renderer
+
+ Renderer
+
Tools\Radiant
@@ -677,6 +683,9 @@
Framework
+
+ Framework
+
Framework
@@ -809,7 +818,7 @@
Renderer
-
+
Renderer
diff --git a/neo/engine/framework/Console.cpp b/neo/engine/framework/Console.cpp
index af32da6e..1656524a 100644
--- a/neo/engine/framework/Console.cpp
+++ b/neo/engine/framework/Console.cpp
@@ -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;
}
diff --git a/neo/engine/framework/EditField.cpp b/neo/engine/framework/EditField.cpp
index 4f69919c..6485ffda 100644
--- a/neo/engine/framework/EditField.cpp
+++ b/neo/engine/framework/EditField.cpp
@@ -523,6 +523,42 @@ void idEditField::SetBuffer( const char *buf ) {
SetCursor( strlen( buffer ) );
}
+static int EditFieldSmallStringWidth( const char *text, int length ) {
+ if ( text == NULL || length <= 0 ) {
+ return 0;
+ }
+
+ idFont *font = renderSystem->RegisterFont( "editor" );
+ if ( font == NULL ) {
+ return length * SMALLCHAR_WIDTH;
+ }
+
+ int width = 0;
+ for ( int i = 0; text[i] != '\0' && i < length; i++ ) {
+ if ( idStr::IsColor( text + i ) ) {
+ i++;
+ continue;
+ }
+ float advance = font->GetGlyphWidth( 0.255f, (const unsigned char)text[i] );
+ if ( advance <= 0.0f ) {
+ advance = SMALLCHAR_WIDTH;
+ }
+ width += idMath::FtoiFast( advance + 0.75f );
+ }
+ return width;
+}
+
+static int EditFieldSmallCharLeft( int ch ) {
+ idFont *font = renderSystem->RegisterFont( "editor" );
+ if ( font == NULL ) {
+ return 0;
+ }
+
+ scaledGlyphInfo_t glyphInfo;
+ font->GetScaledGlyph( 0.255f, ch & 255, glyphInfo );
+ return idMath::FtoiFast( glyphInfo.left );
+}
+
/*
===============
idEditField::Draw
@@ -534,9 +570,6 @@ void idEditField::Draw( int x, int y, int width, bool showCursor, const idMateri
int prestep;
int cursorChar;
char str[MAX_EDIT_LINE];
- int size;
-
- size = SMALLCHAR_WIDTH;
drawLen = widthInChars;
len = strlen( buffer ) + 1;
@@ -587,9 +620,9 @@ void idEditField::Draw( int x, int y, int width, bool showCursor, const idMateri
}
if ( idKeyInput::GetOverstrikeMode() ) {
- cursorChar = 11;
+ cursorChar = '_';
} else {
- cursorChar = 10;
+ cursorChar = '|';
}
// Move the cursor back to account for color codes
@@ -600,5 +633,5 @@ void idEditField::Draw( int x, int y, int width, bool showCursor, const idMateri
}
}
- renderSystem->DrawSmallChar( x + ( cursor - prestep ) * size, y, cursorChar, shader );
+ renderSystem->DrawSmallChar( x + EditFieldSmallStringWidth( str, cursor - prestep ) - EditFieldSmallCharLeft( cursorChar ), y, cursorChar, shader );
}
diff --git a/neo/engine/framework/Licensee.h b/neo/engine/framework/Licensee.h
index bc8da52c..5931344f 100644
--- a/neo/engine/framework/Licensee.h
+++ b/neo/engine/framework/Licensee.h
@@ -43,6 +43,7 @@ If you have questions concerning this license or the applicable additional terms
#endif
#define ENGINE_VERSION GAME_NAME " " __DATE__ " " __TIME__ // printed in console
+#define COMPILE_VERSION " " __DATE__ " " __TIME__
// paths
#define CD_BASEDIR "Doom"
diff --git a/neo/engine/renderer/DeviceContext.cpp b/neo/engine/renderer/DeviceContext.cpp
index 33641cb5..c2954982 100644
--- a/neo/engine/renderer/DeviceContext.cpp
+++ b/neo/engine/renderer/DeviceContext.cpp
@@ -45,31 +45,55 @@ idVec4 idDeviceContext::colorNone;
idCVar gui_smallFontLimit( "gui_smallFontLimit", "0.30", CVAR_GUI | CVAR_ARCHIVE, "" );
idCVar gui_mediumFontLimit( "gui_mediumFontLimit", "0.60", CVAR_GUI | CVAR_ARCHIVE, "" );
+static uint32_t DC_ReadUTF8Char( const char *text, int &index ) {
+ const unsigned char *s = (const unsigned char *)text + index;
+ uint32_t c = s[0];
-idList idDeviceContext::fonts;
+ if ( c < 0x80 || s[1] == '\0' ) {
+ index++;
+ return c;
+ }
+ if ( ( c & 0xE0 ) == 0xC0 ) {
+ index += 2;
+ return ( ( c & 0x1F ) << 6 ) | ( s[1] & 0x3F );
+ }
+ if ( ( c & 0xF0 ) == 0xE0 && s[2] != '\0' ) {
+ index += 3;
+ return ( ( c & 0x0F ) << 12 ) | ( ( s[1] & 0x3F ) << 6 ) | ( s[2] & 0x3F );
+ }
+ if ( ( c & 0xF8 ) == 0xF0 && s[2] != '\0' && s[3] != '\0' ) {
+ index += 4;
+ return ( ( c & 0x07 ) << 18 ) | ( ( s[1] & 0x3F ) << 12 ) | ( ( s[2] & 0x3F ) << 6 ) | ( s[3] & 0x3F );
+ }
+
+ index++;
+ return c;
+}
+
+
+idList idDeviceContext::fonts;
int idDeviceContext::FindFont( const char *name ) {
int c = fonts.Num();
for (int i = 0; i < c; i++) {
- if (idStr::Icmp(name, fonts[i].name) == 0) {
+ if (idStr::Icmp(name, fonts[i]->GetName()) == 0) {
return i;
}
}
- // If the font was not found, try to register it
- idStr fileName = name;
- fileName.Replace("fonts", va("fonts/%s", fontLang.c_str()) );
+ idFont *font = renderSystem->RegisterFont( name );
+ if (font != NULL) {
+ for (int i = 0; i < fonts.Num(); i++) {
+ if (fonts[i] == font) {
+ return i;
+ }
+ }
+ return fonts.Append( font );
+ }
- fontInfoEx_t fontInfo;
- int index = fonts.Append( fontInfo );
- if ( renderSystem->RegisterFont( fileName, fonts[index] ) ){
- idStr::Copynz( fonts[index].name, name, sizeof( fonts[index].name ) );
- return index;
- } else {
- common->Printf( "Could not register font %s [%s]\n", name, fileName.c_str() );
+ common->Printf( "Could not register font %s\n", name );
return -1;
}
-}
void idDeviceContext::SetupFonts() {
fonts.SetGranularity( 1 );
@@ -87,9 +111,9 @@ void idDeviceContext::SetupFonts() {
void idDeviceContext::SetFont( int num ) {
if ( num >= 0 && num < fonts.Num() ) {
- activeFont = &fonts[num];
+ activeFont = fonts[num];
} else {
- activeFont = &fonts[0];
+ activeFont = fonts[0];
}
}
@@ -101,7 +125,7 @@ void idDeviceContext::Init() {
whiteImage->SetSort( SS_GUI );
mbcs = false;
SetupFonts();
- activeFont = &fonts[0];
+ activeFont = fonts[0];
colorPurple = idVec4(1, 0, 1, 1);
colorOrange = idVec4(1, 1, 0, 1);
colorYellow = idVec4(0, 1, 1, 1);
@@ -146,7 +170,6 @@ void idDeviceContext::Shutdown() {
void idDeviceContext::Clear() {
initialized = false;
- useFont = NULL;
activeFont = NULL;
mbcs = false;
}
@@ -645,97 +668,81 @@ void idDeviceContext::DrawCursor(float *x, float *y, float size) {
=======================================================================================================================
*/
-void idDeviceContext::PaintChar(float x,float y,float width,float height,float scale,float s,float t,float s2,float t2,const idMaterial *hShader) {
- float w, h;
- w = width * scale;
- h = height * scale;
+void idDeviceContext::PaintChar(float x, float y, const scaledGlyphInfo_t &glyphInfo) {
+ y -= glyphInfo.top;
+ x += glyphInfo.left;
+
+ float w = glyphInfo.width;
+ float h = glyphInfo.height;
+ float s = glyphInfo.s1;
+ float t = glyphInfo.t1;
+ float s2 = glyphInfo.s2;
+ float t2 = glyphInfo.t2;
+ const idMaterial *hShader = glyphInfo.material;
if (ClippedCoords(&x, &y, &w, &h, &s, &t, &s2, &t2)) {
return;
}
- AdjustCoords(&x, &y, &w, &h);
DrawStretchPic(x, y, w, h, s, t, s2, t2, hShader);
}
-
-void idDeviceContext::SetFontByScale(float scale) {
- if (scale <= gui_smallFontLimit.GetFloat()) {
- useFont = &activeFont->fontInfoSmall;
- activeFont->maxHeight = activeFont->maxHeightSmall;
- activeFont->maxWidth = activeFont->maxWidthSmall;
- } else if (scale <= gui_mediumFontLimit.GetFloat()) {
- useFont = &activeFont->fontInfoMedium;
- activeFont->maxHeight = activeFont->maxHeightMedium;
- activeFont->maxWidth = activeFont->maxWidthMedium;
- } else {
- useFont = &activeFont->fontInfoLarge;
- activeFont->maxHeight = activeFont->maxHeightLarge;
- activeFont->maxWidth = activeFont->maxWidthLarge;
- }
-}
-
int idDeviceContext::DrawText(float x, float y, float scale, idVec4 color, const char *text, float adjust, int limit, int style, int cursor) {
- int len, count;
- idVec4 newColor;
- const glyphInfo_t *glyph;
- float useScale;
- SetFontByScale(scale);
- useScale = scale * useFont->glyphScale;
- count = 0;
- if ( text && color.w != 0.0f ) {
- const unsigned char *s = (const unsigned char*)text;
+ idVec4 newColor;
+
+ idStr drawText = text ? text : "";
+ int charIndex = 0;
+ int count = 0;
+
+ if ( text && color.w != 0.0f && activeFont != NULL ) {
renderSystem->SetColor(color);
memcpy(&newColor[0], &color[0], sizeof(idVec4));
- len = strlen(text);
+ int len = drawText.Length();
if (limit > 0 && len > limit) {
len = limit;
}
- while (s && *s && count < len) {
- if ( *s < GLYPH_START || *s > GLYPH_END ) {
- s++;
- continue;
- }
- glyph = &useFont->glyphs[*s];
+ float prevGlyphSkip = 0.0f;
- //
- // int yadj = Assets.textFont.glyphs[text[i]].bottom +
- // Assets.textFont.glyphs[text[i]].top; float yadj = scale *
- // (Assets.textFont.glyphs[text[i]].imageHeight -
- // Assets.textFont.glyphs[text[i]].height);
- //
- if ( idStr::IsColor((const char*)s) ) {
- if ( *(s+1) == C_COLOR_DEFAULT ) {
+ while ( charIndex < len ) {
+ if ( idStr::IsColor( drawText.c_str() + charIndex ) ) {
+ if ( drawText[ charIndex + 1 ] == C_COLOR_DEFAULT ) {
newColor = color;
} else {
- newColor = idStr::ColorForIndex( *(s+1) );
+ newColor = idStr::ColorForIndex( drawText[ charIndex + 1 ] );
newColor[3] = color[3];
}
- if (cursor == count || cursor == count+1) {
- float partialSkip = ((glyph->xSkip * useScale) + adjust) / 5.0f;
- if ( cursor == count ) {
- partialSkip *= 2.0f;
+ if (cursor == charIndex || cursor == charIndex + 1) {
+ float backup = 0.0f;
+ if ( prevGlyphSkip > 0.0f ) {
+ backup = ( prevGlyphSkip + adjust) / 5.0f;
+ }
+ if ( cursor == charIndex ) {
+ backup *= 2.0f;
} else {
renderSystem->SetColor(newColor);
}
- DrawEditCursor(x - partialSkip, y, scale);
+ DrawEditCursor(x - backup, y, scale);
}
renderSystem->SetColor(newColor);
- s += 2;
+ charIndex += 2;
count += 2;
continue;
- } else {
- float yadj = useScale * glyph->top;
- PaintChar(x,y - yadj,glyph->imageWidth,glyph->imageHeight,useScale,glyph->s,glyph->t,glyph->s2,glyph->t2,glyph->glyph);
-
- if (cursor == count) {
- DrawEditCursor(x, y, scale);
- }
- x += (glyph->xSkip * useScale) + adjust;
- s++;
- count++;
}
+
+ int glyphStart = charIndex;
+ uint32_t textChar = DC_ReadUTF8Char( drawText.c_str(), charIndex );
+ scaledGlyphInfo_t glyphInfo;
+ activeFont->GetScaledGlyph( scale, textChar, glyphInfo );
+ prevGlyphSkip = glyphInfo.xSkip;
+
+ PaintChar( x, y, glyphInfo );
+
+ if (cursor == glyphStart) {
+ DrawEditCursor(x, y, scale);
+ }
+ x += glyphInfo.xSkip + adjust;
+ count += charIndex - glyphStart;
}
if (cursor == len) {
DrawEditCursor(x, y, scale);
@@ -755,32 +762,22 @@ void idDeviceContext::SetSize(float width, float height) {
}
int idDeviceContext::CharWidth( const char c, float scale ) {
- glyphInfo_t *glyph;
- float useScale;
- SetFontByScale(scale);
- fontInfo_t *font = useFont;
- useScale = scale * font->glyphScale;
- glyph = &font->glyphs[(const unsigned char)c];
- return idMath::FtoiFast( glyph->xSkip * useScale );
+ return activeFont == NULL ? 0 : idMath::Ftoi( activeFont->GetGlyphWidth( scale, (const unsigned char)c ) );
}
int idDeviceContext::TextWidth( const char *text, float scale, int limit ) {
- int i, width;
-
- SetFontByScale( scale );
- const glyphInfo_t *glyphs = useFont->glyphs;
-
- if ( text == NULL ) {
+ if ( text == NULL || activeFont == NULL ) {
return 0;
}
- width = 0;
+ int i;
+ float width = 0.0f;
if ( limit > 0 ) {
for ( i = 0; text[i] != '\0' && i < limit; i++ ) {
if ( idStr::IsColor( text + i ) ) {
i++;
} else {
- width += glyphs[((const unsigned char *)text)[i]].xSkip;
+ width += activeFont->GetGlyphWidth( scale, ((const unsigned char *)text)[i] );
}
}
} else {
@@ -788,61 +785,23 @@ int idDeviceContext::TextWidth( const char *text, float scale, int limit ) {
if ( idStr::IsColor( text + i ) ) {
i++;
} else {
- width += glyphs[((const unsigned char *)text)[i]].xSkip;
+ width += activeFont->GetGlyphWidth( scale, ((const unsigned char *)text)[i] );
}
}
}
- return idMath::FtoiFast( scale * useFont->glyphScale * width );
+ return idMath::Ftoi( width );
}
int idDeviceContext::TextHeight(const char *text, float scale, int limit) {
- int len, count;
- float max;
- glyphInfo_t *glyph;
- float useScale;
- const char *s = text;
- SetFontByScale(scale);
- fontInfo_t *font = useFont;
-
- useScale = scale * font->glyphScale;
- max = 0;
- if (text) {
- len = strlen(text);
- if (limit > 0 && len > limit) {
- len = limit;
- }
-
- count = 0;
- while (s && *s && count < len) {
- if ( idStr::IsColor(s) ) {
- s += 2;
- continue;
- }
- else {
- glyph = &font->glyphs[*(const unsigned char*)s];
- if (max < glyph->height) {
- max = glyph->height;
- }
-
- s++;
- count++;
- }
- }
- }
-
- return idMath::FtoiFast( max * useScale );
+ return activeFont == NULL ? 0 : idMath::Ftoi( activeFont->GetLineHeight( scale ) );
}
int idDeviceContext::MaxCharWidth(float scale) {
- SetFontByScale(scale);
- float useScale = scale * useFont->glyphScale;
- return idMath::FtoiFast( activeFont->maxWidth * useScale );
+ return activeFont == NULL ? 0 : idMath::Ftoi( activeFont->GetMaxCharWidth( scale ) );
}
int idDeviceContext::MaxCharHeight(float scale) {
- SetFontByScale(scale);
- float useScale = scale * useFont->glyphScale;
- return idMath::FtoiFast( activeFont->maxHeight * useScale );
+ return activeFont == NULL ? 0 : idMath::Ftoi( activeFont->GetLineHeight( scale ) );
}
const idMaterial *idDeviceContext::GetScrollBarImage(int index) {
@@ -927,11 +886,13 @@ void idDeviceContext::DrawEditCursor( float x, float y, float scale ) {
if ( (int)( com_ticNumber >> 4 ) & 1 ) {
return;
}
- SetFontByScale(scale);
- float useScale = scale * useFont->glyphScale;
- const glyphInfo_t *glyph2 = &useFont->glyphs[(overStrikeMode) ? '_' : '|'];
- float yadj = useScale * glyph2->top;
- PaintChar(x, y - yadj,glyph2->imageWidth,glyph2->imageHeight,useScale,glyph2->s,glyph2->t,glyph2->s2,glyph2->t2,glyph2->glyph);
+ if ( activeFont == NULL ) {
+ return;
+ }
+ char cursorChar = (overStrikeMode) ? '_' : '|';
+ scaledGlyphInfo_t glyphInfo;
+ activeFont->GetScaledGlyph(scale, cursorChar, glyphInfo);
+ PaintChar(x, y, glyphInfo);
}
int idDeviceContext::DrawText( const char *text, float textScale, int textAlign, idVec4 color, idRectangle rectDraw, bool wrap, int cursor, bool calcOnly, idList *breaks, int limit ) {
@@ -948,8 +909,6 @@ int idDeviceContext::DrawText( const char *text, float textScale, int textAlign,
bool lineBreak, wordBreak;
- SetFontByScale( textScale );
-
textWidth = 0;
newLinePtr = NULL;
@@ -1071,7 +1030,7 @@ int idDeviceContext::DrawText( const char *text, float textScale, int textAlign,
buff[len] = '\0';
// update the width
if ( *( buff + len - 1 ) != C_COLOR_ESCAPE && (len <= 1 || *( buff + len - 2 ) != C_COLOR_ESCAPE)) {
- textWidth += textScale * useFont->glyphScale * useFont->glyphs[ (const unsigned char)*( buff + len - 1 ) ].xSkip;
+ textWidth += activeFont != NULL ? activeFont->GetGlyphWidth( textScale, (const unsigned char)*( buff + len - 1 ) ) : 0.0f;
}
}
diff --git a/neo/engine/renderer/DeviceContext.h b/neo/engine/renderer/DeviceContext.h
index ba1f0124..51cfc688 100644
--- a/neo/engine/renderer/DeviceContext.h
+++ b/neo/engine/renderer/DeviceContext.h
@@ -29,6 +29,8 @@ If you have questions concerning this license or the applicable additional terms
#ifndef __DEVICECONTEXT_H__
#define __DEVICECONTEXT_H__
+#include "Font.h"
+
// device context support for gui stuff
//
@@ -87,6 +89,7 @@ public:
void EnableClipping(bool b) { enableClipping = b; };
void SetFont( int num );
+ void SetFont( idFont *font ) { if ( font != NULL ) { activeFont = font; } }
void SetOverStrike(bool b) { overStrikeMode = b; }
@@ -129,15 +132,13 @@ public:
private:
int DrawText(float x, float y, float scale, idVec4 color, const char *text, float adjust, int limit, int style, int cursor = -1);
- void PaintChar(float x,float y,float width,float height,float scale,float s,float t,float s2,float t2,const idMaterial *hShader);
- void SetFontByScale( float scale );
+ void PaintChar(float x, float y, const scaledGlyphInfo_t &glyphInfo);
void Clear( void );
const idMaterial *cursorImages[CURSOR_COUNT];
const idMaterial *scrollBarImages[SCROLLBAR_COUNT];
const idMaterial *whiteImage;
- fontInfoEx_t *activeFont;
- fontInfo_t *useFont;
+ idFont *activeFont;
idStr fontName;
float xScale;
float yScale;
@@ -149,7 +150,7 @@ private:
idList clipRects;
- static idList fonts;
+ static idList fonts;
idStr fontLang;
bool enableClipping;
diff --git a/neo/engine/renderer/Image_init.cpp b/neo/engine/renderer/Image_init.cpp
index 57160d69..3dc0beb5 100644
--- a/neo/engine/renderer/Image_init.cpp
+++ b/neo/engine/renderer/Image_init.cpp
@@ -1494,6 +1494,12 @@ idImage *idImageManager::ImageFromFile( const char *_name, textureFilter_t filte
name.Replace( ".tga", "" );
name.BackSlashesToSlashes();
+ if ( idStr::Icmpn( name.c_str(), "fonts", 5 ) == 0 || idStr::Icmpn( name.c_str(), "newfonts", 8 ) == 0 ) {
+ filter = ( filter == TF_DEFAULT ) ? TF_LINEAR : filter;
+ allowDownSize = false;
+ depth = TD_HIGH_QUALITY;
+ }
+
//
// see if the image is already loaded, unless we
// are in a reloadImages call
@@ -1561,7 +1567,7 @@ idImage *idImageManager::ImageFromFile( const char *_name, textureFilter_t filte
//
image = AllocImage( name );
- // HACK: to allow keep fonts from being mip'd, as new ones will be introduced with localization
+ // HACK: to allow keep old fonts from being mip'd, as new ones will be introduced with localization
// this keeps us from having to make a material for each font tga
if ( name.Find( "fontImage_") >= 0 ) {
allowDownSize = false;
diff --git a/neo/engine/renderer/RenderSystem.cpp b/neo/engine/renderer/RenderSystem.cpp
index 3e290064..9396bc2b 100644
--- a/neo/engine/renderer/RenderSystem.cpp
+++ b/neo/engine/renderer/RenderSystem.cpp
@@ -388,11 +388,47 @@ idRenderSystemLocal::DrawSmallChar
small chars are drawn at native screen resolution
=====================
*/
-void idRenderSystemLocal::DrawSmallChar( int x, int y, int ch, const idMaterial *material ) {
- int row, col;
- float frow, fcol;
- float size;
+static const char *CONSOLE_FONT_NAME = "editor";
+static void R_DrawFontChar( idRenderSystemLocal *renderSystem, float x, float y, float scale, float baselineOffset, int ch ) {
+ idFont *font = renderSystem->RegisterFont( CONSOLE_FONT_NAME );
+ if ( font == NULL || ch == ' ' ) {
+ return;
+ }
+
+ scaledGlyphInfo_t glyphInfo;
+ font->GetScaledGlyph( scale, ch & 255, glyphInfo );
+ if ( glyphInfo.material == NULL ) {
+ return;
+ }
+
+ float baseline = y + baselineOffset;
+ renderSystem->DrawStretchPic( x + glyphInfo.left, baseline - glyphInfo.top,
+ glyphInfo.width, glyphInfo.height,
+ glyphInfo.s1, glyphInfo.t1, glyphInfo.s2, glyphInfo.t2,
+ glyphInfo.material );
+}
+
+static const float CONSOLE_SMALL_FONT_SCALE = 0.255f;
+static const float CONSOLE_SMALL_CHAR_PAD = 0.75f;
+static const float CONSOLE_BIG_FONT_SCALE = 0.33f;
+static const float CONSOLE_BIG_CHAR_PAD = 0.75f;
+
+static float R_FontGlyphAdvance( idRenderSystemLocal *renderSystem, float scale, int ch ) {
+ idFont *font = renderSystem->RegisterFont( CONSOLE_FONT_NAME );
+ if ( font == NULL ) {
+ return SMALLCHAR_WIDTH;
+ }
+
+ float advance = font->GetGlyphWidth( scale, ch & 255 );
+ if ( advance <= 0.0f ) {
+ advance = SMALLCHAR_WIDTH;
+ }
+ return advance;
+}
+
+void idRenderSystemLocal::DrawSmallChar( int x, int y, int ch, const idMaterial *material ) {
+ (void)material;
ch &= 255;
if ( ch == ' ' ) {
@@ -403,17 +439,7 @@ void idRenderSystemLocal::DrawSmallChar( int x, int y, int ch, const idMaterial
return;
}
- row = ch >> 4;
- col = ch & 15;
-
- frow = row * 0.0625f;
- fcol = col * 0.0625f;
- size = 0.0625f;
-
- DrawStretchPic( x, y, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT,
- fcol, frow,
- fcol + size, frow + size,
- material );
+ R_DrawFontChar( this, x, y, CONSOLE_SMALL_FONT_SCALE, SMALLCHAR_HEIGHT - 2.0f, ch );
}
/*
@@ -450,7 +476,7 @@ void idRenderSystemLocal::DrawSmallStringExt( int x, int y, const char *string,
continue;
}
DrawSmallChar( xx, y, *s, material );
- xx += SMALLCHAR_WIDTH;
+ xx += idMath::FtoiFast( R_FontGlyphAdvance( this, CONSOLE_SMALL_FONT_SCALE, *s ) + CONSOLE_SMALL_CHAR_PAD );
s++;
}
SetColor( colorWhite );
@@ -462,10 +488,7 @@ idRenderSystemLocal::DrawBigChar
=====================
*/
void idRenderSystemLocal::DrawBigChar( int x, int y, int ch, const idMaterial *material ) {
- int row, col;
- float frow, fcol;
- float size;
-
+ (void)material;
ch &= 255;
if ( ch == ' ' ) {
@@ -476,17 +499,7 @@ void idRenderSystemLocal::DrawBigChar( int x, int y, int ch, const idMaterial *m
return;
}
- row = ch >> 4;
- col = ch & 15;
-
- frow = row * 0.0625f;
- fcol = col * 0.0625f;
- size = 0.0625f;
-
- DrawStretchPic( x, y, BIGCHAR_WIDTH, BIGCHAR_HEIGHT,
- fcol, frow,
- fcol + size, frow + size,
- material );
+ R_DrawFontChar( this, x, y, CONSOLE_BIG_FONT_SCALE, BIGCHAR_HEIGHT - 1.0f, ch );
}
/*
@@ -523,7 +536,7 @@ void idRenderSystemLocal::DrawBigStringExt( int x, int y, const char *string, co
continue;
}
DrawBigChar( xx, y, *s, material );
- xx += BIGCHAR_WIDTH;
+ xx += idMath::FtoiFast( R_FontGlyphAdvance( this, CONSOLE_BIG_FONT_SCALE, *s ) + CONSOLE_BIG_CHAR_PAD );
s++;
}
SetColor( colorWhite );
diff --git a/neo/engine/renderer/RenderSystem.h b/neo/engine/renderer/RenderSystem.h
index 5e1e5e56..4f98e542 100644
--- a/neo/engine/renderer/RenderSystem.h
+++ b/neo/engine/renderer/RenderSystem.h
@@ -110,49 +110,7 @@ enum dxrWorldId_t {
DXR_WORLD_NUM
};
-// font support
-const int GLYPH_START = 0;
-const int GLYPH_END = 255;
-const int GLYPH_CHARSTART = 32;
-const int GLYPH_CHAREND = 127;
-const int GLYPHS_PER_FONT = GLYPH_END - GLYPH_START + 1;
-
-typedef struct {
- int height; // number of scan lines
- int top; // top of glyph in buffer
- int bottom; // bottom of glyph in buffer
- int pitch; // width for copying
- int xSkip; // x adjustment
- int imageWidth; // width of actual image
- int imageHeight; // height of actual image
- float s; // x offset in image where glyph starts
- float t; // y offset in image where glyph starts
- float s2;
- float t2;
- const idMaterial * glyph; // shader with the glyph
- char shaderName[32];
-} glyphInfo_t;
-
-typedef struct {
- glyphInfo_t glyphs [GLYPHS_PER_FONT];
- float glyphScale;
- char name[64];
-} fontInfo_t;
-
-typedef struct {
- fontInfo_t fontInfoSmall;
- fontInfo_t fontInfoMedium;
- fontInfo_t fontInfoLarge;
- int maxHeight;
- int maxWidth;
- int maxHeightSmall;
- int maxWidthSmall;
- int maxHeightMedium;
- int maxWidthMedium;
- int maxHeightLarge;
- int maxWidthLarge;
- char name[64];
-} fontInfoEx_t;
+#include "Font.h"
const int SMALLCHAR_WIDTH = 8;
const int SMALLCHAR_HEIGHT = 16;
@@ -204,7 +162,7 @@ public:
virtual void EndLevelLoad( void ) = 0;
// font support
- virtual bool RegisterFont( const char *fontName, fontInfoEx_t &font ) = 0;
+ virtual idFont * RegisterFont( const char *fontName ) = 0;
// GUI drawing just involves shader parameter setting and axial image subsections
virtual void SetColor( const idVec4 &rgba ) = 0;
diff --git a/neo/engine/renderer/RenderSystem_init.cpp b/neo/engine/renderer/RenderSystem_init.cpp
index 4645bcbd..92cde900 100644
--- a/neo/engine/renderer/RenderSystem_init.cpp
+++ b/neo/engine/renderer/RenderSystem_init.cpp
@@ -1984,8 +1984,6 @@ void idRenderSystemLocal::Shutdown( void ) {
R_MaskedOcclusionCulling_Shutdown();
- R_DoneFreeType( );
-
if ( glConfig.isInitialized ) {
globalImages->PurgeAllImages();
}
@@ -2015,6 +2013,7 @@ void idRenderSystemLocal::Shutdown( void ) {
delete guiModel;
delete demoGuiModel;
+ FreeFonts();
Clear();
diff --git a/neo/engine/renderer/tr_font.cpp b/neo/engine/renderer/tr_font.cpp
deleted file mode 100644
index c0508eaa..00000000
--- a/neo/engine/renderer/tr_font.cpp
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
-===========================================================================
-
-IceTech GPL Source Code
-Copyright (C) 2026 Justin Marshall
-
-This file is part of the IceTech GPL Source Code ("IceTech Source Code").
-
-IceTech Source Code is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-IceTech Source Code is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with IceTech Source Code. If not, see .
-
-In addition, the IceTech Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the IceTech Source Code. If not, please request a copy in writing from id Software at the address below.
-
-If you have questions concerning this license or the applicable additional terms, you may contact in writing Justin Marshall, justinmarshall20@gmail.com
-
-===========================================================================
-*/
-
-#include "precompiled.h"
-#include "tr_local.h"
-
-#define FILESIZE_fontInfo_t (20548)
-
-#ifdef BUILD_FREETYPE
-#include "../ft2/fterrors.h"
-#include "../ft2/ftsystem.h"
-#include "../ft2/ftimage.h"
-#include "../ft2/freetype.h"
-#include "../ft2/ftoutln.h"
-
-#define _FLOOR(x) ((x) & -64)
-#define _CEIL(x) (((x)+63) & -64)
-#define _TRUNC(x) ((x) >> 6)
-
-FT_Library ftLibrary = NULL;
-#endif
-
-
-#ifdef BUILD_FREETYPE
-
-/*
-============
-R_GetGlyphInfo
-============
-*/
-void R_GetGlyphInfo(FT_GlyphSlot glyph, int* left, int* right, int* width, int* top, int* bottom, int* height, int* pitch) {
-
- *left = _FLOOR(glyph->metrics.horiBearingX);
- *right = _CEIL(glyph->metrics.horiBearingX + glyph->metrics.width);
- *width = _TRUNC(*right - *left);
-
- *top = _CEIL(glyph->metrics.horiBearingY);
- *bottom = _FLOOR(glyph->metrics.horiBearingY - glyph->metrics.height);
- *height = _TRUNC(*top - *bottom);
- *pitch = (qtrue ? (*width + 3) & -4 : (*width + 7) >> 3);
-}
-
-/*
-============
-R_RenderGlyph
-============
-*/
-FT_Bitmap* R_RenderGlyph(FT_GlyphSlot glyph, glyphInfo_t* glyphOut) {
- FT_Bitmap* bit2;
- int left, right, width, top, bottom, height, pitch, size;
-
- R_GetGlyphInfo(glyph, &left, &right, &width, &top, &bottom, &height, &pitch);
-
- if (glyph->format == ft_glyph_format_outline) {
- size = pitch * height;
-
- bit2 = Mem_Alloc(sizeof(FT_Bitmap));
-
- bit2->width = width;
- bit2->rows = height;
- bit2->pitch = pitch;
- bit2->pixel_mode = ft_pixel_mode_grays;
- //bit2->pixel_mode = ft_pixel_mode_mono;
- bit2->buffer = Mem_Alloc(pitch * height);
- bit2->num_grays = 256;
-
- memset(bit2->buffer, 0, size);
-
- FT_Outline_Translate(&glyph->outline, -left, -bottom);
-
- FT_Outline_Get_Bitmap(ftLibrary, &glyph->outline, bit2);
-
- glyphOut->height = height;
- glyphOut->pitch = pitch;
- glyphOut->top = (glyph->metrics.horiBearingY >> 6) + 1;
- glyphOut->bottom = bottom;
-
- return bit2;
- }
- else {
- common->Printf("Non-outline fonts are not supported\n");
- }
- return NULL;
-}
-
-/*
-============
-RE_ConstructGlyphInfo
-============
-*/
-glyphInfo_t* RE_ConstructGlyphInfo(unsigned char* imageOut, int* xOut, int* yOut, int* maxHeight, FT_Face face, const unsigned char c, qboolean calcHeight) {
- int i;
- static glyphInfo_t glyph;
- unsigned char* src, * dst;
- float scaled_width, scaled_height;
- FT_Bitmap* bitmap = NULL;
-
- memset(&glyph, 0, sizeof(glyphInfo_t));
- // make sure everything is here
- if (face != NULL) {
- FT_Load_Glyph(face, FT_Get_Char_Index(face, c), FT_LOAD_DEFAULT);
- bitmap = R_RenderGlyph(face->glyph, &glyph);
- if (bitmap) {
- glyph.xSkip = (face->glyph->metrics.horiAdvance >> 6) + 1;
- }
- else {
- return &glyph;
- }
-
- if (glyph.height > *maxHeight) {
- *maxHeight = glyph.height;
- }
-
- if (calcHeight) {
- Mem_Free(bitmap->buffer);
- Mem_Free(bitmap);
- return &glyph;
- }
-
- /*
- // need to convert to power of 2 sizes so we do not get
- // any scaling from the gl upload
- for (scaled_width = 1 ; scaled_width < glyph.pitch ; scaled_width<<=1)
- ;
- for (scaled_height = 1 ; scaled_height < glyph.height ; scaled_height<<=1)
- ;
- */
-
- scaled_width = glyph.pitch;
- scaled_height = glyph.height;
-
- // we need to make sure we fit
- if (*xOut + scaled_width + 1 >= 255) {
- if (*yOut + *maxHeight + 1 >= 255) {
- *yOut = -1;
- *xOut = -1;
- Mem_Free(bitmap->buffer);
- Mem_Free(bitmap);
- return &glyph;
- }
- else {
- *xOut = 0;
- *yOut += *maxHeight + 1;
- }
- }
- else if (*yOut + *maxHeight + 1 >= 255) {
- *yOut = -1;
- *xOut = -1;
- Mem_Free(bitmap->buffer);
- Mem_Free(bitmap);
- return &glyph;
- }
-
- src = bitmap->buffer;
- dst = imageOut + (*yOut * 256) + *xOut;
-
- if (bitmap->pixel_mode == ft_pixel_mode_mono) {
- for (i = 0; i < glyph.height; i++) {
- int j;
- unsigned char* _src = src;
- unsigned char* _dst = dst;
- unsigned char mask = 0x80;
- unsigned char val = *_src;
- for (j = 0; j < glyph.pitch; j++) {
- if (mask == 0x80) {
- val = *_src++;
- }
- if (val & mask) {
- *_dst = 0xff;
- }
- mask >>= 1;
-
- if (mask == 0) {
- mask = 0x80;
- }
- _dst++;
- }
-
- src += glyph.pitch;
- dst += 256;
-
- }
- }
- else {
- for (i = 0; i < glyph.height; i++) {
- memcpy(dst, src, glyph.pitch);
- src += glyph.pitch;
- dst += 256;
- }
- }
-
- // we now have an 8 bit per pixel grey scale bitmap
- // that is width wide and pf->ftSize->metrics.y_ppem tall
-
- glyph.imageHeight = scaled_height;
- glyph.imageWidth = scaled_width;
- glyph.s = (float)*xOut / 256;
- glyph.t = (float)*yOut / 256;
- glyph.s2 = glyph.s + (float)scaled_width / 256;
- glyph.t2 = glyph.t + (float)scaled_height / 256;
-
- *xOut += scaled_width + 1;
- }
-
- Mem_Free(bitmap->buffer);
- Mem_Free(bitmap);
-
- return &glyph;
-}
-
-#endif
-
-static int fdOffset;
-static byte* fdFile;
-
-/*
-============
-readInt
-============
-*/
-int readInt(void) {
- int i = fdFile[fdOffset] + (fdFile[fdOffset + 1] << 8) + (fdFile[fdOffset + 2] << 16) + (fdFile[fdOffset + 3] << 24);
- fdOffset += 4;
- return i;
-}
-
-/*
-============
-readFloat
-============
-*/
-float readFloat(void) {
- float f;
- memcpy(&f, &fdFile[fdOffset], sizeof(float));
- fdOffset += sizeof(float);
- return LittleFloat(f);
-}
-
-/*
-============
-RegisterFont
-
-Loads 3 point sizes, 12, 24, and 48
-============
-*/
-
-bool idRenderSystemLocal::RegisterFont(const char* fontName, fontInfoEx_t& font) {
-#ifdef QUAKE4
-
- void* faceData;
- ID_TIME_T ftime;
- int fontCount;
- int found;
- char fontDatName[1024];
- char materialName[1024];
-
- memset(&font, 0, sizeof(font));
-
- found = 0;
-
- for (fontCount = 0; fontCount < 3; fontCount++) {
- int pointSize;
- fontInfo_t* outFont;
-
- if (fontCount == 0) {
- pointSize = 12;
- outFont = &font.fontInfoSmall;
- }
- else if (fontCount == 1) {
- pointSize = 24;
- outFont = &font.fontInfoMedium;
- }
- else {
- pointSize = 48;
- outFont = &font.fontInfoLarge;
- }
-
- idStr::snPrintf(fontDatName, sizeof(fontDatName), "%s_%i.fontdat", fontName, pointSize);
- #define FILESIZE_q4FontInfo_t 9236
- if (fileSystem->ReadFile(fontDatName, NULL, &ftime) != FILESIZE_q4FontInfo_t) {
- continue;
- }
-
- if (fileSystem->ReadFile(fontDatName, &faceData, &ftime) <= 0 || faceData == NULL) {
- continue;
- }
-
- fdOffset = 0;
- fdFile = reinterpret_cast(faceData);
-
- found |= 1 << fontCount;
-
- idStr::Copynz(outFont->name, fontDatName, sizeof(outFont->name));
-
- int mw = 0;
- int mh = 0;
-
- for (int i = 0; i < GLYPHS_PER_FONT; i++) {
- glyphInfo_t& glyph = outFont->glyphs[i];
-
- /*
- Quake 4 disk glyph order:
- float width;
- float height;
- float horiAdvance;
- float horiBearingX;
- float horiBearingY;
- float s1;
- float t1;
- float s2;
- float t2;
-
- Doom 3 glyphInfo_t is not the same struct, so map it.
- */
- const float q4Width = readFloat();
- const float q4Height = readFloat();
- const float q4HoriAdvance = readFloat();
- const float q4HoriBearingX = readFloat();
- const float q4HoriBearingY = readFloat();
- const float q4S1 = readFloat();
- const float q4T1 = readFloat();
- const float q4S2 = readFloat();
- const float q4T2 = readFloat();
-
- glyph.height = (int)q4Height;
- glyph.top = (int)q4HoriBearingY;
- glyph.bottom = (int)(q4HoriBearingY - q4Height);
- glyph.pitch = (int)q4Width;
- glyph.xSkip = (int)q4HoriAdvance;
- glyph.imageWidth = (int)q4Width;
- glyph.imageHeight = (int)q4Height;
-
- glyph.s = q4S1;
- glyph.t = q4T1;
- glyph.s2 = q4S2;
- glyph.t2 = q4T2;
-
- glyph.glyph = NULL;
- glyph.shaderName[0] = '\0';
-
- if (mw < glyph.xSkip) {
- mw = glyph.xSkip;
- }
- if (mh < glyph.height) {
- mh = glyph.height;
- }
- }
-
- /*
- Quake 4 stores these after the glyph array:
- pointSize, fontHeight, ascender, descender, material pointer
-
- Doom 3's fontInfo_t does not have those fields, so consume them.
- */
- const float q4PointSize = readFloat();
- const float q4FontHeight = readFloat();
- const float q4Ascender = readFloat();
- const float q4Descender = readFloat();
-
- // consume the saved material pointer / padding from the .fontdat
- readInt();
-
- outFont->glyphScale = 48.0f / pointSize;
-
- fileSystem->FreeFile(faceData);
- faceData = NULL;
-
- /*
- The Quake 4 atlas is the .tga beside the .fontdat:
- fonts/marine_12.fontdat
- fonts/marine_12.tga
-
- Doom 3 stores material per glyph, so assign the same atlas material
- to every glyph.
- */
- idStr::snPrintf(materialName, sizeof(materialName), "%s_%i.tga", fontName, pointSize);
-
- for (int i = 0; i < GLYPHS_PER_FONT; i++) {
- outFont->glyphs[i].glyph = declManager->FindMaterial(materialName);
- if (outFont->glyphs[i].glyph != NULL) {
- outFont->glyphs[i].glyph->SetSort(SS_GUI);
- }
- idStr::Copynz(outFont->glyphs[i].shaderName, materialName, sizeof(outFont->glyphs[i].shaderName));
- }
-
- if (fontCount == 0) {
- font.maxWidthSmall = mw;
- font.maxHeightSmall = mh;
- }
- else if (fontCount == 1) {
- font.maxWidthMedium = mw;
- font.maxHeightMedium = mh;
- }
- else {
- font.maxWidthLarge = mw;
- font.maxHeightLarge = mh;
- }
- }
-
- switch (found) {
- case 1:
- memcpy(&font.fontInfoMedium, &font.fontInfoSmall, sizeof(font.fontInfoMedium));
- font.maxWidthMedium = font.maxWidthSmall;
- font.maxHeightMedium = font.maxHeightSmall;
-
- memcpy(&font.fontInfoLarge, &font.fontInfoSmall, sizeof(font.fontInfoLarge));
- font.maxWidthLarge = font.maxWidthSmall;
- font.maxHeightLarge = font.maxHeightSmall;
- break;
-
- case 2:
- memcpy(&font.fontInfoSmall, &font.fontInfoMedium, sizeof(font.fontInfoSmall));
- font.maxWidthSmall = font.maxWidthMedium;
- font.maxHeightSmall = font.maxHeightMedium;
-
- memcpy(&font.fontInfoLarge, &font.fontInfoMedium, sizeof(font.fontInfoLarge));
- font.maxWidthLarge = font.maxWidthMedium;
- font.maxHeightLarge = font.maxHeightMedium;
- break;
-
- case 3:
- memcpy(&font.fontInfoLarge, &font.fontInfoMedium, sizeof(font.fontInfoLarge));
- font.maxWidthLarge = font.maxWidthMedium;
- font.maxHeightLarge = font.maxHeightMedium;
- break;
-
- case 4:
- memcpy(&font.fontInfoSmall, &font.fontInfoLarge, sizeof(font.fontInfoSmall));
- font.maxWidthSmall = font.maxWidthLarge;
- font.maxHeightSmall = font.maxHeightLarge;
-
- memcpy(&font.fontInfoMedium, &font.fontInfoLarge, sizeof(font.fontInfoMedium));
- font.maxWidthMedium = font.maxWidthLarge;
- font.maxHeightMedium = font.maxHeightLarge;
- break;
-
- case 5:
- memcpy(&font.fontInfoMedium, &font.fontInfoLarge, sizeof(font.fontInfoMedium));
- font.maxWidthMedium = font.maxWidthLarge;
- font.maxHeightMedium = font.maxHeightLarge;
- break;
-
- case 6:
- memcpy(&font.fontInfoSmall, &font.fontInfoMedium, sizeof(font.fontInfoSmall));
- font.maxWidthSmall = font.maxWidthMedium;
- font.maxHeightSmall = font.maxHeightMedium;
- break;
-
- default:
- break;
- }
-
- return found != 0;
-
-#else
-
-#ifdef BUILD_FREETYPE
- FT_Face face;
- int j, k, xOut, yOut, lastStart, imageNumber;
- int scaledSize, newSize, maxHeight, left, satLevels;
- unsigned char* out, * imageBuff;
- glyphInfo_t* glyph;
- idImage* image;
- idMaterial* h;
- float max;
-#endif
-
- void* faceData;
- ID_TIME_T ftime;
- int i, len, fontCount;
- char name[1024];
-
- int pointSize = 12;
-
- assert(sizeof(float) == 4 && "if this is false, readFloat() won't work");
-
- memset(&font, 0, sizeof(font));
-
- for (fontCount = 0; fontCount < 3; fontCount++) {
-
- if (fontCount == 0) {
- pointSize = 12;
- }
- else if (fontCount == 1) {
- pointSize = 24;
- }
- else {
- pointSize = 48;
- }
-
- float glyphScale = 1.0f;
- glyphScale *= 48.0f / pointSize;
-
- idStr::snPrintf(name, sizeof(name), "%s/fontImage_%i.dat", fontName, pointSize);
-
- fontInfo_t* outFont;
- if (fontCount == 0) {
- outFont = &font.fontInfoSmall;
- }
- else if (fontCount == 1) {
- outFont = &font.fontInfoMedium;
- }
- else {
- outFont = &font.fontInfoLarge;
- }
-
- idStr::Copynz(outFont->name, name, sizeof(outFont->name));
-
- len = fileSystem->ReadFile(name, NULL, &ftime);
- if (len != FILESIZE_fontInfo_t) {
- common->Warning("RegisterFont: couldn't find font: '%s'", name);
- return false;
- }
-
- fileSystem->ReadFile(name, &faceData, &ftime);
-
- fdOffset = 0;
- fdFile = reinterpret_cast(faceData);
-
- for (i = 0; i < GLYPHS_PER_FONT; i++) {
- outFont->glyphs[i].height = readInt();
- outFont->glyphs[i].top = readInt();
- outFont->glyphs[i].bottom = readInt();
- outFont->glyphs[i].pitch = readInt();
- outFont->glyphs[i].xSkip = readInt();
- outFont->glyphs[i].imageWidth = readInt();
- outFont->glyphs[i].imageHeight = readInt();
- outFont->glyphs[i].s = readFloat();
- outFont->glyphs[i].t = readFloat();
- outFont->glyphs[i].s2 = readFloat();
- outFont->glyphs[i].t2 = readFloat();
-
- readInt();
-
- memcpy(outFont->glyphs[i].shaderName, &fdFile[fdOffset + 6], 32 - 6);
- fdOffset += 32;
- }
-
- outFont->glyphScale = readFloat();
-
- int mw = 0;
- int mh = 0;
-
- for (i = GLYPH_START; i < GLYPH_END; i++) {
- idStr::snPrintf(name, sizeof(name), "%s/%s", fontName, outFont->glyphs[i].shaderName);
-
- outFont->glyphs[i].glyph = declManager->FindMaterial(name);
- outFont->glyphs[i].glyph->SetSort(SS_GUI);
-
- if (mh < outFont->glyphs[i].height) {
- mh = outFont->glyphs[i].height;
- }
- if (mw < outFont->glyphs[i].xSkip) {
- mw = outFont->glyphs[i].xSkip;
- }
- }
-
- if (fontCount == 0) {
- font.maxWidthSmall = mw;
- font.maxHeightSmall = mh;
- }
- else if (fontCount == 1) {
- font.maxWidthMedium = mw;
- font.maxHeightMedium = mh;
- }
- else {
- font.maxWidthLarge = mw;
- font.maxHeightLarge = mh;
- }
-
- fileSystem->FreeFile(faceData);
- }
-
- return true;
-
-#endif // QUAKE4
-}
-
-/*
-============
-R_InitFreeType
-============
-*/
-void R_InitFreeType(void) {
-#ifdef BUILD_FREETYPE
- if (FT_Init_FreeType(&ftLibrary)) {
- common->Printf("R_InitFreeType: Unable to initialize FreeType.\n");
- }
-#endif
- // registeredFontCount = 0;
-}
-
-/*
-============
-R_DoneFreeType
-============
-*/
-void R_DoneFreeType(void) {
-#ifdef BUILD_FREETYPE
- if (ftLibrary) {
- FT_Done_FreeType(ftLibrary);
- ftLibrary = NULL;
- }
-#endif
- // registeredFontCount = 0;
-}
diff --git a/neo/engine/renderer/tr_local.h b/neo/engine/renderer/tr_local.h
index a17a3bc8..ac289e36 100644
--- a/neo/engine/renderer/tr_local.h
+++ b/neo/engine/renderer/tr_local.h
@@ -707,7 +707,7 @@ public:
virtual void FreeRenderWorld( idRenderWorld *rw );
virtual void BeginLevelLoad( void );
virtual void EndLevelLoad( void );
- virtual bool RegisterFont( const char *fontName, fontInfoEx_t &font );
+ virtual idFont * RegisterFont( const char *fontName );
virtual void SetColor( const idVec4 &rgba );
virtual void SetColor4( float r, float g, float b, float a );
virtual void DrawStretchPic ( const idDrawVert *verts, const glIndex_t *indexes, int vertCount, int indexCount, const idMaterial *material,
@@ -744,6 +744,7 @@ public:
~idRenderSystemLocal( void );
void Clear( void );
+ void FreeFonts( void );
void SetBackEndRenderer(); // sets tr.backEndRenderer based on cvars
void RenderViewToViewport( const renderView_t *renderView, idScreenRect *viewport );
@@ -807,6 +808,7 @@ public:
int guiRecursionLevel; // to prevent infinite overruns
class idGuiModel * guiModel;
class idGuiModel * demoGuiModel;
+ idList fonts;
unsigned short gammaTable[256]; // brightness / gamma modify this
@@ -1079,8 +1081,6 @@ const int GLS_DEFAULT = GLS_DEPTHFUNC_ALWAYS;
void R_Init( void );
void R_InitOpenGL( void );
-void R_DoneFreeType( void );
-
void R_SetColorMappings( void );
void R_ScreenShot_f( const idCmdArgs &args );
diff --git a/neo/engine/sys/osx/Doom3.xcodeproj/project.pbxproj b/neo/engine/sys/osx/Doom3.xcodeproj/project.pbxproj
index 7e8a63ec..db405800 100644
--- a/neo/engine/sys/osx/Doom3.xcodeproj/project.pbxproj
+++ b/neo/engine/sys/osx/Doom3.xcodeproj/project.pbxproj
@@ -151,7 +151,7 @@
812258C20912BC79005D34B9 /* RenderWorld_portals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257810912BC79005D34B9 /* RenderWorld_portals.cpp */; };
812258C30912BC79005D34B9 /* tr_backend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257830912BC79005D34B9 /* tr_backend.cpp */; };
812258C40912BC79005D34B9 /* tr_deform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257840912BC79005D34B9 /* tr_deform.cpp */; };
- 812258C50912BC79005D34B9 /* tr_font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257850912BC79005D34B9 /* tr_font.cpp */; };
+ 812258C50912BC79005D34B9 /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257850912BC79005D34B9 /* Font.cpp */; };
812258C60912BC79005D34B9 /* tr_guisurf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257860912BC79005D34B9 /* tr_guisurf.cpp */; };
812258C70912BC79005D34B9 /* tr_light.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257870912BC79005D34B9 /* tr_light.cpp */; };
812258C80912BC79005D34B9 /* tr_lightrun.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257880912BC79005D34B9 /* tr_lightrun.cpp */; };
@@ -177,6 +177,7 @@
812258DC0912BC79005D34B9 /* Common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257AA0912BC79005D34B9 /* Common.cpp */; };
812258DD0912BC79005D34B9 /* Compressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257AC0912BC79005D34B9 /* Compressor.cpp */; };
812258DE0912BC79005D34B9 /* Console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257AE0912BC79005D34B9 /* Console.cpp */; };
+ 7D0C00010000000000000001 /* ConsoleHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7D0C00020000000000000001 /* ConsoleHistory.cpp */; };
812258DF0912BC79005D34B9 /* CVarSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257B00912BC79005D34B9 /* CVarSystem.cpp */; };
812258E00912BC79005D34B9 /* DeclAF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257B20912BC79005D34B9 /* DeclAF.cpp */; };
812258E10912BC79005D34B9 /* DeclEntityDef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 812257B40912BC79005D34B9 /* DeclEntityDef.cpp */; };
@@ -515,6 +516,7 @@
812257780912BC79005D34B9 /* RenderEntity.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderEntity.cpp; sourceTree = ""; };
812257790912BC79005D34B9 /* RenderSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSystem.cpp; sourceTree = ""; };
8122577A0912BC79005D34B9 /* RenderSystem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderSystem.h; sourceTree = ""; };
+ 8122577A0912BC79005D34C0 /* Font.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Font.h; sourceTree = ""; };
8122577B0912BC79005D34B9 /* RenderSystem_init.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSystem_init.cpp; sourceTree = ""; };
8122577C0912BC79005D34B9 /* RenderWorld.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderWorld.cpp; sourceTree = ""; };
8122577D0912BC79005D34B9 /* RenderWorld.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderWorld.h; sourceTree = ""; };
@@ -525,7 +527,7 @@
812257820912BC79005D34B9 /* simplex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = simplex.h; sourceTree = ""; };
812257830912BC79005D34B9 /* tr_backend.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_backend.cpp; sourceTree = ""; };
812257840912BC79005D34B9 /* tr_deform.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_deform.cpp; sourceTree = ""; };
- 812257850912BC79005D34B9 /* tr_font.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_font.cpp; sourceTree = ""; };
+ 812257850912BC79005D34B9 /* Font.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Font.cpp; sourceTree = ""; };
812257860912BC79005D34B9 /* tr_guisurf.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_guisurf.cpp; sourceTree = ""; };
812257870912BC79005D34B9 /* tr_light.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_light.cpp; sourceTree = ""; };
812257880912BC79005D34B9 /* tr_lightrun.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = tr_lightrun.cpp; sourceTree = ""; };
@@ -566,6 +568,8 @@
812257AD0912BC79005D34B9 /* Compressor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Compressor.h; sourceTree = ""; };
812257AE0912BC79005D34B9 /* Console.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Console.cpp; sourceTree = ""; };
812257AF0912BC79005D34B9 /* Console.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Console.h; sourceTree = ""; };
+ 7D0C00020000000000000001 /* ConsoleHistory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ConsoleHistory.cpp; sourceTree = ""; };
+ 7D0C00030000000000000001 /* ConsoleHistory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ConsoleHistory.h; sourceTree = ""; };
812257B00912BC79005D34B9 /* CVarSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CVarSystem.cpp; sourceTree = ""; };
812257B10912BC79005D34B9 /* CVarSystem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CVarSystem.h; sourceTree = ""; };
812257B20912BC79005D34B9 /* DeclAF.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DeclAF.cpp; sourceTree = ""; };
@@ -1034,6 +1038,7 @@
812257780912BC79005D34B9 /* RenderEntity.cpp */,
812257790912BC79005D34B9 /* RenderSystem.cpp */,
8122577A0912BC79005D34B9 /* RenderSystem.h */,
+ 8122577A0912BC79005D34C0 /* Font.h */,
8122577B0912BC79005D34B9 /* RenderSystem_init.cpp */,
8122577C0912BC79005D34B9 /* RenderWorld.cpp */,
8122577D0912BC79005D34B9 /* RenderWorld.h */,
@@ -1044,7 +1049,7 @@
812257820912BC79005D34B9 /* simplex.h */,
812257830912BC79005D34B9 /* tr_backend.cpp */,
812257840912BC79005D34B9 /* tr_deform.cpp */,
- 812257850912BC79005D34B9 /* tr_font.cpp */,
+ 812257850912BC79005D34B9 /* Font.cpp */,
812257860912BC79005D34B9 /* tr_guisurf.cpp */,
812257870912BC79005D34B9 /* tr_light.cpp */,
812257880912BC79005D34B9 /* tr_lightrun.cpp */,
@@ -1151,6 +1156,8 @@
812257AD0912BC79005D34B9 /* Compressor.h */,
812257AE0912BC79005D34B9 /* Console.cpp */,
812257AF0912BC79005D34B9 /* Console.h */,
+ 7D0C00020000000000000001 /* ConsoleHistory.cpp */,
+ 7D0C00030000000000000001 /* ConsoleHistory.h */,
812257B00912BC79005D34B9 /* CVarSystem.cpp */,
812257B10912BC79005D34B9 /* CVarSystem.h */,
812257B20912BC79005D34B9 /* DeclAF.cpp */,
@@ -1600,7 +1607,7 @@
812258C20912BC79005D34B9 /* RenderWorld_portals.cpp in Sources */,
812258C30912BC79005D34B9 /* tr_backend.cpp in Sources */,
812258C40912BC79005D34B9 /* tr_deform.cpp in Sources */,
- 812258C50912BC79005D34B9 /* tr_font.cpp in Sources */,
+ 812258C50912BC79005D34B9 /* Font.cpp in Sources */,
812258C60912BC79005D34B9 /* tr_guisurf.cpp in Sources */,
812258C70912BC79005D34B9 /* tr_light.cpp in Sources */,
812258C80912BC79005D34B9 /* tr_lightrun.cpp in Sources */,
@@ -1626,6 +1633,7 @@
812258DC0912BC79005D34B9 /* Common.cpp in Sources */,
812258DD0912BC79005D34B9 /* Compressor.cpp in Sources */,
812258DE0912BC79005D34B9 /* Console.cpp in Sources */,
+ 7D0C00010000000000000001 /* ConsoleHistory.cpp in Sources */,
812258DF0912BC79005D34B9 /* CVarSystem.cpp in Sources */,
812258E00912BC79005D34B9 /* DeclAF.cpp in Sources */,
812258E10912BC79005D34B9 /* DeclEntityDef.cpp in Sources */,
diff --git a/neo/engine/sys/scons/SConscript.core b/neo/engine/sys/scons/SConscript.core
index e49b115c..79953bb6 100644
--- a/neo/engine/sys/scons/SConscript.core
+++ b/neo/engine/sys/scons/SConscript.core
@@ -125,9 +125,9 @@ renderer_string = ' \
draw_nv10.cpp \
draw_nv20.cpp \
draw_r200.cpp \
+ Font.cpp \
tr_backend.cpp \
tr_deform.cpp \
- tr_font.cpp \
tr_guisurf.cpp \
tr_light.cpp \
tr_lightrun.cpp \
@@ -151,6 +151,7 @@ framework_string = ' \
Common.cpp \
Compressor.cpp \
Console.cpp \
+ ConsoleHistory.cpp \
DemoFile.cpp \
DeclAF.cpp \
DeclEntityDef.cpp \