Compare commits

..

18 Commits

Author SHA1 Message Date
Alibek Omarov
3baeea1253 engine: client: handle hud_utf8 in client.dll's draw character functions, rather than in engine's CL_DrawCharacter 2025-03-12 07:31:18 +03:00
Alibek Omarov
9ba7cc88d9 engine: client: move Con_UtfProcessChar to cl_gameui. It is now deprecated 2025-03-12 07:26:58 +03:00
Alibek Omarov
9ef7759e05 engine: client: rewrite touch control text drawing with utflib and cl_font 2025-03-12 07:26:58 +03:00
Alibek Omarov
232224f52d engine: client: OSK doesn't need unicode conversion, as it only supports basic latin anyway 2025-03-12 07:26:58 +03:00
Alibek Omarov
18d09d80cc engine: client: like GoldSrc, expect UTF-8 encoded strings in pfnDrawString/pfnDrawStringReverse 2025-03-12 06:15:27 +03:00
Alibek Omarov
67f91fc100 engine: client: decode utf-8 string in CL_DrawCenterPrint, as CL_DrawCharacter requires unicode codepoints now 2025-03-12 06:04:35 +03:00
Alibek Omarov
ca22c4123d engine: client: make CL_DrawCharacter accept unicode codepoints, as it was intended to do 2025-03-11 08:23:16 +03:00
Alibek Omarov
8af0e2c8b4 readme: add missing system dependencies on Linux systems [skip ci] 2025-03-08 02:42:28 +03:00
Alibek Omarov
a5191d8948 engine: client: console: simplify Field_DrawInputLine, try to make it safer 2025-03-08 02:35:32 +03:00
Alibek Omarov
b2d8239829 engine: common: net_http: fix decompression for compressed but not chunked files 2025-03-06 19:10:48 +03:00
Alibek Omarov
34322f025b engine: client: limit ticket generator choices to revemu2013 only 2025-03-06 12:35:32 +03:00
Alibek Omarov
3e6b434733 mainui: update 2025-03-05 22:36:41 +03:00
Alibek Omarov
8359cbe76c scripts: waifulib: add flag --enable-limited-debuginfo which enables -gline-tables-only on GCC and Clang compilers
This saves ~30mb of APK size on Android.
2025-03-05 02:19:39 +03:00
Alibek Omarov
0e90e6285e engine: host: use #if instead of #ifdef when checking for extended hl25 structs compile option 2025-03-03 22:59:44 +03:00
Alibek Omarov
2f5840f650 engine: host: add a cvar that indicates whether engine was built with --enable-hl25-extended-structs or not 2025-03-03 22:53:20 +03:00
Alibek Omarov
3b51a554dd mainui: update 2025-03-02 20:20:54 +03:00
Alibek Omarov
5f0880d4a2 engine: client: lower the bandwidth test fragment sizes to 1400 and less, as using 64k, 32k and more is unreliable 2025-03-02 20:20:40 +03:00
Bohdan Shulyar
884a3c66ac client: touch: fix minor typo that prevented editing touch buttons commands 2025-03-02 20:19:58 +03:00
16 changed files with 292 additions and 241 deletions

View File

