From a49db0356119372f4786d5057568ee45dd373b6a Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Tue, 14 Apr 2026 10:56:46 +0500 Subject: [PATCH] engine: move StudioAPI negotiation to the engine --- engine/client/cl_game.c | 69 +++++++++++- engine/client/client.h | 1 - engine/client/ref_common.c | 8 -- engine/ref_api.h | 10 +- ref/gl/gl_context.c | 3 +- ref/gl/gl_local.h | 3 +- ref/gl/gl_studio.c | 222 ++++++++----------------------------- ref/null/r_context.c | 13 ++- ref/soft/r_context.c | 3 +- ref/soft/r_local.h | 3 +- ref/soft/r_studio.c | 222 ++++++++----------------------------- 11 files changed, 185 insertions(+), 372 deletions(-) diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index f2a3474c..a5ae74a5 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -23,6 +23,8 @@ GNU General Public License for more details. #include "client.h" #include "const.h" #include "triangleapi.h" +#include "r_studioint.h" +#include "mod_local.h" #include "r_efx.h" #include "demo_api.h" #include "ivoicetweak.h" @@ -2173,7 +2175,7 @@ pfnGetViewModel ============= */ -static cl_entity_t* GAME_EXPORT CL_GetViewModel( void ) +static cl_entity_t *GAME_EXPORT CL_GetViewModel( void ) { return &clgame.viewent; } @@ -3929,6 +3931,69 @@ void CL_UnloadProgs( void ) memset( &clgame, 0, sizeof( clgame )); } +static model_t *pfnStudio_Mod_ForName( const char *name, int crash ) +{ + return Mod_ForName( name, crash, false ); +} + +static void *pfnStudio_Mod_Extradata( model_t *mod ) +{ + return Mod_StudioExtradata( mod ); +} + +static void pfnStudio_GetAliasScale( float *x, float *y ) +{ + if( x ) *x = 1.0f; + if( y ) *y = 1.0f; +} + +static float ***pfnStudio_GetAliasTransform( void ) +{ + return NULL; +} + +static model_t *pfnStudio_GetChromeSprite( void ) +{ + return cl_sprite_shell; +} + +static int pfnStudio_IsHardware( void ) +{ + return 1; +} + +static engine_studio_api_t gStudioAPI = +{ + .Mem_Calloc = Mod_Calloc, + .Cache_Check = Mod_CacheCheck, + .LoadCacheFile = Mod_LoadCacheFile, + .Mod_ForName = pfnStudio_Mod_ForName, + .Mod_Extradata = pfnStudio_Mod_Extradata, + .GetModelByIndex = CL_ModelHandle, + .GetCvar = pfnCVarGetPointer, + .GetChromeSprite = pfnStudio_GetChromeSprite, + .GetAliasScale = pfnStudio_GetAliasScale, + .StudioGetAliasTransform = pfnStudio_GetAliasTransform, + .GetViewEntity = CL_GetViewModel, + .IsHardware = pfnStudio_IsHardware, +}; + +static void CL_InitStudioAPI( void ) +{ + static r_studio_interface_t gDefaultStudioDraw; + r_studio_interface_t *pStudioDraw; + + if( !ref.dllFuncs.R_StudioFillAPI( &gStudioAPI, &gDefaultStudioDraw )) + return; + + pStudioDraw = &gDefaultStudioDraw; + + if( clgame.dllFuncs.pfnGetStudioModelInterface ) + clgame.dllFuncs.pfnGetStudioModelInterface( STUDIO_INTERFACE_VERSION, &pStudioDraw, &gStudioAPI ); + + ref.dllFuncs.R_StudioSetDrawInterface( pStudioDraw ); +} + qboolean CL_LoadProgs( const char *name ) { static playermove_t gpMove; @@ -4066,7 +4131,7 @@ qboolean CL_LoadProgs( const char *name ) // initialize game clgame.dllFuncs.pfnInit(); - ref.dllFuncs.CL_InitStudioAPI(); + CL_InitStudioAPI(); return true; } diff --git a/engine/client/client.h b/engine/client/client.h index 42adc46c..ab18db39 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -874,7 +874,6 @@ struct msurface_s *pfnTraceSurface( int ground, float *vstart, float *vend ); void CL_EnableScissor( scissor_state_t *scissor, int x, int y, int width, int height ); void CL_DisableScissor( scissor_state_t *scissor ); qboolean CL_Scissor( const scissor_state_t *scissor, float *x, float *y, float *width, float *height, float *u0, float *v0, float *u1, float *v1 ); - static inline cl_entity_t *CL_EDICT_NUM( int index ) { if( unlikely( !clgame.entities )) // not in game yet diff --git a/engine/client/ref_common.c b/engine/client/ref_common.c index 07e6bee7..acc5b9db 100644 --- a/engine/client/ref_common.c +++ b/engine/client/ref_common.c @@ -287,13 +287,6 @@ static entity_state_t *R_StudioGetPlayerState( int index ) return &cl.frames[cl.parsecountmod].playerstate[index]; } -static int pfnGetStudioModelInterface( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio ) -{ - return clgame.dllFuncs.pfnGetStudioModelInterface ? - clgame.dllFuncs.pfnGetStudioModelInterface( version, ppinterface, pstudio ) : - 0; -} - static const bpc_desc_t *pfnImage_GetPFDesc( int idx ) { return &PFDesc[idx]; @@ -411,7 +404,6 @@ static const ref_api_t gEngfuncs = Mod_CacheCheck, Mod_LoadCacheFile, Mod_Calloc, - pfnGetStudioModelInterface, _Mem_AllocPool, _Mem_FreePool, diff --git a/engine/ref_api.h b/engine/ref_api.h index f3a35632..141ec7ab 100644 --- a/engine/ref_api.h +++ b/engine/ref_api.h @@ -64,7 +64,9 @@ GNU General Public License for more details. // 13. Removed ignore_flags argument from GetCvarPointer // 14. Removed reserved functions, they are leftover from RenderAPI // Removed CL_AddCustomBeam, it's now handled through R_AddEntity -#define REF_API_VERSION 14 +// 15. Replaced CL_InitStudioAPI with R_StudioFillAPI + R_StudioSetDrawInterface +// Engine now builds engine_studio_api_t and handles client DLL negotiation +#define REF_API_VERSION 15 #define TF_SKY (TF_SKYSIDE|TF_NOMIPMAP|TF_ALLOW_NEAREST) #define TF_FONT (TF_NOMIPMAP|TF_CLAMP|TF_ALLOW_NEAREST) @@ -223,7 +225,7 @@ enum ref_defaultsprite_e }; // the order of first three is important! -// so you can use this value in IEngineStudio.StudioIsHardware +// so you can use this value in IEngineStudio.StudioIsHardware (but shouldn't) typedef enum ref_graphic_apis_e { REF_SOFTWARE, // hypothetical: just make a surface to draw on, in software @@ -431,7 +433,6 @@ typedef struct ref_api_s void *(*Mod_CacheCheck)( struct cache_user_s *c ); void (*Mod_LoadCacheFile)( const char *path, struct cache_user_s *cu ); void *(*Mod_Calloc)( int number, size_t size ); - int (*pfnGetStudioModelInterface)( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio ); // memory poolhandle_t (*_Mem_AllocPool)( const char *name, const char *filename, int fileline ) @@ -574,7 +575,8 @@ typedef struct ref_interface_s // studio interface float (*R_StudioEstimateFrame)( cl_entity_t *e, mstudioseqdesc_t *pseqdesc, double time ); void (*R_StudioLerpMovement)( cl_entity_t *e, double time, vec3_t origin, vec3_t angles ); - void (*CL_InitStudioAPI)( void ); + qboolean (*R_StudioFillAPI)( struct engine_studio_api_s *api, struct r_studio_interface_s *pDefaultDraw ); + void (*R_StudioSetDrawInterface)( struct r_studio_interface_s *pDraw ); // bmodel void (*R_SetSkyCloudsTextures)( int solidskyTexture, int alphaskyTexture ); diff --git a/ref/gl/gl_context.c b/ref/gl/gl_context.c index d14a1cf8..659ab067 100644 --- a/ref/gl/gl_context.c +++ b/ref/gl/gl_context.c @@ -466,7 +466,8 @@ const ref_interface_t gReffuncs = R_StudioEstimateFrame, R_StudioLerpMovement, - CL_InitStudioAPI, + R_StudioFillAPI, + R_StudioSetDrawInterface, R_SetSkyCloudsTextures, GL_SubdivideSurface, diff --git a/ref/gl/gl_local.h b/ref/gl/gl_local.h index 76918f85..7e715f92 100644 --- a/ref/gl/gl_local.h +++ b/ref/gl/gl_local.h @@ -420,7 +420,8 @@ void R_GatherPlayerLight( void ); float R_StudioEstimateFrame( cl_entity_t *e, mstudioseqdesc_t *pseqdesc, double time ); void R_StudioLerpMovement( cl_entity_t *e, double time, vec3_t origin, vec3_t angles ); void R_StudioResetPlayerModels( void ); -void CL_InitStudioAPI( void ); +qboolean R_StudioFillAPI( struct engine_studio_api_s *api, struct r_studio_interface_s *pDefaultDraw ); +void R_StudioSetDrawInterface( struct r_studio_interface_s *pDraw ); void Mod_StudioLoadTextures( model_t *mod, void *data ); void Mod_StudioUnloadTextures( void *data ); diff --git a/ref/gl/gl_studio.c b/ref/gl/gl_studio.c index c667dedb..f2478cfe 100644 --- a/ref/gl/gl_studio.c +++ b/ref/gl/gl_studio.c @@ -375,17 +375,6 @@ player_info_t *pfnPlayerInfo( int index ) return gEngfuncs.pfnPlayerInfo( index ); } -/* -=============== -pfnMod_ForName - -=============== -*/ -static model_t *pfnMod_ForName( const char *model, int crash ) -{ - return gEngfuncs.Mod_ForName( model, crash, false ); -} - /* =============== pfnGetPlayerState @@ -400,17 +389,6 @@ static entity_state_t *R_StudioGetPlayerState( int index ) return gEngfuncs.pfnGetPlayerState( index ); } -/* -=============== -pfnGetViewEntity - -=============== -*/ -static cl_entity_t *pfnGetViewEntity( void ) -{ - return tr.viewent; -} - /* =============== pfnGetEngineTimes @@ -438,17 +416,6 @@ static void pfnGetViewInfo( float *origin, float *upv, float *rightv, float *for if( upv ) VectorCopy( RI.vup, upv ); } -/* -=============== -R_GetChromeSprite - -=============== -*/ -static model_t *R_GetChromeSprite( void ) -{ - return gEngfuncs.GetDefaultSprite( REF_CHROME_SPRITE ); -} - /* =============== pfnGetModelCounters @@ -461,18 +428,6 @@ static void pfnGetModelCounters( int **s, int **a ) *a = &r_stats.c_studio_models_drawn; } -/* -=============== -pfnGetAliasScale - -=============== -*/ -static void pfnGetAliasScale( float *x, float *y ) -{ - if( x ) *x = 1.0f; - if( y ) *y = 1.0f; -} - /* =============== pfnStudioGetBoneTransform @@ -495,17 +450,6 @@ static float ****pfnStudioGetLightTransform( void ) return (float ****)g_studio.lighttransform; } -/* -=============== -pfnStudioGetAliasTransform - -=============== -*/ -static float ***pfnStudioGetAliasTransform( void ) -{ - return NULL; -} - /* =============== pfnStudioGetRotationMatrix @@ -2917,18 +2861,6 @@ static void R_StudioSetChromeOrigin( void ) VectorCopy( RI.rvp.vieworigin, g_studio.chrome_origin ); } -/* -=============== -pfnIsHardware - -Xash3D is always works in hardware mode -=============== -*/ -static int pfnIsHardware( void ) -{ - return 1; // 0 is Software, 1 is OpenGL, 2 is Direct3D -} - /* =============== R_StudioDrawPointsShadow @@ -3165,7 +3097,7 @@ static void R_StudioRenderModel( void ) R_StudioRenderFinal( ); R_StudioSetForceFaceFlags( STUDIO_NF_CHROME ); - TriSpriteTexture( R_GetChromeSprite(), 0 ); + TriSpriteTexture( gEngfuncs.GetDefaultSprite( REF_CHROME_SPRITE ), 0 ); RI.currententity->curstate.renderfx = kRenderFxGlowShell; R_StudioRenderFinal( ); @@ -3881,115 +3813,53 @@ void Mod_StudioUnloadTextures( void *data ) } } -static model_t *pfnModelHandle( int modelindex ) +qboolean R_StudioFillAPI( engine_studio_api_t *api, r_studio_interface_t *pDefaultDraw ) { - if( modelindex < 0 || modelindex >= MAX_MODELS ) - return NULL; - return CL_ModelHandle( modelindex ); -} - -static void *pfnMod_CacheCheck( struct cache_user_s *c ) -{ - return gEngfuncs.Mod_CacheCheck( c ); -} - -static void *pfnMod_StudioExtradata( model_t *mod ) -{ - return gEngfuncs.Mod_Extradata( mod_studio, mod ); -} - -static void pfnMod_LoadCacheFile( const char *path, struct cache_user_s *cu ) -{ - gEngfuncs.Mod_LoadCacheFile( path, cu ); -} - -static cvar_t *pfnGetCvarPointer( const char *name ) -{ - return (cvar_t*)gEngfuncs.pfnGetCvarPointer( name ); -} - -static void *pfnMod_Calloc( int number, size_t size ) -{ - return gEngfuncs.Mod_Calloc( number, size ); -} - -static engine_studio_api_t gStudioAPI = -{ - pfnMod_Calloc, - pfnMod_CacheCheck, - pfnMod_LoadCacheFile, - pfnMod_ForName, - pfnMod_StudioExtradata, - pfnModelHandle, - pfnGetCurrentEntity, - pfnPlayerInfo, - R_StudioGetPlayerState, - pfnGetViewEntity, - pfnGetEngineTimes, - pfnGetCvarPointer, - pfnGetViewInfo, - R_GetChromeSprite, - pfnGetModelCounters, - pfnGetAliasScale, - pfnStudioGetBoneTransform, - pfnStudioGetLightTransform, - pfnStudioGetAliasTransform, - pfnStudioGetRotationMatrix, - R_StudioSetupModel, - R_StudioCheckBBox, - R_StudioDynamicLight, - R_StudioEntityLight, - R_StudioSetupLighting, - R_StudioDrawPoints, - R_StudioDrawHulls, - R_StudioDrawAbsBBox, - R_StudioDrawBones, - (void*)R_StudioSetupSkin, - R_StudioSetRemapColors, - R_StudioSetupPlayerModel, - R_StudioClientEvents, - R_StudioGetForceFaceFlags, - R_StudioSetForceFaceFlags, - (void*)R_StudioSetHeader, - R_StudioSetRenderModel, - R_StudioSetupRenderer, - R_StudioRestoreRenderer, - R_StudioSetChromeOrigin, - pfnIsHardware, - GL_StudioDrawShadow, - GL_StudioSetRenderMode, - R_StudioSetRenderamt, - R_StudioSetCullState, - R_StudioRenderShadow, -}; - -static r_studio_interface_t gStudioDraw = -{ - STUDIO_INTERFACE_VERSION, - R_StudioDrawModel, - R_StudioDrawPlayer, -}; - -/* -=============== -CL_InitStudioAPI - -Initialize client studio -=============== -*/ -void CL_InitStudioAPI( void ) -{ - pStudioDraw = &gStudioDraw; - - // trying to grab them from client.dll cl_righthand = gEngfuncs.pfnGetCvarPointer( "cl_righthand" ); - // Xash will be used internal StudioModelRenderer - if( gEngfuncs.pfnGetStudioModelInterface( STUDIO_INTERFACE_VERSION, &pStudioDraw, &gStudioAPI )) - return; + api->GetCurrentEntity = pfnGetCurrentEntity; + api->PlayerInfo = pfnPlayerInfo; + api->GetPlayerState = R_StudioGetPlayerState; + api->GetTimes = pfnGetEngineTimes; + api->GetViewInfo = pfnGetViewInfo; + api->GetModelCounters = pfnGetModelCounters; + api->StudioGetBoneTransform = pfnStudioGetBoneTransform; + api->StudioGetLightTransform = pfnStudioGetLightTransform; + api->StudioGetRotationMatrix = pfnStudioGetRotationMatrix; + api->StudioSetupModel = R_StudioSetupModel; + api->StudioCheckBBox = R_StudioCheckBBox; + api->StudioDynamicLight = R_StudioDynamicLight; + api->StudioEntityLight = R_StudioEntityLight; + api->StudioSetupLighting = R_StudioSetupLighting; + api->StudioDrawPoints = R_StudioDrawPoints; + api->StudioDrawHulls = R_StudioDrawHulls; + api->StudioDrawAbsBBox = R_StudioDrawAbsBBox; + api->StudioDrawBones = R_StudioDrawBones; + api->StudioSetupSkin = (void *)R_StudioSetupSkin; + api->StudioSetRemapColors = R_StudioSetRemapColors; + api->SetupPlayerModel = R_StudioSetupPlayerModel; + api->StudioClientEvents = R_StudioClientEvents; + api->GetForceFaceFlags = R_StudioGetForceFaceFlags; + api->SetForceFaceFlags = R_StudioSetForceFaceFlags; + api->StudioSetHeader = (void *)R_StudioSetHeader; + api->SetRenderModel = R_StudioSetRenderModel; + api->SetupRenderer = R_StudioSetupRenderer; + api->RestoreRenderer = R_StudioRestoreRenderer; + api->SetChromeOrigin = R_StudioSetChromeOrigin; + api->GL_StudioDrawShadow = GL_StudioDrawShadow; + api->GL_SetRenderMode = GL_StudioSetRenderMode; + api->StudioSetRenderamt = R_StudioSetRenderamt; + api->StudioSetCullState = R_StudioSetCullState; + api->StudioRenderShadow = R_StudioRenderShadow; - // NOTE: we always return true even if game interface was not correct - // because we need Draw our StudioModels - // just restore pointer to builtin function - pStudioDraw = &gStudioDraw; + pDefaultDraw->version = STUDIO_INTERFACE_VERSION; + pDefaultDraw->StudioDrawModel = R_StudioDrawModel; + pDefaultDraw->StudioDrawPlayer = R_StudioDrawPlayer; + + return true; +} + +void R_StudioSetDrawInterface( r_studio_interface_t *pDraw ) +{ + pStudioDraw = pDraw; } diff --git a/ref/null/r_context.c b/ref/null/r_context.c index eaf8c90f..82e9b8b0 100644 --- a/ref/null/r_context.c +++ b/ref/null/r_context.c @@ -49,6 +49,16 @@ static void R_SimpleStubBool( qboolean unused ) ; } +static qboolean R_StudioFillAPI( struct engine_studio_api_s *api, struct r_studio_interface_s *pDefaultDraw ) +{ + return false; +} + +static void R_StudioSetDrawInterface( struct r_studio_interface_s *pDraw ) +{ + ; +} + static qboolean R_Init( void ) { gEngfuncs.R_Init_Video( REF_SOFTWARE ); @@ -467,7 +477,8 @@ static const ref_interface_t gReffuncs = .R_StudioEstimateFrame = R_StudioEstimateFrame, .R_StudioLerpMovement = R_StudioLerpMovement, - .CL_InitStudioAPI = R_SimpleStub, + .R_StudioFillAPI = R_StudioFillAPI, + .R_StudioSetDrawInterface = R_StudioSetDrawInterface, .R_SetSkyCloudsTextures = R_SetSkyCloudsTextures, .GL_SubdivideSurface = GL_SubdivideSurface, diff --git a/ref/soft/r_context.c b/ref/soft/r_context.c index 47326431..97bace5b 100644 --- a/ref/soft/r_context.c +++ b/ref/soft/r_context.c @@ -451,7 +451,8 @@ const ref_interface_t gReffuncs = R_StudioEstimateFrame, R_StudioLerpMovement, - CL_InitStudioAPI, + R_StudioFillAPI, + R_StudioSetDrawInterface, R_SetSkyCloudsTextures, GL_SubdivideSurface, diff --git a/ref/soft/r_local.h b/ref/soft/r_local.h index 6d8a5e3c..1aca8f38 100644 --- a/ref/soft/r_local.h +++ b/ref/soft/r_local.h @@ -405,7 +405,8 @@ void R_GatherPlayerLight( void ); float R_StudioEstimateFrame( cl_entity_t *e, mstudioseqdesc_t *pseqdesc, double time ); void R_StudioLerpMovement( cl_entity_t *e, double time, vec3_t origin, vec3_t angles ); void R_StudioResetPlayerModels( void ); -void CL_InitStudioAPI( void ); +qboolean R_StudioFillAPI( struct engine_studio_api_s *api, struct r_studio_interface_s *pDefaultDraw ); +void R_StudioSetDrawInterface( struct r_studio_interface_s *pDraw ); void Mod_StudioLoadTextures( model_t *mod, void *data ); void Mod_StudioUnloadTextures( void *data ); diff --git a/ref/soft/r_studio.c b/ref/soft/r_studio.c index 7e3c0e23..ef26013c 100644 --- a/ref/soft/r_studio.c +++ b/ref/soft/r_studio.c @@ -359,17 +359,6 @@ player_info_t *pfnPlayerInfo( int index ) return gEngfuncs.pfnPlayerInfo( index ); } -/* -=============== -pfnMod_ForName - -=============== -*/ -static model_t *pfnMod_ForName( const char *model, int crash ) -{ - return gEngfuncs.Mod_ForName( model, crash, false ); -} - /* =============== pfnGetPlayerState @@ -384,17 +373,6 @@ static entity_state_t *R_StudioGetPlayerState( int index ) return gEngfuncs.pfnGetPlayerState( index ); } -/* -=============== -pfnGetViewEntity - -=============== -*/ -static cl_entity_t *pfnGetViewEntity( void ) -{ - return tr.viewent; -} - /* =============== pfnGetEngineTimes @@ -429,17 +407,6 @@ static void pfnGetViewInfo( float *origin, float *upv, float *rightv, float *for VectorCopy( RI.vup, upv ); } -/* -=============== -R_GetChromeSprite - -=============== -*/ -static model_t *R_GetChromeSprite( void ) -{ - return gEngfuncs.GetDefaultSprite( REF_CHROME_SPRITE ); -} - /* =============== pfnGetModelCounters @@ -452,20 +419,6 @@ static void pfnGetModelCounters( int **s, int **a ) *a = &r_stats.c_studio_models_drawn; } -/* -=============== -pfnGetAliasScale - -=============== -*/ -static void pfnGetAliasScale( float *x, float *y ) -{ - if( x ) - *x = 1.0f; - if( y ) - *y = 1.0f; -} - /* =============== pfnStudioGetBoneTransform @@ -488,17 +441,6 @@ static float ****pfnStudioGetLightTransform( void ) return (float ****)g_studio.lighttransform; } -/* -=============== -pfnStudioGetAliasTransform - -=============== -*/ -static float ***pfnStudioGetAliasTransform( void ) -{ - return NULL; -} - /* =============== pfnStudioGetRotationMatrix @@ -2575,18 +2517,6 @@ static void R_StudioSetChromeOrigin( void ) VectorCopy( RI.rvp.vieworigin, g_studio.chrome_origin ); } -/* -=============== -pfnIsHardware - -Xash3D is always works in hardware mode -=============== -*/ -static int pfnIsHardware( void ) -{ - return 1; // 0 is Software, 1 is OpenGL, 2 is Direct3D -} - /* =============== GL_StudioSetRenderMode @@ -2683,7 +2613,7 @@ static void R_StudioRenderModel( void ) R_StudioRenderFinal( ); R_StudioSetForceFaceFlags( STUDIO_NF_CHROME ); - TriSpriteTexture( R_GetChromeSprite(), 0 ); + TriSpriteTexture( gEngfuncs.GetDefaultSprite( REF_CHROME_SPRITE ), 0 ); RI.currententity->curstate.renderfx = kRenderFxGlowShell; R_StudioRenderFinal( ); @@ -3415,113 +3345,53 @@ void Mod_StudioUnloadTextures( void *data ) } } -static model_t *pfnModelHandle( int modelindex ) +qboolean R_StudioFillAPI( engine_studio_api_t *api, r_studio_interface_t *pDefaultDraw ) { - return CL_ModelHandle( modelindex ); -} - -static void *pfnMod_CacheCheck( struct cache_user_s *c ) -{ - return gEngfuncs.Mod_CacheCheck( c ); -} - -static void *pfnMod_StudioExtradata( model_t *mod ) -{ - return gEngfuncs.Mod_Extradata( mod_studio, mod ); -} - -static void pfnMod_LoadCacheFile( const char *path, struct cache_user_s *cu ) -{ - gEngfuncs.Mod_LoadCacheFile( path, cu ); -} - -static cvar_t *pfnGetCvarPointer( const char *name ) -{ - return (cvar_t *)gEngfuncs.pfnGetCvarPointer( name ); -} - -static void *pfnMod_Calloc( int number, size_t size ) -{ - return gEngfuncs.Mod_Calloc( number, size ); -} - -static engine_studio_api_t gStudioAPI = -{ - pfnMod_Calloc, - pfnMod_CacheCheck, - pfnMod_LoadCacheFile, - pfnMod_ForName, - pfnMod_StudioExtradata, - pfnModelHandle, - pfnGetCurrentEntity, - pfnPlayerInfo, - R_StudioGetPlayerState, - pfnGetViewEntity, - pfnGetEngineTimes, - pfnGetCvarPointer, - pfnGetViewInfo, - R_GetChromeSprite, - pfnGetModelCounters, - pfnGetAliasScale, - pfnStudioGetBoneTransform, - pfnStudioGetLightTransform, - pfnStudioGetAliasTransform, - pfnStudioGetRotationMatrix, - R_StudioSetupModel, - R_StudioCheckBBox, - R_StudioDynamicLight, - R_StudioEntityLight, - R_StudioSetupLighting, - R_StudioDrawPoints, - R_StudioDrawHulls, - R_StudioDrawAbsBBox, - R_StudioDrawBones, - (void *)R_StudioSetupSkin, - R_StudioSetRemapColors, - R_StudioSetupPlayerModel, - R_StudioClientEvents, - R_StudioGetForceFaceFlags, - R_StudioSetForceFaceFlags, - (void *)R_StudioSetHeader, - R_StudioSetRenderModel, - R_StudioSetupRenderer, - R_StudioRestoreRenderer, - R_StudioSetChromeOrigin, - pfnIsHardware, - GL_StudioDrawShadow, - GL_StudioSetRenderMode, - R_StudioSetRenderamt, - R_StudioSetCullState, - R_StudioRenderShadow, -}; - -static r_studio_interface_t gStudioDraw = -{ - STUDIO_INTERFACE_VERSION, - R_StudioDrawModel, - R_StudioDrawPlayer, -}; - -/* -=============== -CL_InitStudioAPI - -Initialize client studio -=============== -*/ -void GAME_EXPORT CL_InitStudioAPI( void ) -{ - pStudioDraw = &gStudioDraw; - - // trying to grab them from client.dll cl_righthand = gEngfuncs.pfnGetCvarPointer( "cl_righthand" ); - // Xash will be used internal StudioModelRenderer - if( gEngfuncs.pfnGetStudioModelInterface( STUDIO_INTERFACE_VERSION, &pStudioDraw, &gStudioAPI )) - return; + api->GetCurrentEntity = pfnGetCurrentEntity; + api->PlayerInfo = pfnPlayerInfo; + api->GetPlayerState = R_StudioGetPlayerState; + api->GetTimes = pfnGetEngineTimes; + api->GetViewInfo = pfnGetViewInfo; + api->GetModelCounters = pfnGetModelCounters; + api->StudioGetBoneTransform = pfnStudioGetBoneTransform; + api->StudioGetLightTransform = pfnStudioGetLightTransform; + api->StudioGetRotationMatrix = pfnStudioGetRotationMatrix; + api->StudioSetupModel = R_StudioSetupModel; + api->StudioCheckBBox = R_StudioCheckBBox; + api->StudioDynamicLight = R_StudioDynamicLight; + api->StudioEntityLight = R_StudioEntityLight; + api->StudioSetupLighting = R_StudioSetupLighting; + api->StudioDrawPoints = R_StudioDrawPoints; + api->StudioDrawHulls = R_StudioDrawHulls; + api->StudioDrawAbsBBox = R_StudioDrawAbsBBox; + api->StudioDrawBones = R_StudioDrawBones; + api->StudioSetupSkin = (void *)R_StudioSetupSkin; + api->StudioSetRemapColors = R_StudioSetRemapColors; + api->SetupPlayerModel = R_StudioSetupPlayerModel; + api->StudioClientEvents = R_StudioClientEvents; + api->GetForceFaceFlags = R_StudioGetForceFaceFlags; + api->SetForceFaceFlags = R_StudioSetForceFaceFlags; + api->StudioSetHeader = (void *)R_StudioSetHeader; + api->SetRenderModel = R_StudioSetRenderModel; + api->SetupRenderer = R_StudioSetupRenderer; + api->RestoreRenderer = R_StudioRestoreRenderer; + api->SetChromeOrigin = R_StudioSetChromeOrigin; + api->GL_StudioDrawShadow = GL_StudioDrawShadow; + api->GL_SetRenderMode = GL_StudioSetRenderMode; + api->StudioSetRenderamt = R_StudioSetRenderamt; + api->StudioSetCullState = R_StudioSetCullState; + api->StudioRenderShadow = R_StudioRenderShadow; - // NOTE: we always return true even if game interface was not correct - // because we need Draw our StudioModels - // just restore pointer to builtin function - pStudioDraw = &gStudioDraw; + pDefaultDraw->version = STUDIO_INTERFACE_VERSION; + pDefaultDraw->StudioDrawModel = R_StudioDrawModel; + pDefaultDraw->StudioDrawPlayer = R_StudioDrawPlayer; + + return true; +} + +void R_StudioSetDrawInterface( r_studio_interface_t *pDraw ) +{ + pStudioDraw = pDraw; }