Browse Source

Dedicated build

pull/2/head
Alibek Omarov 7 years ago
parent
commit
5d13112e25
  1. 2
      engine/client/cl_main.c
  2. 66
      engine/client/console.c
  3. 241
      engine/client/gl_studio.c
  4. 9
      engine/common/cmd.c
  5. 2
      engine/common/common.h
  6. 6
      engine/common/con_utils.c
  7. 2
      engine/common/custom.c
  8. 4
      engine/common/cvar.c
  9. 497
      engine/common/dedicated.c
  10. 21
      engine/common/filesystem.c
  11. 14
      engine/common/host.c
  12. 2
      engine/common/infostring.c
  13. 109
      engine/common/launcher.c
  14. 10
      engine/common/mod_bmodel.c
  15. 255
      engine/common/mod_studio.c
  16. 19
      engine/common/model.c
  17. 2
      engine/common/net_chan.c
  18. 3
      engine/common/net_encode.c
  19. 4
      engine/common/pm_debug.c
  20. 4
      engine/common/pm_trace.c
  21. 73
      engine/common/sys_con.c
  22. 2
      engine/server/sv_game.c
  23. 5
      engine/server/sv_init.c
  24. 9
      engine/server/sv_phys.c
  25. 23
      engine/server/sv_pmove.c
  26. 4
      engine/server/sv_save.c

2
engine/client/cl_main.c

@ -2769,7 +2769,7 @@ void CL_Init( void )
IN_TouchInit(); IN_TouchInit();
COM_ResetLibraryError(); COM_ResetLibraryError();
if( !CL_LoadProgs( va( "%s/%s", GI->dll_path, GI->client_lib))) if( !CL_LoadProgs( va( "%s/%s", GI->dll_path, SI.clientlib)))
Host_Error( "can't initialize client.dll\n" ); Host_Error( "can't initialize client.dll\n" );
cls.initialized = true; cls.initialized = true;

66
engine/client/console.c

