added DP_QC_ENTITYSTRING builtins.

mvd playback fixes/cleanups
r_fb_models more closely matches ezquake.
readded str[i] support.
fixed char constants (outside of strings).
string table compression no longer affects distinction between "" and string_null.
multiplayer savedgame fixes.
don't bugilly change hexen2's playerclass on loadgame, and preserve the STR_foo globals which are not marked for saving.
fix small bug on player renames. added a temp debug print to try to catch the issue onemanclan is having.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3961 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2012-01-24 04:24:14 +00:00
parent 770948a320
commit 567e9f112b
31 changed files with 714 additions and 690 deletions

View file

@ -1914,7 +1914,7 @@ void CL_TransitionEntities (void)
vec3_t move; vec3_t move;
lerpents_t *le; lerpents_t *le;
player_state_t *pnew, *pold; player_state_t *pnew, *pold;
if (!cl_lerp_players.ival) if (!cl_lerp_players.ival && !(cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV))
{ {
newf = newff = oldf = cl.parsecount; newf = newff = oldf = cl.parsecount;
newf&=UPDATE_MASK; newf&=UPDATE_MASK;
@ -2461,6 +2461,29 @@ CL_ParsePlayerinfo
extern int parsecountmod, oldparsecountmod; extern int parsecountmod, oldparsecountmod;
extern double parsecounttime; extern double parsecounttime;
int lastplayerinfo; int lastplayerinfo;
void CL_ParseClientdata (void);
void CL_MVDUpdateSpectator(void)
{
player_state_t *self, *oldself;
int s;
for (s = 0; s < cl.splitclients; s++)
{
self = &cl.frames[cl.parsecount & UPDATE_MASK].playerstate[cl.playernum[s]];
oldself = &cl.frames[(cls.netchan.outgoing_sequence - 1) & UPDATE_MASK].playerstate[cl.playernum[s]];
// cl.frames[cl.parsecount & UPDATE_MASK].senttime = cl.frames[(cls.netchan.outgoing_sequence - 1) & UPDATE_MASK].senttime;
// self->messagenum = cl.parsecount;
// VectorCopy(oldself->origin, self->origin);
// VectorCopy(oldself->velocity, self->velocity);
// VectorCopy(oldself->viewangles, self->viewangles);
}
CL_ParseClientdata();
}
void CL_ParsePlayerinfo (void) void CL_ParsePlayerinfo (void)
{ {
int msec; int msec;
@ -2470,7 +2493,7 @@ void CL_ParsePlayerinfo (void)
int num; int num;
int i; int i;
int newf; int newf;
vec3_t org; vec3_t org, dist;
lastplayerinfo = num = MSG_ReadByte (); lastplayerinfo = num = MSG_ReadByte ();
if (num >= MAX_CLIENTS) if (num >= MAX_CLIENTS)
@ -2522,6 +2545,10 @@ void CL_ParsePlayerinfo (void)
state->origin[i] = MSG_ReadCoord (); state->origin[i] = MSG_ReadCoord ();
} }
VectorSubtract(state->origin, prevstate->origin, dist);
VectorScale(dist, 1/(cl.frames[parsecountmod].packet_entities.servertime - cl.frames[oldparsecountmod].packet_entities.servertime), state->velocity);
VectorCopy (state->origin, state->predorigin);
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
if (flags & (DF_ANGLES << i)) if (flags & (DF_ANGLES << i))
@ -3096,7 +3123,7 @@ void CL_LinkPlayers (void)
if (pnum < cl.splitclients) if (pnum < cl.splitclients)
{ //this is a local player { //this is a local player
} }
else if (cl_lerp_players.ival) else if (cl_lerp_players.ival || (cls.demoplayback==DPB_MVD || cls.demoplayback == DPB_EZTV))
{ {
lerpents_t *le = &cl.lerpplayers[j]; lerpents_t *le = &cl.lerpplayers[j];
VectorCopy (le->origin, ent->origin); VectorCopy (le->origin, ent->origin);
@ -3518,223 +3545,9 @@ void CL_EmitEntities (void)
void CL_ParseClientdata (void);
/*
void MVD_Interpolate(void)
{
player_state_t *self, *oldself;
CL_ParseClientdata();
self = &cl.frames[cl.parsecount & UPDATE_MASK].playerstate[cl.playernum[0]];
oldself = &cl.frames[(cls.netchan.outgoing_sequence-1) & UPDATE_MASK].playerstate[cl.playernum[0]];
self->messagenum = cl.parsecount;
VectorCopy(oldself->origin, self->origin);
VectorCopy(oldself->velocity, self->velocity);
VectorCopy(oldself->viewangles, self->viewangles);
cls.netchan.outgoing_sequence = cl.parsecount+1;
}
*/
int mvd_fixangle;
static float MVD_AdjustAngle(float current, float ideal, float fraction) {
float move;
move = ideal - current;
if (move >= 180)
move -= 360;
else if (move <= -180)
move += 360;
return current + fraction * move;
}
extern float nextdemotime;
extern float olddemotime;
static void MVD_InitInterpolation(void)
{
player_state_t *state, *oldstate;
int i, tracknum;
frame_t *frame, *oldframe;
vec3_t dist;
struct predicted_player *pplayer;
int s;
#define ISDEAD(i) ( (i) >= 41 && (i) <= 102 )
if (!cl.validsequence)
return;
// if (nextdemotime <= olddemotime)
// return;
frame = &cl.frames[cl.parsecount & UPDATE_MASK];
oldframe = &cl.frames[(cl.parsecount-1) & UPDATE_MASK];
// clients
for (i = 0; i < MAX_CLIENTS; i++)
{
pplayer = &predicted_players[i];
state = &frame->playerstate[i];
oldstate = &oldframe->playerstate[i];
if (pplayer->predict)
{
VectorCopy(pplayer->oldo, oldstate->origin);
VectorCopy(pplayer->olda, oldstate->command.angles);
VectorCopy(pplayer->oldv, oldstate->velocity);
}
pplayer->predict = false;
tracknum = spec_track[0];
if ((mvd_fixangle & 1) << i)
{
if (i == tracknum)
{
state->command.angles[0] = (state->viewangles[0] = cl.viewangles[0][0])*65535/360;
state->command.angles[1] = (state->viewangles[1] = cl.viewangles[0][1])*65535/360;
state->command.angles[2] = (state->viewangles[2] = cl.viewangles[0][2])*65535/360;
}
// no angle interpolation
VectorCopy(state->command.angles, oldstate->command.angles);
mvd_fixangle &= ~(1 << i);
}
// we dont interpolate ourself if we are spectating
for (s = 0; s < cl.splitclients; s++)
{
if (i == cl.playernum[s] && cl.spectator)
break;
}
if (s != cl.splitclients)
continue;
memset(state->velocity, 0, sizeof(state->velocity));
if (state->messagenum != cl.parsecount)
continue; // not present this frame
if (oldstate->messagenum != cl.oldparsecount || !oldstate->messagenum)
continue; // not present last frame
if (!ISDEAD(state->frame) && ISDEAD(oldstate->frame))
continue;
VectorSubtract(state->origin, oldstate->origin, dist);
if (DotProduct(dist, dist) > 22500)
continue;
VectorScale(dist, 1 / (nextdemotime - olddemotime), pplayer->oldv);
VectorCopy(state->origin, pplayer->oldo);
VectorCopy(state->command.angles, pplayer->olda);
pplayer->oldstate = oldstate;
pplayer->predict = true;
}
/*
// nails
for (i = 0; i < cl_num_projectiles; i++)
{
if (!cl.int_projectiles[i].interpolate)
continue;
VectorCopy(cl.int_projectiles[i].origin, cl_projectiles[i].origin);
}
*/
}
void MVD_Interpolate(void)
{
int i, j;
float f;
frame_t *frame, *oldframe;
player_state_t *state, *oldstate, *self, *oldself;
entity_state_t *oldents;
struct predicted_player *pplayer;
static float old;
extern float demtime;
int s;
for (s = 0; s < cl.splitclients; s++)
{
self = &cl.frames[cl.parsecount & UPDATE_MASK].playerstate[cl.playernum[s]];
oldself = &cl.frames[(cls.netchan.outgoing_sequence - 1) & UPDATE_MASK].playerstate[cl.playernum[s]];
self->messagenum = cl.parsecount;
VectorCopy(oldself->origin, self->origin);
VectorCopy(oldself->velocity, self->velocity);
VectorCopy(oldself->viewangles, self->viewangles);
}
if (old != nextdemotime)
{
old = nextdemotime;
MVD_InitInterpolation();
}
CL_ParseClientdata();
cls.netchan.outgoing_sequence = cl.parsecount + 1;
if (!cl.validsequence)
return;
if (nextdemotime <= olddemotime)
return;
frame = &cl.frames[cl.validsequence & UPDATE_MASK];
oldframe = &cl.frames[cl.oldvalidsequence & UPDATE_MASK];
oldents = oldframe->packet_entities.entities;
f = (demtime - olddemotime) / (nextdemotime - olddemotime);
f = bound(0, f, 1);
// interpolate nails
/* for (i = 0; i < cl_num_projectiles; i++)
{
if (!cl.int_projectiles[i].interpolate)
continue;
for (j = 0; j < 3; j++)
{
cl_projectiles[i].origin[j] = cl_oldprojectiles[cl.int_projectiles[i].oldindex].origin[j] +
f * (cl.int_projectiles[i].origin[j] - cl_oldprojectiles[cl.int_projectiles[i].oldindex].origin[j]);
}
}
*/
// interpolate clients
for (i = 0; i < MAX_CLIENTS; i++)
{
pplayer = &predicted_players[i];
state = &frame->playerstate[i];
oldstate = &oldframe->playerstate[i];
if (pplayer->predict)
{
for (j = 0; j < 3; j++)
{
state->viewangles[j] = MVD_AdjustAngle(oldstate->command.angles[j]/65535.0f*360, pplayer->olda[j]/65535.0f*360, f);
state->origin[j] = oldstate->origin[j] + f * (pplayer->oldo[j] - oldstate->origin[j]);
state->velocity[j] = oldstate->velocity[j] + f * (pplayer->oldv[j] - oldstate->velocity[j]);
}
}
}
}
void CL_ClearPredict(void) void CL_ClearPredict(void)
{ {
memset(predicted_players, 0, sizeof(predicted_players)); memset(predicted_players, 0, sizeof(predicted_players));
mvd_fixangle = 0;
} }

View file

@ -1361,7 +1361,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
extern cvar_t cl_splitscreen; extern cvar_t cl_splitscreen;
i = cls.netchan.outgoing_sequence & UPDATE_MASK; i = cls.netchan.outgoing_sequence & UPDATE_MASK;
cl.frames[i].senttime = realtime; // we haven't gotten a reply yet cl.frames[i].senttime = realtime; // we haven't gotten a reply yet
cl.frames[i].receivedtime = -1; // we haven't gotten a reply yet // cl.frames[i].receivedtime = -1; // we haven't gotten a reply yet
if (cl.splitclients > cl_splitscreen.ival+1) if (cl.splitclients > cl_splitscreen.ival+1)
{ {

View file

@ -75,7 +75,7 @@ cvar_t m_yaw = CVARF("m_yaw","0.022", CVAR_ARCHIVE);
cvar_t m_forward = CVARF("m_forward","1", CVAR_ARCHIVE); cvar_t m_forward = CVARF("m_forward","1", CVAR_ARCHIVE);
cvar_t m_side = CVARF("m_side","0.8", CVAR_ARCHIVE); cvar_t m_side = CVARF("m_side","0.8", CVAR_ARCHIVE);
cvar_t cl_lerp_players = CVARD("cl_lerp_players", "1", "Set this to make other players smoother, though it may increase effective latency. Affects only QuakeWorld."); cvar_t cl_lerp_players = CVARD("cl_lerp_players", "0", "Set this to make other players smoother, though it may increase effective latency. Affects only QuakeWorld.");
cvar_t cl_predict_players = CVARD("cl_predict_players", "1", "Clear this cvar to see ents exactly how they are on the server."); cvar_t cl_predict_players = CVARD("cl_predict_players", "1", "Clear this cvar to see ents exactly how they are on the server.");
cvar_t cl_solid_players = CVAR("cl_solid_players", "1"); cvar_t cl_solid_players = CVAR("cl_solid_players", "1");
cvar_t cl_noblink = CVARD("cl_noblink", "0", "Disable the ^^b text blinking feature."); cvar_t cl_noblink = CVARD("cl_noblink", "0", "Disable the ^^b text blinking feature.");
@ -170,6 +170,7 @@ cvar_t ruleset_allow_modified_eyes = SCVAR("ruleset_allow_modified_eyes", "0");
cvar_t ruleset_allow_sensative_texture_replacements = SCVAR("ruleset_allow_sensative_texture_replacements", "1"); cvar_t ruleset_allow_sensative_texture_replacements = SCVAR("ruleset_allow_sensative_texture_replacements", "1");
cvar_t ruleset_allow_localvolume = SCVAR("ruleset_allow_localvolume", "1"); cvar_t ruleset_allow_localvolume = SCVAR("ruleset_allow_localvolume", "1");
cvar_t ruleset_allow_shaders = SCVARF("ruleset_allow_shaders", "1", CVAR_SHADERSYSTEM); cvar_t ruleset_allow_shaders = SCVARF("ruleset_allow_shaders", "1", CVAR_SHADERSYSTEM);
cvar_t ruleset_allow_fbmodels = SCVARF("ruleset_allow_fbmodels", "1", CVAR_SHADERSYSTEM);
extern cvar_t cl_hightrack; extern cvar_t cl_hightrack;
extern cvar_t vid_renderer; extern cvar_t vid_renderer;
@ -2706,6 +2707,8 @@ void CLNQ_ConnectionlessPacket(void)
} }
#endif #endif
void CL_MVDUpdateSpectator (void);
/* /*
================= =================
CL_ReadPackets CL_ReadPackets
@ -2810,6 +2813,7 @@ void CL_ReadPackets (void)
case CP_QUAKEWORLD: case CP_QUAKEWORLD:
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{ {
player_state_t *n,*o;
MSG_BeginReading(cls.netchan.netprim); MSG_BeginReading(cls.netchan.netprim);
cls.netchan.last_received = realtime; cls.netchan.last_received = realtime;
cls.netchan.outgoing_sequence = cls.netchan.incoming_sequence; cls.netchan.outgoing_sequence = cls.netchan.incoming_sequence;
@ -2851,7 +2855,9 @@ void CL_ReadPackets (void)
} }
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
MVD_Interpolate(); {
CL_MVDUpdateSpectator();
}
} }
//============================================================================= //=============================================================================
@ -3273,6 +3279,7 @@ void CL_Init (void)
Cvar_Register (&ruleset_allow_sensative_texture_replacements, cl_controlgroup); Cvar_Register (&ruleset_allow_sensative_texture_replacements, cl_controlgroup);
Cvar_Register (&ruleset_allow_localvolume, cl_controlgroup); Cvar_Register (&ruleset_allow_localvolume, cl_controlgroup);
Cvar_Register (&ruleset_allow_shaders, cl_controlgroup); Cvar_Register (&ruleset_allow_shaders, cl_controlgroup);
Cvar_Register (&ruleset_allow_fbmodels, cl_controlgroup);
Cvar_Register (&qtvcl_forceversion1, cl_controlgroup); Cvar_Register (&qtvcl_forceversion1, cl_controlgroup);
Cvar_Register (&qtvcl_eztvextensions, cl_controlgroup); Cvar_Register (&qtvcl_eztvextensions, cl_controlgroup);

View file

@ -2277,15 +2277,18 @@ void CLQW_ParseServerData (void)
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{ {
int i; int i,j;
MSG_ReadFloat(); MSG_ReadFloat();
cl.playernum[0] = MAX_CLIENTS; for (j = 0; j < MAX_SPLITS; j++)
cl.playernum[1] = MAX_CLIENTS+1; {
cl.playernum[2] = MAX_CLIENTS+2; cl.playernum[j] = MAX_CLIENTS + j;
cl.playernum[3] = MAX_CLIENTS+3;
cl.spectator = true;
for (i = 0; i < UPDATE_BACKUP; i++) for (i = 0; i < UPDATE_BACKUP; i++)
cl.frames[i].playerstate[cl.playernum[0]].pm_type = PM_SPECTATOR; {
cl.frames[i].playerstate[cl.playernum[j]].pm_type = PM_SPECTATOR;
cl.frames[i].playerstate[cl.playernum[j]].messagenum = 1;
}
}
cl.spectator = true;
cl.splitclients = 1; cl.splitclients = 1;
} }
@ -3695,7 +3698,10 @@ void CL_ParseClientdata (void)
i = cls.netchan.incoming_acknowledged; i = cls.netchan.incoming_acknowledged;
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{
cl.oldparsecount = i - 1; cl.oldparsecount = i - 1;
oldparsecountmod = cl.oldparsecount & UPDATE_MASK;
}
cl.parsecount = i; cl.parsecount = i;
i &= UPDATE_MASK; i &= UPDATE_MASK;
parsecountmod = i; parsecountmod = i;
@ -3704,7 +3710,8 @@ void CL_ParseClientdata (void)
frame->senttime = realtime - host_frametime; frame->senttime = realtime - host_frametime;
parsecounttime = cl.frames[i].senttime; parsecounttime = cl.frames[i].senttime;
frame->receivedtime = (cl.gametimemark - cl.oldgametimemark)*20; frame->receivedtime = realtime;
//(cl.gametimemark - cl.oldgametimemark)*20;
// calculate latency // calculate latency
latency = frame->receivedtime - frame->senttime; latency = frame->receivedtime - frame->senttime;

View file

@ -762,7 +762,7 @@ void CL_PredictMovePNum (int pnum)
float f; float f;
frame_t *from, *to = NULL; frame_t *from, *to = NULL;
int oldphysent; int oldphysent;
vec3_t lrp; vec3_t lrp, lrpv;
//these are to make svc_viewentity work better //these are to make svc_viewentity work better
float *vel; float *vel;
@ -881,7 +881,7 @@ fixedorg:
if (Cam_TrackNum(pnum)>=0 && CL_MayLerp()) if (Cam_TrackNum(pnum)>=0 && CL_MayLerp())
{ {
float f; float f;
if (cl_lerp_players.ival) if (cl_lerp_players.ival && (cls.demoplayback==DPB_MVD || cls.demoplayback == DPB_EZTV))
{ {
lerpents_t *le = &cl.lerpplayers[spec_track[pnum]]; lerpents_t *le = &cl.lerpplayers[spec_track[pnum]];
org = le->origin; org = le->origin;
@ -911,14 +911,30 @@ fixedorg:
lrp[i] = to->playerstate[cl.playernum[pnum]].origin[i] + lrp[i] = to->playerstate[cl.playernum[pnum]].origin[i] +
f * (from->playerstate[cl.playernum[pnum]].origin[i] - to->playerstate[cl.playernum[pnum]].origin[i]); f * (from->playerstate[cl.playernum[pnum]].origin[i] - to->playerstate[cl.playernum[pnum]].origin[i]);
lrpv[i] = to->playerstate[spec_track[pnum]].velocity[i] +
f * (from->playerstate[spec_track[pnum]].velocity[i] - to->playerstate[spec_track[pnum]].velocity[i]);
cl.simangles[pnum][i] = LerpAngles16(to->playerstate[spec_track[pnum]].command.angles[i], from->playerstate[spec_track[pnum]].command.angles[i], f)*360.0f/65535; cl.simangles[pnum][i] = LerpAngles16(to->playerstate[spec_track[pnum]].command.angles[i], from->playerstate[spec_track[pnum]].command.angles[i], f)*360.0f/65535;
} }
org = lrp; org = lrp;
vel = lrpv;
goto fixedorg; goto fixedorg;
} }
else else
{
if (cls.demoplayback==DPB_MVD || cls.demoplayback==DPB_EZTV)
{
to = &cl.frames[(cls.netchan.outgoing_sequence-1) & UPDATE_MASK];
to->playerstate->pm_type = PM_SPECTATOR;
VectorCopy (cl.simvel[pnum], from->playerstate[cl.playernum[pnum]].velocity);
VectorCopy (cl.simorg[pnum], from->playerstate[cl.playernum[pnum]].origin);
CL_PredictUsercmd (pnum, &from->playerstate[cl.playernum[pnum]], &to->playerstate[cl.playernum[pnum]], &to->cmd[pnum]);
}
else
{ {
for (i=1 ; i<UPDATE_BACKUP-1 && cl.ackedinputsequence+i < for (i=1 ; i<UPDATE_BACKUP-1 && cl.ackedinputsequence+i <
cls.netchan.outgoing_sequence; i++) cls.netchan.outgoing_sequence; i++)
@ -935,6 +951,7 @@ fixedorg:
break; break;
from = to; from = to;
} }
}
if (independantphysics[pnum].msec) if (independantphysics[pnum].msec)
{ {

View file

@ -899,6 +899,21 @@ void M_Menu_Lighting_f (void)
NULL NULL
}; };
static const char *fb_models_opts[] =
{
"Disabled",
"Entire model",
"If textured",
NULL
};
static const char *fb_models_values[] =
{
"0",
"1",
"2",
NULL
};
int y; int y;
menu_t *menu = M_Options_Title(&y, sizeof(lightingmenuinfo_t)); menu_t *menu = M_Options_Title(&y, sizeof(lightingmenuinfo_t));
int lightselect, dlightselect; int lightselect, dlightselect;
@ -955,6 +970,7 @@ void M_Menu_Lighting_f (void)
MB_SLIDER("Blob Shadows", r_shadows, 0, 1, 0.05, "Small blobs underneath monsters and players, to add depth to the scene without excessive rendering."), MB_SLIDER("Blob Shadows", r_shadows, 0, 1, 0.05, "Small blobs underneath monsters and players, to add depth to the scene without excessive rendering."),
MB_SLIDER("Stains", r_stains, 0, 1, 0.05, "Allows discolouration of world surfaces, commonly used for blood trails."), MB_SLIDER("Stains", r_stains, 0, 1, 0.05, "Allows discolouration of world surfaces, commonly used for blood trails."),
MB_CHECKBOXCVARTIP("No Light Direction", r_nolightdir, 0, "Disables shading calculations for uniform light levels on models from all directions."), MB_CHECKBOXCVARTIP("No Light Direction", r_nolightdir, 0, "Disables shading calculations for uniform light levels on models from all directions."),
MB_COMBOCVAR("Model Fullbrights", r_fb_models, fb_models_opts, fb_models_values, "Affects loading of fullbrights on models/polymeshes."),
MB_END() MB_END()
}; };
MC_AddBulk(menu, bulk, 16, 216, y); MC_AddBulk(menu, bulk, 16, 216, y);

View file

@ -4487,6 +4487,14 @@ static struct {
{"keynumtostring", PF_cl_keynumtostring, 520}, {"keynumtostring", PF_cl_keynumtostring, 520},
{"findkeysforcommand", PF_cl_findkeysforcommand, 521}, {"findkeysforcommand", PF_cl_findkeysforcommand, 521},
{"loadfromdata", PF_loadfromdata, 529},
{"loadfromfile", PF_loadfromfile, 530},
{"callfunction", PF_callfunction, 605},
{"writetofile", PF_writetofile, 606},
{"isfunction", PF_isfunction, 607},
{"parseentitydata", PF_parseentitydata, 608},
{"sprintf", PF_sprintf, 627}, {"sprintf", PF_sprintf, 627},
{NULL} {NULL}

View file

@ -689,95 +689,6 @@ cvar_t pr_menuqc_coreonerror = SCVAR("pr_menuqc_coreonerror", "1");
//new generic functions. //new generic functions.
//float isfunction(string function_name) = #607;
void QCBUILTIN PF_isfunction (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *name = PR_GetStringOfs(prinst, OFS_PARM0);
G_FLOAT(OFS_RETURN) = !!PR_FindFunction(prinst, name, PR_CURRENT);
}
//void callfunction(...) = #605;
void QCBUILTIN PF_callfunction (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *name;
func_t f;
if (*prinst->callargc < 1)
PR_BIError(prinst, "callfunction needs at least one argument\n");
name = PR_GetStringOfs(prinst, OFS_PARM0+(*prinst->callargc-1)*3);
f = PR_FindFunction(prinst, name, PR_CURRENT);
if (f)
PR_ExecuteProgram(prinst, f);
}
//void loadfromfile(string file) = #69;
void QCBUILTIN PF_loadfromfile (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *filename = PR_GetStringOfs(prinst, OFS_PARM0);
char *file = COM_LoadTempFile(filename);
int size;
if (!file)
{
G_FLOAT(OFS_RETURN) = -1;
return;
}
while(prinst->restoreent(prinst, file, &size, NULL))
{
file += size;
}
G_FLOAT(OFS_RETURN) = 0;
}
void QCBUILTIN PF_loadfromdata (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *file = PR_GetStringOfs(prinst, OFS_PARM0);
int size;
if (!*file)
{
G_FLOAT(OFS_RETURN) = -1;
return;
}
while(prinst->restoreent(prinst, file, &size, NULL))
{
file += size;
}
G_FLOAT(OFS_RETURN) = 0;
}
void QCBUILTIN PF_parseentitydata(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
void *ed = G_EDICT(prinst, OFS_PARM0);
char *file = PR_GetStringOfs(prinst, OFS_PARM1);
int size;
if (!*file)
{
G_FLOAT(OFS_RETURN) = -1;
return;
}
if (!prinst->restoreent(prinst, file, &size, ed))
Con_Printf("parseentitydata: missing opening data\n");
else
{
file += size;
while(*file < ' ' && *file)
file++;
if (*file)
Con_Printf("parseentitydata: too much data\n");
}
G_FLOAT(OFS_RETURN) = 0;
}
void QCBUILTIN PF_mod (progfuncs_t *prinst, struct globalvars_s *pr_globals) void QCBUILTIN PF_mod (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
int a = G_FLOAT(OFS_PARM0); int a = G_FLOAT(OFS_PARM0);
@ -1728,7 +1639,7 @@ builtin_t menu_builtins[] = {
PF_cl_setmousetarget, PF_cl_setmousetarget,
PF_cl_getmousetarget, PF_cl_getmousetarget,
PF_callfunction, PF_callfunction,
skip1 //void writetofile(float fhandle, entity ent) = #606; PF_writetofile, //void writetofile(float fhandle, entity ent) = #606;
PF_isfunction, PF_isfunction,
PF_cl_getresolution, PF_cl_getresolution,
PF_cl_keynumtostring, PF_cl_keynumtostring,

View file

@ -87,7 +87,7 @@ cvar_t r_fastskycolour = CVARF ("r_fastskycolour", "0",
cvar_t r_fb_bmodels = CVARAF("r_fb_bmodels", "1", cvar_t r_fb_bmodels = CVARAF("r_fb_bmodels", "1",
"gl_fb_bmodels", CVAR_SEMICHEAT|CVAR_RENDERERLATCH); "gl_fb_bmodels", CVAR_SEMICHEAT|CVAR_RENDERERLATCH);
cvar_t r_fb_models = CVARAF ("r_fb_models", "1", cvar_t r_fb_models = CVARAF ("r_fb_models", "1",
"gl_fb_models", CVAR_SEMICHEAT|CVAR_RENDERERLATCH); "gl_fb_models", CVAR_SEMICHEAT);
cvar_t r_skin_overlays = SCVARF ("r_skin_overlays", "1", cvar_t r_skin_overlays = SCVARF ("r_skin_overlays", "1",
CVAR_SEMICHEAT|CVAR_RENDERERLATCH); CVAR_SEMICHEAT|CVAR_RENDERERLATCH);
cvar_t r_coronas = SCVARF ("r_coronas", "0", cvar_t r_coronas = SCVARF ("r_coronas", "0",

View file

@ -3280,8 +3280,6 @@ Sbar_FinaleOverlay
*/ */
void Sbar_FinaleOverlay (void) void Sbar_FinaleOverlay (void)
{ {
mpic_t *pic;
#ifdef VM_UI #ifdef VM_UI
if (UI_DrawFinale()>0) if (UI_DrawFinale()>0)
return; return;

View file

@ -305,7 +305,7 @@ static void Validation_Server(void)
static void Validation_Skins(void) static void Validation_Skins(void)
{ {
extern cvar_t r_fullbrightSkins, r_fb_models; extern cvar_t r_fullbrightSkins, r_fb_models, ruleset_allow_fbmodels;
int percent = r_fullbrightSkins.value*100; int percent = r_fullbrightSkins.value*100;
if (!allow_f_skins.ival) if (!allow_f_skins.ival)
@ -319,7 +319,9 @@ static void Validation_Skins(void)
if (percent > cls.allow_fbskins*100) if (percent > cls.allow_fbskins*100)
percent = cls.allow_fbskins*100; percent = cls.allow_fbskins*100;
if (percent) if (percent)
Cbuf_AddText(va("say all player skins %i%% fullbright%s\n", percent, r_fb_models.value?" (plus luma)":""), RESTRICT_LOCAL); Cbuf_AddText(va("say all player skins %i%% fullbright%s\n", percent, (r_fb_models.ival == 1 && ruleset_allow_fbmodels.ival)?" (non-player 100%%)":(r_fb_models.value?" (plus luma)":"")), RESTRICT_LOCAL);
else if (r_fb_models.ival == 1 && ruleset_allow_fbmodels.ival)
Cbuf_AddText("say non-player entities glow in the dark like a bright big cheat\n", RESTRICT_LOCAL);
else if (r_fb_models.ival) else if (r_fb_models.ival)
Cbuf_AddText("say luma textures only\n", RESTRICT_LOCAL); Cbuf_AddText("say luma textures only\n", RESTRICT_LOCAL);
else else
@ -390,6 +392,7 @@ rulesetrule_t rulesetrules_strict[] = {
{"ruleset_allow_modified_eyes", "0"}, {"ruleset_allow_modified_eyes", "0"},
{"ruleset_allow_sensative_texture_replacements", "0"}, {"ruleset_allow_sensative_texture_replacements", "0"},
{"ruleset_allow_localvolume", "0"}, {"ruleset_allow_localvolume", "0"},
{"ruleset_allow_fbmodels", "0"},
{"tp_disputablemacros", "0"}, {"tp_disputablemacros", "0"},
{"cl_instantrotate", "0"}, {"cl_instantrotate", "0"},
{"v_projectionmode", "0"}, /*no extended fovs*/ {"v_projectionmode", "0"}, /*no extended fovs*/
@ -407,6 +410,7 @@ rulesetrule_t rulesetrules_nqr[] = {
{"ruleset_allow_sensative_texture_replacements", "0"}, {"ruleset_allow_sensative_texture_replacements", "0"},
{"ruleset_allow_localvolume", "0"}, {"ruleset_allow_localvolume", "0"},
{"ruleset_allow_shaders", "0"}, {"ruleset_allow_shaders", "0"},
{"ruleset_allow_fbmodels", "0"},
{"r_vertexlight", "0"}, {"r_vertexlight", "0"},
{"v_projectionmode", "0"}, {"v_projectionmode", "0"},
{NULL} {NULL}

View file

@ -1283,8 +1283,8 @@ void R_DrawNameTags(void)
#ifdef GLQUAKE #ifdef GLQUAKE
if (qrenderer == QR_OPENGL) if (qrenderer == QR_OPENGL)
{ {
// void GL_Set2D (void); void GL_Set2D (qboolean flipped);
// GL_Set2D(false); GL_Set2D(false);
} }
#endif #endif

View file

@ -320,7 +320,7 @@ int FS_FLocateFile(const char *filename, FSLF_ReturnType_e returntype, flocation
struct vfsfile_s *FS_OpenReadLocation(flocation_t *location); struct vfsfile_s *FS_OpenReadLocation(flocation_t *location);
char *FS_WhichPackForLocation(flocation_t *loc); char *FS_WhichPackForLocation(flocation_t *loc);
qboolean FS_GetPackageDownloadable(char *package); qboolean FS_GetPackageDownloadable(const char *package);
char *FS_GetPackHashes(char *buffer, int buffersize, qboolean referencedonly); char *FS_GetPackHashes(char *buffer, int buffersize, qboolean referencedonly);
char *FS_GetPackNames(char *buffer, int buffersize, int referencedonly, qboolean ext); char *FS_GetPackNames(char *buffer, int buffersize, int referencedonly, qboolean ext);
void FS_ReferenceControl(unsigned int refflag, unsigned int resetflags); void FS_ReferenceControl(unsigned int refflag, unsigned int resetflags);

View file

@ -587,7 +587,7 @@ char *FS_WhichPackForLocation(flocation_t *loc)
} }
/*requires extension*/ /*requires extension*/
qboolean FS_GetPackageDownloadable(char *package) qboolean FS_GetPackageDownloadable(const char *package)
{ {
searchpath_t *search; searchpath_t *search;

View file

@ -963,11 +963,8 @@ void QCBUILTIN PF_fgets (progfuncs_t *prinst, struct globalvars_s *pr_globals)
RETURN_TSTRING(pr_string_temp); RETURN_TSTRING(pr_string_temp);
} }
void QCBUILTIN PF_fputs (progfuncs_t *prinst, struct globalvars_s *pr_globals) static void PF_fwrite (progfuncs_t *prinst, int fnum, char *msg, int len)
{ {
int fnum = G_FLOAT(OFS_PARM0) - FIRST_QC_FILE_INDEX;
char *msg = PF_VarString(prinst, 1, pr_globals);
int len = strlen(msg);
if (fnum < 0 || fnum >= MAX_QC_FILES) if (fnum < 0 || fnum >= MAX_QC_FILES)
{ {
Con_Printf("PF_fgets: File out of range\n"); Con_Printf("PF_fgets: File out of range\n");
@ -1010,6 +1007,15 @@ void QCBUILTIN PF_fputs (progfuncs_t *prinst, struct globalvars_s *pr_globals)
} }
} }
void QCBUILTIN PF_fputs (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int fnum = G_FLOAT(OFS_PARM0) - FIRST_QC_FILE_INDEX;
char *msg = PF_VarString(prinst, 1, pr_globals);
int len = strlen(msg);
PF_fwrite (prinst, fnum, msg, len);
}
void PF_fcloseall (progfuncs_t *prinst) void PF_fcloseall (progfuncs_t *prinst)
{ {
int i; int i;
@ -1235,6 +1241,116 @@ void PR_fclose_progs (progfuncs_t *prinst)
//File access //File access
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
//reflection
//float isfunction(string function_name)
void QCBUILTIN PF_isfunction (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *name = PR_GetStringOfs(prinst, OFS_PARM0);
G_FLOAT(OFS_RETURN) = !!PR_FindFunction(prinst, name, PR_CURRENT);
}
//void callfunction(...)
void QCBUILTIN PF_callfunction (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *name;
func_t f;
if (*prinst->callargc < 1)
PR_BIError(prinst, "callfunction needs at least one argument\n");
name = PR_GetStringOfs(prinst, OFS_PARM0+(*prinst->callargc-1)*3);
*prinst->callargc -= 1;
f = PR_FindFunction(prinst, name, PR_CURRENT);
if (f)
PR_ExecuteProgram(prinst, f);
}
//void loadfromfile(string file)
void QCBUILTIN PF_loadfromfile (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *filename = PR_GetStringOfs(prinst, OFS_PARM0);
char *file = COM_LoadTempFile(filename);
int size;
if (!file)
{
G_FLOAT(OFS_RETURN) = -1;
return;
}
while(prinst->restoreent(prinst, file, &size, NULL))
{
file += size;
}
G_FLOAT(OFS_RETURN) = 0;
}
void QCBUILTIN PF_writetofile(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int fnum = G_FLOAT(OFS_PARM0);
void *ed = G_EDICT(prinst, OFS_PARM1);
char buffer[65536];
char *entstr;
int buflen;
buflen = sizeof(buffer);
entstr = prinst->saveent(prinst, buffer, &buflen, ed); //will save just one entities vars
if (entstr)
{
PF_fwrite (prinst, fnum, entstr, buflen);
}
}
void QCBUILTIN PF_loadfromdata (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *file = PR_GetStringOfs(prinst, OFS_PARM0);
int size;
if (!*file)
{
G_FLOAT(OFS_RETURN) = -1;
return;
}
while(prinst->restoreent(prinst, file, &size, NULL))
{
file += size;
}
G_FLOAT(OFS_RETURN) = 0;
}
void QCBUILTIN PF_parseentitydata(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
void *ed = G_EDICT(prinst, OFS_PARM0);
char *file = PR_GetStringOfs(prinst, OFS_PARM1);
int size;
if (!*file)
{
G_FLOAT(OFS_RETURN) = -1;
return;
}
if (!prinst->restoreent(prinst, file, &size, ed))
Con_Printf("parseentitydata: missing opening data\n");
else
{
file += size;
while(*file < ' ' && *file)
file++;
if (*file)
Con_Printf("parseentitydata: too much data\n");
}
G_FLOAT(OFS_RETURN) = 0;
}
//reflection
////////////////////////////////////////////////////
//Entities //Entities
void QCBUILTIN PF_WasFreed (progfuncs_t *prinst, struct globalvars_s *pr_globals) void QCBUILTIN PF_WasFreed (progfuncs_t *prinst, struct globalvars_s *pr_globals)

View file

@ -159,6 +159,12 @@ void QCBUILTIN PF_search_begin (progfuncs_t *prinst, struct globalvars_s *pr_glo
void QCBUILTIN PF_search_end (progfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_search_end (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_search_getsize (progfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_search_getsize (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_search_getfilename (progfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_search_getfilename (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_isfunction (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_callfunction (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_writetofile(progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_loadfromfile (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_loadfromdata (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_parseentitydata(progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_WasFreed (progfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_WasFreed (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_break (progfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_break (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_crc16 (progfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_crc16 (progfuncs_t *prinst, struct globalvars_s *pr_globals);

View file

@ -1,6 +1,7 @@
package com.fteqw; package com.fteqw;
import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLConfig;
//import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.opengles.GL10; import javax.microedition.khronos.opengles.GL10;
import android.app.Activity; import android.app.Activity;
@ -50,6 +51,32 @@ public class FTEDroidActivity extends Activity
{ {
} }
} }
/*
private class FTEEGLConfig implements GLSurfaceView.EGLConfigChooser
{
@Override
public EGLConfig chooseConfig (javax.microedition.khronos.egl.EGL10 egl, javax.microedition.khronos.egl.EGLDisplay display)
{
int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
EGLConfig[] cfg = new EGLConfig[1];
int[] num_configs = {0};
int[] attribs =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
egl.EGL_SURFACE_TYPE, egl.EGL_WINDOW_BIT,
egl.EGL_BLUE_SIZE, 5,
egl.EGL_GREEN_SIZE, 6,
egl.EGL_RED_SIZE, 5,
egl.EGL_DEPTH_SIZE, 16,
egl.EGL_STENCIL_SIZE, 8,
egl.EGL_NONE, egl.EGL_NONE
};
egl.eglChooseConfig(display, attribs, cfg, 1, num_configs);
return cfg[0];
}
}
*/
private class FTEView extends GLSurfaceView implements SensorEventListener private class FTEView extends GLSurfaceView implements SensorEventListener
{ {
private final FTERenderer rndr; private final FTERenderer rndr;
@ -109,6 +136,7 @@ public class FTEDroidActivity extends Activity
super(context); super(context);
rndr = new FTERenderer(); rndr = new FTERenderer();
// setEGLConfigChooser(new FTEEGLConfig());
setRenderer(rndr); setRenderer(rndr);
setFocusable(true); setFocusable(true);
setFocusableInTouchMode(true); setFocusableInTouchMode(true);

View file

@ -36,7 +36,7 @@ typedef struct
extern cvar_t gl_part_flame, r_fullbrightSkins, r_fb_models; extern cvar_t gl_part_flame, r_fullbrightSkins, r_fb_models, ruleset_allow_fbmodels;
extern cvar_t r_noaliasshadows; extern cvar_t r_noaliasshadows;
@ -740,6 +740,13 @@ static qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel)
e->light_known = 2; e->light_known = 2;
return e->light_known-1; return e->light_known-1;
} }
if (r_fb_models.ival == 1 && ruleset_allow_fbmodels.ival && (clmodel->engineflags & MDLF_EZQUAKEFBCHEAT) && cls.protocol == CP_QUAKEWORLD && cl.deathmatch)
{
e->light_avg[0] = e->light_avg[1] = e->light_avg[2] = 1;
e->light_range[0] = e->light_range[1] = e->light_range[2] = 0;
e->light_known = 2;
return e->light_known-1;
}
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
{ {

View file

@ -566,6 +566,18 @@ model_t *RMod_LoadModel (model_t *mod, qboolean crash)
else if (!strcmp(mod->name, "progs/eyes.mdl")) else if (!strcmp(mod->name, "progs/eyes.mdl"))
mod->engineflags |= MDLF_NOTREPLACEMENTS|MDLF_DOCRC; mod->engineflags |= MDLF_NOTREPLACEMENTS|MDLF_DOCRC;
/*handle ezquake-originated cheats that would feck over fte users if fte didn't support
these are the conditions required for r_fb_models on non-players*/
mod->engineflags |= MDLF_EZQUAKEFBCHEAT;
if ((mod->engineflags & MDLF_DOCRC) ||
!strcmp(mod->name, "progs/backpack.mdl") ||
!strcmp(mod->name, "progs/gib1.mdl") ||
!strcmp(mod->name, "progs/gib2.mdl") ||
!strcmp(mod->name, "progs/gib3.mdl") ||
!strcmp(mod->name, "progs/h_player.mdl") ||
!strncmp(mod->name, "progs/v_", 8))
mod->engineflags &= ~MDLF_EZQUAKEFBCHEAT;
// call the apropriate loader // call the apropriate loader
mod->needload = false; mod->needload = false;

View file

@ -954,6 +954,7 @@ typedef struct model_s
#define MDLF_NEEDOVERBRIGHT 0x040 // only overbright these models with gl_overbright_all set #define MDLF_NEEDOVERBRIGHT 0x040 // only overbright these models with gl_overbright_all set
#define MDLF_BOLT 0x080 // doesn't produce shadows #define MDLF_BOLT 0x080 // doesn't produce shadows
#define MDLF_NOTREPLACEMENTS 0x100 // can be considered a cheat, disable texture replacements #define MDLF_NOTREPLACEMENTS 0x100 // can be considered a cheat, disable texture replacements
#define MDLF_EZQUAKEFBCHEAT 0x200 // this is a blatent cheat, one that can disadvantage us fairly significantly if we don't support it.
//============================================================================ //============================================================================
/* /*

View file

@ -260,8 +260,8 @@ enum qcop_e {
//------------------------------------- //-------------------------------------
//string manipulation. //string manipulation.
OP_ADD_SF, //(char*)c = (char*)a + (float)b OP_ADD_SF, //(char*)c = (char*)a + (float)b add_fi->i
OP_SUB_S, //(float)c = (char*)a - (char*)b OP_SUB_S, //(float)c = (char*)a - (char*)b sub_ii->f
OP_STOREP_C,//(float)c = *(char*)b = (float)a OP_STOREP_C,//(float)c = *(char*)b = (float)a
OP_LOADP_C, //(float)c = *(char*) OP_LOADP_C, //(float)c = *(char*)
//------------------------------------- //-------------------------------------

View file

@ -1649,6 +1649,8 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
ddef16_t *d16; ddef16_t *d16;
ddef32_t *d32; ddef32_t *d32;
func_t CheckSpawn=0; func_t CheckSpawn=0;
void *oldglobals = NULL;
int oldglobalssize = 0;
extern edictrun_t tempedict; extern edictrun_t tempedict;
@ -1797,6 +1799,14 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
current_progstate->builtins = externs->builtinsfor(num, header_crc); current_progstate->builtins = externs->builtinsfor(num, header_crc);
current_progstate->numbuiltins = numbuiltins; current_progstate->numbuiltins = numbuiltins;
} }
if (num == 0 && oldglobals)
{
if (pr_progstate[0].globals_size == oldglobalssize)
memcpy(pr_progstate[0].globals, oldglobals, pr_progstate[0].globals_size);
free(oldglobals);
oldglobals = NULL;
}
} }
else if (!strcmp(qcc_token, "globals")) else if (!strcmp(qcc_token, "globals"))
{ {
@ -1906,6 +1916,21 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
Sys_Error("Bad key \"%s\" in general block", qcc_token); Sys_Error("Bad key \"%s\" in general block", qcc_token);
} }
if (oldglobals)
free(oldglobals);
oldglobals = NULL;
if (pr_progstate[0].globals_size)
{
oldglobals = malloc(pr_progstate[0].globals_size);
if (oldglobals)
{
oldglobalssize = pr_progstate[0].globals_size;
memcpy(oldglobals, pr_progstate[0].globals, oldglobalssize);
}
else
printf("Unable to alloc %i bytes\n", pr_progstate[0].globals_size);
}
PRAddressableFlush(progfuncs, -1); PRAddressableFlush(progfuncs, -1);
resethunk=true; resethunk=true;
@ -2107,6 +2132,10 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
sv_num_edicts = numents; sv_num_edicts = numents;
} }
if (oldglobals)
free(oldglobals);
oldglobals = NULL;
if (resethunk) if (resethunk)
{ {
return entsize; return entsize;
@ -2448,6 +2477,7 @@ retry:
current_progstate->statements = (void *)((qbyte *)pr_progs + pr_progs->ofs_statements); current_progstate->statements = (void *)((qbyte *)pr_progs + pr_progs->ofs_statements);
glob = pr_globals = (void *)((qbyte *)pr_progs + pr_progs->ofs_globals); glob = pr_globals = (void *)((qbyte *)pr_progs + pr_progs->ofs_globals);
current_progstate->globals_size = pr_progs->numglobals*sizeof(*pr_globals);
pr_linenums=NULL; pr_linenums=NULL;
pr_types=NULL; pr_types=NULL;

View file

@ -186,6 +186,7 @@ typedef struct progstate_s
void *statements; void *statements;
// void *global_struct; // void *global_struct;
float *globals; // same as pr_global_struct float *globals; // same as pr_global_struct
int globals_size; // in bytes
typeinfo_t *types; typeinfo_t *types;

View file

@ -4300,12 +4300,21 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
tmp = QCC_PR_Expression (TOP_PRIORITY, 0); tmp = QCC_PR_Expression (TOP_PRIORITY, 0);
QCC_PR_Expect("]"); QCC_PR_Expect("]");
/*if its a pointer that got dereferenced, follow the type*/
if (!idx && t->type == ev_pointer && !d->arraysize) if (!idx && t->type == ev_pointer && !d->arraysize)
t = t->aux_type; t = t->aux_type;
if (!idx && d->type->type == ev_pointer) if (!idx && d->type->type == ev_pointer)
{ {
/*no bounds checks*/ /*no bounds checks on pointer dereferences*/
}
else if (!idx && d->type->type == ev_string)
{
/*automatic runtime bounds checks on strings, I'm not going to check this too much...*/
}
else if (!((!idx)?d->arraysize:t->arraysize))
{
QCC_PR_ParseErrorPrintDef(0, d, "array index on non-array");
} }
else if (tmp->constant) else if (tmp->constant)
{ {
@ -4332,6 +4341,8 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
else else
tmp = QCC_PR_Statement(&pr_opcodes[OP_MUL_I], tmp, QCC_MakeIntConst(t->size), NULL); tmp = QCC_PR_Statement(&pr_opcodes[OP_MUL_I], tmp, QCC_MakeIntConst(t->size), NULL);
} }
/*calc the new index*/
if (idx) if (idx)
idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], idx, QCC_SupplyConversion(tmp, ev_integer, true), NULL); idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], idx, QCC_SupplyConversion(tmp, ev_integer, true), NULL);
else else
@ -4403,6 +4414,10 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
} }
d->type = t; d->type = t;
} }
else if (d->type->type == ev_string)
{
d = QCC_PR_Statement(&pr_opcodes[OP_LOADP_C], d, QCC_SupplyConversion(idx, ev_float, true), NULL);
}
else if (QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F])) else if (QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]))
{ {
/*don't care about assignments. the code can convert an OP_LOADA_F to an OP_ADDRESS on assign*/ /*don't care about assignments. the code can convert an OP_LOADA_F to an OP_ADDRESS on assign*/

View file

@ -1558,6 +1558,7 @@ void QCC_PR_LexVector (void)
default: default:
QCC_PR_ParseError (ERR_INVALIDVECTORIMMEDIATE, "Bad character constant"); QCC_PR_ParseError (ERR_INVALIDVECTORIMMEDIATE, "Bad character constant");
} }
pr_file_p++;
if (*pr_file_p != '\'') if (*pr_file_p != '\'')
QCC_PR_ParseError (ERR_INVALIDVECTORIMMEDIATE, "Bad character constant"); QCC_PR_ParseError (ERR_INVALIDVECTORIMMEDIATE, "Bad character constant");
pr_file_p++; pr_file_p++;

View file

@ -319,11 +319,13 @@ int QCC_CopyString (char *str)
int old; int old;
char *s; char *s;
if (!str)
return 0;
if (!*str)
return 1;
if (opt_noduplicatestrings) if (opt_noduplicatestrings)
{ {
if (!str || !*str)
return 0;
for (s = strings; s < strings+strofs; s++) for (s = strings; s < strings+strofs; s++)
if (!strcmp(s, str)) if (!strcmp(s, str))
{ {
@ -488,7 +490,7 @@ void QCC_InitData (void)
qcc_sourcefile = NULL; qcc_sourcefile = NULL;
numstatements = 1; numstatements = 1;
strofs = 1; strofs = 2;
numfunctions = 1; numfunctions = 1;
numglobaldefs = 1; numglobaldefs = 1;
numfielddefs = 1; numfielddefs = 1;
@ -784,7 +786,7 @@ pbool QCC_WriteData (int crc)
dd->s_name = QCC_CopyString (def->name); dd->s_name = QCC_CopyString (def->name);
dd->ofs = G_INT(def->ofs); dd->ofs = G_INT(def->ofs);
} }
else if ((def->scope||def->constant) && (def->type->type != ev_string || opt_constant_names_strings)) else if ((def->scope||def->constant) && (def->type->type != ev_string || (strncmp(def->name, "dotranslate_", 12) && opt_constant_names_strings)))
{ {
if (opt_constant_names) if (opt_constant_names)
{ {
@ -2992,7 +2994,7 @@ void QCC_main (int argc, char **argv) //as part of the quake engine
QCC_PurgeTemps(); QCC_PurgeTemps();
strings = (void *)qccHunkAlloc(sizeof(char) * MAX_STRINGS); strings = (void *)qccHunkAlloc(sizeof(char) * MAX_STRINGS);
strofs = 1; strofs = 2;
statements = (void *)qccHunkAlloc(sizeof(QCC_dstatement_t) * MAX_STATEMENTS); statements = (void *)qccHunkAlloc(sizeof(QCC_dstatement_t) * MAX_STATEMENTS);
numstatements = 0; numstatements = 0;

View file

@ -8689,7 +8689,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"precache_file", PF_precache_file, 68, 68, 68, 0, "void(string s)"}, //68 {"precache_file", PF_precache_file, 68, 68, 68, 0, "void(string s)"}, //68
{"makestatic", PF_makestatic, 69, 69, 69, 0, "void(entity e)"}, //69 {"makestatic", PF_makestatic, 69, 69, 69, 0, "void(entity e)"}, //69
{"changelevel", PF_changelevel, 70, 70, 70, 0, "void(string mapname)"}, //70 {"changelevel", PF_changelevel, 70, 70, 70, 0, "void(string mapname, optional string newmapstartspot)"}, //70
{"lightstylevalue", PF_lightstylevalue, 0, 0, 71, 0, "float(float lstyle)"}, //70 {"lightstylevalue", PF_lightstylevalue, 0, 0, 71, 0, "float(float lstyle)"}, //70
{"cvar_set", PF_cvar_set, 72, 72, 72, 0, "void(string cvarname, string valuetoset)"}, //72 {"cvar_set", PF_cvar_set, 72, 72, 72, 0, "void(string cvarname, string valuetoset)"}, //72
@ -9239,8 +9239,8 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"cvar_description",PF_cvar_description,0, 0, 0, 518, "string(string cvarname)"}, {"cvar_description",PF_cvar_description,0, 0, 0, 518, "string(string cvarname)"},
{"gettime", PF_Fixme, 0, 0, 0, 519, "float(optional float timetype)"}, {"gettime", PF_Fixme, 0, 0, 0, 519, "float(optional float timetype)"},
// {"loadfromdata", VM_loadfromdata, 0, 0, 0, 529, "??" STUB}, {"loadfromdata", PF_loadfromdata, 0, 0, 0, 529, "void(string s)"},
// {"loadfromfile", VM_loadfromfile, 0, 0, 0, 530, "??" STUB}, {"loadfromfile", PF_loadfromfile, 0, 0, 0, 530, "void(string s)"},
// {"setpause", VM_SV_setpause, 0, 0, 0, 531, "void(float pause)" STUB}, // {"setpause", VM_SV_setpause, 0, 0, 0, 531, "void(float pause)" STUB},
//end dp extras //end dp extras
@ -9255,10 +9255,11 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"physics_addforce",PF_Ignore, 0, 0, 0, 541, "void(entity e, vector force, vector relative_ofs)" STUB}, {"physics_addforce",PF_Ignore, 0, 0, 0, 541, "void(entity e, vector force, vector relative_ofs)" STUB},
{"physics_addtorque",PF_Ignore, 0, 0, 0, 542, "void(entity e, vector torque)" STUB}, {"physics_addtorque",PF_Ignore, 0, 0, 0, 542, "void(entity e, vector torque)" STUB},
//VM_callfunction, // #605 {"callfunction", PF_callfunction, 0, 0, 0, 605, "void(.../*, string funcname*/)"},
//VM_writetofile, // #606 {"writetofile", PF_writetofile, 0, 0, 0, 606, "void(float fh, entity e)"},
//VM_isfunction, // #607 {"isfunction", PF_isfunction, 0, 0, 0, 607, "float(string s)"},
//VM_parseentitydata, // #613 {"parseentitydata", PF_parseentitydata, 0, 0, 0, 608, "void(entity e, string s)"},
//VM_SV_getextresponse, // #624 string getextresponse(void) //VM_SV_getextresponse, // #624 string getextresponse(void)
{"sprintf", PF_sprintf, 0, 0, 0, 627, "string(...)" STUB}, {"sprintf", PF_sprintf, 0, 0, 0, 627, "string(...)" STUB},
@ -9957,6 +9958,7 @@ void PR_DumpPlatform_f(void)
{"FILE_READ", "const float", QW|NQ|CS, FRIK_FILE_READ}, {"FILE_READ", "const float", QW|NQ|CS, FRIK_FILE_READ},
{"FILE_APPEND", "const float", QW|NQ|CS, FRIK_FILE_APPEND}, {"FILE_APPEND", "const float", QW|NQ|CS, FRIK_FILE_APPEND},
{"FILE_WRITE", "const float", QW|NQ|CS, FRIK_FILE_WRITE}, {"FILE_WRITE", "const float", QW|NQ|CS, FRIK_FILE_WRITE},
{"FILE_READNL", "const float", QW|NQ|CS, FRIK_FILE_READNL},
{"FILE_MMAP_READ", "const float", QW|NQ|CS, FRIK_FILE_MMAP_READ}, {"FILE_MMAP_READ", "const float", QW|NQ|CS, FRIK_FILE_MMAP_READ},
{"FILE_MMAP_RW", "const float", QW|NQ|CS, FRIK_FILE_MMAP_RW}, {"FILE_MMAP_RW", "const float", QW|NQ|CS, FRIK_FILE_MMAP_RW},

View file

@ -655,11 +655,14 @@ qboolean SV_LoadLevelCache(char *savename, char *level, char *startspot, qboolea
// load the edicts out of the savegame file // load the edicts out of the savegame file
// the rest of the file is sent directly to the progs engine. // the rest of the file is sent directly to the progs engine.
/*hexen2's gamecode doesn't have SAVE set on all variables, in which case we must clobber them, and run the risk that they were set at map load time, but clear in the savegame.*/
if (progstype != PROG_H2)
{
Q_SetProgsParms(false); Q_SetProgsParms(false);
PR_Configure(svprogfuncs, -1, MAX_PROGS); PR_Configure(svprogfuncs, -1, MAX_PROGS);
PR_RegisterFields(); PR_RegisterFields();
PR_InitEnts(svprogfuncs, sv.world.max_edicts); PR_InitEnts(svprogfuncs, sv.world.max_edicts);
}
modelpos = VFS_TELL(f); modelpos = VFS_TELL(f);
LoadModelsAndSounds(f); LoadModelsAndSounds(f);
@ -854,11 +857,13 @@ void SV_SaveLevelCache(char *savedir, qboolean dontharmgame)
VFS_PRINTF (f, "%i\n", CACHEGAME_VERSION); VFS_PRINTF (f, "%i\n", CACHEGAME_VERSION);
SV_SavegameComment (comment); SV_SavegameComment (comment);
VFS_PRINTF (f, "%s\n", comment); VFS_PRINTF (f, "%s\n", comment);
if (!dontharmgame)
{
for (cl = svs.clients, clnum=0; clnum < MAX_CLIENTS; cl++,clnum++)//fake dropping for (cl = svs.clients, clnum=0; clnum < MAX_CLIENTS; cl++,clnum++)//fake dropping
{ {
if ((cl->state < cs_spawned && !cl->istobeloaded) || dontharmgame) //don't drop if they are still connecting if (cl->state < cs_spawned && !cl->istobeloaded) //don't drop if they are still connecting
{ {
continue; cl->edict->v->solid = 0;
} }
else if (!cl->spectator) else if (!cl->spectator)
{ {
@ -876,6 +881,7 @@ void SV_SaveLevelCache(char *savedir, qboolean dontharmgame)
PR_ExecuteProgram (svprogfuncs, SpectatorDisconnect); PR_ExecuteProgram (svprogfuncs, SpectatorDisconnect);
} }
} }
}
VFS_PRINTF (f, "%d\n", progstype); VFS_PRINTF (f, "%d\n", progstype);
VFS_PRINTF (f, "%f\n", skill.value); VFS_PRINTF (f, "%f\n", skill.value);
VFS_PRINTF (f, "%f\n", deathmatch.value); VFS_PRINTF (f, "%f\n", deathmatch.value);
@ -1053,13 +1059,14 @@ void SV_Savegame_f (void)
void SV_Loadgame_f (void) void SV_Loadgame_f (void)
{ {
levelcache_t *cache; levelcache_t *cache;
char str[MAX_LOCALINFO_STRING+1], *trim; unsigned char str[MAX_LOCALINFO_STRING+1], *trim;
char savename[MAX_QPATH]; unsigned char savename[MAX_QPATH];
vfsfile_t *f; vfsfile_t *f;
char filename[MAX_OSPATH]; unsigned char filename[MAX_OSPATH];
int version; int version;
int clnum; int clnum;
int slots; int slots;
int loadzombies = 0;
client_t *cl; client_t *cl;
gametype_e gametype; gametype_e gametype;
@ -1130,6 +1137,7 @@ void SV_Loadgame_f (void)
cl->state = cs_zombie; cl->state = cs_zombie;
cl->connection_started = realtime+20; cl->connection_started = realtime+20;
cl->istobeloaded = true; cl->istobeloaded = true;
loadzombies++;
memset(&cl->netchan, 0, sizeof(cl->netchan)); memset(&cl->netchan, 0, sizeof(cl->netchan));
for (len = 0; len < NUM_SPAWN_PARMS; len++) for (len = 0; len < NUM_SPAWN_PARMS; len++)
@ -1237,6 +1245,7 @@ void SV_Loadgame_f (void)
SV_LoadLevelCache(savename, str, "", true); SV_LoadLevelCache(savename, str, "", true);
sv.allocated_client_slots = slots; sv.allocated_client_slots = slots;
sv.spawned_client_slots += loadzombies;
} }
#endif #endif

View file

@ -2296,6 +2296,9 @@ client_t *SVC_DirectConnect(void)
newcl->realip_ping = (((rand()^(rand()<<8) ^ *(int*)&realtime)&0xffffff)<<8) | (newcl-svs.clients); newcl->realip_ping = (((rand()^(rand()<<8) ^ *(int*)&realtime)&0xffffff)<<8) | (newcl-svs.clients);
if (newcl->istobeloaded)
newcl->playerclass = newcl->edict->xv->playerclass;
// parse some info from the info strings // parse some info from the info strings
SV_ExtractFromUserinfo (newcl); SV_ExtractFromUserinfo (newcl);
SV_GenerateBasicUserInfo (newcl); SV_GenerateBasicUserInfo (newcl);
@ -3462,7 +3465,7 @@ void SV_CheckTimeouts (void)
if (cl->netchan.last_received < droptime && cl->netchan.remote_address.type != NA_LOOPBACK && cl->protocol != SCP_BAD) { if (cl->netchan.last_received < droptime && cl->netchan.remote_address.type != NA_LOOPBACK && cl->protocol != SCP_BAD) {
SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTTIMEDOUT, cl->name); SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTTIMEDOUT, cl->name);
SV_DropClient (cl); SV_DropClient (cl);
cl->state = cs_free; // don't bother with zombie state cl->state = cs_free; // don't bother with zombie state for local player.
} }
} }
if (cl->state == cs_zombie && if (cl->state == cs_zombie &&
@ -3479,9 +3482,11 @@ void SV_CheckTimeouts (void)
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect); PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
sv.spawned_client_slots--; sv.spawned_client_slots--;
host_client->istobeloaded=false; cl->istobeloaded=false;
SV_BroadcastTPrintf (PRINT_HIGH, STL_LOADZOMIBETIMEDOUT, cl->name); SV_BroadcastTPrintf (PRINT_HIGH, STL_LOADZOMIBETIMEDOUT, cl->name);
// cl->state = cs_zombie; // the real zombieness starts now
// cl->connection_started = realtime;
} }
} }
} }
@ -4548,6 +4553,7 @@ void SV_ExtractFromUserinfo (client_t *cl)
client_t *client; client_t *client;
int dupc = 1; int dupc = 1;
char newname[80], basic[80]; char newname[80], basic[80];
extern cvar_t rank_filename;
val = Info_ValueForKey (cl->userinfo, "team"); val = Info_ValueForKey (cl->userinfo, "team");
Q_strncpyz (cl->team, val, sizeof(cl->teambuf)); Q_strncpyz (cl->team, val, sizeof(cl->teambuf));
@ -4622,7 +4628,7 @@ void SV_ExtractFromUserinfo (client_t *cl)
if (*cl->name && cl->state >= cs_spawned && !cl->spectator) if (*cl->name && cl->state >= cs_spawned && !cl->spectator)
{ {
SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTNAMECHANGE, cl->name, val); SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTNAMECHANGE, cl->name, newname);
} }
Q_strncpyz (cl->name, newname, sizeof(cl->namebuf)); Q_strncpyz (cl->name, newname, sizeof(cl->namebuf));
@ -4633,7 +4639,7 @@ void SV_ExtractFromUserinfo (client_t *cl)
#endif #endif
#ifdef SVRANKING #ifdef SVRANKING
} }
else if (cl->state >= cs_spawned) else if (cl->state >= cs_spawned && *rank_filename.string)
SV_ClientPrintf(cl, PRINT_HIGH, "Your rankings name has not been changed\n"); SV_ClientPrintf(cl, PRINT_HIGH, "Your rankings name has not been changed\n");
#endif #endif
} }

View file

@ -1934,12 +1934,18 @@ void SV_UpdateToReliableMessages (void)
{ {
if (strcmp(host_client->name, name)) if (strcmp(host_client->name, name))
{ {
char oname[80];
Q_strncpyz(oname, host_client->name, sizeof(oname));
#pragma warningmsg("Debug line to try to find OneManClan's issue\n");
Con_Printf("DEBUG: .netname= \"%s\" -> \"%s\" (f=%x n=%p b=%p)\n", oname, name, host_client->edict->v->netname, host_client->name, host_client->namebuf);
Con_DPrintf("Client %s programatically renamed to %s\n", host_client->name, name); Con_DPrintf("Client %s programatically renamed to %s\n", host_client->name, name);
Info_SetValueForKey(host_client->userinfo, "name", name, sizeof(host_client->userinfo)); Info_SetValueForKey(host_client->userinfo, "name", name, sizeof(host_client->userinfo));
if (!strcmp(Info_ValueForKey(host_client->userinfo, "name"), name))
{
SV_ExtractFromUserinfo (host_client); SV_ExtractFromUserinfo (host_client);
if (strcmp(oname, host_client->name))
{
MSG_WriteByte (&sv.reliable_datagram, svc_setinfo); MSG_WriteByte (&sv.reliable_datagram, svc_setinfo);
MSG_WriteByte (&sv.reliable_datagram, i); MSG_WriteByte (&sv.reliable_datagram, i);
MSG_WriteString (&sv.reliable_datagram, "name"); MSG_WriteString (&sv.reliable_datagram, "name");

View file

@ -1513,6 +1513,7 @@ void SV_Spawn_f (void)
{ {
split->entgravity = ent->xv->gravity; split->entgravity = ent->xv->gravity;
split->maxspeed = ent->xv->maxspeed; split->maxspeed = ent->xv->maxspeed;
split->playerclass = ent->xv->playerclass;
} }
else else
{ {