[XMP] Fixed XMP Overriding
Fixed cutscene audio in 58411446 Co-Authored-By: The-Little-Wolf <116989599+the-little-wolf@users.noreply.github.com>
This commit is contained in:
@@ -68,20 +68,28 @@ class AudioMediaPlayer {
|
||||
}
|
||||
XmpApp::PlaybackFlags GetPlaybackFlags() const { return playback_flags_; }
|
||||
|
||||
void SetPlaybackClient(XmpApp::PlaybackClient playback_client) {
|
||||
if (playback_client == XmpApp::PlaybackClient::kSystem) {
|
||||
return;
|
||||
}
|
||||
void SetXMPOverride(bool xmp_override) { xmp_override_ = xmp_override; }
|
||||
bool IsXMPOverrideEnabled() const { return xmp_override_; }
|
||||
|
||||
playback_client_ = playback_client;
|
||||
}
|
||||
|
||||
XmpApp::PlaybackClient GetPlaybackClient() const { return playback_client_; }
|
||||
uint32_t GetDashInItState() const { return dash_init_state; }
|
||||
|
||||
void SetXMPClient(XMP_CLIENT xmp_client) { xmp_client_ = xmp_client; }
|
||||
|
||||
void SetPlaybackController(PlaybackController playback_controller) {
|
||||
playback_controller_ = playback_controller;
|
||||
}
|
||||
|
||||
PlaybackController GetPlaybackController() const {
|
||||
return playback_controller_;
|
||||
}
|
||||
|
||||
XMP_CLIENT GetXMPClient() const { return xmp_client_; }
|
||||
|
||||
bool IsTitleInPlaybackControl() const {
|
||||
return playback_client_ == XmpApp::PlaybackClient::kTitle ||
|
||||
is_title_rendering_enabled_;
|
||||
const bool game_control = xmp_client_ == XMP_CLIENT::Game &&
|
||||
playback_controller_ == PlaybackController::Game;
|
||||
|
||||
return game_control || xmp_override_ || is_title_rendering_enabled_;
|
||||
}
|
||||
|
||||
void SetCaptureCallback(uint32_t callback, uint32_t context,
|
||||
@@ -102,10 +110,12 @@ class AudioMediaPlayer {
|
||||
std::span<uint8_t> LoadSongToMemory();
|
||||
|
||||
XmpApp::State state_ = XmpApp::State::kIdle;
|
||||
XmpApp::PlaybackClient playback_client_ = XmpApp::PlaybackClient::kSystem;
|
||||
bool xmp_override_ = false;
|
||||
XmpApp::PlaybackMode playback_mode_ = XmpApp::PlaybackMode::kInOrder;
|
||||
XmpApp::RepeatMode repeat_mode_ = XmpApp::RepeatMode::kPlaylist;
|
||||
XmpApp::PlaybackFlags playback_flags_ = XmpApp::PlaybackFlags::kDefault;
|
||||
PlaybackController playback_controller_ = PlaybackController::Game;
|
||||
XMP_CLIENT xmp_client_ = XMP_CLIENT::Game;
|
||||
std::atomic<float> volume_ = 0.0f;
|
||||
uint32_t dash_init_state = 0;
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ X_HRESULT XmpApp::XMPCreateTitlePlaylist(
|
||||
memory_->TranslateVirtual(song_descriptor[i].genre_ptr));
|
||||
song->track_number = song_descriptor[i].track_number;
|
||||
song->duration_ms = song_descriptor[i].duration;
|
||||
song->format = static_cast<Song::Format>(
|
||||
song->format = static_cast<SongFormat>(
|
||||
xe::byte_swap<uint32_t>(song_descriptor[i].song_format));
|
||||
|
||||
if (out_song_handles) {
|
||||
@@ -148,25 +148,24 @@ X_HRESULT XmpApp::XMPPrevious() {
|
||||
return X_E_SUCCESS;
|
||||
}
|
||||
|
||||
X_HRESULT XmpApp::XMPGetTitlePlaylistBufferSize(uint32_t xmp_client,
|
||||
X_HRESULT XmpApp::XMPGetTitlePlaylistBufferSize(apu::XMP_CLIENT xmp_client,
|
||||
uint32_t song_count,
|
||||
uint32_t size_ptr) {
|
||||
/* Note:
|
||||
- Query of size for XamAlloc - the result of the alloc is passed to
|
||||
0x0007000D.
|
||||
- xmp_client can range from 0 - 6 but will fail on 1 and set size to zero
|
||||
if its anything other than 0 or 2.
|
||||
*/
|
||||
XELOGD(
|
||||
"XMPGetTitlePlaylistBufferSize(XMP client: 0x{:08X}, Song count: "
|
||||
"0x{:08X}, Size ptr: 0x{:08X})",
|
||||
xmp_client, song_count, size_ptr);
|
||||
uint32_t(xmp_client), song_count, size_ptr);
|
||||
|
||||
if (xmp_client == 1 || !size_ptr || !song_count) {
|
||||
if (xmp_client == apu::XMP_CLIENT::HUD || !size_ptr || !song_count) {
|
||||
return X_E_INVALIDARG;
|
||||
}
|
||||
uint32_t size = 0;
|
||||
if (xmp_client == 0 || xmp_client == 2) {
|
||||
if (xmp_client == apu::XMP_CLIENT::Dash ||
|
||||
xmp_client == apu::XMP_CLIENT::Game) {
|
||||
size = song_count * 0x3E8 + 0x88;
|
||||
}
|
||||
// We don't use the storage, so just fudge the number.
|
||||
@@ -186,37 +185,41 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
reinterpret_cast<XMP_PLAY_TITLE_PLAYLIST*>(buffer);
|
||||
uint32_t playlist_handle = xe::load_and_swap<uint32_t>(
|
||||
memory_->TranslateVirtual(args->storage_ptr));
|
||||
assert_true(args->xmp_client == 0x00000002);
|
||||
assert_true(args->xmp_client == apu::XMP_CLIENT::Game);
|
||||
return XMPPlayTitlePlaylist(playlist_handle, args->song_handle);
|
||||
}
|
||||
case 0x00070003: {
|
||||
assert_true(!buffer_length || buffer_length == 4);
|
||||
uint32_t xmp_client = xe::load_and_swap<uint32_t>(buffer + 0);
|
||||
assert_true(xmp_client == 0x00000002);
|
||||
apu::XMP_CLIENT xmp_client =
|
||||
static_cast<apu::XMP_CLIENT>(xe::load_and_swap<uint32_t>(buffer));
|
||||
assert_true(xmp_client == apu::XMP_CLIENT::Game);
|
||||
return XMPContinue();
|
||||
}
|
||||
case 0x00070004: {
|
||||
assert_true(!buffer_length || buffer_length == sizeof(XMP_STOP));
|
||||
XMP_STOP* args = reinterpret_cast<XMP_STOP*>(buffer);
|
||||
assert_true(args->xmp_client == 0x00000002);
|
||||
return XMPStop(args->unk);
|
||||
assert_true(args->xmp_client == apu::XMP_CLIENT::Game);
|
||||
return XMPStop(args->allow_restart);
|
||||
}
|
||||
case 0x00070005: {
|
||||
assert_true(!buffer_length || buffer_length == 4);
|
||||
uint32_t xmp_client = xe::load_and_swap<uint32_t>(buffer + 0);
|
||||
assert_true(xmp_client == 0x00000002);
|
||||
apu::XMP_CLIENT xmp_client =
|
||||
static_cast<apu::XMP_CLIENT>(xe::load_and_swap<uint32_t>(buffer));
|
||||
assert_true(xmp_client == apu::XMP_CLIENT::Game);
|
||||
return XMPPause();
|
||||
}
|
||||
case 0x00070006: {
|
||||
assert_true(!buffer_length || buffer_length == 4);
|
||||
uint32_t xmp_client = xe::load_and_swap<uint32_t>(buffer + 0);
|
||||
assert_true(xmp_client == 0x00000002);
|
||||
apu::XMP_CLIENT xmp_client =
|
||||
static_cast<apu::XMP_CLIENT>(xe::load_and_swap<uint32_t>(buffer));
|
||||
assert_true(xmp_client == apu::XMP_CLIENT::Game);
|
||||
return XMPNext();
|
||||
}
|
||||
case 0x00070007: {
|
||||
assert_true(!buffer_length || buffer_length == 4);
|
||||
uint32_t xmp_client = xe::load_and_swap<uint32_t>(buffer + 0);
|
||||
assert_true(xmp_client == 0x00000002);
|
||||
apu::XMP_CLIENT xmp_client =
|
||||
static_cast<apu::XMP_CLIENT>(xe::load_and_swap<uint32_t>(buffer));
|
||||
assert_true(xmp_client == apu::XMP_CLIENT::Game);
|
||||
return XMPPrevious();
|
||||
}
|
||||
case 0x00070008: {
|
||||
@@ -230,10 +233,10 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
XMP_SET_PLAYBACK_BEHAVIOR* args =
|
||||
reinterpret_cast<XMP_SET_PLAYBACK_BEHAVIOR*>(buffer);
|
||||
|
||||
assert_true(args->xmp_client == 0x00000002 ||
|
||||
args->xmp_client == 0x00000000);
|
||||
assert_true(args->xmp_client == apu::XMP_CLIENT::Game ||
|
||||
args->xmp_client == apu::XMP_CLIENT::Dash);
|
||||
XELOGD("XMPSetPlaybackBehavior({:08X}, {:08X}, {:08X}, {:08X})",
|
||||
uint32_t(args->xmp_client), uint32_t(args->playback_mode),
|
||||
uint32_t(args->xmp_client.get()), uint32_t(args->playback_mode),
|
||||
uint32_t(args->repeat_mode), uint32_t(args->flags));
|
||||
|
||||
kernel_state_->emulator()->audio_media_player()->SetPlaybackMode(
|
||||
@@ -250,14 +253,14 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
case 0x00070009: {
|
||||
assert_true(!buffer_length || buffer_length == sizeof(XMP_GET_STATUS));
|
||||
XMP_GET_STATUS* args = reinterpret_cast<XMP_GET_STATUS*>(buffer);
|
||||
assert_true(args->xmp_client == 0x00000002);
|
||||
assert_true(args->xmp_client == apu::XMP_CLIENT::Game);
|
||||
return XMPGetStatus(args->state_ptr);
|
||||
}
|
||||
case 0x0007000B: {
|
||||
assert_true(!buffer_length || buffer_length == sizeof(XMP_GET_VOLUME));
|
||||
XMP_GET_VOLUME* args = reinterpret_cast<XMP_GET_VOLUME*>(buffer);
|
||||
|
||||
assert_true(args->xmp_client == 0x00000002);
|
||||
assert_true(args->xmp_client == apu::XMP_CLIENT::Game);
|
||||
XELOGD("XMPGetVolume({:08X})", uint32_t(args->volume_ptr));
|
||||
|
||||
xe::store_and_swap<float>(
|
||||
@@ -269,8 +272,8 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
assert_true(!buffer_length || buffer_length == sizeof(XMP_SET_VOLUME));
|
||||
XMP_SET_VOLUME* args = reinterpret_cast<XMP_SET_VOLUME*>(buffer);
|
||||
|
||||
assert_true(args->xmp_client == 0x00000002);
|
||||
XELOGD("XMPSetVolume({:d}, {:g})", args->xmp_client.get(),
|
||||
assert_true(args->xmp_client == apu::XMP_CLIENT::Game);
|
||||
XELOGD("XMPSetVolume({:d}, {:g})", uint32_t(args->xmp_client.get()),
|
||||
float(args->value));
|
||||
kernel_state_->emulator()->audio_media_player()->SetVolume(
|
||||
float(args->value));
|
||||
@@ -285,8 +288,8 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
xe::store_and_swap<uint32_t>(
|
||||
memory_->TranslateVirtual(args->playlist_handle_ptr),
|
||||
args->storage_ptr);
|
||||
assert_true(args->xmp_client == 0x00000002 ||
|
||||
args->xmp_client == 0x00000000);
|
||||
assert_true(args->xmp_client == apu::XMP_CLIENT::Game ||
|
||||
args->xmp_client == apu::XMP_CLIENT::Dash);
|
||||
std::u16string playlist_name;
|
||||
if (!args->playlist_name_ptr) {
|
||||
playlist_name = u"";
|
||||
@@ -307,7 +310,7 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
reinterpret_cast<XMP_GET_CURRENT_SONG*>(buffer);
|
||||
|
||||
auto info = memory_->TranslateVirtual<XMP_SONGINFO*>(args->info_ptr);
|
||||
assert_true(args->xmp_client == 0x00000002);
|
||||
assert_true(args->xmp_client == apu::XMP_CLIENT::Game);
|
||||
assert_zero(args->unk_ptr);
|
||||
XELOGD("XMPGetCurrentSong({:08X}, {:08X})", uint32_t(args->unk_ptr),
|
||||
uint32_t(args->info_ptr));
|
||||
@@ -341,8 +344,8 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
|
||||
uint32_t playlist_handle = xe::load_and_swap<uint32_t>(
|
||||
memory_->TranslateVirtual(args->storage_ptr));
|
||||
assert_true(args->xmp_client == 0x00000002 ||
|
||||
args->xmp_client == 0x00000000);
|
||||
assert_true(args->xmp_client == apu::XMP_CLIENT::Game ||
|
||||
args->xmp_client == apu::XMP_CLIENT::Dash);
|
||||
return XMPDeleteTitlePlaylist(playlist_handle);
|
||||
}
|
||||
case 0x0007001A: {
|
||||
@@ -352,21 +355,45 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
XMP_SET_PLAYBACK_CONTROLLER* args =
|
||||
reinterpret_cast<XMP_SET_PLAYBACK_CONTROLLER*>(buffer);
|
||||
|
||||
assert_true(
|
||||
(args->xmp_client == 0x00000002 && args->controller == 0x00000000) ||
|
||||
(args->xmp_client == 0x00000000 && args->controller == 0x00000001));
|
||||
const bool XMP_User_Dash =
|
||||
args->xmp_client == apu::XMP_CLIENT::Dash &&
|
||||
args->playback_controller_request == apu::PlaybackController::User;
|
||||
const bool XMPOverrideBackgroundMusic =
|
||||
args->xmp_client == apu::XMP_CLIENT::Game &&
|
||||
args->playback_controller_request == apu::PlaybackController::Game;
|
||||
const bool XMPRestoreBackgroundMusic =
|
||||
args->xmp_client == apu::XMP_CLIENT::Game &&
|
||||
args->playback_controller_request == apu::PlaybackController::Restore;
|
||||
|
||||
assert_true(XMPOverrideBackgroundMusic || XMPRestoreBackgroundMusic ||
|
||||
XMP_User_Dash);
|
||||
|
||||
XELOGD("XMPSetPlaybackController({:08X}, {:08X}, {:08X})",
|
||||
uint32_t(args->xmp_client), uint32_t(args->controller),
|
||||
uint32_t(args->playback_client));
|
||||
uint32_t(args->xmp_client.get()),
|
||||
uint32_t(args->playback_controller_request.get()),
|
||||
uint32_t(args->playback_controller_locked));
|
||||
|
||||
kernel_state_->emulator()->audio_media_player()->SetPlaybackClient(
|
||||
PlaybackClient(uint32_t(args->playback_client)));
|
||||
auto media_player = kernel_state_->emulator()->audio_media_player();
|
||||
|
||||
if (args->playback_controller_request ==
|
||||
apu::PlaybackController::Restore) {
|
||||
media_player->SetXMPClient(apu::XMP_CLIENT::Game);
|
||||
media_player->SetPlaybackController(apu::PlaybackController::Game);
|
||||
} else {
|
||||
media_player->SetXMPClient(args->xmp_client);
|
||||
media_player->SetPlaybackController(
|
||||
args->playback_controller_request.get());
|
||||
}
|
||||
|
||||
media_player->SetXMPOverride(args->playback_controller_locked.get());
|
||||
|
||||
// 58411446
|
||||
kernel_state_->BroadcastNotification(
|
||||
kXNotificationXmpPlaybackControllerChanged,
|
||||
kernel_state_->emulator()
|
||||
->audio_media_player()
|
||||
->IsTitleInPlaybackControl());
|
||||
media_player->IsXMPOverrideEnabled()
|
||||
? false
|
||||
: media_player->IsTitleInPlaybackControl());
|
||||
|
||||
return X_E_SUCCESS;
|
||||
}
|
||||
case 0x0007001B: {
|
||||
@@ -376,20 +403,36 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
XMP_GET_PLAYBACK_CONTROLLER* args =
|
||||
reinterpret_cast<XMP_GET_PLAYBACK_CONTROLLER*>(buffer);
|
||||
|
||||
assert_true(args->xmp_client == 0x00000002);
|
||||
assert_true(args->xmp_client == apu::XMP_CLIENT::Game);
|
||||
XELOGD("XMPGetPlaybackController({:08X}, {:08X}, {:08X})",
|
||||
uint32_t(args->xmp_client), uint32_t(args->controller_ptr),
|
||||
uint32_t(args->locked_ptr));
|
||||
xe::store_and_swap<uint32_t>(
|
||||
memory_->TranslateVirtual(args->controller_ptr), 0);
|
||||
xe::store_and_swap<uint32_t>(memory_->TranslateVirtual(args->locked_ptr),
|
||||
0);
|
||||
uint32_t(args->xmp_client.get()),
|
||||
uint32_t(args->playback_controller_ptr),
|
||||
uint32_t(args->playback_controller_locked_ptr));
|
||||
|
||||
const auto media_player = kernel_state_->emulator()->audio_media_player();
|
||||
|
||||
xe::be<apu::PlaybackController>* controller =
|
||||
memory_->TranslateVirtual<xe::be<apu::PlaybackController>*>(
|
||||
args->playback_controller_ptr);
|
||||
|
||||
*controller = media_player->GetPlaybackController();
|
||||
|
||||
xe::be<uint32_t>* playback_controller_locked =
|
||||
memory_->TranslateVirtual<xe::be<uint32_t>*>(
|
||||
args->playback_controller_locked_ptr);
|
||||
|
||||
*playback_controller_locked = !media_player->IsTitleInPlaybackControl();
|
||||
|
||||
if (!XThread::GetCurrentThread()->main_thread()) {
|
||||
// Atrain spawns a thread 82437FD0 to call this in a tight loop forever.
|
||||
xe::threading::Sleep(std::chrono::milliseconds(10));
|
||||
}
|
||||
|
||||
// Assert if game is not in control of playback.
|
||||
assert_true(media_player->GetPlaybackController() ==
|
||||
apu::PlaybackController::Game);
|
||||
assert_zero(!media_player->IsTitleInPlaybackControl());
|
||||
|
||||
return X_E_SUCCESS;
|
||||
}
|
||||
case 0x00070025: {
|
||||
@@ -402,7 +445,7 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
reinterpret_cast<XMP_CREATE_USER_PLAYLIST_ENUMERATOR*>(buffer);
|
||||
|
||||
XELOGD("XMPCreateUserPlaylistEnumerator({:08X}, {:08X}, {:08X})",
|
||||
uint32_t(args->xmp_client), uint32_t(args->flags),
|
||||
uint32_t(args->xmp_client.get()), uint32_t(args->flags),
|
||||
uint32_t(args->object_ptr));
|
||||
return X_E_SUCCESS;
|
||||
}
|
||||
@@ -413,11 +456,11 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
XMP_GET_PLAYBACK_BEHAVIOR* args =
|
||||
reinterpret_cast<XMP_GET_PLAYBACK_BEHAVIOR*>(buffer);
|
||||
|
||||
assert_true(args->xmp_client == 0x00000002 ||
|
||||
args->xmp_client == 0x00000000);
|
||||
assert_true(args->xmp_client == apu::XMP_CLIENT::Game ||
|
||||
args->xmp_client == apu::XMP_CLIENT::Dash);
|
||||
XELOGD("XMPGetPlaybackBehavior({:08X}, {:08X}, {:08X}, {:08X})",
|
||||
uint32_t(args->xmp_client), uint32_t(args->playback_mode_ptr),
|
||||
uint32_t(args->repeat_mode_ptr),
|
||||
uint32_t(args->xmp_client.get()),
|
||||
uint32_t(args->playback_mode_ptr), uint32_t(args->repeat_mode_ptr),
|
||||
uint32_t(args->playback_flags_ptr));
|
||||
if (args->playback_mode_ptr) {
|
||||
xe::store_and_swap<uint32_t>(
|
||||
@@ -451,13 +494,15 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
XMP_GET_MEDIA_SOURCES* args =
|
||||
reinterpret_cast<XMP_GET_MEDIA_SOURCES*>(buffer);
|
||||
|
||||
assert_true(args->xmp_client == 0x00000002 ||
|
||||
args->xmp_client == 0x00000000);
|
||||
assert_true(args->xmp_client == apu::XMP_CLIENT::Game ||
|
||||
args->xmp_client == apu::XMP_CLIENT::Dash);
|
||||
XELOGD(
|
||||
"XMPGetMediaSources({:08X}, {:08X}, {:08X}, {:08X}, {:08X}), "
|
||||
"unimplemented",
|
||||
args->xmp_client.get(), args->unk1.get(), args->unk1_ptr.get(),
|
||||
args->unk2.get(), args->unk2_ptr.get());
|
||||
uint32_t(args->xmp_client.get()),
|
||||
args->get_connected_sources_only.get(),
|
||||
args->media_resources_ptr.get(), args->max_source.get(),
|
||||
args->sources_returned_ptr.get());
|
||||
return X_E_INVALIDARG;
|
||||
}
|
||||
case 0x0007002E: {
|
||||
@@ -474,12 +519,12 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
assert_true(!buffer_length || buffer_length == sizeof(XMP_DASH_INIT));
|
||||
XMP_DASH_INIT* args = reinterpret_cast<XMP_DASH_INIT*>(buffer);
|
||||
|
||||
assert_true(args->xmp_client == 0x00000002 ||
|
||||
args->xmp_client == 0x00000000);
|
||||
assert_true(args->xmp_client == apu::XMP_CLIENT::Game ||
|
||||
args->xmp_client == apu::XMP_CLIENT::Dash);
|
||||
XELOGD(
|
||||
"XMPDashInIt({:08X}, {:08X}, {:08X}, {:08X}, {:08X}, {:08X}), "
|
||||
"unimplemented",
|
||||
args->xmp_client.get(), args->buffer_ptr.get(),
|
||||
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;
|
||||
@@ -491,8 +536,8 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
XMP_CAPTURE_OUTPUT* args = reinterpret_cast<XMP_CAPTURE_OUTPUT*>(buffer);
|
||||
|
||||
XELOGD("XMPCaptureOutput({:08X}, {:08X}, {:08X}, {:08X})",
|
||||
args->xmp_client.get(), args->callback.get(), args->context.get(),
|
||||
args->title_render.get());
|
||||
uint32_t(args->xmp_client.get()), args->callback.get(),
|
||||
args->context.get(), args->title_render.get());
|
||||
kernel_state_->emulator()->audio_media_player()->SetCaptureCallback(
|
||||
args->callback, args->context, static_cast<bool>(args->title_render));
|
||||
return X_E_SUCCESS;
|
||||
@@ -507,14 +552,14 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
XMP_SET_MEDIA_SOURCE_WORKSPACE* args =
|
||||
reinterpret_cast<XMP_SET_MEDIA_SOURCE_WORKSPACE*>(buffer);
|
||||
|
||||
assert_true(args->xmp_client == 0x00000002 ||
|
||||
args->xmp_client == 0x00000001 ||
|
||||
args->xmp_client == 0x00000000);
|
||||
assert_true(args->xmp_client == apu::XMP_CLIENT::Game ||
|
||||
args->xmp_client == apu::XMP_CLIENT::HUD ||
|
||||
args->xmp_client == apu::XMP_CLIENT::Dash);
|
||||
XELOGD(
|
||||
"XMPSetMediaSourceWorkspace({:08X}, {:08X}, {:08X}, {:08X}), "
|
||||
"unimplemented",
|
||||
args->xmp_client.get(), args->unk1.get(), args->storage_ptr.get(),
|
||||
args->unk2.get());
|
||||
uint32_t(args->xmp_client.get()), args->unk1.get(),
|
||||
args->storage_ptr.get(), args->unk2.get());
|
||||
return X_E_INVALIDARG;
|
||||
}
|
||||
case 0x00070053: {
|
||||
@@ -522,8 +567,8 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
// 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})", args->xmp_client.get(),
|
||||
args->dash_init_state_ptr.get());
|
||||
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),
|
||||
|
||||
@@ -13,6 +13,28 @@
|
||||
#include "xenia/kernel/kernel_state.h"
|
||||
#include "xenia/kernel/xam/app_manager.h"
|
||||
|
||||
namespace xe {
|
||||
namespace apu {
|
||||
enum class XMP_CLIENT : uint32_t {
|
||||
Dash,
|
||||
HUD,
|
||||
Game,
|
||||
Remote,
|
||||
MusicPlayer,
|
||||
MSAL,
|
||||
MCE,
|
||||
};
|
||||
|
||||
enum class PlaybackController : uint32_t {
|
||||
Game,
|
||||
User,
|
||||
Dash,
|
||||
MCE,
|
||||
Restore,
|
||||
};
|
||||
} // namespace apu
|
||||
} // namespace xe
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xam {
|
||||
@@ -53,20 +75,20 @@ struct XMP_SONGINFO {
|
||||
static_assert_size(XMP_SONGINFO, 0x3E0);
|
||||
|
||||
struct XMP_PLAY_TITLE_PLAYLIST {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> storage_ptr;
|
||||
xe::be<uint32_t> song_handle;
|
||||
};
|
||||
static_assert_size(XMP_PLAY_TITLE_PLAYLIST, 0xC);
|
||||
|
||||
struct XMP_STOP {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<uint32_t> unk;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> allow_restart;
|
||||
};
|
||||
static_assert_size(XMP_STOP, 0x8);
|
||||
|
||||
struct XMP_SET_PLAYBACK_BEHAVIOR {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> playback_mode;
|
||||
xe::be<uint32_t> repeat_mode;
|
||||
xe::be<uint32_t> flags;
|
||||
@@ -74,25 +96,25 @@ struct XMP_SET_PLAYBACK_BEHAVIOR {
|
||||
static_assert_size(XMP_SET_PLAYBACK_BEHAVIOR, 0x10);
|
||||
|
||||
struct XMP_GET_STATUS {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> state_ptr;
|
||||
};
|
||||
static_assert_size(XMP_GET_STATUS, 0x8);
|
||||
|
||||
struct XMP_GET_VOLUME {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> volume_ptr;
|
||||
};
|
||||
static_assert_size(XMP_GET_VOLUME, 0x8);
|
||||
|
||||
struct XMP_SET_VOLUME {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<float> value;
|
||||
};
|
||||
static_assert_size(XMP_SET_VOLUME, 0x8);
|
||||
|
||||
struct XMP_CREATE_TITLE_PLAYLIST {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> storage_ptr;
|
||||
xe::be<uint32_t> storage_size;
|
||||
xe::be<uint32_t> songs_ptr;
|
||||
@@ -105,41 +127,41 @@ struct XMP_CREATE_TITLE_PLAYLIST {
|
||||
static_assert_size(XMP_CREATE_TITLE_PLAYLIST, 0x24);
|
||||
|
||||
struct XMP_GET_CURRENT_SONG {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> unk_ptr;
|
||||
xe::be<uint32_t> info_ptr;
|
||||
};
|
||||
static_assert_size(XMP_GET_CURRENT_SONG, 0xC);
|
||||
|
||||
struct XMP_DELETE_TITLE_PLAYLIST {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> storage_ptr;
|
||||
};
|
||||
static_assert_size(XMP_DELETE_TITLE_PLAYLIST, 0x8);
|
||||
|
||||
struct XMP_SET_PLAYBACK_CONTROLLER {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<uint32_t> controller;
|
||||
xe::be<uint32_t> playback_client;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<apu::PlaybackController> playback_controller_request;
|
||||
xe::be<uint32_t> playback_controller_locked;
|
||||
};
|
||||
static_assert_size(XMP_SET_PLAYBACK_CONTROLLER, 0xC);
|
||||
|
||||
struct XMP_GET_PLAYBACK_CONTROLLER {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<uint32_t> controller_ptr;
|
||||
xe::be<uint32_t> locked_ptr;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> playback_controller_ptr;
|
||||
xe::be<uint32_t> playback_controller_locked_ptr;
|
||||
};
|
||||
static_assert_size(XMP_GET_PLAYBACK_CONTROLLER, 0xC);
|
||||
|
||||
struct XMP_CREATE_USER_PLAYLIST_ENUMERATOR {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> flags;
|
||||
xe::be<uint32_t> object_ptr;
|
||||
};
|
||||
static_assert_size(XMP_CREATE_USER_PLAYLIST_ENUMERATOR, 0xC);
|
||||
|
||||
struct XMP_GET_PLAYBACK_BEHAVIOR {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> playback_mode_ptr;
|
||||
xe::be<uint32_t> repeat_mode_ptr;
|
||||
xe::be<uint32_t> playback_flags_ptr;
|
||||
@@ -147,23 +169,23 @@ struct XMP_GET_PLAYBACK_BEHAVIOR {
|
||||
static_assert_size(XMP_GET_PLAYBACK_BEHAVIOR, 0x10);
|
||||
|
||||
struct XMP_GET_MEDIA_SOURCES {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<uint32_t> unk1;
|
||||
xe::be<uint32_t> unk1_ptr;
|
||||
xe::be<uint32_t> unk2;
|
||||
xe::be<uint32_t> unk2_ptr;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> get_connected_sources_only;
|
||||
xe::be<uint32_t> media_resources_ptr; // *MSAL_MEDIASOURCEINFO
|
||||
xe::be<uint32_t> max_source;
|
||||
xe::be<uint32_t> sources_returned_ptr;
|
||||
};
|
||||
static_assert_size(XMP_GET_MEDIA_SOURCES, 0x14);
|
||||
|
||||
struct XMP_GET_TITLE_PLAYLIST_BUFFER_SIZE {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> song_count;
|
||||
xe::be<uint32_t> size_ptr;
|
||||
};
|
||||
static_assert_size(XMP_GET_TITLE_PLAYLIST_BUFFER_SIZE, 0xC);
|
||||
|
||||
struct XMP_DASH_INIT {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> buffer_ptr; // used by XamEnumerate
|
||||
xe::be<uint32_t> buffer_length; // used by XamEnumerate
|
||||
xe::be<uint32_t> unk1;
|
||||
@@ -173,7 +195,7 @@ struct XMP_DASH_INIT {
|
||||
static_assert_size(XMP_DASH_INIT, 0x18);
|
||||
|
||||
struct XMP_CAPTURE_OUTPUT {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> callback;
|
||||
xe::be<uint32_t> context;
|
||||
xe::be<uint32_t> title_render;
|
||||
@@ -181,7 +203,7 @@ struct XMP_CAPTURE_OUTPUT {
|
||||
static_assert_size(XMP_CAPTURE_OUTPUT, 0x10);
|
||||
|
||||
struct XMP_SET_MEDIA_SOURCE_WORKSPACE {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> unk1;
|
||||
xe::be<uint32_t> storage_ptr;
|
||||
xe::be<uint32_t> unk2;
|
||||
@@ -189,7 +211,7 @@ struct XMP_SET_MEDIA_SOURCE_WORKSPACE {
|
||||
static_assert_size(XMP_SET_MEDIA_SOURCE_WORKSPACE, 0x10);
|
||||
|
||||
struct XMP_GET_DASH_INIT_STATE {
|
||||
xe::be<uint32_t> xmp_client;
|
||||
xe::be<apu::XMP_CLIENT> xmp_client;
|
||||
xe::be<uint32_t> dash_init_state_ptr;
|
||||
};
|
||||
static_assert_size(XMP_GET_DASH_INIT_STATE, 0x8);
|
||||
@@ -201,10 +223,6 @@ class XmpApp : public App {
|
||||
kPlaying = 1,
|
||||
kPaused = 2,
|
||||
};
|
||||
enum class PlaybackClient : uint32_t {
|
||||
kSystem = 0,
|
||||
kTitle = 1,
|
||||
};
|
||||
enum class PlaybackMode : uint32_t {
|
||||
kInOrder = 0,
|
||||
kShuffle = 1,
|
||||
@@ -217,12 +235,12 @@ class XmpApp : public App {
|
||||
kDefault = 0,
|
||||
kAutoPause = 1,
|
||||
};
|
||||
struct Song {
|
||||
enum class Format : uint32_t {
|
||||
kWma = 0,
|
||||
kMp3 = 1,
|
||||
};
|
||||
enum class SongFormat : uint32_t {
|
||||
kWma = 0,
|
||||
kMp3 = 1,
|
||||
};
|
||||
|
||||
struct Song {
|
||||
uint32_t handle;
|
||||
std::u16string file_path;
|
||||
std::u16string name;
|
||||
@@ -232,7 +250,7 @@ class XmpApp : public App {
|
||||
std::u16string genre;
|
||||
uint32_t track_number;
|
||||
uint32_t duration_ms;
|
||||
Format format;
|
||||
SongFormat format;
|
||||
};
|
||||
struct Playlist {
|
||||
uint32_t handle;
|
||||
@@ -258,7 +276,7 @@ class XmpApp : public App {
|
||||
X_HRESULT XMPPause();
|
||||
X_HRESULT XMPNext();
|
||||
X_HRESULT XMPPrevious();
|
||||
X_HRESULT XMPGetTitlePlaylistBufferSize(uint32_t xmp_client,
|
||||
X_HRESULT XMPGetTitlePlaylistBufferSize(apu::XMP_CLIENT xmp_client,
|
||||
uint32_t song_count,
|
||||
uint32_t storage_ptr);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user