mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2025-01-22 00:11:20 +00:00
implemented the new interop system
implemented the dynamic lights and integer shader time extensions
This commit is contained in:
parent
b8e4413d2f
commit
9ea5d021d5
16 changed files with 206 additions and 26 deletions
|
@ -26,6 +26,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include "../qcommon/vm_shim.h"
|
||||
|
||||
|
||||
static const byte* interopBufferIn;
|
||||
static int interopBufferInSize;
|
||||
static byte* interopBufferOut;
|
||||
static int interopBufferOutSize;
|
||||
|
||||
|
||||
static void CL_GetGameState( gameState_t* gs )
|
||||
{
|
||||
*gs = cl.gameState;
|
||||
|
@ -292,6 +298,27 @@ void CL_ShutdownCGame()
|
|||
}
|
||||
|
||||
|
||||
static qbool CL_CG_GetValue( char* value, int valueSize, const char* key )
|
||||
{
|
||||
if( Q_stricmp(key, "trap_LocateInteropData") == 0 ) {
|
||||
Com_sprintf( value, valueSize, "%d", CG_EXT_LOCATEINTEROPDATA );
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
if( Q_stricmp(key, "trap_R_AddRefEntityToScene2") == 0 ) {
|
||||
Com_sprintf( value, valueSize, "%d", CG_EXT_R_ADDREFENTITYTOSCENE2 );
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
if( Q_stricmp(key, "trap_R_ForceFixedDLights") == 0 ) {
|
||||
Com_sprintf( value, valueSize, "%d", CG_EXT_R_FORCEFIXEDDLIGHTS );
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
@ -432,7 +459,7 @@ static intptr_t CL_CgameSystemCalls( intptr_t *args )
|
|||
re.ClearScene();
|
||||
return 0;
|
||||
case CG_R_ADDREFENTITYTOSCENE:
|
||||
re.AddRefEntityToScene( VMA(1) );
|
||||
re.AddRefEntityToScene( VMA(1), qfalse );
|
||||
return 0;
|
||||
case CG_R_ADDPOLYTOSCENE:
|
||||
re.AddPolyToScene( args[1], args[2], VMA(3), 1 );
|
||||
|
@ -542,6 +569,25 @@ static intptr_t CL_CgameSystemCalls( intptr_t *args )
|
|||
case CG_R_INPVS:
|
||||
return re.inPVS( VMA(1), VMA(2) );
|
||||
|
||||
// engine extensions
|
||||
|
||||
case CG_EXT_GETVALUE:
|
||||
return CL_CG_GetValue( VMA(1), args[2], VMA(3) );
|
||||
|
||||
case CG_EXT_LOCATEINTEROPDATA:
|
||||
interopBufferIn = VMA(1);
|
||||
interopBufferInSize = args[2];
|
||||
interopBufferOut = VMA(3);
|
||||
interopBufferOutSize = args[4];
|
||||
return 0;
|
||||
|
||||
case CG_EXT_R_ADDREFENTITYTOSCENE2:
|
||||
re.AddRefEntityToScene( VMA(1), qtrue );
|
||||
return 0;
|
||||
|
||||
case CG_EXT_R_FORCEFIXEDDLIGHTS:
|
||||
return 0; // already the case for CNQ3
|
||||
|
||||
default:
|
||||
Com_Error( ERR_DROP, "Bad cgame system trap: %i", args[0] );
|
||||
}
|
||||
|
|
|
@ -26,6 +26,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
vm_t *uivm;
|
||||
|
||||
static const byte* interopBufferIn;
|
||||
static int interopBufferInSize;
|
||||
static byte* interopBufferOut;
|
||||
static int interopBufferOutSize;
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
GetClientState
|
||||
|
@ -745,6 +751,22 @@ static int GetConfigString(int index, char *buf, int size)
|
|||
}
|
||||
|
||||
|
||||
static qbool CL_UI_GetValue( char* value, int valueSize, const char* key )
|
||||
{
|
||||
if( Q_stricmp(key, "trap_LocateInteropData") == 0 ) {
|
||||
Com_sprintf( value, valueSize, "%d", UI_EXT_LOCATEINTEROPDATA );
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
if( Q_stricmp(key, "trap_R_AddRefEntityToScene2") == 0 ) {
|
||||
Com_sprintf( value, valueSize, "%d", UI_EXT_R_ADDREFENTITYTOSCENE2 );
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
@ -845,7 +867,7 @@ static intptr_t CL_UISystemCalls( intptr_t* args )
|
|||
return 0;
|
||||
|
||||
case UI_R_ADDREFENTITYTOSCENE:
|
||||
re.AddRefEntityToScene( VMA(1) );
|
||||
re.AddRefEntityToScene( VMA(1), qfalse );
|
||||
return 0;
|
||||
|
||||
case UI_R_ADDPOLYTOSCENE:
|
||||
|
@ -1077,6 +1099,21 @@ static intptr_t CL_UISystemCalls( intptr_t* args )
|
|||
case UI_VERIFY_CDKEY:
|
||||
return CL_CDKeyValidate(VMA(1), VMA(2));
|
||||
|
||||
// extensions
|
||||
|
||||
case UI_EXT_GETVALUE:
|
||||
return CL_UI_GetValue( VMA(1), args[2], VMA(3) );
|
||||
|
||||
case UI_EXT_LOCATEINTEROPDATA:
|
||||
interopBufferIn = VMA(1);
|
||||
interopBufferInSize = args[2];
|
||||
interopBufferOut = VMA(3);
|
||||
interopBufferOutSize = args[4];
|
||||
return 0;
|
||||
|
||||
case UI_EXT_R_ADDREFENTITYTOSCENE2:
|
||||
re.AddRefEntityToScene( VMA(1), qtrue );
|
||||
return 0;
|
||||
|
||||
default:
|
||||
Com_Error( ERR_DROP, "Bad UI system trap: %i", args[0] );
|
||||
|
|
|
@ -175,7 +175,14 @@ typedef enum {
|
|||
CG_CEIL,
|
||||
DO_NOT_WANT_CG_TESTPRINTINT,
|
||||
DO_NOT_WANT_CG_TESTPRINTFLOAT,
|
||||
CG_ACOS
|
||||
CG_ACOS,
|
||||
|
||||
// engine extensions
|
||||
// the mod should _never_ use these symbols
|
||||
CG_EXT_GETVALUE = 700,
|
||||
CG_EXT_LOCATEINTEROPDATA,
|
||||
CG_EXT_R_ADDREFENTITYTOSCENE2,
|
||||
CG_EXT_R_FORCEFIXEDDLIGHTS
|
||||
} cgameImport_t;
|
||||
|
||||
|
||||
|
|
|
@ -32,13 +32,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include "cg_public.h"
|
||||
|
||||
|
||||
static intptr_t (QDECL *syscall)( intptr_t arg, ... ) = (intptr_t (QDECL *)( intptr_t, ...))-1;
|
||||
dllSyscall_t syscall = (dllSyscall_t)-1;
|
||||
extern int cg_addRefEntSyscallId;
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
void dllEntry( intptr_t (QDECL *syscallptr)( intptr_t arg,... ) ) {
|
||||
void dllEntry( dllSyscall_t syscallptr ) {
|
||||
syscall = syscallptr;
|
||||
}
|
||||
|
||||
|
@ -245,7 +246,7 @@ void trap_R_ClearScene( void ) {
|
|||
}
|
||||
|
||||
void trap_R_AddRefEntityToScene( const refEntity_t *re ) {
|
||||
syscall( CG_R_ADDREFENTITYTOSCENE, re );
|
||||
syscall( cg_addRefEntSyscallId, re );
|
||||
}
|
||||
|
||||
void trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts ) {
|
||||
|
|
|
@ -686,6 +686,9 @@ void Cvar_Update( vmCvar_t *vmCvar )
|
|||
|
||||
void Cvar_Init()
|
||||
{
|
||||
// this cvar is the single entry point of the entire extension system
|
||||
Cvar_Get( "//trap_GetValue", "700", CVAR_INIT | CVAR_ROM );
|
||||
|
||||
cvar_cheats = Cvar_Get( "sv_cheats", "1", CVAR_ROM | CVAR_SYSTEMINFO );
|
||||
Cvar_Get( "git_branch", GIT_BRANCH, CVAR_ROM );
|
||||
Cvar_Get( "git_headHash", GIT_COMMIT, CVAR_ROM );
|
||||
|
|
|
@ -384,8 +384,12 @@ typedef enum {
|
|||
BOTLIB_PC_LOAD_SOURCE,
|
||||
BOTLIB_PC_FREE_SOURCE,
|
||||
BOTLIB_PC_READ_TOKEN,
|
||||
BOTLIB_PC_SOURCE_FILE_AND_LINE
|
||||
BOTLIB_PC_SOURCE_FILE_AND_LINE,
|
||||
|
||||
// engine extensions
|
||||
// the mod should _never_ use these symbols
|
||||
G_EXT_GETVALUE = 700,
|
||||
G_EXT_LOCATEINTEROPDATA
|
||||
} gameImport_t;
|
||||
|
||||
|
||||
|
|
|
@ -32,13 +32,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include "g_public.h"
|
||||
|
||||
|
||||
static intptr_t (QDECL *syscall)( intptr_t arg, ... ) = (intptr_t (QDECL *)( intptr_t, ...))-1;
|
||||
dllSyscall_t syscall = (dllSyscall_t)-1;
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
void dllEntry( intptr_t (QDECL *syscallptr)( intptr_t arg,... ) ) {
|
||||
void dllEntry( dllSyscall_t syscallptr ) {
|
||||
syscall = syscallptr;
|
||||
}
|
||||
|
||||
|
|
47
code/qcommon/syscall_ext.h
Normal file
47
code/qcommon/syscall_ext.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
// only include in cg_ext.c, g_ext.c, ui_ext.c
|
||||
|
||||
#ifndef Q3_VM
|
||||
#include "q_shared.h"
|
||||
extern dllSyscall_t syscall;
|
||||
#endif
|
||||
|
||||
#define EMPTY
|
||||
|
||||
#ifdef Q3_VM
|
||||
#define DEF_TRAP_0(ret, R, Name) typedef R (*Name##_t)(); Name##_t Name
|
||||
#define DEF_TRAP_1(ret, R, Name, A1) typedef R (*Name##_t)(A1); Name##_t Name
|
||||
#define DEF_TRAP_2(ret, R, Name, A1, A2) typedef R (*Name##_t)(A1, A2); Name##_t Name
|
||||
#define DEF_TRAP_3(ret, R, Name, A1, A2, A3) typedef R (*Name##_t)(A1, A2, A3); Name##_t Name
|
||||
#define DEF_TRAP_4(ret, R, Name, A1, A2, A3, A4) typedef R (*Name##_t)(A1, A2, A3, A4); Name##_t Name
|
||||
#define DEF_TRAP_5(ret, R, Name, A1, A2, A3, A4, A5) typedef R (*Name##_t)(A1, A2, A3, A4, A5); Name##_t Name
|
||||
#define DEF_TRAP_6(ret, R, Name, A1, A2, A3, A4, A5, A6) typedef R (*Name##_t)(A1, A2, A3, A4, A5, A6); Name##_t Name
|
||||
#else
|
||||
#define DEF_TRAP_0(ret, R, Name) R Name() { ret syscall(cpma_ext.Name); }
|
||||
#define DEF_TRAP_1(ret, R, Name, A1) R Name(A1 a1) { ret syscall(cpma_ext.Name, (int)a1); }
|
||||
#define DEF_TRAP_2(ret, R, Name, A1, A2) R Name(A1 a1, A2 a2) { ret syscall(cpma_ext.Name, (int)a1, (int)a2); }
|
||||
#define DEF_TRAP_3(ret, R, Name, A1, A2, A3) R Name(A1 a1, A2 a2, A3 a3) { ret syscall(cpma_ext.Name, (int)a1, (int)a2, (int)a3); }
|
||||
#define DEF_TRAP_4(ret, R, Name, A1, A2, A3, A4) R Name(A1 a1, A2 a2, A3 a3, A4 a4) { ret syscall(cpma_ext.Name, (int)a1, (int)a2, (int)a3, (int)a4); }
|
||||
#define DEF_TRAP_5(ret, R, Name, A1, A2, A3, A4, A5) R Name(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { ret syscall(cpma_ext.Name, (int)a1, (int)a2, (int)a3, (int)a4, (int)a5); }
|
||||
#define DEF_TRAP_6(ret, R, Name, A1, A2, A3, A4, A5, A6) R Name(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { ret syscall(cpma_ext.Name, (int)a1, (int)a2, (int)a3, (int)a4, (int)a5, (int)a6); }
|
||||
#endif
|
||||
|
||||
#ifdef Q3_VM
|
||||
#define GET_TRAP(Name) \
|
||||
do { \
|
||||
if (trap_GetValue(syscallStr, sizeof(syscallStr), #Name) && \
|
||||
sscanf(syscallStr, "%d", &syscallId) == 1 && \
|
||||
syscallId != 0) { \
|
||||
cpma_ext.Name = syscallId; \
|
||||
Name = (Name##_t)(~syscallId); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define GET_TRAP(Name) \
|
||||
do { \
|
||||
if (trap_GetValue(syscallStr, sizeof(syscallStr), #Name) && \
|
||||
sscanf(syscallStr, "%d", &syscallId) == 1 && \
|
||||
syscallId != 0) { \
|
||||
cpma_ext.Name = syscallId; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -137,7 +137,13 @@ typedef enum {
|
|||
UI_ATAN2,
|
||||
UI_SQRT,
|
||||
UI_FLOOR,
|
||||
UI_CEIL
|
||||
UI_CEIL,
|
||||
|
||||
// engine extensions
|
||||
// the mod should _never_ use these symbols
|
||||
UI_EXT_GETVALUE = 700,
|
||||
UI_EXT_LOCATEINTEROPDATA,
|
||||
UI_EXT_R_ADDREFENTITYTOSCENE2
|
||||
} uiImport_t;
|
||||
|
||||
|
||||
|
|
|
@ -32,13 +32,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include "ui_public.h"
|
||||
|
||||
|
||||
static intptr_t (QDECL *syscall)( intptr_t arg, ... ) = (intptr_t (QDECL *)( intptr_t, ...))-1;
|
||||
dllSyscall_t syscall = (dllSyscall_t)-1;
|
||||
extern int ui_addRefEntSyscallId;
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
void dllEntry( intptr_t (QDECL *syscallptr)( intptr_t arg,... ) ) {
|
||||
void dllEntry( dllSyscall_t syscallptr ) {
|
||||
syscall = syscallptr;
|
||||
}
|
||||
|
||||
|
@ -150,7 +151,7 @@ void trap_R_ClearScene( void ) {
|
|||
}
|
||||
|
||||
void trap_R_AddRefEntityToScene( const refEntity_t *re ) {
|
||||
syscall( UI_R_ADDREFENTITYTOSCENE, re );
|
||||
syscall( ui_addRefEntSyscallId, re );
|
||||
}
|
||||
|
||||
void trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts ) {
|
||||
|
|
|
@ -15,6 +15,8 @@ struct VM_Arg {
|
|||
VMA_CONVOP( const char );
|
||||
VMA_CONVOP( char );
|
||||
VMA_CONVOP( void );
|
||||
VMA_CONVOP( byte );
|
||||
VMA_CONVOP( const byte );
|
||||
|
||||
VMA_CONVOP( vmCvar_t );
|
||||
|
||||
|
|
|
@ -482,7 +482,7 @@ static void RB_RenderDrawSurfList( const drawSurf_t* drawSurfs, int numDrawSurfs
|
|||
|
||||
if ( entityNum != ENTITYNUM_WORLD ) {
|
||||
backEnd.currentEntity = &backEnd.refdef.entities[entityNum];
|
||||
if (backEnd.isShaderTimeInSec)
|
||||
if (backEnd.currentEntity->intShaderTime)
|
||||
backEnd.refdef.floatTime = originalTime - (double)(backEnd.currentEntity->e.shaderTime.iShaderTime) / 1000.0;
|
||||
else
|
||||
backEnd.refdef.floatTime = originalTime - backEnd.currentEntity->e.shaderTime.fShaderTime;
|
||||
|
@ -596,7 +596,7 @@ static void RB_RenderLitSurfList( dlight_t* dl )
|
|||
|
||||
if ( entityNum != ENTITYNUM_WORLD ) {
|
||||
backEnd.currentEntity = &backEnd.refdef.entities[entityNum];
|
||||
if (backEnd.isShaderTimeInSec)
|
||||
if (backEnd.currentEntity->intShaderTime)
|
||||
backEnd.refdef.floatTime = originalTime - (double)backEnd.currentEntity->e.shaderTime.iShaderTime;
|
||||
else
|
||||
backEnd.refdef.floatTime = originalTime - backEnd.currentEntity->e.shaderTime.fShaderTime;
|
||||
|
@ -1068,9 +1068,6 @@ void RB_ExecuteRenderCommands( const void *data )
|
|||
#else
|
||||
backEnd.smpFrame = 0;
|
||||
#endif
|
||||
|
||||
cvar_t* r_floatfix = ri.Cvar_Get( "r_floatfix", "1", CVAR_NORESTART );
|
||||
backEnd.isShaderTimeInSec = r_floatfix->integer ? qtrue : qfalse;
|
||||
|
||||
while ( 1 ) {
|
||||
data = PADP(data, sizeof(void *));
|
||||
|
|
|
@ -73,6 +73,8 @@ struct trRefEntity_t {
|
|||
vec3_t ambientLight; // color normalized to 0-255
|
||||
int ambientLightInt; // 32 bit rgba packed
|
||||
vec3_t directedLight;
|
||||
|
||||
qbool intShaderTime; // is the shaderTime member an integer?
|
||||
};
|
||||
|
||||
|
||||
|
@ -823,7 +825,6 @@ typedef struct {
|
|||
int* pc; // current stats set, depending on projection2D
|
||||
int pc2D[RB_STATS_MAX];
|
||||
int pc3D[RB_STATS_MAX];
|
||||
qbool isShaderTimeInSec; // use int instead float
|
||||
} backEndState_t;
|
||||
|
||||
|
||||
|
@ -927,8 +928,6 @@ extern backEndState_t backEnd;
|
|||
extern trGlobals_t tr;
|
||||
extern glstate_t glState; // outside of TR since it shouldn't be cleared during ref re-init
|
||||
|
||||
// 1.32e
|
||||
extern cvar_t *r_floatfix;
|
||||
|
||||
//
|
||||
// cvars
|
||||
|
@ -1322,7 +1321,7 @@ SCENE GENERATION
|
|||
void R_ToggleSmpFrame();
|
||||
|
||||
void RE_ClearScene();
|
||||
void RE_AddRefEntityToScene( const refEntity_t *ent );
|
||||
void RE_AddRefEntityToScene( const refEntity_t *ent, qbool intShaderTime );
|
||||
void RE_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts, int num );
|
||||
void RE_AddLightToScene( const vec3_t org, float radius, float r, float g, float b );
|
||||
void RE_RenderScene( const refdef_t *fd );
|
||||
|
|
|
@ -127,7 +127,7 @@ typedef struct {
|
|||
// a scene is built up by calls to R_ClearScene and the various R_Add functions.
|
||||
// Nothing is drawn until R_RenderScene is called.
|
||||
void (*ClearScene)();
|
||||
void (*AddRefEntityToScene)( const refEntity_t *re );
|
||||
void (*AddRefEntityToScene)( const refEntity_t *re, qbool intShaderTime );
|
||||
void (*AddPolyToScene)( qhandle_t hShader, int numVerts, const polyVert_t *verts, int num );
|
||||
qbool (*LightForPoint)( const vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir );
|
||||
void (*AddLightToScene)( const vec3_t org, float radius, float r, float g, float b );
|
||||
|
|
|
@ -163,7 +163,7 @@ void RE_AddPolyToScene( qhandle_t hShader, int numVerts, const polyVert_t* verts
|
|||
///////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void RE_AddRefEntityToScene( const refEntity_t* ent )
|
||||
void RE_AddRefEntityToScene( const refEntity_t* ent, qbool intShaderTime )
|
||||
{
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
|
@ -177,8 +177,10 @@ void RE_AddRefEntityToScene( const refEntity_t* ent )
|
|||
ri.Error( ERR_DROP, "RE_AddRefEntityToScene: bad reType %i", ent->reType );
|
||||
}
|
||||
|
||||
backEndData[tr.smpFrame]->entities[r_numentities].e = *ent;
|
||||
backEndData[tr.smpFrame]->entities[r_numentities].lightingCalculated = qfalse;
|
||||
trRefEntity_t* const trEnt = &backEndData[tr.smpFrame]->entities[r_numentities];
|
||||
trEnt->e = *ent;
|
||||
trEnt->lightingCalculated = qfalse;
|
||||
trEnt->intShaderTime = intShaderTime;
|
||||
r_numentities++;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
botlib_export_t *botlib_export;
|
||||
|
||||
static const byte* interopBufferIn;
|
||||
static int interopBufferInSize;
|
||||
static byte* interopBufferOut;
|
||||
static int interopBufferOutSize;
|
||||
|
||||
|
||||
// these functions must be used instead of pointer arithmetic, because
|
||||
// the game allocates gentities with private information after the server shared part
|
||||
|
@ -229,6 +234,17 @@ static void SV_GetUsercmd( int clientNum, usercmd_t* cmd )
|
|||
}
|
||||
|
||||
|
||||
static qbool SV_G_GetValue( char* value, int valueSize, const char* key )
|
||||
{
|
||||
if( Q_stricmp(key, "trap_LocateInteropData") == 0 ) {
|
||||
Com_sprintf( value, valueSize, "%d", G_EXT_LOCATEINTEROPDATA );
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
@ -775,6 +791,18 @@ static intptr_t SV_GameSystemCalls( intptr_t* args )
|
|||
case TRAP_CEIL:
|
||||
return PASSFLOAT( ceil( VMF(1) ) );
|
||||
|
||||
// extensions
|
||||
|
||||
case G_EXT_GETVALUE:
|
||||
return SV_G_GetValue( VMA(1), args[2], VMA(3) );
|
||||
|
||||
case G_EXT_LOCATEINTEROPDATA:
|
||||
interopBufferIn = VMA(1);
|
||||
interopBufferInSize = args[2];
|
||||
interopBufferOut = VMA(3);
|
||||
interopBufferOutSize = args[4];
|
||||
return 0;
|
||||
|
||||
default:
|
||||
Com_Error( ERR_DROP, "Bad game system trap: %i", args[0] );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue