From 7cf4ed2d3022804c01e98022b9762ca06707f0de Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 12 Apr 2023 00:26:57 +1000 Subject: [PATCH] Netplay: Hand off full buffers to GGPO --- src/core/netplay.cpp | 57 +++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/core/netplay.cpp b/src/core/netplay.cpp index 7ea6b884f..f2f68c081 100644 --- a/src/core/netplay.cpp +++ b/src/core/netplay.cpp @@ -21,6 +21,8 @@ Log_SetChannel(Netplay); namespace Netplay { +using SaveStateBuffer = std::unique_ptr; + struct Input { u32 button_data; @@ -67,7 +69,7 @@ static GGPOPlayerHandle s_local_handle = GGPO_INVALID_HANDLE; static GGPONetworkStats s_last_net_stats{}; static GGPOSession* s_ggpo = nullptr; -static std::deque s_netplay_states; +static std::deque s_save_buffer_pool; static std::array, NUM_CONTROLLER_AND_CARD_PORTS> s_net_input; @@ -139,6 +141,7 @@ void Netplay::Close() { ggpo_close_session(s_ggpo); s_ggpo = nullptr; + s_save_buffer_pool.clear(); s_local_handle = GGPO_INVALID_HANDLE; s_max_pred = 0; @@ -344,7 +347,7 @@ void Netplay::StopNetplaySession() { if (!IsActive()) return; - s_netplay_states.clear(); + Close(); } @@ -404,37 +407,42 @@ bool Netplay::NpAdvFrameCb(void* ctx, int flags) return true; } -bool Netplay::NpSaveFrameCb(void* ctx, uint8_t** buffer, int* len, int* checksum, int frame) +bool Netplay::NpSaveFrameCb(void* ctx, unsigned char** buffer, int* len, int* checksum, int frame) { - bool result = false; - // give ggpo something so it doesnt complain. - u8 dummyData = 43; - *len = sizeof(u8); - *buffer = (unsigned char*)malloc(*len); - if (!*buffer) - return false; - memcpy(*buffer, &dummyData, *len); - // store state for later. - int pred = Netplay::GetMaxPrediction(); - if (frame < pred && s_netplay_states.size() < pred) + SaveStateBuffer our_buffer; + if (s_save_buffer_pool.empty()) { - System::MemorySaveState save; - result = System::SaveMemoryState(&save); - s_netplay_states.push_back(std::move(save)); + our_buffer = std::make_unique(); } else { - // reuse streams - result = System::SaveMemoryState(&s_netplay_states[frame % pred]); + our_buffer = std::move(s_save_buffer_pool.back()); + s_save_buffer_pool.pop_back(); } - return result; + + if (!System::SaveMemoryState(our_buffer.get())) + { + s_save_buffer_pool.push_back(std::move(our_buffer)); + return false; + } + + *len = sizeof(System::MemorySaveState); + *buffer = reinterpret_cast(our_buffer.release()); + return true; } -bool Netplay::NpLoadFrameCb(void* ctx, uint8_t* buffer, int len, int rb_frames, int frame_to_load) +bool Netplay::NpLoadFrameCb(void* ctx, unsigned char* buffer, int len, int rb_frames, int frame_to_load) { // Disable Audio For upcoming rollback SPU::SetAudioOutputMuted(true); - return System::LoadMemoryState(s_netplay_states[frame_to_load % Netplay::GetMaxPrediction()]); + + return System::LoadMemoryState(*reinterpret_cast(buffer)); +} + +void Netplay::NpFreeBuffCb(void* ctx, void* buffer) +{ + SaveStateBuffer our_buffer(reinterpret_cast(buffer)); + s_save_buffer_pool.push_back(std::move(our_buffer)); } bool Netplay::NpOnEventCb(void* ctx, GGPOEvent* ev) @@ -494,8 +502,3 @@ bool Netplay::NpOnEventCb(void* ctx, GGPOEvent* ev) } return true; } - -void Netplay::NpFreeBuffCb(void* ctx, void* buffer) -{ - free(buffer); -} \ No newline at end of file