mirror of https://github.com/AxioDL/jbus.git
Win32 compatibility fixes
This commit is contained in:
parent
ed1adfee0d
commit
c34b81ad6c
|
@ -1,6 +1,10 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
project(jbus)
|
||||
|
||||
if(WIN32)
|
||||
set(JBUS_PLAT_LIBS Ws2_32)
|
||||
endif()
|
||||
|
||||
include_directories(include)
|
||||
add_library(jbus
|
||||
include/jbus/optional.hpp
|
||||
|
@ -8,5 +12,7 @@ add_library(jbus
|
|||
lib/Common.cpp include/jbus/Common.hpp
|
||||
lib/Endpoint.cpp include/jbus/Endpoint.hpp
|
||||
lib/Listener.cpp include/jbus/Listener.hpp)
|
||||
target_link_libraries(jbus ${JBUS_PLAT_LIBS})
|
||||
|
||||
add_executable(joyboot tools/joyboot.cpp)
|
||||
target_link_libraries(joyboot jbus)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "Socket.hpp"
|
||||
#include "optional.hpp"
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
namespace jbus
|
||||
{
|
||||
|
@ -165,7 +166,7 @@ class Endpoint
|
|||
static u64 getTransferTime(u8 cmd);
|
||||
void clockSync();
|
||||
void send(const u8* buffer);
|
||||
size_t seceive(u8* buffer);
|
||||
size_t receive(u8* buffer);
|
||||
size_t runBuffer(u8* buffer, u64& remTicks, EWaitResp resp);
|
||||
bool idleGetStatus(u64& remTicks);
|
||||
void transferProc();
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "Socket.hpp"
|
||||
#include <thread>
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
|
||||
namespace jbus
|
||||
{
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
#ifndef JBUS_SOCKET_HPP
|
||||
#define JBUS_SOCKET_HPP
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <Ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <string>
|
||||
|
||||
#include "Common.hpp"
|
||||
|
@ -52,10 +58,10 @@ class IPAddress
|
|||
else
|
||||
{
|
||||
/* Try to convert the address as a byte representation ("xxx.xxx.xxx.xxx") */
|
||||
uint32_t ip = inet_addr(address.c_str());
|
||||
if (ip != INADDR_NONE)
|
||||
struct in_addr addr;
|
||||
if (inet_pton(AF_INET, address.c_str(), &addr) == 1)
|
||||
{
|
||||
m_address = ip;
|
||||
m_address = addr.s_addr;
|
||||
m_valid = true;
|
||||
}
|
||||
else
|
||||
|
@ -69,9 +75,9 @@ class IPAddress
|
|||
{
|
||||
if (result)
|
||||
{
|
||||
ip = reinterpret_cast<sockaddr_in*>(result->ai_addr)->sin_addr.s_addr;
|
||||
addr = reinterpret_cast<sockaddr_in*>(result->ai_addr)->sin_addr;
|
||||
freeaddrinfo(result);
|
||||
m_address = ip;
|
||||
m_address = addr.s_addr;
|
||||
m_valid = true;
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +102,12 @@ public:
|
|||
/** Server-oriented TCP socket class derived from SFML */
|
||||
class Socket
|
||||
{
|
||||
int m_socket = -1;
|
||||
#ifndef _WIN32
|
||||
using SocketTp = int;
|
||||
#else
|
||||
using SocketTp = SOCKET;
|
||||
#endif
|
||||
SocketTp m_socket = -1;
|
||||
bool m_isBlocking;
|
||||
|
||||
static sockaddr_in createAddress(uint32_t address, unsigned short port)
|
||||
|
@ -119,7 +130,7 @@ class Socket
|
|||
if (isOpen())
|
||||
return false;
|
||||
|
||||
m_socket = socket(PF_INET, SOCK_STREAM, 0);
|
||||
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (m_socket == -1)
|
||||
{
|
||||
fprintf(stderr, "Can't allocate socket\n");
|
||||
|
@ -152,6 +163,20 @@ public:
|
|||
Busy
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
static EResult LastWSAError()
|
||||
{
|
||||
switch (WSAGetLastError())
|
||||
{
|
||||
case WSAEWOULDBLOCK:
|
||||
case WSAEALREADY:
|
||||
return EResult::Busy;
|
||||
default:
|
||||
return EResult::Error;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Socket(bool blocking)
|
||||
: m_isBlocking(blocking) {}
|
||||
~Socket() { close(); }
|
||||
|
@ -175,11 +200,16 @@ public:
|
|||
void setBlocking(bool blocking)
|
||||
{
|
||||
m_isBlocking = blocking;
|
||||
#ifndef _WIN32
|
||||
int status = fcntl(m_socket, F_GETFL);
|
||||
if (m_isBlocking)
|
||||
fcntl(m_socket, F_SETFL, status & ~O_NONBLOCK);
|
||||
else
|
||||
fcntl(m_socket, F_SETFL, status | O_NONBLOCK);
|
||||
#else
|
||||
u_long b = blocking ? 0 : 1;
|
||||
ioctlsocket(m_socket, FIONBIO, &b);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isOpen() const { return m_socket != -1; }
|
||||
|
@ -218,9 +248,15 @@ public:
|
|||
/* Check for errors */
|
||||
if (remoteSocket == -1)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
EResult res = (errno == EAGAIN) ? EResult::Busy : EResult::Error;
|
||||
if (res == EResult::Error)
|
||||
fprintf(stderr, "Failed to accept incoming connection: %s\n", strerror(errno));
|
||||
#else
|
||||
EResult res = LastWSAError();
|
||||
if (res == EResult::Error)
|
||||
fprintf(stderr, "Failed to accept incoming connection\n");
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -252,7 +288,11 @@ public:
|
|||
{
|
||||
if (!isOpen())
|
||||
return;
|
||||
#ifndef _WIN32
|
||||
::close(m_socket);
|
||||
#else
|
||||
closesocket(m_socket);
|
||||
#endif
|
||||
m_socket = -1;
|
||||
}
|
||||
|
||||
|
@ -266,7 +306,7 @@ public:
|
|||
return EResult::Error;
|
||||
|
||||
/* Loop until every byte has been sent */
|
||||
ssize_t result = 0;
|
||||
int result = 0;
|
||||
for (size_t sent = 0; sent < len; sent += result)
|
||||
{
|
||||
/* Send a chunk of data */
|
||||
|
@ -274,7 +314,11 @@ public:
|
|||
|
||||
/* Check for errors */
|
||||
if (result < 0)
|
||||
#ifndef _WIN32
|
||||
return (errno == EAGAIN) ? EResult::Busy : EResult::Error;
|
||||
#else
|
||||
return LastWSAError();
|
||||
#endif
|
||||
}
|
||||
|
||||
transferred = len;
|
||||
|
@ -303,7 +347,11 @@ public:
|
|||
int result = ::recv(m_socket, static_cast<char*>(buf), static_cast<int>(len), _flags);
|
||||
|
||||
if (result < 0)
|
||||
#ifndef _WIN32
|
||||
return (errno == EAGAIN) ? EResult::Busy : EResult::Error;
|
||||
#else
|
||||
return LastWSAError();
|
||||
#endif
|
||||
else if (result == 0)
|
||||
return EResult::Error;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <WinSock2.h>
|
||||
#endif
|
||||
|
||||
#include "jbus/Common.hpp"
|
||||
|
@ -18,6 +19,8 @@ namespace jbus
|
|||
#if __APPLE__
|
||||
static u64 MachToDolphinNum;
|
||||
static u64 MachToDolphinDenom;
|
||||
#elif _WIN32
|
||||
static LARGE_INTEGER PerfFrequency;
|
||||
#endif
|
||||
|
||||
u64 GetGCTicks()
|
||||
|
@ -29,6 +32,12 @@ u64 GetGCTicks()
|
|||
clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||
|
||||
return u64((tp.tv_sec * 1000000000ull) + tp.tv_nsec) * GetGCTicksPerSec() / 1000000000ull;
|
||||
#elif _WIN32
|
||||
LARGE_INTEGER perf;
|
||||
QueryPerformanceCounter(&perf);
|
||||
perf.QuadPart *= GetGCTicksPerSec();
|
||||
perf.QuadPart /= PerfFrequency.QuadPart;
|
||||
return perf.QuadPart;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
@ -36,10 +45,15 @@ u64 GetGCTicks()
|
|||
|
||||
void WaitGCTicks(u64 ticks)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
struct timeval tv = {};
|
||||
tv.tv_sec = ticks / GetGCTicksPerSec();
|
||||
tv.tv_usec = (ticks % GetGCTicksPerSec()) * 1000000 / GetGCTicksPerSec();
|
||||
select(0, NULL, NULL, NULL, &tv);
|
||||
#else
|
||||
Sleep(ticks * 1000 / GetGCTicksPerSec() +
|
||||
(ticks % GetGCTicksPerSec()) * 1000 / GetGCTicksPerSec());
|
||||
#endif
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
|
@ -49,6 +63,10 @@ void Initialize()
|
|||
mach_timebase_info(&timebase);
|
||||
MachToDolphinNum = GetGCTicksPerSec() * timebase.numer;
|
||||
MachToDolphinDenom = 1000000000ull * timebase.denom;
|
||||
#elif _WIN32
|
||||
WSADATA initData;
|
||||
WSAStartup(MAKEWORD(2, 2), &initData);
|
||||
QueryPerformanceFrequency(&PerfFrequency);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "jbus/Endpoint.hpp"
|
||||
|
||||
#define LOG_TRANSFER 0
|
||||
#define LOG_TRANSFER 1
|
||||
|
||||
namespace jbus
|
||||
{
|
||||
|
@ -418,6 +418,7 @@ void Endpoint::clockSync()
|
|||
TickDelta = u32(u64(TickDelta) * 16777216 / GetGCTicksPerSec());
|
||||
m_lastGCTick = GetGCTicks();
|
||||
TickDelta = SBig(TickDelta);
|
||||
m_clockSocket.setBlocking(false);
|
||||
if (m_clockSocket.send(&TickDelta, 4) == net::Socket::EResult::Error)
|
||||
m_running = false;
|
||||
}
|
||||
|
@ -428,6 +429,7 @@ void Endpoint::send(const u8* buffer)
|
|||
|
||||
net::Socket::EResult result;
|
||||
size_t sentBytes;
|
||||
m_dataSocket.setBlocking(false);
|
||||
if (m_lastCmd == CMD_WRITE)
|
||||
result = m_dataSocket.send(buffer, 5, sentBytes);
|
||||
else
|
||||
|
@ -451,7 +453,7 @@ void Endpoint::send(const u8* buffer)
|
|||
m_timeCmdSent = GetGCTicks();
|
||||
}
|
||||
|
||||
size_t Endpoint::seceive(u8* buffer)
|
||||
size_t Endpoint::receive(u8* buffer)
|
||||
{
|
||||
if (!m_dataSocket)
|
||||
{
|
||||
|
@ -523,7 +525,7 @@ size_t Endpoint::runBuffer(u8* buffer, u64& remTicks, EWaitResp resp)
|
|||
|
||||
if (m_waitingResp != EWaitResp::NoWait && m_dataReceivedBytes == 0)
|
||||
{
|
||||
m_dataReceivedBytes = seceive(buffer);
|
||||
m_dataReceivedBytes = receive(buffer);
|
||||
}
|
||||
|
||||
u64 ticksSinceSend = GetGCTicks() - m_timeSent;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "jbus/Listener.hpp"
|
||||
#include "jbus/Endpoint.hpp"
|
||||
|
||||
#define LOG_LISTENER 0
|
||||
#define LOG_LISTENER 1
|
||||
|
||||
namespace jbus
|
||||
{
|
||||
|
@ -25,7 +25,7 @@ void Listener::listenerProc()
|
|||
#if LOG_LISTENER
|
||||
printf("data open failed %s; will retry\n", strerror(errno));
|
||||
#endif
|
||||
sleep(1);
|
||||
WaitGCTicks(GetGCTicksPerSec());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -42,7 +42,7 @@ void Listener::listenerProc()
|
|||
#if LOG_LISTENER
|
||||
printf("clock open failed %s; will retry\n", strerror(errno));
|
||||
#endif
|
||||
sleep(1);
|
||||
WaitGCTicks(GetGCTicksPerSec());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -77,7 +77,7 @@ void Listener::listenerProc()
|
|||
m_endpointQueue.push(std::make_unique<Endpoint>(
|
||||
chan++, std::move(acceptData), std::move(acceptClock)));
|
||||
}
|
||||
sleep(1);
|
||||
WaitGCTicks(GetGCTicksPerSec());
|
||||
}
|
||||
|
||||
m_dataServer.close();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include "jbus/Listener.hpp"
|
||||
#include "jbus/Endpoint.hpp"
|
||||
#include <functional>
|
||||
|
||||
static void clientPadComplimentCheck(jbus::u8* buffer)
|
||||
{
|
||||
|
@ -83,7 +84,9 @@ int main(int argc, char** argv)
|
|||
|
||||
jbus::u8 status;
|
||||
if (endpoint->GBAJoyBootAsync(2, 2, data.get(), fsize,
|
||||
&status, JoyBootDone) != jbus::GBA_READY)
|
||||
&status, std::bind(JoyBootDone,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2)) != jbus::GBA_READY)
|
||||
{
|
||||
fprintf(stderr, "Unable to start JoyBoot\n");
|
||||
return 1;
|
||||
|
|
Loading…
Reference in New Issue