@ -1238,72 +1238,6 @@ void Con_Print( const char *txt )
} }
} }
/*
=============
Con_Printf
=============
*/
void Con_Printf( char *szFmt, ... )
{
static char buffer[MAX_PRINT_MSG];
va_list args;
if( !host.allow_console )
return;
va_start( args, szFmt );
Q_vsnprintf( buffer, sizeof( buffer ), szFmt, args );
va_end( args );
Sys_Print( buffer );
}
/*
=============
Con_DPrintf
=============
*/
void Con_DPrintf( char *szFmt, ... )
{
static char buffer[MAX_PRINT_MSG];
va_list args;
if( host_developer.value < DEV_NORMAL )
return;
va_start( args, szFmt );
Q_vsnprintf( buffer, sizeof( buffer ), szFmt, args );
va_end( args );
if( buffer[0] == '0' && buffer[1] == '\n' && buffer[2] == '\0' )
return; // hlrally spam
Sys_Print( buffer );
}
/*
=============
Con_Reportf
=============
*/
void Con_Reportf( char *szFmt, ... )
{
static char buffer[MAX_PRINT_MSG];
va_list args;
if( host_developer.value < DEV_EXTENDED )
return;
va_start( args, szFmt );
Q_vsnprintf( buffer, sizeof( buffer ), szFmt, args );
va_end( args );
Sys_Print( buffer );
}
/* /*
================ ================
Con_NPrint Con_NPrint

241
engine/client/gl_studio.c

@ -718,56 +718,6 @@ float CL_GetSequenceDuration( cl_entity_t *ent, int sequence )
return 0.1f; return 0.1f;
} }
/*
====================
StudioGetAnim
====================
*/
void *R_StudioGetAnim( studiohdr_t *m_pStudioHeader, model_t *m_pSubModel, mstudioseqdesc_t *pseqdesc )
{
mstudioseqgroup_t *pseqgroup;
cache_user_t *paSequences;
size_t filesize;
byte *buf;
pseqgroup = (mstudioseqgroup_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqgroupindex) + pseqdesc->seqgroup;
if( pseqdesc->seqgroup == 0 )
return ((byte *)m_pStudioHeader + pseqgroup->data + pseqdesc->animindex);
paSequences = (cache_user_t *)m_pSubModel->submodels;
if( paSequences == NULL )
{
paSequences = (cache_user_t *)Mem_Alloc( com_studiocache, MAXSTUDIOGROUPS * sizeof( cache_user_t ));
m_pSubModel->submodels = (void *)paSequences;
}
// check for already loaded
if( !Mod_CacheCheck(( cache_user_t *)&( paSequences[pseqdesc->seqgroup] )))
{
string filepath, modelname, modelpath;
COM_FileBase( m_pSubModel->name, modelname );
COM_ExtractFilePath( m_pSubModel->name, modelpath );
// NOTE: here we build real sub-animation filename because stupid user may rename model without recompile
Q_snprintf( filepath, sizeof( filepath ), "%s/%s%i%i.mdl", modelpath, modelname, pseqdesc->seqgroup / 10, pseqdesc->seqgroup % 10 );
buf = FS_LoadFile( filepath, &filesize, false );
if( !buf || !filesize ) Host_Error( "StudioGetAnim: can't load %s\n", filepath );
if( IDSEQGRPHEADER != *(uint *)buf ) Host_Error( "StudioGetAnim: %s is corrupted\n", filepath );
Con_Printf( "loading: %s\n", filepath );
paSequences[pseqdesc->seqgroup].data = Mem_Alloc( com_studiocache, filesize );
memcpy( paSequences[pseqdesc->seqgroup].data, buf, filesize );
Mem_Free( buf );
}
return ((byte *)paSequences[pseqdesc->seqgroup].data + pseqdesc->animindex);
}
/* /*
==================== ====================
StudioFxTransform StudioFxTransform
@ -877,197 +827,6 @@ void R_StudioCalcBoneAdj( float dadt, float *adj, const byte *pcontroller1, cons
} }
} }
/*
====================
StudioCalcBoneQuaternion
====================
*/
void R_StudioCalcBoneQuaternion( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, vec4_t q )
{
vec3_t angles1;
vec3_t angles2;
int j, k;
for( j = 0; j < 3; j++ )
{
if( !panim || panim->offset[j+3] == 0 )
{
angles2[j] = angles1[j] = pbone->value[j+3]; // default;
}
else
{
mstudioanimvalue_t *panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j+3]);
k = frame;
// debug
if( panimvalue->num.total < panimvalue->num.valid )
k = 0;
// find span of values that includes the frame we want
while( panimvalue->num.total <= k )
{
k -= panimvalue->num.total;
panimvalue += panimvalue->num.valid + 1;
// debug
if( panimvalue->num.total < panimvalue->num.valid )
k = 0;
}
// bah, missing blend!
if( panimvalue->num.valid > k )
{
angles1[j] = panimvalue[k+1].value;
if( panimvalue->num.valid > k + 1 )
{
angles2[j] = panimvalue[k+2].value;
}
else
{
if( panimvalue->num.total > k + 1 )
angles2[j] = angles1[j];
else angles2[j] = panimvalue[panimvalue->num.valid+2].value;
}
}
else
{
angles1[j] = panimvalue[panimvalue->num.valid].value;
if( panimvalue->num.total > k + 1 )
angles2[j] = angles1[j];
else angles2[j] = panimvalue[panimvalue->num.valid+2].value;
}
angles1[j] = pbone->value[j+3] + angles1[j] * pbone->scale[j+3];
angles2[j] = pbone->value[j+3] + angles2[j] * pbone->scale[j+3];
}
if( pbone->bonecontroller[j+3] != -1 && adj != NULL )
{
angles1[j] += adj[pbone->bonecontroller[j+3]];
angles2[j] += adj[pbone->bonecontroller[j+3]];
}
}
if( !VectorCompare( angles1, angles2 ))
{
vec4_t q1, q2;
AngleQuaternion( angles1, q1, true );
AngleQuaternion( angles2, q2, true );
QuaternionSlerp( q1, q2, s, q );
}
else
{
AngleQuaternion( angles1, q, true );
}
}
/*
====================
StudioCalcBonePosition
====================
*/
void R_StudioCalcBonePosition( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, vec3_t pos )
{
vec3_t origin1;
vec3_t origin2;
int j, k;
for( j = 0; j < 3; j++ )
{
if( !panim || panim->offset[j] == 0 )
{
origin2[j] = origin1[j] = pbone->value[j]; // default;
}
else
{
mstudioanimvalue_t *panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j]);
k = frame;
// debug
if( panimvalue->num.total < panimvalue->num.valid )
k = 0;
// find span of values that includes the frame we want
while( panimvalue->num.total <= k )
{
k -= panimvalue->num.total;
panimvalue += panimvalue->num.valid + 1;
// debug
if( panimvalue->num.total < panimvalue->num.valid )
k = 0;
}
// bah, missing blend!
if( panimvalue->num.valid > k )
{
origin1[j] = panimvalue[k+1].value;
if( panimvalue->num.valid > k + 1 )
{
origin2[j] = panimvalue[k+2].value;
}
else
{
if( panimvalue->num.total > k + 1 )
origin2[j] = origin1[j];
else origin2[j] = panimvalue[panimvalue->num.valid+2].value;
}
}
else
{
origin1[j] = panimvalue[panimvalue->num.valid].value;
if( panimvalue->num.total > k + 1 )
origin2[j] = origin1[j];
else origin2[j] = panimvalue[panimvalue->num.valid+2].value;
}
origin1[j] = pbone->value[j] + origin1[j] * pbone->scale[j];
origin2[j] = pbone->value[j] + origin2[j] * pbone->scale[j];
}
if( pbone->bonecontroller[j] != -1 && adj != NULL )
{
origin1[j] += adj[pbone->bonecontroller[j]];
origin2[j] += adj[pbone->bonecontroller[j]];
}
}
if( !VectorCompare( origin1, origin2 ))
{
VectorLerp( origin1, s, origin2, pos );
}
else
{
VectorCopy( origin1, pos );
}
}
/*
====================
StudioSlerpBones
====================
*/
void R_StudioSlerpBones( int numbones, vec4_t q1[], float pos1[][3], vec4_t q2[], float pos2[][3], float s )
{
int i;
s = bound( 0.0f, s, 1.0f );
for( i = 0; i < numbones; i++ )
{
QuaternionSlerp( q1[i], q2[i], s, q1[i] );
VectorLerp( pos1[i], s, pos2[i], pos1[i] );
}
}
/* /*
==================== ====================
StudioCalcRotations StudioCalcRotations

9
engine/common/cmd.c

@ -977,13 +977,16 @@ void Cmd_ExecuteString( char *text )
if( host.apply_game_config ) if( host.apply_game_config )
return; // don't send nothing to server: we is a server! return; // don't send nothing to server: we is a server!
#ifndef XASH_DEDICATED
// forward the command line to the server, so the entity DLL can parse it // forward the command line to the server, so the entity DLL can parse it
if( host.type == HOST_NORMAL ) if( host.type == HOST_NORMAL )
{ {
if( cls.state >= ca_connected ) if( cls.state >= ca_connected )
Cmd_ForwardToServer(); Cmd_ForwardToServer();
} }
else if( text[0] != '@' && host.type == HOST_NORMAL ) else
#endif
if( text[0] != '@' && host.type == HOST_NORMAL )
{ {
// commands with leading '@' are hidden system commands // commands with leading '@' are hidden system commands
Con_Printf( S_WARN "Unknown command \"%s\"\n", text ); Con_Printf( S_WARN "Unknown command \"%s\"\n", text );
@ -999,6 +1002,7 @@ things like godmode, noclip, etc, are commands directed to the server,
so when they are typed in at the console, they will need to be forwarded. so when they are typed in at the console, they will need to be forwarded.
=================== ===================
*/ */
#ifndef XASH_DEDICATED
void Cmd_ForwardToServer( void ) void Cmd_ForwardToServer( void )
{ {
char str[MAX_CMD_BUFFER]; char str[MAX_CMD_BUFFER];
@ -1032,6 +1036,7 @@ void Cmd_ForwardToServer( void )
MSG_WriteString( &cls.netchan.message, str ); MSG_WriteString( &cls.netchan.message, str );
} }
#endif // XASH_DEDICATED
/* /*
============ ============
@ -1141,7 +1146,9 @@ void Cmd_Init( void )
Cmd_AddCommand( "wait", Cmd_Wait_f, "make script execution wait for some rendered frames" ); Cmd_AddCommand( "wait", Cmd_Wait_f, "make script execution wait for some rendered frames" );
Cmd_AddCommand( "cmdlist", Cmd_List_f, "display all console commands beginning with the specified prefix" ); Cmd_AddCommand( "cmdlist", Cmd_List_f, "display all console commands beginning with the specified prefix" );
Cmd_AddCommand( "stuffcmds", Cmd_StuffCmds_f, "execute commandline parameters (must be present in .rc script)" ); Cmd_AddCommand( "stuffcmds", Cmd_StuffCmds_f, "execute commandline parameters (must be present in .rc script)" );
#ifndef XASH_DEDICATED
Cmd_AddCommand( "cmd", Cmd_ForwardToServer, "send a console commandline to the server" ); Cmd_AddCommand( "cmd", Cmd_ForwardToServer, "send a console commandline to the server" );
#endif
Cmd_AddCommand( "alias", Cmd_Alias_f, "create a script function. Without arguments show the list of all alias" ); Cmd_AddCommand( "alias", Cmd_Alias_f, "create a script function. Without arguments show the list of all alias" );
Cmd_AddCommand( "unalias", Cmd_UnAlias_f, "remove a script function" ); Cmd_AddCommand( "unalias", Cmd_UnAlias_f, "remove a script function" );
Cmd_AddCommand( "if", Cmd_If_f, "compare and set condition bits" ); Cmd_AddCommand( "if", Cmd_If_f, "compare and set condition bits" );

2
engine/common/common.h

@ -301,6 +301,8 @@ typedef struct sysinfo_s
string exeName; // exe.filename string exeName; // exe.filename
string rcName; // .rc script name string rcName; // .rc script name
string basedirName; // name of base directory string basedirName; // name of base directory
string gamedll;
string clientlib;
gameinfo_t *GameInfo; // current GameInfo gameinfo_t *GameInfo; // current GameInfo
gameinfo_t *games[MAX_MODS]; // environment games (founded at each engine start) gameinfo_t *games[MAX_MODS]; // environment games (founded at each engine start)
int numgames; int numgames;

6
engine/common/con_utils.c

@ -464,6 +464,7 @@ qboolean Cmd_GetSoundList( const char *s, char *completedname, int length )
return true; return true;
} }
#ifndef XASH_DEDICATED
/* /*
===================================== =====================================
Cmd_GetItemsList Cmd_GetItemsList
@ -510,6 +511,7 @@ qboolean Cmd_GetItemsList( const char *s, char *completedname, int length )
} }
return true; return true;
} }
#endif
/* /*
===================================== =====================================
@ -817,8 +819,10 @@ autocomplete_list_t cmd_list[] =
{ "music", Cmd_GetMusicList, }, { "music", Cmd_GetMusicList, },
{ "movie", Cmd_GetMovieList }, { "movie", Cmd_GetMovieList },
{ "exec", Cmd_GetConfigList }, { "exec", Cmd_GetConfigList },
#ifndef XASH_DEDICATED
{ "give", Cmd_GetItemsList }, { "give", Cmd_GetItemsList },
{ "drop", Cmd_GetItemsList }, { "drop", Cmd_GetItemsList },
#endif
{ "game", Cmd_GetGamesList }, { "game", Cmd_GetGamesList },
{ "save", Cmd_GetSavesList }, { "save", Cmd_GetSavesList },
{ "load", Cmd_GetSavesList }, { "load", Cmd_GetSavesList },
@ -901,6 +905,7 @@ void Cmd_WriteOpenGLVariables( file_t *f )
Cvar_LookupVars( FCVAR_GLCONFIG, NULL, f, Cmd_WriteOpenGLCvar ); Cvar_LookupVars( FCVAR_GLCONFIG, NULL, f, Cmd_WriteOpenGLCvar );
} }
#ifndef XASH_DEDICATED
/* /*
=============== ===============
Host_WriteConfig Host_WriteConfig
@ -946,6 +951,7 @@ void Host_WriteConfig( void )
} }
else MsgDev( D_ERROR, "Couldn't write config.cfg.\n" ); else MsgDev( D_ERROR, "Couldn't write config.cfg.\n" );
} }
#endif
/* /*
=============== ===============

2
engine/common/custom.c

@ -44,11 +44,13 @@ void COM_ClearCustomizationList( customization_t *pHead, qboolean bCleanDecals )
if( pCurrent->bInUse && pCurrent->pInfo ) if( pCurrent->bInUse && pCurrent->pInfo )
{ {
#ifndef XASH_DEDICATED
if( pCurrent->resource.type == t_decal ) if( pCurrent->resource.type == t_decal )
{ {
if( bCleanDecals && CL_Active( )) if( bCleanDecals && CL_Active( ))
R_DecalRemoveAll( pCurrent->nUserData1 ); R_DecalRemoveAll( pCurrent->nUserData1 );
} }
#endif
FS_FreeImage( pCurrent->pInfo ); FS_FreeImage( pCurrent->pInfo );
} }

4
engine/common/cvar.c

@ -90,12 +90,13 @@ static qboolean Cvar_UpdateInfo( convar_t *var, const char *value, qboolean noti
{ {
if( FBitSet( var->flags, FCVAR_USERINFO )) if( FBitSet( var->flags, FCVAR_USERINFO ))
{ {
if ( host.type == HOST_DEDICATED ) if ( Host_IsDedicated() )
{ {
// g-cont. this is a very strange behavior... // g-cont. this is a very strange behavior...
Info_SetValueForKey( SV_Serverinfo(), var->name, value, MAX_SERVERINFO_STRING ), Info_SetValueForKey( SV_Serverinfo(), var->name, value, MAX_SERVERINFO_STRING ),
SV_BroadcastCommand( "fullserverinfo \"%s\"\n", SV_Serverinfo( )); SV_BroadcastCommand( "fullserverinfo \"%s\"\n", SV_Serverinfo( ));
} }
#ifndef XASH_DEDICATED
else else
{ {
if( !Info_SetValueForKey( CL_Userinfo(), var->name, value, MAX_INFO_STRING )) if( !Info_SetValueForKey( CL_Userinfo(), var->name, value, MAX_INFO_STRING ))
@ -104,6 +105,7 @@ static qboolean Cvar_UpdateInfo( convar_t *var, const char *value, qboolean noti
// time to update server copy of userinfo // time to update server copy of userinfo
CL_ServerCommand( true, "setinfo \"%s\" \"%s\"\n", var->name, value ); CL_ServerCommand( true, "setinfo \"%s\" \"%s\"\n", var->name, value );
} }
#endif
} }
if( FBitSet( var->flags, FCVAR_SERVER ) && notify ) if( FBitSet( var->flags, FCVAR_SERVER ) && notify )

497
engine/common/dedicated.c

@ -0,0 +1,497 @@
/*
dedicated.c - stubs for dedicated server
Copyright (C) 2018 a1batross, 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.
*/
#ifdef XASH_DEDICATED
#include "common.h"
#include "mathlib.h"
const char *svc_strings[256] =
{
"svc_bad",
"svc_nop",
"svc_disconnect",
"svc_changing",
"svc_version",
"svc_setview",
"svc_sound",
"svc_time",
"svc_print",
"svc_stufftext",
"svc_setangle",
"svc_serverdata",
"svc_lightstyle",
"svc_updateuserinfo",
"svc_deltatable",
"svc_clientdata",
"svc_stopsound",
"svc_updatepings",
"svc_particle",
"svc_restoresound",
"svc_spawnstatic",
"svc_event_reliable",
"svc_spawnbaseline",
"svc_temp_entity",
"svc_setpause",
"svc_signonnum",
"svc_centerprint",
"svc_event",
"svc_soundindex",
"svc_ambientsound",
"svc_intermission",
"svc_modelindex",
"svc_cdtrack",
"svc_serverinfo",
"svc_eventindex",
"svc_weaponanim",
"svc_bspdecal",
"svc_roomtype",
"svc_addangle",
"svc_usermessage",
"svc_packetentities",
"svc_deltapacketentities",
"svc_chokecount",
"svc_resourcelist",
"svc_deltamovevars",
"svc_customization",
"svc_unused46",
"svc_crosshairangle",
"svc_soundfade",
"svc_unused49",
"svc_unused50",
"svc_director",
"svc_studiodecal",
"svc_unused53",
"svc_unused54",
"svc_unused55",
"svc_unused56",
"svc_querycvarvalue",
"svc_querycvarvalue2",
"svc_unused59",
"svc_unused60",
"svc_unused61",
"svc_unused62",
"svc_unused63",
};
qboolean CL_Active( void )
{
return false;
}
qboolean CL_Initialized( void )
{
return false;
}
qboolean CL_IsInGame( void )
{
return true; // always active for dedicated servers
}
qboolean CL_IsInMenu( void )
{
return false;
}
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;
}
qboolean CL_IsBackgroundDemo( void )
{
return false;
}
qboolean CL_IsBackgroundMap( void )
{
return false;
}
void CL_Init()
{
}
void Key_Init()
{
}
void IN_Init()
{
}
void CL_Drop()
{
}
void CL_ClearEdicts()
{
}
void Key_SetKeyDest(int key_dest)
{
}
void UI_SetActiveMenu( qboolean fActive )
{
}
void CL_WriteMessageHistory()
{
}
void Host_ClientBegin()
{
}
void Host_ClientFrame()
{
}
void Host_InputFrame()
{
Cbuf_Execute();
}
void VID_InitDefaultResolution()
{
}
void Con_Init()
{
}
void R_ClearAllDecals()
{
}
int R_CreateDecalList( struct decallist_s *pList )
{
return 0;
}
void S_StopSound(int entnum, int channel, const char *soundname)
{
}
int S_GetCurrentStaticSounds( soundlist_t *pout, int size )
{
return 0;
}
int CL_GetMaxClients()
{
return 0;
}
void IN_TouchInitConfig()
{
}
void CL_Disconnect()
{
}
void CL_Shutdown()
{
}
void R_ClearStaticEntities()
{
}
void Host_Credits()
{
}
qboolean UI_CreditsActive()
{
return false;
}
void GL_FreeImage( const char *name )
{
}
void S_StopBackgroundTrack()
{
}
void SCR_BeginLoadingPlaque( qboolean is_background )
{
}
int S_GetCurrentDynamicSounds( soundlist_t *pout, int size )
{
return 0;
}
void S_StopAllSounds( qboolean ambient )
{
}
void Con_NPrintf( int idx, char *fmt, ... )
{
}
void Con_NXPrintf( struct con_nprint_s *info, char *fmt, ... )
{
}
const byte *GL_TextureData( unsigned int texnum )
{
return NULL;
}
void SCR_CheckStartupVids()
{
}
imgfilter_t *R_FindTexFilter( const char *texname )
{
return NULL;
}
#include "sprite.h"
/*
====================
Mod_LoadSpriteModel
load sprite model
====================
*/
void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags )
{
dsprite_q1_t *pinq1;
dsprite_hl_t *pinhl;
dsprite_t *pin;
short *numi = NULL;
dframetype_t *pframetype;
msprite_t *psprite;
int i, size;
if( loaded ) *loaded = false;
pin = (dsprite_t *)buffer;
mod->type = mod_sprite;
i = pin->version;
if( pin->ident != IDSPRITEHEADER )
{
MsgDev( D_ERROR, "%s has wrong id (%x should be %x)\n", mod->name, pin->ident, IDSPRITEHEADER );
return;
}
if( i != SPRITE_VERSION_Q1 && i != SPRITE_VERSION_HL && i != SPRITE_VERSION_32 )
{
MsgDev( D_ERROR, "%s has wrong version number (%i should be %i or %i)\n", mod->name, i, SPRITE_VERSION_Q1, SPRITE_VERSION_HL );
return;
}
mod->mempool = Mem_AllocPool( va( "^2%s^7", mod->name ));
if( i == SPRITE_VERSION_Q1 || i == SPRITE_VERSION_32 )
{
pinq1 = (dsprite_q1_t *)buffer;
size = sizeof( msprite_t ) + ( pinq1->numframes - 1 ) * sizeof( psprite->frames );
psprite = Mem_Alloc( mod->mempool, size );
mod->cache.data = psprite; // make link to extradata
psprite->type = pinq1->type;
psprite->texFormat = SPR_ADDITIVE; //SPR_ALPHTEST;
psprite->numframes = mod->numframes = pinq1->numframes;
psprite->facecull = SPR_CULL_FRONT;
psprite->radius = pinq1->boundingradius;
psprite->synctype = pinq1->synctype;
mod->mins[0] = mod->mins[1] = -pinq1->bounds[0] * 0.5f;
mod->maxs[0] = mod->maxs[1] = pinq1->bounds[0] * 0.5f;
mod->mins[2] = -pinq1->bounds[1] * 0.5f;
mod->maxs[2] = pinq1->bounds[1] * 0.5f;
numi = NULL;
}
else if( i == SPRITE_VERSION_HL )
{
pinhl = (dsprite_hl_t *)buffer;
size = sizeof( msprite_t ) + ( pinhl->numframes - 1 ) * sizeof( psprite->frames );
psprite = Mem_Alloc( mod->mempool, size );
mod->cache.data = psprite; // make link to extradata
psprite->type = pinhl->type;
psprite->texFormat = pinhl->texFormat;
psprite->numframes = mod->numframes = pinhl->numframes;
psprite->facecull = pinhl->facetype;
psprite->radius = pinhl->boundingradius;
psprite->synctype = pinhl->synctype;
mod->mins[0] = mod->mins[1] = -pinhl->bounds[0] * 0.5f;
mod->maxs[0] = mod->maxs[1] = pinhl->bounds[0] * 0.5f;
mod->mins[2] = -pinhl->bounds[1] * 0.5f;
mod->maxs[2] = pinhl->bounds[1] * 0.5f;
numi = (short *)(pinhl + 1);
}
if( host.type == HOST_DEDICATED )
{
// skip frames loading
if( loaded ) *loaded = true; // done
psprite->numframes = 0;
return;
}
if( numi == NULL )
{
rgbdata_t *pal;
pal = FS_LoadImage( "#id.pal", (byte *)&i, 768 );
pframetype = (dframetype_t *)(pinq1 + 1);
FS_FreeImage( pal ); // palette installed, no reason to keep this data
}
else if( *numi == 256 )
{
byte *src = (byte *)(numi+1);
rgbdata_t *pal;
// install palette
switch( psprite->texFormat )
{
case SPR_INDEXALPHA:
pal = FS_LoadImage( "#gradient.pal", src, 768 );
break;
case SPR_ALPHTEST:
pal = FS_LoadImage( "#masked.pal", src, 768 );
break;
default:
pal = FS_LoadImage( "#normal.pal", src, 768 );
break;
}
pframetype = (dframetype_t *)(src + 768);
FS_FreeImage( pal ); // palette installed, no reason to keep this data
}
else
{
MsgDev( D_ERROR, "%s has wrong number of palette colors %i (should be 256)\n", mod->name, *numi );
return;
}
if( mod->numframes < 1 )
{
MsgDev( D_ERROR, "%s has invalid # of frames: %d\n", mod->name, mod->numframes );
return;
}
if( loaded ) *loaded = true; // done
}
/*
====================
Mod_UnloadSpriteModel
release sprite model and frames
====================
*/
void Mod_UnloadSpriteModel( model_t *mod )
{
msprite_t *psprite;
mspritegroup_t *pspritegroup;
mspriteframe_t *pspriteframe;
int i, j;
Assert( mod != NULL );
#ifndef XASH_DEDICATED
if( mod->type == mod_sprite )
{
if( host.type != HOST_DEDICATED )
{
psprite = mod->cache.data;
if( psprite )
{
// release all textures
for( i = 0; i < psprite->numframes; i++ )
{
if( psprite->frames[i].type == SPR_SINGLE )
{
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 );
}
}
}
}
}
}
#endif
Mem_FreePool( &mod->mempool );
memset( mod, 0, sizeof( *mod ));
}
#endif // XASH_DEDICATED

