mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-18 00:09:11 +00:00
Added SaveState saving
This commit is contained in:
parent
ef34d8fe0f
commit
473f54de0a
2 changed files with 75 additions and 2 deletions
|
@ -45,6 +45,7 @@
|
|||
#include "Core/GeckoCode.h"
|
||||
#include "Core/HW/EXI/EXI.h"
|
||||
#include "Core/HW/EXI/EXI_DeviceIPL.h"
|
||||
#include "Core/State.h"
|
||||
#ifdef HAS_LIBMGBA
|
||||
#include "Core/HW/GBACore.h"
|
||||
#endif
|
||||
|
@ -975,10 +976,11 @@ void NetPlayClient::OnStartGame(sf::Packet& packet)
|
|||
}
|
||||
|
||||
inputs.clear();
|
||||
|
||||
for (int i = 0; i < m_players.size(); i++)
|
||||
inputs.push_back(std::vector<GCPadStatus>{});
|
||||
|
||||
save_states.reset();
|
||||
|
||||
m_dialog->OnMsgStartGame();
|
||||
}
|
||||
|
||||
|
@ -1634,6 +1636,47 @@ void NetPlayClient::OnFrameEnd()
|
|||
|
||||
if (send_packet)
|
||||
SendAsync(std::move(packet));
|
||||
|
||||
lock.unlock();
|
||||
std::shared_ptr<SaveState> new_save_state = std::make_shared<SaveState>();
|
||||
State::SaveToBuffer(*new_save_state);
|
||||
lock.lock();
|
||||
save_states.New() = new_save_state;
|
||||
|
||||
// Wait for inputs if others are behind us, continue if we're behind them
|
||||
int local_player_port = -1;
|
||||
for (int i = 0; i < m_pad_map.size(); i++)
|
||||
{
|
||||
if (m_pad_map.at(i) == m_local_player->pid)
|
||||
local_player_port = i;
|
||||
}
|
||||
|
||||
for (int remote_players = 0; remote_players < inputs.size(); remote_players++)
|
||||
{
|
||||
if (remote_players == local_player_port)
|
||||
continue;
|
||||
|
||||
auto frame_difference = static_cast<long long>(inputs.at(local_player_port).size()) -
|
||||
static_cast<long long>(inputs.at(remote_players).size());
|
||||
|
||||
if (frame_difference <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (frame_difference > rollback_frames_supported + delay)
|
||||
{
|
||||
if (!m_is_running.IsSet())
|
||||
break;
|
||||
|
||||
frame_difference = static_cast<long long>(inputs.at(local_player_port).size()) -
|
||||
static_cast<long long>(inputs.at(remote_players).size());
|
||||
|
||||
wait_for_inputs.wait_for(lock, 1ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetPlayClient::Send(const sf::Packet& packet, const u8 channel_id)
|
||||
|
|
|
@ -43,7 +43,35 @@ struct SerializedWiimoteState;
|
|||
|
||||
namespace NetPlay
|
||||
{
|
||||
constexpr size_t rollback_frames_supported = 10;
|
||||
constexpr int rollback_frames_supported = 10;
|
||||
using SaveState = std::vector<u8>;
|
||||
// 0 is the closest SaveState in time from the current frame
|
||||
class SaveStateArray
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<SaveState>& New()
|
||||
{
|
||||
std::array<std::shared_ptr<SaveState>, rollback_frames_supported> new_array{};
|
||||
|
||||
for (int i = rollback_frames_supported - 2; i >= 0; i--)
|
||||
{
|
||||
new_array.at(i + 1) = main_array.at(i);
|
||||
}
|
||||
new_array.at(0) = std::shared_ptr<SaveState>{};
|
||||
main_array = std::move(new_array);
|
||||
|
||||
return main_array.at(0);
|
||||
};
|
||||
|
||||
void reset()
|
||||
{
|
||||
for (auto& save_state : main_array)
|
||||
save_state = std::shared_ptr<SaveState>{};
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<std::shared_ptr<SaveState>, rollback_frames_supported> main_array;
|
||||
};
|
||||
|
||||
class NetPlayUI
|
||||
{
|
||||
|
@ -364,6 +392,8 @@ private:
|
|||
|
||||
std::vector<std::vector<GCPadStatus>> inputs;
|
||||
int delay = 2;
|
||||
std::condition_variable wait_for_inputs;
|
||||
SaveStateArray save_states;
|
||||
};
|
||||
|
||||
void NetPlay_Enable(NetPlayClient* const np);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue