Compare commits

..

8 Commits

40 changed files with 482 additions and 530 deletions

6
.gitmodules vendored
View File

@@ -27,13 +27,13 @@
url = https://github.com/FWGS/MultiEmulator url = https://github.com/FWGS/MultiEmulator
[submodule "3rdparty/libogg/libogg"] [submodule "3rdparty/libogg/libogg"]
path = 3rdparty/libogg/libogg path = 3rdparty/libogg/libogg
url = https://github.com/xiph/ogg.git url = https://gitlab.xiph.org/xiph/ogg.git
[submodule "3rdparty/vorbis/vorbis-src"] [submodule "3rdparty/vorbis/vorbis-src"]
path = 3rdparty/vorbis/vorbis-src path = 3rdparty/vorbis/vorbis-src
url = https://github.com/xiph/vorbis.git url = https://gitlab.xiph.org/xiph/vorbis.git
[submodule "3rdparty/opusfile/opusfile"] [submodule "3rdparty/opusfile/opusfile"]
path = 3rdparty/opusfile/opusfile path = 3rdparty/opusfile/opusfile
url = https://github.com/xiph/opusfile.git url = https://gitlab.xiph.org/xiph/opusfile.git
[submodule "3rdparty/libbacktrace/libbacktrace"] [submodule "3rdparty/libbacktrace/libbacktrace"]
path = 3rdparty/libbacktrace/libbacktrace path = 3rdparty/libbacktrace/libbacktrace
url = https://github.com/ianlancetaylor/libbacktrace url = https://github.com/ianlancetaylor/libbacktrace

View File