21
engine/common/filesystem.c

@ -1386,6 +1386,27 @@ void FS_LoadGameInfo( const char *rootfolder )
Sys_Error( "Couldn't find game directory '%s'\n", fs_gamedir ); Sys_Error( "Couldn't find game directory '%s'\n", fs_gamedir );
SI.GameInfo = SI.games[i]; SI.GameInfo = SI.games[i];
if( !Sys_GetParmFromCmdLine( "-dll", SI.gamedll ) )
{
#ifdef XASH_INTERNAL_GAMELIBS
Q_strncpy( SI.gamedll, "server", sizeof( SI.gamedll ) );
#elif defined(_WIN32)
Q_strncpy( SI.gamedll, GI->game_dll, sizeof( SI.gamedll ) );
#elif defined(__APPLE__)
Q_strncpy( SI.gamedll, GI->game_dll_osx, sizeof( SI.gamedll ) );
#else
Q_strncpy( SI.gamedll, GI->game_dll_linux, sizeof( SI.gamedll ) );
#endif
}
if( !Sys_GetParmFromCmdLine( "-clientlib", SI.clientlib ) )
{
#ifdef __ANDROID__
Q_strncpy( SI.clientlib, CLIENTDLL, sizeof( SI.clientlib ) );
#else
Q_strncpy( SI.clientlib, GI->client_lib, sizeof( SI.clientlib ) );
#endif
}
FS_Rescan(); // create new filesystem FS_Rescan(); // create new filesystem
Host_InitDecals (); // reload decals Host_InitDecals (); // reload decals