@@ -66,21 +66,21 @@ This repository contains our fork of HLSDK and restored source code for Half-Lif
* Only for 32-bit engine on 64-bit x86 operating system:
* Enable i386 on your system: `$ sudo dpkg --add-architecture i386`.
* Install `aptitude` ([why?](https://github.com/FWGS/xash3d-fwgs/issues/1828#issuecomment-2415131759)): `$ sudo apt update && sudo apt upgrade && sudo apt install aptitude`
* Install development tools: `$ sudo aptitude --without-recommends install git build-essential gcc-multilib g++-multilib libsdl2-dev:i386 libfreetype-dev:i386 libopus-dev:i386 libbz2-dev:i386`.
* Install development tools: `$ sudo aptitude --without-recommends install git build-essential gcc-multilib g++-multilib libsdl2-dev:i386 libfreetype-dev:i386 libopus-dev:i386 libbz2-dev:i386 libvorbis-dev:i386 libopusfile-dev:i386 libogg-dev:i386`.
* Set PKG_CONFIG_PATH environment variable to point at 32-bit libraries: `$ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig`.
* For 64-bit engine on 64-bit x86 and other non-x86 systems:
* Install development tools: `$ sudo apt install git build-essential python libsdl2-dev libfreetype6-dev libopus-dev libbz2-dev`.
* Install development tools: `$ sudo apt install git build-essential python libsdl2-dev libfreetype6-dev libopus-dev libbz2-dev libvorbis-dev libopusfile-dev libogg-dev`.
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
##### RedHat/Fedora
* Only for 32-bit engine on 64-bit x86 operating system:
* Install development tools: `$ sudo dnf install git gcc gcc-c++ glibc-devel.i686 SDL2-devel.i686 opus-devel.i686 freetype-devel.i686 bzip2-devel.i686`.
* Install development tools: `$ sudo dnf install git gcc gcc-c++ glibc-devel.i686 SDL2-devel.i686 opus-devel.i686 freetype-devel.i686 bzip2-devel.i686 libvorbis-devel.i686 opusfile-devel.i686 libogg-devel.i686`.
* Set PKG_CONFIG_PATH environment variable to point at 32-bit libraries: `$ export PKG_CONFIG_PATH=/usr/lib/pkgconfig`.
* For 64-bit engine on 64-bit x86 and other non-x86 systems:
* Install development tools: `$ sudo dnf install git gcc gcc-c++ SDL2-devel opus-devel freetype-devel bzip2-devel`.
* Install development tools: `$ sudo dnf install git gcc gcc-c++ SDL2-devel opus-devel freetype-devel bzip2-devel libvorbis-devel opusfile-devel libogg-devel`.
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.

View File

@@ -17,7 +17,7 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(BUILD_TYPE "debug")
else()
set(BUILD_TYPE "release")
list(APPEND WAF_EXTRA_ARGS --enable-poly-opt --enable-lto)
list(APPEND WAF_EXTRA_ARGS --enable-poly-opt --enable-lto --enable-limited-debuginfo)
endif()
if(ANDROID_ABI STREQUAL "x86")
@@ -75,7 +75,7 @@ ExternalProject_Add(
BUILD_CMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
WAFLOCK=.lock-waf_android_${ANDROID_ABI}_build
${WAF} configure -T ${BUILD_TYPE} --android=${ANDROID_ABI},,${CMAKE_SYSTEM_VERSION}
-s "${ENGINE_SOURCE_DIR}/3rdparty/SDL" --enable-bundled-deps
-s "${ENGINE_SOURCE_DIR}/3rdparty/SDL" --enable-bundled-deps ${WAF_EXTRA_ARGS}
BUILD_COMMAND ${CMAKE_COMMAND} -E env
WAFLOCK=.lock-waf_android_${ANDROID_ABI}_build

View File

@@ -13,10 +13,12 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include <ctype.h>
#include "common.h"
#include "filesystem.h"
#include "client.h"
#include "qfont.h"
#include "utflib.h"
qboolean CL_FixedFont( cl_font_t *font )
{
@@ -173,31 +175,27 @@ static int CL_CalcTabStop( const cl_font_t *font, int x )
return stop;
}
int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_t *font, int flags )
static int CL_DrawBitmapCharacter( float x, float y, uint32_t uc, const rgba_t color, const cl_font_t *font, int flags )
{
wrect_t *rc;
float w, h;
float s1, t1, s2, t2, half = 0.5f;
int texw, texh;
uint32_t number;
if( !font || !font->valid || y < -font->charHeight )
// bitmap fonts need conversion. Do this and validate the result
if( g_codepage == 1251 )
number = Q_UnicodeToCP1251( uc );
else if( g_codepage == 1252 )
number = Q_UnicodeToCP1252( uc );
else
number = uc;
if( !number || number >= ARRAYSIZE( font->charWidths ))
return 0;
// check if printable
if( number <= 32 )
{
if( number == ' ' )
return font->charWidths[' '];
else if( number == '\t' )
return CL_CalcTabStop( font, x );
return 0;
}
if( FBitSet( flags, FONT_DRAW_UTF8 ))
number = Con_UtfProcessChar( number & 255 );
else number &= 255;
if( !number || !font->charWidths[number])
// start rendering
if( !font->charWidths[number] )
return 0;
R_GetTextureParms( &texw, &texh, font->hFontTexture );
@@ -231,29 +229,60 @@ int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_
return font->charWidths[number];
}
int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_t *font, int flags )
static int CL_DrawTrueTypeCharacter( float x, float y, uint32_t uc, const rgba_t color, cl_font_t *font, int flags )
{
// stub
return 0;
}
int CL_DrawCharacter( float x, float y, uint32_t uc, const rgba_t color, const cl_font_t *font, int flags )
{
if( !font || !font->valid || y < -font->charHeight )
return 0;
// check if printable
if( uc <= 32 )
{
if( uc == ' ' )
return font->charWidths[' '];
else if( uc == '\t' )
return CL_CalcTabStop( font, x );
return 0;
}
if( font->type == FONT_TRUETYPE )
return CL_DrawTrueTypeCharacter( x, y, uc, color, font, flags );
return CL_DrawBitmapCharacter( x, y, uc, color, font, flags );
}
int CL_DrawString( float x, float y, const char *s, const rgba_t color, const cl_font_t *font, int flags )
{
rgba_t current_color;
int draw_len = 0;
utfstate_t utfstate = { 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 ))
CL_SetFontRendermode( font );
Vector4Copy( color, current_color );
while( *s )
for( ; *s; s++ )
{
if( *s == '\n' )
{
s++;
uint32_t uc = (byte)*s;
if( !*s )
if( FBitSet( flags, FONT_DRAW_UTF8 ))
uc = Q_DecodeUTF8( &utfstate, uc );
if( !uc )
continue;
if( uc == '\n' )
{
if( !s[1] ) // ignore newline at end of string if next
break;
// some client functions ignore newlines
@@ -264,30 +293,29 @@ int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_
}
if( FBitSet( flags, FONT_DRAW_RESETCOLORONLF ))
Vector4Copy( color, current_color );
Vector4Copy( color, current_color );
continue;
}
if( IsColorString( s ))
// check for colorstrings
if( uc == '^' && isdigit( s[1] ))
{
// don't copy alpha
if( !FBitSet( flags, FONT_DRAW_FORCECOL ))
VectorCopy( g_color_table[ColorIndex(*( s + 1 ))], current_color );
VectorCopy( g_color_table[ColorIndex( s[1] )], current_color );
s += 2;
s++;
continue;
}
// skip setting rendermode, it was changed for this string already
draw_len += CL_DrawCharacter( x + draw_len, y, (byte)*s, current_color, font, flags | FONT_DRAW_NORENDERMODE );
s++;
draw_len += CL_DrawCharacter( x + draw_len, y, uc, current_color, font, flags | FONT_DRAW_NORENDERMODE );
}
return draw_len;
}
int CL_DrawStringf( cl_font_t *font, float x, float y, const rgba_t color, int flags, const char *fmt, ... )
int CL_DrawStringf( const cl_font_t *font, float x, float y, const rgba_t color, int flags, const char *fmt, ... )
{
va_list va;
char buf[MAX_VA_STRING];
@@ -299,20 +327,63 @@ int CL_DrawStringf( cl_font_t *font, float x, float y, const rgba_t color, int f
return CL_DrawString( x, y, buf, color, font, flags );
}
void CL_DrawCharacterLen( cl_font_t *font, int number, int *width, int *height )
static int CL_DrawBitmapCharacterLen( const cl_font_t *font, uint32_t uc )
{
if( !font || !font->valid ) return;
if( width )
{
if( number == '\t' )
*width = CL_CalcTabStop( font, 0 ); // at least return max tabstop
else *width = font->charWidths[number & 255];
}
if( height ) *height = font->charHeight;
int number;
if( g_codepage == 1251 )
number = Q_UnicodeToCP1251( uc );
else if( g_codepage == 1252 )
number = Q_UnicodeToCP1252( uc );
else
number = uc;
if( !number || number >= ARRAYSIZE( font->charWidths ))
return 0;
return font->charWidths[number];
}
void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height, int flags )
static int CL_DrawTrueTypeCharacterLen( const cl_font_t *font, uint32_t uc )
{
// stub
return 0;
}
void CL_DrawCharacterLen( const cl_font_t *font, uint32_t uc, int *width, int *height )
{
if( !font || !font->valid )
return;
if( height )
*height = font->charHeight;
if( width )
{
// basically matches logic of CL_DrawCharacter
if( uc <= 32 )
{
if( uc == ' ' )
*width = font->charWidths[' '];
else if( uc == '\t' )
*width = CL_CalcTabStop( font, 0 ); // at least return max tabstop
else
*width = 0;
}
else if( font->type == FONT_TRUETYPE )
{
*width = CL_DrawTrueTypeCharacterLen( font, uc );
}
else
{
*width = CL_DrawBitmapCharacterLen( font, uc );
}
}
}
void CL_DrawStringLen( const cl_font_t *font, const char *s, int *width, int *height, int flags )
{
utfstate_t utfstate = { 0 };
int draw_len = 0;
if( !font || !font->valid )
@@ -327,54 +398,45 @@ void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height,
if( !COM_CheckString( s ))
return;
if( FBitSet( flags, FONT_DRAW_UTF8 ))
Con_UtfProcessChar( 0 ); // reset utf state
while( *s )
for( ; *s; s++ )
{
int number;
uint32_t uc = (byte)*s;
int char_width = 0;
if( *s == '\n' )
if( FBitSet( flags, FONT_DRAW_UTF8 ))
uc = Q_DecodeUTF8( &utfstate, uc );
if( !uc )
continue;
if( uc == '\n' )
{
// BUG: no check for end string here
// but high chances somebody's relying on this
s++;
draw_len = 0;
// some client functions ignore newlines
if( !FBitSet( flags, FONT_DRAW_NOLF ))
{
if( height )
*height += font->charHeight;
}
continue;
}
else if( *s == '\t' )
// check for colorstrings
if( uc == '^' && isdigit( s[1] ))
{
draw_len += CL_CalcTabStop( font, 0 ); // at least return max tabstop
s++;
continue;
}
if( IsColorString( s ))
CL_DrawCharacterLen( font, uc, &char_width, NULL );
draw_len += char_width;
if( width )
{
s += 2;
continue;
if( *width < draw_len )
*width = draw_len;
}
if( FBitSet( flags, FONT_DRAW_UTF8 ))
number = Con_UtfProcessChar( (byte)*s );
else number = (byte)*s;
if( number )
{
draw_len += font->charWidths[number];
if( width )
{
if( draw_len > *width )
*width = draw_len;
}
}
s++;
}
}

