summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgibbed <rick@gibbed.us>2020-11-23 05:22:59 -0600
committerRick Gibbed <rick@gibbed.us>2020-11-27 14:19:30 -0600
commit42b1427087be588ea721da141280199710a5a8ff (patch)
tree6e72f5f59ff3a95dddda60d98b2a9b27b9566304
parentaf61a9764778096928245a1e3dde4b6e6b169160 (diff)
[XAM] Split enum exports to a new file.
-rw-r--r--src/xenia/kernel/xam/xam_enum.cc121
-rw-r--r--src/xenia/kernel/xam/xam_info.cc85
-rw-r--r--src/xenia/kernel/xam/xam_module.cc1
-rw-r--r--src/xenia/kernel/xam/xam_private.h1
4 files changed, 123 insertions, 85 deletions
diff --git a/src/xenia/kernel/xam/xam_enum.cc b/src/xenia/kernel/xam/xam_enum.cc
new file mode 100644
index 000000000..d52a6e55b
--- /dev/null
+++ b/src/xenia/kernel/xam/xam_enum.cc
@@ -0,0 +1,121 @@
+/**
+ ******************************************************************************
+ * Xenia : Xbox 360 Emulator Research Project *
+ ******************************************************************************
+ * Copyright 2020 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/base/string_util.h"
+#include "xenia/kernel/kernel_state.h"
+#include "xenia/kernel/user_module.h"
+#include "xenia/kernel/util/shim_utils.h"
+#include "xenia/kernel/xam/xam_module.h"
+#include "xenia/kernel/xam/xam_private.h"
+#include "xenia/kernel/xenumerator.h"
+#include "xenia/kernel/xthread.h"
+#include "xenia/xbox.h"
+
+#if XE_PLATFORM_WIN32
+#include "xenia/base/platform_win.h"
+#endif
+
+#include "third_party/fmt/include/fmt/format.h"
+
+namespace xe {
+namespace kernel {
+namespace xam {
+
+// https://github.com/LestaD/SourceEngine2007/blob/master/se2007/engine/xboxsystem.cpp#L518
+dword_result_t XamEnumerate(dword_t handle, dword_t flags, lpvoid_t buffer,
+ dword_t buffer_length, lpdword_t items_returned,
+ pointer_t<XAM_OVERLAPPED> overlapped) {
+ assert_true(flags == 0);
+
+ auto e = kernel_state()->object_table()->LookupObject<XEnumerator>(handle);
+ if (!e) {
+ if (overlapped) {
+ kernel_state()->CompleteOverlappedImmediateEx(
+ overlapped, X_ERROR_INVALID_HANDLE, X_ERROR_INVALID_HANDLE, 0);
+ return X_ERROR_IO_PENDING;
+ } else {
+ return X_ERROR_INVALID_HANDLE;
+ }
+ }
+
+ size_t actual_buffer_length = (uint32_t)buffer_length;
+ if (buffer_length == e->items_per_enumerate()) {
+ actual_buffer_length = e->item_size() * e->items_per_enumerate();
+ // Known culprits:
+ // Final Fight: Double Impact (saves)
+ XELOGW(
+ "Broken usage of XamEnumerate! buffer length={:X} vs actual "
+ "length={:X} "
+ "(item size={:X}, items per enumerate={})",
+ (uint32_t)buffer_length, actual_buffer_length, e->item_size(),
+ e->items_per_enumerate());
+ }
+
+ buffer.Zero(actual_buffer_length);
+
+ X_RESULT result;
+ uint32_t item_count = 0;
+
+ if (actual_buffer_length < e->item_size()) {
+ result = X_ERROR_INSUFFICIENT_BUFFER;
+ } else if (e->current_item() >= e->item_count()) {
+ result = X_ERROR_NO_MORE_FILES;
+ } else {
+ auto item_buffer = buffer.as<uint8_t*>();
+ auto max_items = actual_buffer_length / e->item_size();
+ while (max_items--) {
+ if (!e->WriteItem(item_buffer)) {
+ break;
+ }
+ item_buffer += e->item_size();
+ item_count++;
+ }
+ result = X_ERROR_SUCCESS;
+ }
+
+ if (items_returned) {
+ assert_true(!overlapped);
+ *items_returned = result == X_ERROR_SUCCESS ? item_count : 0;
+ return result;
+ } else if (overlapped) {
+ assert_true(!items_returned);
+ kernel_state()->CompleteOverlappedImmediateEx(
+ overlapped,
+ result == X_ERROR_SUCCESS ? X_ERROR_SUCCESS : X_ERROR_FUNCTION_FAILED,
+ X_HRESULT_FROM_WIN32(result),
+ result == X_ERROR_SUCCESS ? item_count : 0);
+ return X_ERROR_IO_PENDING;
+ } else {
+ assert_always();
+ return X_ERROR_INVALID_PARAMETER;
+ }
+}
+DECLARE_XAM_EXPORT1(XamEnumerate, kNone, kImplemented);
+
+dword_result_t XamCreateEnumeratorHandle(unknown_t unk1, unknown_t unk2,
+ unknown_t unk3, unknown_t unk4,
+ unknown_t unk5, unknown_t unk6,
+ unknown_t unk7, unknown_t unk8) {
+ return X_ERROR_INVALID_PARAMETER;
+}
+DECLARE_XAM_EXPORT1(XamCreateEnumeratorHandle, kNone, kStub);
+
+dword_result_t XamGetPrivateEnumStructureFromHandle(unknown_t unk1,
+ unknown_t unk2) {
+ return X_ERROR_INVALID_PARAMETER;
+}
+DECLARE_XAM_EXPORT1(XamGetPrivateEnumStructureFromHandle, kNone, kStub);
+
+void RegisterEnumExports(xe::cpu::ExportResolver* export_resolver,
+ KernelState* kernel_state) {}
+
+} // namespace xam
+} // namespace kernel
+} // namespace xe
diff --git a/src/xenia/kernel/xam/xam_info.cc b/src/xenia/kernel/xam/xam_info.cc
index a08ab60aa..438b8a8d0 100644
--- a/src/xenia/kernel/xam/xam_info.cc
+++ b/src/xenia/kernel/xam/xam_info.cc
@@ -337,91 +337,6 @@ dword_result_t XamFree(lpdword_t ptr) {
}
DECLARE_XAM_EXPORT1(XamFree, kMemory, kImplemented);
-// https://github.com/LestaD/SourceEngine2007/blob/master/se2007/engine/xboxsystem.cpp#L518
-dword_result_t XamEnumerate(dword_t handle, dword_t flags, lpvoid_t buffer,
- dword_t buffer_length, lpdword_t items_returned,
- pointer_t<XAM_OVERLAPPED> overlapped) {
- assert_true(flags == 0);
-
- auto e = kernel_state()->object_table()->LookupObject<XEnumerator>(handle);
- if (!e) {
- if (overlapped) {
- kernel_state()->CompleteOverlappedImmediateEx(
- overlapped, X_ERROR_INVALID_HANDLE, X_ERROR_INVALID_HANDLE, 0);
- return X_ERROR_IO_PENDING;
- } else {
- return X_ERROR_INVALID_HANDLE;
- }
- }
-
- size_t actual_buffer_length = (uint32_t)buffer_length;
- if (buffer_length == e->items_per_enumerate()) {
- actual_buffer_length = e->item_size() * e->items_per_enumerate();
- // Known culprits:
- // Final Fight: Double Impact (saves)
- XELOGW(
- "Broken usage of XamEnumerate! buffer length={:X} vs actual "
- "length={:X} "
- "(item size={:X}, items per enumerate={})",
- (uint32_t)buffer_length, actual_buffer_length, e->item_size(),
- e->items_per_enumerate());
- }
-
- buffer.Zero(actual_buffer_length);
-
- X_RESULT result;
- uint32_t item_count = 0;
-
- if (actual_buffer_length < e->item_size()) {
- result = X_ERROR_INSUFFICIENT_BUFFER;
- } else if (e->current_item() >= e->item_count()) {
- result = X_ERROR_NO_MORE_FILES;
- } else {
- auto item_buffer = buffer.as<uint8_t*>();
- auto max_items = actual_buffer_length / e->item_size();
- while (max_items--) {
- if (!e->WriteItem(item_buffer)) {
- break;
- }
- item_buffer += e->item_size();
- item_count++;
- }
- result = X_ERROR_SUCCESS;
- }
-
- if (items_returned) {
- assert_true(!overlapped);
- *items_returned = result == X_ERROR_SUCCESS ? item_count : 0;
- return result;
- } else if (overlapped) {
- assert_true(!items_returned);
- kernel_state()->CompleteOverlappedImmediateEx(
- overlapped,
- result == X_ERROR_SUCCESS ? X_ERROR_SUCCESS : X_ERROR_FUNCTION_FAILED,
- X_HRESULT_FROM_WIN32(result),
- result == X_ERROR_SUCCESS ? item_count : 0);
- return X_ERROR_IO_PENDING;
- } else {
- assert_always();
- return X_ERROR_INVALID_PARAMETER;
- }
-}
-DECLARE_XAM_EXPORT1(XamEnumerate, kNone, kImplemented);
-
-dword_result_t XamCreateEnumeratorHandle(unknown_t unk1, unknown_t unk2,
- unknown_t unk3, unknown_t unk4,
- unknown_t unk5, unknown_t unk6,
- unknown_t unk7, unknown_t unk8) {
- return X_ERROR_INVALID_PARAMETER;
-}
-DECLARE_XAM_EXPORT1(XamCreateEnumeratorHandle, kNone, kStub);
-
-dword_result_t XamGetPrivateEnumStructureFromHandle(unknown_t unk1,
- unknown_t unk2) {
- return X_ERROR_INVALID_PARAMETER;
-}
-DECLARE_XAM_EXPORT1(XamGetPrivateEnumStructureFromHandle, kNone, kStub);
-
dword_result_t XamQueryLiveHiveW(lpu16string_t name, lpvoid_t out_buf,
dword_t out_size, dword_t type /* guess */) {
return X_STATUS_INVALID_PARAMETER_1;
diff --git a/src/xenia/kernel/xam/xam_module.cc b/src/xenia/kernel/xam/xam_module.cc
index b38de2160..f3e05c56a 100644
--- a/src/xenia/kernel/xam/xam_module.cc
+++ b/src/xenia/kernel/xam/xam_module.cc
@@ -30,6 +30,7 @@ XamModule::XamModule(Emulator* emulator, KernelState* kernel_state)
// Register all exported functions.
RegisterAvatarExports(export_resolver_, kernel_state_);
RegisterContentExports(export_resolver_, kernel_state_);
+ RegisterEnumExports(export_resolver_, kernel_state_);
RegisterInfoExports(export_resolver_, kernel_state_);
RegisterInputExports(export_resolver_, kernel_state_);
RegisterLocaleExports(export_resolver_, kernel_state_);
diff --git a/src/xenia/kernel/xam/xam_private.h b/src/xenia/kernel/xam/xam_private.h
index 6006d635b..e9f256874 100644
--- a/src/xenia/kernel/xam/xam_private.h
+++ b/src/xenia/kernel/xam/xam_private.h
@@ -28,6 +28,7 @@ xe::cpu::Export* RegisterExport_xam(xe::cpu::Export* export_entry);
KernelState* kernel_state)
DECLARE_REGISTER_EXPORTS(Avatar);
DECLARE_REGISTER_EXPORTS(Content);
+DECLARE_REGISTER_EXPORTS(Enum);
DECLARE_REGISTER_EXPORTS(Info);
DECLARE_REGISTER_EXPORTS(Input);
DECLARE_REGISTER_EXPORTS(Locale);