14
engine/common/host.c

@ -116,11 +116,13 @@ void Host_EndGame( qboolean abort, const char *message, ... )
MsgDev( D_INFO, "Host_EndGame: %s\n", string ); MsgDev( D_INFO, "Host_EndGame: %s\n", string );
SV_Shutdown( "\n" ); SV_Shutdown( "\n" );
#ifndef XASH_DEDICATED
CL_Disconnect(); CL_Disconnect();
// recreate world if needs // recreate world if needs
CL_ClearEdicts (); CL_ClearEdicts ();
#endif
// release all models // release all models
Mod_FreeAll(); Mod_FreeAll();
@ -412,17 +414,20 @@ double Host_CalcFPS( void )
double fps = 0.0; double fps = 0.0;
// NOTE: we should play demos with same fps as it was recorded // NOTE: we should play demos with same fps as it was recorded
#ifndef XASH_DEDICATED
if( CL_IsPlaybackDemo() || CL_IsRecordDemo( )) if( CL_IsPlaybackDemo() || CL_IsRecordDemo( ))
fps = CL_GetDemoFramerate(); fps = CL_GetDemoFramerate();
else if( Host_IsLocalGame( )) else
#endif
if( Host_IsLocalGame( ))
fps = host_maxfps->value; fps = host_maxfps->value;
else else
{ {
fps = host_maxfps->value; fps = host_maxfps->value;
if( fps == 0.0 ) fps = HOST_FPS; // default for multiplayer if( fps == 0.0 ) fps = HOST_FPS; // default for multiplayer
fps = bound( MIN_FPS, fps, MAX_FPS );
} }
#ifndef XASH_DEDICATED
// probably left part of this condition is redundant :-) // probably left part of this condition is redundant :-)
if( host.type != HOST_DEDICATED && Host_IsLocalGame( ) && !CL_IsTimeDemo( )) if( host.type != HOST_DEDICATED && Host_IsLocalGame( ) && !CL_IsTimeDemo( ))
{ {
@ -434,6 +439,7 @@ double Host_CalcFPS( void )
else fps = 60.0; // default else fps = 60.0; // default
} }
} }
#endif
return fps; return fps;
} }
@ -962,8 +968,10 @@ void EXPORT Host_Shutdown( void )
if( host.status != HOST_ERR_FATAL ) host.status = HOST_SHUTDOWN; // prepare host to normal shutdown if( host.status != HOST_ERR_FATAL ) host.status = HOST_SHUTDOWN; // prepare host to normal shutdown
if( !host.change_game ) Q_strncpy( host.finalmsg, "Server shutdown", sizeof( host.finalmsg )); if( !host.change_game ) Q_strncpy( host.finalmsg, "Server shutdown", sizeof( host.finalmsg ));
#ifndef XASH_DEDICATED
if( host.type == HOST_NORMAL ) if( host.type == HOST_NORMAL )
Host_WriteConfig(); Host_WriteConfig();
#endif
SV_Shutdown( "" ); SV_Shutdown( "" );
CL_Shutdown(); CL_Shutdown();

2
engine/common/infostring.c

