Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,6 @@
[submodule "3rdparty/mbedtls/mbedtls"]
path = 3rdparty/mbedtls/mbedtls
url = https://github.com/FWGS/mbedtls-releases.git
[submodule "3rdparty/miniutl"]
path = 3rdparty/miniutl
url = https://github.com/FWGS/miniutl.git
120 changes: 111 additions & 9 deletions engine/client/cl_font.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,12 @@ void CL_FreeFont( cl_font_t *font )
if( !font || !font->valid )
return;

if( font->ttfont )
{
TTF_Destroy( font->ttfont );
font->ttfont = NULL;
}

ref.dllFuncs.GL_FreeTexture( font->hFontTexture );
memset( font, 0, sizeof( *font ));
}
Expand All @@ -194,6 +200,53 @@ int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_
if( !font || !font->valid || y < -font->charHeight )
return 0;

if( UI_IsVisible() && FBitSet( flags, FONT_DRAW_HUD ) )
return 0;

// truetype dispatch
if( font->ttfont )
{
int r = 255, g = 255, b = 255, a = 255;
// adjust console font color to be more similar to bitmap
if( color )
{
if( font == Con_GetCurFont() )
{
r = (int)( color[0] * 0.80f );
g = (int)( color[1] * 0.75f );
b = (int)( color[2] * 0.95f );
}
else
{
r = color[0];
g = color[1];
b = color[2];
}
a = color[3];
}

if( number <= 32 )
{
if( number == ' ' )
return FBitSet( flags, FONT_DRAW_HUD ) ? (int)( TTF_GetCharWidth( font->ttfont, ' ' ) * clgame.scrInfo.iWidth / refState.width + 0.5f ) : TTF_GetCharWidth( font->ttfont, ' ' );
else if( number == '\t' )
return CL_CalcTabStop( font, x );
return 0;
}

if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ) && font->rendermode )
CL_SetFontRendermode( font );

if( FBitSet( flags, FONT_DRAW_HUD ))
{
float fx = x, fy = y, fw = (float)TTF_GetCharWidth( font->ttfont, number ), fh = (float)TTF_GetHeight( font->ttfont );
SPR_AdjustSize( &fx, &fy, &fw, &fh );
TTF_DrawChar( font->ttfont, (int)fx, (int)fy, number, r, g, b, a );
return (int)( TTF_GetCharWidth( font->ttfont, number ) * clgame.scrInfo.iWidth / refState.width + 0.5f );
}
return TTF_DrawChar( font->ttfont, (int)x, (int)y, number, r, g, b, a );
}

// check if printable
if( number <= 32 )
{
Expand Down Expand Up @@ -246,6 +299,7 @@ int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_
int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_t *font, int flags )
{
int draw_len = 0;
rgba_t curColor;

if( !font || !font->valid )
return 0;
Expand All @@ -256,7 +310,12 @@ int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
CL_SetFontRendermode( font );

CL_SetFontColor( font, color );
if( color )
memcpy( curColor, color, sizeof( curColor ));
else
MakeRGBA( curColor, 255, 255, 255, 255 );

CL_SetFontColor( font, curColor );

SetBits( flags, FONT_DRAW_NOCOLOR | FONT_DRAW_NORENDERMODE );

Expand All @@ -273,26 +332,42 @@ int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_
if( !FBitSet( flags, FONT_DRAW_NOLF ))
{
draw_len = 0;
y += font->charHeight;
if( font->ttfont )
y += FBitSet( flags, FONT_DRAW_HUD ) ? (int)( TTF_GetHeight( font->ttfont ) * clgame.scrInfo.iHeight / refState.height + 0.5f ) : TTF_GetHeight( font->ttfont );
else
y += font->charHeight;
}

if( FBitSet( flags, FONT_DRAW_RESETCOLORONLF ))
CL_SetFontColor( font, color );
{
if( color )
memcpy( curColor, color, sizeof( curColor ));
else
MakeRGBA( curColor, 255, 255, 255, 255 );
CL_SetFontColor( font, curColor );
}
continue;
}

if( IsColorString( s ))
{
// don't copy alpha
if( !FBitSet( flags, FONT_DRAW_FORCECOL ))
CL_SetFontColor( font, g_color_table[ColorIndex(*( s + 1 ))] );
{
const byte *ct = g_color_table[ColorIndex(*( s + 1 ))];
curColor[0] = ct[0];
curColor[1] = ct[1];
curColor[2] = ct[2];
// keep alpha from original color
CL_SetFontColor( font, curColor );
}

s += 2;
continue;
}

// skip setting rendermode, it was changed for this string already
draw_len += CL_DrawCharacter( x + draw_len, y, (byte)*s, NULL, font, flags );
// for truetype, pass curColor explicitly since GL state isn't used
draw_len += CL_DrawCharacter( x + draw_len, y, (byte)*s, font->ttfont ? curColor : NULL, font, flags );