View File

@@ -33,6 +33,7 @@ GNU General Public License for more details.
#include "vgui_draw.h"
#include "sound.h" // SND_STOP_LOOPING
#include "platform/platform.h"
#include "utflib.h"
#define MAX_LINELENGTH 80
#define MAX_TEXTCHANNELS 8 // must be power of two (GoldSrc uses 4 channels)
@@ -408,8 +409,10 @@ void CL_DrawCenterPrint( void )
char *pText;
int i, j, x, y;
int width, lineLength;
byte *colorDefault, line[MAX_LINELENGTH];
byte *colorDefault;
uint32_t line[MAX_LINELENGTH];
int charWidth, charHeight;
utfstate_t utfstate = { 0 };
if( !clgame.centerPrint.time )
return;
@@ -432,14 +435,19 @@ void CL_DrawCenterPrint( void )
lineLength = 0;
width = 0;
while( *pText && *pText != '\n' && lineLength < MAX_LINELENGTH )
for( ; *pText && *pText != '\n' && lineLength < MAX_LINELENGTH; pText++ )
{
byte c = *pText;
line[lineLength] = c;
CL_DrawCharacterLen( font, c, &charWidth, NULL );
uint32_t uc = Q_DecodeUTF8( &utfstate, c );
if( !uc )
continue;
line[lineLength] = uc;
CL_DrawCharacterLen( font, uc, &charWidth, NULL );
width += charWidth;
lineLength++;
pText++;
}
if( lineLength == MAX_LINELENGTH )
@@ -453,7 +461,7 @@ void CL_DrawCenterPrint( void )
for( j = 0; j < lineLength; j++ )
{
if( x >= 0 && y >= 0 && x <= refState.width )
x += CL_DrawCharacter( x, y, line[j], colorDefault, font, FONT_DRAW_UTF8 | FONT_DRAW_HUD | FONT_DRAW_NORENDERMODE );
x += CL_DrawCharacter( x, y, line[j], colorDefault, font, FONT_DRAW_HUD | FONT_DRAW_NORENDERMODE );
}
y += charHeight;
}
@@ -1989,7 +1997,13 @@ static int GAME_EXPORT pfnDrawCharacter( int x, int y, int number, int r, int g,
int flags = FONT_DRAW_HUD;
if( hud_utf8.value )
flags |= FONT_DRAW_UTF8;
{
static utfstate_t utfstate;
number = Q_DecodeUTF8( &utfstate, number );
if( !number )
return 0;
}
return CL_DrawCharacter( x, y, number, color, &cls.creditsFont, flags );
}
@@ -3052,12 +3066,8 @@ pfnDrawString
*/
static int GAME_EXPORT pfnDrawString( int x, int y, const char *str, int r, int g, int b )
{
rgba_t color = { r, g, b, 255 };
int flags = FONT_DRAW_HUD | FONT_DRAW_NOLF;
if( hud_utf8.value )
SetBits( flags, FONT_DRAW_UTF8 );
const rgba_t color = { r, g, b, 255 };
int flags = FONT_DRAW_HUD | FONT_DRAW_NOLF | FONT_DRAW_UTF8;
return CL_DrawString( x, y, str, color, &cls.creditsFont, flags );
}
@@ -3069,13 +3079,10 @@ pfnDrawStringReverse
*/
static int GAME_EXPORT pfnDrawStringReverse( int x, int y, const char *str, int r, int g, int b )
{
rgba_t color = { r, g, b, 255 };
int flags = FONT_DRAW_HUD | FONT_DRAW_NOLF;
const rgba_t color = { r, g, b, 255 };
int flags = FONT_DRAW_HUD | FONT_DRAW_NOLF | FONT_DRAW_UTF8;
int width;
if( hud_utf8.value )
SetBits( flags, FONT_DRAW_UTF8 );
CL_DrawStringLen( &cls.creditsFont, str, &width, NULL, flags );
x -= width;

View File

@@ -1324,10 +1324,21 @@ static int pfnIsCvarReadOnly( const char *name )
return FBitSet( cv->flags, FCVAR_READ_ONLY ) ? 1 : 0;
}
static int GAME_EXPORT pfnUtfProcessChar( int in )
{
// compatibility export, deprecated, do not use
if( !cls.accept_utf8 ) // incoming character is not a UTF-8 sequence
return in;
// otherwise, decode it and convert to selected codepage
return Con_UtfProcessCharForce( in );
}
static ui_extendedfuncs_t gExtendedfuncs =
{
pfnEnableTextInput,
Con_UtfProcessChar,
pfnUtfProcessChar,
Con_UtfMoveLeft,
Con_UtfMoveRight,
pfnGetRenderers,

View File

@@ -98,7 +98,6 @@ CVAR_DEFINE_AUTO( rate, "25000", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE,
static CVAR_DEFINE_AUTO( cl_ticket_generator, "revemu2013", FCVAR_ARCHIVE, "you wouldn't steal a car" );
client_t cl;
client_static_t cls;
clgame_static_t clgame;
@@ -1009,7 +1008,7 @@ static void CL_WriteSteamTicket( sizebuf_t *send )
const char *s;
uint32_t crc;
char buf[768] = { 0 }; // setti and steamemu return 768
size_t i = sizeof( buf );
int i = sizeof( buf );
if( !Q_strcmp( cl_ticket_generator.string, "null" ))
{
@@ -1028,24 +1027,7 @@ static void CL_WriteSteamTicket( sizebuf_t *send )
CRC32_Init( &crc );
CRC32_ProcessBuffer( &crc, s, Q_strlen( s ));
crc = CRC32_Final( crc );
if( !Q_stricmp( cl_ticket_generator.string, "revemu2013" ))
i = GenerateRevEmu2013( buf, crc );
else if( !Q_stricmp( cl_ticket_generator.string, "sc2009" ))
i = GenerateSC2009( buf, crc );
else if( !Q_stricmp( cl_ticket_generator.string, "oldrevemu" ))
i = GenerateOldRevEmu( buf, crc );
else if( !Q_stricmp( cl_ticket_generator.string, "steamemu" ))
i = GenerateSteamEmu( buf, crc );
else if( !Q_stricmp( cl_ticket_generator.string, "revemu" ))
i = GenerateRevEmu( buf, crc );
else if( !Q_stricmp( cl_ticket_generator.string, "setti" ))
i = GenerateSetti( buf );
else if( !Q_stricmp( cl_ticket_generator.string, "avsmp" ))
i = GenerateAVSMP( buf, crc, true );
else
Con_Printf( "%s: unknown generator %s, supported are: null, revemu2003, sc2009, oldrevemu, steamemu, revemu, setti, avsmp\n", __func__, cl_ticket_generator.string );
i = GenerateRevEmu2013( buf, s, crc );
MSG_WriteBytes( send, buf, i );
}

View File

@@ -19,6 +19,7 @@ GNU General Public License for more details.
#include "library.h"
#include "input.h"
#include "platform/platform.h"
#include "utflib.h"
static CVAR_DEFINE_AUTO( vibration_length, "1.0", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "vibration length" );
static CVAR_DEFINE_AUTO( vibration_enable, "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "enable vibration" );
@@ -58,7 +59,13 @@ static int pfnDrawScaledCharacter( int x, int y, int number, int r, int g, int b
int flags = FONT_DRAW_HUD;
if( hud_utf8.value )
SetBits( flags, FONT_DRAW_UTF8 );
{
static utfstate_t utfstate;
number = Q_DecodeUTF8( &utfstate, number );
if( !number )
return 0;
}
if( fabs( g_font_scale - scale ) > 0.1f ||
g_scaled_font.hFontTexture != cls.creditsFont.hFontTexture )

View File

@@ -326,8 +326,12 @@ typedef struct
pfnEventHook func; // user-defined function
} cl_user_event_t;
#define FONT_FIXED 0
#define FONT_VARIABLE 1
enum
{
FONT_FIXED,
FONT_VARIABLE,
FONT_TRUETYPE
};
#define FONT_DRAW_HUD BIT( 0 ) // pass to drawing function to apply hud_scale
#define FONT_DRAW_UTF8 BIT( 1 ) // call UtfProcessChar
@@ -807,11 +811,12 @@ qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float sc
qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font, float scale, convar_t *rendermode, uint texFlags );
void CL_FreeFont( cl_font_t *font );
void CL_SetFontRendermode( cl_font_t *font );
int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_t *font, int flags );
int CL_DrawString( float x, float y, const char *s, const 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 );
int CL_DrawStringf( cl_font_t *font, float x, float y, const rgba_t color, int flags, const char *fmt, ... ) FORMAT_CHECK( 6 );
int CL_DrawCharacter( float x, float y, uint32_t uc, const rgba_t color, const cl_font_t *font, int flags );
void CL_DrawCharacterLen( const cl_font_t *font, uint32_t uc, int *width, int *height );
int CL_DrawString( float x, float y, const char *s, const rgba_t color, const cl_font_t *font, int flags );
int CL_DrawStringf( const cl_font_t *font, float x, float y, const rgba_t color, int flags, const char *fmt, ... ) FORMAT_CHECK( 6 );
void CL_DrawStringLen( const cl_font_t *font, const char *s, int *width, int *height, int flags );
//
@@ -1090,6 +1095,7 @@ void CL_ReadLineFile_f( void );
// console.c
//
extern convar_t con_fontsize;
extern int g_codepage;
int Con_Visible( void );
qboolean Con_FixedFont( void );
void Con_VidInit( void );
@@ -1100,7 +1106,6 @@ void Con_DrawDebug( void );
void Con_RunConsole( void );
void Con_DrawConsole( void );
void Con_DrawVersion( void );
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 );