@ -130,6 +130,7 @@ qboolean Info_IsValid( const char *s )
return true; return true;
} }
#ifndef XASH_DEDICATED
/* /*
============== ==============
Info_WriteVars Info_WriteVars
@ -177,6 +178,7 @@ void Info_WriteVars( file_t *f )
s++; s++;
} }
} }
#endif // XASH_DEDICATED
/* /*
=============== ===============

109
engine/common/launcher.c

@ -0,0 +1,109 @@
/*
launcher.c - direct xash3d launcher
Copyright (C) 2015 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.
*/
#ifdef SINGLE_BINARY
#include <stdlib.h>
#include <string.h>
#ifdef XASH_SDLMAIN
#include "SDL.h"
#endif
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
typedef void (*pfnChangeGame)( const char *progname );
char szGameDir[128]; // safe place to keep gamedir
int g_iArgc;
void Host_Shutdown( void );
void Launcher_ChangeGame( const char *progname );
void *Com_LoadLibrary( char *, int );
int Host_Main( int szArgc, char **szArgv, const char *szGameDir, int chg, pfnChangeGame callback );
char **g_pszArgv;
void Launcher_ChangeGame( const char *progname )
{
strncpy( szGameDir, progname, sizeof( szGameDir ) - 1 );
Host_Shutdown( );
exit( Host_Main( g_iArgc, g_pszArgv, szGameDir, 1, &Launcher_ChangeGame ) );
}
#ifdef XASH_NOCONHOST
#include <windows.h>
int __stdcall WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdLine, int nShow)
{
int szArgc;
char **szArgv;
LPWSTR* lpArgv = CommandLineToArgvW(GetCommandLineW(), &szArgc);
int size, i = 0;
szArgv = (char**)malloc(szArgc*sizeof(char*));
for (; i < szArgc; ++i)
{
size = wcslen(lpArgv[i]) + 1;
szArgv[i] = (char*)malloc(size);
wcstombs(szArgv[i], lpArgv[i], size);
}
LocalFree(lpArgv);
main( szArgc, szArgv );
}
#endif
int main( int argc, char** argv )
{
char gamedir_buf[32] = "";
const char *gamedir = getenv("XASH3D_GAMEDIR");
if( !gamedir )
{
gamedir = "valve";
}
else
{
strncpy( gamedir_buf, gamedir, 32 );
gamedir = gamedir_buf;
}
#ifdef __EMSCRIPTEN__
#ifdef EMSCRIPTEN_LIB_FS
// For some unknown reason emscripten refusing to load libraries later
Com_LoadLibrary("menu", 0 );
Com_LoadLibrary("server", 0 );
Com_LoadLibrary("client", 0 );
#endif
#ifdef XASH_DEDICATED
// NodeJS support for debug
EM_ASM(try{
FS.mkdir('/xash');
FS.mount(NODEFS, { root: '.'}, '/xash' );
FS.chdir('/xash');
}catch(e){};);
#endif
#endif
g_iArgc = argc;
g_pszArgv = argv;
#if TARGET_OS_IPHONE
{
void IOS_LaunchDialog( void );
IOS_LaunchDialog();
}
#endif
return Host_Main( g_iArgc, g_pszArgv, gamedir, 0, &Launcher_ChangeGame );
}
#endif

10
engine/common/mod_bmodel.c

@ -1778,11 +1778,13 @@ static void Mod_LoadTextures( dbspmodel_t *bmod )
if( bmod->isworld ) if( bmod->isworld )
{ {
#ifndef XASH_DEDICATED
// release old sky layers first // release old sky layers first
GL_FreeTexture( tr.solidskyTexture ); GL_FreeTexture( tr.solidskyTexture );
GL_FreeTexture( tr.alphaskyTexture ); GL_FreeTexture( tr.alphaskyTexture );
tr.solidskyTexture = 0; tr.solidskyTexture = 0;
tr.alphaskyTexture = 0; tr.alphaskyTexture = 0;
#endif
} }
if( !bmod->texdatasize ) if( !bmod->texdatasize )
@ -1805,8 +1807,10 @@ static void Mod_LoadTextures( dbspmodel_t *bmod )
loadmodel->textures[i] = tx; loadmodel->textures[i] = tx;
Q_strncpy( tx->name, "*default", sizeof( tx->name )); Q_strncpy( tx->name, "*default", sizeof( tx->name ));
#ifndef XASH_DEDICATED
tx->gl_texturenum = tr.defaultTexture; tx->gl_texturenum = tr.defaultTexture;
tx->width = tx->height = 16; tx->width = tx->height = 16;
#endif
continue; // missed continue; // missed
} }
@ -1851,6 +1855,7 @@ static void Mod_LoadTextures( dbspmodel_t *bmod )
if( remaining >= 770 ) custom_palette = true; if( remaining >= 770 ) custom_palette = true;
} }
#ifndef XASH_DEDICATED
// check for multi-layered sky texture (quake1 specific) // check for multi-layered sky texture (quake1 specific)
if( bmod->isworld && !Q_strncmp( mt->name, "sky", 3 ) && (( mt->width / mt->height ) == 2 )) if( bmod->isworld && !Q_strncmp( mt->name, "sky", 3 ) && (( mt->width / mt->height ) == 2 ))
{ {
@ -1943,6 +1948,7 @@ static void Mod_LoadTextures( dbspmodel_t *bmod )
if( src ) Mem_Free( src ); if( src ) Mem_Free( src );
} }
} }
#endif
} }
// sequence the animations and detail textures // sequence the animations and detail textures
@ -2224,8 +2230,10 @@ static void Mod_LoadSurfaces( dbspmodel_t *bmod )
next_lightofs = 99999999; next_lightofs = 99999999;
} }
#ifndef XASH_DEDICATED // TODO: Do we need subdivide on server?
if( FBitSet( out->flags, SURF_DRAWTURB )) if( FBitSet( out->flags, SURF_DRAWTURB ))
GL_SubdivideSurface( out ); // cut up polygon for warps GL_SubdivideSurface( out ); // cut up polygon for warps
#endif
} }
// now we have enough data to trying determine samplecount per lightmap pixel // now we have enough data to trying determine samplecount per lightmap pixel
@ -2794,6 +2802,7 @@ void Mod_UnloadBrushModel( model_t *mod )
if( mod->name[0] != '*' ) if( mod->name[0] != '*' )
{ {
#ifndef XASH_DEDICATED
for( i = 0; i < mod->numtextures; i++ ) for( i = 0; i < mod->numtextures; i++ )
{ {
tx = mod->textures[i]; tx = mod->textures[i];
@ -2803,6 +2812,7 @@ void Mod_UnloadBrushModel( model_t *mod )
GL_FreeTexture( tx->gl_texturenum ); // main texture GL_FreeTexture( tx->gl_texturenum ); // main texture
GL_FreeTexture( tx->fb_texturenum ); // luma texture GL_FreeTexture( tx->fb_texturenum ); // luma texture
} }
#endif
Mem_FreePool( &mod->mempool ); Mem_FreePool( &mod->mempool );
} }

255
engine/common/mod_studio.c

