mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2026-07-12 18:04:04 +00:00
Add NXDK (Xbox) support
This commit is contained in:
committed by
Cameron Gutman
parent
2600beaf13
commit
40d87314d0
+1
-1
Submodule enet updated: c7353c0593...0eb84dcca8
@@ -58,7 +58,7 @@ void obl_axpyb32_ref(u8 *a, u32 *b, u8 u, unsigned k)
|
||||
for (unsigned idx = 0, p = 0; idx < k; idx += 8 * sizeof(u32), p++) {
|
||||
u32 tmp = b[p];
|
||||
while (tmp > 0) {
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
unsigned long index = 0;
|
||||
_BitScanForward(&index, tmp);
|
||||
unsigned tz = (unsigned int)index;
|
||||
|
||||
+7
-5
@@ -20,7 +20,7 @@ static int activeMutexes = 0;
|
||||
static int activeEvents = 0;
|
||||
static int activeCondVars = 0;
|
||||
|
||||
#if defined(LC_WINDOWS)
|
||||
#if defined(LC_WINDOWS) && !defined(NXDK)
|
||||
|
||||
#pragma pack(push, 8)
|
||||
typedef struct tagTHREADNAME_INFO
|
||||
@@ -65,7 +65,9 @@ void setThreadNameWin32(const char* name) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LC_WINDOWS)
|
||||
DWORD WINAPI ThreadProc(LPVOID lpParameter) {
|
||||
struct thread_context* ctx = (struct thread_context*)lpParameter;
|
||||
#elif defined(__WIIU__)
|
||||
@@ -76,7 +78,7 @@ void* ThreadProc(void* context) {
|
||||
struct thread_context* ctx = (struct thread_context*)context;
|
||||
#endif
|
||||
|
||||
#if defined(LC_WINDOWS)
|
||||
#if defined(LC_WINDOWS) && !defined(NXDK)
|
||||
setThreadNameWin32(ctx->name);
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
pthread_setname_np(pthread_self(), ctx->name);
|
||||
@@ -298,7 +300,7 @@ int PltCreateThread(const char* name, ThreadEntry entry, void* context, PLT_THRE
|
||||
free(ctx);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -309,7 +311,7 @@ int PltCreateThread(const char* name, ThreadEntry entry, void* context, PLT_THRE
|
||||
|
||||
int PltCreateEvent(PLT_EVENT* event) {
|
||||
#if defined(LC_WINDOWS)
|
||||
*event = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
|
||||
*event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!*event) {
|
||||
return -1;
|
||||
}
|
||||
@@ -578,7 +580,7 @@ bool PltSafeStrcpy(char* dest, size_t dest_size, const char* src) {
|
||||
memset(dest, 0xFE, dest_size);
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER) && !defined(NXDK)
|
||||
// strncpy_s() with _TRUNCATE does what we need for MSVC.
|
||||
// We use this rather than strcpy_s() because we don't want
|
||||
// the invalid parameter handler invoked upon failure.
|
||||
|
||||
+34
-17
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(NXDK)
|
||||
// Prevent bogus definitions of error codes
|
||||
// that are incompatible with Winsock errors.
|
||||
#define _CRT_NO_POSIX_ERROR_CODES
|
||||
@@ -13,11 +13,23 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(NXDK)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#elif defined(NXDK)
|
||||
// nxdk exposes Win32-style threading primitives, but its network stack is
|
||||
// lwIP with POSIX/BSD socket compatibility headers. Pull in the socket-facing
|
||||
// headers from the POSIX side so moonlight-common-c uses the Unix backend.
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <mach/mach_time.h>
|
||||
#include <unistd.h>
|
||||
@@ -64,15 +76,19 @@
|
||||
#endif
|
||||
|
||||
#ifdef LC_WINDOWS
|
||||
# if !defined(NXDK)
|
||||
// Windows doesn't have strtok_r() but it has the same
|
||||
// function named strtok_s().
|
||||
#define strtok_r strtok_s
|
||||
# endif
|
||||
|
||||
# if defined(WINAPI_FAMILY) && WINAPI_FAMILY==WINAPI_FAMILY_APP
|
||||
# define LC_UWP
|
||||
# else
|
||||
# define LC_WINDOWS_DESKTOP
|
||||
#endif
|
||||
# if !defined(NXDK)
|
||||
# if defined(WINAPI_FAMILY) && WINAPI_FAMILY==WINAPI_FAMILY_APP
|
||||
# define LC_UWP
|
||||
# else
|
||||
# define LC_WINDOWS_DESKTOP
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -83,7 +99,7 @@
|
||||
if (ListenerCallbacks.logMessage) \
|
||||
ListenerCallbacks.logMessage(s, ##__VA_ARGS__)
|
||||
|
||||
#if defined(LC_WINDOWS)
|
||||
#if defined(LC_WINDOWS) && !defined(__clang__)
|
||||
#include <crtdbg.h>
|
||||
#ifdef LC_DEBUG
|
||||
#define LC_ASSERT(x) __analysis_assume(x); \
|
||||
@@ -116,21 +132,22 @@
|
||||
#define LC_ASSERT_VT(x) LC_ASSERT(x)
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if defined(__has_builtin) && __has_builtin(__builtin_bswap16)
|
||||
#define LC_HAS_BUILTIN_BSWAP
|
||||
#endif
|
||||
|
||||
#if defined(LC_HAS_BUILTIN_BSWAP) || \
|
||||
(defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
|
||||
#define BSWAP16(x) __builtin_bswap16(x)
|
||||
#define BSWAP32(x) __builtin_bswap32(x)
|
||||
#define BSWAP64(x) __builtin_bswap64(x)
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma intrinsic(_byteswap_ushort)
|
||||
#define BSWAP16(x) _byteswap_ushort(x)
|
||||
#pragma intrinsic(_byteswap_ulong)
|
||||
#define BSWAP32(x) _byteswap_ulong(x)
|
||||
#pragma intrinsic(_byteswap_uint64)
|
||||
#define BSWAP64(x) _byteswap_uint64(x)
|
||||
#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
#define BSWAP16(x) __builtin_bswap16(x)
|
||||
#define BSWAP32(x) __builtin_bswap32(x)
|
||||
#define BSWAP64(x) __builtin_bswap64(x)
|
||||
#elif defined(__has_builtin) && __has_builtin(__builtin_bswap16)
|
||||
#define BSWAP16(x) __builtin_bswap16(x)
|
||||
#define BSWAP32(x) __builtin_bswap32(x)
|
||||
#define BSWAP64(x) __builtin_bswap64(x)
|
||||
#else
|
||||
#error Please define your platform byteswap macros!
|
||||
#endif
|
||||
|
||||
+17
-15
@@ -12,7 +12,7 @@
|
||||
#endif
|
||||
#define TCPv6_MSS 1220
|
||||
|
||||
#if defined(LC_WINDOWS)
|
||||
#if defined(LC_WINDOWS) && !defined(NXDK)
|
||||
|
||||
#ifndef SIO_UDP_CONNRESET
|
||||
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR, 12)
|
||||
@@ -70,7 +70,7 @@ void shutdownTcpSocket(SOCKET s) {
|
||||
}
|
||||
|
||||
int setNonFatalRecvTimeoutMs(SOCKET s, int timeoutMs) {
|
||||
#if defined(LC_WINDOWS)
|
||||
#if defined(LC_WINDOWS) && !defined(NXDK)
|
||||
// Windows says that SO_RCVTIMEO puts the socket into an indeterminate state
|
||||
// when a timeout occurs. MSDN doesn't go into it any more than that, but it
|
||||
// seems likely that they are referring to the inability to know whether a
|
||||
@@ -93,7 +93,7 @@ int setNonFatalRecvTimeoutMs(SOCKET s, int timeoutMs) {
|
||||
}
|
||||
|
||||
int pollSockets(struct pollfd* pollFds, int pollFdsCount, int timeoutMs) {
|
||||
#if defined(LC_WINDOWS)
|
||||
#if defined(LC_WINDOWS) && !defined(NXDK)
|
||||
// We could have used WSAPoll() but it has some nasty bugs
|
||||
// https://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/
|
||||
//
|
||||
@@ -206,7 +206,7 @@ int recvUdpSocket(SOCKET s, char* buffer, int size, bool useSelect) {
|
||||
(LastSocketError() == EWOULDBLOCK ||
|
||||
LastSocketError() == EINTR ||
|
||||
LastSocketError() == EAGAIN ||
|
||||
#if defined(LC_WINDOWS)
|
||||
#if defined(LC_WINDOWS) && !defined(NXDK)
|
||||
// This error is specific to overlapped I/O which isn't even
|
||||
// possible to perform with recvfrom(). It seems to randomly
|
||||
// be returned instead of WSAETIMEDOUT on certain systems.
|
||||
@@ -221,7 +221,7 @@ int recvUdpSocket(SOCKET s, char* buffer, int size, bool useSelect) {
|
||||
// We may receive an error due to a previous ICMP Port Unreachable error received
|
||||
// by this socket. We want to ignore those and continue reading. If the remote party
|
||||
// is really dead, ENet or TCP connection failures will trigger connection teardown.
|
||||
#if defined(LC_WINDOWS)
|
||||
#if defined(LC_WINDOWS) && !defined(NXDK)
|
||||
} while (err < 0 && LastSocketError() == WSAECONNRESET);
|
||||
#else
|
||||
} while (err < 0 && LastSocketError() == ECONNREFUSED);
|
||||
@@ -231,7 +231,7 @@ int recvUdpSocket(SOCKET s, char* buffer, int size, bool useSelect) {
|
||||
}
|
||||
|
||||
void closeSocket(SOCKET s) {
|
||||
#if defined(LC_WINDOWS)
|
||||
#if defined(LC_WINDOWS) && !defined(NXDK)
|
||||
closesocket(s);
|
||||
#else
|
||||
close(s);
|
||||
@@ -335,7 +335,7 @@ SOCKET bindUdpSocket(int addressFamily, struct sockaddr_storage* localAddr, SOCK
|
||||
int val = 1;
|
||||
setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (char*)&val, sizeof(val));
|
||||
}
|
||||
#elif defined(LC_WINDOWS)
|
||||
#elif defined(LC_WINDOWS) && !defined(NXDK)
|
||||
{
|
||||
// Disable WSAECONNRESET for UDP sockets on Windows
|
||||
BOOL val = FALSE;
|
||||
@@ -409,10 +409,10 @@ int setSocketNonBlocking(SOCKET s, bool enabled) {
|
||||
#if defined(__vita__) || defined(__HAIKU__)
|
||||
int val = enabled ? 1 : 0;
|
||||
return setsockopt(s, SOL_SOCKET, SO_NONBLOCK, (char*)&val, sizeof(val));
|
||||
#elif defined(O_NONBLOCK)
|
||||
#elif defined(O_NONBLOCK) && !defined(NXDK)
|
||||
return fcntl(s, F_SETFL, (enabled ? O_NONBLOCK : 0) | (fcntl(s, F_GETFL) & ~O_NONBLOCK));
|
||||
#elif defined(FIONBIO)
|
||||
#ifdef LC_WINDOWS
|
||||
#if defined(LC_WINDOWS) && !defined(NXDK)
|
||||
u_long val = enabled ? 1 : 0;
|
||||
#else
|
||||
int val = enabled ? 1 : 0;
|
||||
@@ -452,7 +452,6 @@ SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen,
|
||||
LC_SOCKADDR addr;
|
||||
struct pollfd pfd;
|
||||
int err;
|
||||
int val;
|
||||
|
||||
// Create a non-blocking TCP socket
|
||||
s = createSocket(dstaddr->ss_family, SOCK_STREAM, IPPROTO_TCP, true);
|
||||
@@ -471,7 +470,9 @@ SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen,
|
||||
// Note: This only changes the max packet size we can *receive* from the host PC.
|
||||
// We still must split our own sends into smaller chunks with TCP_NODELAY enabled to
|
||||
// avoid MTU issues on the way out to to the target.
|
||||
#if defined(LC_WINDOWS)
|
||||
#if defined(LC_WINDOWS) && !defined(NXDK)
|
||||
int val;
|
||||
|
||||
// Windows doesn't support setting TCP_MAXSEG but IP_PMTUDISC_DONT forces the MSS to the protocol
|
||||
// minimum which is what we want here. Linux doesn't do this (disabling PMTUD just avoids setting DF).
|
||||
if (dstaddr->ss_family == AF_INET) {
|
||||
@@ -491,12 +492,13 @@ SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen,
|
||||
// restrict MSS to the minimum. It strips all options out of the SYN packet which
|
||||
// forces the remote party to fall back to the minimum MSS. TCP_MAXSEG doesn't seem
|
||||
// to work correctly for outbound connections on macOS/iOS.
|
||||
val = 1;
|
||||
int val = 1;
|
||||
if (setsockopt(s, IPPROTO_TCP, TCP_NOOPT, (char*)&val, sizeof(val)) < 0) {
|
||||
Limelog("setsockopt(TCP_NOOPT, %d) failed: %d\n", val, (int)LastSocketError());
|
||||
}
|
||||
#elif defined(TCP_MAXSEG)
|
||||
val = dstaddr->ss_family == AF_INET ? TCPv4_MSS : TCPv6_MSS;
|
||||
int val = dstaddr->ss_family == AF_INET ? TCPv4_MSS : TCPv6_MSS;
|
||||
|
||||
if (setsockopt(s, IPPROTO_TCP, TCP_MAXSEG, (char*)&val, sizeof(val)) < 0) {
|
||||
Limelog("setsockopt(TCP_MAXSEG, %d) failed: %d\n", val, (int)LastSocketError());
|
||||
}
|
||||
@@ -1004,7 +1006,7 @@ void exitLowLatencyMode(void) {
|
||||
}
|
||||
|
||||
int initializePlatformSockets(void) {
|
||||
#if defined(LC_WINDOWS)
|
||||
#if defined(LC_WINDOWS) && !defined(NXDK)
|
||||
WSADATA data;
|
||||
return WSAStartup(MAKEWORD(2, 0), &data);
|
||||
#elif defined(__vita__) || defined(__WIIU__) || defined(__3DS__)
|
||||
@@ -1027,7 +1029,7 @@ int initializePlatformSockets(void) {
|
||||
}
|
||||
|
||||
void cleanupPlatformSockets(void) {
|
||||
#if defined(LC_WINDOWS)
|
||||
#if defined(LC_WINDOWS) && !defined(NXDK)
|
||||
WSACleanup();
|
||||
#else
|
||||
#endif
|
||||
|
||||
@@ -18,7 +18,7 @@ extern in_port_t n3ds_udp_port;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(NXDK)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <wlanapi.h>
|
||||
@@ -83,7 +83,9 @@ typedef int SOCKADDR_LEN;
|
||||
#include <signal.h>
|
||||
#include <poll.h>
|
||||
|
||||
#ifndef ioctlsocket
|
||||
#define ioctlsocket ioctl
|
||||
#endif
|
||||
#define LastSocketError() errno
|
||||
#define SetLastSocketError(x) errno = x
|
||||
#define INVALID_SOCKET -1
|
||||
|
||||
+2
-2
@@ -117,7 +117,7 @@ reed_solomon_release_t reed_solomon_release_fn;
|
||||
reed_solomon_encode_t reed_solomon_encode_fn;
|
||||
reed_solomon_decode_t reed_solomon_decode_fn;
|
||||
|
||||
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64))
|
||||
#if defined(_MSC_VER) && !defined(NXDK) && (defined(_M_IX86) || defined(_M_AMD64))
|
||||
|
||||
#if defined(_M_AMD64)
|
||||
// For some reason this is needed to avoid a "C1189 No target architecture" error from winnt.h
|
||||
@@ -135,7 +135,7 @@ reed_solomon_decode_t reed_solomon_decode_fn;
|
||||
* @details The streaming code will directly invoke these function pointers during encoding.
|
||||
*/
|
||||
void reed_solomon_init(void) {
|
||||
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64))
|
||||
#if defined(_MSC_VER) && !defined(NXDK) && (defined(_M_IX86) || defined(_M_AMD64))
|
||||
// Visual Studio
|
||||
if (_msc_supports_avx512f()) {
|
||||
reed_solomon_new_fn = reed_solomon_new_avx512;
|
||||
|
||||
Reference in New Issue
Block a user