View File

@@ -34,7 +34,7 @@ static CVAR_DEFINE_AUTO( con_color, "240 180 24", FCVAR_ARCHIVE, "set a custom c
static CVAR_DEFINE_AUTO( scr_drawversion, "1", FCVAR_ARCHIVE, "draw version in menu or screenshots, doesn't affect console" );
static CVAR_DEFINE_AUTO( con_oldfont, "0", 0, "use legacy font from gfx.wad, might be missing or broken" );
static int g_codepage = 0;
int g_codepage = 0;
static qboolean g_messagemode_privileged = true;
@@ -632,15 +632,6 @@ int Con_UtfProcessCharForce( int in )
return '?'; // not implemented yet
}
int GAME_EXPORT Con_UtfProcessChar( int in )
{
if( !cls.accept_utf8 ) // incoming character is not a UTF-8 sequence
return in;
// otherwise, decode it and convert to selected codepage
return Con_UtfProcessCharForce( in );
}
/*
=================
Con_UtfMoveLeft
@@ -1267,45 +1258,16 @@ static void Field_CharEvent( field_t *edit, int ch )
Field_DrawInputLine
==================
*/
static void Field_DrawInputLine( int x, int y, field_t *edit )
static void Field_DrawInputLine( int x, int y, const field_t *edit )
{
int len, cursorChar;
int drawLen;
int prestep, curPos;
char str[MAX_SYSPATH];
byte *colorDefault;
int curPos;
char str[MAX_SYSPATH];
const byte *colorDefault = g_color_table[ColorIndex( COLOR_DEFAULT )];
const int prestep = bound( 0, edit->scroll, sizeof( edit->buffer ) - 1 );
const int drawLen = bound( 0, edit->widthInChars, sizeof( str ));
const int cursorCharPos = bound( 0, edit->cursor - prestep, sizeof( str ));
drawLen = edit->widthInChars;
len = Q_strlen( edit->buffer ) + 1;
colorDefault = g_color_table[ColorIndex( COLOR_DEFAULT )];
// guarantee that cursor will be visible
if( len <= drawLen )
{
prestep = 0;
}
else
{
if( edit->scroll + drawLen > len )
{
edit->scroll = len - drawLen;
if( edit->scroll < 0 ) edit->scroll = 0;
}
prestep = edit->scroll;
}
if( prestep + drawLen > len )
drawLen = len - prestep;
// extract <drawLen> characters from the field at <prestep>
drawLen = Q_min( drawLen, MAX_SYSPATH - 1 );
memcpy( str, edit->buffer + prestep, drawLen );
str[drawLen] = 0;
// save char for overstrike
cursorChar = str[edit->cursor - prestep];
Q_strncpy( str, edit->buffer + prestep, drawLen );
// draw it
CL_DrawString( x, y, str, colorDefault, con.curFont, FONT_DRAW_UTF8 );
@@ -1314,7 +1276,7 @@ static void Field_DrawInputLine( int x, int y, field_t *edit )
if((int)( host.realtime * 4 ) & 1 ) return; // off blink
// calc cursor position
str[edit->cursor - prestep] = 0;
str[cursorCharPos] = 0;
CL_DrawStringLen( con.curFont, str, &curPos, NULL, FONT_DRAW_UTF8 );
if( host.key_overstrike )

View File

@@ -18,6 +18,7 @@ GNU General Public License for more details.
#include "math.h"
#include "vgui_draw.h"
#include "mobility_int.h"
#include "utflib.h"
typedef enum
{
@@ -761,7 +762,7 @@ static void Touch_SetCommand_f( void )
{
touch_button_t *button = Touch_FindButtonNoPattern( &touch.list_user, Cmd_Argv( 1 ), Cmd_CurrentCommandIsPrivileged( ));
if( !button )
if( button )
Touch_SetCommand( button, Cmd_Argv( 2 ) );
else
Con_Printf( S_ERROR "no such button" );
@@ -1298,73 +1299,62 @@ static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 )
}
}
static float Touch_DrawCharacter( float x, float y, int number, float size )
static void Touch_DrawText( float x1, float y1, float x2, float y2, const char *s, byte *color, float size )
{
float s1, s2, t1, t2, width, height;
int w, h;
wrect_t *prc;
float minx, maxy, maxx;
const float scale = TO_SCRN_X( size / 1024.0f );
const float backup_scale = cls.creditsFont.scale;
utfstate_t utfstate = { 0 };
rgba_t current_color;
if( !cls.creditsFont.valid )
return 0;
return;
number &= 255;
number = Con_UtfProcessChar( number );
x1 = TO_SCRN_X( x1 );
y1 = TO_SCRN_Y( y1 );
x2 = TO_SCRN_X( x2 );
y2 = TO_SCRN_Y( y2 );
if( !number )
return 0;
R_GetTextureParms( &w, &h, cls.creditsFont.hFontTexture );
prc = &cls.creditsFont.fontRc[number];
s1 = prc->left / (float)w;
t1 = prc->top / (float)h;
s2 = prc->right / (float)w;
t2 = prc->bottom / (float)h;
width = ( prc->right - prc->left ) / 1024.0f * size;
height = ( prc->bottom - prc->top ) / 1024.0f * size;
ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( x ), TO_SCRN_Y( y ), TO_SCRN_X( width ), TO_SCRN_X( height ),
s1, t1, s2, t2, cls.creditsFont.hFontTexture );
return width;
}
static float Touch_DrawText( float x1, float y1, float x2, float y2, const char *s, byte *color, float size )
{
float x = x1;
float maxy = y2;
float maxx;
float alpha = color[3] / 255.0f;
minx = x1;
maxy = y2;
if( x2 )
maxx = x2 - cls.creditsFont.charWidths['M'] / 1024.0f * size;
maxx = x2 - cls.creditsFont.charWidths['M'] * scale;
else
maxx = 1;
if( !cls.creditsFont.valid )
return GRID_X * 2;
Con_UtfProcessChar( 0 );
ref.dllFuncs.GL_SetRenderMode( kRenderTransAdd );
cls.creditsFont.scale = scale;
// text is additive and alpha does not work
ref.dllFuncs.Color4ub( color[0] * alpha, color[1] * alpha, color[2] * alpha, 255 );
ref.dllFuncs.GL_SetRenderMode( kRenderTransAdd );
VectorScale( color, color[3] / 255.0f, current_color );
current_color[3] = 255;
while( *s )
for( ; *s; s++ )
{
while( *s && ( *s != '\n' ) && ( *s != ';' ) && ( x1 < maxx ))
x1 += Touch_DrawCharacter( x1, y1, *s++, size );
y1 += cls.creditsFont.charHeight / 1024.f * size / Touch_AspectRatio();
int draw_len;
uint32_t uc = Q_DecodeUTF8( &utfstate, (byte)*s );
if( y1 >= maxy )
break;
if( !uc )
continue;
if( *s == '\n' || *s == ';' )
s++;
x1 = x;
if( uc == '\n' || uc == ';' || x1 >= maxx )
{
x1 = minx;
y1 += cls.creditsFont.charHeight * scale;
if( y1 >= maxy )
break;
continue;
}
// because we override font scale without changing charWidths, scale it ourselves
draw_len = CL_DrawCharacter( x1, y1, uc, current_color, &cls.creditsFont, FONT_DRAW_NORENDERMODE );
x1 += draw_len * scale;
}
return x1;
cls.creditsFont.scale = backup_scale;
}
static void Touch_DrawButtons( touchbuttonlist_t *list )

