796 lines
22 KiB
C
796 lines
22 KiB
C
//=======================================================================
|
|
// Copyright XashXT Group 2008 ©
|
|
// cl_progs.c - client.dat interface
|
|
//=======================================================================
|
|
|
|
#include "common.h"
|
|
#include "client.h"
|
|
|
|
#define STAT_MINUS 10 // num frame for '-' stats digit
|
|
|
|
const char *field_nums[11] =
|
|
{
|
|
"hud/num_0",
|
|
"hud/num_1",
|
|
"hud/num_2",
|
|
"hud/num_3",
|
|
"hud/num_4",
|
|
"hud/num_5",
|
|
"hud/num_6",
|
|
"hud/num_7",
|
|
"hud/num_8",
|
|
"hud/num_9",
|
|
"hud/num_-",
|
|
};
|
|
|
|
static shader_t field_shaders[11];
|
|
|
|
/*
|
|
================
|
|
CL_FadeColor
|
|
================
|
|
*/
|
|
float *CL_FadeColor( float starttime, float endtime )
|
|
{
|
|
static vec4_t color;
|
|
float time, fade_time;
|
|
|
|
if( starttime == 0 ) return NULL;
|
|
time = (cls.realtime * 0.001f) - starttime;
|
|
if( time >= endtime ) return NULL;
|
|
|
|
// fade time is 1/4 of endtime
|
|
fade_time = endtime / 4;
|
|
fade_time = bound( 0.3f, fade_time, 10.0f );
|
|
|
|
// fade out
|
|
if((endtime - time) < fade_time)
|
|
color[3] = (endtime - time) * 1.0f / fade_time;
|
|
else color[3] = 1.0;
|
|
color[0] = color[1] = color[2] = 1.0f;
|
|
|
|
return color;
|
|
}
|
|
|
|
void CL_DrawHUD( void )
|
|
{
|
|
CL_VM_Begin();
|
|
|
|
// setup pparms
|
|
prog->globals.cl->health = cl.frame.ps.health;
|
|
prog->globals.cl->maxclients = com.atoi(cl.configstrings[CS_MAXCLIENTS]);
|
|
prog->globals.cl->max_entities = host.max_edicts;
|
|
prog->globals.cl->realtime = cls.realtime * 0.001f;
|
|
prog->globals.cl->paused = cl_paused->integer;
|
|
|
|
// setup args
|
|
PRVM_G_FLOAT(OFS_PARM0) = (float)cls.state;
|
|
PRVM_ExecuteProgram (prog->globals.cl->HUD_Render, "HUD_Render");
|
|
}
|
|
|
|
bool CL_ParseUserMessage( int svc_number )
|
|
{
|
|
bool msg_parsed = false;
|
|
|
|
// setup pparms
|
|
prog->globals.cl->health = cl.frame.ps.health;
|
|
prog->globals.cl->maxclients = com.atoi(cl.configstrings[CS_MAXCLIENTS]);
|
|
prog->globals.cl->realtime = cls.realtime * 0.001f;
|
|
prog->globals.cl->paused = cl_paused->integer;
|
|
|
|
// setup args
|
|
PRVM_G_FLOAT(OFS_PARM0) = (float)svc_number;
|
|
PRVM_ExecuteProgram (prog->globals.cl->HUD_ParseMessage, "HUD_ParseMessage");
|
|
msg_parsed = PRVM_G_FLOAT(OFS_RETURN);
|
|
|
|
return msg_parsed;
|
|
}
|
|
|
|
/*
|
|
====================
|
|
StudioEvent
|
|
|
|
Event callback for studio models
|
|
====================
|
|
*/
|
|
void CL_StudioEvent ( dstudioevent_t *event, entity_state_t *ent )
|
|
{
|
|
// setup args
|
|
PRVM_G_FLOAT(OFS_PARM0) = (float)event->event;
|
|
PRVM_G_INT(OFS_PARM1) = PRVM_SetEngineString( event->options );
|
|
VectorCopy( ent->origin, PRVM_G_VECTOR(OFS_PARM2));
|
|
VectorCopy( ent->angles, PRVM_G_VECTOR(OFS_PARM3));
|
|
PRVM_ExecuteProgram( prog->globals.cl->HUD_StudioEvent, "HUD_StudioEvent");
|
|
}
|
|
|
|
/*
|
|
====================
|
|
GetClientEntity
|
|
|
|
Render callback for studio models
|
|
====================
|
|
*/
|
|
entity_state_t *CL_GetEdictByIndex( int index )
|
|
{
|
|
return &PRVM_EDICT_NUM( index )->priv.cl->current;
|
|
}
|
|
|
|
entity_state_t *CL_GetLocalPlayer( void )
|
|
{
|
|
return &PRVM_EDICT_NUM( cl.playernum + 1 )->priv.cl->current;
|
|
}
|
|
|
|
int CL_GetMaxClients( void )
|
|
{
|
|
return com.atoi(cl.configstrings[CS_MAXCLIENTS]);
|
|
}
|
|
|
|
/*
|
|
===============================================================================
|
|
Client Builtin Functions
|
|
|
|
mathlib, debugger, and various misc helpers
|
|
===============================================================================
|
|
*/
|
|
void CL_BeginIncreaseEdicts( void )
|
|
{
|
|
int i;
|
|
edict_t *ent;
|
|
|
|
// links don't survive the transition, so unlink everything
|
|
for (i = 0, ent = prog->edicts; i < prog->max_edicts; i++, ent++)
|
|
{
|
|
}
|
|
}
|
|
|
|
void CL_EndIncreaseEdicts( void )
|
|
{
|
|
int i;
|
|
edict_t *ent;
|
|
|
|
for (i = 0, ent = prog->edicts; i < prog->max_edicts; i++, ent++)
|
|
{
|
|
}
|
|
}
|
|
|
|
void CL_InitEdict( edict_t *e )
|
|
{
|
|
e->priv.cl->serialnumber = PRVM_NUM_FOR_EDICT(e);
|
|
e->priv.cl->free = false;
|
|
}
|
|
|
|
void CL_FreeEdict( edict_t *ed )
|
|
{
|
|
ed->priv.cl->freetime = cl.time * 0.001f;
|
|
ed->priv.cl->free = true;
|
|
|
|
ed->progs.cl->model = 0;
|
|
ed->progs.cl->modelindex = 0;
|
|
ed->progs.cl->soundindex = 0;
|
|
ed->progs.cl->skin = 0;
|
|
ed->progs.cl->frame = 0;
|
|
VectorClear(ed->progs.cl->origin);
|
|
VectorClear(ed->progs.cl->angles);
|
|
}
|
|
|
|
void CL_FreeEdicts( void )
|
|
{
|
|
int i;
|
|
edict_t *ent;
|
|
|
|
CL_VM_Begin();
|
|
for( i = 1; prog && i < prog->num_edicts; i++ )
|
|
{
|
|
ent = PRVM_EDICT_NUM(i);
|
|
CL_FreeEdict( ent );
|
|
}
|
|
CL_VM_End();
|
|
}
|
|
|
|
void CL_CountEdicts( void )
|
|
{
|
|
edict_t *ent;
|
|
int i, active = 0, models = 0;
|
|
|
|
for (i = 0; i < prog->num_edicts; i++)
|
|
{
|
|
ent = PRVM_EDICT_NUM(i);
|
|
if (ent->priv.cl->free) continue;
|
|
active++;
|
|
if (ent->progs.cl->model) models++;
|
|
}
|
|
|
|
Msg("num_edicts:%3i\n", prog->num_edicts);
|
|
Msg("active :%3i\n", active);
|
|
Msg("view :%3i\n", models);
|
|
}
|
|
|
|
void CL_VM_Begin( void )
|
|
{
|
|
PRVM_Begin;
|
|
PRVM_SetProg( PRVM_CLIENTPROG );
|
|
|
|
if( prog ) *prog->time = cl.time * 0.001f;
|
|
}
|
|
|
|
void CL_VM_End( void )
|
|
{
|
|
PRVM_End;
|
|
}
|
|
|
|
bool CL_LoadEdict( edict_t *ent )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
static void PF_BeginRead( void )
|
|
{
|
|
}
|
|
|
|
static void PF_EndRead( void )
|
|
{
|
|
}
|
|
|
|
static void PF_ReadChar (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadChar( cls.multicast ); }
|
|
static void PF_ReadByte (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadByte( cls.multicast ); }
|
|
static void PF_ReadShort (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadShort( cls.multicast ); }
|
|
static void PF_ReadLong (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadLong( cls.multicast ); }
|
|
static void PF_ReadFloat (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadFloat( cls.multicast ); }
|
|
static void PF_ReadAngle (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadBits( cls.multicast, NET_FLOAT ); }
|
|
static void PF_ReadCoord (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadBits( cls.multicast, NET_FLOAT ); }
|
|
static void PF_ReadString (void){ PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString( MSG_ReadString( cls.multicast) ); }
|
|
static void PF_ReadEntity (void){ VM_RETURN_EDICT( PRVM_PROG_TO_EDICT( MSG_ReadShort( cls.multicast ))); } // entindex
|
|
|
|
/*
|
|
=========
|
|
PF_drawfield
|
|
|
|
void DrawField( float value, vector pos, vector size )
|
|
=========
|
|
*/
|
|
static void PF_drawfield( void )
|
|
{
|
|
char num[16], *ptr;
|
|
int l, frame;
|
|
float value, *pos, *size;
|
|
|
|
if(!VM_ValidateArgs( "drawpic", 3 ))
|
|
return;
|
|
|
|
value = PRVM_G_FLOAT(OFS_PARM0);
|
|
pos = PRVM_G_VECTOR(OFS_PARM1);
|
|
size = PRVM_G_VECTOR(OFS_PARM2);
|
|
|
|
com.snprintf( num, 16, "%i", (int)value );
|
|
l = com.strlen( num );
|
|
ptr = num;
|
|
|
|
if( size[0] == 0.0f ) size[0] = GIANTCHAR_WIDTH;
|
|
if( size[1] == 0.0f ) size[1] = GIANTCHAR_HEIGHT;
|
|
|
|
while( *ptr && l )
|
|
{
|
|
if( *ptr == '-' ) frame = STAT_MINUS;
|
|
else frame = *ptr -'0';
|
|
SCR_DrawPic( pos[0], pos[1], size[0], size[1], field_shaders[frame] );
|
|
pos[0] += size[0];
|
|
ptr++;
|
|
l--;
|
|
}
|
|
re->SetColor( NULL );
|
|
}
|
|
|
|
/*
|
|
=========
|
|
PF_drawnet
|
|
|
|
void DrawNet( vector pos, string image )
|
|
=========
|
|
*/
|
|
static void PF_drawnet( void )
|
|
{
|
|
float *pos;
|
|
shader_t shader;
|
|
|
|
if(!VM_ValidateArgs( "drawnet", 2 ))
|
|
return;
|
|
if(cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged < CMD_BACKUP-1)
|
|
return;
|
|
|
|
VM_ValidateString(PRVM_G_STRING(OFS_PARM1));
|
|
pos = PRVM_G_VECTOR(OFS_PARM0);
|
|
shader = re->RegisterShader( va( "gfx/%s", PRVM_G_STRING(OFS_PARM1)), SHADER_NOMIP );
|
|
|
|
SCR_DrawPic( pos[0], pos[1], -1, -1, shader );
|
|
}
|
|
|
|
/*
|
|
=========
|
|
PF_drawfps
|
|
|
|
void DrawFPS( vector pos )
|
|
=========
|
|
*/
|
|
static void PF_drawfps( void )
|
|
{
|
|
float calc;
|
|
static double nexttime = 0, lasttime = 0;
|
|
static double framerate = 0;
|
|
static long framecount = 0;
|
|
double newtime;
|
|
bool red = false; // fps too low
|
|
char fpsstring[32];
|
|
float *color, *pos;
|
|
|
|
if(cls.state != ca_active) return;
|
|
if(!cl_showfps->integer) return;
|
|
if(!VM_ValidateArgs( "drawfps", 1 ))
|
|
return;
|
|
|
|
newtime = Sys_DoubleTime();
|
|
if( newtime >= nexttime )
|
|
{
|
|
framerate = framecount / (newtime - lasttime);
|
|
lasttime = newtime;
|
|
nexttime = max(nexttime + 1, lasttime - 1);
|
|
framecount = 0;
|
|
}
|
|
framecount++;
|
|
calc = framerate;
|
|
pos = PRVM_G_VECTOR(OFS_PARM0);
|
|
|
|
if ((red = (calc < 1.0f)))
|
|
{
|
|
com.snprintf(fpsstring, sizeof(fpsstring), "%4i spf", (int)(1.0f / calc + 0.5));
|
|
color = g_color_table[1];
|
|
}
|
|
else
|
|
{
|
|
com.snprintf(fpsstring, sizeof(fpsstring), "%4i fps", (int)(calc + 0.5));
|
|
color = g_color_table[3];
|
|
}
|
|
SCR_DrawBigStringColor(pos[0], pos[1], fpsstring, color );
|
|
}
|
|
|
|
/*
|
|
=========
|
|
PF_drawcenterprint
|
|
|
|
void DrawCenterPrint( void )
|
|
=========
|
|
*/
|
|
static void PF_drawcenterprint( void )
|
|
{
|
|
char *start;
|
|
int l, x, y, w;
|
|
float *color;
|
|
|
|
if(!cl.centerPrintTime ) return;
|
|
if(!VM_ValidateArgs( "DrawCenterPrint", 0 ))
|
|
return;
|
|
|
|
color = CL_FadeColor( cl.centerPrintTime * 0.001f, scr_centertime->value );
|
|
if( !color )
|
|
{
|
|
cl.centerPrintTime = 0;
|
|
return;
|
|
}
|
|
|
|
re->SetColor( color );
|
|
start = cl.centerPrint;
|
|
y = cl.centerPrintY - cl.centerPrintLines * BIGCHAR_HEIGHT/2;
|
|
|
|
while( 1 )
|
|
{
|
|
char linebuffer[1024];
|
|
|
|
for ( l = 0; l < 50; l++ )
|
|
{
|
|
if ( !start[l] || start[l] == '\n' )
|
|
break;
|
|
linebuffer[l] = start[l];
|
|
}
|
|
linebuffer[l] = 0;
|
|
|
|
w = cl.centerPrintCharWidth * com.cstrlen( linebuffer );
|
|
x = ( SCREEN_WIDTH - w )>>1;
|
|
|
|
SCR_DrawStringExt( x, y, cl.centerPrintCharWidth, BIGCHAR_HEIGHT, linebuffer, color, false );
|
|
|
|
y += cl.centerPrintCharWidth * 1.5;
|
|
while ( *start && ( *start != '\n' )) start++;
|
|
if( !*start ) break;
|
|
start++;
|
|
}
|
|
re->SetColor( NULL );
|
|
}
|
|
|
|
/*
|
|
=========
|
|
PF_centerprint
|
|
|
|
void HUD_CenterPrint( string text, float y, float charwidth )
|
|
=========
|
|
*/
|
|
static void PF_centerprint( void )
|
|
{
|
|
float y, width;
|
|
const char *text;
|
|
char *s;
|
|
|
|
if(!VM_ValidateArgs( "HUD_CenterPrint", 3 ))
|
|
return;
|
|
|
|
text = PRVM_G_STRING(OFS_PARM0);
|
|
y = PRVM_G_FLOAT(OFS_PARM1);
|
|
width = PRVM_G_FLOAT(OFS_PARM2);
|
|
VM_ValidateString( text );
|
|
|
|
com.strncpy( cl.centerPrint, text, sizeof(cl.centerPrint));
|
|
|
|
cl.centerPrintTime = cls.realtime;
|
|
cl.centerPrintY = y;
|
|
cl.centerPrintCharWidth = width;
|
|
|
|
// count the number of lines for centering
|
|
cl.centerPrintLines = 1;
|
|
s = cl.centerPrint;
|
|
while( *s )
|
|
{
|
|
if (*s == '\n') cl.centerPrintLines++;
|
|
s++;
|
|
}
|
|
}
|
|
|
|
/*
|
|
=========
|
|
PF_levelshot
|
|
|
|
float HUD_MakeLevelShot( void )
|
|
=========
|
|
*/
|
|
static void PF_levelshot( void )
|
|
{
|
|
PRVM_G_FLOAT(OFS_RETURN) = 0;
|
|
if(!VM_ValidateArgs( "HUD_MakeLevelShot", 0 ))
|
|
return;
|
|
|
|
if( cl.make_levelshot )
|
|
{
|
|
Con_ClearNotify();
|
|
cl.make_levelshot = false;
|
|
|
|
// make levelshot at nextframe()
|
|
Cbuf_ExecuteText( EXEC_APPEND, "levelshot\n" );
|
|
PRVM_G_FLOAT(OFS_RETURN) = 1;
|
|
}
|
|
}
|
|
|
|
/*
|
|
=========
|
|
PF_setcolor
|
|
|
|
void HUD_SetColor( vector rgb, float alpha )
|
|
=========
|
|
*/
|
|
static void PF_setcolor( void )
|
|
{
|
|
float *rgb, alpha;
|
|
|
|
if(!VM_ValidateArgs( "HUD_SetColor", 2 ))
|
|
return;
|
|
|
|
rgb = PRVM_G_VECTOR(OFS_PARM0);
|
|
alpha = PRVM_G_FLOAT(OFS_PARM1);
|
|
re->SetColor( GetRGBA( rgb[0], rgb[1], rgb[2], alpha ));
|
|
}
|
|
|
|
/*
|
|
=========
|
|
PF_startsound
|
|
|
|
void CL_StartSound( vector pos, entity e, float chan, float sfx, float vol, float attn, float pitch, float localsound )
|
|
=========
|
|
*/
|
|
static void PF_startsound( void )
|
|
{
|
|
float volume;
|
|
int channel;
|
|
sound_t sound_num;
|
|
int attenuation;
|
|
float *pos = NULL;
|
|
bool client_sound;
|
|
int ent = 0;
|
|
float pitch;
|
|
|
|
if( !VM_ValidateArgs( "CL_StartSound", 8 ))
|
|
return;
|
|
|
|
pos = PRVM_G_VECTOR(OFS_PARM0);
|
|
ent = PRVM_G_EDICTNUM(OFS_PARM1);
|
|
channel = (int)PRVM_G_FLOAT(OFS_PARM2);
|
|
sound_num = (sound_t)PRVM_G_FLOAT(OFS_PARM3);
|
|
volume = PRVM_G_FLOAT(OFS_PARM4);
|
|
attenuation = (int)PRVM_G_FLOAT(OFS_PARM5);
|
|
pitch = (int)PRVM_G_FLOAT(OFS_PARM6);
|
|
client_sound = (bool)PRVM_G_FLOAT(OFS_PARM7);
|
|
|
|
if( client_sound )
|
|
{
|
|
S_StartSound( pos, ent, channel, sound_num, volume, attenuation, pitch );
|
|
}
|
|
else if( cl.sound_precache[sound_num] )
|
|
{
|
|
S_StartSound( pos, ent, channel, cl.sound_precache[sound_num], volume, attenuation, pitch );
|
|
}
|
|
else VM_Warning( "CL_StartSound: can't play sound with index %i\n", sound_num );
|
|
}
|
|
|
|
/*
|
|
=========
|
|
PF_pointcontents
|
|
|
|
float CL_PointContents( vector point )
|
|
=========
|
|
*/
|
|
static void PF_pointcontents( void )
|
|
{
|
|
if( !VM_ValidateArgs( "CL_PointContents", 1 ))
|
|
return;
|
|
PRVM_G_FLOAT(OFS_RETURN) = CL_PointContents(PRVM_G_VECTOR(OFS_PARM0));
|
|
}
|
|
|
|
/*
|
|
=========
|
|
PF_startsound
|
|
|
|
sound_t CL_PrecacheSound( string samp )
|
|
=========
|
|
*/
|
|
static void PF_precachesound( void )
|
|
{
|
|
if( !VM_ValidateArgs( "CL_PrecacheSound", 1 ))
|
|
return;
|
|
|
|
VM_ValidateString(PRVM_G_STRING(OFS_PARM0));
|
|
PRVM_G_FLOAT(OFS_RETURN) = S_RegisterSound(PRVM_G_STRING(OFS_PARM0));
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_findexplosionplane
|
|
|
|
vector CL_FindExplosionPlane( vector org, float radius )
|
|
=================
|
|
*/
|
|
static void PF_findexplosionplane( void )
|
|
{
|
|
static vec3_t planes[6] = {{0, 0, 1}, {0, 1, 0}, {1, 0, 0}, {0, 0, -1}, {0, -1, 0}, {-1, 0, 0}};
|
|
trace_t trace;
|
|
float best = 1.0, radius;
|
|
vec3_t point, dir;
|
|
const float *org;
|
|
int i;
|
|
|
|
if( !VM_ValidateArgs( "CL_FindExplosionPlane", 2 ))
|
|
return;
|
|
|
|
org = PRVM_G_VECTOR(OFS_PARM0);
|
|
radius = PRVM_G_FLOAT(OFS_PARM1);
|
|
VectorClear( dir );
|
|
|
|
for( i = 0; i < 6; i++ )
|
|
{
|
|
VectorMA( org, radius, planes[i], point );
|
|
|
|
trace = CL_Trace( org, vec3_origin, vec3_origin, point, MOVE_WORLDONLY, NULL, MASK_SOLID );
|
|
if( trace.allsolid || trace.fraction == 1.0 )
|
|
continue;
|
|
|
|
if( trace.fraction < best )
|
|
{
|
|
best = trace.fraction;
|
|
VectorCopy( trace.plane.normal, dir );
|
|
}
|
|
}
|
|
VectorCopy( dir, PRVM_G_VECTOR( OFS_RETURN ));
|
|
}
|
|
|
|
// NOTE: intervals between various "interfaces" was leave for future expansions
|
|
prvm_builtin_t vm_cl_builtins[] =
|
|
{
|
|
NULL, // #0 (leave blank as default, but can include easter egg )
|
|
|
|
// system events
|
|
VM_ConPrintf, // #1 void Con_Printf( ... )
|
|
VM_ConDPrintf, // #2 void Con_DPrintf( float level, ... )
|
|
VM_HostError, // #3 void Com_Error( ... )
|
|
VM_SysExit, // #4 void Sys_Exit( void )
|
|
VM_CmdArgv, // #5 string Cmd_Argv( float arg )
|
|
VM_CmdArgc, // #6 float Cmd_Argc( void )
|
|
NULL, // #7 -- reserved --
|
|
NULL, // #8 -- reserved --
|
|
NULL, // #9 -- reserved --
|
|
NULL, // #10 -- reserved --
|
|
|
|
// common tools
|
|
VM_ComTrace, // #11 void Com_Trace( float enable )
|
|
VM_ComFileExists, // #12 float Com_FileExists( string filename )
|
|
VM_ComFileSize, // #13 float Com_FileSize( string filename )
|
|
VM_ComFileTime, // #14 float Com_FileTime( string filename )
|
|
VM_ComLoadScript, // #15 float Com_LoadScript( string filename )
|
|
VM_ComResetScript, // #16 void Com_ResetScript( void )
|
|
VM_ComReadToken, // #17 string Com_ReadToken( float newline )
|
|
VM_Random, // #18 float Random( void )
|
|
VM_ComSearchFiles, // #19 float Com_Search( string mask, float casecmp )
|
|
VM_ComSearchNames, // #20 string Com_SearchFilename( float num )
|
|
VM_RandomLong, // #21 float RandomLong( float min, float max )
|
|
VM_RandomFloat, // #22 float RandomFloat( float min, float max )
|
|
VM_RandomVector, // #23 vector RandomVector( vector min, vector max )
|
|
VM_CvarRegister, // #24 void Cvar_Register( string name, string value, float flags )
|
|
VM_CvarSetValue, // #25 void Cvar_SetValue( string name, float value )
|
|
VM_CvarGetValue, // #26 float Cvar_GetValue( string name )
|
|
VM_CvarSetString, // #27 void Cvar_SetString( string name, string value )
|
|
VM_CvarGetString, // #28 void VM_CvarGetString( void )
|
|
VM_ComVA, // #29 string va( ... )
|
|
VM_ComStrlen, // #30 float strlen( string text )
|
|
VM_TimeStamp, // #31 string Com_TimeStamp( float format )
|
|
VM_LocalCmd, // #32 void LocalCmd( ... )
|
|
VM_SubString, // #33 string substring( string s, float start, float length )
|
|
VM_AddCommand, // #34 void Add_Command( string s )
|
|
NULL, // #35 -- reserved --
|
|
NULL, // #36 -- reserved --
|
|
NULL, // #37 -- reserved --
|
|
NULL, // #38 -- reserved --
|
|
NULL, // #39 -- reserved --
|
|
NULL, // #40 -- reserved --
|
|
|
|
// quakec intrinsics ( compiler will be lookup this functions, don't remove or rename )
|
|
VM_SpawnEdict, // #41 entity spawn( void )
|
|
VM_RemoveEdict, // #42 void remove( entity ent )
|
|
VM_NextEdict, // #43 entity nextent( entity ent )
|
|
VM_CopyEdict, // #44 void copyentity( entity src, entity dst )
|
|
NULL, // #45 -- reserved --
|
|
NULL, // #46 -- reserved --
|
|
NULL, // #47 -- reserved --
|
|
NULL, // #48 -- reserved --
|
|
NULL, // #49 -- reserved --
|
|
NULL, // #50 -- reserved --
|
|
|
|
// filesystem
|
|
VM_FS_Open, // #51 float fopen( string filename, float mode )
|
|
VM_FS_Close, // #52 void fclose( float handle )
|
|
VM_FS_Gets, // #53 string fgets( float handle )
|
|
VM_FS_Puts, // #54 void fputs( float handle, string s )
|
|
NULL, // #55 -- reserved --
|
|
NULL, // #56 -- reserved --
|
|
NULL, // #57 -- reserved --
|
|
NULL, // #58 -- reserved --
|
|
NULL, // #59 -- reserved --
|
|
NULL, // #60 -- reserved --
|
|
|
|
// mathlib
|
|
VM_min, // #61 float min(float a, float b )
|
|
VM_max, // #62 float max(float a, float b )
|
|
VM_bound, // #63 float bound(float min, float val, float max)
|
|
VM_pow, // #64 float pow(float x, float y)
|
|
VM_sin, // #65 float sin(float f)
|
|
VM_cos, // #66 float cos(float f)
|
|
VM_tan, // #67 float tan(float f)
|
|
VM_asin, // #68 float asin(float f)
|
|
VM_acos, // #69 float acos(float f)
|
|
VM_atan, // #70 float atan(float f)
|
|
VM_sqrt, // #71 float sqrt(float f)
|
|
VM_rint, // #72 float rint (float v)
|
|
VM_floor, // #73 float floor(float v)
|
|
VM_ceil, // #74 float ceil (float v)
|
|
VM_fabs, // #75 float fabs (float f)
|
|
VM_fmod, // #76 float fmod( float val, float m )
|
|
NULL, // #77 -- reserved --
|
|
NULL, // #78 -- reserved --
|
|
VM_VectorNormalize, // #79 vector VectorNormalize( vector v )
|
|
VM_VectorLength, // #80 float VectorLength( vector v )
|
|
e10, e10, // #81 - #100 are reserved for future expansions
|
|
|
|
// network messaging
|
|
PF_BeginRead, // #101 void MsgBegin( void )
|
|
PF_ReadByte, // #102 float ReadByte( void )
|
|
PF_ReadChar, // #103 float ReadChar( void )
|
|
PF_ReadShort, // #104 float ReadShort( void )
|
|
PF_ReadLong, // #105 float ReadLong( void )
|
|
PF_ReadFloat, // #106 float ReadFloat( void )
|
|
PF_ReadAngle, // #107 float ReadAngle( void )
|
|
PF_ReadCoord, // #108 float ReadCoord( void )
|
|
PF_ReadString, // #109 string ReadString( void )
|
|
PF_ReadEntity, // #110 entity ReadEntity( void )
|
|
PF_EndRead, // #111 void MsgEnd( void )
|
|
|
|
// clientfuncs_t
|
|
VM_precache_pic, // #112 float precache_pic( string pic )
|
|
VM_drawcharacter, // #113 float DrawChar( vector pos, float char, vector scale, vector rgb, float alpha )
|
|
VM_drawstring, // #114 float DrawString( vector pos, string text, vector scale, vector rgb, float alpha )
|
|
VM_drawpic, // #115 float DrawPic( vector pos, string pic, vector size, vector rgb, float alpha )
|
|
VM_drawfill, // #116 void DrawFill( vector pos, vector size, vector rgb, float alpha )
|
|
VM_drawmodel, // #117 void DrawModel( vector pos, vector size, string mod, vector org, vector ang, float seq )
|
|
PF_drawfield, // #118 void DrawField( float value, vector pos, vector size )
|
|
VM_getimagesize, // #119 vector getimagesize( string pic )
|
|
PF_drawnet, // #120 void DrawNet( vector pos, string image )
|
|
PF_drawfps, // #121 void DrawFPS( vector pos )
|
|
PF_drawcenterprint, // #122 void DrawCenterPrint( void )
|
|
PF_centerprint, // #123 void HUD_CenterPrint( string text, float y, float charwidth )
|
|
PF_levelshot, // #124 float HUD_MakeLevelShot( void )
|
|
PF_setcolor, // #125 void HUD_SetColor( vector rgb, float alpha )
|
|
VM_localsound, // #126 void HUD_PlaySound( string sample )
|
|
PF_startsound, // #127 void CL_StartSound( vector, entity, float, float, float, float, float, float )
|
|
PF_addparticle, // #128 float AddParticle(vector, vector, vector, vector, vector, vector, vector, string, float)
|
|
PF_pointcontents, // #129 float CL_PointContents( vector point )
|
|
PF_precachesound, // #130 sound_t CL_PrecacheSound( string samp )
|
|
PF_adddecal, // #131 void AddDecal( vector, vector, vector, float, float, float, float, string, float )
|
|
PF_addlight, // #132 void AddLight( vector pos, vector col, float rad, float decay, float time, float key )
|
|
NULL, // #133
|
|
NULL, // #134
|
|
NULL, // #135
|
|
NULL, // #136
|
|
NULL, // #137
|
|
PF_findexplosionplane, // #138 vector CL_FindExplosionPlane( vector org, float radius )
|
|
};
|
|
|
|
const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t); //num of builtins
|
|
|
|
void CL_InitClientProgs( void )
|
|
{
|
|
int i;
|
|
|
|
Msg("\n");
|
|
PRVM_Begin;
|
|
|
|
PRVM_InitProg( PRVM_CLIENTPROG );
|
|
if( !prog->loaded )
|
|
{
|
|
prog->progs_mempool = Mem_AllocPool( "Client Progs" );
|
|
prog->name = "client";
|
|
prog->builtins = vm_cl_builtins;
|
|
prog->numbuiltins = vm_cl_numbuiltins;
|
|
prog->edictprivate_size = sizeof(cl_edict_t);
|
|
prog->max_edicts = host.max_edicts<<2;
|
|
prog->limit_edicts = host.max_edicts;
|
|
prog->begin_increase_edicts = CL_BeginIncreaseEdicts;
|
|
prog->end_increase_edicts = CL_EndIncreaseEdicts;
|
|
prog->init_edict = CL_InitEdict;
|
|
prog->free_edict = CL_FreeEdict;
|
|
prog->count_edicts = CL_CountEdicts;
|
|
prog->load_edict = CL_LoadEdict;
|
|
prog->filecrc = PROG_CRC_CLIENT;
|
|
|
|
// using default builtins
|
|
prog->init_cmd = VM_Cmd_Init;
|
|
prog->reset_cmd = VM_Cmd_Reset;
|
|
prog->error_cmd = VM_Error;
|
|
PRVM_LoadProgs( va("%s/client.dat", GI->vprogs_dir ));
|
|
}
|
|
|
|
// init some globals
|
|
prog->globals.cl->realtime = cls.realtime * 0.001f;
|
|
prog->globals.cl->pev = 0;
|
|
prog->globals.cl->mapname = PRVM_SetEngineString( cls.servername );
|
|
prog->globals.cl->playernum = cl.playernum;
|
|
|
|
for( i = 0; i < sizeof( field_nums ) / sizeof( field_nums[0] ); i++ )
|
|
field_shaders[i] = re->RegisterShader( va("gfx/%s", field_nums[i] ), SHADER_NOMIP );
|
|
|
|
// call the prog init
|
|
PRVM_ExecuteProgram( prog->globals.cl->HUD_Init, "HUD_Init" );
|
|
PRVM_End;
|
|
}
|
|
|
|
void CL_FreeClientProgs( void )
|
|
{
|
|
CL_VM_Begin();
|
|
|
|
prog->globals.cl->realtime = cls.realtime * 0.001f;
|
|
prog->globals.cl->pev = 0;
|
|
PRVM_ExecuteProgram(prog->globals.cl->HUD_Shutdown, "HUD_Shutdown");
|
|
PRVM_ResetProg();
|
|
|
|
CL_VM_End();
|
|
} |