]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Bring back the FPS counter in the scoreboard
authorMario <mario@smbclan.net>
Sat, 3 Mar 2018 13:39:22 +0000 (23:39 +1000)
committerMario <mario@smbclan.net>
Sat, 3 Mar 2018 13:39:22 +0000 (23:39 +1000)
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/client/view.qc
qcsrc/common/net_linked.qh
qcsrc/common/scores.qh
qcsrc/common/stats.qh
qcsrc/lib/net.qh
qcsrc/server/client.qc
qcsrc/server/scores.qc
qcsrc/server/scores.qh
qcsrc/server/scores_rules.qc
xonotic-server.cfg

index 200f5b2c55b575ab5b22efa18b2f9c0017ba1f93..f914df7dde266da81b331c964f871183c8e9030c 100644 (file)
@@ -309,6 +309,7 @@ void Cmd_Scoreboard_Help()
        LOG_INFO(_("^3ping^7                     Ping time"));
        LOG_INFO(_("^3pl^7                       Packet loss"));
        LOG_INFO(_("^3elo^7                      Player ELO"));
+       LOG_INFO(_("^3fps^7                      Player FPS"));
        LOG_INFO(_("^3kills^7                    Number of kills"));
        LOG_INFO(_("^3deaths^7                   Number of deaths"));
        LOG_INFO(_("^3suicides^7                 Number of suicides"));
@@ -359,7 +360,7 @@ void Cmd_Scoreboard_Help()
 // otherwise the previous exclusive rule warns anyway
 // e.g. -teams,rc,cts,lms/kills ?+rc/kills
 #define SCOREBOARD_DEFAULT_COLUMNS \
-"ping pl name |" \
+"ping pl fps name |" \
 " -teams,rc,cts,inv,lms/kills +ft,tdm/kills ?+rc,inv/kills" \
 " -teams,lms/deaths +ft,tdm/deaths" \
 " +tdm/sum" \
@@ -464,6 +465,7 @@ void Cmd_Scoreboard_SetFields(int argc)
                        case "elo": sbt_field[sbt_num_fields] = SP_ELO; break;
                        case "dmg": case "damage": sbt_field[sbt_num_fields] = SP_DMG; break;
                        case "dmgtaken": case "damagetaken": sbt_field[sbt_num_fields] = SP_DMGTAKEN; break;
+                       case "fps": sbt_field[sbt_num_fields] = SP_FPS; break;
                        default:
                        {
                                FOREACH(Scores, true, {
@@ -679,6 +681,19 @@ string Scoreboard_GetField(entity pl, PlayerScoreField field)
                        }
                }
 
+               case SP_FPS:
+               {
+                       float fps = pl.(scores(SP_FPS));
+                       if(fps == 0)
+                       {
+                               sbt_field_rgb = '1 1 1';
+                               return ((pl.ping == 0) ? _("N/A") : "..."); // if 0 ping, either connecting or bot (either case can't show proper score)
+                       }
+                       //sbt_field_rgb = HUD_Get_Num_Color(fps, 200);
+                       sbt_field_rgb = '1 0 0' + '0 1 1' * (bound(0, fps, 60) / 60);
+                       return ftos(fps);
+               }
+
                case SP_DMG: case SP_DMGTAKEN:
                        return sprintf("%.1f k", pl.(scores(field)) / 1000);
 
index 9bfa8db9ad0d6e51590150d28896883626528716..dd184bee9bbeb7d8dfcf3f5eb75abf7337d330b5 100644 (file)
@@ -370,6 +370,35 @@ STATIC_INIT(viewmodel) {
        viewmodels[slot] = new(viewmodel);
 }
 
+float showfps_prevfps;
+float showfps_prevfps_time;
+int showfps_framecounter;
+
+void fpscounter_update()
+{
+       if(!STAT(SHOWFPS))
+               return;
+
+       float currentTime = gettime(GETTIME_REALTIME);
+       showfps_framecounter += 1;
+       if(currentTime - showfps_prevfps_time > STAT(SHOWFPS))
+       {
+               showfps_prevfps = showfps_framecounter/(currentTime - showfps_prevfps_time);
+               showfps_framecounter = 0;
+               showfps_prevfps_time = currentTime;
+
+               int channel = MSG_C2S;
+               WriteHeader(channel, fpsreport);
+               WriteShort(channel, bound(0, rint(showfps_prevfps), 65535)); // prevent insane fps values
+       }
+}
+
+STATIC_INIT(fpscounter_init)
+{
+       float currentTime = gettime(GETTIME_REALTIME);
+       showfps_prevfps_time = currentTime; // we must initialize it to avoid an instant low frame sending
+}
+
 void Porto_Draw(entity this);
 STATIC_INIT(Porto)
 {
@@ -1866,6 +1895,7 @@ void CSQC_UpdateView(entity this, float w, float h)
 
        TargetMusic_Advance();
        Fog_Force();
+       fpscounter_update();
 
        if(drawtime == 0)
                drawframetime = 0.01666667; // when we don't know fps yet, we assume 60fps
index 7b69ad5030c9fb9d6ec510612001f2551f37e255..657e761712250cc7aed93ec4f3d93747979588f6 100644 (file)
@@ -55,3 +55,5 @@ REGISTER_NET_LINKED(ENT_CLIENT_SPAWNEVENT)
 REGISTER_NET_LINKED(ENT_CLIENT_WALL)
 
 #include <lib/csqcmodel/net.qh>
+
+REGISTER_NET_C2S(fpsreport)
index 476d0dbbaa612445241bd1450c48642a7f78f347..377a780770300554275d3685e3e6d53e90122bb8 100644 (file)
@@ -39,6 +39,8 @@ REGISTER_SP(FRAGS);
 
 REGISTER_SP(ELO);
 
+REGISTER_SP(FPS);
+
 // TODO: move to common mutators
 
 REGISTER_SP(RACE_TIME);
index db681315a6c4d27b3d804f5fb4a90bc13bf7e196..648ef60e844b8f316662ea633e5c6ac3ca2a12dc 100644 (file)
@@ -121,6 +121,11 @@ REGISTER_STAT(ENTRAP_ORB_ALPHA, float)
 REGISTER_STAT(ITEMSTIME, int, autocvar_sv_itemstime)
 REGISTER_STAT(KILL_TIME, float)
 
+#ifdef SVQC
+float autocvar_sv_showfps = 5;
+#endif
+REGISTER_STAT(SHOWFPS, float, autocvar_sv_showfps)
+
 #ifdef SVQC
 bool autocvar_g_ctf_leaderboard;
 #endif
index b1f5326a9bb5a441b5094de347cfe973086d5bd6..fe2952e2c4025c3d5f84854627824cc3f4ab3d6f 100644 (file)
@@ -304,6 +304,11 @@ MACRO_END
                if (g_buf) strunzone(g_buf);
                g_buf = strzone(tmp);
        }
+       void WriteShort(int to, int b)
+       {
+               WriteByte(to, (b >> 8) & 0xFF);
+               WriteByte(to, b & 0xFF);
+       }
 #elif defined(SVQC)
        int ReadByte()
        {
@@ -311,6 +316,10 @@ MACRO_END
                ydec_single(g_buf, ret);
                return ret;
        }
+       int ReadShort()
+       {
+               return (ReadByte() << 8) | (ReadByte());
+       }
        void WriteByte(int to, int b);
 #endif
 
index 5a199e06dc3396c61b7de4b0ff5e24bf112bcbb8..e898e74e8f996605e6a73bc8548a5a9004ea2336 100644 (file)
@@ -2833,3 +2833,10 @@ void PM_UpdateButtons(entity this, entity store)
        store.v_angle = this.v_angle;
        store.movement = this.movement;
 }