View File

@@ -957,6 +957,7 @@ enum
OSK_ENTER,
OSK_SPECKEY_LAST
};
static const char *osk_keylayout[][4] =
{
{
@@ -973,7 +974,7 @@ static const char *osk_keylayout[][4] =
}
};
struct osk_s
static struct osk_s
{
qboolean enable;
int curlayout;
@@ -1007,7 +1008,6 @@ static qboolean OSK_KeyEvent( int key, int down )
return false;
}
switch ( key )
{
case K_ENTER:
@@ -1050,10 +1050,6 @@ static qboolean OSK_KeyEvent( int key, int down )
ch = (byte)osk.curbutton.val;
// do not pass UTF-8 sequence into the engine, convert it here
if( !cls.accept_utf8 )
ch = Con_UtfProcessCharForce( ch );
if( !ch )
break;
@@ -1188,13 +1184,15 @@ void OSK_Draw( void )
X_STEP * MAX_OSK_ROWS * refState.width,
Y_STEP * MAX_OSK_LINES * refState.height, 100, 100, 100, 100 );
OSK_DrawSpecialButton( "-]", X_START, Y_START + Y_STEP * 2, X_STEP, Y_STEP );
OSK_DrawSpecialButton( "<-", X_START + X_STEP * 12, Y_START + Y_STEP * 2, X_STEP, Y_STEP );
OSK_DrawSpecialButton( "-]", X_START, Y_START + Y_STEP * 2, X_STEP, Y_STEP );
OSK_DrawSpecialButton( "<-", X_START + X_STEP * 12, Y_START + Y_STEP * 2, X_STEP, Y_STEP );
OSK_DrawSpecialButton( "sh", X_START, Y_START + Y_STEP * 3, X_STEP, Y_STEP );
OSK_DrawSpecialButton( "en", X_START + X_STEP * 12, Y_START + Y_STEP * 3, X_STEP, Y_STEP );
for( y = Y_START, j = 0; j < MAX_OSK_LINES; j++, y += Y_STEP )
for( y = Y_START, j = 0; j < MAX_OSK_LINES; j++, y += Y_STEP )
{
for( x = X_START, i = 0; i < MAX_OSK_ROWS; i++, x += X_STEP )
OSK_DrawSymbolButton( curlayout[j][i], x, y, X_STEP, Y_STEP );
}
}

