[XAM] Stubbed XMPCreateUserPlaylistEnumerator
Fixed 545408C0 freezing at main menu.
This commit is contained in:
@@ -329,6 +329,17 @@ enum class UserContextDevice : uint32_t {
|
||||
Microphone = 4,
|
||||
};
|
||||
|
||||
constexpr uint32_t XMP_MAX_METADATA_STRING = 40;
|
||||
constexpr uint32_t XMP_MAX_USER_PLAYLIST_ID = 572;
|
||||
constexpr uint32_t XMP_USER_PLAYLIST_RESERVED_FIELD_SIZE = 168;
|
||||
|
||||
struct XMP_USER_PLAYLIST_INFO {
|
||||
uint8_t id[XMP_MAX_USER_PLAYLIST_ID];
|
||||
xe::be<char16_t> title[XMP_MAX_METADATA_STRING];
|
||||
uint8_t reserved[XMP_USER_PLAYLIST_RESERVED_FIELD_SIZE];
|
||||
};
|
||||
static_assert_size(XMP_USER_PLAYLIST_INFO, 0x334);
|
||||
|
||||
} // namespace xam
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
@@ -79,20 +79,63 @@ dword_result_t XamEnumerate_entry(dword_t handle, dword_t flags,
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XamEnumerate, kNone, kImplemented);
|
||||
|
||||
dword_result_t XamCreateEnumeratorHandle_entry(
|
||||
dword_t user_index, dword_t app_id, dword_t open_message,
|
||||
dword_t close_message, dword_t extra_size, dword_t item_count,
|
||||
dword_t flags, lpdword_t out_handle) {
|
||||
auto e = object_ref<XStaticUntypedEnumerator>(
|
||||
new XStaticUntypedEnumerator(kernel_state(), item_count, extra_size));
|
||||
static uint32_t XMPCreateUserPlaylistEnumeratorHandle(
|
||||
uint32_t user_index, uint32_t app_id, uint32_t open_message,
|
||||
uint32_t close_message, uint32_t extra_size, uint32_t item_count,
|
||||
uint32_t flags, uint32_t& out_enum_handle) {
|
||||
auto e = object_ref<XMPCreateUserPlaylistEnumerator>(
|
||||
new XMPCreateUserPlaylistEnumerator(kernel_state(), item_count));
|
||||
|
||||
auto result = e->Initialize(user_index, app_id, open_message, close_message,
|
||||
flags, extra_size, nullptr);
|
||||
|
||||
if (XFAILED(result)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
*out_handle = e->handle();
|
||||
std::vector<xam::XMP_USER_PLAYLIST_INFO> user_playlist_info = {};
|
||||
|
||||
for (const auto& playlist_info : user_playlist_info) {
|
||||
e->AppendItem(playlist_info);
|
||||
}
|
||||
|
||||
XELOGI("{}: added {} items to enumerator", __func__, e->item_count());
|
||||
|
||||
out_enum_handle = e->handle();
|
||||
return X_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
constexpr uint32_t XMPCreateUserPlaylistEnumeratorMessage = 0x70026;
|
||||
|
||||
dword_result_t XamCreateEnumeratorHandle_entry(
|
||||
dword_t user_index, dword_t app_id, dword_t open_message,
|
||||
dword_t close_message, dword_t extra_size, dword_t item_count,
|
||||
dword_t flags, lpdword_t out_handle) {
|
||||
uint32_t enum_handle = 0;
|
||||
X_STATUS result = 0;
|
||||
|
||||
switch (open_message) {
|
||||
case XMPCreateUserPlaylistEnumeratorMessage: {
|
||||
result = XMPCreateUserPlaylistEnumeratorHandle(
|
||||
user_index, app_id, open_message, close_message, extra_size,
|
||||
item_count, flags, enum_handle);
|
||||
} break;
|
||||
default: {
|
||||
auto e = object_ref<XStaticUntypedEnumerator>(
|
||||
new XStaticUntypedEnumerator(kernel_state(), item_count, extra_size));
|
||||
|
||||
result = e->Initialize(user_index, app_id, open_message, close_message,
|
||||
flags, extra_size, nullptr);
|
||||
enum_handle = e->handle();
|
||||
} break;
|
||||
}
|
||||
|
||||
if (XFAILED(result)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
*out_handle = enum_handle;
|
||||
|
||||
return X_ERROR_SUCCESS;
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XamCreateEnumeratorHandle, kNone, kImplemented);
|
||||
|
||||
@@ -40,6 +40,8 @@ X_STATUS XEnumerator::Initialize(uint32_t user_index, uint32_t app_id,
|
||||
*extra_buffer =
|
||||
!extra_buffer ? nullptr : &native_object[sizeof(X_KENUMERATOR)];
|
||||
}
|
||||
|
||||
extra_size_ = extra_size;
|
||||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -175,5 +177,31 @@ uint32_t XUserStatsEnumerator::WriteItems(uint32_t buffer_ptr,
|
||||
return X_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t XMPCreateUserPlaylistEnumerator::WriteItems(uint32_t buffer_ptr,
|
||||
uint8_t* buffer_data,
|
||||
uint32_t* written_count) {
|
||||
// Fixed 545408C0 freezing at main menu.
|
||||
std::memset(buffer_data, 0, extra_size());
|
||||
|
||||
size_t count = std::min(items_.size() - current_item_, items_per_enumerate());
|
||||
if (!count) {
|
||||
return X_ERROR_NO_MORE_FILES;
|
||||
}
|
||||
|
||||
xam::XMP_USER_PLAYLIST_INFO* results =
|
||||
reinterpret_cast<xam::XMP_USER_PLAYLIST_INFO*>(buffer_data);
|
||||
|
||||
for (size_t i = 0, o = current_item_; i < count; ++i, ++current_item_) {
|
||||
const auto& item = items_[current_item_];
|
||||
results[i] = item;
|
||||
}
|
||||
|
||||
if (written_count) {
|
||||
*written_count = static_cast<uint32_t>(count);
|
||||
}
|
||||
|
||||
return X_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "xenia/kernel/xam/achievement_manager.h"
|
||||
#include "xenia/kernel/xam/user_tracker.h"
|
||||
#include "xenia/kernel/xam/xam.h"
|
||||
#include "xenia/kernel/xobject.h"
|
||||
|
||||
namespace xe {
|
||||
@@ -89,10 +90,12 @@ class XEnumerator : public XObject {
|
||||
|
||||
size_t item_size() const { return item_size_; }
|
||||
size_t items_per_enumerate() const { return items_per_enumerate_; }
|
||||
size_t extra_size() const { return extra_size_; }
|
||||
|
||||
private:
|
||||
size_t items_per_enumerate_;
|
||||
size_t item_size_;
|
||||
size_t extra_size_;
|
||||
};
|
||||
|
||||
class XStaticUntypedEnumerator : public XEnumerator {
|
||||
@@ -219,6 +222,26 @@ class XUserStatsEnumerator : public XEnumerator {
|
||||
size_t current_item_ = 0;
|
||||
};
|
||||
|
||||
class XMPCreateUserPlaylistEnumerator : public XEnumerator {
|
||||
public:
|
||||
XMPCreateUserPlaylistEnumerator(KernelState* kernel_state,
|
||||
size_t items_per_enumerate)
|
||||
: XEnumerator(kernel_state, items_per_enumerate, 0) {}
|
||||
|
||||
size_t item_count() const { return items_.size(); }
|
||||
|
||||
void AppendItem(const xam::XMP_USER_PLAYLIST_INFO& item) {
|
||||
items_.push_back(item);
|
||||
}
|
||||
|
||||
uint32_t WriteItems(uint32_t buffer_ptr, uint8_t* buffer_data,
|
||||
uint32_t* written_count) override;
|
||||
|
||||
private:
|
||||
std::vector<xam::XMP_USER_PLAYLIST_INFO> items_;
|
||||
size_t current_item_ = 0;
|
||||
};
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
Reference in New Issue
Block a user