+
+NET_HANDLE(fpsreport, bool)
+{
+       int fps = ReadShort();
+       PlayerScore_Set(sender, SP_FPS, fps);
+       return true;
+}
index c9948660efe1165c7ed8654dac1ba770e6763277..3f1db42903ddd010c209febba24f608cba1c1840 100644 (file)
@@ -353,6 +353,28 @@ float PlayerScore_Add(entity player, PlayerScoreField scorefield, float score)
        return s.(scores(scorefield));
 }
 
+float PlayerScore_Set(entity player, PlayerScoreField scorefield, float score)
+{
+       if(!scores_initialized) return 0; // FIXME remove this when everything uses this system
+       entity s = CS(player).scorekeeper;
+       if(!s)
+       {
+               if(game_stopped)
+                       return 0;
+               LOG_WARN("Setting score of unknown player!");
+               return 0;
+       }
+
+       float oldscore = s.(scores(scorefield));
+       if(oldscore == score)
+               return oldscore;
+
+       if(scores_label(scorefield) != "")
+               s.SendFlags |= (2 ** (scorefield.m_id % 16));
+       s.(scores(scorefield)) = score;
+       return s.(scores(scorefield));
+}
+
 float PlayerTeamScore_Add(entity player, PlayerScoreField pscorefield, float tscorefield, float score)
 {
        float r;
index e2a57f43fb4a3ffaf36b6a5d33f1d475d793e9db..ad406196635a55b1ecf60667d653eba8a21c27bc 100644 (file)
@@ -24,6 +24,14 @@ void PlayerScore_Detach(entity player);
  */
 float PlayerScore_Add(entity player, PlayerScoreField scorefield, float score);
 
+/**
+ * Sets the player's score to the score parameter.
+ * NEVER call this if PlayerScore_Attach has not been called yet!
+ * Means: FIXME make players unable to join the game when not called ClientConnect yet.
+ * Returns the new (or old if unchanged) score.
+ */
+float PlayerScore_Set(entity player, PlayerScoreField scorefield, float score);
+
 /**
  * \brief Returns the player's score.
  * \param[in] player Player to inspect.
index 8d87407e64ebd3bc165efe3e27b53c6ceef25f0b..64c94001fbc5bcd9ab42caffd6d8c86604368a32 100644 (file)
@@ -55,6 +55,9 @@ void ScoreRules_basics(int teams, float sprio, float stprio, float score_enabled
        ScoreInfo_SetLabel_PlayerScore(SP_DMG, "dmg", 0);
        ScoreInfo_SetLabel_PlayerScore(SP_DMGTAKEN, "dmgtaken", SFL_LOWER_IS_BETTER);
        ScoreInfo_SetLabel_PlayerScore(SP_ELO, "elo", 0);
+
+       if(STAT(SHOWFPS))
+               ScoreInfo_SetLabel_PlayerScore(SP_FPS, "fps", 0);
 }
 void ScoreRules_basics_end()
 {
index 7b6504d5162875ab34d7c6f61710366352c78605..8f1457a034a07e6d4caf2edfdea024d68d55079a 100644 (file)
@@ -555,3 +555,5 @@ set sv_simple_items 1 "allow or forbid client use of simple items"
 set sv_showspectators 1 "Show who's spectating who in the player info panel when client has cl_showspectators on. Shouldn't be used on competitive servers, also disable when watching a suspected cheater"
 
 set sv_damagetext 2 "<= 0: disabled, >= 1: visible to spectators, >= 2: visible to attacker, >= 3: all players see everyone's damage"
+
+set sv_showfps 5 "Show player's FPS counters in the scoreboard. This setting acts as a delay in seconds between updates"