@@ -874,7 +874,7 @@ To run this mods on specific platforms you may be need to compile libraries from
6. [They Hunger: Route666 Demo](https://yadi.sk/d/XKWCseAPohkG6) by *MadMapper* 6. [They Hunger: Route666 Demo](https://yadi.sk/d/XKWCseAPohkG6) by *MadMapper*
## List of supported mods from mobile_hacks branch of HLSDK Portable by FWGS ## List of supported mods from mobile_hacks branch of HLSDK Portable by FWGS
Currently, fresh Xash3D FWGS builds for Android, PS Vita and Nintendo Switch uses libraries from this branch, so you can play mods below out-of-the-box. Currently, fresh Xash3D FWGS builds uses libraries from this branch, so you can play mods below out-of-the-box.
1. **[Afraid of Monsters](https://www.moddb.com/mods/afraid-of-monsters/downloads/afraid-of-monsters-v1)** 1. **[Afraid of Monsters](https://www.moddb.com/mods/afraid-of-monsters/downloads/afraid-of-monsters-v1)**
2. **[Big Lolly](https://www.moddb.com/mods/big-lolly)** 2. **[Big Lolly](https://www.moddb.com/mods/big-lolly)**

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: * Only for 32-bit engine on 64-bit x86 operating system:
* Enable i386 on your system: `$ sudo dpkg --add-architecture i386`. * 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 `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 libvorbis-dev:i386 libopusfile-dev:i386 libogg-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`.
* Set PKG_CONFIG_PATH environment variable to point at 32-bit libraries: `$ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig`. * 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: * 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 libvorbis-dev libopusfile-dev libogg-dev`. * Install development tools: `$ sudo apt install git build-essential python libsdl2-dev libfreetype6-dev libopus-dev libbz2-dev`.
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`. * Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
##### RedHat/Fedora ##### RedHat/Fedora
* Only for 32-bit engine on 64-bit x86 operating system: * 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 libvorbis-devel.i686 opusfile-devel.i686 libogg-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`.
* Set PKG_CONFIG_PATH environment variable to point at 32-bit libraries: `$ export PKG_CONFIG_PATH=/usr/lib/pkgconfig`. * 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: * 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 libvorbis-devel opusfile-devel libogg-devel`. * Install development tools: `$ sudo dnf install git gcc gcc-c++ SDL2-devel opus-devel freetype-devel bzip2-devel`.
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`. * Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.

View File

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

View File

@@ -86,4 +86,8 @@ GNU General Public License for more details.
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#if defined XASH_SDL && !defined REF_DLL
#include <SDL.h>
#endif
#endif // PORT_H #endif // PORT_H

View File

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

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

View File

@@ -1324,21 +1324,10 @@ static int pfnIsCvarReadOnly( const char *name )
return FBitSet( cv->flags, FCVAR_READ_ONLY ) ? 1 : 0; 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 = static ui_extendedfuncs_t gExtendedfuncs =
{ {
pfnEnableTextInput, pfnEnableTextInput,
pfnUtfProcessChar, Con_UtfProcessChar,
Con_UtfMoveLeft, Con_UtfMoveLeft,
Con_UtfMoveRight, Con_UtfMoveRight,
pfnGetRenderers, pfnGetRenderers,

View File

@@ -68,7 +68,7 @@ CVAR_DEFINE_AUTO( hud_scale_minimal_width, "640", FCVAR_ARCHIVE|FCVAR_LATCH, "if
CVAR_DEFINE_AUTO( cl_solid_players, "1", 0, "Make all players not solid (can't traceline them)" ); CVAR_DEFINE_AUTO( cl_solid_players, "1", 0, "Make all players not solid (can't traceline them)" );
CVAR_DEFINE_AUTO( cl_updaterate, "20", FCVAR_USERINFO|FCVAR_ARCHIVE, "refresh rate of server messages" ); CVAR_DEFINE_AUTO( cl_updaterate, "20", FCVAR_USERINFO|FCVAR_ARCHIVE, "refresh rate of server messages" );
CVAR_DEFINE_AUTO( cl_showevents, "0", FCVAR_ARCHIVE, "show events playback" ); CVAR_DEFINE_AUTO( cl_showevents, "0", FCVAR_ARCHIVE, "show events playback" );
CVAR_DEFINE_AUTO( cl_cmdrate, "30", FCVAR_ARCHIVE, "Max number of command packets sent to server per second" ); CVAR_DEFINE_AUTO( cl_cmdrate, "60", FCVAR_ARCHIVE, "Max number of command packets sent to server per second" );
CVAR_DEFINE( cl_interp, "ex_interp", "0.1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "Interpolate object positions starting this many seconds in past" ); CVAR_DEFINE( cl_interp, "ex_interp", "0.1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "Interpolate object positions starting this many seconds in past" );
CVAR_DEFINE_AUTO( cl_nointerp, "0", 0, "disable interpolation of entities and players" ); CVAR_DEFINE_AUTO( cl_nointerp, "0", 0, "disable interpolation of entities and players" );
static CVAR_DEFINE_AUTO( cl_dlmax, "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "max allowed outcoming fragment size" ); static CVAR_DEFINE_AUTO( cl_dlmax, "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "max allowed outcoming fragment size" );
@@ -94,10 +94,11 @@ static CVAR_DEFINE_AUTO( name, username, FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_PRIN
static CVAR_DEFINE_AUTO( model, "", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player model ('player' is a singleplayer model)" ); static CVAR_DEFINE_AUTO( model, "", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player model ('player' is a singleplayer model)" );
static CVAR_DEFINE_AUTO( topcolor, "0", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player top color" ); static CVAR_DEFINE_AUTO( topcolor, "0", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player top color" );
static CVAR_DEFINE_AUTO( bottomcolor, "0", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player bottom color" ); static CVAR_DEFINE_AUTO( bottomcolor, "0", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player bottom color" );
CVAR_DEFINE_AUTO( rate, "25000", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player network rate" ); CVAR_DEFINE_AUTO( rate, "3500", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player network rate" );
static CVAR_DEFINE_AUTO( cl_ticket_generator, "revemu2013", FCVAR_ARCHIVE, "you wouldn't steal a car" ); static CVAR_DEFINE_AUTO( cl_ticket_generator, "revemu2013", FCVAR_ARCHIVE, "you wouldn't steal a car" );
client_t cl; client_t cl;
client_static_t cls; client_static_t cls;
clgame_static_t clgame; clgame_static_t clgame;
@@ -1008,7 +1009,7 @@ static void CL_WriteSteamTicket( sizebuf_t *send )
const char *s; const char *s;
uint32_t crc; uint32_t crc;
char buf[768] = { 0 }; // setti and steamemu return 768 char buf[768] = { 0 }; // setti and steamemu return 768
int i = sizeof( buf ); size_t i = sizeof( buf );
if( !Q_strcmp( cl_ticket_generator.string, "null" )) if( !Q_strcmp( cl_ticket_generator.string, "null" ))
{ {
@@ -1027,7 +1028,24 @@ static void CL_WriteSteamTicket( sizebuf_t *send )
CRC32_Init( &crc ); CRC32_Init( &crc );
CRC32_ProcessBuffer( &crc, s, Q_strlen( s )); CRC32_ProcessBuffer( &crc, s, Q_strlen( s ));
crc = CRC32_Final( crc ); crc = CRC32_Final( crc );
i = GenerateRevEmu2013( buf, s, 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 );
MSG_WriteBytes( send, buf, i ); MSG_WriteBytes( send, buf, i );
} }
@@ -1165,11 +1183,7 @@ Returns bandwidth test fragment size
*/ */
static int CL_GetTestFragmentSize( void ) static int CL_GetTestFragmentSize( void )
{ {
// const int fragmentSizes[CL_TEST_RETRIES] = { 64000, 32000, 10666, 5200, 1400 }; const int fragmentSizes[CL_TEST_RETRIES] = { 64000, 32000, 10666, 5200, 1400 };
// it turns out, even if we pass the bandwidth test, it doesn't mean we can use such large fragments
// as a temporary solution, use smaller fragment sizes
const int fragmentSizes[CL_TEST_RETRIES] = { 1400, 1200, 1000, 800, 508 };
if( cls.connect_retry >= 0 && cls.connect_retry < CL_TEST_RETRIES ) if( cls.connect_retry >= 0 && cls.connect_retry < CL_TEST_RETRIES )
return bound( FRAGMENT_MIN_SIZE, fragmentSizes[cls.connect_retry], FRAGMENT_MAX_SIZE ); return bound( FRAGMENT_MIN_SIZE, fragmentSizes[cls.connect_retry], FRAGMENT_MAX_SIZE );
else else

View File

@@ -19,7 +19,6 @@ GNU General Public License for more details.
#include "library.h" #include "library.h"
#include "input.h" #include "input.h"
#include "platform/platform.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_length, "1.0", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "vibration length" );
static CVAR_DEFINE_AUTO( vibration_enable, "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "enable vibration" ); static CVAR_DEFINE_AUTO( vibration_enable, "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "enable vibration" );
@@ -59,13 +58,7 @@ static int pfnDrawScaledCharacter( int x, int y, int number, int r, int g, int b
int flags = FONT_DRAW_HUD; int flags = FONT_DRAW_HUD;
if( hud_utf8.value ) 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 || if( fabs( g_font_scale - scale ) > 0.1f ||
g_scaled_font.hFontTexture != cls.creditsFont.hFontTexture ) g_scaled_font.hFontTexture != cls.creditsFont.hFontTexture )

View File

@@ -326,12 +326,8 @@ typedef struct
pfnEventHook func; // user-defined function pfnEventHook func; // user-defined function
} cl_user_event_t; } cl_user_event_t;
enum #define FONT_FIXED 0
{ #define FONT_VARIABLE 1
FONT_FIXED,
FONT_VARIABLE,
FONT_TRUETYPE
};
#define FONT_DRAW_HUD BIT( 0 ) // pass to drawing function to apply hud_scale #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_UTF8 BIT( 1 ) // call UtfProcessChar
@@ -811,12 +807,11 @@ 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 ); 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_FreeFont( cl_font_t *font );
void CL_SetFontRendermode( cl_font_t *font ); void CL_SetFontRendermode( cl_font_t *font );
int CL_DrawCharacter( float x, float y, uint32_t uc, const rgba_t color, const cl_font_t *font, int flags ); int CL_DrawCharacter( float x, float y, int number, const rgba_t color, 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, cl_font_t *font, int flags );
void CL_DrawCharacterLen( cl_font_t *font, int number, 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 ); void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height, 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 ); int CL_DrawStringf( 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 );
// //
@@ -1095,7 +1090,6 @@ void CL_ReadLineFile_f( void );
// console.c // console.c
// //
extern convar_t con_fontsize; extern convar_t con_fontsize;
extern int g_codepage;
int Con_Visible( void ); int Con_Visible( void );
qboolean Con_FixedFont( void ); qboolean Con_FixedFont( void );
void Con_VidInit( void ); void Con_VidInit( void );
@@ -1106,6 +1100,7 @@ void Con_DrawDebug( void );
void Con_RunConsole( void ); void Con_RunConsole( void );
void Con_DrawConsole( void ); void Con_DrawConsole( void );
void Con_DrawVersion( void ); void Con_DrawVersion( void );
int Con_UtfProcessChar( int in );
int Con_UtfProcessCharForce( int in ); int Con_UtfProcessCharForce( int in );
int Con_UtfMoveLeft( char *str, int pos ); int Con_UtfMoveLeft( char *str, int pos );
int Con_UtfMoveRight( char *str, int pos, int length ); 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( 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 CVAR_DEFINE_AUTO( con_oldfont, "0", 0, "use legacy font from gfx.wad, might be missing or broken" );
int g_codepage = 0; static int g_codepage = 0;
static qboolean g_messagemode_privileged = true; static qboolean g_messagemode_privileged = true;
@@ -632,6 +632,15 @@ int Con_UtfProcessCharForce( int in )
return '?'; // not implemented yet 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 Con_UtfMoveLeft
@@ -1258,16 +1267,45 @@ static void Field_CharEvent( field_t *edit, int ch )
Field_DrawInputLine Field_DrawInputLine
================== ==================
*/ */
static void Field_DrawInputLine( int x, int y, const field_t *edit ) static void Field_DrawInputLine( int x, int y, field_t *edit )
{ {
int curPos; int len, cursorChar;
char str[MAX_SYSPATH]; int drawLen;
const byte *colorDefault = g_color_table[ColorIndex( COLOR_DEFAULT )]; int prestep, curPos;
const int prestep = bound( 0, edit->scroll, sizeof( edit->buffer ) - 1 ); char str[MAX_SYSPATH];
const int drawLen = bound( 0, edit->widthInChars, sizeof( str )); byte *colorDefault;
const int cursorCharPos = bound( 0, edit->cursor - prestep, sizeof( str ));
Q_strncpy( str, edit->buffer + prestep, drawLen ); 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];
// draw it // draw it
CL_DrawString( x, y, str, colorDefault, con.curFont, FONT_DRAW_UTF8 ); CL_DrawString( x, y, str, colorDefault, con.curFont, FONT_DRAW_UTF8 );
@@ -1276,7 +1314,7 @@ static void Field_DrawInputLine( int x, int y, const field_t *edit )
if((int)( host.realtime * 4 ) & 1 ) return; // off blink if((int)( host.realtime * 4 ) & 1 ) return; // off blink
// calc cursor position // calc cursor position
str[cursorCharPos] = 0; str[edit->cursor - prestep] = 0;
CL_DrawStringLen( con.curFont, str, &curPos, NULL, FONT_DRAW_UTF8 ); CL_DrawStringLen( con.curFont, str, &curPos, NULL, FONT_DRAW_UTF8 );
if( host.key_overstrike ) if( host.key_overstrike )
@@ -1993,7 +2031,7 @@ void Con_DrawVersion( void )
int start, height = refState.height; int start, height = refState.height;
string curbuild; string curbuild;
if( !scr_drawversion.value ) if( !scr_drawversion.value || CL_IsDevOverviewMode() == 2 || net_graph.value )
return; return;
if( cls.key_dest == key_menu ) if( cls.key_dest == key_menu )
@@ -2005,9 +2043,6 @@ void Con_DrawVersion( void )
{ {
qboolean draw_version; qboolean draw_version;
if( CL_IsDevOverviewMode() == 2 || net_graph.value )
return;
draw_version = cls.scrshot_action == scrshot_normal draw_version = cls.scrshot_action == scrshot_normal
|| cls.scrshot_action == scrshot_snapshot || cls.scrshot_action == scrshot_snapshot
|| host.force_draw_version_time > host.realtime; || host.force_draw_version_time > host.realtime;

View File

@@ -18,7 +18,6 @@ GNU General Public License for more details.
#include "math.h" #include "math.h"
#include "vgui_draw.h" #include "vgui_draw.h"
#include "mobility_int.h" #include "mobility_int.h"
#include "utflib.h"
typedef enum typedef enum
{ {
@@ -762,7 +761,7 @@ static void Touch_SetCommand_f( void )
{ {
touch_button_t *button = Touch_FindButtonNoPattern( &touch.list_user, Cmd_Argv( 1 ), Cmd_CurrentCommandIsPrivileged( )); touch_button_t *button = Touch_FindButtonNoPattern( &touch.list_user, Cmd_Argv( 1 ), Cmd_CurrentCommandIsPrivileged( ));
if( button ) if( !button )
Touch_SetCommand( button, Cmd_Argv( 2 ) ); Touch_SetCommand( button, Cmd_Argv( 2 ) );
else else
Con_Printf( S_ERROR "no such button" ); Con_Printf( S_ERROR "no such button" );
@@ -939,7 +938,7 @@ static void Touch_AddButton_f( void )
// to let imagelib choose better format // to let imagelib choose better format
// //
// Remove this when old engine migration would be done // Remove this when old engine migration would be done
if( !Q_stricmp( COM_FileExtension( texture ), "tga" )) if( Q_stricmp( COM_FileExtension( texture ), "tga" ))
COM_StripExtension( texture ); COM_StripExtension( texture );
if( Cmd_Argc( ) >= 8 ) if( Cmd_Argc( ) >= 8 )
@@ -1181,6 +1180,14 @@ void Touch_Init( void )
Cvar_RegisterVariable( &touch_enable ); Cvar_RegisterVariable( &touch_enable );
Cvar_RegisterVariable( &touch_emulate ); Cvar_RegisterVariable( &touch_emulate );
// TODO: touch platform
#if SDL_VERSION_ATLEAST( 2, 0, 10 )
SDL_SetHint( SDL_HINT_MOUSE_TOUCH_EVENTS, "0" );
SDL_SetHint( SDL_HINT_TOUCH_MOUSE_EVENTS, "0" );
#elif defined( SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH )
SDL_SetHint( SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1" );
#endif
touch.initialized = true; touch.initialized = true;
} }
@@ -1299,62 +1306,73 @@ static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 )
} }
} }
static void Touch_DrawText( float x1, float y1, float x2, float y2, const char *s, byte *color, float size ) static float Touch_DrawCharacter( float x, float y, int number, float size )
{ {
float minx, maxy, maxx; float s1, s2, t1, t2, width, height;
const float scale = TO_SCRN_X( size / 1024.0f ); int w, h;
const float backup_scale = cls.creditsFont.scale; wrect_t *prc;
utfstate_t utfstate = { 0 };
rgba_t current_color;
if( !cls.creditsFont.valid ) if( !cls.creditsFont.valid )
return; return 0;
x1 = TO_SCRN_X( x1 ); number &= 255;
y1 = TO_SCRN_Y( y1 ); number = Con_UtfProcessChar( number );
x2 = TO_SCRN_X( x2 );
y2 = TO_SCRN_Y( y2 );
minx = x1; if( !number )
maxy = y2; 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;
if( x2 ) if( x2 )
maxx = x2 - cls.creditsFont.charWidths['M'] * scale; maxx = x2 - cls.creditsFont.charWidths['M'] / 1024.0f * size;
else else
maxx = 1; maxx = 1;
cls.creditsFont.scale = scale; if( !cls.creditsFont.valid )
return GRID_X * 2;
Con_UtfProcessChar( 0 );
ref.dllFuncs.GL_SetRenderMode( kRenderTransAdd );
// text is additive and alpha does not work // text is additive and alpha does not work
ref.dllFuncs.GL_SetRenderMode( kRenderTransAdd ); ref.dllFuncs.Color4ub( color[0] * alpha, color[1] * alpha, color[2] * alpha, 255 );
VectorScale( color, color[3] / 255.0f, current_color );
current_color[3] = 255;
for( ; *s; s++ ) while( *s )
{ {
int draw_len; while( *s && ( *s != '\n' ) && ( *s != ';' ) && ( x1 < maxx ))
uint32_t uc = Q_DecodeUTF8( &utfstate, (byte)*s ); x1 += Touch_DrawCharacter( x1, y1, *s++, size );
y1 += cls.creditsFont.charHeight / 1024.f * size / Touch_AspectRatio();
if( !uc ) if( y1 >= maxy )
continue; break;
if( uc == '\n' || uc == ';' || x1 >= maxx ) if( *s == '\n' || *s == ';' )
{ s++;
x1 = minx; x1 = x;
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 ) static void Touch_DrawButtons( touchbuttonlist_t *list )

View File

@@ -205,10 +205,9 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
} }
} }
void IN_SetRelativeMouseMode( qboolean set ) static void IN_SetRelativeMouseMode( qboolean set, qboolean verbose )
{ {
static qboolean s_bRawInput; static qboolean s_bRawInput;
qboolean verbose = m_grab_debug.value ? true : false;
if( set && !s_bRawInput ) if( set && !s_bRawInput )
{ {
@@ -232,10 +231,9 @@ void IN_SetRelativeMouseMode( qboolean set )
} }
} }
void IN_SetMouseGrab( qboolean set ) static void IN_SetMouseGrab( qboolean set, qboolean verbose )
{ {
static qboolean s_bMouseGrab; static qboolean s_bMouseGrab;
qboolean verbose = m_grab_debug.value ? true : false;
if( set && !s_bMouseGrab ) if( set && !s_bMouseGrab )
{ {
@@ -260,7 +258,7 @@ void IN_SetMouseGrab( qboolean set )
static void IN_CheckMouseState( qboolean active ) static void IN_CheckMouseState( qboolean active )
{ {
qboolean use_raw_input; qboolean use_raw_input, verbose;
#if XASH_WIN32 #if XASH_WIN32
use_raw_input = ( m_rawinput.value && clgame.client_dll_uses_sdl ) || clgame.dllFuncs.pfnLookEvent != NULL; use_raw_input = ( m_rawinput.value && clgame.client_dll_uses_sdl ) || clgame.dllFuncs.pfnLookEvent != NULL;
@@ -268,18 +266,20 @@ static void IN_CheckMouseState( qboolean active )
use_raw_input = true; // always use SDL code use_raw_input = true; // always use SDL code
#endif #endif
verbose = m_grab_debug.value ? true : false;
if( m_ignore.value ) if( m_ignore.value )
active = false; active = false;
if( active && use_raw_input && !host.mouse_visible && cls.state == ca_active ) if( active && use_raw_input && !host.mouse_visible && cls.state == ca_active )
IN_SetRelativeMouseMode( true ); IN_SetRelativeMouseMode( true, verbose );
else else
IN_SetRelativeMouseMode( false ); IN_SetRelativeMouseMode( false, verbose );
if( active && !host.mouse_visible && cls.state == ca_active ) if( active && !host.mouse_visible && cls.state == ca_active )
IN_SetMouseGrab( true ); IN_SetMouseGrab( true, verbose );
else else
IN_SetMouseGrab( false ); IN_SetMouseGrab( false, verbose );
} }
/* /*

View File

@@ -46,9 +46,6 @@ uint IN_CollectInputDevices( void );
void IN_LockInputDevices( qboolean lock ); void IN_LockInputDevices( qboolean lock );
void IN_EngineAppendMove( float frametime, usercmd_t *cmd, qboolean active ); void IN_EngineAppendMove( float frametime, usercmd_t *cmd, qboolean active );
void IN_SetRelativeMouseMode( qboolean set );
void IN_SetMouseGrab( qboolean set );
extern convar_t m_yaw; extern convar_t m_yaw;
extern convar_t m_pitch; extern convar_t m_pitch;
// //

View File

@@ -957,7 +957,6 @@ enum
OSK_ENTER, OSK_ENTER,
OSK_SPECKEY_LAST OSK_SPECKEY_LAST
}; };
static const char *osk_keylayout[][4] = static const char *osk_keylayout[][4] =
{ {
{ {
@@ -974,7 +973,7 @@ static const char *osk_keylayout[][4] =
} }
}; };
static struct osk_s struct osk_s
{ {
qboolean enable; qboolean enable;
int curlayout; int curlayout;
@@ -1008,6 +1007,7 @@ static qboolean OSK_KeyEvent( int key, int down )
return false; return false;
} }
switch ( key ) switch ( key )
{ {
case K_ENTER: case K_ENTER:
@@ -1050,6 +1050,10 @@ static qboolean OSK_KeyEvent( int key, int down )
ch = (byte)osk.curbutton.val; 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 ) if( !ch )
break; break;
@@ -1184,15 +1188,13 @@ void OSK_Draw( void )
X_STEP * MAX_OSK_ROWS * refState.width, X_STEP * MAX_OSK_ROWS * refState.width,
Y_STEP * MAX_OSK_LINES * refState.height, 100, 100, 100, 100 ); 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, 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 + 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( "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 ); 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 ) 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 ); OSK_DrawSymbolButton( curlayout[j][i], x, y, X_STEP, Y_STEP );
}
} }

View File

@@ -16,10 +16,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
*/ */
#if XASH_SDL
#include <SDL.h> // SDL_GetBasePath
#endif
#include <errno.h> #include <errno.h>
#include "common.h" #include "common.h"
#include "library.h" #include "library.h"

View File

@@ -1236,14 +1236,6 @@ 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_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_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(); Mod_Init();
NET_Init(); NET_Init();
NET_InitMasters(); NET_InitMasters();

View File

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

View File

@@ -2027,7 +2027,6 @@ void NET_Init( void )
Cvar_RegisterVariable( &net_fakelag ); Cvar_RegisterVariable( &net_fakelag );
Cvar_RegisterVariable( &net_fakeloss ); Cvar_RegisterVariable( &net_fakeloss );
Cvar_RegisterVariable( &net_resolve_debug ); Cvar_RegisterVariable( &net_resolve_debug );
Cvar_RegisterVariable( &net_clockwindow );
Q_snprintf( cmd, sizeof( cmd ), "%i", PORT_SERVER ); Q_snprintf( cmd, sizeof( cmd ), "%i", PORT_SERVER );
Cvar_FullSet( "hostport", cmd, FCVAR_READ_ONLY ); Cvar_FullSet( "hostport", cmd, FCVAR_READ_ONLY );

View File

@@ -142,10 +142,17 @@ static qboolean vsync;
void GL_UpdateSwapInterval( void ) void GL_UpdateSwapInterval( void )
{ {
if( FBitSet( gl_vsync.flags, FCVAR_CHANGED )) // disable VSync while level is loading
if( cls.state < ca_active )
{ {
ClearBits( gl_vsync.flags, FCVAR_CHANGED ); // setup vsync here
vsync = gl_vsync.value; vsync = false;
SetBits( gl_vsync->flags, FCVAR_CHANGED );
}
else if( FBitSet( gl_vsync->flags, FCVAR_CHANGED ))
{
ClearBits( gl_vsync->flags, FCVAR_CHANGED );
vsync = true;
} }
} }

View File

@@ -161,10 +161,17 @@ void* GL_GetProcAddress( const char *name ) // RenderAPI requirement
void GL_UpdateSwapInterval( void ) void GL_UpdateSwapInterval( void )
{ {
if( FBitSet( gl_vsync.flags, FCVAR_CHANGED )) // disable VSync while level is loading
if( cls.state < ca_active )
{
// setup fb vsync here
fb.vsync = false;
SetBits( gl_vsync.flags, FCVAR_CHANGED );
}
else if( FBitSet( gl_vsync.flags, FCVAR_CHANGED ))
{ {
ClearBits( gl_vsync.flags, FCVAR_CHANGED ); ClearBits( gl_vsync.flags, FCVAR_CHANGED );
fb.vsync = gl_vsync.value; fb.vsync = true;
} }
} }

View File

@@ -31,7 +31,6 @@ GNU General Public License for more details.
============================================================================== ==============================================================================
*/ */
double Platform_DoubleTime( void ); double Platform_DoubleTime( void );
void Platform_Sleep( int msec );
void Platform_ShellExecute( const char *path, const char *parms ); void Platform_ShellExecute( const char *path, const char *parms );
void Platform_MessageBox( const char *title, const char *message, qboolean parentMainWindow ); void Platform_MessageBox( const char *title, const char *message, qboolean parentMainWindow );
void Platform_SetStatus( const char *status ); void Platform_SetStatus( const char *status );
@@ -169,6 +168,19 @@ static inline void Platform_SetupSigtermHandling( void )
#endif #endif
} }
static inline void Platform_Sleep( int msec )
{
#if XASH_TIMER == TIMER_SDL
SDL_Delay( msec );
#elif XASH_TIMER == TIMER_POSIX
usleep( msec * 1000 );
#elif XASH_TIMER == TIMER_WIN32
Sleep( msec );
#else
// stub
#endif
}
static inline qboolean Platform_NanoSleep( int nsec ) static inline qboolean Platform_NanoSleep( int nsec )
{ {
// SDL2 doesn't have nanosleep, so use low-level functions here // SDL2 doesn't have nanosleep, so use low-level functions here

View File

@@ -17,10 +17,9 @@ GNU General Public License for more details.
// have backtrace() and backtrace_symbols() calls, which replace for us // have backtrace() and backtrace_symbols() calls, which replace for us
// platform-specific code // platform-specific code
#if HAVE_EXECINFO #if HAVE_EXECINFO
#include "common.h"
#include <execinfo.h> #include <execinfo.h>
#include <signal.h> #include <signal.h>
#include "common.h"
#include "input.h"
void Sys_Crash( int signal, siginfo_t *si, void *context ) void Sys_Crash( int signal, siginfo_t *si, void *context )
{ {
@@ -71,8 +70,8 @@ void Sys_Crash( int signal, siginfo_t *si, void *context )
// put MessageBox as Sys_Error // put MessageBox as Sys_Error
Msg( "%s\n", message ); Msg( "%s\n", message );
#if !XASH_DEDICATED #ifdef XASH_SDL
IN_SetMouseGrab( false ); SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
#endif #endif
host.crashed = true; host.crashed = true;
Platform_MessageBox( "Xash Error", message, false ); Platform_MessageBox( "Xash Error", message, false );

View File

@@ -17,7 +17,7 @@ GNU General Public License for more details.
#include <signal.h> #include <signal.h>
#include "common.h" #include "common.h"
#include "backtrace.h" #include "backtrace.h"
#include "input.h"
static struct backtrace_state *g_bt_state; static struct backtrace_state *g_bt_state;
static qboolean enable_libbacktrace; static qboolean enable_libbacktrace;
@@ -111,10 +111,8 @@ static int Sys_BacktracePrintFull( void *data, uintptr_t pc, const char *filenam
module_name = dlinfo.dli_fname; module_name = dlinfo.dli_fname;
else module_name = NULL; else module_name = NULL;
if( filename && lineno >= 0 && function ) if( filename && lineno && function )
{ {
filename = COM_FileWithoutPath( filename );
if( module_name ) if( module_name )
Sys_AppendPrint( pd, "%2d: %s (%s:%d) (%s)\n", pd->idx++, function, filename, lineno, module_name ); Sys_AppendPrint( pd, "%2d: %s (%s:%d) (%s)\n", pd->idx++, function, filename, lineno, module_name );
else else
@@ -164,8 +162,8 @@ void Sys_CrashLibbacktrace( int signal, siginfo_t *si, void *context )
// put MessageBox as Sys_Error // put MessageBox as Sys_Error
Msg( "%s\n", message ); Msg( "%s\n", message );
#if !XASH_DEDICATED #ifdef XASH_SDL
IN_SetMouseGrab( false ); SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
#endif #endif
host.crashed = true; host.crashed = true;
Platform_MessageBox( "Xash Error", message, false ); Platform_MessageBox( "Xash Error", message, false );

View File

@@ -26,7 +26,6 @@ GNU General Public License for more details.
#include <signal.h> #include <signal.h>
#include <sys/mman.h> #include <sys/mman.h>
#include "library.h" #include "library.h"
#include "input.h"
void Sys_Crash( int signal, siginfo_t *si, void *context ); void Sys_Crash( int signal, siginfo_t *si, void *context );
void Sys_CrashLibbacktrace( int signal, siginfo_t *si, void *context ); void Sys_CrashLibbacktrace( int signal, siginfo_t *si, void *context );
@@ -193,8 +192,8 @@ void Sys_Crash( int signal, siginfo_t *si, void *context )
// put MessageBox as Sys_Error // put MessageBox as Sys_Error
Msg( "%s\n", message ); Msg( "%s\n", message );
#if !XASH_DEDICATED #ifdef XASH_SDL
IN_SetMouseGrab( false ); SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
#endif #endif
host.crashed = true; host.crashed = true;
Platform_MessageBox( "Xash Error", message, false ); Platform_MessageBox( "Xash Error", message, false );

View File

@@ -174,10 +174,5 @@ double Platform_DoubleTime( void )
#endif #endif
return (double) ts.tv_sec + (double) ts.tv_nsec/1000000000.0; return (double) ts.tv_sec + (double) ts.tv_nsec/1000000000.0;
} }
void Platform_Sleep( int msec )
{
usleep( msec * 1000 );
}
#endif // XASH_TIMER == TIMER_POSIX #endif // XASH_TIMER == TIMER_POSIX

View File

@@ -32,11 +32,6 @@ double Platform_DoubleTime( void )
CurrentTime = SDL_GetPerformanceCounter(); CurrentTime = SDL_GetPerformanceCounter();
return (double)( CurrentTime - g_ClockStart ) / (double)( g_PerformanceFrequency ); return (double)( CurrentTime - g_ClockStart ) / (double)( g_PerformanceFrequency );
} }
void Platform_Sleep( int msec )
{
SDL_Delay( msec );
}
#endif // XASH_TIMER == TIMER_SDL #endif // XASH_TIMER == TIMER_SDL
#if XASH_MESSAGEBOX == MSGBOX_SDL #if XASH_MESSAGEBOX == MSGBOX_SDL
@@ -114,11 +109,8 @@ void SDLash_Init( const char *basedir )
host.type = HOST_DEDICATED; host.type = HOST_DEDICATED;
} }
#if SDL_MAJOR_VERSION >= 2 #if XASH_SDL == 2
SDL_SetHint( SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0" ); SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0");
SDL_SetHint( SDL_HINT_MOUSE_TOUCH_EVENTS, "0" );
SDL_SetHint( SDL_HINT_TOUCH_MOUSE_EVENTS, "0" );
SDL_StopTextInput(); SDL_StopTextInput();
#endif // XASH_SDL == 2 #endif // XASH_SDL == 2

View File

@@ -488,7 +488,13 @@ GL_UpdateSwapInterval
void GL_UpdateSwapInterval( void ) void GL_UpdateSwapInterval( void )
{ {
#if SDL_VERSION_ATLEAST( 2, 0, 0 ) #if SDL_VERSION_ATLEAST( 2, 0, 0 )
if( FBitSet( gl_vsync.flags, FCVAR_CHANGED )) // disable VSync while level is loading
if( cls.state < ca_active )
{
SDL_GL_SetSwapInterval( 0 );
SetBits( gl_vsync.flags, FCVAR_CHANGED );
}
else if( FBitSet( gl_vsync.flags, FCVAR_CHANGED ))
{ {
ClearBits( gl_vsync.flags, FCVAR_CHANGED ); ClearBits( gl_vsync.flags, FCVAR_CHANGED );

View File

@@ -14,15 +14,11 @@ GNU General Public License for more details.
*/ */
#include "platform/platform.h" #include "platform/platform.h"
#include "input.h"
#define DBGHELP 1 // we always enable dbghelp.dll on Windows targets #define DBGHELP 1 // we always enable dbghelp.dll on Windows targets
#if XASH_SDL
#include <SDL.h>
#endif // XASH_SDL
#if DBGHELP #if DBGHELP
#include <winnt.h> #include <winnt.h>
#include <dbghelp.h> #include <dbghelp.h>
#include <psapi.h> #include <psapi.h>
@@ -272,8 +268,8 @@ static long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
// check to avoid recursive call // check to avoid recursive call
host.crashed = true; host.crashed = true;
#if !XASH_DEDICATED #ifdef XASH_SDL
IN_SetMouseGrab( false ); SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
#endif // XASH_SDL #endif // XASH_SDL
#if DBGHELP #if DBGHELP

View File

@@ -36,11 +36,6 @@ double Platform_DoubleTime( void )
return (double)( CurrentTime.QuadPart - g_ClockStart.QuadPart ) / (double)( g_PerformanceFrequency.QuadPart ); return (double)( CurrentTime.QuadPart - g_ClockStart.QuadPart ) / (double)( g_PerformanceFrequency.QuadPart );
} }
void Platform_Sleep( int msec )
{
Sleep( msec );
}
#endif // XASH_TIMER == TIMER_WIN32 #endif // XASH_TIMER == TIMER_WIN32
void Win32_Init( qboolean con_showalways ) void Win32_Init( qboolean con_showalways )

View File

@@ -205,62 +205,69 @@ typedef struct
typedef struct sv_client_s typedef struct sv_client_s
{ {
cl_state_t state; cl_state_t state;
cl_upload_t upstate; // uploading state cl_upload_t upstate; // uploading state
char name[32]; // extracted from userinfo, color string allowed char name[32]; // extracted from userinfo, color string allowed
uint flags; // client flags, some info uint flags; // client flags, some info
uint extensions; // protocol extensions CRC32_t crcValue;
char hashedcdkey[34]; // MD5 hash is 32 hex #'s, plus trailing 0 char userinfo[MAX_INFO_STRING]; // name, etc (received from client)
char userinfo[MAX_INFO_STRING]; // name, etc (received from client) char physinfo[MAX_INFO_STRING]; // set on server (transmit to client)
char physinfo[MAX_INFO_STRING]; // set on server (transmit to client)
char useragent[MAX_INFO_STRING];
byte ignorecmdtime_warned; // did we warn our server operator in the log for this batch of commands? netchan_t netchan;
byte m_bLoopback; // does this client want to hear his own voice? int chokecount; // number of messages rate supressed
uint listeners; // which other clients does this guy's voice stream go to? int delta_sequence; // -1 = no compression.
double next_messagetime; // time when we should send next world state update
double next_checkpingtime; // time to send all players pings to client
double next_sendinfotime; // time to send info about all players
double cl_updaterate; // client requested updaterate
double timebase; // client timebase
double connection_started;
char hashedcdkey[34]; // MD5 hash is 32 hex #'s, plus trailing 0
customization_t customdata; // player customization linked list
resource_t resourcesonhand;
resource_t resourcesneeded; // <mapname.res> from client (server downloading)
usercmd_t lastcmd; // for filling in big drops
double connecttime;
double cmdtime;
double ignorecmdtime;
int packet_loss;
float latency;
int ignored_ents; // if visibility list is full we should know how many entities will be ignored
edict_t *edict; // EDICT_NUM(clientnum+1)
edict_t *pViewEntity; // svc_setview member
edict_t *viewentity[MAX_VIEWENTS]; // list of portal cameras in player PVS
int num_viewents; // num of portal cameras that can merge PVS
qboolean m_bLoopback; // Does this client want to hear his own voice?
uint listeners; // which other clients does this guy's voice stream go to?
// the datagram is written to by sound calls, prints, temp ents, etc.
// it can be harmlessly overflowed.
sizebuf_t datagram;
byte datagram_buf[MAX_DATAGRAM];
client_frame_t *frames; // updates can be delta'd from here
event_state_t events; // delta-updated events cycle
int challenge; // challenge of this user, randomly generated
int userid; // identifying number on server
int extensions;
char useragent[MAX_INFO_STRING];
int ignorecmdtime_warns; // how many times client time was faster than server during this session int ignorecmdtime_warns; // how many times client time was faster than server during this session
int userid; // identifying number on server qboolean ignorecmdtime_warned; // did we warn our server operator in the log for this batch of commands?
netchan_t netchan;
sizebuf_t datagram; // the datagram is written to by sound calls, prints, temp ents, etc.
byte datagram_buf[MAX_DATAGRAM]; // it can be harmlessly overflowed.
int chokecount; // number of messages rate supressed
int delta_sequence; // -1 = no compression.
double next_messagetime; // time when we should send next world state update
double next_checkpingtime; // time to send all players pings to client
double next_sendinfotime; // time to send info about all players
double cl_updaterate; // client requested updaterate
double timebase; // client timebase
double connection_started;
customization_t customdata; // player customization linked list
resource_t resourcesonhand;
resource_t resourcesneeded; // <mapname.res> from client (server downloading)
usercmd_t lastcmd; // for filling in big drops
int packet_loss;
double connecttime;
double cmdtime;
double ignorecmdtime;
float latency;
int ignored_ents; // if visibility list is full we should know how many entities will be ignored
edict_t *edict; // EDICT_NUM(clientnum+1)
edict_t *pViewEntity; // svc_setview member
edict_t *viewentity[MAX_VIEWENTS]; // list of portal cameras in player PVS
int num_viewents; // num of portal cameras that can merge PVS
int userinfo_change_attempts;
double fullupdate_next_calltime; double fullupdate_next_calltime;
double userinfo_next_changetime; double userinfo_next_changetime;
double userinfo_penalty; double userinfo_penalty;
int userinfo_change_attempts;
client_frame_t *frames; // updates can be delta'd from here
event_state_t events; // delta-updated events cycle
} sv_client_t; } sv_client_t;
/* /*

View File

@@ -277,25 +277,6 @@ static sv_client_t *SV_FindEmptySlot( void )
return NULL; return NULL;
} }
static void SV_MaybeNotifyPlayerCountChange( const sv_client_t *cl, const char *address )
{
int i, count = 0;
// if this was the first client on the server, or the last client
// the server can hold, send a heartbeat to the master.
for( i = 0; i < svs.maxclients; i++ )
{
if( svs.clients[i].state >= cs_connected )
count++;
}
if( count == 1 || count == svs.maxclients )
NET_MasterClear();
Log_Printf( "\"%s<%i><%i><>\" connected, address \"%s\"\n",
cl->name, cl->userid, (int)( cl - svs.clients ), address );
}
/* /*
================== ==================
SV_ConnectClient SV_ConnectClient
@@ -307,10 +288,9 @@ static void SV_ConnectClient( netadr_t from )
{ {
char userinfo[MAX_INFO_STRING]; char userinfo[MAX_INFO_STRING];
char protinfo[MAX_INFO_STRING]; char protinfo[MAX_INFO_STRING];
client_frame_t *frames;
sv_client_t *newcl = NULL; sv_client_t *newcl = NULL;
int qport, version; int qport, version;
int i; int i, count = 0;
int challenge; int challenge;
const char *s; const char *s;
int extensions; int extensions;
@@ -355,6 +335,12 @@ static void SV_ConnectClient( netadr_t from )
if( !SV_ProcessUserAgent( from, protinfo )) if( !SV_ProcessUserAgent( from, protinfo ))
return; return;
if( Q_strlen( Info_ValueForKey( protinfo, "uuid" )) != 32 )
{
SV_RejectConnection( from, "invalid authentication certificate length\n" );
return;
}
// extract qport from protocol info // extract qport from protocol info
qport = Q_atoi( Info_ValueForKey( protinfo, "qport" )); qport = Q_atoi( Info_ValueForKey( protinfo, "qport" ));
extensions = Q_atoi( Info_ValueForKey( protinfo, "ext" )); extensions = Q_atoi( Info_ValueForKey( protinfo, "ext" ));
@@ -411,20 +397,20 @@ static void SV_ConnectClient( netadr_t from )
// build a new connection // build a new connection
// accept the new client // accept the new client
sv.current_client = newcl; sv.current_client = newcl;
frames = Mem_Realloc( host.mempool, newcl->frames, sizeof( client_frame_t ) * SV_UPDATE_BACKUP );
memset( frames, 0, sizeof( client_frame_t ) * SV_UPDATE_BACKUP );
SV_ClearResourceLists( newcl );
memset( newcl, 0, sizeof( *newcl ));
newcl->edict = EDICT_NUM(( newcl - svs.clients ) + 1 ); newcl->edict = EDICT_NUM(( newcl - svs.clients ) + 1 );
newcl->frames = frames; newcl->challenge = challenge; // save challenge for checksumming
newcl->frames = (client_frame_t *)Mem_Realloc( host.mempool, newcl->frames, sizeof( client_frame_t ) * SV_UPDATE_BACKUP );
memset( newcl->frames, 0, sizeof( client_frame_t ) * SV_UPDATE_BACKUP );
newcl->userid = g_userid++; // create unique userid newcl->userid = g_userid++; // create unique userid
newcl->state = cs_connected; newcl->state = cs_connected;
newcl->extensions = FBitSet( extensions, NET_EXT_SPLITSIZE ); newcl->extensions = extensions & (NET_EXT_SPLITSIZE);
Q_strncpy( newcl->useragent, protinfo, sizeof( newcl->useragent )); Q_strncpy( newcl->useragent, protinfo, sizeof( newcl->useragent ));
// reset viewentities (from previous level)
memset( newcl->viewentity, 0, sizeof( newcl->viewentity ));
newcl->num_viewents = 0;
// HACKHACK: can hear all players by default to avoid issues // HACKHACK: can hear all players by default to avoid issues
// with server.dll without voice game manager // with server.dll without voice game manager
newcl->listeners = -1; newcl->listeners = -1;
@@ -449,18 +435,47 @@ static void SV_ConnectClient( netadr_t from )
newcl->connection_started = host.realtime; newcl->connection_started = host.realtime;
newcl->cl_updaterate = 0.05; // 20 fps as default newcl->cl_updaterate = 0.05; // 20 fps as default
newcl->delta_sequence = -1; newcl->delta_sequence = -1;
newcl->flags = 0;
// reset any remaining events
memset( &newcl->events, 0, sizeof( newcl->events ));
// parse some info from the info strings (this can override cl_updaterate) // parse some info from the info strings (this can override cl_updaterate)
Q_strncpy( newcl->userinfo, userinfo, sizeof( newcl->userinfo )); Q_strncpy( newcl->userinfo, userinfo, sizeof( newcl->userinfo ));
newcl->fullupdate_next_calltime = 0;
newcl->userinfo_next_changetime = 0;
newcl->userinfo_penalty = 0;
newcl->userinfo_change_attempts = 0;
SV_UserinfoChanged( newcl ); SV_UserinfoChanged( newcl );
SV_ClearResourceLists( newcl );
#if 0
memset( &newcl->resourcesneeded, 0, sizeof( resource_t ));
memset( &newcl->resourcesonhand, 0, sizeof( resource_t ));
newcl->resourcesneeded.pNext = newcl->resourcesneeded.pPrev = &newcl->resourcesneeded;
newcl->resourcesonhand.pNext = newcl->resourcesonhand.pPrev = &newcl->resourcesonhand;
#endif
newcl->next_messagetime = host.realtime + newcl->cl_updaterate; newcl->next_messagetime = host.realtime + newcl->cl_updaterate;
newcl->next_sendinfotime = 0.0;
newcl->ignored_ents = 0;
newcl->chokecount = 0;
// reset stats // reset stats
newcl->next_checkpingtime = -1.0; newcl->next_checkpingtime = -1.0;
newcl->packet_loss = 0;
SV_MaybeNotifyPlayerCountChange( newcl, NET_AdrToString( newcl->netchan.remote_address )); // if this was the first client on the server, or the last client
// the server can hold, send a heartbeat to the master.
for( i = 0; i < svs.maxclients; i++ )
{
if( svs.clients[i].state >= cs_connected )
count++;
}
Log_Printf( "\"%s<%i><%i><>\" connected, address \"%s\"\n", newcl->name, newcl->userid, i, NET_AdrToString( newcl->netchan.remote_address ));
if( count == 1 || count == svs.maxclients )
NET_MasterClear();
} }
/* /*
@@ -472,21 +487,25 @@ A connection request that came from the game module
*/ */
edict_t *GAME_EXPORT SV_FakeConnect( const char *netname ) edict_t *GAME_EXPORT SV_FakeConnect( const char *netname )
{ {
char userinfo[MAX_INFO_STRING]; char userinfo[MAX_INFO_STRING];
int i, count = 0; int i, count = 0;
sv_client_t *cl; sv_client_t *cl;
// find a client slot
cl = SV_FindEmptySlot();
if( !cl )
return NULL; // server is full
userinfo[0] = '\0';
if( !COM_CheckString( netname )) if( !COM_CheckString( netname ))
netname = "Bot"; netname = "Bot";
// find a client slot
for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ )
{
if( cl->state == cs_free )
break;
}
if( i == svs.maxclients )
return NULL; // server is full
userinfo[0] = '\0';
// setup fake client params // setup fake client params
Info_SetValueForKey( userinfo, "name", netname, sizeof( userinfo )); Info_SetValueForKey( userinfo, "name", netname, sizeof( userinfo ));
Info_SetValueForKey( userinfo, "model", "gordon", sizeof( userinfo )); Info_SetValueForKey( userinfo, "model", "gordon", sizeof( userinfo ));
@@ -496,26 +515,34 @@ edict_t *GAME_EXPORT SV_FakeConnect( const char *netname )
// build a new connection // build a new connection
// accept the new client // accept the new client
sv.current_client = cl; sv.current_client = cl;
if( cl->frames )
Mem_Free( cl->frames ); // fakeclients doesn't have frames
SV_ClearResourceLists( cl );
memset( cl, 0, sizeof( *cl )); if( cl->frames ) Mem_Free( cl->frames ); // fakeclients doesn't have frames
memset( cl, 0, sizeof( sv_client_t ));
cl->state = cs_spawned; cl->edict = EDICT_NUM( (cl - svs.clients) + 1 );
cl->edict = EDICT_NUM(( cl - svs.clients ) + 1 ); cl->userid = g_userid++; // create unique userid
cl->userid = g_userid++; // create unique userid
SetBits( cl->flags, FCL_FAKECLIENT ); SetBits( cl->flags, FCL_FAKECLIENT );
// parse some info from the info strings // parse some info from the info strings
Q_strncpy( cl->userinfo, userinfo, sizeof( cl->userinfo )); Q_strncpy( cl->userinfo, userinfo, sizeof( cl->userinfo ));
SV_UserinfoChanged( cl ); SV_UserinfoChanged( cl );
SetBits( cl->flags, FCL_RESEND_USERINFO ); SetBits( cl->flags, FCL_RESEND_USERINFO );
cl->next_sendinfotime = 0.0;
// if this was the first client on the server, or the last client
// the server can hold, send a heartbeat to the master.
for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ )
if( cl->state >= cs_connected ) count++;
cl = sv.current_client;
Log_Printf( "\"%s<%i><%i><>\" connected, address \"local\"\n", cl->name, cl->userid, i );
SetBits( cl->edict->v.flags, FL_CLIENT|FL_FAKECLIENT ); // mark it as fakeclient SetBits( cl->edict->v.flags, FL_CLIENT|FL_FAKECLIENT ); // mark it as fakeclient
cl->connection_started = host.realtime; cl->connection_started = host.realtime;
cl->state = cs_spawned;
SV_MaybeNotifyPlayerCountChange( cl, "local" ); if( count == 1 || count == svs.maxclients )
NET_MasterClear();
return cl->edict; return cl->edict;
} }
@@ -745,7 +772,7 @@ const char *SV_GetClientIDString( sv_client_t *cl )
if( sv_lan.value ) if( sv_lan.value )
return "ID_LAN"; return "ID_LAN";
Q_snprintf( result, sizeof( result ), "ID_%s", cl->hashedcdkey ); Q_snprintf( result, sizeof( result ), "ID_%s", MD5_Print( (byte *)cl->hashedcdkey ));
return result; return result;
} }
@@ -3169,8 +3196,10 @@ void SV_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
if( len > 0 ) if( len > 0 )
Netchan_OutOfBand( NS_SERVER, from, len, (byte*)buf ); Netchan_OutOfBand( NS_SERVER, from, len, (byte*)buf );
} }
else if( sv_log_outofband.value ) else
{
Con_DPrintf( S_ERROR "bad connectionless packet from %s:\n%s\n", NET_AdrToString( from ), args ); Con_DPrintf( S_ERROR "bad connectionless packet from %s:\n%s\n", NET_AdrToString( from ), args );
}
} }
} }
@@ -3301,10 +3330,6 @@ static void SV_ParseClientMove( sv_client_t *cl, sizebuf_t *msg )
SV_RunCmd( cl, &cmds[i], cl->netchan.incoming_sequence - i ); SV_RunCmd( cl, &cmds[i], cl->netchan.incoming_sequence - i );
} }
// was player kicked? stop here
if( cl->state <= cs_zombie )
return;
cl->lastcmd = cmds[0]; cl->lastcmd = cmds[0];
// adjust latency time by 1/2 last client frame since // adjust latency time by 1/2 last client frame since

View File

@@ -763,31 +763,6 @@ qboolean SV_ProcessUserAgent( netadr_t from, const char *useragent )
{ {
const char *input_devices_str = Info_ValueForKey( useragent, "d" ); const char *input_devices_str = Info_ValueForKey( useragent, "d" );
const char *id = Info_ValueForKey( useragent, "uuid" ); const char *id = Info_ValueForKey( useragent, "uuid" );
size_t len, i;
len = Q_strlen( id );
if( len != 32 )
{
SV_RejectConnection( from, "invalid authentication certificate\n" );
return false;
}
for( i = 0; i < len; i++ )
{
char c = id[i];
if( !isdigit( id[i] ) && !( c >= 'a' && c <= 'f' ))
{
SV_RejectConnection( from, "invalid authentication certificate\n" );
return false;
}
}
if( SV_CheckID( id ))
{
SV_RejectConnection( from, "You are banned!\n" );
return false;
}
if( !sv_allow_noinputdevices.value && ( !input_devices_str || !input_devices_str[0] ) ) if( !sv_allow_noinputdevices.value && ( !input_devices_str || !input_devices_str[0] ) )
{ {
@@ -821,6 +796,17 @@ qboolean SV_ProcessUserAgent( netadr_t from, const char *useragent )
} }
} }
if( id )
{
qboolean banned = SV_CheckID( id );
if( banned )
{
SV_RejectConnection( from, "You are banned!\n" );
return false;
}
}
return true; return true;
} }

View File

@@ -892,10 +892,6 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd, int random_seed )
vec3_t oldvel; vec3_t oldvel;
usercmd_t cmd; usercmd_t cmd;
// if the player got kicked, do not process commands
if( cl->state <= cs_zombie )
return;
clent = cl->edict; clent = cl->edict;
cmd = *ucmd; cmd = *ucmd;

View File

@@ -907,7 +907,13 @@ static void GL_InitExtensionsBigGL( void )
GL_CheckExtension( "GL_ARB_seamless_cube_map", NULL, 0, "gl_texture_cubemap_seamless", GL_ARB_SEAMLESS_CUBEMAP, 0 ); GL_CheckExtension( "GL_ARB_seamless_cube_map", NULL, 0, "gl_texture_cubemap_seamless", GL_ARB_SEAMLESS_CUBEMAP, 0 );
} }
GL_CheckExtension( "GL_ARB_texture_non_power_of_two", NULL, 0, "gl_texture_npot", GL_ARB_TEXTURE_NPOT_EXT, 0 ); // NPOT textures support
if( !GL_CheckExtension( "GL_ARB_texture_non_power_of_two", NULL, 0, "gl_texture_npot", GL_ARB_TEXTURE_NPOT_EXT, 0 ))
{
// vitaGL exposes OES extension
GL_CheckExtension( "GL_OES_texture_npot", NULL, 0, "gl_texture_npot", GL_ARB_TEXTURE_NPOT_EXT, 0 );
}
GL_CheckExtension( "GL_ARB_texture_compression", texturecompressionfuncs, ARRAYSIZE( texturecompressionfuncs ), "gl_texture_dxt_compression", GL_TEXTURE_COMPRESSION_EXT, 0 ); GL_CheckExtension( "GL_ARB_texture_compression", texturecompressionfuncs, ARRAYSIZE( texturecompressionfuncs ), "gl_texture_dxt_compression", GL_TEXTURE_COMPRESSION_EXT, 0 );
if( !GL_CheckExtension( "GL_EXT_texture_edge_clamp", NULL, 0, "gl_clamp_to_edge", GL_CLAMPTOEDGE_EXT, 2.0 )) // present in ES2 if( !GL_CheckExtension( "GL_EXT_texture_edge_clamp", NULL, 0, "gl_clamp_to_edge", GL_CLAMPTOEDGE_EXT, 2.0 )) // present in ES2
GL_CheckExtension( "GL_SGIS_texture_edge_clamp", NULL, 0, "gl_clamp_to_edge", GL_CLAMPTOEDGE_EXT, 0 ); GL_CheckExtension( "GL_SGIS_texture_edge_clamp", NULL, 0, "gl_clamp_to_edge", GL_CLAMPTOEDGE_EXT, 0 );

View File

@@ -1093,14 +1093,6 @@ static void R_RenderFullbrights( void )
pglBlendFunc( GL_ONE, GL_ONE ); pglBlendFunc( GL_ONE, GL_ONE );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
// if fullbright textures are drawn in separate pass from VBO they
// cause z-fighting, this is noticeable on `slide_waifufu.bsp` map
if( R_HasEnabledVBO() && gl_polyoffset.value )
{
pglEnable( GL_POLYGON_OFFSET_FILL );
pglPolygonOffset( -1.0f, -gl_polyoffset.value );
}
for( i = draw_fullbrights.first; i <= draw_fullbrights.last; i++ ) for( i = draw_fullbrights.first; i <= draw_fullbrights.last; i++ )
{ {
es = fullbright_surfaces[i]; es = fullbright_surfaces[i];
@@ -1116,9 +1108,6 @@ static void R_RenderFullbrights( void )
es->lumachain = NULL; es->lumachain = NULL;
} }
if( R_HasEnabledVBO() && gl_polyoffset.value )
pglDisable( GL_POLYGON_OFFSET_FILL );
pglDisable( GL_BLEND ); pglDisable( GL_BLEND );
pglDepthMask( GL_TRUE ); pglDepthMask( GL_TRUE );
pglDisable( GL_ALPHA_TEST ); pglDisable( GL_ALPHA_TEST );

View File

@@ -61,8 +61,8 @@ CFLAGS = {
'common': { 'common': {
# disable thread-safe local static initialization for C++11 code, as it cause crashes on Windows XP # disable thread-safe local static initialization for C++11 code, as it cause crashes on Windows XP
'msvc': ['/D_USING_V110_SDK71_', '/FS', '/Zc:threadSafeInit-', '/MT', '/MP', '/Zc:__cplusplus'], 'msvc': ['/D_USING_V110_SDK71_', '/FS', '/Zc:threadSafeInit-', '/MT', '/MP', '/Zc:__cplusplus'],
'clang': ['-g', '-gdwarf-2', '-fvisibility=hidden', '-fno-threadsafe-statics', '-fasynchronous-unwind-tables'], 'clang': ['-g', '-gdwarf-2', '-fvisibility=hidden', '-fno-threadsafe-statics'],
'gcc': ['-g', '-fvisibility=hidden', '-fasynchronous-unwind-tables'], 'gcc': ['-g', '-fvisibility=hidden'],
'owcc': ['-fno-short-enum', '-ffloat-store', '-g3'] 'owcc': ['-fno-short-enum', '-ffloat-store', '-g3']
}, },
'fast': { 'fast': {
@@ -177,9 +177,6 @@ def options(opt):
grp.add_option('--enable-profile', action = 'store_true', dest = 'PROFILE_GENERATE', default = False, 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]') 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, grp.add_option('--use-profile', action = 'store', dest = 'PROFILE_USE', default = None,
help = 'use profile during build [default: %(default)s]') help = 'use profile during build [default: %(default)s]')
@@ -243,28 +240,16 @@ def get_optimization_flags(conf):
linkflags+= [conf.get_flags_by_compiler(PROFILE_USE_LINKFLAGS, conf.env.COMPILER_CC)[0] % conf.options.PROFILE_USE] linkflags+= [conf.get_flags_by_compiler(PROFILE_USE_LINKFLAGS, conf.env.COMPILER_CC)[0] % conf.options.PROFILE_USE]
cflags += [conf.get_flags_by_compiler(PROFILE_USE_CFLAGS, conf.env.COMPILER_CC)[0] % conf.options.PROFILE_USE] cflags += [conf.get_flags_by_compiler(PROFILE_USE_CFLAGS, conf.env.COMPILER_CC)[0] % conf.options.PROFILE_USE]
if conf.env.DEST_OS == 'nswitch': if conf.env.DEST_OS == 'nswitch' and conf.options.BUILD_TYPE == 'debug':
if conf.options.BUILD_TYPE == 'debug': # enable remote debugger
# enable remote debugger cflags.append('-DNSWITCH_DEBUG')
cflags.append('-DNSWITCH_DEBUG')
# this port don't have stack printing support
cflags.remove('-fasynchronous-unwind-tables')
elif conf.env.DEST_OS == 'psvita': elif conf.env.DEST_OS == 'psvita':
# this optimization is broken in vitasdk # this optimization is broken in vitasdk
cflags.append('-fno-optimize-sibling-calls') cflags.append('-fno-optimize-sibling-calls')
# remove fvisibility to allow everything to be exported by default # remove fvisibility to allow everything to be exported by default
cflags.remove('-fvisibility=hidden') cflags.remove('-fvisibility=hidden')
# this port don't have stack printing support
cflags.remove('-fasynchronous-unwind-tables')
if conf.env.COMPILER_CC in ['gcc', 'clang'] and conf.options.LIMITED_DEBUGINFO: if conf.env.COMPILER_CC != 'msvc' and conf.env.COMPILER_CC != 'owcc':
# 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 # HLSDK by default compiles with these options under Linux
# no reason for us to not do the same # no reason for us to not do the same