mirror of
https://github.com/izzy2lost/xenia-edge.git
synced 2026-07-06 00:20:26 -07:00
[XAM/XMP] - XMP Improvements
- Proper returns for XMPContinue, XMPStop, XMPPause, XMPNext, XMPPrevious, and XMPSetPlaybackController - Set saved values in XMPGetPlaybackController - left notes
This commit is contained in:
committed by
Herman S.
parent
c01d6e3abb
commit
7803acc3df
@@ -79,6 +79,12 @@ class AudioMediaPlayer {
|
||||
XmpApp::PlaybackClient GetPlaybackClient() const { return playback_client_; }
|
||||
uint32_t GetDashInItState() const { return dash_init_state; }
|
||||
|
||||
void SetPlaybackController(uint32_t playback_controller) {
|
||||
playback_controller_ = playback_controller;
|
||||
}
|
||||
|
||||
uint32_t GetPlaybackController() const { return playback_controller_; }
|
||||
|
||||
bool IsTitleInPlaybackControl() const {
|
||||
return playback_client_ == XmpApp::PlaybackClient::kTitle ||
|
||||
is_title_rendering_enabled_;
|
||||
@@ -106,6 +112,7 @@ class AudioMediaPlayer {
|
||||
XmpApp::PlaybackMode playback_mode_ = XmpApp::PlaybackMode::kInOrder;
|
||||
XmpApp::RepeatMode repeat_mode_ = XmpApp::RepeatMode::kPlaylist;
|
||||
XmpApp::PlaybackFlags playback_flags_ = XmpApp::PlaybackFlags::kDefault;
|
||||
uint32_t playback_controller_ = 0;
|
||||
float volume_ = 1.0f;
|
||||
uint32_t dash_init_state = 0;
|
||||
|
||||
|
||||
@@ -117,35 +117,63 @@ X_HRESULT XmpApp::XMPPlayTitlePlaylist(uint32_t playlist_handle,
|
||||
return X_E_SUCCESS;
|
||||
}
|
||||
|
||||
X_HRESULT XmpApp::XMPContinue() {
|
||||
XELOGD("XMPContinue()");
|
||||
X_HRESULT XmpApp::XMPAccessCheck(uint32_t xmp_client) {
|
||||
/* Notes:
|
||||
- A shared function that checks xmp_client, which controller and
|
||||
playback_client is currently in xmp thread, and two unk variables held by
|
||||
xmp thread. If any fail it returns X_E_ACCESS_DENIED;
|
||||
- Used by XMPContinue, XMPStop, XMPPause, XMPNext, XMPPrevious,
|
||||
XMPPlayTitlePlaylistEx, XMPPlayUserContent, XMPPlayMediaContainer,
|
||||
XMPRestartPlayback, XMPSetVolumeEx, and XMPSetPlaybackBehaviorEx
|
||||
*/
|
||||
auto playback_client_ =
|
||||
kernel_state_->emulator()->audio_media_player()->GetPlaybackClient();
|
||||
auto controller_ =
|
||||
kernel_state_->emulator()->audio_media_player()->GetPlaybackController();
|
||||
if (xmp_client == 2 &&
|
||||
(playback_client_ != XmpApp::PlaybackClient::kSystem || controller_)) {
|
||||
return X_E_ACCESS_DENIED;
|
||||
} else if (!controller_) {
|
||||
return X_E_ACCESS_DENIED;
|
||||
}
|
||||
if (controller_ == 2 || controller_ == 3) {
|
||||
return X_E_ACCESS_DENIED;
|
||||
}
|
||||
if (xmp_client == 3 && controller_ == 1) {
|
||||
return X_E_ACCESS_DENIED;
|
||||
}
|
||||
return X_E_SUCCESS;
|
||||
}
|
||||
|
||||
X_HRESULT XmpApp::XMPContinue(uint32_t xmp_client) {
|
||||
XELOGD("XMPContinue(XMP Client: 0x{:08X})", xmp_client);
|
||||
kernel_state_->emulator()->audio_media_player()->Continue();
|
||||
return X_E_SUCCESS;
|
||||
return XMPAccessCheck(xmp_client);
|
||||
}
|
||||
|
||||
X_HRESULT XmpApp::XMPStop(uint32_t unk) {
|
||||
X_HRESULT XmpApp::XMPStop(uint32_t xmp_client, uint32_t unk) {
|
||||
assert_zero(unk);
|
||||
XELOGD("XMPStop({:08X})", unk);
|
||||
XELOGD("XMPStop(XMP Client: 0x{:08X}, Unk: 0x{:08X})", xmp_client, unk);
|
||||
kernel_state_->emulator()->audio_media_player()->Stop(true, false);
|
||||
return X_E_SUCCESS;
|
||||
return XMPAccessCheck(xmp_client);
|
||||
}
|
||||
|
||||
X_HRESULT XmpApp::XMPPause() {
|
||||
XELOGD("XMPPause()");
|
||||
X_HRESULT XmpApp::XMPPause(uint32_t xmp_client) {
|
||||
XELOGD("XMPPause(XMP Client: 0x{:08X})", xmp_client);
|
||||
kernel_state_->emulator()->audio_media_player()->Pause();
|
||||
return X_E_SUCCESS;
|
||||
return XMPAccessCheck(xmp_client);
|
||||
}
|
||||
|
||||
X_HRESULT XmpApp::XMPNext() {
|
||||
XELOGD("XMPNext()");
|
||||
X_HRESULT XmpApp::XMPNext(uint32_t xmp_client) {
|
||||
XELOGD("XMPNext(XMP Client: 0x{:08X})", xmp_client);
|
||||
kernel_state_->emulator()->audio_media_player()->Next();
|
||||
return X_E_SUCCESS;
|
||||
return XMPAccessCheck(xmp_client);
|
||||
}
|
||||
|
||||
X_HRESULT XmpApp::XMPPrevious() {
|
||||
XELOGD("XMPPrevious()");
|
||||
X_HRESULT XmpApp::XMPPrevious(uint32_t xmp_client) {
|
||||
XELOGD("XMPPrevious(XMP Client: 0x{:08X})", xmp_client);
|
||||
kernel_state_->emulator()->audio_media_player()->Previous();
|
||||
return X_E_SUCCESS;
|
||||
return XMPAccessCheck(xmp_client);
|
||||
}
|
||||
|
||||
X_HRESULT XmpApp::XMPGetTitlePlaylistBufferSize(uint32_t xmp_client,
|
||||
@@ -177,6 +205,7 @@ X_HRESULT XmpApp::XMPGetTitlePlaylistBufferSize(uint32_t xmp_client,
|
||||
X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
uint32_t buffer_length) {
|
||||
// NOTE: buffer_length may be zero or valid.
|
||||
// TODO: Allow for message_ids to set extended error, only a few set length.
|
||||
auto buffer = memory_->TranslateVirtual(buffer_ptr);
|
||||
switch (message) {
|
||||
case 0x00070002: {
|
||||
@@ -191,33 +220,28 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
}
|
||||
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);
|
||||
return XMPContinue();
|
||||
uint32_t xmp_client = xe::load_and_swap<uint32_t>(buffer);
|
||||
return XMPContinue(xmp_client);
|
||||
}
|
||||
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);
|
||||
return XMPStop(args->xmp_client, args->unk);
|
||||
}
|
||||
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);
|
||||
return XMPPause();
|
||||
uint32_t xmp_client = xe::load_and_swap<uint32_t>(buffer);
|
||||
return XMPPause(xmp_client);
|
||||
}
|
||||
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);
|
||||
return XMPNext();
|
||||
uint32_t xmp_client = xe::load_and_swap<uint32_t>(buffer);
|
||||
return XMPNext(xmp_client);
|
||||
}
|
||||
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);
|
||||
return XMPPrevious();
|
||||
uint32_t xmp_client = xe::load_and_swap<uint32_t>(buffer);
|
||||
return XMPPrevious(xmp_client);
|
||||
}
|
||||
case 0x00070008: {
|
||||
/* Notes:
|
||||
@@ -346,7 +370,10 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
return XMPDeleteTitlePlaylist(playlist_handle);
|
||||
}
|
||||
case 0x0007001A: {
|
||||
// XMPSetPlaybackController
|
||||
/* XMPSetPlaybackController Notes:
|
||||
- if controller is equal to 4 then is uses a backup value stored at a
|
||||
seperate location for both controller and playback client
|
||||
*/
|
||||
assert_true(!buffer_length ||
|
||||
buffer_length == sizeof(XMP_SET_PLAYBACK_CONTROLLER));
|
||||
XMP_SET_PLAYBACK_CONTROLLER* args =
|
||||
@@ -358,9 +385,14 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
XELOGD("XMPSetPlaybackController({:08X}, {:08X}, {:08X})",
|
||||
uint32_t(args->xmp_client), uint32_t(args->controller),
|
||||
uint32_t(args->playback_client));
|
||||
if (args->controller > 4) {
|
||||
return X_E_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
kernel_state_->emulator()->audio_media_player()->SetPlaybackClient(
|
||||
PlaybackClient(uint32_t(args->playback_client)));
|
||||
kernel_state_->emulator()->audio_media_player()->SetPlaybackController(
|
||||
uint32_t(args->controller));
|
||||
|
||||
kernel_state_->BroadcastNotification(
|
||||
kXNotificationXmpPlaybackControllerChanged,
|
||||
@@ -379,11 +411,16 @@ X_HRESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
assert_true(args->xmp_client == 0x00000002);
|
||||
XELOGD("XMPGetPlaybackController({:08X}, {:08X}, {:08X})",
|
||||
uint32_t(args->xmp_client), uint32_t(args->controller_ptr),
|
||||
uint32_t(args->locked_ptr));
|
||||
uint32_t(args->playback_client_ptr));
|
||||
|
||||
auto audio_media_player_ =
|
||||
kernel_state_->emulator()->audio_media_player();
|
||||
xe::store_and_swap<uint32_t>(
|
||||
memory_->TranslateVirtual(args->controller_ptr), 0);
|
||||
xe::store_and_swap<uint32_t>(memory_->TranslateVirtual(args->locked_ptr),
|
||||
0);
|
||||
memory_->TranslateVirtual(args->controller_ptr),
|
||||
uint32_t(audio_media_player_->GetPlaybackController()));
|
||||
xe::store_and_swap<uint32_t>(
|
||||
memory_->TranslateVirtual(args->playback_client_ptr),
|
||||
uint32_t(audio_media_player_->GetPlaybackClient()));
|
||||
|
||||
if (!XThread::GetCurrentThread()->main_thread()) {
|
||||
// Atrain spawns a thread 82437FD0 to call this in a tight loop forever.
|
||||
|
||||
@@ -126,7 +126,7 @@ 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<uint32_t> playback_client_ptr;
|
||||
};
|
||||
static_assert_size(XMP_GET_PLAYBACK_CONTROLLER, 0xC);
|
||||
|
||||
@@ -252,11 +252,12 @@ class XmpApp : public App {
|
||||
X_HRESULT XMPDeleteTitlePlaylist(uint32_t playlist_handle);
|
||||
X_HRESULT XMPPlayTitlePlaylist(uint32_t playlist_handle,
|
||||
uint32_t song_handle);
|
||||
X_HRESULT XMPContinue();
|
||||
X_HRESULT XMPStop(uint32_t unk);
|
||||
X_HRESULT XMPPause();
|
||||
X_HRESULT XMPNext();
|
||||
X_HRESULT XMPPrevious();
|
||||
X_HRESULT XMPAccessCheck(uint32_t xmp_client);
|
||||
X_HRESULT XMPContinue(uint32_t xmp_client);
|
||||
X_HRESULT XMPStop(uint32_t xmp_client, uint32_t unk);
|
||||
X_HRESULT XMPPause(uint32_t xmp_client);
|
||||
X_HRESULT XMPNext(uint32_t xmp_client);
|
||||
X_HRESULT XMPPrevious(uint32_t xmp_client);
|
||||
X_HRESULT XMPGetTitlePlaylistBufferSize(uint32_t xmp_client,
|
||||
uint32_t song_count,
|
||||
uint32_t storage_ptr);
|
||||
|
||||
Reference in New Issue
Block a user