@ -396,6 +396,247 @@ static void Mod_StudioCalcRotations( int boneused[], int numbones, const byte *p
if( pseqdesc->motiontype & STUDIO_Z ) pos[pseqdesc->motionbone][2] = 0.0f; if( pseqdesc->motiontype & STUDIO_Z ) pos[pseqdesc->motionbone][2] = 0.0f;
} }
/*
====================
StudioCalcBoneQuaternion
====================
*/
void R_StudioCalcBoneQuaternion( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, vec4_t q )
{
vec3_t angles1;
vec3_t angles2;
int j, k;
for( j = 0; j < 3; j++ )
{
if( !panim || panim->offset[j+3] == 0 )
{
angles2[j] = angles1[j] = pbone->value[j+3]; // default;
}
else
{
mstudioanimvalue_t *panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j+3]);
k = frame;
// debug
if( panimvalue->num.total < panimvalue->num.valid )
k = 0;
// find span of values that includes the frame we want
while( panimvalue->num.total <= k )
{
k -= panimvalue->num.total;
panimvalue += panimvalue->num.valid + 1;
// debug
if( panimvalue->num.total < panimvalue->num.valid )
k = 0;
}
// bah, missing blend!
if( panimvalue->num.valid > k )
{
angles1[j] = panimvalue[k+1].value;
if( panimvalue->num.valid > k + 1 )
{
angles2[j] = panimvalue[k+2].value;
}
else
{
if( panimvalue->num.total > k + 1 )
angles2[j] = angles1[j];
else angles2[j] = panimvalue[panimvalue->num.valid+2].value;
}
}
else
{
angles1[j] = panimvalue[panimvalue->num.valid].value;
if( panimvalue->num.total > k + 1 )
angles2[j] = angles1[j];
else angles2[j] = panimvalue[panimvalue->num.valid+2].value;
}
angles1[j] = pbone->value[j+3] + angles1[j] * pbone->scale[j+3];
angles2[j] = pbone->value[j+3] + angles2[j] * pbone->scale[j+3];
}
if( pbone->bonecontroller[j+3] != -1 && adj != NULL )
{
angles1[j] += adj[pbone->bonecontroller[j+3]];
angles2[j] += adj[pbone->bonecontroller[j+3]];
}
}
if( !VectorCompare( angles1, angles2 ))
{
vec4_t q1, q2;
AngleQuaternion( angles1, q1, true );
AngleQuaternion( angles2, q2, true );
QuaternionSlerp( q1, q2, s, q );
}
else
{
AngleQuaternion( angles1, q, true );
}
}
/*
====================
StudioCalcBonePosition
====================
*/
void R_StudioCalcBonePosition( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, vec3_t pos )
{
vec3_t origin1;
vec3_t origin2;
int j, k;
for( j = 0; j < 3; j++ )
{
if( !panim || panim->offset[j] == 0 )
{
origin2[j] = origin1[j] = pbone->value[j]; // default;
}
else
{
mstudioanimvalue_t *panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j]);
k = frame;
// debug
if( panimvalue->num.total < panimvalue->num.valid )
k = 0;
// find span of values that includes the frame we want
while( panimvalue->num.total <= k )
{
k -= panimvalue->num.total;
panimvalue += panimvalue->num.valid + 1;
// debug
if( panimvalue->num.total < panimvalue->num.valid )
k = 0;
}
// bah, missing blend!
if( panimvalue->num.valid > k )
{
origin1[j] = panimvalue[k+1].value;
if( panimvalue->num.valid > k + 1 )
{
origin2[j] = panimvalue[k+2].value;
}
else
{
if( panimvalue->num.total > k + 1 )
origin2[j] = origin1[j];
else origin2[j] = panimvalue[panimvalue->num.valid+2].value;
}
}
else
{
origin1[j] = panimvalue[panimvalue->num.valid].value;
if( panimvalue->num.total > k + 1 )
origin2[j] = origin1[j];
else origin2[j] = panimvalue[panimvalue->num.valid+2].value;
}
origin1[j] = pbone->value[j] + origin1[j] * pbone->scale[j];
origin2[j] = pbone->value[j] + origin2[j] * pbone->scale[j];
}
if( pbone->bonecontroller[j] != -1 && adj != NULL )
{
origin1[j] += adj[pbone->bonecontroller[j]];
origin2[j] += adj[pbone->bonecontroller[j]];
}
}
if( !VectorCompare( origin1, origin2 ))
{
VectorLerp( origin1, s, origin2, pos );
}
else
{
VectorCopy( origin1, pos );
}
}
/*
====================
StudioSlerpBones
====================
*/
void R_StudioSlerpBones( int numbones, vec4_t q1[], float pos1[][3], vec4_t q2[], float pos2[][3], float s )
{
int i;
s = bound( 0.0f, s, 1.0f );
for( i = 0; i < numbones; i++ )
{
QuaternionSlerp( q1[i], q2[i], s, q1[i] );
VectorLerp( pos1[i], s, pos2[i], pos1[i] );
}
}
/*
====================
StudioGetAnim
====================
*/
void *R_StudioGetAnim( studiohdr_t *m_pStudioHeader, model_t *m_pSubModel, mstudioseqdesc_t *pseqdesc )
{
mstudioseqgroup_t *pseqgroup;
cache_user_t *paSequences;
size_t filesize;
byte *buf;
pseqgroup = (mstudioseqgroup_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqgroupindex) + pseqdesc->seqgroup;
if( pseqdesc->seqgroup == 0 )
return ((byte *)m_pStudioHeader + pseqgroup->data + pseqdesc->animindex);
paSequences = (cache_user_t *)m_pSubModel->submodels;
if( paSequences == NULL )
{
paSequences = (cache_user_t *)Mem_Alloc( com_studiocache, MAXSTUDIOGROUPS * sizeof( cache_user_t ));
m_pSubModel->submodels = (void *)paSequences;
}
// check for already loaded
if( !Mod_CacheCheck(( cache_user_t *)&( paSequences[pseqdesc->seqgroup] )))
{
string filepath, modelname, modelpath;
COM_FileBase( m_pSubModel->name, modelname );
COM_ExtractFilePath( m_pSubModel->name, modelpath );
// NOTE: here we build real sub-animation filename because stupid user may rename model without recompile
Q_snprintf( filepath, sizeof( filepath ), "%s/%s%i%i.mdl", modelpath, modelname, pseqdesc->seqgroup / 10, pseqdesc->seqgroup % 10 );
buf = FS_LoadFile( filepath, &filesize, false );
if( !buf || !filesize ) Host_Error( "StudioGetAnim: can't load %s\n", filepath );
if( IDSEQGRPHEADER != *(uint *)buf ) Host_Error( "StudioGetAnim: %s is corrupted\n", filepath );
Con_Printf( "loading: %s\n", filepath );
paSequences[pseqdesc->seqgroup].data = Mem_Alloc( com_studiocache, filesize );
memcpy( paSequences[pseqdesc->seqgroup].data, buf, filesize );
Mem_Free( buf );
}
return ((byte *)paSequences[pseqdesc->seqgroup].data + pseqdesc->animindex);
}
/* /*
==================== ====================
StudioSetupBones StudioSetupBones
@ -806,6 +1047,7 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded )
phdr = R_StudioLoadHeader( mod, buffer ); phdr = R_StudioLoadHeader( mod, buffer );
if( !phdr ) return; // bad model if( !phdr ) return; // bad model
#ifndef XASH_DEDICATED
if( phdr->numtextures == 0 ) if( phdr->numtextures == 0 )
{ {
studiohdr_t *thdr; studiohdr_t *thdr;
@ -821,8 +1063,8 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded )
MsgDev( D_WARN, "Mod_LoadStudioModel: %s missing textures file\n", mod->name ); MsgDev( D_WARN, "Mod_LoadStudioModel: %s missing textures file\n", mod->name );
if( buffer2 ) Mem_Free( buffer2 ); if( buffer2 ) Mem_Free( buffer2 );
} }
else else
{ {
Mod_StudioLoadTextures( mod, thdr ); Mod_StudioLoadTextures( mod, thdr );
// give space for textures and skinrefs // give space for textures and skinrefs
@ -857,6 +1099,13 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded )
phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr
phdr->length = phdr->texturedataindex; // update model size phdr->length = phdr->texturedataindex; // update model size
} }
#else
// just copy model into memory
loadmodel->cache.data = Mem_Alloc( loadmodel->mempool, phdr->length );
memcpy( loadmodel->cache.data, buffer, phdr->length );
phdr = loadmodel->cache.data;
#endif
// setup bounding box // setup bounding box
if( !VectorCompare( vec3_origin, phdr->bbmin )) if( !VectorCompare( vec3_origin, phdr->bbmin ))
@ -898,7 +1147,9 @@ void Mod_UnloadStudioModel( model_t *mod )
if( mod->type != mod_studio ) if( mod->type != mod_studio )
return; // not a studio return; // not a studio
#ifndef XASH_DEDICATED
Mod_StudioUnloadTextures( mod->cache.data ); Mod_StudioUnloadTextures( mod->cache.data );
#endif
Mem_FreePool( &mod->mempool ); Mem_FreePool( &mod->mempool );
memset( mod, 0, sizeof( *mod )); memset( mod, 0, sizeof( *mod ));
} }

19
engine/common/model.c

@ -77,7 +77,7 @@ static void Mod_FreeUserData( model_t *mod )
if( !mod->name[0] || mod->name[0] == '*' ) if( !mod->name[0] || mod->name[0] == '*' )
return; return;
if( host.type == HOST_DEDICATED ) if( Host_IsDedicated() )
{ {
if( svgame.physFuncs.Mod_ProcessUserData != NULL ) if( svgame.physFuncs.Mod_ProcessUserData != NULL )
{ {
@ -85,6 +85,7 @@ static void Mod_FreeUserData( model_t *mod )
svgame.physFuncs.Mod_ProcessUserData( mod, false, NULL ); svgame.physFuncs.Mod_ProcessUserData( mod, false, NULL );
} }
} }
#ifndef XASH_DEDICATED
else else
{ {
if( clgame.drawFuncs.Mod_ProcessUserData != NULL ) if( clgame.drawFuncs.Mod_ProcessUserData != NULL )
@ -93,6 +94,7 @@ static void Mod_FreeUserData( model_t *mod )
clgame.drawFuncs.Mod_ProcessUserData( mod, false, NULL ); clgame.drawFuncs.Mod_ProcessUserData( mod, false, NULL );
} }
} }
#endif
} }
/* /*
@ -115,15 +117,17 @@ static void Mod_FreeModel( model_t *mod )
case mod_sprite: case mod_sprite:
Mod_UnloadSpriteModel( mod ); Mod_UnloadSpriteModel( mod );
break; break;
#ifndef XASH_DEDICATED
case mod_alias:
Mod_UnloadAliasModel( mod );
break;
#endif
case mod_studio: case mod_studio:
Mod_UnloadStudioModel( mod ); Mod_UnloadStudioModel( mod );
break; break;
case mod_brush: case mod_brush:
Mod_UnloadBrushModel( mod ); Mod_UnloadBrushModel( mod );
break; break;
case mod_alias:
Mod_UnloadAliasModel( mod );
break;
} }
memset( mod, 0, sizeof( *mod )); memset( mod, 0, sizeof( *mod ));
@ -302,9 +306,12 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
case IDSPRITEHEADER: case IDSPRITEHEADER:
Mod_LoadSpriteModel( mod, buf, &loaded, 0 ); Mod_LoadSpriteModel( mod, buf, &loaded, 0 );
break; break;
// TODO: Load alias models on dedicated too?
#ifndef XASH_DEDICATED
case IDALIASHEADER: case IDALIASHEADER:
Mod_LoadAliasModel( mod, buf, &loaded ); Mod_LoadAliasModel( mod, buf, &loaded );
break; break;
#endif
case Q1BSP_VERSION: case Q1BSP_VERSION:
case HLBSP_VERSION: case HLBSP_VERSION:
case QBSP2_VERSION: case QBSP2_VERSION:
@ -332,7 +339,7 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
if( world.loading ) if( world.loading )
SetBits( mod->flags, MODEL_WORLD ); // mark worldmodel SetBits( mod->flags, MODEL_WORLD ); // mark worldmodel
if( host.type == HOST_DEDICATED ) if( Host_IsDedicated() )
{ {
if( svgame.physFuncs.Mod_ProcessUserData != NULL ) if( svgame.physFuncs.Mod_ProcessUserData != NULL )
{ {
@ -340,6 +347,7 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
svgame.physFuncs.Mod_ProcessUserData( mod, true, buf ); svgame.physFuncs.Mod_ProcessUserData( mod, true, buf );
} }
} }
#ifndef XASH_DEDICATED
else else
{ {
if( clgame.drawFuncs.Mod_ProcessUserData != NULL ) if( clgame.drawFuncs.Mod_ProcessUserData != NULL )
@ -348,6 +356,7 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
clgame.drawFuncs.Mod_ProcessUserData( mod, true, buf ); clgame.drawFuncs.Mod_ProcessUserData( mod, true, buf );
} }
} }
#endif
} }
p = &mod_crcinfo[mod - mod_known]; p = &mod_crcinfo[mod - mod_known];

2
engine/common/net_chan.c

@ -1180,6 +1180,7 @@ Netchan_UpdateProgress
*/ */
void Netchan_UpdateProgress( netchan_t *chan ) void Netchan_UpdateProgress( netchan_t *chan )
{ {
#ifndef XASH_DEDICATED
fragbuf_t *p; fragbuf_t *p;
int i, c = 0; int i, c = 0;
int total = 0; int total = 0;
@ -1256,6 +1257,7 @@ void Netchan_UpdateProgress( netchan_t *chan )
} }
scr_download->value = bestpercent; scr_download->value = bestpercent;
#endif // XASH_DEDICATED
} }
/* /*

3
engine/common/net_encode.c

@ -1798,6 +1798,7 @@ Can go from either a baseline or a previous packet_entity
*/ */
qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state_t *to, int number, qboolean player, float timebase ) qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state_t *to, int number, qboolean player, float timebase )
{ {
#ifndef XASH_DEDICATED
delta_info_t *dt = NULL; delta_info_t *dt = NULL;
delta_t *pField; delta_t *pField;
int i, fRemoveType; int i, fRemoveType;
@ -1877,7 +1878,7 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state
{ {
Delta_ReadField( msg, pField, from, to, timebase ); Delta_ReadField( msg, pField, from, to, timebase );
} }
#endif // XASH_DEDICATED
// message parsed // message parsed
return true; return true;
} }

