mirror of
https://github.com/w23/xash3d-fwgs
synced 2024-12-14 21:20:26 +01:00
engine: client: introduce bare-bones font manager and text drawing manager
* wire hud_fontscale so HUD font scaling can be used independently from hud_scale * allow small optimizatinons, like optional UTF-8 decoding, or not calling SetRenderMode for each character * even less copypasted code in text drawing between client code and console * get rid of direct DrawCharacter calls when it can be just DrawString * fix net_speeds, r_speeds with scaled console fonts * try to fix MobilityAPI's pfnDrawCharacterScaled * center keyboard keys in OSK code
This commit is contained in:
parent
402a0f129d
commit
77ea03a62c
291
engine/client/cl_font.c
Normal file
291
engine/client/cl_font.c
Normal file
@ -0,0 +1,291 @@
|
||||
/*
|
||||
cl_font.c - bare bones engine font manager
|
||||
Copyright (C) 2023 Alibek Omarov
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "filesystem.h"
|
||||
#include "client.h"
|
||||
#include "qfont.h"
|
||||
|
||||
qboolean CL_FixedFont( cl_font_t *font )
|
||||
{
|
||||
return font && font->valid && font->type == FONT_FIXED;
|
||||
}
|
||||
|
||||
static int CL_LoadFontTexture( const char *fontname, uint texFlags, int *width )
|
||||
{
|
||||
int font_width;
|
||||
int tex;
|
||||
|
||||
if( !g_fsapi.FileExists( fontname, false ))
|
||||
return 0;
|
||||
|
||||
tex = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, texFlags );
|
||||
if( !tex )
|
||||
return 0;
|
||||
|
||||
font_width = REF_GET_PARM( PARM_TEX_WIDTH, tex );
|
||||
if( !font_width )
|
||||
{
|
||||
ref.dllFuncs.GL_FreeTexture( tex );
|
||||
return 0;
|
||||
}
|
||||
|
||||
*width = font_width;
|
||||
return tex;
|
||||
}
|
||||
|
||||
qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, int rendermode, uint texFlags )
|
||||
{
|
||||
int font_width, i;
|
||||
|
||||
if( font->valid )
|
||||
return true; // already loaded
|
||||
|
||||
font->hFontTexture = CL_LoadFontTexture( fontname, texFlags, &font_width );
|
||||
if( !font->hFontTexture )
|
||||
return false;
|
||||
|
||||
font->type = FONT_FIXED;
|
||||
font->valid = true;
|
||||
font->scale = scale;
|
||||
font->nearest = FBitSet( texFlags, TF_NEAREST );
|
||||
font->rendermode = rendermode;
|
||||
font->charHeight = Q_rint( font_width / 16 * scale );
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( font->fontRc ); i++ )
|
||||
{
|
||||
font->fontRc[i].left = ( i * font_width / 16 ) % font_width;
|
||||
font->fontRc[i].right = font->fontRc[i].left + font_width / 16;
|
||||
font->fontRc[i].top = ( i / 16 ) * ( font_width / 16 );
|
||||
font->fontRc[i].bottom = font->fontRc[i].top + font_width / 16;
|
||||
|
||||
font->charWidths[i] = Q_rint( font_width / 16 * scale );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font, float scale, int rendermode, uint texFlags )
|
||||
{
|
||||
qfont_t src;
|
||||
file_t *fd;
|
||||
int font_width, i;
|
||||
|
||||
if( font->valid )
|
||||
return true;
|
||||
|
||||
fd = g_fsapi.Open( fontname, "r", false );
|
||||
if( !fd )
|
||||
return false;
|
||||
|
||||
if( g_fsapi.Read( fd, &src, sizeof( qfont_t )) != sizeof( qfont_t ))
|
||||
{
|
||||
g_fsapi.Close( fd );
|
||||
return false;
|
||||
}
|
||||
|
||||
g_fsapi.Close( fd );
|
||||
|
||||
font->hFontTexture = CL_LoadFontTexture( fontname, texFlags, &font_width );
|
||||
if( !font->hFontTexture )
|
||||
return false;
|
||||
|
||||
font->type = FONT_VARIABLE;
|
||||
font->valid = true;
|
||||
font->scale = scale;
|
||||
font->nearest = FBitSet( texFlags, TF_NEAREST );
|
||||
font->rendermode = rendermode;
|
||||
font->charHeight = Q_rint( src.rowheight * scale );
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( font->fontRc ); i++ )
|
||||
{
|
||||
const charinfo *ci = &src.fontinfo[i];
|
||||
|
||||
font->fontRc[i].left = (word)ci->startoffset % font_width;
|
||||
font->fontRc[i].right = font->fontRc[i].left + ci->charwidth;
|
||||
font->fontRc[i].top = (word)ci->startoffset / font_width;
|
||||
font->fontRc[i].bottom = font->fontRc[i].top + src.rowheight;
|
||||
|
||||
font->charWidths[i] = Q_rint( src.fontinfo[i].charwidth * scale );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CL_FreeFont( cl_font_t *font )
|
||||
{
|
||||
if( !font || !font->valid )
|
||||
return;
|
||||
|
||||
ref.dllFuncs.GL_FreeTexture( font->hFontTexture );
|
||||
memset( font, 0, sizeof( *font ));
|
||||
}
|
||||
|
||||
int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *font, int flags )
|
||||
{
|
||||
wrect_t *rc;
|
||||
float w, h;
|
||||
float s1, t1, s2, t2, half = 0.5f;
|
||||
int texw, texh;
|
||||
|
||||
if( !font || !font->valid || y < -font->charHeight )
|
||||
return 0;
|
||||
|
||||
if( FBitSet( flags, FONT_DRAW_UTF8 ))
|
||||
number = Con_UtfProcessChar( number & 255 );
|
||||
else number &= 255;
|
||||
|
||||
if( !number || !font->charWidths[number])
|
||||
return 0;
|
||||
|
||||
R_GetTextureParms( &texw, &texh, font->hFontTexture );
|
||||
if( !texw || !texh )
|
||||
return 0;
|
||||
|
||||
rc = &font->fontRc[number];
|
||||
if( font->nearest )
|
||||
half = 0;
|
||||
|
||||
s1 = ((float)rc->left + half ) / texw;
|
||||
t1 = ((float)rc->top + half ) / texh;
|
||||
s2 = ((float)rc->right - half ) / texw;
|
||||
t2 = ((float)rc->bottom - half ) / texh;
|
||||
w = ( rc->right - rc->left ) * font->scale;
|
||||
h = ( rc->bottom - rc->top ) * font->scale;
|
||||
|
||||
if( FBitSet( flags, FONT_DRAW_HUD ))
|
||||
SPR_AdjustSize( &x, &y, &w, &h );
|
||||
|
||||
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
|
||||
ref.dllFuncs.GL_SetRenderMode( font->rendermode );
|
||||
|
||||
// don't apply color to fixed fonts it's already colored
|
||||
if( font->type != FONT_FIXED || REF_GET_PARM( PARM_TEX_GLFORMAT, font->hFontTexture ) == 0x8045 ) // GL_LUMINANCE8_ALPHA8
|
||||
ref.dllFuncs.Color4ub( color[0], color[1], color[2], color[3] );
|
||||
else ref.dllFuncs.Color4ub( 255, 255, 255, color[3] );
|
||||
ref.dllFuncs.R_DrawStretchPic( x, y, w, h, s1, t1, s2, t2, font->hFontTexture );
|
||||
ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); // don't forget reset color
|
||||
|
||||
return font->charWidths[number];
|
||||
}
|
||||
|
||||
int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *font, int flags )
|
||||
{
|
||||
rgba_t current_color;
|
||||
int draw_len = 0;
|
||||
|
||||
if( !font || !font->valid )
|
||||
return 0;
|
||||
|
||||
if( FBitSet( flags, FONT_DRAW_UTF8 ))
|
||||
Con_UtfProcessChar( 0 ); // clear utf state
|
||||
|
||||
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
|
||||
ref.dllFuncs.GL_SetRenderMode( font->rendermode );
|
||||
|
||||
Vector4Copy( color, current_color );
|
||||
|
||||
while( *s )
|
||||
{
|
||||
if( *s == '\n' )
|
||||
{
|
||||
s++;
|
||||
|
||||
if( !*s )
|
||||
break;
|
||||
|
||||
draw_len = 0;
|
||||
y += font->charHeight;
|
||||
}
|
||||
|
||||
if( IsColorString( s ))
|
||||
{
|
||||
if( FBitSet( flags, FONT_DRAW_FORCECOL ))
|
||||
VectorCopy( g_color_table[ColorIndex(*( s + 1 ))], current_color );
|
||||
|
||||
s += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip setting rendermode, it was changed for this string already
|
||||
draw_len += CL_DrawCharacter( x + draw_len, y, (byte)*s, color, font, flags | FONT_DRAW_NORENDERMODE );
|
||||
|
||||
s++;
|
||||
}
|
||||
|
||||
return draw_len;
|
||||
}
|
||||
|
||||
void CL_DrawCharacterLen( cl_font_t *font, int number, int *width, int *height )
|
||||
{
|
||||
if( !font || !font->valid ) return;
|
||||
if( width ) *width = font->charWidths[number & 255];
|
||||
if( height ) *height = font->charHeight;
|
||||
}
|
||||
|
||||
void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height, int flags )
|
||||
{
|
||||
int draw_len = 0;
|
||||
|
||||
if( !font || !font->valid )
|
||||
return;
|
||||
|
||||
if( height )
|
||||
*height = font->charHeight;
|
||||
|
||||
if( width )
|
||||
*width = 0;
|
||||
|
||||
if( !COM_CheckString( s ))
|
||||
return;
|
||||
|
||||
if( FBitSet( flags, FONT_DRAW_UTF8 ))
|
||||
Con_UtfProcessChar( 0 ); // reset utf state
|
||||
|
||||
while( *s )
|
||||
{
|
||||
int number;
|
||||
|
||||
if( *s == '\n' )
|
||||
{
|
||||
// BUG: no check for end string here
|
||||
// but high chances somebody's relying on this
|
||||
s++;
|
||||
draw_len = 0;
|
||||
if( height )
|
||||
*height += font->charHeight;
|
||||
}
|
||||
|
||||
if( IsColorString( s ))
|
||||
{
|
||||
s += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( FBitSet( flags, FONT_DRAW_UTF8 ))
|
||||
number = Con_UtfProcessChar( (byte)*s );
|
||||
else number = (byte)*s;
|
||||
|
||||
if( number )
|
||||
{
|
||||
draw_len += font->charWidths[*s];
|
||||
|
||||
if( draw_len > *width )
|
||||
*width = draw_len;
|
||||
}
|
||||
|
||||
s++;
|
||||
}
|
||||
}
|
@ -306,9 +306,7 @@ print centerscreen message
|
||||
*/
|
||||
void CL_CenterPrint( const char *text, float y )
|
||||
{
|
||||
int length = 0;
|
||||
int width = 0;
|
||||
char *s;
|
||||
cl_font_t *font = Con_GetCurFont();
|
||||
|
||||
if( !COM_CheckString( text ))
|
||||
return;
|
||||
@ -317,24 +315,13 @@ void CL_CenterPrint( const char *text, float y )
|
||||
clgame.centerPrint.totalWidth = 0;
|
||||
clgame.centerPrint.time = cl.mtime[0]; // allow pause for centerprint
|
||||
Q_strncpy( clgame.centerPrint.message, text, sizeof( clgame.centerPrint.message ));
|
||||
s = clgame.centerPrint.message;
|
||||
|
||||
// count the number of lines for centering
|
||||
while( *s )
|
||||
{
|
||||
if( *s == '\n' )
|
||||
{
|
||||
clgame.centerPrint.lines++;
|
||||
if( width > clgame.centerPrint.totalWidth )
|
||||
clgame.centerPrint.totalWidth = width;
|
||||
width = 0;
|
||||
}
|
||||
else width += clgame.scrInfo.charWidths[*s];
|
||||
s++;
|
||||
length++;
|
||||
}
|
||||
CL_DrawStringLen( font,
|
||||
clgame.centerPrint.message,
|
||||
&clgame.centerPrint.totalWidth,
|
||||
&clgame.centerPrint.totalHeight,
|
||||
FONT_DRAW_HUD | FONT_DRAW_UTF8 );
|
||||
|
||||
clgame.centerPrint.totalHeight = ( clgame.centerPrint.lines * clgame.scrInfo.iCharHeight );
|
||||
clgame.centerPrint.y = CL_AdjustYPos( y, clgame.centerPrint.totalHeight );
|
||||
}
|
||||
|
||||
@ -502,6 +489,7 @@ called each frame
|
||||
*/
|
||||
void CL_DrawCenterPrint( void )
|
||||
{
|
||||
cl_font_t *font = Con_GetCurFont();
|
||||
char *pText;
|
||||
int i, j, x, y;
|
||||
int width, lineLength;
|
||||
@ -521,8 +509,10 @@ void CL_DrawCenterPrint( void )
|
||||
y = clgame.centerPrint.y; // start y
|
||||
colorDefault = g_color_table[7];
|
||||
pText = clgame.centerPrint.message;
|
||||
Con_DrawCharacterLen( 0, NULL, &charHeight );
|
||||
|
||||
CL_DrawCharacterLen( font, 0, NULL, &charHeight );
|
||||
|
||||
ref.dllFuncs.GL_SetRenderMode( font->rendermode );
|
||||
for( i = 0; i < clgame.centerPrint.lines; i++ )
|
||||
{
|
||||
lineLength = 0;
|
||||
@ -532,7 +522,7 @@ void CL_DrawCenterPrint( void )
|
||||
{
|
||||
byte c = *pText;
|
||||
line[lineLength] = c;
|
||||
Con_DrawCharacterLen( c, &charWidth, NULL );
|
||||
CL_DrawCharacterLen( font, c, &charWidth, NULL );
|
||||
width += charWidth;
|
||||
lineLength++;
|
||||
pText++;
|
||||
@ -549,7 +539,7 @@ void CL_DrawCenterPrint( void )
|
||||
for( j = 0; j < lineLength; j++ )
|
||||
{
|
||||
if( x >= 0 && y >= 0 && x <= refState.width )
|
||||
x += Con_DrawCharacter( x, y, line[j], colorDefault );
|
||||
x += CL_DrawCharacter( x, y, line[j], colorDefault, font, FONT_DRAW_UTF8 | FONT_DRAW_HUD | FONT_DRAW_NORENDERMODE );
|
||||
}
|
||||
y += charHeight;
|
||||
}
|
||||
@ -1600,6 +1590,14 @@ int GAME_EXPORT CL_GetScreenInfo( SCREENINFO *pscrinfo )
|
||||
{
|
||||
float scale_factor = hud_scale->value;
|
||||
|
||||
if( FBitSet( hud_fontscale->flags, FCVAR_CHANGED ))
|
||||
{
|
||||
CL_FreeFont( &cls.creditsFont );
|
||||
SCR_LoadCreditsFont();
|
||||
|
||||
ClearBits( hud_fontscale->flags, FCVAR_CHANGED );
|
||||
}
|
||||
|
||||
// setup screen info
|
||||
clgame.scrInfo.iSize = sizeof( clgame.scrInfo );
|
||||
clgame.scrInfo.iFlags = SCRINFO_SCREENFLASH;
|
||||
@ -1844,24 +1842,13 @@ returns drawed chachter width (in real screen pixels)
|
||||
*/
|
||||
static int GAME_EXPORT pfnDrawCharacter( int x, int y, int number, int r, int g, int b )
|
||||
{
|
||||
if( !cls.creditsFont.valid )
|
||||
return 0;
|
||||
rgba_t color = { r, g, b, 255 };
|
||||
int flags = FONT_DRAW_HUD;
|
||||
|
||||
if( hud_utf8->value )
|
||||
number = Con_UtfProcessChar( number );
|
||||
flags |= FONT_DRAW_UTF8;
|
||||
|
||||
number &= 255;
|
||||
|
||||
if( number < 32 ) return 0;
|
||||
if( y < -clgame.scrInfo.iCharHeight )
|
||||
return 0;
|
||||
|
||||
clgame.ds.adjust_size = true;
|
||||
pfnPIC_Set( cls.creditsFont.hFontTexture, r, g, b, 255 );
|
||||
pfnPIC_DrawAdditive( x, y, -1, -1, &cls.creditsFont.fontRc[number] );
|
||||
clgame.ds.adjust_size = false;
|
||||
|
||||
return clgame.scrInfo.charWidths[number];
|
||||
return CL_DrawCharacter( x, y, number, color, &cls.creditsFont, flags );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1873,20 +1860,12 @@ drawing string like a console string
|
||||
*/
|
||||
int GAME_EXPORT pfnDrawConsoleString( int x, int y, char *string )
|
||||
{
|
||||
int drawLen;
|
||||
cl_font_t *font = Con_GetFont( con_fontsize->value );
|
||||
rgba_t color;
|
||||
Vector4Copy( clgame.ds.textColor, color );
|
||||
Vector4Set( clgame.ds.textColor, 255, 255, 255, 255 );
|
||||
|
||||
if( !COM_CheckString( string ))
|
||||
return 0; // silent ignore
|
||||
Con_SetFont( con_fontsize->value );
|
||||
|
||||
clgame.ds.adjust_size = true;
|
||||
drawLen = Con_DrawString( x, y, string, clgame.ds.textColor );
|
||||
MakeRGBA( clgame.ds.textColor, 255, 255, 255, 255 );
|
||||
clgame.ds.adjust_size = false;
|
||||
|
||||
Con_RestoreFont();
|
||||
|
||||
return (x + drawLen); // exclude color prexfixes
|
||||
return x + CL_DrawString( x, y, string, color, font, FONT_DRAW_UTF8 | FONT_DRAW_HUD );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1914,9 +1893,9 @@ compute string length in screen pixels
|
||||
*/
|
||||
void GAME_EXPORT pfnDrawConsoleStringLen( const char *pText, int *length, int *height )
|
||||
{
|
||||
Con_SetFont( con_fontsize->value );
|
||||
Con_DrawStringLen( pText, length, height );
|
||||
Con_RestoreFont();
|
||||
cl_font_t *font = Con_GetFont( con_fontsize->value );
|
||||
|
||||
CL_DrawStringLen( font, pText, length, height, FONT_DRAW_UTF8 | FONT_DRAW_HUD );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2839,23 +2818,7 @@ pfnVGUI2DrawCharacter
|
||||
*/
|
||||
static int GAME_EXPORT pfnVGUI2DrawCharacter( int x, int y, int number, unsigned int font )
|
||||
{
|
||||
if( !cls.creditsFont.valid )
|
||||
return 0;
|
||||
|
||||
number &= 255;
|
||||
|
||||
number = Con_UtfProcessChar( number );
|
||||
|
||||
if( number < 32 ) return 0;
|
||||
if( y < -clgame.scrInfo.iCharHeight )
|
||||
return 0;
|
||||
|
||||
clgame.ds.adjust_size = true;
|
||||
gameui.ds.gl_texturenum = cls.creditsFont.hFontTexture;
|
||||
pfnPIC_DrawAdditive( x, y, -1, -1, &cls.creditsFont.fontRc[number] );
|
||||
clgame.ds.adjust_size = false;
|
||||
|
||||
return clgame.scrInfo.charWidths[number];
|
||||
return pfnDrawCharacter( x, y, number, 255, 255, 255 );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2866,9 +2829,6 @@ pfnVGUI2DrawCharacterAdditive
|
||||
*/
|
||||
static int GAME_EXPORT pfnVGUI2DrawCharacterAdditive( int x, int y, int ch, int r, int g, int b, unsigned int font )
|
||||
{
|
||||
if( !hud_utf8->value )
|
||||
ch = Con_UtfProcessChar( ch );
|
||||
|
||||
return pfnDrawCharacter( x, y, ch, r, g, b );
|
||||
}
|
||||
|
||||
@ -2880,16 +2840,13 @@ pfnDrawString
|
||||
*/
|
||||
static int GAME_EXPORT pfnDrawString( int x, int y, const char *str, int r, int g, int b )
|
||||
{
|
||||
int iWidth = 0;
|
||||
Con_UtfProcessChar(0);
|
||||
rgba_t color = { r, g, b, 255 };
|
||||
int flags = FONT_DRAW_HUD;
|
||||
|
||||
// draw the string until we hit the null character or a newline character
|
||||
for ( ; *str != 0 && *str != '\n'; str++ )
|
||||
{
|
||||
iWidth += pfnVGUI2DrawCharacterAdditive( x + iWidth, y, (unsigned char)*str, r, g, b, 0 );
|
||||
}
|
||||
if( hud_utf8->value )
|
||||
SetBits( flags, FONT_DRAW_UTF8 );
|
||||
|
||||
return iWidth;
|
||||
return CL_DrawString( x, y, str, color, &cls.creditsFont, flags );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2900,11 +2857,19 @@ pfnDrawStringReverse
|
||||
*/
|
||||
static int GAME_EXPORT pfnDrawStringReverse( int x, int y, const char *str, int r, int g, int b )
|
||||
{
|
||||
// find the end of the string
|
||||
char *szIt;
|
||||
for( szIt = (char*)str; *szIt != 0; szIt++ )
|
||||
x -= clgame.scrInfo.charWidths[ (unsigned char) *szIt ];
|
||||
return pfnDrawString( x, y, str, r, g, b );
|
||||
rgba_t color = { r, g, b, 255 };
|
||||
int flags = FONT_DRAW_HUD;
|
||||
int width, height;
|
||||
|
||||
if( hud_utf8->value )
|
||||
SetBits( flags, FONT_DRAW_UTF8 );
|
||||
|
||||
CL_DrawStringLen( &cls.creditsFont, str, &width, &height, flags );
|
||||
|
||||
x -= width;
|
||||
y -= height;
|
||||
|
||||
return CL_DrawString( x, y, str, color, &cls.creditsFont, flags );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -487,22 +487,10 @@ static void PIC_DrawGeneric( float x, float y, float width, float height, const
|
||||
if( prc )
|
||||
{
|
||||
// calc user-defined rectangle
|
||||
s1 = prc->left;
|
||||
t1 = prc->top;
|
||||
s2 = prc->right;
|
||||
t2 = prc->bottom;
|
||||
|
||||
if( clgame.ds.adjust_size )
|
||||
{
|
||||
SPR_AdjustTexCoords( w, h, &s1, &t1, &s2, &t2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
s1 /= (float)w;
|
||||
t1 /= (float)h;
|
||||
s2 /= (float)w;
|
||||
t2 /= (float)h;
|
||||
}
|
||||
s1 = prc->left / (float)w;
|
||||
t1 = prc->top / (float)h;
|
||||
s2 = prc->right / (float)w;
|
||||
t2 = prc->bottom / (float)h;
|
||||
|
||||
if( width == -1 && height == -1 )
|
||||
{
|
||||
@ -526,8 +514,6 @@ static void PIC_DrawGeneric( float x, float y, float width, float height, const
|
||||
if( gameui.ds.scissor_test && !PIC_Scissor( &x, &y, &width, &height, &s1, &t1, &s2, &t2 ))
|
||||
return;
|
||||
|
||||
if( clgame.ds.adjust_size )
|
||||
SPR_AdjustSize( &x, &y, &width, &height );
|
||||
ref.dllFuncs.R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, gameui.ds.gl_texturenum );
|
||||
ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
|
||||
}
|
||||
|
@ -25,6 +25,9 @@ mobile_engfuncs_t *gMobileEngfuncs;
|
||||
convar_t *vibration_length;
|
||||
convar_t *vibration_enable;
|
||||
|
||||
static cl_font_t g_scaled_font;
|
||||
static float g_font_scale;
|
||||
|
||||
static void pfnVibrate( float life, char flags )
|
||||
{
|
||||
if( !vibration_enable->value )
|
||||
@ -60,28 +63,28 @@ static void pfnEnableTextInput( int enable )
|
||||
|
||||
static int pfnDrawScaledCharacter( int x, int y, int number, int r, int g, int b, float scale )
|
||||
{
|
||||
int width = clgame.scrInfo.charWidths[number] * scale * hud_scale->value;
|
||||
int height = clgame.scrInfo.iCharHeight * scale * hud_scale->value;
|
||||
// this call is very ineffective and possibly broken!
|
||||
rgba_t color = { r, g, b, 255 };
|
||||
int flags = FONT_DRAW_HUD;
|
||||
|
||||
if( !cls.creditsFont.valid )
|
||||
return 0;
|
||||
if( hud_utf8->value )
|
||||
SetBits( flags, FONT_DRAW_UTF8 );
|
||||
|
||||
x *= hud_scale->value;
|
||||
y *= hud_scale->value;
|
||||
if( fabs( g_font_scale - scale ) > 0.1f ||
|
||||
g_scaled_font.hFontTexture != cls.creditsFont.hFontTexture )
|
||||
{
|
||||
int i;
|
||||
|
||||
number &= 255;
|
||||
number = Con_UtfProcessChar( number );
|
||||
g_scaled_font = cls.creditsFont;
|
||||
g_scaled_font.scale *= scale;
|
||||
g_scaled_font.charHeight *= scale;
|
||||
for( i = 0; i < ARRAYSIZE( g_scaled_font.charWidths ); i++ )
|
||||
g_scaled_font.charWidths[i] *= scale;
|
||||
|
||||
if( number < 32 )
|
||||
return 0;
|
||||
g_font_scale = scale;
|
||||
}
|
||||
|
||||
if( y < -height )
|
||||
return 0;
|
||||
|
||||
pfnPIC_Set( cls.creditsFont.hFontTexture, r, g, b, 255 );
|
||||
pfnPIC_DrawAdditive( x, y, width, height, &cls.creditsFont.fontRc[number] );
|
||||
|
||||
return width;
|
||||
return CL_DrawCharacter( x, y, number, color, &g_scaled_font, flags );
|
||||
}
|
||||
|
||||
static void *pfnGetNativeObject( const char *obj )
|
||||
|
@ -364,6 +364,7 @@ NetGraph_DrawTextFields
|
||||
static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int count, float avg, int packet_loss, int packet_choke, int graphtype )
|
||||
{
|
||||
static int lastout;
|
||||
cl_font_t *font = Con_GetFont( 0 );
|
||||
rgba_t colors = { 0.9 * 255, 0.9 * 255, 0.7 * 255, 255 };
|
||||
int ptx = Q_max( x + w - NETGRAPH_LERP_HEIGHT - 1, 1 );
|
||||
int pty = Q_max( rect.top + rect.bottom - NETGRAPH_LERP_HEIGHT - 3, 1 );
|
||||
@ -385,16 +386,17 @@ static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int coun
|
||||
|
||||
// move rolling average
|
||||
framerate = FRAMERATE_AVG_FRAC * host.frametime + ( 1.0f - FRAMERATE_AVG_FRAC ) * framerate;
|
||||
Con_SetFont( 0 );
|
||||
|
||||
ref.dllFuncs.GL_SetRenderMode( font->rendermode );
|
||||
|
||||
if( framerate > 0.0f )
|
||||
{
|
||||
y -= net_graphheight->value;
|
||||
|
||||
Con_DrawString( x, y, va( "%.1f fps" , 1.0f / framerate ), colors );
|
||||
CL_DrawString( x, y, va( "%.1f fps" , 1.0f / framerate ), colors, font, FONT_DRAW_NORENDERMODE );
|
||||
|
||||
if( avg > 1.0f )
|
||||
Con_DrawString( x + 75, y, va( "%i ms" , (int)avg ), colors );
|
||||
CL_DrawString( x + 75, y, va( "%i ms" , (int)avg ), colors, font, FONT_DRAW_NORENDERMODE );
|
||||
|
||||
y += 15;
|
||||
|
||||
@ -402,10 +404,10 @@ static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int coun
|
||||
if( !out ) out = lastout;
|
||||
else lastout = out;
|
||||
|
||||
Con_DrawString( x, y, va( "in : %i %.2f kb/s", netstat_graph[j].msgbytes, cls.netchan.flow[FLOW_INCOMING].avgkbytespersec ), colors );
|
||||
CL_DrawString( x, y, va( "in : %i %.2f kb/s", netstat_graph[j].msgbytes, cls.netchan.flow[FLOW_INCOMING].avgkbytespersec ), colors, font, FONT_DRAW_NORENDERMODE );
|
||||
y += 15;
|
||||
|
||||
Con_DrawString( x, y, va( "out: %i %.2f kb/s", out, cls.netchan.flow[FLOW_OUTGOING].avgkbytespersec ), colors );
|
||||
CL_DrawString( x, y, va( "out: %i %.2f kb/s", out, cls.netchan.flow[FLOW_OUTGOING].avgkbytespersec ), colors, font, FONT_DRAW_NORENDERMODE );
|
||||
y += 15;
|
||||
|
||||
if( graphtype > 2 )
|
||||
@ -413,16 +415,14 @@ static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int coun
|
||||
int loss = (int)(( packet_loss + PACKETLOSS_AVG_FRAC ) - 0.01f );
|
||||
int choke = (int)(( packet_choke + PACKETCHOKE_AVG_FRAC ) - 0.01f );
|
||||
|
||||
Con_DrawString( x, y, va( "loss: %i choke: %i", loss, choke ), colors );
|
||||
CL_DrawString( x, y, va( "loss: %i choke: %i", loss, choke ), colors, font, FONT_DRAW_NORENDERMODE );
|
||||
}
|
||||
}
|
||||
|
||||
if( graphtype < 3 )
|
||||
Con_DrawString( ptx, pty, va( "%i/s", (int)cl_cmdrate->value ), colors );
|
||||
CL_DrawString( ptx, pty, va( "%i/s", (int)cl_cmdrate->value ), colors, font, FONT_DRAW_NORENDERMODE );
|
||||
|
||||
Con_DrawString( ptx, last_y, va( "%i/s" , (int)cl_updaterate->value ), colors );
|
||||
|
||||
Con_RestoreFont();
|
||||
CL_DrawString( ptx, last_y, va( "%i/s" , (int)cl_updaterate->value ), colors, font, FONT_DRAW_NORENDERMODE );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -160,6 +160,7 @@ void SCR_NetSpeeds( void )
|
||||
static int max_clfps = 0;
|
||||
int cur_clfps = 0;
|
||||
rgba_t color;
|
||||
cl_font_t *font = Con_GetCurFont();
|
||||
|
||||
if( !host.allow_console )
|
||||
return;
|
||||
@ -196,25 +197,11 @@ void SCR_NetSpeeds( void )
|
||||
Q_memprint( cls.netchan.total_sended )
|
||||
);
|
||||
|
||||
x = refState.width - 320;
|
||||
x = refState.width - 320 * font->scale;
|
||||
y = 384;
|
||||
|
||||
Con_DrawStringLen( NULL, NULL, &height );
|
||||
MakeRGBA( color, 255, 255, 255, 255 );
|
||||
|
||||
p = start = msg;
|
||||
|
||||
do
|
||||
{
|
||||
end = Q_strchr( p, '\n' );
|
||||
if( end ) msg[end-start] = '\0';
|
||||
|
||||
Con_DrawString( x, y, p, color );
|
||||
y += height;
|
||||
|
||||
if( end ) p = end + 1;
|
||||
else break;
|
||||
} while( 1 );
|
||||
CL_DrawString( x, y, msg, color, font, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -234,28 +221,13 @@ void SCR_RSpeeds( void )
|
||||
int x, y, height;
|
||||
char *p, *start, *end;
|
||||
rgba_t color;
|
||||
cl_font_t *font = Con_GetCurFont();
|
||||
|
||||
x = refState.width - 340;
|
||||
x = refState.width - 340 * font->scale;
|
||||
y = 64;
|
||||
|
||||
Con_DrawStringLen( NULL, NULL, &height );
|
||||
MakeRGBA( color, 255, 255, 255, 255 );
|
||||
|
||||
p = start = msg;
|
||||
do
|
||||
{
|
||||
end = Q_strchr( p, '\n' );
|
||||
if( end ) msg[end-start] = '\0';
|
||||
|
||||
Con_DrawString( x, y, p, color );
|
||||
y += height;
|
||||
|
||||
// handle '\n\n'
|
||||
if( *p == '\n' )
|
||||
y += height;
|
||||
if( end ) p = end + 1;
|
||||
else break;
|
||||
} while( 1 );
|
||||
CL_DrawString( x, y, msg, color, font, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -588,6 +560,7 @@ void SCR_LoadCreditsFont( void )
|
||||
{
|
||||
cl_font_t *const font = &cls.creditsFont;
|
||||
qboolean success = false;
|
||||
float scale = hud_fontscale->value;
|
||||
dword crc = 0;
|
||||
|
||||
// replace default gfx.wad textures by current charset's font
|
||||
@ -599,15 +572,15 @@ void SCR_LoadCreditsFont( void )
|
||||
"creditsfont_%s.fnt", Cvar_VariableString( "con_charset" )) > 0 )
|
||||
{
|
||||
if( FS_FileExists( charsetFnt, false ))
|
||||
success = Con_LoadVariableWidthFont( charsetFnt, font, 1.0f, TF_FONT );
|
||||
success = Con_LoadVariableWidthFont( charsetFnt, font, scale, kRenderTransAdd, TF_FONT );
|
||||
}
|
||||
}
|
||||
|
||||
if( !success )
|
||||
success = Con_LoadVariableWidthFont( "gfx/creditsfont.fnt", font, 1.0f, TF_FONT );
|
||||
success = Con_LoadVariableWidthFont( "gfx/creditsfont.fnt", font, scale, kRenderTransAdd, TF_FONT );
|
||||
|
||||
if( !success )
|
||||
success = Con_LoadFixedWidthFont( "gfx/conchars", font, 1.0f, TF_FONT );
|
||||
success = Con_LoadFixedWidthFont( "gfx/conchars", font, scale, kRenderTransAdd, TF_FONT );
|
||||
|
||||
// copy font size for client.dll
|
||||
if( success )
|
||||
|
@ -318,17 +318,25 @@ typedef struct
|
||||
pfnEventHook func; // user-defined function
|
||||
} cl_user_event_t;
|
||||
|
||||
#define FONT_FIXED 0
|
||||
#define FONT_VARIABLE 1
|
||||
#define FONT_FIXED 0
|
||||
#define FONT_VARIABLE 1
|
||||
|
||||
#define FONT_DRAW_HUD BIT( 0 ) // pass to drawing function to apply hud_scale
|
||||
#define FONT_DRAW_UTF8 BIT( 1 ) // call UtfProcessChar
|
||||
#define FONT_DRAW_FORCECOL BIT( 2 ) // ignore colorcodes
|
||||
#define FONT_DRAW_NORENDERMODE BIT( 3 ) // ignore font's default rendermode
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int hFontTexture; // handle to texture
|
||||
wrect_t fontRc[256]; // rectangles
|
||||
byte charWidths[256];
|
||||
int charHeight;
|
||||
int type;
|
||||
qboolean valid; // all rectangles are valid
|
||||
int hFontTexture; // handle to texture
|
||||
wrect_t fontRc[256]; // tex coords
|
||||
float scale; // scale factor
|
||||
byte charWidths[256]; // scaled widths
|
||||
int charHeight; // scaled height
|
||||
int type; // fixed width font or variable
|
||||
int rendermode; // default rendermode
|
||||
qboolean nearest; // nearest filtering enabled
|
||||
qboolean valid; // all rectangles are valid
|
||||
} cl_font_t;
|
||||
|
||||
typedef struct
|
||||
@ -342,7 +350,6 @@ typedef struct
|
||||
int scissor_width;
|
||||
int scissor_height;
|
||||
qboolean scissor_test;
|
||||
qboolean adjust_size; // allow to adjust scale for fonts
|
||||
|
||||
int renderMode; // override kRenderMode from TriAPI
|
||||
TRICULLSTYLE cullMode; // override CULL FACE from TriAPI
|
||||
@ -796,6 +803,19 @@ void CL_ResetEvent( event_info_t *ei );
|
||||
word CL_EventIndex( const char *name );
|
||||
void CL_FireEvents( void );
|
||||
|
||||
//
|
||||
// cl_font.c
|
||||
//
|
||||
qboolean CL_FixedFont( cl_font_t *font );
|
||||
qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, int rendermode, uint texFlags );
|
||||
qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font, float scale, int rendermode, uint texFlags );
|
||||
void CL_FreeFont( cl_font_t *font );
|
||||
int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *font, int flags );
|
||||
int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *font, int flags );
|
||||
void CL_DrawCharacterLen( cl_font_t *font, int number, int *width, int *height );
|
||||
void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height, int flags );
|
||||
|
||||
|
||||
//
|
||||
// cl_game.c
|
||||
//
|
||||
@ -1030,13 +1050,13 @@ int Con_UtfProcessChar( int in );
|
||||
int Con_UtfProcessCharForce( int in );
|
||||
int Con_UtfMoveLeft( char *str, int pos );
|
||||
int Con_UtfMoveRight( char *str, int pos, int length );
|
||||
void Con_DrawStringLen( const char *pText, int *length, int *height );
|
||||
int Con_DrawString( int x, int y, const char *string, rgba_t setColor );
|
||||
int Con_DrawCharacter( int x, int y, int number, rgba_t color );
|
||||
void Con_DrawCharacterLen( int number, int *width, int *height );
|
||||
void Con_DefaultColor( int r, int g, int b );
|
||||
void Con_InvalidateFonts( void );
|
||||
void Con_SetFont( int fontNum );
|
||||
cl_font_t *Con_GetCurFont( void );
|
||||
cl_font_t *Con_GetFont( int num );
|
||||
void Con_DrawCharacterLen( int number, int *width, int *height );
|
||||
int Con_DrawString( int x, int y, const char *string, rgba_t setColor ); // legacy, use cl_font.c
|
||||
void GAME_EXPORT Con_DrawStringLen( const char *pText, int *length, int *height ); // legacy, use cl_font.c
|
||||
void Con_CharEvent( int key );
|
||||
void Con_RestoreFont( void );
|
||||
void Key_Console( int key );
|
||||
@ -1046,8 +1066,6 @@ void Con_Bottom( void );
|
||||
void Con_Top( void );
|
||||
void Con_PageDown( int lines );
|
||||
void Con_PageUp( int lines );
|
||||
qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font, float scale, uint texFlags );
|
||||
qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, uint texFlags );
|
||||
|
||||
//
|
||||
// s_main.c
|
||||
|
@ -116,7 +116,7 @@ typedef struct
|
||||
|
||||
// console fonts
|
||||
cl_font_t chars[CON_NUMFONTS];// fonts.wad/font1.fnt
|
||||
cl_font_t *curFont, *lastUsedFont;
|
||||
cl_font_t *curFont;
|
||||
|
||||
// console input
|
||||
field_t input;
|
||||
@ -555,90 +555,9 @@ Con_FixedFont
|
||||
*/
|
||||
qboolean Con_FixedFont( void )
|
||||
{
|
||||
if( con.curFont && con.curFont->valid && con.curFont->type == FONT_FIXED )
|
||||
return true;
|
||||
return false;
|
||||
return CL_FixedFont( con.curFont );
|
||||
}
|
||||
|
||||
qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, uint texFlags )
|
||||
{
|
||||
int fontWidth;
|
||||
int i;
|
||||
|
||||
if( font->valid )
|
||||
return true; // already loaded
|
||||
|
||||
if( !FS_FileExists( fontname, false ))
|
||||
return false;
|
||||
|
||||
font->hFontTexture = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, texFlags );
|
||||
R_GetTextureParms( &fontWidth, NULL, font->hFontTexture );
|
||||
|
||||
if( font->hFontTexture && fontWidth != 0 )
|
||||
{
|
||||
font->charHeight = fontWidth / 16 * scale;
|
||||
font->type = FONT_FIXED;
|
||||
|
||||
// build fixed rectangles
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
font->fontRc[i].left = (i * (fontWidth / 16)) % fontWidth;
|
||||
font->fontRc[i].right = font->fontRc[i].left + fontWidth / 16;
|
||||
font->fontRc[i].top = (i / 16) * (fontWidth / 16);
|
||||
font->fontRc[i].bottom = font->fontRc[i].top + fontWidth / 16;
|
||||
font->charWidths[i] = fontWidth / 16 * scale;
|
||||
}
|
||||
font->valid = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font, float scale, uint texFlags )
|
||||
{
|
||||
fs_offset_t length;
|
||||
qfont_t *src;
|
||||
byte *buffer;
|
||||
int fontWidth;
|
||||
int i;
|
||||
|
||||
if( font->valid )
|
||||
return true; // already loaded
|
||||
|
||||
if( !FS_FileExists( fontname, false ))
|
||||
return false;
|
||||
|
||||
font->hFontTexture = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, texFlags );
|
||||
R_GetTextureParms( &fontWidth, NULL, font->hFontTexture );
|
||||
|
||||
// setup consolefont
|
||||
if( font->hFontTexture && fontWidth != 0 )
|
||||
{
|
||||
// half-life font with variable chars witdh
|
||||
buffer = FS_LoadFile( fontname, &length, false );
|
||||
|
||||
if( buffer && length >= sizeof( qfont_t ))
|
||||
{
|
||||
src = (qfont_t *)buffer;
|
||||
font->charHeight = src->rowheight * scale;
|
||||
font->type = FONT_VARIABLE;
|
||||
|
||||
// build rectangles
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
font->fontRc[i].left = (word)src->fontinfo[i].startoffset % fontWidth;
|
||||
font->fontRc[i].right = font->fontRc[i].left + src->fontinfo[i].charwidth;
|
||||
font->fontRc[i].top = (word)src->fontinfo[i].startoffset / fontWidth;
|
||||
font->fontRc[i].bottom = font->fontRc[i].top + src->rowheight;
|
||||
font->charWidths[i] = src->fontinfo[i].charwidth * scale;
|
||||
}
|
||||
font->valid = true;
|
||||
}
|
||||
if( buffer ) Mem_Free( buffer );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
@ -650,6 +569,7 @@ INTERNAL RESOURCE
|
||||
static void Con_LoadConsoleFont( int fontNumber, cl_font_t *font )
|
||||
{
|
||||
qboolean success = false;
|
||||
float scale = con_fontscale->value;
|
||||
|
||||
if( font->valid )
|
||||
return; // already loaded
|
||||
@ -657,7 +577,7 @@ static void Con_LoadConsoleFont( int fontNumber, cl_font_t *font )
|
||||
// loading conchars
|
||||
if( Sys_CheckParm( "-oldfont" ))
|
||||
{
|
||||
success = Con_LoadVariableWidthFont( "gfx/conchars.fnt", font, con_fontscale->value, TF_FONT|TF_NEAREST );
|
||||
success = Con_LoadVariableWidthFont( "gfx/conchars.fnt", font, scale, kRenderTransTexture, TF_FONT|TF_NEAREST );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -670,14 +590,14 @@ static void Con_LoadConsoleFont( int fontNumber, cl_font_t *font )
|
||||
if( Q_snprintf( path, sizeof( path ),
|
||||
"font%i_%s.fnt", fontNumber, Cvar_VariableString( "con_charset" )) > 0 )
|
||||
{
|
||||
success = Con_LoadVariableWidthFont( path, font, con_fontscale->value, TF_FONT|TF_NEAREST );
|
||||
success = Con_LoadVariableWidthFont( path, font, scale, kRenderTransTexture, TF_FONT|TF_NEAREST );
|
||||
}
|
||||
}
|
||||
|
||||
if( !success )
|
||||
{
|
||||
Q_snprintf( path, sizeof( path ), "fonts/font%i", fontNumber );
|
||||
success = Con_LoadVariableWidthFont( path, font, con_fontscale->value, TF_FONT|TF_NEAREST );
|
||||
success = Con_LoadVariableWidthFont( path, font, scale, kRenderTransTexture, TF_FONT|TF_NEAREST );
|
||||
}
|
||||
}
|
||||
|
||||
@ -685,7 +605,7 @@ static void Con_LoadConsoleFont( int fontNumber, cl_font_t *font )
|
||||
{
|
||||
// quake fixed font as fallback
|
||||
// keep source to print directly into conback image
|
||||
if( !Con_LoadFixedWidthFont( "gfx/conchars", font, con_fontscale->value, TF_FONT|TF_KEEP_SOURCE ))
|
||||
if( !Con_LoadFixedWidthFont( "gfx/conchars", font, scale, kRenderTransTexture, TF_FONT|TF_KEEP_SOURCE ))
|
||||
Con_DPrintf( S_ERROR "failed to load console font\n" );
|
||||
}
|
||||
}
|
||||
@ -716,7 +636,7 @@ static void Con_LoadConchars( void )
|
||||
fontSize = CON_NUMFONTS - 1;
|
||||
|
||||
// sets the current font
|
||||
con.lastUsedFont = con.curFont = &con.chars[fontSize];
|
||||
con.curFont = &con.chars[fontSize];
|
||||
}
|
||||
|
||||
// CP1251 table
|
||||
@ -889,129 +809,25 @@ static void Con_DrawCharToConback( int num, const byte *conchars, byte *dest )
|
||||
|
||||
/*
|
||||
====================
|
||||
Con_TextAdjustSize
|
||||
Con_GetFont
|
||||
|
||||
draw charcters routine
|
||||
====================
|
||||
*/
|
||||
static void Con_TextAdjustSize( int *x, int *y, int *w, int *h )
|
||||
cl_font_t *Con_GetFont( int num )
|
||||
{
|
||||
float xscale, yscale;
|
||||
|
||||
if( !x && !y && !w && !h ) return;
|
||||
|
||||
// scale for screen sizes
|
||||
xscale = (float)refState.width / (float)clgame.scrInfo.iWidth;
|
||||
yscale = (float)refState.height / (float)clgame.scrInfo.iHeight;
|
||||
|
||||
if( x ) *x *= xscale;
|
||||
if( y ) *y *= yscale;
|
||||
if( w ) *w *= xscale;
|
||||
if( h ) *h *= yscale;
|
||||
num = bound( 0, num, CON_NUMFONTS - 1 );
|
||||
return &con.chars[num];
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
Con_DrawGenericChar
|
||||
Con_GetCurFont
|
||||
|
||||
draw console single character
|
||||
====================
|
||||
*/
|
||||
static int Con_DrawGenericChar( int x, int y, int number, rgba_t color )
|
||||
cl_font_t *Con_GetCurFont( void )
|
||||
{
|
||||
int width, height;
|
||||
float s1, t1, s2, t2;
|
||||
wrect_t *rc;
|
||||
|
||||
number &= 255;
|
||||
|
||||
if( !con.curFont || !con.curFont->valid )
|
||||
return 0;
|
||||
|
||||
number = Con_UtfProcessChar( number );
|
||||
if( !number )
|
||||
return 0;
|
||||
|
||||
if( y < -con.curFont->charHeight )
|
||||
return 0;
|
||||
|
||||
rc = &con.curFont->fontRc[number];
|
||||
R_GetTextureParms( &width, &height, con.curFont->hFontTexture );
|
||||
|
||||
if( !width || !height )
|
||||
return con.curFont->charWidths[number];
|
||||
|
||||
// don't apply color to fixed fonts it's already colored
|
||||
if( con.curFont->type != FONT_FIXED || REF_GET_PARM( PARM_TEX_GLFORMAT, con.curFont->hFontTexture ) == 0x8045 ) // GL_LUMINANCE8_ALPHA8
|
||||
ref.dllFuncs.Color4ub( color[0], color[1], color[2], color[3] );
|
||||
else ref.dllFuncs.Color4ub( 255, 255, 255, color[3] );
|
||||
|
||||
// calc rectangle
|
||||
s1 = (float)rc->left / width;
|
||||
t1 = (float)rc->top / height;
|
||||
s2 = (float)rc->right / width;
|
||||
t2 = (float)rc->bottom / height;
|
||||
width = ( rc->right - rc->left ) * con_fontscale->value;
|
||||
height = ( rc->bottom - rc->top ) * con_fontscale->value;
|
||||
|
||||
if( clgame.ds.adjust_size )
|
||||
Con_TextAdjustSize( &x, &y, &width, &height );
|
||||
ref.dllFuncs.R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, con.curFont->hFontTexture );
|
||||
ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); // don't forget reset color
|
||||
|
||||
return con.curFont->charWidths[number];
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
Con_SetFont
|
||||
|
||||
choose font size
|
||||
====================
|
||||
*/
|
||||
void Con_SetFont( int fontNum )
|
||||
{
|
||||
fontNum = bound( 0, fontNum, CON_NUMFONTS - 1 );
|
||||
con.curFont = &con.chars[fontNum];
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
Con_RestoreFont
|
||||
|
||||
restore auto-selected console font
|
||||
(that based on screen resolution)
|
||||
====================
|
||||
*/
|
||||
void Con_RestoreFont( void )
|
||||
{
|
||||
con.curFont = con.lastUsedFont;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
Con_DrawCharacter
|
||||
|
||||
client version of routine
|
||||
====================
|
||||
*/
|
||||
int Con_DrawCharacter( int x, int y, int number, rgba_t color )
|
||||
{
|
||||
ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture );
|
||||
return Con_DrawGenericChar( x, y, number, color );
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
Con_DrawCharacterLen
|
||||
|
||||
returns character sizes in screen pixels
|
||||
====================
|
||||
*/
|
||||
void Con_DrawCharacterLen( int number, int *width, int *height )
|
||||
{
|
||||
if( width && con.curFont ) *width = con.curFont->charWidths[number];
|
||||
if( height && con.curFont ) *height = con.curFont->charHeight;
|
||||
return con.curFont;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1023,105 +839,7 @@ compute string width and height in screen pixels
|
||||
*/
|
||||
void GAME_EXPORT Con_DrawStringLen( const char *pText, int *length, int *height )
|
||||
{
|
||||
int curLength = 0;
|
||||
|
||||
if( !con.curFont )
|
||||
return;
|
||||
if( height )
|
||||
*height = con.curFont->charHeight;
|
||||
if (!length)
|
||||
return;
|
||||
|
||||
*length = 0;
|
||||
|
||||
while( *pText )
|
||||
{
|
||||
byte c = *pText;
|
||||
|
||||
if( *pText == '\n' )
|
||||
{
|
||||
pText++;
|
||||
curLength = 0;
|
||||
}
|
||||
|
||||
// skip color strings they are not drawing
|
||||
if( IsColorString( pText ))
|
||||
{
|
||||
pText += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Convert to unicode
|
||||
c = Con_UtfProcessChar( c );
|
||||
|
||||
if( c )
|
||||
curLength += con.curFont->charWidths[c];
|
||||
|
||||
pText++;
|
||||
|
||||
if( curLength > *length )
|
||||
*length = curLength;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Con_DrawString
|
||||
|
||||
Draws a multi-colored string, optionally forcing
|
||||
to a fixed color.
|
||||
==================
|
||||
*/
|
||||
int Con_DrawGenericString( int x, int y, const char *string, rgba_t setColor, qboolean forceColor, int hideChar )
|
||||
{
|
||||
rgba_t color;
|
||||
int drawLen = 0;
|
||||
int numDraws = 0;
|
||||
const char *s;
|
||||
|
||||
if( !con.curFont ) return 0; // no font set
|
||||
|
||||
Con_UtfProcessChar( 0 );
|
||||
|
||||
// draw the colored text
|
||||
memcpy( color, setColor, sizeof( color ));
|
||||
s = string;
|
||||
|
||||
while( *s )
|
||||
{
|
||||
if( *s == '\n' )
|
||||
{
|
||||
s++;
|
||||
if( !*s ) break; // at end the string
|
||||
drawLen = 0; // begin new row
|
||||
y += con.curFont->charHeight;
|
||||
}
|
||||
|
||||
if( IsColorString( s ))
|
||||
{
|
||||
if( !forceColor )
|
||||
{
|
||||
memcpy( color, g_color_table[ColorIndex(*(s+1))], sizeof( color ));
|
||||
color[3] = setColor[3];
|
||||
}
|
||||
|
||||
s += 2;
|
||||
numDraws++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// hide char for overstrike mode
|
||||
if( hideChar == numDraws )
|
||||
drawLen += con.curFont->charWidths[*s];
|
||||
else drawLen += Con_DrawCharacter( x + drawLen, y, *s, color );
|
||||
|
||||
numDraws++;
|
||||
s++;
|
||||
}
|
||||
|
||||
ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
|
||||
return drawLen;
|
||||
return CL_DrawStringLen( con.curFont, pText, length, height, FONT_DRAW_UTF8 );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1133,10 +851,9 @@ client version of routine
|
||||
*/
|
||||
int Con_DrawString( int x, int y, const char *string, rgba_t setColor )
|
||||
{
|
||||
return Con_DrawGenericString( x, y, string, setColor, false, -1 );
|
||||
return CL_DrawString( x, y, string, setColor, con.curFont, FONT_DRAW_UTF8 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Con_Init
|
||||
@ -1628,7 +1345,7 @@ Field_DrawInputLine
|
||||
void Field_DrawInputLine( int x, int y, field_t *edit )
|
||||
{
|
||||
int len, cursorChar;
|
||||
int drawLen, hideChar = -1;
|
||||
int drawLen;
|
||||
int prestep, curPos;
|
||||
char str[MAX_SYSPATH];
|
||||
byte *colorDefault;
|
||||
@ -1665,35 +1382,23 @@ void Field_DrawInputLine( int x, int y, field_t *edit )
|
||||
// save char for overstrike
|
||||
cursorChar = str[edit->cursor - prestep];
|
||||
|
||||
if( host.key_overstrike && cursorChar && !((int)( host.realtime * 4 ) & 1 ))
|
||||
hideChar = edit->cursor - prestep; // skip this char
|
||||
|
||||
// draw it
|
||||
Con_DrawGenericString( x, y, str, colorDefault, false, hideChar );
|
||||
CL_DrawString( x, y, str, colorDefault, con.curFont, FONT_DRAW_UTF8 );
|
||||
|
||||
// draw the cursor
|
||||
if((int)( host.realtime * 4 ) & 1 ) return; // off blink
|
||||
|
||||
// calc cursor position
|
||||
str[edit->cursor - prestep] = 0;
|
||||
Con_DrawStringLen( str, &curPos, NULL );
|
||||
Con_UtfProcessChar( 0 );
|
||||
CL_DrawStringLen( con.curFont, str, &curPos, NULL, FONT_DRAW_UTF8 );
|
||||
|
||||
if( host.key_overstrike && cursorChar )
|
||||
if( host.key_overstrike )
|
||||
{
|
||||
// overstrike cursor
|
||||
#if 0
|
||||
pglEnable( GL_BLEND );
|
||||
pglDisable( GL_ALPHA_TEST );
|
||||
pglBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
#endif
|
||||
Con_DrawGenericChar( x + curPos, y, cursorChar, colorDefault );
|
||||
CL_DrawCharacter( x + curPos, y, '|', colorDefault, con.curFont, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_UtfProcessChar( 0 );
|
||||
Con_DrawCharacter( x + curPos, y, '_', colorDefault );
|
||||
CL_DrawCharacter( x + curPos, y, '_', colorDefault, con.curFont, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -1997,7 +1702,7 @@ void Con_DrawInput( int lines )
|
||||
return;
|
||||
|
||||
y = lines - ( con.curFont->charHeight * 2 );
|
||||
Con_DrawCharacter( con.curFont->charWidths[' '], y, ']', g_color_table[7] );
|
||||
CL_DrawCharacter( con.curFont->charWidths[' '], y, ']', g_color_table[7], con.curFont, 0 );
|
||||
Field_DrawInputLine( con.curFont->charWidths[' ']*2, y, &con.input );
|
||||
}
|
||||
|
||||
@ -2142,7 +1847,11 @@ int Con_DrawConsoleLine( int y, int lineno )
|
||||
return 0; // this string will be shown only at notify
|
||||
|
||||
if( y >= con.curFont->charHeight )
|
||||
Con_DrawGenericString( con.curFont->charWidths[' '], y, li->start, g_color_table[7], false, -1 );
|
||||
{
|
||||
float x = con.curFont->charWidths[' '];
|
||||
|
||||
CL_DrawString( x, y, li->start, g_color_table[7], con.curFont, FONT_DRAW_UTF8 );
|
||||
}
|
||||
|
||||
return con.curFont->charHeight;
|
||||
}
|
||||
@ -2212,14 +1921,12 @@ void Con_DrawSolidConsole( int lines )
|
||||
Q_snprintf( curbuild, MAX_STRING, XASH_ENGINE_NAME " %i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
|
||||
|
||||
Con_DrawStringLen( curbuild, &stringLen, &charH );
|
||||
start = refState.width - stringLen;
|
||||
stringLen = Con_StringLength( curbuild );
|
||||
|
||||
start = refState.width - stringLen;
|
||||
fraction = lines / (float)refState.height;
|
||||
color[3] = Q_min( fraction * 2.0f, 1.0f ) * 255; // fadeout version number
|
||||
|
||||
for( i = 0; i < stringLen; i++ )
|
||||
width += Con_DrawCharacter( start + width, 0, curbuild[i], color );
|
||||
Con_DrawString( start, 0, curbuild, color );
|
||||
|
||||
// draw the text
|
||||
if( CON_LINES_COUNT > 0 )
|
||||
@ -2236,7 +1943,7 @@ void Con_DrawSolidConsole( int lines )
|
||||
|
||||
// draw red arrows to show the buffer is backscrolled
|
||||
for( x = 0; x < con.linewidth; x += 4 )
|
||||
Con_DrawCharacter(( x + 1 ) * start, y, '^', g_color_table[1] );
|
||||
CL_DrawCharacter( ( x + 1 ) * start, y, '^', g_color_table[1], con.curFont, 0 );
|
||||
y -= con.curFont->charHeight;
|
||||
}
|
||||
x = lastline;
|
||||
@ -2339,7 +2046,7 @@ void Con_DrawVersion( void )
|
||||
{
|
||||
// draws the current build
|
||||
byte *color = g_color_table[7];
|
||||
int i, stringLen, width = 0, charH = 0;
|
||||
int stringLen, charH = 0;
|
||||
int start, height = refState.height;
|
||||
qboolean draw_version = false;
|
||||
string curbuild;
|
||||
@ -2370,8 +2077,7 @@ void Con_DrawVersion( void )
|
||||
stringLen = Con_StringLength( curbuild );
|
||||
height -= charH * 1.05f;
|
||||
|
||||
for( i = 0; i < stringLen; i++ )
|
||||
width += Con_DrawCharacter( start + width, height, curbuild[i], color );
|
||||
Con_DrawString( start, height, curbuild, color );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2414,7 +2120,7 @@ void Con_RunConsole( void )
|
||||
if( FBitSet( con_charset->flags, FCVAR_CHANGED ) ||
|
||||
FBitSet( con_fontscale->flags, FCVAR_CHANGED ) ||
|
||||
FBitSet( con_fontnum->flags, FCVAR_CHANGED ) ||
|
||||
FBitSet( cl_charset->flags, FCVAR_CHANGED ) )
|
||||
FBitSet( cl_charset->flags, FCVAR_CHANGED ))
|
||||
{
|
||||
// update codepage parameters
|
||||
if( !Q_stricmp( con_charset->string, "cp1251" ))
|
||||
@ -2436,8 +2142,6 @@ void Con_RunConsole( void )
|
||||
g_utf8 = !Q_stricmp( cl_charset->string, "utf-8" );
|
||||
Con_InvalidateFonts();
|
||||
Con_LoadConchars();
|
||||
cls.creditsFont.valid = false;
|
||||
SCR_LoadCreditsFont();
|
||||
ClearBits( con_charset->flags, FCVAR_CHANGED );
|
||||
ClearBits( con_fontnum->flags, FCVAR_CHANGED );
|
||||
ClearBits( con_fontscale->flags, FCVAR_CHANGED );
|
||||
@ -2576,8 +2280,10 @@ Con_InvalidateFonts
|
||||
*/
|
||||
void Con_InvalidateFonts( void )
|
||||
{
|
||||
memset( con.chars, 0, sizeof( con.chars ));
|
||||
con.curFont = con.lastUsedFont = NULL;
|
||||
int i;
|
||||
for( i = 0; i < ARRAYSIZE( con.chars ); i++ )
|
||||
CL_FreeFont( &con.chars[i] );
|
||||
con.curFont = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1148,7 +1148,7 @@ Draw button with symbol on it
|
||||
*/
|
||||
static void OSK_DrawSymbolButton( int symb, float x, float y, float width, float height )
|
||||
{
|
||||
char str[] = {symb & 255, 0};
|
||||
cl_font_t *font = Con_GetCurFont();
|
||||
byte color[] = { 255, 255, 255, 255 };
|
||||
int x1 = x * refState.width,
|
||||
y1 = y * refState.height,
|
||||
@ -1156,14 +1156,15 @@ static void OSK_DrawSymbolButton( int symb, float x, float y, float width, float
|
||||
h = height * refState.height;
|
||||
|
||||
if( symb == osk.curbutton.val )
|
||||
{
|
||||
ref.dllFuncs.FillRGBABlend( x1, y1, w, h, 255, 160, 0, 100 );
|
||||
}
|
||||
|
||||
if( !symb || symb == ' ' || (symb >= OSK_TAB && symb < OSK_SPECKEY_LAST ) )
|
||||
return;
|
||||
|
||||
Con_DrawCharacter( x1 + 1, y1, symb, color );
|
||||
CL_DrawCharacter(
|
||||
x1 + width * 0.4 * refState.width,
|
||||
y1 + height * 0.4 * refState.height,
|
||||
symb, color, font, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1177,7 +1178,11 @@ static void OSK_DrawSpecialButton( const char *name, float x, float y, float wid
|
||||
{
|
||||
byte color[] = { 0, 255, 0, 255 };
|
||||
|
||||
Con_DrawString( x * refState.width, y * refState.height, name, color );
|
||||
Con_DrawString(
|
||||
x * refState.width + width * 0.4 * refState.width,
|
||||
y * refState.height + height * 0.4 * refState.height,
|
||||
name,
|
||||
color );
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user