View File

@@ -1236,6 +1236,14 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
Cvar_Getf( "host_ver", FCVAR_READ_ONLY, "detailed info about this build", "%i " XASH_VERSION " %s %s %s", Q_buildnum(), Q_buildos(), Q_buildarch(), g_buildcommit);
Cvar_Getf( "host_lowmemorymode", FCVAR_READ_ONLY, "indicates if engine compiled for low RAM consumption (0 - normal, 1 - low engine limits, 2 - low protocol limits)", "%i", XASH_LOW_MEMORY );
Cvar_Get( "host_hl25_extended_structs",
#if SUPPORT_HL25_EXTENDED_STRUCTS
"1",
#else
"0",
#endif
FCVAR_READ_ONLY, "indicates if engine was compiled with extended msurface_t struct" );
Mod_Init();
NET_Init();
NET_InitMasters();

View File

@@ -844,7 +844,16 @@ static int HTTP_FileProcessStream( httpfile_t *curfile )
if( curfile->downloaded >= curfile->size )
{
HTTP_FreeFile( curfile, false ); // success
// chunked files are finalized in FileSaveReceivedData
if( curfile->compressed && !curfile->chunked )
{
curfile->pfn_process = HTTP_FileDecompress;
curfile->success = true;
}
else
{
HTTP_FreeFile( curfile, false ); // success
}
return 0;
}
}

