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:
parent
770948a320
commit
567e9f112b
31 changed files with 714 additions and 690 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -3280,8 +3280,6 @@ Sbar_FinaleOverlay
|
|||
*/
|
||||
void Sbar_FinaleOverlay (void)
|
||||
{
|
||||
mpic_t *pic;
|
||||
|
||||
#ifdef VM_UI
|
||||
if (UI_DrawFinale()>0)
|
||||
return;
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
//============================================================================
|
||||
/*
|
||||
|
|
|
@ -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*)
|
||||
//-------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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},
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue