From 11b6f8226ab6da6b418d493ba8f080e3c1fd41bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20B=C3=A1lint=20Misius?= Date: Wed, 14 Jul 2021 12:32:51 +0200 Subject: [PATCH] Tweak FPS sync a bit, fix a few ugly slowdown scenarios --- client.lua | 2 +- tptmp/client/client.lua | 51 +++++++++++++++++++++++++++-------------- tptmp/client/config.lua | 6 ++--- tptmp/client/init.lua | 16 +++++++------ 4 files changed, 47 insertions(+), 28 deletions(-) diff --git a/client.lua b/client.lua index bfbff29..880002d 100755 --- a/client.lua +++ b/client.lua @@ -19,7 +19,7 @@ local ENV_DEFAULTS = { DEFAULT_UI_WIND = 0, TPTMP_PT_UNKNOWN = 0, }, - tpt = { version = {} }, + tpt = { version = { major = 96, minor = 0 } }, http = {}, socket = {}, } diff --git a/tptmp/client/client.lua b/tptmp/client/client.lua index 68a395c..616d050 100644 --- a/tptmp/client/client.lua +++ b/tptmp/client/client.lua @@ -608,12 +608,16 @@ function client_i:handle_fpssync_76_() local lo = self:read_24be_() local elapsed = hi * 0x1000 + math.floor(mi / 0x1000) local count = mi % 0x1000 * 0x1000000 + lo + if member.fps_sync and elapsed <= member.fps_sync_elapsed then + self:fps_sync_end_(member) + end local now_msec = get_msec() if not member.fps_sync then member.fps_sync = true + member.fps_sync_count_diff = 0 member.fps_sync_first = now_msec member.fps_sync_history = {} - if self.fps_sync_ then + if self.fps_sync_count_ then member.fps_sync_count_offset = count - self.fps_sync_count_ end self.window_:backlog_push_fpssync_enable(member.formatted_nick) @@ -1108,18 +1112,38 @@ function client_i:tick_sim_() end end -function client_i:tick_fpssync_() +function client_i:fps_sync_end_(member) + self.window_:backlog_push_fpssync_disable(member.formatted_nick) + member.fps_sync = false +end + +function client_i:tick_fpssync_invalidate_() if self.registered_ then local now_msec = get_msec() for _, member in pairs(self.id_to_member) do if member.fps_sync then if member.fps_sync_last + config.fps_sync_timeout < now_msec then - self.window_:backlog_push_fpssync_disable(member.formatted_nick) - member.fps_sync = false + self:fps_sync_end_(member) end end end + end +end + +function client_i:tick_fpssync_() + if self.registered_ then if self.fps_sync_ then + local now_msec = get_msec() + if not self.fps_sync_first_ then + self.fps_sync_first_ = now_msec + self.fps_sync_last_ = 0 + self.fps_sync_count_ = 0 + for _, member in pairs(self.id_to_member) do + if member.fps_sync then + member.fps_sync_count_offset = member.fps_sync_count + end + end + end self.fps_sync_count_ = self.fps_sync_count_ + 1 if now_msec >= self.fps_sync_last_ + 1000 then self:send_fpssync(now_msec - self.fps_sync_first_, self.fps_sync_count_) @@ -1153,7 +1177,7 @@ function client_i:tick_fpssync_() tpt.setfpscap(2) else local smallest_fps = (smallest_target - self.fps_sync_count_) / (config.fps_sync_plan_ahead_by / 1000) - local fps = math.floor((target_fps + (smallest_fps - target_fps) * config.fps_sync_homing_factor)) + 0.5 + local fps = math.floor((target_fps + (smallest_fps - target_fps) * config.fps_sync_homing_factor) + 0.5) if fps < 10 then fps = 10 end tpt.setfpscap(fps) end @@ -1165,6 +1189,7 @@ function client_i:tick() if self.status_ ~= "running" then return end + self:tick_fpssync_invalidate_() self:tick_read_() self:tick_resume_() self:tick_write_() @@ -1277,22 +1302,14 @@ function client_i:nick_colour_seed(seed) end function client_i:fps_sync(fps_sync) - local prev_fps_sync = self.fps_sync_ - if prev_fps_sync and not fps_sync then + if self.fps_sync_ and not fps_sync then tpt.setfpscap(self.fps_sync_target_) end + if not self.fps_sync_ and fps_sync then + self.fps_sync_first_ = nil + end self.fps_sync_ = fps_sync and true or false self.fps_sync_target_ = fps_sync or false - if not prev_fps_sync and fps_sync then - self.fps_sync_first_ = get_msec() - self.fps_sync_last_ = 0 - self.fps_sync_count_ = 0 - for _, member in pairs(self.id_to_member) do - if member.fps_sync then - member.fps_sync_count_offset = member.fps_sync_count - end - end - end end function client_i:reformat_nicks_() diff --git a/tptmp/client/config.lua b/tptmp/client/config.lua index f3ca36b..32a4aa2 100644 --- a/tptmp/client/config.lua +++ b/tptmp/client/config.lua @@ -106,19 +106,19 @@ local config = { -- * Grace period in milliseconds after which another client is deemed to -- not have FPS synchronization enabled. - fps_sync_timeout = 3000, + fps_sync_timeout = 10000, -- * Interval to plan ahead in milliseconds, after which local number of -- frames simulated should more or less match the number of frames -- everyone else with FPS synchronization enabled has simulated. - fps_sync_plan_ahead_by = 1000, + fps_sync_plan_ahead_by = 3000, -- * Coefficient of linear interpolation between the current target FPS and -- that of the slowest client in the room with FPS synchronization -- enabled used when slowing down to match the number of frames simulated -- by this client. 0 means no slowing down at all, 1 means slowing down -- to the framerate the other client seems to be running at. - fps_sync_homing_factor = 0.8, + fps_sync_homing_factor = 0.5, -- *********************************************************************** diff --git a/tptmp/client/init.lua b/tptmp/client/init.lua index a426b59..8115f1d 100644 --- a/tptmp/client/init.lua +++ b/tptmp/client/init.lua @@ -164,8 +164,6 @@ local function run() [ 1 ] = " REPL", [ 2 ] = " SDEL", } - local brush_text_format = "%s\n" .. colours.commonstr.brush .. "%s %ix%i%s %s" - local select_text_format = "%s\n" .. colours.commonstr.brush .. "%s" local function handle_tick() local now = socket.gettime() if should_reconnect_at and now >= should_reconnect_at then @@ -230,6 +228,11 @@ local function run() end end local offx, offy = 6, -9 + local player_info = member.formatted_nick + if cli.fps_sync_ and member.fps_sync then + player_info = ("%s %s%+i"):format(player_info, colours.commonstr.brush, member.fps_sync_count_diff) + end + local brush_info if member.select or member.place then local xlo, ylo, xhi, yhi, action if member.select then @@ -246,7 +249,7 @@ local function run() action = member.place end gfx.drawRect(xlo, ylo, xhi - xlo + 1, yhi - ylo + 1, pcur_r, pcur_g, pcur_b, pcur_a) - gfx.drawText(px + offx, py + offy, select_text_format:format(member.formatted_nick, action), pcur_r, pcur_g, pcur_b, pcur_a) + brush_info = action else local dsx, dsy = sx * 2 + 1, sy * 2 + 1 if tool_class == "WL" then @@ -258,7 +261,7 @@ local function run() if sx < 50 then offx = offx + sx end - gfx.drawText(px + offx, py + offy, brush_text_format:format(member.formatted_nick, tool_name, dsx, dsy, bmode_to_repr[member.bmode], repl_tool_name or ""), pcur_r, pcur_g, pcur_b, pcur_a) + brush_info = ("%s %ix%i%s %s"):format(tool_name, dsx, dsy, bmode_to_repr[member.bmode], repl_tool_name or "") if not rx then if not lx and member.kmod_s and member.kmod_c then gfx.drawLine(px - 5, py, px + 5, py, pcur_r, pcur_g, pcur_b, pcur_a) @@ -289,9 +292,8 @@ local function run() gfx.drawRect(x, y, w, h, pcur_r, pcur_g, pcur_b, pcur_a) end end - if cli.fps_sync_ and member.fps_sync then - gfx.drawText(px + offx, py + offy + 24, tostring(member.fps_sync_count_diff), pcur_r, pcur_g, pcur_b, pcur_a) - end + gfx.drawText(px + offx, py + offy, player_info, pcur_r, pcur_g, pcur_b, pcur_a) + gfx.drawText(px + offx, py + offy + 12, brush_info, pcur_r, pcur_g, pcur_b, pcur_a) end end end