Commit e28b6551 authored by Jack Andersen's avatar Jack Andersen

New code style refactor

parent 500f88d7
......@@ -4,8 +4,7 @@
#include <cstdint>
#include <cstdlib>
namespace jbus
{
namespace jbus {
using s8 = int8_t;
using u8 = uint8_t;
......@@ -24,114 +23,100 @@ using u64 = uint64_t;
/* Type-sensitive byte swappers */
template <typename T>
static inline T bswap16(T val)
{
static inline T bswap16(T val) {
#if __GNUC__
return __builtin_bswap16(val);
return __builtin_bswap16(val);
#elif _WIN32
return _byteswap_ushort(val);
return _byteswap_ushort(val);
#else
return (val = (val << 8) | ((val >> 8) & 0xFF));
return (val = (val << 8) | ((val >> 8) & 0xFF));
#endif
}
template <typename T>
static inline T bswap32(T val)
{
static inline T bswap32(T val) {
#if __GNUC__
return __builtin_bswap32(val);
return __builtin_bswap32(val);
#elif _WIN32
return _byteswap_ulong(val);
return _byteswap_ulong(val);
#else
val = (val & 0x0000FFFF) << 16 | (val & 0xFFFF0000) >> 16;
val = (val & 0x00FF00FF) << 8 | (val & 0xFF00FF00) >> 8;
return val;
val = (val & 0x0000FFFF) << 16 | (val & 0xFFFF0000) >> 16;
val = (val & 0x00FF00FF) << 8 | (val & 0xFF00FF00) >> 8;
return val;
#endif
}
template <typename T>
static inline T bswap64(T val)
{
static inline T bswap64(T val) {
#if __GNUC__
return __builtin_bswap64(val);
return __builtin_bswap64(val);
#elif _WIN32
return _byteswap_uint64(val);
return _byteswap_uint64(val);
#else
return ((val & 0xFF00000000000000ULL) >> 56) |
((val & 0x00FF000000000000ULL) >> 40) |
((val & 0x0000FF0000000000ULL) >> 24) |
((val & 0x000000FF00000000ULL) >> 8) |
((val & 0x00000000FF000000ULL) << 8) |
((val & 0x0000000000FF0000ULL) << 24) |
((val & 0x000000000000FF00ULL) << 40) |
((val & 0x00000000000000FFULL) << 56);
return ((val & 0xFF00000000000000ULL) >> 56) | ((val & 0x00FF000000000000ULL) >> 40) |
((val & 0x0000FF0000000000ULL) >> 24) | ((val & 0x000000FF00000000ULL) >> 8) |
((val & 0x00000000FF000000ULL) << 8) | ((val & 0x0000000000FF0000ULL) << 24) |
((val & 0x000000000000FF00ULL) << 40) | ((val & 0x00000000000000FFULL) << 56);
#endif
}
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
static inline int16_t SBig(int16_t val) {return bswap16(val);}
static inline uint16_t SBig(uint16_t val) {return bswap16(val);}
static inline int32_t SBig(int32_t val) {return bswap32(val);}
static inline uint32_t SBig(uint32_t val) {return bswap32(val);}
static inline int64_t SBig(int64_t val) {return bswap64(val);}
static inline uint64_t SBig(uint64_t val) {return bswap64(val);}
static inline float SBig(float val)
{
int32_t ival = bswap32(*((int32_t*)(&val)));
return *((float*)(&ival));
static inline int16_t SBig(int16_t val) { return bswap16(val); }
static inline uint16_t SBig(uint16_t val) { return bswap16(val); }
static inline int32_t SBig(int32_t val) { return bswap32(val); }
static inline uint32_t SBig(uint32_t val) { return bswap32(val); }
static inline int64_t SBig(int64_t val) { return bswap64(val); }
static inline uint64_t SBig(uint64_t val) { return bswap64(val); }
static inline float SBig(float val) {
int32_t ival = bswap32(*((int32_t*)(&val)));
return *((float*)(&ival));
}
static inline double SBig(double val)
{
int64_t ival = bswap64(*((int64_t*)(&val)));
return *((double*)(&ival));
static inline double SBig(double val) {
int64_t ival = bswap64(*((int64_t*)(&val)));
return *((double*)(&ival));
}
#ifndef SBIG
#define SBIG(q) ( ( (q) & 0x000000FF ) << 24 | ( (q) & 0x0000FF00 ) << 8 \
| ( (q) & 0x00FF0000 ) >> 8 | ( (q) & 0xFF000000 ) >> 24 )
#define SBIG(q) (((q)&0x000000FF) << 24 | ((q)&0x0000FF00) << 8 | ((q)&0x00FF0000) >> 8 | ((q)&0xFF000000) >> 24)
#endif
static inline int16_t SLittle(int16_t val) {return val;}
static inline uint16_t SLittle(uint16_t val) {return val;}
static inline int32_t SLittle(int32_t val) {return val;}
static inline uint32_t SLittle(uint32_t val) {return val;}
static inline int64_t SLittle(int64_t val) {return val;}
static inline uint64_t SLittle(uint64_t val) {return val;}
static inline float SLittle(float val) {return val;}
static inline double SLittle(double val) {return val;}
static inline int16_t SLittle(int16_t val) { return val; }
static inline uint16_t SLittle(uint16_t val) { return val; }
static inline int32_t SLittle(int32_t val) { return val; }
static inline uint32_t SLittle(uint32_t val) { return val; }
static inline int64_t SLittle(int64_t val) { return val; }
static inline uint64_t SLittle(uint64_t val) { return val; }
static inline float SLittle(float val) { return val; }
static inline double SLittle(double val) { return val; }
#ifndef SLITTLE
#define SLITTLE(q) (q)
#endif
#else
static inline int16_t SLittle(int16_t val) {return bswap16(val);}
static inline uint16_t SLittle(uint16_t val) {return bswap16(val);}
static inline int32_t SLittle(int32_t val) {return bswap32(val);}
static inline uint32_t SLittle(uint32_t val) {return bswap32(val);}
static inline int64_t SLittle(int64_t val) {return bswap64(val);}
static inline uint64_t SLittle(uint64_t val) {return bswap64(val);}
static inline float SLittle(float val)
{
int32_t ival = bswap32(*((int32_t*)(&val)));
return *((float*)(&ival));
static inline int16_t SLittle(int16_t val) { return bswap16(val); }
static inline uint16_t SLittle(uint16_t val) { return bswap16(val); }
static inline int32_t SLittle(int32_t val) { return bswap32(val); }
static inline uint32_t SLittle(uint32_t val) { return bswap32(val); }
static inline int64_t SLittle(int64_t val) { return bswap64(val); }
static inline uint64_t SLittle(uint64_t val) { return bswap64(val); }
static inline float SLittle(float val) {
int32_t ival = bswap32(*((int32_t*)(&val)));
return *((float*)(&ival));
}
static inline double SLittle(double val)
{
int64_t ival = bswap64(*((int64_t*)(&val)));
return *((double*)(&ival));
static inline double SLittle(double val) {
int64_t ival = bswap64(*((int64_t*)(&val)));
return *((double*)(&ival));
}
#ifndef SLITTLE
#define SLITTLE(q) ( ( (q) & 0x000000FF ) << 24 | ( (q) & 0x0000FF00 ) << 8 \
| ( (q) & 0x00FF0000 ) >> 8 | ( (q) & 0xFF000000 ) >> 24 )
#define SLITTLE(q) (((q)&0x000000FF) << 24 | ((q)&0x0000FF00) << 8 | ((q)&0x00FF0000) >> 8 | ((q)&0xFF000000) >> 24)
#endif
static inline int16_t SBig(int16_t val) {return val;}
static inline uint16_t SBig(uint16_t val) {return val;}
static inline int32_t SBig(int32_t val) {return val;}
static inline uint32_t SBig(uint32_t val) {return val;}
static inline int64_t SBig(int64_t val) {return val;}
static inline uint64_t SBig(uint64_t val) {return val;}
static inline float SBig(float val) {return val;}
static inline double SBig(double val) {return val;}
static inline int16_t SBig(int16_t val) { return val; }
static inline uint16_t SBig(uint16_t val) { return val; }
static inline int32_t SBig(int32_t val) { return val; }
static inline uint32_t SBig(uint32_t val) { return val; }
static inline int64_t SBig(int64_t val) { return val; }
static inline uint64_t SBig(uint64_t val) { return val; }
static inline float SBig(float val) { return val; }
static inline double SBig(double val) { return val; }
#ifndef SBIG
#define SBIG(q) (q)
#endif
......@@ -142,24 +127,22 @@ class ThreadLocalEndpoint;
#endif
enum EJStatFlags
{
GBA_JSTAT_MASK = 0x3a,
GBA_JSTAT_FLAGS_SHIFT = 4,
GBA_JSTAT_FLAGS_MASK = 0x30,
GBA_JSTAT_PSF1 = 0x20,
GBA_JSTAT_PSF0 = 0x10,
GBA_JSTAT_SEND = 0x08,
GBA_JSTAT_RECV = 0x02
enum EJStatFlags {
GBA_JSTAT_MASK = 0x3a,
GBA_JSTAT_FLAGS_SHIFT = 4,
GBA_JSTAT_FLAGS_MASK = 0x30,
GBA_JSTAT_PSF1 = 0x20,
GBA_JSTAT_PSF0 = 0x10,
GBA_JSTAT_SEND = 0x08,
GBA_JSTAT_RECV = 0x02
};
enum EJoyReturn
{
GBA_READY = 0,
GBA_NOT_READY = 1,
GBA_BUSY = 2,
GBA_JOYBOOT_UNKNOWN_STATE = 3,
GBA_JOYBOOT_ERR_INVALID = 4
enum EJoyReturn {
GBA_READY = 0,
GBA_NOT_READY = 1,
GBA_BUSY = 2,
GBA_JOYBOOT_UNKNOWN_STATE = 3,
GBA_JOYBOOT_ERR_INVALID = 4
};
/** @brief Standard callback for asynchronous jbus::Endpoint APIs.
......@@ -182,5 +165,4 @@ static constexpr u64 GetGCTicksPerSec() { return 486000000ull; }
/** @brief Initialize platform specifics of JBus library */
void Initialize();
}
} // namespace jbus
This diff is collapsed.
......@@ -6,37 +6,34 @@
#include <queue>
#include <mutex>
namespace jbus
{
namespace jbus {
/** Server interface for accepting incoming connections from GBA emulator instances. */
class Listener
{
net::Socket m_dataServer = {false};
net::Socket m_clockServer = {false};
std::thread m_listenerThread;
std::mutex m_queueLock;
std::queue<std::unique_ptr<Endpoint>> m_endpointQueue;
bool m_running = false;
class Listener {
net::Socket m_dataServer = {false};
net::Socket m_clockServer = {false};
std::thread m_listenerThread;
std::mutex m_queueLock;
std::queue<std::unique_ptr<Endpoint>> m_endpointQueue;
bool m_running = false;
static const uint32_t DataPort = 0xd6ba;
static const uint32_t ClockPort = 0xc10c;
static const uint32_t DataPort = 0xd6ba;
static const uint32_t ClockPort = 0xc10c;
void listenerProc();
void listenerProc();
public:
/** @brief Start listener thread. */
void start();
/** @brief Start listener thread. */
void start();
/** @brief Request stop of listener thread and block until joined. */
void stop();
/** @brief Request stop of listener thread and block until joined. */
void stop();
/** @brief Pop jbus::Endpoint off Listener's queue.
* @return Endpoint instance, ready to issue commands. */
std::unique_ptr<Endpoint> accept();
/** @brief Pop jbus::Endpoint off Listener's queue.
* @return Endpoint instance, ready to issue commands. */
std::unique_ptr<Endpoint> accept();
~Listener();
~Listener();
};
}
} // namespace jbus
......@@ -14,89 +14,71 @@ typedef UINT_PTR SOCKET;
struct sockaddr_in;
namespace jbus::net
{
namespace jbus::net {
/** IP address class derived from SFML */
class IPAddress
{
uint32_t m_address = 0;
bool m_valid = false;
class IPAddress {
uint32_t m_address = 0;
bool m_valid = false;
void resolve(const std::string& address);
void resolve(const std::string& address);
public:
IPAddress(const std::string& address)
{
resolve(address);
}
IPAddress(const std::string& address) { resolve(address); }
uint32_t toInteger() const;
operator bool() const { return m_valid; }
uint32_t toInteger() const;
operator bool() const { return m_valid; }
};
/** Server-oriented TCP socket class derived from SFML */
class Socket
{
class Socket {
#ifndef _WIN32
using SocketTp = int;
using SocketTp = int;
#else
using SocketTp = SOCKET;
using SocketTp = SOCKET;
#endif
SocketTp m_socket = -1;
bool m_isBlocking;
SocketTp m_socket = -1;
bool m_isBlocking;
bool openSocket();
void setRemoteSocket(int remSocket);
bool openSocket();
void setRemoteSocket(int remSocket);
public:
enum class EResult
{
OK,
Error,
Busy
};
enum class EResult { OK, Error, Busy };
#ifdef _WIN32
static EResult LastWSAError();
static EResult LastWSAError();
#endif
Socket(bool blocking)
: m_isBlocking(blocking) {}
~Socket() { close(); }
Socket(const Socket& other) = delete;
Socket& operator=(const Socket& other) = delete;
Socket(Socket&& other)
: m_socket(other.m_socket), m_isBlocking(other.m_isBlocking)
{
other.m_socket = -1;
}
Socket& operator=(Socket&& other)
{
close();
m_socket = other.m_socket;
other.m_socket = -1;
m_isBlocking = other.m_isBlocking;
return *this;
}
void setBlocking(bool blocking);
bool isOpen() const { return m_socket != -1; }
bool openAndListen(const IPAddress& address, uint32_t port);
EResult accept(Socket& remoteSocketOut, sockaddr_in& fromAddress);
EResult accept(Socket& remoteSocketOut);
EResult accept(Socket& remoteSocketOut, std::string& fromHostname);
void close();
EResult send(const void* buf, size_t len, size_t& transferred);
EResult send(const void* buf, size_t len);
EResult recv(void* buf, size_t len, size_t& transferred);
EResult recv(void* buf, size_t len);
operator bool() const { return isOpen(); }
SocketTp GetInternalSocket() const { return m_socket; }
Socket(bool blocking) : m_isBlocking(blocking) {}
~Socket() { close(); }
Socket(const Socket& other) = delete;
Socket& operator=(const Socket& other) = delete;
Socket(Socket&& other) : m_socket(other.m_socket), m_isBlocking(other.m_isBlocking) { other.m_socket = -1; }
Socket& operator=(Socket&& other) {
close();
m_socket = other.m_socket;
other.m_socket = -1;
m_isBlocking = other.m_isBlocking;
return *this;
}
void setBlocking(bool blocking);
bool isOpen() const { return m_socket != -1; }
bool openAndListen(const IPAddress& address, uint32_t port);
EResult accept(Socket& remoteSocketOut, sockaddr_in& fromAddress);
EResult accept(Socket& remoteSocketOut);
EResult accept(Socket& remoteSocketOut, std::string& fromHostname);
void close();
EResult send(const void* buf, size_t len, size_t& transferred);
EResult send(const void* buf, size_t len);
EResult recv(void* buf, size_t len, size_t& transferred);
EResult recv(void* buf, size_t len);
operator bool() const { return isOpen(); }
SocketTp GetInternalSocket() const { return m_socket; }
};
}
} // namespace jbus::net
This diff is collapsed.
......@@ -14,8 +14,7 @@
#include "jbus/Common.hpp"
namespace jbus
{
namespace jbus {
#if __APPLE__
static u64 MachToDolphinNum;
......@@ -24,61 +23,56 @@ static u64 MachToDolphinDenom;
static LARGE_INTEGER PerfFrequency;
#endif
u64 GetGCTicks()
{
u64 GetGCTicks() {
#if __APPLE__
return mach_absolute_time() * MachToDolphinNum / MachToDolphinDenom;
return mach_absolute_time() * MachToDolphinNum / MachToDolphinDenom;
#elif __linux__ || __FreeBSD__
struct timespec tp;
clock_gettime(CLOCK_MONOTONIC, &tp);
struct timespec tp;
clock_gettime(CLOCK_MONOTONIC, &tp);
return u64((tp.tv_sec * 1000000000ull) + tp.tv_nsec) * GetGCTicksPerSec() / 1000000000ull;
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;
LARGE_INTEGER perf;
QueryPerformanceCounter(&perf);
perf.QuadPart *= GetGCTicksPerSec();
perf.QuadPart /= PerfFrequency.QuadPart;
return perf.QuadPart;
#else
return 0;
return 0;
#endif
}
void WaitGCTicks(u64 ticks)
{
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);
struct timeval tv = {};
tv.tv_sec = ticks / GetGCTicksPerSec();
tv.tv_usec = (ticks % GetGCTicksPerSec()) * 1000000 / GetGCTicksPerSec();
select(0, NULL, NULL, NULL, &tv);
#else
if (ticks < GetGCTicksPerSec() / 60)
{
/* NT is useless for scheduling sub-millisecond intervals */
u64 start = GetGCTicks();
do { Sleep(0); } while (GetGCTicks() - start < ticks);
}
else
{
/* Use normal Sleep() for durations longer than ~16ms */
Sleep(ticks * 1000 / GetGCTicksPerSec() +
(ticks % GetGCTicksPerSec()) * 1000 / GetGCTicksPerSec());
}
if (ticks < GetGCTicksPerSec() / 60) {
/* NT is useless for scheduling sub-millisecond intervals */
u64 start = GetGCTicks();
do {
Sleep(0);
} while (GetGCTicks() - start < ticks);
} else {
/* Use normal Sleep() for durations longer than ~16ms */
Sleep(ticks * 1000 / GetGCTicksPerSec() + (ticks % GetGCTicksPerSec()) * 1000 / GetGCTicksPerSec());
}
#endif
}
void Initialize()
{
void Initialize() {
#if __APPLE__
mach_timebase_info_data_t timebase;
mach_timebase_info(&timebase);
MachToDolphinNum = GetGCTicksPerSec() * timebase.numer;
MachToDolphinDenom = 1000000000ull * timebase.denom;
mach_timebase_info_data_t timebase;
mach_timebase_info(&timebase);
MachToDolphinNum = GetGCTicksPerSec() * timebase.numer;
MachToDolphinDenom = 1000000000ull * timebase.denom;
#elif _WIN32
WSADATA initData;
WSAStartup(MAKEWORD(2, 2), &initData);
QueryPerformanceFrequency(&PerfFrequency);
WSADATA initData;
WSAStartup(MAKEWORD(2, 2), &initData);
QueryPerformanceFrequency(&PerfFrequency);
#endif
}
}
} // namespace jbus
This diff is collapsed.
......@@ -3,117 +3,97 @@
#define LOG_LISTENER 0
namespace jbus
{
namespace jbus {
void Listener::listenerProc()
{
void Listener::listenerProc() {
#if LOG_LISTENER
printf("JoyBus listener started\n");
printf("JoyBus listener started\n");
#endif
net::IPAddress localhost("127.0.0.1");
bool dataBound = false;
bool clockBound = false;
while (m_running && (!dataBound || !clockBound))
{
if (!dataBound)
{
if (!(dataBound = m_dataServer.openAndListen(localhost, DataPort)))
{
m_dataServer = net::Socket(false);
net::IPAddress localhost("127.0.0.1");
bool dataBound = false;
bool clockBound = false;
while (m_running && (!dataBound || !clockBound)) {
if (!dataBound) {
if (!(dataBound = m_dataServer.openAndListen(localhost, DataPort))) {
m_dataServer = net::Socket(false);
#if LOG_LISTENER
printf("data open failed %s; will retry\n", strerror(errno));
printf("data open failed %s; will retry\n", strerror(errno));
#endif
WaitGCTicks(GetGCTicksPerSec());
}
else
{
WaitGCTicks(GetGCTicksPerSec());
} else {
#if LOG_LISTENER
printf("data listening on port %d\n", DataPort);
printf("data listening on port %d\n", DataPort);
#endif
}
}
if (!clockBound)
{
if (!(clockBound = m_clockServer.openAndListen(localhost, ClockPort)))
{
m_clockServer = net::Socket(false);
}
}
if (!clockBound) {
if (!(clockBound = m_clockServer.openAndListen(localhost, ClockPort))) {
m_clockServer = net::Socket(false);
#if LOG_LISTENER
printf("clock open failed %s; will retry\n", strerror(errno));
printf("clock open failed %s; will retry\n", strerror(errno));
#endif
WaitGCTicks(GetGCTicksPerSec());
}
else
{
WaitGCTicks(GetGCTicksPerSec());
} else {
#if LOG_LISTENER
printf("clock listening on port %d\n", ClockPort);
printf("clock listening on port %d\n", ClockPort);
#endif
}
}
}
}
}
/* We use blocking I/O since we have a dedicated transfer thread */
net::Socket acceptData = {true};
net::Socket acceptClock = {true};
std::string hostname;
while (m_running)
{
if (m_dataServer.accept(acceptData, hostname) == net::Socket::EResult::OK)
{
/* We use blocking I/O since we have a dedicated transfer thread */
net::Socket acceptData = {true};
net::Socket acceptClock = {true};
std::string hostname;
while (m_running) {
if (m_dataServer.accept(acceptData, hostname) == net::Socket::EResult::OK) {
#if LOG_LISTENER
printf("accepted data connection from %s\n", hostname.c_str());
printf("accepted data connection from %s\n", hostname.c_str());
#endif
}
if (m_clockServer.accept(acceptClock, hostname) == net::Socket::EResult::OK)
{
}
if (m_clockServer.accept(acceptClock, hostname) == net::Socket::EResult::OK) {
#if LOG_LISTENER
printf("accepted clock connection from %s\n", hostname.c_str());
printf("accepted clock connection from %s\n", hostname.c_str());
#endif
}
if (acceptData && acceptClock)
{
std::unique_lock<std::mutex> lk(m_queueLock);
m_endpointQueue.push(std::make_unique<Endpoint>(
0, std::move(acceptData), std::move(acceptClock)));
}
WaitGCTicks(GetGCTicksPerSec());
}
if (acceptData && acceptClock) {
std::unique_lock<std::mutex> lk(m_queueLock);
m_endpointQueue.push(std::make_unique<Endpoint>(0, std::move(acceptData), std::move(acceptClock)));
}
WaitGCTicks(GetGCTicksPerSec());
}
m_dataServer.close();
m_clockServer.close();
m_dataServer.close();
m_clockServer.close();
#if LOG_LISTENER
printf("JoyBus listener stopped\n");
printf("JoyBus listener stopped\n");
#endif
}
void Listener::start()
{
stop();
m_running = true;
m_listenerThread = std::thread(std::bind(&Listener::listenerProc, this));
void Listener::start() {
stop();
m_running = true;
m_listenerThread = std::thread(std::bind(&Listener::listenerProc, this));
}
void Listener::stop()
{
m_running = false;
if (m_listenerThread.joinable())
m_listenerThread.join();
void Listener::stop() {
m_running = false;
if (m_listenerThread.joinable())
m_listenerThread.join();
}
std::unique_ptr<Endpoint> Listener::accept()
{
std::unique_lock<std::mutex> lk(m_queueLock);
if (m_endpointQueue.size())
{
std::unique_ptr<Endpoint> ret;
ret = std::move(m_endpointQueue.front());
m_endpointQueue.pop();
return ret;
}
return {};
std::unique_ptr<Endpoint> Listener::accept() {
std::unique_lock<std::mutex> lk(m_queueLock);
if (m_endpointQueue.size()) {
std::unique_ptr<Endpoint> ret;
ret = std::move(m_endpointQueue.front());
m_endpointQueue.pop();
return ret;
}
return {};
}
Listener::~Listener() { stop(); }
}
} // namespace jbus
This diff is collapsed.
......@@ -3,128 +3,111 @@
#include "jbus/Endpoint.hpp"
#include <functional>
static void clientPadComplimentCheck(jbus::u8* buffer)
{
jbus