View File

@@ -177,6 +177,9 @@ def options(opt):
grp.add_option('--enable-profile', action = 'store_true', dest = 'PROFILE_GENERATE', default = False,
help = 'enable profile generating build (stored in xash3d-prof directory) [default: %(default)s]')
grp.add_option('--enable-limited-debuginfo', action = 'store_true', dest = 'LIMITED_DEBUGINFO', default = False,
help = 'only save line debuginfo, useful for release builds [default: %(default)s]')
grp.add_option('--use-profile', action = 'store', dest = 'PROFILE_USE', default = None,
help = 'use profile during build [default: %(default)s]')
@@ -254,7 +257,14 @@ def get_optimization_flags(conf):
# this port don't have stack printing support
cflags.remove('-fasynchronous-unwind-tables')
if conf.env.COMPILER_CC == 'gcc' or conf.env.COMPILER_CC == 'clang' and conf.env.DEST_OS not in ['android']:
if conf.env.COMPILER_CC in ['gcc', 'clang'] and conf.options.LIMITED_DEBUGINFO:
# probably not a good idea to do this, but it should save space on Android builds especially
# that are never going to be run under debugger, but we still want that readable fileline
# info in backtraces
# might enable this for release/fast/fastnative builds in the future
cflags = ['-gline-tables-only' if flag.startswith('-g') else flag for flag in cflags]
if conf.env.COMPILER_CC in ['gcc', 'clang'] and conf.env.DEST_OS not in ['android']:
# HLSDK by default compiles with these options under Linux
# no reason for us to not do the same