Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decoupling the GGPO API from any static program state #62

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/apps/vectorwar/vectorwar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ fletcher32_checksum(short *data, size_t len)
* so just return true.
*/
bool __cdecl
vw_begin_game_callback(const char *)
vw_begin_game_callback(const char *, void*)
{
return true;
}
Expand All @@ -62,7 +62,7 @@ vw_begin_game_callback(const char *)
* text at the bottom of the screen to notify the user.
*/
bool __cdecl
vw_on_event_callback(GGPOEvent *info)
vw_on_event_callback(GGPOEvent *info, void*)
{
int progress;
switch (info->code) {
Expand Down Expand Up @@ -106,7 +106,7 @@ vw_on_event_callback(GGPOEvent *info)
* during a rollback.
*/
bool __cdecl
vw_advance_frame_callback(int)
vw_advance_frame_callback(int, void*)
{
int inputs[MAX_SHIPS] = { 0 };
int disconnect_flags;
Expand All @@ -124,7 +124,7 @@ vw_advance_frame_callback(int)
* Makes our current state match the state passed in by GGPO.
*/
bool __cdecl
vw_load_game_state_callback(unsigned char *buffer, int len)
vw_load_game_state_callback(unsigned char *buffer, int len, void*)
{
memcpy(&gs, buffer, len);
return true;
Expand All @@ -137,7 +137,7 @@ vw_load_game_state_callback(unsigned char *buffer, int len)
* buffer and len parameters.
*/
bool __cdecl
vw_save_game_state_callback(unsigned char **buffer, int *len, int *checksum, int)
vw_save_game_state_callback(unsigned char **buffer, int *len, int *checksum, int, void*)
{
*len = sizeof(gs);
*buffer = (unsigned char *)malloc(*len);
Expand All @@ -155,7 +155,7 @@ vw_save_game_state_callback(unsigned char **buffer, int *len, int *checksum, int
* Log the gamestate. Used by the synctest debugging tool.
*/
bool __cdecl
vw_log_game_state(char *filename, unsigned char *buffer, int)
vw_log_game_state(char *filename, unsigned char *buffer, int, void*)
{
FILE* fp = nullptr;
fopen_s(&fp, filename, "w");
Expand Down Expand Up @@ -193,7 +193,7 @@ vw_log_game_state(char *filename, unsigned char *buffer, int)
* Free a save state buffer previously returned in vw_save_game_state_callback.
*/
void __cdecl
vw_free_buffer(void *buffer)
vw_free_buffer(void *buffer, void*)
{
free(buffer);
}
Expand Down
15 changes: 8 additions & 7 deletions src/include/ggponet.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,15 +199,15 @@ typedef struct {
* begin_game callback - This callback has been deprecated. You must
* implement it, but should ignore the 'game' parameter.
*/
bool (__cdecl *begin_game)(const char *game);
bool (__cdecl *begin_game)(const char *game, void *userdata);

/*
* save_game_state - The client should allocate a buffer, copy the
* entire contents of the current game state into it, and copy the
* length into the *len parameter. Optionally, the client can compute
* a checksum of the data and store it in the *checksum argument.
*/
bool (__cdecl *save_game_state)(unsigned char **buffer, int *len, int *checksum, int frame);
bool (__cdecl *save_game_state)(unsigned char **buffer, int *len, int *checksum, int frame, void *userdata);

/*
* load_game_state - GGPO.net will call this function at the beginning
Expand All @@ -216,20 +216,20 @@ typedef struct {
* should make the current game state match the state contained in the
* buffer.
*/
bool (__cdecl *load_game_state)(unsigned char *buffer, int len);
bool (__cdecl *load_game_state)(unsigned char *buffer, int len, void *userdata);

/*
* log_game_state - Used in diagnostic testing. The client should use
* the ggpo_log function to write the contents of the specified save
* state in a human readible form.
*/
bool (__cdecl *log_game_state)(char *filename, unsigned char *buffer, int len);
bool (__cdecl *log_game_state)(char *filename, unsigned char *buffer, int len, void *userdata);

/*
* free_buffer - Frees a game state allocated in save_game_state. You
* should deallocate the memory contained in the buffer.
*/
void (__cdecl *free_buffer)(void *buffer);
void (__cdecl *free_buffer)(void *buffer, void *userdata);

/*
* advance_frame - Called during a rollback. You should advance your game
Expand All @@ -240,13 +240,14 @@ typedef struct {
*
* The flags parameter is reserved. It can safely be ignored at this time.
*/
bool (__cdecl *advance_frame)(int flags);
bool (__cdecl *advance_frame)(int flags, void *userdata);

/*
* on_event - Notification that something has happened. See the GGPOEventCode
* structure above for more information.
*/
bool (__cdecl *on_event)(GGPOEvent *info);
bool (__cdecl *on_event)(GGPOEvent *info, void *userdata);
void *userdata;
} GGPOSessionCallbacks;

/*
Expand Down
20 changes: 10 additions & 10 deletions src/lib/ggpo/backends/p2p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Peer2PeerBackend::Peer2PeerBackend(GGPOSessionCallbacks *cb,
/*
* Preload the ROM
*/
_callbacks.begin_game(gamename);
_callbacks.begin_game(gamename, _callbacks.userdata);
}

Peer2PeerBackend::~Peer2PeerBackend()
Expand Down Expand Up @@ -155,7 +155,7 @@ Peer2PeerBackend::DoPoll(int timeout)
GGPOEvent info;
info.code = GGPO_EVENTCODE_TIMESYNC;
info.u.timesync.frames_ahead = interval;
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);
_next_recommended_sleep = current_frame + RECOMMENDATION_INTERVAL;
}
}
Expand Down Expand Up @@ -403,7 +403,7 @@ Peer2PeerBackend::OnUdpProtocolSpectatorEvent(UdpProtocol::Event &evt, int queue

info.code = GGPO_EVENTCODE_DISCONNECTED_FROM_PEER;
info.u.disconnected.player = handle;
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);

break;
}
Expand All @@ -418,19 +418,19 @@ Peer2PeerBackend::OnUdpProtocolEvent(UdpProtocol::Event &evt, GGPOPlayerHandle h
case UdpProtocol::Event::Connected:
info.code = GGPO_EVENTCODE_CONNECTED_TO_PEER;
info.u.connected.player = handle;
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);
break;
case UdpProtocol::Event::Synchronizing:
info.code = GGPO_EVENTCODE_SYNCHRONIZING_WITH_PEER;
info.u.synchronizing.player = handle;
info.u.synchronizing.count = evt.u.synchronizing.count;
info.u.synchronizing.total = evt.u.synchronizing.total;
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);
break;
case UdpProtocol::Event::Synchronzied:
info.code = GGPO_EVENTCODE_SYNCHRONIZED_WITH_PEER;
info.u.synchronized.player = handle;
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);

