GGPO: poll_network functionality and ggpo_set_manual_network_polling
This commit is contained in:
parent
7cf4ed2d30
commit
de9c16bb73
|
@ -541,8 +541,9 @@ GGPO_API GGPOErrorCode __cdecl ggpo_disconnect_player(GGPOSession *,
|
||||||
GGPO_API GGPOErrorCode __cdecl ggpo_advance_frame(GGPOSession *, uint16_t checksum);
|
GGPO_API GGPOErrorCode __cdecl ggpo_advance_frame(GGPOSession *, uint16_t checksum);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ggpo_get_current_frame -- current frame GGPO is dealing with
|
* ggpo_get_current_frame --
|
||||||
*
|
*
|
||||||
|
* current frame GGPO is dealing with
|
||||||
*/
|
*/
|
||||||
GGPO_API GGPOErrorCode __cdecl ggpo_get_current_frame(GGPOSession* ggpo, int& nFrame);
|
GGPO_API GGPOErrorCode __cdecl ggpo_get_current_frame(GGPOSession* ggpo, int& nFrame);
|
||||||
/*
|
/*
|
||||||
|
@ -573,8 +574,16 @@ GGPO_API GGPOErrorCode __cdecl ggpo_get_network_stats(GGPOSession *,
|
||||||
*/
|
*/
|
||||||
GGPO_API GGPOErrorCode __cdecl ggpo_set_disconnect_timeout(GGPOSession *,
|
GGPO_API GGPOErrorCode __cdecl ggpo_set_disconnect_timeout(GGPOSession *,
|
||||||
int timeout);
|
int timeout);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* ggpo_enable_manual_network_polling --
|
||||||
|
*
|
||||||
|
* disables polling done by ggpo and it's expected that ggpo_poll_network will be used instead.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
GGPO_API GGPOErrorCode __cdecl ggpo_set_manual_network_polling(GGPOSession*,
|
||||||
|
bool value);
|
||||||
|
/*
|
||||||
* ggpo_set_disconnect_notify_start --
|
* ggpo_set_disconnect_notify_start --
|
||||||
*
|
*
|
||||||
* The time to wait before the first GGPO_EVENTCODE_NETWORK_INTERRUPTED timeout
|
* The time to wait before the first GGPO_EVENTCODE_NETWORK_INTERRUPTED timeout
|
||||||
|
@ -584,7 +593,15 @@ GGPO_API GGPOErrorCode __cdecl ggpo_set_disconnect_timeout(GGPOSession *,
|
||||||
* before the GGPO_EVENTCODE_NETWORK_INTERRUPTED event is sent.
|
* before the GGPO_EVENTCODE_NETWORK_INTERRUPTED event is sent.
|
||||||
*/
|
*/
|
||||||
GGPO_API GGPOErrorCode __cdecl ggpo_set_disconnect_notify_start(GGPOSession *,
|
GGPO_API GGPOErrorCode __cdecl ggpo_set_disconnect_notify_start(GGPOSession *,
|
||||||
int timeout);
|
int timeout);
|
||||||
|
/*
|
||||||
|
* ggpo_poll_network --
|
||||||
|
*
|
||||||
|
* polls the network socket for any messages to be sent and recieved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
GGPO_API GGPOErrorCode __cdecl ggpo_poll_network(GGPOSession*);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ggpo_log --
|
* ggpo_log --
|
||||||
|
|
|
@ -22,12 +22,14 @@ public:
|
||||||
virtual GGPOErrorCode CurrentFrame(int& current) =0;
|
virtual GGPOErrorCode CurrentFrame(int& current) =0;
|
||||||
virtual GGPOErrorCode Chat(const char* text) = 0;// { return GGPO_OK; }
|
virtual GGPOErrorCode Chat(const char* text) = 0;// { return GGPO_OK; }
|
||||||
virtual GGPOErrorCode DisconnectPlayer(GGPOPlayerHandle handle) = 0;// { return GGPO_OK; }
|
virtual GGPOErrorCode DisconnectPlayer(GGPOPlayerHandle handle) = 0;// { return GGPO_OK; }
|
||||||
|
virtual GGPOErrorCode PollNetwork() = 0;
|
||||||
virtual GGPOErrorCode GetNetworkStats(GGPONetworkStats *stats, GGPOPlayerHandle handle) { return GGPO_OK; }
|
virtual GGPOErrorCode GetNetworkStats(GGPONetworkStats *stats, GGPOPlayerHandle handle) { return GGPO_OK; }
|
||||||
virtual GGPOErrorCode Logv(const char *fmt, va_list list) { ::Logv(fmt, list); return GGPO_OK; }
|
virtual GGPOErrorCode Logv(const char *fmt, va_list list) { ::Logv(fmt, list); return GGPO_OK; }
|
||||||
|
|
||||||
virtual GGPOErrorCode SetFrameDelay(GGPOPlayerHandle player, int delay) { return GGPO_ERRORCODE_UNSUPPORTED; }
|
virtual GGPOErrorCode SetFrameDelay(GGPOPlayerHandle player, int delay) { return GGPO_ERRORCODE_UNSUPPORTED; }
|
||||||
virtual GGPOErrorCode SetDisconnectTimeout(int timeout) { return GGPO_ERRORCODE_UNSUPPORTED; }
|
virtual GGPOErrorCode SetDisconnectTimeout(int timeout) { return GGPO_ERRORCODE_UNSUPPORTED; }
|
||||||
virtual GGPOErrorCode SetDisconnectNotifyStart(int timeout) { return GGPO_ERRORCODE_UNSUPPORTED; }
|
virtual GGPOErrorCode SetDisconnectNotifyStart(int timeout) { return GGPO_ERRORCODE_UNSUPPORTED; }
|
||||||
|
virtual GGPOErrorCode SetManualNetworkPolling(bool value) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ Peer2PeerBackend::Peer2PeerBackend(GGPOSessionCallbacks *cb,
|
||||||
_callbacks = *cb;
|
_callbacks = *cb;
|
||||||
_synchronizing = true;
|
_synchronizing = true;
|
||||||
_next_recommended_sleep = 0;
|
_next_recommended_sleep = 0;
|
||||||
|
_manual_network_polling = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the synchronziation layer
|
* Initialize the synchronziation layer
|
||||||
|
@ -150,6 +151,7 @@ void Peer2PeerBackend::CheckDesync()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GGPOErrorCode
|
GGPOErrorCode
|
||||||
Peer2PeerBackend::DoPoll()
|
Peer2PeerBackend::DoPoll()
|
||||||
{
|
{
|
||||||
|
@ -165,7 +167,8 @@ Peer2PeerBackend::DoPoll()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_sync.InRollback()) {
|
if (!_sync.InRollback()) {
|
||||||
_poll.Pump(0);
|
if (!_manual_network_polling)
|
||||||
|
_poll.Pump(0);
|
||||||
|
|
||||||
PollUdpProtocolEvents();
|
PollUdpProtocolEvents();
|
||||||
CheckDesync();
|
CheckDesync();
|
||||||
|
@ -402,11 +405,27 @@ Peer2PeerBackend::SyncInput(void *values,
|
||||||
}
|
}
|
||||||
return GGPO_OK;
|
return GGPO_OK;
|
||||||
}
|
}
|
||||||
GGPOErrorCode Peer2PeerBackend::CurrentFrame(int& current)
|
|
||||||
|
GGPOErrorCode
|
||||||
|
Peer2PeerBackend::CurrentFrame(int& current)
|
||||||
{
|
{
|
||||||
current = _sync.GetFrameCount();
|
current = _sync.GetFrameCount();
|
||||||
return GGPO_OK;
|
return GGPO_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GGPOErrorCode
|
||||||
|
Peer2PeerBackend::PollNetwork()
|
||||||
|
{
|
||||||
|
_poll.Pump(0);
|
||||||
|
return GGPO_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
GGPOErrorCode Peer2PeerBackend::SetManualNetworkPolling(bool value)
|
||||||
|
{
|
||||||
|
_manual_network_polling = value;
|
||||||
|
return GGPO_OK;
|
||||||
|
}
|
||||||
|
|
||||||
GGPOErrorCode
|
GGPOErrorCode
|
||||||
Peer2PeerBackend::IncrementFrame(uint16_t checksum1)
|
Peer2PeerBackend::IncrementFrame(uint16_t checksum1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,10 @@ public:
|
||||||
virtual GGPOErrorCode SetDisconnectNotifyStart(int timeout) override;
|
virtual GGPOErrorCode SetDisconnectNotifyStart(int timeout) override;
|
||||||
virtual GGPOErrorCode Chat(const char* text) override;
|
virtual GGPOErrorCode Chat(const char* text) override;
|
||||||
virtual GGPOErrorCode CurrentFrame(int& current) override;
|
virtual GGPOErrorCode CurrentFrame(int& current) override;
|
||||||
public:
|
virtual GGPOErrorCode PollNetwork() override;
|
||||||
|
virtual GGPOErrorCode SetManualNetworkPolling(bool value) override;
|
||||||
|
|
||||||
|
public:
|
||||||
virtual void OnMsg(sockaddr_in &from, UdpMsg *msg, int len);
|
virtual void OnMsg(sockaddr_in &from, UdpMsg *msg, int len);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -72,6 +75,8 @@ protected:
|
||||||
int _disconnect_timeout;
|
int _disconnect_timeout;
|
||||||
int _disconnect_notify_start;
|
int _disconnect_notify_start;
|
||||||
|
|
||||||
|
bool _manual_network_polling;
|
||||||
|
|
||||||
UdpMsg::connect_status _local_connect_status[UDP_MSG_MAX_PLAYERS];
|
UdpMsg::connect_status _local_connect_status[UDP_MSG_MAX_PLAYERS];
|
||||||
struct ChecksumEntry {
|
struct ChecksumEntry {
|
||||||
int nFrame;
|
int nFrame;
|
||||||
|
|
|
@ -20,6 +20,7 @@ SpectatorBackend::SpectatorBackend(GGPOSessionCallbacks *cb,
|
||||||
{
|
{
|
||||||
_callbacks = *cb;
|
_callbacks = *cb;
|
||||||
_synchronizing = true;
|
_synchronizing = true;
|
||||||
|
_manual_network_polling = false;
|
||||||
|
|
||||||
for (int i = 0; i < ARRAY_SIZE(_inputs); i++) {
|
for (int i = 0; i < ARRAY_SIZE(_inputs); i++) {
|
||||||
_inputs[i].frame = -1;
|
_inputs[i].frame = -1;
|
||||||
|
@ -46,10 +47,11 @@ SpectatorBackend::~SpectatorBackend()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
GGPOErrorCode
|
GGPOErrorCode
|
||||||
SpectatorBackend::DoPoll()
|
SpectatorBackend::DoPoll()
|
||||||
{
|
{
|
||||||
_poll.Pump(0);
|
if (!_manual_network_polling)
|
||||||
|
_poll.Pump(0);
|
||||||
|
|
||||||
PollUdpProtocolEvents();
|
PollUdpProtocolEvents();
|
||||||
return GGPO_OK;
|
return GGPO_OK;
|
||||||
|
@ -86,11 +88,27 @@ SpectatorBackend::SyncInput(void *values,
|
||||||
return GGPO_OK;
|
return GGPO_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
GGPOErrorCode SpectatorBackend::CurrentFrame(int& current)
|
GGPOErrorCode
|
||||||
|
SpectatorBackend::CurrentFrame(int& current)
|
||||||
{
|
{
|
||||||
current= _next_input_to_send;
|
current= _next_input_to_send;
|
||||||
return GGPO_OK;
|
return GGPO_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GGPOErrorCode
|
||||||
|
SpectatorBackend::PollNetwork()
|
||||||
|
{
|
||||||
|
_poll.Pump(0);
|
||||||
|
return GGPO_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
GGPOErrorCode
|
||||||
|
SpectatorBackend::SetManualNetworkPolling(bool value)
|
||||||
|
{
|
||||||
|
_manual_network_polling = value;
|
||||||
|
return GGPO_OK;
|
||||||
|
}
|
||||||
|
|
||||||
GGPOErrorCode
|
GGPOErrorCode
|
||||||
SpectatorBackend::IncrementFrame(uint16_t checksum)
|
SpectatorBackend::IncrementFrame(uint16_t checksum)
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,7 +36,8 @@ public:
|
||||||
virtual GGPOErrorCode SetDisconnectNotifyStart(int timeout) { return GGPO_ERRORCODE_UNSUPPORTED; }
|
virtual GGPOErrorCode SetDisconnectNotifyStart(int timeout) { return GGPO_ERRORCODE_UNSUPPORTED; }
|
||||||
virtual GGPOErrorCode Chat(const char* text) override { return GGPO_ERRORCODE_UNSUPPORTED; }
|
virtual GGPOErrorCode Chat(const char* text) override { return GGPO_ERRORCODE_UNSUPPORTED; }
|
||||||
virtual GGPOErrorCode CurrentFrame(int& current) override;
|
virtual GGPOErrorCode CurrentFrame(int& current) override;
|
||||||
|
virtual GGPOErrorCode PollNetwork() override;
|
||||||
|
virtual GGPOErrorCode SetManualNetworkPolling(bool value) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void OnMsg(sockaddr_in &from, UdpMsg *msg, int len);
|
virtual void OnMsg(sockaddr_in &from, UdpMsg *msg, int len);
|
||||||
|
@ -57,6 +58,7 @@ protected:
|
||||||
int _num_players;
|
int _num_players;
|
||||||
int _next_input_to_send;
|
int _next_input_to_send;
|
||||||
GameInput _inputs[SPECTATOR_FRAME_BUFFER_SIZE];
|
GameInput _inputs[SPECTATOR_FRAME_BUFFER_SIZE];
|
||||||
|
bool _manual_network_polling;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,7 +27,10 @@ public:
|
||||||
virtual GGPOErrorCode DisconnectPlayer(GGPOPlayerHandle handle) { return GGPO_OK; }
|
virtual GGPOErrorCode DisconnectPlayer(GGPOPlayerHandle handle) { return GGPO_OK; }
|
||||||
virtual GGPOErrorCode Chat(const char* text) override { return GGPO_ERRORCODE_UNSUPPORTED; }
|
virtual GGPOErrorCode Chat(const char* text) override { return GGPO_ERRORCODE_UNSUPPORTED; }
|
||||||
virtual GGPOErrorCode CurrentFrame(int& current) override;
|
virtual GGPOErrorCode CurrentFrame(int& current) override;
|
||||||
protected:
|
virtual GGPOErrorCode PollNetwork() override { return GGPO_OK; };
|
||||||
|
virtual GGPOErrorCode SetManualNetworkPolling(bool value) override { return GGPO_OK; };
|
||||||
|
|
||||||
|
protected:
|
||||||
struct SavedInfo {
|
struct SavedInfo {
|
||||||
int frame;
|
int frame;
|
||||||
int checksum;
|
int checksum;
|
||||||
|
|
|
@ -191,6 +191,16 @@ ggpo_set_disconnect_timeout(GGPOSession *ggpo, int timeout)
|
||||||
return ggpo->SetDisconnectTimeout(timeout);
|
return ggpo->SetDisconnectTimeout(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GGPOErrorCode
|
||||||
|
ggpo_set_manual_network_polling(GGPOSession *ggpo, bool value)
|
||||||
|
{
|
||||||
|
if (!ggpo)
|
||||||
|
{
|
||||||
|
return GGPO_ERRORCODE_INVALID_SESSION;
|
||||||
|
}
|
||||||
|
return ggpo->SetManualNetworkPolling(value);
|
||||||
|
}
|
||||||
|
|
||||||
GGPOErrorCode
|
GGPOErrorCode
|
||||||
ggpo_set_disconnect_notify_start(GGPOSession *ggpo, int timeout)
|
ggpo_set_disconnect_notify_start(GGPOSession *ggpo, int timeout)
|
||||||
{
|
{
|
||||||
|
@ -200,6 +210,16 @@ ggpo_set_disconnect_notify_start(GGPOSession *ggpo, int timeout)
|
||||||
return ggpo->SetDisconnectNotifyStart(timeout);
|
return ggpo->SetDisconnectNotifyStart(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GGPOErrorCode
|
||||||
|
ggpo_poll_network(GGPOSession* ggpo)
|
||||||
|
{
|
||||||
|
if (!ggpo)
|
||||||
|
{
|
||||||
|
return GGPO_ERRORCODE_INVALID_SESSION;
|
||||||
|
}
|
||||||
|
return ggpo->PollNetwork();
|
||||||
|
}
|
||||||
|
|
||||||
GGPOErrorCode ggpo_start_spectating(GGPOSession **session,
|
GGPOErrorCode ggpo_start_spectating(GGPOSession **session,
|
||||||
GGPOSessionCallbacks *cb,
|
GGPOSessionCallbacks *cb,
|
||||||
const char *game,
|
const char *game,
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
#include "common/timer.h"
|
#include "common/timer.h"
|
||||||
#include "digital_controller.h"
|
#include "digital_controller.h"
|
||||||
#include "ggponet.h"
|
#include "ggponet.h"
|
||||||
|
#include "host_settings.h"
|
||||||
#include "pad.h"
|
#include "pad.h"
|
||||||
#include "spu.h"
|
#include "spu.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "host_settings.h"
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
Log_SetChannel(Netplay);
|
Log_SetChannel(Netplay);
|
||||||
|
@ -82,7 +82,6 @@ static Common::Timer::Value s_next_frame_time = 0;
|
||||||
|
|
||||||
// Netplay Impl
|
// Netplay Impl
|
||||||
|
|
||||||
|
|
||||||
s32 Netplay::Start(s32 lhandle, u16 lport, std::string& raddr, u16 rport, s32 ldelay, u32 pred)
|
s32 Netplay::Start(s32 lhandle, u16 lport, std::string& raddr, u16 rport, s32 ldelay, u32 pred)
|
||||||
{
|
{
|
||||||
SetSettings();
|
SetSettings();
|
||||||
|
@ -105,7 +104,7 @@ s32 Netplay::Start(s32 lhandle, u16 lport, std::string& raddr, u16 rport, s32 ld
|
||||||
GGPOErrorCode result;
|
GGPOErrorCode result;
|
||||||
|
|
||||||
result = ggpo_start_session(&s_ggpo, &cb, "Duckstation-Netplay", 2, sizeof(Netplay::Input), lport, s_max_pred);
|
result = ggpo_start_session(&s_ggpo, &cb, "Duckstation-Netplay", 2, sizeof(Netplay::Input), lport, s_max_pred);
|
||||||
//result = ggpo_start_synctest(&s_ggpo, &cb, (char*)"asdf", 2, sizeof(Netplay::Input), 1);
|
// result = ggpo_start_synctest(&s_ggpo, &cb, (char*)"asdf", 2, sizeof(Netplay::Input), 1);
|
||||||
|
|
||||||
ggpo_set_disconnect_timeout(s_ggpo, 3000);
|
ggpo_set_disconnect_timeout(s_ggpo, 3000);
|
||||||
ggpo_set_disconnect_notify_start(s_ggpo, 1000);
|
ggpo_set_disconnect_notify_start(s_ggpo, 1000);
|
||||||
|
@ -133,6 +132,7 @@ s32 Netplay::Start(s32 lhandle, u16 lport, std::string& raddr, u16 rport, s32 ld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ggpo_set_frame_delay(s_ggpo, s_local_handle, ldelay);
|
ggpo_set_frame_delay(s_ggpo, s_local_handle, ldelay);
|
||||||
|
ggpo_set_manual_network_polling(s_ggpo, true);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -227,8 +227,7 @@ void Netplay::Throttle()
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
// Poll network.
|
// Poll network.
|
||||||
// TODO: Ideally we would sleep on the poll()/select() here instead.
|
ggpo_poll_network(s_ggpo);
|
||||||
ggpo_idle(s_ggpo);
|
|
||||||
|
|
||||||
current_time = Common::Timer::GetCurrentValue();
|
current_time = Common::Timer::GetCurrentValue();
|
||||||
if (current_time >= s_next_frame_time)
|
if (current_time >= s_next_frame_time)
|
||||||
|
@ -250,6 +249,7 @@ void Netplay::AdvanceFrame(u16 checksum)
|
||||||
void Netplay::RunFrame()
|
void Netplay::RunFrame()
|
||||||
{
|
{
|
||||||
// run game
|
// run game
|
||||||
|
bool needIdle = true;
|
||||||
auto result = GGPO_OK;
|
auto result = GGPO_OK;
|
||||||
int disconnectFlags = 0;
|
int disconnectFlags = 0;
|
||||||
Netplay::Input inputs[2] = {};
|
Netplay::Input inputs[2] = {};
|
||||||
|
@ -268,8 +268,13 @@ void Netplay::RunFrame()
|
||||||
// enable again when rolling back done
|
// enable again when rolling back done
|
||||||
SPU::SetAudioOutputMuted(false);
|
SPU::SetAudioOutputMuted(false);
|
||||||
NetplayAdvanceFrame(inputs, disconnectFlags);
|
NetplayAdvanceFrame(inputs, disconnectFlags);
|
||||||
|
// coming here means that the system doesnt need to idle anymore
|
||||||
|
needIdle = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// allow ggpo to do housekeeping if needed
|
||||||
|
if (needIdle)
|
||||||
|
ggpo_idle(s_ggpo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Netplay::CollectInput(u32 slot, u32 bind, float value)
|
void Netplay::CollectInput(u32 slot, u32 bind, float value)
|
||||||
|
|
Loading…
Reference in New Issue