2005-01-17 17:43:13 +00:00
# include "quakedef.h"
# ifdef CSQC_DAT
2005-01-24 05:10:11 +00:00
# ifdef RGLQUAKE
# include "glquake.h" //evil to include this
# endif
progfuncs_t * csqcprogs ;
2005-02-28 07:16:19 +00:00
typedef struct {
//These are the functions the engine will call to, found by name.
func_t init_function ;
func_t shutdown_function ;
func_t draw_function ;
func_t keydown_function ;
func_t keyup_function ;
func_t parse_stuffcmd ;
func_t parse_centerprint ;
func_t ent_update ;
func_t ent_remove ;
//These are pointers to the csqc's globals.
float * time ; //float Written before entering most qc functions
int * self ; //entity Written before entering most qc functions
float * forward ; //vector written by anglevectors
float * right ; //vector written by anglevectors
float * up ; //vector written by anglevectors
float * trace_allsolid ; //bool written by traceline
float * trace_startsolid ; //bool written by traceline
float * trace_fraction ; //float written by traceline
float * trace_inwater ; //bool written by traceline
float * trace_inopen ; //bool written by traceline
float * trace_endpos ; //vector written by traceline
float * trace_plane_normal ; //vector written by traceline
float * trace_plane_dist ; //float written by traceline
int * trace_ent ; //entity written by traceline
} csqcglobals_t ;
static csqcglobals_t csqcg ;
void CSQC_FindGlobals ( void )
{
csqcg . time = ( float * ) PR_FindGlobal ( csqcprogs , " time " , 0 ) ;
if ( csqcg . time )
* csqcg . time = Sys_DoubleTime ( ) ;
csqcg . self = ( int * ) PR_FindGlobal ( csqcprogs , " self " , 0 ) ;
csqcg . forward = ( float * ) PR_FindGlobal ( csqcprogs , " v_forward " , 0 ) ;
csqcg . right = ( float * ) PR_FindGlobal ( csqcprogs , " v_right " , 0 ) ;
csqcg . up = ( float * ) PR_FindGlobal ( csqcprogs , " v_up " , 0 ) ;
csqcg . init_function = PR_FindFunction ( csqcprogs , " CSQC_Init " , PR_ANY ) ;
csqcg . shutdown_function = PR_FindFunction ( csqcprogs , " CSQC_Shutdown " , PR_ANY ) ;
csqcg . draw_function = PR_FindFunction ( csqcprogs , " CSQC_UpdateView " , PR_ANY ) ;
csqcg . keydown_function = PR_FindFunction ( csqcprogs , " CSQC_KeyDown " , PR_ANY ) ;
csqcg . keyup_function = PR_FindFunction ( csqcprogs , " CSQC_KeyUp " , PR_ANY ) ;
csqcg . parse_stuffcmd = PR_FindFunction ( csqcprogs , " CSQC_Parse_StuffCmd " , PR_ANY ) ;
csqcg . parse_centerprint = PR_FindFunction ( csqcprogs , " CSQC_Parse_CenterPrint " , PR_ANY ) ;
csqcg . ent_update = PR_FindFunction ( csqcprogs , " CSQC_Ent_Update " , PR_ANY ) ;
csqcg . ent_remove = PR_FindFunction ( csqcprogs , " CSQC_Ent_Remove " , PR_ANY ) ;
}
//this is the list for all the csqc fields.
//(the #define is so the list always matches the ones pulled out)
# define csqcfields \
fieldfloat ( modelindex ) ; \
fieldvector ( origin ) ; \
fieldvector ( angles ) ; \
fieldfloat ( alpha ) ; /*transparency*/ \
fieldfloat ( scale ) ; /*model scale*/ \
fieldfloat ( fatness ) ; /*expand models X units along thier normals.*/ \
fieldfloat ( skin ) ; \
fieldfloat ( colormap ) ; \
fieldfloat ( frame ) ; \
fieldfloat ( oldframe ) ; \
fieldfloat ( lerpfrac ) ; \
\
fieldfloat ( drawmask ) ; /*So that the qc can specify all rockets at once or all bannanas at once*/ \
fieldfunction ( predraw ) ; /*If present, is called just before it's drawn.*/ \
\
fieldstring ( model ) ;
2005-02-09 19:32:09 +00:00
//note: doesn't even have to match the clprogs.dat :)
2005-01-24 05:10:11 +00:00
typedef struct {
2005-02-28 07:16:19 +00:00
# define fieldfloat(name) float name
# define fieldvector(name) vec3_t name
# define fieldentity(name) int name
# define fieldstring(name) string_t name
# define fieldfunction(name) func_t name
csqcfields
# undef fieldfloat
# undef fieldvector
# undef fieldentity
# undef fieldstring
# undef fieldfunction
2005-01-24 05:10:11 +00:00
} csqcentvars_t ;
2005-02-09 19:32:09 +00:00
typedef struct csqcedict_s
2005-01-17 17:43:13 +00:00
{
qboolean isfree ;
float freetime ; // sv.time when the object was freed
int entnum ;
qboolean readonly ; //world
2005-01-24 05:10:11 +00:00
csqcentvars_t v ;
2005-01-17 17:43:13 +00:00
} csqcedict_t ;
2005-02-28 07:16:19 +00:00
csqcedict_t * csqc_edicts ; //consider this 'world'
2005-01-24 05:10:11 +00:00
void CSQC_InitFields ( void )
{ //CHANGING THIS FUNCTION REQUIRES CHANGES TO csqcentvars_t
2005-02-12 18:56:04 +00:00
# define fieldfloat(name) PR_RegisterFieldVar(csqcprogs, ev_float, #name, (int)&((csqcedict_t*)0)->v.name - (int)&((csqcedict_t*)0)->v, -1)
# define fieldvector(name) PR_RegisterFieldVar(csqcprogs, ev_vector, #name, (int)&((csqcedict_t*)0)->v.name - (int)&((csqcedict_t*)0)->v, -1)
# define fieldentity(name) PR_RegisterFieldVar(csqcprogs, ev_entity, #name, (int)&((csqcedict_t*)0)->v.name - (int)&((csqcedict_t*)0)->v, -1)
# define fieldstring(name) PR_RegisterFieldVar(csqcprogs, ev_string, #name, (int)&((csqcedict_t*)0)->v.name - (int)&((csqcedict_t*)0)->v, -1)
# define fieldfunction(name) PR_RegisterFieldVar(csqcprogs, ev_function, #name, (int)&((csqcedict_t*)0)->v.name - (int)&((csqcedict_t*)0)->v, -1)
2005-02-28 07:16:19 +00:00
csqcfields
# undef fieldfloat
# undef fieldvector
# undef fieldentity
# undef fieldstring
# undef fieldfunction
2005-01-24 05:10:11 +00:00
}
2005-02-28 07:16:19 +00:00
csqcedict_t * csqcent [ MAX_EDICTS ] ;
2005-01-17 17:43:13 +00:00
# define RETURN_SSTRING(s) (*(char **)&((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //static - exe will not change it.
char * PF_TempStr ( void ) ;
int csqcentsize ;
//pr_cmds.c builtins that need to be moved to a common.
void VARGS PR_BIError ( progfuncs_t * progfuncs , char * format , . . . ) ;
void PF_cvar_string ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_cvar_set ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_dprint ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_error ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_rint ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_floor ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_ceil ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_Tokenize ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_ArgV ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_FindString ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_FindFloat ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_nextent ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_randomvec ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_Sin ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_Cos ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_Sqrt ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_bound ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_strlen ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_strcat ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_ftos ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_fabs ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_vtos ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_etos ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_stof ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_mod ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_substring ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_stov ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_dupstring ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_forgetstring ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_Spawn ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_min ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_max ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_registercvar ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_pow ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_chr2str ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_localcmd ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_random ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_fopen ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_fclose ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_fputs ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_fgets ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_normalize ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_vlen ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_vectoyaw ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_vectoangles ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_findchain ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_findchainfloat ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_coredump ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_traceon ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_traceoff ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_eprint ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
2005-02-10 00:14:10 +00:00
void PF_strstrofs ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_str2chr ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_chr2str ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_strconv ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_infoadd ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_infoget ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_strncmp ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_strcasecmp ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_strncasecmp ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
2005-02-09 19:32:09 +00:00
//these functions are from pr_menu.dat
void PF_CL_is_cached_pic ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_CL_precache_pic ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_CL_free_pic ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_CL_drawcharacter ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_CL_drawstring ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_CL_drawpic ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_CL_drawfill ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_CL_drawsetcliparea ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_CL_drawresetcliparea ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
void PF_CL_drawgetimagesize ( progfuncs_t * prinst , struct globalvars_s * pr_globals ) ;
2005-02-12 18:56:04 +00:00
# define MAXTEMPBUFFERLEN 1024
2005-01-17 17:43:13 +00:00
void PF_fclose_progs ( progfuncs_t * prinst ) ;
char * PF_VarString ( progfuncs_t * prinst , int first , struct globalvars_s * pr_globals ) ;
2005-02-28 07:16:19 +00:00
static void PF_Remove_ ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
csqcedict_t * ed ;
ed = ( csqcedict_t * ) G_EDICT ( prinst , OFS_PARM0 ) ;
if ( ed - > isfree )
{
Con_DPrintf ( " CSQC Tried removing free entity \n " ) ;
return ;
}
ED_Free ( prinst , ( void * ) ed ) ;
}
2005-01-17 17:43:13 +00:00
static void PF_cvar ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
cvar_t * var ;
char * str ;
str = PR_GetStringOfs ( prinst , OFS_PARM0 ) ;
{
var = Cvar_Get ( str , " " , 0 , " csqc cvars " ) ;
if ( var )
G_FLOAT ( OFS_RETURN ) = var - > value ;
else
G_FLOAT ( OFS_RETURN ) = 0 ;
}
}
//too specific to the prinst's builtins.
static void PF_Fixme ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
Con_Printf ( " \n " ) ;
2005-02-28 07:16:19 +00:00
prinst - > RunError ( prinst , " \n Builtin %i not implemented. \n Menu is not compatable. " , prinst - > lastcalledbuiltinnumber ) ;
2005-01-17 17:43:13 +00:00
PR_BIError ( prinst , " bulitin not implemented " ) ;
}
static void PF_makevectors ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
2005-02-28 07:16:19 +00:00
if ( ! csqcg . forward | | ! csqcg . right | | ! csqcg . up )
Host_EndGame ( " PF_makevectors: one of v_forward, v_right or v_up was not defined \n " ) ;
AngleVectors ( G_VECTOR ( OFS_PARM0 ) , csqcg . forward , csqcg . right , csqcg . up ) ;
2005-01-17 17:43:13 +00:00
}
2005-01-24 05:10:11 +00:00
static void PF_R_AddEntity ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
csqcedict_t * in = ( void * ) G_EDICT ( prinst , OFS_PARM0 ) ;
entity_t ent ;
int i ;
2005-02-28 07:16:19 +00:00
model_t * model ;
if ( in - > v . predraw )
{
int oldself = * csqcg . self ;
* csqcg . self = EDICT_TO_PROG ( prinst , ( void * ) in ) ;
PR_ExecuteProgram ( prinst , in - > v . predraw ) ;
* csqcg . self = oldself ;
}
2005-01-24 05:10:11 +00:00
i = in - > v . modelindex ;
2005-02-12 18:56:04 +00:00
if ( i = = 0 )
return ;
else if ( i > 0 & & i < MAX_MODELS )
2005-02-28 07:16:19 +00:00
model = cl . model_precache [ i ] ;
2005-02-12 18:56:04 +00:00
else if ( i < 0 & & i > - MAX_CSQCMODELS )
2005-02-28 07:16:19 +00:00
model = cl . model_csqcprecache [ - i ] ;
2005-02-12 18:56:04 +00:00
else
2005-01-24 05:10:11 +00:00
return ; //there might be other ent types later as an extension that stop this.
2005-02-28 07:16:19 +00:00
memset ( & ent , 0 , sizeof ( ent ) ) ;
ent . model = model ;
2005-02-12 18:56:04 +00:00
if ( ! ent . model )
{
Con_Printf ( " PF_R_AddEntity: model wasn't precached! \n " ) ;
return ;
}
2005-01-24 05:10:11 +00:00
ent . frame = in - > v . frame ;
ent . oldframe = in - > v . oldframe ;
ent . lerpfrac = in - > v . lerpfrac ;
ent . angles [ 0 ] = in - > v . angles [ 0 ] ;
ent . angles [ 1 ] = in - > v . angles [ 1 ] ;
ent . angles [ 2 ] = in - > v . angles [ 2 ] ;
2005-02-28 07:16:19 +00:00
memcpy ( ent . origin , in - > v . origin , sizeof ( vec3_t ) ) ;
2005-01-24 05:10:11 +00:00
AngleVectors ( ent . angles , ent . axis [ 0 ] , ent . axis [ 1 ] , ent . axis [ 2 ] ) ;
VectorInverse ( ent . axis [ 1 ] ) ;
ent . alpha = in - > v . alpha ;
ent . scale = in - > v . scale ;
V_AddEntity ( & ent ) ;
}
2005-02-28 07:16:19 +00:00
static void PF_R_AddDynamicLight ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
float * org = G_VECTOR ( OFS_PARM0 ) ;
float radius = G_FLOAT ( OFS_PARM1 ) ;
float * rgb = G_VECTOR ( OFS_PARM2 ) ;
V_AddLight ( org , radius , rgb [ 0 ] / 5 , rgb [ 1 ] / 5 , rgb [ 2 ] / 5 ) ;
}
2005-02-09 19:32:09 +00:00
# define MASK_ENGINE 1
static void PF_R_AddEntityMask ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
int mask = G_FLOAT ( OFS_PARM0 ) ;
csqcedict_t * ent ;
int e ;
for ( e = 1 ; e < * prinst - > parms - > sv_num_edicts ; e + + )
{
ent = ( void * ) EDICT_NUM ( prinst , e ) ;
if ( ent - > isfree )
continue ;
if ( ( int ) ent - > v . drawmask & mask )
{
G_INT ( OFS_PARM0 ) = EDICT_TO_PROG ( prinst , ( void * ) ent ) ;
PF_R_AddEntity ( prinst , pr_globals ) ;
}
}
2005-02-12 18:56:04 +00:00
if ( mask & MASK_ENGINE & & cl . worldmodel )
2005-02-09 19:32:09 +00:00
{
2005-02-12 18:56:04 +00:00
CL_LinkViewModel ( ) ;
CL_LinkPlayers ( ) ;
CL_LinkPacketEntities ( ) ;
CL_LinkProjectiles ( ) ;
CL_UpdateTEnts ( ) ;
2005-02-09 19:32:09 +00:00
}
}
2005-02-12 18:56:04 +00:00
//float CalcFov (float fov_x, float width, float height);
2005-01-24 05:10:11 +00:00
//clear scene, and set up the default stuff.
static void PF_R_ClearScene ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
2005-02-09 19:32:09 +00:00
extern frame_t * view_frame ;
extern player_state_t * view_message ;
2005-02-12 18:56:04 +00:00
CL_DecayLights ( ) ;
if ( cl . worldmodel )
{
//work out which packet entities are solid
CL_SetSolidEntities ( ) ;
// Set up prediction for other players
CL_SetUpPlayerPrediction ( false ) ;
// do client side motion prediction
CL_PredictMove ( ) ;
// Set up prediction for other players
CL_SetUpPlayerPrediction ( true ) ;
}
CL_SwapEntityLists ( ) ;
2005-02-09 19:32:09 +00:00
view_frame = & cl . frames [ cls . netchan . incoming_sequence & UPDATE_MASK ] ;
view_message = & view_frame - > playerstate [ cl . playernum [ 0 ] ] ;
V_CalcRefdef ( 0 ) ; //set up the defaults (for player 0)
/*
2005-01-24 05:10:11 +00:00
VectorCopy ( cl . simangles [ 0 ] , r_refdef . viewangles ) ;
2005-02-09 19:32:09 +00:00
VectorCopy ( cl . simorg [ 0 ] , r_refdef . vieworg ) ;
2005-01-24 05:10:11 +00:00
r_refdef . flags = 0 ;
r_refdef . vrect . x = 0 ;
r_refdef . vrect . y = 0 ;
r_refdef . vrect . width = vid . width ;
r_refdef . vrect . height = vid . height ;
2005-02-09 19:32:09 +00:00
r_refdef . fov_x = scr_fov . value ;
r_refdef . fov_y = CalcFov ( r_refdef . fov_x , r_refdef . vrect . width , r_refdef . vrect . height ) ;
*/
2005-01-24 05:10:11 +00:00
}
static void PF_R_SetViewFlag ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
char * s = PR_GetStringOfs ( prinst , OFS_PARM0 ) ;
float * p = G_VECTOR ( OFS_PARM1 ) ;
switch ( * s )
{
case ' F ' :
if ( ! strcmp ( s , " FOV " ) ) //set both fov numbers
{
r_refdef . fov_x = p [ 0 ] ;
r_refdef . fov_y = p [ 1 ] ;
return ;
}
if ( ! strcmp ( s , " FOV_X " ) )
{
r_refdef . fov_x = * p ;
return ;
}
if ( ! strcmp ( s , " FOV_Y " ) )
{
r_refdef . fov_y = * p ;
return ;
}
break ;
case ' O ' :
if ( ! strcmp ( s , " ORIGIN " ) )
{
VectorCopy ( p , r_refdef . vieworg ) ;
return ;
}
if ( ! strcmp ( s , " ORIGIN_X " ) )
{
r_refdef . vieworg [ 0 ] = * p ;
return ;
}
if ( ! strcmp ( s , " ORIGIN_Y " ) )
{
r_refdef . vieworg [ 1 ] = * p ;
return ;
}
if ( ! strcmp ( s , " ORIGIN_Z " ) )
{
r_refdef . vieworg [ 2 ] = * p ;
return ;
}
break ;
case ' A ' :
if ( ! strcmp ( s , " ANGLES " ) )
{
VectorCopy ( p , r_refdef . viewangles ) ;
return ;
}
if ( ! strcmp ( s , " ANGLES_X " ) )
{
r_refdef . viewangles [ 0 ] = * p ;
return ;
}
if ( ! strcmp ( s , " ANGLES_Y " ) )
{
r_refdef . viewangles [ 1 ] = * p ;
return ;
}
if ( ! strcmp ( s , " ANGLES_Z " ) )
{
r_refdef . viewangles [ 2 ] = * p ;
return ;
}
break ;
case ' W ' :
if ( ! strcmp ( s , " WIDTH " ) )
{
r_refdef . vrect . width = * p ;
return ;
}
break ;
case ' H ' :
if ( ! strcmp ( s , " HEIGHT " ) )
{
r_refdef . vrect . height = * p ;
return ;
}
break ;
case ' S ' :
if ( ! strcmp ( s , " SIZE " ) )
{
r_refdef . vrect . width = p [ 0 ] ;
r_refdef . vrect . height = p [ 1 ] ;
return ;
}
break ;
case ' M ' :
if ( ! strcmp ( s , " MIN_X " ) )
{
r_refdef . vrect . x = * p ;
return ;
}
if ( ! strcmp ( s , " MIN_Y " ) )
{
r_refdef . vrect . y = * p ;
return ;
}
if ( ! strcmp ( s , " MIN " ) )
{
r_refdef . vrect . x = p [ 0 ] ;
r_refdef . vrect . y = p [ 1 ] ;
return ;
}
break ;
default :
break ;
}
Con_DPrintf ( " SetViewFlag: %s not recognised \n " , s ) ;
}
static void PF_R_RenderScene ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
2005-02-28 07:16:19 +00:00
if ( cl . worldmodel )
R_PushDlights ( ) ;
2005-02-09 19:32:09 +00:00
2005-01-24 05:10:11 +00:00
# ifdef RGLQUAKE
if ( qrenderer = = QR_OPENGL )
{
gl_ztrickdisabled | = 16 ;
qglDisable ( GL_ALPHA_TEST ) ;
qglDisable ( GL_BLEND ) ;
}
# endif
R_RenderView ( ) ;
# ifdef RGLQUAKE
if ( qrenderer = = QR_OPENGL )
{
gl_ztrickdisabled & = ~ 16 ;
GL_Set2D ( ) ;
qglBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
GL_TexEnv ( GL_MODULATE ) ;
}
# endif
# ifdef RGLQUAKE
if ( qrenderer = = QR_OPENGL )
{
qglDisable ( GL_ALPHA_TEST ) ;
qglEnable ( GL_BLEND ) ;
}
# endif
vid . recalc_refdef = 1 ;
}
2005-01-17 17:43:13 +00:00
2005-02-10 00:14:10 +00:00
static void PF_cs_getstatf ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
int stnum = G_FLOAT ( OFS_PARM0 ) ;
float val = * ( float * ) & cl . stats [ 0 ] [ stnum ] ; //copy float into the stat
G_FLOAT ( OFS_RETURN ) = val ;
}
static void PF_cs_getstati ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
2005-02-12 18:56:04 +00:00
{ //convert an int stat into a qc float.
2005-02-10 00:14:10 +00:00
int stnum = G_FLOAT ( OFS_PARM0 ) ;
2005-02-12 18:56:04 +00:00
int val = cl . stats [ 0 ] [ stnum ] ;
if ( * prinst - > callargc > 1 )
{
int first , count ;
first = G_FLOAT ( OFS_PARM1 ) ;
count = G_FLOAT ( OFS_PARM2 ) ;
G_FLOAT ( OFS_RETURN ) = ( ( ( unsigned int ) val ) & ( ( ( 1 < < count ) - 1 ) < < first ) ) > > first ;
}
2005-02-10 00:14:10 +00:00
else
2005-02-12 18:56:04 +00:00
G_FLOAT ( OFS_RETURN ) = val ;
2005-02-10 00:14:10 +00:00
}
static void PF_cs_getstats ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
int stnum = G_FLOAT ( OFS_PARM0 ) ;
char * out ;
out = PF_TempStr ( ) ;
//the network protocol byteswaps
( ( unsigned int * ) out ) [ 0 ] = LittleLong ( cl . stats [ 0 ] [ stnum + 0 ] ) ;
( ( unsigned int * ) out ) [ 1 ] = LittleLong ( cl . stats [ 0 ] [ stnum + 1 ] ) ;
( ( unsigned int * ) out ) [ 2 ] = LittleLong ( cl . stats [ 0 ] [ stnum + 2 ] ) ;
( ( unsigned int * ) out ) [ 3 ] = LittleLong ( cl . stats [ 0 ] [ stnum + 3 ] ) ;
( ( unsigned int * ) out ) [ 4 ] = 0 ; //make sure it's null terminated
RETURN_SSTRING ( out ) ;
}
2005-02-12 18:56:04 +00:00
static void PF_CSQC_SetOrigin ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
csqcedict_t * ent = ( void * ) G_EDICT ( prinst , OFS_PARM0 ) ;
float * org = G_VECTOR ( OFS_PARM1 ) ;
VectorCopy ( org , ent - > v . origin ) ;
//fixme: add some sort of fast area grid
}
2005-02-28 07:16:19 +00:00
//FIXME: Not fully functional
static void PF_CSQC_traceline ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
float * v1 , * v2 , * mins , * maxs ;
trace_t trace ;
int nomonsters ;
edict_t * ent ;
// int savedhull;
v1 = G_VECTOR ( OFS_PARM0 ) ;
v2 = G_VECTOR ( OFS_PARM1 ) ;
nomonsters = G_FLOAT ( OFS_PARM2 ) ;
ent = G_EDICT ( prinst , OFS_PARM3 ) ;
// if (*prinst->callargc == 6)
// {
// mins = G_VECTOR(OFS_PARM4);
// maxs = G_VECTOR(OFS_PARM5);
// }
// else
{
mins = vec3_origin ;
maxs = vec3_origin ;
}
/*
savedhull = ent - > v . hull ;
ent - > v . hull = 0 ;
trace = SV_Move ( v1 , mins , maxs , v2 , nomonsters , ent ) ;
ent - > v . hull = savedhull ;
*/
memset ( & trace , 0 , sizeof ( trace ) ) ;
trace . fraction = 1 ;
cl . worldmodel - > hulls - > funcs . RecursiveHullCheck ( cl . worldmodel - > hulls , 0 , 0 , 1 , v1 , v2 , & trace ) ;
* csqcg . trace_allsolid = trace . allsolid ;
* csqcg . trace_startsolid = trace . startsolid ;
* csqcg . trace_fraction = trace . fraction ;
* csqcg . trace_inwater = trace . inwater ;
* csqcg . trace_inopen = trace . inopen ;
VectorCopy ( trace . endpos , csqcg . trace_endpos ) ;
VectorCopy ( trace . plane . normal , csqcg . trace_plane_normal ) ;
* csqcg . trace_plane_dist = trace . plane . dist ;
// if (trace.ent)
// *csqcg.trace_ent = EDICT_TO_PROG(prinst, trace.ent);
// else
* csqcg . trace_ent = EDICT_TO_PROG ( prinst , ( void * ) csqc_edicts ) ;
}
static void PF_CSQC_pointcontents ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
float * v ;
int cont ;
v = G_VECTOR ( OFS_PARM0 ) ;
cont = cl . worldmodel - > hulls [ 0 ] . funcs . HullPointContents ( & cl . worldmodel - > hulls [ 0 ] , v ) ;
if ( cont & FTECONTENTS_SOLID )
G_FLOAT ( OFS_RETURN ) = Q1CONTENTS_SOLID ;
else if ( cont & FTECONTENTS_SKY )
G_FLOAT ( OFS_RETURN ) = Q1CONTENTS_SKY ;
else if ( cont & FTECONTENTS_LAVA )
G_FLOAT ( OFS_RETURN ) = Q1CONTENTS_LAVA ;
else if ( cont & FTECONTENTS_SLIME )
G_FLOAT ( OFS_RETURN ) = Q1CONTENTS_SLIME ;
else if ( cont & FTECONTENTS_WATER )
G_FLOAT ( OFS_RETURN ) = Q1CONTENTS_WATER ;
else
G_FLOAT ( OFS_RETURN ) = Q1CONTENTS_EMPTY ;
}
2005-02-12 18:56:04 +00:00
static int FindModel ( char * name , int * free )
{
int i ;
* free = 0 ;
for ( i = 1 ; i < MAX_CSQCMODELS ; i + + )
{
if ( ! * cl . model_csqcname [ i ] )
{
* free = - i ;
break ;
}
if ( ! strcmp ( cl . model_csqcname [ i ] , name ) )
return - i ;
}
for ( i = 1 ; i < MAX_MODELS ; i + + )
{
if ( ! strcmp ( cl . model_name [ i ] , name ) )
return i ;
}
return 0 ;
}
static void PF_CSQC_SetModel ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
csqcedict_t * ent = ( void * ) G_EDICT ( prinst , OFS_PARM0 ) ;
char * modelname = PR_GetStringOfs ( prinst , OFS_PARM1 ) ;
int freei ;
int modelindex = FindModel ( modelname , & freei ) ;
if ( ! modelindex )
{
if ( ! freei )
Host_EndGame ( " CSQC ran out of model slots \n " ) ;
Con_DPrintf ( " Late caching model \" %s \" \n " , modelname ) ;
Q_strncpyz ( cl . model_csqcname [ - freei ] , modelname , sizeof ( cl . model_csqcname [ - freei ] ) ) ; //allocate a slot now
modelindex = freei ;
cl . model_csqcprecache [ - freei ] = Mod_ForName ( cl . model_csqcname [ - freei ] , false ) ;
}
ent - > v . modelindex = modelindex ;
if ( modelindex < 0 )
ent - > v . model = PR_SetString ( prinst , cl . model_csqcname [ - modelindex ] ) ;
else
ent - > v . model = PR_SetString ( prinst , cl . model_name [ modelindex ] ) ;
}
static void PF_CSQC_SetModelIndex ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
csqcedict_t * ent = ( void * ) G_EDICT ( prinst , OFS_PARM0 ) ;
int modelindex = G_FLOAT ( OFS_PARM1 ) ;
ent - > v . modelindex = modelindex ;
if ( modelindex < 0 )
ent - > v . model = PR_SetString ( prinst , cl . model_csqcname [ - modelindex ] ) ;
else
ent - > v . model = PR_SetString ( prinst , cl . model_name [ modelindex ] ) ;
}
static void PF_CSQC_PrecacheModel ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
2005-02-28 07:16:19 +00:00
int modelindex , freei ;
2005-02-12 18:56:04 +00:00
char * modelname = PR_GetStringOfs ( prinst , OFS_PARM0 ) ;
int i ;
2005-02-28 07:16:19 +00:00
for ( i = 1 ; i < MAX_MODELS ; i + + ) //Make sure that the server specified model is loaded..
2005-02-12 18:56:04 +00:00
{
if ( ! * cl . model_name [ i ] )
break ;
if ( ! strcmp ( cl . model_name [ i ] , modelname ) )
{
cl . model_precache [ i ] = Mod_ForName ( cl . model_name [ i ] , false ) ;
break ;
}
}
2005-02-28 07:16:19 +00:00
modelindex = FindModel ( modelname , & freei ) ; //now load it
if ( ! modelindex )
{
if ( ! freei )
Host_EndGame ( " CSQC ran out of model slots \n " ) ;
Q_strncpyz ( cl . model_csqcname [ - freei ] , modelname , sizeof ( cl . model_csqcname [ - freei ] ) ) ; //allocate a slot now
modelindex = freei ;
cl . model_csqcprecache [ - freei ] = Mod_ForName ( cl . model_csqcname [ - freei ] , false ) ;
}
}
static void PF_CSQC_PrecacheSound ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
char * soundname = PR_GetStringOfs ( prinst , OFS_PARM0 ) ;
S_PrecacheSound ( soundname ) ;
2005-02-12 18:56:04 +00:00
}
2005-02-28 07:16:19 +00:00
2005-02-12 18:56:04 +00:00
static void PF_CSQC_ModelnameForIndex ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
int modelindex = G_FLOAT ( OFS_PARM0 ) ;
if ( modelindex < 0 )
G_INT ( OFS_RETURN ) = ( int ) PR_SetString ( prinst , cl . model_csqcname [ - modelindex ] ) ;
else
G_INT ( OFS_RETURN ) = ( int ) PR_SetString ( prinst , cl . model_name [ modelindex ] ) ;
}
2005-01-17 17:43:13 +00:00
2005-02-28 07:16:19 +00:00
static void PF_ReadByte ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
G_FLOAT ( OFS_RETURN ) = MSG_ReadByte ( ) ;
}
static void PF_ReadChar ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
G_FLOAT ( OFS_RETURN ) = MSG_ReadChar ( ) ;
}
static void PF_ReadShort ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
G_FLOAT ( OFS_RETURN ) = MSG_ReadShort ( ) ;
}
static void PF_ReadLong ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
G_FLOAT ( OFS_RETURN ) = MSG_ReadLong ( ) ;
}
static void PF_ReadCoord ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
G_FLOAT ( OFS_RETURN ) = MSG_ReadCoord ( ) ;
}
static void PF_ReadString ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
char * str = PF_TempStr ( ) ;
char * read = MSG_ReadString ( ) ;
Q_strncpyz ( str , read , MAXTEMPBUFFERLEN ) ;
}
static void PF_ReadAngle ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
G_FLOAT ( OFS_RETURN ) = MSG_ReadAngle ( ) ;
}
static void PF_objerror ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
char * s ;
edict_t * ed ;
s = PF_VarString ( prinst , 0 , pr_globals ) ;
/* Con_Printf ("======OBJECT ERROR in %s:\n%s\n", PR_GetString(pr_xfunction->s_name),s);
*/ ed = PROG_TO_EDICT ( prinst , pr_global_struct - > self ) ;
/* ED_Print (ed);
*/
ED_Print ( prinst , ed ) ;
Con_Printf ( " %s " , s ) ;
if ( developer . value )
( * prinst - > pr_trace ) = 2 ;
else
{
ED_Free ( prinst , ed ) ;
prinst - > AbortStack ( prinst ) ;
PR_BIError ( prinst , " Program error: %s " , s ) ;
if ( sv . time > 10 )
Cbuf_AddText ( " restart \n " , RESTRICT_LOCAL ) ;
}
}
static void PF_cs_setsensativityscaler ( progfuncs_t * prinst , struct globalvars_s * pr_globals )
{
in_sensitivityscale = G_FLOAT ( OFS_PARM0 ) ;
}
2005-01-17 17:43:13 +00:00
//warning: functions that depend on globals are bad, mkay?
builtin_t csqc_builtins [ ] = {
//0
PF_Fixme ,
PF_makevectors ,
2005-02-12 18:56:04 +00:00
PF_CSQC_SetOrigin , //PF_setorigin
PF_CSQC_SetModel , //PF_setmodel
2005-01-17 17:43:13 +00:00
PF_Fixme , //PF_setsize
PF_Fixme ,
PF_Fixme , //PF_break,
PF_random ,
PF_Fixme , //PF_sound,
PF_normalize ,
//10
PF_error ,
2005-02-28 07:16:19 +00:00
PF_objerror ,
2005-01-17 17:43:13 +00:00
PF_vlen ,
PF_vectoyaw ,
PF_Spawn ,
2005-02-28 07:16:19 +00:00
PF_Remove_ , //PF_Remove,
PF_CSQC_traceline , //PF_traceline,
2005-02-12 18:56:04 +00:00
PF_Fixme , //PF_checkclient, (don't support)
2005-01-17 17:43:13 +00:00
PF_FindString ,
2005-02-28 07:16:19 +00:00
PF_CSQC_PrecacheSound , //PF_precache_sound,
2005-01-17 17:43:13 +00:00
//20
2005-02-12 18:56:04 +00:00
PF_CSQC_PrecacheModel , //PF_precache_model,
PF_Fixme , //PF_stuffcmd, (don't support)
2005-01-17 17:43:13 +00:00
PF_Fixme , //PF_findradius,
2005-02-12 18:56:04 +00:00
PF_Fixme , //PF_bprint, (don't support)
2005-01-17 17:43:13 +00:00
PF_Fixme , //PF_sprint,
PF_dprint ,
PF_ftos ,
PF_vtos ,
PF_coredump ,
PF_traceon ,
//30
PF_traceoff ,
PF_eprint ,
2005-02-12 18:56:04 +00:00
PF_Fixme , //PF_walkmove, (don't support yet)
2005-01-17 17:43:13 +00:00
PF_Fixme ,
PF_Fixme , //PF_droptofloor,
PF_Fixme , //PF_lightstyle,
PF_rint ,
PF_floor ,
PF_ceil ,
PF_Fixme ,
//40
PF_Fixme , //PF_checkbottom,
2005-02-28 07:16:19 +00:00
PF_CSQC_pointcontents , //PF_pointcontents,
2005-01-17 17:43:13 +00:00
PF_Fixme ,
PF_fabs ,
2005-02-12 18:56:04 +00:00
PF_Fixme , //PF_aim, hehehe... (don't support)
2005-01-17 17:43:13 +00:00
PF_cvar ,
PF_localcmd ,
PF_nextent ,
PF_Fixme , //PF_particle,
PF_Fixme , //PF_changeyaw,
//50
PF_Fixme ,
PF_vectoangles ,
2005-02-28 07:16:19 +00:00
PF_ReadByte ,
PF_ReadChar ,
PF_ReadShort ,
PF_ReadLong ,
PF_ReadCoord ,
PF_ReadAngle ,
PF_ReadString ,
PF_Fixme , //PF_ReadEntity,
2005-01-17 17:43:13 +00:00
//60
PF_Fixme ,
PF_Sin ,
PF_Cos ,
PF_Sqrt ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
SV_MoveToGoal ,
2005-02-12 18:56:04 +00:00
PF_Fixme , //PF_precache_file, (don't support)
2005-01-17 17:43:13 +00:00
PF_Fixme , //PF_makestatic,
//70
2005-02-12 18:56:04 +00:00
PF_Fixme , //PF_changelevel, (don't support)
2005-01-17 17:43:13 +00:00
PF_Fixme ,
PF_cvar_set ,
PF_Fixme , //PF_centerprint,
PF_Fixme , //PF_ambientsound,
2005-02-28 07:16:19 +00:00
PF_CSQC_PrecacheModel , //PF_precache_model,
2005-01-17 17:43:13 +00:00
PF_Fixme , //PF_precache_sound,
PF_Fixme , //PF_precache_file,
PF_Fixme , //PF_setspawnparms,
2005-02-12 18:56:04 +00:00
PF_Fixme , //PF_logfrag, (don't support)
2005-01-17 17:43:13 +00:00
//80
PF_Fixme , //PF_infokey,
PF_stof ,
2005-02-12 18:56:04 +00:00
PF_Fixme , //PF_multicast, (don't support)
2005-01-17 17:43:13 +00:00
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
//90
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
//100
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
//110
2005-02-10 00:14:10 +00:00
PF_fopen ,
PF_fclose ,
PF_fgets ,
PF_fputs ,
PF_strlen ,
2005-01-17 17:43:13 +00:00
2005-02-10 00:14:10 +00:00
PF_strcat ,
PF_substring ,
PF_stov ,
PF_dupstring ,
PF_forgetstring ,
2005-01-17 17:43:13 +00:00
2005-02-09 19:32:09 +00:00
//120
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
//130
PF_R_ClearScene ,
PF_R_AddEntityMask ,
PF_R_AddEntity ,
PF_R_SetViewFlag ,
PF_R_RenderScene ,
2005-02-28 07:16:19 +00:00
PF_R_AddDynamicLight ,
2005-02-09 19:32:09 +00:00
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
//140
PF_CL_is_cached_pic , //0
PF_CL_precache_pic , //1
PF_CL_free_pic , //2
PF_CL_drawcharacter , //3
PF_CL_drawstring , //4
PF_CL_drawpic , //5
PF_CL_drawfill , //6
PF_CL_drawsetcliparea , //7
PF_CL_drawresetcliparea , //8
PF_CL_drawgetimagesize , //9
2005-01-17 17:43:13 +00:00
2005-02-10 00:14:10 +00:00
//150
PF_cs_getstatf ,
PF_cs_getstati ,
PF_cs_getstats ,
2005-02-28 07:16:19 +00:00
PF_CSQC_SetModelIndex ,
PF_CSQC_ModelnameForIndex ,
2005-02-10 00:14:10 +00:00
2005-02-28 07:16:19 +00:00
PF_cs_setsensativityscaler ,
2005-02-10 00:14:10 +00:00
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
//160
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
//170
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
//180
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
//190
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
//200
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
//210
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
//220
PF_Fixme ,
PF_strstrofs ,
PF_str2chr ,
PF_chr2str ,
PF_strconv ,
PF_infoadd ,
PF_infoget ,
PF_strncmp ,
PF_strcasecmp ,
PF_strncasecmp ,
//230
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
//240
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme ,
PF_Fixme
2005-02-09 19:32:09 +00:00
} ;
2005-01-17 17:43:13 +00:00
int csqc_numbuiltins = sizeof ( csqc_builtins ) / sizeof ( csqc_builtins [ 0 ] ) ;
jmp_buf csqc_abort ;
progparms_t csqcprogparms ;
int num_csqc_edicts ;
int COM_FileSize ( char * path ) ;
pbool QC_WriteFile ( char * name , void * data , int len ) ;
void * VARGS PR_Malloc ( int size ) ; //these functions should be tracked by the library reliably, so there should be no need to track them ourselves.
void VARGS PR_Free ( void * mem ) ;
//Any menu builtin error or anything like that will come here.
2005-02-09 19:32:09 +00:00
void VARGS CSQC_Abort ( char * format , . . . ) //an error occured.
2005-01-17 17:43:13 +00:00
{
va_list argptr ;
char string [ 1024 ] ;
va_start ( argptr , format ) ;
_vsnprintf ( string , sizeof ( string ) - 1 , format , argptr ) ;
va_end ( argptr ) ;
Con_Printf ( " CSQC_Abort: %s \n Shutting down csqc \n " , string ) ;
{
static char buffer [ 1024 * 1024 * 8 ] ;
int size = sizeof buffer ;
csqcprogs - > save_ents ( csqcprogs , buffer , & size , 3 ) ;
COM_WriteFile ( " csqccore.txt " , buffer , size ) ;
}
Host_EndGame ( " csqc error " ) ;
}
2005-02-09 19:32:09 +00:00
void CSQC_Shutdown ( void )
{
if ( csqcprogs )
{
CloseProgs ( csqcprogs ) ;
Con_Printf ( " Closed csqc \n " ) ;
}
csqcprogs = NULL ;
2005-02-28 07:16:19 +00:00
in_sensitivityscale = 1 ;
2005-01-24 05:10:11 +00:00
}
2005-01-17 17:43:13 +00:00
double csqctime ;
void CSQC_Init ( void )
{
2005-02-09 19:32:09 +00:00
CSQC_Shutdown ( ) ;
2005-01-17 17:43:13 +00:00
if ( ! qrenderer )
{
return ;
}
2005-02-12 18:56:04 +00:00
memset ( cl . model_csqcname , 0 , sizeof ( cl . model_csqcname ) ) ;
memset ( cl . model_csqcprecache , 0 , sizeof ( cl . model_csqcprecache ) ) ;
2005-01-17 17:43:13 +00:00
csqcprogparms . progsversion = PROGSTRUCT_VERSION ;
csqcprogparms . ReadFile = COM_LoadStackFile ; //char *(*ReadFile) (char *fname, void *buffer, int *len);
csqcprogparms . FileSize = COM_FileSize ; //int (*FileSize) (char *fname); //-1 if file does not exist
csqcprogparms . WriteFile = QC_WriteFile ; //bool (*WriteFile) (char *name, void *data, int len);
csqcprogparms . printf = ( void * ) Con_Printf ; //Con_Printf;//void (*printf) (char *, ...);
csqcprogparms . Sys_Error = Sys_Error ;
csqcprogparms . Abort = CSQC_Abort ;
2005-02-28 07:16:19 +00:00
csqcprogparms . edictsize = sizeof ( csqcedict_t ) - sizeof ( csqcentvars_t ) ;
2005-01-17 17:43:13 +00:00
csqcprogparms . entspawn = NULL ; //void (*entspawn) (struct edict_s *ent); //ent has been spawned, but may not have all the extra variables (that may need to be set) set
csqcprogparms . entcanfree = NULL ; //bool (*entcanfree) (struct edict_s *ent); //return true to stop ent from being freed
csqcprogparms . stateop = NULL ; //StateOp;//void (*stateop) (float var, func_t func);
csqcprogparms . cstateop = NULL ; //CStateOp;
csqcprogparms . cwstateop = NULL ; //CWStateOp;
csqcprogparms . thinktimeop = NULL ; //ThinkTimeOp;
//used when loading a game
csqcprogparms . builtinsfor = NULL ; //builtin_t *(*builtinsfor) (int num); //must return a pointer to the builtins that were used before the state was saved.
csqcprogparms . loadcompleate = NULL ; //void (*loadcompleate) (int edictsize); //notification to reset any pointers.
csqcprogparms . memalloc = PR_Malloc ; //void *(*memalloc) (int size); //small string allocation malloced and freed randomly
csqcprogparms . memfree = PR_Free ; //void (*memfree) (void * mem);
csqcprogparms . globalbuiltins = csqc_builtins ; //builtin_t *globalbuiltins; //these are available to all progs
csqcprogparms . numglobalbuiltins = csqc_numbuiltins ;
csqcprogparms . autocompile = PR_NOCOMPILE ; //enum {PR_NOCOMPILE, PR_COMPILENEXIST, PR_COMPILECHANGED, PR_COMPILEALWAYS} autocompile;
csqcprogparms . gametime = & csqctime ;
csqcprogparms . sv_edicts = ( edict_t * * ) & csqc_edicts ;
csqcprogparms . sv_num_edicts = & num_csqc_edicts ;
csqcprogparms . useeditor = NULL ; //sorry... QCEditor;//void (*useeditor) (char *filename, int line, int nump, char **parms);
csqctime = Sys_DoubleTime ( ) ;
if ( ! csqcprogs )
{
2005-02-28 07:16:19 +00:00
in_sensitivityscale = 1 ;
2005-01-17 17:43:13 +00:00
csqcprogs = InitProgs ( & csqcprogparms ) ;
PR_Configure ( csqcprogs , NULL , - 1 , 1 ) ;
2005-01-24 05:10:11 +00:00
CSQC_InitFields ( ) ; //let the qclib know the field order that the engine needs.
2005-02-06 02:47:36 +00:00
if ( PR_LoadProgs ( csqcprogs , " csprogs.dat " , 0 , NULL , 0 ) < 0 ) //no per-progs builtins.
2005-01-17 17:43:13 +00:00
{
2005-02-09 19:32:09 +00:00
CSQC_Shutdown ( ) ;
2005-01-17 17:43:13 +00:00
//failed to load or something
return ;
}
if ( setjmp ( csqc_abort ) )
{
2005-02-09 19:32:09 +00:00
CSQC_Shutdown ( ) ;
2005-01-17 17:43:13 +00:00
return ;
}
2005-02-28 07:16:19 +00:00
memset ( csqcent , 0 , sizeof ( csqcent ) ) ;
2005-01-24 05:10:11 +00:00
2005-01-17 17:43:13 +00:00
csqcentsize = PR_InitEnts ( csqcprogs , 3072 ) ;
2005-01-24 05:10:11 +00:00
CSQC_FindGlobals ( ) ;
2005-01-17 17:43:13 +00:00
2005-02-28 07:16:19 +00:00
ED_Alloc ( csqcprogs ) ; //we need a word entity.
2005-01-24 05:10:11 +00:00
//world edict becomes readonly
2005-01-17 17:43:13 +00:00
EDICT_NUM ( csqcprogs , 0 ) - > readonly = true ;
EDICT_NUM ( csqcprogs , 0 ) - > isfree = false ;
2005-02-28 07:16:19 +00:00
if ( csqcg . init_function )
PR_ExecuteProgram ( csqcprogs , csqcg . init_function ) ;
2005-02-09 19:32:09 +00:00
Con_Printf ( " Loaded csqc \n " ) ;
2005-01-17 17:43:13 +00:00
}
}
qboolean CSQC_DrawView ( void )
{
2005-02-28 07:16:19 +00:00
if ( ! csqcg . draw_function | | ! csqcprogs )
2005-01-17 17:43:13 +00:00
return false ;
2005-02-12 18:56:04 +00:00
r_secondaryview = 0 ;
if ( cl . worldmodel )
R_LessenStains ( ) ;
2005-02-09 19:32:09 +00:00
2005-02-28 07:16:19 +00:00
if ( csqcg . time )
* csqcg . time = Sys_DoubleTime ( ) ;
PR_ExecuteProgram ( csqcprogs , csqcg . draw_function ) ;
2005-01-17 17:43:13 +00:00
return true ;
}
2005-02-12 18:56:04 +00:00
qboolean CSQC_StuffCmd ( char * cmd )
{
void * pr_globals ;
char * str ;
2005-02-28 07:16:19 +00:00
if ( ! csqcprogs | | ! csqcg . parse_stuffcmd )
2005-02-12 18:56:04 +00:00
return false ;
str = PF_TempStr ( ) ;
Q_strncpyz ( str , cmd , MAXTEMPBUFFERLEN ) ;
pr_globals = PR_globals ( csqcprogs , PR_CURRENT ) ;
( * ( char * * ) & ( ( int * ) pr_globals ) [ OFS_PARM0 ] = PR_SetString ( csqcprogs , str ) ) ;
2005-02-28 07:16:19 +00:00
PR_ExecuteProgram ( csqcprogs , csqcg . parse_stuffcmd ) ;
2005-02-12 18:56:04 +00:00
return true ;
}
qboolean CSQC_CenterPrint ( char * cmd )
{
void * pr_globals ;
char * str ;
2005-02-28 07:16:19 +00:00
if ( ! csqcprogs | | ! csqcg . parse_centerprint )
2005-02-12 18:56:04 +00:00
return false ;
str = PF_TempStr ( ) ;
Q_strncpyz ( str , cmd , MAXTEMPBUFFERLEN ) ;
pr_globals = PR_globals ( csqcprogs , PR_CURRENT ) ;
( * ( char * * ) & ( ( int * ) pr_globals ) [ OFS_PARM0 ] = PR_SetString ( csqcprogs , str ) ) ;
2005-02-28 07:16:19 +00:00
PR_ExecuteProgram ( csqcprogs , csqcg . parse_centerprint ) ;
2005-02-12 18:56:04 +00:00
return G_FLOAT ( OFS_RETURN ) ;
}
//this protocol allows up to 32767 edicts.
2005-02-28 07:16:19 +00:00
# ifdef PEXT_CSQC
2005-02-09 19:32:09 +00:00
void CSQC_ParseEntities ( void )
{
2005-02-12 18:56:04 +00:00
csqcedict_t * ent ;
unsigned short entnum ;
2005-02-28 07:16:19 +00:00
void * pr_globals ;
2005-02-12 18:56:04 +00:00
if ( ! csqcprogs )
2005-02-28 07:16:19 +00:00
Host_EndGame ( " CSQC needs to be initialized on this server. \n " ) ;
pr_globals = PR_globals ( csqcprogs , PR_CURRENT ) ;
if ( csqcg . time )
* csqcg . time = Sys_DoubleTime ( ) ;
2005-02-12 18:56:04 +00:00
for ( ; ; )
{
entnum = MSG_ReadShort ( ) ;
if ( ! entnum )
break ;
if ( entnum & 0x8000 )
{ //remove
entnum & = ~ 0x8000 ;
if ( ! entnum )
2005-02-28 07:16:19 +00:00
Host_EndGame ( " CSQC cannot remove world! \n " ) ;
if ( entnum > = MAX_EDICTS )
Host_EndGame ( " CSQC recieved too many edicts! \n " ) ;
2005-02-12 18:56:04 +00:00
ent = csqcent [ entnum ] ;
if ( ! ent ) //hrm.
continue ;
2005-02-28 07:16:19 +00:00
* csqcg . self = EDICT_TO_PROG ( csqcprogs , ( void * ) ent ) ;
PR_ExecuteProgram ( csqcprogs , csqcg . ent_remove ) ;
2005-02-12 18:56:04 +00:00
csqcent [ entnum ] = NULL ;
//the csqc is expected to call the remove builtin.
}
else
{
2005-02-28 07:16:19 +00:00
if ( entnum > = MAX_EDICTS )
Host_EndGame ( " CSQC recieved too many edicts! \n " ) ;
2005-02-12 18:56:04 +00:00
ent = csqcent [ entnum ] ;
if ( ! ent )
{
2005-02-28 07:16:19 +00:00
ent = ( csqcedict_t * ) ED_Alloc ( csqcprogs ) ;
csqcent [ entnum ] = ent ;
2005-02-12 18:56:04 +00:00
G_FLOAT ( OFS_PARM0 ) = true ;
}
else
G_FLOAT ( OFS_PARM0 ) = false ;
2005-02-28 07:16:19 +00:00
* csqcg . self = EDICT_TO_PROG ( csqcprogs , ( void * ) ent ) ;
PR_ExecuteProgram ( csqcprogs , csqcg . ent_update ) ;
2005-02-12 18:56:04 +00:00
}
2005-02-28 07:16:19 +00:00
}
2005-02-09 19:32:09 +00:00
}
2005-02-28 07:16:19 +00:00
# endif
2005-02-09 19:32:09 +00:00
2005-01-17 17:43:13 +00:00
# endif