diff --git a/src/xenia/apu/audio_media_player.h b/src/xenia/apu/audio_media_player.h index 86f183883..43fe8f664 100644 --- a/src/xenia/apu/audio_media_player.h +++ b/src/xenia/apu/audio_media_player.h @@ -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; } diff --git a/src/xenia/kernel/xam/apps/xmp_app.cc b/src/xenia/kernel/xam/apps/xmp_app.cc index 7fe79e88b..5534215fa 100644 --- a/src/xenia/kernel/xam/apps/xmp_app.cc +++ b/src/xenia/kernel/xam/apps/xmp_app.cc @@ -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( + 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( + args->media_resources_ptr.get() + (i * 0xB4)); + + std::memset(entry, 0x0, 0x28); + *entry = xe::byte_swap(i); + } + + // We're returning 0 which means there is no source of media available. + *kernel_state_->memory()->TranslateVirtual( + 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(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(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( 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; } } diff --git a/src/xenia/kernel/xam/apps/xmp_app.h b/src/xenia/kernel/xam/apps/xmp_app.h index d3e0070d2..a2b2dab58 100644 --- a/src/xenia/kernel/xam/apps/xmp_app.h +++ b/src/xenia/kernel/xam/apps/xmp_app.h @@ -204,9 +204,9 @@ static_assert_size(XMP_CAPTURE_OUTPUT, 0x10); struct XMP_SET_MEDIA_SOURCE_WORKSPACE { xe::be xmp_client; - xe::be unk1; + xe::be workspace_type; xe::be storage_ptr; - xe::be unk2; + xe::be storage_length; }; static_assert_size(XMP_SET_MEDIA_SOURCE_WORKSPACE, 0x10); diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 99c1f84e9..9240f5e6f 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -275,7 +275,7 @@ enum : XNotificationID { kXNotificationXmpTitlePlayListContentChanged = 0x8A000005, kXNotificationXmpLocalMediaContentChanged = 0x8A000006, kXNotificationXmpDashNowPlayingQueueModeChanged = 0x8A000007, - kXNotificationXmpDashInItChanged = 0x8A000009, + kXNotificationXmpDashInitChanged = 0x8A000009, kXNotificationXmpPlaybackBehaviorChangedEx = 0x8A00000A, // XNotification Party