1 /*
2 ===========================================================================
3 Copyright (C) 2013 - 2015, OpenJK contributors
4 
5 This file is part of the OpenJK source code.
6 
7 OpenJK is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
18 ===========================================================================
19 */
20 
21 // cl_cgameapi.cpp  -- client system interaction with client game
22 #include "qcommon/cm_public.h"
23 #include "qcommon/RoffSystem.h"
24 #include "qcommon/stringed_ingame.h"
25 #include "qcommon/timing.h"
26 #include "client.h"
27 #include "cl_uiapi.h"
28 #include "botlib/botlib.h"
29 #include "snd_ambient.h"
30 #include "FXExport.h"
31 #include "FxUtil.h"
32 
33 extern IHeapAllocator *G2VertSpaceClient;
34 extern botlib_export_t *botlib_export;
35 
36 // cgame interface
37 static cgameExport_t *cge; // cgame export table
38 static vm_t *cgvm; // cgame vm, valid for legacy and new api
39 
40 //
41 // cgame vmMain calls
42 //
CGVM_Init(int serverMessageNum,int serverCommandSequence,int clientNum)43 void CGVM_Init( int serverMessageNum, int serverCommandSequence, int clientNum ) {
44 	if ( cgvm->isLegacy ) {
45 		VM_Call( cgvm, CG_INIT, serverMessageNum, serverCommandSequence, clientNum );
46 		return;
47 	}
48 	VMSwap v( cgvm );
49 
50 	cge->Init( serverMessageNum, serverCommandSequence, clientNum );
51 }
52 
CGVM_Shutdown(void)53 void CGVM_Shutdown( void ) {
54 	if ( cgvm->isLegacy ) {
55 		VM_Call( cgvm, CG_SHUTDOWN );
56 		return;
57 	}
58 	VMSwap v( cgvm );
59 
60 	cge->Shutdown();
61 }
62 
CGVM_ConsoleCommand(void)63 qboolean CGVM_ConsoleCommand( void ) {
64 	if ( cgvm->isLegacy ) {
65 		return (qboolean)VM_Call( cgvm, CG_CONSOLE_COMMAND );
66 	}
67 	VMSwap v( cgvm );
68 
69 	return cge->ConsoleCommand();
70 }
71 
CGVM_DrawActiveFrame(int serverTime,stereoFrame_t stereoView,qboolean demoPlayback)72 void CGVM_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demoPlayback ) {
73 	if ( cgvm->isLegacy ) {
74 		VM_Call( cgvm, CG_DRAW_ACTIVE_FRAME, serverTime, stereoView, demoPlayback );
75 		return;
76 	}
77 	VMSwap v( cgvm );
78 
79 	cge->DrawActiveFrame( serverTime, stereoView, demoPlayback );
80 }
81 
CGVM_CrosshairPlayer(void)82 int CGVM_CrosshairPlayer( void ) {
83 	if ( cgvm->isLegacy ) {
84 		return VM_Call( cgvm, CG_CROSSHAIR_PLAYER );
85 	}
86 	VMSwap v( cgvm );
87 
88 	return cge->CrosshairPlayer();
89 }
90 
CGVM_LastAttacker(void)91 int CGVM_LastAttacker( void ) {
92 	if ( cgvm->isLegacy ) {
93 		return VM_Call( cgvm, CG_LAST_ATTACKER );
94 	}
95 	VMSwap v( cgvm );
96 
97 	return cge->LastAttacker();
98 }
99 
CGVM_KeyEvent(int key,qboolean down)100 void CGVM_KeyEvent( int key, qboolean down ) {
101 	if ( cgvm->isLegacy ) {
102 		VM_Call( cgvm, CG_KEY_EVENT, key, down );
103 		return;
104 	}
105 	VMSwap v( cgvm );
106 
107 	cge->KeyEvent( key, down );
108 }
109 
CGVM_MouseEvent(int x,int y)110 void CGVM_MouseEvent( int x, int y ) {
111 	if ( cgvm->isLegacy ) {
112 		VM_Call( cgvm, CG_MOUSE_EVENT, x, y );
113 		return;
114 	}
115 	VMSwap v( cgvm );
116 
117 	cge->MouseEvent( x, y );
118 }
119 
CGVM_EventHandling(int type)120 void CGVM_EventHandling( int type ) {
121 	if ( cgvm->isLegacy ) {
122 		VM_Call( cgvm, CG_EVENT_HANDLING, type );
123 		return;
124 	}
125 	VMSwap v( cgvm );
126 
127 	cge->EventHandling( type );
128 }
129 
CGVM_PointContents(void)130 int CGVM_PointContents( void ) {
131 	if ( cgvm->isLegacy ) {
132 		return VM_Call( cgvm, CG_POINT_CONTENTS );
133 	}
134 	VMSwap v( cgvm );
135 
136 	return cge->PointContents();
137 }
138 
CGVM_GetLerpOrigin(void)139 void CGVM_GetLerpOrigin( void ) {
140 	if ( cgvm->isLegacy ) {
141 		VM_Call( cgvm, CG_GET_LERP_ORIGIN );
142 		return;
143 	}
144 	VMSwap v( cgvm );
145 
146 	cge->GetLerpOrigin();
147 }
148 
CGVM_GetLerpData(void)149 void CGVM_GetLerpData( void ) {
150 	if ( cgvm->isLegacy ) {
151 		VM_Call( cgvm, CG_GET_LERP_DATA );
152 		return;
153 	}
154 	VMSwap v( cgvm );
155 
156 	cge->GetLerpData();
157 }
158 
CGVM_Trace(void)159 void CGVM_Trace( void ) {
160 	if ( cgvm->isLegacy ) {
161 		VM_Call( cgvm, CG_TRACE );
162 		return;
163 	}
164 	VMSwap v( cgvm );
165 
166 	cge->Trace();
167 }
168 
CGVM_G2Trace(void)169 void CGVM_G2Trace( void ) {
170 	if ( cgvm->isLegacy ) {
171 		VM_Call( cgvm, CG_G2TRACE );
172 		return;
173 	}
174 	VMSwap v( cgvm );
175 
176 	cge->G2Trace();
177 }
178 
CGVM_G2Mark(void)179 void CGVM_G2Mark( void ) {
180 	if ( cgvm->isLegacy ) {
181 		VM_Call( cgvm, CG_G2MARK );
182 		return;
183 	}
184 	VMSwap v( cgvm );
185 
186 	cge->G2Mark();
187 }
188 
CGVM_RagCallback(int callType)189 int CGVM_RagCallback( int callType ) {
190 	if ( cgvm->isLegacy ) {
191 		return VM_Call( cgvm, CG_RAG_CALLBACK, callType );
192 	}
193 	VMSwap v( cgvm );
194 
195 	return cge->RagCallback( callType );
196 }
197 
CGVM_IncomingConsoleCommand(void)198 qboolean CGVM_IncomingConsoleCommand( void ) {
199 	if ( cgvm->isLegacy ) {
200 		return (qboolean)VM_Call( cgvm, CG_INCOMING_CONSOLE_COMMAND );
201 	}
202 	VMSwap v( cgvm );
203 
204 	return cge->IncomingConsoleCommand();
205 }
206 
CGVM_NoUseableForce(void)207 qboolean CGVM_NoUseableForce( void ) {
208 	if ( cgvm->isLegacy ) {
209 		return (qboolean)VM_Call( cgvm, CG_GET_USEABLE_FORCE );
210 	}
211 	VMSwap v( cgvm );
212 
213 	return cge->NoUseableForce();
214 }
215 
CGVM_GetOrigin(int entID,vec3_t out)216 void CGVM_GetOrigin( int entID, vec3_t out ) {
217 	if ( cgvm->isLegacy ) {
218 		VM_Call( cgvm, CG_GET_ORIGIN, entID, reinterpret_cast< intptr_t >( out ) );
219 		return;
220 	}
221 	VMSwap v( cgvm );
222 
223 	cge->GetOrigin( entID, out );
224 }
225 
CGVM_GetAngles(int entID,vec3_t out)226 void CGVM_GetAngles( int entID, vec3_t out ) {
227 	if ( cgvm->isLegacy ) {
228 		VM_Call( cgvm, CG_GET_ANGLES, entID, reinterpret_cast< intptr_t >( out ) );
229 		return;
230 	}
231 	VMSwap v( cgvm );
232 
233 	cge->GetAngles( entID, out );
234 }
235 
CGVM_GetOriginTrajectory(int entID)236 trajectory_t *CGVM_GetOriginTrajectory( int entID ) {
237 	if ( cgvm->isLegacy ) {
238 		return (trajectory_t *)VM_Call( cgvm, CG_GET_ORIGIN_TRAJECTORY, entID );
239 	}
240 	VMSwap v( cgvm );
241 
242 	return cge->GetOriginTrajectory( entID );
243 }
244 
CGVM_GetAngleTrajectory(int entID)245 trajectory_t *CGVM_GetAngleTrajectory( int entID ) {
246 	if ( cgvm->isLegacy ) {
247 		return (trajectory_t *)VM_Call( cgvm, CG_GET_ANGLE_TRAJECTORY, entID );
248 	}
249 	VMSwap v( cgvm );
250 
251 	return cge->GetAngleTrajectory( entID );
252 }
253 
CGVM_ROFF_NotetrackCallback(int entID,const char * notetrack)254 void CGVM_ROFF_NotetrackCallback( int entID, const char *notetrack ) {
255 	if ( cgvm->isLegacy ) {
256 		VM_Call( cgvm, CG_ROFF_NOTETRACK_CALLBACK, entID, reinterpret_cast< intptr_t >( notetrack ) );
257 		return;
258 	}
259 	VMSwap v( cgvm );
260 
261 	cge->ROFF_NotetrackCallback( entID, notetrack );
262 }
263 
CGVM_MapChange(void)264 void CGVM_MapChange( void ) {
265 	if ( cgvm->isLegacy ) {
266 		VM_Call( cgvm, CG_MAP_CHANGE );
267 		return;
268 	}
269 	VMSwap v( cgvm );
270 
271 	cge->MapChange();
272 }
273 
CGVM_AutomapInput(void)274 void CGVM_AutomapInput( void ) {
275 	if ( cgvm->isLegacy ) {
276 		VM_Call( cgvm, CG_AUTOMAP_INPUT );
277 		return;
278 	}
279 	VMSwap v( cgvm );
280 
281 	cge->AutomapInput();
282 }
283 
CGVM_MiscEnt(void)284 void CGVM_MiscEnt( void ) {
285 	if ( cgvm->isLegacy ) {
286 		VM_Call( cgvm, CG_MISC_ENT );
287 		return;
288 	}
289 	VMSwap v( cgvm );
290 
291 	cge->MiscEnt();
292 }
293 
CGVM_CameraShake(void)294 void CGVM_CameraShake( void ) {
295 	if ( cgvm->isLegacy ) {
296 		VM_Call( cgvm, CG_FX_CAMERASHAKE );
297 		return;
298 	}
299 	VMSwap v( cgvm );
300 
301 	cge->CameraShake();
302 }
303 
304 
305 //
306 // cgame syscalls
307 //	only used by legacy mods!
308 //
309 
310 extern int CL_GetValueForHidden( const char *s ); //cl_parse.cpp
311 extern qboolean cl_bUseFighterPitch; //cl_input.cpp
312 int CM_LoadSubBSP( const char *name, qboolean clientload ); //cm_load.cpp
313 void FX_FeedTrail( effectTrailArgStruct_t *a ); //FxPrimitives.cpp
314 
315 // wrappers and such
316 
CL_AddCgameCommand(const char * cmdName)317 static void CL_AddCgameCommand( const char *cmdName ) {
318 	Cmd_AddCommand( cmdName, NULL );
319 }
320 
CL_CM_LoadMap(const char * mapname,qboolean subBSP)321 static void CL_CM_LoadMap( const char *mapname, qboolean subBSP ) {
322 	if ( subBSP )	CM_LoadSubBSP( va( "maps/%s.bsp", mapname+1 ), qfalse );
323 	else			CM_LoadMap( mapname, qtrue, NULL );
324 }
325 
CL_GetGlconfig(glconfig_t * glconfig)326 static void CL_GetGlconfig( glconfig_t *glconfig ) {
327 	*glconfig = cls.glconfig;
328 }
329 
CL_GetGameState(gameState_t * gs)330 static void CL_GetGameState( gameState_t *gs ) {
331 	*gs = cl.gameState;
332 }
333 
RegisterSharedMemory(char * memory)334 static void RegisterSharedMemory( char *memory ) {
335 	cl.mSharedMemory = memory;
336 }
337 
CL_Milliseconds(void)338 static int CL_Milliseconds( void ) {
339 	return Sys_Milliseconds();
340 }
341 
CL_AddReliableCommand2(const char * cmd)342 static void CL_AddReliableCommand2( const char *cmd ) {
343 	CL_AddReliableCommand( cmd, qfalse );
344 }
345 
CL_CM_RegisterTerrain(const char * config)346 static int CL_CM_RegisterTerrain( const char *config ) {
347 	return 0;
348 }
349 
350 extern int s_entityWavVol[MAX_GENTITIES];
CL_S_GetVoiceVolume(int entID)351 static int CL_S_GetVoiceVolume( int entID ) {
352 	return s_entityWavVol[entID];
353 }
354 
CL_S_Shutup(qboolean shutup)355 static void CL_S_Shutup( qboolean shutup ) {
356 	s_shutUp = shutup;
357 }
358 
CL_GetCurrentCmdNumber(void)359 static int CL_GetCurrentCmdNumber( void ) {
360 	return cl.cmdNumber;
361 }
362 
_CL_SetUserCmdValue(int stateValue,float sensitivityScale,float mPitchOverride,float mYawOverride,float mSensitivityOverride,int fpSel,int invenSel,qboolean fighterControls)363 static void _CL_SetUserCmdValue( int stateValue, float sensitivityScale, float mPitchOverride, float mYawOverride, float mSensitivityOverride, int fpSel, int invenSel, qboolean fighterControls ) {
364 	cl_bUseFighterPitch = fighterControls;
365 	CL_SetUserCmdValue( stateValue, sensitivityScale, mPitchOverride, mYawOverride, mSensitivityOverride, fpSel, invenSel );
366 }
367 
CL_OpenUIMenu(int menuID)368 static void CL_OpenUIMenu( int menuID ) {
369 	UIVM_SetActiveMenu( (uiMenuCommand_t)menuID );
370 }
371 
CGFX_AddLine(vec3_t start,vec3_t end,float size1,float size2,float sizeParm,float alpha1,float alpha2,float alphaParm,vec3_t sRGB,vec3_t eRGB,float rgbParm,int killTime,qhandle_t shader,int flags)372 static void CGFX_AddLine( vec3_t start, vec3_t end, float size1, float size2, float sizeParm, float alpha1, float alpha2, float alphaParm, vec3_t sRGB, vec3_t eRGB, float rgbParm, int killTime, qhandle_t shader, int flags ) {
373 	FX_AddLine( start, end, size1, size2, sizeParm, alpha1, alpha2, alphaParm, sRGB, eRGB, rgbParm, killTime, shader, flags );
374 }
375 
CGFX_AddPoly(addpolyArgStruct_t * p)376 static void CGFX_AddPoly( addpolyArgStruct_t *p ) {
377 	FX_AddPoly( p->p, p->ev, p->numVerts, p->vel, p->accel, p->alpha1, p->alpha2, p->alphaParm, p->rgb1, p->rgb2, p->rgbParm, p->rotationDelta, p->bounce, p->motionDelay, p->killTime, p->shader, p->flags );
378 }
379 
CGFX_AddBezier(addbezierArgStruct_t * b)380 static void CGFX_AddBezier( addbezierArgStruct_t *b ) {
381 	FX_AddBezier( b->start, b->end, b->control1, b->control1Vel, b->control2, b->control2Vel, b->size1, b->size2, b->sizeParm, b->alpha1, b->alpha2, b->alphaParm, b->sRGB, b->eRGB, b->rgbParm, b->killTime, b->shader, b->flags );
382 }
383 
CGFX_AddPrimitive(effectTrailArgStruct_t * e)384 static void CGFX_AddPrimitive( effectTrailArgStruct_t *e ) {
385 	FX_FeedTrail( e );
386 }
387 
CGFX_AddSprite(addspriteArgStruct_t * s)388 static void CGFX_AddSprite( addspriteArgStruct_t *s ) {
389 	vec3_t rgb = { 1.0f, 1.0f, 1.0f };
390 	FX_AddParticle( s->origin, s->vel, s->accel, s->scale, s->dscale, 0, s->sAlpha, s->eAlpha, 0, rgb, rgb, 0, s->rotation, 0, vec3_origin, vec3_origin, s->bounce, 0, 0, s->life, s->shader, s->flags );
391 }
392 
CGFX_AddElectricity(addElectricityArgStruct_t * p)393 static void CGFX_AddElectricity( addElectricityArgStruct_t *p ) {
394 	FX_AddElectricity( p->start, p->end, p->size1, p->size2, p->sizeParm, p->alpha1, p->alpha2, p->alphaParm, p->sRGB, p->eRGB, p->rgbParm, p->chaos, p->killTime, p->shader, p->flags );
395 }
396 
CL_ROFF_Clean(void)397 static qboolean CL_ROFF_Clean( void ) {
398 	return theROFFSystem.Clean( qtrue );
399 }
400 
CL_ROFF_UpdateEntities(void)401 static void CL_ROFF_UpdateEntities( void ) {
402 	theROFFSystem.UpdateEntities( qtrue );
403 }
404 
CL_ROFF_Cache(char * file)405 static int CL_ROFF_Cache( char *file ) {
406 	return theROFFSystem.Cache( file, qtrue );
407 }
408 
CL_ROFF_Play(int entID,int roffID,qboolean doTranslation)409 static qboolean CL_ROFF_Play( int entID, int roffID, qboolean doTranslation ) {
410 	return theROFFSystem.Play( entID, roffID, doTranslation, qtrue );
411 }
412 
CL_ROFF_Purge_Ent(int entID)413 static qboolean CL_ROFF_Purge_Ent( int entID ) {
414 	return theROFFSystem.PurgeEnt( entID, qtrue );
415 }
416 
CL_GetCurrentSnapshotNumber(int * snapshotNumber,int * serverTime)417 static void CL_GetCurrentSnapshotNumber( int *snapshotNumber, int *serverTime ) {
418 	*snapshotNumber = cl.snap.messageNum;
419 	*serverTime = cl.snap.serverTime;
420 }
421 
CL_SetClientForceAngle(int time,vec3_t angle)422 static void CL_SetClientForceAngle( int time, vec3_t angle ) {
423 	cl.cgameViewAngleForceTime = time;
424 	VectorCopy(angle, cl.cgameViewAngleForce);
425 }
426 
CL_PrecisionTimerStart(void ** p)427 static void CL_PrecisionTimerStart( void **p ) {
428 	timing_c *newTimer = new timing_c; //create the new timer
429 	*p = newTimer; //assign the pointer within the pointer to point at the mem addr of our new timer
430 	newTimer->Start(); //start the timer
431 }
432 
CL_PrecisionTimerEnd(void * p)433 static int CL_PrecisionTimerEnd( void *p ) {
434 	int r = 0;
435 	timing_c *timer = (timing_c *)p; //this is the pointer we assigned in start, so we can directly cast it back
436 	r = timer->End(); //get the result
437 	delete timer; //delete the timer since we're done with it
438 	return r; //return the result
439 }
440 
CL_RMG_Init(int,const char *)441 static void CL_RMG_Init( int /* terrainID */, const char * /* terrainInfo */ ) { }
442 
CGFX_PlayBoltedEffectID(int id,vec3_t org,void * ghoul2,const int boltNum,const int entNum,const int modelNum,int iLooptime,qboolean isRelative)443 static qboolean CGFX_PlayBoltedEffectID( int id, vec3_t org, void *ghoul2, const int boltNum, const int entNum, const int modelNum, int iLooptime, qboolean isRelative ) {
444 	if ( !ghoul2 ) return qfalse;
445 
446 	CGhoul2Info_v &g2 = *((CGhoul2Info_v *)ghoul2);
447 	int boltInfo=0;
448 	if ( re->G2API_AttachEnt( &boltInfo, g2, modelNum, boltNum, entNum, modelNum ) )
449 	{
450 		FX_PlayBoltedEffectID(id, org, boltInfo, &g2, iLooptime, isRelative );
451 		return qtrue;
452 	}
453 	return qfalse;
454 }
455 
CL_SE_GetStringTextString(const char * text,char * buffer,int bufferLength)456 static qboolean CL_SE_GetStringTextString( const char *text, char *buffer, int bufferLength ) {
457 	const char *str;
458 
459 	assert( text && buffer );
460 
461 	str = SE_GetString( text );
462 
463 	if ( str[0] ) {
464 		Q_strncpyz( buffer, str, bufferLength );
465 		return qtrue;
466 	}
467 
468 	Com_sprintf( buffer, bufferLength, "??%s", str );
469 	return qfalse;
470 }
471 
CL_G2API_ListModelSurfaces(void * ghlInfo)472 static void CL_G2API_ListModelSurfaces( void *ghlInfo ) {
473 	re->G2API_ListSurfaces( (CGhoul2Info *)ghlInfo );
474 }
475 
CL_G2API_ListModelBones(void * ghlInfo,int frame)476 static void CL_G2API_ListModelBones( void *ghlInfo, int frame ) {
477 	re->G2API_ListBones( (CGhoul2Info *)ghlInfo, frame );
478 }
479 
CL_G2API_SetGhoul2ModelIndexes(void * ghoul2,qhandle_t * modelList,qhandle_t * skinList)480 static void CL_G2API_SetGhoul2ModelIndexes( void *ghoul2, qhandle_t *modelList, qhandle_t *skinList ) {
481 	if ( !ghoul2 ) return;
482 	re->G2API_SetGhoul2ModelIndexes( *((CGhoul2Info_v *)ghoul2), modelList, skinList );
483 }
484 
CL_G2API_HaveWeGhoul2Models(void * ghoul2)485 static qboolean CL_G2API_HaveWeGhoul2Models( void *ghoul2) {
486 	if ( !ghoul2 ) return qfalse;
487 	return re->G2API_HaveWeGhoul2Models( *((CGhoul2Info_v *)ghoul2) );
488 }
489 
CL_G2API_GetBoltMatrix(void * ghoul2,const int modelIndex,const int boltIndex,mdxaBone_t * matrix,const vec3_t angles,const vec3_t position,const int frameNum,qhandle_t * modelList,vec3_t scale)490 static qboolean CL_G2API_GetBoltMatrix( void *ghoul2, const int modelIndex, const int boltIndex, mdxaBone_t *matrix, const vec3_t angles, const vec3_t position, const int frameNum, qhandle_t *modelList, vec3_t scale ) {
491 	if ( !ghoul2 ) return qfalse;
492 	return re->G2API_GetBoltMatrix( *((CGhoul2Info_v *)ghoul2), modelIndex, boltIndex, matrix, angles, position, frameNum, modelList, scale );
493 }
494 
CL_G2API_GetBoltMatrix_NoReconstruct(void * ghoul2,const int modelIndex,const int boltIndex,mdxaBone_t * matrix,const vec3_t angles,const vec3_t position,const int frameNum,qhandle_t * modelList,vec3_t scale)495 static qboolean CL_G2API_GetBoltMatrix_NoReconstruct( void *ghoul2, const int modelIndex, const int boltIndex, mdxaBone_t *matrix, const vec3_t angles, const vec3_t position, const int frameNum, qhandle_t *modelList, vec3_t scale ) {
496 	if ( !ghoul2 ) return qfalse;
497 	re->G2API_BoltMatrixReconstruction( qfalse );
498 	return re->G2API_GetBoltMatrix( *((CGhoul2Info_v *)ghoul2), modelIndex, boltIndex, matrix, angles, position, frameNum, modelList, scale );
499 }
500 
CL_G2API_GetBoltMatrix_NoRecNoRot(void * ghoul2,const int modelIndex,const int boltIndex,mdxaBone_t * matrix,const vec3_t angles,const vec3_t position,const int frameNum,qhandle_t * modelList,vec3_t scale)501 static qboolean CL_G2API_GetBoltMatrix_NoRecNoRot( void *ghoul2, const int modelIndex, const int boltIndex, mdxaBone_t *matrix, const vec3_t angles, const vec3_t position, const int frameNum, qhandle_t *modelList, vec3_t scale ) {
502 	if ( !ghoul2 ) return qfalse;
503 	// Intentionally not setting bolt matrix reconstruction state per original code comments
504 	re->G2API_BoltMatrixSPMethod( qtrue );
505 	return re->G2API_GetBoltMatrix( *((CGhoul2Info_v *)ghoul2), modelIndex, boltIndex, matrix, angles, position, frameNum, modelList, scale );
506 }
507 
CL_G2API_InitGhoul2Model(void ** ghoul2Ptr,const char * fileName,int modelIndex,qhandle_t customSkin,qhandle_t customShader,int modelFlags,int lodBias)508 static int CL_G2API_InitGhoul2Model( void **ghoul2Ptr, const char *fileName, int modelIndex, qhandle_t customSkin, qhandle_t customShader, int modelFlags, int lodBias ) {
509 #ifdef _FULL_G2_LEAK_CHECKING
510 		g_G2AllocServer = 0;
511 #endif
512 	return re->G2API_InitGhoul2Model( (CGhoul2Info_v **)ghoul2Ptr, fileName, modelIndex, customSkin, customShader, modelFlags, lodBias );
513 }
514 
CL_G2API_SetSkin(void * ghoul2,int modelIndex,qhandle_t customSkin,qhandle_t renderSkin)515 static qboolean CL_G2API_SetSkin( void *ghoul2, int modelIndex, qhandle_t customSkin, qhandle_t renderSkin ) {
516 	if ( !ghoul2 ) return qfalse;
517 	CGhoul2Info_v &g2 = *((CGhoul2Info_v *)ghoul2);
518 	return re->G2API_SetSkin( g2, modelIndex, customSkin, renderSkin );
519 }
520 
CL_G2API_CollisionDetect(CollisionRecord_t * collRecMap,void * ghoul2,const vec3_t angles,const vec3_t position,int frameNumber,int entNum,vec3_t rayStart,vec3_t rayEnd,vec3_t scale,int traceFlags,int useLod,float fRadius)521 static void CL_G2API_CollisionDetect( CollisionRecord_t *collRecMap, void* ghoul2, const vec3_t angles, const vec3_t position, int frameNumber, int entNum, vec3_t rayStart, vec3_t rayEnd, vec3_t scale, int traceFlags, int useLod, float fRadius ) {
522 	if ( !ghoul2 ) return;
523 	re->G2API_CollisionDetect( collRecMap, *((CGhoul2Info_v *)ghoul2), angles, position, frameNumber, entNum, rayStart, rayEnd, scale, G2VertSpaceClient, traceFlags, useLod, fRadius );
524 }
525 
CL_G2API_CollisionDetectCache(CollisionRecord_t * collRecMap,void * ghoul2,const vec3_t angles,const vec3_t position,int frameNumber,int entNum,vec3_t rayStart,vec3_t rayEnd,vec3_t scale,int traceFlags,int useLod,float fRadius)526 static void CL_G2API_CollisionDetectCache( CollisionRecord_t *collRecMap, void* ghoul2, const vec3_t angles, const vec3_t position, int frameNumber, int entNum, vec3_t rayStart, vec3_t rayEnd, vec3_t scale, int traceFlags, int useLod, float fRadius ) {
527 	if ( !ghoul2 ) return;
528 	re->G2API_CollisionDetectCache( collRecMap, *((CGhoul2Info_v *)ghoul2), angles, position, frameNumber, entNum, rayStart, rayEnd, scale, G2VertSpaceClient, traceFlags, useLod, fRadius );
529 }
530 
CL_G2API_CleanGhoul2Models(void ** ghoul2Ptr)531 static void CL_G2API_CleanGhoul2Models( void **ghoul2Ptr ) {
532 #ifdef _FULL_G2_LEAK_CHECKING
533 		g_G2AllocServer = 0;
534 #endif
535 	re->G2API_CleanGhoul2Models( (CGhoul2Info_v **)ghoul2Ptr );
536 }
537 
CL_G2API_SetBoneAngles(void * ghoul2,int modelIndex,const char * boneName,const vec3_t angles,const int flags,const int up,const int right,const int forward,qhandle_t * modelList,int blendTime,int currentTime)538 static qboolean CL_G2API_SetBoneAngles( void *ghoul2, int modelIndex, const char *boneName, const vec3_t angles, const int flags, const int up, const int right, const int forward, qhandle_t *modelList, int blendTime , int currentTime ) {
539 	if ( !ghoul2 ) return qfalse;
540 	return re->G2API_SetBoneAngles( *((CGhoul2Info_v *)ghoul2), modelIndex, boneName, angles, flags, (const Eorientations)up, (const Eorientations)right, (const Eorientations)forward, modelList, blendTime , currentTime );
541 }
542 
CL_G2API_SetBoneAnim(void * ghoul2,const int modelIndex,const char * boneName,const int startFrame,const int endFrame,const int flags,const float animSpeed,const int currentTime,const float setFrame,const int blendTime)543 static qboolean CL_G2API_SetBoneAnim( void *ghoul2, const int modelIndex, const char *boneName, const int startFrame, const int endFrame, const int flags, const float animSpeed, const int currentTime, const float setFrame, const int blendTime ) {
544 	if ( !ghoul2 ) return qfalse;
545 	return re->G2API_SetBoneAnim( *((CGhoul2Info_v *)ghoul2), modelIndex, boneName, startFrame, endFrame, flags, animSpeed, currentTime, setFrame, blendTime );
546 }
547 
CL_G2API_GetBoneAnim(void * ghoul2,const char * boneName,const int currentTime,float * currentFrame,int * startFrame,int * endFrame,int * flags,float * animSpeed,int * modelList,const int modelIndex)548 static qboolean CL_G2API_GetBoneAnim( void *ghoul2, const char *boneName, const int currentTime, float *currentFrame, int *startFrame, int *endFrame, int *flags, float *animSpeed, int *modelList, const int modelIndex ) {
549 	if ( !ghoul2 ) return qfalse;
550 	CGhoul2Info_v &g2 = *((CGhoul2Info_v *)ghoul2);
551 	return re->G2API_GetBoneAnim( g2, modelIndex, boneName, currentTime, currentFrame, startFrame, endFrame, flags, animSpeed, modelList );
552 }
553 
CL_G2API_GetBoneFrame(void * ghoul2,const char * boneName,const int currentTime,float * currentFrame,int * modelList,const int modelIndex)554 static qboolean CL_G2API_GetBoneFrame( void *ghoul2, const char *boneName, const int currentTime, float *currentFrame, int *modelList, const int modelIndex ) {
555 	if ( !ghoul2 ) return qfalse;
556 	CGhoul2Info_v &g2 = *((CGhoul2Info_v *)ghoul2);
557 	int iDontCare1 = 0, iDontCare2 = 0, iDontCare3 = 0;
558 	float fDontCare1 = 0;
559 
560 	return re->G2API_GetBoneAnim(g2, modelIndex, boneName, currentTime, currentFrame, &iDontCare1, &iDontCare2, &iDontCare3, &fDontCare1, modelList);
561 }
562 
CL_G2API_GetGLAName(void * ghoul2,int modelIndex,char * fillBuf)563 static void CL_G2API_GetGLAName( void *ghoul2, int modelIndex, char *fillBuf ) {
564 	if ( !ghoul2 )
565 	{
566 		fillBuf[0] = '\0';
567 		return;
568 	}
569 
570 	char *tmp = re->G2API_GetGLAName( *((CGhoul2Info_v *)ghoul2), modelIndex );
571 	if ( tmp )
572 		strcpy( fillBuf, tmp );
573 	else
574 		fillBuf[0] = '\0';
575 }
576 
CL_G2API_CopyGhoul2Instance(void * g2From,void * g2To,int modelIndex)577 static int CL_G2API_CopyGhoul2Instance( void *g2From, void *g2To, int modelIndex ) {
578 	if ( !g2From || !g2To ) return 0;
579 
580 	return re->G2API_CopyGhoul2Instance( *((CGhoul2Info_v *)g2From), *((CGhoul2Info_v *)g2To), modelIndex );
581 }
582 
CL_G2API_CopySpecificGhoul2Model(void * g2From,int modelFrom,void * g2To,int modelTo)583 static void CL_G2API_CopySpecificGhoul2Model( void *g2From, int modelFrom, void *g2To, int modelTo ) {
584 	if ( !g2From || !g2To) return;
585 	re->G2API_CopySpecificG2Model( *((CGhoul2Info_v *)g2From), modelFrom, *((CGhoul2Info_v *)g2To), modelTo );
586 }
587 
CL_G2API_DuplicateGhoul2Instance(void * g2From,void ** g2To)588 static void CL_G2API_DuplicateGhoul2Instance( void *g2From, void **g2To ) {
589 #ifdef _FULL_G2_LEAK_CHECKING
590 		g_G2AllocServer = 0;
591 #endif
592 	if ( !g2From || !g2To ) return;
593 	re->G2API_DuplicateGhoul2Instance( *((CGhoul2Info_v *)g2From), (CGhoul2Info_v **)g2To );
594 }
595 
CL_G2API_HasGhoul2ModelOnIndex(void * ghlInfo,int modelIndex)596 static qboolean CL_G2API_HasGhoul2ModelOnIndex( void *ghlInfo, int modelIndex ) {
597 	return re->G2API_HasGhoul2ModelOnIndex( (CGhoul2Info_v **)ghlInfo, modelIndex );
598 }
599 
CL_G2API_RemoveGhoul2Model(void * ghlInfo,int modelIndex)600 static qboolean CL_G2API_RemoveGhoul2Model( void *ghlInfo, int modelIndex ) {
601 #ifdef _FULL_G2_LEAK_CHECKING
602 		g_G2AllocServer = 0;
603 #endif
604 	return re->G2API_RemoveGhoul2Model( (CGhoul2Info_v **)ghlInfo, modelIndex );
605 }
606 
CL_G2API_SkinlessModel(void * ghlInfo,int modelIndex)607 static qboolean CL_G2API_SkinlessModel( void *ghlInfo, int modelIndex ) {
608 	if ( !ghlInfo ) return qfalse;
609 
610 	CGhoul2Info_v &g2 = *((CGhoul2Info_v *)ghlInfo);
611 	return re->G2API_SkinlessModel( g2, modelIndex );
612 }
613 
CL_G2API_GetNumGoreMarks(void * ghlInfo,int modelIndex)614 static int CL_G2API_GetNumGoreMarks( void *ghlInfo, int modelIndex ) {
615 #ifdef _G2_GORE
616 	if ( !ghlInfo ) return 0;
617 	CGhoul2Info_v &g2 = *((CGhoul2Info_v *)ghlInfo);
618 	return re->G2API_GetNumGoreMarks( g2, modelIndex );
619 #else
620 	return 0;
621 #endif
622 }
623 
CL_G2API_AddSkinGore(void * ghlInfo,SSkinGoreData * gore)624 static void CL_G2API_AddSkinGore( void *ghlInfo, SSkinGoreData *gore ) {
625 #ifdef _G2_GORE
626 	if ( !ghlInfo ) return;
627 	re->G2API_AddSkinGore( *((CGhoul2Info_v *)ghlInfo), *(SSkinGoreData *)gore );
628 #endif
629 }
630 
CL_G2API_ClearSkinGore(void * ghlInfo)631 static void CL_G2API_ClearSkinGore( void *ghlInfo ) {
632 #ifdef _G2_GORE
633 	if ( !ghlInfo ) return;
634 	re->G2API_ClearSkinGore( *((CGhoul2Info_v *)ghlInfo) );
635 #endif
636 }
637 
CL_G2API_Ghoul2Size(void * ghlInfo)638 static int CL_G2API_Ghoul2Size( void *ghlInfo ) {
639 	if ( !ghlInfo ) return 0;
640 	return re->G2API_Ghoul2Size( *((CGhoul2Info_v *)ghlInfo) );
641 }
642 
CL_G2API_AddBolt(void * ghoul2,int modelIndex,const char * boneName)643 static int CL_G2API_AddBolt( void *ghoul2, int modelIndex, const char *boneName ) {
644 	if ( !ghoul2 ) return -1;
645 	return re->G2API_AddBolt( *((CGhoul2Info_v *)ghoul2), modelIndex, boneName );
646 }
647 
CL_G2API_AttachEnt(int * boltInfo,void * ghlInfoTo,int toBoltIndex,int entNum,int toModelNum)648 static qboolean CL_G2API_AttachEnt( int *boltInfo, void *ghlInfoTo, int toBoltIndex, int entNum, int toModelNum ) {
649 	if ( !ghlInfoTo ) return qfalse;
650 	CGhoul2Info_v &g2 = *((CGhoul2Info_v *)ghlInfoTo);
651 	return re->G2API_AttachEnt( boltInfo, g2, 0, toBoltIndex, entNum, toModelNum );
652 }
653 
CL_G2API_SetBoltInfo(void * ghoul2,int modelIndex,int boltInfo)654 static void CL_G2API_SetBoltInfo( void *ghoul2, int modelIndex, int boltInfo ) {
655 	if ( !ghoul2 ) return;
656 	re->G2API_SetBoltInfo( *((CGhoul2Info_v *)ghoul2), modelIndex, boltInfo );
657 }
658 
CL_G2API_SetRootSurface(void * ghoul2,const int modelIndex,const char * surfaceName)659 static qboolean CL_G2API_SetRootSurface( void *ghoul2, const int modelIndex, const char *surfaceName ) {
660 	if ( !ghoul2 ) return qfalse;
661 	return re->G2API_SetRootSurface( *((CGhoul2Info_v *)ghoul2), modelIndex, surfaceName );
662 }
663 
CL_G2API_SetSurfaceOnOff(void * ghoul2,const char * surfaceName,const int flags)664 static qboolean CL_G2API_SetSurfaceOnOff( void *ghoul2, const char *surfaceName, const int flags ) {
665 	if ( !ghoul2 ) return qfalse;
666 	return re->G2API_SetSurfaceOnOff( *((CGhoul2Info_v *)ghoul2), surfaceName, flags );
667 }
668 
CL_G2API_SetNewOrigin(void * ghoul2,const int boltIndex)669 static qboolean CL_G2API_SetNewOrigin( void *ghoul2, const int boltIndex ) {
670 	if ( !ghoul2 ) return qfalse;
671 	return re->G2API_SetNewOrigin( *((CGhoul2Info_v *)ghoul2), boltIndex );
672 }
673 
CL_G2API_DoesBoneExist(void * ghoul2,int modelIndex,const char * boneName)674 static qboolean CL_G2API_DoesBoneExist( void *ghoul2, int modelIndex, const char *boneName ) {
675 	if ( !ghoul2 ) return qfalse;
676 	CGhoul2Info_v &g2 = *((CGhoul2Info_v *)ghoul2);
677 	return re->G2API_DoesBoneExist( g2, modelIndex, boneName );
678 }
679 
CL_G2API_GetSurfaceRenderStatus(void * ghoul2,const int modelIndex,const char * surfaceName)680 static int CL_G2API_GetSurfaceRenderStatus( void *ghoul2, const int modelIndex, const char *surfaceName ) {
681 	if ( !ghoul2 ) return -1;
682 	CGhoul2Info_v &g2 = *((CGhoul2Info_v *)ghoul2);
683 	return re->G2API_GetSurfaceRenderStatus( g2, modelIndex, surfaceName );
684 }
685 
CL_G2API_GetTime(void)686 static int CL_G2API_GetTime( void ) {
687 	return re->G2API_GetTime( 0 );
688 }
689 
CL_G2API_SetTime(int time,int clock)690 static void CL_G2API_SetTime( int time, int clock ) {
691 	re->G2API_SetTime( time, clock );
692 }
693 
CL_G2API_AbsurdSmoothing(void * ghoul2,qboolean status)694 static void CL_G2API_AbsurdSmoothing( void *ghoul2, qboolean status ) {
695 	if ( !ghoul2 ) return;
696 	CGhoul2Info_v &g2 = *((CGhoul2Info_v *)ghoul2);
697 	re->G2API_AbsurdSmoothing( g2, status );
698 }
699 
CL_G2API_SetRagDoll(void * ghoul2,sharedRagDollParams_t * params)700 static void CL_G2API_SetRagDoll( void *ghoul2, sharedRagDollParams_t *params ) {
701 	if ( !ghoul2 ) return;
702 
703 	CRagDollParams rdParams;
704 	if ( !params ) {
705 		re->G2API_ResetRagDoll( *((CGhoul2Info_v *)ghoul2) );
706 		return;
707 	}
708 
709 	VectorCopy( params->angles, rdParams.angles );
710 	VectorCopy( params->position, rdParams.position );
711 	VectorCopy( params->scale, rdParams.scale );
712 	VectorCopy( params->pelvisAnglesOffset, rdParams.pelvisAnglesOffset );
713 	VectorCopy( params->pelvisPositionOffset, rdParams.pelvisPositionOffset );
714 
715 	rdParams.fImpactStrength = params->fImpactStrength;
716 	rdParams.fShotStrength = params->fShotStrength;
717 	rdParams.me = params->me;
718 
719 	rdParams.startFrame = params->startFrame;
720 	rdParams.endFrame = params->endFrame;
721 
722 	rdParams.collisionType = params->collisionType;
723 	rdParams.CallRagDollBegin = params->CallRagDollBegin;
724 
725 	rdParams.RagPhase = (CRagDollParams::ERagPhase)params->RagPhase;
726 	rdParams.effectorsToTurnOff = (CRagDollParams::ERagEffector)params->effectorsToTurnOff;
727 
728 	re->G2API_SetRagDoll( *((CGhoul2Info_v *)ghoul2), &rdParams );
729 }
730 
CL_G2API_AnimateG2Models(void * ghoul2,int time,sharedRagDollUpdateParams_t * params)731 static void CL_G2API_AnimateG2Models( void *ghoul2, int time, sharedRagDollUpdateParams_t *params ) {
732 	if ( !ghoul2 ) return;
733 	if ( !params ) return;
734 
735 	CRagDollUpdateParams rduParams;
736 	VectorCopy( params->angles, rduParams.angles );
737 	VectorCopy( params->position, rduParams.position );
738 	VectorCopy( params->scale, rduParams.scale );
739 	VectorCopy( params->velocity, rduParams.velocity );
740 
741 	rduParams.me = params->me;
742 	rduParams.settleFrame = params->settleFrame;
743 
744 	re->G2API_AnimateG2ModelsRag( *((CGhoul2Info_v *)ghoul2), time, &rduParams );
745 }
746 
CL_G2API_RagPCJConstraint(void * ghoul2,const char * boneName,vec3_t min,vec3_t max)747 static qboolean CL_G2API_RagPCJConstraint( void *ghoul2, const char *boneName, vec3_t min, vec3_t max ) {
748 	if ( !ghoul2 ) return qfalse;
749 	return re->G2API_RagPCJConstraint( *((CGhoul2Info_v *)ghoul2), boneName, min, max );
750 }
751 
CL_G2API_RagPCJGradientSpeed(void * ghoul2,const char * boneName,const float speed)752 static qboolean CL_G2API_RagPCJGradientSpeed( void *ghoul2, const char *boneName, const float speed ) {
753 	if ( !ghoul2 ) return qfalse;
754 	return re->G2API_RagPCJGradientSpeed( *((CGhoul2Info_v *)ghoul2), boneName, speed );
755 }
756 
CL_G2API_RagEffectorGoal(void * ghoul2,const char * boneName,vec3_t pos)757 static qboolean CL_G2API_RagEffectorGoal( void *ghoul2, const char *boneName, vec3_t pos ) {
758 	if ( !ghoul2 ) return qfalse;
759 	return re->G2API_RagEffectorGoal( *((CGhoul2Info_v *)ghoul2), boneName, pos );
760 }
761 
CL_G2API_GetRagBonePos(void * ghoul2,const char * boneName,vec3_t pos,vec3_t entAngles,vec3_t entPos,vec3_t entScale)762 static qboolean CL_G2API_GetRagBonePos( void *ghoul2, const char *boneName, vec3_t pos, vec3_t entAngles, vec3_t entPos, vec3_t entScale ) {
763 	if ( !ghoul2 ) return qfalse;
764 	return re->G2API_GetRagBonePos( *((CGhoul2Info_v *)ghoul2), boneName, pos, entAngles, entPos, entScale );
765 }
766 
CL_G2API_RagEffectorKick(void * ghoul2,const char * boneName,vec3_t velocity)767 static qboolean CL_G2API_RagEffectorKick( void *ghoul2, const char *boneName, vec3_t velocity ) {
768 	if ( !ghoul2 ) return qfalse;
769 	return re->G2API_RagEffectorKick( *((CGhoul2Info_v *)ghoul2), boneName, velocity );
770 }
771 
CL_G2API_RagForceSolve(void * ghoul2,qboolean force)772 static qboolean CL_G2API_RagForceSolve( void *ghoul2, qboolean force ) {
773 	if ( !ghoul2 ) return qfalse;
774 	return re->G2API_RagForceSolve( *((CGhoul2Info_v *)ghoul2), force );
775 }
776 
CL_G2API_SetBoneIKState(void * ghoul2,int time,const char * boneName,int ikState,sharedSetBoneIKStateParams_t * params)777 static qboolean CL_G2API_SetBoneIKState( void *ghoul2, int time, const char *boneName, int ikState, sharedSetBoneIKStateParams_t *params ) {
778 	if ( !ghoul2 ) return qfalse;
779 	return re->G2API_SetBoneIKState( *((CGhoul2Info_v *)ghoul2), time, boneName, ikState, params );
780 }
781 
CL_G2API_IKMove(void * ghoul2,int time,sharedIKMoveParams_t * params)782 static qboolean CL_G2API_IKMove( void *ghoul2, int time, sharedIKMoveParams_t *params ) {
783 	if ( !ghoul2 ) return qfalse;
784 	return re->G2API_IKMove( *((CGhoul2Info_v *)ghoul2), time, params );
785 }
786 
CL_G2API_RemoveBone(void * ghoul2,const char * boneName,int modelIndex)787 static qboolean CL_G2API_RemoveBone( void *ghoul2, const char *boneName, int modelIndex ) {
788 	if ( !ghoul2 ) return qfalse;
789 	CGhoul2Info_v &g2 = *((CGhoul2Info_v *)ghoul2);
790 	return re->G2API_RemoveBone( g2, modelIndex, boneName );
791 }
792 
CL_G2API_AttachInstanceToEntNum(void * ghoul2,int entityNum,qboolean server)793 static void CL_G2API_AttachInstanceToEntNum( void *ghoul2, int entityNum, qboolean server ) {
794 	if ( !ghoul2 ) return;
795 	re->G2API_AttachInstanceToEntNum( *((CGhoul2Info_v *)ghoul2), entityNum, server );
796 }
797 
CL_G2API_ClearAttachedInstance(int entityNum)798 static void CL_G2API_ClearAttachedInstance( int entityNum ) {
799 	re->G2API_ClearAttachedInstance( entityNum );
800 }
801 
CL_G2API_CleanEntAttachments(void)802 static void CL_G2API_CleanEntAttachments( void ) {
803 	re->G2API_CleanEntAttachments();
804 }
805 
CL_G2API_OverrideServer(void * serverInstance)806 static qboolean CL_G2API_OverrideServer( void *serverInstance ) {
807 	if ( !serverInstance ) return qfalse;
808 	CGhoul2Info_v &g2 = *((CGhoul2Info_v *)serverInstance);
809 	return re->G2API_OverrideServerWithClientData( g2, 0 );
810 }
811 
CL_G2API_GetSurfaceName(void * ghoul2,int surfNumber,int modelIndex,char * fillBuf)812 static void CL_G2API_GetSurfaceName( void *ghoul2, int surfNumber, int modelIndex, char *fillBuf ) {
813 	if ( !ghoul2 ) return;
814 	CGhoul2Info_v &g2 = *((CGhoul2Info_v *)ghoul2);
815 	char *tmp = re->G2API_GetSurfaceName( g2, modelIndex, surfNumber );
816 	strcpy( fillBuf, tmp );
817 }
818 
CL_Key_SetCatcher(int catcher)819 static void CL_Key_SetCatcher( int catcher ) {
820 	// Don't allow the cgame module to close the console
821 	Key_SetCatcher( catcher | ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) );
822 }
823 
CGVM_Cvar_Set(const char * var_name,const char * value)824 static void CGVM_Cvar_Set( const char *var_name, const char *value ) {
825 	Cvar_VM_Set( var_name, value, VM_CGAME );
826 }
827 
CGVM_Cmd_RemoveCommand(const char * cmd_name)828 static void CGVM_Cmd_RemoveCommand( const char *cmd_name ) {
829 	Cmd_VM_RemoveCommand( cmd_name, VM_CGAME );
830 }
831 
832 // legacy syscall
833 
CL_CgameSystemCalls(intptr_t * args)834 intptr_t CL_CgameSystemCalls( intptr_t *args ) {
835 	switch ( args[0] ) {
836 		//rww - alright, DO NOT EVER add a GAME/CGAME/UI generic call without adding a trap to match, and
837 		//all of these traps must be shared and have cases in sv_game, cl_cgame, and cl_ui. They must also
838 		//all be in the same order, and start at 100.
839 	case TRAP_MEMSET:
840 		Com_Memset( VMA(1), args[2], args[3] );
841 		return 0;
842 
843 	case TRAP_MEMCPY:
844 		Com_Memcpy( VMA(1), VMA(2), args[3] );
845 		return 0;
846 
847 	case TRAP_STRNCPY:
848 		strncpy( (char *)VMA(1), (const char *)VMA(2), args[3] );
849 		return args[1];
850 
851 	case TRAP_SIN:
852 		return FloatAsInt( sin( VMF(1) ) );
853 
854 	case TRAP_COS:
855 		return FloatAsInt( cos( VMF(1) ) );
856 
857 	case TRAP_ATAN2:
858 		return FloatAsInt( atan2( VMF(1), VMF(2) ) );
859 
860 	case TRAP_SQRT:
861 		return FloatAsInt( sqrt( VMF(1) ) );
862 
863 	case TRAP_MATRIXMULTIPLY:
864 		MatrixMultiply( (vec3_t *)VMA(1), (vec3_t *)VMA(2), (vec3_t *)VMA(3) );
865 		return 0;
866 
867 	case TRAP_ANGLEVECTORS:
868 		AngleVectors( (const float *)VMA(1), (float *)VMA(2), (float *)VMA(3), (float *)VMA(4) );
869 		return 0;
870 
871 	case TRAP_PERPENDICULARVECTOR:
872 		PerpendicularVector( (float *)VMA(1), (const float *)VMA(2) );
873 		return 0;
874 
875 	case TRAP_FLOOR:
876 		return FloatAsInt( floor( VMF(1) ) );
877 
878 	case TRAP_CEIL:
879 		return FloatAsInt( ceil( VMF(1) ) );
880 
881 	case TRAP_TESTPRINTINT:
882 		return 0;
883 
884 	case TRAP_TESTPRINTFLOAT:
885 		return 0;
886 
887 	case TRAP_ACOS:
888 		return FloatAsInt( Q_acos( VMF(1) ) );
889 
890 	case TRAP_ASIN:
891 		return FloatAsInt( Q_asin( VMF(1) ) );
892 
893 	case CG_PRINT:
894 		Com_Printf( "%s", (const char*)VMA(1) );
895 		return 0;
896 
897 	case CG_ERROR:
898 		Com_Error( ERR_DROP, "%s", (const char*)VMA(1) );
899 		return 0;
900 
901 	case CG_MILLISECONDS:
902 		return CL_Milliseconds();
903 
904 		//rww - precision timer funcs... -ALWAYS- call end after start with supplied ptr, or you'll get a nasty memory leak.
905 		//not that you should be using these outside of debug anyway.. because you shouldn't be. So don't.
906 	case CG_PRECISIONTIMER_START:
907 		CL_PrecisionTimerStart( (void **)VMA(1) );
908 		return 0;
909 
910 	case CG_PRECISIONTIMER_END:
911 		return CL_PrecisionTimerEnd( (void *)args[1] );
912 
913 	case CG_CVAR_REGISTER:
914 		Cvar_Register( (vmCvar_t *)VMA(1), (const char *)VMA(2), (const char *)VMA(3), args[4] );
915 		return 0;
916 
917 	case CG_CVAR_UPDATE:
918 		Cvar_Update( (vmCvar_t *)VMA(1) );
919 		return 0;
920 
921 	case CG_CVAR_SET:
922 		Cvar_VM_Set( (const char *)VMA(1), (const char *)VMA(2), VM_CGAME );
923 		return 0;
924 
925 	case CG_CVAR_VARIABLESTRINGBUFFER:
926 		Cvar_VariableStringBuffer( (const char *)VMA(1), (char *)VMA(2), args[3] );
927 		return 0;
928 
929 	case CG_CVAR_GETHIDDENVALUE:
930 		return CL_GetValueForHidden((const char *)VMA(1));
931 
932 	case CG_ARGC:
933 		return Cmd_Argc();
934 
935 	case CG_ARGV:
936 		Cmd_ArgvBuffer( args[1], (char *)VMA(2), args[3] );
937 		return 0;
938 
939 	case CG_ARGS:
940 		Cmd_ArgsBuffer( (char *)VMA(1), args[2] );
941 		return 0;
942 
943 	case CG_FS_FOPENFILE:
944 		return FS_FOpenFileByMode( (const char *)VMA(1), (int *)VMA(2), (fsMode_t)args[3] );
945 
946 	case CG_FS_READ:
947 		FS_Read( VMA(1), args[2], args[3] );
948 		return 0;
949 
950 	case CG_FS_WRITE:
951 		FS_Write( VMA(1), args[2], args[3] );
952 		return 0;
953 
954 	case CG_FS_FCLOSEFILE:
955 		FS_FCloseFile( args[1] );
956 		return 0;
957 
958 	case CG_FS_GETFILELIST:
959 		return FS_GetFileList( (const char *)VMA(1), (const char *)VMA(2), (char *)VMA(3), args[4] );
960 
961 	case CG_SENDCONSOLECOMMAND:
962 		Cbuf_AddText( (const char *)VMA(1) );
963 		return 0;
964 
965 	case CG_ADDCOMMAND:
966 		CL_AddCgameCommand( (const char *)VMA(1) );
967 		return 0;
968 
969 	case CG_REMOVECOMMAND:
970 		Cmd_VM_RemoveCommand( (const char *)VMA(1), VM_CGAME );
971 		return 0;
972 
973 	case CG_SENDCLIENTCOMMAND:
974 		CL_AddReliableCommand2( (const char *)VMA(1) );
975 		return 0;
976 
977 	case CG_UPDATESCREEN:
978 		// this is used during lengthy level loading, so pump message loop
979 		//		Com_EventLoop();	// FIXME: if a server restarts here, BAD THINGS HAPPEN!
980 		// We can't call Com_EventLoop here, a restart will crash and this _does_ happen
981 		// if there is a map change while we are downloading at pk3.
982 		// ZOID
983 		SCR_UpdateScreen();
984 		return 0;
985 
986 	case CG_CM_LOADMAP:
987 		CL_CM_LoadMap( (const char *)VMA(1), (qboolean)args[2] );
988 		return 0;
989 
990 	case CG_CM_NUMINLINEMODELS:
991 		return CM_NumInlineModels();
992 
993 	case CG_CM_INLINEMODEL:
994 		return CM_InlineModel( args[1] );
995 
996 	case CG_CM_TEMPBOXMODEL:
997 		return CM_TempBoxModel( (const float *)VMA(1), (const float *)VMA(2), /*int capsule*/ qfalse );
998 
999 	case CG_CM_TEMPCAPSULEMODEL:
1000 		return CM_TempBoxModel( (const float *)VMA(1), (const float *)VMA(2), /*int capsule*/ qtrue );
1001 
1002 	case CG_CM_POINTCONTENTS:
1003 		return CM_PointContents( (const float *)VMA(1), args[2] );
1004 
1005 	case CG_CM_TRANSFORMEDPOINTCONTENTS:
1006 		return CM_TransformedPointContents( (const float *)VMA(1), args[2], (const float *)VMA(3), (const float *)VMA(4) );
1007 
1008 	case CG_CM_BOXTRACE:
1009 		CM_BoxTrace( (trace_t *)VMA(1), (const float *)VMA(2), (const float *)VMA(3), (const float *)VMA(4), (const float *)VMA(5), args[6], args[7], /*int capsule*/ qfalse );
1010 		return 0;
1011 
1012 	case CG_CM_CAPSULETRACE:
1013 		CM_BoxTrace( (trace_t *)VMA(1), (const float *)VMA(2), (const float *)VMA(3), (const float *)VMA(4), (const float *)VMA(5), args[6], args[7], /*int capsule*/ qtrue );
1014 		return 0;
1015 
1016 	case CG_CM_TRANSFORMEDBOXTRACE:
1017 		CM_TransformedBoxTrace( (trace_t *)VMA(1), (const float *)VMA(2), (const float *)VMA(3), (const float *)VMA(4), (const float *)VMA(5), args[6], args[7], (const float *)VMA(8), (const float *)VMA(9), /*int capsule*/ qfalse );
1018 		return 0;
1019 
1020 	case CG_CM_TRANSFORMEDCAPSULETRACE:
1021 		CM_TransformedBoxTrace( (trace_t *)VMA(1), (const float *)VMA(2), (const float *)VMA(3), (const float *)VMA(4), (const float *)VMA(5), args[6], args[7], (const float *)VMA(8), (const float *)VMA(9), /*int capsule*/ qtrue );
1022 		return 0;
1023 
1024 	case CG_CM_MARKFRAGMENTS:
1025 		return re->MarkFragments( args[1], (const vec3_t *)VMA(2), (const float *)VMA(3), args[4], (float *)VMA(5), args[6], (markFragment_t *)VMA(7) );
1026 
1027 	case CG_S_GETVOICEVOLUME:
1028 		return CL_S_GetVoiceVolume( args[1] );
1029 
1030 	case CG_S_MUTESOUND:
1031 		S_MuteSound( args[1], args[2] );
1032 		return 0;
1033 
1034 	case CG_S_STARTSOUND:
1035 		S_StartSound( (float *)VMA(1), args[2], args[3], args[4] );
1036 		return 0;
1037 
1038 	case CG_S_STARTLOCALSOUND:
1039 		S_StartLocalSound( args[1], args[2] );
1040 		return 0;
1041 
1042 	case CG_S_CLEARLOOPINGSOUNDS:
1043 		S_ClearLoopingSounds();
1044 		return 0;
1045 
1046 	case CG_S_ADDLOOPINGSOUND:
1047 		S_AddLoopingSound( args[1], (const float *)VMA(2), (const float *)VMA(3), args[4] );
1048 		return 0;
1049 
1050 	case CG_S_ADDREALLOOPINGSOUND:
1051 		/*S_AddRealLoopingSound*/S_AddLoopingSound( args[1], (const float *)VMA(2), (const float *)VMA(3), args[4] );
1052 		return 0;
1053 
1054 	case CG_S_STOPLOOPINGSOUND:
1055 		S_StopLoopingSound( args[1] );
1056 		return 0;
1057 
1058 	case CG_S_UPDATEENTITYPOSITION:
1059 		S_UpdateEntityPosition( args[1], (const float *)VMA(2) );
1060 		return 0;
1061 
1062 	case CG_S_RESPATIALIZE:
1063 		S_Respatialize( args[1], (const float *)VMA(2), (vec3_t *)VMA(3), args[4] );
1064 		return 0;
1065 
1066 	case CG_S_SHUTUP:
1067 		CL_S_Shutup( (qboolean)args[1] );
1068 		return 0;
1069 
1070 	case CG_S_REGISTERSOUND:
1071 		return S_RegisterSound( (const char *)VMA(1) );
1072 
1073 	case CG_S_STARTBACKGROUNDTRACK:
1074 		S_StartBackgroundTrack( (const char *)VMA(1), (const char *)VMA(2), args[3]?qtrue:qfalse );
1075 		return 0;
1076 
1077 	case CG_S_UPDATEAMBIENTSET:
1078 		S_UpdateAmbientSet((const char *)VMA(1), (float *)VMA(2));
1079 		return 0;
1080 
1081 	case CG_AS_PARSESETS:
1082 		AS_ParseSets();
1083 		return 0;
1084 
1085 	case CG_AS_ADDPRECACHEENTRY:
1086 		AS_AddPrecacheEntry((const char *)VMA(1));
1087 		return 0;
1088 
1089 	case CG_S_ADDLOCALSET:
1090 		return S_AddLocalSet((const char *)VMA(1), (float *)VMA(2), (float *)VMA(3), args[4], args[5]);
1091 
1092 	case CG_AS_GETBMODELSOUND:
1093 		return AS_GetBModelSound((const char *)VMA(1), args[2]);
1094 
1095 	case CG_R_LOADWORLDMAP:
1096 		re->LoadWorld( (const char *)VMA(1) );
1097 		return 0;
1098 
1099 	case CG_R_REGISTERMODEL:
1100 		return re->RegisterModel( (const char *)VMA(1) );
1101 
1102 	case CG_R_REGISTERSKIN:
1103 		return re->RegisterSkin( (const char *)VMA(1) );
1104 
1105 	case CG_R_REGISTERSHADER:
1106 		return re->RegisterShader( (const char *)VMA(1) );
1107 
1108 	case CG_R_REGISTERSHADERNOMIP:
1109 		return re->RegisterShaderNoMip( (const char *)VMA(1) );
1110 
1111 	case CG_R_REGISTERFONT:
1112 		return re->RegisterFont( (const char *)VMA(1) );
1113 
1114 	case CG_R_FONT_STRLENPIXELS:
1115 		return re->Font_StrLenPixels( (const char *)VMA(1), args[2], VMF(3) );
1116 
1117 	case CG_R_FONT_STRLENCHARS:
1118 		return re->Font_StrLenChars( (const char *)VMA(1) );
1119 
1120 	case CG_R_FONT_STRHEIGHTPIXELS:
1121 		return re->Font_HeightPixels( args[1], VMF(2) );
1122 
1123 	case CG_R_FONT_DRAWSTRING:
1124 		re->Font_DrawString( args[1], args[2], (const char *)VMA(3), (const float *) VMA(4), args[5], args[6], VMF(7) );
1125 		return 0;
1126 
1127 	case CG_LANGUAGE_ISASIAN:
1128 		return re->Language_IsAsian();
1129 
1130 	case CG_LANGUAGE_USESSPACES:
1131 		return re->Language_UsesSpaces();
1132 
1133 	case CG_ANYLANGUAGE_READCHARFROMSTRING:
1134 		return re->AnyLanguage_ReadCharFromString( (const char *) VMA(1), (int *) VMA(2), (qboolean *) VMA(3) );
1135 
1136 	case CG_R_CLEARSCENE:
1137 		re->ClearScene();
1138 		return 0;
1139 
1140 	case CG_R_CLEARDECALS:
1141 		re->ClearDecals();
1142 		return 0;
1143 
1144 	case CG_R_ADDREFENTITYTOSCENE:
1145 		re->AddRefEntityToScene( (const refEntity_t *)VMA(1) );
1146 		return 0;
1147 
1148 	case CG_R_ADDPOLYTOSCENE:
1149 		re->AddPolyToScene( args[1], args[2], (const polyVert_t *)VMA(3), 1 );
1150 		return 0;
1151 
1152 	case CG_R_ADDPOLYSTOSCENE:
1153 		re->AddPolyToScene( args[1], args[2], (const polyVert_t *)VMA(3), args[4] );
1154 		return 0;
1155 
1156 	case CG_R_ADDDECALTOSCENE:
1157 		re->AddDecalToScene( (qhandle_t)args[1], (const float*)VMA(2), (const float*)VMA(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), (qboolean)args[9], VMF(10), (qboolean)args[11] );
1158 		return 0;
1159 
1160 	case CG_R_LIGHTFORPOINT:
1161 		return re->LightForPoint( (float *)VMA(1), (float *)VMA(2), (float *)VMA(3), (float *)VMA(4) );
1162 
1163 	case CG_R_ADDLIGHTTOSCENE:
1164 		re->AddLightToScene( (const float *)VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
1165 		return 0;
1166 
1167 	case CG_R_ADDADDITIVELIGHTTOSCENE:
1168 		re->AddAdditiveLightToScene( (const float *)VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
1169 		return 0;
1170 
1171 	case CG_R_RENDERSCENE:
1172 		re->RenderScene( (const refdef_t *)VMA(1) );
1173 		return 0;
1174 
1175 	case CG_R_SETCOLOR:
1176 		re->SetColor( (const float *)VMA(1) );
1177 		return 0;
1178 
1179 	case CG_R_DRAWSTRETCHPIC:
1180 		re->DrawStretchPic( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), args[9] );
1181 		return 0;
1182 
1183 	case CG_R_MODELBOUNDS:
1184 		re->ModelBounds( args[1], (float *)VMA(2), (float *)VMA(3) );
1185 		return 0;
1186 
1187 	case CG_R_LERPTAG:
1188 		return re->LerpTag( (orientation_t *)VMA(1), args[2], args[3], args[4], VMF(5), (const char *)VMA(6) );
1189 
1190 	case CG_R_DRAWROTATEPIC:
1191 		re->DrawRotatePic( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), VMF(9), args[10] );
1192 		return 0;
1193 
1194 	case CG_R_DRAWROTATEPIC2:
1195 		re->DrawRotatePic2( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), VMF(9), args[10] );
1196 		return 0;
1197 
1198 	case CG_R_SETRANGEFOG:
1199 		re->SetRangedFog( VMF(1) );
1200 		return 0;
1201 
1202 	case CG_R_SETREFRACTIONPROP:
1203 		re->SetRefractionProperties( VMF(1), VMF(2), (qboolean)args[3], (qboolean)args[4] );
1204 		return 0;
1205 
1206 	case CG_GETGLCONFIG:
1207 		CL_GetGlconfig( (glconfig_t *)VMA(1) );
1208 		return 0;
1209 
1210 	case CG_GETGAMESTATE:
1211 		CL_GetGameState( (gameState_t *)VMA(1) );
1212 		return 0;
1213 
1214 	case CG_GETCURRENTSNAPSHOTNUMBER:
1215 		CL_GetCurrentSnapshotNumber( (int *)VMA(1), (int *)VMA(2) );
1216 		return 0;
1217 
1218 	case CG_GETSNAPSHOT:
1219 		return CL_GetSnapshot( args[1], (snapshot_t *)VMA(2) );
1220 
1221 	case CG_GETDEFAULTSTATE:
1222 		return CL_GetDefaultState(args[1], (entityState_t *)VMA(2));
1223 
1224 	case CG_GETSERVERCOMMAND:
1225 		return CL_GetServerCommand( args[1] );
1226 
1227 	case CG_GETCURRENTCMDNUMBER:
1228 		return CL_GetCurrentCmdNumber();
1229 
1230 	case CG_GETUSERCMD:
1231 		return CL_GetUserCmd( args[1], (struct usercmd_s *)VMA(2) );
1232 
1233 	case CG_SETUSERCMDVALUE:
1234 		_CL_SetUserCmdValue( args[1], VMF(2), VMF(3), VMF(4), VMF(5), args[6], args[7], (qboolean)args[8] );
1235 		return 0;
1236 
1237 	case CG_SETCLIENTFORCEANGLE:
1238 		CL_SetClientForceAngle(args[1], (float *)VMA(2));
1239 		return 0;
1240 
1241 	case CG_SETCLIENTTURNEXTENT:
1242 		return 0;
1243 
1244 	case CG_OPENUIMENU:
1245 		CL_OpenUIMenu( args[1] );
1246 		return 0;
1247 
1248 	case CG_MEMORY_REMAINING:
1249 		return Hunk_MemoryRemaining();
1250 
1251 	case CG_KEY_ISDOWN:
1252 		return Key_IsDown( args[1] );
1253 
1254 	case CG_KEY_GETCATCHER:
1255 		return Key_GetCatcher();
1256 
1257 	case CG_KEY_SETCATCHER:
1258 		CL_Key_SetCatcher( args[1] );
1259 		return 0;
1260 
1261 	case CG_KEY_GETKEY:
1262 		return Key_GetKey( (const char *)VMA(1) );
1263 
1264 	case CG_PC_ADD_GLOBAL_DEFINE:
1265 		return botlib_export->PC_AddGlobalDefine( (char *)VMA(1) );
1266 
1267 	case CG_PC_LOAD_SOURCE:
1268 		return botlib_export->PC_LoadSourceHandle( (const char *)VMA(1) );
1269 
1270 	case CG_PC_FREE_SOURCE:
1271 		return botlib_export->PC_FreeSourceHandle( args[1] );
1272 
1273 	case CG_PC_READ_TOKEN:
1274 		return botlib_export->PC_ReadTokenHandle( args[1], (struct pc_token_s *)VMA(2) );
1275 
1276 	case CG_PC_SOURCE_FILE_AND_LINE:
1277 		return botlib_export->PC_SourceFileAndLine( args[1], (char *)VMA(2), (int *)VMA(3) );
1278 
1279 	case CG_PC_LOAD_GLOBAL_DEFINES:
1280 		return botlib_export->PC_LoadGlobalDefines ( (char *)VMA(1) );
1281 
1282 	case CG_PC_REMOVE_ALL_GLOBAL_DEFINES:
1283 		botlib_export->PC_RemoveAllGlobalDefines ( );
1284 		return 0;
1285 
1286 	case CG_S_STOPBACKGROUNDTRACK:
1287 		S_StopBackgroundTrack();
1288 		return 0;
1289 
1290 	case CG_REAL_TIME:
1291 		return Com_RealTime( (struct qtime_s *)VMA(1) );
1292 
1293 	case CG_SNAPVECTOR:
1294 		Sys_SnapVector( (float *)VMA(1) );
1295 		return 0;
1296 
1297 	case CG_CIN_PLAYCINEMATIC:
1298 		return CIN_PlayCinematic((const char *)VMA(1), args[2], args[3], args[4], args[5], args[6]);
1299 
1300 	case CG_CIN_STOPCINEMATIC:
1301 		return CIN_StopCinematic(args[1]);
1302 
1303 	case CG_CIN_RUNCINEMATIC:
1304 		return CIN_RunCinematic(args[1]);
1305 
1306 	case CG_CIN_DRAWCINEMATIC:
1307 		CIN_DrawCinematic(args[1]);
1308 		return 0;
1309 
1310 	case CG_CIN_SETEXTENTS:
1311 		CIN_SetExtents(args[1], args[2], args[3], args[4], args[5]);
1312 		return 0;
1313 
1314 	case CG_R_REMAP_SHADER:
1315 		re->RemapShader( (const char *)VMA(1), (const char *)VMA(2), (const char *)VMA(3) );
1316 		return 0;
1317 
1318 	case CG_R_GET_LIGHT_STYLE:
1319 		re->GetLightStyle(args[1], (unsigned char *)VMA(2));
1320 		return 0;
1321 
1322 	case CG_R_SET_LIGHT_STYLE:
1323 		re->SetLightStyle(args[1], args[2]);
1324 		return 0;
1325 
1326 	case CG_R_GET_BMODEL_VERTS:
1327 		re->GetBModelVerts( args[1], (float (*)[3])VMA(2), (float *)VMA(3) );
1328 		return 0;
1329 
1330 	case CG_R_GETDISTANCECULL:
1331 		{
1332 			float *f = (float *)VMA(1);
1333 			*f = re->GetDistanceCull();
1334 		}
1335 		return 0;
1336 
1337 	case CG_R_GETREALRES:
1338 		{
1339 			int *w = (int *)VMA(1);
1340 			int *h = (int *)VMA(2);
1341 			re->GetRealRes( w, h );
1342 		}
1343 		return 0;
1344 
1345 	case CG_R_AUTOMAPELEVADJ:
1346 		re->AutomapElevationAdjustment(VMF(1));
1347 		return 0;
1348 
1349 	case CG_R_INITWIREFRAMEAUTO:
1350 		return re->InitializeWireframeAutomap();
1351 
1352 	case CG_GET_ENTITY_TOKEN:
1353 		return re->GetEntityToken( (char *)VMA(1), args[2] );
1354 
1355 	case CG_R_INPVS:
1356 		return re->inPVS( (const float *)VMA(1), (const float *)VMA(2), (byte *)VMA(3) );
1357 
1358 #ifndef DEBUG_DISABLEFXCALLS
1359 	case CG_FX_ADDLINE:
1360 		CGFX_AddLine( (float *)VMA(1), (float *)VMA(2), VMF(3), VMF(4), VMF(5),
1361 			VMF(6), VMF(7), VMF(8),
1362 			(float *)VMA(9), (float *)VMA(10), VMF(11),
1363 			args[12], args[13], args[14]);
1364 		return 0;
1365 	case CG_FX_REGISTER_EFFECT:
1366 		return FX_RegisterEffect((const char *)VMA(1));
1367 
1368 	case CG_FX_PLAY_EFFECT:
1369 		FX_PlayEffect((const char *)VMA(1), (float *)VMA(2), (float *)VMA(3), args[4], args[5] );
1370 		return 0;
1371 
1372 	case CG_FX_PLAY_ENTITY_EFFECT:
1373 		assert(0);
1374 		return 0;
1375 
1376 	case CG_FX_PLAY_EFFECT_ID:
1377 		FX_PlayEffectID(args[1], (float *)VMA(2), (float *)VMA(3), args[4], args[5] );
1378 		return 0;
1379 
1380 	case CG_FX_PLAY_PORTAL_EFFECT_ID:
1381 		FX_PlayEffectID(args[1], (float *)VMA(2), (float *)VMA(3), args[4], args[5], qtrue );
1382 		return 0;
1383 
1384 	case CG_FX_PLAY_ENTITY_EFFECT_ID:
1385 		FX_PlayEntityEffectID(args[1], (float *)VMA(2), (vec3_t *)VMA(3), args[4], args[5], args[6], args[7] );
1386 		return 0;
1387 
1388 	case CG_FX_PLAY_BOLTED_EFFECT_ID:
1389 		return CGFX_PlayBoltedEffectID( args[1], (float *)VMA(2), (void *)args[3], args[4], args[5], args[6], args[7], (qboolean)args[8] );
1390 
1391 	case CG_FX_ADD_SCHEDULED_EFFECTS:
1392 		FX_AddScheduledEffects((qboolean)args[1]);
1393 		return 0;
1394 
1395 	case CG_FX_DRAW_2D_EFFECTS:
1396 		FX_Draw2DEffects ( VMF(1), VMF(2) );
1397 		return 0;
1398 
1399 	case CG_FX_INIT_SYSTEM:
1400 		return FX_InitSystem( (refdef_t*)VMA(1) );
1401 
1402 	case CG_FX_SET_REFDEF:
1403 		FX_SetRefDefFromCGame( (refdef_t*)VMA(1) );
1404 		return 0;
1405 
1406 	case CG_FX_FREE_SYSTEM:
1407 		return FX_FreeSystem();
1408 
1409 	case CG_FX_ADJUST_TIME:
1410 		FX_AdjustTime(args[1]);
1411 		return 0;
1412 
1413 	case CG_FX_RESET:
1414 		FX_Free ( false );
1415 		return 0;
1416 
1417 	case CG_FX_ADDPOLY:
1418 		CGFX_AddPoly( (addpolyArgStruct_t *)VMA(1) );
1419 		return 0;
1420 	case CG_FX_ADDBEZIER:
1421 		CGFX_AddBezier( (addbezierArgStruct_t *)VMA(1) );
1422 		return 0;
1423 	case CG_FX_ADDPRIMITIVE:
1424 		CGFX_AddPrimitive( (effectTrailArgStruct_t *)VMA(1) );
1425 		return 0;
1426 	case CG_FX_ADDSPRITE:
1427 		CGFX_AddSprite( (addspriteArgStruct_t *)VMA(1) );
1428 		return 0;
1429 	case CG_FX_ADDELECTRICITY:
1430 		CGFX_AddElectricity( (addElectricityArgStruct_t *)VMA(1) );
1431 		return 0;
1432 #else
1433 	case CG_FX_REGISTER_EFFECT:
1434 	case CG_FX_PLAY_EFFECT:
1435 	case CG_FX_PLAY_ENTITY_EFFECT:
1436 	case CG_FX_PLAY_EFFECT_ID:
1437 	case CG_FX_PLAY_PORTAL_EFFECT_ID:
1438 	case CG_FX_PLAY_ENTITY_EFFECT_ID:
1439 	case CG_FX_PLAY_BOLTED_EFFECT_ID:
1440 	case CG_FX_ADD_SCHEDULED_EFFECTS:
1441 	case CG_FX_INIT_SYSTEM:
1442 	case CG_FX_FREE_SYSTEM:
1443 	case CG_FX_ADJUST_TIME:
1444 	case CG_FX_ADDPOLY:
1445 	case CG_FX_ADDBEZIER:
1446 	case CG_FX_ADDPRIMITIVE:
1447 	case CG_FX_ADDSPRITE:
1448 	case CG_FX_ADDELECTRICITY:
1449 		return 0;
1450 #endif
1451 
1452 	case CG_ROFF_CLEAN:
1453 		return CL_ROFF_Clean();
1454 
1455 	case CG_ROFF_UPDATE_ENTITIES:
1456 		CL_ROFF_UpdateEntities();
1457 		return 0;
1458 
1459 	case CG_ROFF_CACHE:
1460 		return CL_ROFF_Cache( (char *)VMA(1) );
1461 
1462 	case CG_ROFF_PLAY:
1463 		return CL_ROFF_Play( args[1], args[2], (qboolean)args[3] );
1464 
1465 	case CG_ROFF_PURGE_ENT:
1466 		return CL_ROFF_Purge_Ent( args[1] );
1467 
1468 	case CG_TRUEMALLOC:
1469 		VM_Shifted_Alloc((void **)VMA(1), args[2]);
1470 		return 0;
1471 
1472 	case CG_TRUEFREE:
1473 		VM_Shifted_Free((void **)VMA(1));
1474 		return 0;
1475 
1476 	case CG_G2_LISTSURFACES:
1477 		CL_G2API_ListModelSurfaces( VMA(1) );
1478 		return 0;
1479 
1480 	case CG_G2_LISTBONES:
1481 		CL_G2API_ListModelBones( VMA(1), args[2]);
1482 		return 0;
1483 
1484 	case CG_G2_HAVEWEGHOULMODELS:
1485 		return CL_G2API_HaveWeGhoul2Models( VMA(1) );
1486 
1487 	case CG_G2_SETMODELS:
1488 		CL_G2API_SetGhoul2ModelIndexes( VMA(1), (qhandle_t *)VMA(2), (qhandle_t *)VMA(3) );
1489 		return 0;
1490 
1491 	case CG_G2_GETBOLT:
1492 		return CL_G2API_GetBoltMatrix(VMA(1), args[2], args[3], (mdxaBone_t *)VMA(4), (const float *)VMA(5),(const float *)VMA(6), args[7], (qhandle_t *)VMA(8), (float *)VMA(9));
1493 
1494 	case CG_G2_GETBOLT_NOREC:
1495 		return CL_G2API_GetBoltMatrix_NoReconstruct(VMA(1), args[2], args[3], (mdxaBone_t *)VMA(4), (const float *)VMA(5),(const float *)VMA(6), args[7], (qhandle_t *)VMA(8), (float *)VMA(9));
1496 
1497 	case CG_G2_GETBOLT_NOREC_NOROT:
1498 		return CL_G2API_GetBoltMatrix_NoRecNoRot(VMA(1), args[2], args[3], (mdxaBone_t *)VMA(4), (const float *)VMA(5),(const float *)VMA(6), args[7], (qhandle_t *)VMA(8), (float *)VMA(9));
1499 
1500 	case CG_G2_INITGHOUL2MODEL:
1501 		return CL_G2API_InitGhoul2Model((void **)VMA(1), (const char *)VMA(2), args[3], (qhandle_t) args[4], (qhandle_t) args[5], args[6], args[7]);
1502 
1503 	case CG_G2_SETSKIN:
1504 		return CL_G2API_SetSkin( VMA(1), args[2], args[3], args[4] );
1505 
1506 	case CG_G2_COLLISIONDETECT:
1507 		CL_G2API_CollisionDetect ( (CollisionRecord_t*)VMA(1), VMA(2), (const float*)VMA(3), (const float*)VMA(4), args[5], args[6], (float*)VMA(7), (float*)VMA(8), (float*)VMA(9), args[10], args[11], VMF(12) );
1508 		return 0;
1509 
1510 	case CG_G2_COLLISIONDETECTCACHE:
1511 		CL_G2API_CollisionDetectCache ( (CollisionRecord_t*)VMA(1), VMA(2), (const float*)VMA(3), (const float*)VMA(4), args[5], args[6], (float*)VMA(7), (float*)VMA(8), (float*)VMA(9), args[10], args[11], VMF(12) );
1512 		return 0;
1513 
1514 	case CG_G2_ANGLEOVERRIDE:
1515 		return CL_G2API_SetBoneAngles( VMA(1), args[2], (const char *)VMA(3), (float *)VMA(4), args[5], args[6], args[7], args[8], (qhandle_t *)VMA(9), args[10], args[11] );
1516 
1517 	case CG_G2_CLEANMODELS:
1518 		CL_G2API_CleanGhoul2Models( (void **)VMA(1) );
1519 		return 0;
1520 
1521 	case CG_G2_PLAYANIM:
1522 		return CL_G2API_SetBoneAnim( VMA(1), args[2], (const char *)VMA(3), args[4], args[5], args[6], VMF(7), args[8], VMF(9), args[10] );
1523 
1524 	case CG_G2_GETBONEANIM:
1525 		return CL_G2API_GetBoneAnim( VMA(1), (const char *)VMA(2), args[3], (float *)VMA(4), (int *)VMA(5), (int *)VMA(6), (int *)VMA(7), (float *)VMA(8), (int *)VMA(9), args[10] );
1526 
1527 	case CG_G2_GETBONEFRAME:
1528 		return CL_G2API_GetBoneFrame( VMA(1), (const char*)VMA(2), args[3], (float *)VMA(4), (int *)VMA(5), args[6] );
1529 
1530 	case CG_G2_GETGLANAME:
1531 		CL_G2API_GetGLAName( VMA(1), args[2], (char *)VMA(3) );
1532 		return 0;
1533 
1534 	case CG_G2_COPYGHOUL2INSTANCE:
1535 		return CL_G2API_CopyGhoul2Instance( VMA(1), VMA(2), args[3] );
1536 
1537 	case CG_G2_COPYSPECIFICGHOUL2MODEL:
1538 		CL_G2API_CopySpecificGhoul2Model( VMA(1), args[2], VMA(3), args[4] );
1539 		return 0;
1540 
1541 	case CG_G2_DUPLICATEGHOUL2INSTANCE:
1542 		CL_G2API_DuplicateGhoul2Instance( VMA(1), (void **)VMA(2) );
1543 		return 0;
1544 
1545 	case CG_G2_HASGHOUL2MODELONINDEX:
1546 		return CL_G2API_HasGhoul2ModelOnIndex( VMA(1), args[2]);
1547 
1548 	case CG_G2_REMOVEGHOUL2MODEL:
1549 		return CL_G2API_RemoveGhoul2Model( VMA(1), args[2]);
1550 
1551 	case CG_G2_SKINLESSMODEL:
1552 		return CL_G2API_SkinlessModel( VMA(1), args[2] );
1553 
1554 	case CG_G2_GETNUMGOREMARKS:
1555 		return CL_G2API_GetNumGoreMarks( VMA(1), args[2] );
1556 
1557 	case CG_G2_ADDSKINGORE:
1558 		CL_G2API_AddSkinGore( VMA(1), (SSkinGoreData *)VMA(2));
1559 		return 0;
1560 
1561 	case CG_G2_CLEARSKINGORE:
1562 		CL_G2API_ClearSkinGore ( VMA(1) );
1563 		return 0;
1564 
1565 	case CG_G2_SIZE:
1566 		return CL_G2API_Ghoul2Size ( VMA(1) );
1567 
1568 	case CG_G2_ADDBOLT:
1569 		return CL_G2API_AddBolt( VMA(1), args[2], (const char *)VMA(3));
1570 
1571 	case CG_G2_ATTACHENT:
1572 		return CL_G2API_AttachEnt( (int*)VMA(1), VMA(2), args[3], args[4], args[5] );
1573 
1574 	case CG_G2_SETBOLTON:
1575 		CL_G2API_SetBoltInfo( VMA(1), args[2], args[3] );
1576 		return 0;
1577 
1578 	case CG_G2_SETROOTSURFACE:
1579 		return CL_G2API_SetRootSurface( VMA(1), args[2], (const char *)VMA(3));
1580 
1581 	case CG_G2_SETSURFACEONOFF:
1582 		return CL_G2API_SetSurfaceOnOff( VMA(1), (const char *)VMA(2), args[3]);
1583 
1584 	case CG_G2_SETNEWORIGIN:
1585 		return CL_G2API_SetNewOrigin( VMA(1), args[2]);
1586 
1587 	case CG_G2_DOESBONEEXIST:
1588 		return CL_G2API_DoesBoneExist( VMA(1), args[2], (const char *)VMA(3));
1589 
1590 	case CG_G2_GETSURFACERENDERSTATUS:
1591 		return CL_G2API_GetSurfaceRenderStatus( VMA(1), args[2], (const char *)VMA(3));
1592 
1593 	case CG_G2_GETTIME:
1594 		return CL_G2API_GetTime();
1595 
1596 	case CG_G2_SETTIME:
1597 		CL_G2API_SetTime(args[1], args[2]);
1598 		return 0;
1599 
1600 	case CG_G2_ABSURDSMOOTHING:
1601 		CL_G2API_AbsurdSmoothing( VMA(1), (qboolean)args[2]);
1602 		return 0;
1603 
1604 
1605 	case CG_G2_SETRAGDOLL:
1606 		CL_G2API_SetRagDoll( VMA(1), (sharedRagDollParams_t *)VMA(2) );
1607 		return 0;
1608 
1609 	case CG_G2_ANIMATEG2MODELS:
1610 		CL_G2API_AnimateG2Models( VMA(1), args[2], (sharedRagDollUpdateParams_t *)VMA(3) );
1611 		return 0;
1612 
1613 		//additional ragdoll options -rww
1614 	case CG_G2_RAGPCJCONSTRAINT:
1615 		return CL_G2API_RagPCJConstraint( VMA(1), (const char *)VMA(2), (float *)VMA(3), (float *)VMA(4));
1616 
1617 	case CG_G2_RAGPCJGRADIENTSPEED:
1618 		return CL_G2API_RagPCJGradientSpeed( VMA(1), (const char *)VMA(2), VMF(3));
1619 
1620 	case CG_G2_RAGEFFECTORGOAL:
1621 		return CL_G2API_RagEffectorGoal( VMA(1), (const char *)VMA(2), (float *)VMA(3));
1622 
1623 	case CG_G2_GETRAGBONEPOS:
1624 		return CL_G2API_GetRagBonePos( VMA(1), (const char *)VMA(2), (float *)VMA(3), (float *)VMA(4), (float *)VMA(5), (float *)VMA(6));
1625 
1626 	case CG_G2_RAGEFFECTORKICK:
1627 		return CL_G2API_RagEffectorKick( VMA(1), (const char *)VMA(2), (float *)VMA(3));
1628 
1629 	case CG_G2_RAGFORCESOLVE:
1630 		return CL_G2API_RagForceSolve( VMA(1), (qboolean)args[2]);
1631 
1632 	case CG_G2_SETBONEIKSTATE:
1633 		return CL_G2API_SetBoneIKState( VMA(1), args[2], (const char *)VMA(3), args[4], (sharedSetBoneIKStateParams_t *)VMA(5));
1634 
1635 	case CG_G2_IKMOVE:
1636 		return CL_G2API_IKMove( VMA(1), args[2], (sharedIKMoveParams_t *)VMA(3));
1637 
1638 	case CG_G2_REMOVEBONE:
1639 		return CL_G2API_RemoveBone( VMA(1), (const char *)VMA(2), args[3] );
1640 
1641 	case CG_G2_ATTACHINSTANCETOENTNUM:
1642 		CL_G2API_AttachInstanceToEntNum( VMA(1), args[2], (qboolean)args[3]);
1643 		return 0;
1644 
1645 	case CG_G2_CLEARATTACHEDINSTANCE:
1646 		CL_G2API_ClearAttachedInstance(args[1]);
1647 		return 0;
1648 
1649 	case CG_G2_CLEANENTATTACHMENTS:
1650 		CL_G2API_CleanEntAttachments();
1651 		return 0;
1652 
1653 	case CG_G2_OVERRIDESERVER:
1654 		return CL_G2API_OverrideServer( VMA(1) );
1655 
1656 	case CG_G2_GETSURFACENAME:
1657 		CL_G2API_GetSurfaceName( VMA(1), args[2], args[3], (char *)VMA(4) );
1658 		return 0;
1659 
1660 	case CG_SP_GETSTRINGTEXTSTRING:
1661 		return CL_SE_GetStringTextString( (const char *)VMA(1), (char *)VMA(2), args[3] );
1662 
1663 	case CG_SET_SHARED_BUFFER:
1664 		RegisterSharedMemory( (char *)VMA(1) );
1665 		return 0;
1666 
1667 	case CG_CM_REGISTER_TERRAIN:
1668 		return 0;
1669 
1670 	case CG_RMG_INIT:
1671 		return 0;
1672 
1673 	case CG_RE_INIT_RENDERER_TERRAIN:
1674 		return 0;
1675 
1676 	case CG_R_WEATHER_CONTENTS_OVERRIDE:
1677 		//contentOverride = args[1];
1678 		return 0;
1679 
1680 	case CG_R_WORLDEFFECTCOMMAND:
1681 		re->WorldEffectCommand((const char *)VMA(1));
1682 		return 0;
1683 
1684 	case CG_WE_ADDWEATHERZONE:
1685 		re->AddWeatherZone( (float *)VMA(1), (float *)VMA(2) );
1686 		return 0;
1687 
1688 	default:
1689 		assert(0); // bk010102
1690 		Com_Error( ERR_DROP, "Bad cgame system trap: %ld", (long int) args[0] );
1691 	}
1692 	return 0;
1693 }
1694 
1695 // Stub function for old RMG system.
RE_InitRendererTerrain(const char *)1696 static void RE_InitRendererTerrain ( const char * /*info*/ ) {}
1697 
CL_BindCGame(void)1698 void CL_BindCGame( void ) {
1699 	static cgameImport_t cgi;
1700 	cgameExport_t		*ret;
1701 	GetCGameAPI_t		GetCGameAPI;
1702 	char				dllName[MAX_OSPATH] = "cgame" ARCH_STRING DLL_EXT;
1703 
1704 	memset( &cgi, 0, sizeof( cgi ) );
1705 
1706 	cgvm = VM_Create( VM_CGAME );
1707 	if ( cgvm && !cgvm->isLegacy ) {
1708 		cgi.Print								= Com_Printf;
1709 		cgi.Error								= Com_Error;
1710 		cgi.SnapVector							= Sys_SnapVector;
1711 		cgi.MemoryRemaining						= Hunk_MemoryRemaining;
1712 		cgi.RegisterSharedMemory				= RegisterSharedMemory;
1713 		cgi.TrueMalloc							= VM_Shifted_Alloc;
1714 		cgi.TrueFree							= VM_Shifted_Free;
1715 		cgi.Milliseconds						= CL_Milliseconds;
1716 		cgi.RealTime							= Com_RealTime;
1717 		cgi.PrecisionTimerStart					= CL_PrecisionTimerStart;
1718 		cgi.PrecisionTimerEnd					= CL_PrecisionTimerEnd;
1719 		cgi.Cvar_Register						= Cvar_Register;
1720 		cgi.Cvar_Set							= CGVM_Cvar_Set;
1721 		cgi.Cvar_Update							= Cvar_Update;
1722 		cgi.Cvar_VariableStringBuffer			= Cvar_VariableStringBuffer;
1723 		cgi.AddCommand							= CL_AddCgameCommand;
1724 		cgi.Cmd_Argc							= Cmd_Argc;
1725 		cgi.Cmd_Args							= Cmd_ArgsBuffer;
1726 		cgi.Cmd_Argv							= Cmd_ArgvBuffer;
1727 		cgi.RemoveCommand						= CGVM_Cmd_RemoveCommand;
1728 		cgi.SendClientCommand					= CL_AddReliableCommand2;
1729 		cgi.SendConsoleCommand					= Cbuf_AddText;
1730 		cgi.FS_Close							= FS_FCloseFile;
1731 		cgi.FS_GetFileList						= FS_GetFileList;
1732 		cgi.FS_Open								= FS_FOpenFileByMode;
1733 		cgi.FS_Read								= FS_Read;
1734 		cgi.FS_Write							= FS_Write;
1735 		cgi.UpdateScreen						= SCR_UpdateScreen;
1736 		cgi.CM_InlineModel						= CM_InlineModel;
1737 		cgi.CM_LoadMap							= CL_CM_LoadMap;
1738 		cgi.CM_NumInlineModels					= CM_NumInlineModels;
1739 		cgi.CM_PointContents					= CM_PointContents;
1740 		cgi.CM_RegisterTerrain					= CL_CM_RegisterTerrain;
1741 		cgi.CM_TempModel						= CM_TempBoxModel;
1742 		cgi.CM_Trace							= CM_BoxTrace;
1743 		cgi.CM_TransformedPointContents			= CM_TransformedPointContents;
1744 		cgi.CM_TransformedTrace					= CM_TransformedBoxTrace;
1745 		cgi.RMG_Init							= CL_RMG_Init;
1746 		cgi.S_AddLocalSet						= S_AddLocalSet;
1747 		cgi.S_AddLoopingSound					= S_AddLoopingSound;
1748 		cgi.S_ClearLoopingSounds				= S_ClearLoopingSounds;
1749 		cgi.S_GetVoiceVolume					= CL_S_GetVoiceVolume;
1750 		cgi.S_MuteSound							= S_MuteSound;
1751 		cgi.S_RegisterSound						= S_RegisterSound;
1752 		cgi.S_Respatialize						= S_Respatialize;
1753 		cgi.S_Shutup							= CL_S_Shutup;
1754 		cgi.S_StartBackgroundTrack				= S_StartBackgroundTrack;
1755 		cgi.S_StartLocalSound					= S_StartLocalSound;
1756 		cgi.S_StartSound						= S_StartSound;
1757 		cgi.S_StopBackgroundTrack				= S_StopBackgroundTrack;
1758 		cgi.S_StopLoopingSound					= S_StopLoopingSound;
1759 		cgi.S_UpdateEntityPosition				= S_UpdateEntityPosition;
1760 		cgi.S_UpdateAmbientSet					= S_UpdateAmbientSet;
1761 		cgi.AS_AddPrecacheEntry					= AS_AddPrecacheEntry;
1762 		cgi.AS_GetBModelSound					= AS_GetBModelSound;
1763 		cgi.AS_ParseSets						= AS_ParseSets;
1764 		cgi.R_AddAdditiveLightToScene			= re->AddAdditiveLightToScene;
1765 		cgi.R_AddDecalToScene					= re->AddDecalToScene;
1766 		cgi.R_AddLightToScene					= re->AddLightToScene;
1767 		cgi.R_AddPolysToScene					= re->AddPolyToScene;
1768 		cgi.R_AddRefEntityToScene				= re->AddRefEntityToScene;
1769 		cgi.R_AnyLanguage_ReadCharFromString	= re->AnyLanguage_ReadCharFromString;
1770 		cgi.R_AutomapElevationAdjustment		= re->AutomapElevationAdjustment;
1771 		cgi.R_ClearDecals						= re->ClearDecals;
1772 		cgi.R_ClearScene						= re->ClearScene;
1773 		cgi.R_DrawStretchPic					= re->DrawStretchPic;
1774 		cgi.R_DrawRotatePic						= re->DrawRotatePic;
1775 		cgi.R_DrawRotatePic2					= re->DrawRotatePic2;
1776 		cgi.R_Font_DrawString					= re->Font_DrawString;
1777 		cgi.R_Font_HeightPixels					= re->Font_HeightPixels;
1778 		cgi.R_Font_StrLenChars					= re->Font_StrLenChars;
1779 		cgi.R_Font_StrLenPixels					= re->Font_StrLenPixels;
1780 		cgi.R_GetBModelVerts					= re->GetBModelVerts;
1781 		cgi.R_GetDistanceCull					= re->GetDistanceCull;
1782 		cgi.R_GetEntityToken					= re->GetEntityToken;
1783 		cgi.R_GetLightStyle						= re->GetLightStyle;
1784 		cgi.R_GetRealRes						= re->GetRealRes;
1785 		cgi.R_InitializeWireframeAutomap		= re->InitializeWireframeAutomap;
1786 		cgi.R_InPVS								= re->inPVS;
1787 		cgi.R_Language_IsAsian					= re->Language_IsAsian;
1788 		cgi.R_Language_UsesSpaces				= re->Language_UsesSpaces;
1789 		cgi.R_LerpTag							= re->LerpTag;
1790 		cgi.R_LightForPoint						= re->LightForPoint;
1791 		cgi.R_LoadWorld							= re->LoadWorld;
1792 		cgi.R_MarkFragments						= re->MarkFragments;
1793 		cgi.R_ModelBounds						= re->ModelBounds;
1794 		cgi.R_RegisterFont						= re->RegisterFont;
1795 		cgi.R_RegisterModel						= re->RegisterModel;
1796 		cgi.R_RegisterShader					= re->RegisterShader;
1797 		cgi.R_RegisterShaderNoMip				= re->RegisterShaderNoMip;
1798 		cgi.R_RegisterSkin						= re->RegisterSkin;
1799 		cgi.R_RemapShader						= re->RemapShader;
1800 		cgi.R_RenderScene						= re->RenderScene;
1801 		cgi.R_SetColor							= re->SetColor;
1802 		cgi.R_SetLightStyle						= re->SetLightStyle;
1803 		cgi.R_SetRangedFog						= re->SetRangedFog;
1804 		cgi.R_SetRefractionProperties			= re->SetRefractionProperties;
1805 		cgi.R_WorldEffectCommand				= re->WorldEffectCommand;
1806 		cgi.RE_InitRendererTerrain				= RE_InitRendererTerrain;
1807 		cgi.WE_AddWeatherZone					= re->AddWeatherZone;
1808 		cgi.GetCurrentSnapshotNumber			= CL_GetCurrentSnapshotNumber;
1809 		cgi.GetCurrentCmdNumber					= CL_GetCurrentCmdNumber;
1810 		cgi.GetDefaultState						= CL_GetDefaultState;
1811 		cgi.GetGameState						= CL_GetGameState;
1812 		cgi.GetGlconfig							= CL_GetGlconfig;
1813 		cgi.GetServerCommand					= CL_GetServerCommand;
1814 		cgi.GetSnapshot							= CL_GetSnapshot;
1815 		cgi.GetUserCmd							= CL_GetUserCmd;
1816 		cgi.OpenUIMenu							= CL_OpenUIMenu;
1817 		cgi.SetClientForceAngle					= CL_SetClientForceAngle;
1818 		cgi.SetUserCmdValue						= _CL_SetUserCmdValue;
1819 		cgi.Key_GetCatcher						= Key_GetCatcher;
1820 		cgi.Key_GetKey							= Key_GetKey;
1821 		cgi.Key_IsDown							= Key_IsDown;
1822 		cgi.Key_SetCatcher						= CL_Key_SetCatcher;
1823 		cgi.PC_AddGlobalDefine					= botlib_export->PC_AddGlobalDefine;
1824 		cgi.PC_FreeSource						= botlib_export->PC_FreeSourceHandle;
1825 		cgi.PC_LoadGlobalDefines				= botlib_export->PC_LoadGlobalDefines;
1826 		cgi.PC_LoadSource						= botlib_export->PC_LoadSourceHandle;
1827 		cgi.PC_ReadToken						= botlib_export->PC_ReadTokenHandle;
1828 		cgi.PC_RemoveAllGlobalDefines			= botlib_export->PC_RemoveAllGlobalDefines;
1829 		cgi.PC_SourceFileAndLine				= botlib_export->PC_SourceFileAndLine;
1830 		cgi.CIN_DrawCinematic					= CIN_DrawCinematic;
1831 		cgi.CIN_PlayCinematic					= CIN_PlayCinematic;
1832 		cgi.CIN_RunCinematic					= CIN_RunCinematic;
1833 		cgi.CIN_SetExtents						= CIN_SetExtents;
1834 		cgi.CIN_StopCinematic					= CIN_StopCinematic;
1835 		cgi.FX_AddLine							= CGFX_AddLine;
1836 		cgi.FX_RegisterEffect					= FX_RegisterEffect;
1837 		cgi.FX_PlayEffect						= FX_PlayEffect;
1838 		cgi.FX_PlayEffectID						= FX_PlayEffectID;
1839 		cgi.FX_PlayEntityEffectID				= FX_PlayEntityEffectID;
1840 		cgi.FX_PlayBoltedEffectID				= CGFX_PlayBoltedEffectID;
1841 		cgi.FX_AddScheduledEffects				= FX_AddScheduledEffects;
1842 		cgi.FX_InitSystem						= FX_InitSystem;
1843 		cgi.FX_SetRefDef						= FX_SetRefDef;
1844 		cgi.FX_FreeSystem						= FX_FreeSystem;
1845 		cgi.FX_AdjustTime						= FX_AdjustTime;
1846 		cgi.FX_Draw2DEffects					= FX_Draw2DEffects;
1847 		cgi.FX_AddPoly							= CGFX_AddPoly;
1848 		cgi.FX_AddBezier						= CGFX_AddBezier;
1849 		cgi.FX_AddPrimitive						= CGFX_AddPrimitive;
1850 		cgi.FX_AddSprite						= CGFX_AddSprite;
1851 		cgi.FX_AddElectricity					= CGFX_AddElectricity;
1852 		cgi.SE_GetStringTextString				= CL_SE_GetStringTextString;
1853 		cgi.ROFF_Clean							= CL_ROFF_Clean;
1854 		cgi.ROFF_UpdateEntities					= CL_ROFF_UpdateEntities;
1855 		cgi.ROFF_Cache							= CL_ROFF_Cache;
1856 		cgi.ROFF_Play							= CL_ROFF_Play;
1857 		cgi.ROFF_Purge_Ent						= CL_ROFF_Purge_Ent;
1858 		cgi.G2_ListModelSurfaces				= CL_G2API_ListModelSurfaces;
1859 		cgi.G2_ListModelBones					= CL_G2API_ListModelBones;
1860 		cgi.G2_SetGhoul2ModelIndexes			= CL_G2API_SetGhoul2ModelIndexes;
1861 		cgi.G2_HaveWeGhoul2Models				= CL_G2API_HaveWeGhoul2Models;
1862 		cgi.G2API_GetBoltMatrix					= CL_G2API_GetBoltMatrix;
1863 		cgi.G2API_GetBoltMatrix_NoReconstruct	= CL_G2API_GetBoltMatrix_NoReconstruct;
1864 		cgi.G2API_GetBoltMatrix_NoRecNoRot		= CL_G2API_GetBoltMatrix_NoRecNoRot;
1865 		cgi.G2API_InitGhoul2Model				= CL_G2API_InitGhoul2Model;
1866 		cgi.G2API_SetSkin						= CL_G2API_SetSkin;
1867 		cgi.G2API_CollisionDetect				= CL_G2API_CollisionDetect;
1868 		cgi.G2API_CollisionDetectCache			= CL_G2API_CollisionDetectCache;
1869 		cgi.G2API_CleanGhoul2Models				= CL_G2API_CleanGhoul2Models;
1870 		cgi.G2API_SetBoneAngles					= CL_G2API_SetBoneAngles;
1871 		cgi.G2API_SetBoneAnim					= CL_G2API_SetBoneAnim;
1872 		cgi.G2API_GetBoneAnim					= CL_G2API_GetBoneAnim;
1873 		cgi.G2API_GetBoneFrame					= CL_G2API_GetBoneFrame;
1874 		cgi.G2API_GetGLAName					= CL_G2API_GetGLAName;
1875 		cgi.G2API_CopyGhoul2Instance			= CL_G2API_CopyGhoul2Instance;
1876 		cgi.G2API_CopySpecificGhoul2Model		= CL_G2API_CopySpecificGhoul2Model;
1877 		cgi.G2API_DuplicateGhoul2Instance		= CL_G2API_DuplicateGhoul2Instance;
1878 		cgi.G2API_HasGhoul2ModelOnIndex			= CL_G2API_HasGhoul2ModelOnIndex;
1879 		cgi.G2API_RemoveGhoul2Model				= CL_G2API_RemoveGhoul2Model;
1880 		cgi.G2API_SkinlessModel					= CL_G2API_SkinlessModel;
1881 		cgi.G2API_GetNumGoreMarks				= CL_G2API_GetNumGoreMarks;
1882 		cgi.G2API_AddSkinGore					= CL_G2API_AddSkinGore;
1883 		cgi.G2API_ClearSkinGore					= CL_G2API_ClearSkinGore;
1884 		cgi.G2API_Ghoul2Size					= CL_G2API_Ghoul2Size;
1885 		cgi.G2API_AddBolt						= CL_G2API_AddBolt;
1886 		cgi.G2API_AttachEnt						= CL_G2API_AttachEnt;
1887 		cgi.G2API_SetBoltInfo					= CL_G2API_SetBoltInfo;
1888 		cgi.G2API_SetRootSurface				= CL_G2API_SetRootSurface;
1889 		cgi.G2API_SetSurfaceOnOff				= CL_G2API_SetSurfaceOnOff;
1890 		cgi.G2API_SetNewOrigin					= CL_G2API_SetNewOrigin;
1891 		cgi.G2API_DoesBoneExist					= CL_G2API_DoesBoneExist;
1892 		cgi.G2API_GetSurfaceRenderStatus		= CL_G2API_GetSurfaceRenderStatus;
1893 		cgi.G2API_GetTime						= CL_G2API_GetTime;
1894 		cgi.G2API_SetTime						= CL_G2API_SetTime;
1895 		cgi.G2API_AbsurdSmoothing				= CL_G2API_AbsurdSmoothing;
1896 		cgi.G2API_SetRagDoll					= CL_G2API_SetRagDoll;
1897 		cgi.G2API_AnimateG2Models				= CL_G2API_AnimateG2Models;
1898 		cgi.G2API_RagPCJConstraint				= CL_G2API_RagPCJConstraint;
1899 		cgi.G2API_RagPCJGradientSpeed			= CL_G2API_RagPCJGradientSpeed;
1900 		cgi.G2API_RagEffectorGoal				= CL_G2API_RagEffectorGoal;
1901 		cgi.G2API_GetRagBonePos					= CL_G2API_GetRagBonePos;
1902 		cgi.G2API_RagEffectorKick				= CL_G2API_RagEffectorKick;
1903 		cgi.G2API_RagForceSolve					= CL_G2API_RagForceSolve;
1904 		cgi.G2API_SetBoneIKState				= CL_G2API_SetBoneIKState;
1905 		cgi.G2API_IKMove						= CL_G2API_IKMove;
1906 		cgi.G2API_RemoveBone					= CL_G2API_RemoveBone;
1907 		cgi.G2API_AttachInstanceToEntNum		= CL_G2API_AttachInstanceToEntNum;
1908 		cgi.G2API_ClearAttachedInstance			= CL_G2API_ClearAttachedInstance;
1909 		cgi.G2API_CleanEntAttachments			= CL_G2API_CleanEntAttachments;
1910 		cgi.G2API_OverrideServer				= CL_G2API_OverrideServer;
1911 		cgi.G2API_GetSurfaceName				= CL_G2API_GetSurfaceName;
1912 
1913 		cgi.ext.R_Font_StrLenPixels				= re->ext.Font_StrLenPixels;
1914 
1915 		GetCGameAPI = (GetCGameAPI_t)cgvm->GetModuleAPI;
1916 		ret = GetCGameAPI( CGAME_API_VERSION, &cgi );
1917 		if ( !ret ) {
1918 			//free VM?
1919 			cls.cgameStarted = qfalse;
1920 			Com_Error( ERR_FATAL, "GetGameAPI failed on %s", dllName );
1921 		}
1922 		cge = ret;
1923 
1924 		return;
1925 	}
1926 
1927 	// fall back to legacy syscall/vm_call api
1928 	cgvm = VM_CreateLegacy( VM_CGAME, CL_CgameSystemCalls );
1929 	if ( !cgvm ) {
1930 		cls.cgameStarted = qfalse;
1931 		Com_Error( ERR_DROP, "VM_CreateLegacy on cgame failed" );
1932 	}
1933 }
1934 
CL_UnbindCGame(void)1935 void CL_UnbindCGame( void ) {
1936 	CGVM_Shutdown();
1937 	VM_Free( cgvm );
1938 	cgvm = NULL;
1939 }
1940