mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 11:35:05 +08:00
Compare commits
10 Commits
mbedtls
...
continuous
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3366ad06d0 | ||
|
|
57206b3651 | ||
|
|
d9ecd03b4a | ||
|
|
2de4d0d364 | ||
|
|
cc3889146c | ||
|
|
09f5886751 | ||
|
|
fb5b4fed6e | ||
|
|
1e31fbcd51 | ||
|
|
b2a5f0db5a | ||
|
|
abd7b5ccdd |
1
.github/workflows/c-cpp.yml
vendored
1
.github/workflows/c-cpp.yml
vendored
@@ -70,6 +70,7 @@ jobs:
|
||||
env:
|
||||
SDL_VERSION: 2.32.10
|
||||
FFMPEG_VERSION: 8.1
|
||||
YY_THUNKS_VERSION: v1.2.1
|
||||
GH_CPU_ARCH: ${{ matrix.targetarch }}
|
||||
GH_CPU_OS: ${{ matrix.targetos }}
|
||||
GH_CROSSCOMPILING: ${{ matrix.cross }}
|
||||
|
||||
2
3rdparty/mainui
vendored
2
3rdparty/mainui
vendored
Submodule 3rdparty/mainui updated: 623c34db69...493b08fb49
2
3rdparty/vgui_support
vendored
2
3rdparty/vgui_support
vendored
Submodule 3rdparty/vgui_support updated: e021fb5e7f...d2aaec107d
59
3rdparty/yy-thunks/wscript
vendored
Normal file
59
3rdparty/yy-thunks/wscript
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
import hashlib
|
||||
from waflib import Task, TaskGen, Logs
|
||||
|
||||
OBJ_NAME = 'YY_Thunks_for_WinXP.obj'
|
||||
OBJ_SHA256 = '51a13c4b667c82181d357e274a50308a273be63f5f85ae958465774857721573'
|
||||
DLL_LINKFLAGS = ['-ENTRY:DllMainCRTStartupForYY_Thunks', '-alternatename:_YY_ThunksOriginalDllMainCRTStartup@12=__DllMainCRTStartup@12']
|
||||
|
||||
class copy_yy_thunks(Task.Task):
|
||||
color = 'CYAN'
|
||||
def run(self):
|
||||
return self.outputs[0].write(self.inputs[0].read('rb'), 'wb')
|
||||
|
||||
@TaskGen.feature('yy_thunks')
|
||||
def add_yy_thunks_obj(self):
|
||||
src = self.path.find_node(OBJ_NAME)
|
||||
out = self.path.find_or_declare(OBJ_NAME)
|
||||
self.compiled_tasks = [self.create_task('copy_yy_thunks', src, out)]
|
||||
|
||||
@TaskGen.feature('cshlib', 'cxxshlib')
|
||||
@TaskGen.after_method('process_use')
|
||||
def apply_yy_thunks_dll(self):
|
||||
if 'yy_thunks' not in self.to_list(getattr(self, 'use', [])):
|
||||
return
|
||||
|
||||
try:
|
||||
self.bld.get_tgen_by_name('yy_thunks')
|
||||
except Exception:
|
||||
return
|
||||
self.env.append_value('LINKFLAGS', DLL_LINKFLAGS)
|
||||
|
||||
def options(opt):
|
||||
pass
|
||||
|
||||
def configure(conf):
|
||||
if conf.env.DEST_OS != 'win32' or conf.env.COMPILER_CC != 'msvc':
|
||||
return
|
||||
|
||||
if conf.env.MSVC_TARGETS[0] not in ['amd64_x86', 'x86']:
|
||||
return
|
||||
|
||||
obj = conf.path.find_node(OBJ_NAME)
|
||||
if not obj:
|
||||
Logs.warn('YY-Thunks: %s not found, XP compatibility disabled' % OBJ_NAME)
|
||||
return
|
||||
|
||||
with open(obj.abspath(), 'rb') as f:
|
||||
digest = hashlib.sha256(f.read()).hexdigest()
|
||||
|
||||
if digest != OBJ_SHA256:
|
||||
conf.fatal('%s checksum mismatch: expected %s, got %s' % (OBJ_NAME, OBJ_SHA256, digest))
|
||||
|
||||
conf.env.YY_THUNKS = True
|
||||
|
||||
def build(bld):
|
||||
if bld.env.YY_THUNKS:
|
||||
bld(name='yy_thunks', features='yy_thunks')
|
||||
@@ -28,17 +28,18 @@ used; servers register out of band.
|
||||
|
||||
## Response
|
||||
|
||||
UTF-8 text, tokenized with `COM_ParseFileSafe` (whitespace separates,
|
||||
`//` and `#` start line comments, `"..."` quotes a token). One directive
|
||||
per record:
|
||||
UTF-8 text, parsed line by line. Each line is tokenized with
|
||||
`COM_ParseFileSafe` (whitespace separates, `//` and `#` start line
|
||||
comments, `"..."` quotes a token). Blank lines and comment-only lines
|
||||
are ignored. One directive per line:
|
||||
|
||||
* `ip <address>` — Xash3D server (protocol 49).
|
||||
* `gs <address>` — GoldSrc server (protocol 48).
|
||||
|
||||
`<address>` is parsed by `NET_StringToAdr` (`1.2.3.4:27015`,
|
||||
`[2001:db8::1]:27015`, hostnames). Port defaults to `27015`. Unknown
|
||||
directives are skipped together with one operand so new keywords can be
|
||||
added without breaking older clients.
|
||||
`[2001:db8::1]:27015`, hostnames). Port defaults to `27015`. Lines
|
||||
starting with an unknown directive are skipped entirely, so new keywords
|
||||
with any number of operands can be added without breaking older clients.
|
||||
|
||||
`Content-Type` is not inspected, `text/plain; charset=utf-8` expected.
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
> [!CAUTION]
|
||||
> **Only download Xash3D FWGS from official sources.** Third-party builds, "modded launchers", "optimized" repacks and random mirrors are frequently bundled with malware, miners, spyware and credential stealers. We cannot vouch for anything we did not build. Get official binaries only from the [releases page](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous).
|
||||
|
||||
# Xash3D FWGS Engine <img align="right" width="128" height="128" src="https://github.com/FWGS/xash3d-fwgs/raw/master/game_launch/icon-xash-material.png" alt="Xash3D FWGS icon" />
|
||||
[](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) \
|
||||
[](http://xash.su/discord/) [](https://t.me/flyingwithgauss) \
|
||||
|
||||
@@ -30,7 +30,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
typedef struct usercmd_s
|
||||
{
|
||||
int16_t lerp_msec; // added in HL
|
||||
int8_t msec; // added in QW
|
||||
uint8_t msec; // added in QW
|
||||
uint8_t pad1;
|
||||
vec3_t viewangles;
|
||||
|
||||
|
||||
@@ -1186,8 +1186,8 @@ void CL_ParseBaseline( sizebuf_t *msg, connprotocol_t proto )
|
||||
int type = MSG_ReadUBitLong( msg, 2 );
|
||||
int delta_type;
|
||||
|
||||
if( player ) delta_type = DT_ENTITY_STATE_PLAYER_T;
|
||||
else if( type != ENTITY_NORMAL ) delta_type = DT_CUSTOM_ENTITY_STATE_T;
|
||||
if( FBitSet( type, ENTITY_BEAM )) delta_type = DT_CUSTOM_ENTITY_STATE_T;
|
||||
else if( player ) delta_type = DT_ENTITY_STATE_PLAYER_T;
|
||||
else delta_type = DT_ENTITY_STATE_T;
|
||||
|
||||
Delta_ReadGSFields( msg, delta_type, &ent->prevstate, &ent->baseline, 1.0f );
|
||||
|
||||
@@ -465,7 +465,7 @@ static void CL_ParseSoundPacketGS( sizebuf_t *msg )
|
||||
float attn;
|
||||
if( FBitSet( flags, SND_ATTENUATION ))
|
||||
attn = (float)MSG_ReadByte( msg ) / 64.0f;
|
||||
else attn = ATTN_NONE;
|
||||
else attn = 1.0f;
|
||||
|
||||
int chan = MSG_ReadUBitLong( msg, 3 );
|
||||
int entnum = MSG_ReadUBitLong( msg, MAX_GOLDSRC_ENTITY_BITS );
|
||||
|
||||
@@ -225,33 +225,33 @@ void NET_QueryServerByAddress( netadr_t adr, connprotocol_t proto )
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, A2A_INFO " %i", PROTOCOL_VERSION );
|
||||
}
|
||||
|
||||
static int NET_ParseMasterStaticBody( char *body )
|
||||
static int NET_ParseMasterStaticBody( const byte *body, size_t size )
|
||||
{
|
||||
char token[MAX_TOKEN];
|
||||
char *pfile = body;
|
||||
char line[1024];
|
||||
int offset = 0;
|
||||
int count = 0;
|
||||
|
||||
while(( pfile = COM_ParseFileSafe( pfile, token, sizeof( token ), PFILE_HASH_AS_COMMENT, NULL, NULL )))
|
||||
while( Q_memfgets( (byte *)body, size, &offset, line, sizeof( line )) != NULL )
|
||||
{
|
||||
char token[MAX_TOKEN];
|
||||
char *pfile = line;
|
||||
qboolean gs;
|
||||
netadr_t adr = { 0 };
|
||||
|
||||
pfile = COM_ParseFileSafe( pfile, token, sizeof( token ), PFILE_HASH_AS_COMMENT, NULL, NULL );
|
||||
if( !pfile || token[0] == '\0' )
|
||||
continue;
|
||||
|
||||
if( !Q_strcmp( token, "ip" ))
|
||||
gs = false;
|
||||
else if( !Q_strcmp( token, "gs" ))
|
||||
gs = true;
|
||||
else
|
||||
{
|
||||
pfile = COM_ParseFileSafe( pfile, token, sizeof( token ), PFILE_HASH_AS_COMMENT, NULL, NULL );
|
||||
if( !pfile )
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
pfile = COM_ParseFileSafe( pfile, token, sizeof( token ), PFILE_HASH_AS_COMMENT, NULL, NULL );
|
||||
if( !pfile )
|
||||
break;
|
||||
|
||||
netadr_t adr = { 0 };
|
||||
continue;
|
||||
|
||||
if( !NET_StringToAdr( token, &adr ))
|
||||
{
|
||||
@@ -288,16 +288,9 @@ static void NET_MasterStaticResponse( const char *url, qboolean success, const b
|
||||
return;
|
||||
}
|
||||
|
||||
// HTTP buffer isn't NUL-terminated; COM_ParseFileSafe needs one.
|
||||
char *body = Mem_Malloc( host.mempool, size + 1 );
|
||||
memcpy( body, data, size );
|
||||
body[size] = 0;
|
||||
|
||||
NET_Config( true, false ); // allow remote sends
|
||||
|
||||
int count = NET_ParseMasterStaticBody( body );
|
||||
|
||||
Mem_Free( body );
|
||||
int count = NET_ParseMasterStaticBody( data, size );
|
||||
|
||||
Con_Reportf( "masterstatic: %s yielded %d server(s)\n", url, count );
|
||||
|
||||
@@ -516,7 +509,7 @@ static master_t *NET_AddMaster( const char *addr )
|
||||
|
||||
static void NET_AddMaster_f( void )
|
||||
{
|
||||
if( Cmd_Argc() != 2 )
|
||||
if( Cmd_Argc() != 2 && Cmd_Argc() != 3 )
|
||||
{
|
||||
Msg( S_USAGE "addmaster <address> [gs]\n");
|
||||
return;
|
||||
|
||||
@@ -161,7 +161,7 @@ def build(bld):
|
||||
# public includes for renderers and utils use
|
||||
bld(name = 'engine_includes', export_includes = '. common common/imagelib', use = 'filesystem_includes')
|
||||
|
||||
libs = ['engine_includes', 'public', 'werror', 'backtrace_custom', 'library_suffix', 'build_vcs', 'mbedtls']
|
||||
libs = ['engine_includes', 'public', 'werror', 'backtrace_custom', 'library_suffix', 'build_vcs', 'mbedtls', 'yy_thunks']
|
||||
includes = ['server', 'client', 'client/vgui', 'common/soundlib', 'platform']
|
||||
|
||||
# basic build: dedicated only
|
||||
|
||||
@@ -28,7 +28,7 @@ GNU General Public License for more details.
|
||||
// GoldSrc Directories and ID
|
||||
// GAME gamedir
|
||||
// GAMECONFIG gamedir (rodir integration?)
|
||||
// GAMEDOWNLOAD gamedir_downloads (gamedir/downloads for us)
|
||||
// GAMEDOWNLOAD gamedir_downloads
|
||||
// GAME_FALLBACK liblist.gam's fallback_dir
|
||||
// ROOT and BASE rootdir
|
||||
// PLATFORM platform
|
||||
@@ -41,14 +41,22 @@ GNU General Public License for more details.
|
||||
char * const var = static_cast<char *>( alloca( var ## _size )); \
|
||||
CopyAndFixSlashes( var, ( str ), var ## _size )
|
||||
|
||||
static inline bool IsIdGamedir( const char *id )
|
||||
static bool IsIdGamedir( const char *id )
|
||||
{
|
||||
return !Q_strcmp( id, "GAME" ) ||
|
||||
!Q_strcmp( id, "GAMECONFIG" ) ||
|
||||
!Q_strcmp( id, "GAMEDOWNLOAD" );
|
||||
}
|
||||
|
||||
static inline const char *IdToDir( char *dir, size_t size, const char *id )
|
||||
static searchpath_t *IdToWritableSearchpath( const char *id )
|
||||
{
|
||||
if( !Q_strcmp( id, "GAME" ) || !Q_strcmp( id, "GAMECONFIG" ))
|
||||
return fs_writepath;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *IdToDir( char *dir, size_t size, const char *id )
|
||||
{
|
||||
if( !Q_strcmp( id, "GAME" ))
|
||||
return GI->gamefolder;
|
||||
@@ -72,7 +80,7 @@ static inline const char *IdToDir( char *dir, size_t size, const char *id )
|
||||
return fs_rootdir; // give at least root directory
|
||||
}
|
||||
|
||||
static inline void CopyAndFixSlashes( char *p, const char *in, size_t size )
|
||||
static void CopyAndFixSlashes( char *p, const char *in, size_t size )
|
||||
{
|
||||
Q_strncpy( p, in, size );
|
||||
COM_FixSlashes( p );
|
||||
@@ -147,10 +155,9 @@ public:
|
||||
|
||||
void RemoveFile( const char *path, const char *id ) override
|
||||
{
|
||||
char dir[MAX_VA_STRING], fullpath[MAX_VA_STRING];
|
||||
|
||||
Q_snprintf( fullpath, sizeof( fullpath ), "%s/%s", IdToDir( dir, sizeof( dir ), id ), path );
|
||||
FS_Delete( fullpath ); // FS_Delete is aware of slashes
|
||||
// FIXME: handle writable downloads path
|
||||
if( IdToWritableSearchpath( id ))
|
||||
FS_Delete( path ); // FS_Delete is aware of slashes
|
||||
}
|
||||
|
||||
void CreateDirHierarchy( const char *path, const char *id ) override
|
||||
|
||||
@@ -33,7 +33,7 @@ def configure(conf):
|
||||
def build(bld):
|
||||
bld(name = 'filesystem_includes', export_includes = '.')
|
||||
|
||||
libs = [ 'filesystem_includes', 'sdk_includes', 'werror' ]
|
||||
libs = [ 'filesystem_includes', 'sdk_includes', 'werror', 'yy_thunks' ]
|
||||
|
||||
# on PSVita do not link any libraries that are already in the main executable, but add the includes target
|
||||
if bld.env.DEST_OS != 'psvita':
|
||||
|
||||
@@ -32,7 +32,7 @@ def build(bld):
|
||||
|
||||
bld.program(source = source,
|
||||
target = 'xash3d', # hl.exe
|
||||
use = 'sdk_includes DL USER32 SHELL32 werror',
|
||||
use = 'sdk_includes DL USER32 SHELL32 werror yy_thunks',
|
||||
rpath = bld.env.DEFAULT_RPATH,
|
||||
install_path = bld.env.BINDIR,
|
||||
subsystem = bld.env.MSVC_SUBSYSTEM
|
||||
|
||||
@@ -721,7 +721,7 @@ void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos
|
||||
|
||||
if( model->type != mod_brush )
|
||||
{
|
||||
gEngfuncs.Con_Printf( S_ERROR "Decals must hit mod_brush!\n" );
|
||||
gEngfuncs.Con_Reportf( S_ERROR "Decals must hit mod_brush!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ def configure(conf):
|
||||
conf.check_cc(lib='log')
|
||||
|
||||
def build(bld):
|
||||
libs = [ 'ref_common', 'engine_includes', 'werror' ]
|
||||
libs = [ 'ref_common', 'engine_includes', 'werror', 'yy_thunks' ]
|
||||
# on PSVita do not link any libraries that are already in the main executable, but add the includes target
|
||||
if bld.env.DEST_OS == 'psvita':
|
||||
libs += [ 'sdk_includes', 'vgl_shim' ]
|
||||
|
||||
@@ -13,6 +13,6 @@ def build(bld):
|
||||
source = 'r_context.c',
|
||||
target = 'ref_null',
|
||||
defines = 'REF_DLL',
|
||||
use = 'engine_includes sdk_includes werror',
|
||||
use = 'engine_includes sdk_includes werror yy_thunks',
|
||||
install_path = bld.env.LIBDIR
|
||||
)
|
||||
|
||||
@@ -743,7 +743,7 @@ void GAME_EXPORT R_DecalShoot( int textureIndex, int entityIndex, int modelIndex
|
||||
|
||||
if( model->type != mod_brush )
|
||||
{
|
||||
gEngfuncs.Con_Printf( S_ERROR "Decals must hit mod_brush!\n" );
|
||||
gEngfuncs.Con_Reportf( S_ERROR "Decals must hit mod_brush!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ def configure(conf):
|
||||
return
|
||||
|
||||
def build(bld):
|
||||
libs = [ 'ref_common', 'engine_includes', 'werror' ]
|
||||
libs = [ 'ref_common', 'engine_includes', 'werror', 'yy_thunks' ]
|
||||
# on PSVita do not link any libraries that are already in the main executable, but add the includes target
|
||||
if bld.env.DEST_OS == 'psvita':
|
||||
libs += [ 'sdk_includes' ]
|
||||
|
||||
@@ -8,6 +8,11 @@ mv "SDL2-$SDL_VERSION" SDL2_VC
|
||||
|
||||
if [ "$GH_CPU_ARCH" = "i386" ]; then
|
||||
rustup target add i686-pc-windows-msvc
|
||||
|
||||
# YY-Thunks obj for Windows XP support
|
||||
curl -L "https://github.com/Chuyu-Team/YY-Thunks/releases/download/$YY_THUNKS_VERSION/YY-Thunks-Objs.zip" -o yy-thunks.zip
|
||||
unzip -q -j -o yy-thunks.zip 'objs/x86/YY_Thunks_for_WinXP.obj' -d 3rdparty/yy-thunks
|
||||
rm yy-thunks.zip
|
||||
fi
|
||||
|
||||
curl -L https://github.com/FWGS/potential-meme/releases/download/prebuilts/mingw-w64-x86_64-pkgconf-1.2.3.0-1-any.pkg.tar.zst -o pkgconf.tar.zst
|
||||
|
||||
@@ -19,7 +19,7 @@ def build(bld):
|
||||
bld.program(source = bld.path.ant_glob('*.c'),
|
||||
target = 'mdldec',
|
||||
includes = '.',
|
||||
use = 'engine_includes public M werror',
|
||||
use = 'engine_includes public M werror yy_thunks',
|
||||
install_path = bld.env.BINDIR,
|
||||
subsystem = bld.env.CONSOLE_SUBSYSTEM
|
||||
)
|
||||
|
||||
@@ -12,7 +12,7 @@ def build(bld):
|
||||
bld.program(source = bld.path.ant_glob('*.c'),
|
||||
target = 'xar',
|
||||
includes = '.',
|
||||
use = 'public filesystem_includes werror',
|
||||
use = 'public filesystem_includes werror yy_thunks',
|
||||
rpath = bld.env.DEFAULT_RPATH,
|
||||
install_path = bld.env.BINDIR,
|
||||
subsystem = bld.env.CONSOLE_SUBSYSTEM
|
||||
|
||||
1
wscript
1
wscript
@@ -85,6 +85,7 @@ SUBDIRS = [
|
||||
Subproject('stub/server'),
|
||||
Subproject('3rdparty/libbacktrace'),
|
||||
Subproject('3rdparty/library_suffix'),
|
||||
Subproject('3rdparty/yy-thunks'),
|
||||
|
||||
# disable only by engine feature, makes no sense to even parse subprojects in dedicated mode
|
||||
Subproject('3rdparty/extras', lambda x: x.env.CLIENT and x.env.DEST_OS != 'android'),
|
||||
|
||||
Reference in New Issue
Block a user