From 36dfdceff98c9faab5c2e018705a4efc30ef37fa Mon Sep 17 00:00:00 2001 From: g-cont Date: Thu, 31 Oct 2013 00:00:00 +0400 Subject: [PATCH] 31 Oct 2013 --- common/com_model.h | 3 -- common/render_api.h | 3 +- engine/cdll_exp.h | 69 +++++++++++++++++++++++++++++++++++++++ engine/client/cl_parse.c | 4 +++ engine/client/cl_tent.c | 5 +++ engine/client/client.h | 57 +++----------------------------- engine/client/gl_decals.c | 6 ++-- engine/client/gl_rmain.c | 2 ++ engine/client/s_main.c | 8 +++-- engine/client/s_mix.c | 2 +- engine/client/s_stream.c | 30 +++++++++++++++++ engine/client/sound.h | 7 ++++ engine/common/common.h | 1 + engine/common/random.c | 6 ++-- 14 files changed, 136 insertions(+), 67 deletions(-) create mode 100644 engine/cdll_exp.h diff --git a/common/com_model.h b/common/com_model.h index 39a29679..36312db8 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -35,7 +35,6 @@ 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 @@ -216,8 +215,6 @@ 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 diff --git a/common/render_api.h b/common/render_api.h index 49e0c8e0..92734963 100644 --- a/common/render_api.h +++ b/common/render_api.h @@ -21,7 +21,6 @@ GNU General Public License for more details. // 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 @@ -184,6 +183,8 @@ typedef struct render_api_s 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 ); + void (*S_FadeMusicVolume)( float fadePercent ); // fade background track (0-100 percents) + void (*SetRandomSeed)( long lSeed ); // set custom seed for RANDOM_FLOAT\RANDOM_LONG for predictable random // ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 28 } render_api_t; diff --git a/engine/cdll_exp.h b/engine/cdll_exp.h new file mode 100644 index 00000000..07227057 --- /dev/null +++ b/engine/cdll_exp.h @@ -0,0 +1,69 @@ +/* +cdll_exp.h - exports for client +Copyright (C) 2013 Uncle Mike + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ +#ifndef CDLL_EXP_H +#define CDLL_EXP_H + +// NOTE: ordering is important! +typedef struct cldll_func_s +{ + int (*pfnInitialize)( cl_enginefunc_t *pEnginefuncs, int iVersion ); + void (*pfnInit)( 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 ); + void (*IN_ActivateMouse)( void ); + void (*IN_DeactivateMouse)( void ); + void (*IN_MouseEvent)( int mstate ); + void (*IN_ClearStates)( void ); + void (*IN_Accumulate)( void ); + void (*CL_CreateMove)( float frametime, struct usercmd_s *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 (*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)( struct local_state_s *from, struct local_state_s *to, usercmd_t *cmd, int runfuncs, double time, unsigned int 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 struct netadr_s *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)( struct physent_s *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, struct pmtrace_s *tr ); +} cldll_func_t; + +#endif//CDLL_EXP_H \ No newline at end of file diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 987200b8..813be326 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -465,6 +465,10 @@ void CL_ParseStaticEntity( sizebuf_t *msg ) ent->curstate = state; ent->prevstate = state; + // statics may be respawned in game e.g. for demo recording + if( cls.state == ca_connected ) + ent->trivial_accept = INVALID_HANDLE; + // setup the new static entity CL_UpdateEntityFields( ent ); diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 32a4b895..3a219453 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -84,7 +84,10 @@ void CL_ClearTempEnts( void ) if( !cl_tempents ) return; for( i = 0; i < GI->max_tents - 1; i++ ) + { cl_tempents[i].next = &cl_tempents[i+1]; + cl_tempents[i].entity.trivial_accept = INVALID_HANDLE; + } cl_tempents[GI->max_tents-1].next = NULL; cl_free_tents = cl_tempents; @@ -115,10 +118,12 @@ void CL_PrepareTEnt( TEMPENTITY *pTemp, model_t *pmodel ) { int frameCount = 0; int modelIndex = 0; + int modelHandle = pTemp->entity.trivial_accept; Q_memset( pTemp, 0, sizeof( *pTemp )); // use these to set per-frame and termination conditions / actions + pTemp->entity.trivial_accept = modelHandle; // keep unchanged pTemp->flags = FTENT_NONE; pTemp->die = cl.time + 0.75f; diff --git a/engine/client/client.h b/engine/client/client.h index c4241492..50b8d38b 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -25,6 +25,7 @@ GNU General Public License for more details. #include "pm_defs.h" #include "pm_movevars.h" #include "render_api.h" +#include "cdll_exp.h" #include "screenfade.h" #include "protocol.h" #include "netchan.h" @@ -69,6 +70,8 @@ typedef struct frame_s #define CL_UPDATE_MASK (CL_UPDATE_BACKUP - 1) extern int CL_UPDATE_BACKUP; +#define INVALID_HANDLE 0xFFFF // for XashXT cache system + // the client_t structure is wiped completely at every // server map change typedef struct @@ -295,61 +298,10 @@ typedef struct // 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 ); - void (*pfnInit)( 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 ); - void (*IN_ActivateMouse)( void ); - void (*IN_DeactivateMouse)( void ); - void (*IN_MouseEvent)( int mstate ); - 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 (*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; - typedef struct { void *hInstance; // pointer to client.dll - HUD_FUNCTIONS dllFuncs; // dll exported funcs + cldll_func_t dllFuncs; // dll exported funcs render_interface_t drawFuncs; // custom renderer support byte *mempool; // client edicts pool string mapname; // map name @@ -814,6 +766,7 @@ void S_RestoreSound( const vec3_t pos, int ent, int chan, sound_t handle, float void S_StartSound( const vec3_t pos, int ent, int chan, sound_t sfx, float vol, float attn, int pitch, int flags ); void S_AmbientSound( const vec3_t pos, int ent, sound_t handle, float fvol, float attn, int pitch, int flags ); void S_FadeClientVolume( float fadePercent, float fadeOutSeconds, float holdTime, float fadeInSeconds ); +void S_FadeMusicVolume( float fadePercent ); void S_StartLocalSound( const char *name ); void S_RenderFrame( struct ref_params_s *fd ); void S_ExtraUpdate( void ); diff --git a/engine/client/gl_decals.c b/engine/client/gl_decals.c index 4c61fb96..3d15efe3 100644 --- a/engine/client/gl_decals.c +++ b/engine/client/gl_decals.c @@ -876,15 +876,13 @@ float *R_DecalSetupVerts( decal_t *pDecal, msurface_t *surf, int texture, int *o void DrawSingleDecal( decal_t *pDecal, msurface_t *fa ) { - float *v; - gltexture_t *glt; - int i, numVerts; + float *v; + int i, numVerts; v = R_DecalSetupVerts( pDecal, fa, pDecal->texture, &numVerts ); if( !numVerts ) return; GL_Bind( GL_TEXTURE0, pDecal->texture ); - glt = R_GetTexture( pDecal->texture ); pglBegin( GL_POLYGON ); diff --git a/engine/client/gl_rmain.c b/engine/client/gl_rmain.c index 99e68018..9fc11550 100644 --- a/engine/client/gl_rmain.c +++ b/engine/client/gl_rmain.c @@ -1614,6 +1614,8 @@ static render_api_t gRenderAPI = pfnSPR_LoadExt, R_StudioGetTexture, GL_GetOverviewParms, + S_FadeMusicVolume, + Com_SetRandomSeed, }; /* diff --git a/engine/client/s_main.c b/engine/client/s_main.c index 7b0600ae..e2b36d03 100644 --- a/engine/client/s_main.c +++ b/engine/client/s_main.c @@ -1661,8 +1661,10 @@ void S_Music_f( void ) for( i = 0; i < 2; i++ ) { - if( FS_FileExists( va( "media/%s.%s", intro, ext[i] ), false ) - && FS_FileExists( va( "media/%s.%s", main, ext[i] ), false )) + const char *intro_path = va( "media/%s.%s", intro, ext[i] ); + const char *main_path = va( "media/%s.%s", main, ext[i] ); + + if( FS_FileExists( intro_path, false ) && FS_FileExists( main_path, false )) { // combined track with introduction and main loop theme S_StartBackgroundTrack( intro, main, 0 ); @@ -1670,7 +1672,7 @@ void S_Music_f( void ) } else if( FS_FileExists( va( "media/%s.%s", track, ext[i] ), false )) { - // single looped theme + // single non-looped theme S_StartBackgroundTrack( track, NULL, 0 ); break; } diff --git a/engine/client/s_mix.c b/engine/client/s_mix.c index 7cf18771..3bec45b6 100644 --- a/engine/client/s_mix.c +++ b/engine/client/s_mix.c @@ -1041,7 +1041,7 @@ void MIX_PaintChannels( int endtime ) MIX_MixPaintbuffers( IPAINTBUFFER, IROOMBUFFER, IPAINTBUFFER, count, S_GetMasterVolume() ); // add music or soundtrack from movie (no dsp) - MIX_MixPaintbuffers( IPAINTBUFFER, ISTREAMBUFFER, IPAINTBUFFER, count, s_musicvolume->value ); + MIX_MixPaintbuffers( IPAINTBUFFER, ISTREAMBUFFER, IPAINTBUFFER, count, S_GetMusicVolume() ); // clip all values > 16 bit down to 16 bit MIX_CompressPaintbuffer( IPAINTBUFFER, count ); diff --git a/engine/client/s_stream.c b/engine/client/s_stream.c index be0b3014..21804815 100644 --- a/engine/client/s_stream.c +++ b/engine/client/s_stream.c @@ -19,6 +19,7 @@ GNU General Public License for more details. portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES]; static bg_track_t s_bgTrack; +static musicfade_t musicfade; // controlled by game dlls int s_rawend; void S_PrintBackgroundTrackState( void ) @@ -43,6 +44,33 @@ void S_CheckLerpingState( void ) s_listener.lerping = s_lerping->integer; } +/* +================= +S_FadeMusicVolume +================= +*/ +void S_FadeMusicVolume( float fadePercent ) +{ + musicfade.percent = bound( 0.0f, fadePercent, 100.0f ); +} + +/* +================= +S_GetMusicVolume +================= +*/ +float S_GetMusicVolume( void ) +{ + float scale = 1.0f; + + if( !s_listener.inmenu && musicfade.percent != 0 ) + { + scale = bound( 0.0f, musicfade.percent / 100.0f, 1.0f ); + scale = 1.0f - scale; + } + return s_musicvolume->value * scale; +} + /* ================= S_StartBackgroundTrack @@ -73,6 +101,7 @@ void S_StartBackgroundTrack( const char *introTrack, const char *mainTrack, long // open stream s_bgTrack.stream = FS_OpenStream( va( "media/%s", introTrack )); Q_strncpy( s_bgTrack.current, introTrack, sizeof( s_bgTrack.current )); + Q_memset( &musicfade, 0, sizeof( musicfade )); // clear any soundfade s_bgTrack.source = cls.key_dest; if( position != 0 ) @@ -93,6 +122,7 @@ void S_StopBackgroundTrack( void ) FS_FreeStream( s_bgTrack.stream ); Q_memset( &s_bgTrack, 0, sizeof( bg_track_t )); + Q_memset( &musicfade, 0, sizeof( musicfade )); s_listener.lerping = false; s_rawend = 0; } diff --git a/engine/client/sound.h b/engine/client/sound.h index 4ea60a22..aefb0070 100644 --- a/engine/client/sound.h +++ b/engine/client/sound.h @@ -122,6 +122,11 @@ typedef struct float fadeintime; // # of seconds to restore } soundfade_t; +typedef struct +{ + float percent; +} musicfade_t; + typedef struct { int samples; // mono samples in buffer @@ -248,6 +253,7 @@ extern portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES]; void S_InitScaletable( void ); wavdata_t *S_LoadSound( sfx_t *sfx ); float S_GetMasterVolume( void ); +float S_GetMusicVolume( void ); void S_PrintDeviceName( void ); // @@ -309,6 +315,7 @@ void S_StreamSoundTrack( void ); void S_StreamBackgroundTrack( void ); qboolean S_StreamGetCurrentState( char *currentTrack, char *loopTrack, int *position ); void S_PrintBackgroundTrackState( void ); +void S_FadeMusicVolume( float fadePercent ); // // s_utils.c diff --git a/engine/common/common.h b/engine/common/common.h index 40a5d707..b8314dce 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -830,6 +830,7 @@ char *Cvar_Serverinfo( void ); void Cmd_WriteVariables( file_t *f ); qboolean Cmd_CheckMapsList( qboolean fRefresh ); void Cmd_AutoComplete( char *complete_string ); +void Com_SetRandomSeed( long lSeed ); long Com_RandomLong( long lMin, long lMax ); float Com_RandomFloat( float fMin, float fMax ); void TrimSpace( const char *source, char *dest ); diff --git a/engine/common/random.c b/engine/common/random.c index 709fea8a..ff26e749 100644 --- a/engine/common/random.c +++ b/engine/common/random.c @@ -28,7 +28,7 @@ static long idum = 0; #define EPS 1.2e-7 #define RNMX (1.0 - EPS) -void SeedRandomNumberGenerator( long lSeed ) +void Com_SetRandomSeed( long lSeed ) { if( lSeed ) idum = lSeed; else idum = -time( NULL ); @@ -85,7 +85,7 @@ float Com_RandomFloat( float flLow, float flHigh ) { float fl; - if( idum == 0 ) SeedRandomNumberGenerator(0); + if( idum == 0 ) Com_SetRandomSeed(0); fl = fran1(); // float in [0, 1) return (fl * (flHigh - flLow)) + flLow; // float in [low, high) @@ -96,7 +96,7 @@ long Com_RandomLong( long lLow, long lHigh ) dword maxAcceptable; dword n, x = lHigh-lLow + 1; - if( idum == 0 ) SeedRandomNumberGenerator(0); + if( idum == 0 ) Com_SetRandomSeed(0); if( x <= 0 || MAX_RANDOM_RANGE < x-1 ) return lLow;