CheckInitialSync();
break;
Expand All @@ -439,13 +439,13 @@ Peer2PeerBackend::OnUdpProtocolEvent(UdpProtocol::Event &evt, GGPOPlayerHandle h
info.code = GGPO_EVENTCODE_CONNECTION_INTERRUPTED;
info.u.connection_interrupted.player = handle;
info.u.connection_interrupted.disconnect_timeout = evt.u.network_interrupted.disconnect_timeout;
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);
break;

case UdpProtocol::Event::NetworkResumed:
info.code = GGPO_EVENTCODE_CONNECTION_RESUMED;
info.u.connection_resumed.player = handle;
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);
break;
}
}
Expand Down Expand Up @@ -509,7 +509,7 @@ Peer2PeerBackend::DisconnectPlayerQueue(int queue, int syncto)

info.code = GGPO_EVENTCODE_DISCONNECTED_FROM_PEER;
info.u.disconnected.player = QueueToPlayerHandle(queue);
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);

CheckInitialSync();
}
Expand Down Expand Up @@ -621,7 +621,7 @@ Peer2PeerBackend::CheckInitialSync()

GGPOEvent info;
info.code = GGPO_EVENTCODE_RUNNING;
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);
_synchronizing = false;
}
}
16 changes: 8 additions & 8 deletions src/lib/ggpo/backends/spectator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ SpectatorBackend::SpectatorBackend(GGPOSessionCallbacks *cb,
/*
* Preload the ROM
*/
_callbacks.begin_game(gamename);
_callbacks.begin_game(gamename, _callbacks.userdata);
}

SpectatorBackend::~SpectatorBackend()
Expand Down Expand Up @@ -114,23 +114,23 @@ SpectatorBackend::OnUdpProtocolEvent(UdpProtocol::Event &evt)
case UdpProtocol::Event::Connected:
info.code = GGPO_EVENTCODE_CONNECTED_TO_PEER;
info.u.connected.player = 0;
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);
break;
case UdpProtocol::Event::Synchronizing:
info.code = GGPO_EVENTCODE_SYNCHRONIZING_WITH_PEER;
info.u.synchronizing.player = 0;
info.u.synchronizing.count = evt.u.synchronizing.count;
info.u.synchronizing.total = evt.u.synchronizing.total;
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);
break;
case UdpProtocol::Event::Synchronzied:
if (_synchronizing) {
info.code = GGPO_EVENTCODE_SYNCHRONIZED_WITH_PEER;
info.u.synchronized.player = 0;
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);

