From 4e9d4dcc27c66e236a1dedfcd689b73f134ac624 Mon Sep 17 00:00:00 2001 From: Spoike Date: Sun, 28 Jun 2015 03:43:10 +0000 Subject: [PATCH] fixed over-prediction issue. added two new cvars to control prediction nudging of other players. fixed some serverbrowser issues. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4923 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_ents.c | 16 +++++------ engine/client/cl_main.c | 8 ++++-- engine/client/cl_master.h | 1 + engine/client/cl_pred.c | 2 +- engine/client/m_master.c | 56 ++++++++++++++++++++++++++------------ engine/client/net_master.c | 1 + engine/client/r_part.c | 2 +- 7 files changed, 57 insertions(+), 29 deletions(-) diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 852acc90f..0a4df8015 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -25,6 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. extern cvar_t cl_predict_players; extern cvar_t cl_predict_players_frac; +extern cvar_t cl_predict_players_latency; +extern cvar_t cl_predict_players_nudge; extern cvar_t cl_lerp_players; extern cvar_t cl_solid_players; extern cvar_t cl_item_bobbing; @@ -920,7 +922,7 @@ void CLFTE_ParseEntities(void) if (cl.do_lerp_players) { - float packetage = (realtime - cl.outframes[cl.ackedmovesequence & UPDATE_MASK].senttime) - cls.latency; + float packetage = (realtime - cl.outframes[cl.ackedmovesequence & UPDATE_MASK].senttime) - cls.latency*cl_predict_players_latency.value + cl_predict_players_nudge.value; //predict in-place based upon calculated latencies and stuff, stuff can then be interpolated properly for (oldindex = 0; oldindex < newp->num_entities; oldindex++) { @@ -2991,7 +2993,7 @@ static void CL_TransitionPacketEntities(int newsequence, packet_entities_t *newp from = &latest->entities[i]; //use realtime instead. //also, use the sent timings instead of received as those are assumed to be more reliable - age = (realtime - cl.outframes[cl.ackedmovesequence & UPDATE_MASK].senttime) - cls.latency; + age = (realtime - cl.outframes[cl.ackedmovesequence & UPDATE_MASK].senttime) - cls.latency*cl_predict_players_latency.value + cl_predict_players_nudge.value; break; } } @@ -4189,12 +4191,10 @@ guess_pm_type: if (cl.worldmodel && cl.do_lerp_players && cl_predict_players.ival) { player_state_t exact; - msec += cls.latency*1000; + msec -= 1000 * (cls.latency*cl_predict_players_latency.value-cl_predict_players_nudge.value); // msec = 1000*((realtime - cls.latency + 0.02) - state->state_time); // predict players movement - if (msec > 255) - msec = 255; - state->command.msec = msec; + state->command.msec = bound(0, msec, 255); //FIXME: flag these and do the pred elsewhere. CL_SetSolidEntities(); @@ -4349,7 +4349,7 @@ void CL_LinkPlayers (void) if (cls.demoplayback) predictmsmult *= cl_demospeed.value; - playertime = realtime - cls.latency + 0.02; + playertime = realtime - cls.latency*cl_predict_players_latency.value + cl_predict_players_nudge.value; if (playertime > realtime) playertime = realtime; @@ -4889,7 +4889,7 @@ void CL_SetUpPlayerPrediction(qboolean dopred) int s; - playertime = realtime - cls.latency + 0.02; + playertime = realtime - cls.latency*cl_predict_players_latency.value + cl_predict_players_nudge.value; if (playertime > realtime) playertime = realtime; diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 6509d82f7..0cdc771f4 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -78,8 +78,10 @@ cvar_t m_forward = CVARF("m_forward","1", CVAR_ARCHIVE); cvar_t m_side = CVARF("m_side","0.8", CVAR_ARCHIVE); cvar_t cl_lerp_players = CVARD("cl_lerp_players", "1", "Set this to make other players smoother, though it may increase effective latency. Affects only QuakeWorld."); -cvar_t cl_predict_players = CVARD("cl_predict_players", "1", "Clear this cvar to see ents exactly how they are on the server."); -cvar_t cl_predict_players_frac = CVARD("cl_predict_players_frac", "0.9", "How much of other players to predict. Values less than 1 will help minimize overruns."); +cvar_t cl_predict_players = CVARD("cl_predict_players", "1", "Clear this cvar to see ents exactly how they are on the server."); +cvar_t cl_predict_players_frac = CVARD("cl_predict_players_frac", "0.9", "How much of other players to predict. Values less than 1 will help minimize overruns."); +cvar_t cl_predict_players_latency = CVARD("cl_predict_players_latency", "1.0", "Push the player back according to your latency, to give a smooth consistent simulation of the server."); +cvar_t cl_predict_players_nudge = CVARD("cl_predict_players_nudge", "0.02", "An extra nudge of time, to cover video latency."); cvar_t cl_solid_players = CVARD("cl_solid_players", "1", "Consider other players as solid for player prediction."); cvar_t cl_noblink = CVARD("cl_noblink", "0", "Disable the ^^b text blinking feature."); cvar_t cl_servername = CVARD("cl_servername", "none", "The hostname of the last server you connected to"); @@ -3638,6 +3640,8 @@ void CL_Init (void) Cvar_Register (&cl_lerp_players, cl_controlgroup); Cvar_Register (&cl_predict_players, cl_predictiongroup); Cvar_Register (&cl_predict_players_frac, cl_predictiongroup); + Cvar_Register (&cl_predict_players_latency, cl_predictiongroup); + Cvar_Register (&cl_predict_players_nudge, cl_predictiongroup); Cvar_Register (&cl_solid_players, cl_predictiongroup); #ifdef QUAKESPYAPI diff --git a/engine/client/cl_master.h b/engine/client/cl_master.h index e8a1a39ad..ae7a66913 100644 --- a/engine/client/cl_master.h +++ b/engine/client/cl_master.h @@ -163,6 +163,7 @@ extern struct selectedserver_s { qboolean inuse; netadr_t adr; + float refreshtime; serverdetailedinfo_t *detail; diff --git a/engine/client/cl_pred.c b/engine/client/cl_pred.c index 41844053b..9f55db972 100644 --- a/engine/client/cl_pred.c +++ b/engine/client/cl_pred.c @@ -890,7 +890,7 @@ void CL_PredictMovePNum (int seat) } } - if (cls.demoplayback == DPB_QUAKEWORLD) + if (cls.demoplayback == DPB_QUAKEWORLD || pv->cam_state == CAM_EYECAM) simtime -= cls.latency; simtime += bound(-0.5, cl_predict_timenudge.value, 0.5); diff --git a/engine/client/m_master.c b/engine/client/m_master.c index 58dc761e8..d371d0635 100644 --- a/engine/client/m_master.c +++ b/engine/client/m_master.c @@ -6,7 +6,7 @@ //filtering static cvar_t sb_sortcolumn = CVARF("sb_sortcolumn", "0", CVAR_ARCHIVE); -static cvar_t sb_filtertext = CVARF("sb_filtertext", "", CVAR_ARCHIVE); +static cvar_t sb_filtertext = CVARF("sb_filtertext", "", CVAR_NOSAVE); static cvar_t sb_hideempty = CVARF("sb_hideempty", "0", CVAR_ARCHIVE); static cvar_t sb_hidenotempty = CVARF("sb_hidenotempty", "0", CVAR_ARCHIVE); static cvar_t sb_hidefull = CVARF("sb_hidefull", "0", CVAR_ARCHIVE); @@ -23,7 +23,7 @@ static cvar_t sb_showplayers = CVARF("sb_showplayers", "1", CVAR_ARCHIVE); static cvar_t sb_showfraglimit = CVARF("sb_showfraglimit", "0", CVAR_ARCHIVE); static cvar_t sb_showtimelimit = CVARF("sb_showtimelimit", "0", CVAR_ARCHIVE); -static cvar_t sb_alpha = CVARF("sb_alpha", "0.5", CVAR_ARCHIVE); +static cvar_t sb_alpha = CVARF("sb_alpha", "0.7", CVAR_ARCHIVE); vrect_t joinbutton; static float refreshedtime; @@ -428,6 +428,12 @@ static void SL_PostDraw (menu_t *menu) serverinfo_t *server = selectedserver.inuse?Master_InfoForServer(&selectedserver.adr):NULL; int h = 0; int w = 240; + if (server && selectedserver.refreshtime < realtime) + { + selectedserver.refreshtime = realtime + 4; + server->sends++; + Master_QueryServer(server); + } R2D_ImageColours(1,1,1,1); if (server && server->moreinfo) { @@ -531,7 +537,7 @@ static void SL_PostDraw (menu_t *menu) R2D_FillBlock (x, y+1, 32, 3); R2D_ImagePaletteColour (Sbar_ColorForMap(server->moreinfo->players[i].botc), 1.0); R2D_FillBlock (x, y+4, 32, 4); - Draw_FunStringWidth (x, y, va("%3i", server->moreinfo->players[i].frags), 32, true, false); + Draw_FunStringWidth (x, y, va("%3i", server->moreinfo->players[i].frags), 32-4, true, false); } x += 32+8; Draw_FunStringWidth (x, y, va("%3i", server->moreinfo->players[i].ping), 28, true, false); @@ -644,6 +650,18 @@ static qboolean SL_Key (int key, menu_t *menu) serverpreview = ((serverpreview==3)?1:3); return true; } + else if (key == K_LEFTARROW) + { + if (--serverpreview < 1) + serverpreview = 3; + return true; + } + else if (key == K_RIGHTARROW) + { + if (++serverpreview > 3) + serverpreview = 1; + return true; + } else if (key == 'o' || key == 'j' || key == K_ENTER || key == K_KP_ENTER) //join { if (key == 's' || key == 'o') @@ -678,11 +696,11 @@ doconnect: while(s = strchr(safename, '\n')) *s = ' '; if (key == 'c') - Sys_SaveClipboard(va("%s - %s\n", server->name, NET_StringToAdr(buf, sizeof(buf), &server->adr))); + Sys_SaveClipboard(va("%s - %s\n", server->name, NET_AdrToString(buf, sizeof(buf), &server->adr))); else if (ctrldown) - Cbuf_AddText(va("say_team %s - %s\n", server->name, NET_StringToAdr(buf, sizeof(buf), &server->adr)), RESTRICT_LOCAL); + Cbuf_AddText(va("say_team %s - %s\n", server->name, NET_AdrToString(buf, sizeof(buf), &server->adr)), RESTRICT_LOCAL); else - Cbuf_AddText(va("say %s - %s\n", server->name, NET_StringToAdr(buf, sizeof(buf), &server->adr)), RESTRICT_LOCAL); + Cbuf_AddText(va("say %s - %s\n", server->name, NET_AdrToString(buf, sizeof(buf), &server->adr)), RESTRICT_LOCAL); return true; } //eat (nearly) all keys @@ -693,15 +711,13 @@ doconnect: { info->scrollpos = 0; info->selectedpos = 0; - return true; } - if (key == K_END) + else if (key == K_END) { info->selectedpos = info->numslots-1; info->scrollpos = info->selectedpos - (vid.height-16-7)/8+8; - return true; } - if (key == K_PGDN) + else if (key == K_PGDN) info->selectedpos += 10; else if (key == K_PGUP) info->selectedpos -= 10; @@ -734,7 +750,7 @@ doconnect: snprintf(info->mappic->picturename, 32, "levelshots/nomap"); } - if (serverpreview && server) + if (/*serverpreview &&*/ server) { selectedserver.inuse = true; SListOptionChanged(server); @@ -761,13 +777,19 @@ static void SL_ServerPlayer (int x, int y, menucustom_t *ths, menu_t *menu) if (ths->dint < selectedserver.detail->numplayers) { int i = ths->dint; - R2D_ImagePaletteColour (Sbar_ColorForMap(selectedserver.detail->players[i].topc), 1.0); - R2D_FillBlock (x, y, 28, 4); - R2D_ImagePaletteColour (Sbar_ColorForMap(selectedserver.detail->players[i].botc), 1.0); - R2D_FillBlock (x, y+4, 28, 4); - Draw_FunStringWidth (x, y, va("%3i", selectedserver.detail->players[i].frags), 28, false, false); + if (selectedserver.detail->players[i].isspec) + Draw_FunStringWidth (x, y, "spectator", 32, false, false); + else + { + R2D_ImagePaletteColour (Sbar_ColorForMap(selectedserver.detail->players[i].topc), 1.0); + R2D_FillBlock (x, y, 32, 4); + R2D_ImagePaletteColour (Sbar_ColorForMap(selectedserver.detail->players[i].botc), 1.0); + R2D_FillBlock (x, y+4, 32, 4); - Draw_FunStringWidth (x+28, y, selectedserver.detail->players[i].name, 12*8, false, false); + Draw_FunStringWidth (x, y, va("%3i", selectedserver.detail->players[i].frags), 32-4, true, false); + } + + Draw_FunStringWidth (x+36, y, selectedserver.detail->players[i].name, 128-36, false, false); } } } diff --git a/engine/client/net_master.c b/engine/client/net_master.c index 6f418f13e..7aeffa593 100644 --- a/engine/client/net_master.c +++ b/engine/client/net_master.c @@ -1873,6 +1873,7 @@ void SListOptionChanged(serverinfo_t *newserver) Info_SetValueForKey(newserver->moreinfo->info, "hostname", newserver->name, sizeof(newserver->moreinfo->info)); + selectedserver.refreshtime = realtime+4; newserver->sends++; Master_QueryServer(newserver); } diff --git a/engine/client/r_part.c b/engine/client/r_part.c index 9004b4fd0..5d22c507c 100644 --- a/engine/client/r_part.c +++ b/engine/client/r_part.c @@ -351,7 +351,7 @@ void R_Clutter_Emit(batch_t **batches) batch_t *b; qboolean rebuildlimit = false; - if (!cl.worldmodel || cl.worldmodel->loadstate != MLS_LOADED || r_clutter_density.value <= 0) + if (!cl.worldmodel || cl.worldmodel->loadstate != MLS_LOADED || r_clutter_density.value <= 0 || (r_refdef.flags & RDF_NOWORLDMODEL)) return; if (qrenderer != QR_OPENGL) //vbo only!