24 Oct 2013

This commit is contained in:
g-cont 2013-10-24 00:00:00 +04:00 committed by Alibek Omarov
parent 563304d87a
commit d52b2b3794
30 changed files with 739 additions and 311 deletions

View File

@ -35,6 +35,7 @@ typedef vec_t vec4_t[4];
#define MIPLEVELS 4
#define VERTEXSIZE 7
#define MAXLIGHTMAPS 4
#define MAXSTYLES 12 // BSP32 supports up to 12 styles per face
#define NUM_AMBIENTS 4 // automatic ambient sounds
// model types
@ -126,12 +127,11 @@ struct decal_s
{
decal_t *pnext; // linked list for each surface
msurface_t *psurface; // Surface id for persistence / unlinking
short dx; // Offsets into surface texture
short dy; // (in texture coordinates, so we don't need floats)
float dx; // local texture coordinates
float dy; //
float scale; // Pixel scale
short texture; // Decal texture
byte scale; // Pixel scale
byte flags; // Decal flags FDECAL_*
short entityIndex; // Entity this is attached to
// Xash3D added
vec3_t position; // location of the decal center in world space.
@ -216,6 +216,8 @@ typedef struct mextrasurf_s
vec3_t origin; // surface origin
msurfmesh_t *mesh; // VBO\VA ready surface mesh. Not used by engine but can be used by mod-makers
byte styles[MAXSTYLES]; // expansion for BSP32 (12 lightstyles per surface)
int cached_light[MAXSTYLES]; // values currently used in lightmap
int dlight_s, dlight_t; // gl lightmap coordinates for dynamic lightmaps
int mirrortexturenum; // gl texnum
@ -223,7 +225,7 @@ typedef struct mextrasurf_s
struct mextrasurf_s *mirrorchain; // for gl_texsort drawing
struct mextrasurf_s *detailchain; // for detail textures drawing
int reserved[7]; // just for future expansions or mod-makers
int reserved[32]; // just for future expansions or mod-makers
} mextrasurf_t;
typedef struct hull_s
@ -329,6 +331,8 @@ typedef struct auxvert_s
#define MAX_SCOREBOARDNAME 32
#define MAX_INFO_STRING 256
#include "custom.h"
typedef struct player_info_s
{
int userid; // User id on server
@ -352,6 +356,8 @@ typedef struct player_info_s
float gaitframe;
float gaityaw;
vec3_t prevgaitorigin;
customization_t customdata;
} player_info_t;
//

View File

@ -180,7 +180,7 @@ typedef struct local_state_s
{
entity_state_t playerstate;
clientdata_t client;
weapon_data_t weapondata[32];
weapon_data_t weapondata[64];
} local_state_t;
#endif//ENTITY_STATE_H

View File

@ -33,6 +33,8 @@ typedef struct IVoiceTweak_s
// Get/set control values.
void (*SetControlFloat)( VoiceTweakControl iControl, float value );
float (*GetControlFloat)( VoiceTweakControl iControl );
int (*GetSpeakingVolume)( void );
} IVoiceTweak;
#endif//IVOICETWEAK_H

View File

@ -189,6 +189,7 @@ struct efx_api_s
void (*R_GetPackedColor)( short *packed, short color );
short (*R_LookupColor)( unsigned char r, unsigned char g, unsigned char b );
void (*R_DecalRemoveAll)( int textureIndex ); // textureIndex points to the decal index in the array, not the actual texture index.
void (*R_FireCustomDecal)( int textureIndex, int entity, int modelIndex, float *position, int flags, float scale );
};
#endif//R_EFX_H

View File

@ -108,8 +108,9 @@ typedef struct engine_studio_api_s
void ( *GL_StudioDrawShadow )( void );
void ( *GL_SetRenderMode )( int mode );
// Xash3D extension
struct mstudiotex_s *( *StudioGetTexture )( struct cl_entity_s *e );
void ( *StudioSetRenderamt )( int iRenderamt );
void ( *StudioSetCullState )( int iCull );
void ( *StudioRenderShadow )( int iSprite, float *p1, float *p2, float *p3, float *p4 );
} engine_studio_api_t;
typedef struct server_studio_api_s

View File

@ -19,7 +19,16 @@ GNU General Public License for more details.
#include "lightstyle.h"
#include "dlight.h"
#define CL_RENDER_INTERFACE_VERSION 26
// changes for version 28
// replace decal_t from software declaration to hardware (matched to normal HL)
// mextrasurf_t->byte styles[12] added
// mextrasurf_t->increased limit of reserved fields (up from 7 to 32)
// replace R_StoreEfrags with him extended version
// formed group for BSP decal manipulating
// move misc functions at end of the interface
// added new export for clearing studio decals
#define CL_RENDER_INTERFACE_VERSION 28
#define MAX_STUDIO_DECALS 4096 // + unused space of BSP decals
#define SURF_INFO( surf, mod ) ((mextrasurf_t *)mod->cache.data + (surf - mod->surfaces))
@ -89,13 +98,15 @@ typedef enum
typedef struct beam_s BEAM;
typedef struct particle_s particle_t;
// 10 bytes here
// 12 bytes here
typedef struct modelstate_s
{
short sequence;
short frame; // 10 bits multiple by 4, should be enough
byte blending[2];
byte controller[4];
byte body;
byte skin;
} modelstate_t;
typedef struct decallist_s
@ -105,6 +116,7 @@ typedef struct decallist_s
short entityIndex;
byte depth;
byte flags;
float scale;
// this is the surface plane that we hit so that
// we can move certain decals across
@ -130,7 +142,7 @@ typedef struct render_api_s
void (*R_SetCurrentEntity)( struct cl_entity_s *ent ); // tell engine about both currententity and currentmodel
void (*R_SetCurrentModel)( struct model_s *mod ); // change currentmodel but leave currententity unchanged
void (*GL_SetWorldviewProjectionMatrix)( const float *glmatrix ); // update viewprojection matrix (tracers uses it)
void (*R_StoreEfrags)( struct efrag_s **ppefrag ); // store efrags for static entities
void (*R_StoreEfrags)( struct efrag_s **ppefrag, int framecount );// store efrags for static entities
// Texture tools
int (*GL_FindTexture)( const char *name );
@ -139,15 +151,10 @@ typedef struct render_api_s
int (*GL_CreateTexture)( const char *name, int width, int height, const void *buffer, int flags );
void (*GL_FreeTexture)( unsigned int texnum );
// Draw stuff (decals and particles are drawing by the engine)
// Decals manipulating (draw & remove)
void (*DrawSingleDecal)( struct decal_s *pDecal, struct msurface_s *fa );
void (*GL_DrawParticles)( const float *vieworg, const float *fwd, const float *rt, const float *up, unsigned int clipFlags );
// Misc renderer functions
void (*EnvShot)( const float *vieworg, const char *name, qboolean skyshot ); // creates a cubemap or skybox into gfx\env folder
int (*COM_CompareFileTime)( const char *filename1, const char *filename2, int *iCompare );
void (*Host_Error)( const char *error, ... ); // cause Host Error
int (*SPR_LoadExt)( const char *szPicName, unsigned int texFlags ); // extended version of SPR_Load
float *(*R_DecalSetupVerts)( struct decal_s *pDecal, struct msurface_s *surf, int texture, int *outCount );
void (*R_EntityRemoveDecals)( struct model_s *mod ); // remove all the decals from specified entity (BSP only)
// AVIkit support
void *(*AVI_LoadVideo)( const char *filename, int load_audio, int ignore_hwgamma );
@ -167,14 +174,17 @@ typedef struct render_api_s
void (*GL_TexMatrixIdentity)( void );
void (*GL_CleanUpTextureUnits)( int last ); // pass 0 for clear all the texture units
void (*GL_TexGen)( unsigned int coord, unsigned int mode );
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 26
void (*R_EntityRemoveDecals)( struct model_s *mod ); // remove all the decals from specified entity (BSP only)
float *(*R_DecalSetupVerts)( struct decal_s *pDecal, struct msurface_s *surf, int texture, int *outCount );
void (*R_StoreEfragsExt)( struct efrag_s **ppefrag, int framecount ); // store efrags for static entities
void (*GL_TextureTarget)( unsigned int target ); // change texture unit mode without bind texture
struct mstudiotex_s *( *StudioGetTexture )( struct cl_entity_s *e ); // moved here to avoid incompatibility with IEngineStudio official iface
// Misc renderer functions
void (*GL_DrawParticles)( const float *vieworg, const float *fwd, const float *rt, const float *up, unsigned int clipFlags );
void (*EnvShot)( const float *vieworg, const char *name, qboolean skyshot ); // creates a cubemap or skybox into gfx\env folder
int (*COM_CompareFileTime)( const char *filename1, const char *filename2, int *iCompare );
void (*Host_Error)( const char *error, ... ); // cause Host Error
int (*SPR_LoadExt)( const char *szPicName, unsigned int texFlags ); // extended version of SPR_Load
struct mstudiotex_s *( *StudioGetTexture )( struct cl_entity_s *e );
const struct ref_overview_s *( *GetOverviewParms )( void );
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 28
} render_api_t;
// render callbacks
@ -191,6 +201,8 @@ typedef struct render_interface_s
void (*R_StudioDecalShoot)( int decalTexture, struct cl_entity_s *ent, const float *start, const float *pos, int flags, modelstate_t *state );
// prepare studio decals for save
int (*R_CreateStudioDecalList)( decallist_t *pList, int count, qboolean changelevel );
// clear decals by engine request (e.g. for demo recording or vid_restart)
void (*R_ClearStudioDecals)( void );
// grab r_speeds message
qboolean (*R_SpeedsMessage)( char *out, size_t size );
// replace with built-in R_DrawCubemapView for make skyshots or envshots

View File