info.code = GGPO_EVENTCODE_RUNNING;
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);
_synchronizing = false;
}
break;
Expand All @@ -139,19 +139,19 @@ SpectatorBackend::OnUdpProtocolEvent(UdpProtocol::Event &evt)
info.code = GGPO_EVENTCODE_CONNECTION_INTERRUPTED;
info.u.connection_interrupted.player = 0;
info.u.connection_interrupted.disconnect_timeout = evt.u.network_interrupted.disconnect_timeout;
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);
break;

case UdpProtocol::Event::NetworkResumed:
info.code = GGPO_EVENTCODE_CONNECTION_RESUMED;
info.u.connection_resumed.player = 0;
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);
break;

case UdpProtocol::Event::Disconnected:
info.code = GGPO_EVENTCODE_DISCONNECTED_FROM_PEER;
info.u.disconnected.player = 0;
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);
break;

case UdpProtocol::Event::Input:
Expand Down
10 changes: 5 additions & 5 deletions src/lib/ggpo/backends/synctest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ SyncTestBackend::SyncTestBackend(GGPOSessionCallbacks *cb,
/*
* Preload the ROM
*/
_callbacks.begin_game(gamename);
_callbacks.begin_game(gamename, _callbacks.userdata);
}

SyncTestBackend::~SyncTestBackend()
Expand All @@ -48,7 +48,7 @@ SyncTestBackend::DoPoll(int timeout)
GGPOEvent info;

info.code = GGPO_EVENTCODE_RUNNING;
_callbacks.on_event(&info);
_callbacks.on_event(&info, _callbacks.userdata);
_running = true;
}
return GGPO_OK;
Expand Down Expand Up @@ -132,7 +132,7 @@ SyncTestBackend::IncrementFrame(void)

_rollingback = true;
while(!_saved_frames.empty()) {
_callbacks.advance_frame(0);
_callbacks.advance_frame(0, _callbacks.userdata);

// Verify that the checksumn of this frame is the same as the one in our
// list.
Expand Down Expand Up @@ -210,8 +210,8 @@ SyncTestBackend::LogSaveStates(SavedInfo &info)
{
char filename[MAX_PATH];
sprintf_s(filename, ARRAY_SIZE(filename), "synclogs\\state-%04d-original.log", _sync.GetFrameCount());
_callbacks.log_game_state(filename, (unsigned char *)info.buf, info.cbuf);
_callbacks.log_game_state(filename, (unsigned char *)info.buf, info.cbuf, _callbacks.userdata);

sprintf_s(filename, ARRAY_SIZE(filename), "synclogs\\state-%04d-replay.log", _sync.GetFrameCount());
_callbacks.log_game_state(filename, _sync.GetLastSavedFrame().buf, _sync.GetLastSavedFrame().cbuf);
_callbacks.log_game_state(filename, _sync.GetLastSavedFrame().buf, _sync.GetLastSavedFrame().cbuf, _callbacks.userdata);
}
10 changes: 5 additions & 5 deletions src/lib/ggpo/sync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Sync::~Sync()
* structure so we can efficently copy frames via weak references.
*/
for (int i = 0; i < ARRAY_SIZE(_savedstate.frames); i++) {
_callbacks.free_buffer(_savedstate.frames[i].buf);
_callbacks.free_buffer(_savedstate.frames[i].buf, _callbacks.userdata);
}
delete [] _input_queues;
_input_queues = NULL;
Expand Down Expand Up @@ -161,7 +161,7 @@ Sync::AdjustSimulation(int seek_to)
*/
ResetPrediction(_framecount);
for (int i = 0; i < count; i++) {
_callbacks.advance_frame(0);
_callbacks.advance_frame(0, _callbacks.userdata);
}
ASSERT(_framecount == framecount);

Expand All @@ -187,7 +187,7 @@ Sync::LoadFrame(int frame)
state->frame, state->cbuf, state->checksum);

ASSERT(state->buf && state->cbuf);
_callbacks.load_game_state(state->buf, state->cbuf);
_callbacks.load_game_state(state->buf, state->cbuf, _callbacks.userdata);

// Reset framecount and the head of the state ring-buffer to point in
// advance of the current frame (as if we had just finished executing it).
Expand All @@ -204,11 +204,11 @@ Sync::SaveCurrentFrame()
*/
SavedFrame *state = _savedstate.frames + _savedstate.head;
if (state->buf) {
_callbacks.free_buffer(state->buf);
_callbacks.free_buffer(state->buf, _callbacks.userdata);
state->buf = NULL;
}
state->frame = _framecount;
_callbacks.save_game_state(&state->buf, &state->cbuf, &state->checksum, state->frame);
_callbacks.save_game_state(&state->buf, &state->cbuf, &state->checksum, state->frame, _callbacks.userdata);

Log("=== Saved frame info %d (size: %d checksum: %08x).\n", state->frame, state->cbuf, state->checksum);
_savedstate.head = (_savedstate.head + 1) % ARRAY_SIZE(_savedstate.frames);
Expand Down