ggpo: rollback glitches. win32 init. switch build. stats
Block net rollbacks until the current frame has been processed to avoid glitched textures. Call WSAStartup at init on windows Display net stats when in game Switch build fix
This commit is contained in:
parent
69d0801121
commit
b362a55c04
|
|
@ -303,6 +303,9 @@ typedef struct GGPONetworkStats {
|
|||
int local_frames_behind;
|
||||
int remote_frames_behind;
|
||||
} timesync;
|
||||
struct {
|
||||
int predicted_frames;
|
||||
} sync;
|
||||
} GGPONetworkStats;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -529,6 +529,7 @@ Peer2PeerBackend::GetNetworkStats(GGPONetworkStats *stats, GGPOPlayerHandle play
|
|||
|
||||
memset(stats, 0, sizeof *stats);
|
||||
_endpoints[queue].GetNetworkStats(stats);
|
||||
stats->sync.predicted_frames = _sync.GetPredictedFrames();
|
||||
|
||||
return GGPO_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@ struct Init
|
|||
{
|
||||
Init() {
|
||||
srand(Platform::GetCurrentTimeMS() + Platform::GetProcessID());
|
||||
#ifdef _WIN32
|
||||
WSADATA wsaData;
|
||||
WSAStartup(MAKEWORD(2, 0), &wsaData);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
static Init init;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,11 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#ifdef __SWITCH__
|
||||
#include "nswitch.h"
|
||||
#else
|
||||
#include <netinet/ip.h>
|
||||
#endif
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ public:
|
|||
|
||||
int GetFrameCount() { return _framecount; }
|
||||
bool InRollback() { return _rollingback; }
|
||||
int GetPredictedFrames() { return _framecount - _last_confirmed_frame; }
|
||||
|
||||
bool GetEvent(Event &e);
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ cResetEvent rs, re;
|
|||
static bool do_swap;
|
||||
std::mutex swap_mutex;
|
||||
u32 fb_w_cur = 1;
|
||||
static cResetEvent vramRollback;
|
||||
|
||||
// direct framebuffer write detection
|
||||
static bool render_called = false;
|
||||
|
|
@ -197,6 +198,7 @@ static bool rend_frame(TA_context* ctx)
|
|||
if (!proc || (!ctx->rend.isRTT && !ctx->rend.isRenderFramebuffer))
|
||||
// If rendering to texture, continue locking until the frame is rendered
|
||||
re.Set();
|
||||
rend_allow_rollback();
|
||||
|
||||
return proc && renderer->Render();
|
||||
}
|
||||
|
|
@ -437,6 +439,7 @@ void rend_cancel_emu_wait()
|
|||
{
|
||||
FinishRender(NULL);
|
||||
re.Set();
|
||||
rend_allow_rollback();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -470,3 +473,18 @@ void rend_swap_frame(u32 fb_r_sof1)
|
|||
}
|
||||
swap_mutex.unlock();
|
||||
}
|
||||
|
||||
void rend_disable_rollback()
|
||||
{
|
||||
vramRollback.Reset();
|
||||
}
|
||||
|
||||
void rend_allow_rollback()
|
||||
{
|
||||
vramRollback.Set();
|
||||
}
|
||||
|
||||
void rend_start_rollback()
|
||||
{
|
||||
vramRollback.Wait();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@ bool rend_single_frame(const bool& enabled);
|
|||
void rend_swap_frame(u32 fb_r_sof1);
|
||||
void rend_set_fb_write_addr(u32 fb_w_sof1);
|
||||
void rend_reset();
|
||||
void rend_disable_rollback();
|
||||
void rend_start_rollback();
|
||||
void rend_allow_rollback();
|
||||
|
||||
///////
|
||||
extern TA_context* _pvrrc;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#if defined(__SWITCH__)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include "Renderer_if.h"
|
||||
|
||||
extern u32 fskip;
|
||||
extern u32 FrameCount;
|
||||
|
|
@ -101,7 +102,8 @@ bool QueueRender(TA_context* ctx)
|
|||
fskip++;
|
||||
return false;
|
||||
}
|
||||
|
||||
// disable net rollbacks until the render thread has processed the frame
|
||||
rend_disable_rollback();
|
||||
frame_finished.Reset();
|
||||
mtx_rqueue.lock();
|
||||
TA_context* old = rqueue;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
#include <xxhash.h>
|
||||
#include "imgui/imgui.h"
|
||||
|
||||
//#define SYNC_TEST 1
|
||||
|
||||
|
|
@ -59,6 +60,8 @@ struct MemPages
|
|||
static std::unordered_map<int, MemPages> deltaStates;
|
||||
static int lastSavedFrame = -1;
|
||||
|
||||
static int timesyncOccurred;
|
||||
|
||||
/*
|
||||
* begin_game callback - This callback has been deprecated. You must
|
||||
* implement it, but should ignore the 'game' parameter.
|
||||
|
|
@ -99,6 +102,7 @@ static bool on_event(GGPOEvent *info)
|
|||
break;
|
||||
case GGPO_EVENTCODE_TIMESYNC:
|
||||
INFO_LOG(NETWORK, "Timesync: %d frames ahead", info->u.timesync.frames_ahead);
|
||||
timesyncOccurred += 5;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000 * info->u.timesync.frames_ahead / 60)); // FIXME assumes 60 FPS
|
||||
break;
|
||||
case GGPO_EVENTCODE_CONNECTION_INTERRUPTED:
|
||||
|
|
@ -149,6 +153,7 @@ static bool load_game_state(unsigned char *buffer, int len)
|
|||
{
|
||||
INFO_LOG(NETWORK, "load_game_state");
|
||||
|
||||
rend_start_rollback();
|
||||
// FIXME will invalidate too much stuff: palette/fog textures, maple stuff
|
||||
// FIXME dynarecs
|
||||
int frame = *(u32 *)buffer;
|
||||
|
|
@ -172,6 +177,7 @@ static bool load_game_state(unsigned char *buffer, int len)
|
|||
DEBUG_LOG(NETWORK, "Restored frame %d pages: %d ram, %d vram, %d aica ram", f, (u32)pages.ram.size(),
|
||||
(u32)pages.vram.size(), (u32)pages.aram.size());
|
||||
}
|
||||
rend_allow_rollback(); // ggpo might load another state right after this one
|
||||
memwatch::reset();
|
||||
memwatch::protect();
|
||||
return true;
|
||||
|
|
@ -468,6 +474,59 @@ std::future<bool> startNetwork()
|
|||
});
|
||||
}
|
||||
|
||||
void displayStats()
|
||||
{
|
||||
if (!active())
|
||||
return;
|
||||
GGPONetworkStats stats;
|
||||
ggpo_get_network_stats(ggpoSession, remotePlayer, &stats);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0);
|
||||
ImGui::SetNextWindowPos(ImVec2(10, 10));
|
||||
ImGui::SetNextWindowSize(ImVec2(95 * scaling, 0));
|
||||
ImGui::SetNextWindowBgAlpha(0.7f);
|
||||
ImGui::Begin("", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration);
|
||||
|
||||
ImGui::Columns(2, "cols", false);
|
||||
ImGui::SetColumnWidth(0, 55 * scaling);
|
||||
ImGui::SetColumnWidth(1, 40 * scaling);
|
||||
ImGui::Text("Send Q");
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("%d", stats.network.send_queue_len);
|
||||
ImGui::NextColumn();
|
||||
|
||||
ImGui::Text("Ping");
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("%d", stats.network.ping);
|
||||
ImGui::NextColumn();
|
||||
|
||||
if (stats.sync.predicted_frames == 7)
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1, 0, 0, 1));
|
||||
ImGui::Text("Predicted");
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("%d", stats.sync.predicted_frames);
|
||||
ImGui::NextColumn();
|
||||
if (stats.sync.predicted_frames == 7)
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
int timesync = timesyncOccurred;
|
||||
if (timesync > 0)
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1, 0, 0, 1));
|
||||
ImGui::Text("Behind");
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("%d", stats.timesync.local_frames_behind);
|
||||
if (timesync > 0)
|
||||
{
|
||||
ImGui::PopStyleColor();
|
||||
timesyncOccurred--;
|
||||
}
|
||||
ImGui::Columns(1);
|
||||
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar(2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else // LIBRETRO
|
||||
|
|
@ -496,5 +555,8 @@ std::future<bool> startNetwork() {
|
|||
return std::async(std::launch::deferred, []{ return false; });;
|
||||
}
|
||||
|
||||
void displayStats() {
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -28,5 +28,6 @@ void stopSession();
|
|||
void getInput(u32 out_kcode[4]);
|
||||
void nextFrame();
|
||||
bool active();
|
||||
void displayStats();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2242,7 +2242,7 @@ void gui_display_osd()
|
|||
if (message.empty())
|
||||
message = getFPSNotification();
|
||||
|
||||
if (!message.empty() || config::FloatVMUs || crosshairsNeeded())
|
||||
if (!message.empty() || config::FloatVMUs || crosshairsNeeded() || ggpo::active())
|
||||
{
|
||||
ImGui_Impl_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
|
@ -2263,6 +2263,7 @@ void gui_display_osd()
|
|||
if (config::FloatVMUs)
|
||||
display_vmus();
|
||||
// gui_plot_render_time(screen_width, screen_height);
|
||||
ggpo::displayStats();
|
||||
|
||||
ImGui::Render();
|
||||
ImGui_impl_RenderDrawData(ImGui::GetDrawData());
|
||||
|
|
|
|||
Loading…
Reference in New Issue