mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-06 03:54:52 +08:00
Compare commits
51 Commits
continuous
...
continuous
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec5e9cb6e3 | ||
|
|
f4b4546197 | ||
|
|
f047749e61 | ||
|
|
87840ce91d | ||
|
|
bf31e9f634 | ||
|
|
f86d84daed | ||
|
|
41ed920d35 | ||
|
|
df23ddb545 | ||
|
|
767556ccad | ||
|
|
f9dab2ad19 | ||
|
|
66cb3a6120 | ||
|
|
7672a370da | ||
|
|
870e47ed03 | ||
|
|
32d4bdb80f | ||
|
|
929dfd2c71 | ||
|
|
f437af6451 | ||
|
|
413a0fb2e5 | ||
|
|
793adadb06 | ||
|
|
999b43b89f | ||
|
|
bd60c88c7d | ||
|
|
23b9a2eddf | ||
|
|
0b57d97c8c | ||
|
|
6255293dd4 | ||
|
|
04136d95a3 | ||
|
|
40aa29e42a | ||
|
|
a709f30da9 | ||
|
|
0796c14e79 | ||
|
|
a9c0a4be23 | ||
|
|
3e1209d3a4 | ||
|
|
caf14c1b7c | ||
|
|
27f7d2c8d2 | ||
|
|
8ee430eda2 | ||
|
|
484e4cb225 | ||
|
|
b080ad9954 | ||
|
|
f6625d9188 | ||
|
|
1eb2816bc4 | ||
|
|
077be5aaf3 | ||
|
|
d59875f114 | ||
|
|
e89191ed39 | ||
|
|
ea21438637 | ||
|
|
0d2e8333e8 | ||
|
|
338399e622 | ||
|
|
27cab8aad5 | ||
|
|
1545a49b4c | ||
|
|
3ca15250e8 | ||
|
|
6cbac51731 | ||
|
|
e310c666b1 | ||
|
|
677b0170aa | ||
|
|
9150b770e4 | ||
|
|
2ad6511c31 | ||
|
|
0848f28d83 |
12
.cirrus.yml
12
.cirrus.yml
@@ -1,15 +1,3 @@
|
|||||||
task:
|
|
||||||
name: freebsd-13-amd64
|
|
||||||
freebsd_instance:
|
|
||||||
image_family: freebsd-13-2
|
|
||||||
setup_script:
|
|
||||||
- pkg update
|
|
||||||
- pkg install -y pkgconf git sdl2 python fontconfig opus
|
|
||||||
- git submodule update --init --recursive
|
|
||||||
test_script:
|
|
||||||
- ./scripts/cirrus/build_freebsd.sh dedicated
|
|
||||||
- ./scripts/cirrus/build_freebsd.sh full
|
|
||||||
|
|
||||||
task:
|
task:
|
||||||
name: freebsd-14-amd64
|
name: freebsd-14-amd64
|
||||||
freebsd_instance:
|
freebsd_instance:
|
||||||
|
|||||||
2
3rdparty/mainui
vendored
2
3rdparty/mainui
vendored
Submodule 3rdparty/mainui updated: dc467364d0...757ace3d4e
2
3rdparty/vgui_support
vendored
2
3rdparty/vgui_support
vendored
Submodule 3rdparty/vgui_support updated: a2a7b9073f...7276993f3f
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
boneinfo.h - structure that send delta-compressed bones across network
|
|
||||||
Copyright (C) 2018 Uncle Mike
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BONEINFO_H
|
|
||||||
#define BONEINFO_H
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
vec3_t angles;
|
|
||||||
vec3_t origin;
|
|
||||||
} boneinfo_t;
|
|
||||||
|
|
||||||
#endif//BONEINFO_H
|
|
||||||
@@ -83,12 +83,15 @@ typedef uint64_t longtime_t;
|
|||||||
#define NONNULL __attribute__(( nonnull ))
|
#define NONNULL __attribute__(( nonnull ))
|
||||||
#define _format( x ) __attribute__(( format( printf, x, x + 1 )))
|
#define _format( x ) __attribute__(( format( printf, x, x + 1 )))
|
||||||
#define ALLOC_CHECK( x ) __attribute__(( alloc_size( x )))
|
#define ALLOC_CHECK( x ) __attribute__(( alloc_size( x )))
|
||||||
|
#define NO_ASAN __attribute__(( no_sanitize( "address" )))
|
||||||
#define RENAME_SYMBOL( x ) asm( x )
|
#define RENAME_SYMBOL( x ) asm( x )
|
||||||
#else
|
#else
|
||||||
#if defined( _MSC_VER )
|
#if defined( _MSC_VER )
|
||||||
#define EXPORT __declspec( dllexport )
|
#define EXPORT __declspec( dllexport )
|
||||||
|
#define NO_ASAN __declspec( no_sanitize_address )
|
||||||
#else
|
#else
|
||||||
#define EXPORT
|
#define EXPORT
|
||||||
|
#define NO_ASAN
|
||||||
#endif
|
#endif
|
||||||
#define GAME_EXPORT
|
#define GAME_EXPORT
|
||||||
#define NORETURN
|
#define NORETURN
|
||||||
@@ -98,18 +101,17 @@ typedef uint64_t longtime_t;
|
|||||||
#define RENAME_SYMBOL( x )
|
#define RENAME_SYMBOL( x )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( __GNUC__ >= 3 )
|
#if __GNUC__ >= 3
|
||||||
#define unlikely( x ) __builtin_expect( x, 0 )
|
#define unlikely( x ) __builtin_expect( x, 0 )
|
||||||
#define likely( x ) __builtin_expect( x, 1 )
|
#define likely( x ) __builtin_expect( x, 1 )
|
||||||
#elif defined( __has_builtin )
|
#elif defined( __has_builtin )
|
||||||
#if __has_builtin( __builtin_expect )
|
#if __has_builtin( __builtin_expect ) // this must be after defined() check
|
||||||
#define unlikely( x ) __builtin_expect( x, 0 )
|
#define unlikely( x ) __builtin_expect( x, 0 )
|
||||||
#define likely( x ) __builtin_expect( x, 1 )
|
#define likely( x ) __builtin_expect( x, 1 )
|
||||||
#else
|
|
||||||
#define unlikely( x ) ( x )
|
|
||||||
#define likely( x ) ( x )
|
|
||||||
#endif
|
#endif
|
||||||
#else
|
#endif
|
||||||
|
|
||||||
|
#if !defined( unlikely ) || !defined( likely )
|
||||||
#define unlikely( x ) ( x )
|
#define unlikely( x ) ( x )
|
||||||
#define likely( x ) ( x )
|
#define likely( x ) ( x )
|
||||||
#endif
|
#endif
|
||||||
@@ -128,6 +130,14 @@ typedef uint64_t longtime_t;
|
|||||||
#define STATIC_ASSERT( x, y ) STATIC_ASSERT_2( __LINE__, x, y )
|
#define STATIC_ASSERT( x, y ) STATIC_ASSERT_2( __LINE__, x, y )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined( __cplusplus ) && __STDC_VERSION__ >= 199101L // not C++ and C99 or newer
|
||||||
|
#define XASH_RESTRICT restrict
|
||||||
|
#elif _MSC_VER || __GNUC__ || __clang__ // compiler-specific extensions
|
||||||
|
#define XASH_RESTRICT __restrict
|
||||||
|
#else
|
||||||
|
#define XASH_RESTRICT // nothing
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef XASH_BIG_ENDIAN
|
#ifdef XASH_BIG_ENDIAN
|
||||||
#define LittleLong(x) (((int)(((x)&255)<<24)) + ((int)((((x)>>8)&255)<<16)) + ((int)(((x)>>16)&255)<<8) + (((x) >> 24)&255))
|
#define LittleLong(x) (((int)(((x)&255)<<24)) + ((int)((((x)>>8)&255)<<16)) + ((int)(((x)>>16)&255)<<8) + (((x) >> 24)&255))
|
||||||
#define LittleLongSW(x) (x = LittleLong(x) )
|
#define LittleLongSW(x) (x = LittleLong(x) )
|
||||||
|
|||||||
@@ -70,16 +70,17 @@ qboolean CL_CheckFile( sizebuf_t *msg, resource_t *pResource )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( cl.downloadUrl[0] )
|
host.downloadcount++;
|
||||||
|
|
||||||
|
if( cl.http_download )
|
||||||
{
|
{
|
||||||
HTTP_AddDownload( filepath, pResource->nDownloadSize, true );
|
HTTP_AddDownload( filepath, pResource->nDownloadSize, true );
|
||||||
host.downloadcount++;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
MSG_BeginClientCmd( msg, clc_stringcmd );
|
{
|
||||||
MSG_WriteStringf( msg, "dlfile %s", filepath );
|
MSG_BeginClientCmd( msg, clc_stringcmd );
|
||||||
host.downloadcount++;
|
MSG_WriteStringf( msg, "dlfile %s", filepath );
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1097,6 +1097,20 @@ static void GAME_EXPORT pfnCon_DefaultColor( int r, int g, int b )
|
|||||||
Con_DefaultColor( r, g, b, true );
|
Con_DefaultColor( r, g, b, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GAME_EXPORT pfnSetCursor( void *hCursor )
|
||||||
|
{
|
||||||
|
uintptr_t cursor;
|
||||||
|
|
||||||
|
if( !gameui.use_extended_api )
|
||||||
|
return; // ignore original Xash menus
|
||||||
|
|
||||||
|
cursor = (uintptr_t)hCursor;
|
||||||
|
if( cursor < dc_user || cursor > dc_last )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Platform_SetCursorType( cursor );
|
||||||
|
}
|
||||||
|
|
||||||
// engine callbacks
|
// engine callbacks
|
||||||
static ui_enginefuncs_t gEngfuncs =
|
static ui_enginefuncs_t gEngfuncs =
|
||||||
{
|
{
|
||||||
@@ -1176,7 +1190,7 @@ static ui_enginefuncs_t gEngfuncs =
|
|||||||
pfnHostEndGame,
|
pfnHostEndGame,
|
||||||
COM_RandomFloat,
|
COM_RandomFloat,
|
||||||
COM_RandomLong,
|
COM_RandomLong,
|
||||||
IN_SetCursor,
|
pfnSetCursor,
|
||||||
pfnIsMapValid,
|
pfnIsMapValid,
|
||||||
GL_ProcessTexture,
|
GL_ProcessTexture,
|
||||||
COM_CompareFileTime,
|
COM_CompareFileTime,
|
||||||
@@ -1286,7 +1300,7 @@ qboolean UI_LoadProgs( void )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gameui.use_text_api = false;
|
gameui.use_extended_api = false;
|
||||||
|
|
||||||
// make local copy of engfuncs to prevent overwrite it with user dll
|
// make local copy of engfuncs to prevent overwrite it with user dll
|
||||||
memcpy( &gpEngfuncs, &gEngfuncs, sizeof( gpEngfuncs ));
|
memcpy( &gpEngfuncs, &gEngfuncs, sizeof( gpEngfuncs ));
|
||||||
@@ -1313,7 +1327,7 @@ qboolean UI_LoadProgs( void )
|
|||||||
if( GetExtAPI( MENU_EXTENDED_API_VERSION, &gameui.dllFuncs2, &gpExtendedfuncs ) )
|
if( GetExtAPI( MENU_EXTENDED_API_VERSION, &gameui.dllFuncs2, &gpExtendedfuncs ) )
|
||||||
{
|
{
|
||||||
Con_Reportf( "UI_LoadProgs: extended Menu API initialized\n" );
|
Con_Reportf( "UI_LoadProgs: extended Menu API initialized\n" );
|
||||||
gameui.use_text_api = true;
|
gameui.use_extended_api = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // otherwise, fallback to old and deprecated extensions
|
else // otherwise, fallback to old and deprecated extensions
|
||||||
@@ -1325,7 +1339,7 @@ qboolean UI_LoadProgs( void )
|
|||||||
if( GiveTextApi( &gpExtendedfuncs ) ) // they are binary compatible, so we can just pass extended funcs API to menu
|
if( GiveTextApi( &gpExtendedfuncs ) ) // they are binary compatible, so we can just pass extended funcs API to menu
|
||||||
{
|
{
|
||||||
Con_Reportf( "UI_LoadProgs: extended text API initialized\n" );
|
Con_Reportf( "UI_LoadProgs: extended text API initialized\n" );
|
||||||
gameui.use_text_api = true;
|
gameui.use_extended_api = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -587,21 +587,38 @@ CL_CreateCmd
|
|||||||
*/
|
*/
|
||||||
static void CL_CreateCmd( void )
|
static void CL_CreateCmd( void )
|
||||||
{
|
{
|
||||||
usercmd_t nullcmd, *cmd;
|
usercmd_t nullcmd, *cmd;
|
||||||
runcmd_t *pcmd;
|
runcmd_t *pcmd;
|
||||||
vec3_t angles;
|
qboolean active;
|
||||||
qboolean active;
|
double accurate_ms;
|
||||||
int input_override;
|
vec3_t angles;
|
||||||
int i, ms;
|
int input_override;
|
||||||
|
int i, ms;
|
||||||
|
|
||||||
if( cls.state < ca_connected || cls.state == ca_cinematic )
|
if( cls.state < ca_connected || cls.state == ca_cinematic )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// store viewangles in case it's will be freeze
|
// store viewangles in case it's will be freeze
|
||||||
VectorCopy( cl.viewangles, angles );
|
VectorCopy( cl.viewangles, angles );
|
||||||
ms = bound( 1, host.frametime * 1000, 255 );
|
|
||||||
input_override = 0;
|
input_override = 0;
|
||||||
|
|
||||||
|
// fix rounding error and framerate depending player move
|
||||||
|
accurate_ms = host.frametime * 1000;
|
||||||
|
ms = (int)accurate_ms;
|
||||||
|
cl.frametime_remainder += accurate_ms - ms; // accumulate rounding error each frame
|
||||||
|
|
||||||
|
// add a ms if error accumulates enough
|
||||||
|
if( cl.frametime_remainder >= 1.0 )
|
||||||
|
{
|
||||||
|
int ms2 = (int)cl.frametime_remainder;
|
||||||
|
|
||||||
|
ms += ms2;
|
||||||
|
cl.frametime_remainder -= ms2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ms can't be negative, rely on error accumulation only if FPS > 1000
|
||||||
|
ms = Q_min( ms, 255 );
|
||||||
|
|
||||||
CL_SetSolidEntities();
|
CL_SetSolidEntities();
|
||||||
CL_PushPMStates();
|
CL_PushPMStates();
|
||||||
CL_SetSolidPlayers( cl.playernum );
|
CL_SetSolidPlayers( cl.playernum );
|
||||||
@@ -1618,9 +1635,17 @@ static size_t NONNULL CL_BuildMasterServerScanRequest( char *buf, size_t size, u
|
|||||||
#ifndef XASH_ALL_SERVERS
|
#ifndef XASH_ALL_SERVERS
|
||||||
Info_SetValueForKey( info, "gamedir", GI->gamefolder, remaining );
|
Info_SetValueForKey( info, "gamedir", GI->gamefolder, remaining );
|
||||||
#endif
|
#endif
|
||||||
Info_SetValueForKey( info, "clver", XASH_VERSION, remaining ); // let master know about client version
|
// let master know about client version
|
||||||
|
Info_SetValueForKey( info, "clver", XASH_VERSION, remaining );
|
||||||
Info_SetValueForKey( info, "nat", nat ? "1" : "0", remaining );
|
Info_SetValueForKey( info, "nat", nat ? "1" : "0", remaining );
|
||||||
|
Info_SetValueForKey( info, "commit", Q_buildcommit(), remaining );
|
||||||
|
Info_SetValueForKey( info, "branch", Q_buildbranch(), remaining );
|
||||||
|
Info_SetValueForKey( info, "os", Q_buildos(), remaining );
|
||||||
|
Info_SetValueForKey( info, "arch", Q_buildarch(), remaining );
|
||||||
|
|
||||||
|
Q_snprintf( temp, sizeof( temp ), "%d", Q_buildnum() );
|
||||||
|
Info_SetValueForKey( info, "buildnum", temp, remaining );
|
||||||
|
|
||||||
Q_snprintf( temp, sizeof( temp ), "%x", *key );
|
Q_snprintf( temp, sizeof( temp ), "%x", *key );
|
||||||
Info_SetValueForKey( info, "key", temp, remaining );
|
Info_SetValueForKey( info, "key", temp, remaining );
|
||||||
|
|
||||||
@@ -2510,11 +2535,6 @@ void CL_ProcessFile( qboolean successfully_received, const char *filename )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pfilename = filename;
|
|
||||||
|
|
||||||
if( !Q_strnicmp( filename, DEFAULT_SOUNDPATH, sound_len ))
|
|
||||||
pfilename += sound_len;
|
|
||||||
|
|
||||||
for( p = cl.resourcesneeded.pNext; p != &cl.resourcesneeded; p = p->pNext )
|
for( p = cl.resourcesneeded.pNext; p != &cl.resourcesneeded; p = p->pNext )
|
||||||
{
|
{
|
||||||
if( !Q_strnicmp( filename, "!MD5", 4 ))
|
if( !Q_strnicmp( filename, "!MD5", 4 ))
|
||||||
@@ -2524,18 +2544,20 @@ void CL_ProcessFile( qboolean successfully_received, const char *filename )
|
|||||||
if( !memcmp( p->rgucMD5_hash, rgucMD5_hash, 16 ))
|
if( !memcmp( p->rgucMD5_hash, rgucMD5_hash, 16 ))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if( p->type == t_sound )
|
||||||
|
{
|
||||||
|
const char *pfilename = filename;
|
||||||
|
|
||||||
|
if( !Q_strnicmp( filename, DEFAULT_SOUNDPATH, sound_len ))
|
||||||
|
pfilename += sound_len;
|
||||||
|
|
||||||
|
if( !Q_stricmp( p->szFileName, pfilename ))
|
||||||
|
break;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( p->type == t_generic )
|
if( !Q_stricmp( p->szFileName, filename ))
|
||||||
{
|
|
||||||
if( !Q_stricmp( p->szFileName, filename ))
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( !Q_stricmp( p->szFileName, pfilename ))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2600,7 +2622,7 @@ void CL_ProcessFile( qboolean successfully_received, const char *filename )
|
|||||||
|
|
||||||
if( cls.netchan.tempbuffer )
|
if( cls.netchan.tempbuffer )
|
||||||
{
|
{
|
||||||
Con_Printf( "Received a decal %s, but didn't find it in resources needed list!\n", pfilename );
|
Con_Printf( "Received a decal %s, but didn't find it in resources needed list!\n", filename );
|
||||||
Mem_Free( cls.netchan.tempbuffer );
|
Mem_Free( cls.netchan.tempbuffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2693,10 +2715,32 @@ static void CL_Physinfo_f( void )
|
|||||||
Con_Printf( "Total %i symbols\n", Q_strlen( cls.physinfo ));
|
Con_Printf( "Total %i symbols\n", Q_strlen( cls.physinfo ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static qboolean CL_ShouldRescanFilesystem( void )
|
||||||
|
{
|
||||||
|
resource_t *res;
|
||||||
|
|
||||||
|
for( res = cl.resourcesonhand.pNext; res && res != &cl.resourcesonhand; res = res->pNext )
|
||||||
|
{
|
||||||
|
if( res->type == t_generic )
|
||||||
|
{
|
||||||
|
const char *ext = COM_FileExtension( res->szFileName );
|
||||||
|
// TODO: query supported archives format from fs_stdio
|
||||||
|
// TODO: query if was already opened
|
||||||
|
if( !Q_stricmp( ext, "wad" ) || !Q_stricmp( ext, "pk3" ) || !Q_stricmp( ext, "pak" ))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
qboolean CL_PrecacheResources( void )
|
qboolean CL_PrecacheResources( void )
|
||||||
{
|
{
|
||||||
resource_t *pRes;
|
resource_t *pRes;
|
||||||
|
|
||||||
|
// if we downloaded new WAD files or any other archives they must be added to searchpath
|
||||||
|
if( CL_ShouldRescanFilesystem( ))
|
||||||
|
g_fsapi.Rescan();
|
||||||
|
|
||||||
// NOTE: world need to be loaded as first model
|
// NOTE: world need to be loaded as first model
|
||||||
for( pRes = cl.resourcesonhand.pNext; pRes && pRes != &cl.resourcesonhand; pRes = pRes->pNext )
|
for( pRes = cl.resourcesonhand.pNext; pRes && pRes != &cl.resourcesonhand; pRes = pRes->pNext )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -458,6 +458,7 @@ void CL_BatchResourceRequest( qboolean initialize )
|
|||||||
byte data[MAX_INIT_MSG];
|
byte data[MAX_INIT_MSG];
|
||||||
resource_t *p, *n;
|
resource_t *p, *n;
|
||||||
sizebuf_t msg;
|
sizebuf_t msg;
|
||||||
|
qboolean done_downloading = true;
|
||||||
|
|
||||||
MSG_Init( &msg, "Resource Batch", data, sizeof( data ));
|
MSG_Init( &msg, "Resource Batch", data, sizeof( data ));
|
||||||
|
|
||||||
@@ -487,7 +488,10 @@ void CL_BatchResourceRequest( qboolean initialize )
|
|||||||
case t_model:
|
case t_model:
|
||||||
case t_eventscript:
|
case t_eventscript:
|
||||||
if( !CL_CheckFile( &msg, p ))
|
if( !CL_CheckFile( &msg, p ))
|
||||||
|
{
|
||||||
|
done_downloading = false;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
CL_MoveToOnHandList( p );
|
CL_MoveToOnHandList( p );
|
||||||
break;
|
break;
|
||||||
case t_skin:
|
case t_skin:
|
||||||
@@ -501,6 +505,7 @@ void CL_BatchResourceRequest( qboolean initialize )
|
|||||||
MSG_BeginClientCmd( &msg, clc_stringcmd );
|
MSG_BeginClientCmd( &msg, clc_stringcmd );
|
||||||
MSG_WriteStringf( &msg, "dlfile !MD5%s", MD5_Print( p->rgucMD5_hash ));;
|
MSG_WriteStringf( &msg, "dlfile !MD5%s", MD5_Print( p->rgucMD5_hash ));;
|
||||||
SetBits( p->ucFlags, RES_REQUESTED );
|
SetBits( p->ucFlags, RES_REQUESTED );
|
||||||
|
done_downloading = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -525,11 +530,7 @@ void CL_BatchResourceRequest( qboolean initialize )
|
|||||||
|
|
||||||
if( cls.state != ca_disconnected )
|
if( cls.state != ca_disconnected )
|
||||||
{
|
{
|
||||||
if( !cl.downloadUrl[0] && !MSG_GetNumBytesWritten( &msg ) && CL_PrecacheResources( ))
|
if( done_downloading && CL_PrecacheResources( ))
|
||||||
{
|
|
||||||
CL_RegisterResources( &msg );
|
|
||||||
}
|
|
||||||
if( cl.downloadUrl[0] && host.downloadcount == 0 && CL_PrecacheResources( ) )
|
|
||||||
{
|
{
|
||||||
CL_RegisterResources( &msg );
|
CL_RegisterResources( &msg );
|
||||||
}
|
}
|
||||||
@@ -1840,13 +1841,10 @@ void CL_ParseResLocation( sizebuf_t *msg )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while( ( data = COM_ParseFile( data, token, sizeof( token ) ) ) )
|
while(( data = COM_ParseFile( data, token, sizeof( token ))))
|
||||||
{
|
{
|
||||||
Con_Reportf( "Adding %s as download location\n", token );
|
Con_Reportf( "Adding %s as download location\n", token );
|
||||||
|
cl.http_download = true;
|
||||||
if( !cl.downloadUrl[0] )
|
|
||||||
Q_strncpy( cl.downloadUrl, token, sizeof( token ) );
|
|
||||||
|
|
||||||
HTTP_AddCustomServer( token );
|
HTTP_AddCustomServer( token );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -844,7 +844,7 @@ static void CL_QuakeExecStuff( void )
|
|||||||
while( 1 )
|
while( 1 )
|
||||||
{
|
{
|
||||||
// skip whitespace up to a /n
|
// skip whitespace up to a /n
|
||||||
while( *text && ((byte)*text) <= ' ' && *text != '\r' && *text != '\n' )
|
while( *text && ((byte)*text ) <= ' ' && *text != '\r' && *text != '\n' )
|
||||||
text++;
|
text++;
|
||||||
|
|
||||||
if( *text == '\n' || *text == '\r' )
|
if( *text == '\n' || *text == '\r' )
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ GNU General Public License for more details.
|
|||||||
|
|
||||||
int R_FatPVS( const vec3_t org, float radius, byte *visbuffer, qboolean merge, qboolean fullvis )
|
int R_FatPVS( const vec3_t org, float radius, byte *visbuffer, qboolean merge, qboolean fullvis )
|
||||||
{
|
{
|
||||||
return Mod_FatPVS( org, radius, visbuffer, world.visbytes, merge, fullvis );
|
return Mod_FatPVS( org, radius, visbuffer, world.visbytes, merge, fullvis, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
lightstyle_t *CL_GetLightStyle( int number )
|
lightstyle_t *CL_GetLightStyle( int number )
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ typedef struct
|
|||||||
char serverinfo[MAX_SERVERINFO_STRING];
|
char serverinfo[MAX_SERVERINFO_STRING];
|
||||||
player_info_t players[MAX_CLIENTS]; // collected info about all other players include himself
|
player_info_t players[MAX_CLIENTS]; // collected info about all other players include himself
|
||||||
double lastresourcecheck;
|
double lastresourcecheck;
|
||||||
string downloadUrl;
|
qboolean http_download;
|
||||||
event_state_t events;
|
event_state_t events;
|
||||||
|
|
||||||
// predicting stuff but not only...
|
// predicting stuff but not only...
|
||||||
@@ -276,6 +276,8 @@ typedef struct
|
|||||||
model_t *worldmodel; // pointer to world
|
model_t *worldmodel; // pointer to world
|
||||||
|
|
||||||
int lostpackets; // count lost packets and show dialog in menu
|
int lostpackets; // count lost packets and show dialog in menu
|
||||||
|
|
||||||
|
double frametime_remainder;
|
||||||
} client_t;
|
} client_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -518,7 +520,7 @@ typedef struct
|
|||||||
int logo_yres;
|
int logo_yres;
|
||||||
float logo_length;
|
float logo_length;
|
||||||
|
|
||||||
qboolean use_text_api;
|
qboolean use_extended_api;
|
||||||
} gameui_static_t;
|
} gameui_static_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -630,6 +632,9 @@ typedef struct
|
|||||||
int extensions;
|
int extensions;
|
||||||
|
|
||||||
netadr_t serveradr;
|
netadr_t serveradr;
|
||||||
|
|
||||||
|
// do we accept utf8 as input
|
||||||
|
qboolean accept_utf8;
|
||||||
} client_static_t;
|
} client_static_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ static CVAR_DEFINE_AUTO( scr_drawversion, "1", FCVAR_ARCHIVE, "draw version in m
|
|||||||
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" );
|
||||||
|
|
||||||
static int g_codepage = 0;
|
static int g_codepage = 0;
|
||||||
static qboolean g_utf8 = false;
|
|
||||||
|
|
||||||
static qboolean g_messagemode_privileged = true;
|
static qboolean g_messagemode_privileged = true;
|
||||||
|
|
||||||
@@ -635,10 +634,13 @@ int Con_UtfProcessCharForce( int in )
|
|||||||
|
|
||||||
int GAME_EXPORT Con_UtfProcessChar( int in )
|
int GAME_EXPORT Con_UtfProcessChar( int in )
|
||||||
{
|
{
|
||||||
if( !g_utf8 )
|
if( !cls.accept_utf8 ) // incoming character is not a UTF-8 sequence
|
||||||
return in;
|
return in;
|
||||||
|
|
||||||
|
// otherwise, decode it and convert to selected codepage
|
||||||
return Con_UtfProcessCharForce( in );
|
return Con_UtfProcessCharForce( in );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
Con_UtfMoveLeft
|
Con_UtfMoveLeft
|
||||||
@@ -652,7 +654,7 @@ int Con_UtfMoveLeft( char *str, int pos )
|
|||||||
int k = 0;
|
int k = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if( !g_utf8 )
|
if( !cls.accept_utf8 ) // incoming character is not a UTF-8 sequence
|
||||||
return pos - 1;
|
return pos - 1;
|
||||||
|
|
||||||
if( pos == 1 )
|
if( pos == 1 )
|
||||||
@@ -679,7 +681,7 @@ int Con_UtfMoveRight( char *str, int pos, int length )
|
|||||||
utfstate_t state = { 0 };
|
utfstate_t state = { 0 };
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if( !g_utf8 )
|
if( !cls.accept_utf8 ) // incoming character is not a UTF-8 sequence
|
||||||
return pos + 1;
|
return pos + 1;
|
||||||
|
|
||||||
for( i = pos; i <= length; i++ )
|
for( i = pos; i <= length; i++ )
|
||||||
@@ -2097,7 +2099,7 @@ void Con_RunConsole( void )
|
|||||||
g_codepage = 1252;
|
g_codepage = 1252;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_utf8 = !Q_stricmp( cl_charset.string, "utf-8" );
|
cls.accept_utf8 = !Q_stricmp( cl_charset.string, "utf-8" );
|
||||||
Con_InvalidateFonts();
|
Con_InvalidateFonts();
|
||||||
Con_LoadConchars();
|
Con_LoadConchars();
|
||||||
ClearBits( con_charset.flags, FCVAR_CHANGED );
|
ClearBits( con_charset.flags, FCVAR_CHANGED );
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ GNU General Public License for more details.
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "vgui_draw.h"
|
#include "vgui_draw.h"
|
||||||
|
#include "cursor_type.h"
|
||||||
|
|
||||||
#if XASH_SDL
|
#if XASH_SDL
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
@@ -123,11 +124,6 @@ static void IN_StartupMouse( void )
|
|||||||
in_mouseinitialized = true;
|
in_mouseinitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GAME_EXPORT IN_SetCursor( void *hCursor )
|
|
||||||
{
|
|
||||||
// stub
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===========
|
===========
|
||||||
IN_MouseSavePos
|
IN_MouseSavePos
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ void IN_DeactivateMouse( void );
|
|||||||
void IN_MouseSavePos( void );
|
void IN_MouseSavePos( void );
|
||||||
void IN_MouseRestorePos( void );
|
void IN_MouseRestorePos( void );
|
||||||
void IN_ToggleClientMouse( int newstate, int oldstate );
|
void IN_ToggleClientMouse( int newstate, int oldstate );
|
||||||
void IN_SetCursor( void *hCursor );
|
|
||||||
|
|
||||||
uint IN_CollectInputDevices( void );
|
uint IN_CollectInputDevices( void );
|
||||||
void IN_LockInputDevices( qboolean lock );
|
void IN_LockInputDevices( qboolean lock );
|
||||||
|
|||||||
@@ -553,7 +553,7 @@ static void Key_AddKeyCommands( int key, const char *kb, qboolean down )
|
|||||||
}
|
}
|
||||||
|
|
||||||
buttonPtr = button;
|
buttonPtr = button;
|
||||||
while(( kb[i] <= ' ' || kb[i] == ';' ) && kb[i] != 0 )
|
while((((byte)kb[i]) <= ' ' || kb[i] == ';' ) && kb[i] != 0 )
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -749,10 +749,10 @@ void GAME_EXPORT Key_Event( int key, int down )
|
|||||||
if( cls.key_dest == key_menu )
|
if( cls.key_dest == key_menu )
|
||||||
{
|
{
|
||||||
// only non printable keys passed
|
// only non printable keys passed
|
||||||
if( !gameui.use_text_api )
|
if( !gameui.use_extended_api )
|
||||||
Key_EnableTextInput( true, false );
|
Key_EnableTextInput( true, false );
|
||||||
//pass printable chars for old menus
|
//pass printable chars for old menus
|
||||||
if( !gameui.use_text_api && !host.textmode && down && ( key >= 32 ) && ( key <= 'z' ) )
|
if( !gameui.use_extended_api && !host.textmode && down && ( key >= 32 ) && ( key <= 'z' ) )
|
||||||
{
|
{
|
||||||
if( Key_IsDown( K_SHIFT ) )
|
if( Key_IsDown( K_SHIFT ) )
|
||||||
{
|
{
|
||||||
@@ -1055,15 +1055,16 @@ static qboolean OSK_KeyEvent( int key, int down )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ch = Con_UtfProcessChar((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;
|
||||||
|
|
||||||
Con_CharEvent( ch );
|
CL_CharEvent( ch );
|
||||||
if( cls.key_dest == key_menu )
|
|
||||||
UI_CharEvent ( ch );
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1118,7 +1119,6 @@ static void OSK_EnableTextInput( qboolean enable, qboolean force )
|
|||||||
{
|
{
|
||||||
osk.curlayout = 0;
|
osk.curlayout = 0;
|
||||||
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
|
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -685,6 +685,9 @@ void Mod_CreatePolygonsForHull( int hullnum )
|
|||||||
if( hullnum < 1 || hullnum > 3 )
|
if( hullnum < 1 || hullnum > 3 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if( !world.num_hull_models )
|
||||||
|
Mod_InitDebugHulls( mod ); // FIXME: build hulls for separate bmodels (shells, medkits etc)
|
||||||
|
|
||||||
Con_Printf( "generating polygons for hull %u...\n", hullnum );
|
Con_Printf( "generating polygons for hull %u...\n", hullnum );
|
||||||
start = Sys_DoubleTime();
|
start = Sys_DoubleTime();
|
||||||
|
|
||||||
|
|||||||
@@ -154,7 +154,8 @@ static const sx_preset_t rgsxpre_hlalpha052[] =
|
|||||||
static const sx_preset_t *ptable = rgsxpre;
|
static const sx_preset_t *ptable = rgsxpre;
|
||||||
|
|
||||||
// cvars
|
// cvars
|
||||||
static CVAR_DEFINE_AUTO( dsp_off, "0", FCVAR_ARCHIVE, "disable DSP processing" );
|
static CVAR_DEFINE_AUTO( dsp_off, "0", FCVAR_ARCHIVE, "disable DSP processing (deprecated)" );
|
||||||
|
static CVAR_DEFINE_AUTO( room_off, "0", FCVAR_ARCHIVE, "disable DSP processing (GoldSrc compatible cvar)" );
|
||||||
static CVAR_DEFINE_AUTO( dsp_coeff_table, "0", FCVAR_ARCHIVE, "select DSP coefficient table: 0 for release or 1 for alpha 0.52" );
|
static CVAR_DEFINE_AUTO( dsp_coeff_table, "0", FCVAR_ARCHIVE, "select DSP coefficient table: 0 for release or 1 for alpha 0.52" );
|
||||||
static CVAR_DEFINE_AUTO( room_type, "0", 0, "current room type preset" );
|
static CVAR_DEFINE_AUTO( room_type, "0", 0, "current room type preset" );
|
||||||
|
|
||||||
@@ -232,6 +233,7 @@ void SX_Init( void )
|
|||||||
sxmod2cur = sxmod2 = 450 * ( idsp_dma_speed / SOUND_11k );
|
sxmod2cur = sxmod2 = 450 * ( idsp_dma_speed / SOUND_11k );
|
||||||
|
|
||||||
Cvar_RegisterVariable( &dsp_off );
|
Cvar_RegisterVariable( &dsp_off );
|
||||||
|
Cvar_RegisterVariable( &room_off );
|
||||||
Cvar_RegisterVariable( &dsp_coeff_table );
|
Cvar_RegisterVariable( &dsp_coeff_table );
|
||||||
|
|
||||||
Cvar_RegisterVariable( &roomwater_type );
|
Cvar_RegisterVariable( &roomwater_type );
|
||||||
@@ -809,7 +811,7 @@ DSP_Process
|
|||||||
*/
|
*/
|
||||||
void DSP_Process( portable_samplepair_t *pbfront, int sampleCount )
|
void DSP_Process( portable_samplepair_t *pbfront, int sampleCount )
|
||||||
{
|
{
|
||||||
if( dsp_off.value || !sampleCount )
|
if( dsp_off.value || room_off.value || !sampleCount )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// preset is already installed by CheckNewDspPresets
|
// preset is already installed by CheckNewDspPresets
|
||||||
@@ -843,7 +845,7 @@ CheckNewDspPresets
|
|||||||
*/
|
*/
|
||||||
void CheckNewDspPresets( void )
|
void CheckNewDspPresets( void )
|
||||||
{
|
{
|
||||||
if( dsp_off.value != 0.0f )
|
if( dsp_off.value || room_off.value )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( FBitSet( dsp_coeff_table.flags, FCVAR_CHANGED ))
|
if( FBitSet( dsp_coeff_table.flags, FCVAR_CHANGED ))
|
||||||
|
|||||||
@@ -640,7 +640,7 @@ void Cmd_TokenizeString( const char *text )
|
|||||||
while( 1 )
|
while( 1 )
|
||||||
{
|
{
|
||||||
// skip whitespace up to a /n
|
// skip whitespace up to a /n
|
||||||
while( *text && *text <= ' ' && *text != '\r' && *text != '\n' )
|
while( *text && ((byte)*text ) <= ' ' && *text != '\r' && *text != '\n' )
|
||||||
text++;
|
text++;
|
||||||
|
|
||||||
if( *text == '\n' || *text == '\r' )
|
if( *text == '\n' || *text == '\r' )
|
||||||
|
|||||||
@@ -25,16 +25,19 @@ GNU General Public License for more details.
|
|||||||
|
|
||||||
static const char *file_exts[] =
|
static const char *file_exts[] =
|
||||||
{
|
{
|
||||||
"cfg",
|
// ban text files that don't make sense as resource
|
||||||
"lst",
|
"cfg", "lst", "ini", "log",
|
||||||
"exe",
|
|
||||||
"vbs",
|
// ban Windows code
|
||||||
"com",
|
"exe", "vbs", "com", "bat",
|
||||||
"bat",
|
"dll", "sys", "ps1",
|
||||||
"dll",
|
|
||||||
"ini",
|
// ban common unix code
|
||||||
"log",
|
// NOTE: in unix anything can be executed as long it has access flag
|
||||||
"sys",
|
"so", "sh", "dylib",
|
||||||
|
|
||||||
|
// ban mobile archives
|
||||||
|
"apk", "ipa",
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
@@ -900,7 +903,10 @@ qboolean COM_IsSafeFileToDownload( const char *filename )
|
|||||||
if( !COM_CheckString( filename ))
|
if( !COM_CheckString( filename ))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( !Q_strncmp( filename, "!MD5", 4 ))
|
ext = COM_FileExtension( lwrfilename );
|
||||||
|
|
||||||
|
// only allow extensionless files that start with !MD5
|
||||||
|
if( !Q_strncmp( filename, "!MD5", 4 ) && ext[0] == 0 )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
Q_strnlwr( filename, lwrfilename, sizeof( lwrfilename ));
|
Q_strnlwr( filename, lwrfilename, sizeof( lwrfilename ));
|
||||||
@@ -923,8 +929,6 @@ qboolean COM_IsSafeFileToDownload( const char *filename )
|
|||||||
if( Q_strlen( first ) != 4 )
|
if( Q_strlen( first ) != 4 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ext = COM_FileExtension( lwrfilename );
|
|
||||||
|
|
||||||
for( i = 0; i < ARRAYSIZE( file_exts ); i++ )
|
for( i = 0; i < ARRAYSIZE( file_exts ); i++ )
|
||||||
{
|
{
|
||||||
if( !Q_stricmp( ext, file_exts[i] ))
|
if( !Q_stricmp( ext, file_exts[i] ))
|
||||||
|
|||||||
@@ -129,6 +129,22 @@ static void Sys_StackTrace( PEXCEPTION_POINTERS pInfo )
|
|||||||
stackframe.AddrBStore.Mode = AddrModeFlat;
|
stackframe.AddrBStore.Mode = AddrModeFlat;
|
||||||
stackframe.AddrStack.Offset = context.IntSp;
|
stackframe.AddrStack.Offset = context.IntSp;
|
||||||
stackframe.AddrStack.Mode = AddrModeFlat;
|
stackframe.AddrStack.Mode = AddrModeFlat;
|
||||||
|
#elif _M_ARM
|
||||||
|
image = IMAGE_FILE_MACHINE_ARMNT;
|
||||||
|
stackframe.AddrPC.Offset = context.Pc;
|
||||||
|
stackframe.AddrPC.Mode = AddrModeFlat;
|
||||||
|
stackframe.AddrFrame.Offset = context.R11;
|
||||||
|
stackframe.AddrFrame.Mode = AddrModeFlat;
|
||||||
|
stackframe.AddrStack.Offset = context.Sp;
|
||||||
|
stackframe.AddrStack.Mode = AddrModeFlat;
|
||||||
|
#elif _M_ARM64
|
||||||
|
image = IMAGE_FILE_MACHINE_ARM64;
|
||||||
|
stackframe.AddrPC.Offset = context.Pc;
|
||||||
|
stackframe.AddrPC.Mode = AddrModeFlat;
|
||||||
|
stackframe.AddrFrame.Offset = context.Fp;
|
||||||
|
stackframe.AddrFrame.Mode = AddrModeFlat;
|
||||||
|
stackframe.AddrStack.Offset = context.Sp;
|
||||||
|
stackframe.AddrStack.Mode = AddrModeFlat;
|
||||||
#elif
|
#elif
|
||||||
#error
|
#error
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ GNU General Public License for more details.
|
|||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "server.h" // LUMP_ error codes
|
#include "server.h" // LUMP_ error codes
|
||||||
#include "ref_common.h"
|
#include "ref_common.h"
|
||||||
|
#if defined( HAVE_OPENMP )
|
||||||
|
#include <omp.h>
|
||||||
|
#endif // HAVE_OPENMP
|
||||||
|
|
||||||
#define MIPTEX_CUSTOM_PALETTE_SIZE_BYTES ( sizeof( int16_t ) + 768 )
|
#define MIPTEX_CUSTOM_PALETTE_SIZE_BYTES ( sizeof( int16_t ) + 768 )
|
||||||
|
|
||||||
@@ -578,6 +581,42 @@ void Mod_PrintWorldStats_f( void )
|
|||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
===================
|
||||||
|
Mod_DecompressPVS
|
||||||
|
|
||||||
|
TODO: replace all Mod_DecompressPVS calls by this
|
||||||
|
===================
|
||||||
|
*/
|
||||||
|
static void Mod_DecompressPVSTo( byte *const out, const byte *in, size_t visbytes )
|
||||||
|
{
|
||||||
|
byte *dst = out;
|
||||||
|
|
||||||
|
if( !in ) // no visinfo, make all visible
|
||||||
|
{
|
||||||
|
memset( out, 0xFF, visbytes );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( dst < out + visbytes )
|
||||||
|
{
|
||||||
|
if( *in ) // uncompressed
|
||||||
|
{
|
||||||
|
*dst++ = *in++;
|
||||||
|
}
|
||||||
|
else // zero repeated `c` times
|
||||||
|
{
|
||||||
|
size_t c = in[1];
|
||||||
|
if( c > out + visbytes - dst )
|
||||||
|
c = out + visbytes - dst;
|
||||||
|
|
||||||
|
memset( dst, 0, c );
|
||||||
|
in += 2;
|
||||||
|
dst += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===================
|
===================
|
||||||
Mod_DecompressPVS
|
Mod_DecompressPVS
|
||||||
@@ -585,41 +624,36 @@ Mod_DecompressPVS
|
|||||||
*/
|
*/
|
||||||
static byte *Mod_DecompressPVS( const byte *in, int visbytes )
|
static byte *Mod_DecompressPVS( const byte *in, int visbytes )
|
||||||
{
|
{
|
||||||
byte *out;
|
Mod_DecompressPVSTo( g_visdata, in, visbytes );
|
||||||
int c;
|
return g_visdata;
|
||||||
|
}
|
||||||
|
|
||||||
out = g_visdata;
|
static size_t Mod_CompressPVS( byte *const out, const byte *in, size_t inbytes )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
byte *dst = out;
|
||||||
|
|
||||||
if( !in )
|
for( i = 0; i < inbytes; i++ )
|
||||||
{
|
{
|
||||||
// no vis info, so make all visible
|
size_t j = i + 1, rep = 1;
|
||||||
while( visbytes )
|
|
||||||
|
*dst++ = in[i];
|
||||||
|
|
||||||
|
// only compress zeros
|
||||||
|
if( in[i] )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for( ; j < inbytes && rep != 255; j++, rep++ )
|
||||||
{
|
{
|
||||||
*out++ = 0xff;
|
if( in[j] )
|
||||||
visbytes--;
|
break;
|
||||||
}
|
}
|
||||||
return g_visdata;
|
|
||||||
|
*dst++ = rep;
|
||||||
|
i = j - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
return dst - out;
|
||||||
{
|
|
||||||
if( *in )
|
|
||||||
{
|
|
||||||
*out++ = *in++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = in[1];
|
|
||||||
in += 2;
|
|
||||||
|
|
||||||
while( c )
|
|
||||||
{
|
|
||||||
*out++ = 0;
|
|
||||||
c--;
|
|
||||||
}
|
|
||||||
} while( out - g_visdata < visbytes );
|
|
||||||
|
|
||||||
return g_visdata;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -653,22 +687,11 @@ NOTE: can return NULL
|
|||||||
*/
|
*/
|
||||||
byte *Mod_GetPVSForPoint( const vec3_t p )
|
byte *Mod_GetPVSForPoint( const vec3_t p )
|
||||||
{
|
{
|
||||||
mnode_t *node;
|
mleaf_t *leaf;
|
||||||
mleaf_t *leaf = NULL;
|
|
||||||
|
|
||||||
ASSERT( worldmodel != NULL );
|
ASSERT( worldmodel != NULL );
|
||||||
|
|
||||||
node = worldmodel->nodes;
|
leaf = Mod_PointInLeaf( p, worldmodel->nodes );
|
||||||
|
|
||||||
while( 1 )
|
|
||||||
{
|
|
||||||
if( node->contents < 0 )
|
|
||||||
{
|
|
||||||
leaf = (mleaf_t *)node;
|
|
||||||
break; // we found a leaf
|
|
||||||
}
|
|
||||||
node = node->children[PlaneDiff( p, node->plane ) <= 0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if( leaf && leaf->cluster >= 0 )
|
if( leaf && leaf->cluster >= 0 )
|
||||||
return Mod_DecompressPVS( leaf->compressed_vis, world.visbytes );
|
return Mod_DecompressPVS( leaf->compressed_vis, world.visbytes );
|
||||||
@@ -681,7 +704,7 @@ Mod_FatPVS_RecursiveBSPNode
|
|||||||
|
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
static void Mod_FatPVS_RecursiveBSPNode( const vec3_t org, float radius, byte *visbuffer, int visbytes, mnode_t *node )
|
static void Mod_FatPVS_RecursiveBSPNode( const vec3_t org, float radius, byte *visbuffer, int visbytes, mnode_t *node, qboolean phs )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -696,7 +719,7 @@ static void Mod_FatPVS_RecursiveBSPNode( const vec3_t org, float radius, byte *v
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// go down both sides
|
// go down both sides
|
||||||
Mod_FatPVS_RecursiveBSPNode( org, radius, visbuffer, visbytes, node->children[0] );
|
Mod_FatPVS_RecursiveBSPNode( org, radius, visbuffer, visbytes, node->children[0], phs );
|
||||||
node = node->children[1];
|
node = node->children[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -704,10 +727,19 @@ static void Mod_FatPVS_RecursiveBSPNode( const vec3_t org, float radius, byte *v
|
|||||||
// if this leaf is in a cluster, accumulate the vis bits
|
// if this leaf is in a cluster, accumulate the vis bits
|
||||||
if(((mleaf_t *)node)->cluster >= 0 )
|
if(((mleaf_t *)node)->cluster >= 0 )
|
||||||
{
|
{
|
||||||
byte *vis = Mod_DecompressPVS( ((mleaf_t *)node)->compressed_vis, world.visbytes );
|
byte *vis;
|
||||||
|
|
||||||
for( i = 0; i < visbytes; i++ )
|
if( phs )
|
||||||
visbuffer[i] |= vis[i];
|
{
|
||||||
|
int i = ((mleaf_t *)node)->cluster + 1;
|
||||||
|
vis = Mod_DecompressPVS( &world.compressed_phs[world.phsofs[i]], world.visbytes );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vis = Mod_DecompressPVS( ((mleaf_t *)node)->compressed_vis, world.visbytes );
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_memor( visbuffer, vis, visbytes );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -719,7 +751,7 @@ Calculates a PVS that is the inclusive or of all leafs
|
|||||||
within radius pixels of the given point.
|
within radius pixels of the given point.
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis )
|
int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis, qboolean phs )
|
||||||
{
|
{
|
||||||
int bytes = world.visbytes;
|
int bytes = world.visbytes;
|
||||||
mleaf_t *leaf = NULL;
|
mleaf_t *leaf = NULL;
|
||||||
@@ -736,9 +768,17 @@ int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, q
|
|||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// requested PHS but we don't have PHS for some reason
|
||||||
|
// enable full visibility
|
||||||
|
if( phs && !( world.compressed_phs && world.phsofs ))
|
||||||
|
{
|
||||||
|
memset( visbuffer, 0xFF, bytes );
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
if( !merge ) memset( visbuffer, 0x00, bytes );
|
if( !merge ) memset( visbuffer, 0x00, bytes );
|
||||||
|
|
||||||
Mod_FatPVS_RecursiveBSPNode( org, radius, visbuffer, bytes, worldmodel->nodes );
|
Mod_FatPVS_RecursiveBSPNode( org, radius, visbuffer, bytes, worldmodel->nodes, phs );
|
||||||
|
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
@@ -1835,7 +1875,7 @@ static void Mod_LoadEntities( model_t *mod, dbspmodel_t *bmod )
|
|||||||
COM_FixSlashes( pszWadFile );
|
COM_FixSlashes( pszWadFile );
|
||||||
COM_FileBase( pszWadFile, token, sizeof( token ));
|
COM_FileBase( pszWadFile, token, sizeof( token ));
|
||||||
|
|
||||||
// make sure what wad is really exist
|
// make sure that wad is really exist
|
||||||
if( FS_FileExists( va( "%s.wad", token ), false ))
|
if( FS_FileExists( va( "%s.wad", token ), false ))
|
||||||
{
|
{
|
||||||
int num = bmod->wadlist.count++;
|
int num = bmod->wadlist.count++;
|
||||||
@@ -2028,18 +2068,16 @@ static qboolean Mod_LooksLikeWaterTexture( const char *name )
|
|||||||
|
|
||||||
static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureIndex )
|
static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureIndex )
|
||||||
{
|
{
|
||||||
#if !XASH_DEDICATED
|
|
||||||
texture_t *texture = NULL;
|
texture_t *texture = NULL;
|
||||||
mip_t *mipTex = NULL;
|
mip_t *mipTex = NULL;
|
||||||
qboolean usesCustomPalette = false;
|
qboolean usesCustomPalette = false;
|
||||||
uint32_t txFlags = 0;
|
uint32_t txFlags = 0;
|
||||||
|
|
||||||
// Don't load texture data on dedicated server, as there is no renderer.
|
// don't load texture data on dedicated server, as there is no renderer.
|
||||||
|
// but count the wadusage for automatic precache
|
||||||
|
//
|
||||||
// FIXME: for ENGINE_IMPROVED_LINETRACE we need to load textures on server too
|
// FIXME: for ENGINE_IMPROVED_LINETRACE we need to load textures on server too
|
||||||
// but there is no facility for this yet
|
// but there is no facility for this yet
|
||||||
if( Host_IsDedicated( ))
|
|
||||||
return;
|
|
||||||
|
|
||||||
texture = mod->textures[textureIndex];
|
texture = mod->textures[textureIndex];
|
||||||
mipTex = Mod_GetMipTexForTexture( bmod, textureIndex );
|
mipTex = Mod_GetMipTexForTexture( bmod, textureIndex );
|
||||||
|
|
||||||
@@ -2055,10 +2093,15 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
|
|||||||
// check for multi-layered sky texture (quake1 specific)
|
// check for multi-layered sky texture (quake1 specific)
|
||||||
if( bmod->isworld && Q_strncmp( mipTex->name, "sky", 3 ) == 0 && ( mipTex->width / mipTex->height ) == 2 )
|
if( bmod->isworld && Q_strncmp( mipTex->name, "sky", 3 ) == 0 && ( mipTex->width / mipTex->height ) == 2 )
|
||||||
{
|
{
|
||||||
ref.dllFuncs.R_InitSkyClouds( mipTex, texture, usesCustomPalette ); // load quake sky
|
#if !XASH_DEDICATED
|
||||||
|
if( !Host_IsDedicated( ))
|
||||||
|
{
|
||||||
|
ref.dllFuncs.R_InitSkyClouds( mipTex, texture, usesCustomPalette ); // load quake sky
|
||||||
|
|
||||||
if( R_GetBuiltinTexture( REF_SOLIDSKY_TEXTURE ) && R_GetBuiltinTexture( REF_ALPHASKY_TEXTURE ))
|
if( R_GetBuiltinTexture( REF_SOLIDSKY_TEXTURE ) && R_GetBuiltinTexture( REF_ALPHASKY_TEXTURE ))
|
||||||
SetBits( world.flags, FWORLD_SKYSPHERE );
|
SetBits( world.flags, FWORLD_SKYSPHERE );
|
||||||
|
}
|
||||||
|
#endif // !XASH_DEDICATED
|
||||||
|
|
||||||
// No texture to load in this case, so just exit.
|
// No texture to load in this case, so just exit.
|
||||||
return;
|
return;
|
||||||
@@ -2076,11 +2119,18 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
|
|||||||
|
|
||||||
if( wadIndex >= 0 )
|
if( wadIndex >= 0 )
|
||||||
{
|
{
|
||||||
texture->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texpath, NULL, 0, txFlags );
|
#if !XASH_DEDICATED
|
||||||
|
if( !Host_IsDedicated( ))
|
||||||
|
texture->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texpath, NULL, 0, txFlags );
|
||||||
|
#endif // !XASH_DEDICATED
|
||||||
bmod->wadlist.wadusage[wadIndex]++;
|
bmod->wadlist.wadusage[wadIndex]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !XASH_DEDICATED
|
||||||
|
if( Host_IsDedicated( ))
|
||||||
|
return;
|
||||||
|
|
||||||
// WAD failed, so use internal texture (if present)
|
// WAD failed, so use internal texture (if present)
|
||||||
if( mipTex->offsets[0] > 0 && texture->gl_texturenum == 0 )
|
if( mipTex->offsets[0] > 0 && texture->gl_texturenum == 0 )
|
||||||
{
|
{
|
||||||
@@ -2709,6 +2759,153 @@ static void Mod_LoadLeafs( model_t *mod, dbspmodel_t *bmod )
|
|||||||
SetBits( world.flags, FWORLD_WATERALPHA );
|
SetBits( world.flags, FWORLD_WATERALPHA );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===========
|
||||||
|
Mod_CalcPHS
|
||||||
|
|
||||||
|
To be called while loading world for multiplayer game server
|
||||||
|
===========
|
||||||
|
*/
|
||||||
|
static void Mod_CalcPHS( model_t *mod )
|
||||||
|
{
|
||||||
|
const qboolean vis_stats = host_developer.value >= DEV_EXTENDED;
|
||||||
|
const size_t rowbytes = ALIGN( world.visbytes, 4 ); // force align rows by 32-bit boundary
|
||||||
|
const size_t count = mod->numleafs + 1; // same as mod->submodels[0].visleafs + 1
|
||||||
|
double t1;
|
||||||
|
double t2;
|
||||||
|
size_t total_compressed_size = 0;
|
||||||
|
size_t hcount = 0;
|
||||||
|
size_t vcount = 0;
|
||||||
|
int i;
|
||||||
|
byte *uncompressed_pvs;
|
||||||
|
byte *uncompressed_phs;
|
||||||
|
|
||||||
|
if( !mod->visdata )
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if defined( HAVE_OPENMP )
|
||||||
|
Con_Reportf( "Building PHS in %d threads...\n", omp_get_max_threads( ));
|
||||||
|
#else
|
||||||
|
Con_Reportf( "Building PHS...\n" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uncompressed_pvs = Mem_Calloc( mod->mempool, rowbytes * count * 2 );
|
||||||
|
uncompressed_phs = &uncompressed_pvs[rowbytes * count];
|
||||||
|
|
||||||
|
world.phsofs = Mem_Calloc( mod->mempool, sizeof( size_t ) * count );
|
||||||
|
world.compressed_phs = NULL;
|
||||||
|
|
||||||
|
t1 = Platform_DoubleTime();
|
||||||
|
|
||||||
|
#pragma omp parallel
|
||||||
|
{
|
||||||
|
// uncompress pvs first
|
||||||
|
#pragma omp for schedule( static, 256 ) // there might be thousands of leafs, split by 256
|
||||||
|
for( i = 0; i < count; i++ )
|
||||||
|
Mod_DecompressPVSTo( &uncompressed_pvs[rowbytes * i], mod->leafs[i].compressed_vis, world.visbytes );
|
||||||
|
|
||||||
|
// now create phs
|
||||||
|
#pragma omp for schedule( static, 256 ) reduction( + : vcount, hcount )
|
||||||
|
for( i = 0; i < count; i++ )
|
||||||
|
{
|
||||||
|
const byte *scan = &uncompressed_pvs[rowbytes * i];
|
||||||
|
byte *dst = &uncompressed_phs[rowbytes * i]; // rowbytes, not rowwords!
|
||||||
|
size_t j;
|
||||||
|
|
||||||
|
memcpy( dst, scan, rowbytes );
|
||||||
|
|
||||||
|
for( j = 0; j < rowbytes; j++ )
|
||||||
|
{
|
||||||
|
size_t k;
|
||||||
|
uint bitbyte = scan[j];
|
||||||
|
|
||||||
|
if( bitbyte == 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for( k = 0; k < 8; k++ )
|
||||||
|
{
|
||||||
|
size_t index;
|
||||||
|
|
||||||
|
if( !FBitSet( bitbyte, BIT( k )))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// OR this pvs row into the phs
|
||||||
|
// +1 because pvs is 1 based
|
||||||
|
index = (( j * 8 ) + k + 1 );
|
||||||
|
if( index >= count )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Q_memor( dst, &uncompressed_pvs[rowbytes * index], rowbytes );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( vis_stats && i != 0 )
|
||||||
|
{
|
||||||
|
size_t j;
|
||||||
|
|
||||||
|
for( j = 0; j < count; j++ )
|
||||||
|
{
|
||||||
|
if( CHECKVISBIT( scan, j ))
|
||||||
|
vcount++;
|
||||||
|
|
||||||
|
if( CHECKVISBIT( dst, j ))
|
||||||
|
hcount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// since I can't predict at which spot compressed array
|
||||||
|
// should be put, this loop is single threaded
|
||||||
|
for( i = 0; i < count; i++ )
|
||||||
|
{
|
||||||
|
const byte *src = &uncompressed_phs[rowbytes * i];
|
||||||
|
byte temp_compressed_row[(MAX_MAP_LEAFS+1)/4]; // compression for this row might be ineffective
|
||||||
|
size_t compressed_size;
|
||||||
|
|
||||||
|
compressed_size = Mod_CompressPVS( temp_compressed_row, src, rowbytes );
|
||||||
|
|
||||||
|
world.compressed_phs = Mem_Realloc( mod->mempool, world.compressed_phs, total_compressed_size + compressed_size );
|
||||||
|
memcpy( &world.compressed_phs[total_compressed_size], temp_compressed_row, compressed_size );
|
||||||
|
world.phsofs[i] = total_compressed_size;
|
||||||
|
|
||||||
|
total_compressed_size += compressed_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
t2 = Platform_DoubleTime();
|
||||||
|
|
||||||
|
if( vis_stats )
|
||||||
|
Con_Reportf( "Average leaves visible / audible / total: %i / %i / %i\n", vcount / count, hcount / count, count );
|
||||||
|
Con_Reportf( "Uncompressed PHS size: %s\n", Q_memprint( rowbytes * count ));
|
||||||
|
Con_Reportf( "Compressed PHS size: %s\n", Q_memprint( total_compressed_size + sizeof( *world.phsofs ) * count ));
|
||||||
|
Con_Reportf( "PHS building time: %.2f ms\n", ( t2 - t1 ) * 1000.0f );
|
||||||
|
|
||||||
|
// TODO: rewrite this into a unit test
|
||||||
|
// NOTE: how to get GoldSrc fat PHS and PVS data
|
||||||
|
// start a multiplayer server with some op4_bootcamp (for example)
|
||||||
|
// attach to process with GDB:
|
||||||
|
// (gdb) p gPAS[0]
|
||||||
|
// $0 = (byte *) ...
|
||||||
|
// (gdb) p gPAS[gPVSRowBytes * (cl.worldmodel->numleafs + 1)]
|
||||||
|
// $1 = (byte *) ...
|
||||||
|
// (gdb) dump binary memory op4_bootcamp_gs.phs $0 $1
|
||||||
|
// (gdb) p gPVS[0]
|
||||||
|
// $2 = (byte *) ...
|
||||||
|
// (gdb) p gPVS[gPVSRowBytes * (cl.worldmodel->numleafs + 1)]
|
||||||
|
// $3 = (byte *) ...
|
||||||
|
// (gdb) dump binary memory op4_bootcamp_gs.pvs $0 $1
|
||||||
|
//
|
||||||
|
// NOTE: as of writing, uncompressed PVS and PHS data do match! hooray!
|
||||||
|
//
|
||||||
|
// FS_WriteFile( "op4_bootcamp.pvs", uncompressed_pvs, rowbytes * count );
|
||||||
|
// FS_WriteFile( "op4_bootcamp.phs", uncompressed_phs, rowbytes * count );
|
||||||
|
|
||||||
|
// release uncompressed data
|
||||||
|
Mem_Free( uncompressed_pvs );
|
||||||
|
|
||||||
|
// TODO: cache the PHS somewhere, it might take a long time on giant maps
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
Mod_LoadClipnodes
|
Mod_LoadClipnodes
|
||||||
@@ -2906,6 +3103,7 @@ static qboolean Mod_LoadBmodelLumps( model_t *mod, const byte *mod_base, qboolea
|
|||||||
char wadvalue[2048];
|
char wadvalue[2048];
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
int i, ret, flags = 0;
|
int i, ret, flags = 0;
|
||||||
|
qboolean wadlist_warn = false;
|
||||||
|
|
||||||
// always reset the intermediate struct
|
// always reset the intermediate struct
|
||||||
memset( bmod, 0, sizeof( dbspmodel_t ));
|
memset( bmod, 0, sizeof( dbspmodel_t ));
|
||||||
@@ -3000,23 +3198,37 @@ static qboolean Mod_LoadBmodelLumps( model_t *mod, const byte *mod_base, qboolea
|
|||||||
{
|
{
|
||||||
world.version = bmod->version;
|
world.version = bmod->version;
|
||||||
#if !XASH_DEDICATED
|
#if !XASH_DEDICATED
|
||||||
Mod_InitDebugHulls( mod ); // FIXME: build hulls for separate bmodels (shells, medkits etc)
|
|
||||||
world.deluxedata = bmod->deluxedata_out; // deluxemap data pointer
|
world.deluxedata = bmod->deluxedata_out; // deluxemap data pointer
|
||||||
world.shadowdata = bmod->shadowdata_out; // occlusion data pointer
|
world.shadowdata = bmod->shadowdata_out; // occlusion data pointer
|
||||||
#endif // XASH_DEDICATED
|
#endif // XASH_DEDICATED
|
||||||
|
|
||||||
|
if( SV_Active() && svs.maxclients > 1 )
|
||||||
|
Mod_CalcPHS( mod );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( i = 0; i < bmod->wadlist.count; i++ )
|
for( i = 0; i < bmod->wadlist.count; i++ )
|
||||||
{
|
{
|
||||||
|
string wadname;
|
||||||
|
|
||||||
if( !bmod->wadlist.wadusage[i] )
|
if( !bmod->wadlist.wadusage[i] )
|
||||||
continue;
|
continue;
|
||||||
ret = Q_snprintf( &wadvalue[len], sizeof( wadvalue ), "%s.wad; ", bmod->wadlist.wadnames[i] );
|
|
||||||
if( ret == -1 )
|
Q_snprintf( wadname, sizeof( wadname ), "%s.wad", bmod->wadlist.wadnames[i] );
|
||||||
|
|
||||||
|
// a1ba: automatically precache used wad files so client will download it
|
||||||
|
if( SV_Active( ))
|
||||||
|
SV_GenericIndex( wadname );
|
||||||
|
|
||||||
|
if( !wadlist_warn )
|
||||||
{
|
{
|
||||||
Con_DPrintf( S_WARN "Too many wad files for output!\n" );
|
ret = Q_snprintf( &wadvalue[len], sizeof( wadvalue ), "%s; ", wadname );
|
||||||
break;
|
if( ret == -1 )
|
||||||
|
{
|
||||||
|
Con_DPrintf( S_WARN "Too many wad files for output!\n" );
|
||||||
|
wadlist_warn = true;
|
||||||
|
}
|
||||||
|
len += ret;
|
||||||
}
|
}
|
||||||
len += ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( COM_CheckString( wadvalue ))
|
if( COM_CheckString( wadvalue ))
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ GNU General Public License for more details.
|
|||||||
|
|
||||||
#define REFPVS_RADIUS 2.0f // radius for rendering
|
#define REFPVS_RADIUS 2.0f // radius for rendering
|
||||||
#define FATPVS_RADIUS 8.0f // FatPVS use radius smaller than the FatPHS
|
#define FATPVS_RADIUS 8.0f // FatPVS use radius smaller than the FatPHS
|
||||||
#define FATPHS_RADIUS 16.0f
|
#define FATPHS_RADIUS 8.0f // see SV_AddToFatPAS in GoldSrc
|
||||||
|
|
||||||
#define WORLD_INDEX (1) // world index is always 1
|
#define WORLD_INDEX (1) // world index is always 1
|
||||||
|
|
||||||
@@ -115,6 +115,10 @@ typedef struct world_static_s
|
|||||||
int max_recursion;
|
int max_recursion;
|
||||||
|
|
||||||
uint32_t version; // BSP version
|
uint32_t version; // BSP version
|
||||||
|
|
||||||
|
// Potentially Hearable Set
|
||||||
|
byte *compressed_phs;
|
||||||
|
size_t *phsofs;
|
||||||
} world_static_t;
|
} world_static_t;
|
||||||
|
|
||||||
#ifndef REF_DLL
|
#ifndef REF_DLL
|
||||||
@@ -151,7 +155,7 @@ void Mod_FreeUnused( void );
|
|||||||
void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *loaded );
|
void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *loaded );
|
||||||
qboolean Mod_TestBmodelLumps( file_t *f, const char *name, const byte *mod_base, qboolean silent, dlump_t *entities );
|
qboolean Mod_TestBmodelLumps( file_t *f, const char *name, const byte *mod_base, qboolean silent, dlump_t *entities );
|
||||||
qboolean Mod_HeadnodeVisible( mnode_t *node, const byte *visbits, int *lastleaf );
|
qboolean Mod_HeadnodeVisible( mnode_t *node, const byte *visbits, int *lastleaf );
|
||||||
int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis );
|
int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis, qboolean false );
|
||||||
qboolean Mod_BoxVisible( const vec3_t mins, const vec3_t maxs, const byte *visbits );
|
qboolean Mod_BoxVisible( const vec3_t mins, const vec3_t maxs, const byte *visbits );
|
||||||
int Mod_CheckLump( const char *filename, const int lump, int *lumpsize );
|
int Mod_CheckLump( const char *filename, const int lump, int *lumpsize );
|
||||||
int Mod_ReadLump( const char *filename, const int lump, void **lumpdata, int *lumpsize );
|
int Mod_ReadLump( const char *filename, const int lump, void **lumpdata, int *lumpsize );
|
||||||
|
|||||||
@@ -780,7 +780,7 @@ extract texture filename from modelname
|
|||||||
*/
|
*/
|
||||||
const char *Mod_StudioTexName( const char *modname )
|
const char *Mod_StudioTexName( const char *modname )
|
||||||
{
|
{
|
||||||
static char texname[MAX_QPATH];
|
static char texname[MAX_QPATH+1];
|
||||||
|
|
||||||
Q_strncpy( texname, modname, sizeof( texname ));
|
Q_strncpy( texname, modname, sizeof( texname ));
|
||||||
COM_StripExtension( texname );
|
COM_StripExtension( texname );
|
||||||
@@ -841,6 +841,22 @@ static studiohdr_t *R_StudioLoadHeader( model_t *mod, const void *buffer )
|
|||||||
return (studiohdr_t *)buffer;
|
return (studiohdr_t *)buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static studiohdr_t *Mod_MaybeTruncateStudioTextureData( model_t *mod )
|
||||||
|
{
|
||||||
|
#if XASH_LOW_MEMORY
|
||||||
|
studiohdr_t *phdr = (studiohdr_t *)mod->cache.data;
|
||||||
|
|
||||||
|
mod->cache.data = Mem_Realloc( mod->mempool, mod->cache.data, phdr->texturedataindex );
|
||||||
|
phdr = (studiohdr_t *)mod->cache.data; // get the new pointer on studiohdr
|
||||||
|
phdr->length = phdr->texturedataindex; // update model size
|
||||||
|
|
||||||
|
return phdr;
|
||||||
|
#else
|
||||||
|
// NOTE: some mods potentially might require full studio model data
|
||||||
|
return (studiohdr_t *)mod->cache.data;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
Mod_LoadStudioModel
|
Mod_LoadStudioModel
|
||||||
@@ -860,73 +876,62 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded )
|
|||||||
phdr = R_StudioLoadHeader( mod, buffer );
|
phdr = R_StudioLoadHeader( mod, buffer );
|
||||||
if( !phdr ) return; // bad model
|
if( !phdr ) return; // bad model
|
||||||
|
|
||||||
if( !Host_IsDedicated() )
|
if( !Host_IsDedicated( ) && phdr->numtextures == 0 )
|
||||||
{
|
{
|
||||||
if( phdr->numtextures == 0 )
|
studiohdr_t *thdr;
|
||||||
|
void *buffer2;
|
||||||
|
|
||||||
|
buffer2 = FS_LoadFile( Mod_StudioTexName( mod->name ), NULL, false );
|
||||||
|
thdr = R_StudioLoadHeader( mod, buffer2 );
|
||||||
|
|
||||||
|
if( thdr != NULL )
|
||||||
{
|
{
|
||||||
studiohdr_t *thdr;
|
byte *in, *out;
|
||||||
byte *in, *out;
|
size_t size1, size2;
|
||||||
void *buffer2 = NULL;
|
|
||||||
size_t size1, size2;
|
|
||||||
|
|
||||||
buffer2 = FS_LoadFile( Mod_StudioTexName( mod->name ), NULL, false );
|
|
||||||
thdr = R_StudioLoadHeader( mod, buffer2 );
|
|
||||||
|
|
||||||
if( !thdr )
|
|
||||||
{
|
|
||||||
Con_Printf( S_WARN "Mod_LoadStudioModel: %s missing textures file\n", mod->name );
|
|
||||||
if( buffer2 ) Mem_Free( buffer2 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if !XASH_DEDICATED
|
#if !XASH_DEDICATED
|
||||||
ref.dllFuncs.Mod_StudioLoadTextures( mod, thdr );
|
// TODO: Mod_StudioLoadTextures will crash if passed a merged studio model!
|
||||||
|
ref.dllFuncs.Mod_StudioLoadTextures( mod, thdr );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// give space for textures and skinrefs
|
// give space for textures and skinrefs
|
||||||
size1 = thdr->numtextures * sizeof( mstudiotexture_t );
|
size1 = thdr->numtextures * sizeof( mstudiotexture_t );
|
||||||
size2 = thdr->numskinfamilies * thdr->numskinref * sizeof( short );
|
size2 = thdr->numskinfamilies * thdr->numskinref * sizeof( short );
|
||||||
mod->cache.data = Mem_Calloc( mod->mempool, phdr->length + size1 + size2 );
|
mod->cache.data = Mem_Calloc( mod->mempool, phdr->length + size1 + size2 );
|
||||||
memcpy( mod->cache.data, buffer, phdr->length ); // copy main mdl buffer
|
memcpy( mod->cache.data, buffer, phdr->length ); // copy main mdl buffer
|
||||||
phdr = (studiohdr_t *)mod->cache.data; // get the new pointer on studiohdr
|
|
||||||
phdr->numskinfamilies = thdr->numskinfamilies;
|
|
||||||
phdr->numtextures = thdr->numtextures;
|
|
||||||
phdr->numskinref = thdr->numskinref;
|
|
||||||
phdr->textureindex = phdr->length;
|
|
||||||
phdr->skinindex = phdr->textureindex + size1;
|
|
||||||
|
|
||||||
in = (byte *)thdr + thdr->textureindex;
|
|
||||||
out = (byte *)phdr + phdr->textureindex;
|
|
||||||
memcpy( out, in, size1 + size2 ); // copy textures + skinrefs
|
|
||||||
phdr->length += size1 + size2;
|
|
||||||
Mem_Free( buffer2 ); // release T.mdl
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// NOTE: don't modify source buffer because it's used for CRC computing
|
|
||||||
mod->cache.data = Mem_Calloc( mod->mempool, phdr->length );
|
|
||||||
memcpy( mod->cache.data, buffer, phdr->length );
|
|
||||||
phdr = (studiohdr_t *)mod->cache.data; // get the new pointer on studiohdr
|
phdr = (studiohdr_t *)mod->cache.data; // get the new pointer on studiohdr
|
||||||
#if !XASH_DEDICATED
|
phdr->numskinfamilies = thdr->numskinfamilies;
|
||||||
ref.dllFuncs.Mod_StudioLoadTextures( mod, phdr );
|
phdr->numtextures = thdr->numtextures;
|
||||||
#endif
|
phdr->numskinref = thdr->numskinref;
|
||||||
|
phdr->textureindex = phdr->length;
|
||||||
|
phdr->skinindex = phdr->textureindex + size1;
|
||||||
|
|
||||||
// NOTE: we wan't keep raw textures in memory. just cutoff model pointer above texture base
|
in = (byte *)thdr + thdr->textureindex;
|
||||||
mod->cache.data = Mem_Realloc( mod->mempool, mod->cache.data, phdr->texturedataindex );
|
out = (byte *)phdr + phdr->textureindex;
|
||||||
phdr = (studiohdr_t *)mod->cache.data; // get the new pointer on studiohdr
|
memcpy( out, in, size1 + size2 ); // copy textures + skinrefs
|
||||||
phdr->length = phdr->texturedataindex; // update model size
|
phdr->length += size1 + size2;
|
||||||
}
|
}
|
||||||
|
else Con_Printf( S_WARN "%s: %s missing textures file\n", __func__, mod->name );
|
||||||
|
|
||||||
|
if( buffer2 )
|
||||||
|
Mem_Free( buffer2 ); // release T.mdl
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// just copy model into memory
|
// NOTE: don't modify source buffer because it's used for CRC computing
|
||||||
mod->cache.data = Mem_Calloc( mod->mempool, phdr->length );
|
mod->cache.data = Mem_Calloc( mod->mempool, phdr->length );
|
||||||
memcpy( mod->cache.data, buffer, phdr->length );
|
memcpy( mod->cache.data, buffer, phdr->length );
|
||||||
|
|
||||||
phdr = mod->cache.data;
|
phdr = mod->cache.data;
|
||||||
|
|
||||||
|
#if !XASH_DEDICATED
|
||||||
|
if( !Host_IsDedicated( ))
|
||||||
|
ref.dllFuncs.Mod_StudioLoadTextures( mod, phdr );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: we may not want to keep raw textures in memory. just cutoff model pointer above texture base
|
||||||
|
phdr = Mod_MaybeTruncateStudioTextureData( mod );
|
||||||
|
|
||||||
// setup bounding box
|
// setup bounding box
|
||||||
if( !VectorCompare( vec3_origin, phdr->bbmin ))
|
if( !VectorCompare( vec3_origin, phdr->bbmin ))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -114,6 +114,11 @@ void Mod_FreeModel( model_t *mod )
|
|||||||
world.version = 0;
|
world.version = 0;
|
||||||
world.shadowdata = NULL;
|
world.shadowdata = NULL;
|
||||||
world.deluxedata = NULL;
|
world.deluxedata = NULL;
|
||||||
|
|
||||||
|
// data already freed by Mem_FreePool above
|
||||||
|
world.hull_models = NULL;
|
||||||
|
world.compressed_phs = NULL;
|
||||||
|
world.phsofs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset( mod, 0, sizeof( *mod ));
|
memset( mod, 0, sizeof( *mod ));
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ void MSG_ExciseBits( sizebuf_t *sb, int startbit, int bitstoremove );
|
|||||||
|
|
||||||
// Bit-write functions
|
// Bit-write functions
|
||||||
void MSG_WriteOneBit( sizebuf_t *sb, int nValue );
|
void MSG_WriteOneBit( sizebuf_t *sb, int nValue );
|
||||||
void MSG_WriteUBitLong( sizebuf_t *sb, uint curData, int numbits );
|
NO_ASAN void MSG_WriteUBitLong( sizebuf_t *sb, uint curData, int numbits );
|
||||||
void MSG_WriteSBitLong( sizebuf_t *sb, int data, int numbits );
|
void MSG_WriteSBitLong( sizebuf_t *sb, int data, int numbits );
|
||||||
void MSG_WriteBitLong( sizebuf_t *sb, uint data, int numbits, qboolean bSigned );
|
void MSG_WriteBitLong( sizebuf_t *sb, uint data, int numbits, qboolean bSigned );
|
||||||
qboolean MSG_WriteBits( sizebuf_t *sb, const void *pData, int nBits );
|
qboolean MSG_WriteBits( sizebuf_t *sb, const void *pData, int nBits );
|
||||||
|
|||||||
@@ -919,13 +919,20 @@ int Netchan_CreateFileFragments( netchan_t *chan, const char *filename )
|
|||||||
int remaining;
|
int remaining;
|
||||||
int bufferid = 1;
|
int bufferid = 1;
|
||||||
fs_offset_t filesize = 0;
|
fs_offset_t filesize = 0;
|
||||||
char compressedfilename[MAX_OSPATH];
|
|
||||||
int compressedFileTime;
|
int compressedFileTime;
|
||||||
int fileTime;
|
int fileTime;
|
||||||
qboolean firstfragment = true;
|
qboolean firstfragment = true;
|
||||||
qboolean bCompressed = false;
|
qboolean bCompressed = false;
|
||||||
fragbufwaiting_t *wait, *p;
|
fragbufwaiting_t *wait, *p;
|
||||||
fragbuf_t *buf;
|
fragbuf_t *buf;
|
||||||
|
char compressedfilename[sizeof( buf->filename ) + 5];
|
||||||
|
|
||||||
|
// shouldn't be critical, but just in case
|
||||||
|
if( Q_strlen( filename ) > sizeof( buf->filename ) - 1 )
|
||||||
|
{
|
||||||
|
Con_Printf( S_WARN "Unable to transfer %s due to path length overflow\n", filename );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(( filesize = FS_FileSize( filename, false )) <= 0 )
|
if(( filesize = FS_FileSize( filename, false )) <= 0 )
|
||||||
{
|
{
|
||||||
@@ -937,8 +944,7 @@ int Netchan_CreateFileFragments( netchan_t *chan, const char *filename )
|
|||||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||||
else chunksize = FRAGMENT_MAX_SIZE; // fallback
|
else chunksize = FRAGMENT_MAX_SIZE; // fallback
|
||||||
|
|
||||||
Q_strncpy( compressedfilename, filename, sizeof( compressedfilename ));
|
Q_snprintf( compressedfilename, sizeof( compressedfilename ), "%s.ztmp", filename );
|
||||||
COM_ReplaceExtension( compressedfilename, ".ztmp", sizeof( compressedfilename ));
|
|
||||||
compressedFileTime = FS_FileTime( compressedfilename, false );
|
compressedFileTime = FS_FileTime( compressedfilename, false );
|
||||||
fileTime = FS_FileTime( filename, false );
|
fileTime = FS_FileTime( filename, false );
|
||||||
|
|
||||||
@@ -1521,10 +1527,9 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
|||||||
|
|
||||||
if( pbuf->iscompressed )
|
if( pbuf->iscompressed )
|
||||||
{
|
{
|
||||||
char compressedfilename[MAX_OSPATH];
|
char compressedfilename[sizeof( pbuf->filename ) + 5];
|
||||||
|
|
||||||
Q_strncpy( compressedfilename, pbuf->filename, sizeof( compressedfilename ));
|
Q_snprintf( compressedfilename, sizeof( compressedfilename ), "%s.ztmp", pbuf->filename );
|
||||||
COM_ReplaceExtension( compressedfilename, ".ztmp", sizeof( compressedfilename ));
|
|
||||||
file = FS_Open( compressedfilename, "rb", false );
|
file = FS_Open( compressedfilename, "rb", false );
|
||||||
}
|
}
|
||||||
else file = FS_Open( pbuf->filename, "rb", false );
|
else file = FS_Open( pbuf->filename, "rb", false );
|
||||||
|
|||||||
@@ -2375,7 +2375,7 @@ static qboolean HTTP_ProcessStream( httpfile_t *curfile )
|
|||||||
|
|
||||||
if( curfile->header_size >= sizeof( buf ))
|
if( curfile->header_size >= sizeof( buf ))
|
||||||
{
|
{
|
||||||
Con_Reportf( S_ERROR "Header too big, the size is %s\n", curfile->header_size );
|
Con_Reportf( S_ERROR "Header too big, the size is %d\n", curfile->header_size );
|
||||||
HTTP_FreeFile( curfile, true );
|
HTTP_FreeFile( curfile, true );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2395,8 +2395,6 @@ static qboolean HTTP_ProcessStream( httpfile_t *curfile )
|
|||||||
int cutheadersize = begin - curfile->buf + 4; // after that begin of data
|
int cutheadersize = begin - curfile->buf + 4; // after that begin of data
|
||||||
char *content_length_line;
|
char *content_length_line;
|
||||||
|
|
||||||
Con_Reportf( "HTTP: Got response!\n" );
|
|
||||||
|
|
||||||
if( !Q_strstr( curfile->buf, "200 OK" ))
|
if( !Q_strstr( curfile->buf, "200 OK" ))
|
||||||
{
|
{
|
||||||
*begin = 0; // cut string to print out response
|
*begin = 0; // cut string to print out response
|
||||||
@@ -2420,10 +2418,10 @@ static qboolean HTTP_ProcessStream( httpfile_t *curfile )
|
|||||||
content_length_line += sizeof( "Content-Length: " ) - 1;
|
content_length_line += sizeof( "Content-Length: " ) - 1;
|
||||||
size = Q_atoi( content_length_line );
|
size = Q_atoi( content_length_line );
|
||||||
|
|
||||||
Con_Reportf( "HTTP: File size is %d\n", size );
|
Con_Reportf( "HTTP: Got 200 OK! File size is %d\n", size );
|
||||||
|
|
||||||
if( ( curfile->size != -1 ) && ( curfile->size != size )) // check size if specified, not used
|
if( ( curfile->size != -1 ) && ( curfile->size != size )) // check size if specified, not used
|
||||||
Con_Reportf( S_WARN "Server reports wrong file size!\n" );
|
Con_Reportf( S_WARN "Server reports wrong file size for %s!\n", curfile->path );
|
||||||
|
|
||||||
curfile->size = size;
|
curfile->size = size;
|
||||||
curfile->header_size = 0;
|
curfile->header_size = 0;
|
||||||
@@ -2535,7 +2533,7 @@ void HTTP_Run( void )
|
|||||||
|
|
||||||
if( !curfile->file )
|
if( !curfile->file )
|
||||||
{
|
{
|
||||||
Con_Printf( S_ERROR "cannot open %s!\n", name );
|
Con_Printf( S_ERROR "HTTP: cannot open %s!\n", name );
|
||||||
HTTP_FreeFile( curfile, true );
|
HTTP_FreeFile( curfile, true );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ int open_mpeg_stream( void *mpg, void *file, pfread f_read, pfseek f_seek, wavin
|
|||||||
|
|
||||||
if( !mh || !sc ) return 0;
|
if( !mh || !sc ) return 0;
|
||||||
|
|
||||||
ret = mpg123_replace_reader_handle( mh, (void *)f_read, (void *)f_seek, NULL );
|
ret = mpg123_replace_reader_handle( mh, f_read, f_seek, NULL );
|
||||||
if( ret != MPG123_OK )
|
if( ret != MPG123_OK )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|||||||
@@ -34,9 +34,15 @@ typedef struct
|
|||||||
int playtime; // stream size in milliseconds
|
int playtime; // stream size in milliseconds
|
||||||
} wavinfo_t;
|
} wavinfo_t;
|
||||||
|
|
||||||
|
#ifdef _MSC_VER // a1ba: MSVC6 don't have ssize_t
|
||||||
|
typedef long mpg_ssize_t;
|
||||||
|
#else
|
||||||
|
typedef ssize_t mpg_ssize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
// custom stdio
|
// custom stdio
|
||||||
typedef long (*pfread)( void *handle, void *buf, size_t count );
|
typedef mpg_ssize_t (*pfread)( void *handle, void *buf, size_t count );
|
||||||
typedef long (*pfseek)( void *handle, long offset, int whence );
|
typedef fs_offset_t (*pfseek)( void *handle, fs_offset_t offset, int whence );
|
||||||
|
|
||||||
extern void *create_decoder( int *error );
|
extern void *create_decoder( int *error );
|
||||||
extern int feed_mpeg_header( void *mpg, const byte *data, long bufsize, long streamsize, wavinfo_t *sc );
|
extern int feed_mpeg_header( void *mpg, const byte *data, long bufsize, long streamsize, wavinfo_t *sc );
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ typedef struct mpg123_handle_s mpg123_handle_t;
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "fmt123.h"
|
#include "fmt123.h"
|
||||||
#include STDINT_H
|
#include STDINT_H
|
||||||
|
#include "xash3d_types.h"
|
||||||
|
|
||||||
#ifndef FALSE
|
#ifndef FALSE
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
@@ -50,7 +51,7 @@ typedef unsigned char byte;
|
|||||||
typedef unsigned short word;
|
typedef unsigned short word;
|
||||||
typedef unsigned long ulong;
|
typedef unsigned long ulong;
|
||||||
typedef unsigned int uint;
|
typedef unsigned int uint;
|
||||||
typedef long mpg_off_t;
|
typedef fs_offset_t mpg_off_t;
|
||||||
|
|
||||||
#ifdef _MSC_VER // a1ba: MSVC6 don't have ssize_t
|
#ifdef _MSC_VER // a1ba: MSVC6 don't have ssize_t
|
||||||
typedef long mpg_ssize_t;
|
typedef long mpg_ssize_t;
|
||||||
|
|||||||
@@ -853,11 +853,21 @@ int open_feed( mpg123_handle_t *fr )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mpg_ssize_t read_mpgtypes( int fd, void *buf, size_t count )
|
||||||
|
{
|
||||||
|
return read( fd, buf, count );
|
||||||
|
}
|
||||||
|
|
||||||
|
static mpg_off_t lseek_mpgtypes( int fd, mpg_off_t offset, int whence )
|
||||||
|
{
|
||||||
|
return lseek( fd, offset, whence );
|
||||||
|
}
|
||||||
|
|
||||||
static int default_init( mpg123_handle_t *fr )
|
static int default_init( mpg123_handle_t *fr )
|
||||||
{
|
{
|
||||||
fr->rdat.fdread = plain_read;
|
fr->rdat.fdread = plain_read;
|
||||||
fr->rdat.read = fr->rdat.r_read != NULL ? fr->rdat.r_read : read;
|
fr->rdat.read = fr->rdat.r_read != NULL ? fr->rdat.r_read : read_mpgtypes;
|
||||||
fr->rdat.lseek = fr->rdat.r_lseek != NULL ? fr->rdat.r_lseek : lseek;
|
fr->rdat.lseek = fr->rdat.r_lseek != NULL ? fr->rdat.r_lseek : lseek_mpgtypes;
|
||||||
fr->rdat.filelen = get_fileinfo( fr );
|
fr->rdat.filelen = get_fileinfo( fr );
|
||||||
fr->rdat.filepos = 0;
|
fr->rdat.filepos = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -291,14 +291,14 @@ qboolean Sound_LoadMPG( const char *name, const byte *buffer, fs_offset_t filesi
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static fs_offset_t FS_SeekMpg( void *file, fs_offset_t offset, int whence )
|
||||||
=================
|
|
||||||
FS_SeekEx
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
static fs_offset_t FS_SeekEx( file_t *file, fs_offset_t offset, int whence )
|
|
||||||
{
|
{
|
||||||
return FS_Seek( file, offset, whence ) == -1 ? -1 : FS_Tell( file );
|
return g_fsapi.Seek((file_t *)file, offset, whence ) == -1 ? -1 : g_fsapi.Tell((file_t *)file );
|
||||||
|
}
|
||||||
|
|
||||||
|
static mpg_ssize_t FS_ReadMpg( void *file, void *buf, size_t count )
|
||||||
|
{
|
||||||
|
return g_fsapi.Read((file_t *)file, buf, count );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -334,7 +334,7 @@ stream_t *Stream_OpenMPG( const char *filename )
|
|||||||
if( ret ) Con_DPrintf( S_ERROR "%s\n", get_error( mpeg ));
|
if( ret ) Con_DPrintf( S_ERROR "%s\n", get_error( mpeg ));
|
||||||
|
|
||||||
// trying to open stream and read header
|
// trying to open stream and read header
|
||||||
if( !open_mpeg_stream( mpeg, file, (void*)FS_Read, (void*)FS_SeekEx, &sc ))
|
if( !open_mpeg_stream( mpeg, file, FS_ReadMpg, FS_SeekMpg, &sc ))
|
||||||
{
|
{
|
||||||
Con_DPrintf( S_ERROR "Stream_OpenMPG: failed to load (%s): %s\n", filename, get_error( mpeg ));
|
Con_DPrintf( S_ERROR "Stream_OpenMPG: failed to load (%s): %s\n", filename, get_error( mpeg ));
|
||||||
close_decoder( mpeg );
|
close_decoder( mpeg );
|
||||||
|
|||||||
@@ -20,63 +20,6 @@ GNU General Public License for more details.
|
|||||||
#include "xash3d_mathlib.h"
|
#include "xash3d_mathlib.h"
|
||||||
#include "studio.h"
|
#include "studio.h"
|
||||||
|
|
||||||
// just for debug
|
|
||||||
const char *et_name[] =
|
|
||||||
{
|
|
||||||
"normal",
|
|
||||||
"player",
|
|
||||||
"tempentity",
|
|
||||||
"beam",
|
|
||||||
"fragmented",
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
===============================================================================
|
|
||||||
|
|
||||||
ENTITY LINKING
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
===============
|
|
||||||
ClearLink
|
|
||||||
|
|
||||||
ClearLink is used for new headnodes
|
|
||||||
===============
|
|
||||||
*/
|
|
||||||
void ClearLink( link_t *l )
|
|
||||||
{
|
|
||||||
l->prev = l->next = l;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
===============
|
|
||||||
RemoveLink
|
|
||||||
|
|
||||||
remove link from chain
|
|
||||||
===============
|
|
||||||
*/
|
|
||||||
void RemoveLink( link_t *l )
|
|
||||||
{
|
|
||||||
l->next->prev = l->prev;
|
|
||||||
l->prev->next = l->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
===============
|
|
||||||
InsertLinkBefore
|
|
||||||
|
|
||||||
kept trigger and solid entities seperate
|
|
||||||
===============
|
|
||||||
*/
|
|
||||||
void InsertLinkBefore( link_t *l, link_t *before )
|
|
||||||
{
|
|
||||||
l->next = before;
|
|
||||||
l->prev = before->prev;
|
|
||||||
l->prev->next = l;
|
|
||||||
l->next->prev = l;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
World_MoveBounds
|
World_MoveBounds
|
||||||
|
|||||||
@@ -35,13 +35,6 @@ ENTITY AREA CHECKING
|
|||||||
|
|
||||||
#include "lightstyle.h"
|
#include "lightstyle.h"
|
||||||
|
|
||||||
extern const char *et_name[];
|
|
||||||
|
|
||||||
// linked list
|
|
||||||
void InsertLinkBefore( link_t *l, link_t *before );
|
|
||||||
void RemoveLink( link_t *l );
|
|
||||||
void ClearLink( link_t *l );
|
|
||||||
|
|
||||||
// trace common
|
// trace common
|
||||||
void World_MoveBounds( const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, vec3_t boxmins, vec3_t boxmaxs );
|
void World_MoveBounds( const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, vec3_t boxmins, vec3_t boxmaxs );
|
||||||
void World_TransformAABB( matrix4x4 transform, const vec3_t mins, const vec3_t maxs, vec3_t outmins, vec3_t outmaxs );
|
void World_TransformAABB( matrix4x4 transform, const vec3_t mins, const vec3_t maxs, vec3_t outmins, vec3_t outmaxs );
|
||||||
|
|||||||
@@ -357,13 +357,17 @@ SDLash_InputEvent
|
|||||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||||
static void SDLash_InputEvent( SDL_TextInputEvent input )
|
static void SDLash_InputEvent( SDL_TextInputEvent input )
|
||||||
{
|
{
|
||||||
char *text;
|
const char *text;
|
||||||
|
|
||||||
VGui_ReportTextInput( input.text );
|
VGui_ReportTextInput( input.text );
|
||||||
|
|
||||||
for( text = input.text; *text; text++ )
|
for( text = input.text; *text; text++ )
|
||||||
{
|
{
|
||||||
int ch;
|
int ch = (byte)*text;
|
||||||
|
|
||||||
ch = Con_UtfProcessChar((byte)*text );
|
// do not pass UTF-8 sequence into the engine, convert it here
|
||||||
|
if( !cls.accept_utf8 )
|
||||||
|
ch = Con_UtfProcessCharForce( ch );
|
||||||
|
|
||||||
if( !ch )
|
if( !ch )
|
||||||
continue;
|
continue;
|
||||||
@@ -453,7 +457,7 @@ SDLash_EventFilter
|
|||||||
|
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
static void SDLash_EventFilter( SDL_Event *event )
|
static void SDLash_EventHandler( SDL_Event *event )
|
||||||
{
|
{
|
||||||
switch ( event->type )
|
switch ( event->type )
|
||||||
{
|
{
|
||||||
@@ -684,7 +688,7 @@ void Platform_RunEvents( void )
|
|||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
|
||||||
while( !host.crashed && !host.shutdown_issued && SDL_PollEvent( &event ) )
|
while( !host.crashed && !host.shutdown_issued && SDL_PollEvent( &event ) )
|
||||||
SDLash_EventFilter( &event );
|
SDLash_EventHandler( &event );
|
||||||
|
|
||||||
#if XASH_PSVITA
|
#if XASH_PSVITA
|
||||||
PSVita_InputUpdate();
|
PSVita_InputUpdate();
|
||||||
|
|||||||
@@ -843,6 +843,8 @@ qboolean VID_CreateWindow( int width, int height, window_mode_t window_mode )
|
|||||||
#else // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
#else // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||||
Uint32 flags = 0;
|
Uint32 flags = 0;
|
||||||
|
|
||||||
|
Q_strncpy( wndname, GI->title, sizeof( wndname ));
|
||||||
|
|
||||||
if( window_mode != WINDOW_MODE_WINDOWED )
|
if( window_mode != WINDOW_MODE_WINDOWED )
|
||||||
SetBits( flags, SDL_FULLSCREEN|SDL_HWSURFACE );
|
SetBits( flags, SDL_FULLSCREEN|SDL_HWSURFACE );
|
||||||
|
|
||||||
|
|||||||
@@ -475,6 +475,7 @@ extern convar_t sv_fullupdate_penalty_time;
|
|||||||
extern convar_t sv_log_outofband;
|
extern convar_t sv_log_outofband;
|
||||||
extern convar_t sv_allow_autoaim;
|
extern convar_t sv_allow_autoaim;
|
||||||
extern convar_t sv_aim;
|
extern convar_t sv_aim;
|
||||||
|
extern convar_t sv_allow_testpacket;
|
||||||
|
|
||||||
//===========================================================
|
//===========================================================
|
||||||
//
|
//
|
||||||
@@ -503,6 +504,7 @@ void SV_ActivateServer( int runPhysics );
|
|||||||
qboolean SV_SpawnServer( const char *server, const char *startspot, qboolean background );
|
qboolean SV_SpawnServer( const char *server, const char *startspot, qboolean background );
|
||||||
model_t *SV_ModelHandle( int modelindex );
|
model_t *SV_ModelHandle( int modelindex );
|
||||||
void SV_DeactivateServer( void );
|
void SV_DeactivateServer( void );
|
||||||
|
void SV_FreeTestPacket( void );
|
||||||
|
|
||||||
//
|
//
|
||||||
// sv_phys.c
|
// sv_phys.c
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ static void SV_GetChallenge( netadr_t from )
|
|||||||
if( i == MAX_CHALLENGES )
|
if( i == MAX_CHALLENGES )
|
||||||
{
|
{
|
||||||
// this is the first time this client has asked for a challenge
|
// this is the first time this client has asked for a challenge
|
||||||
svs.challenges[oldest].challenge = (COM_RandomLong( 0, 0xFFFF ) << 16) | COM_RandomLong( 0, 0xFFFF );
|
svs.challenges[oldest].challenge = (COM_RandomLong( 0, 0x7FFF ) << 16) | COM_RandomLong( 0, 0xFFFF );
|
||||||
svs.challenges[oldest].adr = from;
|
svs.challenges[oldest].adr = from;
|
||||||
svs.challenges[oldest].time = host.realtime;
|
svs.challenges[oldest].time = host.realtime;
|
||||||
svs.challenges[oldest].connected = false;
|
svs.challenges[oldest].connected = false;
|
||||||
@@ -852,7 +852,7 @@ static void SV_TestBandWidth( netadr_t from )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// quickly reject invalid packets
|
// quickly reject invalid packets
|
||||||
if( !svs.testpacket_buf ||
|
if( !sv_allow_testpacket.value || !svs.testpacket_buf ||
|
||||||
( packetsize <= FRAGMENT_MIN_SIZE ) ||
|
( packetsize <= FRAGMENT_MIN_SIZE ) ||
|
||||||
( packetsize > FRAGMENT_MAX_SIZE ))
|
( packetsize > FRAGMENT_MAX_SIZE ))
|
||||||
{
|
{
|
||||||
@@ -2035,7 +2035,7 @@ static qboolean SV_Kill_f( sv_client_t *cl )
|
|||||||
{
|
{
|
||||||
if( !SV_IsValidEdict( cl->edict ))
|
if( !SV_IsValidEdict( cl->edict ))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if( cl->state != cs_spawned )
|
if( cl->state != cs_spawned )
|
||||||
{
|
{
|
||||||
SV_ClientPrintf( cl, "Can't suicide - not connected!\n" );
|
SV_ClientPrintf( cl, "Can't suicide - not connected!\n" );
|
||||||
@@ -2424,7 +2424,7 @@ static qboolean SV_EntList_f( sv_client_t *cl )
|
|||||||
|
|
||||||
// filter by string
|
// filter by string
|
||||||
if( Cmd_Argc() > 1 )
|
if( Cmd_Argc() > 1 )
|
||||||
{
|
{
|
||||||
if( !Q_stricmpext( Cmd_Argv( 1 ), STRING( ent->v.classname ) ) && !Q_stricmpext( Cmd_Argv( 1 ), STRING( ent->v.targetname ) ) )
|
if( !Q_stricmpext( Cmd_Argv( 1 ), STRING( ent->v.classname ) ) && !Q_stricmpext( Cmd_Argv( 1 ), STRING( ent->v.targetname ) ) )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,10 +30,8 @@ GNU General Public License for more details.
|
|||||||
static int GAME_EXPORT pfnModelIndex( const char *m );
|
static int GAME_EXPORT pfnModelIndex( const char *m );
|
||||||
|
|
||||||
// fatpvs stuff
|
// fatpvs stuff
|
||||||
static byte fatpvs[MAX_MAP_LEAFS/8];
|
static byte fatphs[(MAX_MAP_LEAFS+7)/8];
|
||||||
static byte fatphs[MAX_MAP_LEAFS/8];
|
static byte clientpvs[(MAX_MAP_LEAFS+7)/8]; // for find client in PVS
|
||||||
static byte clientpvs[MAX_MAP_LEAFS/8]; // for find client in PVS
|
|
||||||
static vec3_t viewPoint[MAX_CLIENTS];
|
|
||||||
|
|
||||||
// exports
|
// exports
|
||||||
typedef void (__cdecl *LINK_ENTITY_FUNC)( entvars_t *pev );
|
typedef void (__cdecl *LINK_ENTITY_FUNC)( entvars_t *pev );
|
||||||
@@ -258,7 +256,7 @@ void GAME_EXPORT SV_SetModel( edict_t *ent, const char *modelname )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !modelname || modelname[0] <= ' ' )
|
if( !modelname || ((byte)modelname[0] ) <= ' ' )
|
||||||
{
|
{
|
||||||
Con_Printf( S_WARN "SV_SetModel: null name\n" );
|
Con_Printf( S_WARN "SV_SetModel: null name\n" );
|
||||||
return;
|
return;
|
||||||
@@ -339,11 +337,12 @@ static qboolean SV_CheckClientVisiblity( sv_client_t *cl, const byte *mask )
|
|||||||
if( !mask ) return true; // GoldSrc rules
|
if( !mask ) return true; // GoldSrc rules
|
||||||
|
|
||||||
clientnum = cl - svs.clients;
|
clientnum = cl - svs.clients;
|
||||||
VectorCopy( viewPoint[clientnum], vieworg );
|
|
||||||
|
|
||||||
// Invasion issues: wrong camera position received in ENGINE_SET_PVS
|
// Invasion issues: wrong camera position received in ENGINE_SET_PVS
|
||||||
if( cl->pViewEntity && !VectorCompare( vieworg, cl->pViewEntity->v.origin ))
|
if( cl->pViewEntity )
|
||||||
VectorCopy( cl->pViewEntity->v.origin, vieworg );
|
VectorCopy( cl->pViewEntity->v.origin, vieworg );
|
||||||
|
else
|
||||||
|
VectorCopy( cl->edict->v.origin, vieworg );
|
||||||
|
|
||||||
leaf = Mod_PointInLeaf( vieworg, sv.worldmodel->nodes );
|
leaf = Mod_PointInLeaf( vieworg, sv.worldmodel->nodes );
|
||||||
|
|
||||||
@@ -422,7 +421,7 @@ static int SV_Multicast( int dest, const vec3_t origin, const edict_t *ent, qboo
|
|||||||
case MSG_PAS:
|
case MSG_PAS:
|
||||||
if( origin == NULL ) return false;
|
if( origin == NULL ) return false;
|
||||||
// NOTE: GoldSource not using PHS for singleplayer
|
// NOTE: GoldSource not using PHS for singleplayer
|
||||||
Mod_FatPVS( origin, FATPHS_RADIUS, fatphs, world.fatbytes, false, ( svs.maxclients == 1 ));
|
Mod_FatPVS( origin, FATPHS_RADIUS, fatphs, world.fatbytes, false, ( svs.maxclients == 1 ), true );
|
||||||
mask = fatphs; // using the FatPVS like a PHS
|
mask = fatphs; // using the FatPVS like a PHS
|
||||||
break;
|
break;
|
||||||
case MSG_PVS_R:
|
case MSG_PVS_R:
|
||||||
@@ -4157,7 +4156,7 @@ void GAME_EXPORT SV_PlaybackEventFull( int flags, const edict_t *pInvoker, word
|
|||||||
// setup pvs cluster for invoker
|
// setup pvs cluster for invoker
|
||||||
if( !FBitSet( flags, FEV_GLOBAL ))
|
if( !FBitSet( flags, FEV_GLOBAL ))
|
||||||
{
|
{
|
||||||
Mod_FatPVS( pvspoint, FATPHS_RADIUS, fatphs, world.fatbytes, false, ( svs.maxclients == 1 ));
|
Mod_FatPVS( pvspoint, FATPHS_RADIUS, fatphs, world.fatbytes, false, ( svs.maxclients == 1 ), true );
|
||||||
mask = fatphs; // using the FatPVS like a PHS
|
mask = fatphs; // using the FatPVS like a PHS
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4278,43 +4277,16 @@ so we can't use a single PVS point
|
|||||||
*/
|
*/
|
||||||
static byte *GAME_EXPORT pfnSetFatPVS( const float *org )
|
static byte *GAME_EXPORT pfnSetFatPVS( const float *org )
|
||||||
{
|
{
|
||||||
qboolean fullvis = false;
|
static byte fatpvs[(MAX_MAP_LEAFS+7)/8];
|
||||||
|
qboolean fullvis = false, merge = false;
|
||||||
|
|
||||||
if( !sv.worldmodel->visdata || sv_novis.value || !org || CL_DisableVisibility( ))
|
if( !sv.worldmodel->visdata || sv_novis.value || !org || CL_DisableVisibility( ))
|
||||||
fullvis = true;
|
fullvis = true;
|
||||||
|
|
||||||
// portals can't change viewpoint!
|
if( FBitSet( sv.hostflags, SVF_MERGE_VISIBILITY ))
|
||||||
if( !FBitSet( sv.hostflags, SVF_MERGE_VISIBILITY ))
|
merge = true;
|
||||||
{
|
|
||||||
vec3_t viewPos, offset;
|
|
||||||
qboolean client_active = pfnGetCurrentPlayer() != -1;
|
|
||||||
|
|
||||||
// see code from client.cpp for understanding:
|
Mod_FatPVS( org, FATPVS_RADIUS, fatpvs, world.fatbytes, merge, fullvis, false );
|
||||||
// org = pView->v.origin + pView->v.view_ofs;
|
|
||||||
// if ( pView->v.flags & FL_DUCKING )
|
|
||||||
// {
|
|
||||||
// org = org + ( VEC_HULL_MIN - VEC_DUCK_HULL_MIN );
|
|
||||||
// }
|
|
||||||
// so we have unneeded duck calculations who have affect when player
|
|
||||||
// is ducked into water. Remove offset to restore right PVS position
|
|
||||||
if( client_active && FBitSet( sv.current_client->edict->v.flags, FL_DUCKING ))
|
|
||||||
{
|
|
||||||
VectorSubtract( svgame.pmove->player_mins[0], svgame.pmove->player_mins[1], offset );
|
|
||||||
VectorSubtract( org, offset, viewPos );
|
|
||||||
}
|
|
||||||
else VectorCopy( org, viewPos );
|
|
||||||
|
|
||||||
// build a new PVS frame
|
|
||||||
Mod_FatPVS( viewPos, FATPVS_RADIUS, fatpvs, world.fatbytes, false, fullvis );
|
|
||||||
|
|
||||||
if( client_active )
|
|
||||||
VectorCopy( viewPos, viewPoint[pfnGetCurrentPlayer()] );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// merge PVS
|
|
||||||
Mod_FatPVS( org, FATPVS_RADIUS, fatpvs, world.fatbytes, true, fullvis );
|
|
||||||
}
|
|
||||||
|
|
||||||
return fatpvs;
|
return fatpvs;
|
||||||
}
|
}
|
||||||
@@ -4329,40 +4301,15 @@ so we can't use a single PHS point
|
|||||||
*/
|
*/
|
||||||
static byte *GAME_EXPORT pfnSetFatPAS( const float *org )
|
static byte *GAME_EXPORT pfnSetFatPAS( const float *org )
|
||||||
{
|
{
|
||||||
qboolean fullvis = false;
|
qboolean fullvis = false, merge = false;
|
||||||
|
|
||||||
if( !sv.worldmodel->visdata || sv_novis.value || !org || CL_DisableVisibility( ))
|
if( !sv.worldmodel->visdata || sv_novis.value || !org || CL_DisableVisibility( ))
|
||||||
fullvis = true;
|
fullvis = true;
|
||||||
|
|
||||||
// portals can't change viewpoint!
|
if( FBitSet( sv.hostflags, SVF_MERGE_VISIBILITY ))
|
||||||
if( !FBitSet( sv.hostflags, SVF_MERGE_VISIBILITY ))
|
merge = true;
|
||||||
{
|
|
||||||
vec3_t viewPos, offset;
|
|
||||||
qboolean client_active = pfnGetCurrentPlayer() != -1;
|
|
||||||
|
|
||||||
// see code from client.cpp for understanding:
|
Mod_FatPVS( org, FATPHS_RADIUS, fatphs, world.fatbytes, merge, fullvis, true );
|
||||||
// org = pView->v.origin + pView->v.view_ofs;
|
|
||||||
// if ( pView->v.flags & FL_DUCKING )
|
|
||||||
// {
|
|
||||||
// org = org + ( VEC_HULL_MIN - VEC_DUCK_HULL_MIN );
|
|
||||||
// }
|
|
||||||
// so we have unneeded duck calculations who have affect when player
|
|
||||||
// is ducked into water. Remove offset to restore right PVS position
|
|
||||||
if( client_active && FBitSet( sv.current_client->edict->v.flags, FL_DUCKING ))
|
|
||||||
{
|
|
||||||
VectorSubtract( svgame.pmove->player_mins[0], svgame.pmove->player_mins[1], offset );
|
|
||||||
VectorSubtract( org, offset, viewPos );
|
|
||||||
}
|
|
||||||
else VectorCopy( org, viewPos );
|
|
||||||
|
|
||||||
// build a new PHS frame
|
|
||||||
Mod_FatPVS( viewPos, FATPHS_RADIUS, fatphs, world.fatbytes, false, fullvis );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// merge PHS
|
|
||||||
Mod_FatPVS( org, FATPHS_RADIUS, fatphs, world.fatbytes, true, fullvis );
|
|
||||||
}
|
|
||||||
|
|
||||||
return fatphs;
|
return fatphs;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -906,6 +906,21 @@ qboolean CRC32_MapFile( dword *crcvalue, const char *filename, qboolean multipla
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SV_FreeTestPacket( void )
|
||||||
|
{
|
||||||
|
if( svs.testpacket_buf )
|
||||||
|
{
|
||||||
|
Mem_Free( svs.testpacket_buf );
|
||||||
|
svs.testpacket_buf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( svs.testpacket_crcs )
|
||||||
|
{
|
||||||
|
Mem_Free( svs.testpacket_crcs );
|
||||||
|
svs.testpacket_crcs = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
SV_GenerateTestPacket
|
SV_GenerateTestPacket
|
||||||
@@ -917,7 +932,13 @@ static void SV_GenerateTestPacket( void )
|
|||||||
uint32_t crc;
|
uint32_t crc;
|
||||||
file_t *file;
|
file_t *file;
|
||||||
byte *filepos;
|
byte *filepos;
|
||||||
int i, filesize;
|
int i;
|
||||||
|
|
||||||
|
if( !sv_allow_testpacket.value )
|
||||||
|
{
|
||||||
|
SV_FreeTestPacket();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// testpacket already generated once, exit
|
// testpacket already generated once, exit
|
||||||
// testpacket and lookup table takes ~300k of memory
|
// testpacket and lookup table takes ~300k of memory
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ CVAR_DEFINE_AUTO( sv_proxies, "1", FCVAR_SERVER, "maximum count of allowed proxi
|
|||||||
CVAR_DEFINE_AUTO( sv_send_logos, "1", 0, "send custom decal logo to other players so they can view his too" );
|
CVAR_DEFINE_AUTO( sv_send_logos, "1", 0, "send custom decal logo to other players so they can view his too" );
|
||||||
CVAR_DEFINE_AUTO( sv_send_resources, "1", 0, "allow to download missed resources for players" );
|
CVAR_DEFINE_AUTO( sv_send_resources, "1", 0, "allow to download missed resources for players" );
|
||||||
CVAR_DEFINE_AUTO( sv_logbans, "0", 0, "print into the server log info about player bans" );
|
CVAR_DEFINE_AUTO( sv_logbans, "0", 0, "print into the server log info about player bans" );
|
||||||
CVAR_DEFINE_AUTO( sv_allow_upload, "1", FCVAR_SERVER, "allow uploading custom resources on a server" );
|
CVAR_DEFINE( sv_allow_upload, "sv_allowupload", "1", FCVAR_SERVER, "allow uploading custom resources on a server" );
|
||||||
CVAR_DEFINE( sv_allow_download, "sv_allowdownload", "1", FCVAR_SERVER, "allow downloading custom resources to the client" );
|
CVAR_DEFINE( sv_allow_download, "sv_allowdownload", "1", FCVAR_SERVER, "allow downloading custom resources to the client" );
|
||||||
static CVAR_DEFINE_AUTO( sv_allow_dlfile, "1", 0, "compatibility cvar, does nothing" );
|
static CVAR_DEFINE_AUTO( sv_allow_dlfile, "1", 0, "compatibility cvar, does nothing" );
|
||||||
CVAR_DEFINE_AUTO( sv_uploadmax, "0.5", FCVAR_SERVER, "max size to upload custom resources (500 kB as default)" );
|
CVAR_DEFINE_AUTO( sv_uploadmax, "0.5", FCVAR_SERVER, "max size to upload custom resources (500 kB as default)" );
|
||||||
@@ -150,6 +150,8 @@ CVAR_DEFINE_AUTO( sv_userinfo_penalty_attempts, "4", FCVAR_ARCHIVE, "if max atte
|
|||||||
CVAR_DEFINE_AUTO( sv_fullupdate_penalty_time, "1", FCVAR_ARCHIVE, "allow fullupdate command only once in this timewindow (set 0 to disable)" );
|
CVAR_DEFINE_AUTO( sv_fullupdate_penalty_time, "1", FCVAR_ARCHIVE, "allow fullupdate command only once in this timewindow (set 0 to disable)" );
|
||||||
CVAR_DEFINE_AUTO( sv_log_outofband, "0", FCVAR_ARCHIVE, "log out of band messages, can be useful for server admins and for engine debugging" );
|
CVAR_DEFINE_AUTO( sv_log_outofband, "0", FCVAR_ARCHIVE, "log out of band messages, can be useful for server admins and for engine debugging" );
|
||||||
|
|
||||||
|
CVAR_DEFINE_AUTO( sv_allow_testpacket, "1", FCVAR_ARCHIVE, "allow generating and sending a big blob of data to test maximum packet size" );
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
@@ -973,6 +975,7 @@ void SV_Init( void )
|
|||||||
Cvar_RegisterVariable( &sv_userinfo_penalty_attempts );
|
Cvar_RegisterVariable( &sv_userinfo_penalty_attempts );
|
||||||
Cvar_RegisterVariable( &sv_fullupdate_penalty_time );
|
Cvar_RegisterVariable( &sv_fullupdate_penalty_time );
|
||||||
Cvar_RegisterVariable( &sv_log_outofband );
|
Cvar_RegisterVariable( &sv_log_outofband );
|
||||||
|
Cvar_RegisterVariable( &sv_allow_testpacket );
|
||||||
|
|
||||||
// when we in developer-mode automatically turn cheats on
|
// when we in developer-mode automatically turn cheats on
|
||||||
if( host_developer.value ) Cvar_SetValue( "sv_cheats", 1.0f );
|
if( host_developer.value ) Cvar_SetValue( "sv_cheats", 1.0f );
|
||||||
@@ -1115,6 +1118,9 @@ void SV_Shutdown( const char *finalmsg )
|
|||||||
SV_FreeClients();
|
SV_FreeClients();
|
||||||
svs.maxclients = 0;
|
svs.maxclients = 0;
|
||||||
|
|
||||||
|
// release test packet blob
|
||||||
|
SV_FreeTestPacket();
|
||||||
|
|
||||||
// release all models
|
// release all models
|
||||||
Mod_FreeAll();
|
Mod_FreeAll();
|
||||||
|
|
||||||
|
|||||||
@@ -358,6 +358,53 @@ static hull_t *SV_HullForStudioModel( edict_t *ent, vec3_t mins, vec3_t maxs, ve
|
|||||||
return SV_HullForEntity( ent, mins, maxs, offset );
|
return SV_HullForEntity( ent, mins, maxs, offset );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
ENTITY LINKING
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
ClearLink
|
||||||
|
|
||||||
|
ClearLink is used for new headnodes
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
static void ClearLink( link_t *l )
|
||||||
|
{
|
||||||
|
l->prev = l->next = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
RemoveLink
|
||||||
|
|
||||||
|
remove link from chain
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
static void RemoveLink( link_t *l )
|
||||||
|
{
|
||||||
|
l->next->prev = l->prev;
|
||||||
|
l->prev->next = l->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
InsertLinkBefore
|
||||||
|
|
||||||
|
kept trigger and solid entities seperate
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
static void InsertLinkBefore( link_t *l, link_t *before )
|
||||||
|
{
|
||||||
|
l->next = before;
|
||||||
|
l->prev = before->prev;
|
||||||
|
l->prev->next = l;
|
||||||
|
l->next->prev = l;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
|
||||||
|
|||||||
@@ -2425,7 +2425,7 @@ static void *FS_CustomAlloc( size_t size )
|
|||||||
|
|
||||||
static void FS_CustomFree( void *data )
|
static void FS_CustomFree( void *data )
|
||||||
{
|
{
|
||||||
return Mem_Free( data );
|
Mem_Free( data );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -274,6 +274,13 @@ const byte *Q_memmem( const byte *haystack, size_t haystacklen, const byte *need
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Q_memor( byte *XASH_RESTRICT dst, const byte *XASH_RESTRICT src, size_t len )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for( i = 0; i < len; i++ ) // msvc likes to optimize this loop form
|
||||||
|
dst[i] |= src[i];
|
||||||
|
}
|
||||||
|
|
||||||
const char* Q_timestamp( int format )
|
const char* Q_timestamp( int format )
|
||||||
{
|
{
|
||||||
static string timestamp;
|
static string timestamp;
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ enum
|
|||||||
#define PFILE_TOKEN_MAX_LENGTH 1024
|
#define PFILE_TOKEN_MAX_LENGTH 1024
|
||||||
#define PFILE_FS_TOKEN_MAX_LENGTH 512
|
#define PFILE_FS_TOKEN_MAX_LENGTH 512
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define restrict
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
//
|
//
|
||||||
// build.c
|
// build.c
|
||||||
//
|
//
|
||||||
@@ -72,6 +76,7 @@ void Q_atov( float *vec, const char *str, size_t siz );
|
|||||||
qboolean Q_stricmpext( const char *pattern, const char *text );
|
qboolean Q_stricmpext( const char *pattern, const char *text );
|
||||||
qboolean Q_strnicmpext( const char *pattern, const char *text, size_t minimumlen );
|
qboolean Q_strnicmpext( const char *pattern, const char *text, size_t minimumlen );
|
||||||
const byte *Q_memmem( const byte *haystack, size_t haystacklen, const byte *needle, size_t needlelen );
|
const byte *Q_memmem( const byte *haystack, size_t haystacklen, const byte *needle, size_t needlelen );
|
||||||
|
void Q_memor( byte *XASH_RESTRICT dst, const byte *XASH_RESTRICT src, size_t len );
|
||||||
const char *Q_timestamp( int format );
|
const char *Q_timestamp( int format );
|
||||||
int Q_vsnprintf( char *buffer, size_t buffersize, const char *format, va_list args );
|
int Q_vsnprintf( char *buffer, size_t buffersize, const char *format, va_list args );
|
||||||
int Q_snprintf( char *buffer, size_t buffersize, const char *format, ... ) _format( 3 );
|
int Q_snprintf( char *buffer, size_t buffersize, const char *format, ... ) _format( 3 );
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ GNU General Public License for more details.
|
|||||||
// REFTODO: rewrite in triapi
|
// REFTODO: rewrite in triapi
|
||||||
void R_DrawWorldHull( void )
|
void R_DrawWorldHull( void )
|
||||||
{
|
{
|
||||||
hull_model_t *hull = &tr.world->hull_models[0];
|
hull_model_t *hull;
|
||||||
winding_t *poly;
|
winding_t *poly;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -42,6 +42,8 @@ void R_DrawWorldHull( void )
|
|||||||
if( !r_showhull->value )
|
if( !r_showhull->value )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
hull = &tr.world->hull_models[0];
|
||||||
|
|
||||||
pglDisable( GL_TEXTURE_2D );
|
pglDisable( GL_TEXTURE_2D );
|
||||||
|
|
||||||
list_for_each_entry( poly, &hull->polys, chain )
|
list_for_each_entry( poly, &hull->polys, chain )
|
||||||
|
|||||||
@@ -66,10 +66,10 @@ Draw_StretchPicImplementation
|
|||||||
static void R_DrawStretchPicImplementation( int x, int y, int w, int h, int s1, int t1, int s2, int t2, image_t *pic )
|
static void R_DrawStretchPicImplementation( int x, int y, int w, int h, int s1, int t1, int s2, int t2, image_t *pic )
|
||||||
{
|
{
|
||||||
pixel_t *source, *dest;
|
pixel_t *source, *dest;
|
||||||
unsigned int v, u, sv;
|
unsigned int u, sv;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
unsigned int f, fstep;
|
unsigned int f, fstep;
|
||||||
int skip;
|
int skip, v;
|
||||||
qboolean transparent = false;
|
qboolean transparent = false;
|
||||||
pixel_t *buffer;
|
pixel_t *buffer;
|
||||||
|
|
||||||
@@ -212,9 +212,9 @@ void GAME_EXPORT R_DrawStretchPic( float x, float y, float w, float h, float s1,
|
|||||||
void Draw_Fill (int x, int y, int w, int h)
|
void Draw_Fill (int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
pixel_t *dest;
|
pixel_t *dest;
|
||||||
unsigned int v, u;
|
unsigned int u;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
int skip;
|
int skip, v;
|
||||||
pixel_t src = vid.color;
|
pixel_t src = vid.color;
|
||||||
int alpha = vid.alpha;
|
int alpha = vid.alpha;
|
||||||
|
|
||||||
|
|||||||
@@ -410,19 +410,10 @@ void R_EntityRemoveDecals( model_t *mod );
|
|||||||
void R_ClearDecals( void );
|
void R_ClearDecals( void );
|
||||||
void R_DecalComputeBasis( msurface_t *surf, int flags, vec3_t textureSpaceBasis[3] );
|
void R_DecalComputeBasis( msurface_t *surf, int flags, vec3_t textureSpaceBasis[3] );
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
//
|
|
||||||
// gl_drawhulls.c
|
|
||||||
//
|
|
||||||
void R_DrawWorldHull( void );
|
|
||||||
void R_DrawModelHull( void );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void GL_Bind( int tmu, unsigned int texnum );
|
void GL_Bind( int tmu, unsigned int texnum );
|
||||||
|
|
||||||
//
|
//
|
||||||
// gl_draw.cM_PI
|
// gl_draw.c
|
||||||
//
|
//
|
||||||
void R_Set2DMode( qboolean enable );
|
void R_Set2DMode( qboolean enable );
|
||||||
void R_DrawTileClear( int texnum, int x, int y, int w, int h );
|
void R_DrawTileClear( int texnum, int x, int y, int w, int h );
|
||||||
|
|||||||
@@ -122,9 +122,9 @@ POLLY_CFLAGS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
OPENMP_CFLAGS = {
|
OPENMP_CFLAGS = {
|
||||||
'gcc': ['-fopenmp'],
|
'gcc': ['-fopenmp', '-DHAVE_OPENMP=1'],
|
||||||
'clang': ['-fopenmp'],
|
'clang': ['-fopenmp', '-DHAVE_OPENMP=1'],
|
||||||
'msvc': ['/openmp']
|
'msvc': ['/openmp', '/DHAVE_OPENMP=1']
|
||||||
}
|
}
|
||||||
|
|
||||||
OPENMP_LINKFLAGS = {
|
OPENMP_LINKFLAGS = {
|
||||||
|
|||||||
2
waf.bat
2
waf.bat
@@ -25,7 +25,7 @@ Setlocal EnableDelayedExpansion
|
|||||||
set PYTHON_DIR_OK=FALSE
|
set PYTHON_DIR_OK=FALSE
|
||||||
set REGPATH=
|
set REGPATH=
|
||||||
|
|
||||||
for %%i in (3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.7 2.6 2.5) do (
|
for %%i in (3.13 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.7) do (
|
||||||
for %%j in (HKCU HKLM) do (
|
for %%j in (HKCU HKLM) do (
|
||||||
for %%k in (SOFTWARE\Wow6432Node SOFTWARE) do (
|
for %%k in (SOFTWARE\Wow6432Node SOFTWARE) do (
|
||||||
for %%l in (Python\PythonCore IronPython) do (
|
for %%l in (Python\PythonCore IronPython) do (
|
||||||
|
|||||||
Reference in New Issue
Block a user