added cprint console command.
fixed nq client loading-screen persisting bug fixed nq clients getting flooded by packets. fixed nq clients not receiving any entities removed a bit of redundant code in pmove fteqcc: merged array function calls with real function calls, fixing return values in the process. vid_preservegamma now defaults to off. windows sucks. tweeked the prototype FTE_CSQC_SKELETONOBJECTS a bit. still not official nor advertised. added a little bit more functionality to halflife support csqc got some pmove tweeks. this is how I want it to work. nothing has been changed that is really incompatible with darkplaces in this commit. added markers around some ext_csqc_1 features. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3178 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
42b4577802
commit
5f1a9d8cbf
20 changed files with 1141 additions and 614 deletions
|
@ -2460,6 +2460,7 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
|
|||
|
||||
case 4:
|
||||
SCR_EndLoadingPlaque (); // allow normal screen updates
|
||||
SCR_SetLoadingStage(LS_NONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -206,6 +206,7 @@ float oldsbar = 0;
|
|||
|
||||
void SCR_ScreenShot_f (void);
|
||||
void SCR_RSShot_f (void);
|
||||
void SCR_CPrint_f(void);
|
||||
|
||||
cvar_t show_fps = SCVARF("show_fps", "0", CVAR_ARCHIVE);
|
||||
cvar_t show_fps_x = SCVAR("show_fps_x", "-1");
|
||||
|
@ -223,6 +224,8 @@ cvar_t show_speed_y = SCVAR("show_speed_y", "-9");
|
|||
extern char cl_screengroup[];
|
||||
void CLSCR_Init(void)
|
||||
{
|
||||
Cmd_AddCommand("cprint", SCR_CPrint_f);
|
||||
|
||||
Cvar_Register(&show_fps, cl_screengroup);
|
||||
Cvar_Register(&show_fps_x, cl_screengroup);
|
||||
Cvar_Register(&show_fps_y, cl_screengroup);
|
||||
|
@ -432,9 +435,9 @@ Called for important messages that should stay in the center of the screen
|
|||
for a few moments
|
||||
==============
|
||||
*/
|
||||
void SCR_CenterPrint (int pnum, char *str, qboolean fromgamecode)
|
||||
void SCR_CenterPrint (int pnum, char *str, qboolean skipgamecode)
|
||||
{
|
||||
if (!fromgamecode)
|
||||
if (!skipgamecode)
|
||||
{
|
||||
#ifdef CSQC_DAT
|
||||
if (CSQC_CenterPrint(pnum, str)) //csqc nabbed it.
|
||||
|
@ -466,6 +469,11 @@ void SCR_CenterPrint (int pnum, char *str, qboolean fromgamecode)
|
|||
}
|
||||
}
|
||||
|
||||
void SCR_CPrint_f(void)
|
||||
{
|
||||
SCR_CenterPrint(0, Cmd_Argv(0), true);
|
||||
}
|
||||
|
||||
void SCR_EraseCenterString (void)
|
||||
{
|
||||
int pnum;
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
#include "quakedef.h"
|
||||
|
||||
#include "glquake.h"
|
||||
|
||||
#ifdef HLCLIENT
|
||||
|
||||
#define CLIENTDLLNAME "cl_dlls/client"
|
||||
|
||||
#define notimp(l) Con_Printf("halflife cl builtin not implemented on line %i\n", l)
|
||||
|
||||
//#define HLCL_API_VERSION 6
|
||||
#define HLCL_API_VERSION 7
|
||||
|
||||
|
||||
//make shared
|
||||
struct hlcvar_s *GHL_CVarGetPointer(char *varname);
|
||||
|
||||
|
||||
#define HLPIC model_t*
|
||||
|
||||
typedef struct
|
||||
|
@ -534,12 +536,12 @@ void CLGHL_setcrosshair (HLPIC pic, hlsubrect_t rect, int r, int g, int b)
|
|||
{
|
||||
}
|
||||
|
||||
int CLGHL_cvar_register (char *name, char *defvalue, int flags)
|
||||
struct hlcvar_s *CLGHL_cvar_register (char *name, char *defvalue, int flags)
|
||||
{
|
||||
if (Cvar_Get(name, defvalue, 0, "Halflife cvars"))
|
||||
return GHL_CVarGetPointer(name);
|
||||
else
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
float CLGHL_cvar_getfloat (char *name)
|
||||
{
|
||||
|
@ -598,7 +600,23 @@ void CLGHL_localcmd (char *command)
|
|||
|
||||
void CLGHL_getplayerinfo (int entnum, hlplayerinfo_t *result)
|
||||
{
|
||||
notimp(__LINE__);
|
||||
player_info_t *player;
|
||||
entnum--;
|
||||
if (entnum < 0 || entnum >= MAX_CLIENTS)
|
||||
return;
|
||||
|
||||
player = &cl.players[entnum];
|
||||
result->name = player->name;
|
||||
result->ping = player->ping;
|
||||
result->tcolour = player->rtopcolor;
|
||||
result->bcolour = player->rbottomcolor;
|
||||
result->isus = true;
|
||||
result->isspec = player->spectator;
|
||||
result->pl = player->pl;
|
||||
if (player->skin)
|
||||
result->model = player->skin->name;
|
||||
else
|
||||
result->model = "";
|
||||
}
|
||||
|
||||
void CLGHL_startsound_name (char *name, float vol)
|
||||
|
@ -630,7 +648,21 @@ void CLGHL_anglevectors (float *ina, float *outf, float *outr, float *outu)
|
|||
hlmsginfo_t *CLGHL_get_message_info (char *name)
|
||||
{
|
||||
//fixme: add parser
|
||||
return NULL;
|
||||
hlmsginfo_t *ret;
|
||||
ret = Z_Malloc(sizeof(*ret));
|
||||
memset(ret, 0, sizeof(*ret));
|
||||
ret->name = name;
|
||||
ret->message = name;
|
||||
ret->x = 0;
|
||||
ret->y = 0;
|
||||
*(int*)&ret->c1 = 0xffffffff;
|
||||
*(int*)&ret->c2 = 0xffffffff;
|
||||
ret->effect = 0;
|
||||
ret->fadein = 0;
|
||||
ret->fadeout = 0;
|
||||
ret->fxtime = 0;
|
||||
ret->holdtime = 1000;
|
||||
return ret;
|
||||
}
|
||||
int CLGHL_drawchar (int x, int y, int charnum, int r, int g, int b)
|
||||
{
|
||||
|
@ -714,6 +746,7 @@ int CLGHL_keyevent(int key, int down)
|
|||
Key_Event(K_MOUSE1+key-241, down);
|
||||
else
|
||||
Con_Printf("CLGHL_keyevent: Unrecognised HL key code\n");
|
||||
return true; //fixme: check the return type
|
||||
}
|
||||
void CLGHL_getmousepos(int *outx, int *outy){notimp(__LINE__);}
|
||||
int CLGHL_movetypeisnoclip(void){notimp(__LINE__);return 0;}
|
||||
|
@ -806,8 +839,8 @@ model_t *CLGHL_loadmapsprite(char *name)
|
|||
notimp(__LINE__);return NULL;
|
||||
}
|
||||
|
||||
void CLGHL_fs_addgamedir(char *basedir, char *appname){notimp(__LINE__);return NULL;}
|
||||
int CLGHL_expandfilename(char *filename, char *outbuff, int outsize){notimp(__LINE__);return NULL;}
|
||||
void CLGHL_fs_addgamedir(char *basedir, char *appname){notimp(__LINE__);}
|
||||
int CLGHL_expandfilename(char *filename, char *outbuff, int outsize){notimp(__LINE__);return false;}
|
||||
|
||||
char *CLGHL_player_key(int pnum, char *key){notimp(__LINE__);return NULL;}
|
||||
void CLGHL_player_setkey(char *key, char *value){notimp(__LINE__);return NULL;}
|
||||
|
@ -836,7 +869,7 @@ void CLGHL_setmouseenable(qboolean enable)
|
|||
|
||||
|
||||
|
||||
|
||||
#if HLCL_API_VERSION >= 7
|
||||
int CLGHL_demo_isrecording(void)
|
||||
{
|
||||
return cls.demorecording;
|
||||
|
@ -863,6 +896,7 @@ struct hl_demo_api_s hl_demo_api =
|
|||
|
||||
0xdeadbeef
|
||||
};
|
||||
#endif
|
||||
|
||||
CLHL_cgamefuncs_t CLHL_cgamefuncs;
|
||||
CLHL_enginecgamefuncs_t CLHL_enginecgamefuncs =
|
||||
|
@ -1000,22 +1034,29 @@ dllhandle_t clg;
|
|||
|
||||
int CLHL_GamecodeDoesMouse(void)
|
||||
{
|
||||
if (!clg || !CLHL_cgamefuncs.CL_CreateMove)
|
||||
return false;
|
||||
return true;
|
||||
#if HLCL_API_VERSION >= 7
|
||||
if (clg && CLHL_cgamefuncs.CL_CreateMove)
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
int CLHL_MouseEvent(unsigned int buttonmask)
|
||||
{
|
||||
#if HLCL_API_VERSION >= 7
|
||||
if (!CLHL_GamecodeDoesMouse())
|
||||
return false;
|
||||
|
||||
CLHL_cgamefuncs.IN_MouseEvent(buttonmask);
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CLHL_SetMouseActive(int activate)
|
||||
{
|
||||
#if HLCL_API_VERSION >= 7
|
||||
static int oldactive;
|
||||
if (!clg)
|
||||
{
|
||||
|
@ -1036,6 +1077,7 @@ void CLHL_SetMouseActive(int activate)
|
|||
if (CLHL_cgamefuncs.IN_DeactivateMouse)
|
||||
CLHL_cgamefuncs.IN_DeactivateMouse();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CLHL_UnloadClientGame(void)
|
||||
|
@ -1062,18 +1104,6 @@ void CLHL_LoadClientGame(void)
|
|||
dllfunction_t funcs[] =
|
||||
{
|
||||
{(void*)&initfunc, "Initialize"},
|
||||
{(void*)&CLHL_cgamefuncs.HUD_VidInit, "HUD_VidInit"},
|
||||
{(void*)&CLHL_cgamefuncs.HUD_Init, "HUD_Init"},
|
||||
{(void*)&CLHL_cgamefuncs.HUD_Shutdown, "HUD_Shutdown"},
|
||||
{(void*)&CLHL_cgamefuncs.HUD_Redraw, "HUD_Redraw"},
|
||||
{(void*)&CLHL_cgamefuncs.HUD_UpdateClientData, "HUD_UpdateClientData"},
|
||||
{(void*)&CLHL_cgamefuncs.HUD_Reset, "HUD_Reset"},
|
||||
#if HLCL_API_VERSION >= 7
|
||||
{(void*)&CLHL_cgamefuncs.CL_CreateMove, "CL_CreateMove"},
|
||||
{(void*)&CLHL_cgamefuncs.IN_ActivateMouse, "IN_ActivateMouse"},
|
||||
{(void*)&CLHL_cgamefuncs.IN_DeactivateMouse, "IN_DeactivateMouse"},
|
||||
{(void*)&CLHL_cgamefuncs.IN_MouseEvent, "IN_MouseEvent"},
|
||||
#endif
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
@ -1102,12 +1132,28 @@ void CLHL_LoadClientGame(void)
|
|||
return;
|
||||
}
|
||||
|
||||
CLHL_cgamefuncs.HUD_Init();
|
||||
CLHL_cgamefuncs.HUD_VidInit();
|
||||
CLHL_cgamefuncs.HUD_VidInit = (void*)Sys_GetAddressForName(clg, "HUD_VidInit");
|
||||
CLHL_cgamefuncs.HUD_Init = (void*)Sys_GetAddressForName(clg, "HUD_Init");
|
||||
CLHL_cgamefuncs.HUD_Shutdown = (void*)Sys_GetAddressForName(clg, "HUD_Shutdown");
|
||||
CLHL_cgamefuncs.HUD_Redraw = (void*)Sys_GetAddressForName(clg, "HUD_Redraw");
|
||||
CLHL_cgamefuncs.HUD_UpdateClientData = (void*)Sys_GetAddressForName(clg, "HUD_UpdateClientData");
|
||||
CLHL_cgamefuncs.HUD_Reset = (void*)Sys_GetAddressForName(clg, "HUD_Reset");
|
||||
#if HLCL_API_VERSION >= 7
|
||||
CLHL_cgamefuncs.CL_CreateMove = (void*)Sys_GetAddressForName(clg, "CL_CreateMove");
|
||||
CLHL_cgamefuncs.IN_ActivateMouse = (void*)Sys_GetAddressForName(clg, "IN_ActivateMouse");
|
||||
CLHL_cgamefuncs.IN_DeactivateMouse = (void*)Sys_GetAddressForName(clg, "IN_DeactivateMouse");
|
||||
CLHL_cgamefuncs.IN_MouseEvent = (void*)Sys_GetAddressForName(clg, "IN_MouseEvent");
|
||||
#endif
|
||||
|
||||
if (CLHL_cgamefuncs.HUD_Init)
|
||||
CLHL_cgamefuncs.HUD_Init();
|
||||
if (CLHL_cgamefuncs.HUD_VidInit)
|
||||
CLHL_cgamefuncs.HUD_VidInit();
|
||||
}
|
||||
|
||||
int CLHL_BuildUserInput(int msecs, usercmd_t *cmd)
|
||||
{
|
||||
#if HLCL_API_VERSION >= 7
|
||||
hlusercmd_t hlcmd;
|
||||
if (!clg || !CLHL_cgamefuncs.CL_CreateMove)
|
||||
return false;
|
||||
|
@ -1127,6 +1173,9 @@ int CLHL_BuildUserInput(int msecs, usercmd_t *cmd)
|
|||
cmd->buttons = hlcmd.buttons;
|
||||
cmd->lightlevel = hlcmd.lightlevel;
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
int CLHL_DrawHud(void)
|
||||
|
@ -1137,6 +1186,8 @@ int CLHL_DrawHud(void)
|
|||
if (!clg || !CLHL_cgamefuncs.HUD_Redraw)
|
||||
return false;
|
||||
|
||||
memset(&state, 0, sizeof(state));
|
||||
|
||||
// state.origin;
|
||||
// state.viewangles;
|
||||
#if HLCL_API_VERSION < 7
|
||||
|
|
|
@ -118,7 +118,7 @@ extern void SCR_EndLoadingPlaque (void);
|
|||
extern void SCR_DrawConsole (qboolean noback);
|
||||
extern void SCR_SetUpToDrawConsole (void);
|
||||
extern void SCR_EraseCenterString (void);
|
||||
extern void SCR_CenterPrint (int pnum, char *str, qboolean fromgamecode);
|
||||
extern void SCR_CenterPrint (int pnum, char *str, qboolean skipgamecode);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -141,7 +141,7 @@ extern qboolean Mod_GetTag (struct model_s *model, int tagnum, framestate_t
|
|||
extern int Mod_TagNumForName (struct model_s *model, char *name);
|
||||
|
||||
int Mod_GetNumBones(struct model_s *model, qboolean allowtags);
|
||||
int Mod_GetBoneRelations(struct model_s *model, int numbones, framestate_t *fstate, float *result);
|
||||
int Mod_GetBoneRelations(struct model_s *model, int firstbone, int lastbone, framestate_t *fstate, float *result);
|
||||
int Mod_GetBoneParent(struct model_s *model, int bonenum);
|
||||
char *Mod_GetBoneName(struct model_s *model, int bonenum);
|
||||
|
||||
|
|
|
@ -281,6 +281,7 @@ static void CSQC_FindGlobals(void)
|
|||
fieldvector(origin); \
|
||||
fieldvector(angles); \
|
||||
fieldvector(velocity); \
|
||||
fieldfloat(pmove_flags); /*transparency*/ \
|
||||
fieldfloat(alpha); /*transparency*/ \
|
||||
fieldfloat(scale); /*model scale*/ \
|
||||
fieldfloat(fatness); /*expand models X units along their normals.*/ \
|
||||
|
@ -326,7 +327,9 @@ static void CSQC_FindGlobals(void)
|
|||
fieldentity(chain); \
|
||||
fieldentity(enemy); \
|
||||
fieldentity(groundentity); \
|
||||
fieldentity(owner); \
|
||||
fieldentity(owner); \
|
||||
\
|
||||
fieldfunction(touch); \
|
||||
\
|
||||
fieldfloat(solid); \
|
||||
fieldvector(mins); \
|
||||
|
@ -482,6 +485,87 @@ void CS_ClearWorld (void)
|
|||
CS_LinkEdict((csqcedict_t*)EDICT_NUM(csqcprogs, i), false);
|
||||
}
|
||||
|
||||
#define MAX_NODELINKS 256 //all this means is that any more than this will not touch.
|
||||
static csqcedict_t *csnodelinks[MAX_NODELINKS];
|
||||
void CS_TouchLinks ( csqcedict_t *ent, areanode_t *node )
|
||||
{ //Spike: rewritten this function to cope with killtargets used on a few maps.
|
||||
link_t *l, *next;
|
||||
csqcedict_t *touch;
|
||||
int old_self, old_other;
|
||||
|
||||
int linkcount = 0, ln;
|
||||
|
||||
//work out who they are first.
|
||||
for (l = node->trigger_edicts.next ; l != &node->trigger_edicts ; l = next)
|
||||
{
|
||||
if (linkcount == MAX_NODELINKS)
|
||||
break;
|
||||
next = l->next;
|
||||
touch = (csqcedict_t*)EDICT_FROM_AREA(l);
|
||||
if (touch == ent)
|
||||
continue;
|
||||
|
||||
if (!touch->v->touch || touch->v->solid != SOLID_TRIGGER)
|
||||
continue;
|
||||
|
||||
if (ent->v->absmin[0] > touch->v->absmax[0]
|
||||
|| ent->v->absmin[1] > touch->v->absmax[1]
|
||||
|| ent->v->absmin[2] > touch->v->absmax[2]
|
||||
|| ent->v->absmax[0] < touch->v->absmin[0]
|
||||
|| ent->v->absmax[1] < touch->v->absmin[1]
|
||||
|| ent->v->absmax[2] < touch->v->absmin[2] )
|
||||
continue;
|
||||
|
||||
// if (!((int)ent->xv->dimension_solid & (int)touch->xv->dimension_hit))
|
||||
// continue;
|
||||
|
||||
csnodelinks[linkcount++] = touch;
|
||||
}
|
||||
|
||||
old_self = *csqcg.self;
|
||||
old_other = *csqcg.other;
|
||||
for (ln = 0; ln < linkcount; ln++)
|
||||
{
|
||||
touch = csnodelinks[ln];
|
||||
|
||||
//make sure nothing moved it away
|
||||
if (touch->isfree)
|
||||
continue;
|
||||
if (!touch->v->touch || touch->v->solid != SOLID_TRIGGER)
|
||||
continue;
|
||||
if (ent->v->absmin[0] > touch->v->absmax[0]
|
||||
|| ent->v->absmin[1] > touch->v->absmax[1]
|
||||
|| ent->v->absmin[2] > touch->v->absmax[2]
|
||||
|| ent->v->absmax[0] < touch->v->absmin[0]
|
||||
|| ent->v->absmax[1] < touch->v->absmin[1]
|
||||
|| ent->v->absmax[2] < touch->v->absmin[2] )
|
||||
continue;
|
||||
|
||||
// if (!((int)ent->xv->dimension_solid & (int)touch->xv->dimension_hit)) //didn't change did it?...
|
||||
// continue;
|
||||
|
||||
*csqcg.self = EDICT_TO_PROG(csqcprogs, (edict_t*)touch);
|
||||
*csqcg.other = EDICT_TO_PROG(csqcprogs, (edict_t*)ent);
|
||||
|
||||
PR_ExecuteProgram (csqcprogs, touch->v->touch);
|
||||
|
||||
if (ent->isfree)
|
||||
break;
|
||||
}
|
||||
*csqcg.self = old_self;
|
||||
*csqcg.other = old_other;
|
||||
|
||||
|
||||
// recurse down both sides
|
||||
if (node->axis == -1 || ent->isfree)
|
||||
return;
|
||||
|
||||
if ( ent->v->absmax[node->axis] > node->dist )
|
||||
CS_TouchLinks ( ent, node->children[0] );
|
||||
if ( ent->v->absmin[node->axis] < node->dist )
|
||||
CS_TouchLinks ( ent, node->children[1] );
|
||||
}
|
||||
|
||||
static void CS_UnlinkEdict (csqcedict_t *ent)
|
||||
{
|
||||
if (!ent->area.prev)
|
||||
|
@ -542,9 +626,13 @@ static void CS_LinkEdict(csqcedict_t *ent, qboolean touchtriggers)
|
|||
// link it in
|
||||
|
||||
if (ent->v->solid == SOLID_TRIGGER)
|
||||
InsertLinkBefore (&ent->area, &node->trigger_edicts);
|
||||
InsertLinkBefore(&ent->area, &node->trigger_edicts);
|
||||
else
|
||||
InsertLinkBefore (&ent->area, &node->solid_edicts);
|
||||
InsertLinkBefore(&ent->area, &node->solid_edicts);
|
||||
|
||||
// if touch_triggers, touch all entities at this node and decend for more
|
||||
if (touchtriggers)
|
||||
CS_TouchLinks(ent, cs_areanodes);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
@ -1812,6 +1900,8 @@ static void csqc_setmodel(progfuncs_t *prinst, csqcedict_t *ent, int modelindex)
|
|||
VectorClear(ent->v->mins);
|
||||
VectorClear(ent->v->maxs);
|
||||
}
|
||||
|
||||
CS_LinkEdict(ent, false);
|
||||
}
|
||||
|
||||
static void PF_cs_SetModel(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
|
@ -2127,6 +2217,12 @@ static void PF_cs_runplayerphysics (progfuncs_t *prinst, struct globalvars_s *pr
|
|||
extern vec3_t player_mins;
|
||||
extern vec3_t player_maxs;
|
||||
|
||||
csqcedict_t *ent;
|
||||
if (*prinst->callargc >= 1)
|
||||
ent = (void*)G_EDICT(prinst, OFS_PARM0);
|
||||
else
|
||||
ent = NULL;
|
||||
|
||||
if (!cl.worldmodel)
|
||||
return; //urm..
|
||||
/*
|
||||
|
@ -2181,14 +2277,12 @@ typedef struct {
|
|||
|
||||
*/
|
||||
|
||||
//debugging field
|
||||
pmove.sequence = *csqcg.clientcommandframe;
|
||||
|
||||
pmove.pm_type = PM_NORMAL;
|
||||
|
||||
pmove.jump_msec = 0;//(cls.z_ext & Z_EXT_PM_TYPE) ? 0 : from->jump_msec;
|
||||
if (csqcg.pmove_jump_held)
|
||||
pmove.jump_held = *csqcg.pmove_jump_held;
|
||||
if (csqcg.pmove_waterjumptime)
|
||||
pmove.waterjumptime = *csqcg.pmove_waterjumptime;
|
||||
|
||||
//set up the movement command
|
||||
msecs = *csqcg.input_timelength*1000 + 0.5f;
|
||||
|
@ -2203,16 +2297,30 @@ typedef struct {
|
|||
pmove.cmd.upmove = csqcg.input_movevalues[2];
|
||||
pmove.cmd.buttons = *csqcg.input_buttons;
|
||||
|
||||
VectorCopy(csqcg.pmove_org, pmove.origin);
|
||||
VectorCopy(csqcg.pmove_vel, pmove.velocity);
|
||||
VectorCopy(csqcg.pmove_maxs, player_maxs);
|
||||
VectorCopy(csqcg.pmove_mins, player_mins);
|
||||
if (ent)
|
||||
{
|
||||
pmove.jump_held = (int)ent->v->pmove_flags & PMF_JUMP_HELD;
|
||||
pmove.waterjumptime = 0;
|
||||
VectorCopy(ent->v->origin, pmove.origin);
|
||||
VectorCopy(ent->v->velocity, pmove.velocity);
|
||||
VectorCopy(ent->v->maxs, player_maxs);
|
||||
VectorCopy(ent->v->mins, player_mins);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (csqcg.pmove_jump_held)
|
||||
pmove.jump_held = *csqcg.pmove_jump_held;
|
||||
if (csqcg.pmove_waterjumptime)
|
||||
pmove.waterjumptime = *csqcg.pmove_waterjumptime;
|
||||
VectorCopy(csqcg.pmove_org, pmove.origin);
|
||||
VectorCopy(csqcg.pmove_vel, pmove.velocity);
|
||||
VectorCopy(csqcg.pmove_maxs, player_maxs);
|
||||
VectorCopy(csqcg.pmove_mins, player_mins);
|
||||
}
|
||||
pmove.hullnum = 1;
|
||||
|
||||
CL_SetSolidEntities();
|
||||
|
||||
|
||||
|
||||
while(msecs) //break up longer commands
|
||||
{
|
||||
pmove.cmd.msec = msecs;
|
||||
|
@ -2222,16 +2330,29 @@ typedef struct {
|
|||
PM_PlayerMove(1);
|
||||
}
|
||||
|
||||
if (csqcg.pmove_jump_held)
|
||||
*csqcg.pmove_jump_held = pmove.jump_held;
|
||||
if (csqcg.pmove_waterjumptime)
|
||||
*csqcg.pmove_waterjumptime = pmove.waterjumptime;
|
||||
VectorCopy(pmove.origin, csqcg.pmove_org);
|
||||
VectorCopy(pmove.velocity, csqcg.pmove_vel);
|
||||
if (ent)
|
||||
{
|
||||
VectorCopy(pmove.angles, ent->v->angles);
|
||||
ent->v->angles[0] *= -1/3.0f;
|
||||
VectorCopy(pmove.origin, ent->v->origin);
|
||||
VectorCopy(pmove.velocity, ent->v->velocity);
|
||||
ent->v->pmove_flags = 0;
|
||||
ent->v->pmove_flags += pmove.jump_held ? PMF_JUMP_HELD : 0;
|
||||
ent->v->pmove_flags += pmove.onladder ? PMF_LADDER : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (csqcg.pmove_jump_held)
|
||||
*csqcg.pmove_jump_held = pmove.jump_held;
|
||||
if (csqcg.pmove_waterjumptime)
|
||||
*csqcg.pmove_waterjumptime = pmove.waterjumptime;
|
||||
VectorCopy(pmove.origin, csqcg.pmove_org);
|
||||
VectorCopy(pmove.velocity, csqcg.pmove_vel);
|
||||
}
|
||||
|
||||
pmove.origin[0] = ((int)(pmove.origin[0]*8))/8.0f;
|
||||
pmove.origin[1] = ((int)(pmove.origin[1]*8))/8.0f;
|
||||
pmove.origin[2] = ((int)(pmove.origin[2]*8))/8.0f;
|
||||
//fixme: touch solids
|
||||
|
||||
CS_LinkEdict (ent, true);
|
||||
}
|
||||
|
||||
static void PF_cs_getentitytoken (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
|
@ -3529,35 +3650,24 @@ skelobject_t *skel_get(progfuncs_t *prinst, int skelidx, int bonecount)
|
|||
}
|
||||
}
|
||||
|
||||
//#263 float(entity ent) skel_buildrel (FTE_CSQC_SKELETONOBJECTS)
|
||||
//#263 float(entity ent, float skel) skel_updaterel (FTE_CSQC_SKELETONOBJECTS)
|
||||
static void PF_skel_buildrel (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
//float(float modelindex) skel_create (FTE_CSQC_SKELETONOBJECTS)
|
||||
static void PF_skel_create (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
csqcedict_t *ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM0);
|
||||
int skelidx;
|
||||
int numbones;
|
||||
framestate_t fstate;
|
||||
skelobject_t *skelobj;
|
||||
qboolean isabs;
|
||||
model_t *model;
|
||||
if (*prinst->callargc > 1)
|
||||
skelidx = G_FLOAT(OFS_PARM1);
|
||||
else
|
||||
skelidx = 0;
|
||||
int midx;
|
||||
|
||||
midx = G_FLOAT(OFS_PARM0);
|
||||
|
||||
//default to failure
|
||||
G_FLOAT(OFS_RETURN) = 0;
|
||||
|
||||
model = CSQC_GetModelForIndex(ent->v->modelindex);
|
||||
model = CSQC_GetModelForIndex(midx);
|
||||
if (!model)
|
||||
return; //no model set, can't get a skeleton
|
||||
|
||||
cs_getframestate(ent, ent->v->renderflags, &fstate);
|
||||
|
||||
//heh... don't copy.
|
||||
fstate.bonecount = 0;
|
||||
fstate.bonestate = NULL;
|
||||
|
||||
isabs = false;
|
||||
numbones = Mod_GetNumBones(model, isabs);
|
||||
if (!numbones)
|
||||
|
@ -3568,26 +3678,76 @@ static void PF_skel_buildrel (progfuncs_t *prinst, struct globalvars_s *pr_globa
|
|||
return; //this isn't a skeletal model.
|
||||
}
|
||||
|
||||
skelobj = skel_get(prinst, skelidx, numbones);
|
||||
skelobj = skel_get(prinst, 0, numbones);
|
||||
if (!skelobj)
|
||||
return; //couldn't get one, ran out of memory or something?
|
||||
|
||||
if (isabs || skelobj->numbones != Mod_GetBoneRelations(model, skelobj->numbones, &fstate, skelobj->bonematrix))
|
||||
{
|
||||
isabs = true;
|
||||
// float *ab;
|
||||
// ab = Alias_GetBonePositions(model, &fstate, skelobj->bonematrix, skelobj->numbones);
|
||||
// if (ab != skelobj->bonematrix)
|
||||
// memcpy(skelobj->bonematrix, ab, skelobj->numbones*12*sizeof(float));
|
||||
}
|
||||
|
||||
skelobj->model = model;
|
||||
skelobj->absolute = isabs;
|
||||
|
||||
G_FLOAT(OFS_RETURN) = (skelobj - skelobjects) + 1;
|
||||
}
|
||||
|
||||
//#264 float(float skel) skel_get_numbones (FTE_CSQC_SKELETONOBJECTS)
|
||||
//float(float skel, entity ent, float modelindex, float retainfrac, float firstbone, float lastbone) skel_get_numbones (FTE_CSQC_SKELETONOBJECTS)
|
||||
static void PF_skel_build(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int skelidx = G_FLOAT(OFS_PARM0);
|
||||
csqcedict_t *ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM1);
|
||||
int midx = G_FLOAT(OFS_PARM2);
|
||||
int retainfrac = G_FLOAT(OFS_PARM3);
|
||||
int firstbone = G_FLOAT(OFS_PARM4)-1;
|
||||
int lastbone = G_FLOAT(OFS_PARM5)-1;
|
||||
|
||||
int numbones;
|
||||
framestate_t fstate;
|
||||
skelobject_t *skelobj;
|
||||
model_t *model;
|
||||
|
||||
//default to failure
|
||||
G_FLOAT(OFS_RETURN) = 0;
|
||||
|
||||
model = CSQC_GetModelForIndex(midx);
|
||||
if (!model)
|
||||
return; //invalid model, can't get a skeleton
|
||||
|
||||
cs_getframestate(ent, ent->v->renderflags, &fstate);
|
||||
|
||||
//heh... don't copy.
|
||||
fstate.bonecount = 0;
|
||||
fstate.bonestate = NULL;
|
||||
|
||||
numbones = Mod_GetNumBones(model, false);
|
||||
if (!numbones)
|
||||
{
|
||||
return; //this isn't a skeletal model.
|
||||
}
|
||||
|
||||
skelobj = skel_get(prinst, skelidx, 0);
|
||||
if (!skelobj)
|
||||
return; //couldn't get one, ran out of memory or something?
|
||||
|
||||
if (lastbone < 0)
|
||||
lastbone = numbones;
|
||||
if (lastbone > numbones)
|
||||
lastbone = numbones;
|
||||
if (firstbone < 0)
|
||||
firstbone = 0;
|
||||
|
||||
if (retainfrac >= 1)
|
||||
{
|
||||
//retain everything...
|
||||
}
|
||||
else if (retainfrac>0)
|
||||
{
|
||||
//codeme
|
||||
}
|
||||
else
|
||||
Mod_GetBoneRelations(model, firstbone, lastbone, &fstate, skelobj->bonematrix);
|
||||
|
||||
G_FLOAT(OFS_RETURN) = (skelobj - skelobjects) + 1;
|
||||
}
|
||||
|
||||
//float(float skel) skel_get_numbones (FTE_CSQC_SKELETONOBJECTS)
|
||||
static void PF_skel_get_numbones (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int skelidx = G_FLOAT(OFS_PARM0);
|
||||
|
@ -3601,7 +3761,7 @@ static void PF_skel_get_numbones (progfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
G_FLOAT(OFS_RETURN) = skelobj->numbones;
|
||||
}
|
||||
|
||||
//#265 string(float skel, float bonenum) skel_get_bonename (FTE_CSQC_SKELETONOBJECTS) (returns tempstring)
|
||||
//string(float skel, float bonenum) skel_get_bonename (FTE_CSQC_SKELETONOBJECTS) (returns tempstring)
|
||||
static void PF_skel_get_bonename (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int skelidx = G_FLOAT(OFS_PARM0);
|
||||
|
@ -3618,7 +3778,7 @@ static void PF_skel_get_bonename (progfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
}
|
||||
}
|
||||
|
||||
//#266 float(float skel, float bonenum) skel_get_boneparent (FTE_CSQC_SKELETONOBJECTS)
|
||||
//float(float skel, float bonenum) skel_get_boneparent (FTE_CSQC_SKELETONOBJECTS)
|
||||
static void PF_skel_get_boneparent (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int skelidx = G_FLOAT(OFS_PARM0);
|
||||
|
@ -3633,7 +3793,7 @@ static void PF_skel_get_boneparent (progfuncs_t *prinst, struct globalvars_s *pr
|
|||
G_FLOAT(OFS_RETURN) = Mod_GetBoneParent(skelobj->model, boneidx);
|
||||
}
|
||||
|
||||
//#267 float(float skel, string tagname) gettagindex (DP_MD3_TAGSINFO)
|
||||
//float(float skel, string tagname) gettagindex (DP_MD3_TAGSINFO)
|
||||
static void PF_skel_find_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int skelidx = G_FLOAT(OFS_PARM0);
|
||||
|
@ -3647,7 +3807,7 @@ static void PF_skel_find_bone (progfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
G_FLOAT(OFS_RETURN) = Mod_TagNumForName(skelobj->model, bname);
|
||||
}
|
||||
|
||||
//#268 vector(float skel, float bonenum) skel_get_bonerel (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
|
||||
//vector(float skel, float bonenum) skel_get_bonerel (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
|
||||
static void PF_skel_get_bonerel (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int skelidx = G_FLOAT(OFS_PARM0);
|
||||
|
@ -3687,34 +3847,98 @@ static void PF_skel_get_bonerel (progfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
}
|
||||
}
|
||||
|
||||
//#269 vector(float skel, float bonenum) skel_get_boneabs (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
|
||||
//vector(float skel, float bonenum) skel_get_boneabs (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
|
||||
static void PF_skel_get_boneabs (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int skelidx = G_FLOAT(OFS_PARM0);
|
||||
int boneidx = G_FLOAT(OFS_PARM1)-1;
|
||||
float *matrix[4];
|
||||
float *rmatrix[4];
|
||||
float workingm[12], tempmatrix[3][4];
|
||||
skelobject_t *skelobj;
|
||||
matrix[0] = csqcg.forward;
|
||||
matrix[1] = csqcg.right;
|
||||
matrix[2] = csqcg.up;
|
||||
matrix[3] = G_VECTOR(OFS_RETURN);
|
||||
int i;
|
||||
rmatrix[0] = csqcg.forward;
|
||||
rmatrix[1] = csqcg.right;
|
||||
rmatrix[2] = csqcg.up;
|
||||
rmatrix[3] = G_VECTOR(OFS_RETURN);
|
||||
|
||||
skelobj = skel_get(prinst, skelidx, 0);
|
||||
|
||||
//codeme
|
||||
if (!skelobj || (unsigned int)boneidx >= skelobj->numbones)
|
||||
{
|
||||
rmatrix[0][0] = 1;
|
||||
rmatrix[0][1] = 0;
|
||||
rmatrix[0][2] = 0;
|
||||
|
||||
rmatrix[1][0] = 0;
|
||||
rmatrix[1][1] = 1;
|
||||
rmatrix[1][2] = 0;
|
||||
|
||||
rmatrix[2][0] = 0;
|
||||
rmatrix[2][1] = 0;
|
||||
rmatrix[2][2] = 1;
|
||||
|
||||
rmatrix[3][0] = 0;
|
||||
rmatrix[3][1] = 0;
|
||||
rmatrix[3][2] = 0;
|
||||
}
|
||||
else if (skelobj->absolute)
|
||||
{
|
||||
//can just copy it out
|
||||
memcpy(rmatrix[0], skelobj->bonematrix + boneidx*12 + 0, sizeof(vec3_t));
|
||||
memcpy(rmatrix[1], skelobj->bonematrix + boneidx*12 + 3, sizeof(vec3_t));
|
||||
memcpy(rmatrix[2], skelobj->bonematrix + boneidx*12 + 6, sizeof(vec3_t));
|
||||
memcpy(rmatrix[3], skelobj->bonematrix + boneidx*12 + 9, sizeof(vec3_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
//we need to work out the abs position
|
||||
|
||||
//testme
|
||||
|
||||
//set up an identity matrix
|
||||
for (i = 0;i < 12;i++)
|
||||
workingm[i] = 0;
|
||||
workingm[0] = 1;
|
||||
workingm[5] = 1;
|
||||
workingm[10] = 1;
|
||||
|
||||
while(boneidx >= 0)
|
||||
{
|
||||
//copy out the previous working matrix, so we don't stomp on it
|
||||
memcpy(tempmatrix, workingm, sizeof(tempmatrix));
|
||||
R_ConcatTransforms((void*)(skelobj->bonematrix + boneidx*12), (void*)tempmatrix, (void*)workingm);
|
||||
|
||||
boneidx = Mod_GetBoneParent(skelobj->model, boneidx+1)-1;
|
||||
}
|
||||
memcpy(rmatrix[0], (workingm+0), sizeof(vec3_t));
|
||||
memcpy(rmatrix[1], (workingm+3), sizeof(vec3_t));
|
||||
memcpy(rmatrix[2], (workingm+6), sizeof(vec3_t));
|
||||
memcpy(rmatrix[3], (workingm+9), sizeof(vec3_t));
|
||||
}
|
||||
}
|
||||
|
||||
//#270 void(float skel, float bonenum, vector org) skel_set_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
|
||||
//void(float skel, float bonenum, vector org) skel_set_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
|
||||
static void PF_skel_set_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int skelidx = G_FLOAT(OFS_PARM0);
|
||||
unsigned int boneidx = G_FLOAT(OFS_PARM1)-1;
|
||||
float *matrix[4];
|
||||
skelobject_t *skelobj;
|
||||
matrix[0] = csqcg.forward;
|
||||
matrix[1] = csqcg.right;
|
||||
matrix[2] = csqcg.up;
|
||||
matrix[3] = G_VECTOR(OFS_PARM2);
|
||||
|
||||
if (*prinst->callargc > 5)
|
||||
{
|
||||
matrix[3] = G_VECTOR(OFS_PARM2);
|
||||
matrix[0] = G_VECTOR(OFS_PARM3);
|
||||
matrix[1] = G_VECTOR(OFS_PARM4);
|
||||
matrix[2] = G_VECTOR(OFS_PARM5);
|
||||
}
|
||||
else
|
||||
{
|
||||
matrix[0] = csqcg.forward;
|
||||
matrix[1] = csqcg.right;
|
||||
matrix[2] = csqcg.up;
|
||||
matrix[3] = G_VECTOR(OFS_PARM2);
|
||||
}
|
||||
|
||||
skelobj = skel_get(prinst, skelidx, 0);
|
||||
if (!skelobj || boneidx >= skelobj->numbones)
|
||||
|
@ -3726,7 +3950,7 @@ static void PF_skel_set_bone (progfuncs_t *prinst, struct globalvars_s *pr_globa
|
|||
VectorCopy(matrix[3], skelobj->bonematrix+12*boneidx+9);
|
||||
}
|
||||
|
||||
//#271 void(float skel, float bonenum, vector org) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
|
||||
//void(float skel, float bonenum, vector org) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
|
||||
static void PF_skel_mul_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int skelidx = G_FLOAT(OFS_PARM0);
|
||||
|
@ -3734,10 +3958,20 @@ static void PF_skel_mul_bone (progfuncs_t *prinst, struct globalvars_s *pr_globa
|
|||
float temp[3][4];
|
||||
float mult[3][4];
|
||||
skelobject_t *skelobj;
|
||||
VectorCopy(csqcg.forward, mult[0]);
|
||||
VectorCopy(csqcg.right, mult[1]);
|
||||
VectorCopy(csqcg.up, mult[2]);
|
||||
VectorCopy(G_VECTOR(OFS_PARM2), mult[3]);
|
||||
if (*prinst->callargc > 5)
|
||||
{
|
||||
VectorCopy(G_VECTOR(OFS_PARM2), mult[3]);
|
||||
VectorCopy(G_VECTOR(OFS_PARM3), mult[0]);
|
||||
VectorCopy(G_VECTOR(OFS_PARM4), mult[1]);
|
||||
VectorCopy(G_VECTOR(OFS_PARM5), mult[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy(csqcg.forward, mult[0]);
|
||||
VectorCopy(csqcg.right, mult[1]);
|
||||
VectorCopy(csqcg.up, mult[2]);
|
||||
VectorCopy(G_VECTOR(OFS_PARM2), mult[3]);
|
||||
}
|
||||
|
||||
skelobj = skel_get(prinst, skelidx, 0);
|
||||
if (!skelobj || boneidx >= skelobj->numbones)
|
||||
|
@ -3750,7 +3984,7 @@ static void PF_skel_mul_bone (progfuncs_t *prinst, struct globalvars_s *pr_globa
|
|||
R_ConcatTransforms(mult, temp, (float(*)[4])(skelobj->bonematrix+12*boneidx));
|
||||
}
|
||||
|
||||
//#272 void(float skel, float startbone, float endbone, vector org) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
|
||||
//void(float skel, float startbone, float endbone, vector org) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
|
||||
static void PF_skel_mul_bones (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int skelidx = G_FLOAT(OFS_PARM0);
|
||||
|
@ -3759,10 +3993,20 @@ static void PF_skel_mul_bones (progfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
float temp[3][4];
|
||||
float mult[3][4];
|
||||
skelobject_t *skelobj;
|
||||
VectorCopy(csqcg.forward, mult[0]);
|
||||
VectorCopy(csqcg.right, mult[1]);
|
||||
VectorCopy(csqcg.up, mult[2]);
|
||||
VectorCopy(G_VECTOR(OFS_PARM2), mult[3]);
|
||||
if (*prinst->callargc > 6)
|
||||
{
|
||||
VectorCopy(G_VECTOR(OFS_PARM3), mult[3]);
|
||||
VectorCopy(G_VECTOR(OFS_PARM4), mult[0]);
|
||||
VectorCopy(G_VECTOR(OFS_PARM5), mult[1]);
|
||||
VectorCopy(G_VECTOR(OFS_PARM6), mult[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy(csqcg.forward, mult[0]);
|
||||
VectorCopy(csqcg.right, mult[1]);
|
||||
VectorCopy(csqcg.up, mult[2]);
|
||||
VectorCopy(G_VECTOR(OFS_PARM3), mult[3]);
|
||||
}
|
||||
|
||||
skelobj = skel_get(prinst, skelidx, 0);
|
||||
if (!skelobj)
|
||||
|
@ -3781,7 +4025,7 @@ static void PF_skel_mul_bones (progfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
}
|
||||
}
|
||||
|
||||
//#273 void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones (FTE_CSQC_SKELETONOBJECTS)
|
||||
//void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones (FTE_CSQC_SKELETONOBJECTS)
|
||||
static void PF_skel_copybones (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int skeldst = G_FLOAT(OFS_PARM0);
|
||||
|
@ -3796,6 +4040,8 @@ static void PF_skel_copybones (progfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
skelobjsrc = skel_get(prinst, skelsrc, 0);
|
||||
if (!skelobjdst || !skelobjsrc)
|
||||
return;
|
||||
if (skelobjsrc->absolute != skelobjdst->absolute)
|
||||
return;
|
||||
|
||||
if (startbone == -1)
|
||||
startbone = 0;
|
||||
|
@ -3809,7 +4055,7 @@ static void PF_skel_copybones (progfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
}
|
||||
}
|
||||
|
||||
//#274 void(float skel) skel_delete (FTE_CSQC_SKELETONOBJECTS)
|
||||
//void(float skel) skel_delete (FTE_CSQC_SKELETONOBJECTS)
|
||||
static void PF_skel_delete (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int skelidx = G_FLOAT(OFS_PARM0);
|
||||
|
@ -4802,19 +5048,20 @@ static struct {
|
|||
{"stoh", PF_stoh, 261},
|
||||
{"htos", PF_htos, 262},
|
||||
|
||||
{"skel_buildrel", PF_skel_buildrel, 263},//float(entity ent) skel_buildrel (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"skel_get_numbones", PF_skel_get_numbones, 264},//float(float skel) skel_get_numbones (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"skel_get_bonename", PF_skel_get_bonename, 265},//string(float skel, float bonenum) skel_get_bonename (FTE_CSQC_SKELETONOBJECTS) (returns tempstring)
|
||||
{"skel_get_boneparent", PF_skel_get_boneparent, 266},//float(float skel, float bonenum) skel_get_boneparent (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"skel_find_bone", PF_skel_find_bone, 267},//float(float skel, string tagname) gettagindex (DP_MD3_TAGSINFO)
|
||||
{"skel_get_bonerel", PF_skel_get_bonerel, 268},//vector(float skel, float bonenum) skel_get_bonerel (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
|
||||
{"skel_get_boneabs", PF_skel_get_boneabs, 269},//vector(float skel, float bonenum) skel_get_boneabs (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
|
||||
{"skel_set_bone", PF_skel_set_bone, 270},//void(float skel, float bonenum, vector org) skel_set_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
|
||||
{"skel_mul_bone", PF_skel_mul_bone, 271},//void(float skel, float bonenum, vector org) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
|
||||
{"skel_mul_bones", PF_skel_mul_bones, 272},//void(float skel, float startbone, float endbone, vector org) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
|
||||
{"skel_copybones", PF_skel_copybones, 273},//void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"skel_delete", PF_skel_delete, 274},//void(float skel) skel_delete (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"frameforname", PF_frameforname, 275}, // #275
|
||||
{"skel_create", PF_skel_create, 263},//float(float modlindex) skel_create = #263; // (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"skel_build", PF_skel_build, 264},//float(float skel, entity ent, float modlindex, float firstbone, float lastbone) skel_build = #263; // (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"skel_get_numbones", PF_skel_get_numbones, 265},//float(float skel) skel_get_numbones = #264; // (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"skel_get_bonename", PF_skel_get_bonename, 266},//string(float skel, float bonenum) skel_get_bonename = #265; // (FTE_CSQC_SKELETONOBJECTS) (returns tempstring)
|
||||
{"skel_get_boneparent", PF_skel_get_boneparent, 267},//float(float skel, float bonenum) skel_get_boneparent = #266; // (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"skel_find_bone", PF_skel_find_bone, 268},//float(float skel, string tagname) skel_get_boneidx = #267; // (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"skel_get_bonerel", PF_skel_get_bonerel, 269},//vector(float skel, float bonenum) skel_get_bonerel = #268; // (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
|
||||
{"skel_get_boneabs", PF_skel_get_boneabs, 270},//vector(float skel, float bonenum) skel_get_boneabs = #269; // (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
|
||||
{"skel_set_bone", PF_skel_set_bone, 271},//void(float skel, float bonenum, vector org) skel_set_bone = #270; // (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
|
||||
{"skel_mul_bone", PF_skel_mul_bone, 272},//void(float skel, float bonenum, vector org) skel_mul_bone = #271; // (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
|
||||
{"skel_mul_bones", PF_skel_mul_bones, 273},//void(float skel, float startbone, float endbone, vector org) skel_mul_bone = #272; // (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
|
||||
{"skel_copybones", PF_skel_copybones, 274},//void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones = #273; // (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"skel_delete", PF_skel_delete, 275},//void(float skel) skel_delete = #274; // (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"frameforname", PF_frameforname, 276},//void(float modidx, string framename) frameforname = #275 (FTE_CSQC_SKELETONOBJECTS)
|
||||
|
||||
//300
|
||||
{"clearscene", PF_R_ClearScene, 300}, // #300 void() clearscene (EXT_CSQC)
|
||||
|
@ -5157,8 +5404,19 @@ void CSQC_Shutdown(void)
|
|||
}
|
||||
csqcprogs = NULL;
|
||||
|
||||
Z_Free(csqcdelta_pack_new.e);
|
||||
memset(&csqcdelta_pack_new, 0, sizeof(csqcdelta_pack_new));
|
||||
Z_Free(csqcdelta_pack_old.e);
|
||||
memset(&csqcdelta_pack_old, 0, sizeof(csqcdelta_pack_old));
|
||||
|
||||
memset(&deltafunction, 0, sizeof(deltafunction));
|
||||
memset(csqcdelta_playerents, 0, sizeof(csqcdelta_playerents));
|
||||
|
||||
csqcmapentitydata = NULL;
|
||||
csqcmapentitydataloaded = false;
|
||||
|
||||
in_sensitivityscale = 1;
|
||||
num_csqc_edicts = 0;
|
||||
|
||||
csqc_usinglistener = false;
|
||||
}
|
||||
|
@ -5276,6 +5534,7 @@ double csqctime;
|
|||
qboolean CSQC_Init (unsigned int checksum)
|
||||
{
|
||||
int i;
|
||||
string_t *str;
|
||||
csqcedict_t *worldent;
|
||||
csqcchecksum = checksum;
|
||||
|
||||
|
@ -5349,6 +5608,7 @@ qboolean CSQC_Init (unsigned int checksum)
|
|||
csqcprogs = InitProgs(&csqcprogparms);
|
||||
PR_Configure(csqcprogs, -1, 16);
|
||||
|
||||
CS_ClearWorld();
|
||||
CSQC_InitFields(); //let the qclib know the field order that the engine needs.
|
||||
|
||||
csqc_isdarkplaces = false;
|
||||
|
@ -5368,18 +5628,16 @@ qboolean CSQC_Init (unsigned int checksum)
|
|||
return false;
|
||||
}
|
||||
|
||||
num_csqc_edicts = 0;
|
||||
CS_ClearWorld();
|
||||
|
||||
PF_InitTempStrings(csqcprogs);
|
||||
|
||||
CSQC_FindGlobals();
|
||||
|
||||
csqc_fakereadbyte = -1;
|
||||
memset(csqcent, 0, sizeof(*csqcent)*maxcsqcentities); //clear the server->csqc entity translations.
|
||||
|
||||
csqcentsize = PR_InitEnts(csqcprogs, pr_csmaxedicts.value);
|
||||
|
||||
CSQC_FindGlobals();
|
||||
|
||||
ED_Alloc(csqcprogs); //we need a word entity.
|
||||
//world edict becomes readonly
|
||||
worldent = (csqcedict_t *)EDICT_NUM(csqcprogs, 0);
|
||||
|
@ -5388,17 +5646,18 @@ qboolean CSQC_Init (unsigned int checksum)
|
|||
worldent->isfree = false;
|
||||
worldent->v->model = PR_SetString(csqcprogs, cl.model_name[1]);
|
||||
|
||||
Z_Free(csqcdelta_pack_new.e);
|
||||
memset(&csqcdelta_pack_new, 0, sizeof(csqcdelta_pack_new));
|
||||
Z_Free(csqcdelta_pack_old.e);
|
||||
memset(&csqcdelta_pack_old, 0, sizeof(csqcdelta_pack_old));
|
||||
|
||||
memset(&deltafunction, 0, sizeof(deltafunction));
|
||||
|
||||
memset(csqcdelta_playerents, 0, sizeof(csqcdelta_playerents));
|
||||
|
||||
csqcmapentitydata = NULL;
|
||||
csqcmapentitydataloaded = false;
|
||||
str = (string_t*)csqcprogs->GetEdictFieldValue(csqcprogs, (edict_t*)worldent, "message", NULL);
|
||||
if (str)
|
||||
*str = PR_SetString(csqcprogs, cl.levelname);
|
||||
|
||||
str = (string_t*)PR_FindGlobal(csqcprogs, "mapname", 0);
|
||||
if (str)
|
||||
{
|
||||
char *s = Info_ValueForKey(cl.serverinfo, "map");
|
||||
if (!*s)
|
||||
s = "unknown";
|
||||
*str = PR_NewString(csqcprogs, s, strlen(s)+1);
|
||||
}
|
||||
|
||||
if (csqcg.init_function)
|
||||
{
|
||||
|
@ -5410,6 +5669,7 @@ qboolean CSQC_Init (unsigned int checksum)
|
|||
}
|
||||
|
||||
Con_Printf("Loaded csqc\n");
|
||||
csqcmapentitydataloaded = false;
|
||||
}
|
||||
|
||||
return true; //success!
|
||||
|
|
|
@ -356,7 +356,7 @@ cvar_t r_shadows = SCVARF ("r_shadows", "0",
|
|||
CVAR_ARCHIVE | CVAR_RENDERERLATCH);
|
||||
cvar_t r_vertexdlights = SCVAR ("r_vertexdlights", "1");
|
||||
|
||||
cvar_t vid_preservegamma = SCVAR ("vid_preservegamma", "1");
|
||||
cvar_t vid_preservegamma = SCVAR ("vid_preservegamma", "0");
|
||||
cvar_t vid_hardwaregamma = SCVARF ("vid_hardwaregamma", "1",
|
||||
CVAR_ARCHIVE | CVAR_RENDERERLATCH);
|
||||
cvar_t vid_desktopgamma = SCVARF ("vid_desktopgamma", "0",
|
||||
|
|
|
@ -105,4 +105,4 @@ enum
|
|||
LS_CLIENT,
|
||||
};
|
||||
int SCR_GetLoadingStage(void);
|
||||
void SCR_SetLoadingStage(int stage);
|
||||
void SCR_SetLoadingStage(int stage);
|
||||
|
|
|
@ -133,7 +133,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define Q2CLIENT //client can connect to q2 servers
|
||||
#define Q3CLIENT
|
||||
#define Q3SERVER
|
||||
// #define HLSERVER
|
||||
// #define HLCLIENT //we can run HL gamecode (not protocol compatible)
|
||||
// #define HLSERVER //we can run HL gamecode (not protocol compatible)
|
||||
#define NQPROT //server and client are capable of using quake1/netquake protocols. (qw is still prefered. uses the command 'nqconnect')
|
||||
#define FISH //sw rendering only
|
||||
#define ZLIB //zip/pk3 support
|
||||
|
|
|
@ -194,7 +194,7 @@ static int Alias_BuildLerps(float plerp[4], float *pose[4], int numbones, galias
|
|||
}
|
||||
|
||||
//
|
||||
int Alias_GetBoneRelations(galiasinfo_t *inf, framestate_t *fstate, float *result, int numbones)
|
||||
int Alias_GetBoneRelations(galiasinfo_t *inf, framestate_t *fstate, float *result, int firstbone, int lastbones)
|
||||
{
|
||||
#ifdef SKELETALMODELS
|
||||
if (inf->numbones)
|
||||
|
@ -215,20 +215,20 @@ int Alias_GetBoneRelations(galiasinfo_t *inf, framestate_t *fstate, float *resul
|
|||
|
||||
int bonegroup;
|
||||
int cbone = 0;
|
||||
int lastbone;
|
||||
int endbone;
|
||||
|
||||
if (numbones > inf->numbones)
|
||||
numbones = inf->numbones;
|
||||
if (!numbones)
|
||||
if (lastbones > inf->numbones)
|
||||
lastbones = inf->numbones;
|
||||
if (!lastbones)
|
||||
return 0;
|
||||
|
||||
for (bonegroup = 0; bonegroup < FS_COUNT; bonegroup++)
|
||||
{
|
||||
lastbone = fstate->g[bonegroup].endbone;
|
||||
if (bonegroup == FS_COUNT-1 || lastbone > numbones)
|
||||
lastbone = numbones;
|
||||
endbone = fstate->g[bonegroup].endbone;
|
||||
if (bonegroup == FS_COUNT-1 || endbone > lastbones)
|
||||
endbone = lastbones;
|
||||
|
||||
if (lastbone == cbone)
|
||||
if (endbone == cbone)
|
||||
continue;
|
||||
|
||||
frame1 = fstate->g[bonegroup].frame[0];
|
||||
|
@ -259,14 +259,14 @@ int Alias_GetBoneRelations(galiasinfo_t *inf, framestate_t *fstate, float *resul
|
|||
|
||||
if (numposes == 1)
|
||||
{
|
||||
memcpy(result, pose[0]+cbone*12, (lastbone-cbone)*12*sizeof(float));
|
||||
result += (lastbone-cbone)*12;
|
||||
cbone = lastbone;
|
||||
memcpy(result, pose[0]+cbone*12, (lastbones-cbone)*12*sizeof(float));
|
||||
result += (lastbones-cbone)*12;
|
||||
cbone = lastbones;
|
||||
}
|
||||
else
|
||||
{
|
||||
//set up the identity matrix
|
||||
for (; cbone < lastbone; cbone++)
|
||||
for (; cbone < lastbones; cbone++)
|
||||
{
|
||||
//set up the per-bone transform matrix
|
||||
for (k = 0;k < 12;k++)
|
||||
|
@ -306,7 +306,7 @@ float *Alias_GetBonePositions(galiasinfo_t *inf, framestate_t *fstate, float *bu
|
|||
}
|
||||
else
|
||||
{
|
||||
numbones = Alias_GetBoneRelations(inf, fstate, (float*)relationsbuf, inf->numbones);
|
||||
numbones = Alias_GetBoneRelations(inf, fstate, (float*)relationsbuf, 0, inf->numbones);
|
||||
if (numbones == inf->numbones)
|
||||
relations = (float*)relationsbuf;
|
||||
}
|
||||
|
@ -2351,7 +2351,7 @@ int Mod_GetNumBones(model_t *model, qboolean allowtags)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int Mod_GetBoneRelations(model_t *model, int numbones, framestate_t *fstate, float *result)
|
||||
int Mod_GetBoneRelations(model_t *model, int firstbone, int lastbone, framestate_t *fstate, float *result)
|
||||
{
|
||||
#ifdef SKELETALMODELS
|
||||
galiasinfo_t *inf;
|
||||
|
@ -2361,7 +2361,7 @@ int Mod_GetBoneRelations(model_t *model, int numbones, framestate_t *fstate, flo
|
|||
return false;
|
||||
|
||||
inf = Mod_Extradata(model);
|
||||
return Alias_GetBoneRelations(inf, fstate, result, numbones);
|
||||
return Alias_GetBoneRelations(inf, fstate, result, firstbone, lastbone);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2131,6 +2131,9 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base
|
|||
//append SteamApps\common\hexen 2
|
||||
}
|
||||
|
||||
#ifndef NPQTV //this is *really* unfortunate, but doing this crashes the browser
|
||||
//I assume its because the client
|
||||
|
||||
if (poshname)
|
||||
{
|
||||
char resultpath[MAX_PATH];
|
||||
|
@ -2173,6 +2176,7 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base
|
|||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -623,7 +623,6 @@ PM_AirMove
|
|||
void PM_AirMove (void)
|
||||
{
|
||||
int i;
|
||||
vec3_t wishvel;
|
||||
float fmove, smove;
|
||||
vec3_t wishdir;
|
||||
float wishspeed;
|
||||
|
@ -637,10 +636,9 @@ void PM_AirMove (void)
|
|||
VectorNormalize (right);
|
||||
|
||||
for (i=0 ; i<2 ; i++)
|
||||
wishvel[i] = forward[i]*fmove + right[i]*smove;
|
||||
wishvel[2] = 0;
|
||||
wishdir[i] = forward[i]*fmove + right[i]*smove;
|
||||
wishdir[2] = 0;
|
||||
|
||||
VectorCopy (wishvel, wishdir);
|
||||
wishspeed = VectorNormalize(wishdir);
|
||||
|
||||
//
|
||||
|
@ -648,7 +646,6 @@ void PM_AirMove (void)
|
|||
//
|
||||
if (wishspeed > movevars.maxspeed)
|
||||
{
|
||||
VectorScale (wishvel, movevars.maxspeed/wishspeed, wishvel);
|
||||
wishspeed = movevars.maxspeed;
|
||||
}
|
||||
|
||||
|
|
|
@ -1325,6 +1325,12 @@ static void QCC_FreeTemps(void)
|
|||
{
|
||||
temp_t *t;
|
||||
|
||||
if (def_ret.temp && def_ret.temp->used)
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_DEBUGGING, "Return value still in use in %s", pr_scope->name);
|
||||
def_ret.temp->used = false;
|
||||
}
|
||||
|
||||
t = functemps;
|
||||
while(t)
|
||||
{
|
||||
|
@ -2583,6 +2589,208 @@ void QCC_PrecacheFileOptimised (char *n, int ch)
|
|||
numfiles++;
|
||||
}
|
||||
|
||||
QCC_def_t *QCC_PR_GenerateFunctionCall (QCC_def_t *func, QCC_def_t *arglist[], int argcount) //warning, the func could have no name set if it's a field call.
|
||||
{
|
||||
QCC_def_t *d, *oldret, *oself;
|
||||
int i;
|
||||
QCC_type_t *t;
|
||||
int extraparms=false;
|
||||
int np;
|
||||
int laststatement = numstatements;
|
||||
|
||||
int callconvention;
|
||||
QCC_dstatement_t *st;
|
||||
|
||||
|
||||
func->timescalled++;
|
||||
|
||||
if (QCC_OPCodeValid(&pr_opcodes[OP_CALL1H]))
|
||||
callconvention = OP_CALL1H; //FTE extended
|
||||
else
|
||||
callconvention = OP_CALL1; //standard
|
||||
|
||||
t = func->type;
|
||||
|
||||
if (t->type == ev_variant)
|
||||
{
|
||||
t->aux_type = type_variant;
|
||||
}
|
||||
|
||||
if (t->type != ev_function && t->type != ev_variant)
|
||||
{
|
||||
QCC_PR_ParseErrorPrintDef (ERR_NOTAFUNCTION, func, "not a function");
|
||||
}
|
||||
|
||||
// copy the arguments to the global parameter variables
|
||||
if (t->type == ev_variant)
|
||||
{
|
||||
extraparms = true;
|
||||
np = 0;
|
||||
}
|
||||
else if (t->num_parms < 0)
|
||||
{
|
||||
extraparms = true;
|
||||
np = (t->num_parms * -1) - 1;
|
||||
}
|
||||
else
|
||||
np = t->num_parms;
|
||||
|
||||
if (strchr(func->name, ':') && laststatement && statements[laststatement-1].op == OP_LOAD_FNC && statements[laststatement-1].c == func->ofs)
|
||||
{ //we're entering OO code with a different self.
|
||||
//eg: other.touch(self)
|
||||
|
||||
//FIXME: problems could occur with hexen2 calling conventions when parm0/1 is 'self'
|
||||
//thiscall. copy the right ent into 'self' (if it's not the same offset)
|
||||
d = QCC_PR_GetDef(type_entity, "self", NULL, true, 1, false);
|
||||
if (statements[laststatement-1].a != d->ofs)
|
||||
{
|
||||
oself = QCC_GetTemp(type_entity);
|
||||
//oself = self
|
||||
QCC_PR_SimpleStatement(OP_STORE_ENT, d->ofs, oself->ofs, 0, false);
|
||||
//self = other
|
||||
QCC_PR_SimpleStatement(OP_STORE_ENT, statements[laststatement-1].a, d->ofs, 0, false);
|
||||
|
||||
//if the args refered to self, update them to refer to oself instead
|
||||
//(as self is now set to 'other')
|
||||
for (i = 0; i < argcount; i++)
|
||||
{
|
||||
if (arglist[i]->ofs == d->ofs)
|
||||
{
|
||||
arglist[i] = oself;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//it was self.func() anyway
|
||||
oself = NULL;
|
||||
d = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //regular func call
|
||||
oself = NULL;
|
||||
d = NULL;
|
||||
}
|
||||
|
||||
// write the arguments (except for first two if hexenc)
|
||||
for (i = 0; i < argcount; i++)
|
||||
{
|
||||
if (i>=MAX_PARMS)
|
||||
d = extra_parms[i - MAX_PARMS];
|
||||
else
|
||||
d = &def_parms[i];
|
||||
|
||||
if (callconvention == OP_CALL1H)
|
||||
if (i < 2)
|
||||
{
|
||||
//first two args are passed in the call opcode, so don't need to be copied
|
||||
arglist[i]->references++;
|
||||
d->references++;
|
||||
QCC_FreeTemp(arglist[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arglist[i]->type->size>1 || !opt_nonvec_parms)
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_V], arglist[i], d, (QCC_dstatement_t **)0xffffffff));
|
||||
else
|
||||
{
|
||||
d->type = arglist[i]->type;
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], arglist[i], d, (QCC_dstatement_t **)0xffffffff));
|
||||
optres_nonvec_parms++;
|
||||
}
|
||||
}
|
||||
|
||||
//if the return value was in use, save it off now, so that it doesn't get clobbered
|
||||
if (def_ret.temp->used)
|
||||
{
|
||||
oldret = QCC_GetTemp(def_ret.type);
|
||||
if (def_ret.type->size == 3)
|
||||
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_V], &def_ret, oldret, NULL));
|
||||
else
|
||||
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], &def_ret, oldret, NULL));
|
||||
QCC_UnFreeTemp(oldret);
|
||||
QCC_UnFreeTemp(&def_ret);
|
||||
QCC_PR_ParseWarning(WARN_FIXEDRETURNVALUECONFLICT, "Return value conflict - output is inefficient");
|
||||
}
|
||||
else
|
||||
oldret = NULL;
|
||||
|
||||
//we dont need to lock the local containing the function index because its thrown away after the call anyway
|
||||
//(if a function is called in the argument list then it'll be locked as part of that call)
|
||||
QCC_FreeTemp(func);
|
||||
QCC_LockActiveTemps(); //any temps before are likly to be used with the return value.
|
||||
QCC_UnFreeTemp(func);
|
||||
|
||||
//generate the call
|
||||
if (argcount>MAX_PARMS)
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[callconvention-1+MAX_PARMS], func, 0, (QCC_dstatement_t **)&st));
|
||||
else if (argcount)
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[callconvention-1+argcount], func, 0, (QCC_dstatement_t **)&st));
|
||||
else
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_CALL0], func, 0, (QCC_dstatement_t **)&st));
|
||||
|
||||
if (callconvention == OP_CALL1H)
|
||||
{
|
||||
if (argcount)
|
||||
{
|
||||
st->b = arglist[0]->ofs;
|
||||
// QCC_FreeTemp(param[0]);
|
||||
if (argcount>1)
|
||||
{
|
||||
st->c = arglist[1]->ofs;
|
||||
// QCC_FreeTemp(param[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//restore the class owner
|
||||
if (oself)
|
||||
QCC_PR_SimpleStatement(OP_STORE_ENT, oself->ofs, d->ofs, 0, false);
|
||||
|
||||
for(; argcount; argcount--)
|
||||
{
|
||||
QCC_FreeTemp(arglist[argcount-1]);
|
||||
}
|
||||
|
||||
if (oldret)
|
||||
{
|
||||
//if we preserved the ofs_ret global, restore it here
|
||||
if (t->type == ev_variant)
|
||||
{
|
||||
d = QCC_GetTemp(type_variant);
|
||||
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, &def_ret, d, NULL));
|
||||
}
|
||||
else
|
||||
{
|
||||
d = QCC_GetTemp(t->aux_type);
|
||||
if (t->aux_type->size == 3)
|
||||
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_V, &def_ret, d, NULL));
|
||||
else
|
||||
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, &def_ret, d, NULL));
|
||||
}
|
||||
if (def_ret.type->size == 3)
|
||||
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_V, oldret, &def_ret, NULL));
|
||||
else
|
||||
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, oldret, &def_ret, NULL));
|
||||
QCC_FreeTemp(oldret);
|
||||
QCC_UnFreeTemp(&def_ret);
|
||||
QCC_UnFreeTemp(d);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
if (t->type == ev_variant)
|
||||
def_ret.type = type_variant;
|
||||
else
|
||||
def_ret.type = t->aux_type;
|
||||
if (def_ret.temp->used)
|
||||
QCC_PR_ParseWarning(WARN_FIXEDRETURNVALUECONFLICT, "Return value conflict - output is inefficient");
|
||||
def_ret.temp->used = true;
|
||||
|
||||
return &def_ret;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
PR_ParseFunctionCall
|
||||
|
@ -2591,14 +2799,13 @@ PR_ParseFunctionCall
|
|||
QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could have no name set if it's a field call.
|
||||
{
|
||||
QCC_def_t *e, *d, *old, *oself;
|
||||
int arg, i;
|
||||
int arg;
|
||||
QCC_type_t *t, *p;
|
||||
int extraparms=false;
|
||||
int np;
|
||||
int laststatement = numstatements;
|
||||
|
||||
int callconvention;
|
||||
QCC_dstatement_t *st;
|
||||
|
||||
QCC_def_t *param[MAX_PARMS+MAX_EXTRA_PARMS];
|
||||
|
||||
|
@ -3009,361 +3216,161 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
|
|||
else
|
||||
np = t->num_parms;
|
||||
|
||||
if (def_ret.temp->used)
|
||||
{
|
||||
old = QCC_GetTemp(def_ret.type);
|
||||
if (def_ret.type->size == 3)
|
||||
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_V], &def_ret, old, NULL));
|
||||
else
|
||||
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], &def_ret, old, NULL));
|
||||
QCC_UnFreeTemp(old);
|
||||
QCC_UnFreeTemp(&def_ret);
|
||||
QCC_PR_ParseWarning(WARN_FIXEDRETURNVALUECONFLICT, "Return value conflict - output is inefficient");
|
||||
}
|
||||
else
|
||||
old = NULL;
|
||||
|
||||
//we dont need to lock the local containing the function index because its thrown away after the call anyway
|
||||
//(if a function is called in the argument list then it'll be locked as part of that call)
|
||||
QCC_FreeTemp(func);
|
||||
QCC_LockActiveTemps(); //any temps before are likly to be used with the return value.
|
||||
QCC_UnFreeTemp(func);
|
||||
|
||||
//any temps referenced to build the parameters don't need to be locked.
|
||||
|
||||
if (opt_vectorcalls && (t->num_parms == 1 && t->param->type == ev_vector))
|
||||
{ //if we're using vectorcalls
|
||||
//if it's a function, takes a vector
|
||||
|
||||
//vectorcalls is an evil hack
|
||||
//it'll make your mod bigger and less efficient.
|
||||
//however, it'll cut down on numpr_globals, so your mod can become a much greater size.
|
||||
vec3_t arg;
|
||||
if (pr_token_type == tt_immediate && pr_immediate_type == type_vector)
|
||||
if (!QCC_PR_CheckToken(")"))
|
||||
{
|
||||
p = t->param;
|
||||
do
|
||||
{
|
||||
memcpy(arg, pr_immediate.vector, sizeof(arg));
|
||||
while(*pr_file_p == ' ' || *pr_file_p == '\t' || *pr_file_p == '\n')
|
||||
pr_file_p++;
|
||||
if (*pr_file_p == ')')
|
||||
{ //woot
|
||||
def_parms[0].ofs = OFS_PARM0+0;
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(arg[0]), &def_parms[0], (QCC_dstatement_t **)0xffffffff));
|
||||
def_parms[0].ofs = OFS_PARM0+1;
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(arg[1]), &def_parms[0], (QCC_dstatement_t **)0xffffffff));
|
||||
def_parms[0].ofs = OFS_PARM0+2;
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(arg[2]), &def_parms[0], (QCC_dstatement_t **)0xffffffff));
|
||||
def_parms[0].ofs = OFS_PARM0;
|
||||
if (extraparms && arg >= MAX_PARMS)
|
||||
QCC_PR_ParseErrorPrintDef (ERR_TOOMANYPARAMETERSVARARGS, func, "More than %i parameters on varargs function", MAX_PARMS);
|
||||
else if (arg >= MAX_PARMS+MAX_EXTRA_PARMS)
|
||||
QCC_PR_ParseErrorPrintDef (ERR_TOOMANYTOTALPARAMETERS, func, "More than %i parameters", MAX_PARMS+MAX_EXTRA_PARMS);
|
||||
if (!extraparms && arg >= t->num_parms)
|
||||
{
|
||||
QCC_PR_ParseWarning (WARN_TOOMANYPARAMETERSFORFUNC, "too many parameters");
|
||||
QCC_PR_ParsePrintDef(WARN_TOOMANYPARAMETERSFORFUNC, func);
|
||||
}
|
||||
|
||||
|
||||
//with vectorcalls, we store the vector into the args as individual floats
|
||||
//this allows better reuse of vector constants.
|
||||
//copy it into the offset now, because we can.
|
||||
if (opt_vectorcalls && pr_token_type == tt_immediate && pr_immediate_type == type_vector && arg < MAX_PARMS && !def_parms[arg].temp->used)
|
||||
{
|
||||
e = &def_parms[arg];
|
||||
|
||||
e->ofs = OFS_PARM0+0;
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(pr_immediate.vector[0]), e, (QCC_dstatement_t **)0xffffffff));
|
||||
e->ofs = OFS_PARM0+1;
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(pr_immediate.vector[1]), e, (QCC_dstatement_t **)0xffffffff));
|
||||
e->ofs = OFS_PARM0+2;
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], QCC_MakeFloatDef(pr_immediate.vector[2]), e, (QCC_dstatement_t **)0xffffffff));
|
||||
e->ofs = OFS_PARM0;
|
||||
|
||||
QCC_PR_Lex();
|
||||
QCC_PR_Expect(")");
|
||||
}
|
||||
else
|
||||
{ //bum
|
||||
e = QCC_PR_Expression (TOP_PRIORITY, false);
|
||||
if (e->type->type != ev_vector)
|
||||
{
|
||||
if (flag_laxcasts)
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_LAXCAST, "type mismatch on parm %i - (%s should be %s)", 1, TypeName(e->type), TypeName(type_vector));
|
||||
QCC_PR_ParsePrintDef(WARN_LAXCAST, func);
|
||||
}
|
||||
else
|
||||
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHPARM, func, "type mismatch on parm %i - (%s should be %s)", 1, TypeName(e->type), TypeName(type_vector));
|
||||
}
|
||||
QCC_PR_Expect(")");
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_V], e, &def_parms[0], (QCC_dstatement_t **)0xffffffff));
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //bother
|
||||
e = QCC_PR_Expression (TOP_PRIORITY, false);
|
||||
if (e->type->type != ev_vector)
|
||||
{
|
||||
if (flag_laxcasts)
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_LAXCAST, "type mismatch on parm %i - (%s should be %s)", 1, TypeName(e->type), TypeName(type_vector));
|
||||
QCC_PR_ParsePrintDef(WARN_LAXCAST, func);
|
||||
}
|
||||
else
|
||||
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHPARM, func, "type mismatch on parm %i - (%s should be %s)", 1, TypeName(e->type), TypeName(type_vector));
|
||||
}
|
||||
QCC_PR_Expect(")");
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_V], e, &def_parms[0], (QCC_dstatement_t **)0xffffffff));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!QCC_PR_CheckToken(")"))
|
||||
{
|
||||
p = t->param;
|
||||
do
|
||||
{
|
||||
if (extraparms && arg >= MAX_PARMS)
|
||||
QCC_PR_ParseErrorPrintDef (ERR_TOOMANYPARAMETERSVARARGS, func, "More than %i parameters on varargs function", MAX_PARMS);
|
||||
else if (arg >= MAX_PARMS+MAX_EXTRA_PARMS)
|
||||
QCC_PR_ParseErrorPrintDef (ERR_TOOMANYTOTALPARAMETERS, func, "More than %i parameters", MAX_PARMS+MAX_EXTRA_PARMS);
|
||||
if (!extraparms && arg >= t->num_parms)
|
||||
{
|
||||
QCC_PR_ParseWarning (WARN_TOOMANYPARAMETERSFORFUNC, "too many parameters");
|
||||
QCC_PR_ParsePrintDef(WARN_TOOMANYPARAMETERSFORFUNC, func);
|
||||
}
|
||||
|
||||
e = QCC_PR_Expression (TOP_PRIORITY, false);
|
||||
|
||||
if (arg == 0 && func->name)
|
||||
if (arg == 0 && func->name)
|
||||
{
|
||||
// save information for model and sound caching
|
||||
if (!strncmp(func->name,"precache_", 9))
|
||||
{
|
||||
// save information for model and sound caching
|
||||
if (!strncmp(func->name,"precache_", 9))
|
||||
{
|
||||
if (!strncmp(func->name+9,"sound", 5))
|
||||
QCC_PrecacheSound (e, func->name[14]);
|
||||
else if (!strncmp(func->name+9,"model", 5))
|
||||
QCC_PrecacheModel (e, func->name[14]);
|
||||
else if (!strncmp(func->name+9,"texture", 7))
|
||||
QCC_PrecacheTexture (e, func->name[16]);
|
||||
else if (!strncmp(func->name+9,"file", 4))
|
||||
QCC_PrecacheFile (e, func->name[13]);
|
||||
}
|
||||
if (!strncmp(func->name+9,"sound", 5))
|
||||
QCC_PrecacheSound (e, func->name[14]);
|
||||
else if (!strncmp(func->name+9,"model", 5))
|
||||
QCC_PrecacheModel (e, func->name[14]);
|
||||
else if (!strncmp(func->name+9,"texture", 7))
|
||||
QCC_PrecacheTexture (e, func->name[16]);
|
||||
else if (!strncmp(func->name+9,"file", 4))
|
||||
QCC_PrecacheFile (e, func->name[13]);
|
||||
}
|
||||
}
|
||||
|
||||
if (arg>=MAX_PARMS)
|
||||
if (arg>=MAX_PARMS)
|
||||
{
|
||||
if (!extra_parms[arg - MAX_PARMS])
|
||||
{
|
||||
if (!extra_parms[arg - MAX_PARMS])
|
||||
{
|
||||
d = (QCC_def_t *) qccHunkAlloc (sizeof(QCC_def_t));
|
||||
d->name = "extra parm";
|
||||
d->ofs = QCC_GetFreeOffsetSpace (3);
|
||||
extra_parms[arg - MAX_PARMS] = d;
|
||||
}
|
||||
d = extra_parms[arg - MAX_PARMS];
|
||||
d = (QCC_def_t *) qccHunkAlloc (sizeof(QCC_def_t));
|
||||
d->name = "extra parm";
|
||||
d->ofs = QCC_GetFreeOffsetSpace (3);
|
||||
extra_parms[arg - MAX_PARMS] = d;
|
||||
}
|
||||
else
|
||||
d = &def_parms[arg];
|
||||
d = extra_parms[arg - MAX_PARMS];
|
||||
}
|
||||
else
|
||||
d = &def_parms[arg];
|
||||
|
||||
if (pr_classtype && e->type->type == ev_field && p->type != ev_field)
|
||||
{ //convert.
|
||||
oself = QCC_PR_GetDef(type_entity, "self", NULL, true, 1, false);
|
||||
switch(e->type->aux_type->type)
|
||||
{
|
||||
case ev_string:
|
||||
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_S, oself, e, NULL);
|
||||
break;
|
||||
case ev_integer:
|
||||
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_I, oself, e, NULL);
|
||||
break;
|
||||
case ev_float:
|
||||
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_F, oself, e, NULL);
|
||||
break;
|
||||
case ev_function:
|
||||
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_FNC, oself, e, NULL);
|
||||
break;
|
||||
case ev_vector:
|
||||
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_V, oself, e, NULL);
|
||||
break;
|
||||
case ev_entity:
|
||||
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_ENT, oself, e, NULL);
|
||||
break;
|
||||
default:
|
||||
QCC_Error(ERR_INTERNAL, "Bad member type. Try forced expansion");
|
||||
}
|
||||
}
|
||||
|
||||
if (p)
|
||||
if (pr_classtype && e->type->type == ev_field && p->type != ev_field)
|
||||
{ //convert.
|
||||
oself = QCC_PR_GetDef(type_entity, "self", NULL, true, 1, false);
|
||||
switch(e->type->aux_type->type)
|
||||
{
|
||||
if (typecmp(e->type, p))
|
||||
/*if (e->type->type != ev_integer && p->type != ev_function)
|
||||
if (e->type->type != ev_function && p->type != ev_integer)
|
||||
if ( e->type->type != p->type )*/
|
||||
case ev_string:
|
||||
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_S, oself, e, NULL);
|
||||
break;
|
||||
case ev_integer:
|
||||
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_I, oself, e, NULL);
|
||||
break;
|
||||
case ev_float:
|
||||
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_F, oself, e, NULL);
|
||||
break;
|
||||
case ev_function:
|
||||
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_FNC, oself, e, NULL);
|
||||
break;
|
||||
case ev_vector:
|
||||
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_V, oself, e, NULL);
|
||||
break;
|
||||
case ev_entity:
|
||||
e = QCC_PR_Statement(pr_opcodes+OP_LOAD_ENT, oself, e, NULL);
|
||||
break;
|
||||
default:
|
||||
QCC_Error(ERR_INTERNAL, "Bad member type. Try forced expansion");
|
||||
}
|
||||
}
|
||||
|
||||
if (p)
|
||||
{
|
||||
if (typecmp(e->type, p))
|
||||
/*if (e->type->type != ev_integer && p->type != ev_function)
|
||||
if (e->type->type != ev_function && p->type != ev_integer)
|
||||
if ( e->type->type != p->type )*/
|
||||
{
|
||||
if (p->type == ev_integer && e->type->type == ev_float) //convert float -> int... is this a constant?
|
||||
e = QCC_PR_Statement(pr_opcodes+OP_CONV_FTOI, e, NULL, NULL);
|
||||
else if (p->type == ev_float && e->type->type == ev_integer) //convert float -> int... is this a constant?
|
||||
e = QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, e, NULL, NULL);
|
||||
else if (p->type == ev_function && e->type->type == ev_integer && e->constant && !((int*)qcc_pr_globals)[e->ofs])
|
||||
{ //you're allowed to use int 0 to pass a null function pointer
|
||||
//this is basically because __NULL__ is defined as ~0 (int 0)
|
||||
}
|
||||
else if (p->type != ev_variant) //can cast to variant whatever happens
|
||||
{
|
||||
if (p->type == ev_integer && e->type->type == ev_float) //convert float -> int... is this a constant?
|
||||
e = QCC_PR_Statement(pr_opcodes+OP_CONV_FTOI, e, NULL, NULL);
|
||||
else if (p->type == ev_float && e->type->type == ev_integer) //convert float -> int... is this a constant?
|
||||
e = QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, e, NULL, NULL);
|
||||
else if (p->type == ev_function && e->type->type == ev_integer && e->constant && !((int*)qcc_pr_globals)[e->ofs])
|
||||
{ //you're allowed to use int 0 to pass a null function pointer
|
||||
//this is basically because __NULL__ is defined as ~0 (int 0)
|
||||
}
|
||||
else if (p->type != ev_variant) //can cast to variant whatever happens
|
||||
if (flag_laxcasts || (p->type == ev_function && e->type->type == ev_function))
|
||||
{
|
||||
if (flag_laxcasts || (p->type == ev_function && e->type->type == ev_function))
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_LAXCAST, "type mismatch on parm %i - (%s should be %s)", arg+1, TypeName(e->type), TypeName(p));
|
||||
QCC_PR_ParsePrintDef(WARN_LAXCAST, func);
|
||||
}
|
||||
else
|
||||
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHPARM, func, "type mismatch on parm %i - (%s should be %s)", arg+1, TypeName(e->type), TypeName(p));
|
||||
QCC_PR_ParseWarning(WARN_LAXCAST, "type mismatch on parm %i - (%s should be %s)", arg+1, TypeName(e->type), TypeName(p));
|
||||
QCC_PR_ParsePrintDef(WARN_LAXCAST, func);
|
||||
}
|
||||
else
|
||||
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHPARM, func, "type mismatch on parm %i - (%s should be %s)", arg+1, TypeName(e->type), TypeName(p));
|
||||
}
|
||||
|
||||
d->type = p;
|
||||
|
||||
p=p->next;
|
||||
}
|
||||
// a vector copy will copy everything
|
||||
else
|
||||
d->type = type_void;
|
||||
|
||||
if (arg == 1 && !STRCMP(func->name, "setmodel"))
|
||||
{
|
||||
QCC_SetModel(e);
|
||||
}
|
||||
|
||||
param[arg] = e;
|
||||
/* if (e->type->size>1)
|
||||
QCC_PR_Statement (&pr_opcodes[OP_STORE_V], e, d, (QCC_dstatement_t **)0xffffffff);
|
||||
else
|
||||
QCC_PR_Statement (&pr_opcodes[OP_STORE_F], e, d, (QCC_dstatement_t **)0xffffffff);
|
||||
*/
|
||||
arg++;
|
||||
} while (QCC_PR_CheckToken (","));
|
||||
d->type = p;
|
||||
|
||||
if (t->num_parms != -1 && arg < np)
|
||||
QCC_PR_ParseWarning (WARN_TOOFEWPARAMS, "too few parameters on call to %s", func->name);
|
||||
QCC_PR_Expect (")");
|
||||
}
|
||||
else if (np)
|
||||
{
|
||||
QCC_PR_ParseWarning (WARN_TOOFEWPARAMS, "%s: Too few parameters", func->name);
|
||||
QCC_PR_ParsePrintDef (WARN_TOOFEWPARAMS, func);
|
||||
}
|
||||
|
||||
// qcc_functioncalled++;
|
||||
for (i = 0; i < arg; i++)
|
||||
{
|
||||
if (i>=MAX_PARMS)
|
||||
d = extra_parms[i - MAX_PARMS];
|
||||
else
|
||||
d = &def_parms[i];
|
||||
|
||||
if (callconvention == OP_CALL1H)
|
||||
if (i < 2)
|
||||
{
|
||||
param[i]->references++;
|
||||
d->references++;
|
||||
QCC_FreeTemp(param[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param[i]->type->size>1 || !opt_nonvec_parms)
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_V], param[i], d, (QCC_dstatement_t **)0xffffffff));
|
||||
else
|
||||
{
|
||||
d->type = param[i]->type;
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], param[i], d, (QCC_dstatement_t **)0xffffffff));
|
||||
optres_nonvec_parms++;
|
||||
p=p->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strchr(func->name, ':') && laststatement && statements[laststatement-1].op == OP_LOAD_FNC && statements[laststatement-1].c == func->ofs)
|
||||
{ //we're entering OO code with a different self.
|
||||
|
||||
//FIXME: problems could occur with hexen2 calling conventions when parm0/1 is 'self'
|
||||
//thiscall. copy the right ent into 'self' (if it's not the same offset)
|
||||
d = QCC_PR_GetDef(type_entity, "self", NULL, true, 1, false);
|
||||
if (statements[laststatement-1].a != d->ofs)
|
||||
{
|
||||
oself = QCC_GetTemp(type_entity);
|
||||
QCC_PR_SimpleStatement(OP_STORE_ENT, d->ofs, oself->ofs, 0, false);
|
||||
QCC_PR_SimpleStatement(OP_STORE_ENT, statements[laststatement-1].a, d->ofs, 0, false);
|
||||
|
||||
if (callconvention == OP_CALL1H) //other.function(self)
|
||||
//hexenc calling convention would mean that the
|
||||
//passed parameter is essentually (self=other),
|
||||
//so pass oself instead which won't be affected
|
||||
{
|
||||
QCC_def_t *temp;
|
||||
if (arg>=1 && param[0]->ofs == d->ofs)
|
||||
{
|
||||
temp = QCC_GetTemp(type_entity);
|
||||
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_ENT, oself, temp, NULL));
|
||||
QCC_UnFreeTemp(temp);
|
||||
param[0] = temp;
|
||||
}
|
||||
if (arg>=2 && param[1]->ofs == d->ofs)
|
||||
{
|
||||
temp = QCC_GetTemp(type_entity);
|
||||
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_ENT, oself, temp, NULL));
|
||||
QCC_UnFreeTemp(temp);
|
||||
param[1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
oself = NULL;
|
||||
d = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
oself = NULL;
|
||||
d = NULL;
|
||||
}
|
||||
|
||||
if (arg>MAX_PARMS)
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[callconvention-1+MAX_PARMS], func, 0, (QCC_dstatement_t **)&st));
|
||||
else if (arg)
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[callconvention-1+arg], func, 0, (QCC_dstatement_t **)&st));
|
||||
else
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_CALL0], func, 0, (QCC_dstatement_t **)&st));
|
||||
|
||||
if (callconvention == OP_CALL1H)
|
||||
{
|
||||
if (arg)
|
||||
{
|
||||
st->b = param[0]->ofs;
|
||||
// QCC_FreeTemp(param[0]);
|
||||
if (arg>1)
|
||||
{
|
||||
st->c = param[1]->ofs;
|
||||
// QCC_FreeTemp(param[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (oself)
|
||||
QCC_PR_SimpleStatement(OP_STORE_ENT, oself->ofs, d->ofs, 0, false);
|
||||
|
||||
for(; arg; arg--)
|
||||
{
|
||||
QCC_FreeTemp(param[arg-1]);
|
||||
}
|
||||
|
||||
if (old)
|
||||
{
|
||||
if (t->type == ev_variant)
|
||||
{
|
||||
d = QCC_GetTemp(type_variant);
|
||||
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, &def_ret, d, NULL));
|
||||
}
|
||||
else
|
||||
{
|
||||
d = QCC_GetTemp(t->aux_type);
|
||||
if (t->aux_type->size == 3)
|
||||
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_V, &def_ret, d, NULL));
|
||||
// a vector copy will copy everything
|
||||
else
|
||||
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, &def_ret, d, NULL));
|
||||
}
|
||||
if (def_ret.type->size == 3)
|
||||
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_V, old, &def_ret, NULL));
|
||||
else
|
||||
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_STORE_F, old, &def_ret, NULL));
|
||||
QCC_FreeTemp(old);
|
||||
QCC_UnFreeTemp(&def_ret);
|
||||
QCC_UnFreeTemp(d);
|
||||
d->type = type_void;
|
||||
|
||||
return d;
|
||||
if (arg == 1 && !STRCMP(func->name, "setmodel"))
|
||||
{
|
||||
QCC_SetModel(e);
|
||||
}
|
||||
|
||||
param[arg] = e;
|
||||
/* if (e->type->size>1)
|
||||
QCC_PR_Statement (&pr_opcodes[OP_STORE_V], e, d, (QCC_dstatement_t **)0xffffffff);
|
||||
else
|
||||
QCC_PR_Statement (&pr_opcodes[OP_STORE_F], e, d, (QCC_dstatement_t **)0xffffffff);
|
||||
*/
|
||||
arg++;
|
||||
} while (QCC_PR_CheckToken (","));
|
||||
|
||||
if (t->num_parms != -1 && arg < np)
|
||||
QCC_PR_ParseWarning (WARN_TOOFEWPARAMS, "too few parameters on call to %s", func->name);
|
||||
QCC_PR_Expect (")");
|
||||
}
|
||||
else if (np)
|
||||
{
|
||||
QCC_PR_ParseWarning (WARN_TOOFEWPARAMS, "%s: Too few parameters", func->name);
|
||||
QCC_PR_ParsePrintDef (WARN_TOOFEWPARAMS, func);
|
||||
}
|
||||
|
||||
if (t->type == ev_variant)
|
||||
def_ret.type = type_variant;
|
||||
else
|
||||
def_ret.type = t->aux_type;
|
||||
if (def_ret.temp->used)
|
||||
QCC_PR_ParseWarning(WARN_FIXEDRETURNVALUECONFLICT, "Return value conflict - output is inefficient");
|
||||
def_ret.temp->used = true;
|
||||
|
||||
return &def_ret;
|
||||
return QCC_PR_GenerateFunctionCall(func, param, arg);
|
||||
}
|
||||
|
||||
int constchecks;
|
||||
|
@ -3990,31 +3997,19 @@ reloop:
|
|||
{ //hexen2 style retrieval, mixed with q1 style assignments...
|
||||
if (QCC_PR_CheckToken("=")) //(hideous concept)
|
||||
{
|
||||
QCC_dstatement_t *st;
|
||||
QCC_def_t *funcretr;
|
||||
QCC_def_t *args[2];
|
||||
if (d->scope)
|
||||
QCC_PR_ParseError(0, "Scoped array without specific engine support");
|
||||
if (def_ret.temp->used && ao != &def_ret)
|
||||
QCC_PR_ParseWarning(0, "RETURN VALUE ALREADY IN USE");
|
||||
|
||||
funcretr = QCC_PR_GetDef(type_function, qcva("ArraySet*%s", d->name), NULL, true, 1, false);
|
||||
nd = QCC_PR_Expression(TOP_PRIORITY, true);
|
||||
if (nd->type->type != d->type->type)
|
||||
QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, d, "Type Mismatch on array assignment");
|
||||
|
||||
QCC_LockActiveTemps();
|
||||
QCC_PR_Statement (&pr_opcodes[OP_CALL2H], funcretr, 0, &st);
|
||||
st->a = ao->ofs;
|
||||
st->b = nd->ofs;
|
||||
QCC_FreeTemp(ao);
|
||||
QCC_FreeTemp(nd);
|
||||
qcc_usefulstatement = true;
|
||||
|
||||
nd = &def_ret;
|
||||
def_ret.temp->used = true;
|
||||
d=nd;
|
||||
d->type = newtype;
|
||||
return d;
|
||||
args[0] = ao;
|
||||
args[1] = nd;
|
||||
return QCC_PR_GenerateFunctionCall(funcretr, args, 2);
|
||||
}
|
||||
|
||||
switch(newtype->type)
|
||||
|
@ -4058,39 +4053,34 @@ reloop:
|
|||
QCC_def_t *funcretr;
|
||||
if (d->scope)
|
||||
QCC_PR_ParseError(0, "Scoped array without specific engine support");
|
||||
if (def_ret.temp->used && ao != &def_ret)
|
||||
QCC_PR_ParseWarning(0, "RETURN VALUE ALREADY IN USE");
|
||||
|
||||
|
||||
if (QCC_PR_CheckToken("="))
|
||||
{
|
||||
QCC_def_t *args[2];
|
||||
|
||||
funcretr = QCC_PR_GetDef(type_function, qcva("ArraySet*%s", d->name), NULL, true, 1, false);
|
||||
|
||||
nd = QCC_PR_Expression(TOP_PRIORITY, true);
|
||||
if (nd->type->type != d->type->type)
|
||||
QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, d, "Type Mismatch on array assignment");
|
||||
|
||||
def_parms[0].type = type_float;
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], ao, &def_parms[0], NULL));
|
||||
def_parms[1].type = nd->type;
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_V], nd, &def_parms[1], NULL));
|
||||
QCC_LockActiveTemps();
|
||||
QCC_PR_Statement (&pr_opcodes[OP_CALL2], funcretr, 0, NULL);
|
||||
qcc_usefulstatement = true;
|
||||
args[0] = ao;
|
||||
args[1] = nd;
|
||||
qcc_usefulstatement=true;
|
||||
nd = QCC_PR_GenerateFunctionCall(funcretr, args, 2);
|
||||
nd->type = d->type->aux_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
def_parms[0].type = type_float;
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], ao, &def_parms[0], NULL));
|
||||
funcretr = QCC_PR_GetDef(type_function, qcva("ArrayGet*%s", d->name), NULL, true, 1, false);
|
||||
QCC_LockActiveTemps();
|
||||
QCC_PR_Statement (&pr_opcodes[OP_CALL1], funcretr, 0, NULL);
|
||||
}
|
||||
QCC_def_t *args[1];
|
||||
|
||||
nd = &def_ret;
|
||||
def_ret.temp->used = true;
|
||||
d=nd;
|
||||
d->type = newtype;
|
||||
return d;
|
||||
def_parms[0].type = type_float;
|
||||
funcretr = QCC_PR_GetDef(type_function, qcva("ArrayGet*%s", d->name), NULL, true, 1, false);
|
||||
|
||||
args[0] = ao;
|
||||
nd = QCC_PR_GenerateFunctionCall(funcretr, args, 1);
|
||||
nd->type = d->type->aux_type;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -7258,7 +7248,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
|
|||
else
|
||||
QCC_PR_Statement3(&pr_opcodes[OP_FETCH_GBL_F], def, index, &def_ret, true);
|
||||
|
||||
QCC_PR_Statement(&pr_opcodes[OP_RETURN], &def_ret, NULL, NULL);
|
||||
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_RETURN], &def_ret, NULL, NULL));
|
||||
|
||||
//finish the jump
|
||||
st->b = &statements[numstatements] - st;
|
||||
|
@ -7291,6 +7281,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
|
|||
ret = QCC_PR_GetDef(type_vector, "vec__", pr_scope, true, 1, false);
|
||||
ret->references+=4;
|
||||
QCC_PR_Statement3(pr_opcodes+OP_STORE_V, &def_ret, ret, NULL, false);
|
||||
QCC_FreeTemp(&def_ret);
|
||||
|
||||
div3 = QCC_PR_Statement(pr_opcodes+OP_MUL_F, intdiv3, QCC_MakeFloatDef(3), NULL);
|
||||
QCC_PR_Statement3(pr_opcodes+OP_SUB_F, index, div3, index, false);
|
||||
|
@ -7411,7 +7402,7 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname)
|
|||
//note that the array size is coded into the globals, one index before the array.
|
||||
|
||||
QCC_PR_Statement3(&pr_opcodes[OP_CONV_FTOI], index, NULL, index, true); //address stuff is integer based, but standard qc (which this accelerates in supported engines) only supports floats
|
||||
QCC_PR_SimpleStatement (OP_BOUNDCHECK, index->ofs, ((int*)qcc_pr_globals)[def->ofs-1], 0, true);//annoy the programmer. :p
|
||||
QCC_PR_SimpleStatement (OP_BOUNDCHECK, index->ofs, ((int*)qcc_pr_globals)[def->ofs-1]+1, 0, true);//annoy the programmer. :p
|
||||
if (def->type->size != 1)//shift it upwards for larger types
|
||||
QCC_PR_Statement3(&pr_opcodes[OP_MUL_I], index, QCC_MakeIntDef(def->type->size), index, true);
|
||||
QCC_PR_Statement3(&pr_opcodes[OP_GLOBALADDRESS], def, index, index, true); //comes with built in add
|
||||
|
|
|
@ -117,31 +117,32 @@ builtin_t pr_builtin[1024];
|
|||
extern BuiltinList_t BuiltinList[];
|
||||
|
||||
struct {
|
||||
func_t ChatMessage;
|
||||
|
||||
func_t getplayerstat[MAX_CL_STATS];
|
||||
func_t getplayerstati[MAX_CL_STATS];
|
||||
|
||||
func_t UserCmd, ParseClientCommand, ParseConnectionlessPacket;
|
||||
func_t ConsoleCmd;
|
||||
func_t ChatMessage; //mvdsv parsing of 'say' commands
|
||||
func_t UserCmd; //mvdsv
|
||||
func_t ConsoleCmd; //mvdsv
|
||||
func_t UserInfo_Changed;
|
||||
func_t localinfoChanged;
|
||||
|
||||
func_t ParseClientCommand; //KRIMZON_SV_PARSECLIENTCOMMAND
|
||||
func_t ParseConnectionlessPacket; //FTE_QC_SENDPACKET
|
||||
|
||||
func_t PausedTic;
|
||||
func_t ShouldPause;
|
||||
|
||||
func_t ClassChangeWeapon;
|
||||
func_t RunClientCommand; //EXT_CSQC_1
|
||||
|
||||
func_t ClassChangeWeapon;//hexen2 support
|
||||
} gfuncs;
|
||||
func_t getplayerstat[MAX_CL_STATS];
|
||||
func_t getplayerstati[MAX_CL_STATS];
|
||||
func_t SpectatorConnect;
|
||||
func_t SpectatorThink;
|
||||
func_t SpectatorDisconnect;
|
||||
func_t getplayerstat[MAX_CL_STATS]; //unnamed FTE extension
|
||||
func_t getplayerstati[MAX_CL_STATS];//unnamed FTE extension
|
||||
func_t SpectatorConnect; //QW
|
||||
func_t SpectatorThink; //QW
|
||||
func_t SpectatorDisconnect; //QW
|
||||
|
||||
func_t SV_PlayerPhysicsQC; //DP's DP_SV_PLAYERPHYSICS extension
|
||||
func_t EndFrameQC;
|
||||
func_t EndFrameQC; //a common extension
|
||||
|
||||
qboolean pr_items2;
|
||||
qboolean pr_items2; //hipnotic (or was it rogue?)
|
||||
|
||||
nqglobalvars_t realpr_nqglobal_struct;
|
||||
nqglobalvars_t *pr_nqglobal_struct = &realpr_nqglobal_struct;
|
||||
|
@ -483,6 +484,7 @@ void PR_LoadGlabalStruct(void)
|
|||
#define globalint(need,name) ((nqglobalvars_t*)pr_globals)->name = (int *)PR_FindGlobal(svprogfuncs, #name, 0); if (need && !((nqglobalvars_t*)pr_globals)->name) SV_Error("Could not find export \""#name"\" in progs\n");
|
||||
#define globalstring(need,name) ((nqglobalvars_t*)pr_globals)->name = (int *)PR_FindGlobal(svprogfuncs, #name, 0); if (need && !((nqglobalvars_t*)pr_globals)->name) SV_Error("Could not find export \""#name"\" in progs\n");
|
||||
#define globalvec(need,name) ((nqglobalvars_t*)pr_globals)->V_##name = (vec3_t *)PR_FindGlobal(svprogfuncs, #name, 0); if (need && !((nqglobalvars_t*)pr_globals)->V_##name) SV_Error("Could not find export \""#name"\" in progs\n");
|
||||
#define globalvec_(need,name) ((nqglobalvars_t*)pr_globals)->name = (vec3_t *)PR_FindGlobal(svprogfuncs, #name, 0); if (need && !((nqglobalvars_t*)pr_globals)->name) SV_Error("Could not find export \""#name"\" in progs\n");
|
||||
#define globalfunc(need,name) ((nqglobalvars_t*)pr_globals)->name = (func_t *)PR_FindGlobal(svprogfuncs, #name, 0); if (need && !((nqglobalvars_t*)pr_globals)->name) SV_Error("Could not find export \""#name"\" in progs\n");
|
||||
// globalint(pad);
|
||||
globalint (true, self); //we need the qw ones, but any in standard quake and not quakeworld, we don't really care about.
|
||||
|
@ -528,9 +530,15 @@ void PR_LoadGlabalStruct(void)
|
|||
globalfunc (false, SetNewParms);
|
||||
globalfunc (false, SetChangeParms);
|
||||
globalfloat (false, cycle_wrapped);
|
||||
|
||||
globalfloat (false, dimension_send);
|
||||
|
||||
|
||||
globalfloat (false, clientcommandframe);
|
||||
globalfloat (false, input_timelength);
|
||||
globalvec_ (false, input_angles);
|
||||
globalvec_ (false, input_movevalues);
|
||||
globalfloat (false, input_buttons);
|
||||
|
||||
memset(&evalc_idealpitch, 0, sizeof(evalc_idealpitch));
|
||||
memset(&evalc_pitch_speed, 0, sizeof(evalc_pitch_speed));
|
||||
|
||||
|
@ -550,6 +558,10 @@ void PR_LoadGlabalStruct(void)
|
|||
((nqglobalvars_t*)pr_globals)->trace_surfaceflags = &writeonly;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
pr_global_struct->dimension_send = 255;
|
||||
|
||||
pr_teamfield = 0;
|
||||
|
@ -575,6 +587,7 @@ void PR_LoadGlabalStruct(void)
|
|||
gfuncs.PausedTic = PR_FindFunction(svprogfuncs, "SV_PausedTic", PR_ANY);
|
||||
gfuncs.ShouldPause = PR_FindFunction(svprogfuncs, "SV_ShouldPause", PR_ANY);
|
||||
gfuncs.ClassChangeWeapon = PR_FindFunction(svprogfuncs, "ClassChangeWeapon", PR_ANY);
|
||||
gfuncs.RunClientCommand = PR_FindFunction(svprogfuncs, "SV_RunClientCommand", PR_ANY);
|
||||
|
||||
if (pr_no_playerphysics.value)
|
||||
SV_PlayerPhysicsQC = 0;
|
||||
|
@ -8297,6 +8310,7 @@ void PF_sv_gettaginfo(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|||
|
||||
//the first implementation of this function was (float type, float num, string name)
|
||||
//it is now float num, float type, .field
|
||||
//EXT_CSQC_1
|
||||
void PF_clientstat(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
#if 0 //this is the old code
|
||||
|
@ -8306,6 +8320,8 @@ void PF_clientstat(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|||
SV_QCStatFieldIdx(G_FLOAT(OFS_PARM1), G_INT(OFS_PARM2)+prinst->fieldadjust, G_FLOAT(OFS_PARM0));
|
||||
#endif
|
||||
}
|
||||
//EXT_CSQC_1
|
||||
//void(float num, float type, string name) globalstat
|
||||
void PF_globalstat(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
char *name = PF_VarString(prinst, 2, pr_globals);
|
||||
|
@ -8316,42 +8332,60 @@ void PF_globalstat(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|||
#endif
|
||||
}
|
||||
|
||||
//EXT_CSQC_1
|
||||
void PF_runclientphys(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
unsigned int i, n;
|
||||
extern vec3_t player_maxs, player_mins;
|
||||
float msecs;
|
||||
pmove.sequence = *pr_nqglobal_struct->clientcommandframe;
|
||||
pmove.pm_type = PM_NORMAL;
|
||||
extern qbyte playertouch[];
|
||||
unsigned int msecs;
|
||||
edict_t *ent = G_EDICT(prinst, OFS_PARM0);
|
||||
edict_t *touched;
|
||||
if (pr_nqglobal_struct->clientcommandframe)
|
||||
pmove.sequence = *pr_nqglobal_struct->clientcommandframe;
|
||||
else
|
||||
pmove.sequence = 0;
|
||||
if (host_client && host_client->edict == ent)
|
||||
pmove.pm_type = SV_PMTypeForClient(host_client);
|
||||
else
|
||||
pmove.pm_type = PM_NORMAL;
|
||||
|
||||
pmove.jump_msec = 0;//(cls.z_ext & Z_EXT_PM_TYPE) ? 0 : from->jump_msec;
|
||||
if (pr_nqglobal_struct->pmove_jump_held)
|
||||
pmove.jump_held = *pr_nqglobal_struct->pmove_jump_held;
|
||||
if (pr_nqglobal_struct->pmove_waterjumptime)
|
||||
pmove.waterjumptime = *pr_nqglobal_struct->pmove_waterjumptime;
|
||||
|
||||
pmove.jump_held = ((int)ent->xv->pmove_flags)&PMF_JUMP_HELD;
|
||||
pmove.waterjumptime = ent->v->teleport_time;
|
||||
|
||||
//set up the movement command
|
||||
msecs = *pr_nqglobal_struct->input_timelength*1000 + 0.5f;
|
||||
msecs = pr_global_struct->input_timelength*1000 + 0.5f;
|
||||
//precision inaccuracies. :(
|
||||
#define ANGLE2SHORT(x) (x) * (65536/360.0)
|
||||
pmove.cmd.angles[0] = ANGLE2SHORT(pr_nqglobal_struct->input_angles[0]);
|
||||
pmove.cmd.angles[1] = ANGLE2SHORT(pr_nqglobal_struct->input_angles[1]);
|
||||
pmove.cmd.angles[2] = ANGLE2SHORT(pr_nqglobal_struct->input_angles[2]);
|
||||
VectorCopy(pr_nqglobal_struct->input_angles, pmove.angles);
|
||||
pmove.cmd.angles[0] = ANGLE2SHORT((pr_global_struct->input_angles)[0]);
|
||||
pmove.cmd.angles[1] = ANGLE2SHORT((pr_global_struct->input_angles)[1]);
|
||||
pmove.cmd.angles[2] = ANGLE2SHORT((pr_global_struct->input_angles)[2]);
|
||||
VectorCopy(pr_global_struct->input_angles, pmove.angles);
|
||||
|
||||
pmove.cmd.forwardmove = (*pr_nqglobal_struct->input_movevalues)[0];
|
||||
pmove.cmd.sidemove = (*pr_nqglobal_struct->input_movevalues)[1];
|
||||
pmove.cmd.upmove = (*pr_nqglobal_struct->input_movevalues)[2];
|
||||
pmove.cmd.buttons = *pr_nqglobal_struct->input_buttons;
|
||||
pmove.cmd.forwardmove = (pr_global_struct->input_movevalues)[0];
|
||||
pmove.cmd.sidemove = (pr_global_struct->input_movevalues)[1];
|
||||
pmove.cmd.upmove = (pr_global_struct->input_movevalues)[2];
|
||||
pmove.cmd.buttons = pr_global_struct->input_buttons;
|
||||
|
||||
VectorCopy(*pr_nqglobal_struct->pmove_org, pmove.origin);
|
||||
VectorCopy(*pr_nqglobal_struct->pmove_vel, pmove.velocity);
|
||||
VectorCopy(*pr_nqglobal_struct->pmove_maxs, player_maxs);
|
||||
VectorCopy(*pr_nqglobal_struct->pmove_mins, player_mins);
|
||||
pmove.hullnum = 1;
|
||||
VectorCopy(ent->v->origin, pmove.origin);
|
||||
VectorCopy(ent->v->velocity, pmove.velocity);
|
||||
VectorCopy(ent->v->maxs, player_maxs);
|
||||
VectorCopy(ent->v->mins, player_mins);
|
||||
pmove.hullnum = SV_HullNumForPlayer(ent->xv->hull, ent->v->mins, ent->v->maxs);
|
||||
|
||||
pmove.numphysent = 1;
|
||||
pmove.physents[0].model = sv.worldmodel;
|
||||
AddLinksToPmove ( PROG_TO_EDICT(svprogfuncs, pr_global_struct->self), sv_areanodes );
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
extern vec3_t pmove_mins, pmove_maxs;
|
||||
pmove_mins[i] = pmove.origin[i] - 256;
|
||||
pmove_maxs[i] = pmove.origin[i] + 256;
|
||||
}
|
||||
AddLinksToPmove(ent, sv_areanodes);
|
||||
// AddAllEntsToPmove();
|
||||
|
||||
|
||||
while(msecs) //break up longer commands
|
||||
|
@ -8363,12 +8397,160 @@ void PF_runclientphys(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|||
PM_PlayerMove(1);
|
||||
}
|
||||
|
||||
if (pr_nqglobal_struct->pmove_jump_held)
|
||||
*pr_nqglobal_struct->pmove_jump_held = pmove.jump_held;
|
||||
if (pr_nqglobal_struct->pmove_waterjumptime)
|
||||
*pr_nqglobal_struct->pmove_waterjumptime = pmove.waterjumptime;
|
||||
VectorCopy(pmove.origin, *pr_nqglobal_struct->pmove_org);
|
||||
VectorCopy(pmove.velocity, *pr_nqglobal_struct->pmove_vel);
|
||||
ent->xv->pmove_flags = 0;
|
||||
ent->xv->pmove_flags += ((int)pmove.jump_held?PMF_JUMP_HELD:0);
|
||||
ent->xv->pmove_flags += ((int)pmove.onladder?PMF_LADDER:0);
|
||||
ent->v->teleport_time = pmove.waterjumptime;
|
||||
VectorCopy(pmove.origin, ent->v->origin);
|
||||
VectorCopy(pmove.velocity, ent->v->velocity);
|
||||
|
||||
|
||||
|
||||
ent->v->waterlevel = pmove.waterlevel;
|
||||
|
||||
if (pmove.watertype & FTECONTENTS_SOLID)
|
||||
ent->v->watertype = Q1CONTENTS_SOLID;
|
||||
else if (pmove.watertype & FTECONTENTS_SKY)
|
||||
ent->v->watertype = Q1CONTENTS_SKY;
|
||||
else if (pmove.watertype & FTECONTENTS_LAVA)
|
||||
ent->v->watertype = Q1CONTENTS_LAVA;
|
||||
else if (pmove.watertype & FTECONTENTS_SLIME)
|
||||
ent->v->watertype = Q1CONTENTS_SLIME;
|
||||
else if (pmove.watertype & FTECONTENTS_WATER)
|
||||
ent->v->watertype = Q1CONTENTS_WATER;
|
||||
else
|
||||
ent->v->watertype = Q1CONTENTS_EMPTY;
|
||||
|
||||
if (pmove.onground)
|
||||
{
|
||||
ent->v->flags = (int)sv_player->v->flags | FL_ONGROUND;
|
||||
ent->v->groundentity = EDICT_TO_PROG(svprogfuncs, EDICT_NUM(svprogfuncs, pmove.physents[pmove.groundent].info));
|
||||
}
|
||||
else
|
||||
ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND;
|
||||
|
||||
|
||||
SV_LinkEdict(ent, true);
|
||||
for (i=0 ; i<pmove.numtouch ; i++)
|
||||
{
|
||||
if (pmove.physents[pmove.touchindex[i]].notouch)
|
||||
continue;
|
||||
n = pmove.physents[pmove.touchindex[i]].info;
|
||||
touched = EDICT_NUM(svprogfuncs, n);
|
||||
if (!ent->v->touch || (playertouch[n/8]&(1<<(n%8))))
|
||||
continue;
|
||||
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, touched);
|
||||
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, ent);
|
||||
pr_global_struct->time = sv.time;
|
||||
#ifdef VM_Q1
|
||||
if (svs.gametype == GT_Q1QVM)
|
||||
Q1QVM_Touch();
|
||||
else
|
||||
#endif
|
||||
PR_ExecuteProgram (svprogfuncs, touched->v->touch);
|
||||
playertouch[n/8] |= 1 << (n%8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//EXT_CSQC_1 (called when a movement command is received. runs full acceleration + movement)
|
||||
qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd)
|
||||
{
|
||||
if (gfuncs.RunClientCommand)
|
||||
{
|
||||
#ifdef SVCHAT
|
||||
if (SV_ChatMove(ucmd->impulse))
|
||||
{
|
||||
ucmd->buttons = 0;
|
||||
ucmd->impulse = 0;
|
||||
ucmd->forwardmove = ucmd->sidemove = ucmd->upmove = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!sv_player->v->fixangle)
|
||||
{
|
||||
sv_player->v->v_angle[0] = SHORT2ANGLE(ucmd->angles[0]);
|
||||
sv_player->v->v_angle[1] = SHORT2ANGLE(ucmd->angles[1]);
|
||||
sv_player->v->v_angle[2] = SHORT2ANGLE(ucmd->angles[2]);
|
||||
}
|
||||
|
||||
if (progstype == PROG_H2)
|
||||
sv_player->xv->light_level = 128; //hmm... HACK!!!
|
||||
|
||||
sv_player->v->button0 = ucmd->buttons & 1;
|
||||
sv_player->v->button2 = (ucmd->buttons >> 1) & 1;
|
||||
// DP_INPUTBUTTONS
|
||||
sv_player->xv->button3 = ((ucmd->buttons >> 2) & 1);
|
||||
sv_player->xv->button4 = ((ucmd->buttons >> 3) & 1);
|
||||
sv_player->xv->button5 = ((ucmd->buttons >> 4) & 1);
|
||||
sv_player->xv->button6 = ((ucmd->buttons >> 5) & 1);
|
||||
sv_player->xv->button7 = ((ucmd->buttons >> 6) & 1);
|
||||
sv_player->xv->button8 = ((ucmd->buttons >> 7) & 1);
|
||||
if (ucmd->impulse && SV_FiltureImpulse(ucmd->impulse, host_client->trustlevel))
|
||||
sv_player->v->impulse = ucmd->impulse;
|
||||
|
||||
if (host_client->iscuffed)
|
||||
{
|
||||
sv_player->v->impulse = 0;
|
||||
sv_player->v->button0 = 0;
|
||||
}
|
||||
|
||||
if (host_client->state && host_client->protocol != SCP_BAD)
|
||||
{
|
||||
sv_player->xv->movement[0] = ucmd->forwardmove * host_frametime;
|
||||
sv_player->xv->movement[1] = ucmd->sidemove * host_frametime;
|
||||
sv_player->xv->movement[2] = ucmd->upmove * host_frametime;
|
||||
}
|
||||
|
||||
SV_CheckVelocity(sv_player);
|
||||
|
||||
//
|
||||
// angles
|
||||
// show 1/3 the pitch angle and all the roll angle
|
||||
if (sv_player->v->health > 0)
|
||||
{
|
||||
if (!sv_player->v->fixangle)
|
||||
{
|
||||
sv_player->v->angles[PITCH] = -sv_player->v->v_angle[PITCH]/3;
|
||||
sv_player->v->angles[YAW] = sv_player->v->v_angle[YAW];
|
||||
}
|
||||
sv_player->v->angles[ROLL] =
|
||||
V_CalcRoll (sv_player->v->angles, sv_player->v->velocity)*4;
|
||||
}
|
||||
|
||||
//prethink should be consistant with what the engine normally does
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, client->edict);
|
||||
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PlayerPreThink);
|
||||
SV_RunThink (client->edict);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
pr_global_struct->input_timelength = ucmd->msec/1000.0f;
|
||||
//precision inaccuracies. :(
|
||||
#define ANGLE2SHORT(x) (x) * (65536/360.0)
|
||||
(pr_global_struct->input_angles)[0] = SHORT2ANGLE(ucmd->angles[0]);
|
||||
(pr_global_struct->input_angles)[1] = SHORT2ANGLE(ucmd->angles[1]);
|
||||
(pr_global_struct->input_angles)[2] = SHORT2ANGLE(ucmd->angles[2]);
|
||||
|
||||
(pr_global_struct->input_movevalues)[0] = ucmd->forwardmove;
|
||||
(pr_global_struct->input_movevalues)[1] = ucmd->sidemove;
|
||||
(pr_global_struct->input_movevalues)[2] = ucmd->upmove;
|
||||
pr_global_struct->input_buttons = ucmd->buttons;
|
||||
// pr_global_struct->input_impulse = ucmd->impulse;
|
||||
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, client->edict);
|
||||
PR_ExecuteProgram(svprogfuncs, gfuncs.RunClientCommand);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//DP_QC_GETSURFACE
|
||||
|
@ -8931,8 +9113,8 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"calltimeofday", PF_calltimeofday, 0, 0, 0, 231},
|
||||
|
||||
//EXT_CSQC
|
||||
{"clientstat", PF_clientstat, 0, 0, 0, 232},
|
||||
{"runclientphys", PF_runclientphys, 0, 0, 0, 233},
|
||||
{"clientstat", PF_clientstat, 0, 0, 0, 232}, //EXT_CSQC
|
||||
{"globalstat", PF_globalstat, 0, 0, 0, 233}, //EXT_CSQC_1 actually
|
||||
//END EXT_CSQC
|
||||
{"isbackbuffered", PF_isbackbuffered, 0, 0, 0, 234},
|
||||
{"te_bloodqw", PF_te_bloodqw, 0, 0, 0, 239},
|
||||
|
@ -8971,6 +9153,8 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
// {"cprint", PF_sv_cprint, 0, 0, 0, 338}, // #338 void(string s) cprint (EXT_CSQC)
|
||||
{"print", PF_print, 0, 0, 0, 339}, // #339 void(string s) print (EXT_CSQC)
|
||||
|
||||
{"runclientphys", PF_runclientphys, 0, 0, 0, 347},
|
||||
|
||||
// {"runningserver", PF_sv_runningserver,0, 0, 0, 350}, // #350 float() isserver (EXT_CSQC)
|
||||
// {"registercommand", PF_sv_registercommand,0, 0, 0, 352}, // #352 void(string cmdname) registercommand (EXT_CSQC)
|
||||
{"wasfreed", PF_WasFreed, 0, 0, 0, 353}, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
|
||||
|
@ -9550,7 +9734,7 @@ void PR_RegisterFields(void) //it's just easier to do it this way.
|
|||
fieldxfloat(fatness);
|
||||
fieldxentity(view2);
|
||||
fieldxvector(movement);
|
||||
fieldxfloat(fteflags);
|
||||
fieldxfloat(pmove_flags);
|
||||
fieldxfloat(vweapmodelindex);
|
||||
|
||||
//dp extra fields
|
||||
|
|
|
@ -84,15 +84,9 @@ typedef struct nqglobalvars_s
|
|||
|
||||
float *clientcommandframe;
|
||||
float *input_timelength;
|
||||
float *input_angles;
|
||||
vec3_t *input_angles;
|
||||
vec3_t *input_movevalues;
|
||||
float *input_buttons;
|
||||
float *pmove_jump_held;
|
||||
float *pmove_waterjumptime;
|
||||
vec3_t *pmove_org;
|
||||
vec3_t *pmove_vel;
|
||||
vec3_t *pmove_mins;
|
||||
vec3_t *pmove_maxs;
|
||||
} nqglobalvars_t;
|
||||
|
||||
#define P_VEC(v) (pr_global_struct->V_##v)
|
||||
|
@ -193,8 +187,7 @@ typedef struct extentvars_s
|
|||
float alpha; //DP_ENT_ALPHA
|
||||
float fatness; //FTE_PEXT_FATNESS
|
||||
int view2; //FTE_PEXT_VIEW2
|
||||
float fteflags;
|
||||
vec3_t movement;
|
||||
vec3_t movement;
|
||||
float vweapmodelindex;
|
||||
|
||||
//dp extra fields
|
||||
|
@ -248,10 +241,11 @@ typedef struct extentvars_s
|
|||
float hasted; //hexen2 uses this AS WELL as maxspeed
|
||||
|
||||
//csqc stuph.
|
||||
func_t SendEntity;
|
||||
float SendFlags;
|
||||
float Version;
|
||||
float pvsflags;
|
||||
func_t SendEntity; //EXT_CSQC
|
||||
float SendFlags; //EXT_CSQC_1 (one of the DP guys came up with it)
|
||||
float Version; //EXT_CSQC (obsolete)
|
||||
float pvsflags; //EXT_CSQC_1
|
||||
float pmove_flags; //EXT_CSQC_1 (FIXME: is this really needed?)
|
||||
|
||||
//FTE_ENT_UNIQUESPAWNID
|
||||
float uniquespawnid;
|
||||
|
|
|
@ -817,8 +817,8 @@ typedef struct
|
|||
#define FL_MOVECHAIN_ANGLE 32768 // when in a move chain, will update the angle
|
||||
#define FL_CLASS_DEPENDENT 2097152
|
||||
|
||||
#define FF_CROUCHING 1 //fte flags. seperate from flags
|
||||
#define FF_LADDER 2 //fte flags. seperate from flags
|
||||
#define PMF_JUMP_HELD 1
|
||||
#define PMF_LADDER 2 //pmove flags. seperate from flags
|
||||
|
||||
#define PVSF_NORMALPVS 0x0
|
||||
#define PVSF_NOTRACECHECK 0x1
|
||||
|
|
|
@ -1686,7 +1686,7 @@ void SV_WritePlayersToClient (client_t *client, edict_t *clent, qbyte *pvs, size
|
|||
{
|
||||
clstate_t clst;
|
||||
clst.playernum = j;
|
||||
clst.onladder = (int)ent->xv->fteflags&FF_LADDER;
|
||||
clst.onladder = (int)ent->xv->pmove_flags&PMF_LADDER;
|
||||
clst.lastcmd = &cl->lastcmd;
|
||||
clst.modelindex = vent->v->modelindex;
|
||||
clst.modelindex2 = vent->xv->vweapmodelindex;
|
||||
|
|
|
@ -1916,7 +1916,8 @@ client_t *SVC_DirectConnect(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
SV_FixupName(name, name, sizeof(name));
|
||||
SV_FixupName(name, temp.namebuf, sizeof(temp.namebuf));
|
||||
name = temp.namebuf;
|
||||
|
||||
if (!*name)
|
||||
{
|
||||
|
@ -2070,7 +2071,7 @@ client_t *SVC_DirectConnect(void)
|
|||
switch(newcl->protocol)
|
||||
{
|
||||
#ifdef Q3SERVER
|
||||
case CP_QUAKE3:
|
||||
case SCP_QUAKE3:
|
||||
Huff_PreferedCompressionCRC();
|
||||
if (temp.frameunion.q3frames)
|
||||
Z_Free(temp.frameunion.q3frames);
|
||||
|
@ -2078,7 +2079,8 @@ client_t *SVC_DirectConnect(void)
|
|||
break;
|
||||
#endif
|
||||
|
||||
case CP_QUAKE2:
|
||||
#ifdef Q2SERVER
|
||||
case SCP_QUAKE2:
|
||||
// build a new connection
|
||||
// accept the new client
|
||||
// this is the only place a client_t is ever initialized
|
||||
|
@ -2088,6 +2090,7 @@ client_t *SVC_DirectConnect(void)
|
|||
|
||||
temp.frameunion.q2frames = Z_Malloc(sizeof(q2client_frame_t)*Q2UPDATE_BACKUP);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
temp.frameunion.frames = newcl->frameunion.frames; //don't touch these.
|
||||
|
|
|
@ -1995,6 +1995,7 @@ void SV_SendClientMessages (void)
|
|||
{
|
||||
int i, j;
|
||||
client_t *c;
|
||||
float pt = sv.physicstime;
|
||||
|
||||
#ifdef Q3SERVER
|
||||
if (svs.gametype == GT_QUAKE3)
|
||||
|
@ -2128,7 +2129,7 @@ void SV_SendClientMessages (void)
|
|||
if (ISNQCLIENT(c))
|
||||
{ //nq clients get artificial choke too
|
||||
c->send_message = false;
|
||||
if (c->nextservertimeupdate != sv.physicstime && c->state != cs_zombie)
|
||||
if (c->nextservertimeupdate != pt && c->state != cs_zombie)
|
||||
{
|
||||
c->send_message = true;
|
||||
|
||||
|
|
|
@ -1417,8 +1417,8 @@ void SV_Begin_Core(client_t *split)
|
|||
|
||||
client_t *oh;
|
||||
int i;
|
||||
if (progstype == PROG_H2 && host_client->playerclass)
|
||||
host_client->edict->xv->playerclass = host_client->playerclass; //make sure it's set the same as the userinfo
|
||||
if (progstype == PROG_H2 && split->playerclass)
|
||||
split->edict->xv->playerclass = host_client->playerclass; //make sure it's set the same as the userinfo
|
||||
|
||||
#ifdef Q2SERVER
|
||||
if (ge)
|
||||
|
@ -1517,8 +1517,11 @@ void SV_Begin_Core(client_t *split)
|
|||
else
|
||||
#endif
|
||||
{
|
||||
globalvars_t *pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
|
||||
|
||||
pr_global_struct->time = sv.physicstime;
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
|
||||
G_FLOAT(OFS_PARM0) = split->csqcactive; //this arg is part of EXT_CSQC_1, but doesn't have to be supported by the mod
|
||||
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect);
|
||||
|
||||
// actually spawn the player
|
||||
|
@ -4640,7 +4643,7 @@ void AddLinksToPmove ( edict_t *player, areanode_t *node )
|
|||
if (model)
|
||||
// test the point
|
||||
if (model->funcs.PointContents (model, player->v->origin) == FTECONTENTS_SOLID)
|
||||
player->xv->fteflags = (int)player->xv->fteflags | FF_LADDER; //touch that ladder!
|
||||
player->xv->pmove_flags = (int)player->xv->pmove_flags | PMF_LADDER; //touch that ladder!
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4822,6 +4825,11 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
|
|||
// end KK hack copied from QuakeForge anti-cheat
|
||||
//it's amazing how code get's copied around...
|
||||
|
||||
if (SV_RunFullQCMovement(host_client, ucmd))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
cmd = *ucmd;
|
||||
|
||||
|
@ -5037,10 +5045,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
|
|||
pmove.numphysent = 1;
|
||||
pmove.physents[0].model = sv.worldmodel;
|
||||
pmove.cmd = *ucmd;
|
||||
if (sv.worldmodel->fromgame == fg_quake)
|
||||
pmove.hullnum = ((int)sv_player->xv->fteflags&FF_CROUCHING)?3:1;
|
||||
else
|
||||
pmove.hullnum = SV_HullNumForPlayer(sv_player->xv->hull, sv_player->v->mins, sv_player->v->maxs);
|
||||
pmove.hullnum = SV_HullNumForPlayer(sv_player->xv->hull, sv_player->v->mins, sv_player->v->maxs);
|
||||
|
||||
movevars.entgravity = host_client->entgravity/movevars.gravity;
|
||||
movevars.maxspeed = host_client->maxspeed;
|
||||
|
@ -5059,14 +5064,14 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
|
|||
pmove_mins[i] = pmove.origin[i] - 256;
|
||||
pmove_maxs[i] = pmove.origin[i] + 256;
|
||||
}
|
||||
sv_player->xv->fteflags = (int)sv_player->xv->fteflags & ~FF_LADDER; //assume not touching ladder trigger
|
||||
sv_player->xv->pmove_flags = (int)sv_player->xv->pmove_flags & ~PMF_LADDER; //assume not touching ladder trigger
|
||||
#if 1
|
||||
AddLinksToPmove ( sv_player, sv_areanodes );
|
||||
#else
|
||||
AddAllEntsToPmove ();
|
||||
#endif
|
||||
|
||||
if ((int)sv_player->xv->fteflags & FF_LADDER)
|
||||
if ((int)sv_player->xv->pmove_flags & PMF_LADDER)
|
||||
pmove.onladder = true;
|
||||
else
|
||||
pmove.onladder = false;
|
||||
|
@ -5393,7 +5398,7 @@ haveannothergo:
|
|||
MSG_ReadDeltaUsercmd (&oldest, &oldcmd);
|
||||
MSG_ReadDeltaUsercmd (&oldcmd, &newcmd);
|
||||
}
|
||||
break;;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5716,12 +5721,12 @@ void SVNQ_ReadClientMove (usercmd_t *move)
|
|||
else
|
||||
host_client->last_sequence = 0;
|
||||
cltime = MSG_ReadFloat ();
|
||||
if (cltime < move->fservertime)
|
||||
cltime = move->fservertime;
|
||||
if (cltime > sv.time)
|
||||
cltime = sv.time;
|
||||
if (cltime < sv.time - 2) //if you do lag more than this, you won't get your free time.
|
||||
cltime = sv.time - 2;
|
||||
if (cltime < move->fservertime)
|
||||
cltime = move->fservertime;
|
||||
timesincelast = cltime - move->fservertime;
|
||||
move->fservertime = cltime;
|
||||
move->servertime = move->fservertime;
|
||||
|
@ -5800,6 +5805,23 @@ void SVNQ_ReadClientMove (usercmd_t *move)
|
|||
if (cursor_entitynumber) cursor_entitynumber->edict = entnum;
|
||||
}
|
||||
|
||||
if (SV_RunFullQCMovement(host_client, move))
|
||||
{
|
||||
pr_global_struct->time = sv.physicstime;
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
|
||||
#ifdef VM_Q1
|
||||
if (svs.gametype == GT_Q1QVM)
|
||||
Q1QVM_PostThink();
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (pr_global_struct->PlayerPostThink)
|
||||
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PlayerPostThink);
|
||||
}
|
||||
host_client->isindependant = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (i && SV_FiltureImpulse(i, host_client->trustlevel))
|
||||
host_client->edict->v->impulse = i;
|
||||
|
|
|
@ -11,8 +11,6 @@ I think globals.maxentities is the hard cap, rather than current max like in q1.
|
|||
#include "crc.h"
|
||||
#include "model_hl.h"
|
||||
|
||||
#define GAMECODEMODULE Cvar_Get("hl_svgame", "valve/dlls/mp.dll", 0, "halflife cvars")->string
|
||||
|
||||
#define ignore(s) Con_Printf("Fixme: " s "\n")
|
||||
#define notimp(l) Con_Printf("halflife sv builtin not implemented on line %i\n", l)
|
||||
|
||||
|
@ -762,15 +760,27 @@ void GHL_GetGameDir(char *gamedir)
|
|||
}
|
||||
unk GHL_Cvar_RegisterVariable(unk){notimp(__LINE__);}
|
||||
unk GHL_FadeClientVolume(unk){notimp(__LINE__);}
|
||||
unk GHL_SetClientMaxspeed(unk){notimp(__LINE__);}
|
||||
unk GHL_SetClientMaxspeed(unk)
|
||||
{
|
||||
notimp(__LINE__);
|
||||
}
|
||||
unk GHL_CreateFakeClient(unk){notimp(__LINE__);}
|
||||
unk GHL_RunPlayerMove(unk){notimp(__LINE__);}
|
||||
int GHL_NumberOfEntities(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
unk GHL_GetInfoKeyBuffer(unk){notimp(__LINE__);}
|
||||
unk GHL_InfoKeyValue(unk){notimp(__LINE__);}
|
||||
char *GHL_GetInfoKeyBuffer(hledict_t *ed)
|
||||
{
|
||||
if (!ed)
|
||||
return svs.info;
|
||||
|
||||
return svs.clients[ed - SVHL_Edict - 1].userinfo;
|
||||
}
|
||||
char *GHL_InfoKeyValue(char *infostr, char *key)
|
||||
{
|
||||
return Info_ValueForKey(infostr, key);
|
||||
}
|
||||
unk GHL_SetKeyValue(unk){notimp(__LINE__);}
|
||||
unk GHL_SetClientKeyValue(unk){notimp(__LINE__);}
|
||||
unk GHL_IsMapValid(unk){notimp(__LINE__);}
|
||||
|
|
Loading…
Reference in a new issue