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

linux and unix build support #37

Open
wants to merge 2 commits into
base: dev/crossplatform
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
22 changes: 18 additions & 4 deletions src/CMakeSources.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,24 @@ set(GGPO_LIB_SRC_NOFILTER
)

if(UNIX)
set(GGPO_LIB_SRC_NOFILTER
${GGPO_LIB_SRC_NOFILTER}
"lib/ggpo/platform_linux.cpp"
)
if(APPLE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdeclspec")
set(GGPO_LIB_SRC_NOFILTER
${GGPO_LIB_SRC_NOFILTER}
"lib/ggpo/platform_unix.h"
"lib/ggpo/platform_unix.cpp"
"lib/ggpo/pevents.h"
"lib/ggpo/pevents.cpp"
)
else(APPLE)
set(GGPO_LIB_SRC_NOFILTER
${GGPO_LIB_SRC_NOFILTER}
"lib/ggpo/platform_linux.h"
"lib/ggpo/platform_linux.cpp"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

platform_linux.* and platform_unix.* are almost identical. We can probably just use platform_unix.* on both MacOS and Linux (potentially with an #ifdef or two).

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I totally agree.

"lib/ggpo/pevents.h"
"lib/ggpo/pevents.cpp"
)
endif(APPLE)
endif()

set(GGPO_LIB_INC_NETWORK
Expand Down
2 changes: 1 addition & 1 deletion src/apps/vectorwar/gdi_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ GDIRenderer::DrawConnectState(HDC hdc, Ship &ship, PlayerConnectionInfo &info, C

case Disconnecting:
sprintf(status, "Waiting for player...");
progress = (timeGetTime() - info.disconnect_start) * 100 / info.disconnect_timeout;
progress = (Platform::GetCurrentTimeMS() - info.disconnect_start) * 100 / info.disconnect_timeout;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Platform type is an internal implementation detail of the GGPO SDK. Ideally the sample code wouldn't use it (or even be able to include those dependencies)

break;
}

Expand Down
4 changes: 2 additions & 2 deletions src/apps/vectorwar/ggpo_perfmon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ ggpo_perfmon_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_INITDIALOG:
{
char pid[64];
sprintf(pid, "%d", GetCurrentProcessId());
sprintf(pid, "%d", Platform::GetProcessId());
SetWindowTextA(GetDlgItem(hwndDlg, IDC_PID), pid);
return TRUE;
}
Expand Down Expand Up @@ -210,7 +210,7 @@ ggpoutil_perfmon_update(GGPOSession *ggpo, GGPOPlayerHandle players[], int num_p
}
}

int now = timeGetTime();
int now = Platform::GetCurrentTimeMS();
if (_dialog) {
InvalidateRect(GetDlgItem(_dialog, IDC_FAIRNESS_GRAPH), NULL, FALSE);
InvalidateRect(GetDlgItem(_dialog, IDC_NETWORK_GRAPH), NULL, FALSE);
Expand Down
6 changes: 3 additions & 3 deletions src/apps/vectorwar/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ CreateMainWindow(HINSTANCE hInstance)
int width = 640, height = 480;
WCHAR titlebuf[128];

wsprintf(titlebuf, L"(pid:%d) ggpo sdk sample: vector war", GetCurrentProcessId());
wsprintf(titlebuf, L"(pid:%d) ggpo sdk sample: vector war", Platform::GetProcessId());
wndclass.cbSize = sizeof(wndclass);
wndclass.lpfnWndProc = MainWindowProc;
wndclass.lpszClassName = L"vwwnd";
Expand All @@ -71,7 +71,7 @@ RunMainLoop(HWND hwnd)
MSG msg = { 0 };
int start, next, now;

start = next = now = timeGetTime();
start = next = now = Platform::GetCurrentTimeMS();
while(1) {
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
Expand All @@ -80,7 +80,7 @@ RunMainLoop(HWND hwnd)
return;
}
}
now = timeGetTime();
now = Platform::GetCurrentTimeMS();
VectorWar_Idle(max(0, next - now - 1));
if (now >= next) {
VectorWar_RunFrame(hwnd);
Expand Down
4 changes: 2 additions & 2 deletions src/apps/vectorwar/vectorwar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ vw_on_event_callback(GGPOEvent *info)
break;
case GGPO_EVENTCODE_CONNECTION_INTERRUPTED:
ngs.SetDisconnectTimeout(info->u.connection_interrupted.player,
timeGetTime(),
Platform::GetCurrentTimeMS(),
info->u.connection_interrupted.disconnect_timeout);
break;
case GGPO_EVENTCODE_CONNECTION_RESUMED:
Expand All @@ -92,7 +92,7 @@ vw_on_event_callback(GGPOEvent *info)
ngs.SetConnectState(info->u.disconnected.player, Disconnected);
break;
case GGPO_EVENTCODE_TIMESYNC:
Sleep(1000 * info->u.timesync.frames_ahead / 60);
Platform::SleepMS(1000 * info->u.timesync.frames_ahead / 60);
break;
}
return true;
Expand Down
47 changes: 31 additions & 16 deletions src/include/ggponet.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@
#ifndef _GGPONET_H_
#define _GGPONET_H_

#if defined(_MSC_VER)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pull request did something similar which will conflict with a lot of these changes. Could you re-pull dev/crossplatform into your fork and restage?

// Microsoft
#define EXPORT __declspec(dllexport)
#elif defined(APPLE) || defined(__GNUC__)
// GCC
#define EXPORT __attribute__((visibility("default")))
#else
// do nothing and hope for the best?
#define EXPORT
#endif

#ifdef __GNUC__
#define __cdecl __attribute__((cdecl))
#endif

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -303,7 +318,7 @@ typedef struct GGPONetworkStats {
*
* local_port - The port GGPO should bind to for UDP traffic.
*/
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_start_session(GGPOSession **session,
EXPORT GGPOErrorCode __cdecl ggpo_start_session(GGPOSession **session,
GGPOSessionCallbacks *cb,
const char *game,
int num_players,
Expand All @@ -322,7 +337,7 @@ __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,
EXPORT GGPOErrorCode __cdecl ggpo_add_player(GGPOSession *session,
GGPOPlayer *player,
GGPOPlayerHandle *handle);

Expand Down Expand Up @@ -351,7 +366,7 @@ __declspec(dllexport) GGPOErrorCode __cdecl ggpo_add_player(GGPOSession *session
* recommended value is 1.
*
*/
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_start_synctest(GGPOSession **session,
EXPORT GGPOErrorCode __cdecl ggpo_start_synctest(GGPOSession **session,
GGPOSessionCallbacks *cb,
char *game,
int num_players,
Expand Down Expand Up @@ -383,7 +398,7 @@ __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,
EXPORT GGPOErrorCode __cdecl ggpo_start_spectating(GGPOSession **session,
GGPOSessionCallbacks *cb,
const char *game,
int num_players,
Expand All @@ -397,7 +412,7 @@ __declspec(dllexport) GGPOErrorCode __cdecl ggpo_start_spectating(GGPOSession **
* 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 *);
EXPORT GGPOErrorCode __cdecl ggpo_close_session(GGPOSession *);


/*
Expand All @@ -406,7 +421,7 @@ __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 *,
EXPORT GGPOErrorCode __cdecl ggpo_set_frame_delay(GGPOSession *,
GGPOPlayerHandle player,
int frame_delay);

Expand All @@ -419,7 +434,7 @@ __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 *,
EXPORT GGPOErrorCode __cdecl ggpo_idle(GGPOSession *,
int timeout);

/*
Expand All @@ -437,7 +452,7 @@ __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 *,
EXPORT GGPOErrorCode __cdecl ggpo_add_local_input(GGPOSession *,
GGPOPlayerHandle player,
void *values,
int size);
Expand All @@ -459,7 +474,7 @@ __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 *,
EXPORT GGPOErrorCode __cdecl ggpo_synchronize_input(GGPOSession *,
void *values,
int size,
int *disconnect_flags);
Expand All @@ -470,7 +485,7 @@ __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 *,
EXPORT GGPOErrorCode __cdecl ggpo_disconnect_player(GGPOSession *,
GGPOPlayerHandle player);

/*
Expand All @@ -481,7 +496,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 *);
EXPORT GGPOErrorCode __cdecl ggpo_advance_frame(GGPOSession *);

/*
* ggpo_get_network_stats --
Expand All @@ -493,7 +508,7 @@ __declspec(dllexport) GGPOErrorCode __cdecl ggpo_advance_frame(GGPOSession *);
*
* stats - Out parameter to the network statistics.
*/
__declspec(dllexport) GGPOErrorCode __cdecl ggpo_get_network_stats(GGPOSession *,
EXPORT GGPOErrorCode __cdecl ggpo_get_network_stats(GGPOSession *,
GGPOPlayerHandle player,
GGPONetworkStats *stats);

Expand All @@ -509,7 +524,7 @@ __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 *,
EXPORT GGPOErrorCode __cdecl ggpo_set_disconnect_timeout(GGPOSession *,
int timeout);

/*
Expand All @@ -521,7 +536,7 @@ __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 *,
EXPORT GGPOErrorCode __cdecl ggpo_set_disconnect_notify_start(GGPOSession *,
int timeout);

/*
Expand All @@ -532,15 +547,15 @@ __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 *,
EXPORT 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 *,
EXPORT void __cdecl ggpo_logv(GGPOSession *,
const char *fmt,
va_list args);

Expand Down
2 changes: 1 addition & 1 deletion src/lib/ggpo/backends/p2p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ Peer2PeerBackend::DoPoll(int timeout)
}
// XXX: this is obviously a farce...
if (timeout) {
Sleep(1);
Platform::SleepMS(1);
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/lib/ggpo/backends/synctest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,9 @@ SyncTestBackend::RaiseSyncError(const char *fmt, ...)
va_end(args);

puts(buf);
#ifdef _WIN32
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can just delete this instead of the #ifdef

OutputDebugStringA(buf);
#endif
EndLog();
DebugBreak();
}
Expand All @@ -187,7 +189,7 @@ SyncTestBackend::BeginLog(int saving)
EndLog();

char filename[MAX_PATH];
CreateDirectoryA("synclogs", NULL);
Platform::CreateDirectory("synclogs", NULL);
sprintf(filename, "synclogs\\%s-%04d-%s.log",
saving ? "state" : "log",
_sync.GetFrameCount(),
Expand Down
6 changes: 6 additions & 0 deletions src/lib/ggpo/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,18 @@
#include "backends/spectator.h"
#include "ggponet.h"

#ifdef _WIN32
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move these functions into the platform specific files instead (e.g. DllMain goes into platform_windows.cpp)?

BOOL WINAPI
DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
srand(Platform::GetCurrentTimeMS() + Platform::GetProcessID());
return TRUE;
}
#else
static void __attribute__((constructor)) DllMain() {
srand(Platform::GetCurrentTimeMS() + Platform::GetProcessID());
}
#endif

void
ggpo_log(GGPOSession *ggpo, const char *fmt, ...)
Expand Down
17 changes: 16 additions & 1 deletion src/lib/ggpo/network/udp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ CreateSocket(int bind_port, int retries)
sockaddr_in sin;
int port;
int optval = 1;
struct linger loptval;
loptval.l_onoff = 0;
loptval.l_linger = 0;

s = socket(AF_INET, SOCK_DGRAM, 0);
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&optval, sizeof optval);
setsockopt(s, SOL_SOCKET, SO_DONTLINGER, (const char *)&optval, sizeof optval);
setsockopt(s, SOL_SOCKET, SO_LINGER, (const char *)&loptval, sizeof loptval);

// non-blocking...
u_long iMode = 1;
Expand Down Expand Up @@ -70,8 +73,12 @@ Udp::SendTo(char *buffer, int len, int flags, struct sockaddr *dst, int destlen)

int res = sendto(_socket, buffer, len, flags, dst, destlen);
if (res == SOCKET_ERROR) {
#ifdef _WIN32
DWORD err = WSAGetLastError();
DWORD e2 = WSAENOTSOCK;
#else
int err = 1;
#endif
Log("unknown error in sendto (erro: %d wsaerr: %d).\n", res, err);
ASSERT(FALSE && "Unknown error in sendto");
}
Expand All @@ -83,7 +90,11 @@ Udp::OnLoopPoll(void *cookie)
{
uint8 recv_buf[MAX_UDP_PACKET_SIZE];
sockaddr_in recv_addr;
#ifdef _WIN32
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the definition of socklen_t is in WS2tcpip.h. Let's just include that in platform_window.h and remove these ifdefs.

int recv_addr_len;
#else
socklen_t recv_addr_len;
#endif

for (;;) {
recv_addr_len = sizeof(recv_addr);
Expand All @@ -92,7 +103,11 @@ Udp::OnLoopPoll(void *cookie)
// TODO: handle len == 0... indicates a disconnect.

if (len == -1) {
#ifdef _WIN32
int error = WSAGetLastError();
#else
int error = 1;
#endif
if (error != WSAEWOULDBLOCK) {
Log("recvfrom WSAGetLastError returned %d (%x).\n", error, error);
}
Expand Down
5 changes: 5 additions & 0 deletions src/lib/ggpo/network/udp_proto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,13 @@ UdpProtocol::HandlesMsg(sockaddr_in &from,
if (!_udp) {
return false;
}
#ifdef _WIN32
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Windows has a #define s_addr S_un.S_addr in WinSock2.h, so I bet you can just use the else version on all platforms.

return _peer_addr.sin_addr.S_un.S_addr == from.sin_addr.S_un.S_addr &&
_peer_addr.sin_port == from.sin_port;
#else
return _peer_addr.sin_addr.s_addr == from.sin_addr.s_addr &&
_peer_addr.sin_port == from.sin_port;
#endif
}

void
Expand Down
2 changes: 1 addition & 1 deletion src/lib/ggpo/network/udp_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class UdpProtocol : public IPollSink
} network_interrupted;
} u;

UdpProtocol::Event(Type t = Unknown) : type(t) { }
Event(Type t = Unknown) : type(t) { }
};

public:
Expand Down
Loading