[XMP] Return success for XMPGetMediaSources with 0 sources

- Renamed XMPDashInIt to XMPDashInit
- Added broadcast to XMPDashInit
- Renamed some unknown fields of XMP_SET_MEDIA_SOURCE_WORKSPACE
This commit is contained in:
Gliniak
2026-06-04 22:39:43 +02:00
committed by Radosław Gliński
parent 99fd19d025
commit 49c700b9c5
4 changed files with 47 additions and 13 deletions

View File

@@ -71,7 +71,7 @@ class AudioMediaPlayer {
void SetXMPOverride(bool xmp_override) { xmp_override_ = xmp_override; }
bool IsXMPOverrideEnabled() const { return xmp_override_; }
uint32_t GetDashInItState() const { return dash_init_state; }
uint32_t GetDashInitState() const { return dash_init_state; }
void SetXMPClient(XMP_CLIENT xmp_client) { xmp_client_ = xmp_client; }

View File

@@ -486,6 +486,7 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
return X_E_SUCCESS;
}
case 0x0007002B: {
constexpr uint8_t kMaxSourcesForMediaPlayer = 10;
// XMPGetMediaSources
// Called on the NXE and Kinect dashboard after clicking on the picture,
// video, and music library
@@ -503,7 +504,38 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
args->get_connected_sources_only.get(),
args->media_resources_ptr.get(), args->max_source.get(),
args->sources_returned_ptr.get());
return X_E_INVALIDARG;
if (!args->sources_returned_ptr) {
return X_E_INVALIDARG;
}
if (!args->media_resources_ptr) {
*kernel_state_->memory()->TranslateVirtual<uint32_t*>(
args->sources_returned_ptr.get()) = kMaxSourcesForMediaPlayer;
return X_E_SUCCESS;
}
if (args->max_source.get() < kMaxSourcesForMediaPlayer) {
return 0x80070008;
}
for (uint8_t i = 0; i < kMaxSourcesForMediaPlayer; ++i) {
if (!args->get_connected_sources_only) {
// There should be some call to handle it, but we ignore it for now.
}
// Some 0xB4 struct, but no idea what it is.
auto entry = kernel_state_->memory()->TranslateVirtual<uint32_t*>(
args->media_resources_ptr.get() + (i * 0xB4));
std::memset(entry, 0x0, 0x28);
*entry = xe::byte_swap<uint32_t>(i);
}
// We're returning 0 which means there is no source of media available.
*kernel_state_->memory()->TranslateVirtual<uint32_t*>(
args->sources_returned_ptr.get()) = 0x0;
return X_E_SUCCESS;
}
case 0x0007002E: {
assert_true(!buffer_length ||
@@ -514,7 +546,7 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
args->size_ptr);
}
case 0x0007002F: {
// XMPDashInIt
// XMPDashInit
// Called on the start up of all dashboard versions before kinect
assert_true(!buffer_length || buffer_length == sizeof(XMP_DASH_INIT));
XMP_DASH_INIT* args = reinterpret_cast<XMP_DASH_INIT*>(buffer);
@@ -522,12 +554,14 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
assert_true(args->xmp_client == apu::XMP_CLIENT::Game ||
args->xmp_client == apu::XMP_CLIENT::Dash);
XELOGD(
"XMPDashInIt({:08X}, {:08X}, {:08X}, {:08X}, {:08X}, {:08X}), "
"XMPDashInit({:08X}, {:08X}, {:08X}, {:08X}, {:08X}, {:08X}), "
"unimplemented",
uint32_t(args->xmp_client.get()), args->buffer_ptr.get(),
args->buffer_length.get(), args->unk1.get(), args->unk2.get(),
args->storage_ptr.get());
return X_E_INVALIDARG;
kernel_state_->BroadcastNotification(kXNotificationXmpDashInitChanged, 1);
return X_E_SUCCESS;
}
case 0x0007003D: {
// XMPCaptureOutput
@@ -558,21 +592,21 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
XELOGD(
"XMPSetMediaSourceWorkspace({:08X}, {:08X}, {:08X}, {:08X}), "
"unimplemented",
uint32_t(args->xmp_client.get()), args->unk1.get(),
args->storage_ptr.get(), args->unk2.get());
return X_E_INVALIDARG;
uint32_t(args->xmp_client.get()), args->workspace_type.get(),
args->storage_ptr.get(), args->storage_length.get());
return X_E_SUCCESS;
}
case 0x00070053: {
// Called on the blades dashboard Version 4532-5787 after clicking on the
// picture or video library. It only receives buffer
XMP_GET_DASH_INIT_STATE* args =
reinterpret_cast<XMP_GET_DASH_INIT_STATE*>(buffer);
XELOGD("XMPGetDashInItState({:08X}, {:08X})",
XELOGD("XMPGetDashInitState({:08X}, {:08X})",
uint32_t(args->xmp_client.get()), args->dash_init_state_ptr.get());
xe::store_and_swap<uint32_t>(
memory_->TranslateVirtual(args->dash_init_state_ptr),
kernel_state_->emulator()->audio_media_player()->GetDashInItState());
kernel_state_->emulator()->audio_media_player()->GetDashInitState());
return X_E_SUCCESS;
}
}

View File

@@ -204,9 +204,9 @@ static_assert_size(XMP_CAPTURE_OUTPUT, 0x10);
struct XMP_SET_MEDIA_SOURCE_WORKSPACE {
xe::be<apu::XMP_CLIENT> xmp_client;
xe::be<uint32_t> unk1;
xe::be<uint32_t> workspace_type;
xe::be<uint32_t> storage_ptr;
xe::be<uint32_t> unk2;
xe::be<uint32_t> storage_length;
};
static_assert_size(XMP_SET_MEDIA_SOURCE_WORKSPACE, 0x10);

View File

@@ -275,7 +275,7 @@ enum : XNotificationID {
kXNotificationXmpTitlePlayListContentChanged = 0x8A000005,
kXNotificationXmpLocalMediaContentChanged = 0x8A000006,
kXNotificationXmpDashNowPlayingQueueModeChanged = 0x8A000007,
kXNotificationXmpDashInItChanged = 0x8A000009,
kXNotificationXmpDashInitChanged = 0x8A000009,
kXNotificationXmpPlaybackBehaviorChangedEx = 0x8A00000A,
// XNotification Party