4
engine/common/pm_debug.c

@ -29,6 +29,7 @@ draw line from particles
*/ */
void PM_ParticleLine( const vec3_t start, const vec3_t end, int pcolor, float life, float zvel ) void PM_ParticleLine( const vec3_t start, const vec3_t end, int pcolor, float life, float zvel )
{ {
#ifndef XASH_DEDICATED
float len, curdist; float len, curdist;
vec3_t diff, pos; vec3_t diff, pos;
@ -43,6 +44,7 @@ void PM_ParticleLine( const vec3_t start, const vec3_t end, int pcolor, float li
CL_Particle( pos, pcolor, life, 0, zvel ); CL_Particle( pos, pcolor, life, 0, zvel );
curdist += 2.0f; curdist += 2.0f;
} }
#endif // XASH_DEDICATED
} }
/* /*
@ -67,6 +69,7 @@ PM_DrawBBox
*/ */
void PM_DrawBBox( const vec3_t mins, const vec3_t maxs, const vec3_t origin, int pcolor, float life ) void PM_DrawBBox( const vec3_t mins, const vec3_t maxs, const vec3_t origin, int pcolor, float life )
{ {
#ifndef XASH_DEDICATED
vec3_t p[8], tmp; vec3_t p[8], tmp;
float gap = BOX_GAP; float gap = BOX_GAP;
int i; int i;
@ -85,4 +88,5 @@ void PM_DrawBBox( const vec3_t mins, const vec3_t maxs, const vec3_t origin, int
{ {
PM_DrawRectangle( p[boxpnt[i][1]], p[boxpnt[i][0]], p[boxpnt[i][2]], p[boxpnt[i][3]], pcolor, life ); PM_DrawRectangle( p[boxpnt[i][1]], p[boxpnt[i][0]], p[boxpnt[i][2]], p[boxpnt[i][3]], pcolor, life );
} }
#endif // XASH_DEDICATED
} }

4
engine/common/pm_trace.c

@ -461,7 +461,9 @@ pmtrace_t PM_PlayerTraceExt( playermove_t *pmove, vec3_t start, vec3_t end, int
// run custom sweep callback // run custom sweep callback
if( pmove->server || Host_IsLocalClient( )) if( pmove->server || Host_IsLocalClient( ))
SV_ClipPMoveToEntity( pe, start, mins, maxs, end, &trace_bbox ); SV_ClipPMoveToEntity( pe, start, mins, maxs, end, &trace_bbox );
#ifndef XASH_DEDICATED
else CL_ClipPMoveToEntity( pe, start, mins, maxs, end, &trace_bbox ); else CL_ClipPMoveToEntity( pe, start, mins, maxs, end, &trace_bbox );
#endif
} }
else if( hullcount == 1 ) else if( hullcount == 1 )
{ {
@ -628,7 +630,9 @@ int PM_TestPlayerPosition( playermove_t *pmove, vec3_t pos, pmtrace_t *ptrace, p
// run custom sweep callback // run custom sweep callback
if( pmove->server || Host_IsLocalClient( )) if( pmove->server || Host_IsLocalClient( ))
SV_ClipPMoveToEntity( pe, pos, mins, maxs, pos, &trace ); SV_ClipPMoveToEntity( pe, pos, mins, maxs, pos, &trace );
#ifndef XASH_DEDICATED
else CL_ClipPMoveToEntity( pe, pos, mins, maxs, pos, &trace ); else CL_ClipPMoveToEntity( pe, pos, mins, maxs, pos, &trace );
#endif
// if we inside the custom hull // if we inside the custom hull
if( trace.allsolid ) if( trace.allsolid )

73
engine/common/sys_con.c

@ -221,3 +221,76 @@ void Sys_PrintLog( const char *pMsg )
fprintf( s_ld.logfile, "%s %s", logtime, pMsg ); fprintf( s_ld.logfile, "%s %s", logtime, pMsg );
fflush( s_ld.logfile ); fflush( s_ld.logfile );
} }
/*
=============================================================================
CONSOLE PRINT
=============================================================================
*/
/*
=============
Con_Printf
=============
*/
void Con_Printf( char *szFmt, ... )
{
static char buffer[MAX_PRINT_MSG];
va_list args;
if( !host.allow_console )
return;
va_start( args, szFmt );
Q_vsnprintf( buffer, sizeof( buffer ), szFmt, args );
va_end( args );
Sys_Print( buffer );
}
/*
=============
Con_DPrintf
=============
*/
void Con_DPrintf( char *szFmt, ... )
{
static char buffer[MAX_PRINT_MSG];
va_list args;
if( host_developer.value < DEV_NORMAL )
return;
va_start( args, szFmt );
Q_vsnprintf( buffer, sizeof( buffer ), szFmt, args );
va_end( args );
if( buffer[0] == '0' && buffer[1] == '\n' && buffer[2] == '\0' )
return; // hlrally spam
Sys_Print( buffer );
}
/*
=============
Con_Reportf
=============
*/
void Con_Reportf( char *szFmt, ... )
{
static char buffer[MAX_PRINT_MSG];
va_list args;
if( host_developer.value < DEV_EXTENDED )
return;
va_start( args, szFmt );
Q_vsnprintf( buffer, sizeof( buffer ), szFmt, args );
va_end( args );
Sys_Print( buffer );
}

2
engine/server/sv_game.c

@ -584,11 +584,13 @@ void SV_RestartAmbientSounds( void )
SV_StartSound( pfnPEntityOfEntIndex( si->entnum ), CHAN_STATIC, si->name, si->volume, si->attenuation, 0, si->pitch ); SV_StartSound( pfnPEntityOfEntIndex( si->entnum ), CHAN_STATIC, si->name, si->volume, si->attenuation, 0, si->pitch );
} }
#ifndef XASH_DEDICATED // TODO: ???
// restart soundtrack // restart soundtrack
if( S_StreamGetCurrentState( curtrack, looptrack, &position )) if( S_StreamGetCurrentState( curtrack, looptrack, &position ))
{ {
SV_StartMusic( curtrack, looptrack, position ); SV_StartMusic( curtrack, looptrack, position );
} }
#endif
} }
/* /*

5
engine/server/sv_init.c

@ -645,9 +645,10 @@ qboolean SV_InitGame( void )
return true; // already initialized ? return true; // already initialized ?
// first initialize? // first initialize?
if( !SV_LoadProgs( GI->game_dll )) COM_ResetLibraryError();
if( !SV_LoadProgs( SI.gamedll ))
{ {
Con_Printf( S_ERROR "can't initialize %s\n", GI->game_dll ); Con_Printf( S_ERROR "can't initialize %s: %s\n", SI.gamedll, COM_GetLibraryError() );
return false; // failed to loading server.dll return false; // failed to loading server.dll
} }

9
engine/server/sv_phys.c

@ -21,7 +21,9 @@ GNU General Public License for more details.
#include "gl_export.h" #include "gl_export.h"
typedef int (*PHYSICAPI)( int, server_physics_api_t*, physics_interface_t* ); typedef int (*PHYSICAPI)( int, server_physics_api_t*, physics_interface_t* );
#ifndef XASH_DEDICATED
extern triangleapi_t gTriApi; extern triangleapi_t gTriApi;
#endif
/* /*
pushmove objects do not obey gravity, and do not interact with each other or trigger fields, pushmove objects do not obey gravity, and do not interact with each other or trigger fields,
@ -2004,10 +2006,17 @@ static server_physics_api_t gPhysicsAPI =
SV_GetHeadNode, SV_GetHeadNode,
SV_ServerState, SV_ServerState,
Host_Error, Host_Error,
#ifndef XASH_DEDICATED
&gTriApi, // ouch! &gTriApi, // ouch!
pfnDrawConsoleString, pfnDrawConsoleString,
pfnDrawSetTextColor, pfnDrawSetTextColor,
pfnDrawConsoleStringLen, pfnDrawConsoleStringLen,
#else
NULL, // ouch! ouch!
NULL, // ouch! ouch!
NULL, // ouch! ouch!
NULL, // ouch! ouch!
#endif
Con_NPrintf, Con_NPrintf,
Con_NXPrintf, Con_NXPrintf,
SV_GetLightStyle, SV_GetLightStyle,

23
engine/server/sv_pmove.c

@ -323,6 +323,27 @@ void SV_AddLaddersToPmove( areanode_t *node, const vec3_t pmove_mins, const vec3
SV_AddLaddersToPmove( node->children[1], pmove_mins, pmove_maxs ); SV_AddLaddersToPmove( node->children[1], pmove_mins, pmove_maxs );
} }
static void pfnParticle( float *origin, int color, float life, int zpos, int zvel )
{
int v;
if( !origin )
{
MsgDev( D_ERROR, "SV_StartParticle: NULL origin. Ignored\n" );
return;
}
MSG_WriteByte( &sv.reliable_datagram, svc_particle );
MSG_WriteVec3Coord( &sv.reliable_datagram, origin );
MSG_WriteChar( &sv.reliable_datagram, 0 ); // no x-vel
MSG_WriteChar( &sv.reliable_datagram, 0 ); // no y-vel
v = bound( -128, (zpos * zvel) * 16.0f, 127 );
MSG_WriteChar( &sv.reliable_datagram, v ); // write z-vel
MSG_WriteByte( &sv.reliable_datagram, 1 );
MSG_WriteByte( &sv.reliable_datagram, color );
MSG_WriteByte( &sv.reliable_datagram, bound( 0, life * 8, 255 ));
}
static int pfnTestPlayerPosition( float *pos, pmtrace_t *ptrace ) static int pfnTestPlayerPosition( float *pos, pmtrace_t *ptrace )
{ {
return PM_TestPlayerPosition( svgame.pmove, pos, ptrace, NULL ); return PM_TestPlayerPosition( svgame.pmove, pos, ptrace, NULL );
@ -564,7 +585,7 @@ void SV_InitClientMove( void )
// common utilities // common utilities
svgame.pmove->PM_Info_ValueForKey = Info_ValueForKey; svgame.pmove->PM_Info_ValueForKey = Info_ValueForKey;
svgame.pmove->PM_Particle = CL_Particle; // for local system only svgame.pmove->PM_Particle = pfnParticle;
svgame.pmove->PM_TestPlayerPosition = pfnTestPlayerPosition; svgame.pmove->PM_TestPlayerPosition = pfnTestPlayerPosition;
svgame.pmove->Con_NPrintf = Con_NPrintf; svgame.pmove->Con_NPrintf = Con_NPrintf;
svgame.pmove->Con_DPrintf = Con_DPrintf; svgame.pmove->Con_DPrintf = Con_DPrintf;

4
engine/server/sv_save.c

@ -1118,8 +1118,10 @@ static void SaveClientState( SAVERESTOREDATA *pSaveData, const char *level, int
{ {
// sounds won't going across transition // sounds won't going across transition
header.soundCount = S_GetCurrentDynamicSounds( soundInfo, MAX_CHANNELS ); header.soundCount = S_GetCurrentDynamicSounds( soundInfo, MAX_CHANNELS );
#ifndef XASH_DEDICATED
// music not reqiured to save position: it's just continue playing on a next level // music not reqiured to save position: it's just continue playing on a next level
S_StreamGetCurrentState( header.introTrack, header.mainTrack, &header.trackPosition ); S_StreamGetCurrentState( header.introTrack, header.mainTrack, &header.trackPosition );
#endif
} }
// save viewentity to allow camera works after save\restore // save viewentity to allow camera works after save\restore
@ -2098,8 +2100,10 @@ void SV_SaveGame( const char *pName )
SaveBuildComment( comment, sizeof( comment )); SaveBuildComment( comment, sizeof( comment ));
result = SaveGameSlot( savename, comment ); result = SaveGameSlot( savename, comment );
#ifndef XASH_DEDICATED
if( result && !FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE )) if( result && !FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
CL_HudMessage( "GAMESAVED" ); // defined in titles.txt CL_HudMessage( "GAMESAVED" ); // defined in titles.txt
#endif
} }
/* /*

Loading…
Cancel
Save