s++;
}
Expand All @@ -315,6 +390,20 @@ int CL_DrawStringf( cl_font_t *font, float x, float y, const rgba_t color, int f
void CL_DrawCharacterLen( cl_font_t *font, int number, int *width, int *height )
{
if( !font || !font->valid ) return;

if( font->ttfont )
{
if( width )
{
if( number == '\t' )
*width = CL_CalcTabStop( font, 0 );
else
*width = TTF_GetCharWidth( font->ttfont, number );
}
if( height ) *height = TTF_GetHeight( font->ttfont );
return;
}

if( width )
{
if( number == '\t' )
Expand All @@ -332,7 +421,12 @@ void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height,
return;

if( height )
*height = font->charHeight;
{
if( font->ttfont )
*height = FBitSet( flags, FONT_DRAW_HUD ) ? (int)( TTF_GetHeight( font->ttfont ) * clgame.scrInfo.iHeight / refState.height + 0.5f ) : TTF_GetHeight( font->ttfont );
else
*height = font->charHeight;
}

if( width )
*width = 0;
Expand All @@ -356,7 +450,12 @@ void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height,
if( !FBitSet( flags, FONT_DRAW_NOLF ))
{
if( height )
*height += font->charHeight;
{
if( font->ttfont )
*height += FBitSet( flags, FONT_DRAW_HUD ) ? (int)( TTF_GetHeight( font->ttfont ) * clgame.scrInfo.iHeight / refState.height + 0.5f ) : TTF_GetHeight( font->ttfont );
else
*height += font->charHeight;
}
}
continue;
}
Expand All @@ -379,7 +478,10 @@ void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height,

if( number )
{
draw_len += font->charWidths[number];
if( font->ttfont )
draw_len += FBitSet( flags, FONT_DRAW_HUD ) ? (int)( TTF_GetCharWidth( font->ttfont, number ) * clgame.scrInfo.iWidth / refState.width + 0.5f ) : TTF_GetCharWidth( font->ttfont, number );
else
draw_len += font->charWidths[number];

if( width )
{
Expand Down
10 changes: 9 additions & 1 deletion engine/client/cl_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ CVAR_DEFINE_AUTO( cl_trace_messages, "0", FCVAR_CHEAT, "enable message names tra
CVAR_DEFINE_AUTO( cl_trace_events, "0", FCVAR_CHEAT, "enable events tracing (good for developers)" );
static CVAR_DEFINE_AUTO( cl_nat, "0", 0, "show servers running under NAT" );
CVAR_DEFINE_AUTO( hud_utf8, "0", FCVAR_ARCHIVE, "Use utf-8 encoding for hud text" );
CVAR_DEFINE_AUTO( hud_truetype, "0", FCVAR_ARCHIVE | FCVAR_VIDRESTART, "use truetype font for on-screen text if available" );
CVAR_DEFINE_AUTO( hud_truetype_size, "18", FCVAR_ARCHIVE | FCVAR_VIDRESTART, "font height for hud_truetype text" );
CVAR_DEFINE_AUTO( hud_truetype_name, "", FCVAR_ARCHIVE | FCVAR_VIDRESTART, "truetype font name for hud text (empty = default)" );
CVAR_DEFINE_AUTO( ui_renderworld, "0", FCVAR_ARCHIVE, "render world when UI is visible" );
static CVAR_DEFINE_AUTO( cl_maxframetime, "0", 0, "set deadline timer for client rendering to catch freezes" );
CVAR_DEFINE_AUTO( cl_fixmodelinterpolationartifacts, "1", 0, "try to fix up models interpolation on a moving platforms (monsters on trains for example)" );
Expand Down Expand Up @@ -3684,6 +3687,9 @@ static void CL_InitLocal( void )
Cvar_RegisterVariable( &cl_timeout );
Cvar_RegisterVariable( &cl_charset );
Cvar_RegisterVariable( &hud_utf8 );
Cvar_RegisterVariable( &hud_truetype );
Cvar_RegisterVariable( &hud_truetype_size );
Cvar_RegisterVariable( &hud_truetype_name );

Cvar_RegisterVariable( &rcon_address );

Expand Down Expand Up @@ -3951,7 +3957,8 @@ void CL_Init( void )

CL_InitLocal();

VID_Init(); // init video
TTF_Init();
VID_Init(); // init video

// unreliable buffer. unsed for unreliable commands and voice stream
MSG_Init( &cls.datagram, "cls.datagram", cls.datagram_buf, sizeof( cls.datagram_buf ));
Expand Down Expand Up @@ -4009,6 +4016,7 @@ void CL_Shutdown( void )
g_fsapi.Delete( "demoheader.tmp" ); // remove tmp file
SCR_FreeCinematic (); // release AVI's *after* client.dll because custom renderer may use them
S_Shutdown ();
TTF_Shutdown();
R_Shutdown ();

Con_Shutdown ();
Expand Down
39 changes: 39 additions & 0 deletions engine/client/cl_scrn.c
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,9 @@ void SCR_LoadCreditsFont( void )
if( !success )
success = Con_LoadFixedWidthFont( "gfx/conchars", font, scale, &hud_fontrender, TF_FONT|TF_NEAREST );

if( success )
Con_DPrintf( "Loaded HUD bitmap font (scale %.1f)\n", scale );

// copy font size for client.dll
if( success )
{
Expand All @@ -746,6 +749,39 @@ void SCR_LoadCreditsFont( void )
clgame.scrInfo.charWidths[i] = cls.creditsFont.charWidths[i];
}
else Con_DPrintf( S_ERROR "failed to load HUD font\n" );

if( success && hud_truetype.value && hud_truetype_size.value > 0 )
{
float hudScale = 1.0f;
int ttfSize;

if( hud_scale.value >= 320.0f && hud_scale.value >= hud_scale_minimal_width.value )
{
hudScale = refState.width / hud_scale.value;
if( hudScale < 1.0f ) hudScale = 1.0f;
}
else if( hud_scale.value && hud_scale.value != 1.0f )
{
float scaled_width = refState.width / hud_scale.value;
if( scaled_width >= hud_scale_minimal_width.value )
hudScale = hud_scale.value;
}

ttfSize = (int)( hud_truetype_size.value * hudScale + 0.5f );
const char *fontName = COM_StringEmptyOrNULL( hud_truetype_name.string ) ? DEFAULT_MENUFONT : hud_truetype_name.string;
font->ttfont = TTF_Create( fontName, ttfSize, DEFAULT_WEIGHT, 0, 0 );

if( !font->ttfont && fontName != DEFAULT_MENUFONT )
{
Con_Printf( S_WARN "Failed to load hud_truetype font '%s', falling back to '%s'\n", fontName, DEFAULT_MENUFONT );
font->ttfont = TTF_Create( DEFAULT_MENUFONT, ttfSize, DEFAULT_WEIGHT, 0, 0 );
}

if( font->ttfont )
Con_DPrintf( "Loaded HUD truetype font '%s' size %i\n", fontName, ttfSize );
else
Con_Printf( S_ERROR "Failed to load HUD truetype font '%s'\n", fontName );
}
}

/*
Expand Down Expand Up @@ -893,6 +929,9 @@ void SCR_VidInit( void )

CL_ClearSpriteTextures(); // now all hud sprites are invalid

CL_FreeFont( &cls.creditsFont );
SCR_LoadCreditsFont();

// vid_state has changed
if( gameui.hInstance ) gameui.dllFuncs.pfnVidInit();
if( clgame.hInstance ) clgame.dllFuncs.pfnVidInit();
Expand Down
39 changes: 39 additions & 0 deletions engine/client/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ typedef struct
int type; // fixed width font or variable
convar_t *rendermode; // user-defined default rendermode
qboolean valid; // all rectangles are valid
void *ttfont; // CTrueTypeFont* when truetype is active, NULL otherwise
} cl_font_t;

typedef struct scissor_state_s
Expand Down Expand Up @@ -724,6 +725,9 @@ extern convar_t cl_trace_stufftext;
extern convar_t cl_trace_messages;
extern convar_t cl_trace_events;
extern convar_t hud_utf8;
extern convar_t hud_truetype;
extern convar_t hud_truetype_size;
extern convar_t hud_truetype_name;
extern convar_t cl_showevents;
extern convar_t scr_centertime;
extern convar_t scr_viewsize;
Expand Down Expand Up @@ -833,6 +837,41 @@ void CL_ResetEvent( event_info_t *ei );
word CL_EventIndex( const char *name );
void CL_FireEvents( void );

//
// font/TrueTypeFont.cpp
//

// default font names and weights
#define DEFAULT_MENUFONT "Trebuchet MS"
#define DEFAULT_CONFONT "Tahoma"
#define DEFAULT_WEIGHT 500

// default font sizes
#define TTF_CONSOLE_CHAR_HEIGHT 18
#define TTF_SMALL_CHAR_HEIGHT 20
#define TTF_MED_CHAR_HEIGHT 26
#define TTF_BIG_CHAR_HEIGHT 40

#ifdef __cplusplus
extern "C" {
#endif
void TTF_Init( void );
void TTF_Shutdown( void );
void *TTF_Create( const char *name, int tall, int weight, int flags, int outlineSize );
void TTF_Destroy( void *font );
int TTF_DrawChar( void *font, int x, int y, int ch, int r, int g, int b, int a );
int TTF_GetHeight( void *font );
int TTF_GetAscent( void *font );
int TTF_GetMaxCharWidth( void *font );
int TTF_GetEllipsisWide( void *font );
int TTF_GetCharWidth( void *font, int ch );
void TTF_GetCharABCWidths( void *font, int ch, int *a, int *b, int *c );
void TTF_SetRenderMode( int additive );
struct ttf_funcs_s *TTF_GetFuncs( void );
#ifdef __cplusplus
}
#endif

//
// cl_font.c
//
Expand Down
Loading
Loading