@ -52,7 +52,11 @@ typedef struct triangleapi_s
int (*WorldToScreen)( float *world, float *screen ); // Returns 1 if it's z clipped
void (*Fog)( float flFogColor[3], float flStart, float flEnd, int bOn ); //Works just like GL_FOG, flFogColor is r/g/b.
void (*ScreenToWorld)( float *screen, float *world );
void (*GetMatrix)( const int pname, float *matrix );
int (*BoxInPVS)( float *mins, float *maxs );
void (*LightAtPoint)( float *pos, float *value );
void (*Color4fRendermode)( float r, float g, float b, float a, int rendermode );
void (*FogParams)( float flDensity, int iFogSkybox );
} triangleapi_t;
#endif//TRIANGLEAPI_H

View File

@ -28,6 +28,14 @@ extern "C" {
#include "const.h"
#define MAX_ALIAS_NAME 32
typedef struct cmdalias_s
{
struct cmdalias_s *next;
char name[MAX_ALIAS_NAME];
char *value;
} cmdalias_t;
// this file is included by both the engine and the client-dll,
// so make sure engine declarations aren't done twice
@ -97,6 +105,8 @@ typedef struct hud_player_info_s
char *model;
short topcolor;
short bottomcolor;
unsigned __int64 m_nSteamID;
} hud_player_info_t;
typedef struct cl_enginefuncs_s
@ -250,75 +260,43 @@ typedef struct cl_enginefuncs_s
void (*pfnSetMousePos)( int x, int y );
void (*pfnSetMouseEnable)( qboolean fEnable );
struct cvar_s* (*pfnGetCvarList)( void );
struct cmd_s* (*pfnGetCmdList)( void );
char* (*pfnCvarName)( struct cvar_s* cvar );
char* (*pfnCmdName)( struct cmd_s* cmd );
// undocumented interface starts here
struct cvar_s* (*pfnGetFirstCvarPtr)( void );
void* (*pfnGetFirstCmdFunctionHandle)( void );
void* (*pfnGetNextCmdFunctionHandle)( void *cmdhandle );
const char* (*pfnGetCmdFunctionName)( void *cmdhandle );
float (*pfnGetClientOldTime)( void );
float (*pfnGetGravity)( void );
struct model_s* (*pfnGetModelByIndex)( int index );
void (*pfnSetFilterMode)( int mode ); // same as gl_texsort in original Quake
void (*pfnSetFilterColor)( float red, float green, float blue );
void (*pfnSetFilterBrightness)( float brightness );
void *(*pfnSequenceGet)( const char *fileName, const char *entryName );
void (*pfnSPR_DrawGeneric)( int frame, int x, int y, const wrect_t *prc, int blendsrc, int blenddst, int width, int height );
void *(*pfnSequencePickSentence)( const char *groupName, int pickMethod, int *entryPicked );
int (*pfnDrawString)( int x, int y, const char *str, int r, int g, int b );
int (*pfnDrawStringReverse)( int x, int y, const char *str, int r, int g, int b );
const char *(*LocalPlayerInfo_ValueForKey)( const char* key );
int (*pfnVGUI2DrawCharacter)( int x, int y, int ch, unsigned int font );
int (*pfnVGUI2DrawCharacterAdditive)( int x, int y, int ch, int r, int g, int b, unsigned int font );
unsigned int (*pfnGetApproxWavePlayLen)( char *filename );
void* (*GetCareerGameUI)( void ); // g-cont. !!!! potential crash-point!
void (*Cvar_Set)( char *name, char *value );
int (*pfnIsPlayingCareerMatch)( void );
void (*pfnPlaySoundVoiceByName)( char *szSound, float volume, int pitch );
void (*pfnPrimeMusicStream)( char *filename, int looping );
double (*pfnSys_FloatTime)( void );
float (*pfnGetServerTime)( void );
float (*pfnGetGravity)( void );
const struct model_s* (*pfnPrecacheSprite)( HSPRITE spr );
// Appears to modifies hidden cvar gl_texsort.
void (*pfnEnableTexSort)( int enable );
// Colour scaling values for screen. Only works when gl_texsort is active.
void (*pfnSetLightmapColor)( float red, float green, float blue );
// Final scaling factor for screen. Only works when gl_texsort is active.
void (*pfnSetLightmapScale)( float scale );
// Seems to be a client entry point to the pfnSequenceGet function introduced for CS:CZ
void* (*pfnSequenceGet)( const char *fileName, const char *entryName );
// Draws a sprite on the screen - parameters are likely incorrect.
void (*pfnSPR_DrawGeneric)( int frame, int x, int y, const wrect_t *prc, int blendsrc, int blenddst, int u3, int u4 );
// Seems to be a client entry point to the pfnSequencePickSentence function introduced for CS:CZ
void* (*pfnSequencePickSentence)( const char *groupName, int pickMethod, int *picked );
// localizes hud string, uses Legacy font from skin def
// also supports unicode strings
int (*pfnDrawLocalizedHudString)( int x, int y, const char* str, int r, int g, int b );
// i can't get this to work for some reason, don't use this
int (*pfnDrawLocalizedConsoleString)( int x, int y, const char* str );
// gets keyvalue for local player, useful for querying vgui menus or autohelp
const char *(*LocalPlayerInfo_ValueForKey)( const char* key );
void (*pfnDrawText)( int x, int y, const char* text, unsigned long font );
int (*pfnDrawUnicodeCharacter)( int x, int y, short number, int r, int g, int b, unsigned long hfont );
// Seems to be a client entry point to the pfnGetApproxWavePlayLen function introduced for CS:CZ
unsigned int (*pfnGetApproxWavePlayLen)( char *filename );
// for condition zero, returns interface from GameUI
void* (*GetCareerGameInterface)( void ); // g-cont. !!!! potential crash-point!
// Sets cvar value - why is this needed when Cvar_SetValue already exists?
void (*Cvar_Set)( char *name, char *value );
// Seems to be a client entry point to the pfnIsCareerMatch function introduced for CS:CZ
int (*pfnIsCareerMatch)( void );
// passes pitch as param
void (*pfnStartDynamicSound)( char *filename, float volume, float pitch );
void (*pfnMP3_InitStream)( char *filename, int flags );
float (*pfnSys_FloatTime)( void );
void (*pfnProcessTutorMessageDecayBuffer)( int *buffer, int buflen );
void (*pfnConstructTutorMessageDecayBuffer)( int *buffer, int buflen );
void (*pfnResetTutorMessageDecayData)( void );
// Seems to be an exact copy of the previous StartDynamicSound function???
void (*pfnStartDynamicSound2)( char *filename, float volume, float pitch );
// Same like pfnFillRGBA - with other mode (substractive)
void (*pfnFillRGBA2)( int x, int y, int width, int height, int r, int g, int b, int a );
// decay funcs
void (*pfnProcessTutorMessageDecayBuffer)( int *buffer, int buflen );
void (*pfnConstructTutorMessageDecayBuffer)( int *buffer, int buflen );
void (*pfnResetTutorMessageDecayData)( void );
void (*pfnPlaySoundByNameAtPitch)( char *szSound, float volume, int pitch );
void (*pfnFillRGBABlend)( int x, int y, int width, int height, int r, int g, int b, int a );
int (*pfnGetAppID)( void );
cmdalias_t *(*pfnGetAliases)( void );
void (*pfnVguiWrap2_GetMouseDelta)( int *x, int *y );
} cl_enginefunc_t;
#define CLDLL_INTERFACE_VERSION 7

View File

