Merge pull request #39 from pond3r/dev/crossplatform
Merge latest dev/crossplatform into master
This commit is contained in:
11
appveyor.yml
11
appveyor.yml
@@ -4,13 +4,18 @@ version: 2.4.3.{build}
|
||||
|
||||
image: Visual Studio 2019
|
||||
|
||||
skip_commits:
|
||||
files:
|
||||
- doc/*
|
||||
environment:
|
||||
matrix:
|
||||
- GGPO_SHARED_LIB: on
|
||||
- GGPO_SHARED_LIB: off
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
skip_commits:
|
||||
files:
|
||||
- doc/*
|
||||
|
||||
configuration:
|
||||
- Debug
|
||||
- Release
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
@echo off
|
||||
set local
|
||||
|
||||
cmake -G "Visual Studio 16 2019" -A x64 -B build -DBUILD_SHARED_LIBS=off
|
||||
IF "%GGPO_SHARED_LIB%" == "" (
|
||||
echo GGPO_SHARED_LIB not set. Defaulting to off
|
||||
set GGPO_SHARED_LIB=off
|
||||
)
|
||||
|
||||
echo Generating GGPO Visual Studio solution files.
|
||||
echo GGPO_SHARED_LIB=%GGPO_SHARED_LIB%
|
||||
|
||||
cmake -G "Visual Studio 16 2019" -A x64 -B build -DBUILD_SHARED_LIBS=%GGPO_SHARED_LIB%
|
||||
|
||||
echo Finished! Open build/GGPO.sln in Visual Studio to build.
|
||||
|
||||
IF "%1"=="--no-prompt" goto :done
|
||||
:: pause so the user can see the output if they double clicked the configure script
|
||||
pause
|
||||
|
||||
:done
|
||||
:done
|
||||
|
||||
@@ -14,6 +14,8 @@ target_include_directories(GGPO PUBLIC
|
||||
if(WIN32 AND BUILD_SHARED_LIBS)
|
||||
# Link to Multimedia API and Winsocks during a shared build.
|
||||
target_link_libraries(GGPO PUBLIC winmm.lib ws2_32.lib)
|
||||
add_definitions(-DGGPO_SHARED_LIB)
|
||||
add_definitions(-DGGPO_SDK_EXPORT)
|
||||
endif()
|
||||
|
||||
set_target_properties(GGPO PROPERTIES VERSION ${PROJECT_VERSION})
|
||||
|
||||
@@ -23,6 +23,13 @@ set(GGPO_LIB_SRC_NOFILTER
|
||||
"lib/ggpo/timesync.cpp"
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
set(GGPO_LIB_SRC_NOFILTER
|
||||
${GGPO_LIB_SRC_NOFILTER}
|
||||
"lib/ggpo/platform_linux.cpp"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(GGPO_LIB_INC_NETWORK
|
||||
"lib/ggpo/network/udp.h"
|
||||
"lib/ggpo/network/udp_msg.h"
|
||||
|
||||
@@ -4,6 +4,10 @@ add_executable(VectorWar WIN32
|
||||
${GGPO_EXAMPLES_VECTORWAR_SRC}
|
||||
)
|
||||
|
||||
if(WIN32 AND BUILD_SHARED_LIBS)
|
||||
add_definitions(-DGGPO_SHARED_LIB)
|
||||
endif()
|
||||
|
||||
add_common_flags(VectorWar)
|
||||
# Change the character set to unicode.
|
||||
add_definitions(-D_UNICODE -DUNICODE)
|
||||
|
||||
@@ -14,6 +14,22 @@ extern "C" {
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
// On windows, export at build time and import at runtime.
|
||||
// ELF systems don't need an explicit export/import.
|
||||
#ifdef _WIN32
|
||||
# if defined(GGPO_SHARED_LIB)
|
||||
# ifdef GGPO_SDK_EXPORT
|
||||
# define GGPO_API __declspec(dllexport)
|
||||
# else
|
||||
# define GGPO_API __declspec(dllimport)
|
||||
# endif
|
||||
# else
|
||||
# define GGPO_API
|
||||
# endif
|
||||
#else
|
||||
# define GGPO_API
|
||||
#endif
|
||||
|
||||
#define GGPO_MAX_PLAYERS 4
|
||||
#define GGPO_MAX_PREDICTION_FRAMES 8
|
||||
#define GGPO_MAX_SPECTATORS 32
|
||||
@@ -303,12 +319,12 @@ typedef struct GGPONetworkStats {
|
||||
*
|
||||
* local_port - The port GGPO should bind to for UDP traffic.
|
||||
*/
|
||||
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_start_session(GGPOSession **session,
|
||||
GGPOSessionCallbacks *cb,
|
||||
const char *game,
|
||||
int num_players,
|
||||
int input_size,
|
||||
int localport);
|
||||
GGPO_API GGPOErrorCode __cdecl ggpo_start_session(GGPOSession **session,
|
||||
GGPOSessionCallbacks *cb,
|
||||
const char *game,
|
||||
int num_players,
|
||||
int input_size,
|
||||
int localport);
|
||||
|
||||
|
||||
/*
|
||||
@@ -322,9 +338,9 @@ __declspec(dllexport) GGPOErrorCode __cdecl ggpo_start_session(GGPOSession **ses
|
||||
* handle - An out parameter to a handle used to identify this player in the future.
|
||||
* (e.g. in the on_event callbacks).
|
||||
*/
|
||||
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_add_player(GGPOSession *session,
|
||||
GGPOPlayer *player,
|
||||
GGPOPlayerHandle *handle);
|
||||
GGPO_API GGPOErrorCode __cdecl ggpo_add_player(GGPOSession *session,
|
||||
GGPOPlayer *player,
|
||||
GGPOPlayerHandle *handle);
|
||||
|
||||
|
||||
/*
|
||||
@@ -351,12 +367,12 @@ __declspec(dllexport) GGPOErrorCode __cdecl ggpo_add_player(GGPOSession *session
|
||||
* recommended value is 1.
|
||||
*
|
||||
*/
|
||||
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_start_synctest(GGPOSession **session,
|
||||
GGPOSessionCallbacks *cb,
|
||||
char *game,
|
||||
int num_players,
|
||||
int input_size,
|
||||
int frames);
|
||||
GGPO_API GGPOErrorCode __cdecl ggpo_start_synctest(GGPOSession **session,
|
||||
GGPOSessionCallbacks *cb,
|
||||
char *game,
|
||||
int num_players,
|
||||
int input_size,
|
||||
int frames);
|
||||
|
||||
|
||||
/*
|
||||
@@ -383,21 +399,21 @@ __declspec(dllexport) GGPOErrorCode __cdecl ggpo_start_synctest(GGPOSession **se
|
||||
*
|
||||
* host_port - The port of the session on the host
|
||||
*/
|
||||
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_start_spectating(GGPOSession **session,
|
||||
GGPOSessionCallbacks *cb,
|
||||
const char *game,
|
||||
int num_players,
|
||||
int input_size,
|
||||
int local_port,
|
||||
char *host_ip,
|
||||
int host_port);
|
||||
GGPO_API GGPOErrorCode __cdecl ggpo_start_spectating(GGPOSession **session,
|
||||
GGPOSessionCallbacks *cb,
|
||||
const char *game,
|
||||
int num_players,
|
||||
int input_size,
|
||||
int local_port,
|
||||
char *host_ip,
|
||||
int host_port);
|
||||
|
||||
/*
|
||||
* ggpo_close_session --
|
||||
* Used to close a session. You must call ggpo_close_session to
|
||||
* free the resources allocated in ggpo_start_session.
|
||||
*/
|
||||
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_close_session(GGPOSession *);
|
||||
GGPO_API GGPOErrorCode __cdecl ggpo_close_session(GGPOSession *);
|
||||
|
||||
|
||||
/*
|
||||
@@ -406,9 +422,9 @@ __declspec(dllexport) GGPOErrorCode __cdecl ggpo_close_session(GGPOSession *);
|
||||
* Change the amount of frames ggpo will delay local input. Must be called
|
||||
* before the first call to ggpo_synchronize_input.
|
||||
*/
|
||||
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_set_frame_delay(GGPOSession *,
|
||||
GGPOPlayerHandle player,
|
||||
int frame_delay);
|
||||
GGPO_API GGPOErrorCode __cdecl ggpo_set_frame_delay(GGPOSession *,
|
||||
GGPOPlayerHandle player,
|
||||
int frame_delay);
|
||||
|
||||
/*
|
||||
* ggpo_idle --
|
||||
@@ -419,8 +435,8 @@ __declspec(dllexport) GGPOErrorCode __cdecl ggpo_set_frame_delay(GGPOSession *,
|
||||
* timeout - The amount of time GGPO.net is allowed to spend in this function,
|
||||
* in milliseconds.
|
||||
*/
|
||||
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_idle(GGPOSession *,
|
||||
int timeout);
|
||||
GGPO_API GGPOErrorCode __cdecl ggpo_idle(GGPOSession *,
|
||||
int timeout);
|
||||
|
||||
/*
|
||||
* ggpo_add_local_input --
|
||||
@@ -437,10 +453,10 @@ __declspec(dllexport) GGPOErrorCode __cdecl ggpo_idle(GGPOSession *,
|
||||
* size - The size of the controller inputs. This must be exactly equal to the
|
||||
* size passed into ggpo_start_session.
|
||||
*/
|
||||
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_add_local_input(GGPOSession *,
|
||||
GGPOPlayerHandle player,
|
||||
void *values,
|
||||
int size);
|
||||
GGPO_API GGPOErrorCode __cdecl ggpo_add_local_input(GGPOSession *,
|
||||
GGPOPlayerHandle player,
|
||||
void *values,
|
||||
int size);
|
||||
|
||||
/*
|
||||
* ggpo_synchronize_input --
|
||||
@@ -459,10 +475,10 @@ __declspec(dllexport) GGPOErrorCode __cdecl ggpo_add_local_input(GGPOSession *,
|
||||
* that player will be zeroed and the i-th flag will be set. For example,
|
||||
* if only player 3 has disconnected, disconnect flags will be 8 (i.e. 1 << 3).
|
||||
*/
|
||||
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_synchronize_input(GGPOSession *,
|
||||
void *values,
|
||||
int size,
|
||||
int *disconnect_flags);
|
||||
GGPO_API GGPOErrorCode __cdecl ggpo_synchronize_input(GGPOSession *,
|
||||
void *values,
|
||||
int size,
|
||||
int *disconnect_flags);
|
||||
|
||||
/*
|
||||
* ggpo_disconnect_player --
|
||||
@@ -470,8 +486,8 @@ __declspec(dllexport) GGPOErrorCode __cdecl ggpo_synchronize_input(GGPOSession *
|
||||
* Disconnects a remote player from a game. Will return GGPO_ERRORCODE_PLAYER_DISCONNECTED
|
||||
* if you try to disconnect a player who has already been disconnected.
|
||||
*/
|
||||
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_disconnect_player(GGPOSession *,
|
||||
GGPOPlayerHandle player);
|
||||
GGPO_API GGPOErrorCode __cdecl ggpo_disconnect_player(GGPOSession *,
|
||||
GGPOPlayerHandle player);
|
||||
|
||||
/*
|
||||
* ggpo_advance_frame --
|
||||
@@ -481,7 +497,7 @@ __declspec(dllexport) GGPOErrorCode __cdecl ggpo_disconnect_player(GGPOSession *
|
||||
* you advance the gamestate by a frame, even during rollbacks. GGPO.net
|
||||
* may call your save_state callback before this function returns.
|
||||
*/
|
||||
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_advance_frame(GGPOSession *);
|
||||
GGPO_API GGPOErrorCode __cdecl ggpo_advance_frame(GGPOSession *);
|
||||
|
||||
/*
|
||||
* ggpo_get_network_stats --
|
||||
@@ -493,9 +509,9 @@ __declspec(dllexport) GGPOErrorCode __cdecl ggpo_advance_frame(GGPOSession *);
|
||||
*
|
||||
* stats - Out parameter to the network statistics.
|
||||
*/
|
||||
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_get_network_stats(GGPOSession *,
|
||||
GGPOPlayerHandle player,
|
||||
GGPONetworkStats *stats);
|
||||
GGPO_API GGPOErrorCode __cdecl ggpo_get_network_stats(GGPOSession *,
|
||||
GGPOPlayerHandle player,
|
||||
GGPONetworkStats *stats);
|
||||
|
||||
/*
|
||||
* ggpo_set_disconnect_timeout --
|
||||
@@ -509,8 +525,8 @@ __declspec(dllexport) GGPOErrorCode __cdecl ggpo_get_network_stats(GGPOSession *
|
||||
*
|
||||
* timeout - The time in milliseconds to wait before disconnecting a peer.
|
||||
*/
|
||||
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_set_disconnect_timeout(GGPOSession *,
|
||||
int timeout);
|
||||
GGPO_API GGPOErrorCode __cdecl ggpo_set_disconnect_timeout(GGPOSession *,
|
||||
int timeout);
|
||||
|
||||
/*
|
||||
* ggpo_set_disconnect_notify_start --
|
||||
@@ -521,8 +537,8 @@ __declspec(dllexport) GGPOErrorCode __cdecl ggpo_set_disconnect_timeout(GGPOSess
|
||||
* timeout - The amount of time which needs to elapse without receiving a packet
|
||||
* before the GGPO_EVENTCODE_NETWORK_INTERRUPTED event is sent.
|
||||
*/
|
||||
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_set_disconnect_notify_start(GGPOSession *,
|
||||
int timeout);
|
||||
GGPO_API GGPOErrorCode __cdecl ggpo_set_disconnect_notify_start(GGPOSession *,
|
||||
int timeout);
|
||||
|
||||
/*
|
||||
* ggpo_log --
|
||||
@@ -532,17 +548,17 @@ __declspec(dllexport) GGPOErrorCode __cdecl ggpo_set_disconnect_notify_start(GGP
|
||||
* variable is set to 1. This will change in future versions of the
|
||||
* SDK.
|
||||
*/
|
||||
__declspec(dllexport) void __cdecl ggpo_log(GGPOSession *,
|
||||
const char *fmt, ...);
|
||||
GGPO_API void __cdecl ggpo_log(GGPOSession *,
|
||||
const char *fmt, ...);
|
||||
/*
|
||||
* ggpo_logv --
|
||||
*
|
||||
* A varargs compatible version of ggpo_log. See ggpo_log for
|
||||
* more details.
|
||||
*/
|
||||
__declspec(dllexport) void __cdecl ggpo_logv(GGPOSession *,
|
||||
const char *fmt,
|
||||
va_list args);
|
||||
GGPO_API void __cdecl ggpo_logv(GGPOSession *,
|
||||
const char *fmt,
|
||||
va_list args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
||||
@@ -16,4 +16,4 @@ void BitVector_WriteNibblet(uint8 *vector, int nibble, int *offset);
|
||||
int BitVector_ReadBit(uint8 *vector, int *offset);
|
||||
int BitVector_ReadNibblet(uint8 *vector, int *offset);
|
||||
|
||||
#endif _BITVECTOR_H
|
||||
#endif // _BITVECTOR_H
|
||||
|
||||
@@ -314,8 +314,8 @@ InputQueue::Log(const char *fmt, ...)
|
||||
sprintf(buf, "input q%d | ", _id);
|
||||
offset = strlen(buf);
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf + offset, ARRAYSIZE(buf) - offset - 1, fmt, args);
|
||||
buf[ARRAYSIZE(buf)-1] = '\0';
|
||||
vsnprintf(buf + offset, ARRAY_SIZE(buf) - offset - 1, fmt, args);
|
||||
buf[ARRAY_SIZE(buf)-1] = '\0';
|
||||
::Log(buf);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ void Logv(const char *fmt, va_list args)
|
||||
return;
|
||||
}
|
||||
if (!logfile) {
|
||||
sprintf(logbuf, "log-%d.log", GetCurrentProcessId());
|
||||
sprintf(logbuf, "log-%d.log", Platform::GetProcessID());
|
||||
logfile = fopen(logbuf, "w");
|
||||
}
|
||||
Logv(logfile, fmt, args);
|
||||
@@ -44,9 +44,9 @@ void Logv(FILE *fp, const char *fmt, va_list args)
|
||||
static int start = 0;
|
||||
int t = 0;
|
||||
if (!start) {
|
||||
start = timeGetTime();
|
||||
start = Platform::GetCurrentTimeMS();
|
||||
} else {
|
||||
t = timeGetTime() - start;
|
||||
t = Platform::GetCurrentTimeMS() - start;
|
||||
}
|
||||
fprintf(fp, "%d.%03d : ", t / 1000, t % 1000);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
BOOL WINAPI
|
||||
DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
srand(timeGetTime() + GetCurrentProcessId());
|
||||
srand(Platform::GetCurrentTimeMS() + Platform::GetProcessID());
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -117,8 +117,8 @@ Udp::Log(const char *fmt, ...)
|
||||
strcpy(buf, "udp | ");
|
||||
offset = strlen(buf);
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf + offset, ARRAYSIZE(buf) - offset - 1, fmt, args);
|
||||
buf[ARRAYSIZE(buf)-1] = '\0';
|
||||
vsnprintf(buf + offset, ARRAY_SIZE(buf) - offset - 1, fmt, args);
|
||||
buf[ARRAY_SIZE(buf)-1] = '\0';
|
||||
::Log(buf);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ UdpProtocol::OnLoopPoll(void *cookie)
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int now = timeGetTime();
|
||||
unsigned int now = Platform::GetCurrentTimeMS();
|
||||
unsigned int next_interval;
|
||||
|
||||
PumpSendQueue();
|
||||
@@ -210,7 +210,7 @@ UdpProtocol::OnLoopPoll(void *cookie)
|
||||
|
||||
if (!_state.running.last_quality_report_time || _state.running.last_quality_report_time + QUALITY_REPORT_INTERVAL < now) {
|
||||
UdpMsg *msg = new UdpMsg(UdpMsg::QualityReport);
|
||||
msg->u.quality_report.ping = timeGetTime();
|
||||
msg->u.quality_report.ping = Platform::GetCurrentTimeMS();
|
||||
msg->u.quality_report.frame_advantage = _local_frame_advantage;
|
||||
SendMsg(msg);
|
||||
_state.running.last_quality_report_time = now;
|
||||
@@ -261,7 +261,7 @@ void
|
||||
UdpProtocol::Disconnect()
|
||||
{
|
||||
_current_state = Disconnected;
|
||||
_shutdown_timeout = timeGetTime() + UDP_SHUTDOWN_TIMER;
|
||||
_shutdown_timeout = Platform::GetCurrentTimeMS() + UDP_SHUTDOWN_TIMER;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -279,13 +279,13 @@ UdpProtocol::SendMsg(UdpMsg *msg)
|
||||
LogMsg("send", msg);
|
||||
|
||||
_packets_sent++;
|
||||
_last_send_time = timeGetTime();
|
||||
_last_send_time = Platform::GetCurrentTimeMS();
|
||||
_bytes_sent += msg->PacketSize();
|
||||
|
||||
msg->hdr.magic = _magic_number;
|
||||
msg->hdr.sequence_number = _next_send_seq++;
|
||||
|
||||
_send_queue.push(QueueEntry(timeGetTime(), _peer_addr, msg));
|
||||
_send_queue.push(QueueEntry(Platform::GetCurrentTimeMS(), _peer_addr, msg));
|
||||
PumpSendQueue();
|
||||
}
|
||||
|
||||
@@ -336,13 +336,13 @@ UdpProtocol::OnMsg(UdpMsg *msg, int len)
|
||||
|
||||
_next_recv_seq = seq;
|
||||
LogMsg("recv", msg);
|
||||
if (msg->hdr.type >= ARRAYSIZE(table)) {
|
||||
if (msg->hdr.type >= ARRAY_SIZE(table)) {
|
||||
OnInvalid(msg, len);
|
||||
} else {
|
||||
handled = (this->*(table[msg->hdr.type]))(msg, len);
|
||||
}
|
||||
if (handled) {
|
||||
_last_recv_time = timeGetTime();
|
||||
_last_recv_time = Platform::GetCurrentTimeMS();
|
||||
if (_disconnect_notify_sent && _current_state == Running) {
|
||||
QueueEvent(Event(Event::NetworkResumed));
|
||||
_disconnect_notify_sent = false;
|
||||
@@ -353,7 +353,7 @@ UdpProtocol::OnMsg(UdpMsg *msg, int len)
|
||||
void
|
||||
UdpProtocol::UpdateNetworkStats(void)
|
||||
{
|
||||
int now = timeGetTime();
|
||||
int now = Platform::GetCurrentTimeMS();
|
||||
|
||||
if (_stats_start_time == 0) {
|
||||
_stats_start_time = now;
|
||||
@@ -410,8 +410,8 @@ UdpProtocol::Log(const char *fmt, ...)
|
||||
sprintf(buf, "udpproto%d | ", _queue);
|
||||
offset = strlen(buf);
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf + offset, ARRAYSIZE(buf) - offset - 1, fmt, args);
|
||||
buf[ARRAYSIZE(buf)-1] = '\0';
|
||||
vsnprintf(buf + offset, ARRAY_SIZE(buf) - offset - 1, fmt, args);
|
||||
buf[ARRAY_SIZE(buf)-1] = '\0';
|
||||
::Log(buf);
|
||||
va_end(args);
|
||||
}
|
||||
@@ -534,7 +534,7 @@ UdpProtocol::OnInput(UdpMsg *msg, int len)
|
||||
* of the network.
|
||||
*/
|
||||
UdpMsg::connect_status* remote_status = msg->u.input.peer_connect_status;
|
||||
for (int i = 0; i < ARRAYSIZE(_peer_connect_status); i++) {
|
||||
for (int i = 0; i < ARRAY_SIZE(_peer_connect_status); i++) {
|
||||
ASSERT(remote_status[i].last_frame >= _peer_connect_status[i].last_frame);
|
||||
_peer_connect_status[i].disconnected = _peer_connect_status[i].disconnected || remote_status[i].disconnected;
|
||||
_peer_connect_status[i].last_frame = MAX(_peer_connect_status[i].last_frame, remote_status[i].last_frame);
|
||||
@@ -596,7 +596,7 @@ UdpProtocol::OnInput(UdpMsg *msg, int len)
|
||||
|
||||
_last_received_input.desc(desc);
|
||||
|
||||
_state.running.last_input_packet_recv_time = timeGetTime();
|
||||
_state.running.last_input_packet_recv_time = Platform::GetCurrentTimeMS();
|
||||
|
||||
Log("Sending frame %d to emu queue %d (%s).\n", _last_received_input.frame, _queue, desc);
|
||||
QueueEvent(evt);
|
||||
@@ -654,7 +654,7 @@ UdpProtocol::OnQualityReport(UdpMsg *msg, int len)
|
||||
bool
|
||||
UdpProtocol::OnQualityReply(UdpMsg *msg, int len)
|
||||
{
|
||||
_round_trip_time = timeGetTime() - msg->u.quality_reply.pong;
|
||||
_round_trip_time = Platform::GetCurrentTimeMS() - msg->u.quality_reply.pong;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -723,14 +723,14 @@ UdpProtocol::PumpSendQueue()
|
||||
// should really come up with a gaussian distributation based on the configured
|
||||
// value, but this will do for now.
|
||||
int jitter = (_send_latency * 2 / 3) + ((rand() % _send_latency) / 3);
|
||||
if (timeGetTime() < _send_queue.front().queue_time + jitter) {
|
||||
if (Platform::GetCurrentTimeMS() < _send_queue.front().queue_time + jitter) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_oop_percent && !_oo_packet.msg && ((rand() % 100) < _oop_percent)) {
|
||||
int delay = rand() % (_send_latency * 10 + 1000);
|
||||
Log("creating rogue oop (seq: %d delay: %d)\n", entry.msg->hdr.sequence_number, delay);
|
||||
_oo_packet.send_time = timeGetTime() + delay;
|
||||
_oo_packet.send_time = Platform::GetCurrentTimeMS() + delay;
|
||||
_oo_packet.msg = entry.msg;
|
||||
_oo_packet.dest_addr = entry.dest_addr;
|
||||
} else {
|
||||
@@ -743,7 +743,7 @@ UdpProtocol::PumpSendQueue()
|
||||
}
|
||||
_send_queue.pop();
|
||||
}
|
||||
if (_oo_packet.msg && _oo_packet.send_time < timeGetTime()) {
|
||||
if (_oo_packet.msg && _oo_packet.send_time < Platform::GetCurrentTimeMS()) {
|
||||
Log("sending rogue oop!");
|
||||
_udp->SendTo((char *)_oo_packet.msg, _oo_packet.msg->PacketSize(), 0,
|
||||
(struct sockaddr *)&_oo_packet.dest_addr, sizeof _oo_packet.dest_addr);
|
||||
|
||||
23
src/lib/ggpo/platform_linux.cpp
Normal file
23
src/lib/ggpo/platform_linux.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
|
||||
*
|
||||
* Use of this software is governed by the MIT license that can be found
|
||||
* in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "platform_linux.h"
|
||||
|
||||
struct timespec start = { 0 }
|
||||
|
||||
uint32 Platform::GetCurrentTimeMS() {
|
||||
if (start.tv_sec == 0 && start.tv_nsec == 0) {
|
||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||
return 0
|
||||
}
|
||||
struct timespec current;
|
||||
clock_gettime(CLOCK_MONOTONIC, ¤t);
|
||||
|
||||
return ((current.tv_sec - start.tv_sec) * 1000) +
|
||||
((current.tv_nsec - start.tv_nsec ) / 1000000) +
|
||||
}
|
||||
|
||||
27
src/lib/ggpo/platform_linux.h
Normal file
27
src/lib/ggpo/platform_linux.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
|
||||
*
|
||||
* Use of this software is governed by the MIT license that can be found
|
||||
* in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef _GGPO_LINUX_H_
|
||||
#define _GGPO_LINUX_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
class Platform {
|
||||
public: // types
|
||||
typedef pid_t ProcessID;
|
||||
|
||||
public: // functions
|
||||
static ProcessID GetProcessID() { return getpid(); }
|
||||
static void AssertFailed(char *msg) { }
|
||||
static uint32 GetCurrentTimeMS();
|
||||
};
|
||||
|
||||
#endif
|
||||
25
src/lib/ggpo/platform_windows.h
Normal file
25
src/lib/ggpo/platform_windows.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
|
||||
*
|
||||
* Use of this software is governed by the MIT license that can be found
|
||||
* in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef _GGPO_WINDOWS_H_
|
||||
#define _GGPO_WINDOWS_H_
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
class Platform {
|
||||
public: // types
|
||||
typedef DWORD ProcessID;
|
||||
|
||||
public: // functions
|
||||
static ProcessID GetProcessID() { return GetCurrentProcessId(); }
|
||||
static void AssertFailed(char *msg) { MessageBoxA(NULL, msg, "GGPO Assertion Failed", MB_OK | MB_ICONEXCLAMATION); }
|
||||
static uint32 GetCurrentTimeMS() { return timeGetTime(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -60,9 +60,9 @@ Poll::Pump(int timeout)
|
||||
bool finished = false;
|
||||
|
||||
if (_start_time == 0) {
|
||||
_start_time = timeGetTime();
|
||||
_start_time = Platform::GetCurrentTimeMS();
|
||||
}
|
||||
int elapsed = timeGetTime() - _start_time;
|
||||
int elapsed = Platform::GetCurrentTimeMS() - _start_time;
|
||||
int maxwait = ComputeWaitTime(elapsed);
|
||||
if (maxwait != INFINITE) {
|
||||
timeout = MIN(timeout, maxwait);
|
||||
|
||||
@@ -32,7 +32,6 @@ public:
|
||||
|
||||
void Run();
|
||||
bool Pump(int timeout);
|
||||
int GetTime() { return timeGetTime(); }
|
||||
|
||||
protected:
|
||||
int ComputeWaitTime(int elapsed);
|
||||
|
||||
@@ -192,7 +192,7 @@ Sync::LoadFrame(int frame)
|
||||
// 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).
|
||||
_framecount = state->frame;
|
||||
_savedstate.head = (_savedstate.head + 1) % ARRAYSIZE(_savedstate.frames);
|
||||
_savedstate.head = (_savedstate.head + 1) % ARRAY_SIZE(_savedstate.frames);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -211,7 +211,7 @@ Sync::SaveCurrentFrame()
|
||||
_callbacks.save_game_state(&state->buf, &state->cbuf, &state->checksum, state->frame);
|
||||
|
||||
Log("=== Saved frame info %d (size: %d checksum: %08x).\n", state->frame, state->cbuf, state->checksum);
|
||||
_savedstate.head = (_savedstate.head + 1) % ARRAYSIZE(_savedstate.frames);
|
||||
_savedstate.head = (_savedstate.head + 1) % ARRAY_SIZE(_savedstate.frames);
|
||||
}
|
||||
|
||||
Sync::SavedFrame&
|
||||
@@ -219,7 +219,7 @@ Sync::GetLastSavedFrame()
|
||||
{
|
||||
int i = _savedstate.head - 1;
|
||||
if (i < 0) {
|
||||
i = ARRAYSIZE(_savedstate.frames) - 1;
|
||||
i = ARRAY_SIZE(_savedstate.frames) - 1;
|
||||
}
|
||||
return _savedstate.frames[i];
|
||||
}
|
||||
@@ -228,7 +228,7 @@ Sync::GetLastSavedFrame()
|
||||
int
|
||||
Sync::FindSavedFrameIndex(int frame)
|
||||
{
|
||||
int i, count = ARRAYSIZE(_savedstate.frames);
|
||||
int i, count = ARRAY_SIZE(_savedstate.frames);
|
||||
for (i = 0; i < count; i++) {
|
||||
if (_savedstate.frames[i].frame == frame) {
|
||||
break;
|
||||
|
||||
@@ -24,9 +24,9 @@ TimeSync::advance_frame(GameInput &input, int advantage, int radvantage)
|
||||
int sleep_time = 0;
|
||||
|
||||
// Remember the last frame and frame advantage
|
||||
_last_inputs[input.frame % ARRAYSIZE(_last_inputs)] = input;
|
||||
_local[input.frame % ARRAYSIZE(_local)] = advantage;
|
||||
_remote[input.frame % ARRAYSIZE(_remote)] = radvantage;
|
||||
_last_inputs[input.frame % ARRAY_SIZE(_last_inputs)] = input;
|
||||
_local[input.frame % ARRAY_SIZE(_local)] = advantage;
|
||||
_remote[input.frame % ARRAY_SIZE(_remote)] = radvantage;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -35,16 +35,16 @@ TimeSync::recommend_frame_wait_duration(bool require_idle_input)
|
||||
// Average our local and remote frame advantages
|
||||
int i, sum = 0;
|
||||
float advantage, radvantage;
|
||||
for (i = 0; i < ARRAYSIZE(_local); i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(_local); i++) {
|
||||
sum += _local[i];
|
||||
}
|
||||
advantage = sum / (float)ARRAYSIZE(_local);
|
||||
advantage = sum / (float)ARRAY_SIZE(_local);
|
||||
|
||||
sum = 0;
|
||||
for (i = 0; i < ARRAYSIZE(_remote); i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(_remote); i++) {
|
||||
sum += _remote[i];
|
||||
}
|
||||
radvantage = sum / (float)ARRAYSIZE(_remote);
|
||||
radvantage = sum / (float)ARRAY_SIZE(_remote);
|
||||
|
||||
static int count = 0;
|
||||
count++;
|
||||
@@ -74,7 +74,7 @@ TimeSync::recommend_frame_wait_duration(bool require_idle_input)
|
||||
// user's input isn't sweeping in arcs (e.g. fireball motions in
|
||||
// Street Fighter), which could cause the player to miss moves.
|
||||
if (require_idle_input) {
|
||||
for (i = 1; i < ARRAYSIZE(_last_inputs); i++) {
|
||||
for (i = 1; i < ARRAY_SIZE(_last_inputs); i++) {
|
||||
if (!_last_inputs[i].equal(_last_inputs[0], true)) {
|
||||
Log("iteration %d: rejecting due to input stuff at position %d...!!!\n", count, i);
|
||||
return 0;
|
||||
|
||||
@@ -7,13 +7,6 @@
|
||||
|
||||
#ifndef _TYPES_H
|
||||
#define _TYPES_H
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
/*
|
||||
* Keep the compiler happy
|
||||
*/
|
||||
@@ -29,17 +22,31 @@
|
||||
*/
|
||||
#pragma warning(disable: 4018 4100 4127 4201 4389 4800)
|
||||
|
||||
|
||||
/*
|
||||
* Simple types
|
||||
*/
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned int uint32;
|
||||
typedef unsigned char byte;
|
||||
typedef char int8;
|
||||
typedef short int16;
|
||||
typedef int int32;
|
||||
|
||||
/*
|
||||
* Additional headers
|
||||
*/
|
||||
#if defined(_WINDOWS)
|
||||
# include "platform_windows.h"
|
||||
#elif defined(__GNUC__)
|
||||
# include "platform_linux.h"
|
||||
#else
|
||||
# error Unsupported platform
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Macros
|
||||
@@ -48,12 +55,12 @@ typedef int int32;
|
||||
do { \
|
||||
if (!(x)) { \
|
||||
char buf[1024]; \
|
||||
sprintf_s(buf, sizeof(buf) - 1, "Assertion: %s @ %s:%d (pid:%d)", #x, __FILE__, __LINE__, GetCurrentProcessId()); \
|
||||
snprintf(buf, sizeof(buf) - 1, "Assertion: %s @ %s:%d (pid:%d)", #x, __FILE__, __LINE__, Platform::GetProcessID()); \
|
||||
Log("%s\n", buf); \
|
||||
Log("\n"); \
|
||||
Log("\n"); \
|
||||
Log("\n"); \
|
||||
MessageBoxA(NULL, buf, "GGPO Assertion Failed", MB_OK | MB_ICONEXCLAMATION); \
|
||||
Platform::AssertFailed(buf); \
|
||||
exit(0); \
|
||||
} \
|
||||
} while (false)
|
||||
@@ -74,4 +81,4 @@ typedef int int32;
|
||||
# define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#endif // _TYPES_H
|
||||
#endif // _TYPES_H
|
||||
|
||||
Reference in New Issue
Block a user