1
0
Fork 0
forked from fte/fteqw

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;
lerpents_t *le;
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&=UPDATE_MASK;
@ -2461,6 +2461,29 @@ CL_ParsePlayerinfo
extern int parsecountmod, oldparsecountmod;
extern double parsecounttime;
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)
{
int msec;
@ -2470,7 +2493,7 @@ void CL_ParsePlayerinfo (void)
int num;
int i;
int newf;
vec3_t org;
vec3_t org, dist;
lastplayerinfo = num = MSG_ReadByte ();
if (num >= MAX_CLIENTS)
@ -2522,6 +2545,10 @@ void CL_ParsePlayerinfo (void)
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++)
{
if (flags & (DF_ANGLES << i))
@ -3096,7 +3123,7 @@ void CL_LinkPlayers (void)
if (pnum < cl.splitclients)
{ //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];
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)
{
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;
i = cls.netchan.outgoing_sequence & UPDATE_MASK;
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)
{

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_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_solid_players = CVAR("cl_solid_players", "1");
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_localvolume = SCVAR("ruleset_allow_localvolume", "1");
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 vid_renderer;
@ -2706,6 +2707,8 @@ void CLNQ_ConnectionlessPacket(void)
}
#endif
void CL_MVDUpdateSpectator (void);
/*
=================
CL_ReadPackets
@ -2810,6 +2813,7 @@ void CL_ReadPackets (void)
case CP_QUAKEWORLD:
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{
player_state_t *n,*o;
MSG_BeginReading(cls.netchan.netprim);
cls.netchan.last_received = realtime;
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)
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_localvolume, 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_eztvextensions, cl_controlgroup);

View file

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

View file

@ -762,7 +762,7 @@ void CL_PredictMovePNum (int pnum)
float f;
frame_t *from, *to = NULL;
int oldphysent;
vec3_t lrp;
vec3_t lrp, lrpv;
//these are to make svc_viewentity work better
float *vel;
@ -881,7 +881,7 @@ fixedorg:
if (Cam_TrackNum(pnum)>=0 && CL_MayLerp())
{
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]];
org = le->origin;
@ -911,29 +911,46 @@ fixedorg:
lrp[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;
}
org = lrp;
vel = lrpv;
goto fixedorg;
}
else
{
for (i=1 ; i<UPDATE_BACKUP-1 && cl.ackedinputsequence+i <
cls.netchan.outgoing_sequence; i++)
if (cls.demoplayback==DPB_MVD || cls.demoplayback==DPB_EZTV)
{
to = &cl.frames[(cl.ackedinputsequence+i) & UPDATE_MASK];
if (cl.intermission)
to->playerstate->pm_type = PM_FLY;
CL_PredictUsercmd (pnum, &from->playerstate[cl.playernum[pnum]]
, &to->playerstate[cl.playernum[pnum]], &to->cmd[pnum]);
to = &cl.frames[(cls.netchan.outgoing_sequence-1) & UPDATE_MASK];
to->playerstate->pm_type = PM_SPECTATOR;
cl.onground[pnum] = pmove.onground;
VectorCopy (cl.simvel[pnum], from->playerstate[cl.playernum[pnum]].velocity);
VectorCopy (cl.simorg[pnum], from->playerstate[cl.playernum[pnum]].origin);
if (to->senttime >= realtime)
break;
from = to;
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 <
cls.netchan.outgoing_sequence; i++)
{
to = &cl.frames[(cl.ackedinputsequence+i) & UPDATE_MASK];
if (cl.intermission)
to->playerstate->pm_type = PM_FLY;
CL_PredictUsercmd (pnum, &from->playerstate[cl.playernum[pnum]]
, &to->playerstate[cl.playernum[pnum]], &to->cmd[pnum]);
cl.onground[pnum] = pmove.onground;
if (to->senttime >= realtime)
break;
from = to;
}
}
if (independantphysics[pnum].msec)

View file

@ -899,6 +899,21 @@ void M_Menu_Lighting_f (void)
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;
menu_t *menu = M_Options_Title(&y, sizeof(lightingmenuinfo_t));
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("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_COMBOCVAR("Model Fullbrights", r_fb_models, fb_models_opts, fb_models_values, "Affects loading of fullbrights on models/polymeshes."),
MB_END()
};
MC_AddBulk(menu, bulk, 16, 216, y);

View file

@ -4446,35 +4446,35 @@ static struct {
#endif
//DP_QC_CRC16
{"crc16", PF_crc16, 494}, // #494 float(float caseinsensitive, string s, ...) crc16
{"crc16", PF_crc16, 494}, // #494 float(float caseinsensitive, string s, ...) crc16
//DP_QC_CVAR_TYPE
{"cvar_type", PF_cvar_type, 495}, // #495 float(string name) cvar_type
{"cvar_type", PF_cvar_type, 495}, // #495 float(string name) cvar_type
//DP_QC_ENTITYDATA
{"numentityfields", PF_numentityfields, 496}, // #496 float() numentityfields
{"entityfieldname", PF_entityfieldname, 497}, // #497 string(float fieldnum) entityfieldname
{"entityfieldtype", PF_entityfieldtype, 498}, // #498 float(float fieldnum) entityfieldtype
{"getentityfieldstring",PF_getentityfieldstring, 499}, // #499 string(float fieldnum, entity ent) getentityfieldstring
{"numentityfields", PF_numentityfields, 496}, // #496 float() numentityfields
{"entityfieldname", PF_entityfieldname, 497}, // #497 string(float fieldnum) entityfieldname
{"entityfieldtype", PF_entityfieldtype, 498}, // #498 float(float fieldnum) entityfieldtype
{"getentityfieldstring",PF_getentityfieldstring, 499}, // #499 string(float fieldnum, entity ent) getentityfieldstring
{"putentityfieldstring",PF_putentityfieldstring, 500}, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring
//DP_SV_WRITEPICTURE
{"WritePicture", PF_ReadPicture, 501}, // #501 void(float to, string s, float sz) WritePicture
{"WritePicture", PF_ReadPicture, 501}, // #501 void(float to, string s, float sz) WritePicture
//no 502 documented
//DP_QC_WHICHPACK
{"whichpack", PF_whichpack, 503}, // #503 string(string filename) whichpack
{"whichpack", PF_whichpack, 503}, // #503 string(string filename) whichpack
//DP_QC_URI_ESCAPE
{"uri_escape", PF_uri_escape, 510}, // #510 string(string in) uri_escape
{"uri_unescape", PF_uri_unescape, 511}, // #511 string(string in) uri_unescape = #511;
{"uri_escape", PF_uri_escape, 510}, // #510 string(string in) uri_escape
{"uri_unescape", PF_uri_unescape, 511}, // #511 string(string in) uri_unescape = #511;
//DP_QC_NUM_FOR_EDICT
{"num_for_edict", PF_num_for_edict, 512}, // #512 float(entity ent) num_for_edict
{"num_for_edict", PF_num_for_edict, 512}, // #512 float(entity ent) num_for_edict
//DP_QC_URI_GET
{"uri_get", PF_uri_get, 513}, // #513 float(string uril, float id) uri_get
{"uri_get", PF_uri_get, 513}, // #513 float(string uril, float id) uri_get
{"tokenize_console", PF_tokenize_console, 514},
{"argv_start_index", PF_argv_start_index, 515},
@ -4487,6 +4487,14 @@ static struct {
{"keynumtostring", PF_cl_keynumtostring, 520},
{"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},
{NULL}

View file

@ -689,95 +689,6 @@ cvar_t pr_menuqc_coreonerror = SCVAR("pr_menuqc_coreonerror", "1");
//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)
{
int a = G_FLOAT(OFS_PARM0);
@ -1728,7 +1639,7 @@ builtin_t menu_builtins[] = {
PF_cl_setmousetarget,
PF_cl_getmousetarget,
PF_callfunction,
skip1 //void writetofile(float fhandle, entity ent) = #606;
PF_writetofile, //void writetofile(float fhandle, entity ent) = #606;
PF_isfunction,
PF_cl_getresolution,
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",
"gl_fb_bmodels", CVAR_SEMICHEAT|CVAR_RENDERERLATCH);
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_SEMICHEAT|CVAR_RENDERERLATCH);
cvar_t r_coronas = SCVARF ("r_coronas", "0",

View file

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

View file

@ -305,7 +305,7 @@ static void Validation_Server(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;
if (!allow_f_skins.ival)
@ -319,7 +319,9 @@ static void Validation_Skins(void)
if (percent > cls.allow_fbskins*100)
percent = cls.allow_fbskins*100;
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)
Cbuf_AddText("say luma textures only\n", RESTRICT_LOCAL);
else
@ -390,6 +392,7 @@ rulesetrule_t rulesetrules_strict[] = {
{"ruleset_allow_modified_eyes", "0"},
{"ruleset_allow_sensative_texture_replacements", "0"},
{"ruleset_allow_localvolume", "0"},
{"ruleset_allow_fbmodels", "0"},
{"tp_disputablemacros", "0"},
{"cl_instantrotate", "0"},
{"v_projectionmode", "0"}, /*no extended fovs*/
@ -407,6 +410,7 @@ rulesetrule_t rulesetrules_nqr[] = {
{"ruleset_allow_sensative_texture_replacements", "0"},
{"ruleset_allow_localvolume", "0"},
{"ruleset_allow_shaders", "0"},
{"ruleset_allow_fbmodels", "0"},
{"r_vertexlight", "0"},
{"v_projectionmode", "0"},
{NULL}

View file

@ -1283,8 +1283,8 @@ void R_DrawNameTags(void)
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL)
{
// void GL_Set2D (void);
// GL_Set2D(false);
void GL_Set2D (qboolean flipped);
GL_Set2D(false);
}
#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);
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_GetPackNames(char *buffer, int buffersize, int referencedonly, qboolean ext);
void FS_ReferenceControl(unsigned int refflag, unsigned int resetflags);

View file

@ -587,7 +587,7 @@ char *FS_WhichPackForLocation(flocation_t *loc)
}
/*requires extension*/
qboolean FS_GetPackageDownloadable(char *package)
qboolean FS_GetPackageDownloadable(const char *package)
{
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);
}
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)
{
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)
{
int i;
@ -1235,6 +1241,116 @@ void PR_fclose_progs (progfuncs_t *prinst)
//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
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_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_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_break (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_crc16 (progfuncs_t *prinst, struct globalvars_s *pr_globals);

View file

@ -1,284 +1,312 @@
package com.fteqw;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import android.opengl.GLSurfaceView;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.hardware.SensorManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
public class FTEDroidActivity extends Activity
{
private SensorManager sensorman;
private Sensor sensoracc;
private FTEView view;
private class FTERenderer implements GLSurfaceView.Renderer
{
private boolean inited;
@Override
public void onDrawFrame(GL10 gl)
{
if (inited == true)
{
FTEDroidEngine.frame();
}
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
FTEDroidEngine.init(width, height);
inited = true;
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
}
}
private class FTEView extends GLSurfaceView implements SensorEventListener
{
private final FTERenderer rndr;
private byte[] audbuf;
private AudioTrack at;
private void audioInit()
{
final int notifframes = 2048;
if (at != null)
at.stop();
int sspeed = 11025;
int speakers = 1;
int sz = 4*AudioTrack.getMinBufferSize(sspeed, ((speakers==2)?AudioFormat.CHANNEL_CONFIGURATION_STEREO:AudioFormat.CHANNEL_CONFIGURATION_MONO), AudioFormat.ENCODING_PCM_16BIT);
if (sz < notifframes*2)
sz = notifframes*2;
at = new AudioTrack(AudioManager.STREAM_MUSIC, sspeed, ((speakers==2)?AudioFormat.CHANNEL_CONFIGURATION_STEREO:AudioFormat.CHANNEL_CONFIGURATION_MONO), AudioFormat.ENCODING_PCM_16BIT, sz, AudioTrack.MODE_STREAM);
final int framesz = 2; /*mono 16bit*/
audbuf = new byte[notifframes*framesz];
at.setPlaybackPositionUpdateListener(new AudioTrack.OnPlaybackPositionUpdateListener()
{
@Override
public void onMarkerReached(AudioTrack track)
{
}
@Override
public void onPeriodicNotification(AudioTrack track)
{
int avail = FTEDroidEngine.paintaudio(audbuf, audbuf.length);
at.write(audbuf, 0, notifframes*framesz);
}
});
at.setPositionNotificationPeriod(notifframes);
at.setStereoVolume(1, 1);
at.play();
/*buffer needs to be completely full before it'll start playing*/
while(sz > 0)
{
at.write(audbuf, 0, notifframes*framesz);
sz -= notifframes;
}
}
public void resume()
{
/*poke audio into submission*/
if (at != null)
at.play();
}
public FTEView(Context context)
{
super(context);
rndr = new FTERenderer();
setRenderer(rndr);
setFocusable(true);
setFocusableInTouchMode(true);
audioInit();
}
private void sendKey(final boolean presseddown, final int qcode, final int unicode)
{
queueEvent(new Runnable()
{
public void run()
{
FTEDroidEngine.keypress(presseddown?1:0, qcode, unicode);
}
});
}
private void sendAccelerometer(final float x, final float y, final float z)
{
queueEvent(new Runnable()
{
public void run()
{
FTEDroidEngine.accelerometer(x, y, z);
}
});
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
final int act = event.getAction();
final float x = event.getX();
final float y = event.getY();
//float p = event.getPressure();
queueEvent(new Runnable()
{
public void run()
{
switch(act)
{
case MotionEvent.ACTION_DOWN:
FTEDroidEngine.motion(1, x, y);
break;
case MotionEvent.ACTION_UP:
FTEDroidEngine.motion(2, x, y);
break;
case MotionEvent.ACTION_MOVE:
FTEDroidEngine.motion(0, x, y);
break;
}
}
});
return true;
}
/*
@Override
public boolean onTrackballEvent(MotionEvent event)
{
int act = event.getAction();
float x = event.getX();
float y = event.getY();
}
*/
private static final int K_UPARROW = 132;
private static final int K_DOWNARROW = 133;
private static final int K_LEFTARROW = 134;
private static final int K_RIGHTARROW = 135;
private int mapKey(int acode, int unicode)
{
switch(acode)
{
case KeyEvent.KEYCODE_DPAD_UP:
return K_UPARROW;
case KeyEvent.KEYCODE_DPAD_DOWN:
return K_DOWNARROW;
case KeyEvent.KEYCODE_DPAD_LEFT:
return K_LEFTARROW;
case KeyEvent.KEYCODE_DPAD_RIGHT:
return K_RIGHTARROW;
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
return '\r';
case KeyEvent.KEYCODE_BACK:
return 27;
case KeyEvent.KEYCODE_DEL:
return 127;
default:
if (unicode < 128)
return Character.toLowerCase(unicode);
}
return 0;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
int uc = event.getUnicodeChar();
sendKey(true, mapKey(keyCode, uc), uc);
return true;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event)
{
int uc = event.getUnicodeChar();
sendKey(false, mapKey(keyCode, uc), uc);
return true;
}
public void onAccuracyChanged(Sensor sensor, int accuracy)
{
}
private float gx,gy,gz;
public void onSensorChanged(final SensorEvent event)
{
// alpha is calculated as t / (t + dT)
// with t, the low-pass filter's time-constant
// and dT, the event delivery rate
final float alpha = 0.8f;
gx = alpha * gx + (1 - alpha) * event.values[0];
gy = alpha * gy + (1 - alpha) * event.values[1];
gz = alpha * gz + (1 - alpha) * event.values[2];
sendAccelerometer(event.values[0] - gx, event.values[1] - gy, event.values[2] - gz);
}
}
@Override
public void onCreate(Bundle savedInstanceState)
{
//go full-screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
view = new FTEView(this);
setContentView(view);
// setContentView(R.layout.main);
sensorman = (SensorManager)getSystemService(SENSOR_SERVICE);
sensoracc = sensorman.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
@Override
protected void onResume()
{
super.onResume();
sensorman.registerListener((SensorEventListener)view, sensoracc, SensorManager.SENSOR_DELAY_GAME);
view.resume();
}
@Override
protected void onStop()
{
sensorman.unregisterListener(view);
super.onStop();
}
@Override
protected void onPause()
{
sensorman.unregisterListener(view);
super.onPause();
}
}
package com.fteqw;
import javax.microedition.khronos.egl.EGLConfig;
//import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import android.opengl.GLSurfaceView;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.hardware.SensorManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
public class FTEDroidActivity extends Activity
{
private SensorManager sensorman;
private Sensor sensoracc;
private FTEView view;
private class FTERenderer implements GLSurfaceView.Renderer
{
private boolean inited;
@Override
public void onDrawFrame(GL10 gl)
{
if (inited == true)
{
FTEDroidEngine.frame();
}
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
FTEDroidEngine.init(width, height);
inited = true;
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
}
}
/*
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 final FTERenderer rndr;
private byte[] audbuf;
private AudioTrack at;
private void audioInit()
{
final int notifframes = 2048;
if (at != null)
at.stop();
int sspeed = 11025;
int speakers = 1;
int sz = 4*AudioTrack.getMinBufferSize(sspeed, ((speakers==2)?AudioFormat.CHANNEL_CONFIGURATION_STEREO:AudioFormat.CHANNEL_CONFIGURATION_MONO), AudioFormat.ENCODING_PCM_16BIT);
if (sz < notifframes*2)
sz = notifframes*2;
at = new AudioTrack(AudioManager.STREAM_MUSIC, sspeed, ((speakers==2)?AudioFormat.CHANNEL_CONFIGURATION_STEREO:AudioFormat.CHANNEL_CONFIGURATION_MONO), AudioFormat.ENCODING_PCM_16BIT, sz, AudioTrack.MODE_STREAM);
final int framesz = 2; /*mono 16bit*/
audbuf = new byte[notifframes*framesz];
at.setPlaybackPositionUpdateListener(new AudioTrack.OnPlaybackPositionUpdateListener()
{
@Override
public void onMarkerReached(AudioTrack track)
{
}
@Override
public void onPeriodicNotification(AudioTrack track)
{
int avail = FTEDroidEngine.paintaudio(audbuf, audbuf.length);
at.write(audbuf, 0, notifframes*framesz);
}
});
at.setPositionNotificationPeriod(notifframes);
at.setStereoVolume(1, 1);
at.play();
/*buffer needs to be completely full before it'll start playing*/
while(sz > 0)
{
at.write(audbuf, 0, notifframes*framesz);
sz -= notifframes;
}
}
public void resume()
{
/*poke audio into submission*/
if (at != null)
at.play();
}
public FTEView(Context context)
{
super(context);
rndr = new FTERenderer();
// setEGLConfigChooser(new FTEEGLConfig());
setRenderer(rndr);
setFocusable(true);
setFocusableInTouchMode(true);
audioInit();
}
private void sendKey(final boolean presseddown, final int qcode, final int unicode)
{
queueEvent(new Runnable()
{
public void run()
{
FTEDroidEngine.keypress(presseddown?1:0, qcode, unicode);
}
});
}
private void sendAccelerometer(final float x, final float y, final float z)
{
queueEvent(new Runnable()
{
public void run()
{
FTEDroidEngine.accelerometer(x, y, z);
}
});
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
final int act = event.getAction();
final float x = event.getX();
final float y = event.getY();
//float p = event.getPressure();
queueEvent(new Runnable()
{
public void run()
{
switch(act)
{
case MotionEvent.ACTION_DOWN:
FTEDroidEngine.motion(1, x, y);
break;
case MotionEvent.ACTION_UP:
FTEDroidEngine.motion(2, x, y);
break;
case MotionEvent.ACTION_MOVE:
FTEDroidEngine.motion(0, x, y);
break;
}
}
});
return true;
}
/*
@Override
public boolean onTrackballEvent(MotionEvent event)
{
int act = event.getAction();
float x = event.getX();
float y = event.getY();
}
*/
private static final int K_UPARROW = 132;
private static final int K_DOWNARROW = 133;
private static final int K_LEFTARROW = 134;
private static final int K_RIGHTARROW = 135;
private int mapKey(int acode, int unicode)
{
switch(acode)
{
case KeyEvent.KEYCODE_DPAD_UP:
return K_UPARROW;
case KeyEvent.KEYCODE_DPAD_DOWN:
return K_DOWNARROW;
case KeyEvent.KEYCODE_DPAD_LEFT:
return K_LEFTARROW;
case KeyEvent.KEYCODE_DPAD_RIGHT:
return K_RIGHTARROW;
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
return '\r';
case KeyEvent.KEYCODE_BACK:
return 27;
case KeyEvent.KEYCODE_DEL:
return 127;
default:
if (unicode < 128)
return Character.toLowerCase(unicode);
}
return 0;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
int uc = event.getUnicodeChar();
sendKey(true, mapKey(keyCode, uc), uc);
return true;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event)
{
int uc = event.getUnicodeChar();
sendKey(false, mapKey(keyCode, uc), uc);
return true;
}
public void onAccuracyChanged(Sensor sensor, int accuracy)
{
}
private float gx,gy,gz;
public void onSensorChanged(final SensorEvent event)
{
// alpha is calculated as t / (t + dT)
// with t, the low-pass filter's time-constant
// and dT, the event delivery rate
final float alpha = 0.8f;
gx = alpha * gx + (1 - alpha) * event.values[0];
gy = alpha * gy + (1 - alpha) * event.values[1];
gz = alpha * gz + (1 - alpha) * event.values[2];
sendAccelerometer(event.values[0] - gx, event.values[1] - gy, event.values[2] - gz);
}
}
@Override
public void onCreate(Bundle savedInstanceState)
{
//go full-screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
view = new FTEView(this);
setContentView(view);
// setContentView(R.layout.main);
sensorman = (SensorManager)getSystemService(SENSOR_SERVICE);
sensoracc = sensorman.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
@Override
protected void onResume()
{
super.onResume();
sensorman.registerListener((SensorEventListener)view, sensoracc, SensorManager.SENSOR_DELAY_GAME);
view.resume();
}
@Override
protected void onStop()
{
sensorman.unregisterListener(view);
super.onStop();
}
@Override
protected void onPause()
{
sensorman.unregisterListener(view);
super.onPause();
}
}

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;
@ -740,6 +740,13 @@ static qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel)
e->light_known = 2;
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))
{

View file

@ -566,6 +566,18 @@ model_t *RMod_LoadModel (model_t *mod, qboolean crash)
else if (!strcmp(mod->name, "progs/eyes.mdl"))
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
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_BOLT 0x080 // doesn't produce shadows
#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.
OP_ADD_SF, //(char*)c = (char*)a + (float)b
OP_SUB_S, //(float)c = (char*)a - (char*)b
OP_ADD_SF, //(char*)c = (char*)a + (float)b add_fi->i
OP_SUB_S, //(float)c = (char*)a - (char*)b sub_ii->f
OP_STOREP_C,//(float)c = *(char*)b = (float)a
OP_LOADP_C, //(float)c = *(char*)
//-------------------------------------

View file

@ -1649,6 +1649,8 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
ddef16_t *d16;
ddef32_t *d32;
func_t CheckSpawn=0;
void *oldglobals = NULL;
int oldglobalssize = 0;
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->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"))
{
@ -1906,6 +1916,21 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
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);
resethunk=true;
@ -2107,6 +2132,10 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
sv_num_edicts = numents;
}
if (oldglobals)
free(oldglobals);
oldglobals = NULL;
if (resethunk)
{
return entsize;
@ -2448,6 +2477,7 @@ retry:
current_progstate->statements = (void *)((qbyte *)pr_progs + pr_progs->ofs_statements);
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_types=NULL;

View file

@ -186,6 +186,7 @@ typedef struct progstate_s
void *statements;
// void *global_struct;
float *globals; // same as pr_global_struct
int globals_size; // in bytes
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);
QCC_PR_Expect("]");
/*if its a pointer that got dereferenced, follow the type*/
if (!idx && t->type == ev_pointer && !d->arraysize)
t = t->aux_type;
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)
{
@ -4332,6 +4341,8 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
else
tmp = QCC_PR_Statement(&pr_opcodes[OP_MUL_I], tmp, QCC_MakeIntConst(t->size), NULL);
}
/*calc the new index*/
if (idx)
idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], idx, QCC_SupplyConversion(tmp, ev_integer, true), NULL);
else
@ -4403,6 +4414,10 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
}
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]))
{
/*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:
QCC_PR_ParseError (ERR_INVALIDVECTORIMMEDIATE, "Bad character constant");
}
pr_file_p++;
if (*pr_file_p != '\'')
QCC_PR_ParseError (ERR_INVALIDVECTORIMMEDIATE, "Bad character constant");
pr_file_p++;

View file

@ -319,11 +319,13 @@ int QCC_CopyString (char *str)
int old;
char *s;
if (!str)
return 0;
if (!*str)
return 1;
if (opt_noduplicatestrings)
{
if (!str || !*str)
return 0;
for (s = strings; s < strings+strofs; s++)
if (!strcmp(s, str))
{
@ -488,7 +490,7 @@ void QCC_InitData (void)
qcc_sourcefile = NULL;
numstatements = 1;
strofs = 1;
strofs = 2;
numfunctions = 1;
numglobaldefs = 1;
numfielddefs = 1;
@ -784,7 +786,7 @@ pbool QCC_WriteData (int crc)
dd->s_name = QCC_CopyString (def->name);
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)
{
@ -2992,7 +2994,7 @@ void QCC_main (int argc, char **argv) //as part of the quake engine
QCC_PurgeTemps();
strings = (void *)qccHunkAlloc(sizeof(char) * MAX_STRINGS);
strofs = 1;
strofs = 2;
statements = (void *)qccHunkAlloc(sizeof(QCC_dstatement_t) * MAX_STATEMENTS);
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
{"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
{"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)"},
{"gettime", PF_Fixme, 0, 0, 0, 519, "float(optional float timetype)"},
// {"loadfromdata", VM_loadfromdata, 0, 0, 0, 529, "??" STUB},
// {"loadfromfile", VM_loadfromfile, 0, 0, 0, 530, "??" STUB},
{"loadfromdata", PF_loadfromdata, 0, 0, 0, 529, "void(string s)"},
{"loadfromfile", PF_loadfromfile, 0, 0, 0, 530, "void(string s)"},
// {"setpause", VM_SV_setpause, 0, 0, 0, 531, "void(float pause)" STUB},
//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_addtorque",PF_Ignore, 0, 0, 0, 542, "void(entity e, vector torque)" STUB},
//VM_callfunction, // #605
//VM_writetofile, // #606
//VM_isfunction, // #607
//VM_parseentitydata, // #613
{"callfunction", PF_callfunction, 0, 0, 0, 605, "void(.../*, string funcname*/)"},
{"writetofile", PF_writetofile, 0, 0, 0, 606, "void(float fh, entity e)"},
{"isfunction", PF_isfunction, 0, 0, 0, 607, "float(string s)"},
{"parseentitydata", PF_parseentitydata, 0, 0, 0, 608, "void(entity e, string s)"},
//VM_SV_getextresponse, // #624 string getextresponse(void)
{"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_APPEND", "const float", QW|NQ|CS, FRIK_FILE_APPEND},
{"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_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
// the rest of the file is sent directly to the progs engine.
Q_SetProgsParms(false);
PR_Configure(svprogfuncs, -1, MAX_PROGS);
PR_RegisterFields();
PR_InitEnts(svprogfuncs, sv.world.max_edicts);
/*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);
PR_Configure(svprogfuncs, -1, MAX_PROGS);
PR_RegisterFields();
PR_InitEnts(svprogfuncs, sv.world.max_edicts);
}
modelpos = VFS_TELL(f);
LoadModelsAndSounds(f);
@ -854,26 +857,29 @@ void SV_SaveLevelCache(char *savedir, qboolean dontharmgame)
VFS_PRINTF (f, "%i\n", CACHEGAME_VERSION);
SV_SavegameComment (comment);
VFS_PRINTF (f, "%s\n", comment);
for (cl = svs.clients, clnum=0; clnum < MAX_CLIENTS; cl++,clnum++)//fake dropping
if (!dontharmgame)
{
if ((cl->state < cs_spawned && !cl->istobeloaded) || dontharmgame) //don't drop if they are still connecting
for (cl = svs.clients, clnum=0; clnum < MAX_CLIENTS; cl++,clnum++)//fake dropping
{
continue;
}
else if (!cl->spectator)
{
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
sv.spawned_client_slots--;
}
else if (SpectatorDisconnect)
{
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
PR_ExecuteProgram (svprogfuncs, SpectatorDisconnect);
if (cl->state < cs_spawned && !cl->istobeloaded) //don't drop if they are still connecting
{
cl->edict->v->solid = 0;
}
else if (!cl->spectator)
{
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
sv.spawned_client_slots--;
}
else if (SpectatorDisconnect)
{
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
PR_ExecuteProgram (svprogfuncs, SpectatorDisconnect);
}
}
}
VFS_PRINTF (f, "%d\n", progstype);
@ -1053,13 +1059,14 @@ void SV_Savegame_f (void)
void SV_Loadgame_f (void)
{
levelcache_t *cache;
char str[MAX_LOCALINFO_STRING+1], *trim;
char savename[MAX_QPATH];
unsigned char str[MAX_LOCALINFO_STRING+1], *trim;
unsigned char savename[MAX_QPATH];
vfsfile_t *f;
char filename[MAX_OSPATH];
unsigned char filename[MAX_OSPATH];
int version;
int clnum;
int slots;
int loadzombies = 0;
client_t *cl;
gametype_e gametype;
@ -1130,6 +1137,7 @@ void SV_Loadgame_f (void)
cl->state = cs_zombie;
cl->connection_started = realtime+20;
cl->istobeloaded = true;
loadzombies++;
memset(&cl->netchan, 0, sizeof(cl->netchan));
for (len = 0; len < NUM_SPAWN_PARMS; len++)
@ -1237,6 +1245,7 @@ void SV_Loadgame_f (void)
SV_LoadLevelCache(savename, str, "", true);
sv.allocated_client_slots = slots;
sv.spawned_client_slots += loadzombies;
}
#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);
if (newcl->istobeloaded)
newcl->playerclass = newcl->edict->xv->playerclass;
// parse some info from the info strings
SV_ExtractFromUserinfo (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) {
SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTTIMEDOUT, cl->name);
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 &&
@ -3479,9 +3482,11 @@ void SV_CheckTimeouts (void)
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
sv.spawned_client_slots--;
host_client->istobeloaded=false;
cl->istobeloaded=false;
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;
int dupc = 1;
char newname[80], basic[80];
extern cvar_t rank_filename;
val = Info_ValueForKey (cl->userinfo, "team");
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)
{
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));
@ -4633,7 +4639,7 @@ void SV_ExtractFromUserinfo (client_t *cl)
#endif
#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");
#endif
}

View file

@ -1934,12 +1934,18 @@ void SV_UpdateToReliableMessages (void)
{
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);
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, i);
MSG_WriteString (&sv.reliable_datagram, "name");

View file

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