engine: move StudioAPI negotiation to the engine

This commit is contained in:
Alibek Omarov
2026-04-14 10:56:46 +05:00
parent 84b7b5803b
commit a49db03561
11 changed files with 185 additions and 372 deletions

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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,

View File

@@ -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 );

View File

@@ -466,7 +466,8 @@ const ref_interface_t gReffuncs =
R_StudioEstimateFrame,
R_StudioLerpMovement,
CL_InitStudioAPI,
R_StudioFillAPI,
R_StudioSetDrawInterface,
R_SetSkyCloudsTextures,
GL_SubdivideSurface,

View File

@@ -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 );

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -451,7 +451,8 @@ const ref_interface_t gReffuncs =
R_StudioEstimateFrame,
R_StudioLerpMovement,
CL_InitStudioAPI,
R_StudioFillAPI,
R_StudioSetDrawInterface,
R_SetSkyCloudsTextures,
GL_SubdivideSurface,

View File

@@ -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 );

View File

@@ -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;
}