Compare commits

..

2 Commits

Author SHA1 Message Date
Alibek Omarov
9cd456e414 ci: add wafcache to all targets that use Waf, except Android which uses generated CMakeLists instead 2025-01-13 20:24:45 +03:00
Alibek Omarov
4a7a5f0b8c wscript: add option to use wafcache 2025-01-13 20:02:59 +03:00
117 changed files with 2454 additions and 2907 deletions

View File

@@ -1,10 +1,10 @@
task:
name: freebsd-14-amd64
freebsd_instance:
image_family: freebsd-14-2
image_family: freebsd-14-0
setup_script:
- pkg update
- pkg install -y pkgconf git sdl2 python fontconfig libvorbis opusfile bzip2
- pkg install -y pkgconf git sdl2 python fontconfig opus
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated
@@ -16,7 +16,7 @@ task:
image_family: freebsd-15-0-snap
setup_script:
- pkg update
- pkg install -y pkgconf git sdl2 python fontconfig libvorbis opusfile bzip2
- pkg install -y pkgconf git sdl2 python fontconfig opus
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated

View File

@@ -6,8 +6,21 @@ jobs:
# steps:
# - name: Cleanup
# run: rm -rf .* || true
get_prev_runid:
runs-on: ubuntu-latest
outputs:
value: ${{ steps.do.outputs.value }}
steps:
- id: do
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
value=$(gh run -R ${{ github.repository }} list -b${{ github.ref_name }} -ssuccess -L1 --json databaseId -q'.[0].databaseId')
echo "Last run ID is $value"
echo "value=$value" >> "$GITHUB_OUTPUT"
build:
runs-on: ${{ matrix.os }}
needs: get_prev_runid
continue-on-error: true
strategy:
fail-fast: false
@@ -66,14 +79,22 @@ jobs:
targetos: apple
targetarch: amd64
env:
SDL_VERSION: 2.30.12
SDL_VERSION: 2.30.11
GH_CPU_ARCH: ${{ matrix.targetarch }}
GH_CROSSCOMPILING: ${{ matrix.cross }}
WAFCACHE: ${{ github.workspace }}/wafcache/
WAFCACHE_EVICT_MAX_BYTES: 1000000 # github only gives 10gb for the whole repository
WAFCACHE_STATS: 1 # enable statistics in build log
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: Restore cache
uses: actions/cache/restore@v4
with:
key: ${{ runner.os }}-${{ matrix.targetos }}-${{ matrix.targetarch }}-${{ needs.get_prev_runid.outputs.value }}
path: ${{ github.workspace }}/wafcache/
- name: Install dependencies
run: bash scripts/gha/deps_${{ matrix.targetos }}.sh
- name: Build engine
@@ -85,9 +106,14 @@ jobs:
with:
name: artifact-${{ matrix.targetos }}-${{ matrix.targetarch }}
path: artifacts/*
- name: Save cache
uses: actions/cache/save@v4
with:
path: ${{ github.workspace }}/wafcache/
key: ${{ runner.os }}-${{ matrix.targetos }}-${{ matrix.targetarch }}-${{ github.run_id }}
flatpak:
runs-on: ubuntu-latest
continue-on-error: true
strategy:
matrix:
include:
@@ -101,7 +127,7 @@ jobs:
with:
submodules: recursive
- name: Build flatpak (Compat.i386)
uses: FWGS/flatpak-github-actions/flatpak-builder@v6.3-fix
uses: FWGS/flatpak-github-actions/flatpak-builder@v6.3
with:
bundle: ${{ matrix.app }}.flatpak
manifest-path: scripts/flatpak/${{ matrix.app }}.yml

View File

@@ -25,4 +25,5 @@ def build(bld):
name = 'extras.pk3',
files = srcdir.ant_glob('**/*'),
relative_to = srcdir,
compresslevel = 0,
install_path = install_path)

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -16,31 +16,41 @@
#include STDINT_H
#include <assert.h>
typedef uint8_t byte;
typedef float vec_t;
typedef vec_t vec2_t[2];
typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4];
typedef vec_t quat_t[4];
typedef byte rgba_t[4]; // unsigned byte colorpack
typedef byte rgb_t[3]; // unsigned byte colorpack
typedef vec_t matrix3x4[3][4];
typedef vec_t matrix4x4[4][4];
typedef uint32_t poolhandle_t;
typedef unsigned char byte;
typedef int sound_t;
typedef float vec_t;
typedef vec_t vec2_t[2];
typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4];
typedef vec_t quat_t[4];
typedef byte rgba_t[4]; // unsigned byte colorpack
typedef byte rgb_t[3]; // unsigned byte colorpack
typedef vec_t matrix3x4[3][4];
typedef vec_t matrix4x4[4][4];
typedef uint32_t poolhandle_t;
#undef true
#undef false
// true and false are keywords in C++ and C23
#if !__cplusplus && __STDC_VERSION__ < 202311L
enum { false, true };
#endif
#ifndef __cplusplus
typedef enum { false, true } qboolean;
#else
typedef int qboolean;
#endif
#define MAX_STRING 256 // generic string
#define MAX_VA_STRING 1024 // compatibility macro
#define MAX_SYSPATH 1024 // system filepath
#define MAX_MODS 512 // environment games that engine can keep visible
typedef uint64_t longtime_t;
#define MAX_STRING 256 // generic string
#define MAX_INFO_STRING 256 // infostrings are transmitted across network
#define MAX_SERVERINFO_STRING 512 // server handles too many settings. expand to 1024?
#define MAX_LOCALINFO_STRING 32768 // localinfo used on server and not sended to the clients
#define MAX_SYSPATH 1024 // system filepath
#define MAX_VA_STRING 1024 // string length returned by va()
#define MAX_PRINT_MSG 8192 // how many symbols can handle single call of Con_Printf or Con_DPrintf
#define MAX_TOKEN 2048 // parse token length
#define MAX_MODS 512 // environment games that engine can keep visible
#define MAX_USERMSG_LENGTH 2048 // don't modify it's relies on a client-side definitions
#define BIT( n ) ( 1U << ( n ))
#define BIT64( n ) ( 1ULL << ( n ))
@@ -199,16 +209,35 @@ _inline float LittleFloat( float f )
#endif
typedef unsigned int dword;
typedef unsigned int uint;
typedef char string[MAX_STRING];
typedef off_t fs_offset_t;
typedef unsigned int dword;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef char string[MAX_STRING];
typedef struct file_s file_t; // normal file
typedef struct stream_s stream_t; // sound stream for background music playing
typedef off_t fs_offset_t;
#if XASH_WIN32
typedef int fs_size_t; // return type of _read, _write funcs
typedef int fs_size_t; // return type of _read, _write funcs
#else /* !XASH_WIN32 */
typedef ssize_t fs_size_t;
typedef ssize_t fs_size_t;
#endif /* !XASH_WIN32 */
typedef struct dllfunc_s
{
const char *name;
void **func;
} dllfunc_t;
typedef struct dll_info_s
{
const char *name; // name of library
const dllfunc_t *fcts; // list of dll exports
const size_t num_fcts;
qboolean crash; // crash if dll not found
void *link; // hinstance of loading library
} dll_info_t;
typedef void (*setpair_t)( const char *key, const void *value, const void *buffer, void *numpairs );
typedef void *(*pfnCreateInterface_t)( const char *, int * );
// config strings are a general means of communication from

View File

@@ -153,7 +153,6 @@ static void CL_WriteErrorMessage( int current_count, sizebuf_t *msg )
FS_Write( fp, &cls.starting_count, sizeof( int ));
FS_Write( fp, &current_count, sizeof( int ));
FS_Write( fp, &cls.legacymode, sizeof( cls.legacymode ));
FS_Write( fp, MSG_GetData( msg ), MSG_GetMaxBytes( msg ));
FS_Close( fp );
@@ -169,7 +168,7 @@ list last 32 messages for debugging net troubleshooting
*/
void CL_WriteMessageHistory( void )
{
oldcmd_t *old;
oldcmd_t *old, *failcommand;
sizebuf_t *msg = &net_message;
int i, thecmd;
@@ -193,49 +192,9 @@ void CL_WriteMessageHistory( void )
thecmd++;
}
old = &cls_message_debug.oldcmd[thecmd];
Con_Printf( S_RED "BAD: " S_DEFAULT "%i %04i %s\n", old->frame_number, old->starting_offset, CL_MsgInfo( old->command ));
CL_WriteErrorMessage( old->starting_offset, msg );
failcommand = &cls_message_debug.oldcmd[thecmd];
Con_Printf( "BAD: %3i:%s\n", MSG_GetNumBytesRead( msg ) - 1, CL_MsgInfo( failcommand->command ));
if( host_developer.value >= DEV_EXTENDED )
CL_WriteErrorMessage( MSG_GetNumBytesRead( msg ) - 1, msg );
cls_message_debug.parsing = false;
}
void CL_ReplayBufferDat_f( void )
{
file_t *f = FS_Open( Cmd_Argv( 1 ), "rb", true );
sizebuf_t msg;
char buffer[NET_MAX_MESSAGE];
int starting_count, current_count, protocol;
fs_offset_t len;
if( !f )
return;
FS_Read( f, &starting_count, sizeof( starting_count ));
FS_Read( f, &current_count, sizeof( current_count ));
FS_Read( f, &protocol, sizeof( protocol ));
cls.legacymode = protocol;
len = FS_Read( f, buffer, sizeof( buffer ));
FS_Close( f );
MSG_Init( &msg, __func__, buffer, len );
Delta_Shutdown();
Delta_Init();
clgame.maxEntities = MAX_EDICTS;
clgame.entities = Mem_Calloc( clgame.mempool, sizeof( *clgame.entities ) * clgame.maxEntities );
// ad-hoc implement
#if 0
{
const int message_pos = 12; // put real number here
MSG_SeekToBit( &msg, ( message_pos - 12 + 1 ) << 3, SEEK_SET );
CL_ParseYourMom( &msg, protocol );
}
#endif
Sys_Quit( __func__ );
}

View File

@@ -373,7 +373,7 @@ CL_WriteDemoUserMessage
Dumps the user message (demoaction)
====================
*/
void GAME_EXPORT CL_WriteDemoUserMessage( int size, byte *buffer )
void CL_WriteDemoUserMessage( const byte *buffer, size_t size )
{
if( !cls.demorecording || cls.demowaiting )
return;
@@ -624,10 +624,11 @@ static void CL_ReadDemoUserCmd( qboolean discard )
if( !discard )
{
const usercmd_t nullcmd = { 0 };
usercmd_t nullcmd;
sizebuf_t buf;
demoangle_t *a;
memset( &nullcmd, 0, sizeof( nullcmd ));
MSG_Init( &buf, "UserCmd", data, sizeof( data ));
// a1ba: I have no proper explanation why

View File

@@ -2229,3 +2229,4 @@ void CL_ThinkParticle( double frametime, particle_t *p )
break;
}
}

View File

@@ -556,7 +556,7 @@ static void CL_InitTitles( const char *filename )
Q_snprintf( name, sizeof( name ), TEXT_MSGNAME, i );
cl_textmessage[i].pName = copystringpool( clgame.mempool, name );
cl_textmessage[i].pName = _copystring( clgame.mempool, name, __FILE__, __LINE__ );
cl_textmessage[i].pMessage = cl_textbuffer[i];
}
@@ -3348,6 +3348,28 @@ DemoApi implementation
=================
*/
/*
=================
Demo_IsRecording
=================
*/
static int GAME_EXPORT Demo_IsRecording( void )
{
return cls.demorecording;
}
/*
=================
Demo_IsPlayingback
=================
*/
static int GAME_EXPORT Demo_IsPlayingback( void )
{
return cls.demoplayback;
}
/*
=================
Demo_IsTimeDemo
@@ -3359,6 +3381,17 @@ static int GAME_EXPORT Demo_IsTimeDemo( void )
return cls.timedemo;
}
/*
=================
Demo_WriteBuffer
=================
*/
static void GAME_EXPORT Demo_WriteBuffer( int size, byte *buffer )
{
CL_WriteDemoUserMessage( buffer, size );
}
/*
=================
NetworkApi implementation
@@ -3544,6 +3577,28 @@ static int GAME_EXPORT NetAPI_CompareAdr( netadr_t *a, netadr_t *b )
return NET_CompareAdr( *a, *b );
}
/*
=================
NetAPI_StringToAdr
=================
*/
static int GAME_EXPORT NetAPI_StringToAdr( char *s, netadr_t *a )
{
return NET_StringToAdr( s, a );
}
/*
=================
NetAPI_ValueForKey
=================
*/
static const char * GAME_EXPORT NetAPI_ValueForKey( const char *s, const char *key )
{
return Info_ValueForKey( s, key );
}
/*
=================
NetAPI_RemoveKey
@@ -3740,10 +3795,10 @@ static event_api_t gEventApi =
static demo_api_t gDemoApi =
{
(void *)CL_IsRecordDemo,
(void *)CL_IsPlaybackDemo,
Demo_IsRecording,
Demo_IsPlayingback,
Demo_IsTimeDemo,
CL_WriteDemoUserMessage,
Demo_WriteBuffer,
};
net_api_t gNetApi =
@@ -3755,8 +3810,8 @@ net_api_t gNetApi =
NetAPI_CancelAllRequests,
NetAPI_AdrToString,
NetAPI_CompareAdr,
(void *)NET_StringToAdr,
Info_ValueForKey,
NetAPI_StringToAdr,
NetAPI_ValueForKey,
NetAPI_RemoveKey,
NetAPI_SetValueForKey,
};

View File

@@ -76,7 +76,6 @@ static CVAR_DEFINE_AUTO( cl_upmax, "1200", FCVAR_ARCHIVE, "max allowed incoming
CVAR_DEFINE_AUTO( cl_lw, "1", FCVAR_ARCHIVE|FCVAR_USERINFO, "enable client weapon predicting" );
CVAR_DEFINE_AUTO( cl_charset, "utf-8", FCVAR_ARCHIVE, "1-byte charset to use (iconv style)" );
CVAR_DEFINE_AUTO( cl_trace_consistency, "0", FCVAR_ARCHIVE, "enable consistency info tracing (good for developers)" );
CVAR_DEFINE_AUTO( cl_trace_stufftext, "0", FCVAR_ARCHIVE, "enable stufftext (server-to-client console commands) tracing (good for developers)" );
CVAR_DEFINE_AUTO( cl_trace_messages, "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable message names tracing (good for developers)" );
CVAR_DEFINE_AUTO( cl_trace_events, "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable events tracing (good for developers)" );
@@ -148,6 +147,11 @@ qboolean CL_IsRecordDemo( void )
return cls.demorecording;
}
qboolean CL_IsTimeDemo( void )
{
return cls.timedemo;
}
qboolean CL_DisableVisibility( void )
{
return cls.envshot_disable_vis;
@@ -594,7 +598,7 @@ CL_CreateCmd
*/
static void CL_CreateCmd( void )
{
usercmd_t nullcmd = { 0 }, *cmd;
usercmd_t nullcmd, *cmd;
runcmd_t *pcmd;
qboolean active;
double accurate_ms;
@@ -646,6 +650,7 @@ static void CL_CreateCmd( void )
}
else
{
memset( &nullcmd, 0, sizeof( nullcmd ));
cmd = &nullcmd;
}
@@ -718,20 +723,11 @@ static void CL_WritePacket( void )
int numbackup, maxbackup, maxcmds;
const connprotocol_t proto = cls.legacymode;
// FIXME: on Xash protocol we don't send move commands until ca_active
// to prevent outgoing_command outrun incoming_acknowledged
// which is fatal for some buggy mods like TFC
//
// ... but GoldSrc don't have (real) ca_validate state, so we consider
// ca_validate the same as ca_active, otherwise we don't pass validation
// of server-side mods like ReAuthCheck
const connstate_t min_state = proto == PROTO_GOLDSRC ? ca_validate : ca_active;
// don't send anything if playing back a demo
if( cls.demoplayback || cls.state < ca_connected || cls.state == ca_cinematic )
return;
if( cls.state < min_state )
if( cls.state <= ca_connected )
{
Netchan_TransmitBits( &cls.netchan, 0, "" );
return;
@@ -829,7 +825,7 @@ static void CL_WritePacket( void )
buf.pData[key] = CRC32_BlockSequence( &buf.pData[key + 1], size, cls.netchan.outgoing_sequence );
COM_Munge( &buf.pData[key + 1], Q_min( size, 255 ), cls.netchan.outgoing_sequence );
}
else if( !Host_IsLocalClient( ))
else
{
int size = MSG_GetRealBytesWritten( &buf ) - key - 1;
buf.pData[key] = CRC32_BlockSequence( &buf.pData[key + 1], size, cls.netchan.outgoing_sequence );
@@ -1598,9 +1594,6 @@ void CL_SetupNetchanForProtocol( connprotocol_t proto )
}
break;
default:
if( !Host_IsLocalClient( ))
SetBits( flags, NETCHAN_USE_LZSS );
cls.extensions = Q_atoi( Info_ValueForKey( Cmd_Argv( 1 ), "ext" ));
if( FBitSet( cls.extensions, NET_EXT_SPLITSIZE ))
@@ -3394,7 +3387,6 @@ static void CL_InitLocal( void )
Cvar_RegisterVariable( &rcon_address );
Cvar_RegisterVariable( &cl_trace_consistency );
Cvar_RegisterVariable( &cl_trace_stufftext );
Cvar_RegisterVariable( &cl_trace_messages );
Cvar_RegisterVariable( &cl_trace_events );
@@ -3489,8 +3481,6 @@ static void CL_InitLocal( void )
Cmd_AddCommand ("fullserverinfo", CL_FullServerinfo_f, "sent by server when serverinfo changes" );
Cmd_AddCommand ("upload", CL_BeginUpload_f, "uploading file to the server" );
Cmd_AddRestrictedCommand( "replaybufferdat", CL_ReplayBufferDat_f, "development and debugging tool" );
Cmd_AddRestrictedCommand ("quit", CL_Quit_f, "quit from game" );
Cmd_AddRestrictedCommand ("exit", CL_Quit_f, "quit from game" );
@@ -3668,8 +3658,6 @@ void CL_Init( void )
if( !CL_LoadProgs( libpath ))
Host_Error( "can't initialize %s: %s\n", libpath, COM_GetLibraryError( ));
ID_Init();
cls.build_num = 0;
cls.initialized = true;
cl.maxclients = 1; // allow to drawing player in menu

View File

@@ -1614,23 +1614,6 @@ void CL_UpdateUserPings( sizebuf_t *msg )
}
}
static const char *CL_CheckTypeToString( int check_type )
{
// renamed so they have same width and look better in console output
switch( check_type )
{
case force_exactfile:
return "exactfile";
case force_model_samebounds:
return "samebounds";
case force_model_specifybounds:
return "specbounds";
case force_model_specifybounds_if_avail:
return "specbounds2";
}
return "unknown";
}
static void CL_SendConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
{
qboolean user_changed_diskfile;
@@ -1896,9 +1879,6 @@ static void CL_ParseConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
return;
}
if( cl_trace_consistency.value )
Con_Printf( "Server wants consistency of the following resources:\n" );
skip_crc_change = NULL;
lastcheck = 0;
@@ -1930,7 +1910,7 @@ static void CL_ParseConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
pc = &cl.consistency_list[cl.num_consistency];
cl.num_consistency++;
memset( pc, 0, sizeof( *pc ));
memset( pc, 0, sizeof( consistency_t ));
pc->filename = pResource->szFileName;
pc->issound = (pResource->type == t_sound);
pc->orig_index = delta;
@@ -1943,9 +1923,6 @@ static void CL_ParseConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
pc->check_type = pResource->rguc_reserved[0];
}
if( cl_trace_consistency.value )
Con_Printf( "%s\t%s\t%s\n", COM_ResourceTypeFromIndex( pResource->type ), CL_CheckTypeToString( pc->check_type ), pc->filename );
skip_crc_change = pResource;
lastcheck = delta;
}

View File