@ -2629,9 +2629,9 @@ pfnGetServerTime
=============
*/
float pfnGetServerTime( void )
float pfnGetClientOldTime( void )
{
return cl.mtime[0];
return cl.oldtime;
}
/*
@ -2645,19 +2645,6 @@ float pfnGetGravity( void )
return clgame.movevars.gravity;
}
/*
=============
pfnPrecacheSprite
=============
*/
const model_t *pfnPrecacheSprite( HSPRITE hSprite )
{
if( hSprite <= 0 || hSprite > ( MAX_IMAGES - 1 ))
return NULL; // bad image
return &clgame.sprites[hSprite];
}
/*
=============
pfnEnableTexSort
@ -2706,24 +2693,24 @@ void pfnSPR_DrawGeneric( int frame, int x, int y, const wrect_t *prc, int blends
/*
=============
pfnDrawLocalizedHudString
pfnDrawString
TODO: implement
=============
*/
int pfnDrawLocalizedHudString( int x, int y, const char* str, int r, int g, int b )
int pfnDrawString( int x, int y, const char *str, int r, int g, int b )
{
return 0;
}
/*
=============
pfnDrawLocalizedConsoleString
pfnDrawStringReverse
TODO: implement
=============
*/
int pfnDrawLocalizedConsoleString( int x, int y, const char* str )
int pfnDrawStringReverse( int x, int y, const char *str, int r, int g, int b )
{
return 0;
}
@ -2741,23 +2728,24 @@ const char *LocalPlayerInfo_ValueForKey( const char* key )
/*
=============
pfnDrawText
pfnVGUI2DrawCharacter
TODO: implement
=============
*/
void pfnDrawText( int x, int y, const char* text, unsigned long font )
int pfnVGUI2DrawCharacter( int x, int y, int ch, unsigned int font )
{
return 0;
}
/*
=============
pfnDrawUnicodeCharacter
pfnVGUI2DrawCharacterAdditive
TODO: implement
=============
*/
int pfnDrawUnicodeCharacter( int x, int y, short number, int r, int g, int b, unsigned long hfont )
int pfnVGUI2DrawCharacterAdditive( int x, int y, int ch, int r, int g, int b, unsigned int font )
{
return 0;
}
@ -2776,11 +2764,11 @@ void *GetCareerGameInterface( void )
/*
=============
pfnStartDynamicSound
pfnPlaySoundVoiceByName
=============
*/
void pfnStartDynamicSound( char *filename, float volume, float pitch )
void pfnPlaySoundVoiceByName( char *filename, float volume, int pitch )
{
int hSound = S_RegisterSound( filename );
S_StartSound( NULL, cl.refdef.viewentity, CHAN_AUTO, hSound, volume, ATTN_NORM, pitch, SND_STOP_LOOPING );
@ -2792,7 +2780,7 @@ pfnMP3_InitStream
=============
*/
void pfnMP3_InitStream( char *filename, int flags )
void pfnMP3_InitStream( char *filename, int looping )
{
if( !filename )
{
@ -2800,8 +2788,7 @@ void pfnMP3_InitStream( char *filename, int flags )
return;
}
// g-cont. flag 1 is probably 'LOOP'
if( flags & 1 )
if( looping )
{
S_StartBackgroundTrack( filename, filename, 0 );
}
@ -2813,22 +2800,11 @@ void pfnMP3_InitStream( char *filename, int flags )
/*
=============
pfnSys_FloatTime
pfnPlaySoundByNameAtPitch
=============
*/
float pfnSys_FloatTime( void )
{
return (float)Sys_DoubleTime();
}
/*
=============
pfnStartDynamicSound2
=============
*/
void pfnStartDynamicSound2( char *filename, float volume, float pitch )
void pfnPlaySoundByNameAtPitch( char *filename, float volume, int pitch )
{
int hSound = S_RegisterSound( filename );
S_StartSound( NULL, cl.refdef.viewentity, CHAN_STATIC, hSound, volume, ATTN_NORM, pitch, SND_STOP_LOOPING );
@ -2836,11 +2812,11 @@ void pfnStartDynamicSound2( char *filename, float volume, float pitch )
/*
=============
pfnFillRGBA2
pfnFillRGBABlend
=============
*/
void pfnFillRGBA2( int x, int y, int width, int height, int r, int g, int b, int a )
void pfnFillRGBABlend( int x, int y, int width, int height, int r, int g, int b, int a )
{
r = bound( 0, r, 255 );
g = bound( 0, g, 255 );
@ -2859,6 +2835,28 @@ void pfnFillRGBA2( int x, int y, int width, int height, int r, int g, int b, int
pglColor4ub( 255, 255, 255, 255 );
}
/*
=============
pfnGetAppID
=============
*/
int pfnGetAppID( void )
{
return 220; // standard Valve value
}
/*
=============
pfnVguiWrap2_GetMouseDelta
TODO: implement
=============
*/
void pfnVguiWrap2_GetMouseDelta( int *x, int *y )
{
}
/*
=================
TriApi implementation
@ -3149,6 +3147,76 @@ void TriFog( float flFogColor[3], float flStart, float flEnd, int bOn )
pglHint( GL_FOG_HINT, GL_NICEST );
}
/*
=============
TriGetMatrix
very strange export
=============
*/
void TriGetMatrix( const int pname, float *matrix )
{
pglGetFloatv( pname, matrix );
}
/*
=============
TriBoxInPVS
check box in pvs (absmin, absmax)
=============
*/
int TriBoxInPVS( float *mins, float *maxs )
{
return Mod_BoxVisible( mins, maxs, Mod_GetCurrentVis( ));
}
/*
=============
TriLightAtPoint
NOTE: dlights are ignored
=============
*/
void TriLightAtPoint( float *pos, float *value )
{
color24 ambient;
if( !pos || !value )
return;
R_LightForPoint( pos, &ambient, false, false, 0.0f );
value[0] = (float)ambient.r * 255.0f;
value[1] = (float)ambient.g * 255.0f;
value[2] = (float)ambient.b * 255.0f;
}
/*
=============
TriColor4fRendermode
Heavy legacy of Quake...
=============
*/
void TriColor4fRendermode( float r, float g, float b, float a, int rendermode )
{
if( rendermode == kRenderTransAlpha )
pglColor4f( r, g, b, a );
else pglColor4f( r * a, g * a, b * a, 1.0f );
}
/*
=============
TriForParams
=============
*/
void TriFogParams( float flDensity, int iFogSkybox )
{
// FIXME: implement
}
/*
=================
DemoApi implementation
@ -3455,6 +3523,18 @@ float Voice_GetControlFloat( VoiceTweakControl iControl )
return 1.0f;
}
/*
=================
Voice_GetSpeakingVolume
=================
*/
int Voice_GetSpeakingVolume( void )
{
// TODO: implement
return 255;
}
// shared between client and server
triangleapi_t gTriApi =
{
@ -3473,6 +3553,11 @@ triangleapi_t gTriApi =
R_WorldToScreen, // NOTE: XPROJECT, YPROJECT should be done in client.dll
TriFog,
R_ScreenToWorld,
TriGetMatrix,
TriBoxInPVS,
TriLightAtPoint,
TriColor4fRendermode,
TriFogParams,
};
static efx_api_t gEfxApi =
@ -3610,6 +3695,7 @@ static IVoiceTweak gVoiceApi =
Voice_EndVoiceTweakMode,
Voice_SetControlFloat,
Voice_GetControlFloat,
Voice_GetSpeakingVolume,
};
// engine callbacks
@ -3717,35 +3803,38 @@ static cl_enginefunc_t gEngfuncs =
pfnSetMousePos,
pfnSetMouseEnable,
Cvar_GetList,
Cmd_GetList,
Cvar_GetName,
Cmd_GetFirstFunctionHandle,
Cmd_GetNextFunctionHandle,
Cmd_GetName,
pfnGetServerTime,
pfnGetClientOldTime,
pfnGetGravity,
pfnPrecacheSprite,
Mod_Handle,
pfnEnableTexSort,
pfnSetLightmapColor,
pfnSetLightmapScale,
pfnSequenceGet,
pfnSPR_DrawGeneric,
pfnSequencePickSentence,
pfnDrawLocalizedHudString,
pfnDrawLocalizedConsoleString,
pfnDrawString,
pfnDrawStringReverse,
LocalPlayerInfo_ValueForKey,
pfnDrawText,
pfnDrawUnicodeCharacter,
pfnVGUI2DrawCharacter,
pfnVGUI2DrawCharacterAdditive,
Sound_GetApproxWavePlayLen,
GetCareerGameInterface,
Cvar_Set,
pfnIsCareerMatch,
pfnStartDynamicSound,
pfnPlaySoundVoiceByName,
pfnMP3_InitStream,
pfnSys_FloatTime,
Sys_DoubleTime,
pfnProcessTutorMessageDecayBuffer,
pfnConstructTutorMessageDecayBuffer,
pfnResetTutorMessageDecayData,
pfnStartDynamicSound2,
pfnFillRGBA2,
pfnPlaySoundByNameAtPitch,
pfnFillRGBABlend,
pfnGetAppID,
Cmd_AliasGetList,
pfnVguiWrap2_GetMouseDelta,
};
void CL_UnloadProgs( void )
@ -3778,6 +3867,8 @@ qboolean CL_LoadProgs( const char *name )
{
static playermove_t gpMove;
const dllfunc_t *func;
CL_EXPORT_FUNCS F; // export 'F'
qboolean critical_exports = true;
if( clgame.hInstance ) CL_UnloadProgs();
@ -3803,24 +3894,58 @@ qboolean CL_LoadProgs( const char *name )
for( func = cdll_exports; func && func->name; func++ )
*func->func = NULL;
// trying to get single export named 'F'
if(( F = (void *)Com_GetProcAddress( clgame.hInstance, "F" )) != NULL )
{
MsgDev( D_NOTE, "CL_LoadProgs: found single callback export\n" );
// trying to fill interface now
F( &clgame.dllFuncs );
// check critical functions again
for( func = cdll_exports; func && func->name; func++ )
{
if( func->func == NULL )
break; // BAH critical function was missed
}
// because all the exports are loaded through function 'F"
if( !func || !func->name )
critical_exports = false;
}
for( func = cdll_exports; func && func->name != NULL; func++ )
{
if( *func->func != NULL )
continue; // already get through 'F'
// functions are cleared before all the extensions are evaluated
if(!( *func->func = (void *)Com_GetProcAddress( clgame.hInstance, func->name )))
{
MsgDev( D_NOTE, "CL_LoadProgs: failed to get address of %s proc\n", func->name );
Com_FreeLibrary( clgame.hInstance );
clgame.hInstance = NULL;
return false;
if( critical_exports )
{
Com_FreeLibrary( clgame.hInstance );
clgame.hInstance = NULL;
return false;
}
}
}
// clear new exports
for( func = cdll_new_exports; func && func->name; func++ )
*func->func = NULL;
// it may be loaded through 'F' so we don't need to clear them
if( critical_exports )
{
// clear new exports
for( func = cdll_new_exports; func && func->name; func++ )
*func->func = NULL;
}
for( func = cdll_new_exports; func && func->name != NULL; func++ )
{
if( *func->func != NULL )
continue; // already get through 'F'
// functions are cleared before all the extensions are evaluated
// NOTE: new exports can be missed without stop the engine
if(!( *func->func = (void *)Com_GetProcAddress( clgame.hInstance, func->name )))

View File

@ -489,9 +489,11 @@ CL_ParseStaticDecal
*/
void CL_ParseStaticDecal( sizebuf_t *msg )
{
vec3_t origin;
int decalIndex, entityIndex, modelIndex;
int flags;
vec3_t origin;
int decalIndex, entityIndex, modelIndex;
cl_entity_t *ent = NULL;
float scale;
int flags;
BF_ReadVec3Coord( msg, origin );
decalIndex = BF_ReadWord( msg );
@ -501,8 +503,9 @@ void CL_ParseStaticDecal( sizebuf_t *msg )
modelIndex = BF_ReadWord( msg );
else modelIndex = 0;
flags = BF_ReadByte( msg );
scale = (float)BF_ReadWord( msg ) / 4096.0f;
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, modelIndex, origin, flags );
CL_FireCustomDecal( CL_DecalIndex( decalIndex ), entityIndex, modelIndex, origin, flags|FDECAL_CLIPTEST, scale );
}
/*
@ -1103,8 +1106,8 @@ void CL_ParseStudioDecal( sizebuf_t *msg )
BF_ReadVec3Coord( msg, pos );
BF_ReadVec3Coord( msg, start );
decalIndex = BF_ReadShort( msg );
entityIndex = BF_ReadShort( msg );
decalIndex = BF_ReadWord( msg );
entityIndex = BF_ReadWord( msg );
flags = BF_ReadByte( msg );
state.sequence = BF_ReadShort( msg );
@ -1115,14 +1118,9 @@ void CL_ParseStudioDecal( sizebuf_t *msg )
state.controller[1] = BF_ReadByte( msg );
state.controller[2] = BF_ReadByte( msg );
state.controller[3] = BF_ReadByte( msg );
if( cls.state == ca_connected )
{
// this message came on restore.
// read modelindex in case client models are not linked with entities
// because first client frame has not yet received
modelIndex = BF_ReadShort( msg );
}
modelIndex = BF_ReadWord( msg );
state.body = BF_ReadByte( msg );
state.skin = BF_ReadByte( msg );
if( clgame.drawFuncs.R_StudioDecalShoot != NULL )
{

View File

@ -2593,7 +2593,19 @@ normal temporary decal
*/
void CL_DecalShoot( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags )
{
R_DecalShoot( textureIndex, entityIndex, modelIndex, pos, (flags|FDECAL_CLIPTEST), NULL );
R_DecalShoot( textureIndex, entityIndex, modelIndex, pos, (flags|FDECAL_CLIPTEST), NULL, 1.0f );
}
/*
===============
CL_FireCustomDecal
custom temporary decal
===============
*/
void CL_FireCustomDecal( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags, float scale )
{
R_DecalShoot( textureIndex, entityIndex, modelIndex, pos, flags, NULL, scale );
}
/*
@ -2605,7 +2617,7 @@ spray custom colored decal (clan logo etc)
*/
void CL_PlayerDecal( int textureIndex, int entityIndex, float *pos )
{
R_DecalShoot( textureIndex, entityIndex, 0, pos, 0, NULL );
R_DecalShoot( textureIndex, entityIndex, 0, pos, 0, NULL, 1.0f );
}
/*

View File

@ -292,51 +292,57 @@ typedef struct
int flags; // FNETAPI_MULTIPLE_RESPONSE etc
} net_request_t;
// new versions of client dlls have a sanigle export with all callbacks
typedef void (*CL_EXPORT_FUNCS)( void *pv );
// NOTE: ordering is important!
typedef struct
{
int (*pfnInitialize)( cl_enginefunc_t *pEnginefuncs, int iVersion );
int (*pfnVidInit)( void );
void (*pfnInit)( void );
void (*pfnShutdown)( void );
int (*pfnVidInit)( void );
int (*pfnRedraw)( float flTime, int intermission );
int (*pfnUpdateClientData)( client_data_t *cdata, float flTime );
void (*pfnReset)( void );
void (*pfnPlayerMove)( struct playermove_s *ppmove, int server );
void (*pfnPlayerMoveInit)( struct playermove_s *ppmove );
char (*pfnPlayerMoveTexture)( char *name );
int (*pfnConnectionlessPacket)( const netadr_t *net_from, const char *args, char *buffer, int *size );
int (*pfnGetHullBounds)( int hullnumber, float *mins, float *maxs );
void (*pfnFrame)( double time );
void (*pfnVoiceStatus)( int entindex, qboolean bTalking );
void (*pfnDirectorMessage)( int iSize, void *pbuf );
void (*pfnPostRunCmd)( local_state_t *from, local_state_t *to, usercmd_t *cmd, int runfuncs, double time, uint random_seed );
int (*pfnKey_Event)( int eventcode, int keynum, const char *pszCurrentBinding );
void (*pfnDemo_ReadBuffer)( int size, byte *buffer );
int (*pfnAddEntity)( int type, cl_entity_t *ent, const char *modelname );
void (*pfnCreateEntities)( void );
void (*pfnStudioEvent)( const struct mstudioevent_s *event, const cl_entity_t *entity );
void (*pfnTxferLocalOverrides)( entity_state_t *state, const clientdata_t *client );
void (*pfnProcessPlayerState)( entity_state_t *dst, const entity_state_t *src );
void (*pfnTxferPredictionData)( entity_state_t *ps, const entity_state_t *pps, clientdata_t *pcd, const clientdata_t *ppcd, weapon_data_t *wd, const weapon_data_t *pwd );
void (*pfnTempEntUpdate)( double frametime, double client_time, double cl_gravity, struct tempent_s **ppTempEntFree, struct tempent_s **ppTempEntActive, int ( *Callback_AddVisibleEntity )( cl_entity_t *pEntity ), void ( *Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ));
int (*pfnGetStudioModelInterface)( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio );
void (*pfnChatInputPosition)( int *x, int *y );
void (*pfnDrawNormalTriangles)( void );
void (*pfnDrawTransparentTriangles)( void );
cl_entity_t *(*pfnGetUserEntity)( int index );
void *(*KB_Find)( const char *name );
void (*CAM_Think)( void ); // camera stuff
int (*CL_IsThirdPerson)( void );
void (*CL_CameraOffset)( float *ofs );
void (*CL_CreateMove)( float frametime, usercmd_t *cmd, int active );
void (*IN_ActivateMouse)( void );
void (*IN_DeactivateMouse)( void );
void (*IN_MouseEvent)( int mstate );
void (*IN_Accumulate)( void );
void (*IN_ClearStates)( void );
void (*IN_Accumulate)( void );
void (*CL_CreateMove)( float frametime, usercmd_t *cmd, int active );
int (*CL_IsThirdPerson)( void );
void (*CL_CameraOffset)( float *ofs );
void *(*KB_Find)( const char *name );
void (*CAM_Think)( void ); // camera stuff
void (*pfnCalcRefdef)( ref_params_t *pparams );
int (*pfnGetRenderInterface)( int version, render_api_t *renderfuncs, render_interface_t *callback );
int (*pfnAddEntity)( int type, cl_entity_t *ent, const char *modelname );
void (*pfnCreateEntities)( void );
void (*pfnDrawNormalTriangles)( void );
void (*pfnDrawTransparentTriangles)( void );
void (*pfnStudioEvent)( const struct mstudioevent_s *event, const cl_entity_t *entity );
void (*pfnPostRunCmd)( local_state_t *from, local_state_t *to, usercmd_t *cmd, int runfuncs, double time, uint random_seed );
void (*pfnShutdown)( void );
void (*pfnTxferLocalOverrides)( entity_state_t *state, const clientdata_t *client );
void (*pfnProcessPlayerState)( entity_state_t *dst, const entity_state_t *src );
void (*pfnTxferPredictionData)( entity_state_t *ps, const entity_state_t *pps, clientdata_t *pcd, const clientdata_t *ppcd, weapon_data_t *wd, const weapon_data_t *pwd );
void (*pfnDemo_ReadBuffer)( int size, byte *buffer );
int (*pfnConnectionlessPacket)( const netadr_t *net_from, const char *args, char *buffer, int *size );
int (*pfnGetHullBounds)( int hullnumber, float *mins, float *maxs );
void (*pfnFrame)( double time );
int (*pfnKey_Event)( int eventcode, int keynum, const char *pszCurrentBinding );
void (*pfnTempEntUpdate)( double frametime, double client_time, double cl_gravity, struct tempent_s **ppTempEntFree, struct tempent_s **ppTempEntActive, int ( *Callback_AddVisibleEntity )( cl_entity_t *pEntity ), void ( *Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ));
cl_entity_t *(*pfnGetUserEntity)( int index );
void (*pfnVoiceStatus)( int entindex, qboolean bTalking );
void (*pfnDirectorMessage)( int iSize, void *pbuf );
int (*pfnGetStudioModelInterface)( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio );
void (*pfnChatInputPosition)( int *x, int *y );
int (*pfnGetPlayerTeam)( int playerIndex );
void *(*pfnGetClientFactory)( void );
// Xash3D extension
int (*pfnGetRenderInterface)( int version, render_api_t *renderfuncs, render_interface_t *callback );
void (*pfnClipMoveToEntity)( physent_t *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, pmtrace_t *tr );
} HUD_FUNCTIONS;
@ -741,8 +747,10 @@ void CL_ClearAllRemaps( void );
int CL_AddEntity( int entityType, cl_entity_t *pEnt );
void CL_WeaponAnim( int iAnim, int body );
void CL_ClearEffects( void );
void CL_ClearEfrags( void );
void CL_TestLights( void );
void CL_DrawParticlesExternal( const float *vieworg, const float *fwd, const float *rt, const float *up, uint clipFlags );
void CL_FireCustomDecal( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags, float scale );
void CL_DecalShoot( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags );
void CL_PlayerDecal( int textureIndex, int entityIndex, float *pos );
void CL_InitParticles( void );

View File

@ -27,8 +27,8 @@ GNU General Public License for more details.
// empirically determined constants for minimizing overalpping decals
#define MAX_OVERLAP_DECALS 6
#define DECAL_OVERLAP_DIST 8
#define FLOAT_TO_SHORT( x ) (short)(x * 32)
#define SHORT_TO_FLOAT( x ) ((float)x * (1.0f/32.0f))
#define MIN_DECAL_SCALE 0.01f
#define MAX_DECAL_SCALE 10.0f
// clip edges
#define LEFT_EDGE 0
@ -212,8 +212,8 @@ void R_SetupDecalVertsForMSurface( decal_t *pDecal, msurface_t *surf, vec3_t tex
for( i = 0, v = surf->polys->verts[0]; i < surf->polys->numverts; i++, v += VERTEXSIZE, verts += VERTEXSIZE )
{
VectorCopy( v, verts ); // copy model space coordinates
verts[3] = DotProduct( verts, textureSpaceBasis[0] ) - SHORT_TO_FLOAT( pDecal->dx ) + 0.5f;
verts[4] = DotProduct( verts, textureSpaceBasis[1] ) - SHORT_TO_FLOAT( pDecal->dy ) + 0.5f;
verts[3] = DotProduct( verts, textureSpaceBasis[0] ) - pDecal->dx + 0.5f;
verts[4] = DotProduct( verts, textureSpaceBasis[1] ) - pDecal->dy + 0.5f;
verts[5] = verts[6] = 0.0f;
}
}
@ -226,8 +226,8 @@ void R_SetupDecalClip( decal_t *pDecal, msurface_t *surf, int texture, vec3_t te
// Generate texture coordinates for each vertex in decal s,t space
// probably should pre-generate this, store it and use it for decal-decal collisions
// as in R_DecalsIntersect()
pDecal->dx = FLOAT_TO_SHORT( DotProduct( pDecal->position, textureSpaceBasis[0] ));
pDecal->dy = FLOAT_TO_SHORT( DotProduct( pDecal->position, textureSpaceBasis[1] ));
pDecal->dx = DotProduct( pDecal->position, textureSpaceBasis[0] );
pDecal->dy = DotProduct( pDecal->position, textureSpaceBasis[1] );
}
// Quick and dirty sutherland Hodgman clipper
@ -505,15 +505,15 @@ static decal_t *R_DecalIntersect( decalinfo_t *decalinfo, msurface_t *surf, int
// this decal's (pDecal's) [0,0,1,1] clip space, just like we would if we were
// clipping a triangle into pDecal's clip space.
Vector2Set( vDecalMin,
DotProduct( testPosition[0], testBasis[0] ) - SHORT_TO_FLOAT( pDecal->dx ) + 0.5f,
DotProduct( testPosition[1], testBasis[1] ) - SHORT_TO_FLOAT( pDecal->dy ) + 0.5f );
DotProduct( testPosition[0], testBasis[0] ) - pDecal->dx + 0.5f,
DotProduct( testPosition[1], testBasis[1] ) - pDecal->dy + 0.5f );
VectorAdd( decalinfo->m_Position, decalExtents[0], testPosition[0] );
VectorAdd( decalinfo->m_Position, decalExtents[1], testPosition[1] );
Vector2Set( vDecalMax,
DotProduct( testPosition[0], testBasis[0] ) - SHORT_TO_FLOAT( pDecal->dx ) + 0.5f,
DotProduct( testPosition[1], testBasis[1] ) - SHORT_TO_FLOAT( pDecal->dy ) + 0.5f );
DotProduct( testPosition[0], testBasis[0] ) - pDecal->dx + 0.5f,
DotProduct( testPosition[1], testBasis[1] ) - pDecal->dy + 0.5f );
// Now figure out the part of the projection that intersects pDecal's
// clip box [0,0,1,1].
@ -593,8 +593,8 @@ static void R_DecalCreate( decalinfo_t *decalinfo, msurface_t *surf, float x, fl
if( pdecal->flags & FDECAL_USESAXIS )
VectorCopy( decalinfo->m_SAxis, pdecal->saxis );
pdecal->dx = FLOAT_TO_SHORT( x );
pdecal->dy = FLOAT_TO_SHORT( y );
pdecal->dx = x;
pdecal->dy = y;
pdecal->texture = decalinfo->m_iTexture;
// set scaling
@ -758,7 +758,7 @@ static void R_DecalNode( model_t *model, mnode_t *node, decalinfo_t *decalinfo )
}
// Shoots a decal onto the surface of the BSP. position is the center of the decal in world coords
void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos, int flags, vec3_t saxis )
void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos, int flags, vec3_t saxis, float scale )
{
decalinfo_t decalInfo;
hull_t *hull;
@ -795,7 +795,7 @@ void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos
decalInfo.m_pModel = model;
hull = &model->hulls[0]; // always use #0 hull
if( ent )
if( ent && !( flags & FDECAL_LOCAL_SPACE ))
{
vec3_t pos_l;
@ -811,7 +811,9 @@ void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos
{
VectorSubtract( pos, ent->origin, pos_l );
}
VectorCopy( pos_l, decalInfo.m_Position );
flags |= FDECAL_LOCAL_SPACE; // decal position moved into local space
}
else
{
@ -842,7 +844,7 @@ void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos
if(( height >> 1 ) > decalInfo.m_Size )
decalInfo.m_Size = height >> 1;
decalInfo.m_scale = 1.0f;
decalInfo.m_scale = bound( MIN_DECAL_SCALE, scale, MAX_DECAL_SCALE );
// compute the decal dimensions in world space
decalInfo.m_decalWidth = width / decalInfo.m_scale;
@ -1128,6 +1130,7 @@ int R_CreateDecalList( decallist_t *pList, qboolean changelevel )
pList[total].depth = depth;
pList[total].flags = decal->flags;
pList[total].scale = decal->scale;
R_DecalUnProject( decal, &pList[total] );
FS_FileBase( R_GetTexture( decal->texture )->name, pList[total].name );
@ -1197,4 +1200,30 @@ void R_EntityRemoveDecals( model_t *mod )
for( p = psurf->pdecals; p; p = p->pnext )
R_DecalUnlink( p );
}
}
/*
===============
R_ClearAllDecals
remove all decals from anything
used for full decals restart
===============
*/
void R_ClearAllDecals( void )
{
decal_t *pdecal;
int i;
// because gDecalCount may be zeroed after recach the decal limit
for( i = 0; i < MAX_RENDER_DECALS; i++ )
{
pdecal = &gDecalPool[i];
R_DecalUnlink( pdecal );
}
if( clgame.drawFuncs.R_ClearStudioDecals )
{
clgame.drawFuncs.R_ClearStudioDecals();
}
}

View File

@ -484,7 +484,7 @@ void GL_SetRenderMode( int mode );
void R_RunViewmodelEvents( void );
void R_DrawViewModel( void );
int R_GetSpriteTexture( const struct model_s *m_pSpriteModel, int frame );
void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos, int flags, vec3_t saxis );
void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos, int flags, vec3_t saxis, float scale );
void R_RemoveEfrags( struct cl_entity_s *ent );
void R_AddEfrags( struct cl_entity_s *ent );
void R_DecalRemoveAll( int texture );

View File

@ -1564,11 +1564,6 @@ static int GL_LoadTextureNoFilter( const char *name, const byte *buf, size_t siz
return GL_LoadTexture( name, buf, size, flags, NULL );
}
static void GL_StoreEfrags( efrag_t **ppefrag )
{
R_StoreEfrags( ppefrag, tr.framecount );
}
static const ref_overview_t *GL_GetOverviewParms( void )
{
return &clgame.overView;
@ -1587,18 +1582,15 @@ static render_api_t gRenderAPI =
R_SetCurrentEntity,
R_SetCurrentModel,
GL_SetWorldviewProjectionMatrix,
GL_StoreEfrags,
R_StoreEfrags,
GL_FindTexture,
GL_TextureName,
GL_LoadTextureNoFilter,
GL_CreateTexture,
GL_FreeTexture,
DrawSingleDecal,
CL_DrawParticlesExternal,
R_EnvShot,
COM_CompareFileTime,
Host_Error,
pfnSPR_LoadExt,
R_DecalSetupVerts,
R_EntityRemoveDecals,
AVI_LoadVideo,
AVI_GetVideoInfo,
AVI_GetAudioInfo,
@ -1614,11 +1606,13 @@ static render_api_t gRenderAPI =
GL_LoadIdentityTexMatrix,
GL_CleanUpTextureUnits,
GL_TexGen,
R_EntityRemoveDecals,
R_DecalSetupVerts,
R_StoreEfrags,
GL_TextureTarget,
R_StudioGetTexture, // moved here to avoid incompatibility with official expanded interface of IEngineStduio (HLSDK Update at 30.08.2013)
CL_DrawParticlesExternal,
R_EnvShot,
COM_CompareFileTime,
Host_Error,
pfnSPR_LoadExt,
R_StudioGetTexture,
GL_GetOverviewParms,
};

View File

@ -384,6 +384,26 @@ imgfilter_t *R_FindTexFilter( const char *texname )
return NULL;
}
/*
=======================
R_ClearStaticEntities
e.g. by demo request
=======================
*/
void R_ClearStaticEntities( void )
{
int i;
// clear out efrags in case the level hasn't been reloaded
for( i = 0; i < cl.worldmodel->numleafs; i++ )
cl.worldmodel->leafs[i+1].efrags = NULL;
clgame.numStatics = 0;
CL_ClearEfrags ();
}
void R_NewMap( void )
{
texture_t *tx;

View File

@ -112,6 +112,7 @@ char g_nCachedBoneNames[MAXSTUDIOBONES][32];
int g_nCachedBones; // number of bones in cache
int g_nStudioCount; // for chrome update
int g_iRenderMode; // currentmodel rendermode
int g_iBackFaceCull;
vec3_t studio_mins, studio_maxs;
float studio_radius;
@ -1835,9 +1836,65 @@ mstudiotexture_t *R_StudioGetTexture( cl_entity_t *e )
return ptexture;
}
void R_StudioSetRenderamt( int iRenderamt )
{
if( !RI.currententity ) return;
RI.currententity->curstate.renderamt = iRenderamt;
RI.currententity->curstate.renderamt = R_ComputeFxBlend( RI.currententity );
}
/*
===============
R_SolidEntityCompare
R_StudioSetCullState
sets true for enable backculling (for left-hand viewmodel)
===============
*/
void R_StudioSetCullState( int iCull )
{
g_iBackFaceCull = iCull;
}
/*
===============
R_StudioRenderShadow
just a prefab for render shadow
===============
*/
void R_StudioRenderShadow( int iSprite, float *p1, float *p2, float *p3, float *p4 )
{
if( !p1 || !p2 || !p3 || !p4 )
return;
if( TriSpriteTexture( Mod_Handle( iSprite ), 0 ))
{
pglEnable( GL_BLEND );
pglDisable( GL_ALPHA_TEST );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglColor4f( 0.0f, 0.0f, 0.0f, 1.0f ); // render only alpha
pglBegin( GL_QUADS );
pglTexCoord2f( 0.0f, 0.0f );
pglVertex3fv( p1 );
pglTexCoord2f( 0.0f, 1.0f );
pglVertex3fv( p2 );
pglTexCoord2f( 1.0f, 1.0f );
pglVertex3fv( p3 );
pglTexCoord2f( 1.0f, 0.0f );
pglVertex3fv( p4 );
pglEnd();
pglDisable( GL_BLEND );
pglDisable( GL_ALPHA_TEST );
}
}
/*
===============
R_StudioMeshCompare
Sorting opaque entities by model type
===============
@ -1972,6 +2029,12 @@ static void R_StudioDrawPoints( void )
pglBlendFunc( GL_SRC_ALPHA, GL_ONE );
pglDepthMask( GL_FALSE );
}
else if( g_nFaceFlags & STUDIO_NF_ALPHA )
{
GL_SetRenderMode( kRenderTransTexture );
alpha = RI.currententity->curstate.renderamt * (1.0f / 255.0f);
pglDepthMask( GL_FALSE );
}
else
{
GL_SetRenderMode( g_iRenderMode );
@ -2506,6 +2569,9 @@ static void R_StudioSetupRenderer( int rendermode )
// enable depthmask on studiomodels
if( glState.drawTrans && g_iRenderMode != kRenderTransAdd )
pglDepthMask( GL_TRUE );
if( g_iBackFaceCull )
GL_FrontFace( true );
}
/*
@ -2524,6 +2590,10 @@ static void R_StudioRestoreRenderer( void )
pglDepthMask( GL_FALSE );
else pglDepthMask( GL_TRUE );
if( g_iBackFaceCull )
GL_FrontFace( false );
g_iBackFaceCull = false;
m_fDoRemap = false;
}
@ -3266,7 +3336,8 @@ void R_DrawViewModel( void )
pglDepthRange( gldepthmin, gldepthmin + 0.3f * ( gldepthmax - gldepthmin ));
// backface culling for left-handed weapons
if( r_lefthand->integer == 1 ) GL_FrontFace( !glState.frontFace );
if( r_lefthand->integer == 1 || g_iBackFaceCull )
GL_FrontFace( !glState.frontFace );
pStudioDraw->StudioDrawModel( STUDIO_RENDER );
@ -3274,7 +3345,8 @@ void R_DrawViewModel( void )
pglDepthRange( gldepthmin, gldepthmax );
// backface culling for left-handed weapons
if( r_lefthand->integer == 1 ) GL_FrontFace( !glState.frontFace );
if( r_lefthand->integer == 1 || g_iBackFaceCull )
GL_FrontFace( !glState.frontFace );
RI.currententity = NULL;
RI.currentmodel = NULL;
@ -3583,7 +3655,9 @@ static engine_studio_api_t gStudioAPI =
pfnIsHardware,
GL_StudioDrawShadow,
GL_SetRenderMode,
R_StudioGetTexture, // Xash3D
R_StudioSetRenderamt,
R_StudioSetCullState,
R_StudioRenderShadow,
};
static r_studio_interface_t gStudioDraw =
@ -3608,8 +3682,15 @@ void CL_InitStudioAPI( void )
if( !clgame.dllFuncs.pfnGetStudioModelInterface )
return;
MsgDev( D_NOTE, "InitStudioAPI " );
if( clgame.dllFuncs.pfnGetStudioModelInterface( STUDIO_INTERFACE_VERSION, &pStudioDraw, &gStudioAPI ))
{
MsgDev( D_NOTE, "- ok\n" );
return;
}
MsgDev( D_NOTE, "- failed\n" );
// NOTE: we always return true even if game interface was not correct
// because we need Draw our StudioModels

View File

@ -23,7 +23,7 @@ static char mond[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int Q_buildnum( void )
{
// do not touch this! Only author of Xash3D can increase buildnumbers!
#if 0
#if 1
int m = 0, d = 0, y = 0;
static int b = 0;

View File

@ -19,14 +19,6 @@ GNU General Public License for more details.
#define MAX_CMD_BUFFER 16384
#define MAX_CMD_LINE 1024
#define MAX_ALIAS_NAME 32
typedef struct cmdalias_s
{
struct cmdalias_s *next;
char name[MAX_ALIAS_NAME];
char *value;
} cmdalias_t;
typedef struct
{
@ -429,16 +421,37 @@ char *Cmd_Args( void )
return cmd_args;
}
/*
============
Cmd_AliasGetList
============
*/
struct cmdalias_s *Cmd_AliasGetList( void )
{
return cmd_alias;
}
/*
============
Cmd_GetList
============
*/
cmd_t *Cmd_GetList( void )
struct cmd_s *Cmd_GetFirstFunctionHandle( void )
{
return cmd_functions;
}
/*
============
Cmd_GetNext
============
*/
struct cmd_s *Cmd_GetNextFunctionHandle( struct cmd_s *cmd )
{
return (cmd) ? cmd->next : NULL;
}
/*
============
Cmd_GetName

View File

@ -504,6 +504,7 @@ used by CS:CZ
*/
void *pfnSequenceGet( const char *fileName, const char *entryName )
{
Msg( "Sequence_Get: file %s, entry %s\n", fileName, entryName );
return NULL;
}
@ -516,6 +517,9 @@ used by CS:CZ
*/
void *pfnSequencePickSentence( const char *groupName, int pickMethod, int *picked )
{
Msg( "Sequence_PickSentence: group %s, pickMethod %i\n", groupName, pickMethod );
*picked = 0;
return NULL;
}

