Testing travis xenia powerpc testing
This commit is contained in:
parent
8947a7626e
commit
b66f10f2b8
|
@ -14,8 +14,7 @@ os:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- LLVM_VERSION=3.8.0
|
|
||||||
- LLVM_ARCHIVE_PATH=$HOME/clang+llvm.tar.xz
|
|
||||||
|
|
||||||
dist: trusty
|
dist: trusty
|
||||||
sudo: required
|
sudo: required
|
||||||
|
@ -52,6 +51,9 @@ script:
|
||||||
# Build and run our simple hello world test.
|
# Build and run our simple hello world test.
|
||||||
- ./xenia-build build --config=debug --target=xenia-base-tests
|
- ./xenia-build build --config=debug --target=xenia-base-tests
|
||||||
- ./build/bin/Linux/Debug/xenia-base-tests
|
- ./build/bin/Linux/Debug/xenia-base-tests
|
||||||
|
# Build and run ppc tests
|
||||||
|
- ./xenia-build build --config=debug --target=xenia-cpu-ppc-tests
|
||||||
|
- ./build/bin/Linux/Debug/xenia-cpu-ppc-tests
|
||||||
|
|
||||||
# TODO(DrChat): Enable builds in the future.
|
# TODO(DrChat): Enable builds in the future.
|
||||||
# Build all of xenia.
|
# Build all of xenia.
|
||||||
|
|
|
@ -76,6 +76,9 @@ filter("platforms:Linux")
|
||||||
buildoptions({
|
buildoptions({
|
||||||
"-mlzcnt", -- Assume lzcnt supported.
|
"-mlzcnt", -- Assume lzcnt supported.
|
||||||
})
|
})
|
||||||
|
links({
|
||||||
|
"pthread",
|
||||||
|
})
|
||||||
|
|
||||||
filter({"platforms:Linux", "language:C++"})
|
filter({"platforms:Linux", "language:C++"})
|
||||||
buildoptions({
|
buildoptions({
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include "xenia/cpu/ppc/ppc_context.h"
|
#include "xenia/cpu/ppc/ppc_context.h"
|
||||||
#include "xenia/cpu/ppc/ppc_hir_builder.h"
|
#include "xenia/cpu/ppc/ppc_hir_builder.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace ppc {
|
namespace ppc {
|
||||||
|
|
|
@ -35,3 +35,6 @@ project("xenia-cpu-ppc-tests")
|
||||||
"2>&1",
|
"2>&1",
|
||||||
"1>scratch/stdout-testing.txt",
|
"1>scratch/stdout-testing.txt",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
-- xenia-base needs this
|
||||||
|
links({"xenia-ui"})
|
||||||
|
|
|
@ -13,5 +13,6 @@ test_suite("xenia-cpu-tests", project_root, ".", {
|
||||||
|
|
||||||
-- TODO(benvanik): cut these dependencies?
|
-- TODO(benvanik): cut these dependencies?
|
||||||
"xenia-kernel",
|
"xenia-kernel",
|
||||||
|
"xenia-ui", -- needed by xenia-base
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -49,10 +49,10 @@ class GraphicsSystem {
|
||||||
return command_processor_.get();
|
return command_processor_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeRingBuffer(uint32_t ptr, uint32_t log2_size);
|
virtual void InitializeRingBuffer(uint32_t ptr, uint32_t log2_size);
|
||||||
void EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size);
|
virtual void EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size);
|
||||||
|
|
||||||
void SetInterruptCallback(uint32_t callback, uint32_t user_data);
|
virtual void SetInterruptCallback(uint32_t callback, uint32_t user_data);
|
||||||
void DispatchInterruptCallback(uint32_t source, uint32_t cpu);
|
void DispatchInterruptCallback(uint32_t source, uint32_t cpu);
|
||||||
|
|
||||||
virtual void ClearCaches();
|
virtual void ClearCaches();
|
||||||
|
|
|
@ -126,6 +126,9 @@ uint32_t KernelModule::GetProcAddressByOrdinal(uint16_t ordinal) {
|
||||||
uint32_t guest_addr =
|
uint32_t guest_addr =
|
||||||
GenerateTrampoline(export_entry->name, handler, export_entry);
|
GenerateTrampoline(export_entry->name, handler, export_entry);
|
||||||
|
|
||||||
|
XELOGD("GetProcAddressByOrdinal(\"%s\", \"%s\") = %.8X", name().c_str(),
|
||||||
|
export_entry->name, guest_addr);
|
||||||
|
|
||||||
// Register the function in our map.
|
// Register the function in our map.
|
||||||
guest_trampoline_map_[ordinal] = guest_addr;
|
guest_trampoline_map_[ordinal] = guest_addr;
|
||||||
return guest_addr;
|
return guest_addr;
|
||||||
|
|
|
@ -10,9 +10,7 @@ project("xenia-kernel")
|
||||||
"xenia-apu",
|
"xenia-apu",
|
||||||
"xenia-base",
|
"xenia-base",
|
||||||
"xenia-cpu",
|
"xenia-cpu",
|
||||||
"xenia-gpu",
|
|
||||||
"xenia-hid",
|
"xenia-hid",
|
||||||
"xenia-ui",
|
|
||||||
"xenia-vfs",
|
"xenia-vfs",
|
||||||
})
|
})
|
||||||
defines({
|
defines({
|
||||||
|
|
|
@ -108,7 +108,7 @@ X_STATUS UserModule::LoadFromMemory(const void* addr, const size_t length) {
|
||||||
module_format_ = kModuleFormatElf;
|
module_format_ = kModuleFormatElf;
|
||||||
} else {
|
} else {
|
||||||
auto magic16 = xe::load_and_swap<uint16_t>(addr);
|
auto magic16 = xe::load_and_swap<uint16_t>(addr);
|
||||||
if (magic16 == 'MZ') {
|
if (magic16 == 0x4D5A) {
|
||||||
XELOGE("XNA executables are not yet implemented");
|
XELOGE("XNA executables are not yet implemented");
|
||||||
return X_STATUS_NOT_IMPLEMENTED;
|
return X_STATUS_NOT_IMPLEMENTED;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -22,9 +22,16 @@
|
||||||
#include "xenia/kernel/xthread.h"
|
#include "xenia/kernel/xthread.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
|
#ifdef XE_PLATFORM_WIN32
|
||||||
// NOTE: must be included last as it expects windows.h to already be included.
|
// NOTE: must be included last as it expects windows.h to already be included.
|
||||||
#define _WINSOCK_DEPRECATED_NO_WARNINGS // inet_addr
|
#define _WINSOCK_DEPRECATED_NO_WARNINGS // inet_addr
|
||||||
#include <winsock2.h> // NOLINT(build/include_order)
|
#include <winsock2.h> // NOLINT(build/include_order)
|
||||||
|
#elif XE_PLATFORM_LINUX
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/ip.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
@ -43,8 +50,8 @@ enum {
|
||||||
// https://github.com/pmrowla/hl2sdk-csgo/blob/master/common/xbox/xboxstubs.h
|
// https://github.com/pmrowla/hl2sdk-csgo/blob/master/common/xbox/xboxstubs.h
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// FYI: IN_ADDR should be in network-byte order.
|
// FYI: IN_ADDR should be in network-byte order.
|
||||||
IN_ADDR ina; // IP address (zero if not static/DHCP)
|
in_addr ina; // IP address (zero if not static/DHCP)
|
||||||
IN_ADDR inaOnline; // Online IP address (zero if not online)
|
in_addr inaOnline; // Online IP address (zero if not online)
|
||||||
xe::be<uint16_t> wPortOnline; // Online port
|
xe::be<uint16_t> wPortOnline; // Online port
|
||||||
uint8_t abEnet[6]; // Ethernet MAC address
|
uint8_t abEnet[6]; // Ethernet MAC address
|
||||||
uint8_t abOnline[20]; // Online identification
|
uint8_t abOnline[20]; // Online identification
|
||||||
|
@ -53,7 +60,7 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
xe::be<int32_t> status;
|
xe::be<int32_t> status;
|
||||||
xe::be<uint32_t> cina;
|
xe::be<uint32_t> cina;
|
||||||
IN_ADDR aina[8];
|
in_addr aina[8];
|
||||||
} XNDNS;
|
} XNDNS;
|
||||||
|
|
||||||
struct Xsockaddr_t {
|
struct Xsockaddr_t {
|
||||||
|
@ -96,7 +103,7 @@ void LoadSockaddr(const uint8_t* ptr, sockaddr* out_addr) {
|
||||||
auto in_addr = reinterpret_cast<sockaddr_in*>(out_addr);
|
auto in_addr = reinterpret_cast<sockaddr_in*>(out_addr);
|
||||||
in_addr->sin_port = xe::load_and_swap<uint16_t>(ptr + 2);
|
in_addr->sin_port = xe::load_and_swap<uint16_t>(ptr + 2);
|
||||||
// Maybe? Depends on type.
|
// Maybe? Depends on type.
|
||||||
in_addr->sin_addr.S_un.S_addr = *(uint32_t*)(ptr + 4);
|
in_addr->sin_addr.s_addr = *(uint32_t*)(ptr + 4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -115,7 +122,7 @@ void StoreSockaddr(const sockaddr& addr, uint8_t* ptr) {
|
||||||
xe::store_and_swap<uint16_t>(ptr + 0, in_addr.sin_family);
|
xe::store_and_swap<uint16_t>(ptr + 0, in_addr.sin_family);
|
||||||
xe::store_and_swap<uint16_t>(ptr + 2, in_addr.sin_port);
|
xe::store_and_swap<uint16_t>(ptr + 2, in_addr.sin_port);
|
||||||
// Maybe? Depends on type.
|
// Maybe? Depends on type.
|
||||||
xe::store_and_swap<uint32_t>(ptr + 4, in_addr.sin_addr.S_un.S_addr);
|
xe::store_and_swap<uint32_t>(ptr + 4, in_addr.sin_addr.s_addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -126,19 +133,19 @@ void StoreSockaddr(const sockaddr& addr, uint8_t* ptr) {
|
||||||
|
|
||||||
// https://github.com/joolswills/mameox/blob/master/MAMEoX/Sources/xbox_Network.cpp#L136
|
// https://github.com/joolswills/mameox/blob/master/MAMEoX/Sources/xbox_Network.cpp#L136
|
||||||
struct XNetStartupParams {
|
struct XNetStartupParams {
|
||||||
BYTE cfgSizeOfStruct;
|
uint8_t cfgSizeOfStruct;
|
||||||
BYTE cfgFlags;
|
uint8_t cfgFlags;
|
||||||
BYTE cfgSockMaxDgramSockets;
|
uint8_t cfgSockMaxDgramSockets;
|
||||||
BYTE cfgSockMaxStreamSockets;
|
uint8_t cfgSockMaxStreamSockets;
|
||||||
BYTE cfgSockDefaultRecvBufsizeInK;
|
uint8_t cfgSockDefaultRecvBufsizeInK;
|
||||||
BYTE cfgSockDefaultSendBufsizeInK;
|
uint8_t cfgSockDefaultSendBufsizeInK;
|
||||||
BYTE cfgKeyRegMax;
|
uint8_t cfgKeyRegMax;
|
||||||
BYTE cfgSecRegMax;
|
uint8_t cfgSecRegMax;
|
||||||
BYTE cfgQosDataLimitDiv4;
|
uint8_t cfgQosDataLimitDiv4;
|
||||||
BYTE cfgQosProbeTimeoutInSeconds;
|
uint8_t cfgQosProbeTimeoutInSeconds;
|
||||||
BYTE cfgQosProbeRetries;
|
uint8_t cfgQosProbeRetries;
|
||||||
BYTE cfgQosSrvMaxSimultaneousResponses;
|
uint8_t cfgQosSrvMaxSimultaneousResponses;
|
||||||
BYTE cfgQosPairWaitTimeInSeconds;
|
uint8_t cfgQosPairWaitTimeInSeconds;
|
||||||
};
|
};
|
||||||
|
|
||||||
XNetStartupParams xnet_startup_params = {0};
|
XNetStartupParams xnet_startup_params = {0};
|
||||||
|
@ -186,13 +193,13 @@ dword_result_t NetDll_XNetGetOpt(dword_t one, dword_t option_id,
|
||||||
case 1:
|
case 1:
|
||||||
if (*buffer_size < sizeof(XNetStartupParams)) {
|
if (*buffer_size < sizeof(XNetStartupParams)) {
|
||||||
*buffer_size = sizeof(XNetStartupParams);
|
*buffer_size = sizeof(XNetStartupParams);
|
||||||
return WSAEMSGSIZE;
|
return 0x2738; // WSAEMSGSIZE
|
||||||
}
|
}
|
||||||
std::memcpy(buffer_ptr, &xnet_startup_params, sizeof(XNetStartupParams));
|
std::memcpy(buffer_ptr, &xnet_startup_params, sizeof(XNetStartupParams));
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
XELOGE("NetDll_XNetGetOpt: option %d unimplemented", option_id);
|
XELOGE("NetDll_XNetGetOpt: option %d unimplemented", option_id);
|
||||||
return WSAEINVAL;
|
return 0x2726; // WSAEINVAL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DECLARE_XAM_EXPORT(NetDll_XNetGetOpt, ExportTag::kNetworking);
|
DECLARE_XAM_EXPORT(NetDll_XNetGetOpt, ExportTag::kNetworking);
|
||||||
|
@ -210,7 +217,8 @@ DECLARE_XAM_EXPORT(NetDll_XNetRandom,
|
||||||
|
|
||||||
dword_result_t NetDll_WSAStartup(dword_t caller, word_t version,
|
dword_result_t NetDll_WSAStartup(dword_t caller, word_t version,
|
||||||
pointer_t<X_WSADATA> data_ptr) {
|
pointer_t<X_WSADATA> data_ptr) {
|
||||||
// TODO(benvanik): abstraction layer needed.
|
// TODO(benvanik): abstraction layer needed.
|
||||||
|
#ifdef XE_PLATFORM_WIN32
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
ZeroMemory(&wsaData, sizeof(WSADATA));
|
ZeroMemory(&wsaData, sizeof(WSADATA));
|
||||||
int ret = WSAStartup(version, &wsaData);
|
int ret = WSAStartup(version, &wsaData);
|
||||||
|
@ -230,6 +238,17 @@ dword_result_t NetDll_WSAStartup(dword_t caller, word_t version,
|
||||||
uint32_t vendor_ptr = xe::load_and_swap<uint32_t>(data_out + 0x190);
|
uint32_t vendor_ptr = xe::load_and_swap<uint32_t>(data_out + 0x190);
|
||||||
xe::store_and_swap<uint32_t>(data_out + 0x190, vendor_ptr);
|
xe::store_and_swap<uint32_t>(data_out + 0x190, vendor_ptr);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
int ret = 0;
|
||||||
|
if (data_ptr) {
|
||||||
|
// Guess these values!
|
||||||
|
data_ptr->version = version.value();
|
||||||
|
data_ptr->description[0] = '\0';
|
||||||
|
data_ptr->system_status[0] = '\0';
|
||||||
|
data_ptr->max_sockets = 100;
|
||||||
|
data_ptr->max_udpdg = 1024;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
/*
|
/*
|
||||||
|
@ -425,8 +444,8 @@ dword_result_t NetDll_XNetGetTitleXnAddr(dword_t caller,
|
||||||
pointer_t<XNADDR> addr_ptr) {
|
pointer_t<XNADDR> addr_ptr) {
|
||||||
// Just return a loopback address atm.
|
// Just return a loopback address atm.
|
||||||
// FIXME: This needs to return the ethernet MAC address!
|
// FIXME: This needs to return the ethernet MAC address!
|
||||||
addr_ptr->ina.S_un.S_addr = htonl(INADDR_LOOPBACK);
|
addr_ptr->ina.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
addr_ptr->inaOnline.S_un.S_addr = 0;
|
addr_ptr->inaOnline.s_addr = 0;
|
||||||
addr_ptr->wPortOnline = 0;
|
addr_ptr->wPortOnline = 0;
|
||||||
std::memset(addr_ptr->abEnet, 0, 6);
|
std::memset(addr_ptr->abEnet, 0, 6);
|
||||||
std::memset(addr_ptr->abOnline, 0, 20);
|
std::memset(addr_ptr->abOnline, 0, 20);
|
||||||
|
@ -610,9 +629,13 @@ int_result_t NetDll_shutdown(dword_t caller, dword_t socket_handle, int_t how) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ret = socket->Shutdown(how);
|
auto ret = socket->Shutdown(how);
|
||||||
if (ret == SOCKET_ERROR) {
|
if (ret == -1) {
|
||||||
|
#ifdef XE_PLATFORM_WIN32
|
||||||
uint32_t error_code = WSAGetLastError();
|
uint32_t error_code = WSAGetLastError();
|
||||||
XThread::SetLastError(error_code);
|
XThread::SetLastError(error_code);
|
||||||
|
#else
|
||||||
|
XThread::SetLastError(0x0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -726,6 +749,12 @@ DECLARE_XAM_EXPORT(NetDll_listen,
|
||||||
dword_result_t NetDll_accept(dword_t caller, dword_t socket_handle,
|
dword_result_t NetDll_accept(dword_t caller, dword_t socket_handle,
|
||||||
pointer_t<XSOCKADDR> addr_ptr,
|
pointer_t<XSOCKADDR> addr_ptr,
|
||||||
lpdword_t addrlen_ptr) {
|
lpdword_t addrlen_ptr) {
|
||||||
|
if (!addr_ptr) {
|
||||||
|
// WSAEFAULT
|
||||||
|
XThread::SetLastError(0x271E);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
auto socket =
|
auto socket =
|
||||||
kernel_state()->object_table()->LookupObject<XSocket>(socket_handle);
|
kernel_state()->object_table()->LookupObject<XSocket>(socket_handle);
|
||||||
if (!socket) {
|
if (!socket) {
|
||||||
|
@ -889,7 +918,7 @@ dword_result_t NetDll_recvfrom(dword_t caller, dword_t socket_handle,
|
||||||
if (from_ptr) {
|
if (from_ptr) {
|
||||||
native_from = *from_ptr;
|
native_from = *from_ptr;
|
||||||
}
|
}
|
||||||
uint32_t native_fromlen = fromlen_ptr ? *fromlen_ptr : 0;
|
uint32_t native_fromlen = fromlen_ptr ? fromlen_ptr.value() : 0;
|
||||||
int ret = socket->RecvFrom(buf_ptr, buf_len, flags, &native_from,
|
int ret = socket->RecvFrom(buf_ptr, buf_len, flags, &native_from,
|
||||||
fromlen_ptr ? &native_fromlen : 0);
|
fromlen_ptr ? &native_fromlen : 0);
|
||||||
|
|
||||||
|
@ -904,9 +933,13 @@ dword_result_t NetDll_recvfrom(dword_t caller, dword_t socket_handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
// TODO: Better way of getting the error code
|
// TODO: Better way of getting the error code
|
||||||
|
#ifdef XE_PLATFORM_WIN32
|
||||||
uint32_t error_code = WSAGetLastError();
|
uint32_t error_code = WSAGetLastError();
|
||||||
XThread::SetLastError(error_code);
|
XThread::SetLastError(error_code);
|
||||||
|
#else
|
||||||
|
XThread::SetLastError(0x0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -79,7 +79,7 @@ dword_result_t NtAllocateVirtualMemory(lpdword_t base_addr_ptr,
|
||||||
// it's simple today we could extend it to do better things in the future.
|
// it's simple today we could extend it to do better things in the future.
|
||||||
|
|
||||||
// Must request a size.
|
// Must request a size.
|
||||||
if (!base_addr_ptr) {
|
if (!base_addr_ptr || !region_size_ptr) {
|
||||||
return X_STATUS_INVALID_PARAMETER;
|
return X_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
// Check allocation type.
|
// Check allocation type.
|
||||||
|
@ -106,8 +106,8 @@ dword_result_t NtAllocateVirtualMemory(lpdword_t base_addr_ptr,
|
||||||
uint32_t adjusted_base = *base_addr_ptr - (*base_addr_ptr % page_size);
|
uint32_t adjusted_base = *base_addr_ptr - (*base_addr_ptr % page_size);
|
||||||
// For some reason, some games pass in negative sizes.
|
// For some reason, some games pass in negative sizes.
|
||||||
uint32_t adjusted_size = int32_t(*region_size_ptr) < 0
|
uint32_t adjusted_size = int32_t(*region_size_ptr) < 0
|
||||||
? -int32_t(*region_size_ptr)
|
? -int32_t(region_size_ptr.value())
|
||||||
: *region_size_ptr;
|
: region_size_ptr.value();
|
||||||
adjusted_size = xe::round_up(adjusted_size, page_size);
|
adjusted_size = xe::round_up(adjusted_size, page_size);
|
||||||
|
|
||||||
// Allocate.
|
// Allocate.
|
||||||
|
|
|
@ -238,7 +238,7 @@ dword_result_t RtlMultiByteToUnicodeN(lpword_t destination_ptr,
|
||||||
pointer_t<uint8_t> source_ptr,
|
pointer_t<uint8_t> source_ptr,
|
||||||
dword_t source_len) {
|
dword_t source_len) {
|
||||||
uint32_t copy_len = destination_len >> 1;
|
uint32_t copy_len = destination_len >> 1;
|
||||||
copy_len = copy_len < source_len ? copy_len : source_len;
|
copy_len = copy_len < source_len ? copy_len : source_len.value();
|
||||||
|
|
||||||
// TODO(benvanik): maybe use MultiByteToUnicode on Win32? would require
|
// TODO(benvanik): maybe use MultiByteToUnicode on Win32? would require
|
||||||
// swapping.
|
// swapping.
|
||||||
|
@ -262,7 +262,7 @@ dword_result_t RtlUnicodeToMultiByteN(pointer_t<uint8_t> destination_ptr,
|
||||||
lpdword_t written_ptr,
|
lpdword_t written_ptr,
|
||||||
lpword_t source_ptr, dword_t source_len) {
|
lpword_t source_ptr, dword_t source_len) {
|
||||||
uint32_t copy_len = source_len >> 1;
|
uint32_t copy_len = source_len >> 1;
|
||||||
copy_len = copy_len < destination_len ? copy_len : destination_len;
|
copy_len = copy_len < destination_len ? copy_len : destination_len.value();
|
||||||
|
|
||||||
// TODO(benvanik): maybe use UnicodeToMultiByte on Win32?
|
// TODO(benvanik): maybe use UnicodeToMultiByte on Win32?
|
||||||
for (uint32_t i = 0; i < copy_len; i++) {
|
for (uint32_t i = 0; i < copy_len; i++) {
|
||||||
|
|
|
@ -14,10 +14,18 @@
|
||||||
#include "xenia/kernel/xam/xam_module.h"
|
#include "xenia/kernel/xam/xam_module.h"
|
||||||
// #include "xenia/kernel/xnet.h"
|
// #include "xenia/kernel/xnet.h"
|
||||||
|
|
||||||
#if XE_PLATFORM_WIN32
|
#ifdef XE_PLATFORM_WIN32
|
||||||
|
// clang-format off
|
||||||
|
#include "xenia/base/platform_win.h"
|
||||||
|
#include <WS2tcpip.h>
|
||||||
#include <WinSock2.h>
|
#include <WinSock2.h>
|
||||||
#elif XE_PLATFORM_LINUX
|
// clang-format on
|
||||||
#error TODO: Proper network includes
|
#else
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/ip.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
@ -54,7 +62,7 @@ X_STATUS XSocket::Close() {
|
||||||
#if XE_PLATFORM_WIN32
|
#if XE_PLATFORM_WIN32
|
||||||
int ret = closesocket(native_handle_);
|
int ret = closesocket(native_handle_);
|
||||||
#elif XE_PLATFORM_LINUX
|
#elif XE_PLATFORM_LINUX
|
||||||
|
int ret = close(native_handle_);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
@ -88,6 +96,7 @@ X_STATUS XSocket::SetOption(uint32_t level, uint32_t optname, void* optval_ptr,
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS XSocket::IOControl(uint32_t cmd, uint8_t* arg_ptr) {
|
X_STATUS XSocket::IOControl(uint32_t cmd, uint8_t* arg_ptr) {
|
||||||
|
#ifdef XE_PLATFORM_WIN32
|
||||||
int ret = ioctlsocket(native_handle_, cmd, (u_long*)arg_ptr);
|
int ret = ioctlsocket(native_handle_, cmd, (u_long*)arg_ptr);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
// TODO: Get last error
|
// TODO: Get last error
|
||||||
|
@ -95,6 +104,9 @@ X_STATUS XSocket::IOControl(uint32_t cmd, uint8_t* arg_ptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return X_STATUS_SUCCESS;
|
return X_STATUS_SUCCESS;
|
||||||
|
#elif XE_PLATFORM_LINUX
|
||||||
|
return X_STATUS_UNSUCCESSFUL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS XSocket::Connect(N_XSOCKADDR* name, int name_len) {
|
X_STATUS XSocket::Connect(N_XSOCKADDR* name, int name_len) {
|
||||||
|
@ -129,9 +141,9 @@ X_STATUS XSocket::Listen(int backlog) {
|
||||||
|
|
||||||
object_ref<XSocket> XSocket::Accept(N_XSOCKADDR* name, int* name_len) {
|
object_ref<XSocket> XSocket::Accept(N_XSOCKADDR* name, int* name_len) {
|
||||||
sockaddr n_sockaddr;
|
sockaddr n_sockaddr;
|
||||||
int n_name_len = sizeof(sockaddr);
|
socklen_t n_name_len = sizeof(sockaddr);
|
||||||
SOCKET ret = accept(native_handle_, &n_sockaddr, &n_name_len);
|
uintptr_t ret = accept(native_handle_, &n_sockaddr, &n_name_len);
|
||||||
if (ret == INVALID_SOCKET) {
|
if (ret == -1) {
|
||||||
std::memset(name, 0, *name_len);
|
std::memset(name, 0, *name_len);
|
||||||
*name_len = 0;
|
*name_len = 0;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -182,7 +194,7 @@ int XSocket::RecvFrom(uint8_t* buf, uint32_t buf_len, uint32_t flags,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sockaddr_in nfrom;
|
sockaddr_in nfrom;
|
||||||
int nfromlen = sizeof(sockaddr_in);
|
socklen_t nfromlen = sizeof(sockaddr_in);
|
||||||
int ret = recvfrom(native_handle_, reinterpret_cast<char*>(buf), buf_len,
|
int ret = recvfrom(native_handle_, reinterpret_cast<char*>(buf), buf_len,
|
||||||
flags, (sockaddr*)&nfrom, &nfromlen);
|
flags, (sockaddr*)&nfrom, &nfromlen);
|
||||||
if (from) {
|
if (from) {
|
||||||
|
@ -219,7 +231,7 @@ int XSocket::SendTo(uint8_t* buf, uint32_t buf_len, uint32_t flags,
|
||||||
|
|
||||||
sockaddr_in nto;
|
sockaddr_in nto;
|
||||||
if (to) {
|
if (to) {
|
||||||
nto.sin_addr.S_un.S_addr = to->sin_addr;
|
nto.sin_addr.s_addr = to->sin_addr;
|
||||||
nto.sin_family = to->sin_family;
|
nto.sin_family = to->sin_family;
|
||||||
nto.sin_port = to->sin_port;
|
nto.sin_port = to->sin_port;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "xenia/vfs/devices/stfs_container_file.h"
|
#include "xenia/vfs/devices/stfs_container_file.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "xenia/vfs/devices/stfs_container_entry.h"
|
#include "xenia/vfs/devices/stfs_container_entry.h"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue