From a77bd676021a2fd3e60c8ee82bfc9b96afd77456 Mon Sep 17 00:00:00 2001 From: Spoike Date: Tue, 12 Mar 2013 22:53:23 +0000 Subject: [PATCH] ------------------------------------------------------------------------ r4196 | acceptthis | 2013-02-12 19:06:07 +0000 (Tue, 12 Feb 2013) | 9 lines split in/out client frames, so that we can cope with separate packet/movement sequences for nq+prediction. Make default ports a little more explicit. interpolate input frames. should make things smoother when the input rate does not match video rate. fix centering of crosshairs make sure skins are flushed properly on vid_restart, so 24bit skins don't get messed up. keep sounds ticking even when inaudible. qc addressable block now has a max of 2gb. .__variant works as a function argument. NQ clients now receive player physics consistant with QuakeWorld. ------------------------------------------------------------------------ git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4194 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_cam.c | 8 +- engine/client/cl_cg.c | 2 +- engine/client/cl_demo.c | 7 +- engine/client/cl_ents.c | 149 ++++--- engine/client/cl_input.c | 131 +++--- engine/client/cl_main.c | 41 +- engine/client/cl_parse.c | 112 ++--- engine/client/cl_pred.c | 251 ++++++----- engine/client/cl_screen.c | 4 +- engine/client/cl_tent.c | 6 +- engine/client/cl_ui.c | 2 +- engine/client/client.h | 40 +- engine/client/clq2_ents.c | 5 +- engine/client/clq3_parse.c | 16 +- engine/client/in_win.c | 6 +- engine/client/m_items.c | 17 +- engine/client/menu.c | 8 +- engine/client/net_master.c | 8 +- engine/client/pr_csqc.c | 824 ++++++++++++++++++++----------------- engine/client/pr_menu.c | 331 ++++----------- engine/client/quakedef.h | 1 + engine/client/r_2d.c | 14 +- engine/client/renderer.c | 2 +- engine/client/sbar.c | 6 +- engine/client/screen.h | 2 + engine/client/skin.c | 13 + engine/client/snd_dma.c | 34 +- engine/client/snd_mix.c | 25 ++ engine/client/textedit.c | 22 +- engine/client/view.c | 2 +- engine/client/zqtp.c | 18 +- engine/common/cvar.h | 1 + engine/common/net.h | 2 +- engine/common/net_chan.c | 7 +- engine/common/net_wins.c | 22 +- engine/common/plugin.c | 35 +- engine/common/pmove.c | 10 +- engine/common/pr_bgcmd.c | 17 +- engine/common/pr_common.h | 16 +- engine/common/protocol.h | 5 +- engine/common/translate.c | 2 +- engine/gl/gl_font.c | 27 ++ engine/gl/gl_model.c | 3 + engine/gl/gl_screen.c | 2 +- engine/gl/gl_shadow.c | 11 +- engine/gl/gl_vidnt.c | 12 + engine/qclib/initlib.c | 121 +++--- engine/qclib/progsint.h | 6 +- engine/qclib/progslib.h | 2 +- engine/qclib/qcc_pr_comp.c | 3 + engine/server/pr_cmds.c | 60 +-- engine/server/server.h | 1 + engine/server/sv_ccmds.c | 2 +- engine/server/sv_ents.c | 26 +- engine/server/sv_init.c | 15 +- engine/server/sv_main.c | 55 ++- engine/server/sv_mvd.c | 4 +- engine/server/sv_phys.c | 29 +- engine/server/sv_send.c | 17 +- engine/server/sv_user.c | 65 ++- engine/server/svq2_ents.c | 2 +- 61 files changed, 1418 insertions(+), 1269 deletions(-) diff --git a/engine/client/cl_cam.c b/engine/client/cl_cam.c index e4d82c8f6..3bd23b65e 100644 --- a/engine/client/cl_cam.c +++ b/engine/client/cl_cam.c @@ -420,7 +420,7 @@ void Cam_SelfTrack(int pnum) void Cam_Track(int pnum, usercmd_t *cmd) { player_state_t *player, *self; - frame_t *frame; + inframe_t *frame; vec3_t vec; float len; @@ -443,7 +443,7 @@ void Cam_Track(int pnum, usercmd_t *cmd) return; } - frame = &cl.frames[cl.validsequence & UPDATE_MASK]; + frame = &cl.inframes[cl.validsequence & UPDATE_MASK]; player = frame->playerstate + spec_track[pnum]; self = frame->playerstate + cl.playernum[pnum]; @@ -517,7 +517,7 @@ void Cam_SetAutoTrack(int userid) void Cam_TrackCrosshairedPlayer(int pnum) { - frame_t *frame; + inframe_t *frame; player_state_t *player; int i; float dot = 0.1, bestdot=0; @@ -525,7 +525,7 @@ void Cam_TrackCrosshairedPlayer(int pnum) vec3_t selforg; vec3_t dir; - frame = &cl.frames[cl.validsequence & UPDATE_MASK]; + frame = &cl.inframes[cl.validsequence & UPDATE_MASK]; player = frame->playerstate + cl.playernum[pnum]; VectorCopy(player->origin, selforg); diff --git a/engine/client/cl_cg.c b/engine/client/cl_cg.c index bc64a08fe..ae32cad27 100644 --- a/engine/client/cl_cg.c +++ b/engine/client/cl_cg.c @@ -337,7 +337,7 @@ qboolean CGQ3_GetUserCmd(int cmdNumber, q3usercmd_t *ucmd) if (ccs.currentUserCmdNumber - cmdNumber > CMD_MASK) return false; // too old - cmd = &cl.frames[(cmdNumber) & CMD_MASK].cmd[0]; + cmd = &cl.outframes[(cmdNumber) & CMD_MASK].cmd[0]; ucmd->angles[0] = cmd->angles[0]; ucmd->angles[1] = cmd->angles[1]; ucmd->angles[2] = cmd->angles[2]; diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index 4ef752afb..c03f2bdbf 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -668,7 +668,7 @@ readnext: { // user sent input i = cls.netchan.outgoing_sequence & UPDATE_MASK; - pcmd = &cl.frames[i].cmd[0]; + pcmd = &cl.outframes[i].cmd[0]; r = readdemobytes (&demopos, &q1cmd, sizeof(q1cmd)); if (r != sizeof(q1cmd)) { @@ -690,9 +690,9 @@ readnext: pcmd->buttons = q1cmd.buttons; - cl.frames[i].senttime = demotime; - cl.frames[i].receivedtime = -1; // we haven't gotten a reply yet + cl.outframes[i].senttime = realtime; cls.netchan.outgoing_sequence++; + cl.movesequence = cls.netchan.outgoing_sequence; for (i=0 ; i<3 ; i++) { readdemobytes (&demopos, &f, 4); @@ -775,6 +775,7 @@ readit: } cls.netchan.outgoing_sequence = LittleLong(j); cls.netchan.incoming_sequence = LittleLong(i); + cl.movesequence = cls.netchan.outgoing_sequence; if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV) cls.netchan.incoming_acknowledged = cls.netchan.incoming_sequence; diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 6dd4c0e89..4fec0e7f2 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -464,7 +464,7 @@ void FlushEntityPacket (void) memset (&olde, 0, sizeof(olde)); cl.validsequence = 0; // can't render a frame - cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].invalid = true; + cl.inframes[cls.netchan.incoming_sequence&UPDATE_MASK].invalid = true; // read it all, but ignore it while (1) @@ -719,6 +719,7 @@ void CLFTE_ParseEntities(void) qboolean isvalid = false; entity_state_t *e; qboolean removeflag; + int inputframe = cls.netchan.incoming_sequence; // int i; // for (i = cl.validsequence+1; i < cls.netchan.incoming_sequence; i++) @@ -737,11 +738,10 @@ void CLFTE_ParseEntities(void) int i; for (i = 0; i < MAX_SPLITS; i++) cl.playerview[i].fixangle = false; - cls.netchan.outgoing_sequence = cls.netchan.incoming_unreliable; - cls.netchan.incoming_sequence = cls.netchan.outgoing_sequence; - cls.netchan.outgoing_sequence++; + cls.netchan.incoming_sequence = cls.netchan.incoming_unreliable; cl.last_servermessage = realtime; - cl.ackedinputsequence = MSG_ReadLong(); + if (cls.fteprotocolextensions2 & PEXT2_PREDINFO) + inputframe = MSG_ReadLong(); if (cl.numackframes == sizeof(cl.ackframes)/sizeof(cl.ackframes[0])) cl.numackframes--; @@ -750,7 +750,7 @@ void CLFTE_ParseEntities(void) else cl.ackframes[cl.numackframes++] = cls.netchan.incoming_sequence; - cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].receivedtime = realtime; + cl.inframes[cls.netchan.incoming_sequence&UPDATE_MASK].receivedtime = realtime; // if (cl.validsequence != cls.netchan.incoming_sequence-1) // Con_Printf("CLIENT: Dropped a frame\n"); @@ -759,9 +759,9 @@ void CLFTE_ParseEntities(void) newpacket = cls.netchan.incoming_sequence&UPDATE_MASK; oldpacket = cl.validsequence&UPDATE_MASK; - newp = &cl.frames[newpacket].packet_entities; - oldp = &cl.frames[oldpacket].packet_entities; - cl.frames[newpacket].invalid = true; + newp = &cl.inframes[newpacket].packet_entities; + oldp = &cl.inframes[oldpacket].packet_entities; + cl.inframes[newpacket].invalid = true; if (!cl.validsequence || cls.netchan.incoming_sequence-cl.validsequence >= UPDATE_BACKUP-1 || oldp == newp) @@ -874,8 +874,8 @@ void CLFTE_ParseEntities(void) /*update the prediction info if needed*/ // if (e->u.q1.pmovetype) { - frame_t *fram; - fram = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK]; + inframe_t *fram; + fram = &cl.inframes[cls.netchan.incoming_sequence & UPDATE_MASK]; CL_PlayerFrameUpdated(&fram->playerstate[e->number-1], e, cls.netchan.incoming_sequence); } } @@ -884,17 +884,14 @@ void CLFTE_ParseEntities(void) { cl.oldvalidsequence = cl.validsequence; cl.validsequence = cls.netchan.incoming_sequence; - cl.ackedinputsequence = cl.validsequence; - cl.frames[newpacket].invalid = false; + cl.ackedmovesequence = inputframe; + cl.inframes[newpacket].invalid = false; } else { newp->num_entities = 0; cl.validsequence = 0; } - - /*ackedinputsequence is updated when we have new player prediction info*/ - cl.ackedinputsequence = cls.netchan.incoming_sequence; } /* @@ -915,8 +912,8 @@ void CLQW_ParsePacketEntities (qboolean delta) int from; newpacket = cls.netchan.incoming_sequence&UPDATE_MASK; - newp = &cl.frames[newpacket].packet_entities; - cl.frames[newpacket].invalid = false; + newp = &cl.inframes[newpacket].packet_entities; + cl.inframes[newpacket].invalid = false; if (cls.protocol == CP_QUAKEWORLD && cls.demoplayback == DPB_MVD) { @@ -942,7 +939,7 @@ void CLQW_ParsePacketEntities (qboolean delta) // Con_Printf("%i %i from %i\n", cls.netchan.outgoing_sequence, cls.netchan.incoming_sequence, from); - oldpacket = cl.frames[newpacket].delta_sequence; + oldpacket = cl.inframes[newpacket].delta_sequence; if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV) from = oldpacket = cls.netchan.incoming_sequence - 1; @@ -970,7 +967,7 @@ void CLQW_ParsePacketEntities (qboolean delta) return; } - oldp = &cl.frames[oldpacket & UPDATE_MASK].packet_entities; + oldp = &cl.inframes[oldpacket & UPDATE_MASK].packet_entities; full = false; } else @@ -982,6 +979,7 @@ void CLQW_ParsePacketEntities (qboolean delta) cl.oldvalidsequence = cl.validsequence; cl.validsequence = cls.netchan.incoming_sequence; + cl.ackedmovesequence = cl.validsequence; oldindex = 0; newindex = 0; @@ -1130,7 +1128,7 @@ entity_state_t *CL_FindOldPacketEntity(int num) packet_entities_t *pack; if (!cl.validsequence) return NULL; - pack = &cl.frames[(cls.netchan.incoming_sequence-1)&UPDATE_MASK].packet_entities; + pack = &cl.inframes[(cls.netchan.incoming_sequence-1)&UPDATE_MASK].packet_entities; for (pnum=0 ; pnumnum_entities ; pnum++) { @@ -1300,10 +1298,10 @@ void CLDP_ParseDarkPlaces5Entities(void) //the things I do.. :o( cl.ackframes[cl.numackframes++] = MSG_ReadLong(); /*server sequence to be acked*/ if (cls.protocol_nq >= CPNQ_DP7) - cl.ackedinputsequence = MSG_ReadLong(); /*client input sequence which has been acked*/ + cl.ackedmovesequence = MSG_ReadLong(); /*client input sequence which has been acked*/ - cl.frames[(cls.netchan.incoming_sequence)&UPDATE_MASK].receivedtime = realtime; - pack = &cl.frames[(cls.netchan.incoming_sequence)&UPDATE_MASK].packet_entities; + cl.inframes[(cls.netchan.incoming_sequence)&UPDATE_MASK].receivedtime = realtime; + pack = &cl.inframes[(cls.netchan.incoming_sequence)&UPDATE_MASK].packet_entities; pack->servertime = cl.gametime; oldpack = *pack; oldi = 0; @@ -1428,7 +1426,7 @@ void CLNQ_ParseEntity(unsigned int bits) cls.signon = 4; CLNQ_SignonReply (); } - pack = &cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities; + pack = &cl.inframes[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities; if (bits & NQU_MOREBITS) @@ -1566,7 +1564,7 @@ entity_state_t *CL_FindPacketEntity(int num) int pnum; entity_state_t *s1; packet_entities_t *pack; - pack = &cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities; + pack = &cl.inframes[cl.validsequence&UPDATE_MASK].packet_entities; for (pnum=0 ; pnumnum_entities ; pnum++) { @@ -1625,10 +1623,10 @@ void CL_RotateAroundTag(entity_t *ent, int entnum, int parenttagent, int parentt } else { - org = cl.frames[parsecountmod].playerstate[parenttagent-1].origin; - ang = cl.frames[parsecountmod].playerstate[parenttagent-1].viewangles; + org = cl.inframes[parsecountmod].playerstate[parenttagent-1].origin; + ang = cl.inframes[parsecountmod].playerstate[parenttagent-1].viewangles; } - model = cl.frames[parsecountmod].playerstate[parenttagent-1].modelindex; + model = cl.inframes[parsecountmod].playerstate[parenttagent-1].modelindex; CL_LerpNetFrameState(FS_REG, &fstate, &cl.lerpplayers[parenttagent-1]); } @@ -2248,7 +2246,7 @@ void CLQ1_AddVisibleBBoxes(void) #endif case 3: { - frame_t *frame; + inframe_t *frame; packet_entities_t *pak; entity_state_t *state; model_t *mod; @@ -2262,7 +2260,7 @@ void CLQ1_AddVisibleBBoxes(void) "alphagen vertex\n" "}\n" "}\n"); - frame = &cl.frames[cl.parsecount & UPDATE_MASK]; + frame = &cl.inframes[cl.parsecount & UPDATE_MASK]; pak = &frame->packet_entities; for (i=0 ; inum_entities ; i++) @@ -2279,7 +2277,7 @@ void CLQ1_AddVisibleBBoxes(void) if (!cl.model_precache[state->modelindex]) continue; /*this makes non-inline bsp objects non-solid for prediction*/ - if ((*cl.model_precache[state->modelindex]->name == '*' || cl.model_precache[state->modelindex]->numsubmodels) && cl.model_precache[state->modelindex]->hulls[1].firstclipnode) + if ((cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) || ((*cl.model_precache[state->modelindex]->name == '*' || cl.model_precache[state->modelindex]->numsubmodels) && cl.model_precache[state->modelindex]->hulls[1].firstclipnode)) { mod = cl.model_precache[state->modelindex]; VectorAdd(state->origin, mod->mins, min); @@ -2882,23 +2880,23 @@ static qboolean CL_ChooseInterpolationFrames(int *newf, int *oldf, float servert //we should be picking the packet just after the server time, and the one just before for (i = cls.netchan.incoming_sequence; i >= cls.netchan.incoming_sequence-UPDATE_MASK; i--) { - if (cl.frames[i&UPDATE_MASK].receivedtime < 0 || cl.frames[i&UPDATE_MASK].invalid) + if (cl.inframes[i&UPDATE_MASK].receivedtime < 0 || cl.inframes[i&UPDATE_MASK].invalid) continue; //packetloss/choke, it's really only a problem for the oldframe, but... - if (cl.frames[i&UPDATE_MASK].packet_entities.servertime >= servertime) + if (cl.inframes[i&UPDATE_MASK].packet_entities.servertime >= servertime) { - if (cl.frames[i&UPDATE_MASK].packet_entities.servertime) + if (cl.inframes[i&UPDATE_MASK].packet_entities.servertime) { - if (!newtime || newtime != cl.frames[i&UPDATE_MASK].packet_entities.servertime) //if it's a duplicate, pick the latest (so just-shot rockets are still present) + if (!newtime || newtime != cl.inframes[i&UPDATE_MASK].packet_entities.servertime) //if it's a duplicate, pick the latest (so just-shot rockets are still present) { - newtime = cl.frames[i&UPDATE_MASK].packet_entities.servertime; + newtime = cl.inframes[i&UPDATE_MASK].packet_entities.servertime; *newf = i; } } } else if (newtime) { - if (cl.frames[i&UPDATE_MASK].packet_entities.servertime != newtime) + if (cl.inframes[i&UPDATE_MASK].packet_entities.servertime != newtime) { //it does actually lerp, and isn't an identical frame. *oldf = i; break; @@ -2917,7 +2915,7 @@ static qboolean CL_ChooseInterpolationFrames(int *newf, int *oldf, float servert /*just grab the most recent frame that is valid*/ for (i = cls.netchan.incoming_sequence; i >= cls.netchan.incoming_sequence-UPDATE_MASK; i--) { - if (cl.frames[i&UPDATE_MASK].receivedtime < 0 || cl.frames[i&UPDATE_MASK].invalid) + if (cl.inframes[i&UPDATE_MASK].receivedtime < 0 || cl.inframes[i&UPDATE_MASK].invalid) continue; //packetloss/choke, it's really only a problem for the oldframe, but... *oldf = *newf = i; return true; @@ -2943,7 +2941,7 @@ qboolean CL_MayLerp(void) if (cls.protocol == CP_NETQUAKE) //this includes DP protocols. return !cl_nolerp_netquake.ival; #endif - if (cl_nolerp.ival == 2 && cls.gamemode != GAME_DEATHMATCH) + if (cl_nolerp.ival == 2 && !cls.deathmatch) return true; return !cl_nolerp.ival; } @@ -2967,7 +2965,7 @@ void CL_TransitionEntities (void) //force our emulated time to as late as we can, if we're not using interpolation, which has the effect of disabling all interpolation if (nolerp) - servertime = cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities.servertime; + servertime = cl.inframes[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities.servertime; else servertime = cl.servertime; @@ -2981,8 +2979,8 @@ void CL_TransitionEntities (void) newf&=UPDATE_MASK; oldf&=UPDATE_MASK; /*transition the ents and stuff*/ - packnew = &cl.frames[newf].packet_entities; - packold = &cl.frames[oldf].packet_entities; + packnew = &cl.inframes[newf].packet_entities; + packold = &cl.inframes[oldf].packet_entities; // Con_Printf("%f %f %f (%i)\n", packold->servertime, servertime, packnew->servertime, newff); // Con_Printf("%f %f %f\n", cl.oldgametime, servertime, cl.gametime); @@ -3009,8 +3007,8 @@ void CL_TransitionEntities (void) frac = 1; //lerp totally into the new else frac = (servertime-packold->servertime)/(packnew->servertime-packold->servertime); - pnew = &cl.frames[newf].playerstate[0]; - pold = &cl.frames[oldf].playerstate[0]; + pnew = &cl.inframes[newf].playerstate[0]; + pold = &cl.inframes[oldf].playerstate[0]; for (p = 0; p < cl.allocated_client_slots; p++, pnew++, pold++) { if (pnew->messagenum != newff) @@ -3152,7 +3150,7 @@ void CL_LinkPacketEntities (void) if (radius) { radius += r_lightflicker.value?((flicker + state->number)&31):0; - CL_NewDlight(state->number, state->origin, radius, 0.1, colour[0], colour[1], colour[2]); + CL_NewDlight(state->number, ent->origin, radius, 0.1, colour[0], colour[1], colour[2]); } } if (state->lightpflags & PFLAGS_FULLDYNAMIC) @@ -3168,7 +3166,7 @@ void CL_LinkPacketEntities (void) colour[1] = state->light[1]/1024.0f; colour[2] = state->light[2]/1024.0f; } - dl = CL_NewDlight(state->number, state->origin, state->light[3]?state->light[3]:350, 0.1, colour[0], colour[1], colour[2]); + dl = CL_NewDlight(state->number, ent->origin, state->light[3]?state->light[3]:350, 0.1, colour[0], colour[1], colour[2]); dl->corona = (state->lightpflags & PFLAGS_CORONA)?1:0; dl->coronascale = 0.25; dl->flags &= ~LFLAG_FLASHBLEND; @@ -3208,7 +3206,7 @@ void CL_LinkPacketEntities (void) if (cl.model_precache_vwep[0]) { - if (state->modelindex == cl_playerindex) + if (state->modelindex == cl_playerindex && !cl.model_precache_vwep[0]->needload) { model = cl.model_precache_vwep[0]; model2 = cl.model_precache_vwep[state->modelindex2]; @@ -3622,8 +3620,8 @@ void CL_MVDUpdateSpectator(void) 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 = &cl.inframes[cl.parsecount & UPDATE_MASK].playerstate[cl.playernum[s]]; + oldself = &cl.inframes[(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; @@ -3654,8 +3652,8 @@ void CL_ParsePlayerinfo (void) info = &cl.players[num]; - oldstate = &cl.frames[oldparsecountmod].playerstate[num]; - state = &cl.frames[parsecountmod].playerstate[num]; + oldstate = &cl.inframes[oldparsecountmod].playerstate[num]; + state = &cl.inframes[parsecountmod].playerstate[num]; if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV) { @@ -3667,7 +3665,7 @@ void CL_ParsePlayerinfo (void) } else { - prevstate = &cl.frames[info->prevcount & UPDATE_MASK].playerstate[num]; + prevstate = &cl.inframes[info->prevcount & UPDATE_MASK].playerstate[num]; } memcpy(state, prevstate, sizeof(player_state_t)); info->prevcount = cl.parsecount; @@ -3699,7 +3697,7 @@ void CL_ParsePlayerinfo (void) } VectorSubtract(state->origin, prevstate->origin, dist); - VectorScale(dist, 1/(cl.frames[parsecountmod].packet_entities.servertime - cl.frames[oldparsecountmod].packet_entities.servertime), state->velocity); + VectorScale(dist, 1/(cl.inframes[parsecountmod].packet_entities.servertime - cl.inframes[oldparsecountmod].packet_entities.servertime), state->velocity); VectorCopy (state->origin, state->predorigin); for (i = 0; i < 3; i++) @@ -3976,7 +3974,7 @@ guess_pm_type: //can't CL_SetStatInt as we don't know if its actually us or not for (i = 0; i < cl.splitclients; i++) { - if (spec_track[i] == num) + if ((cl.spectator?spec_track[i]:cl.playernum[i]) == num) { cl.playerview[i].stats[STAT_WEAPONFRAME] = state->weaponframe; cl.playerview[i].statsf[STAT_WEAPONFRAME] = state->weaponframe; @@ -4123,8 +4121,8 @@ void CL_LinkPlayers (void) double playertime; entity_t *ent; int msec; - frame_t *frame; - frame_t *fromf; + inframe_t *frame; + inframe_t *fromf; int oldphysent; vec3_t angles; qboolean predictplayers; @@ -4141,8 +4139,8 @@ void CL_LinkPlayers (void) if (playertime > realtime) playertime = realtime; - frame = &cl.frames[cl.validsequence&UPDATE_MASK]; - fromf = &cl.frames[cl.oldvalidsequence&UPDATE_MASK]; + frame = &cl.inframes[cl.validsequence&UPDATE_MASK]; + fromf = &cl.inframes[cl.oldvalidsequence&UPDATE_MASK]; predictplayers = cl_predict_players.ival; if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV) @@ -4510,7 +4508,7 @@ void CL_LinkViewModel(void) plnum = Cam_TrackNum(r_refdef.currentplayernum); if (plnum == -1) plnum = cl.playernum[r_refdef.currentplayernum]; - plstate = &cl.frames[parsecountmod].playerstate[plnum]; + plstate = &cl.inframes[parsecountmod].playerstate[plnum]; CLQ1_AddPowerupShell(V_AddEntity(&ent), true, plstate?plstate->effects:0); @@ -4548,7 +4546,7 @@ Builds all the pmove physents for the current frame void CL_SetSolidEntities (void) { int i; - frame_t *frame; + inframe_t *frame; packet_entities_t *pak; entity_state_t *state; physent_t *pent; @@ -4559,7 +4557,7 @@ void CL_SetSolidEntities (void) pmove.physents[0].info = 0; pmove.numphysent = 1; - frame = &cl.frames[parsecountmod]; + frame = &cl.inframes[parsecountmod]; pak = &frame->packet_entities; for (i=0 ; inum_entities ; i++) @@ -4575,17 +4573,18 @@ void CL_SetSolidEntities (void) continue; if (!cl.model_precache[state->modelindex]) continue; - /*this makes non-inline bsp objects non-solid for prediction*/ - if ((*cl.model_precache[state->modelindex]->name == '*' || cl.model_precache[state->modelindex]->numsubmodels) && cl.model_precache[state->modelindex]->hulls[1].firstclipnode) - { - pent = &pmove.physents[pmove.numphysent]; - memset(pent, 0, sizeof(physent_t)); - pent->model = cl.model_precache[state->modelindex]; - VectorCopy (state->angles, pent->angles); - pent->angles[0]*=-1; - } - else + /*vanilla protocols have no 'solid' information. all entities get assigned ES_SOLID_BSP, even if its not actually solid. + so we need to make sure that item pickups are not erroneously considered solid, but doors etc are. + yes, this probably means that externally loaded models will be predicted non-solid - you'll need to upgrade your network protocol for the gamecode to be able to specify solidity. + */ + if (!(cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) && !((*cl.model_precache[state->modelindex]->name == '*' || cl.model_precache[state->modelindex]->numsubmodels) && cl.model_precache[state->modelindex]->hulls[1].firstclipnode)) continue; + + pent = &pmove.physents[pmove.numphysent]; + memset(pent, 0, sizeof(physent_t)); + pent->model = cl.model_precache[state->modelindex]; + VectorCopy (state->angles, pent->angles); + pent->angles[0]*=-1; } else { @@ -4649,7 +4648,7 @@ void CL_SetUpPlayerPrediction(qboolean dopred) player_state_t exact; double playertime; int msec; - frame_t *frame; + inframe_t *frame; struct predicted_player *pplayer; extern cvar_t cl_nopred; float predictmsmult = 1000*cl_predict_players_frac.value; @@ -4663,7 +4662,7 @@ void CL_SetUpPlayerPrediction(qboolean dopred) if (cl_nopred.value || /*cls.demoplayback ||*/ cl.paused || cl.worldmodel->needload) return; - frame = &cl.frames[cl.parsecount&UPDATE_MASK]; + frame = &cl.inframes[cl.parsecount&UPDATE_MASK]; for (j=0, pplayer = predicted_players, state=frame->playerstate; j < MAX_CLIENTS; @@ -4687,7 +4686,7 @@ void CL_SetUpPlayerPrediction(qboolean dopred) { if (j == cl.playernum[s]) { - VectorCopy(cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].playerstate[cl.playernum[s]].origin, + VectorCopy(cl.inframes[cls.netchan.outgoing_sequence&UPDATE_MASK].playerstate[cl.playernum[s]].origin, pplayer->origin); break; } diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index 21d1fe29c..201f86f0e 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -277,7 +277,7 @@ void IN_JumpDown (void) else #endif if (condition && cl.playerview[pnum].stats[STAT_HEALTH] > 0 && !cls.demoplayback && !cl.spectator && - cl.frames[cl.validsequence&UPDATE_MASK].playerstate[cl.playernum[pnum]].messagenum == cl.validsequence && cl.waterlevel[pnum] >= 2 && (!cl.teamfortress || !(in_forward.state[pnum] & 1)) + cl.inframes[cl.validsequence&UPDATE_MASK].playerstate[cl.playernum[pnum]].messagenum == cl.validsequence && cl.waterlevel[pnum] >= 2 && (!cl.teamfortress || !(in_forward.state[pnum] & 1)) ) KeyDown(&in_up); else if (condition && cl.spectator && Cam_TrackNum(pnum) == -1) @@ -804,7 +804,7 @@ void CL_FinishMove (usercmd_t *cmd, int msecs, int pnum) // always dump the first two message, because it may contain leftover inputs // from the last level // - if (++cl.movemessages <= 2) + if (cl.movesequence <= 2) { cmd->buttons = 0; return; @@ -923,16 +923,13 @@ void CLNQ_SendMove (usercmd_t *cmd, int pnum, sizebuf_t *buf) { int i; - vec3_t cursor_start, cursor_impact; - int cursor_entitynumber=0;//I hate warnings as errors - if (cls.demoplayback!=DPB_NONE) return; //err... don't bother... :) // // always dump the first two message, because it may contain leftover inputs // from the last level // - if (++cl.movemessages <= 2 || cls.state == ca_connected) + if (cl.movesequence <= 2 || cls.state == ca_connected) { MSG_WriteByte (buf, clc_nop); return; @@ -940,8 +937,8 @@ void CLNQ_SendMove (usercmd_t *cmd, int pnum, sizebuf_t *buf) MSG_WriteByte (buf, clc_move); - if (cls.protocol_nq >= CPNQ_DP7) - MSG_WriteLong(buf, cls.netchan.outgoing_sequence); + if (cls.protocol_nq >= CPNQ_DP7 || (cls.fteprotocolextensions2 & PEXT2_PREDINFO)) + MSG_WriteLong(buf, cl.movesequence); MSG_WriteFloat (buf, cl.gametime); // so server can get ping times @@ -961,20 +958,15 @@ void CLNQ_SendMove (usercmd_t *cmd, int pnum, sizebuf_t *buf) MSG_WriteShort (buf, cmd->sidemove); MSG_WriteShort (buf, cmd->upmove); - if (cls.protocol_nq >= CPNQ_DP6) + if (cls.protocol_nq >= CPNQ_DP6 || (cls.fteprotocolextensions2 & PEXT2_PRYDONCURSOR)) { + vec3_t cursor_start, cursor_impact; + int cursor_entitynumber; + CL_UpdatePrydonCursor(cmd, cursor_screen, cursor_start, cursor_impact, &cursor_entitynumber); + MSG_WriteLong (buf, cmd->buttons); - } - else - MSG_WriteByte (buf, cmd->buttons); - - - MSG_WriteByte (buf, cmd->impulse); - - - if (cls.protocol_nq >= CPNQ_DP6) - { + MSG_WriteByte (buf, cmd->impulse); MSG_WriteShort (buf, cursor_screen[0] * 32767.0f); MSG_WriteShort (buf, cursor_screen[1] * 32767.0f); MSG_WriteFloat (buf, cursor_start[0]); @@ -985,6 +977,11 @@ void CLNQ_SendMove (usercmd_t *cmd, int pnum, sizebuf_t *buf) MSG_WriteFloat (buf, cursor_impact[2]); MSG_WriteEntity (buf, cursor_entitynumber); } + else + { + MSG_WriteByte (buf, cmd->buttons); + MSG_WriteByte (buf, cmd->impulse); + } } void Name_Callback(struct cvar_s *var, char *oldvalue) @@ -1001,14 +998,28 @@ void Name_Callback(struct cvar_s *var, char *oldvalue) void CLNQ_SendCmd(sizebuf_t *buf) { int i; + usercmd_t *cmd; -// if (cls.signon == 4) + i = cl.movesequence & UPDATE_MASK; + cl.outframes[i].senttime = realtime; + cmd = &cl.outframes[i].cmd[0]; + *cmd = independantphysics[0]; + cmd->lightlevel = 0; +#ifdef CSQC_DAT + CSQC_Input_Frame(0, cmd); +#endif + memset(&independantphysics[0], 0, sizeof(independantphysics[0])); + + + + //inputs are only sent once we receive an entity. + if (cls.signon == 4) { // send the unreliable message if (independantphysics[0].impulse && !cls.netchan.message.cursize) - CLNQ_SendMove (&independantphysics[0], 0, &cls.netchan.message); + CLNQ_SendMove (cmd, 0, &cls.netchan.message); else - CLNQ_SendMove (&independantphysics[0], 0, buf); + CLNQ_SendMove (cmd, 0, buf); } for (i = 0; i < cl.numackframes; i++) @@ -1017,8 +1028,6 @@ void CLNQ_SendCmd(sizebuf_t *buf) MSG_WriteLong(buf, cl.ackframes[i]); } cl.numackframes = 0; - - memset(&independantphysics[0], 0, sizeof(independantphysics[0])); } #else void Name_Callback(struct cvar_s *var, char *oldvalue) @@ -1287,7 +1296,7 @@ qboolean CL_WriteDeltas (int plnum, sizebuf_t *buf) i = (cls.netchan.outgoing_sequence-2) & UPDATE_MASK; - cmd = &cl.frames[i].cmd[plnum]; + cmd = &cl.outframes[i].cmd[plnum]; if (cl_c2sImpulseBackup.ival >= 2) dontdrop = dontdrop || cmd->impulse; MSG_WriteDeltaUsercmd (buf, &nullcmd, cmd); @@ -1296,21 +1305,21 @@ qboolean CL_WriteDeltas (int plnum, sizebuf_t *buf) i = (cls.netchan.outgoing_sequence-1) & UPDATE_MASK; if (cl_c2sImpulseBackup.ival >= 3) dontdrop = dontdrop || cmd->impulse; - cmd = &cl.frames[i].cmd[plnum]; + cmd = &cl.outframes[i].cmd[plnum]; MSG_WriteDeltaUsercmd (buf, oldcmd, cmd); oldcmd = cmd; i = (cls.netchan.outgoing_sequence) & UPDATE_MASK; if (cl_c2sImpulseBackup.ival >= 1) dontdrop = dontdrop || cmd->impulse; - cmd = &cl.frames[i].cmd[plnum]; + cmd = &cl.outframes[i].cmd[plnum]; MSG_WriteDeltaUsercmd (buf, oldcmd, cmd); return dontdrop; } #ifdef Q2CLIENT -qboolean CL_SendCmdQ2 (sizebuf_t *buf) +qboolean CLQ2_SendCmd (sizebuf_t *buf) { int seq_hash; qboolean dontdrop; @@ -1323,7 +1332,7 @@ qboolean CL_SendCmdQ2 (sizebuf_t *buf) // send this and the previous cmds in the message, so // if the last packet was dropped, it can be recovered i = cls.netchan.outgoing_sequence & UPDATE_MASK; - cmd = &cl.frames[i].cmd[0]; + cmd = &cl.outframes[i].cmd[0]; if (cls.resendinfo) { @@ -1349,13 +1358,12 @@ qboolean CL_SendCmdQ2 (sizebuf_t *buf) // msecs = msecs - (double)msecstouse; i = cls.netchan.outgoing_sequence & UPDATE_MASK; - cmd = &cl.frames[i].cmd[0]; + cmd = &cl.outframes[i].cmd[0]; *cmd = independantphysics[0]; cmd->lightlevel = lightlev; - cl.frames[i].senttime = realtime; - cl.frames[i].receivedtime = -1; // we haven't gotten a reply yet + cl.outframes[i].senttime = realtime; memset(&independantphysics[0], 0, sizeof(independantphysics[0])); if (cmd->buttons) @@ -1368,8 +1376,6 @@ qboolean CL_SendCmdQ2 (sizebuf_t *buf) buf->data + checksumIndex + 1, buf->cursize - checksumIndex - 1, seq_hash); - cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = -1; - if (cl.sendprespawn) buf->cursize = 0; //tastyspleen.net is alergic. @@ -1377,16 +1383,18 @@ qboolean CL_SendCmdQ2 (sizebuf_t *buf) } #endif -qboolean CL_SendCmdQW (sizebuf_t *buf) +qboolean CLQW_SendCmd (sizebuf_t *buf) { int seq_hash; qboolean dontdrop = false; usercmd_t *cmd; int checksumIndex, firstsize, plnum; int clientcount, lost; - int curframe = cls.netchan.outgoing_sequence & UPDATE_MASK; + int curframe; int st = buf->cursize; + cl.movesequence = cls.netchan.outgoing_sequence; //make sure its correct even over map changes. + curframe = cls.netchan.outgoing_sequence & UPDATE_MASK; seq_hash = cls.netchan.outgoing_sequence; // send this and the previous cmds in the message, so @@ -1399,7 +1407,7 @@ qboolean CL_SendCmdQW (sizebuf_t *buf) for (plnum = 0; plnumlightlevel = 0; @@ -1408,15 +1416,13 @@ qboolean CL_SendCmdQW (sizebuf_t *buf) #endif memset(&independantphysics[plnum], 0, sizeof(independantphysics[plnum])); } - cl.frames[curframe].senttime = realtime; - cl.frames[curframe].receivedtime = -1; // we haven't gotten a reply yet - + cl.outframes[curframe].senttime = realtime; if ((cls.fteprotocolextensions2 & PEXT2_PRYDONCURSOR) && (*cl_prydoncursor.string && cl_prydoncursor.ival >= 0) && cls.state == ca_active) { vec3_t cursor_start, cursor_impact; int cursor_entitynumber = 0; - cmd = &cl.frames[curframe].cmd[0]; + cmd = &cl.outframes[curframe].cmd[0]; CL_UpdatePrydonCursor(cmd, cursor_screen, cursor_start, cursor_impact, &cursor_entitynumber); MSG_WriteByte (buf, clc_prydoncursor); MSG_WriteShort(buf, cursor_screen[0] * 32767.0f); @@ -1445,7 +1451,7 @@ qboolean CL_SendCmdQW (sizebuf_t *buf) firstsize=0; for (plnum = 0; plnum= UPDATE_BACKUP-1) cl.validsequence = 0; + //delta_sequence is the _expected_ previous sequences, so is set before it arrives. if (cl.validsequence && !cl_nodelta.ival && cls.state == ca_active && !cls.demorecording) { - cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = cl.validsequence; + cl.inframes[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = cl.validsequence; MSG_WriteByte (buf, clc_delta); // Con_Printf("%i\n", cl.validsequence); MSG_WriteByte (buf, cl.validsequence&255); } else - cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = -1; + cl.inframes[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = -1; if (cl.sendprespawn) buf->cursize = st; //tastyspleen.net is alergic. @@ -1515,10 +1522,11 @@ void CL_SendCmd (double frametime, qboolean mainloop) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV) { extern cvar_t cl_splitscreen; - cl.ackedinputsequence = cls.netchan.outgoing_sequence; - 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.ackedmovesequence = cl.movesequence; + i = cl.movesequence & UPDATE_MASK; + cl.movesequence++; + cl.outframes[i].senttime = realtime; // we haven't gotten a reply yet +// cl.outframes[i].receivedtime = -1; // we haven't gotten a reply yet if (cl.splitclients > cl_splitscreen.ival+1) { @@ -1528,7 +1536,7 @@ void CL_SendCmd (double frametime, qboolean mainloop) } for (plnum = 0; plnum < cl.splitclients; plnum++) { - cmd = &cl.frames[i].cmd[plnum]; + cmd = &cl.outframes[i].cmd[plnum]; memset(cmd, 0, sizeof(*cmd)); msecs += frametime*1000; @@ -1567,7 +1575,7 @@ void CL_SendCmd (double frametime, qboolean mainloop) clientcmdlist = next; } - cls.netchan.outgoing_sequence++; + cls.netchan.outgoing_sequence = cl.movesequence; } IN_Move (NULL, 0); @@ -1721,26 +1729,17 @@ void CL_SendCmd (double frametime, qboolean mainloop) #ifdef NQPROT case CP_NETQUAKE: msecs -= (double)msecstouse; - i = cls.netchan.outgoing_sequence & UPDATE_MASK; - cmd = &cl.frames[i].cmd[0]; - *cmd = independantphysics[0]; - cl.frames[i].senttime = realtime; - cl.frames[i].receivedtime = -1; // nq doesn't allow us to find our own packetloss - -#ifdef CSQC_DAT - CSQC_Input_Frame(0, cmd); -#endif CLNQ_SendCmd (&buf); break; #endif case CP_QUAKEWORLD: msecs -= (double)msecstouse; - dontdrop = CL_SendCmdQW (&buf); + dontdrop = CLQW_SendCmd (&buf); break; #ifdef Q2CLIENT case CP_QUAKE2: msecs -= (double)msecstouse; - dontdrop = CL_SendCmdQ2 (&buf); + dontdrop = CLQ2_SendCmd (&buf); break; #endif #ifdef Q3CLIENT @@ -1755,12 +1754,14 @@ void CL_SendCmd (double frametime, qboolean mainloop) } } - i = (cls.netchan.outgoing_sequence) & UPDATE_MASK; - cmd = &cl.frames[i].cmd[0]; + i = cl.movesequence & UPDATE_MASK; + cmd = &cl.outframes[i].cmd[0]; if (cls.demorecording) CL_WriteDemoCmd(cmd); + cl.movesequence++; + #ifdef IRCCONNECT if (cls.netchan.remote_address.type == NA_IRC) { @@ -1771,7 +1772,7 @@ void CL_SendCmd (double frametime, qboolean mainloop) else { // don't count this message when calculating PL - cl.frames[i].receivedtime = -3; + cl.inframes[i].latency = -3; // drop this message cls.netchan.outgoing_sequence++; dropcount++; @@ -1801,7 +1802,7 @@ void CL_SendCmd (double frametime, qboolean mainloop) else { // don't count this message when calculating PL - cl.frames[i].receivedtime = -3; + cl.inframes[i].latency = -3; // drop this message cls.netchan.outgoing_sequence++; dropcount++; diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index a1a300bad..62b6ef80e 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -476,7 +476,7 @@ void CL_SendConnectPacket (int mtu, t1 = Sys_DoubleTime (); - if (!NET_StringToAdr (cls.servername, &adr)) + if (!NET_StringToAdr (cls.servername, PORT_QWSERVER, &adr)) { Con_TPrintf (TLC_BADSERVERADDRESS); connect_time = -1; @@ -493,8 +493,6 @@ void CL_SendConnectPacket (int mtu, return; } - if (adr.port == 0) - adr.port = BigShort (PORT_QWSERVER); t2 = Sys_DoubleTime (); cls.resendinfo = false; @@ -651,7 +649,7 @@ void CL_CheckForResend (void) break; #endif default: - cl.movemessages = 0; + cl.movesequence = 0; if (!strcmp(cl_loopbackprotocol.string, "qw")) cls.protocol = CP_QUAKEWORLD; else if (!strcmp(cl_loopbackprotocol.string, "fitz")) //actually proquake, because we might as well use the extra angles @@ -692,7 +690,7 @@ void CL_CheckForResend (void) if (cls.protocol == CP_NETQUAKE) { - if (!NET_StringToAdr (cls.servername, &adr)) + if (!NET_StringToAdr (cls.servername, connect_defaultport, &adr)) { Con_TPrintf (TLC_BADSERVERADDRESS); connect_time = -1; @@ -762,7 +760,7 @@ void CL_CheckForResend (void) return; t1 = Sys_DoubleTime (); - if (!NET_StringToAdr (cls.servername, &adr)) + if (!NET_StringToAdr (cls.servername, connect_defaultport, &adr)) { Con_TPrintf (TLC_BADSERVERADDRESS); connect_time = -1; @@ -777,15 +775,6 @@ void CL_CheckForResend (void) return; } - if (adr.port == 0) - { - adr.port = BigShort (connect_defaultport); //assume a different port for nq - - if (!strchr(cls.servername, ':')) - { - Q_strncatz(cls.servername, va(":%u", connect_defaultport), sizeof(cls.servername)); - } - } t2 = Sys_DoubleTime (); connect_time = realtime+t2-t1; // for retransmit requests @@ -1064,9 +1053,7 @@ void CL_Rcon_f (void) return; } - NET_StringToAdr (rcon_address.string, &to); - if (!to.port) - to.port = PORT_QWSERVER; + NET_StringToAdr (rcon_address.string, PORT_QWSERVER, &to); } NET_SendPacket (NS_CLIENT, strlen(message)+1, message @@ -1129,10 +1116,10 @@ void CL_ClearState (void) for (i = 0; i < UPDATE_BACKUP; i++) { - if (cl.frames[i].packet_entities.entities) + if (cl.inframes[i].packet_entities.entities) { - Z_Free(cl.frames[i].packet_entities.entities); - cl.frames[i].packet_entities.entities = NULL; + Z_Free(cl.inframes[i].packet_entities.entities); + cl.inframes[i].packet_entities.entities = NULL; } } @@ -1325,6 +1312,9 @@ void CL_Disconnect (void) Cvar_ForceSet(&cl_servername, "none"); CL_ClearState(); + + //now start up the csqc/menu module again. + CSQC_UnconnectedInit(); } #undef serverrunning @@ -1627,10 +1617,7 @@ void CL_CheckServerInfo(void) if (cls.maxfps < 20) cls.maxfps = 72; - if (!atoi(Info_ValueForKey(cl.serverinfo, "deathmatch"))) - cls.gamemode = GAME_COOP; - else - cls.gamemode = GAME_DEATHMATCH; + cls.deathmatch = atoi(Info_ValueForKey(cl.serverinfo, "deathmatch")); cls.z_ext = atoi(Info_ValueForKey(cl.serverinfo, "*z_ext")); @@ -1926,7 +1913,7 @@ void CL_Packet_f (void) return; } - if (!NET_StringToAdr (Cmd_Argv(1), &adr)) + if (!NET_StringToAdr (Cmd_Argv(1), PORT_QWSERVER, &adr)) { Con_Printf ("Bad address: %s\n", Cmd_Argv(1)); return; @@ -2780,7 +2767,7 @@ void CL_ReadPackets (void) case NQP_ERROR: break; case NQP_DATAGRAM://datagram - cls.netchan.incoming_sequence = cls.netchan.outgoing_sequence - 3; +// cls.netchan.incoming_sequence = cls.netchan.outgoing_sequence - 3; case NQP_RELIABLE://reliable MSG_ChangePrimitives(cls.netchan.netprim); CLNQ_ParseServerMessage (); diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 457258764..e215cbd41 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -315,26 +315,28 @@ int packet_latency[NET_TIMINGS]; int CL_CalcNet (void) { - int a, i; - frame_t *frame; - int lost; + int i; + inframe_t *frame; + int lost = 0; int percent; int sent; - int pending; // char st[80]; sent = NET_TIMINGS; for (i=cls.netchan.outgoing_sequence-UPDATE_BACKUP+1 - ; i <= cls.netchan.outgoing_sequence + ; i <= (cl_countpendingpl.ival?cls.netchan.outgoing_sequence:cl.parsecount) ; i++) { - frame = &cl.frames[i&UPDATE_MASK]; - if (frame->receivedtime == -1) + frame = &cl.inframes[i&UPDATE_MASK]; + if (frame->latency == -1) + { packet_latency[i&NET_TIMINGSMASK] = 9999; // dropped - else if (frame->receivedtime == -2) + lost++; + } + else if (frame->latency == -2) packet_latency[i&NET_TIMINGSMASK] = 10000; // choked - else if (frame->receivedtime == -3) + else if (frame->latency == -3) { packet_latency[i&NET_TIMINGSMASK] = 9997; // c2spps sent--; @@ -342,38 +344,13 @@ int CL_CalcNet (void) else if (frame->invalid) packet_latency[i&NET_TIMINGSMASK] = 9998; // invalid delta else - packet_latency[i&NET_TIMINGSMASK] = (frame->receivedtime - frame->senttime)*60; + packet_latency[i&NET_TIMINGSMASK] = frame->latency * 60; } - lost = 0; - for (a=0 ; asenttime = realtime - host_frametime; - parsecounttime = cl.frames[i].senttime; - - frame->receivedtime = realtime; - //(cl.gametimemark - cl.oldgametimemark)*20; + frame = &cl.inframes[i]; +// if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV) +// frame->senttime = realtime - host_frametime; + parsecounttime = cl.outframes[i].senttime; // calculate latency - latency = frame->receivedtime - frame->senttime; + frame->latency = realtime - parsecounttime; - if (latency < 0 || latency > 1.0) + if (frame->latency < 0 || frame->latency > 1.0) { // Con_Printf ("Odd latency: %5.2f\n", latency); } else { // drift the average latency towards the observed latency - if (latency < cls.latency) - cls.latency = latency; + if (frame->latency < cls.latency) + cls.latency = frame->latency; else cls.latency += 0.001; // drift up, so correction are needed } @@ -4313,7 +4283,7 @@ void CL_MuzzleFlash (int destsplit) if (i-1 == cl.playernum[destsplit] && cl_muzzleflash.value == 2) return; - pack = &cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities; + pack = &cl.inframes[cl.validsequence&UPDATE_MASK].packet_entities; for (pnum=0 ; pnumnum_entities ; pnum++) //try looking for an entity with that id first { @@ -4331,7 +4301,7 @@ void CL_MuzzleFlash (int destsplit) { //that ent number doesn't exist, go for a player with that number if ((unsigned)(i) <= MAX_CLIENTS && i > 0) { - pl = &cl.frames[parsecountmod].playerstate[i-1]; + pl = &cl.inframes[cl.validsequence&UPDATE_MASK].playerstate[i-1]; dl = CL_AllocDlight (-i); VectorCopy (pl->origin, dl->origin); //set it's origin @@ -5664,7 +5634,7 @@ void CLQW_ParseServerMessage (void) case svc_chokecount: // some preceding packets were choked i = MSG_ReadByte (); for (j=0 ; ju.q1.movement[0]; cmd.sidemove = state->u.q1.movement[1]; @@ -886,28 +886,56 @@ qboolean CL_PredictPlayer(lerpents_t *le, entity_state_t *state, int sequence) CL_PredictMove ============== */ -void CL_PredictMovePNum (int pnum) +void CL_PredictMovePNum (int vnum) { - frame_t ind; + inframe_t indstate; + outframe_t indcmd; int i; float f; - frame_t *from, *to = NULL; + inframe_t *from, *to = NULL; + outframe_t *cmdfrom, *cmdto; int oldphysent; vec3_t lrp, lrpv; - + double simtime; + extern cvar_t cl_netfps; + //these are to make svc_viewentity work better float *vel; float *org; float stepheight = 0; + float netfps = cl_netfps.value; + if (!netfps) + { + //every video frame has its own input frame. + simtime = realtime; + } + else + { + netfps = bound(6.7, netfps, cls.maxfps); + if (netfps < 30) + { + //extrapolate if we've a low net rate. This should reduce apparent lag, but will be jerky if the net rate is not an (inverse) multiple of the monitor rate. + //this is in addition to any monitor desync. + simtime = realtime; + } + else + { + //interpolate. The input rate is completely smoothed out, at the cost of some latency. + //You can still get juddering if the video rate doesn't match the monitor refresh rate (and isn't so high that it doesn't matter). + //note that the code below will back-date input frames if the server acks too fast. + netfps = bound(6.7, netfps, cls.maxfps); + simtime = realtime - (1/netfps); + } + } - cl.nolocalplayer[pnum] = !!(cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS); + cl.nolocalplayer[vnum] = !!(cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) || (cls.protocol != CP_QUAKEWORLD); #ifdef Q2CLIENT if (cls.protocol == CP_QUAKE2) { if (!cl.worldmodel || cl.worldmodel->needload) return; - cl.crouch[pnum] = 0; + cl.crouch[vnum] = 0; CLQ2_PredictMovement(); return; } @@ -916,117 +944,121 @@ void CL_PredictMovePNum (int pnum) if (cl_pushlatency.value > 0) Cvar_Set (&cl_pushlatency, "0"); - if (cl.paused && !(cls.demoplayback!=DPB_MVD && cls.demoplayback!=DPB_EZTV) && (!cl.spectator || !autocam[pnum])) + if (cl.paused && !(cls.demoplayback!=DPB_MVD && cls.demoplayback!=DPB_EZTV) && (!cl.spectator || !autocam[vnum])) return; if (cl.intermission==1 && cls.protocol == CP_QUAKEWORLD) { - cl.crouch[pnum] = 0; + cl.crouch[vnum] = 0; return; } #ifdef NQPROT - if (cls.protocol == CP_NETQUAKE) + if (cls.protocol == CP_NETQUAKE && !(cls.fteprotocolextensions2 & PEXT2_PREDINFO)) { - cl.ackedinputsequence = cls.netchan.outgoing_sequence; + cl.ackedmovesequence = cl.movesequence; } #endif - if (!cl.ackedinputsequence) + if (!cl.validsequence) { return; } - if (cls.netchan.outgoing_sequence - cl.ackedinputsequence >= UPDATE_BACKUP-1) + if (cl.movesequence - cl.ackedmovesequence >= UPDATE_BACKUP-1) { //lagging like poo. if (!cl.intermission) //keep the angles working though. - VectorCopy (cl.playerview[pnum].viewangles, cl.playerview[pnum].simangles); + VectorCopy (cl.playerview[vnum].viewangles, cl.playerview[vnum].simangles); return; } // this is the last frame received from the server - from = &cl.frames[cl.ackedinputsequence & UPDATE_MASK]; + from = &cl.inframes[cl.validsequence & UPDATE_MASK]; + cmdfrom = &cl.outframes[cl.ackedmovesequence & UPDATE_MASK]; if (!cl.intermission) { - VectorCopy (cl.playerview[pnum].viewangles, cl.playerview[pnum].simangles); + VectorCopy (cl.playerview[vnum].viewangles, cl.playerview[vnum].simangles); } - vel = from->playerstate[cl.playernum[pnum]].velocity; - org = from->playerstate[cl.playernum[pnum]].origin; + vel = from->playerstate[cl.playernum[vnum]].velocity; + org = from->playerstate[cl.playernum[vnum]].origin; #ifdef PEXT_SETVIEW - if (cl.viewentity[pnum]) + if (cl.viewentity[vnum] && (cl.viewentity[vnum] != cl.playernum[vnum]+1 || cl.ackedmovesequence == cl.movesequence)) { - if (cl.viewentity[pnum] < cl.maxlerpents) + if (cl.viewentity[vnum] < cl.maxlerpents) { - cl.nolocalplayer[pnum] = true; + cl.nolocalplayer[vnum] = true; // Con_Printf("Using lerped pos\n"); - org = cl.lerpents[cl.viewentity[pnum]].origin; + org = cl.lerpents[cl.viewentity[vnum]].origin; vel = vec3_origin; goto fixedorg; } } #endif - if (!from->playerstate[cl.playernum[pnum]].messagenum) + if (!from->playerstate[cl.playernum[vnum]].messagenum) { //no player states?? put the view on an ent - if (cl.playernum[pnum] < cl.maxlerpents) + if (cl.playernum[vnum] < cl.maxlerpents) { - cl.nolocalplayer[pnum] = true; + cl.nolocalplayer[vnum] = true; // Con_Printf("Using lerped pos\n"); - org = cl.lerpents[cl.playernum[pnum]+1].origin; + org = cl.lerpents[cl.playernum[vnum]+1].origin; vel = vec3_origin; goto fixedorg; } } - if (((cl_nopred.value && cls.demoplayback!=DPB_MVD && cls.demoplayback != DPB_EZTV)|| cl.playerview[pnum].fixangle || cl.paused)) + if (((cl_nopred.value && cls.demoplayback!=DPB_MVD && cls.demoplayback != DPB_EZTV)|| cl.playerview[vnum].fixangle || cl.paused)) { if (cl_lerp_players.ival && !cls.demoplayback) { lerpents_t *le; - if (cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) - le = &cl.lerpents[spec_track[pnum]+1]; + if (cl.nolocalplayer[vnum]) + le = &cl.lerpents[spec_track[vnum]+1]; else - le = &cl.lerpplayers[spec_track[pnum]]; + le = &cl.lerpplayers[spec_track[vnum]]; org = le->origin; vel = vec3_origin; } fixedorg: - VectorCopy (vel, cl.playerview[pnum].simvel); - VectorCopy (org, cl.playerview[pnum].simorg); + VectorCopy (vel, cl.playerview[vnum].simvel); + VectorCopy (org, cl.playerview[vnum].simorg); - to = &cl.frames[cl.ackedinputsequence & UPDATE_MASK]; +// to = &cl.inframes[cl.ackedinputsequence & UPDATE_MASK]; - CL_CatagorizePosition(pnum); + CL_CatagorizePosition(vnum); goto out; } // predict forward until cl.time <= to->senttime oldphysent = pmove.numphysent; CL_SetSolidPlayers(); - pmove.skipent = cl.playernum[pnum]+1; + pmove.skipent = cl.playernum[vnum]+1; - to = &cl.frames[cl.ackedinputsequence & UPDATE_MASK]; +// Con_Printf("%i<%i %i\n", cl.ackedmovesequence, cl.movesequence, cl.validsequence); - if (Cam_TrackNum(pnum)>=0 && CL_MayLerp()) + to = &cl.inframes[cl.validsequence & UPDATE_MASK]; + cmdto = &cl.outframes[cl.ackedmovesequence & UPDATE_MASK]; + + if (Cam_TrackNum(vnum)>=0 && CL_MayLerp()) { float f; if (cl_lerp_players.ival && (cls.demoplayback==DPB_MVD || cls.demoplayback == DPB_EZTV)) { - lerpents_t *le = &cl.lerpplayers[spec_track[pnum]]; + lerpents_t *le = &cl.lerpplayers[spec_track[vnum]]; org = le->origin; vel = vec3_origin; - VectorCopy(le->angles, cl.playerview[pnum].simangles); + VectorCopy(le->angles, cl.playerview[vnum].simangles); goto fixedorg; } - to = &cl.frames[cl.validsequence & UPDATE_MASK]; - from = &cl.frames[cl.oldvalidsequence & UPDATE_MASK]; + to = &cl.inframes[cl.validsequence & UPDATE_MASK]; + from = &cl.inframes[cl.oldvalidsequence & UPDATE_MASK]; //figure out the lerp factor if (cl.gametime == cl.servertime) @@ -1046,118 +1078,139 @@ fixedorg: // calculate origin for (i=0 ; i<3 ; i++) { - lrp[i] = to->playerstate[spec_track[pnum]].origin[i] + - f * (from->playerstate[spec_track[pnum]].origin[i] - to->playerstate[spec_track[pnum]].origin[i]); + lrp[i] = to->playerstate[spec_track[vnum]].origin[i] + + f * (from->playerstate[spec_track[vnum]].origin[i] - to->playerstate[spec_track[vnum]].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]); + lrpv[i] = to->playerstate[spec_track[vnum]].velocity[i] + + f * (from->playerstate[spec_track[vnum]].velocity[i] - to->playerstate[spec_track[vnum]].velocity[i]); - cl.playerview[pnum].simangles[i] = LerpAngles16(to->playerstate[spec_track[pnum]].command.angles[i], from->playerstate[spec_track[pnum]].command.angles[i], f)*360.0f/65535; + cl.playerview[vnum].simangles[i] = LerpAngles16(to->playerstate[spec_track[vnum]].command.angles[i], from->playerstate[spec_track[vnum]].command.angles[i], f)*360.0f/65535; } org = lrp; vel = lrpv; - cl.pmovetype[pnum] = PM_NONE; + cl.pmovetype[vnum] = PM_NONE; goto fixedorg; } else { if (cls.demoplayback==DPB_MVD || cls.demoplayback==DPB_EZTV) { - to = &cl.frames[(cls.netchan.outgoing_sequence-1) & UPDATE_MASK]; + to = &cl.inframes[(cls.netchan.outgoing_sequence-1) & UPDATE_MASK]; + cmdto = &cl.outframes[(cl.movesequence-1) & UPDATE_MASK]; to->playerstate->pm_type = PM_SPECTATOR; - VectorCopy (cl.playerview[pnum].simvel, from->playerstate[cl.playernum[pnum]].velocity); - VectorCopy (cl.playerview[pnum].simorg, from->playerstate[cl.playernum[pnum]].origin); + VectorCopy (cl.playerview[vnum].simvel, from->playerstate[cl.playernum[vnum]].velocity); + VectorCopy (cl.playerview[vnum].simorg, from->playerstate[cl.playernum[vnum]].origin); - CL_PredictUsercmd (pnum, cl.playernum[pnum]+1, &from->playerstate[cl.playernum[pnum]], &to->playerstate[cl.playernum[pnum]], &to->cmd[pnum]); + CL_PredictUsercmd (vnum, cl.playernum[vnum]+1, &from->playerstate[cl.playernum[vnum]], &to->playerstate[cl.playernum[vnum]], &cmdto->cmd[vnum]); } else { - for (i=1 ; iplayerstate[cl.playernum[pnum]] - , &to->playerstate[cl.playernum[pnum]], &to->cmd[pnum]); + to = &cl.inframes[(cl.validsequence+i) & UPDATE_MASK]; + cmdto = &cl.outframes[(cl.ackedmovesequence+i) & UPDATE_MASK]; - if (to->senttime >= realtime) + CL_PredictUsercmd (vnum, cl.playernum[vnum]+1, &from->playerstate[cl.playernum[vnum]], &to->playerstate[cl.playernum[vnum]], &cmdto->cmd[vnum]); + + if (cmdto->senttime >= simtime) break; from = to; + cmdfrom = cmdto; } } - if (independantphysics[pnum].msec) + if (simtime > cmdto->senttime) { + float msec; + cmdfrom = cmdto; from = to; - to = &ind; - to->cmd[pnum] = independantphysics[pnum]; - to->senttime = realtime; - CL_PredictUsercmd (pnum, cl.playernum[pnum]+1, &from->playerstate[cl.playernum[pnum]] - , &to->playerstate[cl.playernum[pnum]], &to->cmd[pnum]); - } - cl.onground[pnum] = pmove.onground; - cl.pmovetype[pnum] = to->playerstate[cl.playernum[pnum]].pm_type; - stepheight = to->playerstate[cl.playernum[pnum]].origin[2] - from->playerstate[cl.playernum[pnum]].origin[2]; + to = &indstate; + cmdto = &indcmd; + if (independantphysics[vnum].msec && !cls.demoplayback) + cmdto->cmd[vnum] = independantphysics[vnum]; + else + cmdto->cmd[vnum] = cmdfrom->cmd[vnum]; + cmdto->senttime = simtime; + msec = ((cmdto->senttime - cmdfrom->senttime) * 1000) + 0.5; + cmdto->cmd[vnum].msec = bound(0, msec, 250); - if (cl.nolocalplayer[pnum] && cl.maxlerpents > cl.playernum[pnum]+1) - { - //keep the entity tracking the prediction position, so mirrors don't go all weird - VectorCopy(to->playerstate[cl.playernum[pnum]].origin, cl.lerpents[cl.playernum[pnum]+1].origin); - VectorScale(to->cmd[pnum].angles, 360.0f / 0xffff, cl.lerpents[cl.playernum[pnum]+1].angles); - cl.lerpents[cl.playernum[pnum]+1].angles[0] *= -0.333; + CL_PredictUsercmd (vnum, cl.playernum[vnum]+1, &from->playerstate[cl.playernum[vnum]] + , &to->playerstate[cl.playernum[vnum]], &cmdto->cmd[vnum]); } + cl.onground[vnum] = pmove.onground; + cl.pmovetype[vnum] = to->playerstate[cl.playernum[vnum]].pm_type; + stepheight = to->playerstate[cl.playernum[vnum]].origin[2] - from->playerstate[cl.playernum[vnum]].origin[2]; + } + + //backdate it if our simulation time is in the past. this will happen on localhost, but not on 300-ping servers. + for (i = 0; cmdfrom->senttime > simtime && i < 16; i++) + { + to = from; + cmdto = cmdfrom; + from = &cl.inframes[(cl.validsequence-i) & UPDATE_MASK]; + cmdfrom = &cl.outframes[(cl.ackedmovesequence-i) & UPDATE_MASK]; } pmove.numphysent = oldphysent; - if (1)//!independantphysics.msec) +// Con_Printf("%f %f %f\n", cmdfrom->senttime, simtime, cmdto->senttime); + if (cmdto->senttime == cmdfrom->senttime) { - VectorCopy (to->playerstate[cl.playernum[pnum]].velocity, cl.playerview[pnum].simvel); - VectorCopy (to->playerstate[cl.playernum[pnum]].origin, cl.playerview[pnum].simorg); + VectorCopy (to->playerstate[cl.playernum[vnum]].velocity, cl.playerview[vnum].simvel); + VectorCopy (to->playerstate[cl.playernum[vnum]].origin, cl.playerview[vnum].simorg); } else { + int pnum = cl.playernum[vnum]; // now interpolate some fraction of the final frame - if (to->senttime == from->senttime) - f = 0; - else - { - f = (realtime - from->senttime) / (to->senttime - from->senttime); + f = (simtime - cmdfrom->senttime) / (cmdto->senttime - cmdfrom->senttime); - if (f < 0) - f = 0; - if (f > 1) - f = 1; - } + if (f < 0) + f = 0; + if (f > 1) + f = 1; for (i=0 ; i<3 ; i++) - if ( fabs(org[i] - to->playerstate[cl.playernum[pnum]].origin[i]) > 128) + if ( fabs(from->playerstate[pnum].origin[i] - to->playerstate[pnum].origin[i]) > 128) { // teleported, so don't lerp - VectorCopy (to->playerstate[cl.playernum[pnum]].velocity, cl.playerview[pnum].simvel); - VectorCopy (to->playerstate[cl.playernum[pnum]].origin, cl.playerview[pnum].simorg); + VectorCopy (to->playerstate[pnum].velocity, cl.playerview[vnum].simvel); + VectorCopy (to->playerstate[pnum].origin, cl.playerview[vnum].simorg); goto out; } for (i=0 ; i<3 ; i++) { - cl.playerview[pnum].simorg[i] = org[i] - + f*(to->playerstate[cl.playernum[pnum]].origin[i] - org[i]); - cl.playerview[pnum].simvel[i] = vel[i] - + f*(to->playerstate[cl.playernum[pnum]].velocity[i] - vel[i]); + cl.playerview[vnum].simorg[i] = (1-f)*from->playerstate[pnum].origin[i] + f*to->playerstate[pnum].origin[i]; + cl.playerview[vnum].simvel[i] = (1-f)*from->playerstate[pnum].velocity[i] + f*to->playerstate[pnum].velocity[i]; + + if (cl.spectator) + cl.playerview[vnum].simangles[i] = LerpAngles16(from->playerstate[pnum].command.angles[i], to->playerstate[pnum].command.angles[i], f) * (360.0/65535); + else if (cls.demoplayback == DPB_QUAKEWORLD) + cl.playerview[vnum].simangles[i] = LerpAngles16(cmdfrom->cmd[vnum].angles[i], cmdto->cmd[vnum].angles[i], f) * (360.0/65535); } - CL_CatagorizePosition(pnum); + CL_CatagorizePosition(vnum); } + if (cl.nolocalplayer[vnum] && cl.maxlerpents > cl.playernum[vnum]+1) + { + //keep the entity tracking the prediction position, so mirrors don't go all weird + VectorCopy(to->playerstate[cl.playernum[vnum]].origin, cl.lerpents[cl.playernum[vnum]+1].origin); + VectorScale(cmdto->cmd[vnum].angles, 360.0f / 0xffff, cl.lerpents[cl.playernum[vnum]+1].angles); + cl.lerpents[cl.playernum[vnum]+1].angles[0] *= -0.333; + } + if (cls.demoplayback) - CL_LerpMove (pnum, to->senttime); + CL_LerpMove (vnum, cmdto->senttime); out: - CL_CalcCrouch (pnum, stepheight); - cl.waterlevel[pnum] = pmove.waterlevel; - VectorCopy(pmove.gravitydir, cl.playerview[pnum].gravitydir); + CL_CalcCrouch (vnum, stepheight); + cl.waterlevel[vnum] = pmove.waterlevel; + VectorCopy(pmove.gravitydir, cl.playerview[vnum].gravitydir); } void CL_PredictMove (void) diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index 449e1efa6..8afb9a680 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -1360,7 +1360,7 @@ void SCR_DrawUPS (void) else track = -1; if (track != -1) - vel = cl.frames[cl.validsequence&UPDATE_MASK].playerstate[track].velocity; + vel = cl.inframes[cl.validsequence&UPDATE_MASK].playerstate[track].velocity; else vel = cl.playerview[0].simvel; lastups = sqrt((vel[0]*vel[0]) + (vel[1]*vel[1])); @@ -1770,7 +1770,7 @@ void SCR_SetUpToDrawConsole (void) key_dest = key_console; scr_conlines = scr_con_current = vid.height * fullscreenpercent; } - else if ((key_dest == key_console || key_dest == key_game) && SCR_GetLoadingStage() == LS_NONE && cls.state < ca_active && !Media_PlayingFullScreen()) + else if ((key_dest == key_console || key_dest == key_game) && SCR_GetLoadingStage() == LS_NONE && cls.state < ca_active && !Media_PlayingFullScreen() && !CSQC_UnconnectedOkay(false)) { if (cls.state < ca_demostart) key_dest = key_console; diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 7bac43f9a..47538983c 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -3075,7 +3075,7 @@ void CL_UpdateBeams (void) // VectorSubtract(cl.simorg, b->start, org); // VectorAdd(b->end, org, b->end); //move the end point by simorg-start - pl = &cl.frames[cl.parsecount&UPDATE_MASK].playerstate[b->entity-1]; + pl = &cl.inframes[cl.parsecount&UPDATE_MASK].playerstate[b->entity-1]; if (pl->messagenum == cl.parsecount || cls.protocol == CP_NETQUAKE) { vec3_t fwd, org, ang; @@ -3091,7 +3091,7 @@ void CL_UpdateBeams (void) if (cl_truelightning.ival >= 2 && cls.netchan.outgoing_sequence > cl_truelightning.ival) { - frame_t *frame = &cl.frames[(cls.netchan.outgoing_sequence-cl_truelightning.ival)&UPDATE_MASK]; + inframe_t *frame = &cl.inframes[(cls.netchan.outgoing_sequence-cl_truelightning.ival)&UPDATE_MASK]; viewang = frame->playerstate[cl.playernum[j]].viewangles; viewang[0] = (frame->playerstate[cl.playernum[j]].command.angles[0] * 360) / 65336.0; viewang[1] = (frame->playerstate[cl.playernum[j]].command.angles[1] * 360) / 65336.0; @@ -3154,7 +3154,7 @@ void CL_UpdateBeams (void) } else if (b->entity <= cl.allocated_client_slots && b->entity > 0) { - pl = &cl.frames[cl.parsecount&UPDATE_MASK].playerstate[b->entity-1]; + pl = &cl.inframes[cl.parsecount&UPDATE_MASK].playerstate[b->entity-1]; VectorCopy(pl->origin, b->start); b->start[2]+=16; } diff --git a/engine/client/cl_ui.c b/engine/client/cl_ui.c index 5187ce7a8..1a81eb81d 100644 --- a/engine/client/cl_ui.c +++ b/engine/client/cl_ui.c @@ -773,7 +773,7 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con if (ui_pings[i].type == NA_INVALID) { serverinfo_t *info; - NET_StringToAdr(cmdtext + 5, &ui_pings[i]); + NET_StringToAdr(cmdtext + 5, 0, &ui_pings[i]); info = Master_InfoForServer(ui_pings[i]); if (info) { diff --git a/engine/client/client.h b/engine/client/client.h index 46b3f7caa..4cbd5f6c0 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -187,23 +187,30 @@ typedef struct player_info_s typedef struct { + double senttime; // time cmd was sent off + // generated on client side - usercmd_t cmd[MAX_SPLITS]; // cmd that generated the frame - double senttime; // time cmd was sent off - int delta_sequence; // sequence number to delta from, -1 = full update + usercmd_t cmd[MAX_SPLITS]; // cmd that generated the frame int cmd_sequence; + int server_message_num; + + int server_time; + int client_time; +} outframe_t; + +typedef struct +{ + //this is the sequence we requested for this frame. + int delta_sequence; // sequence number to delta from, -1 = full update + float latency; // received from server double receivedtime; // time message was received, or -1 player_state_t playerstate[MAX_CLIENTS+MAX_SPLITS]; // message received that reflects performing - // the usercmd + // the usercmd packet_entities_t packet_entities; qboolean invalid; // true if the packet_entities delta was invalid - - int server_time; - int client_time; - int server_message_num; -} frame_t; +} inframe_t; #ifdef Q2CLIENT typedef struct @@ -427,7 +434,7 @@ typedef struct qboolean allow_cheats; qboolean allow_semicheats; //defaults to true, but this allows a server to enforce a strict ruleset (smackdown type rules). float maxfps; //server capped - enum {GAME_DEATHMATCH, GAME_COOP} gamemode; + int deathmatch; #ifdef NQPROT int signon; @@ -510,14 +517,11 @@ typedef struct int parsecount; // server message counter int oldparsecount; int oldvalidsequence; - int ackedinputsequence; //in quakeworld/q2 this is always equal to validsequence. dp can differ. + int ackedmovesequence; //in quakeworld/q2 this is always equal to validsequence. nq can differ. may only be updated when validsequence is updated. int validsequence; // this is the sequence number of the last good // packetentity_t we got. If this is 0, we can't // render a frame yet - int movemessages; // since connecting to this server - // throw out the first couple, so the player - // doesn't accidentally do something the - // first frame + int movesequence; // int spectator; @@ -534,7 +538,8 @@ typedef struct #endif // sentcmds[cl.netchan.outgoing_sequence & UPDATE_MASK] = cmd - frame_t frames[UPDATE_BACKUP]; + outframe_t outframes[UPDATE_BACKUP]; //user inputs (cl.ackedmovesequence+1 to cl.movesequence are still pending) + inframe_t inframes[UPDATE_BACKUP]; //server state (cl.validsequence is the most recent set) lerpents_t *lerpents; int maxlerpents; //number of slots allocated. int lerpentssequence; @@ -1089,6 +1094,8 @@ char *CG_GetConfigString(int num); #ifdef CSQC_DAT qboolean CSQC_Inited(void); void CSQC_RendererRestarted(void); +qboolean CSQC_UnconnectedOkay(qboolean inprinciple); +qboolean CSQC_UnconnectedInit(void); qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checksum); qboolean CSQC_ConsoleLink(char *text, char *info); void CSQC_RegisterCvarsAndThings(void); @@ -1222,6 +1229,7 @@ void Skin_FlushSkin(char *name); void Skin_AllSkins_f (void); void Skin_NextDownload (void); void Skin_FlushPlayers(void); +void Skin_FlushAll(void); #define RSSHOT_WIDTH 320 #define RSSHOT_HEIGHT 200 diff --git a/engine/client/clq2_ents.c b/engine/client/clq2_ents.c index 1ff0bb15a..c4558438e 100644 --- a/engine/client/clq2_ents.c +++ b/engine/client/clq2_ents.c @@ -1015,11 +1015,10 @@ void CLQ2_ParseFrame (void) i = MSG_ReadByte (); for (j=0 ; jcls.netchan.outgoing_sequence-Q3UPDATE_BACKUP ; i--) { - frame = &cl.frames[i & Q3UPDATE_MASK]; + frame = &cl.outframes[i & Q3UPDATE_MASK]; if (frame->server_message_num == snap.deltaFrame) { snap.ping = Sys_Milliseconds() - frame->client_time; @@ -873,7 +873,7 @@ void CLQ3_SendCmd(usercmd_t *cmd) int i; char data[MAX_OVERALLMSGLEN]; sizebuf_t msg; - frame_t *frame, *oldframe; + outframe_t *frame, *oldframe; int cmdcount, key; usercmd_t *to, *from; extern int keycatcher; @@ -905,12 +905,12 @@ void CLQ3_SendCmd(usercmd_t *cmd) if (key_dest != key_game || (keycatcher&3)) cmd->buttons |= 2; //add in the 'at console' button - cl.frames[ccs.currentUserCmdNumber&CMD_MASK].cmd[0] = *cmd; + cl.outframes[ccs.currentUserCmdNumber&CMD_MASK].cmd[0] = *cmd; ccs.currentUserCmdNumber++; - frame = &cl.frames[cls.netchan.outgoing_sequence & Q3UPDATE_MASK]; + frame = &cl.outframes[cls.netchan.outgoing_sequence & Q3UPDATE_MASK]; frame->cmd_sequence = ccs.currentUserCmdNumber; frame->server_message_num = ccs.serverMessageNum; frame->server_time = cl.gametime; @@ -938,7 +938,7 @@ void CLQ3_SendCmd(usercmd_t *cmd) } i = (cls.netchan.outgoing_sequence - 1); - oldframe = &cl.frames[i & Q3UPDATE_MASK]; + oldframe = &cl.outframes[i & Q3UPDATE_MASK]; cmdcount = ccs.currentUserCmdNumber - oldframe->cmd_sequence; if (cmdcount > Q3UPDATE_MASK) cmdcount = Q3UPDATE_MASK; @@ -964,7 +964,7 @@ void CLQ3_SendCmd(usercmd_t *cmd) from = &nullcmd; for (i = oldframe->cmd_sequence; i < ccs.currentUserCmdNumber; i++) { - to = &cl.frames[i&CMD_MASK].cmd[0]; + to = &cl.outframes[i&CMD_MASK].cmd[0]; MSG_Q3_WriteDeltaUsercmd( &msg, key, from, to ); from = to; } @@ -992,7 +992,7 @@ void CLQ3_SendAuthPacket(netadr_t gameserver) if (*key) { Con_Printf("Resolving %s\n", Q3_AUTHORIZE_SERVER_NAME); - if (NET_StringToAdr(Q3_AUTHORIZE_SERVER_NAME, &authaddr)) + if (NET_StringToAdr(Q3_AUTHORIZE_SERVER_NAME, 0, &authaddr)) { msg.data = data; msg.cursize = 0; diff --git a/engine/client/in_win.c b/engine/client/in_win.c index b6fc05098..a8c38bdbe 100644 --- a/engine/client/in_win.c +++ b/engine/client/in_win.c @@ -1981,8 +1981,8 @@ void INS_JoyMove (float *movements, int pnum) static qbyte scantokey[128] = { -// 0 1 2 3 4 5 6 7 -// 8 9 A B C D E F +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F 0 , 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', K_BACKSPACE, 9, // 0 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', @@ -1995,7 +1995,7 @@ static qbyte scantokey[128] = K_UPARROW, K_PGUP, '-', K_LEFTARROW,'5', K_RIGHTARROW,'+', K_END, // 4 K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0, 0, K_F11, K_F12, 0, 0, 0, 0, 0, 0, 0, // 5 - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, '\\', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 7 diff --git a/engine/client/m_items.c b/engine/client/m_items.c index a98ede5c5..9599c49f3 100644 --- a/engine/client/m_items.c +++ b/engine/client/m_items.c @@ -28,7 +28,7 @@ void Draw_TextBox (int x, int y, int width, int lines) if (!p) //assume none exist { R2D_ImageColours(0.0, 0.0, 0.0, 1.0); - R2D_FillBlock(x, y, width + 16, 8 * (2 + lines)); + R2D_FillBlock(x, y, width*16 + 16, 8 * (2 + lines)); R2D_ImageColours(1.0, 1.0, 1.0, 1.0); return; } @@ -1862,6 +1862,11 @@ void M_Menu_Main_f (void) int mgt; +#ifdef CSQC_DAT + if (CSQC_ConsoleCommand(va("%s %s", Cmd_Argv(0), Cmd_Args))) + return; +#endif + SCR_EndLoadingPlaque(); //just in case... /* @@ -1920,7 +1925,7 @@ void M_Menu_Main_f (void) b->common.tooltip = "Singleplayer."; mainm->selecteditem = (menuoption_t *)b; b->common.width = 12*20; - b->common.height = 20; + b->common.height = 32; #endif b = MC_AddConsoleCommand (mainm, 68, 53, "", "menu_multi\n"); b->common.tooltip = "Multiplayer."; @@ -1928,19 +1933,19 @@ void M_Menu_Main_f (void) mainm->selecteditem = (menuoption_t *)b; #endif b->common.width = 12*20; - b->common.height = 20; + b->common.height = 32; b = MC_AddConsoleCommand (mainm, 68, 93, "", "menu_options\n"); b->common.tooltip = "Options."; b->common.width = 12*20; - b->common.height = 20; + b->common.height = 32; b = MC_AddConsoleCommand (mainm, 68, 133, "", "menu_video\n"); b->common.tooltip = "Video Options."; b->common.width = 12*20; - b->common.height = 20; + b->common.height = 32; b = MC_AddConsoleCommand (mainm, 68, 173, "", "menu_quit\n"); b->common.tooltip = "Quit to DOS."; b->common.width = 12*20; - b->common.height = 20; + b->common.height = 32; mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, 42, mainm->selecteditem->common.posy); } diff --git a/engine/client/menu.c b/engine/client/menu.c index 49f9751f2..bb9faaee9 100644 --- a/engine/client/menu.c +++ b/engine/client/menu.c @@ -57,7 +57,7 @@ void M_BuildTranslationTable(int top, int bottom, qbyte *translationTable) qbyte *dest, *source; qbyte identityTable[256]; - int pc = Cvar_Get("cl_playerclass", "1", 0, "foo")->value; + int pc = Cvar_Get("cl_playerclass", "1", 0, "Hexen2")->value; if (h2playertranslations && pc) { int i; @@ -196,6 +196,10 @@ void M_ToggleMenu_f (void) return; } +#ifdef CSQC_DAT + if (CSQC_ConsoleCommand("togglemenu")) + return; +#endif #ifdef MENU_DAT if (MP_Toggle()) return; @@ -1027,6 +1031,8 @@ void M_Reinit(void) #endif { M_Init_Internal(); + + CSQC_UnconnectedInit(); } } diff --git a/engine/client/net_master.c b/engine/client/net_master.c index dc6ae3b87..d7b2d0ba0 100644 --- a/engine/client/net_master.c +++ b/engine/client/net_master.c @@ -597,7 +597,7 @@ void Master_AddMaster (char *address, int type, char *description) netadr_t adr; master_t *mast; - if (!NET_StringToAdr(address, &adr)) + if (!NET_StringToAdr(address, 0, &adr)) { Con_Printf("Failed to resolve address \"%s\"\n", address); return; @@ -805,7 +805,7 @@ qboolean Master_LoadMasterList (char *filename, int defaulttype, int depth) Master_LoadMasterList(file, servertype, depth); else if (servertype < 0) { - if (NET_StringToAdr(line, &net_from)) + if (NET_StringToAdr(line, 0, &net_from)) CL_ReadServerInfo(va("\\hostname\\%s", name), -servertype, true); else Con_Printf("Failed to resolve address - \"%s\"\n", line); @@ -1160,7 +1160,7 @@ void MasterInfo_ProcessHTTP(vfsfile_t *file, int type) if (*s == '#') //hash is a comment, apparently. continue; - if (!NET_StringToAdr(s, &adr)) + if (!NET_StringToAdr(s, 80, &adr)) continue; if ((info = Master_InfoForServer(adr))) //remove if the server already exists. @@ -1228,7 +1228,7 @@ char *jsonnode(int level, char *node) if (level == 1) { if (!strcmp(key, "IPAddress")) - NET_StringToAdr(com_token, &adr); + NET_StringToAdr(com_token, 0, &adr); if (!strcmp(key, "Port")) port = atoi(com_token); if (!strcmp(key, "DNS")) diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 339048cce..f66042bee 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -80,6 +80,7 @@ cvar_t pr_csqc_memsize = CVAR("pr_csqc_memsize", "-1"); cvar_t cl_csqcdebug = CVAR("cl_csqcdebug", "0"); //prints entity numbers which arrive (so I can tell people not to apply it to players...) cvar_t cl_nocsqc = CVAR("cl_nocsqc", "0"); cvar_t pr_csqc_coreonerror = CVAR("pr_csqc_coreonerror", "1"); +cvar_t pr_csqc_formenus = CVAR("pr_csqc_formenus", "1"); extern cvar_t dpcompat_stats; cvar_t dpcompat_corruptglobals = CVAR("dpcompat_corruptglobals", "0"); @@ -2166,7 +2167,7 @@ static void QCBUILTIN PF_cs_getinputstate (pubprogfuncs_t *prinst, struct global cmd->angles[f] = ((int)(cl.playerview[csqc_lplayernum].viewangles[f]*65536.0/360)&65535); } else - cmd = &cl.frames[f&UPDATE_MASK].cmd[csqc_lplayernum]; + cmd = &cl.outframes[f&UPDATE_MASK].cmd[csqc_lplayernum]; cs_set_input_state(cmd); @@ -2313,6 +2314,15 @@ static void QCBUILTIN PF_cs_serverkey (pubprogfuncs_t *prinst, struct globalvars else ret = NET_AdrToString(adr, sizeof(adr), cls.netchan.remote_address); } + else if (!strcmp(keyname, "state")) + { + if (cls.state == ca_disconnected) + ret = "disconnected"; + else if (cls.state == ca_active) + ret = "active"; + else + ret = "connecting"; + } else if (!strcmp(keyname, "protocol")) { //using this is pretty acedemic, really. Not particuarly portable. switch (cls.protocol) @@ -2366,7 +2376,16 @@ static void QCBUILTIN PF_cs_serverkey (pubprogfuncs_t *prinst, struct globalvars } else { - ret = Info_ValueForKey(cl.serverinfo, keyname); +#ifndef CLIENTONLY + if (cls.state < ca_onserver) + { + ret = Info_ValueForKey(svs.info, keyname); + if (!*ret) + ret = Info_ValueForKey(localinfo, keyname); + } + else +#endif + ret = Info_ValueForKey(cl.serverinfo, keyname); } if (*ret) @@ -4035,380 +4054,380 @@ static struct { int ebfsnum; } BuiltinList[] = { //0 - {"makevectors", PF_cs_makevectors, 1}, // #1 void() makevectors (QUAKE) - {"setorigin", PF_cs_SetOrigin, 2}, // #2 void(entity e, vector org) setorigin (QUAKE) - {"setmodel", PF_cs_SetModel, 3}, // #3 void(entity e, string modl) setmodel (QUAKE) - {"setsize", PF_cs_SetSize, 4}, // #4 void(entity e, vector mins, vector maxs) setsize (QUAKE) + {"makevectors", PF_cs_makevectors, 1}, // #1 void() makevectors (QUAKE) + {"setorigin", PF_cs_SetOrigin, 2}, // #2 void(entity e, vector org) setorigin (QUAKE) + {"setmodel", PF_cs_SetModel, 3}, // #3 void(entity e, string modl) setmodel (QUAKE) + {"setsize", PF_cs_SetSize, 4}, // #4 void(entity e, vector mins, vector maxs) setsize (QUAKE) //5 - {"debugbreak", PF_cs_break, 6}, // #6 void() debugbreak (QUAKE) - {"random", PF_random, 7}, // #7 float() random (QUAKE) - {"sound", PF_cs_sound, 8}, // #8 void(entity e, float chan, string samp, float vol, float atten) sound (QUAKE) - {"normalize", PF_normalize, 9}, // #9 vector(vector in) normalize (QUAKE) + {"debugbreak", PF_cs_break, 6}, // #6 void() debugbreak (QUAKE) + {"random", PF_random, 7}, // #7 float() random (QUAKE) + {"sound", PF_cs_sound, 8}, // #8 void(entity e, float chan, string samp, float vol, float atten) sound (QUAKE) + {"normalize", PF_normalize, 9}, // #9 vector(vector in) normalize (QUAKE) //10 - {"error", PF_error, 10}, // #10 void(string errortext) error (QUAKE) - {"objerror", PF_objerror, 11}, // #11 void(string errortext) onjerror (QUAKE) - {"vlen", PF_vlen, 12}, // #12 float(vector v) vlen (QUAKE) - {"vectoyaw", PF_vectoyaw, 13}, // #13 float(vector v) vectoyaw (QUAKE) - {"spawn", PF_Spawn, 14}, // #14 entity() spawn (QUAKE) - {"remove", PF_cs_remove, 15}, // #15 void(entity e) remove (QUAKE) - {"traceline", PF_cs_traceline, 16}, // #16 void(vector v1, vector v2, float nomonst, entity forent) traceline (QUAKE) - {"checkclient", PF_NoCSQC, 17}, // #17 entity() checkclient (QUAKE) (don't support) - {"find", PF_FindString, 18}, // #18 entity(entity start, .string fld, string match) findstring (QUAKE) - {"precache_sound", PF_cs_PrecacheSound, 19}, // #19 void(string str) precache_sound (QUAKE) + {"error", PF_error, 10}, // #10 void(string errortext) error (QUAKE) + {"objerror", PF_objerror, 11}, // #11 void(string errortext) onjerror (QUAKE) + {"vlen", PF_vlen, 12}, // #12 float(vector v) vlen (QUAKE) + {"vectoyaw", PF_vectoyaw, 13}, // #13 float(vector v) vectoyaw (QUAKE) + {"spawn", PF_Spawn, 14}, // #14 entity() spawn (QUAKE) + {"remove", PF_cs_remove, 15}, // #15 void(entity e) remove (QUAKE) + {"traceline", PF_cs_traceline, 16}, // #16 void(vector v1, vector v2, float nomonst, entity forent) traceline (QUAKE) + {"checkclient", PF_NoCSQC, 17}, // #17 entity() checkclient (QUAKE) (don't support) + {"find", PF_FindString, 18}, // #18 entity(entity start, .string fld, string match) findstring (QUAKE) + {"precache_sound", PF_cs_PrecacheSound, 19}, // #19 void(string str) precache_sound (QUAKE) //20 - {"precache_model", PF_cs_PrecacheModel, 20}, // #20 void(string str) precache_model (QUAKE) - {"stuffcmd", PF_NoCSQC, 21}, // #21 void(entity client, string s) stuffcmd (QUAKE) (don't support) - {"findradius", PF_cs_findradius, 22}, // #22 entity(vector org, float rad) findradius (QUAKE) - {"bprint", PF_NoCSQC, 23}, // #23 void(string s, ...) bprint (QUAKE) (don't support) - {"sprint", PF_NoCSQC, 24}, // #24 void(entity e, string s, ...) sprint (QUAKE) (don't support) - {"dprint", PF_dprint, 25}, // #25 void(string s, ...) dprint (QUAKE) - {"ftos", PF_ftos, 26}, // #26 string(float f) ftos (QUAKE) - {"vtos", PF_vtos, 27}, // #27 string(vector f) vtos (QUAKE) - {"coredump", PF_coredump, 28}, // #28 void(void) coredump (QUAKE) - {"traceon", PF_traceon, 29}, // #29 void() traceon (QUAKE) + {"precache_model", PF_cs_PrecacheModel, 20}, // #20 void(string str) precache_model (QUAKE) + {"stuffcmd", PF_NoCSQC, 21}, // #21 void(entity client, string s) stuffcmd (QUAKE) (don't support) + {"findradius", PF_cs_findradius, 22}, // #22 entity(vector org, float rad) findradius (QUAKE) + {"bprint", PF_NoCSQC, 23}, // #23 void(string s, ...) bprint (QUAKE) (don't support) + {"sprint", PF_NoCSQC, 24}, // #24 void(entity e, string s, ...) sprint (QUAKE) (don't support) + {"dprint", PF_dprint, 25}, // #25 void(string s, ...) dprint (QUAKE) + {"ftos", PF_ftos, 26}, // #26 string(float f) ftos (QUAKE) + {"vtos", PF_vtos, 27}, // #27 string(vector f) vtos (QUAKE) + {"coredump", PF_coredump, 28}, // #28 void(void) coredump (QUAKE) + {"traceon", PF_traceon, 29}, // #29 void() traceon (QUAKE) //30 - {"traceoff", PF_traceoff, 30}, // #30 void() traceoff (QUAKE) - {"eprint", PF_eprint, 31}, // #31 void(entity e) eprint (QUAKE) - {"walkmove", PF_cs_walkmove, 32}, // #32 float(float yaw, float dist) walkmove (QUAKE) - {"?", PF_Fixme, 33}, // #33 - {"droptofloor", PF_cs_droptofloor, 34}, // #34 - {"lightstyle", PF_cs_lightstyle, 35}, // #35 void(float lightstyle, string stylestring) lightstyle (QUAKE) - {"rint", PF_rint, 36}, // #36 float(float f) rint (QUAKE) - {"floor", PF_floor, 37}, // #37 float(float f) floor (QUAKE) - {"ceil", PF_ceil, 38}, // #38 float(float f) ceil (QUAKE) -// {"?", PF_Fixme, 39}, // #39 + {"traceoff", PF_traceoff, 30}, // #30 void() traceoff (QUAKE) + {"eprint", PF_eprint, 31}, // #31 void(entity e) eprint (QUAKE) + {"walkmove", PF_cs_walkmove, 32}, // #32 float(float yaw, float dist) walkmove (QUAKE) + {"?", PF_Fixme, 33}, // #33 + {"droptofloor", PF_cs_droptofloor, 34}, // #34 + {"lightstyle", PF_cs_lightstyle, 35}, // #35 void(float lightstyle, string stylestring) lightstyle (QUAKE) + {"rint", PF_rint, 36}, // #36 float(float f) rint (QUAKE) + {"floor", PF_floor, 37}, // #37 float(float f) floor (QUAKE) + {"ceil", PF_ceil, 38}, // #38 float(float f) ceil (QUAKE) +// {"?", PF_Fixme, 39}, // #39 //40 - {"checkbottom", PF_cs_checkbottom, 40}, // #40 float(entity e) checkbottom (QUAKE) - {"pointcontents", PF_cs_pointcontents, 41}, // #41 float(vector org) pointcontents (QUAKE) -// {"?", PF_Fixme, 42}, // #42 - {"fabs", PF_fabs, 43}, // #43 float(float f) fabs (QUAKE) - {"aim", PF_NoCSQC, 44}, // #44 vector(entity e, float speed) aim (QUAKE) (don't support) - {"cvar", PF_cvar, 45}, // #45 float(string cvarname) cvar (QUAKE) - {"localcmd", PF_localcmd, 46}, // #46 void(string str) localcmd (QUAKE) - {"nextent", PF_nextent, 47}, // #47 entity(entity e) nextent (QUAKE) - {"particle", PF_cs_particle, 48}, // #48 void(vector org, vector dir, float colour, float count) particle (QUAKE) - {"changeyaw", PF_cs_changeyaw, 49}, // #49 void() changeyaw (QUAKE) + {"checkbottom", PF_cs_checkbottom, 40}, // #40 float(entity e) checkbottom (QUAKE) + {"pointcontents", PF_cs_pointcontents, 41}, // #41 float(vector org) pointcontents (QUAKE) +// {"?", PF_Fixme, 42}, // #42 + {"fabs", PF_fabs, 43}, // #43 float(float f) fabs (QUAKE) + {"aim", PF_NoCSQC, 44}, // #44 vector(entity e, float speed) aim (QUAKE) (don't support) + {"cvar", PF_cvar, 45}, // #45 float(string cvarname) cvar (QUAKE) + {"localcmd", PF_localcmd, 46}, // #46 void(string str) localcmd (QUAKE) + {"nextent", PF_nextent, 47}, // #47 entity(entity e) nextent (QUAKE) + {"particle", PF_cs_particle, 48}, // #48 void(vector org, vector dir, float colour, float count) particle (QUAKE) + {"changeyaw", PF_cs_changeyaw, 49}, // #49 void() changeyaw (QUAKE) //50 // {"?", PF_Fixme, 50}, // #50 - {"vectoangles", PF_vectoangles, 51}, // #51 vector(vector v) vectoangles (QUAKE) -// {"WriteByte", PF_Fixme, 52}, // #52 void(float to, float f) WriteByte (QUAKE) -// {"WriteChar", PF_Fixme, 53}, // #53 void(float to, float f) WriteChar (QUAKE) -// {"WriteShort", PF_Fixme, 54}, // #54 void(float to, float f) WriteShort (QUAKE) + {"vectoangles", PF_vectoangles, 51}, // #51 vector(vector v) vectoangles (QUAKE) +// {"WriteByte", PF_Fixme, 52}, // #52 void(float to, float f) WriteByte (QUAKE) +// {"WriteChar", PF_Fixme, 53}, // #53 void(float to, float f) WriteChar (QUAKE) +// {"WriteShort", PF_Fixme, 54}, // #54 void(float to, float f) WriteShort (QUAKE) -// {"WriteLong", PF_Fixme, 55}, // #55 void(float to, float f) WriteLong (QUAKE) -// {"WriteCoord", PF_Fixme, 56}, // #56 void(float to, float f) WriteCoord (QUAKE) -// {"WriteAngle", PF_Fixme, 57}, // #57 void(float to, float f) WriteAngle (QUAKE) -// {"WriteString", PF_Fixme, 58}, // #58 void(float to, float f) WriteString (QUAKE) -// {"WriteEntity", PF_Fixme, 59}, // #59 void(float to, float f) WriteEntity (QUAKE) +// {"WriteLong", PF_Fixme, 55}, // #55 void(float to, float f) WriteLong (QUAKE) +// {"WriteCoord", PF_Fixme, 56}, // #56 void(float to, float f) WriteCoord (QUAKE) +// {"WriteAngle", PF_Fixme, 57}, // #57 void(float to, float f) WriteAngle (QUAKE) +// {"WriteString", PF_Fixme, 58}, // #58 void(float to, float f) WriteString (QUAKE) +// {"WriteEntity", PF_Fixme, 59}, // #59 void(float to, float f) WriteEntity (QUAKE) //60 - {"sin", PF_Sin, 60}, // #60 float(float angle) sin (DP_QC_SINCOSSQRTPOW) - {"cos", PF_Cos, 61}, // #61 float(float angle) cos (DP_QC_SINCOSSQRTPOW) - {"sqrt", PF_Sqrt, 62}, // #62 float(float value) sqrt (DP_QC_SINCOSSQRTPOW) - {"changepitch", PF_cs_changepitch, 63}, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) - {"tracetoss", PF_cs_tracetoss, 64}, // #64 void(entity ent, entity ignore) tracetoss (DP_QC_TRACETOSS) + {"sin", PF_Sin, 60}, // #60 float(float angle) sin (DP_QC_SINCOSSQRTPOW) + {"cos", PF_Cos, 61}, // #61 float(float angle) cos (DP_QC_SINCOSSQRTPOW) + {"sqrt", PF_Sqrt, 62}, // #62 float(float value) sqrt (DP_QC_SINCOSSQRTPOW) + {"changepitch", PF_cs_changepitch, 63}, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) + {"tracetoss", PF_cs_tracetoss, 64}, // #64 void(entity ent, entity ignore) tracetoss (DP_QC_TRACETOSS) - {"etos", PF_etos, 65}, // #65 string(entity ent) etos (DP_QC_ETOS) - {"?", PF_Fixme, 66}, // #66 - {"movetogoal", PF_cs_movetogoal, 67}, // #67 void(float step) movetogoal (QUAKE) - {"precache_file", PF_NoCSQC, 68}, // #68 void(string s) precache_file (QUAKE) (don't support) - {"makestatic", PF_cs_makestatic, 69}, // #69 void(entity e) makestatic (QUAKE) + {"etos", PF_etos, 65}, // #65 string(entity ent) etos (DP_QC_ETOS) + {"?", PF_Fixme, 66}, // #66 + {"movetogoal", PF_cs_movetogoal, 67}, // #67 void(float step) movetogoal (QUAKE) + {"precache_file", PF_NoCSQC, 68}, // #68 void(string s) precache_file (QUAKE) (don't support) + {"makestatic", PF_cs_makestatic, 69}, // #69 void(entity e) makestatic (QUAKE) //70 - {"changelevel", PF_NoCSQC, 70}, // #70 void(string mapname) changelevel (QUAKE) (don't support) -// {"?", PF_Fixme, 71}, // #71 - {"cvar_set", PF_cvar_set, 72}, // #72 void(string cvarname, string valuetoset) cvar_set (QUAKE) - {"centerprint", PF_NoCSQC, 73}, // #73 void(entity ent, string text) centerprint (QUAKE) (don't support - cprint is supported instead) - {"ambientsound", PF_cl_ambientsound, 74}, // #74 void (vector pos, string samp, float vol, float atten) ambientsound (QUAKE) + {"changelevel", PF_NoCSQC, 70}, // #70 void(string mapname) changelevel (QUAKE) (don't support) +// {"?", PF_Fixme, 71}, // #71 + {"cvar_set", PF_cvar_set, 72}, // #72 void(string cvarname, string valuetoset) cvar_set (QUAKE) + {"centerprint", PF_NoCSQC, 73}, // #73 void(entity ent, string text) centerprint (QUAKE) (don't support - cprint is supported instead) + {"ambientsound", PF_cl_ambientsound, 74}, // #74 void (vector pos, string samp, float vol, float atten) ambientsound (QUAKE) - {"precache_model2", PF_cs_PrecacheModel, 75}, // #75 void(string str) precache_model2 (QUAKE) - {"precache_sound2", PF_cs_PrecacheSound, 76}, // #76 void(string str) precache_sound2 (QUAKE) - {"precache_file2", PF_NoCSQC, 77}, // #77 void(string str) precache_file2 (QUAKE) - {"setspawnparms", PF_NoCSQC, 78}, // #78 void() setspawnparms (QUAKE) (don't support) - {"logfrag", PF_NoCSQC, 79}, // #79 void(entity killer, entity killee) logfrag (QW_ENGINE) (don't support) + {"precache_model2", PF_cs_PrecacheModel, 75}, // #75 void(string str) precache_model2 (QUAKE) + {"precache_sound2", PF_cs_PrecacheSound, 76}, // #76 void(string str) precache_sound2 (QUAKE) + {"precache_file2", PF_NoCSQC, 77}, // #77 void(string str) precache_file2 (QUAKE) + {"setspawnparms", PF_NoCSQC, 78}, // #78 void() setspawnparms (QUAKE) (don't support) + {"logfrag", PF_NoCSQC, 79}, // #79 void(entity killer, entity killee) logfrag (QW_ENGINE) (don't support) //80 - {"infokey", PF_NoCSQC, 80}, // #80 string(entity e, string keyname) infokey (QW_ENGINE) (don't support) - {"stof", PF_stof, 81}, // #81 float(string s) stof (FRIK_FILE or QW_ENGINE) - {"multicast", PF_NoCSQC, 82}, // #82 void(vector where, float set) multicast (QW_ENGINE) (don't support) + {"infokey", PF_NoCSQC, 80}, // #80 string(entity e, string keyname) infokey (QW_ENGINE) (don't support) + {"stof", PF_stof, 81}, // #81 float(string s) stof (FRIK_FILE or QW_ENGINE) + {"multicast", PF_NoCSQC, 82}, // #82 void(vector where, float set) multicast (QW_ENGINE) (don't support) //90 - {"tracebox", PF_cs_tracebox, 90}, - {"randomvec", PF_randomvector, 91}, // #91 vector() randomvec (DP_QC_RANDOMVEC) - {"getlight", PF_cl_getlight, 92}, // #92 vector(vector org) getlight (DP_QC_GETLIGHT) - {"registercvar", PF_registercvar, 93}, // #93 void(string cvarname, string defaultvalue) registercvar (DP_QC_REGISTERCVAR) - {"min", PF_min, 94}, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND) + {"tracebox", PF_cs_tracebox, 90}, + {"randomvec", PF_randomvector, 91}, // #91 vector() randomvec (DP_QC_RANDOMVEC) + {"getlight", PF_cl_getlight, 92}, // #92 vector(vector org) getlight (DP_QC_GETLIGHT) + {"registercvar", PF_registercvar, 93}, // #93 void(string cvarname, string defaultvalue) registercvar (DP_QC_REGISTERCVAR) + {"min", PF_min, 94}, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND) - {"max", PF_max, 95}, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND) - {"bound", PF_bound, 96}, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND) - {"pow", PF_pow, 97}, // #97 float(float value) pow (DP_QC_SINCOSSQRTPOW) - {"findfloat", PF_FindFloat, 98}, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT) - {"checkextension", PF_checkextension, 99}, // #99 float(string extname) checkextension (EXT_CSQC) + {"max", PF_max, 95}, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND) + {"bound", PF_bound, 96}, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND) + {"pow", PF_pow, 97}, // #97 float(float value) pow (DP_QC_SINCOSSQRTPOW) + {"findfloat", PF_FindFloat, 98}, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT) + {"checkextension", PF_checkextension, 99}, // #99 float(string extname) checkextension (EXT_CSQC) //110 - {"fopen", PF_fopen, 110}, // #110 float(string strname, float accessmode) fopen (FRIK_FILE) - {"fclose", PF_fclose, 111}, // #111 void(float fnum) fclose (FRIK_FILE) - {"fgets", PF_fgets, 112}, // #112 string(float fnum) fgets (FRIK_FILE) - {"fputs", PF_fputs, 113}, // #113 void(float fnum, string str) fputs (FRIK_FILE) - {"strlen", PF_strlen, 114}, // #114 float(string str) strlen (FRIK_FILE) + {"fopen", PF_fopen, 110}, // #110 float(string strname, float accessmode) fopen (FRIK_FILE) + {"fclose", PF_fclose, 111}, // #111 void(float fnum) fclose (FRIK_FILE) + {"fgets", PF_fgets, 112}, // #112 string(float fnum) fgets (FRIK_FILE) + {"fputs", PF_fputs, 113}, // #113 void(float fnum, string str) fputs (FRIK_FILE) + {"strlen", PF_strlen, 114}, // #114 float(string str) strlen (FRIK_FILE) - {"strcat", PF_strcat, 115}, // #115 string(string str1, string str2, ...) strcat (FRIK_FILE) - {"substring", PF_substring, 116}, // #116 string(string str, float start, float length) substring (FRIK_FILE) - {"stov", PF_stov, 117}, // #117 vector(string str) stov (FRIK_FILE) - {"strzone", PF_dupstring, 118}, // #118 string(string str) dupstring (FRIK_FILE) - {"strunzone", PF_forgetstring, 119}, // #119 void(string str) freestring (FRIK_FILE) + {"strcat", PF_strcat, 115}, // #115 string(string str1, string str2, ...) strcat (FRIK_FILE) + {"substring", PF_substring, 116}, // #116 string(string str, float start, float length) substring (FRIK_FILE) + {"stov", PF_stov, 117}, // #117 vector(string str) stov (FRIK_FILE) + {"strzone", PF_dupstring, 118}, // #118 string(string str) dupstring (FRIK_FILE) + {"strunzone", PF_forgetstring, 119}, // #119 void(string str) freestring (FRIK_FILE) //200 - {"getmodelindex", PF_cs_PrecacheModel, 200}, - {"externcall", PF_externcall, 201}, - {"addprogs", PF_cs_addprogs, 202}, - {"externvalue", PF_externvalue, 203}, - {"externset", PF_externset, 204}, + {"getmodelindex", PF_cs_PrecacheModel, 200}, + {"externcall", PF_externcall, 201}, + {"addprogs", PF_cs_addprogs, 202}, + {"externvalue", PF_externvalue, 203}, + {"externset", PF_externset, 204}, - {"externrefcall", PF_externrefcall, 205}, - {"instr", PF_instr, 206}, - {"openportal", PF_cs_OpenPortal, 207}, //q2bsps - {"registertempent", PF_NoCSQC, 208},//{"RegisterTempEnt", PF_RegisterTEnt, 0, 0, 0, 208}, - {"customtempent", PF_NoCSQC, 209},//{"CustomTempEnt", PF_CustomTEnt, 0, 0, 0, 209}, + {"externrefcall", PF_externrefcall, 205}, + {"instr", PF_instr, 206}, + {"openportal", PF_cs_OpenPortal, 207}, //q2bsps + {"registertempent", PF_NoCSQC, 208},//{"RegisterTempEnt", PF_RegisterTEnt, 0, 0, 0, 208}, + {"customtempent", PF_NoCSQC, 209},//{"CustomTempEnt", PF_CustomTEnt, 0, 0, 0, 209}, //210 -// {"fork", PF_Fixme, 210},//{"fork", PF_Fork, 0, 0, 0, 210}, - {"abort", PF_Abort, 211}, //#211 void() abort (FTE_MULTITHREADED) -// {"sleep", PF_Fixme, 212},//{"sleep", PF_Sleep, 0, 0, 0, 212}, - {"forceinfokey", PF_NoCSQC, 213},//{"forceinfokey", PF_ForceInfoKey, 0, 0, 0, 213}, - {"chat", PF_NoCSQC, 214},//{"chat", PF_chat, 0, 0, 0, 214},// #214 void(string filename, float starttag, entity edict) SV_Chat (FTE_NPCCHAT) +// {"fork", PF_Fixme, 210},//{"fork", PF_Fork, 0, 0, 0, 210}, + {"abort", PF_Abort, 211}, //#211 void() abort (FTE_MULTITHREADED) +// {"sleep", PF_Fixme, 212},//{"sleep", PF_Sleep, 0, 0, 0, 212}, + {"forceinfokey", PF_NoCSQC, 213},//{"forceinfokey", PF_ForceInfoKey, 0, 0, 0, 213}, + {"chat", PF_NoCSQC, 214},//{"chat", PF_chat, 0, 0, 0, 214},// #214 void(string filename, float starttag, entity edict) SV_Chat (FTE_NPCCHAT) - {"particle2", PF_cs_particle2, 215}, //215 (FTE_PEXT_HEXEN2) - {"particle3", PF_cs_particle3, 216}, //216 (FTE_PEXT_HEXEN2) - {"particle4", PF_cs_particle4, 217}, //217 (FTE_PEXT_HEXEN2) + {"particle2", PF_cs_particle2, 215}, //215 (FTE_PEXT_HEXEN2) + {"particle3", PF_cs_particle3, 216}, //216 (FTE_PEXT_HEXEN2) + {"particle4", PF_cs_particle4, 217}, //217 (FTE_PEXT_HEXEN2) //EXT_DIMENSION_PLANES - {"bitshift", PF_bitshift, 218}, //#218 bitshift (EXT_DIMENSION_PLANES) - {"te_lightningblood", PF_cl_te_lightningblood, 219},// #219 te_lightningblood void(vector org) (FTE_TE_STANDARDEFFECTBUILTINS) + {"bitshift", PF_bitshift, 218}, //#218 bitshift (EXT_DIMENSION_PLANES) + {"te_lightningblood", PF_cl_te_lightningblood, 219},// #219 te_lightningblood void(vector org) (FTE_TE_STANDARDEFFECTBUILTINS) //220 -// {"map_builtin", PF_Fixme, 220}, //like #100 - takes 2 args. arg0 is builtinname, 1 is number to map to. - {"strstrofs", PF_strstrofs, 221}, // #221 float(string s1, string sub) strstrofs (FTE_STRINGS) - {"str2chr", PF_str2chr, 222}, // #222 float(string str, float index) str2chr (FTE_STRINGS) - {"chr2str", PF_chr2str, 223}, // #223 string(float chr, ...) chr2str (FTE_STRINGS) - {"strconv", PF_strconv, 224}, // #224 string(float ccase, float redalpha, float redchars, string str, ...) strconv (FTE_STRINGS) +// {"map_builtin", PF_Fixme, 220}, //like #100 - takes 2 args. arg0 is builtinname, 1 is number to map to. + {"strstrofs", PF_strstrofs, 221}, // #221 float(string s1, string sub) strstrofs (FTE_STRINGS) + {"str2chr", PF_str2chr, 222}, // #222 float(string str, float index) str2chr (FTE_STRINGS) + {"chr2str", PF_chr2str, 223}, // #223 string(float chr, ...) chr2str (FTE_STRINGS) + {"strconv", PF_strconv, 224}, // #224 string(float ccase, float redalpha, float redchars, string str, ...) strconv (FTE_STRINGS) - {"strpad", PF_strpad, 225}, // #225 string strpad(float pad, string str1, ...) strpad (FTE_STRINGS) - {"infoadd", PF_infoadd, 226}, // #226 string(string old, string key, string value) infoadd - {"infoget", PF_infoget, 227}, // #227 string(string info, string key) infoget - {"strncmp", PF_strncmp, 228}, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS) - {"strcasecmp", PF_strcasecmp, 229}, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS) + {"strpad", PF_strpad, 225}, // #225 string strpad(float pad, string str1, ...) strpad (FTE_STRINGS) + {"infoadd", PF_infoadd, 226}, // #226 string(string old, string key, string value) infoadd + {"infoget", PF_infoget, 227}, // #227 string(string info, string key) infoget + {"strncmp", PF_strncmp, 228}, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS) + {"strcasecmp", PF_strcasecmp, 229}, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS) //230 - {"strncasecmp", PF_strncasecmp, 230}, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS) - {"calltimeofday", PF_calltimeofday, 231}, - {"clientstat", PF_NoCSQC, 232}, // #231 clientstat - {"runclientphys", PF_NoCSQC, 233}, // #232 runclientphys -// {"isbackbuffered", PF_NoCSQC, 234}, // #233 float(entity ent) isbackbuffered + {"strncasecmp", PF_strncasecmp, 230}, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS) + {"calltimeofday", PF_calltimeofday, 231}, + {"clientstat", PF_NoCSQC, 232}, // #231 clientstat + {"runclientphys", PF_NoCSQC, 233}, // #232 runclientphys +// {"isbackbuffered", PF_NoCSQC, 234}, // #233 float(entity ent) isbackbuffered //I messed up, 234 is meant to be isbackbuffered. luckily that's not present in csqc, but still, this is messy. Don't document this. - {"rotatevectorsbytag", PF_rotatevectorsbytag, 234}, // #234 + {"rotatevectorsbytag", PF_rotatevectorsbytag, 234}, // #234 {"rotatevectorsbyangle", PF_rotatevectorsbyangles, 235}, // #235 {"rotatevectorsbyvectors", PF_rotatevectorsbymatrix, 236}, // #236 - {"skinforname", PF_skinforname, 237}, // #237 - {"shaderforname", PF_shaderforname, 238}, // #238 - {"te_bloodqw", PF_cl_te_bloodqw, 239}, // #239 void te_bloodqw(vector org[, float count]) (FTE_TE_STANDARDEFFECTBUILTINS) + {"skinforname", PF_skinforname, 237}, // #237 + {"shaderforname", PF_shaderforname, 238}, // #238 + {"te_bloodqw", PF_cl_te_bloodqw, 239}, // #239 void te_bloodqw(vector org[, float count]) (FTE_TE_STANDARDEFFECTBUILTINS) -// {"checkpvs", PF_checkpvs, 240}, -// {"matchclientname", PF_matchclient, 241}, - {"sendpacket", PF_NoCSQC, 242}, //void(string dest, string content) sendpacket = #242; (FTE_QC_SENDPACKET) +// {"checkpvs", PF_checkpvs, 240}, +// {"matchclientname", PF_matchclient, 241}, + {"sendpacket", PF_NoCSQC, 242}, //void(string dest, string content) sendpacket = #242; (FTE_QC_SENDPACKET) -// {"bulleten", PF_bulleten, 243}, (removed builtin) - {"rotatevectorsbytag", PF_rotatevectorsbytag, 244}, +// {"bulleten", PF_bulleten, 243}, (removed builtin) + {"rotatevectorsbytag", PF_rotatevectorsbytag, 244}, - {"sqlconnect", PF_NoCSQC, 250}, // #250 float([string host], [string user], [string pass], [string defaultdb], [string driver]) sqlconnect (FTE_SQL) - {"sqldisconnect", PF_NoCSQC, 251}, // #251 void(float serveridx) sqldisconnect (FTE_SQL) - {"sqlopenquery", PF_NoCSQC, 252}, // #252 float(float serveridx, void(float serveridx, float queryidx, float rows, float columns, float eof) callback, float querytype, string query) sqlopenquery (FTE_SQL) - {"sqlclosequery", PF_NoCSQC, 253}, // #253 void(float serveridx, float queryidx) sqlclosequery (FTE_SQL) - {"sqlreadfield", PF_NoCSQC, 254}, // #254 string(float serveridx, float queryidx, float row, float column) sqlreadfield (FTE_SQL) - {"sqlerror", PF_NoCSQC, 255}, // #255 string(float serveridx, [float queryidx]) sqlerror (FTE_SQL) - {"sqlescape", PF_NoCSQC, 256}, // #256 string(float serveridx, string data) sqlescape (FTE_SQL) - {"sqlversion", PF_NoCSQC, 257}, // #257 string(float serveridx) sqlversion (FTE_SQL) - {"sqlreadfloat", PF_NoCSQC, 258}, // #258 float(float serveridx, float queryidx, float row, float column) sqlreadfloat (FTE_SQL) + {"sqlconnect", PF_NoCSQC, 250}, // #250 float([string host], [string user], [string pass], [string defaultdb], [string driver]) sqlconnect (FTE_SQL) + {"sqldisconnect", PF_NoCSQC, 251}, // #251 void(float serveridx) sqldisconnect (FTE_SQL) + {"sqlopenquery", PF_NoCSQC, 252}, // #252 float(float serveridx, void(float serveridx, float queryidx, float rows, float columns, float eof) callback, float querytype, string query) sqlopenquery (FTE_SQL) + {"sqlclosequery", PF_NoCSQC, 253}, // #253 void(float serveridx, float queryidx) sqlclosequery (FTE_SQL) + {"sqlreadfield", PF_NoCSQC, 254}, // #254 string(float serveridx, float queryidx, float row, float column) sqlreadfield (FTE_SQL) + {"sqlerror", PF_NoCSQC, 255}, // #255 string(float serveridx, [float queryidx]) sqlerror (FTE_SQL) + {"sqlescape", PF_NoCSQC, 256}, // #256 string(float serveridx, string data) sqlescape (FTE_SQL) + {"sqlversion", PF_NoCSQC, 257}, // #257 string(float serveridx) sqlversion (FTE_SQL) + {"sqlreadfloat", PF_NoCSQC, 258}, // #258 float(float serveridx, float queryidx, float row, float column) sqlreadfloat (FTE_SQL) - {"stoi", PF_stoi, 259}, - {"itos", PF_itos, 260}, - {"stoh", PF_stoh, 261}, - {"htos", PF_htos, 262}, + {"stoi", PF_stoi, 259}, + {"itos", PF_itos, 260}, + {"stoh", PF_stoh, 261}, + {"htos", PF_htos, 262}, - {"skel_create", PF_skel_create, 263},//float(float modlindex) skel_create = #263; // (FTE_CSQC_SKELETONOBJECTS) - {"skel_build", PF_skel_build, 264},//float(float skel, entity ent, float modelindex, float retainfrac, float firstbone, float lastbone, optional float addition) skel_build = #264; // (FTE_CSQC_SKELETONOBJECTS) - {"skel_get_numbones", PF_skel_get_numbones, 265},//float(float skel) skel_get_numbones = #265; // (FTE_CSQC_SKELETONOBJECTS) - {"skel_get_bonename", PF_skel_get_bonename, 266},//string(float skel, float bonenum) skel_get_bonename = #266; // (FTE_CSQC_SKELETONOBJECTS) (returns tempstring) - {"skel_get_boneparent", PF_skel_get_boneparent, 267},//float(float skel, float bonenum) skel_get_boneparent = #267; // (FTE_CSQC_SKELETONOBJECTS) - {"skel_find_bone", PF_skel_find_bone, 268},//float(float skel, string tagname) skel_get_boneidx = #268; // (FTE_CSQC_SKELETONOBJECTS) - {"skel_get_bonerel", PF_skel_get_bonerel, 269},//vector(float skel, float bonenum) skel_get_bonerel = #269; // (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc) - {"skel_get_boneabs", PF_skel_get_boneabs, 270},//vector(float skel, float bonenum) skel_get_boneabs = #270; // (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc) - {"skel_set_bone", PF_skel_set_bone, 271},//void(float skel, float bonenum, vector org) skel_set_bone = #271; // (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc) - {"skel_mul_bone", PF_skel_mul_bone, 272},//void(float skel, float bonenum, vector org) skel_mul_bone = #272; // (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc) - {"skel_mul_bones", PF_skel_mul_bones, 273},//void(float skel, float startbone, float endbone, vector org) skel_mul_bone = #273; // (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc) - {"skel_copybones", PF_skel_copybones, 274},//void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones = #274; // (FTE_CSQC_SKELETONOBJECTS) - {"skel_delete", PF_skel_delete, 275},//void(float skel) skel_delete = #275; // (FTE_CSQC_SKELETONOBJECTS) - {"frameforname", PF_frameforname, 276},//void(float modidx, string framename) frameforname = #276 (FTE_CSQC_SKELETONOBJECTS) - {"frameduration", PF_frameduration, 277},//void(float modidx, float framenum) frameduration = #277 (FTE_CSQC_SKELETONOBJECTS) + {"skel_create", PF_skel_create, 263},//float(float modlindex) skel_create = #263; // (FTE_CSQC_SKELETONOBJECTS) + {"skel_build", PF_skel_build, 264},//float(float skel, entity ent, float modelindex, float retainfrac, float firstbone, float lastbone, optional float addition) skel_build = #264; // (FTE_CSQC_SKELETONOBJECTS) + {"skel_get_numbones", PF_skel_get_numbones, 265},//float(float skel) skel_get_numbones = #265; // (FTE_CSQC_SKELETONOBJECTS) + {"skel_get_bonename", PF_skel_get_bonename, 266},//string(float skel, float bonenum) skel_get_bonename = #266; // (FTE_CSQC_SKELETONOBJECTS) (returns tempstring) + {"skel_get_boneparent", PF_skel_get_boneparent, 267},//float(float skel, float bonenum) skel_get_boneparent = #267; // (FTE_CSQC_SKELETONOBJECTS) + {"skel_find_bone", PF_skel_find_bone, 268},//float(float skel, string tagname) skel_get_boneidx = #268; // (FTE_CSQC_SKELETONOBJECTS) + {"skel_get_bonerel", PF_skel_get_bonerel, 269},//vector(float skel, float bonenum) skel_get_bonerel = #269; // (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc) + {"skel_get_boneabs", PF_skel_get_boneabs, 270},//vector(float skel, float bonenum) skel_get_boneabs = #270; // (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc) + {"skel_set_bone", PF_skel_set_bone, 271},//void(float skel, float bonenum, vector org) skel_set_bone = #271; // (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc) + {"skel_mul_bone", PF_skel_mul_bone, 272},//void(float skel, float bonenum, vector org) skel_mul_bone = #272; // (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc) + {"skel_mul_bones", PF_skel_mul_bones, 273},//void(float skel, float startbone, float endbone, vector org) skel_mul_bone = #273; // (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc) + {"skel_copybones", PF_skel_copybones, 274},//void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones = #274; // (FTE_CSQC_SKELETONOBJECTS) + {"skel_delete", PF_skel_delete, 275},//void(float skel) skel_delete = #275; // (FTE_CSQC_SKELETONOBJECTS) + {"frameforname", PF_frameforname, 276},//void(float modidx, string framename) frameforname = #276 (FTE_CSQC_SKELETONOBJECTS) + {"frameduration", PF_frameduration, 277},//void(float modidx, float framenum) frameduration = #277 (FTE_CSQC_SKELETONOBJECTS) - {"terrain_edit", PF_terrain_edit, 278},//void(float action, vector pos, float radius, float quant) terrain_edit = #278 (??FTE_TERRAIN_EDIT??) - {"touchtriggers", PF_touchtriggers, 279},//void() touchtriggers = #279; - {"skel_ragupdate", PF_skel_ragedit, 281},// (FTE_QC_RAGDOLL) - {"skel_mmap", PF_skel_mmap, 282},// (FTE_QC_RAGDOLL) - {"skel_set_bone_world", PF_skel_set_bone_world, 283}, - {"frametoname", PF_frametoname, 284},//string(float modidx, float framenum) frametoname - {"skintoname", PF_skintoname, 285},//string(float modidx, float skin) skintoname + {"terrain_edit", PF_terrain_edit, 278},//void(float action, vector pos, float radius, float quant) terrain_edit = #278 (??FTE_TERRAIN_EDIT??) + {"touchtriggers", PF_touchtriggers, 279},//void() touchtriggers = #279; + {"skel_ragupdate", PF_skel_ragedit, 281},// (FTE_QC_RAGDOLL) + {"skel_mmap", PF_skel_mmap, 282},// (FTE_QC_RAGDOLL) + {"skel_set_bone_world", PF_skel_set_bone_world, 283}, + {"frametoname", PF_frametoname, 284},//string(float modidx, float framenum) frametoname + {"skintoname", PF_skintoname, 285},//string(float modidx, float skin) skintoname //300 - {"clearscene", PF_R_ClearScene, 300}, // #300 void() clearscene (EXT_CSQC) - {"addentities", PF_R_AddEntityMask, 301}, // #301 void(float mask) addentities (EXT_CSQC) - {"addentity", PF_R_AddEntity, 302}, // #302 void(entity ent) addentity (EXT_CSQC) - {"setproperty", PF_R_SetViewFlag, 303}, // #303 float(float property, ...) setproperty (EXT_CSQC) - {"renderscene", PF_R_RenderScene, 304}, // #304 void() renderscene (EXT_CSQC) + {"clearscene", PF_R_ClearScene, 300}, // #300 void() clearscene (EXT_CSQC) + {"addentities", PF_R_AddEntityMask, 301}, // #301 void(float mask) addentities (EXT_CSQC) + {"addentity", PF_R_AddEntity, 302}, // #302 void(entity ent) addentity (EXT_CSQC) + {"setproperty", PF_R_SetViewFlag, 303}, // #303 float(float property, ...) setproperty (EXT_CSQC) + {"renderscene", PF_R_RenderScene, 304}, // #304 void() renderscene (EXT_CSQC) - {"dynamiclight_add", PF_R_DynamicLight_Add, 305}, // #305 float(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC) + {"dynamiclight_add", PF_R_DynamicLight_Add, 305}, // #305 float(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC) - {"R_BeginPolygon", PF_R_PolygonBegin, 306}, // #306 void(string texturename) R_BeginPolygon (EXT_CSQC_???) - {"R_PolygonVertex", PF_R_PolygonVertex, 307}, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex (EXT_CSQC_???) - {"R_EndPolygon", PF_R_PolygonEnd, 308}, // #308 void() R_EndPolygon (EXT_CSQC_???) + {"R_BeginPolygon", PF_R_PolygonBegin, 306}, // #306 void(string texturename) R_BeginPolygon (EXT_CSQC_???) + {"R_PolygonVertex", PF_R_PolygonVertex, 307}, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex (EXT_CSQC_???) + {"R_EndPolygon", PF_R_PolygonEnd, 308}, // #308 void() R_EndPolygon (EXT_CSQC_???) - {"getproperty", PF_R_GetViewFlag, 309}, // #309 vector/float(float property) getproperty (EXT_CSQC_1) + {"getproperty", PF_R_GetViewFlag, 309}, // #309 vector/float(float property) getproperty (EXT_CSQC_1) //310 //maths stuff that uses the current view settings. - {"unproject", PF_cs_unproject, 310}, // #310 vector (vector v) unproject (EXT_CSQC) - {"project", PF_cs_project, 311}, // #311 vector (vector v) project (EXT_CSQC) + {"unproject", PF_cs_unproject, 310}, // #310 vector (vector v) unproject (EXT_CSQC) + {"project", PF_cs_project, 311}, // #311 vector (vector v) project (EXT_CSQC) // {"?", PF_Fixme, 312}, // #312 // {"?", PF_Fixme, 313}, // #313 //2d (immediate) operations -// {"drawtextfield", PF_CL_DrawTextField, 314}, - {"drawline", PF_CL_drawline, 315}, // #315 void(float width, vector pos1, vector pos2) drawline (EXT_CSQC) - {"iscachedpic", PF_CL_is_cached_pic, 316}, // #316 float(string name) iscachedpic (EXT_CSQC) - {"precache_pic", PF_CL_precache_pic, 317}, // #317 string(string name, float trywad) precache_pic (EXT_CSQC) - {"drawgetimagesize", PF_CL_drawgetimagesize, 318}, // #318 vector(string picname) draw_getimagesize (EXT_CSQC) - {"freepic", PF_CL_free_pic, 319}, // #319 void(string name) freepic (EXT_CSQC) +// {"drawtextfield", PF_CL_DrawTextField, 314}, + {"drawline", PF_CL_drawline, 315}, // #315 void(float width, vector pos1, vector pos2) drawline (EXT_CSQC) + {"iscachedpic", PF_CL_is_cached_pic, 316}, // #316 float(string name) iscachedpic (EXT_CSQC) + {"precache_pic", PF_CL_precache_pic, 317}, // #317 string(string name, float trywad) precache_pic (EXT_CSQC) + {"drawgetimagesize", PF_CL_drawgetimagesize, 318}, // #318 vector(string picname) draw_getimagesize (EXT_CSQC) + {"freepic", PF_CL_free_pic, 319}, // #319 void(string name) freepic (EXT_CSQC) //320 - {"drawcharacter", PF_CL_drawcharacter, 320}, // #320 float(vector position, float character, vector scale, vector rgb, float alpha [, float flag]) drawcharacter (EXT_CSQC, [EXT_CSQC_???]) - {"drawrawstring", PF_CL_drawrawstring, 321}, // #321 float(vector position, string text, vector scale, vector rgb, float alpha [, float flag]) drawstring (EXT_CSQC, [EXT_CSQC_???]) - {"drawpic", PF_CL_drawpic, 322}, // #322 float(vector position, string pic, vector size, vector rgb, float alpha [, float flag]) drawpic (EXT_CSQC, [EXT_CSQC_???]) - {"drawfill", PF_CL_drawfill, 323}, // #323 float(vector position, vector size, vector rgb, float alpha [, float flag]) drawfill (EXT_CSQC, [EXT_CSQC_???]) - {"drawsetcliparea", PF_CL_drawsetcliparea, 324}, // #324 void(float x, float y, float width, float height) drawsetcliparea (EXT_CSQC_???) - {"drawresetcliparea", PF_CL_drawresetcliparea, 325}, // #325 void(void) drawresetcliparea (EXT_CSQC_???) + {"drawcharacter", PF_CL_drawcharacter, 320}, // #320 float(vector position, float character, vector scale, vector rgb, float alpha [, float flag]) drawcharacter (EXT_CSQC, [EXT_CSQC_???]) + {"drawrawstring", PF_CL_drawrawstring, 321}, // #321 float(vector position, string text, vector scale, vector rgb, float alpha [, float flag]) drawstring (EXT_CSQC, [EXT_CSQC_???]) + {"drawpic", PF_CL_drawpic, 322}, // #322 float(vector position, string pic, vector size, vector rgb, float alpha [, float flag]) drawpic (EXT_CSQC, [EXT_CSQC_???]) + {"drawfill", PF_CL_drawfill, 323}, // #323 float(vector position, vector size, vector rgb, float alpha [, float flag]) drawfill (EXT_CSQC, [EXT_CSQC_???]) + {"drawsetcliparea", PF_CL_drawsetcliparea, 324}, // #324 void(float x, float y, float width, float height) drawsetcliparea (EXT_CSQC_???) + {"drawresetcliparea", PF_CL_drawresetcliparea, 325}, // #325 void(void) drawresetcliparea (EXT_CSQC_???) - {"drawstring", PF_CL_drawcolouredstring, 326}, // #326 - {"stringwidth", PF_CL_stringwidth, 327}, // #327 EXT_CSQC_'DARKPLACES' - {"drawsubpic", PF_CL_drawsubpic, 328}, // #328 EXT_CSQC_'DARKPLACES' + {"drawstring", PF_CL_drawcolouredstring, 326}, // #326 + {"stringwidth", PF_CL_stringwidth, 327}, // #327 EXT_CSQC_'DARKPLACES' + {"drawsubpic", PF_CL_drawsubpic, 328}, // #328 EXT_CSQC_'DARKPLACES' // {"?", PF_Fixme, 329}, // #329 EXT_CSQC_'DARKPLACES' //330 - {"getstati", PF_cs_getstati, 330}, // #330 float(float stnum) getstati (EXT_CSQC) - {"getstatbits", PF_cs_getstatbits, 331}, // #331 float(float stnum) getstatbits (EXT_CSQC) - {"getstats", PF_cs_getstats, 332}, // #332 string(float firststnum) getstats (EXT_CSQC) - {"setmodelindex", PF_cs_SetModelIndex, 333}, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC) - {"modelnameforindex", PF_cs_ModelnameForIndex, 334}, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC) + {"getstati", PF_cs_getstati, 330}, // #330 float(float stnum) getstati (EXT_CSQC) + {"getstatbits", PF_cs_getstatbits, 331}, // #331 float(float stnum) getstatbits (EXT_CSQC) + {"getstats", PF_cs_getstats, 332}, // #332 string(float firststnum) getstats (EXT_CSQC) + {"setmodelindex", PF_cs_SetModelIndex, 333}, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC) + {"modelnameforindex", PF_cs_ModelnameForIndex, 334}, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC) - {"particleeffectnum", PF_cs_particleeffectnum, 335}, // #335 float(string effectname) particleeffectnum (EXT_CSQC) - {"trailparticles", PF_cs_trailparticles, 336}, // #336 void(float effectnum, entity ent, vector start, vector end) trailparticles (EXT_CSQC), - {"pointparticles", PF_cs_pointparticles, 337}, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC) + {"particleeffectnum", PF_cs_particleeffectnum, 335}, // #335 float(string effectname) particleeffectnum (EXT_CSQC) + {"trailparticles", PF_cs_trailparticles, 336}, // #336 void(float effectnum, entity ent, vector start, vector end) trailparticles (EXT_CSQC), + {"pointparticles", PF_cs_pointparticles, 337}, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC) - {"cprint", PF_cl_cprint, 338}, // #338 void(string s) cprint (EXT_CSQC) - {"print", PF_print, 339}, // #339 void(string s) print (EXT_CSQC) + {"cprint", PF_cl_cprint, 338}, // #338 void(string s) cprint (EXT_CSQC) + {"print", PF_print, 339}, // #339 void(string s) print (EXT_CSQC) //340 - {"keynumtostring", PF_cl_keynumtostring, 340}, // #340 string(float keynum) keynumtostring (EXT_CSQC) - {"stringtokeynum", PF_cl_stringtokeynum, 341}, // #341 float(string keyname) stringtokeynum (EXT_CSQC) - {"getkeybind", PF_cl_getkeybind, 342}, // #342 string(float keynum) getkeybind (EXT_CSQC) + {"keynumtostring", PF_cl_keynumtostring, 340}, // #340 string(float keynum) keynumtostring (EXT_CSQC) + {"stringtokeynum", PF_cl_stringtokeynum, 341}, // #341 float(string keyname) stringtokeynum (EXT_CSQC) + {"getkeybind", PF_cl_getkeybind, 342}, // #342 string(float keynum) getkeybind (EXT_CSQC) // {"?", PF_Fixme, 343}, // #343 - {"getmousepos", PF_cl_getmousepos, 344}, // #344 This is a DP extension + {"getmousepos", PF_cl_getmousepos, 344}, // #344 This is a DP extension - {"getinputstate", PF_cs_getinputstate, 345}, // #345 float(float framenum) getinputstate (EXT_CSQC) + {"getinputstate", PF_cs_getinputstate, 345}, // #345 float(float framenum) getinputstate (EXT_CSQC) {"setsensitivityscaler", PF_cs_setsensativityscaler, 346}, // #346 void(float sens) setsensitivityscaler (EXT_CSQC) - {"runstandardplayerphysics", PF_cs_runplayerphysics, 347}, // #347 void() runstandardplayerphysics (EXT_CSQC) + {"runstandardplayerphysics",PF_cs_runplayerphysics, 347}, // #347 void() runstandardplayerphysics (EXT_CSQC) - {"getplayerkeyvalue", PF_cs_getplayerkey, 348}, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC) + {"getplayerkeyvalue", PF_cs_getplayerkey, 348}, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC) - {"isdemo", PF_cl_playingdemo, 349}, // #349 float() isdemo (EXT_CSQC) + {"isdemo", PF_cl_playingdemo, 349}, // #349 float() isdemo (EXT_CSQC) //350 - {"isserver", PF_cl_runningserver, 350}, // #350 float() isserver (EXT_CSQC) + {"isserver", PF_cl_runningserver, 350}, // #350 float() isserver (EXT_CSQC) - {"SetListener", PF_cs_setlistener, 351}, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC) - {"registercommand", PF_cs_registercommand, 352}, // #352 void(string cmdname) registercommand (EXT_CSQC) - {"wasfreed", PF_WasFreed, 353}, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too) + {"SetListener", PF_cs_setlistener, 351}, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC) + {"registercommand", PF_cs_registercommand, 352}, // #352 void(string cmdname) registercommand (EXT_CSQC) + {"wasfreed", PF_WasFreed, 353}, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too) - {"serverkey", PF_cs_serverkey, 354}, // #354 string(string key) serverkey; - {"getentitytoken", PF_cs_getentitytoken, 355}, // #355 string() getentitytoken; - {"findfont", PF_CL_findfont, 356}, - {"loadfont", PF_CL_loadfont, 357}, -// {"?", PF_Fixme, 358}, // #358 - {"sendevent", PF_cs_sendevent, 359}, // #359 void(string evname, string evargs, ...) (EXT_CSQC_1) + {"serverkey", PF_cs_serverkey, 354}, // #354 string(string key) serverkey; + {"getentitytoken", PF_cs_getentitytoken, 355}, // #355 string() getentitytoken; + {"findfont", PF_CL_findfont, 356}, + {"loadfont", PF_CL_loadfont, 357}, +// {"?", PF_Fixme, 358}, // #358 + {"sendevent", PF_cs_sendevent, 359}, // #359 void(string evname, string evargs, ...) (EXT_CSQC_1) //360 //note that 'ReadEntity' is pretty hard to implement reliably. Modders should use a combination of ReadShort, and findfloat, and remember that it might not be known clientside (pvs culled or other reason) - {"readbyte", PF_ReadByte, 360}, // #360 float() readbyte (EXT_CSQC) - {"readchar", PF_ReadChar, 361}, // #361 float() readchar (EXT_CSQC) - {"readshort", PF_ReadShort, 362}, // #362 float() readshort (EXT_CSQC) - {"readlong", PF_ReadLong, 363}, // #363 float() readlong (EXT_CSQC) - {"readcoord", PF_ReadCoord, 364}, // #364 float() readcoord (EXT_CSQC) + {"readbyte", PF_ReadByte, 360}, // #360 float() readbyte (EXT_CSQC) + {"readchar", PF_ReadChar, 361}, // #361 float() readchar (EXT_CSQC) + {"readshort", PF_ReadShort, 362}, // #362 float() readshort (EXT_CSQC) + {"readlong", PF_ReadLong, 363}, // #363 float() readlong (EXT_CSQC) + {"readcoord", PF_ReadCoord, 364}, // #364 float() readcoord (EXT_CSQC) - {"readangle", PF_ReadAngle, 365}, // #365 float() readangle (EXT_CSQC) - {"readstring", PF_ReadString, 366}, // #366 string() readstring (EXT_CSQC) - {"readfloat", PF_ReadFloat, 367}, // #367 string() readfloat (EXT_CSQC) - {"readentitynum", PF_ReadEntityNum, 368}, // #368 float() readentitynum (EXT_CSQC) + {"readangle", PF_ReadAngle, 365}, // #365 float() readangle (EXT_CSQC) + {"readstring", PF_ReadString, 366}, // #366 string() readstring (EXT_CSQC) + {"readfloat", PF_ReadFloat, 367}, // #367 string() readfloat (EXT_CSQC) + {"readentitynum", PF_ReadEntityNum, 368}, // #368 float() readentitynum (EXT_CSQC) // {"readserverentitystate", PF_ReadServerEntityState, 369}, // #369 void(float flags, float simtime) readserverentitystate (EXT_CSQC_1) // {"readsingleentitystate", PF_ReadSingleEntityState, 370}, - {"deltalisten", PF_DeltaListen, 371}, // #371 float(string modelname, float flags) deltalisten (EXT_CSQC_1) + {"deltalisten", PF_DeltaListen, 371}, // #371 float(string modelname, float flags) deltalisten (EXT_CSQC_1) - {"dynamiclight_get", PF_R_DynamicLight_Get, 372}, - {"dynamiclight_set", PF_R_DynamicLight_Set, 373}, - {"particleeffectquery", PF_cs_particleeffectquery, 374}, - {"adddecal", PF_R_AddDecal, 375}, + {"dynamiclight_get", PF_R_DynamicLight_Get, 372}, + {"dynamiclight_set", PF_R_DynamicLight_Set, 373}, + {"particleeffectquery", PF_cs_particleeffectquery, 374}, + {"adddecal", PF_R_AddDecal, 375}, - {"memalloc", PF_memalloc, 384}, - {"memfree", PF_memfree, 385}, - {"memcpy", PF_memcpy, 386}, - {"memset", PF_memset, 387}, + {"memalloc", PF_memalloc, 384}, + {"memfree", PF_memfree, 385}, + {"memcpy", PF_memcpy, 386}, + {"memset", PF_memset, 387}, //400 - {"copyentity", PF_cs_copyentity, 400}, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY) - {"setcolors", PF_NoCSQC, 401}, // #401 void(entity cl, float colours) setcolors (DP_SV_SETCOLOR) (don't implement) - {"findchain", PF_cs_findchain, 402}, // #402 entity(string field, string match) findchain (DP_QC_FINDCHAIN) - {"findchainfloat", PF_cs_findchainfloat, 403}, // #403 entity(float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT) - {"effect", PF_cl_effect, 404}, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT) + {"copyentity", PF_cs_copyentity, 400}, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY) + {"setcolors", PF_NoCSQC, 401}, // #401 void(entity cl, float colours) setcolors (DP_SV_SETCOLOR) (don't implement) + {"findchain", PF_cs_findchain, 402}, // #402 entity(string field, string match) findchain (DP_QC_FINDCHAIN) + {"findchainfloat", PF_cs_findchainfloat, 403}, // #403 entity(float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT) + {"effect", PF_cl_effect, 404}, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT) - {"te_blood", PF_cl_te_blooddp, 405}, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD) - {"te_bloodshower", PF_cl_te_bloodshower,406}, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER) - {"te_explosionrgb", PF_cl_te_explosionrgb, 407}, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB) - {"te_particlecube", PF_cl_te_particlecube,408}, // #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE) - {"te_particlerain", PF_cl_te_particlerain, 409}, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN) + {"te_blood", PF_cl_te_blooddp, 405}, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD) + {"te_bloodshower", PF_cl_te_bloodshower,406}, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER) + {"te_explosionrgb", PF_cl_te_explosionrgb, 407}, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB) + {"te_particlecube", PF_cl_te_particlecube,408}, // #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE) + {"te_particlerain", PF_cl_te_particlerain, 409}, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN) - {"te_particlesnow", PF_cl_te_particlesnow,410}, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW) - {"te_spark", PF_cl_te_spark, 411}, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK) - {"te_gunshotquad", PF_cl_te_gunshotquad, 412}, // #412 void(vector org) te_gunshotquad (DP_TE_QUADEFFECTS1) - {"te_spikequad", PF_cl_te_spikequad, 413}, // #413 void(vector org) te_spikequad (DP_TE_QUADEFFECTS1) - {"te_superspikequad", PF_cl_te_superspikequad,414}, // #414 void(vector org) te_superspikequad (DP_TE_QUADEFFECTS1) + {"te_particlesnow", PF_cl_te_particlesnow,410}, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW) + {"te_spark", PF_cl_te_spark, 411}, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK) + {"te_gunshotquad", PF_cl_te_gunshotquad, 412}, // #412 void(vector org) te_gunshotquad (DP_TE_QUADEFFECTS1) + {"te_spikequad", PF_cl_te_spikequad, 413}, // #413 void(vector org) te_spikequad (DP_TE_QUADEFFECTS1) + {"te_superspikequad", PF_cl_te_superspikequad,414}, // #414 void(vector org) te_superspikequad (DP_TE_QUADEFFECTS1) - {"te_explosionquad", PF_cl_te_explosionquad, 415}, // #415 void(vector org) te_explosionquad (DP_TE_QUADEFFECTS1) - {"te_smallflash", PF_cl_te_smallflash, 416}, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH) - {"te_customflash", PF_cl_te_customflash, 417}, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH) - {"te_gunshot", PF_cl_te_gunshot, 418}, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS) - {"te_spike", PF_cl_te_spike, 419}, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS) + {"te_explosionquad", PF_cl_te_explosionquad, 415}, // #415 void(vector org) te_explosionquad (DP_TE_QUADEFFECTS1) + {"te_smallflash", PF_cl_te_smallflash, 416}, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH) + {"te_customflash", PF_cl_te_customflash, 417}, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH) + {"te_gunshot", PF_cl_te_gunshot, 418}, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS) + {"te_spike", PF_cl_te_spike, 419}, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS) - {"te_superspike", PF_cl_te_superspike,420}, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS) - {"te_explosion", PF_cl_te_explosion, 421}, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS) - {"te_tarexplosion", PF_cl_te_tarexplosion,422}, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS) - {"te_wizspike", PF_cl_te_wizspike, 423}, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS) - {"te_knightspike", PF_cl_te_knightspike,424}, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS) + {"te_superspike", PF_cl_te_superspike,420}, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS) + {"te_explosion", PF_cl_te_explosion, 421}, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS) + {"te_tarexplosion", PF_cl_te_tarexplosion,422}, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS) + {"te_wizspike", PF_cl_te_wizspike, 423}, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS) + {"te_knightspike", PF_cl_te_knightspike,424}, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS) - {"te_lavasplash", PF_cl_te_lavasplash,425}, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS) - {"te_teleport", PF_cl_te_teleport, 426}, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS) - {"te_explosion2", PF_cl_te_explosion2,427}, // #427 void(vector org, float color, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS) - {"te_lightning1", PF_cl_te_lightning1, 428}, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS) - {"te_lightning2", PF_cl_te_lightning2,429}, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS) + {"te_lavasplash", PF_cl_te_lavasplash,425}, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS) + {"te_teleport", PF_cl_te_teleport, 426}, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS) + {"te_explosion2", PF_cl_te_explosion2,427}, // #427 void(vector org, float color, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS) + {"te_lightning1", PF_cl_te_lightning1, 428}, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS) + {"te_lightning2", PF_cl_te_lightning2,429}, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS) {"te_lightning3", PF_cl_te_lightning3, 430}, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS) {"te_beam", PF_cl_te_beam, 431}, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS) @@ -4422,82 +4441,82 @@ static struct { {"getsurfacenearpoint", PF_getsurfacenearpoint, 438}, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE) {"getsurfaceclippedpoint", PF_getsurfaceclippedpoint, 439}, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE) - {"clientcommand", PF_NoCSQC, 440}, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND) (don't implement) - {"tokenize", PF_Tokenize, 441}, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND) - {"argv", PF_ArgV, 442}, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND) - {"setattachment", PS_cs_setattachment,443}, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS) - {"search_begin", PF_search_begin, 444}, // #444 float search_begin(string pattern, float caseinsensitive, float quiet) (DP_QC_FS_SEARCH) + {"clientcommand", PF_NoCSQC, 440}, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND) (don't implement) + {"tokenize", PF_Tokenize, 441}, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND) + {"argv", PF_ArgV, 442}, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND) + {"setattachment", PS_cs_setattachment,443}, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS) + {"search_begin", PF_search_begin, 444}, // #444 float search_begin(string pattern, float caseinsensitive, float quiet) (DP_QC_FS_SEARCH) - {"search_end", PF_search_end, 445}, // #445 void search_end(float handle) (DP_QC_FS_SEARCH) - {"search_getsize", PF_search_getsize, 446}, // #446 float search_getsize(float handle) (DP_QC_FS_SEARCH) - {"search_getfilename", PF_search_getfilename,447}, // #447 string search_getfilename(float handle, float num) (DP_QC_FS_SEARCH) - {"cvar_string", PF_cvar_string, 448}, // #448 string(float n) cvar_string (DP_QC_CVAR_STRING) - {"findflags", PF_FindFlags, 449}, // #449 entity(entity start, .entity fld, float match) findflags (DP_QC_FINDFLAGS) + {"search_end", PF_search_end, 445}, // #445 void search_end(float handle) (DP_QC_FS_SEARCH) + {"search_getsize", PF_search_getsize, 446}, // #446 float search_getsize(float handle) (DP_QC_FS_SEARCH) + {"search_getfilename", PF_search_getfilename,447}, // #447 string search_getfilename(float handle, float num) (DP_QC_FS_SEARCH) + {"cvar_string", PF_cvar_string, 448}, // #448 string(float n) cvar_string (DP_QC_CVAR_STRING) + {"findflags", PF_FindFlags, 449}, // #449 entity(entity start, .entity fld, float match) findflags (DP_QC_FINDFLAGS) - {"findchainflags", PF_cs_findchainflags, 450}, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS) - {"gettagindex", PF_gettagindex, 451}, // #451 float(entity ent, string tagname) gettagindex (DP_MD3_TAGSINFO) - {"gettaginfo", PF_gettaginfo, 452}, // #452 vector(entity ent, float tagindex) gettaginfo (DP_MD3_TAGSINFO) - {"dropclient", PF_NoCSQC, 453}, // #453 void(entity player) dropclient (DP_SV_BOTCLIENT) (don't implement) - {"spawnclient", PF_NoCSQC, 454}, // #454 entity() spawnclient (DP_SV_BOTCLIENT) (don't implement) + {"findchainflags", PF_cs_findchainflags, 450}, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS) + {"gettagindex", PF_gettagindex, 451}, // #451 float(entity ent, string tagname) gettagindex (DP_MD3_TAGSINFO) + {"gettaginfo", PF_gettaginfo, 452}, // #452 vector(entity ent, float tagindex) gettaginfo (DP_MD3_TAGSINFO) + {"dropclient", PF_NoCSQC, 453}, // #453 void(entity player) dropclient (DP_SV_BOTCLIENT) (don't implement) + {"spawnclient", PF_NoCSQC, 454}, // #454 entity() spawnclient (DP_SV_BOTCLIENT) (don't implement) - {"clienttype", PF_NoCSQC, 455}, // #455 float(entity client) clienttype (DP_SV_BOTCLIENT) (don't implement) + {"clienttype", PF_NoCSQC, 455}, // #455 float(entity client) clienttype (DP_SV_BOTCLIENT) (don't implement) // {"WriteUnterminatedString",PF_WriteString2, 456}, //writestring but without the null terminator. makes things a little nicer. //DP_TE_FLAMEJET -// {"te_flamejet", PF_te_flamejet, 457}, // #457 void(vector org, vector vel, float howmany) te_flamejet +// {"te_flamejet", PF_te_flamejet, 457}, // #457 void(vector org, vector vel, float howmany) te_flamejet //no 458 documented. //DP_QC_EDICT_NUM - {"edict_num", PF_edict_for_num, 459}, // #459 entity(float entnum) edict_num + {"edict_num", PF_edict_for_num, 459}, // #459 entity(float entnum) edict_num //DP_QC_STRINGBUFFERS - {"buf_create", PF_buf_create, 460}, // #460 float() buf_create - {"buf_del", PF_buf_del, 461}, // #461 void(float bufhandle) buf_del - {"buf_getsize", PF_buf_getsize, 462}, // #462 float(float bufhandle) buf_getsize - {"buf_copy", PF_buf_copy, 463}, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy - {"buf_sort", PF_buf_sort, 464}, // #464 void(float bufhandle, float sortpower, float backward) buf_sort - {"buf_implode", PF_buf_implode, 465}, // #465 string(float bufhandle, string glue) buf_implode - {"bufstr_get", PF_bufstr_get, 466}, // #466 string(float bufhandle, float string_index) bufstr_get - {"bufstr_set", PF_bufstr_set, 467}, // #467 void(float bufhandle, float string_index, string str) bufstr_set - {"bufstr_add", PF_bufstr_add, 468}, // #468 float(float bufhandle, string str, float order) bufstr_add - {"bufstr_free", PF_bufstr_free, 469}, // #469 void(float bufhandle, float string_index) bufstr_free + {"buf_create", PF_buf_create, 460}, // #460 float() buf_create + {"buf_del", PF_buf_del, 461}, // #461 void(float bufhandle) buf_del + {"buf_getsize", PF_buf_getsize, 462}, // #462 float(float bufhandle) buf_getsize + {"buf_copy", PF_buf_copy, 463}, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy + {"buf_sort", PF_buf_sort, 464}, // #464 void(float bufhandle, float sortpower, float backward) buf_sort + {"buf_implode", PF_buf_implode, 465}, // #465 string(float bufhandle, string glue) buf_implode + {"bufstr_get", PF_bufstr_get, 466}, // #466 string(float bufhandle, float string_index) bufstr_get + {"bufstr_set", PF_bufstr_set, 467}, // #467 void(float bufhandle, float string_index, string str) bufstr_set + {"bufstr_add", PF_bufstr_add, 468}, // #468 float(float bufhandle, string str, float order) bufstr_add + {"bufstr_free", PF_bufstr_free, 469}, // #469 void(float bufhandle, float string_index) bufstr_free //no 470 documented //DP_QC_ASINACOSATANATAN2TAN - {"asin", PF_asin, 471}, // #471 float(float s) asin - {"acos", PF_acos, 472}, // #472 float(float c) acos - {"atan", PF_atan, 473}, // #473 float(float t) atan - {"atan2", PF_atan2, 474}, // #474 float(float c, float s) atan2 - {"tan", PF_tan, 475}, // #475 float(float a) tan + {"asin", PF_asin, 471}, // #471 float(float s) asin + {"acos", PF_acos, 472}, // #472 float(float c) acos + {"atan", PF_atan, 473}, // #473 float(float t) atan + {"atan2", PF_atan2, 474}, // #474 float(float c, float s) atan2 + {"tan", PF_tan, 475}, // #475 float(float a) tan ////DP_QC_STRINGCOLORFUNCTIONS - {"strlennocol", PF_strlennocol, 476}, // #476 float(string s) strlennocol - {"strdecolorize", PF_strdecolorize, 477}, // #477 string(string s) strdecolorize + {"strlennocol", PF_strlennocol, 476}, // #476 float(string s) strlennocol + {"strdecolorize", PF_strdecolorize, 477}, // #477 string(string s) strdecolorize //DP_QC_STRFTIME - {"strftime", PF_strftime, 478}, // #478 string(float uselocaltime, string format, ...) strftime + {"strftime", PF_strftime, 478}, // #478 string(float uselocaltime, string format, ...) strftime //DP_QC_TOKENIZEBYSEPARATOR - {"tokenizebyseparator",PF_tokenizebyseparator, 479}, // #479 float(string s, string separator1, ...) tokenizebyseparator + {"tokenizebyseparator", PF_tokenizebyseparator, 479}, // #479 float(string s, string separator1, ...) tokenizebyseparator //DP_QC_STRING_CASE_FUNCTIONS - {"strtolower", PF_strtolower, 480}, // #476 string(string s) strtolower - {"strtoupper", PF_strtoupper, 481}, // #476 string(string s) strlennocol + {"strtolower", PF_strtolower, 480}, // #476 string(string s) strtolower + {"strtoupper", PF_strtoupper, 481}, // #476 string(string s) strlennocol //DP_QC_CVAR_DEFSTRING - {"cvar_defstring", PF_cvar_defstring, 482}, // #482 string(string s) cvar_defstring + {"cvar_defstring", PF_cvar_defstring, 482}, // #482 string(string s) cvar_defstring //DP_SV_POINTSOUND - {"pointsound", PF_cs_pointsound, 483}, // #483 void(vector origin, string sample, float volume, float attenuation) pointsound + {"pointsound", PF_cs_pointsound, 483}, // #483 void(vector origin, string sample, float volume, float attenuation) pointsound //DP_QC_STRREPLACE - {"strreplace", PF_strreplace, 484}, // #484 string(string search, string replace, string subject) strreplace - {"strireplace", PF_strireplace, 485}, // #485 string(string search, string replace, string subject) strireplace + {"strreplace", PF_strreplace, 484}, // #484 string(string search, string replace, string subject) strreplace + {"strireplace", PF_strireplace, 485}, // #485 string(string search, string replace, string subject) strireplace //DP_QC_GETSURFACEPOINTATTRIBUTE @@ -4505,78 +4524,96 @@ static struct { #ifndef NOMEDIA //DP_GECKO_SUPPORT - {"gecko_create", PF_cs_gecko_create, 487}, // #487 float(string name) gecko_create( string name ) - {"gecko_destroy", PF_cs_gecko_destroy, 488}, // #488 void(string name) gecko_destroy( string name ) - {"gecko_navigate", PF_cs_gecko_navigate, 489}, // #489 void(string name) gecko_navigate( string name, string URI ) - {"gecko_keyevent", PF_cs_gecko_keyevent, 490}, // #490 float(string name) gecko_keyevent( string name, float key, float eventtype ) - {"gecko_mousemove", PF_cs_gecko_mousemove, 491}, // #491 void gecko_mousemove( string name, float x, float y ) - {"gecko_resize", PF_cs_gecko_resize, 492}, // #492 void gecko_resize( string name, float w, float h ) + {"gecko_create", PF_cs_gecko_create, 487}, // #487 float(string name) gecko_create( string name ) + {"gecko_destroy", PF_cs_gecko_destroy, 488}, // #488 void(string name) gecko_destroy( string name ) + {"gecko_navigate", PF_cs_gecko_navigate, 489}, // #489 void(string name) gecko_navigate( string name, string URI ) + {"gecko_keyevent", PF_cs_gecko_keyevent, 490}, // #490 float(string name) gecko_keyevent( string name, float key, float eventtype ) + {"gecko_mousemove", PF_cs_gecko_mousemove, 491}, // #491 void gecko_mousemove( string name, float x, float y ) + {"gecko_resize", PF_cs_gecko_resize, 492}, // #492 void gecko_resize( string name, float w, float h ) {"gecko_get_texture_extent",PF_cs_gecko_get_texture_extent, 493}, // #493 vector gecko_get_texture_extent( string name ) #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 - {"putentityfieldstring",PF_putentityfieldstring, 500}, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring + {"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 -// {"boxparticles", PF_Fixme, 502}, +// {"boxparticles", PF_Fixme, 502}, //DP_QC_WHICHPACK - {"whichpack", PF_whichpack, 503}, // #503 string(string filename) whichpack + {"whichpack", PF_whichpack, 503}, // #503 string(string filename) whichpack //DP_CSQC_QUERYRENDERENTITY - {"getentity", PF_getentity, 504}, // #504 __variant(float entnum, fload fieldnum) getentity + {"getentity", PF_getentity, 504}, // #504 __variant(float entnum, fload fieldnum) getentity //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}, - {"argv_end_index", PF_argv_end_index, 516}, - {"buf_cvarlist", PF_buf_cvarlist, 517}, - {"cvar_description", PF_cvar_description, 518}, + {"tokenize_console", PF_tokenize_console, 514}, + {"argv_start_index", PF_argv_start_index, 515}, + {"argv_end_index", PF_argv_end_index, 516}, + {"buf_cvarlist", PF_buf_cvarlist, 517}, + {"cvar_description", PF_cvar_description, 518}, - {"gettime", PF_cs_gettime, 519}, + {"gettime", PF_cs_gettime, 519}, - {"keynumtostring", PF_cl_keynumtostring, 520}, - {"findkeysforcommand", PF_cl_findkeysforcommand, 521}, + {"keynumtostring", PF_cl_keynumtostring, 520}, + {"findkeysforcommand", PF_cl_findkeysforcommand, 521}, - {"loadfromdata", PF_loadfromdata, 529}, - {"loadfromfile", PF_loadfromfile, 530}, + {"loadfromdata", PF_loadfromdata, 529}, + {"loadfromfile", PF_loadfromfile, 530}, - {"callfunction", PF_callfunction, 605}, - {"writetofile", PF_writetofile, 606}, - {"isfunction", PF_isfunction, 607}, - {"parseentitydata", PF_parseentitydata, 608}, - {"keynumtostring", PF_cl_keynumtostring, 609}, + {"callfunction", PF_callfunction, 605}, + {"writetofile", PF_writetofile, 606}, + {"isfunction", PF_isfunction, 607}, + {"parseentitydata", PF_parseentitydata, 608}, + {"keynumtostring", PF_cl_keynumtostring, 609}, - {"findkeysforcommand", PF_cl_findkeysforcommand, 610}, - {"stringtokeynum", PF_cl_stringtokeynum, 614}, + {"findkeysforcommand", PF_cl_findkeysforcommand, 610}, + {"gethostcachevalue", PF_cl_gethostcachevalue, 611}, + {"gethostcachestring", PF_cl_gethostcachestring, 612}, + {"parseentitydata", PF_parseentitydata, 613}, + {"stringtokeynum", PF_cl_stringtokeynum, 614}, - {"sprintf", PF_sprintf, 627}, + {"resethostcachemasks", PF_cl_resethostcachemasks, 615}, + {"sethostcachemaskstring", PF_cl_sethostcachemaskstring,616}, + {"sethostcachemasknumber", PF_cl_sethostcachemasknumber,617}, + {"resorthostcache", PF_cl_resorthostcache, 618}, + {"sethostcachesort", PF_cl_sethostcachesort, 619}, + {"refreshhostcache", PF_cl_refreshhostcache, 620}, + {"gethostcachenumber", PF_cl_gethostcachenumber, 621}, + {"gethostcacheindexforkey", PF_cl_gethostcacheindexforkey,622}, + {"addwantedhostcachekey", PF_cl_addwantedhostcachekey, 623}, + {"getextresponse", PF_cl_getextresponse, 624}, + {"netaddress_resolve", PF_netaddress_resolve, 625}, - {"getsurfacenumtriangles",PF_getsurfacenumtriangles,628}, - {"getsurfacetriangle", PF_getsurfacetriangle, 629}, + {"sprintf", PF_sprintf, 627}, + {"getsurfacenumtriangles", PF_getsurfacenumtriangles,628}, + {"getsurfacetriangle", PF_getsurfacetriangle, 629}, - {"digest_hex", PF_digest_hex, 639}, +// {"setkeybind", PF_Fixme, 630}, + {"getbindmaps", PF_cl_GetBindMap, 631}, + {"setbindmaps", PF_cl_SetBindMap, 632}, + + {"digest_hex", PF_digest_hex, 639}, {NULL} }; @@ -4904,6 +4941,28 @@ qboolean CSQC_Inited(void) return false; } +qboolean CSQC_UnconnectedOkay(qboolean inprinciple) +{ + return false; + + if (!inprinciple) + { + if (!csqcprogs) + return false; + return true; + } + else + { + if (pr_csqc_formenus.ival) + return true; + return false; + } +} +qboolean CSQC_UnconnectedInit(void) +{ + return false; +} + double csqctime; qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checksum) { @@ -4911,6 +4970,8 @@ qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checks string_t *str; csqcedict_t *worldent; qboolean loaded = false; + if (csprogs_promiscuous != anycsqc || csprogs_checksum != checksum) + CSQC_Shutdown(); csprogs_promiscuous = anycsqc; csprogs_checksum = checksum; @@ -5313,6 +5374,7 @@ void CSQC_RegisterCvarsAndThings(void) Cmd_AddCommandD("cl_cmd", CSQC_GameCommand_f, "Calls the csqc's GameCommand function"); Cmd_AddCommand("breakpoint_csqc", CSQC_Breakpoint_f); + Cvar_Register(&pr_csqc_formenus, CSQCPROGSGROUP); Cvar_Register(&pr_csqc_memsize, CSQCPROGSGROUP); Cvar_Register(&pr_csqc_maxedicts, CSQCPROGSGROUP); Cvar_Register(&cl_csqcdebug, CSQCPROGSGROUP); @@ -5337,7 +5399,10 @@ qboolean CSQC_DrawView(void) csqc_resortfrags = true; - if (!csqcg.draw_function || !csqcprogs || !cl.worldmodel) + if (!csqcg.draw_function || !csqcprogs) + return false; + + if (cls.state < (csqcg.loadresource?ca_active:ca_onserver) && !CSQC_UnconnectedOkay(false)) return false; r_secondaryview = 0; @@ -5378,18 +5443,18 @@ qboolean CSQC_DrawView(void) if (!cl.paused) { if (csqcg.clientcommandframe) - *csqcg.clientcommandframe = cls.netchan.outgoing_sequence; + *csqcg.clientcommandframe = cl.movesequence; if (csqcg.servercommandframe) - *csqcg.servercommandframe = cl.ackedinputsequence; + *csqcg.servercommandframe = cl.ackedmovesequence; if (csqcg.gamespeed) *csqcg.gamespeed = cl.gamespeed; } else { if (csqcg.clientcommandframe) - *csqcg.clientcommandframe = cl.ackedinputsequence; + *csqcg.clientcommandframe = cl.movesequence; if (csqcg.servercommandframe) - *csqcg.servercommandframe = cl.ackedinputsequence; + *csqcg.servercommandframe = cl.ackedmovesequence; if (csqcg.gamespeed) *csqcg.gamespeed = 0; } @@ -5421,9 +5486,12 @@ qboolean CSQC_DrawView(void) qboolean CSQC_KeyPress(int key, int unicode, qboolean down, int devid) { void *pr_globals; + extern qboolean editormodal; if (!csqcprogs || !csqcg.input_event) return false; + if (editormodal) + return false; pr_globals = PR_globals(csqcprogs, PR_CURRENT); G_FLOAT(OFS_PARM0) = down?CSIE_KEYDOWN:CSIE_KEYUP; @@ -5505,6 +5573,8 @@ qboolean CSQC_ConsoleCommand(char *cmd) void *pr_globals; if (!csqcprogs || !csqcg.console_command) return false; + if (editormodal) + return false; pr_globals = PR_globals(csqcprogs, PR_CURRENT); (((string_t *)pr_globals)[OFS_PARM0] = PR_TempString(csqcprogs, cmd)); @@ -5685,7 +5755,7 @@ void CSQC_Input_Frame(int lplayernum, usercmd_t *cmd) *csqcg.cltime = cl.time; if (csqcg.clientcommandframe) - *csqcg.clientcommandframe = cls.netchan.outgoing_sequence; + *csqcg.clientcommandframe = cl.movesequence; cs_set_input_state(cmd); PR_ExecuteProgram (csqcprogs, csqcg.input_frame); @@ -5779,9 +5849,9 @@ void CSQC_ParseEntities(void) *csqcg.cltime = cl.time; if (csqcg.clientcommandframe) - *csqcg.clientcommandframe = cls.netchan.outgoing_sequence; + *csqcg.clientcommandframe = cl.movesequence; if (csqcg.servercommandframe) - *csqcg.servercommandframe = cl.ackedinputsequence; + *csqcg.servercommandframe = cl.ackedmovesequence; for(;;) { diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index 1e7dd4992..977099d0c 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -8,17 +8,7 @@ #endif #if defined(MENU_DAT) || defined(CSQC_DAT) - -struct -{ - float *drawfont; - float *drawfontscale; -} mp_globs; - - - - - +#include "cl_master.h" //float drawfill(vector position, vector size, vector rgb, float alpha, float flag) = #457; void QCBUILTIN PF_CL_drawfill (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) @@ -91,30 +81,15 @@ void PR_CL_BeginString(pubprogfuncs_t *prinst, float vx, float vy, float szx, fl int fontidx = 0; //default by default... world_t *world = prinst->parms->user; struct font_s *font = font_conchar; - if (!world) + + if (world->g.drawfontscale) { - //menu progs. - if (mp_globs.drawfontscale) - { - szx *= mp_globs.drawfontscale[0]; - szy *= mp_globs.drawfontscale[1]; - } - if (mp_globs.drawfont) - { - fontidx = *mp_globs.drawfont; - } + szx *= world->g.drawfontscale[0]; + szy *= world->g.drawfontscale[1]; } - else + if (world->g.drawfont) { - if (world->g.drawfontscale) - { - szx *= world->g.drawfontscale[0]; - szy *= world->g.drawfontscale[1]; - } - if (world->g.drawfont) - { - fontidx = *world->g.drawfont; - } + fontidx = *world->g.drawfont; } if (fontidx >= 0 && fontidx < FONT_SLOTS) @@ -905,164 +880,6 @@ static void QCBUILTIN PF_CopyEntity (pubprogfuncs_t *prinst, struct globalvars_s memcpy(out->fields, in->fields, menuentsize); } -#ifdef CL_MASTER -#include "cl_master.h" - -void QCBUILTIN PF_M_gethostcachevalue (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) -{ - hostcacheglobal_t hcg = G_FLOAT(OFS_PARM0); - G_FLOAT(OFS_RETURN) = 0; - switch(hcg) - { - case SLIST_HOSTCACHEVIEWCOUNT: - CL_QueryServers(); - Master_CheckPollSockets(); - G_FLOAT(OFS_RETURN) = Master_NumSorted(); - return; - case SLIST_HOSTCACHETOTALCOUNT: - CL_QueryServers(); - Master_CheckPollSockets(); - G_FLOAT(OFS_RETURN) = Master_TotalCount(); - return; - - case SLIST_MASTERQUERYCOUNT: - case SLIST_MASTERREPLYCOUNT: - case SLIST_SERVERQUERYCOUNT: - case SLIST_SERVERREPLYCOUNT: - G_FLOAT(OFS_RETURN) = 0; - return; - - case SLIST_SORTFIELD: - G_FLOAT(OFS_RETURN) = Master_GetSortField(); - return; - case SLIST_SORTDESCENDING: - G_FLOAT(OFS_RETURN) = Master_GetSortDescending(); - return; - default: - return; - } -} - -//void resethostcachemasks(void) = #615; -void QCBUILTIN PF_M_resethostcachemasks(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) -{ - Master_ClearMasks(); -} -//void sethostcachemaskstring(float mask, float fld, string str, float op) = #616; -void QCBUILTIN PF_M_sethostcachemaskstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) -{ - int mask = G_FLOAT(OFS_PARM0); - int field = G_FLOAT(OFS_PARM1); - char *str = PR_GetStringOfs(prinst, OFS_PARM2); - int op = G_FLOAT(OFS_PARM3); - - Master_SetMaskString(mask, field, str, op); -} -//void sethostcachemasknumber(float mask, float fld, float num, float op) = #617; -void QCBUILTIN PF_M_sethostcachemasknumber(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) -{ - int mask = G_FLOAT(OFS_PARM0); - int field = G_FLOAT(OFS_PARM1); - int str = G_FLOAT(OFS_PARM2); - int op = G_FLOAT(OFS_PARM3); - - Master_SetMaskInteger(mask, field, str, op); -} -//void resorthostcache(void) = #618; -void QCBUILTIN PF_M_resorthostcache(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) -{ - Master_SortServers(); -} -//void sethostcachesort(float fld, float descending) = #619; -void QCBUILTIN PF_M_sethostcachesort(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) -{ - Master_SetSortField(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1)); -} -//void refreshhostcache(void) = #620; -void QCBUILTIN PF_M_refreshhostcache(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) -{ - MasterInfo_Refresh(); -} -//float gethostcachenumber(float fld, float hostnr) = #621; -void QCBUILTIN PF_M_gethostcachenumber(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) -{ - float ret = 0; - int keynum = G_FLOAT(OFS_PARM0); - int svnum = G_FLOAT(OFS_PARM1); - serverinfo_t *sv; - sv = Master_SortedServer(svnum); - - ret = Master_ReadKeyFloat(sv, keynum); - - G_FLOAT(OFS_RETURN) = ret; -} -void QCBUILTIN PF_M_gethostcachestring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) -{ - char *ret; - int keynum = G_FLOAT(OFS_PARM0); - int svnum = G_FLOAT(OFS_PARM1); - serverinfo_t *sv; - - sv = Master_SortedServer(svnum); - ret = Master_ReadKeyString(sv, keynum); - - RETURN_TSTRING(ret); -} - -//float gethostcacheindexforkey(string key) = #622; -void QCBUILTIN PF_M_gethostcacheindexforkey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) -{ - char *keyname = PR_GetStringOfs(prinst, OFS_PARM0); - - G_FLOAT(OFS_RETURN) = Master_KeyForName(keyname); -} -//void addwantedhostcachekey(string key) = #623; -void QCBUILTIN PF_M_addwantedhostcachekey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) -{ - PF_M_gethostcacheindexforkey(prinst, pr_globals); -} - -void QCBUILTIN PF_M_getextresponse(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) -{ - //this does something weird - G_INT(OFS_RETURN) = 0; -} - -void QCBUILTIN PF_netaddress_resolve(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) -{ - char *address = PR_GetStringOfs(prinst, OFS_PARM0); - netadr_t adr; - char result[256]; - if (NET_StringToAdr(address, &adr)) - RETURN_TSTRING(NET_AdrToString (result, sizeof(result), adr)); - else - RETURN_TSTRING(""); -} -#else - -void PF_gethostcachevalue (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;} -void PF_gethostcachestring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) {G_INT(OFS_RETURN) = 0;} -//void resethostcachemasks(void) = #615; -void PF_M_resethostcachemasks(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){} -//void sethostcachemaskstring(float mask, float fld, string str, float op) = #616; -void PF_M_sethostcachemaskstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){} -//void sethostcachemasknumber(float mask, float fld, float num, float op) = #617; -void PF_M_sethostcachemasknumber(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){} -//void resorthostcache(void) = #618; -void PF_M_resorthostcache(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){} -//void sethostcachesort(float fld, float descending) = #619; -void PF_M_sethostcachesort(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){} -//void refreshhostcache(void) = #620; -void PF_M_refreshhostcache(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) {} -//float gethostcachenumber(float fld, float hostnr) = #621; -void PF_M_gethostcachenumber(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;} -//float gethostcacheindexforkey(string key) = #622; -void PF_M_gethostcacheindexforkey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;} -//void addwantedhostcachekey(string key) = #623; -void PF_M_addwantedhostcachekey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){} -#endif - - void QCBUILTIN PF_localsound (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *soundname = PR_GetStringOfs(prinst, OFS_PARM0); @@ -1491,6 +1308,11 @@ static struct { //gap {"shaderforname", PF_shaderforname, 238}, //gap + {"print", PF_print, 339}, + {"keynumtostring", PF_cl_keynumtostring, 340}, + {"stringtokeynum", PF_cl_stringtokeynum, 341}, + {"getkeybind", PF_cl_getkeybind, 342}, + //gap {"isdemo", PF_isdemo, 349}, //gap {"findfont", PF_CL_findfont, 356}, @@ -1585,33 +1407,29 @@ static struct { {"getresolution", PF_cl_getresolution, 608}, {"keynumtostring", PF_cl_keynumtostring, 609}, {"findkeysforcommand", PF_cl_findkeysforcommand, 610}, -#ifdef CL_MASTER - {"gethostcachevalue", PF_M_gethostcachevalue, 611}, - {"gethostcachestring", PF_M_gethostcachestring, 612}, -#endif + {"gethostcachevalue", PF_cl_gethostcachevalue, 611}, + {"gethostcachestring", PF_cl_gethostcachestring, 612}, {"parseentitydata", PF_parseentitydata, 613}, {"stringtokeynum", PF_cl_stringtokeynum, 614}, - {"resethostcachemasks", PF_M_resethostcachemasks, 615}, - {"sethostcachemaskstring", PF_M_sethostcachemaskstring,616}, - {"sethostcachemasknumber", PF_M_sethostcachemasknumber,617}, - {"resorthostcache", PF_M_resorthostcache, 618}, - {"sethostcachesort", PF_M_sethostcachesort, 619}, - {"refreshhostcache", PF_M_refreshhostcache, 620}, - {"gethostcachenumber", PF_M_gethostcachenumber, 621}, - {"gethostcacheindexforkey", PF_M_gethostcacheindexforkey,622}, - {"addwantedhostcachekey", PF_M_addwantedhostcachekey, 623}, -#ifdef CL_MASTER - {"getextresponse", PF_M_getextresponse, 624}, + {"resethostcachemasks", PF_cl_resethostcachemasks, 615}, + {"sethostcachemaskstring", PF_cl_sethostcachemaskstring,616}, + {"sethostcachemasknumber", PF_cl_sethostcachemasknumber,617}, + {"resorthostcache", PF_cl_resorthostcache, 618}, + {"sethostcachesort", PF_cl_sethostcachesort, 619}, + {"refreshhostcache", PF_cl_refreshhostcache, 620}, + {"gethostcachenumber", PF_cl_gethostcachenumber, 621}, + {"gethostcacheindexforkey", PF_cl_gethostcacheindexforkey,622}, + {"addwantedhostcachekey", PF_cl_addwantedhostcachekey,623}, + {"getextresponse", PF_cl_getextresponse, 624}, {"netaddress_resolve", PF_netaddress_resolve, 625}, -#endif //gap {"sprintf", PF_sprintf, 627}, //gap {"setkeybind", PF_Fixme, 630}, - {"getbindmaps", PF_Fixme, 631}, - {"setbindmaps", PF_Fixme, 632}, + {"getbindmaps", PF_cl_GetBindMap, 631}, + {"setbindmaps", PF_cl_SetBindMap, 632}, {"crypto_getkeyfp", PF_crypto_getkeyfp, 633}, {"crypto_getidfp", PF_crypto_getidfp, 634}, {"crypto_getencryptlevel", PF_crypto_getencryptlevel, 635}, @@ -1659,10 +1477,10 @@ void M_Init_Internal (void); void M_DeInit_Internal (void); int inmenuprogs; -pubprogfuncs_t *menuprogs; progparms_t menuprogparms; menuedict_t *menu_edicts; int num_menu_edicts; +world_t menu_world; func_t mp_init_function; func_t mp_shutdown_function; @@ -1680,7 +1498,7 @@ void MP_Shutdown (void) { extern int mouseusedforgui; func_t temp; - if (!menuprogs) + if (!menu_world.progs) return; /* { @@ -1695,11 +1513,11 @@ void MP_Shutdown (void) temp = mp_shutdown_function; mp_shutdown_function = 0; if (temp && !inmenuprogs) - PR_ExecuteProgram(menuprogs, temp); + PR_ExecuteProgram(menu_world.progs, temp); - PR_Common_Shutdown(menuprogs, false); - menuprogs->CloseProgs(menuprogs); - menuprogs = NULL; + PR_Common_Shutdown(menu_world.progs, false); + menu_world.progs->CloseProgs(menu_world.progs); + memset(&menu_world, 0, sizeof(menu_world)); PR_ResetFonts(true); #ifdef CL_MASTER @@ -1732,7 +1550,7 @@ void VARGS Menu_Abort (char *format, ...) char *buffer; int size = 1024*1024*8; buffer = Z_Malloc(size); - menuprogs->save_ents(menuprogs, buffer, &size, 3); + menu_world.progs->save_ents(menu_world.progs, buffer, &size, 3); COM_WriteFile("menucore.txt", buffer, size); Z_Free(buffer); } @@ -1749,9 +1567,9 @@ void VARGS Menu_Abort (char *format, ...) void MP_CvarChanged(cvar_t *var) { - if (menuprogs) + if (menu_world.progs) { - PR_AutoCvar(menuprogs, var); + PR_AutoCvar(menu_world.progs, var); } } @@ -1809,17 +1627,18 @@ qboolean MP_Init (void) menuprogparms.useeditor = NULL;//sorry... QCEditor;//void (*useeditor) (char *filename, int line, int nump, char **parms); menuprogparms.useeditor = QCEditor;//void (*useeditor) (char *filename, int line, int nump, char **parms); + menuprogparms.user = &menu_world; menutime = Sys_DoubleTime(); - if (!menuprogs) + if (!menu_world.progs) { Con_DPrintf("Initializing menu.dat\n"); - menuprogs = InitProgs(&menuprogparms); - PR_Configure(menuprogs, 64*1024*1024, 1); - if (PR_LoadProgs(menuprogs, "menu.dat", 10020, NULL, 0) < 0) //no per-progs builtins. + menu_world.progs = InitProgs(&menuprogparms); + PR_Configure(menu_world.progs, 64*1024*1024, 1); + if (PR_LoadProgs(menu_world.progs, "menu.dat", 10020, NULL, 0) < 0) //no per-progs builtins. { //failed to load or something -// CloseProgs(menuprogs); +// CloseProgs(menu_world.progs); // menuprogs = NULL; return false; } @@ -1831,33 +1650,33 @@ qboolean MP_Init (void) } inmenuprogs++; - PF_InitTempStrings(menuprogs); + PF_InitTempStrings(menu_world.progs); - mp_time = (float*)PR_FindGlobal(menuprogs, "time", 0, NULL); + mp_time = (float*)PR_FindGlobal(menu_world.progs, "time", 0, NULL); if (mp_time) *mp_time = Sys_DoubleTime(); - mp_globs.drawfont = (float*)PR_FindGlobal(menuprogs, "drawfont", 0, NULL); - mp_globs.drawfontscale = (float*)PR_FindGlobal(menuprogs, "drawfontscale", 0, NULL); + menu_world.g.drawfont = (float*)PR_FindGlobal(menu_world.progs, "drawfont", 0, NULL); + menu_world.g.drawfontscale = (float*)PR_FindGlobal(menu_world.progs, "drawfontscale", 0, NULL); - PR_AutoCvarSetup(menuprogs); + PR_AutoCvarSetup(menu_world.progs); - menuentsize = PR_InitEnts(menuprogs, 8192); + menuentsize = PR_InitEnts(menu_world.progs, 8192); //'world' edict -// EDICT_NUM(menuprogs, 0)->readonly = true; - EDICT_NUM(menuprogs, 0)->isfree = false; +// EDICT_NUM(menu_world.progs, 0)->readonly = true; + EDICT_NUM(menu_world.progs, 0)->isfree = false; - mp_init_function = PR_FindFunction(menuprogs, "m_init", PR_ANY); - mp_shutdown_function = PR_FindFunction(menuprogs, "m_shutdown", PR_ANY); - mp_draw_function = PR_FindFunction(menuprogs, "m_draw", PR_ANY); - mp_keydown_function = PR_FindFunction(menuprogs, "m_keydown", PR_ANY); - mp_keyup_function = PR_FindFunction(menuprogs, "m_keyup", PR_ANY); - mp_toggle_function = PR_FindFunction(menuprogs, "m_toggle", PR_ANY); + mp_init_function = PR_FindFunction(menu_world.progs, "m_init", PR_ANY); + mp_shutdown_function = PR_FindFunction(menu_world.progs, "m_shutdown", PR_ANY); + mp_draw_function = PR_FindFunction(menu_world.progs, "m_draw", PR_ANY); + mp_keydown_function = PR_FindFunction(menu_world.progs, "m_keydown", PR_ANY); + mp_keyup_function = PR_FindFunction(menu_world.progs, "m_keyup", PR_ANY); + mp_toggle_function = PR_FindFunction(menu_world.progs, "m_toggle", PR_ANY); if (mp_init_function) - PR_ExecuteProgram(menuprogs, mp_init_function); + PR_ExecuteProgram(menu_world.progs, mp_init_function); inmenuprogs--; Con_DPrintf("Initialized menu.dat\n"); @@ -1870,20 +1689,20 @@ static void MP_GameCommand_f(void) { void *pr_globals; func_t gamecommand; - if (!menuprogs) + if (!menu_world.progs) return; - gamecommand = PR_FindFunction(menuprogs, "GameCommand", PR_ANY); + gamecommand = PR_FindFunction(menu_world.progs, "GameCommand", PR_ANY); if (!gamecommand) return; - pr_globals = PR_globals(menuprogs, PR_CURRENT); - (((string_t *)pr_globals)[OFS_PARM0] = PR_TempString(menuprogs, Cmd_Args())); - PR_ExecuteProgram (menuprogs, gamecommand); + pr_globals = PR_globals(menu_world.progs, PR_CURRENT); + (((string_t *)pr_globals)[OFS_PARM0] = PR_TempString(menu_world.progs, Cmd_Args())); + PR_ExecuteProgram (menu_world.progs, gamecommand); } void MP_CoreDump_f(void) { - if (!menuprogs) + if (!menu_world.progs) { Con_Printf("Can't core dump, you need to be running the CSQC progs first."); return; @@ -1892,7 +1711,7 @@ void MP_CoreDump_f(void) { int size = 1024*1024*8; char *buffer = BZ_Malloc(size); - menuprogs->save_ents(menuprogs, buffer, &size, 3); + menu_world.progs->save_ents(menu_world.progs, buffer, &size, 3); COM_WriteFile("menucore.txt", buffer, size); BZ_Free(buffer); } @@ -1911,13 +1730,13 @@ void MP_Breakpoint_f(void) char *filename = Cmd_Argv(1); int line = atoi(Cmd_Argv(2)); - if (!menuprogs) + if (!menu_world.progs) { Con_Printf("Menu not running\n"); return; } - wasset = menuprogs->ToggleBreak(menuprogs, filename, line, 3); - isset = menuprogs->ToggleBreak(menuprogs, filename, line, 2); + wasset = menu_world.progs->ToggleBreak(menu_world.progs, filename, line, 3); + isset = menu_world.progs->ToggleBreak(menu_world.progs, filename, line, 2); if (wasset == isset) Con_Printf("Breakpoint was not valid\n"); @@ -1944,7 +1763,7 @@ void MP_RegisterCvarsAndCmds(void) void MP_Draw(void) { - if (!menuprogs) + if (!menu_world.progs) return; if (setjmp(mp_abort)) return; @@ -1955,7 +1774,7 @@ void MP_Draw(void) inmenuprogs++; if (mp_draw_function) - PR_ExecuteProgram(menuprogs, mp_draw_function); + PR_ExecuteProgram(menu_world.progs, mp_draw_function); inmenuprogs--; } @@ -1996,10 +1815,10 @@ void MP_Keydown(int key, int unicode) inmenuprogs++; if (mp_keydown_function) { - void *pr_globals = PR_globals(menuprogs, PR_CURRENT); + void *pr_globals = PR_globals(menu_world.progs, PR_CURRENT); G_FLOAT(OFS_PARM0) = MP_TranslateFTEtoDPCodes(key); G_FLOAT(OFS_PARM1) = unicode; - PR_ExecuteProgram(menuprogs, mp_keydown_function); + PR_ExecuteProgram(menu_world.progs, mp_keydown_function); } inmenuprogs--; } @@ -2021,17 +1840,17 @@ void MP_Keyup(int key, int unicode) inmenuprogs++; if (mp_keyup_function) { - void *pr_globals = PR_globals(menuprogs, PR_CURRENT); + void *pr_globals = PR_globals(menu_world.progs, PR_CURRENT); G_FLOAT(OFS_PARM0) = MP_TranslateFTEtoDPCodes(key); G_FLOAT(OFS_PARM1) = unicode; - PR_ExecuteProgram(menuprogs, mp_keyup_function); + PR_ExecuteProgram(menu_world.progs, mp_keyup_function); } inmenuprogs--; } qboolean MP_Toggle(void) { - if (!menuprogs) + if (!menu_world.progs) return false; #ifdef TEXTEDITOR if (editormodal) @@ -2048,9 +1867,9 @@ qboolean MP_Toggle(void) inmenuprogs++; if (mp_toggle_function) { - void *pr_globals = PR_globals(menuprogs, PR_CURRENT); + void *pr_globals = PR_globals(menu_world.progs, PR_CURRENT); G_FLOAT(OFS_PARM0) = 1; - PR_ExecuteProgram(menuprogs, mp_toggle_function); + PR_ExecuteProgram(menu_world.progs, mp_toggle_function); } inmenuprogs--; diff --git a/engine/client/quakedef.h b/engine/client/quakedef.h index 3a71e02cb..fac9c3f7f 100644 --- a/engine/client/quakedef.h +++ b/engine/client/quakedef.h @@ -84,6 +84,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #pragma warning( 4 : 4267) //truncation from const double to float +#pragma warning( 4 : 4710) //function not inlined #pragma warning( error : 4020) diff --git a/engine/client/r_2d.c b/engine/client/r_2d.c index 30ef487de..f591e3dc1 100644 --- a/engine/client/r_2d.c +++ b/engine/client/r_2d.c @@ -1103,7 +1103,7 @@ void R2D_DrawCrosshair(void) int sc; float sx, sy, sizex, sizey; - float size, chc; + float size; if (crosshair.ival < 1) return; @@ -1112,7 +1112,7 @@ void R2D_DrawCrosshair(void) if (crosshair.ival == 1 && !crosshairimage.string[0]) { // adjust console crosshair scale to match default - size = crosshairsize.value / 8; + size = crosshairsize.value; if (size == 0) size = 8; else if (size < 0) @@ -1121,8 +1121,8 @@ void R2D_DrawCrosshair(void) { SCR_CrosshairPosition(sc, &x, &y); Font_BeginScaledString(font_conchar, x, y, size, size, &sx, &sy); - sx -= Font_CharWidth('+' | 0xe000 | CON_WHITEMASK)/2; - sy -= Font_CharHeight()/2; + sx -= Font_CharScaleWidth('+' | 0xe000 | CON_WHITEMASK)/2; + sy -= Font_CharScaleHeight()/2; Font_ForceColour(ch_color[0], ch_color[1], ch_color[2], crosshairalpha.value); Font_DrawScaleChar(sx, sy, '+' | 0xe000 | CON_WHITEMASK); Font_InvalidateColour(); @@ -1138,13 +1138,11 @@ void R2D_DrawCrosshair(void) size = -size; sizex = size; sizey = size; - chc = 0; } else { sizex = (size*vid.rotpixelwidth) / (float)vid.width; sizey = (size*vid.rotpixelheight) / (float)vid.height; - chc = size / 16.0; } sizex = (int)sizex; @@ -1159,8 +1157,8 @@ void R2D_DrawCrosshair(void) SCR_CrosshairPosition(sc, &x, &y); //translate to pixel coord, for rounding - x = ((x-sizex-chc)*vid.rotpixelwidth) / (float)vid.width; - y = ((y-sizey-chc)*vid.rotpixelheight) / (float)vid.height; + x = ((x-sizex+(sizex/CS_WIDTH))*vid.rotpixelwidth) / (float)vid.width; + y = ((y-sizey+(sizey/CS_HEIGHT))*vid.rotpixelheight) / (float)vid.height; //translate to screen coords sx = ((x)*(int)vid.width) / (float)vid.rotpixelwidth; diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 1db09a970..d0f111886 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -1365,7 +1365,7 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n")); } } - Skin_FlushPlayers(); + Skin_FlushAll(); #ifdef CSQC_DAT CSQC_RendererRestarted(); diff --git a/engine/client/sbar.c b/engine/client/sbar.c index f167ab6f0..63f26a6e5 100644 --- a/engine/client/sbar.c +++ b/engine/client/sbar.c @@ -1850,7 +1850,7 @@ void Sbar_DrawScoreboard (void) #ifndef CLIENTONLY /*no scoreboard in single player (if you want bots, set deathmatch)*/ - if (sv.state && cls.gamemode == GAME_COOP && sv.allocated_client_slots == 1) + if (sv.state && !cls.deathmatch && sv.allocated_client_slots == 1) { return; } @@ -2474,7 +2474,7 @@ void Sbar_Draw (void) { if (!pnum) { - if (cls.gamemode != GAME_DEATHMATCH) + if (!cls.deathmatch) Sbar_CoopScoreboard (); else Sbar_SoloScoreboard (); @@ -3292,7 +3292,7 @@ void Sbar_IntermissionOverlay (void) Sbar_Start(); - if (cls.gamemode != GAME_DEATHMATCH) + if (!cls.deathmatch) Sbar_CoopIntermission(); else if (cl.teamplay > 0 && !sb_showscores) Sbar_TeamOverlay (); diff --git a/engine/client/screen.h b/engine/client/screen.h index b52498cee..7e3c31328 100644 --- a/engine/client/screen.h +++ b/engine/client/screen.h @@ -105,7 +105,9 @@ void Font_BeginString(struct font_s *font, int vx, int vy, int *px, int *py); void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, float szy, float *px, float *py); /*avoid using*/ void Font_Transform(int vx, int vy, int *px, int *py); int Font_CharHeight(void); +float Font_CharScaleHeight(void); int Font_CharWidth(unsigned int charcode); +float Font_CharScaleWidth(unsigned int charcode); int Font_CharEndCoord(struct font_s *font, int x, unsigned int charcode); int Font_DrawChar(int px, int py, unsigned int charcode); float Font_DrawScaleChar(float px, float py, unsigned int charcode); /*avoid using*/ diff --git a/engine/client/skin.c b/engine/client/skin.c index 6e93b2872..2ea796824 100644 --- a/engine/client/skin.c +++ b/engine/client/skin.c @@ -590,6 +590,19 @@ void Skin_FlushPlayers(void) CL_NewTranslation(i); } +void Skin_FlushAll(void) +{ //wipe the skin info + int i; + for (i=0 ; isn.speed); - - ambient_sfx[AMBIENT_WATER] = S_PrecacheSound ("ambience/water1.wav"); - ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav"); - - S_StopAllSounds (true); } @@ -1279,6 +1269,13 @@ void S_Purge(qboolean retaintouched) sfx_t *sfx; int i; + //make sure ambients are kept. silly ambients. + if (retaintouched) + { + ambient_sfx[AMBIENT_WATER] = S_PrecacheSound ("ambience/water1.wav"); + ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav"); + } + S_LockMixer(); for (i=0 ; i < num_sfx ; i++) { @@ -1438,8 +1435,9 @@ void SND_Spatialize(soundcardinfo_t *sc, channel_t *ch) dist = VectorNormalize(world_vec) * ch->dist_mult; - listener_vec[1] = DotProduct(listener_right, world_vec); + //rotate the world_vec into listener space, so that the audio direction stored in the speakerdir array can be used directly. listener_vec[0] = DotProduct(listener_forward, world_vec); + listener_vec[1] = DotProduct(listener_right, world_vec); listener_vec[2] = DotProduct(listener_up, world_vec); if (snd_leftisright.ival) @@ -1447,9 +1445,7 @@ void SND_Spatialize(soundcardinfo_t *sc, channel_t *ch) for (i = 0; i < sc->sn.numchannels; i++) { - scale = (1 + DotProduct(listener_vec, sc->speakerdir[i])) / 2; - if (scale > 1) - scale = 1; + scale = 1 + DotProduct(listener_vec, sc->speakerdir[i]); scale = (1.0 - dist) * scale * sc->dist[i]; ch->vol[i] = (int) (ch->master_vol * scale); if (ch->vol[i] < 0) @@ -1813,7 +1809,7 @@ void S_UpdateAmbientSounds (soundcardinfo_t *sc) return; l = Q1BSP_LeafForPoint(cl.worldmodel, listener_origin); - if (!l || !ambient_level.value) + if (!l || ambient_level.value <= 0) { for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++) { diff --git a/engine/client/snd_mix.c b/engine/client/snd_mix.c index 21f55d543..7e6881079 100644 --- a/engine/client/snd_mix.c +++ b/engine/client/snd_mix.c @@ -146,7 +146,32 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime) if (!s) continue; if (!ch->vol[0] && !ch->vol[1] && !ch->vol[2] && !ch->vol[3] && !ch->vol[4] && !ch->vol[5]) + { + //does it still make a sound if it cannot be heard?... + //technically no... + //this code is hacky. + if (!s->decoder.decodedata && s->decoder.buf) + { + scache = s->decoder.buf; + ch->pos += (end-sc->paintedtime)*ch->rate; + if (ch->pos > scache->length) + { + ch->pos = 0; + if (scache->loopstart != -1) + ch->pos = scache->loopstart<looping) + { + ch->sfx = NULL; + if (s->decoder.abort) + { + if (!S_IsPlayingSomewhere(s)) + s->decoder.abort(s); + } + } + } + } continue; + } ltime = sc->paintedtime; while (ltime < end) diff --git a/engine/client/textedit.c b/engine/client/textedit.c index 80439e587..c765c9dc1 100644 --- a/engine/client/textedit.c +++ b/engine/client/textedit.c @@ -32,6 +32,7 @@ static cvar_t editstripcr = CVARD("edit_stripcr", "1", "remove \\r from eols (on static cvar_t editaddcr = CVARD("edit_addcr", editaddcr_default, "make sure that each line ends with a \\r (on save)"); static cvar_t edittabspacing = CVARD("edit_tabsize", "4", "How wide tab alignment is"); cvar_t debugger = CVARD("debugger", debugger_default, "When enabled, QC errors and debug events will enable step-by-step tracing."); +extern cvar_t pr_sourcedir; static pubprogfuncs_t *editprogfuncs; @@ -83,6 +84,7 @@ static char OpenEditorFile[256]; qboolean editoractive; //(export) +keydest_t editor_oldkeydest = key_game; qboolean editormodal; //doesn't return. (export) static qboolean madechanges; static qboolean editenabled; @@ -187,7 +189,8 @@ static void CloseEditor(void) { fileblock_t *b; - key_dest = key_game; + if (key_dest == key_editor) + key_dest = editor_oldkeydest; editoractive = false; editprogfuncs = NULL; @@ -280,6 +283,7 @@ static void EditorNewFile(void) madechanges = true; executionlinenum = -1; + editor_oldkeydest = key_dest; key_dest = key_editor; editoractive = true; editenabled = true; @@ -299,7 +303,7 @@ static void EditorOpenFile(char *name, qboolean readonly) if (!(F = FS_OpenVFS(OpenEditorFile, "rb", FS_GAME))) { - Q_snprintfz(OpenEditorFile, sizeof(OpenEditorFile), "src/%s", name); + Q_snprintfz(OpenEditorFile, sizeof(OpenEditorFile), "%s/%s", pr_sourcedir.string, name); if (!(F = FS_OpenVFS(OpenEditorFile, "rb", FS_GAME))) { Con_Printf("Couldn't open file \"%s\"\nA new file will be created\n", name); @@ -382,6 +386,7 @@ static void EditorOpenFile(char *name, qboolean readonly) executionlinenum = -1; editenabled = !readonly; + editor_oldkeydest = key_dest; key_dest = key_editor; editoractive = true; } @@ -1066,7 +1071,14 @@ void Editor_Draw(void) fileblock_t *b; if (key_dest != key_console) + { + if (editor_oldkeydest == key_menu && !editormodal) + { + CloseEditor(); + return; + } key_dest = key_editor; + } if ((editoractive && cls.state == ca_disconnected) || editormodal) R2D_EditorBackground(); @@ -1211,6 +1223,10 @@ int QCLibEditor(pubprogfuncs_t *prfncs, char *filename, int line, int statement, f1 += 4; if (!strncmp(f2, "src/", 4)) f2 += 4; + if (!strncmp(f1, "source/", 7)) + f1 += 7; + if (!strncmp(f2, "source/", 7)) + f2 += 7; stepasm = line < 0; @@ -1263,6 +1279,7 @@ int QCLibEditor(pubprogfuncs_t *prfncs, char *filename, int line, int statement, if (!parms) { + int oldkeydest = key_dest; double oldrealtime = realtime; editormodal = true; @@ -1280,6 +1297,7 @@ int QCLibEditor(pubprogfuncs_t *prfncs, char *filename, int line, int statement, } realtime = oldrealtime; + key_dest = oldkeydest; editormodal = false; } diff --git a/engine/client/view.c b/engine/client/view.c index 293c1095c..744ffa013 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -235,7 +235,7 @@ void V_DriftPitch (int pnum) // don't count small mouse motion if (cl.playerview[pnum].nodrift) { - if ( fabs(cl.frames[(cls.netchan.outgoing_sequence-1)&UPDATE_MASK].cmd[pnum].forwardmove) < 200) + if ( fabs(cl.outframes[(cl.movesequence-1)&UPDATE_MASK].cmd[pnum].forwardmove) < 200) cl.playerview[pnum].driftmove = 0; else cl.playerview[pnum].driftmove += host_frametime; diff --git a/engine/client/zqtp.c b/engine/client/zqtp.c index d94b35355..226f53f19 100644 --- a/engine/client/zqtp.c +++ b/engine/client/zqtp.c @@ -523,7 +523,7 @@ static char *Macro_Powerups (void) if (cl.playerview[SP].stats[STAT_ITEMS] & IT_INVISIBILITY) MacroBuf_strcat_with_separator (tp_name_ring.string); - effects = cl.frames[cl.parsecount&UPDATE_MASK].playerstate[cl.playernum[SP]].effects; + effects = cl.inframes[cl.parsecount&UPDATE_MASK].playerstate[cl.playernum[SP]].effects; if ( (effects & (QWEF_FLAG1|QWEF_FLAG2)) || // CTF (cl.teamfortress && cl.playerview[SP].stats[STAT_ITEMS] & (IT_KEY1|IT_KEY2)) ) // TF MacroBuf_strcat_with_separator (tp_name_flag.string); @@ -879,7 +879,7 @@ static void CountNearbyPlayers(qboolean dead) if (!cl.oldparsecount || !cl.parsecount || cls.state < ca_active) return; - state = cl.frames[cl.oldparsecount & UPDATE_MASK].playerstate; + state = cl.inframes[cl.oldparsecount & UPDATE_MASK].playerstate; info = cl.players; for (i = 0; i < MAX_CLIENTS; i++, info++, state++) { if (i != cl.playernum[0] && state->messagenum == cl.oldparsecount && !info->spectator && !ISDEAD(state->frame)) { @@ -2502,7 +2502,7 @@ static void TP_FindModelNumbers (void) // for armors, returns skinnum+1 on success static int FindNearestItem (int flags, item_t **pitem) { - frame_t *frame; + inframe_t *frame; packet_entities_t *pak; entity_state_t *ent; int i = 0, bestidx = 0, bestskin = 0; @@ -2510,11 +2510,11 @@ static int FindNearestItem (int flags, item_t **pitem) vec3_t org, v; item_t *item; - VectorCopy (cl.frames[cl.validsequence&UPDATE_MASK] + VectorCopy (cl.inframes[cl.validsequence&UPDATE_MASK] .playerstate[cl.playernum[SP]].origin, org); // look in previous frame - frame = &cl.frames[cl.oldvalidsequence&UPDATE_MASK]; + frame = &cl.inframes[cl.oldvalidsequence&UPDATE_MASK]; pak = &frame->packet_entities; bestdist = 100.0f; bestidx = 0; @@ -2651,7 +2651,7 @@ void TP_ParsePlayerInfo(player_state_t *oldstate, player_state_t *state, player_ { if ((state->effects & (QWEF_FLAG1|QWEF_FLAG2)) && !(oldstate->effects & (QWEF_FLAG1|QWEF_FLAG2))) { - ExecTookTrigger (tp_name_flag.string, it_flag, cl.frames[cl.validsequence & UPDATE_MASK].playerstate[cl.playernum[SP]].origin); + ExecTookTrigger (tp_name_flag.string, it_flag, cl.inframes[cl.validsequence & UPDATE_MASK].playerstate[cl.playernum[SP]].origin); } else if (!(state->effects & (QWEF_FLAG1|QWEF_FLAG2)) && (oldstate->effects & (QWEF_FLAG1|QWEF_FLAG2))) { @@ -2938,7 +2938,7 @@ static void TP_FindPoint (void) pointflags_dmm &= ~it_weapons; } - pak = &cl.frames[cl.validsequence & UPDATE_MASK].packet_entities; + pak = &cl.inframes[cl.validsequence & UPDATE_MASK].packet_entities; for (i = 0,ent = pak->entities; i < pak->num_entities; i++, ent++) { item = model2item[ent->modelindex]; @@ -2972,7 +2972,7 @@ static void TP_FindPoint (void) } } - state = cl.frames[cl.parsecount & UPDATE_MASK].playerstate; + state = cl.inframes[cl.parsecount & UPDATE_MASK].playerstate; info = cl.players; for (j = 0; j < MAX_CLIENTS; j++, info++, state++) { @@ -3177,7 +3177,7 @@ void TP_StatChanged (int stat, int value) if (cl.teamfortress && !cl.spectator) { ExecTookTrigger (tp_name_flag.string, it_flag, - cl.frames[cl.validsequence&UPDATE_MASK].playerstate[cl.playernum[SP]].origin); + cl.inframes[cl.validsequence&UPDATE_MASK].playerstate[cl.playernum[SP]].origin); } } diff --git a/engine/common/cvar.h b/engine/common/cvar.h index d8f277d4e..cb2a014bd 100644 --- a/engine/common/cvar.h +++ b/engine/common/cvar.h @@ -92,6 +92,7 @@ typedef struct cvar_s #define CVARAFC(ConsoleName,Value,ConsoleName2,Flags,Callback) CVARAFC(ConsoleName, Value, ConsoleName2, Flags, NULL, Callback) #define CVARAF(ConsoleName,Value,ConsoleName2,Flags) CVARAFDC(ConsoleName, Value, ConsoleName2, Flags, NULL, NULL) #define CVARFC(ConsoleName,Value,Flags,Callback) CVARAFDC(ConsoleName, Value, NULL, Flags, NULL, Callback) +#define CVARAD(ConsoleName,Value,ConsoleName2,Description) CVARAFDC(ConsoleName, Value, ConsoleName2, 0, Description, NULL) #define CVARFD(ConsoleName,Value,Flags,Description) CVARAFDC(ConsoleName, Value, NULL, Flags, Description, NULL) #define CVARF(ConsoleName,Value,Flags) CVARFC(ConsoleName, Value, Flags, NULL) #define CVARC(ConsoleName,Value,Callback) CVARFC(ConsoleName, Value, 0, Callback) diff --git a/engine/common/net.h b/engine/common/net.h index c7f77aca1..64e4f789f 100644 --- a/engine/common/net.h +++ b/engine/common/net.h @@ -97,7 +97,7 @@ qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b); char *NET_AdrToString (char *s, int len, netadr_t a); char *NET_BaseAdrToString (char *s, int len, netadr_t a); qboolean NET_StringToSockaddr (const char *s, int defaultport, struct sockaddr_qstorage *sadr, int *addrfamily, int *addrsize); -qboolean NET_StringToAdr (const char *s, netadr_t *a); +qboolean NET_StringToAdr (const char *s, int defaultport, netadr_t *a); qboolean NET_IsClientLegal(netadr_t *adr); qboolean NET_IsLoopBackAddress (netadr_t adr); diff --git a/engine/common/net_chan.c b/engine/common/net_chan.c index 61a6c7903..77bffdb81 100644 --- a/engine/common/net_chan.c +++ b/engine/common/net_chan.c @@ -196,6 +196,7 @@ unsigned int Net_PextMask(int maskset, qboolean fornq) if (pext_replacementdeltas.ival) mask |= PEXT2_REPLACEMENTDELTAS; + //mask |= PEXT2_PREDINFO; if (MAX_CLIENTS != QWMAX_CLIENTS) mask |= PEXT2_MAXPLAYERS; @@ -203,7 +204,7 @@ unsigned int Net_PextMask(int maskset, qboolean fornq) if (fornq) { //only ones that are tested - mask &= PEXT2_VOICECHAT | PEXT2_REPLACEMENTDELTAS; + mask &= PEXT2_VOICECHAT | PEXT2_REPLACEMENTDELTAS | PEXT2_PREDINFO; } } @@ -431,13 +432,13 @@ nqprot_t NQNetChan_Process(netchan_t *chan) { if (sequence <= chan->incoming_unreliable) { - Con_DPrintf("Stale datagram recieved\n"); + Con_DPrintf("Stale datagram recieved (%i<=%i)\n", sequence, chan->incoming_unreliable); return NQP_ERROR; } drop = sequence - chan->incoming_unreliable - 1; if (drop > 0) { - Con_DPrintf("Dropped %i datagrams\n", drop); + Con_DPrintf("Dropped %i datagrams (%i - %i)\n", chan->incoming_unreliable+1, sequence-1); chan->drop_count += drop; } chan->incoming_unreliable = sequence; diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index 4c6313cf1..895953a58 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -856,7 +856,7 @@ dblbreak: accepts anything that NET_StringToSockaddr accepts plus certain url schemes including: tcp, irc */ -qboolean NET_StringToAdr (const char *s, netadr_t *a) +qboolean NET_StringToAdr (const char *s, int defaultport, netadr_t *a) { struct sockaddr_qstorage sadr; @@ -1116,7 +1116,7 @@ qboolean NET_StringToAdrMasked (const char *s, netadr_t *a, netadr_t *amask) i = sizeof(t); Q_strncpyz(t, s, i); - if (!ParsePartialIPv4(t, a) && !NET_StringToAdr(t, a)) + if (!ParsePartialIPv4(t, a) && !NET_StringToAdr(t, 0, a)) return false; spoint++; @@ -1135,7 +1135,7 @@ qboolean NET_StringToAdrMasked (const char *s, netadr_t *a, netadr_t *amask) } if (c == NULL) // we have an address so resolve it and return - return ParsePartialIPv4(spoint, amask) || NET_StringToAdr(spoint, amask); + return ParsePartialIPv4(spoint, amask) || NET_StringToAdr(spoint, 0, amask); // otherwise generate mask for given bits i = atoi(spoint); @@ -1145,7 +1145,7 @@ qboolean NET_StringToAdrMasked (const char *s, netadr_t *a, netadr_t *amask) { // we don't have a slash, resolve and fill with a full mask i = ParsePartialIPv4(s, a); - if (!i && !NET_StringToAdr(s, a)) + if (!i && !NET_StringToAdr(s, 0, a)) return false; memset (amask, 0, sizeof(*amask)); @@ -1937,8 +1937,8 @@ qboolean NET_PortToAdr (int adrfamily, const char *s, netadr_t *a) char *e; int port; port = strtoul(s, &e, 10); - if (*e) - return NET_StringToAdr(s, a); + if (*e) //if *e then its not just a single number in there, so treat it as a proper address. + return NET_StringToAdr(s, 0, a); else if (port) { memset(a, 0, sizeof(*a)); @@ -3493,7 +3493,7 @@ struct ftenet_generic_connection_s *FTENET_IRCConnect_EstablishConnection(qboole ftenet_ircconnect_connection_t *newcon; netadr_t adr; - if (!NET_StringToAdr(address, &adr)) + if (!NET_StringToAdr(address, 6667, &adr)) return NULL; //couldn't resolve the name @@ -3860,7 +3860,7 @@ qboolean NET_EnsureRoute(ftenet_connections_t *collection, char *routename, char { netadr_t adr; - NET_StringToAdr(host, &adr); + NET_StringToAdr(host, 0, &adr); switch(adr.type) { @@ -4302,8 +4302,8 @@ void NET_GetLocalAddress (int socket, netadr_t *out) gethostname(buff, 512); buff[512-1] = 0; - if (!NET_StringToAdr (buff, &adr)) //urm - NET_StringToAdr ("127.0.0.1", &adr); + if (!NET_StringToAdr (buff, 0, &adr)) //urm + NET_StringToAdr ("127.0.0.1", 0, &adr); namelen = sizeof(address); @@ -4709,7 +4709,7 @@ vfsfile_t *FS_OpenTCP(const char *name) tcpfile_t *newf; int sock; netadr_t adr = {0}; - if (NET_StringToAdr(name, &adr)) + if (NET_StringToAdr(name, 0, &adr)) { sock = TCP_OpenStream(adr); if (sock == INVALID_SOCKET) diff --git a/engine/common/plugin.c b/engine/common/plugin.c index cf358cbb0..ed1ff95ed 100644 --- a/engine/common/plugin.c +++ b/engine/common/plugin.c @@ -807,24 +807,12 @@ static qintptr_t VARGS Plug_Net_TCPListen(void *offset, quintptr_t mask, const q int maxcount = VM_LONG(arg[2]); netadr_t a; - if (localip) - { - if (!NET_StringToAdr(localip, &a)) - return -1; - NetadrToSockadr(&a, &address); - } - else - { - memset(&address, 0, sizeof(address)); - ((struct sockaddr_in*)&address)->sin_family = AF_INET; - } + if (!localip) + localip = "0.0.0.0"; //pass "[::]" for ipv6 - if (((struct sockaddr_in*)&address)->sin_family == AF_INET && !((struct sockaddr_in*)&address)->sin_port) - ((struct sockaddr_in*)&address)->sin_port = htons(localport); -#ifdef IPPROTO_IPV6 - else if (((struct sockaddr_in6*)&address)->sin6_family == AF_INET6 && !((struct sockaddr_in6*)&address)->sin6_port) - ((struct sockaddr_in6*)&address)->sin6_port = htons(localport); -#endif + if (!NET_StringToAdr(localip, localport, &a)) + return -1; + NetadrToSockadr(&a, &address); switch(((struct sockaddr*)&address)->sa_family) { @@ -914,8 +902,8 @@ static qintptr_t VARGS Plug_Net_Accept(void *offset, quintptr_t mask, const qint //EBUILTIN(int, NET_TCPConnect, (char *ip, int port)); qintptr_t VARGS Plug_Net_TCPConnect(void *offset, quintptr_t mask, const qintptr_t *arg) { - char *localip = VM_POINTER(arg[0]); - unsigned short localport = VM_LONG(arg[1]); + char *remoteip = VM_POINTER(arg[0]); + unsigned short remoteport = VM_LONG(arg[1]); int handle; struct sockaddr_qstorage to, from; @@ -924,16 +912,9 @@ qintptr_t VARGS Plug_Net_TCPConnect(void *offset, quintptr_t mask, const qintptr netadr_t a; - if (!NET_StringToAdr(localip, &a)) + if (!NET_StringToAdr(remoteip, remoteport, &a)) return -1; NetadrToSockadr(&a, &to); - if (((struct sockaddr_in*)&to)->sin_family == AF_INET && !((struct sockaddr_in*)&to)->sin_port) - ((struct sockaddr_in*)&to)->sin_port = htons(localport); -#ifdef IPPROTO_IPV6 - else if (((struct sockaddr_in6*)&to)->sin6_family == AF_INET6 && !((struct sockaddr_in6*)&to)->sin6_port) - ((struct sockaddr_in6*)&to)->sin6_port = htons(localport); -#endif - if ((sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { diff --git a/engine/common/pmove.c b/engine/common/pmove.c index fec5291ba..6ab0911ff 100644 --- a/engine/common/pmove.c +++ b/engine/common/pmove.c @@ -695,6 +695,9 @@ void PM_AirMove (void) blocked = PM_StepSlideMove (true); else blocked = PM_SlideMove (); + + if (blocked & BLOCKED_FLOOR) + pmove.onground = true; } } @@ -978,6 +981,10 @@ void PM_NudgePosition (void) for (i=0 ; i<3 ; i++) base[i] = ((int)(base[i]*8)) * 0.125; + if (pmove.velocity[0] || pmove.velocity[1]) + if (PM_TestPlayerPosition (pmove.origin)) + return; + for (z=0 ; z<=4 ; z++) { for (x=0 ; x<=4 ; x++) @@ -1096,7 +1103,8 @@ void PM_PlayerMove (float gamespeed) frametime = pmove.cmd.msec * 0.001*gamespeed; pmove.numtouch = 0; - if (pmove.pm_type == PM_NONE || pmove.pm_type == PM_FREEZE) { + if (pmove.pm_type == PM_NONE || pmove.pm_type == PM_FREEZE) + { PM_CategorizePosition (); return; } diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index 993fd7c58..8c57d33b3 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -2770,7 +2770,7 @@ static void PR_uri_get_callback(struct dl_download *dl) { extern pubprogfuncs_t *menuprogs; world_t *w = dl->user_ctx; - pubprogfuncs_t *prinst = w?w->progs:menuprogs; + pubprogfuncs_t *prinst = w->progs; float id = dl->user_num; func_t func; @@ -2834,6 +2834,17 @@ void QCBUILTIN PF_uri_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob #endif G_FLOAT(OFS_RETURN) = 0; } +void QCBUILTIN PF_netaddress_resolve(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + char *address = PR_GetStringOfs(prinst, OFS_PARM0); + int defaultport = (prinst->callargc > 1)?G_FLOAT(OFS_PARM1):0; + netadr_t adr; + char result[256]; + if (NET_StringToAdr(address, defaultport, &adr)) + RETURN_TSTRING(NET_AdrToString (result, sizeof(result), adr)); + else + RETURN_TSTRING(""); +} //////////////////////////////////////////////////// //Console functions @@ -4069,7 +4080,7 @@ lh_extension_t QSG_Extensions[] = { {"FTE_PEXT_SPAWNSTATIC"}, //means that static entities can have alpha/scale and anything else the engine supports on normal ents. (Added for >256 models, while still being compatible - previous system failed with -1 skins) {"FTE_PEXT_CUSTOMTENTS", 2, NULL, {"RegisterTempEnt", "CustomTempEnt"}}, {"FTE_PEXT_256PACKETENTITIES"}, //client is able to receive unlimited packet entities (server caps itself to 256 to prevent insanity). - {"FTE_PEXT_64PLAYERS"}, + {NULL}, {"TEI_SHOWLMP2", 6, NULL, {"showpic", "hidepic", "movepic", "changepic", "showpicent", "hidepicent"}}, //telejano doesn't actually export the moveent/changeent (we don't want to either cos it would stop frik_file stuff being autoregistered) {"DP_GFX_QUAKE3MODELTAGS", 1, NULL, {"setattachment"}}, {"FTE_PK3DOWNLOADS"}, @@ -4079,7 +4090,7 @@ lh_extension_t QSG_Extensions[] = { {"PEXT_DPFLAGS"}, - //{"EXT_CSQC"}, //this is the base csqc extension. I'm not sure what needs to be separate and what does not. + {"EXT_CSQC"}, //this is the base csqc extension. I'm not sure what needs to be separate and what does not. //{"EXT_CSQC_DELTAS"},//this is a separate extension because the feature may be banned in a league due to cheat protection. //the rest are generic extensions diff --git a/engine/common/pr_common.h b/engine/common/pr_common.h index 4d45ea7fe..b7f503d32 100644 --- a/engine/common/pr_common.h +++ b/engine/common/pr_common.h @@ -325,8 +325,22 @@ void QCBUILTIN PF_R_PolygonEnd(pubprogfuncs_t *prinst, struct globalvars_s *pr_g #define PF_R_PolygonEnd PF_Fixme #endif +void QCBUILTIN PF_cl_gethostcachevalue (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_gethostcachestring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_resethostcachemasks(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_sethostcachemaskstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_sethostcachemasknumber(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_resorthostcache(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_sethostcachesort(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_refreshhostcache(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_gethostcachenumber(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_gethostcacheindexforkey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_addwantedhostcachekey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_getextresponse(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_netaddress_resolve(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_cl_getmousepos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); - +void QCBUILTIN PF_cl_GetBindMap (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_SetBindMap (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_cl_keynumtostring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_cl_findkeysforcommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_cl_stringtokeynum(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); diff --git a/engine/common/protocol.h b/engine/common/protocol.h index a4612c489..b1bc04eb5 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -75,7 +75,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define PEXT2_SETANGLEDELTA 0x00000004 #define PEXT2_REPLACEMENTDELTAS 0x00000008 #define PEXT2_MAXPLAYERS 0x00000010 //Client is able to cope with more players than 32. abs max becomes 255, due to colormap issues. -//#define PEXT2_PK3DOWNLOADS 0x10000000 //retrieve a list of pk3s/pk3s/paks for downloading (with optional URL and crcs) +#define PEXT2_PREDINFO 0x00000020 //movevars, NQ input sequences+acks. //ZQuake transparent protocol extensions. #define Z_EXT_PM_TYPE (1<<0) // basic PM_TYPE functionality (reliable jump_held) @@ -378,6 +378,9 @@ enum clcq2_ops_e #define PC_PARTICLE 0x4000 #define PC_UNUSED 0xc000 +#define GAME_COOP 0 +#define GAME_DEATHMATCH 1 + // playerinfo flags from server // playerinfo always sends: playernum, flags, origin[] and framenumber diff --git a/engine/common/translate.c b/engine/common/translate.c index 4f6e58a73..fb38a3b34 100644 --- a/engine/common/translate.c +++ b/engine/common/translate.c @@ -263,7 +263,7 @@ static char *defaultlanguagetext = -cvar_t language = SCVAR("language", "uk"); +cvar_t language = SCVAR("language", "en-gb"); char lastlang[9]; typedef struct trans_s { diff --git a/engine/gl/gl_font.c b/engine/gl/gl_font.c index abf9c26ae..df48bae6b 100644 --- a/engine/gl/gl_font.c +++ b/engine/gl/gl_font.c @@ -16,7 +16,9 @@ void Font_BeginString(struct font_s *font, int vx, int vy, int *px, int *py); void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, float szy, float *px, float *py); /*avoid using*/ void Font_Transform(int vx, int vy, int *px, int *py); int Font_CharHeight(void); +float Font_CharScaleHeight(void); int Font_CharWidth(unsigned int charcode); +float Font_CharScaleWidth(unsigned int charcode); int Font_CharEndCoord(struct font_s *font, int x, unsigned int charcode); int Font_DrawChar(int px, int py, unsigned int charcode); float Font_DrawScaleChar(float px, float py, unsigned int charcode); /*avoid using*/ @@ -1241,6 +1243,12 @@ int Font_CharHeight(void) return curfont->charheight; } +//obtains the font's row height (each row of chars should be drawn using this increment) +float Font_CharScaleHeight(void) +{ + return curfont->charheight * curfont_scale[1]; +} + /* This is where the character ends. Note: this function supports tabs - x must always be based off 0, with Font_LineDraw actually used to draw the line. @@ -1285,6 +1293,25 @@ int Font_CharWidth(unsigned int charcode) return c->advance; } +//obtains the width of a character from a given font. This is how wide it is. The next char should be drawn at x + result. +float Font_CharScaleWidth(unsigned int charcode) +{ + struct charcache_s *c; + struct font_s *font = curfont; + if (charcode&CON_HIDDEN) + return 0; + if ((charcode & CON_2NDCHARSETTEXT) && font->alt) + font = font->alt; + + c = Font_GetChar(curfont, (CHARIDXTYPE)(charcode&CON_CHARMASK)); + if (!c) + { + return 0; + } + + return c->advance * curfont_scale[0]; +} + //for a given font, calculate the line breaks and word wrapping for a block of text //start+end are the input string //starts+ends are an array of line start and end points, which have maxlines elements. diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index d7ed8b102..fdd602ef1 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -1786,7 +1786,10 @@ void RMod_LoadLighting (lump_t *l) } } else if (litdata) + { Con_Printf("lit \"%s\" isn't a lit\n", litname); + litdata = NULL; + } // else //failed to find } diff --git a/engine/gl/gl_screen.c b/engine/gl/gl_screen.c index d1a9c4b55..33d93c5a8 100644 --- a/engine/gl/gl_screen.c +++ b/engine/gl/gl_screen.c @@ -158,7 +158,7 @@ void GLSCR_UpdateScreen (void) else #endif #ifdef CSQC_DAT - if (cls.state == ca_active && CSQC_DrawView()) + if (CSQC_DrawView()) nohud = true; else #endif diff --git a/engine/gl/gl_shadow.c b/engine/gl/gl_shadow.c index bd99bd27f..ff6690802 100644 --- a/engine/gl/gl_shadow.c +++ b/engine/gl/gl_shadow.c @@ -1389,12 +1389,19 @@ static qboolean Sh_VisOverlaps(qbyte *v1, qbyte *v2) int i, m; if (!v2) return false; - m = (cl.worldmodel->numleafs-1)>>3; - for (i=0 ; inumleafs+7)>>3; + + for (i=(m&~3) ; i>=2; + for (i=0 ; i +#define STRING_SPECMASK 0xc0000000 // +#define STRING_TEMP 0x80000000 //temp string, will be collected. +#define STRING_STATIC 0xc0000000 //pointer to non-qcvm string. +#define STRING_NORMAL_ 0x00000000 //stringtable/mutable. should always be a fallthrough +#define STRING_NORMAL2_ 0x40000000 //stringtable/mutable. should always be a fallthrough + typedef struct prmemb_s { struct prmemb_s *prev; int level; @@ -384,7 +390,7 @@ static void PDECL PR_memfree (pubprogfuncs_t *ppf, void *memptr) // PR_memvalidate(progfuncs); } -void PRAddressableFlush(progfuncs_t *progfuncs, int totalammount) +void PRAddressableFlush(progfuncs_t *progfuncs, size_t totalammount) { prinst.addressableused = 0; if (totalammount < 0) //flush @@ -440,7 +446,7 @@ int PDECL PR_InitEnts(pubprogfuncs_t *ppf, int max_ents) edictrun_t tempedict; //used as a safty buffer static float tempedictfields[2048]; -void PDECL PR_Configure (pubprogfuncs_t *ppf, int addressable_size, int max_progs) //can be used to wipe all memory +void PDECL PR_Configure (pubprogfuncs_t *ppf, size_t addressable_size, int max_progs) //can be used to wipe all memory { progfuncs_t *progfuncs = (progfuncs_t*)ppf; unsigned int i; @@ -462,8 +468,16 @@ void PDECL PR_Configure (pubprogfuncs_t *ppf, int addressable_size, int max_prog } PRHunkFree(progfuncs, 0); //clear mem - our hunk may not be a real hunk. - if (addressable_size<0) + if (addressable_size<0 || addressable_size == (size_t)-1) + { +#ifdef _WIN64 + addressable_size = 0x80000000; //use of virtual address space rather than physical memory means we can just go crazy and use the max of 2gb. +#else addressable_size = 8*1024*1024; +#endif + } + if (addressable_size > 0x80000000) + addressable_size = 0x80000000; PRAddressableFlush(progfuncs, addressable_size); pr_progstate = PRHunkAlloc(progfuncs, sizeof(progstate_t) * max_progs, "progstatetable"); @@ -784,7 +798,7 @@ string_t PDECL PR_StringToProgs (pubprogfuncs_t *ppf, char *str) for (i = prinst.numallocedstrings-1; i >= 0; i--) { if (prinst.allocedstrings[i] == str) - return (string_t)((unsigned int)i | 0x80000000); + return (string_t)((unsigned int)i | STRING_STATIC); if (!prinst.allocedstrings[i]) free = i; } @@ -793,7 +807,7 @@ string_t PDECL PR_StringToProgs (pubprogfuncs_t *ppf, char *str) { i = free; prinst.allocedstrings[i] = str; - return (string_t)((unsigned int)i | 0x80000000); + return (string_t)((unsigned int)i | STRING_STATIC); } prinst.maxallocedstrings += 1024; @@ -810,7 +824,7 @@ string_t PDECL PR_StringToProgs (pubprogfuncs_t *ppf, char *str) if (!prinst.allocedstrings[i]) { prinst.allocedstrings[i] = str; - return (string_t)((unsigned int)i | 0x80000000); + return (string_t)((unsigned int)i | STRING_STATIC); } } @@ -824,29 +838,27 @@ char *PDECL PR_RemoveProgsString (pubprogfuncs_t *ppf, string_t str) //input string is expected to be an allocated string //if its a temp, or a constant, just return NULL. - if ((unsigned int)str & 0xc0000000) + if (((unsigned int)str & STRING_SPECMASK) == STRING_STATIC) { - if ((unsigned int)str & 0x80000000) + int i = str & ~STRING_SPECMASK; + if (i >= prinst.numallocedstrings) { - int i = str & ~0x80000000; - if (i >= prinst.numallocedstrings) - { - progfuncs->funcs.pr_trace = 1; - return NULL; - } - if (prinst.allocedstrings[i]) - { - ret = prinst.allocedstrings[i]; - prinst.allocedstrings[i] = NULL; //remove it - return ret; - } - else - { - progfuncs->funcs.pr_trace = 1; - return NULL; //urm, was freed... - } + progfuncs->funcs.pr_trace = 1; + return NULL; + } + if (prinst.allocedstrings[i]) + { + ret = prinst.allocedstrings[i]; + prinst.allocedstrings[i] = NULL; //remove it + return ret; + } + else + { + progfuncs->funcs.pr_trace = 1; + return NULL; //urm, was freed... } } + printf("invalid static string %x\n", str); progfuncs->funcs.pr_trace = 1; return NULL; } @@ -854,41 +866,38 @@ char *PDECL PR_RemoveProgsString (pubprogfuncs_t *ppf, string_t str) char *ASMCALL PR_StringToNative (pubprogfuncs_t *ppf, string_t str) { progfuncs_t *progfuncs = (progfuncs_t*)ppf; - if ((unsigned int)str & 0xc0000000) + if (((unsigned int)str & STRING_SPECMASK) == STRING_STATIC) { - if ((unsigned int)str & 0x80000000) + int i = str & ~STRING_SPECMASK; + if (i >= prinst.numallocedstrings) { - int i = str & ~0x80000000; - if (i >= prinst.numallocedstrings) - { - printf("invalid string %x\n", str); - PR_StackTrace(&progfuncs->funcs); - progfuncs->funcs.pr_trace = 1; - return ""; - } - if (prinst.allocedstrings[i]) - return prinst.allocedstrings[i]; - else - { - printf("invalid string %x\n", str); - PR_StackTrace(&progfuncs->funcs); - progfuncs->funcs.pr_trace = 1; - return ""; //urm, was freed... - } + printf("invalid string %x\n", str); + PR_StackTrace(&progfuncs->funcs); + progfuncs->funcs.pr_trace = 1; + return ""; } - if ((unsigned int)str & 0x40000000) + if (prinst.allocedstrings[i]) + return prinst.allocedstrings[i]; + else { - int i = str & ~0x40000000; - if (i >= prinst.numtempstrings) - { - printf("invalid temp string %x\n", str); - PR_StackTrace(&progfuncs->funcs); - progfuncs->funcs.pr_trace = 1; - return ""; - } - return prinst.tempstrings[i]; + printf("invalid string %x\n", str); + PR_StackTrace(&progfuncs->funcs); + progfuncs->funcs.pr_trace = 1; + return ""; //urm, was freed... } } + if (((unsigned int)str & STRING_SPECMASK) == STRING_TEMP) + { + int i = str & ~STRING_SPECMASK; + if (i >= prinst.numtempstrings) + { + printf("invalid temp string %x\n", str); + PR_StackTrace(&progfuncs->funcs); + progfuncs->funcs.pr_trace = 1; + return ""; + } + return prinst.tempstrings[i]; + } if ((unsigned int)str >= (unsigned int)prinst.addressableused) { @@ -932,7 +941,7 @@ string_t PDECL PR_AllocTempString (pubprogfuncs_t *ppf, const char *str) prinst.tempstrings[i] = progfuncs->funcs.parms->memalloc(strlen(str)+1); strcpy(prinst.tempstrings[i], str); - return (string_t)((unsigned int)i | 0x40000000); + return (string_t)((unsigned int)i | STRING_TEMP); } string_t PDECL PR_AllocTempStringLen (pubprogfuncs_t *ppf, char **str, unsigned int len) { @@ -965,7 +974,7 @@ string_t PDECL PR_AllocTempStringLen (pubprogfuncs_t *ppf, char **str, unsigne prinst.tempstrings[i] = progfuncs->funcs.parms->memalloc(len); *str = prinst.tempstrings[i]; - return (string_t)((unsigned int)i | 0x40000000); + return (string_t)((unsigned int)i | STRING_TEMP); } void PR_FreeTemps (progfuncs_t *progfuncs, int depth) diff --git a/engine/qclib/progsint.h b/engine/qclib/progsint.h index ae3074ff6..0a61f43d0 100644 --- a/engine/qclib/progsint.h +++ b/engine/qclib/progsint.h @@ -153,8 +153,8 @@ int reorganisefields; //initlib.c int mfreelist; char * addressablehunk; - unsigned int addressableused; - unsigned int addressablesize; + size_t addressableused; + size_t addressablesize; struct edict_s **edicttable; } prinst_t; @@ -466,7 +466,7 @@ fdef_t *ED_FindField (progfuncs_t *progfuncs, char *name); fdef_t *ED_FieldAtOfs (progfuncs_t *progfuncs, unsigned int ofs); dfunction_t *ED_FindFunction (progfuncs_t *progfuncs, char *name, progsnum_t *pnum, progsnum_t fromprogs); func_t PDECL PR_FindFunc(pubprogfuncs_t *progfncs, char *funcname, progsnum_t pnum); -void PDECL PR_Configure (pubprogfuncs_t *progfncs, int addressable_size, int max_progs); +void PDECL PR_Configure (pubprogfuncs_t *progfncs, size_t addressable_size, int max_progs); int PDECL PR_InitEnts(pubprogfuncs_t *progfncs, int maxents); char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val); void PDECL QC_ClearEdict (pubprogfuncs_t *progfuncs, struct edict_s *ed); diff --git a/engine/qclib/progslib.h b/engine/qclib/progslib.h index dbba654c4..178940d00 100644 --- a/engine/qclib/progslib.h +++ b/engine/qclib/progslib.h @@ -66,7 +66,7 @@ struct pubprogfuncs_s void (PDECL *CloseProgs) (pubprogfuncs_t *inst); - void (PDECL *Configure) (pubprogfuncs_t *prinst, int addressablesize, int max_progs); //configure buffers and memory. Used to reset and must be called first. Flushes a running VM. + void (PDECL *Configure) (pubprogfuncs_t *prinst, size_t addressablesize, int max_progs); //configure buffers and memory. Used to reset and must be called first. Flushes a running VM. progsnum_t (PDECL *LoadProgs) (pubprogfuncs_t *prinst, char *s, int headercrc, builtin_t *builtins, int numbuiltins); //load a progs int (PDECL *InitEnts) (pubprogfuncs_t *prinst, int max_ents); //returns size of edicts for use with nextedict macro void (PDECL *ExecuteProgram) (pubprogfuncs_t *prinst, func_t fnum); //start execution diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index 3d153b9a9..79bea749b 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -3846,6 +3846,9 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could //note that we don't allow passing 0.0f for null. //WARNING: field 0 is actually a valid field, and is commonly modelindex. } + else if (p->type == ev_field && e->type->type == ev_field && (p->aux_type->type == ev_variant || e->type->aux_type->type == ev_variant)) + { //allow passing variant fields etc + } else if ((p->type == ev_vector) && e->type->type == ev_integer && e->constant && !((int*)qcc_pr_globals)[e->ofs]) { //also allow it for vector types too, but make sure the entire vector is valid. diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index e32c8bab3..00fd50118 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -8859,7 +8859,7 @@ static void QCBUILTIN PF_SendPacket(pubprogfuncs_t *prinst, struct globalvars_s char *address = PR_GetStringOfs(prinst, OFS_PARM0); char *contents = PF_VarString(prinst, 1, pr_globals); - NET_StringToAdr(address, &to); + NET_StringToAdr(address, 0, &to); NET_SendPacket(NS_SERVER, strlen(contents), contents, to); } @@ -9273,7 +9273,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"calltimeofday", PF_calltimeofday, 0, 0, 0, 231, "void()"}, //EXT_CSQC - {"clientstat", PF_clientstat, 0, 0, 0, 232, "void(float num, float type, .void fld)"}, //EXT_CSQC + {"clientstat", PF_clientstat, 0, 0, 0, 232, "void(float num, float type, .__variant fld)"}, //EXT_CSQC {"globalstat", PF_globalstat, 0, 0, 0, 233, "void(float num, float type, string name)"}, //EXT_CSQC_1 actually //END EXT_CSQC {"isbackbuffered", PF_isbackbuffered, 0, 0, 0, 234, "float(entity player)"}, @@ -9680,14 +9680,14 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"gethostcacheindexforkey",PF_Fixme, 0, 0, 0, 622, "float(string key)"}, {"addwantedhostcachekey",PF_Fixme, 0, 0, 0, 623, "void(string key)"}, {"getextresponse", PF_Fixme, 0, 0, 0, 624, "string()"}, - {"netaddress_resolve",PF_Fixme, 0, 0, 0, 625, "string(string, float)"}, + {"netaddress_resolve",PF_netaddress_resolve,0, 0, 0, 625, "string(string dnsname, optional float defport)"}, // {"getgamedirinfo", PF_Fixme, 0, 0, 0, 626, "string(float n, float prop)"}, {"sprintf", PF_sprintf, 0, 0, 0, 627, "string(string fmt, ...)"}, {"getsurfacenumtriangles",PF_getsurfacenumtriangles,0,0,0, 628, "float(entity e, float s)"}, {"getsurfacetriangle",PF_getsurfacetriangle,0, 0, 0, 629, "vector(entity e, float s, float n)"}, // {"setkeybind", PF_Fixme, 0, 0, 0, 630, "float(float key, string bind, optional float bindmap)"}, -// {"getbindmaps", PF_Fixme, 0, 0, 0, 631, "vector()"}, -// {"setbindmaps", PF_Fixme, 0, 0, 0, 632, "float(vector bm)"}, + {"getbindmaps", PF_Fixme, 0, 0, 0, 631, "vector()" STUB}, + {"setbindmaps", PF_Fixme, 0, 0, 0, 632, "float(vector bm)" STUB}, {"crypto_getkeyfp", PF_Fixme, 0, 0, 0, 633, "string(string addr)" STUB}, {"crypto_getidfp", PF_Fixme, 0, 0, 0, 634, "string(string addr)" STUB}, {"crypto_getencryptlevel",PF_Fixme, 0, 0, 0, 635, "string(string addr)" STUB}, @@ -10214,6 +10214,7 @@ void PR_DumpPlatform_f(void) #undef comfieldstring #undef comfieldfunction + {"URI_Get_Callback", "noref void(float reqid, float responsecode, string resourcebody)", QW|NQ|CS|MENU}, {"SpectatorConnect", "noref void()", QW|NQ}, {"SpectatorDisconnect", "noref void()", QW|NQ}, {"SpectatorThink", "noref void()", QW|NQ}, @@ -10414,6 +10415,17 @@ void PR_DumpPlatform_f(void) {"MF_TRACER2", "const float", QW|NQ, EF_MF_TRACER2>>24}, {"MF_TRACER3", "const float", QW|NQ, EF_MF_TRACER3>>24}, + //including these for csqc stat types. +// {"EV_VOID", "const float", QW|NQ, ev_void}, + {"EV_STRING", "const float", QW|NQ, ev_string}, + {"EV_FLOAT", "const float", QW|NQ, ev_float}, +// {"EV_VECTOR", "const float", QW|NQ, ev_vector}, + {"EV_ENTITY", "const float", QW|NQ, ev_entity}, +// {"EV_FIELD", "const float", QW|NQ, ev_field}, +// {"EV_FUNCTION", "const float", QW|NQ, ev_function}, +// {"EV_POINTER", "const float", QW|NQ, ev_pointer}, + {"EV_INTEGER", "const float", QW|NQ, ev_integer}, + {"STAT_HEALTH", "const float", CS, STAT_HEALTH}, {"STAT_WEAPON", "const float", CS, STAT_WEAPON}, {"STAT_AMMO", "const float", CS, STAT_AMMO}, @@ -10538,24 +10550,24 @@ void PR_DumpPlatform_f(void) {"TEREDIT_MESH_KILL", "const float", CS, ter_mesh_kill}, {"TEREDIT_TINT", "const float", CS, ter_tint}, - {"SLIST_HOSTCACHEVIEWCOUNT", "const float", MENU, SLIST_HOSTCACHEVIEWCOUNT}, - {"SLIST_HOSTCACHETOTALCOUNT", "const float", MENU, SLIST_HOSTCACHETOTALCOUNT}, - {"SLIST_MASTERQUERYCOUNT", "const float", MENU, SLIST_MASTERQUERYCOUNT}, - {"SLIST_MASTERREPLYCOUNT", "const float", MENU, SLIST_MASTERREPLYCOUNT}, - {"SLIST_SERVERQUERYCOUNT", "const float", MENU, SLIST_SERVERQUERYCOUNT}, - {"SLIST_SERVERREPLYCOUNT", "const float", MENU, SLIST_SERVERREPLYCOUNT}, - {"SLIST_SORTFIELD", "const float", MENU, SLIST_SORTFIELD}, - {"SLIST_SORTDESCENDING", "const float", MENU, SLIST_SORTDESCENDING}, - {"SLIST_TEST_CONTAINS", "const float", MENU, SLIST_TEST_CONTAINS}, - {"SLIST_TEST_NOTCONTAIN", "const float", MENU, SLIST_TEST_NOTCONTAIN}, - {"SLIST_TEST_LESSEQUAL", "const float", MENU, SLIST_TEST_LESSEQUAL}, - {"SLIST_TEST_LESS", "const float", MENU, SLIST_TEST_LESS}, - {"SLIST_TEST_EQUAL", "const float", MENU, SLIST_TEST_EQUAL}, - {"SLIST_TEST_GREATER", "const float", MENU, SLIST_TEST_GREATER}, - {"SLIST_TEST_GREATEREQUAL", "const float", MENU, SLIST_TEST_GREATEREQUAL}, - {"SLIST_TEST_NOTEQUAL", "const float", MENU, SLIST_TEST_NOTEQUAL}, - {"SLIST_TEST_STARTSWITH", "const float", MENU, SLIST_TEST_STARTSWITH}, - {"SLIST_TEST_NOTSTARTSWITH", "const float", MENU, SLIST_TEST_NOTSTARTSWITH}, + {"SLIST_HOSTCACHEVIEWCOUNT", "const float", CS|MENU, SLIST_HOSTCACHEVIEWCOUNT}, + {"SLIST_HOSTCACHETOTALCOUNT", "const float", CS|MENU, SLIST_HOSTCACHETOTALCOUNT}, + {"SLIST_MASTERQUERYCOUNT", "const float", CS|MENU, SLIST_MASTERQUERYCOUNT}, + {"SLIST_MASTERREPLYCOUNT", "const float", CS|MENU, SLIST_MASTERREPLYCOUNT}, + {"SLIST_SERVERQUERYCOUNT", "const float", CS|MENU, SLIST_SERVERQUERYCOUNT}, + {"SLIST_SERVERREPLYCOUNT", "const float", CS|MENU, SLIST_SERVERREPLYCOUNT}, + {"SLIST_SORTFIELD", "const float", CS|MENU, SLIST_SORTFIELD}, + {"SLIST_SORTDESCENDING", "const float", CS|MENU, SLIST_SORTDESCENDING}, + {"SLIST_TEST_CONTAINS", "const float", CS|MENU, SLIST_TEST_CONTAINS}, + {"SLIST_TEST_NOTCONTAIN", "const float", CS|MENU, SLIST_TEST_NOTCONTAIN}, + {"SLIST_TEST_LESSEQUAL", "const float", CS|MENU, SLIST_TEST_LESSEQUAL}, + {"SLIST_TEST_LESS", "const float", CS|MENU, SLIST_TEST_LESS}, + {"SLIST_TEST_EQUAL", "const float", CS|MENU, SLIST_TEST_EQUAL}, + {"SLIST_TEST_GREATER", "const float", CS|MENU, SLIST_TEST_GREATER}, + {"SLIST_TEST_GREATEREQUAL", "const float", CS|MENU, SLIST_TEST_GREATEREQUAL}, + {"SLIST_TEST_NOTEQUAL", "const float", CS|MENU, SLIST_TEST_NOTEQUAL}, + {"SLIST_TEST_STARTSWITH", "const float", CS|MENU, SLIST_TEST_STARTSWITH}, + {"SLIST_TEST_NOTSTARTSWITH", "const float", CS|MENU, SLIST_TEST_NOTSTARTSWITH}, {NULL} }; @@ -10800,8 +10812,10 @@ void PR_DumpPlatform_f(void) { if (PR_CSQC_BuiltinValid(BuiltinList[i].name, idx)) nd |= CS; +#ifdef MENU_DAT if (MP_BuiltinValid(BuiltinList[i].name, idx)) nd |= MENU; +#endif if (!nd) { diff --git a/engine/server/server.h b/engine/server/server.h index 7d8fb32c2..a872b02b1 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -308,6 +308,7 @@ typedef struct //merge? int num_entities; int first_entity; // into the circular sv_packet_entities[] int senttime; // for ping calculations + float ping_time; } q2client_frame_t; #endif #ifdef Q3SERVER diff --git a/engine/server/sv_ccmds.c b/engine/server/sv_ccmds.c index bb8f0f85c..907847673 100644 --- a/engine/server/sv_ccmds.c +++ b/engine/server/sv_ccmds.c @@ -1954,7 +1954,7 @@ void SV_Snap (int uid) { pcxname[strlen(pcxname) - 6] = i/10 + '0'; pcxname[strlen(pcxname) - 5] = i%10 + '0'; - Q_snprintfz (checkname, sizeof(checkname), "%s/snap/%s", gamedirfile, pcxname); + Q_snprintfz (checkname, sizeof(checkname), "snap/%s", pcxname); if (!COM_FCheckExists(checkname)) break; // file doesn't exist } diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index 57b241f93..7240bdb5b 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -1201,9 +1201,9 @@ void SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizebuf_t /*start writing the packet*/ MSG_WriteByte (msg, svcfte_updateentities); - if (ISNQCLIENT(client)) + if (ISNQCLIENT(client) && (client->fteprotocolextensions2 & PEXT2_PREDINFO)) { - MSG_WriteLong(msg, client->netchan.incoming_unreliable); + MSG_WriteLong(msg, client->last_sequence); } // Con_Printf("Gen sequence %i\n", sequence); MSG_WriteFloat(msg, sv.world.physicstime); @@ -2842,16 +2842,24 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli } } - if (ent->v->solid == SOLID_BSP || (ent->v->skin < 0 && ent->v->modelindex)) + if (client && client->edict && (ent->v->owner == client->edict->entnum)) + state->solid = 0; + else if (ent->v->solid == SOLID_BSP || (ent->v->skin < 0 && ent->v->modelindex)) state->solid = ES_SOLID_BSP; else if (ent->v->solid == SOLID_BBOX || ent->v->solid == SOLID_SLIDEBOX || ent->v->skin < 0) { - i = bound(0, -ent->v->mins[0]/8, 31); - state->solid = i; - i = bound(0, -ent->v->mins[2]/8, 31); - state->solid |= i<<5; - i = bound(0, ((ent->v->maxs[2]+32)/8), 63); /*up can be negative*/ - state->solid |= i<<10; + unsigned int mdl = ent->v->modelindex; + if (mdl < MAX_MODELS && sv.models[mdl] && sv.models[mdl]->type == mod_brush) + state->solid = ES_SOLID_BSP; + else + { + i = bound(0, -ent->v->mins[0]/8, 31); + state->solid = i; + i = bound(0, -ent->v->mins[2]/8, 31); + state->solid |= i<<5; + i = bound(0, ((ent->v->maxs[2]+32)/8), 63); /*up can be negative*/ + state->solid |= i<<10; + } } else state->solid = 0; diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 02504f2f5..a209c695f 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -776,11 +776,17 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us #endif - + sv.state = ss_loading; if (usecinematic) { + qboolean Mod_LoadQ2BrushModel (model_t *mod, void *buffer); + extern model_t *loadmodel; + strcpy (sv.name, server); strcpy (sv.modelname, ""); + + loadmodel = sv.world.worldmodel = Mod_FindName (sv.modelname); + loadmodel->needload = !Mod_LoadQ2BrushModel (sv.world.worldmodel, NULL); } else { @@ -794,13 +800,12 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us else if (COM_FCheckExists(va(exts[2], server))) Q_snprintfz (sv.modelname, sizeof(sv.modelname), exts[2], server); } + sv.world.worldmodel = Mod_ForName (sv.modelname, true); } - sv.state = ss_loading; - sv.world.worldmodel = Mod_ForName (sv.modelname, true); if (!sv.world.worldmodel || sv.world.worldmodel->needload) - Sys_Error("%s is missing or corrupt\n", sv.modelname); + Sys_Error("\"%s\" is missing or corrupt\n", sv.modelname); if (sv.world.worldmodel->type != mod_brush && sv.world.worldmodel->type != mod_heightmap) - Sys_Error("%s is not a bsp model\n", sv.modelname); + Sys_Error("\"%s\" is not a bsp model\n", sv.modelname); sv.state = ss_dead; #ifndef SERVERONLY diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 27520b0b3..2f4e77a9d 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -210,7 +210,7 @@ cvar_t hostname = CVARF("hostname","unnamed", CVAR_SERVERINFO); cvar_t secure = CVARF("secure", "", CVAR_SERVERINFO); -extern cvar_t sv_nomsec; +extern cvar_t sv_nqplayerphysics; char cvargroup_serverpermissions[] = "server permission variables"; char cvargroup_serverinfo[] = "serverinfo variables"; @@ -807,7 +807,6 @@ int SV_CalcPing (client_t *cl, qboolean forcecalc) float ping; int i; int count; - register client_frame_t *frame; if (!cl->frameunion.frames) return 0; @@ -817,7 +816,24 @@ int SV_CalcPing (client_t *cl, qboolean forcecalc) case SCP_BAD: break; case SCP_QUAKE2: - break; + { + q2client_frame_t *frame; + ping = 0; + count = 0; + for (frame = cl->frameunion.q2frames, i=0 ; iping_time > 0) + { + ping += frame->ping_time; + count++; + } + } + if (!count) + return 9999; + ping /= count; + + } + return ping; case SCP_QUAKE3: break; case SCP_DARKPLACES6: @@ -826,20 +842,22 @@ int SV_CalcPing (client_t *cl, qboolean forcecalc) case SCP_PROQUAKE: case SCP_FITZ666: case SCP_QUAKEWORLD: - ping = 0; - count = 0; - for (frame = cl->frameunion.frames, i=0 ; iping_time > 0) + register client_frame_t *frame; + ping = 0; + count = 0; + for (frame = cl->frameunion.frames, i=0 ; iping_time; - count++; + if (frame->ping_time > 0) + { + ping += frame->ping_time; + count++; + } } + if (!count) + return 9999; + ping /= count; } - if (!count) - return 9999; - ping /= count; - return ping*1000; } return 0; @@ -1662,7 +1680,7 @@ void SV_AcceptMessage(int protocol) MSG_WriteByte(&sb, CCREP_ACCEPT); NET_LocalAddressForRemote(svs.sockets, &net_from, &localaddr, 0); MSG_WriteLong(&sb, ShortSwap(localaddr.port)); - MSG_WriteByte(&sb, 1/*MOD_PROQUAKE*/); + MSG_WriteByte(&sb, (protocol==SCP_NETQUAKE)?0:1/*MOD_PROQUAKE*/); MSG_WriteByte(&sb, 10 * 3.50/*MOD_PROQUAKE_VERSION*/); *(int*)sb.data = BigLong(NETFLAG_CTL|sb.cursize); NET_SendPacket(NS_SERVER, sb.cursize, sb.data, net_from); @@ -3441,9 +3459,7 @@ void SV_OpenRoute_f(void) netadr_t to; char data[64]; - NET_StringToAdr(Cmd_Argv(1), &to); - if (!to.port) - to.port = PORT_QWCLIENT; + NET_StringToAdr(Cmd_Argv(1), PORT_QWCLIENT, &to); sprintf(data, "\xff\xff\xff\xff%c", S2C_CONNECTION); @@ -3513,7 +3529,6 @@ qboolean SV_ReadPackets (float *delay) SVNQ_ExecuteClientMessage(cl); } } - break; } else { @@ -4343,7 +4358,7 @@ void SV_InitLocal (void) Cvar_Register (&sv_csqcdebug, cvargroup_servercontrol); Cvar_Register (&sv_gamespeed, cvargroup_serverphysics); - Cvar_Register (&sv_nomsec, cvargroup_serverphysics); + Cvar_Register (&sv_nqplayerphysics, cvargroup_serverphysics); Cvar_Register (&pr_allowbutton1, cvargroup_servercontrol); Cvar_Register (&pausable, cvargroup_servercontrol); @@ -4473,7 +4488,7 @@ void Master_Heartbeat (void) if (!*sv_masterlist[i].cv.string) sv_masterlist[i].adr.port = 0; - else if (!NET_StringToAdr(sv_masterlist[i].cv.string, &sv_masterlist[i].adr)) + else if (!NET_StringToAdr(sv_masterlist[i].cv.string, 0, &sv_masterlist[i].adr)) { sv_masterlist[i].adr.port = 0; Con_Printf ("Couldn't resolve master \"%s\"\n", sv_masterlist[i].cv.string); diff --git a/engine/server/sv_mvd.c b/engine/server/sv_mvd.c index 557030e73..229b84f2c 100644 --- a/engine/server/sv_mvd.c +++ b/engine/server/sv_mvd.c @@ -1601,8 +1601,6 @@ static qboolean SV_MVD_Record (mvddest_t *dest) { /*everything*/ demo.recorder.fteprotocolextensions = PEXT_CSQC | PEXT_COLOURMOD | PEXT_DPFLAGS | PEXT_CUSTOMTEMPEFFECTS | PEXT_ENTITYDBL | PEXT_ENTITYDBL2 | PEXT_FATNESS | PEXT_HEXEN2 | PEXT_HULLSIZE | PEXT_LIGHTSTYLECOL | PEXT_MODELDBL | PEXT_SCALE | PEXT_SETATTACHMENT | PEXT_SETVIEW | PEXT_SOUNDDBL | PEXT_SPAWNSTATIC2 | PEXT_TRANS | PEXT_VIEW2; demo.recorder.fteprotocolextensions2 = PEXT2_VOICECHAT | PEXT2_SETANGLEDELTA | PEXT2_PRYDONCURSOR | PEXT2_REPLACEMENTDELTAS; - /*assume that all playback will be done with a valid csprogs that can correctly decode*/ - demo.recorder.csqcactive = true; /*enable these, because we might as well (stat ones are always useful)*/ demo.recorder.zquake_extensions = Z_EXT_PM_TYPE | Z_EXT_PM_TYPE_NEW | Z_EXT_VIEWHEIGHT | Z_EXT_SERVERTIME | Z_EXT_PITCHLIMITS | Z_EXT_JOIN_OBSERVE | Z_EXT_VWEP; } @@ -1616,6 +1614,8 @@ static qboolean SV_MVD_Record (mvddest_t *dest) //pointless extensions that are redundant with mvds demo.recorder.fteprotocolextensions &= ~PEXT_ACCURATETIMINGS | PEXT_HLBSP|PEXT_Q2BSP|PEXT_Q3BSP; + /*assume that all playback will be done with a valid csprogs that can correctly decode*/ + demo.recorder.csqcactive = (demo.recorder.fteprotocolextensions & PEXT_CSQC); } // else // SV_WriteRecordMVDMessage(&buf, dem_read); diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index c947683ec..4d281a1e9 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -2041,6 +2041,7 @@ void World_Physics_Frame(world_t *w) int i; qboolean retouch; wedict_t *ent; + extern cvar_t sv_nqplayerphysics; w->framenum++; @@ -2085,8 +2086,32 @@ void World_Physics_Frame(world_t *w) { if (!svs.clients[i-1].isindependant) { - WPhys_RunEntity (w, ent); - WPhys_RunNewmis (w); + if (sv_nqplayerphysics.ival || svs.clients[i-1].state < cs_spawned) + { + WPhys_RunEntity (w, ent); + WPhys_RunNewmis (w); + } + else + { + int newt; + int delt; + newt = sv.time*1000; + delt = newt - svs.clients[i-1].msecs; + if (delt > 1000/77 || delt < -10) + { + float ft = host_frametime; + host_client = &svs.clients[i-1]; + sv_player = svs.clients[i-1].edict; + svs.clients[i-1].msecs = newt; + SV_PreRunCmd(); + svs.clients[i-1].last_check = 0; + svs.clients[i-1].lastcmd.msec = bound(0, delt, 255); + SV_RunCmd (&svs.clients[i-1].lastcmd, true); + svs.clients[i-1].lastcmd.impulse = 0; + SV_PostRunCmd(); + *w->g.frametime = host_frametime = ft; + } + } } // else // World_LinkEdict(w, (wedict_t*)ent, true); diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index f5ca0fa4e..d02097752 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -1229,7 +1229,10 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg) { MSG_WriteByte (msg, svc_time); MSG_WriteFloat(msg, sv.world.physicstime); - client->nextservertimeupdate = sv.world.physicstime; + + if (client->fteprotocolextensions2 & PEXT2_PREDINFO) + MSG_WriteLong(msg, client->last_sequence); + // Con_Printf("%f\n", sv.world.physicstime); } @@ -1620,6 +1623,12 @@ void SV_CalcClientStats(client_t *client, int statsi[MAX_CL_STATS], float statsf else statsi[STAT_VIEWZOOM] = ent->xv->viewzoom*255; + if (client->fteprotocolextensions2 & PEXT2_PREDINFO) + { + statsf[STAT_MOVEVARS_GRAVITY] = sv_gravity.value; + statsf[STAT_MOVEVARS_ENTGRAVITY] = host_client->entgravity; + statsf[STAT_MOVEVARS_MAXSPEED] = host_client->maxspeed; + } if (client->protocol == SCP_DARKPLACES7) { /*note: statsf is truncated, which would mess things up*/ @@ -1637,7 +1646,7 @@ void SV_CalcClientStats(client_t *client, int statsi[MAX_CL_STATS], float statsf statsfi[STAT_MOVEVARS_AIRACCELERATE] = sv_airaccelerate.value; statsfi[STAT_MOVEVARS_WATERACCELERATE] = sv_wateraccelerate.value; statsfi[STAT_MOVEVARS_ENTGRAVITY] = host_client->entgravity; - statsfi[STAT_MOVEVARS_JUMPVELOCITY] = 280;//sv_jumpvelocity.value; //bah + statsfi[STAT_MOVEVARS_JUMPVELOCITY] = 270;//sv_jumpvelocity.value; //bah statsfi[STAT_MOVEVARS_EDGEFRICTION] = sv_edgefriction.value; statsfi[STAT_MOVEVARS_MAXAIRSPEED] = host_client->maxspeed; statsfi[STAT_MOVEVARS_STEPHEIGHT] = 18; @@ -2400,7 +2409,7 @@ void SV_SendClientMessages (void) } else { - if (c->nextservertimeupdate > pt + 0.5*2) + if (c->nextservertimeupdate > pt + 0.1) c->nextservertimeupdate = 0; c->netchan.nqunreliableonly = false; @@ -2409,7 +2418,7 @@ void SV_SendClientMessages (void) if (c->nextservertimeupdate < pt && c->state != cs_zombie) { c->send_message = true; - c->nextservertimeupdate = pt; + c->nextservertimeupdate = pt + 1.0/77; } } } diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 9e3fa18f5..c82c3f4c6 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -58,11 +58,11 @@ cvar_t cmd_allowaccess = SCVAR("cmd_allowaccess", "0"); //set to 1 to allow cmd cvar_t cmd_gamecodelevel = SCVAR("cmd_gamecodelevel", "50"); //execution level which gamecode is told about (for unrecognised commands) cvar_t sv_pure = CVARFD("sv_pure", "", CVAR_SERVERINFO, "The most evil cvar in the world."); -cvar_t sv_nomsec = CVARD("sv_nomsec", "0", "Ignore client msec times, runs using NQ physics instead."); +cvar_t sv_nqplayerphysics = CVARAD("sv_nqplayerphysics", "0", "sv_nomsec", "Disregard player prediction and run NQ-style player physics instead. This can be used for compatibility with mods that expect exact behaviour."); cvar_t sv_edgefriction = CVARAF("sv_edgefriction", "2", "edgefriction", 0); -cvar_t sv_brokenmovetypes = CVARD("sv_brokenmovetypes", "0", "Emulate standard quakeworld movetypes. Shouldn't be used for any games other than QuakeWorld."); +cvar_t sv_brokenmovetypes = CVARD("sv_brokenmovetypes", "0", "Emulate vanilla quakeworld by forcing MOVETYPE_WALK on all players. Shouldn't be used for any games other than QuakeWorld."); cvar_t sv_chatfilter = CVAR("sv_chatfilter", "0"); @@ -416,8 +416,6 @@ void SV_New_f (void) host_client->prespawn_idx = 0; } -#define GAME_DEATHMATCH 0 -#define GAME_COOP 1 void SVNQ_New_f (void) { extern cvar_t coop; @@ -998,6 +996,7 @@ void SV_SendClientPrespawnInfo(client_t *client) client->prespawn_idx |= 0x80000000; } } + if (client->prespawn_stage == PRESPAWN_MODELLIST) { started = false; @@ -4350,9 +4349,9 @@ void Cmd_FPSList_f(void) } if (frames) - SV_ClientPrintf(host_client, PRINT_HIGH, "%s: %gfps (min%g max %g), in: %ibps, out: %ibps\n", cl->name, ftime/frames, minf, maxf, (int)cl->inrate, (int)cl->outrate); + SV_ClientPrintf(host_client, PRINT_HIGH, "%s: %gfps (min%g max %g), c2s: %ibps, s2c: %ibps\n", cl->name, ftime/frames, minf, maxf, (int)cl->inrate, (int)cl->outrate); else - SV_ClientPrintf(host_client, PRINT_HIGH, "%s: unknown framerate, in: %ibps, out: %ibps\n", cl->name, (int)cl->inrate, (int)cl->outrate); + SV_ClientPrintf(host_client, PRINT_HIGH, "%s: unknown framerate, c2s: %ibps, s2c: %ibps\n", cl->name, (int)cl->inrate, (int)cl->outrate); } } @@ -5363,9 +5362,6 @@ int SV_PMTypeForClient (client_t *cl) } #endif - if (!cl->isindependant) - return PM_NONE; - if (sv_brokenmovetypes.value) //this is to mimic standard qw servers, which don't support movetypes other than MOVETYPE_FLY. { //it prevents bugs from being visible in unsuspecting mods. if (cl->spectator) @@ -5442,6 +5438,11 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse) // To prevent a infinite loop if (!recurse) { + if (!host_client->last_check) + { + host_client->msecs = 0; + host_client->last_check = realtime; + } host_client->msecs += ucmd->msec; if ((tmp_time = realtime - host_client->last_check) >= sv_cheatspeedchecktime.value) @@ -5613,7 +5614,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse) } if (SV_PlayerPhysicsQC && !host_client->spectator) - { //csqc independant physics support + { //player movement tweaks that fuck over player prediction. pr_global_struct->frametime = host_frametime; pr_global_struct->time = sv.time; WPhys_RunEntity(&sv.world, (wedict_t*)sv_player); @@ -6296,7 +6297,7 @@ haveannothergo: #endif if (!sv.paused) { - if (sv_nomsec.ival) + if (sv_nqplayerphysics.ival) { cl->isindependant = false; if (!sv_player->v->fixangle) @@ -6465,6 +6466,24 @@ void SVQ2_ExecuteClientMessage (client_t *cl) // calc ping time frame = &cl->frameunion.q2frames[cl->netchan.incoming_acknowledged & Q2UPDATE_MASK]; + if (frame->senttime != -1) + { + int ping_time = realtime*1000 - frame->senttime; //no more phenomanally low pings please + if (ping_time > sv_minping.value+1) + { + cl->delay -= 0.001; + if (cl->delay < 0) + cl->delay = 0; + } + if (ping_time < sv_minping.value) + { + cl->delay += 0.001; + if (cl->delay > 1) + cl->delay = 1; + } + frame->senttime = -1; + frame->ping_time = ping_time; + } // make sure the reply sequence number matches the incoming // sequence number @@ -6474,8 +6493,8 @@ void SVQ2_ExecuteClientMessage (client_t *cl) cl->send_message = false; // don't reply, sequences have slipped // save time for ping calculations - cl->frameunion.q2frames[cl->netchan.outgoing_sequence & Q2UPDATE_MASK].senttime = realtime; -// cl->q2frames[cl->netchan.outgoing_sequence & UPDATE_MASK].ping_time = -1; + cl->frameunion.q2frames[cl->netchan.outgoing_sequence & Q2UPDATE_MASK].senttime = realtime*1000; + cl->frameunion.q2frames[cl->netchan.outgoing_sequence & Q2UPDATE_MASK].ping_time = -1; host_client = cl; sv_player = host_client->edict; @@ -6520,7 +6539,8 @@ void SVQ2_ExecuteClientMessage (client_t *cl) lastframe = MSG_ReadLong(); - if (lastframe != host_client->delta_sequence) { + if (lastframe != host_client->delta_sequence) + { cl->delta_sequence = lastframe; } @@ -6616,7 +6636,7 @@ void SVNQ_ReadClientMove (usercmd_t *move) frame = &host_client->frameunion.frames[host_client->netchan.incoming_acknowledged & UPDATE_MASK]; - if (host_client->protocol == SCP_DARKPLACES7) + if (host_client->protocol == SCP_DARKPLACES7 || (host_client->fteprotocolextensions2 & PEXT2_PREDINFO)) host_client->last_sequence = MSG_ReadLong (); else host_client->last_sequence = 0; @@ -6665,11 +6685,11 @@ void SVNQ_ReadClientMove (usercmd_t *move) move->sidemove = MSG_ReadShort (); move->upmove = MSG_ReadShort (); - move->msec=timesincelast*1000; + move->msec=bound(0, timesincelast*1000, 255); frame->move_msecs = timesincelast*1000; // read buttons - if (host_client->protocol == SCP_DARKPLACES6 || host_client->protocol == SCP_DARKPLACES7) + if (host_client->protocol == SCP_DARKPLACES6 || host_client->protocol == SCP_DARKPLACES7 || (host_client->fteprotocolextensions2 & PEXT2_PRYDONCURSOR)) bits = MSG_ReadLong(); else bits = MSG_ReadByte (); @@ -6679,7 +6699,7 @@ void SVNQ_ReadClientMove (usercmd_t *move) if (i) move->impulse = i; - if (host_client->protocol == SCP_DARKPLACES6 || host_client->protocol == SCP_DARKPLACES7) + if (host_client->protocol == SCP_DARKPLACES6 || host_client->protocol == SCP_DARKPLACES7 || (host_client->fteprotocolextensions2 & PEXT2_PRYDONCURSOR)) { SV_ReadPrydonCursor(); } @@ -6702,8 +6722,8 @@ void SVNQ_ReadClientMove (usercmd_t *move) } - if (i && SV_FilterImpulse(i, host_client->trustlevel)) - host_client->edict->v->impulse = i; +// if (i && SV_FilterImpulse(i, host_client->trustlevel)) +// host_client->edict->v->impulse = i; host_client->edict->v->button0 = bits & 1; host_client->edict->v->button2 = (bits >> 1) & 1; @@ -6720,8 +6740,11 @@ void SVNQ_ReadClientMove (usercmd_t *move) if (host_client->last_sequence) { host_frametime = timesincelast; - WPhys_RunEntity(&sv.world, (wedict_t*)host_client->edict); + host_client->isindependant = true; + SV_PreRunCmd(); + SV_RunCmd (move, true); + SV_PostRunCmd(); } else host_client->isindependant = false; diff --git a/engine/server/svq2_ents.c b/engine/server/svq2_ents.c index d45a3b9bb..80d3eaa45 100644 --- a/engine/server/svq2_ents.c +++ b/engine/server/svq2_ents.c @@ -634,7 +634,7 @@ void SVQ2_BuildClientFrame (client_t *client) // this is the frame we are creating frame = &client->frameunion.q2frames[sv.framenum & Q2UPDATE_MASK]; - frame->senttime = realtime; // save it for ping calc later + frame->senttime = realtime*1000; // save it for ping calc later // find the client's PVS for (i=0 ; i<3 ; i++)