View File

@ -612,6 +612,7 @@ qboolean Host_NewGame( const char *mapName, qboolean loadGame );
void Host_EndGame( const char *message, ... );
void Host_AbortCurrentFrame( void );
void Host_RestartAmbientSounds( void );
void Host_RestartDecals( void );
qboolean CL_ChangeGame( const char *gamefolder, qboolean bReset );
void Host_WriteServerConfig( const char *name );
void Host_WriteOpenGLConfig( void );
@ -661,6 +662,7 @@ void *Cache_Check( byte *mempool, struct cache_user_s *c );
edict_t* pfnPEntityOfEntIndex( int iEntIndex );
void pfnGetModelBounds( model_t *mod, float *mins, float *maxs );
void pfnGetGameDir( char *szGetGameDir );
int pfnDecalIndex( const char *m );
int pfnGetModelType( model_t *mod );
int pfnIsMapValid( char *filename );
void Con_DPrintf( char *fmt, ... );
@ -771,7 +773,13 @@ int COM_ExpandFilename( const char *fileName, char *nameOutBuffer, int nameOutBu
struct pmtrace_s *PM_TraceLine( float *start, float *end, int flags, int usehull, int ignore_pe );
void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float attn, int flags, int pitch );
void SV_StartMusic( const char *curtrack, const char *looptrack, fs_offset_t position );
void SV_CreateDecal( struct sizebuf_s *msg, const float *origin, int decalIndex, int entityIndex, int modelIndex, int flags, float scale );
void SV_CreateStudioDecal( struct sizebuf_s *msg, const float *origin, const float *start, int decalIndex, int entityIndex, int modelIndex,
int flags, struct modelstate_s *state );
struct sizebuf_s *SV_GetReliableDatagram( void );
int R_CreateDecalList( struct decallist_s *pList, qboolean changelevel );
void R_ClearAllDecals( void );
void R_ClearStaticEntities( void );
qboolean S_StreamGetCurrentState( char *currentTrack, char *loopTrack, int *position );
struct cl_entity_s *CL_GetEntityByIndex( int index );
struct cl_entity_s *CL_GetLocalPlayer( void );
@ -828,10 +836,11 @@ void TrimSpace( const char *source, char *dest );
void GL_FreeImage( const char *name );
void VID_RestoreGamma( void );
void UI_SetActiveMenu( qboolean fActive );
struct cmd_s *Cmd_GetList( void );
struct cmd_s *Cmd_GetFirstFunctionHandle( void );
struct cmd_s *Cmd_GetNextFunctionHandle( struct cmd_s *cmd );
struct cmdalias_s *Cmd_AliasGetList( void );
char *Cmd_GetName( struct cmd_s *cmd );
cvar_t *Cvar_GetList( void );
char *Cvar_GetName( cvar_t *cvar );
typedef struct autocomplete_list_s
{

View File

@ -20,6 +20,7 @@ GNU General Public License for more details.
#include "mathlib.h"
#include "input.h"
#include "features.h"
#include "render_api.h" // decallist_t
typedef void (*pfnChangeGame)( const char *progname );
@ -383,6 +384,62 @@ void Host_RestartAmbientSounds( void )
}
}
/*
=================
Host_RestartDecals
Write all the decals into demo
=================
*/
void Host_RestartDecals( void )
{
decallist_t *entry;
int decalIndex;
int modelIndex;
sizebuf_t *msg;
int i;
if( !SV_Active( ))
{
return;
}
// g-cont. add space for studiodecals if present
host.decalList = (decallist_t *)Z_Malloc( sizeof( decallist_t ) * MAX_RENDER_DECALS * 2 );
host.numdecals = R_CreateDecalList( host.decalList, false );
// remove decals from map
R_ClearAllDecals();
// write decals into reliable datagram
msg = SV_GetReliableDatagram();
// restore decals and write them into network message
for( i = 0; i < host.numdecals; i++ )
{
entry = &host.decalList[i];
decalIndex = pfnDecalIndex( entry->name );
modelIndex = pfnPEntityOfEntIndex( entry->entityIndex )->v.modelindex;
// BSP and studio decals has different messages
if( entry->flags & FDECAL_STUDIO )
{
// NOTE: studio decal trace start saved into impactPlaneNormal
SV_CreateStudioDecal( msg, entry->position, entry->impactPlaneNormal, decalIndex, entry->entityIndex,
modelIndex, entry->flags, &entry->studio_state );
}
else
{
SV_CreateDecal( msg, entry->position, decalIndex, entry->entityIndex, modelIndex, entry->flags, entry->scale );
}
}
Z_Free( host.decalList );
host.decalList = NULL;
host.numdecals = 0;
}
/*
===================
Host_GetConsoleCommands

View File

@ -35,7 +35,7 @@ _inline int BitByte( int bits )
return PAD_NUMBER( bits, 8 ) >> 3;
}
typedef struct
typedef struct sizebuf_s
{
qboolean bOverflow; // overflow reading or writing
const char *pDebugName; // buffer name (pointer to const name)

View File

@ -135,6 +135,7 @@ GNU General Public License for more details.
#define FDECAL_NOCLIP 0x10 // Decal is not clipped by containing polygon
#define FDECAL_USESAXIS 0x20 // Uses the s axis field to determine orientation (footprints)
#define FDECAL_STUDIO 0x40 // Indicates a studio decal
#define FDECAL_LOCAL_SPACE 0x80 // decal is in local space (any decal after serialization)
// Max number of history commands to send ( 2 by default ) in case of dropped packets
#define NUM_BACKUP_COMMAND_BITS 4

View File

@ -272,6 +272,7 @@ typedef struct enginefuncs_s
void (*pfnResetTutorMessageDecayData)( void );
void (*pfnQueryClientCvarValue)( const edict_t *player, const char *cvarName );
void (*pfnQueryClientCvarValue2)( const edict_t *player, const char *cvarName, int requestID );
int (*CheckParm)( char *parm, char **ppnext );
} enginefuncs_t;
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 138

View File

@ -553,9 +553,6 @@ void SV_SetModel( edict_t *ent, const char *name );
void SV_CopyTraceToGlobal( trace_t *trace );
void SV_SetMinMaxSize( edict_t *e, const float *min, const float *max );
edict_t* SV_FindEntityByString( edict_t *pStartEdict, const char *pszField, const char *pszValue );
void SV_CreateDecal( const float *origin, int decalIndex, int entityIndex, int modelIndex, int flags );
void SV_CreateStudioDecal( const float *origin, const float *start, int decalIndex, int entityIndex, int modelIndex,
int flags, struct modelstate_s *state );
void SV_PlaybackEventFull( int flags, const edict_t *pInvoker, word eventindex, float delay, float *origin,
float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 );
void SV_PlaybackReliableEvent( sizebuf_t *msg, word eventindex, float delay, event_args_t *args );
@ -572,15 +569,15 @@ sv_client_t *SV_ClientFromEdict( const edict_t *pEdict, qboolean spawned_only );
void SV_SetClientMaxspeed( sv_client_t *cl, float fNewMaxspeed );
int SV_MapIsValid( const char *filename, const char *spawn_entity, const char *landmark_name );
void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float attn, int flags, int pitch );
void SV_CreateStaticEntity( sv_static_entity_t *ent );
void SV_CreateStaticEntity( struct sizebuf_s *msg, sv_static_entity_t *ent );
edict_t* pfnPEntityOfEntIndex( int iEntIndex );
int pfnIndexOfEdict( const edict_t *pEdict );
void SV_UpdateBaseVelocity( edict_t *ent );
byte *pfnSetFatPVS( const float *org );
byte *pfnSetFatPAS( const float *org );
int pfnPrecacheModel( const char *s );
int pfnDecalIndex( const char *m );
int pfnNumberOfEntities( void );
void SV_RestartStaticEnts( void );
_inline edict_t *SV_EDICT_NUM( int n, const char * file, const int line )
{

View File

@ -1963,6 +1963,10 @@ void SV_ExecuteClientCommand( sv_client_t *cl, char *s )
{
// resend the ambient sounds for demo recording
Host_RestartAmbientSounds();
// resend all the decals for demo recording
Host_RestartDecals();
// resend all the static ents for demo recording
SV_RestartStaticEnts();
}
}
}

View File

@ -362,6 +362,18 @@ qboolean SV_Send( int dest, const vec3_t origin, const edict_t *ent )
return numsends; // debug
}
/*
=======================
SV_GetReliableDatagram
Get shared reliable buffer
=======================
*/
sizebuf_t *SV_GetReliableDatagram( void )
{
return &sv.reliable_datagram;
}
/*
=======================
SV_CreateDecal
@ -369,23 +381,24 @@ SV_CreateDecal
NOTE: static decals only accepted when game is loading
=======================
*/
void SV_CreateDecal( const float *origin, int decalIndex, int entityIndex, int modelIndex, int flags )
void SV_CreateDecal( sizebuf_t *msg, const float *origin, int decalIndex, int entityIndex, int modelIndex, int flags, float scale )
{
if( sv.state != ss_loading )
if( msg == &sv.signon && sv.state != ss_loading )
return;
// this can happens if serialized map contain 4096 static decals...
if(( BF_GetNumBytesWritten( &sv.signon ) + 20 ) >= BF_GetMaxBytes( &sv.signon ))
if(( BF_GetNumBytesWritten( msg ) + 20 ) >= BF_GetMaxBytes( msg ))
return;
// static decals are posters, it's always reliable
BF_WriteByte( &sv.signon, svc_bspdecal );
BF_WriteVec3Coord( &sv.signon, origin );
BF_WriteWord( &sv.signon, decalIndex );
BF_WriteShort( &sv.signon, entityIndex );
BF_WriteByte( msg, svc_bspdecal );
BF_WriteVec3Coord( msg, origin );
BF_WriteWord( msg, decalIndex );
BF_WriteShort( msg, entityIndex );
if( entityIndex > 0 )
BF_WriteWord( &sv.signon, modelIndex );
BF_WriteByte( &sv.signon, flags );
BF_WriteWord( msg, modelIndex );
BF_WriteByte( msg, flags );
BF_WriteWord( msg, scale * 4096 );
}
/*
@ -395,9 +408,9 @@ SV_CreateStudioDecal
NOTE: static decals only accepted when game is loading
=======================
*/
void SV_CreateStudioDecal( const float *origin, const float *start, int decalIndex, int entityIndex, int modelIndex, int flags, modelstate_t *state )
void SV_CreateStudioDecal( sizebuf_t *msg, const float *origin, const float *start, int decalIndex, int entityIndex, int modelIndex, int flags, modelstate_t *state )
{
if( sv.state != ss_loading )
if( msg == &sv.signon && sv.state != ss_loading )
return;
// bad model or bad entity (e.g. changelevel)
@ -408,29 +421,29 @@ void SV_CreateStudioDecal( const float *origin, const float *start, int decalInd
ASSERT( start );
// this can happens if serialized map contain 4096 static decals...
if(( BF_GetNumBytesWritten( &sv.signon ) + 28 ) >= BF_GetMaxBytes( &sv.signon ))
if(( BF_GetNumBytesWritten( msg ) + 30 ) >= BF_GetMaxBytes( msg ))
return;
// static decals are posters, it's always reliable
BF_WriteByte( &sv.signon, svc_studiodecal );
BF_WriteVec3Coord( &sv.signon, origin );
BF_WriteVec3Coord( &sv.signon, start );
BF_WriteWord( &sv.signon, decalIndex );
BF_WriteShort( &sv.signon, entityIndex );
BF_WriteByte( &sv.signon, flags );
BF_WriteByte( msg, svc_studiodecal );
BF_WriteVec3Coord( msg, origin );
BF_WriteVec3Coord( msg, start );
BF_WriteWord( msg, decalIndex );
BF_WriteWord( msg, entityIndex );
BF_WriteByte( msg, flags );
// write model state
BF_WriteShort( &sv.signon, state->sequence );
BF_WriteShort( &sv.signon, state->frame );
BF_WriteByte( &sv.signon, state->blending[0] );
BF_WriteByte( &sv.signon, state->blending[1] );
BF_WriteByte( &sv.signon, state->controller[0] );
BF_WriteByte( &sv.signon, state->controller[1] );
BF_WriteByte( &sv.signon, state->controller[2] );
BF_WriteByte( &sv.signon, state->controller[3] );
// write additional data (excluded from the game message)
BF_WriteShort( &sv.signon, modelIndex );
BF_WriteShort( msg, state->sequence );
BF_WriteShort( msg, state->frame );
BF_WriteByte( msg, state->blending[0] );
BF_WriteByte( msg, state->blending[1] );
BF_WriteByte( msg, state->controller[0] );
BF_WriteByte( msg, state->controller[1] );
BF_WriteByte( msg, state->controller[2] );
BF_WriteByte( msg, state->controller[3] );
BF_WriteWord( msg, modelIndex );
BF_WriteByte( msg, state->body );
BF_WriteByte( msg, state->skin );
}
/*
@ -440,38 +453,61 @@ SV_CreateStaticEntity
NOTE: static entities only accepted when game is loading
=======================
*/
void SV_CreateStaticEntity( sv_static_entity_t *ent )
void SV_CreateStaticEntity( sizebuf_t *msg, sv_static_entity_t *ent )
{
int index, i;
// this can happens if serialized map contain too many static entities...
if(( BF_GetNumBytesWritten( &sv.signon ) + 64 ) >= BF_GetMaxBytes( &sv.signon ))
if(( BF_GetNumBytesWritten( msg ) + 64 ) >= BF_GetMaxBytes( msg ))
return;
index = SV_ModelIndex( ent->model );
BF_WriteByte( &sv.signon, svc_spawnstatic );
BF_WriteShort(&sv.signon, index );
BF_WriteByte( &sv.signon, ent->sequence );
BF_WriteByte( &sv.signon, ent->frame );
BF_WriteWord( &sv.signon, ent->colormap );
BF_WriteByte( &sv.signon, ent->skin );
BF_WriteByte( msg, svc_spawnstatic );
BF_WriteShort(msg, index );
BF_WriteByte( msg, ent->sequence );
BF_WriteByte( msg, ent->frame );
BF_WriteWord( msg, ent->colormap );
BF_WriteByte( msg, ent->skin );
for( i = 0; i < 3; i++ )
{
BF_WriteCoord( &sv.signon, ent->origin[i] );
BF_WriteBitAngle( &sv.signon, ent->angles[i], 16 );
BF_WriteCoord( msg, ent->origin[i] );
BF_WriteBitAngle( msg, ent->angles[i], 16 );
}
BF_WriteByte( &sv.signon, ent->rendermode );
BF_WriteByte( msg, ent->rendermode );
if( ent->rendermode != kRenderNormal )
{
BF_WriteByte( &sv.signon, ent->renderamt );
BF_WriteByte( &sv.signon, ent->rendercolor.r );
BF_WriteByte( &sv.signon, ent->rendercolor.g );
BF_WriteByte( &sv.signon, ent->rendercolor.b );
BF_WriteByte( &sv.signon, ent->renderfx );
BF_WriteByte( msg, ent->renderamt );
BF_WriteByte( msg, ent->rendercolor.r );
BF_WriteByte( msg, ent->rendercolor.g );
BF_WriteByte( msg, ent->rendercolor.b );
BF_WriteByte( msg, ent->renderfx );
}
}
/*
=================
SV_RestartStaticEnts
Write all the static ents into demo
=================
*/
void SV_RestartStaticEnts( void )
{
sv_static_entity_t *clent;
int i;
// remove all the static entities on the client
R_ClearStaticEntities();
// resend them again
for( i = 0; i < sv.num_static_entities; i++ )
{
clent = &sv.static_entities[i];
SV_CreateStaticEntity( &sv.reliable_datagram, clent );
}
}
@ -1642,7 +1678,7 @@ static void pfnMakeStatic( edict_t *ent )
clent->rendercolor.b = ent->v.rendercolor[2];
clent->renderfx = ent->v.renderfx;
SV_CreateStaticEntity( clent );
SV_CreateStaticEntity( &sv.signon, clent );
// remove at end of the frame
ent->v.flags |= FL_KILLME;
@ -2420,7 +2456,7 @@ void pfnMessageBegin( int msg_dest, int msg_num, const float *pOrigin, edict_t *
if( msg_num < svc_lastmsg )
{
svgame.msg_name = NULL;
svgame.msg_index = -1; // this is a system message
svgame.msg_index = -msg_num; // this is a system message
if( msg_num == svc_temp_entity )
{
@ -2484,14 +2520,14 @@ void pfnMessageEnd( void )
svgame.msg_started = false;
// HACKHACK: clearing HudText in background mode
if( sv.background && svgame.msg[svgame.msg_index].number == svgame.gmsgHudText )
if( sv.background && svgame.msg_index >= 0 && svgame.msg[svgame.msg_index].number == svgame.gmsgHudText )
{
BF_Clear( &sv.multicast );
return;
}
// check for system message
if( svgame.msg_index == -1 )
if( svgame.msg_index < 0 )
{
if( svgame.msg_size_index != -1 )
{
@ -2551,6 +2587,15 @@ void pfnMessageEnd( void )
return;
}
if( svgame.msg_index < 0 && abs( svgame.msg_index ) == svc_studiodecal && svgame.msg_realsize == 27 )
{
// oldstyle message for svc_studiodecal has missed four additional bytes:
// modelIndex, skin and body. Write it here for backward compatibility
BF_WriteWord( &sv.multicast, 0 );
BF_WriteByte( &sv.multicast, 0 );
BF_WriteByte( &sv.multicast, 0 );
}
if( !VectorIsNull( svgame.msg_org )) org = svgame.msg_org;
svgame.msg_dest = bound( MSG_BROADCAST, svgame.msg_dest, MSG_SPEC );
@ -3284,7 +3329,7 @@ void pfnStaticDecal( const float *origin, int decalIndex, int entityIndex, int m
return;
}
SV_CreateDecal( origin, decalIndex, entityIndex, modelIndex, FDECAL_PERMANENT );
SV_CreateDecal( &sv.signon, origin, decalIndex, entityIndex, modelIndex, FDECAL_PERMANENT, 1.0f );
}
/*
@ -4237,6 +4282,25 @@ void pfnQueryClientCvarValue2( const edict_t *player, const char *cvarName, int
MsgDev( D_ERROR, "QueryClientCvarValue: tried to send to a non-client!\n" );
}
}
/*
=============
pfnCheckParm
=============
*/
static int pfnCheckParm( char *parm, char **ppnext )
{
static char str[64];
if( Sys_GetParmFromCmdLine( parm, str ))
{
// get the pointer on cmdline param
if( ppnext ) *ppnext = str;
return 1;
}
return 0;
}
// engine callbacks
static enginefuncs_t gEngfuncs =
@ -4398,6 +4462,7 @@ static enginefuncs_t gEngfuncs =
pfnResetTutorMessageDecayData,
pfnQueryClientCvarValue,
pfnQueryClientCvarValue2,
pfnCheckParm,
};
/*

View File

@ -30,7 +30,7 @@ half-life implementation of saverestore system
#define SAVEFILE_HEADER (('V'<<24)+('L'<<16)+('A'<<8)+'V') // little-endian "VALV"
#define SAVEGAME_HEADER (('V'<<24)+('A'<<16)+('S'<<8)+'J') // little-endian "JSAV"
#define SAVEGAME_VERSION 0x0065 // Version 0.65
#define CLIENT_SAVEGAME_VERSION 0x0067 // Version 0.67
#define CLIENT_SAVEGAME_VERSION 0x0068 // Version 0.68
#define SAVE_AGED_COUNT 1
#define SAVENAME_LENGTH 128 // matches with MAX_OSPATH
@ -452,7 +452,7 @@ void ReapplyDecal( SAVERESTOREDATA *pSaveData, decallist_t *entry, qboolean adja
if( flags & FDECAL_STUDIO )
{
// NOTE: studio decal trace start saved into impactPlaneNormal
SV_CreateStudioDecal( entry->position, entry->impactPlaneNormal, decalIndex, entityIndex, modelIndex, flags, &entry->studio_state );
SV_CreateStudioDecal( &sv.signon, entry->position, entry->impactPlaneNormal, decalIndex, entityIndex, modelIndex, flags, &entry->studio_state );
return;
}
else if( adjacent && entityIndex != 0 && !SV_IsValidEdict( pEdict ))
@ -484,7 +484,7 @@ void ReapplyDecal( SAVERESTOREDATA *pSaveData, decallist_t *entry, qboolean adja
{
entityIndex = pfnIndexOfEdict( tr.ent );
if( entityIndex > 0 ) modelIndex = tr.ent->v.modelindex;
SV_CreateDecal( tr.endpos, decalIndex, entityIndex, modelIndex, flags );
SV_CreateDecal( &sv.signon, tr.endpos, decalIndex, entityIndex, modelIndex, flags, entry->scale );
}
}
}
@ -492,7 +492,7 @@ void ReapplyDecal( SAVERESTOREDATA *pSaveData, decallist_t *entry, qboolean adja
{
// global entity is exist on new level so we can apply decal in local space
// NOTE: this case also used for transition world decals
SV_CreateDecal( entry->position, decalIndex, entityIndex, modelIndex, flags );
SV_CreateDecal( &sv.signon, entry->position, decalIndex, entityIndex, modelIndex, flags, entry->scale );
}
}
@ -1100,6 +1100,7 @@ void SV_SaveClientState( SAVERESTOREDATA *pSaveData, const char *level )
{
vec3_t localPos;
decallist_t *entry;
word decalScale;
byte nameSize;
entry = &decalList[i];
@ -1109,12 +1110,14 @@ void SV_SaveClientState( SAVERESTOREDATA *pSaveData, const char *level )
else VectorCopy( entry->position, localPos );
nameSize = Q_strlen( entry->name ) + 1;
decalScale = (entry->scale * 4096);
FS_Write( pFile, localPos, sizeof( localPos ));
FS_Write( pFile, &nameSize, sizeof( nameSize ));
FS_Write( pFile, entry->name, nameSize );
FS_Write( pFile, &entry->entityIndex, sizeof( entry->entityIndex ));
FS_Write( pFile, &entry->flags, sizeof( entry->flags ));
FS_Write( pFile, &decalScale, sizeof( decalScale ));
FS_Write( pFile, entry->impactPlaneNormal, sizeof( entry->impactPlaneNormal ));
if( entry->flags & FDECAL_STUDIO )
@ -1275,6 +1278,7 @@ void SV_LoadClientState( SAVERESTOREDATA *pSaveData, const char *level, qboolean
{
vec3_t localPos;
decallist_t *entry;
word decalScale;
byte nameSize;
entry = &decalList[i];
@ -1284,12 +1288,15 @@ void SV_LoadClientState( SAVERESTOREDATA *pSaveData, const char *level, qboolean
FS_Read( pFile, entry->name, nameSize );
FS_Read( pFile, &entry->entityIndex, sizeof( entry->entityIndex ));
FS_Read( pFile, &entry->flags, sizeof( entry->flags ));
FS_Read( pFile, &decalScale, sizeof( decalScale ));
FS_Read( pFile, entry->impactPlaneNormal, sizeof( entry->impactPlaneNormal ));
if( pSaveData->fUseLandmark && ( entry->flags & FDECAL_USE_LANDMARK ))
VectorAdd( localPos, pSaveData->vecLandmarkOffset, entry->position );
else VectorCopy( localPos, entry->position );
entry->scale = ((float)decalScale / 4096.0f);
if( entry->flags & FDECAL_STUDIO )
{
// read additional data for studio decals
@ -1345,7 +1352,7 @@ void SV_LoadClientState( SAVERESTOREDATA *pSaveData, const char *level, qboolean
FS_Read( pFile, &entry->renderfx, sizeof( entry->renderfx ));
}
SV_CreateStaticEntity( entry );
SV_CreateStaticEntity( &sv.signon, entry );
}
}

View File

@ -65,12 +65,10 @@ Studio models are position independent, so the cache manager can move them.
#define STUDIO_NF_CHROME 0x0002
#define STUDIO_NF_FULLBRIGHT 0x0004
#define STUDIO_NF_COLORMAP 0x0008 // can changed by colormap command
#define STUDIO_NF_BLENDED 0x0010 // rendering as semitransparent
#define STUDIO_NF_ALPHA 0x0010 // rendering as semitransparent
#define STUDIO_NF_ADDITIVE 0x0020 // rendering with additive mode
#define STUDIO_NF_TRANSPARENT 0x0040 // use texture with alpha channel
#define STUDIO_NF_BUMPMAP 0x0080 // heightmap that can be transformed into normalmap and heightmap
#define STUDIO_NF_GLOSSMAP 0x0100 // glossmap
#define STUDIO_NF_LUMATEXTURE 0x0200 // optional luma_texture
#define STUDIO_NF_QUAKESKIN 0x8000 // special hack for determine alias skins
// motion flags
@ -102,6 +100,7 @@ Studio models are position independent, so the cache manager can move them.
#define STUDIO_HAS_NORMALS 0x0001
#define STUDIO_HAS_VERTICES 0x0002
#define STUDIO_HAS_BBOX 0x0004
#define STUDIO_HAS_CHROME 0x0008 // if any of the textures have chrome on them
typedef struct
{