@@ -91,11 +91,11 @@ static void CL_ParseNewMovevars( sizebuf_t *msg )
typedef struct delta_header_t
{
qboolean remove;
qboolean custom;
qboolean instanced;
uint16_t instanced_baseline_index;
uint16_t offset;
qboolean remove : 1;
qboolean custom : 1;
qboolean instanced : 1;
uint instanced_baseline_index : 6;
uint offset : 6;
} delta_header_t;
static int CL_ParseDeltaHeader( sizebuf_t *msg, qboolean delta, int oldnum, struct delta_header_t *hdr )
@@ -160,47 +160,33 @@ static int CL_GetEntityDelta( const struct delta_header_t *hdr, int entnum )
return DT_ENTITY_STATE_T;
}
static int CL_FlushEntityPacketGS( frame_t *frame, sizebuf_t *msg )
static void CL_FlushEntityPacketGS( frame_t *frame, sizebuf_t *msg )
{
int playerbytes = 0, numbase = 0;
frame->valid = false;
cl.validsequence = 0; // can't render a frame
// read it all but ignore it
while( 1 )
{
int newnum, bufstart;
int num = 0;
entity_state_t from = { 0 }, to;
delta_header_t hdr;
qboolean player;
if( MSG_ReadWord( msg ) != 0 )
{
MSG_SeekToBit( msg, -16, SEEK_CUR );
numbase = newnum = CL_ParseDeltaHeader( msg, true, numbase, &hdr );
num = CL_ParseDeltaHeader( msg, false, num, &hdr );
}
else break;
if( MSG_CheckOverflow( msg ))
Host_Error( "%s: overflow\n", __func__ );
player = CL_IsPlayerIndex( newnum );
bufstart = MSG_GetNumBytesRead( msg );
if( hdr.remove )
continue;
Delta_ReadGSFields( msg, CL_GetEntityDelta( &hdr, newnum ), &from, &to, cl.mtime[0] );
if( player )
playerbytes += MSG_GetNumBytesRead( msg ) - bufstart;
Delta_ReadGSFields( msg, CL_GetEntityDelta( &hdr, num ), &from, &to, cl.mtime[0] );
}
if( MSG_CheckOverflow( msg ))
Host_Error( "%s: overflow\n", __func__ );
return playerbytes;
}
static void CL_DeltaEntityGS( const delta_header_t *hdr, sizebuf_t *msg, frame_t *frame, int newnum, const entity_state_t *from )
@@ -217,7 +203,7 @@ static void CL_DeltaEntityGS( const delta_header_t *hdr, sizebuf_t *msg, frame_t
if(( newnum < 0 ) || ( newnum >= clgame.maxEntities ))
{
Con_DPrintf( S_ERROR "CL_DeltaEntity: invalid newnum: %d\n", newnum );
Host_Error( "%s: bad delta entity number: %i\n", __func__, newnum );
Host_Error( "%s: bad delta entity number: %i", __func__, newnum );
return;
}
@@ -281,7 +267,7 @@ static void CL_CopyPacketEntity( frame_t *frame, int num, const entity_state_t *
static int CL_ParsePacketEntitiesGS( sizebuf_t *msg, qboolean delta )
{
frame_t *frame, *oldframe;
int oldindex, oldnum, numbase = 0;
int oldindex, newnum, oldnum, numbase = 0;
entity_state_t *oldent;
int count;
int playerbytes = 0;
@@ -328,7 +314,7 @@ static int CL_ParsePacketEntitiesGS( sizebuf_t *msg, qboolean delta )
// read it all but ignore it
while( 1 )
{
int bufstart, newnum;
int bufstart;
qboolean player;
delta_header_t hdr;
int val = MSG_ReadWord( msg );
@@ -548,7 +534,7 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
{
if( MSG_CheckOverflow( msg ))
{
Host_Error( "%s: overflow!\n", __func__ );
Host_Error( "CL_ParseServerMessage: overflow!\n" );
return;
}

View File

@@ -233,11 +233,6 @@ static intptr_t pfnRenderGetParm( int parm, int arg )
return CL_RenderGetParm( parm, arg, true );
}
static void pfnAVI_StreamSound( void *avi, int entnum, float fvol, float attn, float synctime )
{
return; // stub, use AVI_SetParm and AVI_Think to stream AVI sound
}
static render_api_t gRenderAPI =
{
pfnRenderGetParm, // GL_RenderGetParm,
@@ -270,7 +265,7 @@ static render_api_t gRenderAPI =
NULL, // R_UploadStretchRaw,
(void*)AVI_FreeVideo,
(void*)AVI_IsActive,
(void*)pfnAVI_StreamSound,
S_StreamAviSamples,
NULL,
NULL,
NULL, // GL_Bind,

View File

@@ -688,7 +688,6 @@ extern convar_t r_showtextures;
extern convar_t cl_bmodelinterp;
extern convar_t cl_lw; // local weapons
extern convar_t cl_charset;
extern convar_t cl_trace_consistency;
extern convar_t cl_trace_stufftext;
extern convar_t cl_trace_messages;
extern convar_t cl_trace_events;
@@ -737,7 +736,6 @@ void CL_ClearResourceLists( void );
//
// cl_debug.c
//
void CL_ReplayBufferDat_f( void );
void CL_Parse_Debug( qboolean enable );
void CL_Parse_RecordCommand( int cmd, int startoffset );
void CL_ResetFrame( frame_t *frame );
@@ -769,7 +767,7 @@ void CL_StartupDemoHeader( void );
void CL_DrawDemoRecording( void );
void CL_WriteDemoUserCmd( int cmdnumber );
void CL_WriteDemoMessage( qboolean startup, int start, sizebuf_t *msg );
void CL_WriteDemoUserMessage( int size, byte *buffer );
void CL_WriteDemoUserMessage( const byte *buffer, size_t size );
qboolean CL_DemoReadMessage( byte *buffer, size_t *length );
void CL_DemoInterpolateAngles( void );
void CL_CheckStartupDemos( void );
@@ -1121,7 +1119,7 @@ void Con_PageUp( int lines );
//
// s_main.c
//
typedef int sound_t;
void S_StreamAviSamples( void *Avi, int entnum, float fvol, float attn, float synctime );
void S_StartBackgroundTrack( const char *intro, const char *loop, int position, qboolean fullpath );
void S_StopBackgroundTrack( void );
void S_StreamSetPause( int pause );
@@ -1210,13 +1208,6 @@ void Key_EnableTextInput( qboolean enable, qboolean force );
int Key_ToUpper( int key );
void OSK_Draw( void );
//
// identification.c
//
void ID_Init( void );
const char *ID_GetMD5( void );
void GAME_EXPORT ID_SetCustomClientID( const char *id );
extern rgba_t g_color_table[8];
extern triangleapi_t gTriApi;
extern net_api_t gNetApi;

View File

@@ -622,7 +622,7 @@ int Con_UtfProcessCharForce( int in )
// TODO: get rid of global state where possible
static utfstate_t state = { 0 };
uint32_t ch = Q_DecodeUTF8( &state, in );
int ch = Q_DecodeUTF8( &state, in );
if( g_codepage == 1251 )
return Q_UnicodeToCP1251( ch );
@@ -2092,7 +2092,10 @@ void Con_RunConsole( void )
}
else
{
g_codepage = 0;
Con_Printf( S_WARN "Unknown charset %s, defaulting to cp1252", con_charset.string );
Cvar_DirectSet( &con_charset, "cp1252" );
g_codepage = 1252;
}
cls.accept_utf8 = !Q_stricmp( cl_charset.string, "utf-8" );

View File

@@ -43,6 +43,7 @@ static struct joy_axis_s
short val;
short prevval;
} joyaxis[MAX_AXES] = { 0 };
static byte currentbinding; // add posibility to remap keys, to place it in joykeys[]
static qboolean joy_initialized;
static CVAR_DEFINE_AUTO( joy_pitch, "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick pitch sensitivity" );
@@ -59,9 +60,9 @@ static CVAR_DEFINE_AUTO( joy_pitch_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE
static CVAR_DEFINE_AUTO( joy_yaw_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "yaw axis deadzone. Value from 0 to 32767" );
static CVAR_DEFINE_AUTO( joy_axis_binding, "sfpyrl", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "axis hardware id to engine inner axis binding, "
"s - side, f - forward, y - yaw, p - pitch, r - left trigger, l - right trigger" );
static CVAR_DEFINE_AUTO( joy_found, "0", FCVAR_READ_ONLY, "is joystick is connected" );
static CVAR_DEFINE_AUTO( joy_index, "0", FCVAR_READ_ONLY, "current active joystick" );
CVAR_DEFINE_AUTO( joy_enable, "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable joystick" );
static CVAR_DEFINE_AUTO( joy_have_gyro, "0", FCVAR_READ_ONLY, "tells whether current active gamepad has gyroscope or not" );
static CVAR_DEFINE_AUTO( joy_calibrated, "0", FCVAR_READ_ONLY, "tells whether current active gamepad gyroscope has been calibrated or not" );
/*
============
@@ -70,30 +71,7 @@ Joy_IsActive
*/
qboolean Joy_IsActive( void )
{
return joy_enable.value;
}
/*
===========
Joy_SetCapabilities
===========
*/
void Joy_SetCapabilities( qboolean have_gyro )
{
Cvar_FullSet( joy_have_gyro.name, have_gyro ? "1" : "0", joy_have_gyro.flags );
}
/*
===========
Joy_SetCalibrationState
===========
*/
void Joy_SetCalibrationState( joy_calibration_state_t state )
{
if( (int)joy_calibrated.value == state )
return;
Cvar_FullSet( joy_calibrated.name, va( "%d", state ), joy_calibrated.flags );
return joy_found.value && joy_enable.value;
}
/*
@@ -103,7 +81,7 @@ Joy_HatMotionEvent
DPad events
============
*/
static void Joy_HatMotionEvent( int value )
void Joy_HatMotionEvent( byte hat, byte value )
{
struct
{
@@ -118,6 +96,9 @@ static void Joy_HatMotionEvent( int value )
};
int i;
if( !joy_found.value )
return;
for( i = 0; i < ARRAYSIZE( keys ); i++ )
{
if( value & keys[i].mask )
@@ -244,7 +225,7 @@ static void Joy_ProcessStick( const engineAxis_t engineAxis, short value )
val |= Joy_GetHatValueForAxis( JOY_AXIS_SIDE );
val |= Joy_GetHatValueForAxis( JOY_AXIS_FWD );
Joy_HatMotionEvent( val );
Joy_HatMotionEvent( 0, val );
}
}
@@ -255,9 +236,23 @@ Joy_AxisMotionEvent
Axis events
=============
*/
void Joy_AxisMotionEvent( engineAxis_t engineAxis, short value )
void Joy_AxisMotionEvent( byte axis, short value )
{
if( engineAxis >= JOY_AXIS_NULL )
if( !joy_found.value )
return;
if( axis >= MAX_AXES )
{
Con_Reportf( "Only 6 axes is supported\n" );
return;
}
Joy_KnownAxisMotionEvent( joyaxesmap[axis], value );
}
void Joy_KnownAxisMotionEvent( engineAxis_t engineAxis, short value )
{
if( engineAxis == JOY_AXIS_NULL )
return;
if( value == joyaxis[engineAxis].val )
@@ -271,14 +266,66 @@ void Joy_AxisMotionEvent( engineAxis_t engineAxis, short value )
/*
=============
Joy_GyroEvent
Joy_BallMotionEvent
Gyroscope events
Trackball events. UNDONE
=============
*/
void Joy_GyroEvent( vec3_t data )
void Joy_BallMotionEvent( byte ball, short xrel, short yrel )
{
//if( !joy_found.value )
// return;
}
/*
=============
Joy_ButtonEvent
Button events
=============
*/
void Joy_ButtonEvent( byte button, byte down )
{
if( !joy_found.value )
return;
// generic game button code.
if( button > 32 )
{
int origbutton = button;
button = ( button & 31 ) + K_AUX1;
Con_Reportf( "Only 32 joybuttons is supported, converting %i button ID to %s\n", origbutton, Key_KeynumToString( button ) );
}
else button += K_AUX1;
Key_Event( button, down );
}
/*
=============
Joy_RemoveEvent
Called when joystick is removed. For future expansion
=============
*/
void Joy_RemoveEvent( void )
{
if( joy_found.value )
Cvar_FullSet( "joy_found", "0", FCVAR_READ_ONLY );
}
/*
=============
Joy_RemoveEvent
Called when joystick is removed. For future expansion
=============
*/
void Joy_AddEvent( void )
{
if( joy_enable.value && !joy_found.value )
Cvar_FullSet( "joy_found", "1", FCVAR_READ_ONLY );
}
/*
@@ -317,19 +364,14 @@ void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw )
*fw -= joy_forward.value * (float)joyaxis[JOY_AXIS_FWD ].val/(float)SHRT_MAX; // must be form -1.0 to 1.0
*side += joy_side.value * (float)joyaxis[JOY_AXIS_SIDE].val/(float)SHRT_MAX;
#if !defined(XASH_SDL)
*dpitch += joy_pitch.value * (float)joyaxis[JOY_AXIS_PITCH].val/(float)SHRT_MAX * host.realframetime; // abs axis rotate is frametime related
*dyaw -= joy_yaw.value * (float)joyaxis[JOY_AXIS_YAW ].val/(float)SHRT_MAX * host.realframetime;
#else
// HACKHACK: SDL have inverted look axis.
*dpitch -= joy_pitch.value * (float)joyaxis[JOY_AXIS_PITCH].val/(float)SHRT_MAX * host.realframetime;
*dyaw += joy_yaw.value * (float)joyaxis[JOY_AXIS_YAW ].val/(float)SHRT_MAX * host.realframetime;
}
static void Joy_CalibrateGyro_f( void )
{
if( !joy_have_gyro.value )
{
Con_Printf( "Current active gamepad doesn't have gyroscope\n" );
return;
}
Platform_CalibrateGamepadGyro();
#endif
}
/*
@@ -341,8 +383,6 @@ Main init procedure
*/
void Joy_Init( void )
{
Cmd_AddRestrictedCommand( "joy_calibrate_gyro", Joy_CalibrateGyro_f, "calibrate gamepad gyroscope. You must to put gamepad on stationary surface" );
Cvar_RegisterVariable( &joy_pitch );
Cvar_RegisterVariable( &joy_yaw );
Cvar_RegisterVariable( &joy_side );
@@ -362,9 +402,11 @@ void Joy_Init( void )
Cvar_RegisterVariable( &joy_yaw_deadzone );
Cvar_RegisterVariable( &joy_axis_binding );
Cvar_RegisterVariable( &joy_found );
// we doesn't loaded config.cfg yet, so this cvar is not archive.
// change by +set joy_index in cmdline
Cvar_RegisterVariable( &joy_index );
Cvar_RegisterVariable( &joy_have_gyro );
Cvar_RegisterVariable( &joy_calibrated );
Cvar_RegisterVariable( &joy_enable );
// renamed from -nojoy to -noenginejoy to not conflict with
@@ -375,7 +417,7 @@ void Joy_Init( void )
return;
}
Platform_JoyInit();
Cvar_FullSet( "joy_found", va( "%d", Platform_JoyInit( joy_index.value )), FCVAR_READ_ONLY );
joy_initialized = true;
}
@@ -389,5 +431,8 @@ Shutdown joystick code
*/
void Joy_Shutdown( void )
{
Platform_JoyShutdown();
if( joy_initialized )
{
Cvar_FullSet( "joy_found", 0, FCVAR_READ_ONLY );
}
}

View File

@@ -902,10 +902,9 @@ static void Touch_AddButton_f( void )
rgba_t color;
int argc = Cmd_Argc( );
touch_button_t *button = NULL;
const char *name, *command;
const char *name, *texture, *command;
float x1, y1, x2, y2;
qboolean privileged = Cmd_CurrentCommandIsPrivileged();
string texture;
if( argc < 4 )
{
@@ -914,18 +913,9 @@ static void Touch_AddButton_f( void )
}
name = Cmd_Argv( 1 );
Q_strncpy( texture, Cmd_Argv( 2 ), sizeof( texture ));
texture = Cmd_Argv( 2 );
command = Cmd_Argv( 3 );
// HACKHACK: old engine specifically used .tga for touch buttons
// and because new engine extras.pk3 don't have .tga textures
// (which instead were converted to .png) strip extension to let
// to let imagelib choose better format
//
// Remove this when old engine migration would be done
if( Q_stricmp( COM_FileExtension( texture ), "tga" ))
COM_StripExtension( texture );
if( argc < 8 )
{
x1 = y1 = 0.4f;

View File

@@ -104,21 +104,18 @@ typedef enum engineAxis_e
JOY_AXIS_NULL
} engineAxis_t;
typedef enum joy_calibration_state_s
{
JOY_NOT_CALIBRATED = 0,
JOY_CALIBRATING,
JOY_FAILED_TO_CALIBRATE,
JOY_CALIBRATED
} joy_calibration_state_t;
qboolean Joy_IsActive( void );
void Joy_SetCapabilities( qboolean have_gyro );
void Joy_SetCalibrationState( joy_calibration_state_t state );
void Joy_AxisMotionEvent( engineAxis_t engineAxis, short value );
void Joy_GyroEvent( vec3_t data );
void Joy_HatMotionEvent( byte hat, byte value );
void Joy_AxisMotionEvent( byte axis, short value );
void Joy_KnownAxisMotionEvent( engineAxis_t engineAxis, short value );
void Joy_BallMotionEvent( byte ball, short xrel, short yrel );
void Joy_ButtonEvent( byte button, byte down );
void Joy_AddEvent( void );
void Joy_RemoveEvent( void );
void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw );
void Joy_Init( void );
void Joy_Shutdown( void );
void Joy_EnableTextInput(qboolean enable, qboolean force);
#endif//INPUT_H

View File

@@ -51,7 +51,7 @@ static const keyname_t keynames[] =
{"CTRL", K_CTRL, "+attack" },
{"SHIFT", K_SHIFT, "+speed" },
{"CAPSLOCK", K_CAPSLOCK, "" },
{"SCROLLOCK", K_SCROLLLOCK, "" },
{"SCROLLOCK", K_SCROLLOCK, "" },
{"F1", K_F1, "cmd help" },
{"F2", K_F2, "menu_savegame" },
{"F3", K_F3, "menu_loadgame" },
@@ -215,7 +215,7 @@ const char *Key_KeynumToString( int keynum )
return "<OUT OF RANGE>";
// check for printable ascii (don't use quote)
if( keynum > 32 && keynum < 127 && keynum != '"' && keynum != ';' && keynum != K_SCROLLLOCK )
if( keynum > 32 && keynum < 127 && keynum != '"' && keynum != ';' && keynum != K_SCROLLOCK )
{
tinystr[0] = keynum;
tinystr[1] = 0;
@@ -861,9 +861,7 @@ void GAME_EXPORT Key_ClearStates( void )
for( i = 0; i < 256; i++ )
{
if( i >= K_MOUSE1 && i <= K_MOUSE5 )
IN_MouseEvent( i - K_MOUSE1, false );
else
if( keys[i].down && i < K_MOUSE1 && i > K_MOUSE5 )
Key_Event( i, false );
keys[i].down = 0;
@@ -871,6 +869,9 @@ void GAME_EXPORT Key_ClearStates( void )
keys[i].gamedown = 0;
}
for( i = K_MOUSE1; i < K_MOUSE5; i++ ) // from K_MOUSE1 to K_MOUSE5
IN_MouseEvent( i - K_MOUSE1, false );
if( clgame.hInstance )
clgame.dllFuncs.IN_ClearStates();
}
@@ -1107,7 +1108,7 @@ static qboolean OSK_KeyEvent( int key, int down )
/*
=============
OSK_EnableTextInput
Joy_EnableTextInput
Enables built-in IME
=============

View File

@@ -312,7 +312,7 @@ static int DLY_Init( int idelay, float delay )
cur = &rgsxdly[idelay];
cur->cdelaysamplesmax = ((int)(delay * idsp_dma_speed) << sxhires) + 1;
cur->lpdelayline = (int *)Mem_Calloc( sndpool, cur->cdelaysamplesmax * sizeof( int ));
cur->lpdelayline = (int *)Z_Calloc( cur->cdelaysamplesmax * sizeof( int ));
cur->xfade = 0;
// init modulation

View File

@@ -107,18 +107,17 @@ S_CreateDefaultSound
*/
static wavdata_t *S_CreateDefaultSound( void )
{
wavdata_t *sc;
uint samples = SOUND_DMA_SPEED;
uint channels = 1;
uint width = 2;
size_t size = samples * width * channels;
wavdata_t *sc;
sc = Mem_Calloc( sndpool, sizeof( wavdata_t ) + size );
sc->width = width;
sc->channels = channels;
sc = Mem_Calloc( sndpool, sizeof( wavdata_t ));
sc->width = 2;
sc->channels = 1;
sc->loopStart = 0;
sc->rate = SOUND_DMA_SPEED;
sc->samples = samples;
sc->size = size;
sc->samples = SOUND_DMA_SPEED;
sc->size = sc->samples * sc->width * sc->channels;
sc->buffer = Mem_Calloc( sndpool, sc->size );
return sc;
}

View File

@@ -1207,6 +1207,86 @@ void S_RawSamples( uint samples, uint rate, word width, word channels, const byt
S_RawEntSamples( entnum, samples, rate, width, channels, data, snd_vol );
}
/*
===================
S_PositionedRawSamples
===================
*/
void S_StreamAviSamples( void *Avi, int entnum, float fvol, float attn, float synctime )
{
int bufferSamples;
int fileSamples;
byte raw[MAX_RAW_SAMPLES];
float duration = 0.0f;
int r, fileBytes;
rawchan_t *ch = NULL;
if( !dma.initialized || s_listener.paused || !CL_IsInGame( ))
return;
if( entnum < 0 || entnum >= GI->max_edicts )
return;
if( !( ch = S_FindRawChannel( entnum, true )))
return;
if( ch->sound_info.rate == 0 )
{
if( !AVI_GetAudioInfo( Avi, &ch->sound_info ))
return; // no audiotrack
}
ch->master_vol = bound( 0, fvol * 255, 255 );
ch->dist_mult = (attn / SND_CLIP_DISTANCE);
// see how many samples should be copied into the raw buffer
if( ch->s_rawend < soundtime )
ch->s_rawend = soundtime;
// position is changed, synchronization is lost etc
if( fabs( ch->oldtime - synctime ) > s_mixahead.value )
ch->sound_info.loopStart = AVI_TimeToSoundPosition( Avi, synctime * 1000 );
ch->oldtime = synctime; // keep actual time
while( ch->s_rawend < soundtime + ch->max_samples )
{
wavdata_t *info = &ch->sound_info;
bufferSamples = ch->max_samples - (ch->s_rawend - soundtime);
// decide how much data needs to be read from the file
fileSamples = bufferSamples * ((float)info->rate / SOUND_DMA_SPEED );
if( fileSamples <= 1 ) return; // no more samples need
// our max buffer size
fileBytes = fileSamples * ( info->width * info->channels );
if( fileBytes > sizeof( raw ))
{
fileBytes = sizeof( raw );
fileSamples = fileBytes / ( info->width * info->channels );
}
// read audio stream
r = AVI_GetAudioChunk( Avi, raw, info->loopStart, fileBytes );
info->loopStart += r; // advance play position
if( r < fileBytes )
{
fileBytes = r;
fileSamples = r / ( info->width * info->channels );
}
if( r > 0 )
{
// add to raw buffer
ch->s_rawend = S_RawSamplesStereo( ch->rawsamples, ch->s_rawend, ch->max_samples,
fileSamples, info->rate, info->width, info->channels, raw );
}
else break; // no more samples for this frame
}
}
/*
===================
S_FreeIdleRawChannels
@@ -1874,15 +1954,14 @@ qboolean S_Init( void )
Cmd_AddCommand( "spk", S_SayReliable_f, "reliable play a specified sententce" );
Cmd_AddCommand( "speak", S_Say_f, "playing a specified sententce" );
sndpool = Mem_AllocPool( "Sound Zone" );
dma.backendName = "None";
if( !SNDDMA_Init( ))
if( !SNDDMA_Init( ) )
{
Con_Printf( "Audio: sound system can't be initialized\n" );
Mem_FreePool( &sndpool );
return false;
}
sndpool = Mem_AllocPool( "Sound Zone" );
soundtime = 0;
paintedtime = 0;

View File

@@ -16,7 +16,6 @@ GNU General Public License for more details.
#include "common.h"
#include "sound.h"
#include "client.h"
#include "soundlib.h"
static bg_track_t s_bgTrack;
static musicfade_t musicfade; // controlled by game dlls
@@ -213,7 +212,7 @@ void S_StreamBackgroundTrack( void )
while( ch->s_rawend < soundtime + ch->max_samples )
{
const stream_t *info = s_bgTrack.stream;
wavdata_t *info = FS_StreamInfo( s_bgTrack.stream );
bufferSamples = ch->max_samples - (ch->s_rawend - soundtime);

View File

@@ -557,7 +557,7 @@ static void VOX_ReadSentenceFile_( byte *buf, fs_offset_t size )
int index = cszrawsentences;
int size = strlen( name ) + strlen( value ) + 2;
rgpszrawsentence[index] = Mem_Malloc( sndpool, size );
rgpszrawsentence[index] = Mem_Malloc( host.mempool, size );
memcpy( rgpszrawsentence[index], name, size );
rgpszrawsentence[index][size - 1] = 0;
cszrawsentences++;

View File

@@ -114,6 +114,7 @@ typedef struct rawchan_s
vec3_t origin; // only use if fixed_origin is set
volatile uint s_rawend;
float oldtime; // catch time jumps
wavdata_t sound_info; // advance play position
size_t max_samples; // buffer length
portable_samplepair_t rawsamples[]; // variable sized
} rawchan_t;
@@ -170,8 +171,6 @@ typedef struct
int source; // may be game, menu, etc
} bg_track_t;
typedef int sound_t;
//====================================================================
#define MAX_DYNAMIC_CHANNELS (60 + NUM_AMBIENTS)

View File

@@ -29,20 +29,17 @@ static void Sound_Reset( void )
static MALLOC_LIKE( FS_FreeSound, 1 ) wavdata_t *SoundPack( void )
{
wavdata_t *pack = Mem_Malloc( host.soundpool, sizeof( *pack ) + sound.size );
wavdata_t *pack = Mem_Calloc( host.soundpool, sizeof( wavdata_t ));
pack->buffer = sound.wav;
pack->width = sound.width;
pack->rate = sound.rate;
pack->type = sound.type;
pack->size = sound.size;
pack->loopStart = sound.loopstart;
pack->samples = sound.samples;
pack->type = sound.type;
pack->flags = sound.flags;
pack->rate = sound.rate;
pack->width = sound.width;
pack->channels = sound.channels;
memcpy( pack->buffer, sound.wav, sound.size );
Mem_Free( sound.wav );
sound.wav = NULL;
pack->flags = sound.flags;
return pack;
}
@@ -135,6 +132,7 @@ free WAV buffer
void FS_FreeSound( wavdata_t *pack )
{
if( !pack ) return;
if( pack->buffer ) Mem_Free( pack->buffer );
Mem_Free( pack );
}
@@ -201,6 +199,33 @@ stream_t *FS_OpenStream( const char *filename )
return stream;
}
/*
================
FS_StreamInfo
get basic stream info
================
*/
wavdata_t *FS_StreamInfo( stream_t *stream )
{
static wavdata_t info;
if( !stream ) return NULL;
// fill structure
info.loopStart = 0;
info.rate = stream->rate;
info.width = stream->width;
info.channels = stream->channels;
info.flags = SOUND_STREAM;
info.size = stream->size;
info.buffer = NULL;
info.samples = 0; // not actual for streams
info.type = stream->type;
return &info;
}
/*
================
FS_ReadStream

View File

@@ -17,7 +17,7 @@ GNU General Public License for more details.
#include "base_cmd.h"
#include "cdll_int.h"
#define HASH_SIZE 64 // 64 * 4 * 4 == 1024 bytes
#define HASH_SIZE 128 // 128 * 4 * 4 == 2048 bytes
typedef struct base_command_hashmap_s base_command_hashmap_t;
@@ -26,11 +26,10 @@ struct base_command_hashmap_s
base_command_t *basecmd; // base command: cvar, alias or command
base_command_hashmap_t *next;
base_command_type_e type; // type for faster searching
char name[]; // key for searching
char name[1]; // key for searching
};
static base_command_hashmap_t *hashed_cmds[HASH_SIZE];
static poolhandle_t basecmd_pool;
#define BaseCmd_HashKey( x ) COM_HashKey( name, HASH_SIZE )
@@ -43,27 +42,11 @@ Find base command in bucket
*/
static base_command_hashmap_t *BaseCmd_FindInBucket( base_command_hashmap_t *bucket, base_command_type_e type, const char *name )
{
base_command_hashmap_t *i;
base_command_hashmap_t *i = bucket;
for( ; i && ( i->type != type || Q_stricmp( name, i->name ) ); // filter out
i = i->next );
for( i = bucket; i != NULL; i = i->next )
{
int cmp;
if( i->type != type )
continue;
cmp = Q_stricmp( i->name, name );
if( cmp < 0 )
continue;
if( cmp > 0 )
break;
return i;
}
return NULL;
return i;
}
/*
@@ -107,31 +90,27 @@ void BaseCmd_FindAll( const char *name, base_command_t **cmd, base_command_t **a
base_command_hashmap_t *base = BaseCmd_GetBucket( name );
base_command_hashmap_t *i = base;
ASSERT( cmd && alias && cvar );
*cmd = *alias = *cvar = NULL;
for( ; i; i = i->next )
{
int cmp = Q_stricmp( i->name, name );
if( cmp < 0 )
continue;
if( cmp > 0 )
break;
switch( i->type )
if( !Q_stricmp( i->name, name ) )
{
case HM_CMD:
*cmd = i->basecmd;
break;
case HM_CMDALIAS:
*alias = i->basecmd;
break;
case HM_CVAR:
*cvar = i->basecmd;
break;
default:
break;
switch( i->type )
{
case HM_CMD:
*cmd = i->basecmd;
break;
case HM_CMDALIAS:
*alias = i->basecmd;
break;
case HM_CVAR:
*cvar = i->basecmd;
break;
default: break;
}
}
}
}
@@ -149,14 +128,14 @@ void BaseCmd_Insert( base_command_type_e type, base_command_t *basecmd, const ch
uint hash = BaseCmd_HashKey( name );
size_t len = Q_strlen( name );
elem = Mem_Malloc( basecmd_pool, sizeof( base_command_hashmap_t ) + len + 1 );
elem = Z_Malloc( sizeof( base_command_hashmap_t ) + len );
elem->basecmd = basecmd;
elem->type = type;
Q_strncpy( elem->name, name, len + 1 );
// link the variable in alphanumerical order
for( cur = NULL, find = hashed_cmds[hash];
find && Q_stricmp( find->name, elem->name ) < 0;
find && Q_strcmp( find->name, elem->name ) < 0;
cur = find, find = find->next );
if( cur ) cur->next = elem;
@@ -177,23 +156,9 @@ void BaseCmd_Remove( base_command_type_e type, const char *name )
uint hash = BaseCmd_HashKey( name );
base_command_hashmap_t *i, *prev;
for( prev = NULL, i = hashed_cmds[hash]; i != NULL; prev = i, i = i->next )
{
int cmp;
if( i->type != type )
continue;
cmp = Q_stricmp( i->name, name );
if( cmp < 0 )
continue;
if( cmp > 0 )
i = NULL;
break;
}
for( prev = NULL, i = hashed_cmds[hash]; i &&
( Q_strcmp( i->name, name ) || i->type != type); // filter out
prev = i, i = i->next );
if( !i )
{
@@ -218,15 +183,9 @@ initialize base command hashmap system
*/
void BaseCmd_Init( void )
{
basecmd_pool = Mem_AllocPool( "BaseCmd" );
memset( hashed_cmds, 0, sizeof( hashed_cmds ) );
}
void BaseCmd_Shutdown( void )
{
Mem_FreePool( &basecmd_pool );
}
/*
============
BaseCmd_Stats_f

View File

@@ -32,7 +32,6 @@ typedef enum base_command_type
typedef void base_command_t;
void BaseCmd_Init( void );
void BaseCmd_Shutdown( void );
base_command_t *BaseCmd_Find( base_command_type_e type, const char *name );
void BaseCmd_FindAll( const char *name,
base_command_t **cmd, base_command_t **alias, base_command_t **cvar );

View File

@@ -46,7 +46,6 @@ static cmdalias_t *cmd_alias;
static uint cmd_condition;
static int cmd_condlevel;
static qboolean cmd_currentCommandIsPrivileged;
static poolhandle_t cmd_pool;
static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPrivileged );
@@ -433,7 +432,7 @@ static void Cmd_Alias_f( void )
{
if( !Q_strcmp( s, a->name ))
{
Mem_Free( a->value );
Z_Free( a->value );
break;
}
}
@@ -442,7 +441,7 @@ static void Cmd_Alias_f( void )
{
cmdalias_t *cur, *prev;
a = Mem_Malloc( cmd_pool, sizeof( cmdalias_t ));
a = Z_Malloc( sizeof( cmdalias_t ));
Q_strncpy( a->name, s, sizeof( a->name ));
@@ -470,7 +469,7 @@ static void Cmd_Alias_f( void )
}
Q_strncat( cmd, "\n", sizeof( cmd ));
a->value = copystringpool( cmd_pool, cmd );
a->value = copystring( cmd );
}
/*
@@ -530,7 +529,7 @@ struct cmd_s
char *name;
xcommand_t function;
int flags;
char desc[];
char *desc;
};
static int cmd_argc;
@@ -637,7 +636,7 @@ void Cmd_TokenizeString( const char *text )
// clear the args from the last string
for( i = 0; i < cmd_argc; i++ )
Mem_Free( cmd_argv[i] );
Z_Free( cmd_argv[i] );
cmd_argc = 0; // clear previous args
cmd_args = NULL;
@@ -671,7 +670,7 @@ void Cmd_TokenizeString( const char *text )
if( cmd_argc < MAX_CMD_TOKENS )
{
cmd_argv[cmd_argc] = copystringpool( cmd_pool, cmd_token );
cmd_argv[cmd_argc] = copystring( cmd_token );
cmd_argc++;
}
}
@@ -684,8 +683,7 @@ Cmd_AddCommandEx
*/
int Cmd_AddCommandEx( const char *cmd_name, xcommand_t function, const char *cmd_desc, int iFlags, const char *funcname )
{
cmd_t *cmd, *cur, *prev;
size_t desc_len;
cmd_t *cmd, *cur, *prev;
if( !COM_CheckString( cmd_name ))
{
@@ -709,8 +707,8 @@ int Cmd_AddCommandEx( const char *cmd_name, xcommand_t function, const char *cmd
// unfortunately, we lose original command this way
if( FBitSet( cmd->flags, CMD_OVERRIDABLE ))
{
desc_len = Q_strlen( cmd->desc ) + 1;
Q_strncpy( cmd->desc, cmd_desc, desc_len );
Mem_Free( cmd->desc );
cmd->desc = copystring( cmd_desc );
cmd->function = function;
cmd->flags = iFlags;
@@ -725,10 +723,9 @@ int Cmd_AddCommandEx( const char *cmd_name, xcommand_t function, const char *cmd
}
// use a small malloc to avoid zone fragmentation
desc_len = Q_strlen( cmd_desc ) + 1;
cmd = Mem_Malloc( cmd_pool, sizeof( cmd_t ) + desc_len );
cmd->name = copystringpool( cmd_pool, cmd_name );
Q_strncpy( cmd->desc, cmd_desc, desc_len );
cmd = Z_Malloc( sizeof( cmd_t ) );
cmd->name = copystring( cmd_name );
cmd->desc = copystring( cmd_desc );
cmd->function = function;
cmd->flags = iFlags;
@@ -775,6 +772,9 @@ void GAME_EXPORT Cmd_RemoveCommand( const char *cmd_name )
if( cmd->name )
Mem_Free( cmd->name );
if( cmd->desc )
Mem_Free( cmd->desc );
Mem_Free( cmd );
return;
}
@@ -1202,6 +1202,7 @@ void Cmd_Unlink( int group )
*prev = cmd->next;
if( cmd->name ) Mem_Free( cmd->name );
if( cmd->desc ) Mem_Free( cmd->desc );
Mem_Free( cmd );
count++;
@@ -1339,7 +1340,6 @@ Cmd_Init
*/
void Cmd_Init( void )
{
cmd_pool = Mem_AllocPool( "Console Commands" );
cmd_functions = NULL;
cmd_condition = 0;
cmd_alias = NULL;
@@ -1366,11 +1366,6 @@ void Cmd_Init( void )
#endif
}
void Cmd_Shutdown( void )
{
Mem_FreePool( &cmd_pool );
}
#if XASH_ENGINE_TESTS
#include "tests.h"

View File

@@ -76,14 +76,23 @@ XASH SPECIFIC - sort of hack that works only in Xash3D not in GoldSrc
#define HACKS_RELATED_HLMODS // some HL-mods works differently under Xash and can't be fixed without some hacks at least at current time
enum dev_level_e
enum
{
DEV_NONE = 0,
DEV_NORMAL,
DEV_EXTENDED
};
typedef enum instance_e
enum
{
D_INFO = 1, // "-dev 1", shows various system messages
D_WARN, // "-dev 2", shows not critical system warnings
D_ERROR, // "-dev 3", shows critical warnings
D_REPORT, // "-dev 4", special case for game reports
D_NOTE // "-dev 5", show system notifications for engine developers
};
typedef enum
{
HOST_NORMAL, // listen server, singleplayer
HOST_DEDICATED,
@@ -99,14 +108,14 @@ typedef enum instance_e
#include "com_model.h"
#include "com_strings.h"
#include "crtlib.h"
#define FSCALLBACK_OVERRIDE_OPEN
#define FSCALLBACK_OVERRIDE_LOADFILE
#define FSCALLBACK_OVERRIDE_MALLOC_LIKE
#include "fscallback.h"
#include "cvar.h"
#include "con_nprint.h"
#include "crclib.h"
#include "ref_api.h"
#define FSCALLBACK_OVERRIDE_OPEN
#define FSCALLBACK_OVERRIDE_LOADFILE
#define FSCALLBACK_OVERRIDE_MALLOC_LIKE
#include "fscallback.h"
// PERFORMANCE INFO
#define MIN_FPS 20.0f // host minimum fps value for maxfps.
@@ -137,11 +146,6 @@ typedef enum instance_e
#define MAX_STATIC_ENTITIES 32 // static entities that moved on the client when level is spawn
#endif
#define MAX_SERVERINFO_STRING 512 // server handles too many settings. expand to 1024?
#define MAX_PRINT_MSG 8192 // how many symbols can handle single call of Con_Printf or Con_DPrintf
#define MAX_TOKEN 2048 // parse token length
#define MAX_USERMSG_LENGTH 2048 // don't modify it's relies on a client-side definitions
#define GameState (&host.game)
#define FORCE_DRAW_VERSION_TIME 5.0 // draw version for 5 seconds
@@ -185,7 +189,7 @@ GAMEINFO stuff
internal shared gameinfo structure (readonly for engine parts)
========================================================================
*/
typedef enum host_status_e
typedef enum
{
HOST_INIT = 0, // initalize operations
HOST_FRAME, // host running
@@ -196,7 +200,7 @@ typedef enum host_status_e
HOST_CRASHED // an exception handler called
} host_status_t;
typedef enum host_state_e
typedef enum
{
STATE_RUNFRAME = 0,
STATE_LOAD_LEVEL,
@@ -205,7 +209,7 @@ typedef enum host_state_e
STATE_GAME_SHUTDOWN,
} host_state_t;
typedef struct game_status_e
typedef struct
{
host_state_t curstate;
host_state_t nextstate;
@@ -216,7 +220,7 @@ typedef struct game_status_e
qboolean newGame; // unload the server.dll before start a new map
} game_status_t;
typedef enum keydest_e
typedef enum
{
key_console = 0,
key_game,
@@ -224,7 +228,7 @@ typedef enum keydest_e
key_message
} keydest_t;
typedef enum rdtype_e
typedef enum
{
RD_NONE = 0,
RD_CLIENT,
@@ -234,7 +238,7 @@ typedef enum rdtype_e
#include "net_ws.h"
// console field
typedef struct field_e
typedef struct
{
string buffer;
int cursor;
@@ -252,7 +256,7 @@ typedef struct host_redirect_s
int lines;
} host_redirect_t;
typedef struct soundlist_e
typedef struct
{
char name[MAX_QPATH];
short entnum;
@@ -293,7 +297,7 @@ typedef struct host_parm_s
host_status_t status; // global host state
game_status_t game; // game manager
instance_t type; // running at
uint type; // running at
poolhandle_t mempool; // static mempool for misc allocations
poolhandle_t imagepool; // imagelib mempool
poolhandle_t soundpool; // soundlib mempool
@@ -428,7 +432,6 @@ int Cmd_Argc( void );
const char *Cmd_Args( void ) RETURNS_NONNULL;
const char *Cmd_Argv( int arg ) RETURNS_NONNULL;
void Cmd_Init( void );
void Cmd_Shutdown( void );
void Cmd_Unlink( int group );
int Cmd_AddCommandEx( const char *cmd_name, xcommand_t function, const char *cmd_desc, int flags, const char *funcname );
@@ -487,7 +490,7 @@ internal sound format
typically expanded to wav buffer
========================================================================
*/
typedef enum sndformat_e
typedef enum
{
WF_UNKNOWN = 0,
WF_PCMDATA,
@@ -498,7 +501,7 @@ typedef enum sndformat_e
} sndformat_t;
// wavdata output flags
typedef enum sndFlags_e
typedef enum
{
// wavdata->flags
SOUND_LOOPED = BIT( 0 ), // this is looped sound (contain cue markers)
@@ -508,29 +511,29 @@ typedef enum sndFlags_e
SOUND_RESAMPLE = BIT( 12 ), // resample sound to specified rate
} sndFlags_t;
typedef struct wavdata_s
typedef struct
{
size_t size; // for bounds checking
word rate; // num samples per second (e.g. 11025 - 11 khz)
byte width; // resolution - bum bits divided by 8 (8 bit is 1, 16 bit is 2)
byte channels; // num channels (1 - mono, 2 - stereo)
uint loopStart; // offset at this point sound will be looping while playing more than only once
uint samples; // total samplecount in wav
uint type; // compression type
uint flags; // misc sound flags
word rate; // num samples per second (e.g. 11025 - 11 khz)
byte width; // resolution - bum bits divided by 8 (8 bit is 1, 16 bit is 2)
byte channels; // num channels (1 - mono, 2 - stereo)
byte buffer[]; // sound buffer
byte *buffer; // sound buffer
size_t size; // for bounds checking
} wavdata_t;
//
// soundlib
//
typedef struct stream_s stream_t;
void Sound_Init( void );
void Sound_Shutdown( void );
void FS_FreeSound( wavdata_t *pack );
void FS_FreeStream( stream_t *stream );
wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size ) MALLOC_LIKE( FS_FreeSound, 1 ) WARN_UNUSED_RESULT;
stream_t *FS_OpenStream( const char *filename ) MALLOC_LIKE( FS_FreeStream, 1 ) WARN_UNUSED_RESULT;
wavdata_t *FS_StreamInfo( stream_t *stream );
int FS_ReadStream( stream_t *stream, int bytes, void *buffer );
int FS_SetStreamPos( stream_t *stream, int newpos );
int FS_GetStreamPos( stream_t *stream );
@@ -575,19 +578,11 @@ CLIENT / SERVER SYSTEMS
==============================================================
*/
#if !XASH_DEDICATED
void CL_Init( void );
void CL_Shutdown( void );
void Host_ClientBegin( void );
void Host_ClientFrame( void );
int CL_Active( void );
#else
static inline void CL_Init( void ) { }
static inline void CL_Shutdown( void ) { }
static inline void Host_ClientBegin( void ) { Cbuf_Execute(); }
static inline void Host_ClientFrame( void ) { }
static inline int CL_Active( void ) { return 0; }
#endif
void SV_Init( void );
void SV_Shutdown( const char *finalmsg );
@@ -625,7 +620,6 @@ int pfnNumberOfEntities( void );
int pfnIsInGame( void );
float pfnTime( void );
#define copystring( s ) _copystring( host.mempool, s, __FILE__, __LINE__ )
#define copystringpool( pool, s ) _copystring( pool, s, __FILE__, __LINE__ )
#define SV_CopyString( s ) _copystring( svgame.stringspool, s, __FILE__, __LINE__ )
#define freestring( s ) if( s != NULL ) { Mem_Free( s ); s = NULL; }
char *_copystring( poolhandle_t mempool, const char *s, const char *filename, int fileline );
@@ -676,7 +670,6 @@ int CSCR_WriteGameCVars( file_t *cfg, const char *scriptfilename );
//
// hpak.c
//
const char *COM_ResourceTypeFromIndex( int index );
void HPAK_Init( void );
qboolean HPAK_GetDataPointer( const char *filename, struct resource_s *pRes, byte **buffer, int *size );
qboolean HPAK_ResourceForHash( const char *filename, byte *hash, struct resource_s *pRes );
@@ -710,32 +703,13 @@ typedef enum connprotocol_e
struct physent_s;
struct sv_client_s;
typedef struct sizebuf_s sizebuf_t;
int SV_GetMaxClients( void );
#if !XASH_DEDICATED
qboolean CL_Initialized( void );
qboolean CL_IsInGame( void );
qboolean CL_IsInConsole( void );
qboolean CL_IsIntermission( void );
qboolean CL_DisableVisibility( void );
qboolean CL_IsRecordDemo( void );
qboolean CL_IsPlaybackDemo( void );
qboolean UI_CreditsActive( void );
int CL_GetMaxClients( void );
#else
static inline qboolean CL_Initialized( void ) { return false; }
static inline qboolean CL_IsInGame( void ) { return true; } // always true for dedicated
static inline qboolean CL_IsInConsole( void ) { return false; }
static inline qboolean CL_IsIntermission( void ) { return false; }
static inline qboolean CL_DisableVisibility( void ) { return false; }
static inline qboolean CL_IsRecordDemo( void ) { return false; }
static inline qboolean CL_IsPlaybackDemo( void ) { return false; }
static inline qboolean UI_CreditsActive( void ) { return false; }
static inline int CL_GetMaxClients( void ) { return SV_GetMaxClients(); }
#endif
qboolean CL_Initialized( void );
char *CL_Userinfo( void );
void CL_CharEvent( int key );
qboolean CL_DisableVisibility( void );
byte *COM_LoadFile( const char *filename, int usehunk, int *pLength ) MALLOC_LIKE( free, 1 );
struct cmd_s *Cmd_GetFirstFunctionHandle( void );
struct cmd_s *Cmd_GetNextFunctionHandle( struct cmd_s *cmd );
@@ -753,7 +727,13 @@ const char *CL_MsgInfo( int cmd );
void SV_DrawDebugTriangles( void );
void SV_DrawOrthoTriangles( void );
double CL_GetDemoFramerate( void );
qboolean UI_CreditsActive( void );
void CL_StopPlayback( void );
int CL_GetMaxClients( void );
int SV_GetMaxClients( void );
qboolean CL_IsRecordDemo( void );
qboolean CL_IsTimeDemo( void );
qboolean CL_IsPlaybackDemo( void );
qboolean SV_Initialized( void );
void CL_ProcessFile( qboolean successfully_received, const char *filename );
int SV_GetSaveComment( const char *savename, char *comment );
@@ -866,6 +846,13 @@ void V_CheckGamma( void );
void V_CheckGammaEnd( void );
intptr_t V_GetGammaPtr( int parm );
//
// identification.c
//
void ID_Init( void );
const char *ID_GetMD5( void );
void GAME_EXPORT ID_SetCustomClientID( const char *id );
//
// masterlist.c
//

View File

@@ -19,7 +19,6 @@ GNU General Public License for more details.
#include "eiface.h" // ARRAYSIZE
static convar_t *cvar_vars = NULL; // head of list
static poolhandle_t cvar_pool;
CVAR_DEFINE_AUTO( cmd_scripting, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED, "enable simple condition checking and variable operations" );
typedef struct cvar_filter_quirks_s
@@ -433,7 +432,7 @@ convar_t *Cvar_Get( const char *name, const char *value, int flags, const char *
{
// directly set value
freestring( var->string );
var->string = copystringpool( cvar_pool, value );
var->string = copystring( value );
var->value = Q_atof( var->string );
SetBits( var->flags, flags );
@@ -453,18 +452,18 @@ convar_t *Cvar_Get( const char *name, const char *value, int flags, const char *
Con_Reportf( "%s change description from %s to %s\n", var->name, var->desc, var_desc );
// update description if needs
freestring( var->desc );
var->desc = copystringpool( cvar_pool, var_desc );
var->desc = copystring( var_desc );
}
return var;
}
// allocate a new cvar
var = Mem_Malloc( cvar_pool, sizeof( *var ));
var->name = copystringpool( cvar_pool, name );
var->string = copystringpool( cvar_pool, value );
var->def_string = copystringpool( cvar_pool, value );
var->desc = copystringpool( cvar_pool, var_desc );
var = Z_Malloc( sizeof( *var ));
var->name = copystring( name );
var->string = copystring( value );
var->def_string = copystring( value );
var->desc = copystring( var_desc );
var->value = Q_atof( var->string );
var->flags = flags|FCVAR_ALLOCATED;
@@ -550,7 +549,7 @@ void Cvar_RegisterVariable( convar_t *var )
if( FBitSet( var->flags, FCVAR_EXTENDED ))
var->def_string = var->string; // just swap pointers
var->string = copystringpool( cvar_pool, var->string );
var->string = copystring( var->string );
var->value = Q_atof( var->string );
// find the supposed position in chain (alphanumerical order)
@@ -680,7 +679,7 @@ static convar_t *Cvar_Set2( const char *var_name, const char *value )
// and finally changed the cvar itself
freestring( var->string );
var->string = copystringpool( cvar_pool, pszValue );
var->string = copystring( pszValue );
var->value = Q_atof( var->string );
// tell engine about changes
@@ -739,7 +738,7 @@ void GAME_EXPORT Cvar_DirectSet( convar_t *var, const char *value )
// and finally changed the cvar itself
freestring( var->string );
var->string = copystringpool( cvar_pool, pszValue );
var->string = copystring( pszValue );
var->value = Q_atof( var->string );
// tell engine about changes
@@ -782,7 +781,7 @@ void Cvar_FullSet( const char *var_name, const char *value, int flags )
}
freestring( var->string );
var->string = copystringpool( cvar_pool, value );
var->string = copystring( value );
var->value = Q_atof( var->string );
SetBits( var->flags, flags );
@@ -1190,7 +1189,6 @@ static void Cvar_List_f( void )
for( var = cvar_vars; var; var = var->next )
{
char value[MAX_VA_STRING];
char *p;
if( var->name[0] == '@' )
continue; // never shows system cvars
@@ -1198,9 +1196,7 @@ static void Cvar_List_f( void )
if( match && !Q_strnicmpext( match, var->name, matchlen ))
continue;
p = Q_strchr( var->string, '^' );
if( IsColorString( p ))
if( Q_colorstr( var->string ))
Q_snprintf( value, sizeof( value ), "\"%s\"", var->string );
else Q_snprintf( value, sizeof( value ), "\"^2%s^7\"", var->string );
@@ -1261,7 +1257,7 @@ pending_cvar_t *Cvar_PrepareToUnlink( int group )
continue;
namelen = Q_strlen( cv->name ) + 1;
p = Mem_Malloc( cvar_pool, sizeof( *list ) + namelen );
p = Mem_Malloc( host.mempool, sizeof( *list ) + namelen );
p->next = NULL;
p->cv_cur = cv;
p->cv_next = cv->next;
@@ -1337,7 +1333,6 @@ Reads in all archived cvars
*/
void Cvar_Init( void )
{
cvar_pool = Mem_AllocPool( "Console Variables" );
cvar_vars = NULL;
cvar_active_filter_quirks = NULL;
Cvar_RegisterVariable( &cmd_scripting );
@@ -1350,11 +1345,6 @@ void Cvar_Init( void )
Cmd_AddCommand( "cvarlist", Cvar_List_f, "display all console variables beginning with the specified prefix" );
}
void Cvar_Shutdown( void )
{
Mem_FreePool( &cvar_pool );
}
/*
============
Cvar_PostFSInit

View File

@@ -30,8 +30,6 @@ typedef struct pending_cvar_s
char cv_name[];
} pending_cvar_t;
typedef void (*setpair_t)( const char *key, const void *value, const void *buffer, void *numpairs );
cvar_t *Cvar_GetList( void );
#define Cvar_FindVar( name ) Cvar_FindVarExt( name, 0 )
convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group );
@@ -54,7 +52,6 @@ void Cvar_Reset( const char *var_name );
void Cvar_SetCheatState( void );
qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged );
void Cvar_Init( void );
void Cvar_Shutdown( void );
void Cvar_PostFSInit( void );
void Cvar_Unlink( int group );

View File

@@ -49,6 +49,52 @@ const char *CL_MsgInfo( int cmd )
return sz;
}
int GAME_EXPORT CL_Active( void )
{
return false;
}
qboolean CL_Initialized( void )
{
return false;
}
qboolean CL_IsInGame( void )
{
return true; // always active for dedicated servers
}
qboolean CL_IsInConsole( void )
{
return false;
}
qboolean CL_IsIntermission( void )
{
return false;
}
qboolean CL_IsPlaybackDemo( void )
{
return false;
}
qboolean CL_IsRecordDemo( void )
{
return false;
}
qboolean CL_DisableVisibility( void )
{
return false;
}
void CL_Init( void )
{
}
void Key_Init( void )
{
@@ -84,6 +130,16 @@ void CL_WriteMessageHistory( void )
}
void Host_ClientBegin( void )
{
Cbuf_Execute();
}
void Host_ClientFrame( void )
{
}
void Host_InputFrame( void )
{
}
@@ -103,6 +159,11 @@ void GAME_EXPORT S_StopSound(int entnum, int channel, const char *soundname)
}
int GAME_EXPORT CL_GetMaxClients( void )
{
return 0;
}
void IN_TouchInitConfig( void )
{
@@ -113,6 +174,11 @@ void CL_Disconnect( void )
}
void CL_Shutdown( void )
{
}
void R_ClearStaticEntities( void )
{
@@ -123,6 +189,11 @@ void Host_Credits( void )
}
qboolean UI_CreditsActive( void )
{
return false;
}
void S_StopBackgroundTrack( void )
{
@@ -133,6 +204,11 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
}
int S_GetCurrentDynamicSounds( soundlist_t *pout, int size )
{
return 0;
}
void S_StopAllSounds( qboolean ambient )
{

View File

@@ -183,23 +183,14 @@ static qboolean FS_DetermineRootDirectory( char *out, size_t size )
#elif XASH_PSVITA
if( PSVita_GetBasePath( out, size ))
return true;
Sys_Error( "couldn't find %s data directory", XASH_ENGINE_NAME );
Sys_Error( "couldn't find Xash3D data directory" );
return false;
#elif ( XASH_SDL == 2 ) && !XASH_NSWITCH // GetBasePath not impl'd in switch-sdl2
path = SDL_GetBasePath();
#if XASH_APPLE
if( path != NULL && Q_stristr( path, ".app" ))
{
SDL_free((void *)path );
path = SDL_GetPrefPath( NULL, XASH_ENGINE_NAME );
}
#endif
if( path != NULL )
{
Q_strncpy( out, path, size );
SDL_free((void *)path );
SDL_free(( void *)path );
return true;
}

View File

@@ -201,6 +201,7 @@ static void Sys_PrintUsage( const char *exename )
O("-daemonize ", "run engine as a daemon")
#endif
#if XASH_SDL == 2
O("-sdl_joy_old_api ","use SDL legacy joystick API")
O("-sdl_renderer <n> ","use alternative SDL_Renderer for software")
#endif // XASH_SDL
#if XASH_ANDROID && !XASH_SDL
@@ -1130,7 +1131,7 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
#if XASH_DEDICATED
Platform_SetupSigtermHandling();
#endif
Platform_Init( Host_IsDedicated( ) || developer >= DEV_EXTENDED, basedir );
Platform_Init( Host_IsDedicated( ) || developer >= DEV_EXTENDED );
FS_Init( basedir );
Sys_InitLog();
@@ -1255,6 +1256,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
CL_Init();
HTTP_Init();
ID_Init();
SoundList_Init();
if( Host_IsDedicated( ))
@@ -1398,10 +1400,6 @@ void Host_ShutdownWithReason( const char *reason )
Host_FreeCommon();
Platform_Shutdown();
BaseCmd_Shutdown();
Cmd_Shutdown();
Cvar_Shutdown();
// must be last, console uses this
Mem_FreePool( &host.mempool );

View File

@@ -38,7 +38,7 @@ static void HPAK_MaxSize_f( void )
Con_Printf( S_ERROR "hpk_maxsize is deprecated, use hpk_max_size\n" );
}
const char *COM_ResourceTypeFromIndex( int type )
static const char *HPAK_TypeFromIndex( int type )
{
switch( type )
{
@@ -104,7 +104,7 @@ static void HPAK_CreatePak( const char *filename, resource_t *pResource, byte *p
string pakname;
byte md5[16];
file_t *fout;
MD5Context_t ctx = { 0 };
MD5Context_t ctx;
if( !COM_CheckString( filename ))
return;
@@ -125,6 +125,7 @@ static void HPAK_CreatePak( const char *filename, resource_t *pResource, byte *p
}
// let's hash it.
memset( &ctx, 0, sizeof( MD5Context_t ));
MD5Init( &ctx );
if( pData == NULL )
@@ -213,7 +214,7 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource,
file_t *file_src;
file_t *file_dst;
byte md5[16];
MD5Context_t ctx = { 0 };
MD5Context_t ctx;
if( pData == NULL && pFile == NULL )
return;
@@ -225,6 +226,7 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource,
}
// hash it
memset( &ctx, 0, sizeof( MD5Context_t ));
MD5Init( &ctx );
if( !pData )
@@ -461,7 +463,7 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
if( !quiet )
{
Con_Printf( "%i: %s %s %s: ", i, COM_ResourceTypeFromIndex( pRes->type ),
Con_Printf( "%i: %s %s %s: ", i, HPAK_TypeFromIndex( pRes->type ),
Q_pretifymem( pRes->nDownloadSize, 2 ), pRes->szFileName );
}
@@ -942,7 +944,7 @@ static void HPAK_List_f( void )
{
entry = &directory.entries[nCurrent];
COM_FileBase( entry->resource.szFileName, lumpname, sizeof( lumpname ));
type = COM_ResourceTypeFromIndex( entry->resource.type );
type = HPAK_TypeFromIndex( entry->resource.type );
size = Q_memprint( entry->resource.nDownloadSize );
Con_Printf( "%i: %10s %s %s\n : %s\n", nCurrent + 1, type, size, lumpname, MD5_Print( entry->resource.rgucMD5_hash ));
@@ -1037,7 +1039,7 @@ static void HPAK_Extract_f( void )
continue;
COM_FileBase( entry->resource.szFileName, lumpname, sizeof( lumpname ) );
type = COM_ResourceTypeFromIndex( entry->resource.type );
type = HPAK_TypeFromIndex( entry->resource.type );
size = Q_memprint( entry->resource.nDownloadSize );
Con_Printf( "Extracting %i: %10s %s %s\n", nCurrent + 1, type, size, lumpname );

View File

@@ -611,7 +611,7 @@ void GAME_EXPORT ID_SetCustomClientID( const char *id )
void ID_Init( void )
{
MD5Context_t hash = { 0 };
MD5Context_t hash = {0};
byte md5[16];
int i;
@@ -632,7 +632,7 @@ void ID_Init( void )
#elif XASH_WIN32
{
CHAR szBuf[MAX_PATH];
ID_GetKeyData( HKEY_CURRENT_USER, "Software\\"XASH_ENGINE_NAME"\\", "xash_id", szBuf, MAX_PATH );
ID_GetKeyData( HKEY_CURRENT_USER, "Software\\Xash3D\\", "xash_id", szBuf, MAX_PATH );
sscanf(szBuf, "%016"PRIX64, &id);
id ^= SYSTEM_XOR_MASK;
@@ -686,7 +686,7 @@ void ID_Init( void )
{
CHAR Buf[MAX_PATH];
sprintf( Buf, "%016"PRIX64, id^SYSTEM_XOR_MASK );
ID_SetKeyData( HKEY_CURRENT_USER, "Software\\"XASH_ENGINE_NAME"\\", REG_SZ, "xash_id", Buf, Q_strlen(Buf) );
ID_SetKeyData( HKEY_CURRENT_USER, "Software\\Xash3D\\", REG_SZ, "xash_id", Buf, Q_strlen(Buf) );
}
#else
{

View File

@@ -28,20 +28,12 @@ Image_LoadPAL
qboolean Image_LoadPAL( const char *name, const byte *buffer, fs_offset_t filesize )
{
int rendermode = LUMP_NORMAL;
byte pal[768];
if( filesize > sizeof( pal ))
if( filesize != 768 )
{
Con_DPrintf( S_ERROR "%s: (%s) have invalid size (%li should be less or equal than %d)\n", __func__, name, (long)filesize, sizeof( pal ));
Con_DPrintf( S_ERROR "%s: (%s) have invalid size (%li should be %d)\n", __func__, name, (long)filesize, 768 );
return false;
}
else if( filesize < sizeof( pal ) && buffer != NULL )
{
// palette might be truncated, fill it with zeros
memset( pal, 0, sizeof( pal ));
memcpy( pal, buffer, filesize );
buffer = pal;
}
if( name[0] == '#' )
{

View File

@@ -482,7 +482,7 @@ static int Mod_LoadTextureFromWadList( wadlist_t *list, const char *name, rgbdat
return -1;
}
static fs_offset_t Mod_CalculateMipTexSize( const mip_t *mt, qboolean palette )
static fs_offset_t Mod_CalculateMipTexSize( mip_t *mt, qboolean palette )
{
if( !mt )
return 0;
@@ -2359,7 +2359,7 @@ static qboolean Mod_SearchForTextureReplacement( char *out, size_t size, const c
return false;
}
static void Mod_InitSkyClouds( model_t *mod, const mip_t *mt, texture_t *tx, qboolean custom_palette )
static void Mod_InitSkyClouds( model_t *mod, mip_t *mt, texture_t *tx, qboolean custom_palette )
{
#if !XASH_DEDICATED
rgbdata_t r_temp, *r_sky;
@@ -2516,6 +2516,9 @@ done:
static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureIndex )
{
texture_t *texture = NULL;
mip_t *mipTex = NULL;
qboolean usesCustomPalette = false;
uint32_t txFlags = 0;
char texpath[MAX_VA_STRING];
char safemtname[16]; // only for external textures
@@ -2523,10 +2526,12 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
// don't load texture data on dedicated server, as there is no renderer.
// but count the wadusage for automatic precache
texture_t *texture = mod->textures[textureIndex];
const mip_t *mipTex = Mod_GetMipTexForTexture( bmod, textureIndex );
const qboolean usesCustomPalette = Mod_CalcMipTexUsesCustomPalette( mod, bmod, textureIndex );
const qboolean iswater = Mod_LooksLikeWaterTexture( mipTex->name );
//
// FIXME: for ENGINE_IMPROVED_LINETRACE we need to load textures on server too
// but there is no facility for this yet
texture = mod->textures[textureIndex];
mipTex = Mod_GetMipTexForTexture( bmod, textureIndex );
usesCustomPalette = Mod_CalcMipTexUsesCustomPalette( mod, bmod, textureIndex );
// check for multi-layered sky texture (quake1 specific)
if( bmod->isworld && Q_strncmp( mipTex->name, "sky", 3 ) == 0 && ( mipTex->width / mipTex->height ) == 2 )
@@ -2535,13 +2540,11 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
return;
}
// FIXME: for ENGINE_IMPROVED_LINETRACE we need to load textures on server too
// but there is no facility for this yet
if( FBitSet( host.features, ENGINE_IMPROVED_LINETRACE ) && mipTex->name[0] == '{' )
SetBits( txFlags, TF_KEEP_SOURCE ); // Paranoia2 texture alpha-tracing
// check if this is water to keep the source texture and expand it to RGBA (so ripple effect works)
if( iswater )
if( Mod_LooksLikeWaterTexture( mipTex->name ))
SetBits( txFlags, TF_KEEP_SOURCE | TF_EXPAND_SOURCE );
// Texture loading order:
@@ -2606,13 +2609,8 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
texture->gl_texturenum = R_GetBuiltinTexture( REF_DEFAULT_TEXTURE );
}
texture->fb_texturenum = 0;
// Check for luma texture
// a1ba: ignore for water because fb_texturenum will be used to store ripple texture
if( iswater )
return;
texture->fb_texturenum = 0;
if( load_external ) // external textures will not have TF_HAS_LUMA flag because it set only from WAD images loader
{
if( Mod_SearchForTextureReplacement( texpath, sizeof( texpath ), mod->name, safemtname, "_luma" ))

View File

@@ -868,7 +868,7 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded )
mod->type = mod_studio;
phdr = R_StudioLoadHeader( mod, buffer );
if( !phdr || phdr->length < sizeof( studiohdr_t )) // garbage value in length
if( !phdr )
return; // bad model
#if !XASH_DEDICATED

View File

@@ -258,7 +258,7 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
{
char tempname[MAX_QPATH];
fs_offset_t length = 0;
qboolean loaded, loaded2 = false;
qboolean loaded;
byte *buf;
model_info_t *p;
@@ -279,7 +279,7 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
buf = FS_LoadFile( tempname, &length, false );
if( !buf || length < sizeof( uint ))
if( !buf )
{
memset( mod, 0, sizeof( model_t ));
@@ -329,12 +329,11 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
// let the server.dll load custom data
svgame.physFuncs.Mod_ProcessUserData( mod, true, buf );
}
loaded2 = true;
}
#if !XASH_DEDICATED
else
{
loaded2 = ref.dllFuncs.Mod_ProcessRenderData( mod, true, buf );
loaded = ref.dllFuncs.Mod_ProcessRenderData( mod, true, buf );
}
#endif
}
@@ -346,7 +345,7 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
hdr->pposeverts = NULL;
}
if( !loaded || !loaded2 )
if( !loaded )
{
Mod_FreeModel( mod );
Mem_Free( buf );
@@ -611,41 +610,3 @@ void Mod_NeedCRC( const char *name, qboolean needCRC )
if( needCRC ) SetBits( p->flags, FCRC_SHOULD_CHECKSUM );
else ClearBits( p->flags, FCRC_SHOULD_CHECKSUM );
}
#if XASH_ENGINE_TESTS
static const uint8_t *fuzz_data;
static size_t fuzz_size;
static byte *Fuzz_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly )
{
byte *buf = Mem_Malloc( host.mempool, fuzz_size );
memcpy( buf, fuzz_data, fuzz_size );
*filesizeptr = fuzz_size;
return buf;
}
int EXPORT Fuzz_Mod_LoadModel( const uint8_t *Data, size_t Size );
int EXPORT Fuzz_Mod_LoadModel( const uint8_t *Data, size_t Size )
{
model_t mod = { .name = "test", .needload = NL_NEEDS_LOADED };
Memory_Init();
host.type = HOST_DEDICATED;
host.mempool = Mem_AllocPool( "fuzzing pool" );
fuzz_data = Data;
fuzz_size = Size;
refState.draw_surfaces = NULL;
g_fsapi.LoadFile = Fuzz_LoadFile;
if( Mod_LoadModel( &mod, false ) && mod.mempool )
Mem_FreePool( &mod.mempool );
Mem_FreePool( &host.mempool );
return 0;
}
#endif // XASH_ENGINE_TESTS

View File

@@ -18,177 +18,11 @@ GNU General Public License for more details.
#include "net_buffer.h"
#include "xash3d_mathlib.h"
static const uint32_t BitWriteMasks[32][32] =
{ {
0xfffffffe, 0xfffffffc, 0xfffffff8, 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80, 0xffffff00,
0xfffffe00, 0xfffffc00, 0xfffff800, 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000,
0xfffe0000, 0xfffc0000, 0xfff80000, 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, 0xff000000,
0xfe000000, 0xfc000000, 0xf8000000, 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000, 0x00000000,
}, {
0xfffffffd, 0xfffffff9, 0xfffffff1, 0xffffffe1, 0xffffffc1, 0xffffff81, 0xffffff01, 0xfffffe01,
0xfffffc01, 0xfffff801, 0xfffff001, 0xffffe001, 0xffffc001, 0xffff8001, 0xffff0001, 0xfffe0001,
0xfffc0001, 0xfff80001, 0xfff00001, 0xffe00001, 0xffc00001, 0xff800001, 0xff000001, 0xfe000001,
0xfc000001, 0xf8000001, 0xf0000001, 0xe0000001, 0xc0000001, 0x80000001, 0x00000001, 0x00000001,
}, {
0xfffffffb, 0xfffffff3, 0xffffffe3, 0xffffffc3, 0xffffff83, 0xffffff03, 0xfffffe03, 0xfffffc03,
0xfffff803, 0xfffff003, 0xffffe003, 0xffffc003, 0xffff8003, 0xffff0003, 0xfffe0003, 0xfffc0003,
0xfff80003, 0xfff00003, 0xffe00003, 0xffc00003, 0xff800003, 0xff000003, 0xfe000003, 0xfc000003,
0xf8000003, 0xf0000003, 0xe0000003, 0xc0000003, 0x80000003, 0x00000003, 0x00000003, 0x00000003,
}, {
0xfffffff7, 0xffffffe7, 0xffffffc7, 0xffffff87, 0xffffff07, 0xfffffe07, 0xfffffc07, 0xfffff807,
0xfffff007, 0xffffe007, 0xffffc007, 0xffff8007, 0xffff0007, 0xfffe0007, 0xfffc0007, 0xfff80007,
0xfff00007, 0xffe00007, 0xffc00007, 0xff800007, 0xff000007, 0xfe000007, 0xfc000007, 0xf8000007,
0xf0000007, 0xe0000007, 0xc0000007, 0x80000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007,
}, {
0xffffffef, 0xffffffcf, 0xffffff8f, 0xffffff0f, 0xfffffe0f, 0xfffffc0f, 0xfffff80f, 0xfffff00f,
0xffffe00f, 0xffffc00f, 0xffff800f, 0xffff000f, 0xfffe000f, 0xfffc000f, 0xfff8000f, 0xfff0000f,
0xffe0000f, 0xffc0000f, 0xff80000f, 0xff00000f, 0xfe00000f, 0xfc00000f, 0xf800000f, 0xf000000f,
0xe000000f, 0xc000000f, 0x8000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f,
}, {
0xffffffdf, 0xffffff9f, 0xffffff1f, 0xfffffe1f, 0xfffffc1f, 0xfffff81f, 0xfffff01f, 0xffffe01f,
0xffffc01f, 0xffff801f, 0xffff001f, 0xfffe001f, 0xfffc001f, 0xfff8001f, 0xfff0001f, 0xffe0001f,
0xffc0001f, 0xff80001f, 0xff00001f, 0xfe00001f, 0xfc00001f, 0xf800001f, 0xf000001f, 0xe000001f,
0xc000001f, 0x8000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f,
}, {
0xffffffbf, 0xffffff3f, 0xfffffe3f, 0xfffffc3f, 0xfffff83f, 0xfffff03f, 0xffffe03f, 0xffffc03f,
0xffff803f, 0xffff003f, 0xfffe003f, 0xfffc003f, 0xfff8003f, 0xfff0003f, 0xffe0003f, 0xffc0003f,
0xff80003f, 0xff00003f, 0xfe00003f, 0xfc00003f, 0xf800003f, 0xf000003f, 0xe000003f, 0xc000003f,
0x8000003f, 0x0000003f, 0x0000003f, 0x0000003f, 0x0000003f, 0x0000003f, 0x0000003f, 0x0000003f,
}, {
0xffffff7f, 0xfffffe7f, 0xfffffc7f, 0xfffff87f, 0xfffff07f, 0xffffe07f, 0xffffc07f, 0xffff807f,
0xffff007f, 0xfffe007f, 0xfffc007f, 0xfff8007f, 0xfff0007f, 0xffe0007f, 0xffc0007f, 0xff80007f,
0xff00007f, 0xfe00007f, 0xfc00007f, 0xf800007f, 0xf000007f, 0xe000007f, 0xc000007f, 0x8000007f,
0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f,
}, {
0xfffffeff, 0xfffffcff, 0xfffff8ff, 0xfffff0ff, 0xffffe0ff, 0xffffc0ff, 0xffff80ff, 0xffff00ff,
0xfffe00ff, 0xfffc00ff, 0xfff800ff, 0xfff000ff, 0xffe000ff, 0xffc000ff, 0xff8000ff, 0xff0000ff,
0xfe0000ff, 0xfc0000ff, 0xf80000ff, 0xf00000ff, 0xe00000ff, 0xc00000ff, 0x800000ff, 0x000000ff,
0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
}, {
0xfffffdff, 0xfffff9ff, 0xfffff1ff, 0xffffe1ff, 0xffffc1ff, 0xffff81ff, 0xffff01ff, 0xfffe01ff,
0xfffc01ff, 0xfff801ff, 0xfff001ff, 0xffe001ff, 0xffc001ff, 0xff8001ff, 0xff0001ff, 0xfe0001ff,
0xfc0001ff, 0xf80001ff, 0xf00001ff, 0xe00001ff, 0xc00001ff, 0x800001ff, 0x000001ff, 0x000001ff,
0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff,
}, {
0xfffffbff, 0xfffff3ff, 0xffffe3ff, 0xffffc3ff, 0xffff83ff, 0xffff03ff, 0xfffe03ff, 0xfffc03ff,
0xfff803ff, 0xfff003ff, 0xffe003ff, 0xffc003ff, 0xff8003ff, 0xff0003ff, 0xfe0003ff, 0xfc0003ff,
0xf80003ff, 0xf00003ff, 0xe00003ff, 0xc00003ff, 0x800003ff, 0x000003ff, 0x000003ff, 0x000003ff,
0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff,
}, {
0xfffff7ff, 0xffffe7ff, 0xffffc7ff, 0xffff87ff, 0xffff07ff, 0xfffe07ff, 0xfffc07ff, 0xfff807ff,
0xfff007ff, 0xffe007ff, 0xffc007ff, 0xff8007ff, 0xff0007ff, 0xfe0007ff, 0xfc0007ff, 0xf80007ff,
0xf00007ff, 0xe00007ff, 0xc00007ff, 0x800007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff,
0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff,
}, {
0xffffefff, 0xffffcfff, 0xffff8fff, 0xffff0fff, 0xfffe0fff, 0xfffc0fff, 0xfff80fff, 0xfff00fff,
0xffe00fff, 0xffc00fff, 0xff800fff, 0xff000fff, 0xfe000fff, 0xfc000fff, 0xf8000fff, 0xf0000fff,
0xe0000fff, 0xc0000fff, 0x80000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff,
0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff,
}, {
0xffffdfff, 0xffff9fff, 0xffff1fff, 0xfffe1fff, 0xfffc1fff, 0xfff81fff, 0xfff01fff, 0xffe01fff,
0xffc01fff, 0xff801fff, 0xff001fff, 0xfe001fff, 0xfc001fff, 0xf8001fff, 0xf0001fff, 0xe0001fff,
0xc0001fff, 0x80001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff,
0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff,
}, {
0xffffbfff, 0xffff3fff, 0xfffe3fff, 0xfffc3fff, 0xfff83fff, 0xfff03fff, 0xffe03fff, 0xffc03fff,
0xff803fff, 0xff003fff, 0xfe003fff, 0xfc003fff, 0xf8003fff, 0xf0003fff, 0xe0003fff, 0xc0003fff,
0x80003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff,
0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff,
}, {
0xffff7fff, 0xfffe7fff, 0xfffc7fff, 0xfff87fff, 0xfff07fff, 0xffe07fff, 0xffc07fff, 0xff807fff,
0xff007fff, 0xfe007fff, 0xfc007fff, 0xf8007fff, 0xf0007fff, 0xe0007fff, 0xc0007fff, 0x80007fff,
0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff,
0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff,
}, {
0xfffeffff, 0xfffcffff, 0xfff8ffff, 0xfff0ffff, 0xffe0ffff, 0xffc0ffff, 0xff80ffff, 0xff00ffff,
0xfe00ffff, 0xfc00ffff, 0xf800ffff, 0xf000ffff, 0xe000ffff, 0xc000ffff, 0x8000ffff, 0x0000ffff,
0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff,
0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff,
}, {
0xfffdffff, 0xfff9ffff, 0xfff1ffff, 0xffe1ffff, 0xffc1ffff, 0xff81ffff, 0xff01ffff, 0xfe01ffff,
0xfc01ffff, 0xf801ffff, 0xf001ffff, 0xe001ffff, 0xc001ffff, 0x8001ffff, 0x0001ffff, 0x0001ffff,
0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff,
0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff,
}, {
0xfffbffff, 0xfff3ffff, 0xffe3ffff, 0xffc3ffff, 0xff83ffff, 0xff03ffff, 0xfe03ffff, 0xfc03ffff,
0xf803ffff, 0xf003ffff, 0xe003ffff, 0xc003ffff, 0x8003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff,
0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff,
0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff,
}, {
0xfff7ffff, 0xffe7ffff, 0xffc7ffff, 0xff87ffff, 0xff07ffff, 0xfe07ffff, 0xfc07ffff, 0xf807ffff,
0xf007ffff, 0xe007ffff, 0xc007ffff, 0x8007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff,
0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff,
0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff,
}, {
0xffefffff, 0xffcfffff, 0xff8fffff, 0xff0fffff, 0xfe0fffff, 0xfc0fffff, 0xf80fffff, 0xf00fffff,
0xe00fffff, 0xc00fffff, 0x800fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff,
0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff,
0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff,
}, {
0xffdfffff, 0xff9fffff, 0xff1fffff, 0xfe1fffff, 0xfc1fffff, 0xf81fffff, 0xf01fffff, 0xe01fffff,
0xc01fffff, 0x801fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff,
0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff,
0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff,
}, {
0xffbfffff, 0xff3fffff, 0xfe3fffff, 0xfc3fffff, 0xf83fffff, 0xf03fffff, 0xe03fffff, 0xc03fffff,
0x803fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff,
0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff,
0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff,
}, {
0xff7fffff, 0xfe7fffff, 0xfc7fffff, 0xf87fffff, 0xf07fffff, 0xe07fffff, 0xc07fffff, 0x807fffff,
0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff,
0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff,
0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff,
}, {
0xfeffffff, 0xfcffffff, 0xf8ffffff, 0xf0ffffff, 0xe0ffffff, 0xc0ffffff, 0x80ffffff, 0x00ffffff,
0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff,
0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff,
0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff,
}, {
0xfdffffff, 0xf9ffffff, 0xf1ffffff, 0xe1ffffff, 0xc1ffffff, 0x81ffffff, 0x01ffffff, 0x01ffffff,
0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
}, {
0xfbffffff, 0xf3ffffff, 0xe3ffffff, 0xc3ffffff, 0x83ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
}, {
0xf7ffffff, 0xe7ffffff, 0xc7ffffff, 0x87ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff,
0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff,
0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff,
0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff,
}, {
0xefffffff, 0xcfffffff, 0x8fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff,
0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff,
0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff,
0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff,
}, {
0xdfffffff, 0x9fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff,
0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff,
0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff,
0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff,
}, {
0xbfffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff,
0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff,
0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff,
0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff,
}, {
0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
} };
static const uint32_t ExtraMasks[32] =
{
0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
};
// precalculated bit masks for WriteUBitLong.
// Using these tables instead of doing the calculations
// gives a 33% speedup in WriteUBitLong.
static uint32_t BitWriteMasks[32][33];
static uint32_t ExtraMasks[32];
const char *const svc_strings[svc_lastmsg+1] =
{
"svc_bad",
@@ -298,41 +132,65 @@ const char *const svc_quake_strings[svc_lastmsg+1] =
[svc_fog] = "svc_quake_fog",
};
void MSG_InitMasks( void )
{
uint startbit, endbit;
uint maskBit, nBitsLeft;
for( startbit = 0; startbit < 32; startbit++ )
{
for( nBitsLeft = 0; nBitsLeft < 33; nBitsLeft++ )
{
endbit = startbit + nBitsLeft;
BitWriteMasks[startbit][nBitsLeft] = (uint)BIT( startbit ) - 1;
if( endbit < 32 ) BitWriteMasks[startbit][nBitsLeft] |= ~((uint)BIT( endbit ) - 1 );
}
}
for( maskBit = 0; maskBit < 32; maskBit++ )
ExtraMasks[maskBit] = (uint)BIT( maskBit ) - 1;
}
void MSG_WriteUBitLong( sizebuf_t *sb, uint curData, int numbits )
{
int nBitsLeft = numbits;
int iCurBit = sb->iCurBit;
uint iDWord = iCurBit >> 5; // Mask in a dword.
uint32_t iCurBitMasked;
int nBitsWritten;
Assert( numbits >= 1 && numbits <= 32 );
Assert( numbits >= 0 && numbits <= 32 );
// bounds checking..
if( MSG_Overflow( sb, numbits ))
if(( sb->iCurBit + numbits ) > sb->nDataBits )
{
sb->bOverflow = true;
sb->iCurBit = sb->nDataBits;
return;
}
iCurBitMasked = iCurBit & 31;
((uint32_t *)sb->pData)[iDWord] &= BitWriteMasks[iCurBitMasked][nBitsLeft-1];
((uint32_t *)sb->pData)[iDWord] |= curData << iCurBitMasked;
// did it span a dword?
nBitsWritten = 32 - iCurBitMasked;
if( nBitsWritten < nBitsLeft )
else
{
nBitsLeft -= nBitsWritten;
iCurBit += nBitsWritten;
curData >>= nBitsWritten;
int nBitsLeft = numbits;
int iCurBit = sb->iCurBit;
uint iDWord = iCurBit >> 5; // Mask in a dword.
uint32_t iCurBitMasked;
int nBitsWritten;
Assert(( iDWord * 4 + sizeof( int )) <= (uint)MSG_GetMaxBytes( sb ));
iCurBitMasked = iCurBit & 31;
((uint32_t *)sb->pData)[iDWord+1] &= BitWriteMasks[iCurBitMasked][nBitsLeft-1];
((uint32_t *)sb->pData)[iDWord+1] |= curData << iCurBitMasked;
((uint32_t *)sb->pData)[iDWord] &= BitWriteMasks[iCurBitMasked][nBitsLeft];
((uint32_t *)sb->pData)[iDWord] |= curData << iCurBitMasked;
// did it span a dword?
nBitsWritten = 32 - iCurBitMasked;
if( nBitsWritten < nBitsLeft )
{
nBitsLeft -= nBitsWritten;
iCurBit += nBitsWritten;
curData >>= nBitsWritten;
iCurBitMasked = iCurBit & 31;
((uint32_t *)sb->pData)[iDWord+1] &= BitWriteMasks[iCurBitMasked][nBitsLeft];
((uint32_t *)sb->pData)[iDWord+1] |= curData << iCurBitMasked;
}
sb->iCurBit += numbits;
}
sb->iCurBit += numbits;
}
/*
@@ -380,7 +238,7 @@ qboolean MSG_WriteBits( sizebuf_t *sb, const void *pData, int nBits )
int nBitsLeft = nBits;
// get output dword-aligned.
while((( uintptr_t )pOut & 3 ) != 0 && nBitsLeft >= 8 )
while((( uint32_t )pOut & 3 ) != 0 && nBitsLeft >= 8 )
{
MSG_WriteUBitLong( sb, *pOut, 8 );
@@ -417,14 +275,16 @@ qboolean MSG_WriteBits( sizebuf_t *sb, const void *pData, int nBits )
void MSG_WriteBitAngle( sizebuf_t *sb, float fAngle, int numbits )
{
const uint shift = ( 1 << numbits );
const uint mask = shift - 1;
uint mask, shift;
int d;
// clamp the angle before receiving
fAngle = fmod( fAngle, 360.0f );
if( fAngle < 0 ) fAngle += 360.0f;
shift = ( 1 << numbits );
mask = shift - 1;
d = (int)(( fAngle * shift ) / 360.0f );
d &= mask;
@@ -578,8 +438,9 @@ uint MSG_ReadUBitLong( sizebuf_t *sb, int numbits )
return 0; // end of message
}
if( MSG_Overflow( sb, numbits ))
if(( sb->iCurBit + numbits ) > sb->nDataBits )
{
sb->bOverflow = true;
sb->iCurBit = sb->nDataBits;
return 0;
}
@@ -652,9 +513,13 @@ qboolean MSG_ReadBits( sizebuf_t *sb, void *pOutData, int nBits )
float MSG_ReadBitAngle( sizebuf_t *sb, int numbits )
{
float shift = (float)( 1 << numbits );
int i = MSG_ReadUBitLong( sb, numbits );
float fReturn = (float)i * ( 360.0f / shift );
float fReturn, shift;
int i;
shift = (float)( 1 << numbits );
i = MSG_ReadUBitLong( sb, numbits );
fReturn = (float)i * ( 360.0f / shift );
// clamp the finale angle
if( fReturn < -180.0f ) fReturn += 360.0f;
@@ -666,11 +531,11 @@ float MSG_ReadBitAngle( sizebuf_t *sb, int numbits )
// Append numbits least significant bits from data to the current bit stream
int MSG_ReadSBitLong( sizebuf_t *sb, int numbits )
{
int r;
int r, sign;
if( sb->iAlternateSign )
{
int sign = MSG_ReadOneBit( sb );
sign = MSG_ReadOneBit( sb );
r = MSG_ReadUBitLong( sb, numbits - 1 );
if( sign )
@@ -679,7 +544,9 @@ int MSG_ReadSBitLong( sizebuf_t *sb, int numbits )
else
{
r = MSG_ReadUBitLong( sb, numbits - 1 );
if( MSG_ReadOneBit( sb ))
sign = MSG_ReadOneBit( sb );
if( sign )
r = -( BIT( numbits - 1 ) - r );
}
@@ -800,12 +667,12 @@ qboolean MSG_ReadBytes( sizebuf_t *sb, void *pOut, int nBytes )
static char *MSG_ReadStringExt( sizebuf_t *sb, qboolean bLine )
{
static char string[4096];
int l = 0;
int l = 0, c;
do
{
// use MSG_ReadByte so -1 is out of bounds
int c = MSG_ReadByte( sb );
c = MSG_ReadByte( sb );
if( c == 0 ) break;
else if( bLine && c == '\n' )
@@ -998,6 +865,8 @@ static void Test_Buffer_ExciseBits( void )
void Test_RunBuffer( void )
{
MSG_InitMasks();
TRUN( Test_Buffer_BitByte( ));
TRUN( Test_Buffer_Write( ));
TRUN( Test_Buffer_Read( ));

View File

@@ -193,6 +193,7 @@ static inline void MSG_StartBitWriting( sizebuf_t *sb )
sb->iAlternateSign++;
}
void MSG_InitMasks( void ); // called once at startup engine
void MSG_ExciseBits( sizebuf_t *sb, int startbit, int bitstoremove );
// Bit-write functions

View File

@@ -272,6 +272,8 @@ void Netchan_Init( void )
Cvar_FullSet( net_qport.name, buf, net_qport.flags );
net_mempool = Mem_AllocPool( "Network Pool" );
MSG_InitMasks(); // initialize bit-masks
}
void Netchan_Shutdown( void )
@@ -341,7 +343,6 @@ void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, voi
chan->split = FBitSet( flags, NETCHAN_USE_LEGACY_SPLIT ) ? true : false;
chan->use_munge = FBitSet( flags, NETCHAN_USE_MUNGE ) ? true : false;
chan->use_bz2 = FBitSet( flags, NETCHAN_USE_BZIP2 ) ? true : false;
chan->use_lzss = FBitSet( flags, NETCHAN_USE_LZSS ) ? true : false;
chan->gs_netchan = FBitSet( flags, NETCHAN_GOLDSRC ) ? true : false;
MSG_Init( &chan->message, "NetData", chan->message_buf, sizeof( chan->message_buf ));
@@ -767,7 +768,7 @@ static void Netchan_CreateFragments_( netchan_t *chan, sizebuf_t *msg )
Host_Error( "%s: BZ2 compression is not supported for server", __func__ );
#endif
}
else if( chan->use_lzss && !LZSS_IsCompressed( MSG_GetData( msg ), MSG_GetMaxBytes( msg )))
else if( !chan->use_bz2 && !LZSS_IsCompressed( MSG_GetData( msg ), MSG_GetMaxBytes( msg )))
{
uint uCompressedSize = 0;
uint uSourceSize = MSG_GetNumBytesWritten( msg );
@@ -1174,7 +1175,7 @@ qboolean Netchan_CopyNormalFragments( netchan_t *chan, sizebuf_t *msg, size_t *l
p = n;
}
if( chan->use_bz2 && !memcmp( MSG_GetData( msg ), "BZ2", 4 ))
if( chan->use_bz2 && !memcmp( MSG_GetData( msg ), "BZ2", 4 ) )
{
#if !XASH_DEDICATED
byte buf[0x10000];
@@ -1195,7 +1196,7 @@ qboolean Netchan_CopyNormalFragments( netchan_t *chan, sizebuf_t *msg, size_t *l
Host_Error( "%s: BZ2 compression is not supported for server\n", __func__ );
#endif
}
else if( chan->use_lzss && LZSS_IsCompressed( MSG_GetData( msg ), size ))
else if( !chan->use_bz2 && LZSS_IsCompressed( MSG_GetData( msg ), size ))
{
uint uDecompressedLen = LZSS_GetActualSize( MSG_GetData( msg ), size );
byte buf[NET_MAX_MESSAGE];
@@ -1346,7 +1347,7 @@ qboolean Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg )
Host_Error( "%s: BZ2 compression is not supported for server", __func__ );
#endif
}
else if( chan->use_lzss && LZSS_IsCompressed( buffer, nsize + 1 ))
else if( LZSS_IsCompressed( buffer, nsize + 1 ))
{
byte *uncompressedBuffer;

View File

@@ -2282,6 +2282,10 @@ void Test_RunDelta( void )
char buffer[4096] = { 0 };
const double timebase = 123.123;
// a1ba: netbuffer bitmasks are initialized in netchan for some reason
// initialize it ourselves just in case
MSG_InitMasks(); // initialize bit-masks
Delta_AddField( dt, "dt_string", DT_STRING, 1, 1.0f, 1.0f );
Delta_AddField( dt, "dt_timewindow_big", DT_TIMEWINDOW_BIG, 24, 1000.f, 1.0f );
Delta_AddField( dt, "dt_timewindow_8", DT_TIMEWINDOW_8, 8, 1.0f, 1.0f );

View File

@@ -505,14 +505,11 @@ static int HTTP_FileDecompress( httpfile_t *file )
if( zlib_result == Z_OK || zlib_result == Z_STREAM_END )
{
g_fsapi.WriteFile( name, data_out, decompressed_len );
HTTP_FreeFile( file, false );
Mem_Free( data_in );
}
else HTTP_FreeFile( file, true );
Mem_Free( data_in );
Mem_Free( data_out );
g_fsapi.WriteFile( name, data_out, decompressed_len );
HTTP_FreeFile( file, false );
return 1;
}

View File

@@ -214,7 +214,6 @@ typedef enum netchan_flags_e
NETCHAN_USE_MUNGE = BIT( 1 ),
NETCHAN_USE_BZIP2 = BIT( 2 ),
NETCHAN_GOLDSRC = BIT( 3 ),
NETCHAN_USE_LZSS = BIT( 4 ), // mutually exclusive with bzip2
} netchan_flags_t;
// Network Connection Channel
@@ -286,7 +285,6 @@ typedef struct netchan_s
qboolean split;
qboolean use_munge;
qboolean use_bz2;
qboolean use_lzss;
qboolean gs_netchan;
} netchan_t;

View File

@@ -89,6 +89,16 @@ void Sound_Shutdown( void )
Mem_FreePool( &host.soundpool );
}
static byte *Sound_Copy( size_t size )
{
byte *out;
out = Mem_Realloc( host.soundpool, sound.tempbuffer, size );
sound.tempbuffer = NULL;
return out;
}
uint GAME_EXPORT Sound_GetApproxWavePlayLen( const char *filepath )
{
string name;
@@ -368,7 +378,6 @@ static qboolean Sound_ResampleInternal( wavdata_t *sc, int outrate, int outwidth
const int inwidth = sc->width;
const int inchannels = sc->channels;
const int incount = sc->samples;
const int insize = sc->size;
qboolean handled = false;
double stepscale;
double t1, t2;
@@ -422,30 +431,22 @@ static qboolean Sound_ResampleInternal( wavdata_t *sc, int outrate, int outwidth
else // upsample case, w/ interpolation
handled = Sound_ConvertUpsample( sc, inwidth, inchannels, incount, outwidth, outchannels, outcount, stepscale );
if( !handled )
{
// restore previously changed data
sc->rate = inrate;
sc->width = inwidth;
sc->channels = inchannels;
sc->samples = incount;
sc->size = insize;
t2 = Sys_DoubleTime();
if( handled )
{
if( t2 - t1 > 0.01f ) // critical, report to mod developer
Con_Printf( S_WARN "%s: from [%d bit %d Hz %dch] to [%d bit %d Hz %dch] (took %.3fs)\n", __func__, inwidth * 8, inrate, inchannels, outwidth * 8, outrate, outchannels, t2 - t1 );
else
Con_Reportf( "%s: from [%d bit %d Hz %dch] to [%d bit %d Hz %dch] (took %.3fs)\n", __func__, inwidth * 8, inrate, inchannels, outwidth * 8, outrate, outchannels, t2 - t1 );
}
else
Con_Printf( S_ERROR "%s: unsupported from [%d bit %d Hz %dch] to [%d bit %d Hz %dch]\n", __func__, inwidth * 8, inrate, inchannels, outwidth * 8, outrate, outchannels );
return false;
}
t2 = Sys_DoubleTime();
sc->rate = outrate;
sc->width = outwidth;
if( t2 - t1 > 0.01f ) // critical, report to mod developer
Con_Printf( S_WARN "%s: from [%d bit %d Hz %dch] to [%d bit %d Hz %dch] (took %.3fs)\n", __func__, inwidth * 8, inrate, inchannels, outwidth * 8, outrate, outchannels, t2 - t1 );
else
Con_Reportf( "%s: from [%d bit %d Hz %dch] to [%d bit %d Hz %dch] (took %.3fs)\n", __func__, inwidth * 8, inrate, inchannels, outwidth * 8, outrate, outchannels, t2 - t1 );
return true;
return handled;
}
qboolean Sound_Process( wavdata_t **wav, int rate, int width, int channels, uint flags )
@@ -463,11 +464,8 @@ qboolean Sound_Process( wavdata_t **wav, int rate, int width, int channels, uint
if( result )
{
snd = Mem_Realloc( host.soundpool, snd, sizeof( *snd ) + snd->size );
memcpy( snd->buffer, sound.tempbuffer, snd->size );
Mem_Free( sound.tempbuffer );
sound.tempbuffer = NULL;
Mem_Free( snd->buffer ); // free original image buffer
snd->buffer = Sound_Copy( snd->size ); // unzone buffer
}
}

View File

@@ -41,15 +41,6 @@ NOTE: never change this structure because all dll descriptions in xash code
writes into struct by offsets not names
========================================================================
*/
typedef struct dll_info_s
{
const char *name; // name of library
const dllfunc_t *fcts; // list of dll exports
const size_t num_fcts;
qboolean crash; // crash if dll not found
void *link; // hinstance of loading library
} dll_info_t;
extern int error_on_exit;
double Sys_DoubleTime( void );
char *Sys_GetClipboardData( void );

View File

@@ -68,13 +68,7 @@ extern "C" {
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#if (_MSC_VER >= 1900)
#include <stdbool.h>
#else
#define bool int
#define false 0
#define true 1
#endif
static int WAI_PREFIX(getModulePath_)(HMODULE module, char* out, int capacity, int* dirname_length)
{
@@ -249,11 +243,6 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
#endif
#endif
#if !defined(WAI_STRINGIZE)
#define WAI_STRINGIZE(s)
#define WAI_STRINGIZE_(s) #s
#endif
#if defined(__ANDROID__) || defined(ANDROID)
#include <fcntl.h>
#include <sys/mman.h>
@@ -276,20 +265,20 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
for (;;)
{
char buffer[128 + PATH_MAX];
uintptr_t low, high;
char buffer[PATH_MAX < 1024 ? 1024 : PATH_MAX];
uint64_t low, high;
char perms[5];
uint64_t offset;
uint32_t major, minor, inode;
char path[PATH_MAX + 1];
uint32_t major, minor;
char path[PATH_MAX];
uint32_t inode;
if (!fgets(buffer, sizeof(buffer), maps))
break;
if (sscanf(buffer, "%" SCNxPTR "-%" SCNxPTR " %s %" SCNx64 " %x:%x %u %" WAI_STRINGIZE(PATH_MAX) "[^\n]\n", &low, &high, perms, &offset, &major, &minor, &inode, path) == 8)
if (sscanf(buffer, "%" PRIx64 "-%" PRIx64 " %s %" PRIx64 " %x:%x %u %s\n", &low, &high, perms, &offset, &major, &minor, &inode, path) == 8)
{
void* _addr = WAI_RETURN_ADDRESS();
uintptr_t addr = (uintptr_t)_addr;
uint64_t addr = (uintptr_t)WAI_RETURN_ADDRESS();
if (low <= addr && addr <= high)
{
char* resolved;

View File

@@ -31,8 +31,7 @@ extern "C" {
* @param out destination buffer, optional
* @param capacity destination buffer capacity
* @param dirname_length optional recipient for the length of the dirname part
* of the path. Available only when `capacity` is large enough to retrieve the
* path.
* of the path.
*
* @return the length of the executable path on success (without a terminal NUL
* character), otherwise `-1`
@@ -53,8 +52,7 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length);
* @param out destination buffer, optional
* @param capacity destination buffer capacity
* @param dirname_length optional recipient for the length of the dirname part
* of the path. Available only when `capacity` is large enough to retrieve the
* path.
* of the path.
*
* @return the length of the module path on success (without a terminal NUL
* character), otherwise `-1`

View File

@@ -18,7 +18,7 @@ GNU General Public License for more details.
#include "common.h"
#define MEMHEADER_SENTINEL1 0xA1BAU
#define MEMHEADER_SENTINEL1 0xDEADF00DU
#define MEMHEADER_SENTINEL2 0xDFU
#ifdef XASH_CUSTOM_SWAP
@@ -51,29 +51,31 @@ static void *Q_realloc( void *mem, size_t size )
#define Q_realloc realloc
#endif
// keep this structure as compact as possible while keeping it aligned
// on ILP32 it's 24 bytes, which is aligned to 8 byte boundary
// on LP64 it's 40 bytes, which is also aligned to 8 byte boundary
typedef struct memheader_s
{
struct memheader_s *next, *prev; // next and previous memheaders in chain belonging to pool
const char *filename; // file name and line where Mem_Alloc was called
size_t size; // size of the memory after the header (excluding header and sentinel2)
poolhandle_t poolptr; // pool this memheader belongs to
uint16_t fileline;
uint16_t sentinel1; // must be equal to MEMHEADER_SENTINEL1
struct memheader_s *next; // next and previous memheaders in chain belonging to pool
struct memheader_s *prev;
const char *filename; // file name and line where Mem_Alloc was called
size_t size; // size of the memory after the header (excluding header and sentinel2)
poolhandle_t poolptr; // pool this memheader belongs to
int fileline;
#if !XASH_64BIT
uint32_t pad0; // doesn't have value, only to make Mem_Alloc return aligned addresses on ILP32
#endif
uint32_t sentinel1; // should always be MEMHEADER_SENTINEL1
// immediately followed by data, which is followed by a MEMHEADER_SENTINEL2 byte
} memheader_t;
typedef struct mempool_s
{
struct memheader_s *chain; // chain of individual memory allocations
size_t totalsize; // total memory allocated in this pool (inside memheaders)
size_t realsize; // total memory allocated in this pool (actual malloc total)
size_t lastchecksize; // updated each time the pool is displayed by memlist
const char *filename; // file name and line where Mem_AllocPool was called
int fileline;
char name[64]; // name of the pool
struct memheader_s *chain; // chain of individual memory allocations
size_t totalsize; // total memory allocated in this pool (inside memheaders)
size_t realsize; // total memory allocated in this pool (actual malloc total)
size_t lastchecksize; // updated each time the pool is displayed by memlist
const char *filename; // file name and line where Mem_AllocPool was called
int fileline;
char name[64]; // name of the pool
} mempool_t;
static mempool_t *poolchain = NULL; // critical stuff
@@ -231,7 +233,10 @@ static void Mem_FreeBlock( memheader_t *mem, const char *filename, int fileline
void _Mem_Free( void *data, const char *filename, int fileline )
{
if( data == NULL )
{
Sys_Error( "%s: data == NULL (called at %s:%i)\n", __func__, filename, fileline );
return;
}
Mem_FreeBlock((memheader_t *)((byte *)data - sizeof( memheader_t )), filename, fileline );
}
@@ -516,5 +521,4 @@ Memory_Init
void Memory_Init( void )
{
poolchain = NULL; // init mem chain
poolcount = 0;
}

View File

@@ -1,164 +1,186 @@
/*
Copyright (C) 1997-2001 Id Software, Inc.
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
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 2
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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// taken from Quake-2 source code and modified for GoldSrc compatibility
#ifndef KEYDEFS_H
#define KEYDEFS_H
//
// these are the key numbers that should be passed to Key_Event
// normal keys should be passed as lowercased ascii
//
#define K_TAB 9
#define K_ENTER 13
#define K_ESCAPE 27
#define K_SPACE 32
#define K_SCROLLLOCK 70
#define K_BACKSPACE 127
#define K_UPARROW 128
#define K_DOWNARROW 129
#define K_LEFTARROW 130
#define K_RIGHTARROW 131
#define K_ALT 132
#define K_CTRL 133
#define K_SHIFT 134
#define K_F1 135
#define K_F2 136
#define K_F3 137
#define K_F4 138
#define K_F5 139
#define K_F6 140
#define K_F7 141
#define K_F8 142
#define K_F9 143
#define K_F10 144
#define K_F11 145
#define K_F12 146
#define K_INS 147
#define K_DEL 148
#define K_PGDN 149
#define K_PGUP 150
#define K_HOME 151
#define K_END 152
#define K_TAB 9
#define K_ENTER 13
#define K_ESCAPE 27
#define K_SPACE 32
#define K_SCROLLOCK 70
#define K_KP_HOME 160
#define K_KP_UPARROW 161
#define K_KP_PGUP 162
#define K_KP_LEFTARROW 163
#define K_KP_5 164
// normal keys should be passed as lowercased ascii
#define K_BACKSPACE 127
#define K_UPARROW 128
#define K_DOWNARROW 129
#define K_LEFTARROW 130
#define K_RIGHTARROW 131
#define K_ALT 132
#define K_CTRL 133
#define K_SHIFT 134
#define K_F1 135
#define K_F2 136
#define K_F3 137
#define K_F4 138
#define K_F5 139
#define K_F6 140
#define K_F7 141
#define K_F8 142
#define K_F9 143
#define K_F10 144
#define K_F11 145
#define K_F12 146
#define K_INS 147
#define K_DEL 148
#define K_PGDN 149
#define K_PGUP 150
#define K_HOME 151
#define K_END 152
#define K_KP_HOME 160
#define K_KP_UPARROW 161
#define K_KP_PGUP 162
#define K_KP_LEFTARROW 163
#define K_KP_5 164
#define K_KP_RIGHTARROW 165
#define K_KP_END 166
#define K_KP_DOWNARROW 167
#define K_KP_PGDN 168
#define K_KP_ENTER 169
#define K_KP_INS 170
#define K_KP_DEL 171
#define K_KP_SLASH 172
#define K_KP_MINUS 173
#define K_KP_PLUS 174
#define K_CAPSLOCK 175
#define K_KP_MUL 176
#define K_WIN 177
#define K_KP_NUMLOCK 178
#define K_KP_END 166
#define K_KP_DOWNARROW 167
#define K_KP_PGDN 168
#define K_KP_ENTER 169
#define K_KP_INS 170
#define K_KP_DEL 171
#define K_KP_SLASH 172
#define K_KP_MINUS 173
#define K_KP_PLUS 174
#define K_CAPSLOCK 175
#define K_KP_MUL 176
#define K_WIN 177
#define K_KP_NUMLOCK 178
//
// joystick buttons
//
#define K_JOY1 203
#define K_JOY2 204
#define K_JOY3 205
#define K_JOY4 206
#define K_JOY1 203 // LTRIGGER (L2)
#define K_JOY2 204 // RTRIGGER (R2)
#define K_JOY3 205
#define K_JOY4 206
//
// aux keys are for multi-buttoned joysticks to generate so they can use
// the normal binding process
//
#define K_AUX1 207
#define K_AUX2 208
#define K_AUX3 209
#define K_AUX4 210
#define K_AUX5 211
#define K_AUX6 212
#define K_AUX7 213
#define K_AUX8 214
#define K_AUX9 215
#define K_AUX10 216
#define K_AUX11 217
#define K_AUX12 218
#define K_AUX13 219
#define K_AUX14 220
#define K_AUX15 221
#define K_AUX16 222
#define K_AUX17 223
#define K_AUX18 224
#define K_AUX19 225
#define K_AUX20 226
#define K_AUX21 227
#define K_AUX22 228
#define K_AUX23 229
#define K_AUX24 230
#define K_AUX25 231
#define K_AUX26 232
#define K_AUX27 233
#define K_AUX28 234
#define K_AUX29 235
#define K_AUX30 236
#define K_AUX31 237
#define K_AUX32 238
#define K_AUX1 207
#define K_A_BUTTON K_AUX1
//
// button names for game pads
//
#define K_A_BUTTON K_AUX1
#define K_B_BUTTON K_AUX2
#define K_X_BUTTON K_AUX3
#define K_Y_BUTTON K_AUX4
#define K_L1_BUTTON K_AUX5
#define K_R1_BUTTON K_AUX6
#define K_BACK_BUTTON K_AUX7
#define K_MODE_BUTTON K_AUX8
#define K_START_BUTTON K_AUX9
#define K_LSTICK K_AUX10
#define K_RSTICK K_AUX11
#define K_L2_BUTTON K_AUX12
#define K_R2_BUTTON K_AUX13
#define K_C_BUTTON K_AUX14
#define K_Z_BUTTON K_AUX15
#define K_DPAD_UP K_AUX16
#define K_DPAD_DOWN K_AUX17
#define K_DPAD_LEFT K_AUX18
#define K_DPAD_RIGHT K_AUX19
#define K_MISC_BUTTON K_AUX20
#define K_PADDLE1_BUTTON K_AUX21
#define K_AUX2 208
#define K_B_BUTTON K_AUX2
#define K_AUX3 209
#define K_X_BUTTON K_AUX3
#define K_AUX4 210
#define K_Y_BUTTON K_AUX4
#define K_AUX5 211
#define K_L1_BUTTON K_AUX5
#define K_AUX6 212
#define K_R1_BUTTON K_AUX6
#define K_AUX7 213
#define K_BACK_BUTTON K_AUX7
#define K_AUX8 214
#define K_MODE_BUTTON K_AUX8
#define K_AUX9 215
#define K_START_BUTTON K_AUX9
#define K_AUX10 216
#define K_LSTICK K_AUX10
#define K_AUX11 217
#define K_RSTICK K_AUX11
#define K_AUX12 218
#define K_L2_BUTTON K_AUX12
#define K_AUX13 219
#define K_R2_BUTTON K_AUX13
#define K_AUX14 220
#define K_C_BUTTON K_AUX14
#define K_AUX15 221
#define K_Z_BUTTON K_AUX15
#define K_AUX16 222
#define K_DPAD_UP K_AUX16
#define K_AUX17 223
#define K_DPAD_DOWN K_AUX17
#define K_AUX18 224
#define K_DPAD_LEFT K_AUX18
#define K_AUX19 225
#define K_DPAD_RIGHT K_AUX19
#define K_AUX20 226
#define K_MISC_BUTTON K_AUX20 // Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button
#define K_AUX21 227
#define K_PADDLE1_BUTTON K_AUX21 // Xbox Elite paddle P1-P4
#define K_AUX22 228
#define K_PADDLE2_BUTTON K_AUX22
#define K_AUX23 229
#define K_PADDLE3_BUTTON K_AUX23
#define K_AUX24 230
#define K_PADDLE4_BUTTON K_AUX24
#define K_TOUCHPAD K_AUX25
#define K_AUX25 231
#define K_TOUCHPAD K_AUX25 // PS4/PS5 touchpad button
#define K_AUX26 232
#define K_AUX27 233
#define K_AUX28 234
#define K_AUX29 235
#define K_AUX30 236
#define K_AUX31 237
#define K_AUX32 238
#define K_MWHEELDOWN 239
#define K_MWHEELUP 240
#define K_PAUSE 255
//
// mouse buttons generate virtual keys
//
#define K_MWHEELDOWN 239
#define K_MWHEELUP 240
#define K_MOUSE1 241
#define K_MOUSE2 242
#define K_MOUSE3 243
#define K_MOUSE4 244
#define K_MOUSE5 245
#define K_MOUSE1 241
#define K_MOUSE2 242
#define K_MOUSE3 243
#define K_MOUSE4 244
#define K_MOUSE5 245
#define K_PAUSE 255
#endif//KEYDEFS_H

View File

@@ -32,7 +32,7 @@
#include <android/log.h>
#include "linker.h"
static const Elf_Sym *soinfo_elf_lookup( const struct soinfo *si, unsigned hash, const char *name )
static const Elf_Sym *soinfo_elf_lookup( const soinfo *si, unsigned hash, const char *name )
{
const Elf_Sym *symtab = si->symtab;
const char *strtab = si->strtab;
@@ -87,14 +87,14 @@ static unsigned elfhash( const unsigned char *name )
Binary Interface) where in Chapter 5 it discuss resolving "Shared
Object Dependencies" in breadth first search order.
*/
static const Elf_Sym *dlsym_handle_lookup( const struct soinfo *si, const char *name )
static const Elf_Sym *dlsym_handle_lookup( const soinfo *si, const char *name )
{
return soinfo_elf_lookup( si, elfhash((const unsigned char *)name ), name );
}
void *dlsym_weak( void *handle, const char *symbol )
extern "C" void *dlsym_weak( void *handle, const char *symbol )
{
const struct soinfo *found = (struct soinfo *)handle;
const soinfo *found = (soinfo *)handle;
const Elf_Sym *sym = dlsym_handle_lookup( found, symbol );
if( sym != NULL )

View File

@@ -31,8 +31,10 @@
#include <unistd.h>
#include <sys/types.h>
#include <stdbool.h>
// #include <elf.h>
#include <linux/elf.h>
// #include <sys/exec_elf.h>
// #include <link.h>
// a1ba: we don't really need custom linker on Android 64, because
// it's only intended to workaround bug which persist on Android < 4.4
@@ -67,8 +69,8 @@ struct link_map_t {
uintptr_t l_addr;
char *l_name;
uintptr_t l_ld;
struct link_map_t *l_next;
struct link_map_t *l_prev;
link_map_t *l_next;
link_map_t *l_prev;
};
// Values for r_debug->state
@@ -83,7 +85,7 @@ enum {
#define SOINFO_NAME_LEN 128
typedef void (*linker_function_t)( void );
typedef void (*linker_function_t)();
// Android uses REL for 32-bit but only uses RELA for 64-bit.
#if defined( __LP64__ )
@@ -91,6 +93,7 @@ typedef void (*linker_function_t)( void );
#endif
struct soinfo {
public:
char name[SOINFO_NAME_LEN];
const Elf_Phdr *phdr;
size_t phnum;
@@ -109,7 +112,7 @@ struct soinfo {
uint32_t unused3; // DO NOT USE, maintained for compatibility
#endif
struct soinfo *next;
soinfo *next;
unsigned flags;
const char *strtab;
@@ -161,8 +164,8 @@ struct soinfo {
unsigned mips_gotsym;
#endif
size_t ref_count;
struct link_map_t link_map;
size_t ref_count;
link_map_t link_map;
bool constructors_called;
@@ -174,6 +177,14 @@ struct soinfo {
bool has_text_relocations;
#endif
bool has_DT_SYMBOLIC;
void CallConstructors();
void CallDestructors();
void CallPreInitConstructors();
private:
void CallArray( const char *array_name, linker_function_t *functions, size_t count, bool reverse );
void CallFunction( const char *function_name, linker_function_t function );
};
#endif

View File

@@ -91,6 +91,11 @@ void GAME_EXPORT Platform_SetMousePos(int x, int y)
}
int Platform_JoyInit( int numjoy )
{
return 0;
}
void Platform_EnableTextInput( qboolean enable )
{
keystate.chars = enable;

View File

@@ -184,7 +184,7 @@ qboolean SNDDMA_Init( void )
return false;
}
dma.buffer = Mem_Malloc( sndpool, samples * 2 ); //allocate pcm frame buffer
dma.buffer = Z_Malloc( samples * 2 ); //allocate pcm frame buffer
dma.samplepos = 0;
dma.samples = samples;
dma.format.width = 2;

View File

@@ -281,8 +281,13 @@ void GAME_EXPORT Platform_SetMousePos(int x, int y)
}
void Platform_Vibrate( float life, char flags )
void Platform_Vibrate(float life, char flags)
{
}
int Platform_JoyInit( int numjoy )
{
return 0;
}
#endif

View File

@@ -55,7 +55,7 @@ char *Posix_Input( void );
#endif
#if XASH_SDL
void SDLash_Init( const char *basedir );
void SDLash_Init( void );
void SDLash_Shutdown( void );
#endif
@@ -104,7 +104,7 @@ void Linux_SetTimer( float time );
int Linux_GetProcessID( void );
#endif
static inline void Platform_Init( qboolean con_showalways, const char *basedir )
static inline void Platform_Init( qboolean con_showalways )
{
#if XASH_POSIX
// daemonize as early as possible, because we need to close our file descriptors
@@ -112,7 +112,7 @@ static inline void Platform_Init( qboolean con_showalways, const char *basedir )
#endif
#if XASH_SDL
SDLash_Init( basedir );
SDLash_Init( );
#endif
#if XASH_ANDROID
@@ -178,7 +178,7 @@ static inline void Platform_Sleep( int msec )
#endif
}
#if XASH_WIN32 || XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX || XASH_APPLE
#if XASH_WIN32 || XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX
void Sys_SetupCrashHandler( void );
void Sys_RestoreCrashHandler( void );
#else
@@ -199,8 +199,7 @@ static inline void Sys_RestoreCrashHandler( void )
==============================================================================
*/
void Platform_Vibrate( float life, char flags ); // left for compatibility
void Platform_Vibrate2( float time, int low_freq, int high_freq, uint flags );
void Platform_Vibrate( float life, char flags );
/*
==============================================================================
@@ -210,27 +209,7 @@ void Platform_Vibrate2( float time, int low_freq, int high_freq, uint flags );
==============================================================================
*/
// Gamepad support
#if XASH_SDL
int Platform_JoyInit( void ); // returns number of connected gamepads, negative if error
void Platform_JoyShutdown( void );
void Platform_CalibrateGamepadGyro( void );
#else
static inline int Platform_JoyInit( void )
{
return 0;
}
static inline void Platform_JoyShutdown( void )
{
}
static inline void Platform_CalibrateGamepadGyro( void )
{
}
#endif
int Platform_JoyInit( int numjoy ); // returns number of connected gamepads, negative if error
// Text input
void Platform_EnableTextInput( qboolean enable );
key_modifier_t Platform_GetKeyModifiers( void );

View File

@@ -1,85 +0,0 @@
/*
crashhandler.c - advanced crashhandler
Copyright (C) 2016 Mittorn
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.
*/
// on Glibc (which potentially might not be only Linux) systems we
// have backtrace() and backtrace_symbols() calls, which replace for us
// platform-specific code
#if HAVE_EXECINFO
#include "common.h"
#include <execinfo.h>
#include <signal.h>
void Sys_Crash( int signal, siginfo_t *si, void *context )
{
char message[8192];
int len, logfd, i = 0;
int size;
void *addrs[16];
char **syms;
// safe actions first, stack and memory may be corrupted
len = Q_snprintf( message, sizeof( message ), "Ver: " XASH_ENGINE_NAME " " XASH_VERSION " (build %i-%s, %s-%s)\n",
Q_buildnum(), g_buildcommit, Q_buildos(), Q_buildarch() );
#if !XASH_FREEBSD && !XASH_NETBSD && !XASH_OPENBSD && !XASH_APPLE // they don't have si_ptr
len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p %p\n", signal, si->si_errno, si->si_code, si->si_addr, si->si_ptr );
#else
len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p\n", signal, si->si_errno, si->si_code, si->si_addr );
#endif
write( STDERR_FILENO, message, len );
// flush buffers before writing directly to descriptors
fflush( stdout );
fflush( stderr );
// now get log fd and write trace directly to log
logfd = Sys_LogFileNo();
write( logfd, message, len );
size = backtrace( addrs, sizeof( addrs ) / sizeof( addrs[0] ));
syms = backtrace_symbols( addrs, size );
for( i = 0; i < size && syms; i++ )
{
size_t symlen = Q_strlen( syms[i] );
char ch = '\n';
write( logfd, syms[i], symlen );
write( logfd, &ch, 1 );
write( STDERR_FILENO, syms[i], symlen );
write( STDERR_FILENO, &ch, 1 );
len += Q_snprintf( message + len, sizeof( message ) - len, "%2d: %s\n", i, syms[i] );
}
// put MessageBox as Sys_Error
Msg( "%s\n", message );
#ifdef XASH_SDL
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
#endif
host.crashed = true;
Platform_MessageBox( "Xash Error", message, false );
// log saved, now we can try to save configs and close log correctly, it may crash
if( host.type == HOST_NORMAL )
CL_Crashed();
host.status = HOST_CRASHED;
Sys_Quit( "crashed" );
}
#endif // HAVE_EXECINFO

View File

@@ -18,8 +18,7 @@ GNU General Public License for more details.
// while this is mostly POSIX-compatible functions
// the contents of ucontext_t is platform-dependent
// before adding new OS here, check platform.h
#define _XOPEN_SOURCE 1 // required for ucontext
#if XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX || XASH_APPLE
#if XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX
#ifndef XASH_OPENBSD
#include <ucontext.h>
#endif
@@ -27,11 +26,6 @@ GNU General Public License for more details.
#include <sys/mman.h>
#include "library.h"
void Sys_Crash( int signal, siginfo_t *si, void *context );
static struct sigaction oldFilter;
#if !HAVE_EXECINFO
#define STACK_BACKTRACE_STR "Stack backtrace:\n"
#define STACK_DUMP_STR "Stack dump:\n"
@@ -39,6 +33,8 @@ static struct sigaction oldFilter;
#define STACK_DUMP_STR_LEN ( sizeof( STACK_DUMP_STR ) - 1 )
#define ALIGN( x, y ) (((uintptr_t) ( x ) + (( y ) - 1 )) & ~(( y ) - 1 ))
static struct sigaction oldFilter;
static int Sys_PrintFrame( char *buf, int len, int i, void *addr )
{
Dl_info dlinfo;
@@ -57,7 +53,7 @@ static int Sys_PrintFrame( char *buf, int len, int i, void *addr )
return Q_snprintf( buf, len, "%2d: %p\n", i, addr ); // print only address
}
void Sys_Crash( int signal, siginfo_t *si, void *context )
static void Sys_Crash( int signal, siginfo_t *si, void *context)
{
void *pc = NULL, **bp = NULL, **sp = NULL; // this must be set for every OS!
char message[8192];
@@ -119,7 +115,7 @@ void Sys_Crash( int signal, siginfo_t *si, void *context )
len = Q_snprintf( message, sizeof( message ), "Ver: " XASH_ENGINE_NAME " " XASH_VERSION " (build %i-%s, %s-%s)\n",
Q_buildnum(), g_buildcommit, Q_buildos(), Q_buildarch() );
#if !XASH_FREEBSD && !XASH_NETBSD && !XASH_OPENBSD && !XASH_APPLE
#if !XASH_FREEBSD && !XASH_NETBSD && !XASH_OPENBSD
len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p %p\n", signal, si->si_errno, si->si_code, si->si_addr, si->si_ptr );
#else
len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p\n", signal, si->si_errno, si->si_code, si->si_addr );
@@ -204,8 +200,6 @@ void Sys_Crash( int signal, siginfo_t *si, void *context )
Sys_Quit( "crashed" );
}
#endif // !HAVE_EXECINFO
void Sys_SetupCrashHandler( void )
{
struct sigaction act = { 0 };

View File

@@ -88,8 +88,52 @@ GNU General Public License for more details.
#define SDL_SCANCODE_PRINTSCREEN SDLK_PRINT
#define SDL_SCANCODE_UNKNOWN SDLK_UNKNOWN
#define SDL_GetScancodeName( x ) "unknown"
#define SDL_JoystickID Uint8
#endif
static int SDLash_GameControllerButtonMapping[] =
{
#if XASH_NSWITCH // devkitPro/SDL has inverted Nintendo layout for SDL_GameController
K_B_BUTTON, K_A_BUTTON, K_Y_BUTTON, K_X_BUTTON,
#else
K_A_BUTTON, K_B_BUTTON, K_X_BUTTON, K_Y_BUTTON,
#endif
K_BACK_BUTTON, K_MODE_BUTTON, K_START_BUTTON,
K_LSTICK, K_RSTICK,
K_L1_BUTTON, K_R1_BUTTON,
K_DPAD_UP, K_DPAD_DOWN, K_DPAD_LEFT, K_DPAD_RIGHT,
K_MISC_BUTTON,
K_PADDLE1_BUTTON, K_PADDLE2_BUTTON, K_PADDLE3_BUTTON, K_PADDLE4_BUTTON,
K_TOUCHPAD,
};
// Swap axis to follow default axis binding:
// LeftX, LeftY, RightX, RightY, TriggerRight, TriggerLeft
static int SDLash_GameControllerAxisMapping[] =
{
JOY_AXIS_SIDE, // SDL_CONTROLLER_AXIS_LEFTX,
JOY_AXIS_FWD, // SDL_CONTROLLER_AXIS_LEFTY,
JOY_AXIS_PITCH, // SDL_CONTROLLER_AXIS_RIGHTX,
JOY_AXIS_YAW, // SDL_CONTROLLER_AXIS_RIGHTY,
JOY_AXIS_LT, // SDL_CONTROLLER_AXIS_TRIGGERLEFT,
JOY_AXIS_RT, // SDL_CONTROLLER_AXIS_TRIGGERRIGHT,
};
static qboolean SDLash_IsInstanceIDAGameController( SDL_JoystickID joyId )
{
#if !SDL_VERSION_ATLEAST( 2, 0, 4 )
// HACKHACK: if we're not initialized g_joy, then we're probably using gamecontroller api
// so return true
if( !g_joy )
return true;
return false;
#else
if( SDL_GameControllerFromInstanceID( joyId ) != NULL )
return true;
return false;
#endif
}
/*
=============
SDLash_KeyEvent
@@ -221,7 +265,7 @@ static void SDLash_KeyEvent( SDL_KeyboardEvent key )
break;
}
case SDL_SCANCODE_PAUSE: keynum = K_PAUSE; break;
case SDL_SCANCODE_SCROLLLOCK: keynum = K_SCROLLLOCK; break;
case SDL_SCANCODE_SCROLLLOCK: keynum = K_SCROLLOCK; break;
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
case SDL_SCANCODE_APPLICATION: keynum = K_WIN; break; // (compose key) ???
// don't console spam on known functional buttons, not used in engine
@@ -364,6 +408,50 @@ static void SDLash_ActiveEvent( int gain )
}
}
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
static size_t num_open_game_controllers = 0;
static void SDLash_GameController_Add( int index )
{
extern convar_t joy_enable; // private to input system
SDL_GameController *controller;
if( !joy_enable.value )
return;
controller = SDL_GameControllerOpen( index );
if( !controller )
{
Con_Reportf( "Failed to open SDL GameController %d: %s\n", index, SDL_GetError( ) );
SDL_ClearError( );
return;
}
#if SDL_VERSION_ATLEAST( 2, 0, 6 )
Con_Reportf( "Added controller: %s (%i:%i:%i)\n",
SDL_GameControllerName( controller ),
SDL_GameControllerGetVendor( controller ),
SDL_GameControllerGetProduct( controller ),
SDL_GameControllerGetProductVersion( controller ));
#endif // SDL_VERSION_ATLEAST( 2, 0, 6 )
++num_open_game_controllers;
if( num_open_game_controllers == 1 )
Joy_AddEvent( );
}
static void SDLash_GameController_Remove( SDL_JoystickID joystick_id )
{
Con_Reportf( "Removed controller %i\n", joystick_id );
// `Joy_RemoveEvent` sets `joy_found` to `0`.
// We only want to do this when all the game controllers have been removed.
--num_open_game_controllers;
if( num_open_game_controllers == 0 )
Joy_RemoveEvent( );
}
#endif
/*
=============
SDLash_EventFilter
@@ -391,6 +479,28 @@ static void SDLash_EventHandler( SDL_Event *event )
SDLash_KeyEvent( event->key );
break;
/* Joystick events */
case SDL_JOYAXISMOTION:
if ( !SDLash_IsInstanceIDAGameController( event->jaxis.which ))
Joy_AxisMotionEvent( event->jaxis.axis, event->jaxis.value );
break;
case SDL_JOYBALLMOTION:
if ( !SDLash_IsInstanceIDAGameController( event->jball.which ))
Joy_BallMotionEvent( event->jball.ball, event->jball.xrel, event->jball.yrel );
break;
case SDL_JOYHATMOTION:
if ( !SDLash_IsInstanceIDAGameController( event->jhat.which ))
Joy_HatMotionEvent( event->jhat.hat, event->jhat.value );
break;
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
if ( !SDLash_IsInstanceIDAGameController( event->jbutton.which ))
Joy_ButtonEvent( event->jbutton.button, event->jbutton.state );
break;
case SDL_QUIT:
Sys_Quit( "caught SDL_QUIT" );
break;
@@ -458,17 +568,46 @@ static void SDLash_EventHandler( SDL_Event *event )
SDLash_InputEvent( event->text );
break;
case SDL_JOYDEVICEADDED:
Joy_AddEvent();
break;
case SDL_JOYDEVICEREMOVED:
Joy_RemoveEvent();
break;
/* GameController API */
case SDL_CONTROLLERAXISMOTION:
{
if( !Joy_IsActive( ))
break;
if( event->caxis.axis >= 0 && event->caxis.axis < ARRAYSIZE( SDLash_GameControllerAxisMapping ))
{
Joy_KnownAxisMotionEvent( SDLash_GameControllerAxisMapping[event->caxis.axis], event->caxis.value );
}
break;
}
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP:
{
if( !Joy_IsActive( ))
break;
// TODO: Use joyinput funcs, for future multiple gamepads support
if( event->cbutton.button >= 0 && event->cbutton.button < ARRAYSIZE( SDLash_GameControllerButtonMapping ))
{
Key_Event( SDLash_GameControllerButtonMapping[event->cbutton.button], event->cbutton.state );
}
break;
}
case SDL_CONTROLLERDEVICEADDED:
SDLash_GameController_Add( event->cdevice.which );
break;
case SDL_CONTROLLERDEVICEREMOVED:
case SDL_CONTROLLERTOUCHPADDOWN:
case SDL_CONTROLLERTOUCHPADMOTION:
case SDL_CONTROLLERTOUCHPADUP:
case SDL_CONTROLLERSENSORUPDATE:
SDLash_HandleGameControllerEvent( event );
SDLash_GameController_Remove( event->cdevice.which );
break;
case SDL_WINDOWEVENT:

View File

@@ -28,16 +28,14 @@ void GL_InitExtensions( void );
qboolean GL_DeleteContext( void );
void VID_SaveWindowSize( int width, int height, qboolean maximized );
// joystick events
extern SDL_Joystick *g_joy;
//
// in_sdl.c
//
void SDLash_InitCursors( void );
void SDLash_FreeCursors( void );
//
// joy_sdl.c
//
void SDLash_HandleGameControllerEvent( SDL_Event *ev );
#endif // XASH_SDL
#endif // KEYWRAPPER_H

View File

@@ -1,6 +1,6 @@
/*
in_sdl.c - SDL input component
Copyright (C) 2018-2025 a1batross
vid_sdl.c - SDL input component
Copyright (C) 2018 a1batross
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
@@ -12,6 +12,7 @@ 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.
*/
#if !XASH_DEDICATED
#include <SDL.h>
#include "common.h"
@@ -23,6 +24,7 @@ GNU General Public License for more details.
#include "sound.h"
#include "vid_common.h"
SDL_Joystick *g_joy = NULL;
#if !SDL_VERSION_ATLEAST( 2, 0, 0 )
#define SDL_WarpMouseInWindow( win, x, y ) SDL_WarpMouse( ( x ), ( y ) )
#else
@@ -124,6 +126,20 @@ void Platform_SetClipboardText( const char *buffer )
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
}
/*
=============
Platform_Vibrate
=============
*/
void Platform_Vibrate( float time, char flags )
{
#if SDL_VERSION_ATLEAST( 2, 0, 9 )
if( g_joy )
SDL_JoystickRumble( g_joy, 0xFFFF, 0xFFFF, time * 1000.0f );
#endif // SDL_VERSION_ATLEAST( 2, 0, 9 )
}
#if !XASH_PSVITA
/*
@@ -141,6 +157,120 @@ void Platform_EnableTextInput( qboolean enable )
#endif // !XASH_PSVITA
/*
=============
SDLash_JoyInit_Old
=============
*/
static int SDLash_JoyInit_Old( int numjoy )
{
int num;
int i;
Con_Reportf( "Joystick: SDL\n" );
if( SDL_WasInit( SDL_INIT_JOYSTICK ) != SDL_INIT_JOYSTICK &&
SDL_InitSubSystem( SDL_INIT_JOYSTICK ) )
{
Con_Reportf( "Failed to initialize SDL Joysitck: %s\n", SDL_GetError() );
return 0;
}
if( g_joy )
{
SDL_JoystickClose( g_joy );
}
num = SDL_NumJoysticks();
if( num > 0 )
Con_Reportf( "%i joysticks found:\n", num );
else
{
Con_Reportf( "No joystick found.\n" );
return 0;
}
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
for( i = 0; i < num; i++ )
Con_Reportf( "%i\t: %s\n", i, SDL_JoystickNameForIndex( i ) );
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
Con_Reportf( "Pass +set joy_index N to command line, where N is number, to select active joystick\n" );
g_joy = SDL_JoystickOpen( numjoy );
if( !g_joy )
{
Con_Reportf( "Failed to select joystick: %s\n", SDL_GetError( ) );
return 0;
}
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
Con_Reportf( "Selected joystick: %s\n"
"\tAxes: %i\n"
"\tHats: %i\n"
"\tButtons: %i\n"
"\tBalls: %i\n",
SDL_JoystickName( g_joy ), SDL_JoystickNumAxes( g_joy ), SDL_JoystickNumHats( g_joy ),
SDL_JoystickNumButtons( g_joy ), SDL_JoystickNumBalls( g_joy ) );
SDL_GameControllerEventState( SDL_DISABLE );
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
SDL_JoystickEventState( SDL_ENABLE );
return num;
}
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
/*
=============
SDLash_JoyInit_New
=============
*/
static int SDLash_JoyInit_New( int numjoy )
{
int count, numJoysticks, i;
Con_Reportf( "Joystick: SDL GameController API\n" );
if( SDL_WasInit( SDL_INIT_GAMECONTROLLER ) != SDL_INIT_GAMECONTROLLER &&
SDL_InitSubSystem( SDL_INIT_GAMECONTROLLER ) )
{
Con_Reportf( "Failed to initialize SDL GameController API: %s\n", SDL_GetError() );
return 0;
}
SDL_GameControllerAddMappingsFromFile( "controllermappings.txt" );
count = 0;
numJoysticks = SDL_NumJoysticks();
for ( i = 0; i < numJoysticks; i++ )
if( SDL_IsGameController( i ) )
++count;
return count;
}
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
/*
=============
Platform_JoyInit
=============
*/
int Platform_JoyInit( int numjoy )
{
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
// SDL_Joystick is now an old API
// SDL_GameController is preferred
if( !Sys_CheckParm( "-sdl_joy_old_api" ) )
return SDLash_JoyInit_New(numjoy);
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
return SDLash_JoyInit_Old(numjoy);
}
/*
========================
SDLash_InitCursors
@@ -288,3 +418,5 @@ key_modifier_t Platform_GetKeyModifiers( void )
return KeyModifier_None;
#endif
}
#endif // XASH_DEDICATED

View File

@@ -1,391 +0,0 @@
/*
joy_sdl.c - SDL gamepads
Copyright (C) 2018-2025 a1batross
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include <SDL.h>
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
#include "common.h"
#include "keydefs.h"
#include "input.h"
#include "client.h"
#include "events.h"
static const int g_button_mapping[] =
{
#if XASH_NSWITCH // devkitPro/SDL has inverted Nintendo layout for SDL_GameController
K_B_BUTTON, K_A_BUTTON, K_Y_BUTTON, K_X_BUTTON,
#else
K_A_BUTTON, K_B_BUTTON, K_X_BUTTON, K_Y_BUTTON,
#endif
K_BACK_BUTTON, K_MODE_BUTTON, K_START_BUTTON,
K_LSTICK, K_RSTICK,
K_L1_BUTTON, K_R1_BUTTON,
K_DPAD_UP, K_DPAD_DOWN, K_DPAD_LEFT, K_DPAD_RIGHT,
K_MISC_BUTTON,
K_PADDLE1_BUTTON, K_PADDLE2_BUTTON, K_PADDLE3_BUTTON, K_PADDLE4_BUTTON,
K_TOUCHPAD,
};
// Swap axis to follow default axis binding:
static const engineAxis_t g_axis_mapping[] =
{
JOY_AXIS_SIDE, // SDL_CONTROLLER_AXIS_LEFTX,
JOY_AXIS_FWD, // SDL_CONTROLLER_AXIS_LEFTY,
JOY_AXIS_PITCH, // SDL_CONTROLLER_AXIS_RIGHTX,
JOY_AXIS_YAW, // SDL_CONTROLLER_AXIS_RIGHTY,
JOY_AXIS_LT, // SDL_CONTROLLER_AXIS_TRIGGERLEFT,
JOY_AXIS_RT, // SDL_CONTROLLER_AXIS_TRIGGERRIGHT,
};
static SDL_JoystickID g_current_gamepad_id = -1; // used to send rumble to
static SDL_GameController *g_current_gamepad;
static SDL_GameController **g_gamepads;
static size_t g_num_gamepads;
#define CALIBRATION_TIME 10.0f
static struct
{
float time;
vec3_t data;
vec3_t calibrated_values;
int samples;
} gyrocal;
static void SDLash_RestartCalibration( void )
{
Joy_SetCalibrationState( JOY_NOT_CALIBRATED );
memset( &gyrocal, 0, sizeof( gyrocal ));
gyrocal.time = host.realtime + CALIBRATION_TIME;
Con_Printf( "Starting gyroscope calibration...\n" );
}
static void SDLash_FinalizeCalibration( void )
{
float data_rate = 10.0f; // let's say we're polling at 10Hz?
int min_samples;
#if SDL_VERSION_ATLEAST( 2, 0, 16 )
data_rate = SDL_GameControllerGetSensorDataRate( g_current_gamepad, SDL_SENSOR_GYRO );
if( !data_rate )
data_rate = 10.0f;
#endif
min_samples = Q_rint( CALIBRATION_TIME * data_rate * 0.75f );
// we waited for few seconds and got too few samples
if( gyrocal.samples <= min_samples )
{
Joy_SetCalibrationState( JOY_FAILED_TO_CALIBRATE );
return;
}
VectorScale( gyrocal.data, 1.0f / gyrocal.samples, gyrocal.calibrated_values );
Joy_SetCalibrationState( JOY_CALIBRATED );
Con_Printf( "Calibration done. Result: %f %f %f\n", gyrocal.calibrated_values[0], gyrocal.calibrated_values[1], gyrocal.calibrated_values[2] );
gyrocal.time = 0.0f;
}
static void SDLash_GameControllerAddMappings( const char *name )
{
fs_offset_t len = 0;
byte *p = FS_LoadFile( name, &len, false );
if( !p )
return;
if( len > 0 && len < INT32_MAX ) // function accepts int, SDL3 fixes this
{
SDL_RWops *rwops = SDL_RWFromConstMem( p, (int)len );
SDL_GameControllerAddMappingsFromRW( rwops, true );
}
Mem_Free( p );
}
static void SDLash_SetActiveGameController( SDL_JoystickID id )
{
SDL_GameController *oldgc;
if( g_current_gamepad_id == id )
return;
g_current_gamepad_id = id;
oldgc = g_current_gamepad;
#if SDL_VERSION_ATLEAST( 2, 0, 14 )
SDL_GameControllerSetSensorEnabled( oldgc, SDL_SENSOR_GYRO, SDL_FALSE );
#endif // SDL_VERSION_ATLEAST( 2, 0, 14 )
if( id < 0 )
{
g_current_gamepad = NULL;
Joy_SetCapabilities( false );
Joy_SetCalibrationState( JOY_NOT_CALIBRATED );
}
else
{
qboolean have_gyro = false;
g_current_gamepad = SDL_GameControllerFromInstanceID( id );
#if SDL_VERSION_ATLEAST( 2, 0, 14 )
have_gyro = SDL_GameControllerHasSensor( g_current_gamepad, SDL_SENSOR_GYRO );
if( have_gyro )
{
SDL_GameControllerSetSensorEnabled( g_current_gamepad, SDL_SENSOR_GYRO, SDL_TRUE );
SDLash_RestartCalibration();
}
#endif // SDL_VERSION_ATLEAST( 2, 0, 14 )
Joy_SetCapabilities( have_gyro );
}
}
static void SDLash_GameControllerAdded( int device_index )
{
SDL_GameController *gc;
SDL_GameController **list;
gc = SDL_GameControllerOpen( device_index );
if( !gc )
{
Con_Printf( S_ERROR "SDL_GameControllerOpen: %s\n", SDL_GetError( ));
return;
}
list = Mem_Realloc( host.mempool, g_gamepads, sizeof( *list ) * ( g_num_gamepads + 1 ));
list[g_num_gamepads++] = gc;
g_gamepads = list;
// set as current device if none other set
if( g_current_gamepad_id < 0 )
{
SDL_Joystick *joy = SDL_GameControllerGetJoystick( gc );
if( joy )
SDLash_SetActiveGameController( SDL_JoystickInstanceID( joy ));
}
Con_Printf( "Detected \"%s\" game controller.\nMapping string: %s\n", SDL_GameControllerName( gc ), SDL_GameControllerMapping( gc ));
}
static void SDLash_GameControllerRemoved( SDL_JoystickID id )
{
size_t i;
if( id == g_current_gamepad_id )
SDLash_SetActiveGameController( -1 );
// now close the device
for( i = 0; i < g_num_gamepads; i++ )
{
SDL_GameController *gc = g_gamepads[i];
SDL_Joystick *joy;
if( !gc )
continue;
joy = SDL_GameControllerGetJoystick( gc );
if( !joy )
continue;
if( SDL_JoystickInstanceID( joy ) == id )
{
Con_Printf( "Game controller \"%s\" was disconnected\n", SDL_GameControllerName( gc ));
SDL_GameControllerClose( gc );
g_gamepads[i] = NULL;
}
}
}
static void SDLash_GameControllerSensorUpdate( SDL_ControllerSensorEvent sensor )
{
vec3_t data;
if( sensor.which != g_current_gamepad_id )
return;
if( sensor.sensor != SDL_SENSOR_GYRO )
return;
if( gyrocal.time != 0.0f )
{
if( host.realtime > gyrocal.time )
SDLash_FinalizeCalibration();
VectorAdd( gyrocal.data, sensor.data, gyrocal.data );
gyrocal.samples++;
Joy_SetCalibrationState( JOY_CALIBRATING );
return;
}
VectorSubtract( sensor.data, gyrocal.calibrated_values, data );
Joy_GyroEvent( data );
}
void SDLash_HandleGameControllerEvent( SDL_Event *ev )
{
int x;
switch( ev->type )
{
case SDL_CONTROLLERAXISMOTION:
SDLash_SetActiveGameController( ev->caxis.which );
x = ev->caxis.axis;
if( x >= 0 && x < ARRAYSIZE( g_axis_mapping ))
Joy_AxisMotionEvent( g_axis_mapping[x], ev->caxis.value );
break;
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP:
SDLash_SetActiveGameController( ev->cbutton.which );
x = ev->cbutton.button;
if( x >= 0 && x < ARRAYSIZE( g_button_mapping ))
Key_Event( g_button_mapping[x], ev->cbutton.state );
break;
case SDL_CONTROLLERDEVICEREMOVED:
SDLash_GameControllerRemoved( ev->cdevice.which );
break;
case SDL_CONTROLLERDEVICEADDED:
SDLash_GameControllerAdded( ev->cdevice.which );
break;
#if SDL_VERSION_ATLEAST( 2, 0, 14 )
case SDL_CONTROLLERSENSORUPDATE:
SDLash_GameControllerSensorUpdate( ev->csensor );
break;
#endif
}
}
void Platform_CalibrateGamepadGyro( void )
{
SDLash_RestartCalibration();
}
void Platform_Vibrate2( float time, int val1, int val2, uint flags )
{
#if SDL_VERSION_ATLEAST( 2, 0, 9 )
SDL_GameController *gc = g_current_gamepad;
Uint32 ms;
if( g_current_gamepad_id < 0 || !gc )
return;
if( val1 < 0 )
val1 = COM_RandomLong( 0x7FFF, 0xFFFF );
if( val2 < 0 )
val2 = COM_RandomLong( 0x7FFF, 0xFFFF );
ms = (Uint32)ceil( time );
SDL_GameControllerRumble( gc, val1, val2, ms );
#endif // SDL_VERSION_ATLEAST( 2, 0, 9 )
}
/*
=============
Platform_Vibrate
=============
*/
void Platform_Vibrate( float time, char flags )
{
Platform_Vibrate2( time, -1, -1, flags );
}
/*
=============
Platform_JoyInit
=============
*/
int Platform_JoyInit( void )
{
int count, numJoysticks, i;
Con_Reportf( "Joystick: SDL GameController API\n" );
if( SDL_WasInit( SDL_INIT_GAMECONTROLLER ) != SDL_INIT_GAMECONTROLLER &&
SDL_InitSubSystem( SDL_INIT_GAMECONTROLLER ))
{
Con_Reportf( "Failed to initialize SDL GameController API: %s\n", SDL_GetError( ));
return 0;
}
SDLash_GameControllerAddMappings( "gamecontrollerdb.txt" ); // shipped in extras.pk3
SDLash_GameControllerAddMappings( "controllermappings.txt" );
count = 0;
numJoysticks = SDL_NumJoysticks();
for ( i = 0; i < numJoysticks; i++ )
{
if( SDL_IsGameController( i ))
++count;
}
return count;
}
/*
=============
Platform_JoyShutdown
=============
*/
void Platform_JoyShutdown( void )
{
size_t i;
SDLash_SetActiveGameController( -1 );
for( i = 0; i < g_num_gamepads; i++ )
{
if( !g_gamepads[i] )
continue;
SDL_GameControllerClose( g_gamepads[i] );
g_gamepads[i] = NULL;
}
Mem_Free( g_gamepads );
g_gamepads = NULL;
g_num_gamepads = 0;
SDL_QuitSubSystem( SDL_INIT_GAMECONTROLLER );
}
#else // SDL_VERSION_ATLEAST( 2, 0, 0 )
void Platform_Vibrate( float time, char flags )
{
}
int Platform_JoyInit( void )
{
return 0;
}
void Platform_JoyShutdown( void )
{
}
#endif

View File

@@ -175,7 +175,7 @@ qboolean SNDDMA_Init( void )
if( !samplecount )
samplecount = 0x8000;
dma.samples = samplecount * obtained.channels;
dma.buffer = Mem_Malloc( sndpool, dma.samples * 2 );
dma.buffer = Z_Calloc( dma.samples * 2 );
dma.samplepos = 0;
sdl_format = obtained.format;

View File

@@ -20,9 +20,9 @@ GNU General Public License for more details.
#if XASH_TIMER == TIMER_SDL
double Platform_DoubleTime( void )
{
static Uint64 g_PerformanceFrequency;
static Uint64 g_ClockStart;
Uint64 CurrentTime;
static longtime_t g_PerformanceFrequency;
static longtime_t g_ClockStart;
longtime_t CurrentTime;
if( !g_PerformanceFrequency )
{
@@ -78,19 +78,8 @@ static void SDLCALL SDLash_LogOutputFunction( void *userdata, int category, SDL_
}
}
void SDLash_Init( const char *basedir )
void SDLash_Init( void )
{
#if XASH_APPLE
char *path = SDL_GetBasePath();
if( path != NULL )
{
char buf[MAX_VA_STRING];
Q_snprintf( buf, sizeof( buf ), "%s%s/extras.pk3", path, basedir );
setenv( "XASH3D_EXTRAS_PAK1", buf, true );
}
#endif
SDL_LogSetOutputFunction( SDLash_LogOutputFunction, NULL );
if( host_developer.value >= 2 )

View File

@@ -145,7 +145,7 @@ void Wcon_ShowConsole( qboolean show )
void Wcon_DisableInput( void )
{
if( host.type != HOST_DEDICATED || !s_wcd.hWnd )
if( host.type != HOST_DEDICATED )
return;
s_wcd.inputEnabled = false;
@@ -469,9 +469,6 @@ print into window console
*/
void Wcon_WinPrint( const char *pMsg )
{
if( !s_wcd.hWnd )
return;
int nLen;
if( s_wcd.consoleTextLen )
{
@@ -518,18 +515,13 @@ void Wcon_CreateConsole( qboolean con_showalways )
}
s_wcd.attached = ( AttachConsole( ATTACH_PARENT_PROCESS ) != 0 );
if( s_wcd.attached )
{
if( s_wcd.attached ) {
GetConsoleTitle( &s_wcd.previousTitle, sizeof( s_wcd.previousTitle ));
s_wcd.previousCodePage = GetConsoleCP();
s_wcd.previousOutputCodePage = GetConsoleOutputCP();
}
else
{
if( host.type != HOST_DEDICATED && host_developer.value == DEV_NONE )
return; // don't initialize console in case of regular game startup, it's useless anyway
else
AllocConsole();
else {
AllocConsole();
}
SetConsoleTitle( s_wcd.title );
@@ -578,7 +570,7 @@ register console commands (dedicated only)
*/
void Wcon_InitConsoleCommands( void )
{
if( host.type != HOST_DEDICATED || !s_wcd.hWnd )
if( host.type != HOST_DEDICATED )
return;
Cmd_AddCommand( "clear", Wcon_Clear_f, "clear console history" );
@@ -631,7 +623,7 @@ char *Wcon_Input( void )
DWORD eventsCount;
static INPUT_RECORD events[1024];
if( !s_wcd.inputEnabled || !s_wcd.hWnd )
if( !s_wcd.inputEnabled )
return NULL;
while( true )
@@ -674,7 +666,7 @@ set server status string in console
*/
void Platform_SetStatus( const char *pStatus )
{
if( s_wcd.attached || !s_wcd.hWnd )
if( s_wcd.attached )
return;
Q_strncpy( s_wcd.statusLine, pStatus, sizeof( s_wcd.statusLine ) - 1 );

View File

@@ -66,7 +66,6 @@ extern int SV_UPDATE_BACKUP;
#define MAX_PUSHED_ENTS 256
#define MAX_VIEWENTS 128
#define MAX_LOCALINFO_STRING 32768 // localinfo used on server and not sended to the clients
#define MAX_ENT_LEAFS( ext ) (( ext ) ? MAX_ENT_LEAFS_32 : MAX_ENT_LEAFS_16 )
@@ -499,24 +498,10 @@ qboolean SV_ProcessUserAgent( netadr_t from, const char *useragent );
qboolean SV_InitGame( void );
void SV_ActivateServer( int runPhysics );
qboolean SV_SpawnServer( const char *server, const char *startspot, qboolean background );
model_t *SV_ModelHandle( int modelindex );
void SV_DeactivateServer( void );
void SV_FreeTestPacket( void );
/*
================
SV_ModelHandle
get model by handle
================
*/
static inline model_t *GAME_EXPORT SV_ModelHandle( int modelindex )
{
if( modelindex < 0 || modelindex >= MAX_MODELS )
return NULL;
return sv.models[modelindex];
}
//
// sv_phys.c
//
@@ -688,6 +673,7 @@ void SV_ClearGameState( void );
// sv_pmove.c
//
void SV_InitClientMove( void );
qboolean SV_PlayerIsFrozen( edict_t *pClient );
void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd, int random_seed );
//

View File

@@ -305,7 +305,6 @@ static void SV_ConnectClient( netadr_t from )
int challenge;
const char *s;
int extensions;
uint netchan_flags = 0;
if( Cmd_Argc() < 5 )
{
@@ -432,9 +431,7 @@ static void SV_ConnectClient( netadr_t from )
newcl->listeners = -1;
// initailize netchan
if( !Host_IsLocalClient( ))
SetBits( netchan_flags, NETCHAN_USE_LZSS );
Netchan_Setup( NS_SERVER, &newcl->netchan, from, qport, newcl, SV_GetFragmentSize, netchan_flags );
Netchan_Setup( NS_SERVER, &newcl->netchan, from, qport, newcl, SV_GetFragmentSize, 0 );
MSG_Init( &newcl->datagram, "Datagram", newcl->datagram_buf, sizeof( newcl->datagram_buf )); // datagram buf
Q_strncpy( newcl->hashedcdkey, Info_ValueForKey( protinfo, "uuid" ), 32 );
@@ -453,6 +450,8 @@ static void SV_ConnectClient( netadr_t from )
newcl->delta_sequence = -1;
newcl->flags = 0;
// reset any remaining events
memset( &newcl->events, 0, sizeof( newcl->events ));
@@ -478,7 +477,7 @@ static void SV_ConnectClient( netadr_t from )
// reset stats
newcl->next_checkpingtime = -1.0;
newcl->packet_loss = 0;
newcl->packet_loss = 0.0f;
// if this was the first client on the server, or the last client
// the server can hold, send a heartbeat to the master.
@@ -1171,7 +1170,7 @@ SV_EstablishTimeBase
Finangles latency and the like.
===================
*/
static void SV_EstablishTimeBase( sv_client_t *cl, const usercmd_t *cmds, int dropped, int numbackup, int numcmds )
static void SV_EstablishTimeBase( sv_client_t *cl, usercmd_t *cmds, int dropped, int numbackup, int numcmds )
{
double runcmd_time = 0.0;
int i, cmdnum = dropped;
@@ -2870,20 +2869,14 @@ static qboolean SV_EntCreate_f( sv_client_t *cl )
// XashXT does not implement SV_CreateEntity, use saverestore export
if( !ent && svgame.physFuncs.pfnCreateEntitiesInRestoreList )
{
ENTITYTABLE table = {
.classname = classname,
.id = -1,
.size = 1,
.flags = 1337,
};
SAVERESTOREDATA data = {
.tableCount = 1,
.pTable = &table
};
svgame.physFuncs.pfnCreateEntitiesInRestoreList( &data, table.flags, false );
SAVERESTOREDATA data = { 0 };
ENTITYTABLE table = { 0 };
data.tableCount = 1;
data.pTable = &table;
table.classname = classname;
table.id = -1;
table.size = 1;
svgame.physFuncs.pfnCreateEntitiesInRestoreList( &data, 0, false );
ent = table.pent;
}
@@ -3219,20 +3212,6 @@ void SV_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
}
}
static qboolean SV_PlayerIsFrozen( const edict_t *pClient )
{
if( sv_background_freeze.value && sv.background )
return true;
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
return false;
if( FBitSet( pClient->v.flags, FL_FROZEN ))
return true;
return false;
}
/*
==================
SV_ParseClientMove
@@ -3247,20 +3226,29 @@ each of the backup packets.
*/
static void SV_ParseClientMove( sv_client_t *cl, sizebuf_t *msg )
{
const usercmd_t nullcmd = { 0 }, *from = &nullcmd; // first cmd are starting from null-compressed usercmd_t
client_frame_t *frame = &cl->frames[cl->netchan.incoming_acknowledged & SV_UPDATE_MASK];
usercmd_t cmds[CMD_BACKUP] = { 0 }, *to;
edict_t *player = cl->edict;
model_t *model;
client_frame_t *frame;
int key, size, checksum1, checksum2;
int i, numbackup, totalcmds, numcmds;
usercmd_t nullcmd, *to, *from;
usercmd_t cmds[CMD_BACKUP];
float packet_loss;
edict_t *player;
model_t *model;
int key = MSG_GetRealBytesRead( msg );
int checksum1 = MSG_ReadByte( msg );
int packet_loss = MSG_ReadByte( msg );
int numbackup = MSG_ReadByte( msg );
int numcmds = MSG_ReadByte( msg );
int totalcmds = numcmds + numbackup;
int i;
player = cl->edict;
frame = &cl->frames[cl->netchan.incoming_acknowledged & SV_UPDATE_MASK];
memset( &nullcmd, 0, sizeof( usercmd_t ));
memset( cmds, 0, sizeof( cmds ));
key = MSG_GetRealBytesRead( msg );
checksum1 = MSG_ReadByte( msg );
packet_loss = MSG_ReadByte( msg );
numbackup = MSG_ReadByte( msg );
numcmds = MSG_ReadByte( msg );
totalcmds = numcmds + numbackup;
net_drop -= (numcmds - 1);
if( totalcmds < 0 || totalcmds >= CMD_MASK )
@@ -3270,6 +3258,8 @@ static void SV_ParseClientMove( sv_client_t *cl, sizebuf_t *msg )
return;
}
from = &nullcmd; // first cmd are starting from null-compressed usercmd_t
for( i = totalcmds - 1; i >= 0; i-- )
{
to = &cmds[i];
@@ -3280,17 +3270,14 @@ static void SV_ParseClientMove( sv_client_t *cl, sizebuf_t *msg )
if( cl->state != cs_spawned )
return;
if( !Host_IsLocalClient( ))
{
// if the checksum fails, ignore the rest of the packet
int size = MSG_GetRealBytesRead( msg ) - key - 1;
int checksum2 = CRC32_BlockSequence( msg->pData + key + 1, size, cl->netchan.incoming_sequence );
// if the checksum fails, ignore the rest of the packet
size = MSG_GetRealBytesRead( msg ) - key - 1;
checksum2 = CRC32_BlockSequence( msg->pData + key + 1, size, cl->netchan.incoming_sequence );
if( checksum2 != checksum1 )
{
Con_Reportf( S_ERROR "%s: failed command checksum for %s (%d != %d)\n", __func__, cl->name, checksum2, checksum1 );
return;
}
if( checksum2 != checksum1 )
{
Con_Reportf( S_ERROR "%s: failed command checksum for %s (%d != %d)\n", __func__, cl->name, checksum2, checksum1 );
return;
}
cl->packet_loss = packet_loss;

View File

@@ -492,15 +492,14 @@ SV_EmitPings
*/
static void SV_EmitPings( sizebuf_t *msg )
{
sv_client_t *cl;
int i;
sv_client_t *cl;
int packet_loss;
int i, ping;
MSG_BeginServerCmd( msg, svc_pings );
for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ )
{
int packet_loss, ping;
if( cl->state != cs_spawned )
continue;

View File

@@ -273,6 +273,20 @@ int GAME_EXPORT SV_GenericIndex( const char *filename )
return i;
}
/*
================
SV_ModelHandle
get model by handle
================
*/
model_t *GAME_EXPORT SV_ModelHandle( int modelindex )
{
if( modelindex < 0 || modelindex >= MAX_MODELS )
return NULL;
return sv.models[modelindex];
}
static resourcetype_t SV_DetermineResourceType( const char *filename )
{
if( !Q_strncmp( filename, DEFAULT_SOUNDPATH, sizeof( DEFAULT_SOUNDPATH ) - 1 ) && Sound_SupportedFileFormat( COM_FileExtension( filename )))

View File

@@ -23,6 +23,19 @@ GNU General Public License for more details.
static qboolean has_update = false;
static void SV_GetTrueOrigin( sv_client_t *cl, int edictnum, vec3_t origin );
qboolean SV_PlayerIsFrozen( edict_t *pClient )
{
if( sv_background_freeze.value && sv.background )
return true;
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
return false;
if( FBitSet( pClient->v.flags, FL_FROZEN ))
return true;
return false;
}
void SV_ClipPMoveToEntity( physent_t *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, pmtrace_t *tr )
{
Assert( tr != NULL );

View File

@@ -2279,7 +2279,7 @@ int GAME_EXPORT SV_GetSaveComment( const char *savename, char *comment )
if( tag == 0x0065 )
{
Q_strncpy( comment, "<old version "XASH_ENGINE_NAME" unsupported>", MAX_STRING );
Q_strncpy( comment, "<old version Xash3D unsupported>", MAX_STRING );
FS_Close( f );
return 0;
}

View File

@@ -5,19 +5,9 @@
from waflib import Logs
from waflib.extras import pthread
import os
from copy import copy
top = '.'
EXECINFO_TEST = '''#include <execinfo.h>
int main(int argc, char **argv)
{
backtrace(0, 0);
backtrace_symbols(0, 0);
return 0;
}
'''
def options(opt):
grp = opt.add_option_group('Engine options')
@@ -47,85 +37,98 @@ def options(opt):
opt.load('sdl2')
def find_sdl(conf):
err_msg = '%s not available! If you want to build dedicated server, specify --dedicated'
if conf.env.DEST_OS in ['nswitch', 'psvita']:
err_msg = '%s not available!'
conf.load('sdl2')
if conf.options.SDL3:
if not conf.env.HAVE_SDL3:
conf.fatal(err_msg % 'SDL3')
conf.env.XASH_SDL = 3
else:
if not conf.env.HAVE_SDL2:
conf.fatal(err_msg % 'SDL2')
conf.env.XASH_SDL = 2
def configure(conf):
# Common dependencies, will be linked to both dedicated server and client
if conf.env.DEST_OS == 'linux':
conf.check_cc(lib='rt')
if conf.env.MAGX:
conf.define('XASH_CRASHHANDLER', 0)
elif conf.env.DEST_OS == 'haiku':
conf.env.LIB_HAIKU = ['network']
conf.env.LIBPATH_HAIKU = ['/boot/system/lib']
elif conf.env.DEST_OS == 'wasi':
conf.options.NO_ASYNC_RESOLVE = True
conf.env.CFLAGS += ['-mllvm', '-wasm-enable-sjlj']
elif conf.env.DEST_OS == 'sunos':
conf.check_cc(lib='socket')
# check for dedicated server build
if conf.options.DEDICATED:
conf.define('XASH_DEDICATED', 1)
elif conf.env.DEST_OS == 'dos':
conf.options.STATIC = True
conf.options.NO_ASYNC_RESOLVE = True
if not conf.check_cc( fragment='int main(){ int i = socket();}', lib = 'wattcpwl', mandatory=False ):
conf.define('XASH_NO_NETWORK',1)
elif conf.env.DEST_OS == 'nswitch':
# re-enable undefined reference errors
conf.env.CXXFLAGS += ['-Wl,--no-undefined']
conf.env.CFLAGS += ['-Wl,--no-undefined']
# allow the SDL2 sanity check to complete properly by linking in lm normally
conf.env.LDFLAGS += ['-lm']
conf.load('sdl2')
if not conf.env.HAVE_SDL2:
conf.fatal('SDL2 not availiable! Install switch-sdl2!')
conf.define('XASH_SDL', 2)
# then remove them to avoid them getting linked to shared objects
conf.env.LIB_SDL2.remove('stdc++') # remove libstdc++ linking from SDL2, we link it later
conf.env.LDFLAGS.remove('-lm')
elif conf.env.DEST_OS == 'psvita':
# allow the SDL2 sanity check to complete properly by linking in some deps missing from the pkg-config file
extra_libs = ['-lstdc++', '-lm', '-lSceShaccCgExt', '-lSceShaccCg_stub', '-ltaihen_stub', '-lSceKernelDmacMgr_stub']
conf.env.LDFLAGS += extra_libs
conf.load('sdl2')
if not conf.env.HAVE_SDL2:
conf.fatal('SDL2 not availiable! Install switch-sdl2!')
conf.define('XASH_SDL', 2)
# then remove them to avoid them getting linked to shared objects
for lib in extra_libs:
conf.env.LDFLAGS.remove(lib)
elif conf.options.FBDEV_SW:
# unused, XASH_LINUX without XASH_SDL gives fbdev & alsa support
# conf.define('XASH_FBDEV', 1)
conf.check_cc( lib = 'asound' )
elif conf.options.SDL12:
conf.define('XASH_SDL', 12)
conf.check_cfg(package='sdl', args='--cflags --libs', uselib_store='SDL2' )
conf.env.HAVE_SDL2 = True
else:
conf.load('sdl2')
if conf.options.SDL3:
if not conf.env.HAVE_SDL3:
conf.fatal('SDL3 not available! If you want to build dedicated server, specify --dedicated')
conf.define('XASH_SDL', 3)
else:
if not conf.env.HAVE_SDL2:
conf.fatal('SDL2 not available! If you want to build dedicated server, specify --dedicated')
conf.define('XASH_SDL', 2)
if conf.env.DEST_OS == 'haiku':
conf.env.LIB_HAIKU = ['network']
conf.env.LIBPATH_HAIKU = ['/boot/system/lib']
if conf.env.DEST_OS == 'wasi':
conf.options.NO_ASYNC_RESOLVE = True
conf.env.append_unique('CFLAGS', '-mllvm')
conf.env.append_unique('CFLAGS', '-wasm-enable-sjlj')
if conf.env.DEST_OS == 'sunos':
conf.check_cc(lib='socket')
if conf.options.STATIC:
conf.env.STATIC = True
conf.define('XASH_NO_LIBDL',1)
if not conf.env.DEST_OS in ['win32', 'android'] and not conf.options.NO_ASYNC_RESOLVE:
conf.check_pthreads(mode='c')
if conf.env.DEST_OS == 'linux':
conf.check_cc(lib='rt')
if hasattr(conf.options, 'DLLEMU'):
conf.define_cond('XASH_DLL_LOADER', conf.options.DLLEMU)
if conf.env.MAGX:
conf.define('XASH_CRASHHANDLER', 0)
conf.env.ENGINE_TESTS = conf.options.ENGINE_TESTS
if conf.options.ENGINE_FUZZ:
conf.env.append_unique('CFLAGS', '-fsanitize=fuzzer-no-link')
conf.env.append_unique('LINKFLAGS', '-fsanitize=fuzzer')
# Client-only dependencies
if conf.env.CLIENT:
if conf.env.DEST_OS in ['nswitch', 'psvita']:
extra_libs = ['-lm']
if conf.env.DEST_OS == 'psvita':
extra_libs = ['-lstdc++', '-lm', '-lSceShaccCgExt', '-lSceShaccCg_stub', '-ltaihen_stub', '-lSceKernelDmacMgr_stub']
conf.env.append_unique('CXXFLAGS', ['-Wl,--no-undefined'])
conf.env.append_unique('CFLAGS', ['-Wl,--no-undefined'])
conf.env.LDFLAGS += extra_libs
find_sdl(conf)
for lib in extra_libs: conf.env.LDFLAGS.remove(lib)
if conf.env.DEST_OS == 'nswitch': # remove libstdc++ linking from SDL2, we link it later
conf.env.LIB_SDL2.remove('stdc++')
elif conf.env.DEST_OS == 'linux' and conf.options.FBDEV_SW:
conf.check_cc(lib='asound')
elif conf.options.SDL12: # TODO: move to sdl2.py
conf.check_cfg(package='sdl', args='--cflags --libs', uselib_store='SDL2')
conf.env.XASH_SDL = 12
conf.env.HAVE_SDL2 = True
else:
find_sdl(conf)
if conf.options.STATIC:
conf.env.STATIC = True
conf.define('XASH_NO_LIBDL', 1)
if not conf.env.DEST_OS in ['win32', 'android'] and not conf.options.NO_ASYNC_RESOLVE:
conf.check_pthreads(mode='c')
if hasattr(conf.options, 'DLLEMU'):
conf.define_cond('XASH_DLL_LOADER', conf.options.DLLEMU)
conf.check_cc(fragment=EXECINFO_TEST, msg='Checking for glibc backtrace()', mandatory=False, define_name='HAVE_EXECINFO')
conf.define('ENGINE_DLL', 1)
conf.define_cond('XASH_ENGINE_TESTS', conf.options.ENGINE_TESTS)
conf.define_cond('XASH_ENGINE_TESTS', conf.env.ENGINE_TESTS)
conf.define_cond('XASH_STATIC_LIBS', conf.env.STATIC_LINKING)
conf.define_cond('XASH_CUSTOM_SWAP', conf.options.CUSTOM_SWAP)
conf.define_cond('XASH_ENABLE_MAIN', conf.env.DISABLE_LAUNCHER)
conf.define_cond('XASH_NO_ASYNC_NS_RESOLVE', conf.options.NO_ASYNC_RESOLVE)
conf.define_cond('PSAPI_VERSION', conf.env.DEST_OS == 'win32') # will be defined as 1
@@ -136,103 +139,140 @@ def build(bld):
# public includes for renderers and utils use
bld(name = 'engine_includes', export_includes = '. common common/imagelib', use = 'filesystem_includes')
libs = ['engine_includes', 'public', 'dllemu', 'werror']
includes = ['server', 'client', 'client/vgui', 'common/soundlib']
is_cxx_link = False
libs = [ 'engine_includes', 'public', 'dllemu', 'werror' ]
# basic build: dedicated only
source = bld.path.ant_glob(['common/*.c', 'common/imagelib/*.c', 'common/soundlib/*.c', 'server/*.c'])
source = bld.path.ant_glob([
'common/*.c',
'common/imagelib/*.c',
'common/soundlib/*.c',
'server/*.c'])
# include platform-specific sources, this shall not fail if directory doesn't exist
source += bld.path.ant_glob('platform/%s/*.c' % bld.env.DEST_OS)
# Android _is_ Linux based, after all
if bld.env.DEST_OS == 'android':
source += bld.path.ant_glob('platform/linux/*.c')
# include common POSIX conformant code
if bld.env.DEST_OS not in ['win32', 'dos']:
source += bld.path.ant_glob('platform/posix/*.c')
# include sources for optional features
if bld.get_define('XASH_CUSTOM_SWAP'):
source += ['platform/misc/kmalloc.c', 'platform/misc/sbrk.c']
if bld.get_define('XASH_STATIC_LIBS'):
source += ['platform/misc/lib_static.c']
if bld.env.ENGINE_TESTS:
source += bld.path.ant_glob(['tests/*.c'])
if bld.env.DEST_OS == 'win32':
libs += ['USER32', 'SHELL32', 'GDI32', 'ADVAPI32', 'DBGHELP', 'PSAPI', 'WS2_32']
elif bld.env.DEST_OS == 'nswitch':
libs += ['SOLDER']
libs += ['USER32', 'SHELL32', 'GDI32', 'ADVAPI32', 'DBGHELP', 'PSAPI', 'WS2_32' ]
source += bld.path.ant_glob(['platform/win32/*.c'])
elif bld.env.DEST_OS not in ['dos', 'nswitch', 'psvita']: #posix
libs += [ 'M', 'RT', 'PTHREAD', 'ASOUND']
if not bld.env.STATIC:
libs += ['DL']
source += bld.path.ant_glob(['platform/posix/*.c'])
if bld.env.DEST_OS == 'linux':
source += bld.path.ant_glob(['platform/linux/*.c'])
if bld.env.DEST_OS == 'irix':
source += bld.path.ant_glob(['platform/irix/*.c'])
if bld.env.DEST_OS == 'dos':
source += bld.path.ant_glob(['platform/dos/*.c'])
source += bld.path.ant_glob(['platform/stub/s_stub.c'])
if bld.env.DEST_OS == 'haiku':
libs.append('HAIKU')
if bld.get_define('XASH_CUSTOM_SWAP'):
source += bld.path.ant_glob(['platform/misc/kmalloc.c', 'platform/misc/sbrk.c'])
if bld.env.STATIC_LINKING:
source += bld.path.ant_glob(['platform/misc/lib_static.c'])
is_cxx_link = True
if bld.env.HAVE_SDL2 or bld.env.HAVE_SDL3:
libs.append('SDL3' if bld.env.HAVE_SDL3 else 'SDL2')
source += bld.path.ant_glob(['platform/sdl/*.c'])
if bld.env.MAGX:
libs.append('MAGX')
is_cxx_link = True
if bld.env.DEST_OS == 'android':
libs += ['LOG']
source += bld.path.ant_glob(['platform/android/*.cpp', 'platform/android/*.c', 'platform/linux/*.c'])
if bld.env.DEST_OS == 'nswitch':
libs += [ 'SOLDER' ]
source += bld.path.ant_glob(['platform/posix/*.c'])
source += bld.path.ant_glob(['platform/nswitch/*.c'])
# HACK: link in the entirety of libstdc++ so that dynamic libs could use all of it without manual exporting
# we can't do this right away because std::filesystem will complain about not having pathconf(),
# which we have defined in sys_nswitch.c
bld.env.LDFLAGS += ['-v', '-Wl,--whole-archive', '-lstdc++', '-Wl,--no-whole-archive', '-lm']
elif bld.env.DEST_OS == 'psvita':
libs += ['VRTLD']
if bld.env.DEST_OS == 'psvita':
libs += [ 'VRTLD' ]
source += bld.path.ant_glob(['platform/posix/*.c'])
source += bld.path.ant_glob(['platform/psvita/*.c'])
# HACK: link in the entirety of libstdc++ so that dynamic libs could use all of it without manual exporting
# also link in all the funky dependencies that aren't in SDL2's LDFLAGS
bld.env.LDFLAGS += ['-Wl,--whole-archive', '-lstdc++', '-lpthread', '-Wl,--no-whole-archive',
'-lm', '-lSceShaccCgExt', '-lkubridge_stub', '-ltaihen_stub', '-lSceShaccCg_stub', '-lSceKernelModulemgr_stub', '-lSceSblSsMgr_stub', '-lSceVshBridge_stub', '-lSceKernelDmacMgr_stub',
bld.env.LDFLAGS += [
'-Wl,--whole-archive',
'-lstdc++',
'-lpthread',
'-Wl,--no-whole-archive',
'-lm',
'-lSceShaccCgExt',
'-lkubridge_stub',
'-ltaihen_stub',
'-lSceShaccCg_stub',
'-lSceKernelModulemgr_stub',
'-lSceSblSsMgr_stub',
'-lSceVshBridge_stub',
'-lSceKernelDmacMgr_stub'
]
else: # POSIX
libs += ['M', 'RT', 'PTHREAD', 'ASOUND', 'HAIKU', 'MAGX', 'LOG', 'SOCKET']
if not bld.env.STATIC:
libs += ['DL']
if bld.env.SERVER:
# TODO: avoid possible name collision when client is built without launcher
# but dedicated server is enabled. They're both called 'xash' in this case
bld.program(
source = copy(source),
target = 'xash',
use = copy(libs),
includes = includes,
defines = 'XASH_ENABLE_MAIN=1 XASH_DEDICATED=1',
rpath = bld.env.DEFAULT_RPATH,
install_path = bld.env.BINDIR,
)
if bld.env.DEST_OS == 'sunos':
libs.append('SOCKET')
if bld.env.CLIENT:
defines = []
if bld.env.XASH_SDL:
libs += ['SDL3' if bld.env.HAVE_SDL3 else 'SDL2']
source += bld.path.ant_glob(['platform/sdl/*.c'])
defines += ['XASH_SDL=%d' % bld.env.XASH_SDL]
# add client files
if not bld.env.DEDICATED:
source += bld.path.ant_glob([
'client/*.c',
'client/vgui/*.c',
'client/avi/*.c',
'client/soundlib/*.c',
'client/soundlib/libmpg/*.c',
])
is_cxx_link = True
libs += ['bzip2', 'MultiEmulator', 'opus', 'opusfile', 'vorbis', 'vorbisfile']
# add client files
if not bld.env.DEDICATED:
source += bld.path.ant_glob('client/**/*.c')
libs += ['bzip2', 'MultiEmulator', 'opus', 'opusfile', 'vorbis', 'vorbisfile']
rpath = bld.env.DEFAULT_RPATH
# Android port is linked differently
if bld.env.DEST_OS == 'android':
f = bld.shlib
install_path = bld.env.LIBDIR
defines += ['XASH_ENABLE_MAIN=1', 'XASH_SDLMAIN=1']
elif not bld.env.LAUNCHER:
f = bld.program
install_path = bld.env.BINDIR
defines += ['XASH_ENABLE_MAIN=1']
# Switch and PSVita have custom parameters
if bld.env.DEST_OS in ['nswitch', 'psvita']:
rpath = None
install_path = None
features = 'cxx c cxxprogram cprogram'
# Always build as shared library on Android
elif bld.env.DISABLE_LAUNCHER and bld.env.DEST_OS != 'android':
install_path = bld.env.BINDIR
if bld.env.STATIC:
features = 'cxx c cxxprogram_static cprogram_static'
elif is_cxx_link:
features = 'cxx c cxxprogram cprogram'
else:
f = bld.shlib
install_path = bld.env.LIBDIR
features = 'c cprogram'
else:
install_path = bld.env.LIBDIR
if is_cxx_link:
features = 'cxx c cxxshlib cshlib'
else:
features = 'c cshlib'
if bld.env.DEST_OS in ['nswitch', 'psvita']:
install_path = None
f(source = source,
target = 'xash',
includes = includes,
features = 'cxx c',
use = libs,
defines = defines,
install_path = install_path,
special_install_path = bld.env.BINDIR,
nacp = 'platform/nswitch/xash3d-fwgs.nacp',
icon = 'platform/nswitch/icon.jpg',
sce_sys = 'platform/psvita/sce_sys',
title_id = 'XASH10000',
app_name = 'xash3d-fwgs',
rpath = bld.env.DEFAULT_RPATH,
)
bld(source = source,
target = 'xash',
features = features,
includes = 'server client client/vgui common/soundlib',
use = libs,
install_path = install_path,
nro_install_path = bld.env.BINDIR,
nacp = 'platform/nswitch/xash3d-fwgs.nacp',
icon = 'platform/nswitch/icon.jpg',
sce_sys = 'platform/psvita/sce_sys',
title_id = 'XASH10000',
app_name = 'xash3d-fwgs',
rpath = rpath,
)

View File

@@ -242,7 +242,7 @@ static byte *FS_LoadAndroidAssetsFile( searchpath_t *search, const char *path, i
if( filesize ) *filesize = 0;
asset = AAssetManager_open( search->assets->asset_manager, path, AASSET_MODE_BUFFER );
asset = AAssetManager_open( search->assets->asset_manager, path, AASSET_MODE_RANDOM );
if( !asset )
return NULL;

View File

@@ -49,7 +49,6 @@ GNU General Public License for more details.
#include "common/protocol.h"
#define FILE_COPY_SIZE (1024 * 1024)
#define SAVE_AGED_COUNT 2 // the default count of quick and auto saves
fs_globals_t FI;
qboolean fs_ext_path = false; // attempt to read\write from ./ or ../ pathes
@@ -448,7 +447,6 @@ FS_ClearSearchPath
void FS_ClearSearchPath( void )
{
searchpath_t *cur, **prev;
int i;
prev = &fs_searchpaths;
@@ -470,12 +468,6 @@ void FS_ClearSearchPath( void )
cur->pfnClose( cur );
Mem_Free( cur );
}
for( i = 0; i < FI.numgames; i++ )
{
if( FI.games[i] )
FI.games[i]->added = false;
}
}
/*
@@ -636,11 +628,13 @@ static qboolean FS_WriteGameInfo( const char *filepath, gameinfo_t *GameInfo )
if( GameInfo->noskills )
FS_Printf( f, "noskills\t\t\"%i\"\n", GameInfo->noskills );
#define SAVE_AGED_COUNT 2 // the default count of quick and auto saves
if( GameInfo->quicksave_aged_count != SAVE_AGED_COUNT )
FS_Printf( f, "quicksave_aged_count\t\t%d\n", GameInfo->quicksave_aged_count );
if( GameInfo->autosave_aged_count != SAVE_AGED_COUNT )
FS_Printf( f, "autosave_aged_count\t\t%d\n", GameInfo->autosave_aged_count );
#undef SAVE_AGED_COUNT
// HL25 compatibility
if( GameInfo->animated_title )
@@ -706,9 +700,6 @@ static void FS_InitGameInfo( gameinfo_t *GameInfo, const char *gamedir, qboolean
GameInfo->max_beams = 128;
GameInfo->max_particles = 4096;
GameInfo->version = 1.0f;
GameInfo->quicksave_aged_count = SAVE_AGED_COUNT;
GameInfo->autosave_aged_count = SAVE_AGED_COUNT;
}
static void FS_ParseGenericGameInfo( gameinfo_t *GameInfo, const char *buf, const qboolean isGameInfo )
@@ -1129,7 +1120,7 @@ static qboolean FS_ParseGameInfo( const char *gamedir, gameinfo_t *GameInfo, qbo
if( rodir )
Q_snprintf( gamedir_path, sizeof( gamedir_path ), "%s/%s", fs_rodir, gamedir );
else
Q_snprintf( gamedir_path, sizeof( gamedir_path ), "%s", gamedir );
Q_snprintf( gamedir_path, sizeof( gamedir_path ), "%s/%s", fs_rootdir, gamedir );
if( !FS_CheckForXashGameDir( gamedir_path ))
{
@@ -1199,11 +1190,11 @@ void FS_AddGameHierarchy( const char *dir, uint flags )
qboolean isGameDir = flags & FS_GAMEDIR_PATH;
char buf[MAX_VA_STRING];
GI->added = true;
if( !COM_CheckString( dir ))
return;
Con_Printf( "%s( %s )\n", __func__, dir );
// add the common game directory
// recursive gamedirs
@@ -1214,21 +1205,12 @@ void FS_AddGameHierarchy( const char *dir, uint flags )
{
dir = FI.games[i]->gamefolder; // fixup directory case
if( FI.games[i]->added ) // already added, refusing
break;
// don't add our game directory as base dir to prevent cyclic dependency
if( Q_stricmp( FI.games[i]->basedir, GI->gamefolder ))
break;
// don't add directory which basedir is equal to this gamefolder to prevent
// endless loop
if( Q_stricmp( FI.games[i]->basedir, FI.games[i]->gamefolder ))
break;
Con_Reportf( "%s: adding recursive basedir %s\n", __func__, FI.games[i]->basedir );
FI.games[i]->added = true;
FS_AddGameHierarchy( FI.games[i]->basedir, flags & (~FS_GAMEDIR_PATH));
if( !FI.games[i]->added && Q_stricmp( FI.games[i]->gamefolder, FI.games[i]->basedir ))
{
FI.games[i]->added = true;
FS_AddGameHierarchy( FI.games[i]->basedir, flags & (~FS_GAMEDIR_PATH) );
}
break;
}
}
@@ -1285,8 +1267,6 @@ void FS_Rescan( void )
FS_AddGameHierarchy( GI->basedir, 0 );
if( Q_stricmp( GI->basedir, GI->falldir ) && Q_stricmp( GI->gamefolder, GI->falldir ))
FS_AddGameHierarchy( GI->falldir, 0 );
GI->added = true;
FS_AddGameHierarchy( GI->gamefolder, FS_GAMEDIR_PATH );
}
@@ -2242,12 +2222,6 @@ int FS_Close( file_t *file )
return EOF;
}
if( file->ztk )
{
inflateEnd( &file->ztk->zstream );
Mem_Free( file->ztk );
}
Mem_Free( file );
return 0;
}
@@ -2353,93 +2327,7 @@ fs_offset_t FS_Read( file_t *file, void *buffer, size_t buffersize )
// NOTE: at this point, the read buffer is always empty
FS_EnsureOpenFile( file ); // FIXME: broken XASH_REDUCE_FD in case of compressed files!
if( FBitSet( file->flags, FILE_DEFLATED ))
{
// If the file is compressed, it's more complicated...
// We cycle through a few operations until we have read enough data
while( buffersize > 0 )
{
ztoolkit_t *ztk = file->ztk;
int error;
// NOTE: at this point, the read buffer is always empty
// If "input" is also empty, we need to refill it
if( ztk->in_ind == ztk->in_len )
{
// If we are at the end of the file
if( file->position == file->real_length )
return done;
count = (fs_offset_t)( ztk->comp_length - ztk->in_position );
if( count > (fs_offset_t)sizeof( ztk->input ))
count = (fs_offset_t)sizeof( ztk->input );
lseek( file->handle, file->offset + (fs_offset_t)ztk->in_position, SEEK_SET );
if( read( file->handle, ztk->input, count ) != count )
{
Con_Printf( "%s: unexpected end of file\n", __func__ );
break;
}
ztk->in_ind = 0;
ztk->in_len = count;
ztk->in_position += count;
}
ztk->zstream.next_in = &ztk->input[ztk->in_ind];
ztk->zstream.avail_in = (unsigned int)( ztk->in_len - ztk->in_ind );
// Now that we are sure we have compressed data available, we need to determine
// if it's better to inflate it in "file->buff" or directly in "buffer"
// Inflate the data in "file->buff"
if( buffersize < sizeof( file->buff ) / 2 )
{
ztk->zstream.next_out = file->buff;
ztk->zstream.avail_out = sizeof( file->buff );
}
else
{
ztk->zstream.next_out = &((unsigned char*)buffer)[done];
ztk->zstream.avail_out = (unsigned int)buffersize;
}
error = inflate( &ztk->zstream, Z_SYNC_FLUSH );
if( error != Z_OK && error != Z_STREAM_END )
{
Con_Printf( "%s: Can't inflate file (%d)\n", __func__, error );
break;
}
ztk->in_ind = ztk->in_len - ztk->zstream.avail_in;
if( buffersize < sizeof( file->buff ) / 2 )
{
file->buff_len = (fs_offset_t)sizeof( file->buff ) - ztk->zstream.avail_out;
file->position += file->buff_len;
// Copy the requested data in "buffer" (as much as we can)
count = (fs_offset_t)buffersize > file->buff_len ? file->buff_len : (fs_offset_t)buffersize;
memcpy( &((unsigned char*)buffer)[done], file->buff, count );
file->buff_ind = count;
}
else
{
count = (fs_offset_t)( buffersize - ztk->zstream.avail_out );
file->position += count;
// Purge cached data
FS_Purge( file );
}
done += count;
buffersize -= count;
}
return done;
}
FS_EnsureOpenFile( file );
// we must take care to not read after the end of the file
count = file->real_length - file->position;
@@ -2655,59 +2543,11 @@ int FS_Seek( file_t *file, fs_offset_t offset, int whence )
// Purge cached data
FS_Purge( file );
if( FBitSet( file->flags, FILE_DEFLATED ))
{
// Seeking in compressed files is more a hack than anything else,
// but we need to support it, so here we go.
ztoolkit_t *ztk = file->ztk;
unsigned char *buffer;
fs_offset_t buffersize;
// If we have to go back in the file, we need to restart from the beginning
if( offset <= file->position )
{
ztk->in_ind = 0;
ztk->in_len = 0;
ztk->in_position = 0;
file->position = 0;
if( lseek( file->handle, file->offset, SEEK_SET ) == -1 )
Con_Printf("IMPOSSIBLE: couldn't seek in already opened pk3 file.\n");
// Reset the Zlib stream
ztk->zstream.next_in = ztk->input;
ztk->zstream.avail_in = 0;
inflateReset( &ztk->zstream );
}
// We need a big buffer to force inflating into it directly
buffersize = 2 * sizeof( file->buff );
buffer = (unsigned char *)Mem_Malloc( fs_mempool, buffersize );
// Skip all data until we reach the requested offset
while( offset > ( file->position - file->buff_len + file->buff_ind ))
{
fs_offset_t diff = offset - ( file->position - file->buff_len + file->buff_ind );
fs_offset_t count;
count = ( diff > buffersize ) ? buffersize : diff;
if( FS_Read( file, buffer, count ) != count )
{
Mem_Free( buffer );
return -1;
}
}
Mem_Free( buffer );
return 0;
}
if( lseek( file->handle, file->offset + offset, SEEK_SET ) == -1 )
return -1;
file->position = offset;
return 0;
}
/*
@@ -2865,20 +2705,25 @@ qboolean CRC32_File( dword *crcvalue, const char *filename )
qboolean MD5_HashFile( byte digest[16], const char *pszFileName, uint seed[4] )
{
file_t *file;
MD5Context_t MD5_Hash = { 0 };
byte buffer[1024];
MD5Context_t MD5_Hash;
int bytes;
if(( file = FS_Open( pszFileName, "rb", false )) == NULL )
return false;
memset( &MD5_Hash, 0, sizeof( MD5Context_t ));
MD5Init( &MD5_Hash );
if( seed )
{
MD5Update( &MD5_Hash, (const byte *)seed, 16 );
}
while( 1 )
{
byte buffer[1024];
int bytes = FS_Read( file, buffer, sizeof( buffer ));
bytes = FS_Read( file, buffer, sizeof( buffer ));
if( bytes > 0 )
MD5Update( &MD5_Hash, buffer, bytes );

View File

@@ -143,8 +143,6 @@ typedef struct fs_globals_t
int numgames;
} fs_globals_t;
typedef struct file_s file_t;
typedef struct fs_api_t
{
qboolean (*InitStdio)( qboolean unused_set_to_true, const char *rootdir, const char *basedir, const char *gamedir, const char *rodir );

View File

@@ -22,7 +22,6 @@ GNU General Public License for more details.
#include <stdlib.h>
#include "xash3d_types.h"
#include "filesystem.h"
#include "miniz.h"
#if XASH_ANDROID
#include <android/asset_manager.h>
@@ -41,16 +40,6 @@ typedef struct wfile_s wfile_t;
typedef struct android_assets_s android_assets_t;
#define FILE_BUFF_SIZE (2048)
#define FILE_DEFLATED BIT( 0 )
typedef struct ztoolkit_s
{
z_stream zstream;
size_t comp_length;
size_t in_ind, in_len;
size_t in_position;
byte input[FILE_BUFF_SIZE];
} ztoolkit_t;
struct file_s
{
@@ -61,9 +50,7 @@ struct file_s
fs_offset_t real_length; // uncompressed file size (for files opened in "read" mode)
fs_offset_t position; // current position in the file
fs_offset_t offset; // offset into the package (0 if external file)
uint32_t flags;
ztoolkit_t *ztk; // if not NULL, all read functions must go through decompression
// contents buffer
fs_offset_t buff_ind; // buffer current index
fs_offset_t buff_len; // buffer current length

View File

@@ -92,19 +92,20 @@ struct wfile_s
typedef struct wadtype_s
{
char ext[4];
signed char type;
const char *ext;
signed char type;
} wadtype_t;
// associate extension with wad type
static const wadtype_t wad_types[] =
static const wadtype_t wad_types[7] =
{
{ "pal", TYP_PALETTE }, // palette
{ "dds", TYP_DDSTEX }, // DDS image
{ "lmp", TYP_GFXPIC }, // quake1, hl pic
{ "fnt", TYP_QFONT }, // hl qfonts
{ "mip", TYP_MIPTEX }, // hl/q1 mip
{ "txt", TYP_SCRIPT }, // scripts
{ "pal", TYP_PALETTE }, // palette
{ "dds", TYP_DDSTEX }, // DDS image
{ "lmp", TYP_GFXPIC }, // quake1, hl pic
{ "fnt", TYP_QFONT }, // hl qfonts
{ "mip", TYP_MIPTEX }, // hl/q1 mip
{ "txt", TYP_SCRIPT }, // scripts
{ NULL, TYP_NONE }
};
/*
@@ -116,19 +117,18 @@ Extracts file type from extension
*/
static signed char W_TypeFromExt( const char *lumpname )
{
const char *ext = COM_FileExtension( lumpname );
int i;
const char *ext = COM_FileExtension( lumpname );
const wadtype_t *type;
// we not known about filetype, so match only by filename
if( !Q_strcmp( ext, "*" ) || !COM_CheckStringEmpty( ext ))
return TYP_ANY;
for( i = 0; i < sizeof( wad_types ) / sizeof( wad_types[0] ); i++ )
for( type = wad_types; type->ext; type++ )
{
if( !Q_stricmp( ext, wad_types[i].ext ))
return wad_types[i].type;
if( !Q_stricmp( ext, type->ext ))
return type->type;
}
return TYP_NONE;
}
@@ -141,18 +141,17 @@ Convert type to extension
*/
static const char *W_ExtFromType( signed char lumptype )
{
int i;
const wadtype_t *type;
// we not known aboyt filetype, so match only by filename
if( lumptype == TYP_NONE || lumptype == TYP_ANY )
return "";
for( i = 0; i < sizeof( wad_types ) / sizeof( wad_types[0] ); i++ )
for( type = wad_types; type->ext; type++ )
{
if( lumptype == wad_types[i].type )
return wad_types[i].ext;
if( lumptype == type->type )
return type->ext;
}
return "";
}

View File

@@ -27,6 +27,7 @@ GNU General Public License for more details.
#include "filesystem_internal.h"
#include "crtlib.h"
#include "common/com_strings.h"
#include "miniz.h"
#define ZIP_HEADER_LF (('K'<<8)+('P')+(0x03<<16)+(0x04<<24))
#define ZIP_HEADER_SPANNED ((0x08<<24)+(0x07<<16)+('K'<<8)+'P')
@@ -388,43 +389,15 @@ Open a packed file using its package file descriptor
static file_t *FS_OpenFile_ZIP( searchpath_t *search, const char *filename, const char *mode, int pack_ind )
{
zipfile_t *pfile = &search->zip->files[pack_ind];
file_t *f = FS_OpenHandle( search, search->zip->handle->handle, pfile->offset, pfile->size );
if( !f )
return NULL;
if( pfile->flags == ZIP_COMPRESSION_DEFLATED )
// compressed files handled in Zip_LoadFile
if( pfile->flags != ZIP_COMPRESSION_NO_COMPRESSION )
{
ztoolkit_t *ztk;
SetBits( f->flags, FILE_DEFLATED );
ztk = Mem_Calloc( fs_mempool, sizeof( *ztk ));
ztk->comp_length = pfile->compressed_size;
ztk->zstream.next_in = ztk->input;
ztk->zstream.avail_in = 0;
if( inflateInit2( &ztk->zstream, -MAX_WBITS ) != Z_OK )
{
Con_Printf( "%s: inflate init error (file: %s)\n", __func__, filename );
FS_Close( f );
Mem_Free( ztk );
return NULL;
}
ztk->zstream.next_out = f->buff;
ztk->zstream.avail_out = sizeof( f->buff );
f->ztk = ztk;
}
else if( pfile->flags != ZIP_COMPRESSION_NO_COMPRESSION )
{
Con_Reportf( S_ERROR "%s: %s: file compressed with unknown algorithm.\n", __func__, filename );
FS_Close( f );
Con_Printf( S_ERROR "%s: can't open compressed file %s\n", __func__, pfile->name );
return NULL;
}
return f;
return FS_OpenHandle( search, search->zip->handle->handle, pfile->offset, pfile->size );
}
/*

View File

@@ -33,6 +33,26 @@ void Q_strnlwr( const char *in, char *out, size_t size_out )
out[i] = Q_tolower( out[i] );
}
size_t Q_colorstr( const char *string )
{
const char *p = string;
size_t len = 0;
if( !string )
return len;
while(( p = Q_strchr( p, '^' )))
{
if( IsColorString( p ))
{
len += 2;
p += 2;
}
}
return len;
}
int Q_atoi_hex( int sign, const char *str )
{
int c, val = 0;

View File

@@ -70,6 +70,7 @@ extern const char *g_buildbranch;
//
void Q_strnlwr( const char *in, char *out, size_t size_out );
#define Q_strlen( str ) (( str ) ? strlen(( str )) : 0 )
size_t Q_colorstr( const char *string );
int Q_atoi_hex( int sign, const char *str );
int Q_atoi( const char *str );
float Q_atof( const char *str );
@@ -107,12 +108,6 @@ int matchpattern_with_separator( const char *in, const char *pattern, qboolean c
//
// dllhelpers.c
//
typedef struct dllfunc_s
{
const char *name;
void **func;
} dllfunc_t;
void ClearExports( const dllfunc_t *funcs, size_t num_funcs );
qboolean ValidateExports( const dllfunc_t *funcs, size_t num_funcs );

View File

@@ -46,6 +46,17 @@ static int Test_Strnlwr( void )
return 0;
}
static int Test_Colorstr( void )
{
if( Q_colorstr( "^1color^2string" ) != 4 )
return 1;
if( Q_colorstr( "colorlessstring" ) != 0 )
return 2;
return 0;
}
static int Test_FixSlashes( void )
{
string s = "path\\with\\back\\slashes";
@@ -82,6 +93,11 @@ int main( void )
if( ret > 0 )
return ret + 16;
ret = Test_Colorstr();
if( ret > 0 )
return ret + 32;
ret = Test_FixSlashes();
if( ret > 0 )

View File

@@ -114,35 +114,27 @@ uint32_t Q_DecodeUTF16( utfstate_t *s, uint32_t in )
return 0;
}
static size_t Q_CodepointLength( uint32_t ch )
{
if( ch <= 0x7fu )
return 1;
else if( ch <= 0x7ffu )
return 2;
else if( ch <= 0xffffu )
return 3;
return 4;
}
size_t Q_EncodeUTF8( char dst[4], uint32_t ch )
{
switch( Q_CodepointLength( ch ))
if( ch <= 0x7fu )
{
case 1:
dst[0] = ch;
return 1;
case 2:
}
else if( ch <= 0x7ffu )
{
dst[0] = 0xc0u | (( ch >> 6 ) & 0x1fu );
dst[1] = 0x80u | (( ch ) & 0x3fu );
return 2;
case 3:
}
else if( ch <= 0xffffu )
{
dst[0] = 0xe0u | (( ch >> 12 ) & 0x0fu );
dst[1] = 0x80u | (( ch >> 6 ) & 0x3fu );
dst[2] = 0x80u | (( ch ) & 0x3fu );
return 3;
}
dst[0] = 0xf0u | (( ch >> 18 ) & 0x07u );
dst[1] = 0x80u | (( ch >> 12 ) & 0x3fu );
dst[2] = 0x80u | (( ch >> 6 ) & 0x3fu );
@@ -171,6 +163,18 @@ size_t Q_UTF8Length( const char *s )
return len;
}
static size_t Q_CodepointLength( uint32_t ch )
{
if( ch <= 0x7fu )
return 1;
else if( ch <= 0x7ffu )
return 2;
else if( ch <= 0xffffu )
return 3;
return 4;
}
size_t Q_UTF16ToUTF8( char *dst, size_t dstsize, const uint16_t *src, size_t srcsize )
{
utfstate_t state = { 0 };

View File

@@ -185,7 +185,7 @@ int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const mplane_t *p );
//
static inline void Matrix3x4_LoadIdentity( matrix3x4 m )
{
memset( m, 0, sizeof( matrix3x4 ));
memset( m, 0, sizeof( *m ));
m[0][0] = m[1][1] = m[2][2] = 1.0f;
}
#define Matrix3x4_Copy( out, in ) memcpy( out, in, sizeof( matrix3x4 ))
@@ -201,7 +201,7 @@ void Matrix3x4_AnglesFromMatrix( const matrix3x4 in, vec3_t out );
static inline void Matrix4x4_LoadIdentity( matrix4x4 m )
{
memset( m, 0, sizeof( matrix4x4 ));
memset( m, 0, sizeof( *m ));
m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f;
}
#define Matrix4x4_Copy( out, in ) memcpy( out, in, sizeof( matrix4x4 ))

View File

@@ -192,7 +192,7 @@ static void APIENTRY GL2_BindTexture( GLenum tex, GLuint obj )
static char *GL_PrintInfoLog( GLhandleARB object, qboolean program )
{
static char msg[8192];
GLuint maxLength = 0;
int maxLength = 0;
if( program && pglGetProgramiv )
pglGetProgramiv( object, GL_OBJECT_INFO_LOG_LENGTH_ARB, &maxLength );
@@ -282,8 +282,8 @@ static GLuint GL2_GenerateShader( gl2wrap_prog_t *prog, GLenum type )
static gl2wrap_prog_t *GL2_GetProg( const GLuint flags )
{
int i, loc;
GLuint status = 0, vp, fp, glprog;
int i, loc, status;
GLuint vp, fp, glprog;
gl2wrap_prog_t *prog;
// try to find existing prog matching this feature set
@@ -352,7 +352,6 @@ static gl2wrap_prog_t *GL2_GetProg( const GLuint flags )
pglGetProgramiv( glprog, GL_OBJECT_LINK_STATUS_ARB, &status );
else
pglGetObjectParameterivARB( glprog, GL_OBJECT_LINK_STATUS_ARB, &status );
if( status == GL_FALSE )
{
gEngfuncs.Con_Reportf( S_ERROR "%s: Failed linking progs for 0x%04x!\n%s\n", __func__, prog->flags, GL_PrintInfoLog( glprog, true ));

View File

@@ -88,13 +88,11 @@ static void Mod_BrushUnloadTextures( model_t *mod )
for( i = 0; i < mod->numtextures; i++ )
{
texture_t *tx = mod->textures[i];
if( !tx )
if( !tx || tx->gl_texturenum == tr.defaultTexture )
continue; // free slot
if( tx->gl_texturenum != tr.defaultTexture )
GL_FreeTexture( tx->gl_texturenum ); // main texture
GL_FreeTexture( tx->fb_texturenum ); // luma texture
GL_FreeTexture( tx->dt_texturenum ); // detail texture
GL_FreeTexture( tx->gl_texturenum ); // main texture
GL_FreeTexture( tx->fb_texturenum ); // luma texture
}
}
@@ -124,35 +122,33 @@ static void Mod_UnloadTextures( model_t *mod )
static qboolean Mod_ProcessRenderData( model_t *mod, qboolean create, const byte *buf )
{
qboolean loaded = false;
qboolean loaded = true;
if( create )
{
switch( mod->type )
{
case mod_studio:
// Mod_LoadStudioModel( mod, buf, loaded );
break;
case mod_sprite:
Mod_LoadSpriteModel( mod, buf, &loaded, mod->numtexinfo );
break;
case mod_alias:
Mod_LoadAliasModel( mod, buf, &loaded );
break;
case mod_brush:
// Mod_LoadBrushModel( mod, buf, loaded );
break;
default: gEngfuncs.Host_Error( "%s: unsupported type %d\n", __func__, mod->type );
}
}
if( loaded && gEngfuncs.drawFuncs->Mod_ProcessUserData )
gEngfuncs.drawFuncs->Mod_ProcessUserData( mod, create, buf );
if( !create )
{
if( gEngfuncs.drawFuncs->Mod_ProcessUserData )
gEngfuncs.drawFuncs->Mod_ProcessUserData( mod, false, buf );
Mod_UnloadTextures( mod );
return true;
}
switch( mod->type )
{
case mod_studio:
case mod_brush:
loaded = true;
break;
case mod_sprite:
Mod_LoadSpriteModel( mod, buf, &loaded, mod->numtexinfo );
break;
case mod_alias:
Mod_LoadAliasModel( mod, buf, &loaded );
break;
default:
gEngfuncs.Host_Error( "%s: unsupported type %d\n", __func__, mod->type );
return false;
}
if( gEngfuncs.drawFuncs->Mod_ProcessUserData )
gEngfuncs.drawFuncs->Mod_ProcessUserData( mod, true, buf );
return loaded;
}

View File

@@ -16,7 +16,7 @@ GNU General Public License for more details.
#include "gl_local.h"
#include "xash3d_mathlib.h"
static void GL_FrustumSetPlane( gl_frustum_t *out, int side, const vec3_t vecNormal, float flDist )
void GL_FrustumSetPlane( gl_frustum_t *out, int side, const vec3_t vecNormal, float flDist )
{
Assert( side >= 0 && side < FRUSTUM_PLANES );

View File

@@ -33,6 +33,7 @@ typedef struct gl_frustum_s
void GL_FrustumInitProj( gl_frustum_t *out, float flZNear, float flZFar, float flFovX, float flFovY );
void GL_FrustumInitOrtho( gl_frustum_t *out, float xLeft, float xRight, float yTop, float yBottom, float flZNear, float flZFar );
void GL_FrustumSetPlane( gl_frustum_t *out, int side, const vec3_t vecNormal, float flDist );
// cull methods
qboolean GL_FrustumCullBox( gl_frustum_t *out, const vec3_t mins, const vec3_t maxs, int userClipFlags );

View File

@@ -2338,6 +2338,7 @@ void R_InitImages( void )
// validate cvars
R_SetTextureParameters();
GL_CreateInternalTextures();
R_InitRipples();
gEngfuncs.Cmd_AddCommand( "texturelist", R_TextureList_f, "display loaded textures list" );
}

View File

@@ -130,6 +130,7 @@ typedef struct gltexture_s
float xscale;
float yscale;
int servercount;
uint hashValue;
struct gltexture_s *nextHash;
} gl_texture_t;
@@ -437,6 +438,8 @@ void R_DrawWaterSurfaces( void );
void R_DrawBrushModel( cl_entity_t *e );
void GL_SubdivideSurface( model_t *mod, msurface_t *fa );
void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa );
void DrawGLPoly( glpoly2_t *p, float xScale, float yScale );
texture_t *R_TextureAnimation( msurface_t *s );
void GL_SetupFogColorForSurfaces( void );
void R_DrawAlphaTextureChains( void );
void GL_RebuildLightmaps( void );
@@ -500,9 +503,10 @@ void R_DrawSkyBox( void );
void R_DrawClouds( void );
void R_UnloadSkybox( void );
void EmitWaterPolys( msurface_t *warp, qboolean reverse, qboolean ripples );
void R_InitRipples( void );
void R_ResetRipples( void );
void R_AnimateRipples( void );
qboolean R_UploadRipples( texture_t *image );
qboolean R_UploadRipples( const texture_t *image );
//#include "vid_common.h"
@@ -555,6 +559,8 @@ void CL_AddCustomBeam( cl_entity_t *pEnvBeam );
#define GL_CheckForErrors() GL_CheckForErrors_( __FILE__, __LINE__ )
void GL_CheckForErrors_( const char *filename, const int fileline );
const char *GL_ErrorString( int err );
qboolean GL_Support( int r_ext );
int GL_MaxTextureUnits( void );
//
// gl_triapi.c
@@ -754,22 +760,6 @@ static inline uint LinearGammaTable( uint b )
return !FBitSet( gp_host->features, ENGINE_LINEAR_GAMMA_SPACE ) ? tr.lineargammatable[b] : b;
}
static inline qboolean GL_Support( int r_ext )
{
if( r_ext >= 0 && r_ext < GL_EXTCOUNT )
return glConfig.extension[r_ext] ? true : false;
gEngfuncs.Con_Printf( S_ERROR "%s: invalid extension %d\n", __func__, r_ext );
return false;
}
static inline int GL_MaxTextureUnits( void )
{
if( GL_Support( GL_SHADER_GLSL100_EXT ))
return Q_min( Q_max( glConfig.max_texture_coords, glConfig.max_teximage_units ), MAX_TEXTURE_UNITS );
return glConfig.max_texture_units;
}
#define WORLDMODEL (gp_cl->models[1])
//
@@ -812,7 +802,6 @@ extern convar_t r_shadows;
extern convar_t r_ripple;
extern convar_t r_ripple_updatetime;
extern convar_t r_ripple_spawntime;
extern convar_t r_large_lightmaps;
//
// engine shared convars

View File

@@ -37,7 +37,6 @@ CVAR_DEFINE( r_vbo_overbrightmode, "gl_vbo_overbrightmode", "0", FCVAR_GLCONFIG,
CVAR_DEFINE_AUTO( r_ripple, "0", FCVAR_GLCONFIG, "enable software-like water texture ripple simulation" );
CVAR_DEFINE_AUTO( r_ripple_updatetime, "0.05", FCVAR_GLCONFIG, "how fast ripple simulation is" );
CVAR_DEFINE_AUTO( r_ripple_spawntime, "0.1", FCVAR_GLCONFIG, "how fast new ripples spawn" );
CVAR_DEFINE_AUTO( r_large_lightmaps, "0", FCVAR_GLCONFIG|FCVAR_LATCH, "enable larger lightmap atlas textures (might break custom renderer mods)" );
DEFINE_ENGINE_SHARED_CVAR_LIST()
@@ -465,6 +464,32 @@ static void GL_SetExtension( int r_ext, int enable )
else gEngfuncs.Con_Printf( S_ERROR "%s: invalid extension %d\n", __func__, r_ext );
}
/*
=================
GL_Support
=================
*/
qboolean GL_Support( int r_ext )
{
if( r_ext >= 0 && r_ext < GL_EXTCOUNT )
return glConfig.extension[r_ext] ? true : false;
gEngfuncs.Con_Printf( S_ERROR "%s: invalid extension %d\n", __func__, r_ext );
return false;
}
/*
=================
GL_MaxTextureUnits
=================
*/
int GL_MaxTextureUnits( void )
{
if( GL_Support( GL_SHADER_GLSL100_EXT ))
return Q_min( Q_max( glConfig.max_texture_coords, glConfig.max_teximage_units ), MAX_TEXTURE_UNITS );
return glConfig.max_texture_units;
}
/*
=================
GL_CheckExtension
@@ -906,13 +931,7 @@ static void GL_InitExtensionsBigGL( void )
GL_CheckExtension( "GL_ARB_seamless_cube_map", NULL, 0, "gl_texture_cubemap_seamless", GL_ARB_SEAMLESS_CUBEMAP, 0 );
}
// NPOT textures support
if( !GL_CheckExtension( "GL_ARB_texture_non_power_of_two", NULL, 0, "gl_texture_npot", GL_ARB_TEXTURE_NPOT_EXT, 0 ))
{
// vitaGL exposes OES extension
GL_CheckExtension( "GL_OES_texture_npot", NULL, 0, "gl_texture_npot", GL_ARB_TEXTURE_NPOT_EXT, 0 );
}
GL_CheckExtension( "GL_ARB_texture_non_power_of_two", NULL, 0, "gl_texture_npot", GL_ARB_TEXTURE_NPOT_EXT, 0 );
GL_CheckExtension( "GL_ARB_texture_compression", texturecompressionfuncs, ARRAYSIZE( texturecompressionfuncs ), "gl_texture_dxt_compression", GL_TEXTURE_COMPRESSION_EXT, 0 );
if( !GL_CheckExtension( "GL_EXT_texture_edge_clamp", NULL, 0, "gl_clamp_to_edge", GL_CLAMPTOEDGE_EXT, 2.0 )) // present in ES2
GL_CheckExtension( "GL_SGIS_texture_edge_clamp", NULL, 0, "gl_clamp_to_edge", GL_CLAMPTOEDGE_EXT, 0 );
@@ -1154,7 +1173,6 @@ static void GL_InitCommands( void )
gEngfuncs.Cvar_RegisterVariable( &r_vbo_dlightmode );
gEngfuncs.Cvar_RegisterVariable( &r_vbo_overbrightmode );
gEngfuncs.Cvar_RegisterVariable( &r_vbo_detail );
gEngfuncs.Cvar_RegisterVariable( &r_large_lightmaps );
gEngfuncs.Cvar_RegisterVariable( &gl_extensions );
gEngfuncs.Cvar_RegisterVariable( &gl_texture_nearest );

View File

@@ -478,7 +478,7 @@ R_TextureAnimation
Returns the proper texture for a given time and surface
===============
*/
static texture_t *R_TextureAnimation( msurface_t *s )
texture_t *R_TextureAnimation( msurface_t *s )
{
texture_t *base = s->texinfo->texture;
int count, reletive;
@@ -812,7 +812,7 @@ static void R_BuildLightMap( const msurface_t *surf, byte *dest, int stride, qbo
DrawGLPoly
================
*/
static void DrawGLPoly( glpoly2_t *p, float xScale, float yScale )
void DrawGLPoly( glpoly2_t *p, float xScale, float yScale )
{
float *v;
float sOffset, sy;
@@ -1855,7 +1855,7 @@ typedef struct vbodecaldata_s
// gl_decals.c
extern decal_t gDecalPool[MAX_RENDER_DECALS];
static struct vbo_static_s
struct vbo_static_s
{
// quickly free all allocations on map change
poolhandle_t mempool;
@@ -1891,7 +1891,7 @@ static struct vbo_static_s
qboolean enabled;
} vbos;
static struct multitexturestate_s
struct multitexturestate_s
{
int tmu_gl; // texture tmu
int tmu_dt; // detail tmu
@@ -3858,7 +3858,7 @@ void GL_BuildLightmaps( void )
memset( &RI, 0, sizeof( RI ));
// update the lightmap blocksize
if( FBitSet( gp_host->features, ENGINE_LARGE_LIGHTMAPS ) || tr.world->version == QBSP2_VERSION || r_large_lightmaps.value )
if( FBitSet( gp_host->features, ENGINE_LARGE_LIGHTMAPS ) || tr.world->version == QBSP2_VERSION )
tr.block_size = BLOCK_SIZE_MAX;
else tr.block_size = BLOCK_SIZE_DEFAULT;

View File

@@ -152,11 +152,11 @@ load sprite model
*/
void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags )
{
const dsprite_t *pin;
const short *numi = NULL;
const byte *pframetype;
msprite_t *psprite;
int i;
const dsprite_t *pin;
const short *numi = NULL;
const byte *pframetype;
msprite_t *psprite;
int i;
pin = buffer;
psprite = mod->cache.data;
@@ -164,7 +164,7 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
if( pin->version == SPRITE_VERSION_Q1 || pin->version == SPRITE_VERSION_32 )
numi = NULL;
else if( pin->version == SPRITE_VERSION_HL )
numi = (const short *)((const byte *)buffer + sizeof( dsprite_hl_t ));
numi = (const short *)((const byte*)buffer + sizeof( dsprite_hl_t ));
r_texFlags = texFlags;
sprite_version = pin->version;
@@ -179,32 +179,31 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
pframetype = ((const byte*)buffer + sizeof( dsprite_q1_t )); // pinq1 + 1
gEngfuncs.FS_FreeImage( pal ); // palette installed, no reason to keep this data
}
else if( *numi <= 256 )
else if( *numi == 256 )
{
const byte *src = (const byte *)(numi+1);
rgbdata_t *pal;
size_t pal_bytes = *numi * 3;
// install palette
switch( psprite->texFormat )
{
case SPR_INDEXALPHA:
pal = gEngfuncs.FS_LoadImage( "#gradient.pal", src, pal_bytes );
pal = gEngfuncs.FS_LoadImage( "#gradient.pal", src, 768 );
break;
case SPR_ALPHTEST:
pal = gEngfuncs.FS_LoadImage( "#masked.pal", src, pal_bytes );
pal = gEngfuncs.FS_LoadImage( "#masked.pal", src, 768 );
break;
default:
pal = gEngfuncs.FS_LoadImage( "#normal.pal", src, pal_bytes );
pal = gEngfuncs.FS_LoadImage( "#normal.pal", src, 768 );
break;
}
pframetype = (const byte *)(src + pal_bytes);
pframetype = (const byte *)(src + 768);
gEngfuncs.FS_FreeImage( pal ); // palette installed, no reason to keep this data
}
else
{
gEngfuncs.Con_DPrintf( S_ERROR "%s has wrong number of palette colors %i (should be less or equal than 256)\n", mod->name, *numi );
gEngfuncs.Con_DPrintf( S_ERROR "%s has wrong number of palette colors %i (should be 256)\n", mod->name, *numi );
return;
}
@@ -250,31 +249,32 @@ release sprite model and frames
*/
void Mod_SpriteUnloadTextures( void *data )
{
msprite_t *psprite = data;
int i;
msprite_t *psprite;
mspritegroup_t *pspritegroup;
mspriteframe_t *pspriteframe;
int i, j;
if( !data )
return;
psprite = data;
// release all textures
for( i = 0; i < psprite->numframes; i++ )
if( psprite )
{
if( !psprite->frames[i].frameptr )
continue;
if( psprite->frames[i].type == SPR_SINGLE )
// release all textures
for( i = 0; i < psprite->numframes; i++ )
{
GL_FreeTexture( psprite->frames[i].frameptr->gl_texturenum );
}
else
{
mspritegroup_t *pspritegroup = (mspritegroup_t *)psprite->frames[i].frameptr;
int j;
for( j = 0; j < pspritegroup->numframes; j++ )
if( psprite->frames[i].type == SPR_SINGLE )
{
if( pspritegroup->frames[j] )
GL_FreeTexture( pspritegroup->frames[j]->gl_texturenum );
pspriteframe = psprite->frames[i].frameptr;
GL_FreeTexture( pspriteframe->gl_texturenum );
}
else
{
pspritegroup = (mspritegroup_t *)psprite->frames[i].frameptr;
for( j = 0; j < pspritegroup->numframes; j++ )
{
pspriteframe = pspritegroup->frames[i];
GL_FreeTexture( pspriteframe->gl_texturenum );
}
}
}
}

View File

@@ -79,6 +79,8 @@ static struct
qboolean update;
uint32_t texture[RIPPLES_TEXSIZE];
int gl_texturenum;
int rippletexturenum;
} g_ripple;
@@ -247,16 +249,8 @@ static void MakeSkyVec( float s, float t, int axis )
s = (s + 1.0f) * 0.5f;
t = (t + 1.0f) * 0.5f;
if( GL_Support( GL_CLAMPTOEDGE_EXT ))
{
s = bound( 0.0f, s, 1.0f );
t = bound( 0.0f, t, 1.0f );
}
else
{
s = bound( 1.0f / 512.0f, s, 511.0f / 512.0f );
t = bound( 1.0f / 512.0f, t, 511.0f / 512.0f );
}
s = bound( 1.0f / 512.0f, s, 511.0f / 512.0f );
t = bound( 1.0f / 512.0f, t, 511.0f / 512.0f );
t = 1.0f - t;
@@ -661,6 +655,22 @@ void R_ResetRipples( void )
memset( g_ripple.buf, 0, sizeof( g_ripple.buf ));
}
void R_InitRipples( void )
{
rgbdata_t pic = { 0 };
pic.width = pic.height = RIPPLES_CACHEWIDTH;
pic.depth = 1;
pic.flags = IMAGE_HAS_COLOR;
pic.buffer = (byte *)g_ripple.texture;
pic.type = PF_RGBA_32;
pic.size = sizeof( g_ripple.texture );
pic.numMips = 1;
memset( pic.buffer, 0, pic.size );
g_ripple.rippletexturenum = GL_LoadTextureInternal( "*rippletex", &pic, TF_NOMIPMAP|TF_ALLOW_NEAREST );
}
static void R_SwapBufs( void )
{
short *tempbufp = g_ripple.curbuf;
@@ -728,32 +738,12 @@ void R_AnimateRipples( void )
R_RunRipplesAnimation( g_ripple.oldbuf, g_ripple.curbuf );
}
static void R_GetRippleTextureSize( const texture_t *image, int *width, int *height )
{
// try to preserve aspect ratio
if( image->width > image->height )
{
*width = RIPPLES_CACHEWIDTH;
*height = (float)image->height / image->width * RIPPLES_CACHEWIDTH;
}
else if( image->width < image->height )
{
*width = (float)image->width / image->height * RIPPLES_CACHEWIDTH;
*height = RIPPLES_CACHEWIDTH;
}
else
{
*width = *height = RIPPLES_CACHEWIDTH;
}
}
qboolean R_UploadRipples( texture_t *image )
qboolean R_UploadRipples( const texture_t *image )
{
const gl_texture_t *glt;
const uint32_t *pixels;
int y;
int width, height, size;
qboolean update = g_ripple.update;
if( !r_ripple.value )
{
@@ -763,48 +753,29 @@ qboolean R_UploadRipples( texture_t *image )
// discard unuseful textures
glt = R_GetTexture( image->gl_texturenum );
if( !glt || !glt->original || !glt->original->buffer )
if( !glt || !glt->original || !glt->original->buffer || !FBitSet( glt->flags, TF_EXPAND_SOURCE ))
{
GL_Bind( XASH_TEXTURE0, image->gl_texturenum );
return false;
}
if( !image->fb_texturenum )
{
rgbdata_t pic = { 0 };
string name;
Q_snprintf( name, sizeof( name ), "*rippletex_%s", image->name );
R_GetRippleTextureSize( image, &width, &height );
pic.width = width;
pic.height = height;
pic.depth = 1;
pic.flags = IMAGE_HAS_COLOR;
pic.buffer = (byte *)g_ripple.texture;
pic.type = PF_RGBA_32;
pic.size = width * height * 4;
pic.numMips = 1;
memset( pic.buffer, 0, pic.size );
image->fb_texturenum = GL_LoadTextureInternal( name, &pic, TF_NOMIPMAP | TF_ALLOW_NEAREST );
update = true;
image->dt_texturenum = ( tr.framecount - 1 ) & 0xFFFF;
}
GL_Bind( XASH_TEXTURE0, image->fb_texturenum );
GL_Bind( XASH_TEXTURE0, g_ripple.rippletexturenum );
// no updates this frame
if( !update || image->dt_texturenum == ( tr.framecount & 0xFFFF ))
if( !g_ripple.update && image->gl_texturenum == g_ripple.gl_texturenum )
return true;
// prevent rendering texture multiple times in frame
image->dt_texturenum = tr.framecount & 0xFFFF;
R_GetRippleTextureSize( image, &width, &height );
g_ripple.gl_texturenum = image->gl_texturenum;
size = r_ripple.value == 1.0f ? 64 : RIPPLES_CACHEWIDTH;
// try to preserve aspect ratio
width = height = RIPPLES_CACHEWIDTH; // always render at maximum size
if( image->width > image->height )
height = (float)image->height / image->width * width;
else if( image->width < image->height )
width = (float)image->width / image->height * height;
pixels = (const uint32_t *)glt->original->buffer;
for( y = 0; y < height; y++ )

View File

@@ -66,33 +66,34 @@ void Mod_UnloadTextures( model_t *mod );
static qboolean GAME_EXPORT Mod_ProcessRenderData( model_t *mod, qboolean create, const byte *buf )
{
qboolean loaded = false;
qboolean loaded = true;
if( create )
{
switch( mod->type )
{
case mod_studio:
// Mod_LoadStudioModel( mod, buf, loaded );
break;
case mod_sprite:
Mod_LoadSpriteModel( mod, buf, &loaded, mod->numtexinfo );
break;
case mod_alias:
// Mod_LoadAliasModel( mod, buf, &loaded );
break;
case mod_brush:
// Mod_LoadBrushModel( mod, buf, loaded );
break;
default: gEngfuncs.Host_Error( "%s: unsupported type %d\n", __func__, mod->type );
}
}
if( loaded && gEngfuncs.drawFuncs->Mod_ProcessUserData )
gEngfuncs.drawFuncs->Mod_ProcessUserData( mod, create, buf );
if( !create )
{
if( gEngfuncs.drawFuncs->Mod_ProcessUserData )
gEngfuncs.drawFuncs->Mod_ProcessUserData( mod, false, buf );
Mod_UnloadTextures( mod );
return true;
}
switch( mod->type )
{
case mod_studio:
case mod_brush:
case mod_alias:
loaded = true;
break;
case mod_sprite:
Mod_LoadSpriteModel( mod, buf, &loaded, mod->numtexinfo );
break;
default:
gEngfuncs.Host_Error( "%s: unsupported type %d\n", __func__, mod->type );
return false;
}
if( gEngfuncs.drawFuncs->Mod_ProcessUserData )
gEngfuncs.drawFuncs->Mod_ProcessUserData( mod, true, buf );
return loaded;
}

Some files were not shown because too many files have changed in this diff Show More