diff --git a/libxenia.vcxproj b/libxenia.vcxproj
index f6514e97e..8fea84eab 100644
--- a/libxenia.vcxproj
+++ b/libxenia.vcxproj
@@ -168,6 +168,7 @@
+
diff --git a/libxenia.vcxproj.filters b/libxenia.vcxproj.filters
index f5c621472..2ab1c4149 100644
--- a/libxenia.vcxproj.filters
+++ b/libxenia.vcxproj.filters
@@ -712,6 +712,9 @@
src\xenia\kernel\util
+
+ src\xenia\kernel
+
diff --git a/src/xenia/cpu/export_resolver.h b/src/xenia/cpu/export_resolver.h
index 9895f278a..b5b697023 100644
--- a/src/xenia/cpu/export_resolver.h
+++ b/src/xenia/cpu/export_resolver.h
@@ -40,6 +40,7 @@ struct ExportTag {
static const type kFileSystem = 1 << 14;
static const type kModules = 1 << 15;
static const type kUserProfiles = 1 << 16;
+ static const type kNetworking = 1 << 17;
// Export will be logged on each call.
static const type kLog = 1 << 30;
diff --git a/src/xenia/kernel/xam_module.cc b/src/xenia/kernel/xam_module.cc
index 4ec00c02a..b4fe1d72d 100644
--- a/src/xenia/kernel/xam_module.cc
+++ b/src/xenia/kernel/xam_module.cc
@@ -27,6 +27,7 @@ XamModule::XamModule(Emulator* emulator, KernelState* kernel_state)
xam::RegisterMsgExports(export_resolver_, kernel_state_);
xam::RegisterNetExports(export_resolver_, kernel_state_);
xam::RegisterNotifyExports(export_resolver_, kernel_state_);
+ xam::RegisterNuiExports(export_resolver_, kernel_state_);
xam::RegisterUIExports(export_resolver_, kernel_state_);
xam::RegisterUserExports(export_resolver_, kernel_state_);
xam::RegisterVideoExports(export_resolver_, kernel_state_);
diff --git a/src/xenia/kernel/xam_net.cc b/src/xenia/kernel/xam_net.cc
index fdd4caf7e..94aaf0876 100644
--- a/src/xenia/kernel/xam_net.cc
+++ b/src/xenia/kernel/xam_net.cc
@@ -55,21 +55,24 @@ void StoreSockaddr(const sockaddr& addr, uint8_t* ptr) {
}
}
-// typedef struct {
-// BYTE cfgSizeOfStruct;
-// BYTE cfgFlags;
-// BYTE cfgSockMaxDgramSockets;
-// BYTE cfgSockMaxStreamSockets;
-// BYTE cfgSockDefaultRecvBufsizeInK;
-// BYTE cfgSockDefaultSendBufsizeInK;
-// BYTE cfgKeyRegMax;
-// BYTE cfgSecRegMax;
-// BYTE cfgQosDataLimitDiv4;
-// BYTE cfgQosProbeTimeoutInSeconds;
-// BYTE cfgQosProbeRetries;
-// BYTE cfgQosSrvMaxSimultaneousResponses;
-// BYTE cfgQosPairWaitTimeInSeconds;
-//} XNetStartupParams;
+// https://github.com/joolswills/mameox/blob/master/MAMEoX/Sources/xbox_Network.cpp#L136
+struct XNetStartupParams {
+ BYTE cfgSizeOfStruct;
+ BYTE cfgFlags;
+ BYTE cfgSockMaxDgramSockets;
+ BYTE cfgSockMaxStreamSockets;
+ BYTE cfgSockDefaultRecvBufsizeInK;
+ BYTE cfgSockDefaultSendBufsizeInK;
+ BYTE cfgKeyRegMax;
+ BYTE cfgSecRegMax;
+ BYTE cfgQosDataLimitDiv4;
+ BYTE cfgQosProbeTimeoutInSeconds;
+ BYTE cfgQosProbeRetries;
+ BYTE cfgQosSrvMaxSimultaneousResponses;
+ BYTE cfgQosPairWaitTimeInSeconds;
+};
+
+XNetStartupParams xnet_startup_params = {0};
SHIM_CALL NetDll_XNetStartup_shim(PPCContext* ppc_context,
KernelState* kernel_state) {
@@ -78,6 +81,13 @@ SHIM_CALL NetDll_XNetStartup_shim(PPCContext* ppc_context,
XELOGD("NetDll_XNetStartup(%d, %.8X)", arg0, params_ptr);
+ if (params_ptr) {
+ auto params =
+ kernel_memory()->TranslateVirtual(params_ptr);
+ assert_true(params->cfgSizeOfStruct == sizeof(XNetStartupParams));
+ std::memcpy(&xnet_startup_params, params, sizeof(XNetStartupParams));
+ }
+
SHIM_SET_RETURN_32(0);
}
@@ -91,6 +101,24 @@ SHIM_CALL NetDll_XNetCleanup_shim(PPCContext* ppc_context,
SHIM_SET_RETURN_32(0);
}
+dword_result_t NetDll_XNetGetOpt(dword_t one, dword_t option_id,
+ lpvoid_t buffer_ptr, lpdword_t buffer_size) {
+ assert_true(one == 1);
+ switch (option_id) {
+ case 1:
+ if (*buffer_size < sizeof(XNetStartupParams)) {
+ *buffer_size = sizeof(XNetStartupParams);
+ return WSAEMSGSIZE;
+ }
+ std::memcpy(buffer_ptr, &xnet_startup_params, sizeof(XNetStartupParams));
+ return 0;
+ default:
+ XELOGE("NetDll_XNetGetOpt: option %d unimplemented", option_id);
+ return WSAEINVAL;
+ }
+}
+DECLARE_XAM_EXPORT(NetDll_XNetGetOpt, ExportTag::kNetworking);
+
SHIM_CALL NetDll_XNetRandom_shim(PPCContext* ppc_context,
KernelState* kernel_state) {
uint32_t arg0 = SHIM_GET_ARG_32(0);
diff --git a/src/xenia/kernel/xam_nui.cc b/src/xenia/kernel/xam_nui.cc
new file mode 100644
index 000000000..06cf94040
--- /dev/null
+++ b/src/xenia/kernel/xam_nui.cc
@@ -0,0 +1,40 @@
+/**
+ ******************************************************************************
+ * Xenia : Xbox 360 Emulator Research Project *
+ ******************************************************************************
+ * Copyright 2015 Ben Vanik. All rights reserved. *
+ * Released under the BSD license - see LICENSE in the root for more details. *
+ ******************************************************************************
+ */
+
+#include "xenia/base/logging.h"
+#include "xenia/emulator.h"
+#include "xenia/kernel/kernel_state.h"
+#include "xenia/kernel/util/shim_utils.h"
+#include "xenia/kernel/xam_private.h"
+#include "xenia/xbox.h"
+
+namespace xe {
+namespace kernel {
+
+struct X_NUI_DEVICE_STATUS {
+ xe::be unk0;
+ xe::be unk1;
+ xe::be unk2;
+ xe::be status;
+ xe::be unk4;
+ xe::be unk5;
+};
+static_assert(sizeof(X_NUI_DEVICE_STATUS) == 24, "Size matters");
+
+void XamNuiGetDeviceStatus(pointer_t status_ptr) {
+ status_ptr.Zero();
+ status_ptr->status = 0; // Not connected.
+}
+DECLARE_XAM_EXPORT(XamNuiGetDeviceStatus, ExportTag::kStub);
+
+} // namespace kernel
+} // namespace xe
+
+void xe::kernel::xam::RegisterNuiExports(
+ xe::cpu::ExportResolver* export_resolver, KernelState* kernel_state) {}
diff --git a/src/xenia/kernel/xam_private.h b/src/xenia/kernel/xam_private.h
index 1167f68e0..85706c4e4 100644
--- a/src/xenia/kernel/xam_private.h
+++ b/src/xenia/kernel/xam_private.h
@@ -34,6 +34,8 @@ void RegisterNetExports(xe::cpu::ExportResolver* export_resolver,
KernelState* kernel_state);
void RegisterNotifyExports(xe::cpu::ExportResolver* export_resolver,
KernelState* kernel_state);
+void RegisterNuiExports(xe::cpu::ExportResolver* export_resolver,
+ KernelState* kernel_state);
void RegisterUIExports(xe::cpu::ExportResolver* export_resolver,
KernelState* kernel_state);
void RegisterUserExports(xe::cpu::ExportResolver* export_resolver,