[Kernel] Use structures in XmpApp.

This commit is contained in:
gibbed 2020-04-13 10:51:02 -05:00 committed by Rick Gibbed
parent ae7555e9ff
commit a7d4d6ee70
1 changed files with 109 additions and 66 deletions

View File

@ -254,16 +254,22 @@ X_RESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
} }
case 0x00070008: { case 0x00070008: {
assert_true(!buffer_length || buffer_length == 16); assert_true(!buffer_length || buffer_length == 16);
uint32_t xmp_client = xe::load_and_swap<uint32_t>(buffer + 0); struct {
uint32_t playback_mode = xe::load_and_swap<uint32_t>(buffer + 4); xe::be<uint32_t> xmp_client;
uint32_t repeat_mode = xe::load_and_swap<uint32_t>(buffer + 8); xe::be<uint32_t> playback_mode;
uint32_t flags = xe::load_and_swap<uint32_t>(buffer + 12); xe::be<uint32_t> repeat_mode;
assert_true(xmp_client == 0x00000002); xe::be<uint32_t> flags;
XELOGD("XMPSetPlaybackBehavior({:08X}, {:08X}, {:08X})", playback_mode, }* args = memory_->TranslateVirtual<decltype(args)>(buffer_ptr);
repeat_mode, flags); static_assert_size(decltype(*args), 16);
playback_mode_ = static_cast<PlaybackMode>(playback_mode);
repeat_mode_ = static_cast<RepeatMode>(repeat_mode); assert_true(args->xmp_client == 0x00000002 ||
unknown_flags_ = flags; args->xmp_client == 0x00000000);
XELOGD("XMPSetPlaybackBehavior({:08X}, {:08X}, {:08X})",
uint32_t(args->playback_mode), uint32_t(args->repeat_mode),
uint32_t(args->flags));
playback_mode_ = static_cast<PlaybackMode>(uint32_t(args->playback_mode));
repeat_mode_ = static_cast<RepeatMode>(uint32_t(args->repeat_mode));
unknown_flags_ = args->flags;
kernel_state_->BroadcastNotification(kMsgPlaybackBehaviorChanged, 0); kernel_state_->BroadcastNotification(kMsgPlaybackBehaviorChanged, 0);
return X_ERROR_SUCCESS; return X_ERROR_SUCCESS;
} }
@ -281,6 +287,7 @@ X_RESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
xe::be<uint32_t> xmp_client; xe::be<uint32_t> xmp_client;
xe::be<uint32_t> volume_ptr; xe::be<uint32_t> volume_ptr;
}* args = memory_->TranslateVirtual<decltype(args)>(buffer_ptr); }* args = memory_->TranslateVirtual<decltype(args)>(buffer_ptr);
static_assert_size(decltype(*args), 8);
assert_true(args->xmp_client == 0x00000002); assert_true(args->xmp_client == 0x00000002);
XELOGD("XMPGetVolume({:08X})", uint32_t(args->volume_ptr)); XELOGD("XMPGetVolume({:08X})", uint32_t(args->volume_ptr));
@ -290,50 +297,66 @@ X_RESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
} }
case 0x0007000C: { case 0x0007000C: {
assert_true(!buffer_length || buffer_length == 8); assert_true(!buffer_length || buffer_length == 8);
uint32_t xmp_client = xe::load_and_swap<uint32_t>(buffer + 0); struct {
float float_value = xe::load_and_swap<float>(buffer + 4); xe::be<uint32_t> xmp_client;
assert_true(xmp_client == 0x00000002); xe::be<float> value;
XELOGD("XMPSetVolume({})", float_value); }* args = memory_->TranslateVirtual<decltype(args)>(buffer_ptr);
volume_ = float_value; static_assert_size(decltype(*args), 8);
assert_true(args->xmp_client == 0x00000002);
XELOGD("XMPSetVolume({:g})", float(args->value));
volume_ = args->value;
return X_ERROR_SUCCESS; return X_ERROR_SUCCESS;
} }
case 0x0007000D: { case 0x0007000D: {
assert_true(!buffer_length || buffer_length == 36); assert_true(!buffer_length || buffer_length == 36);
uint32_t xmp_client = xe::load_and_swap<uint32_t>(buffer + 0); struct {
uint32_t storage_ptr = xe::load_and_swap<uint32_t>(buffer + 4); xe::be<uint32_t> xmp_client;
uint32_t storage_size = xe::load_and_swap<uint32_t>(buffer + 8); xe::be<uint32_t> storage_ptr;
uint32_t songs_ptr = xe::load_and_swap<uint32_t>(buffer + 12); xe::be<uint32_t> storage_size;
uint32_t song_count = xe::load_and_swap<uint32_t>(buffer + 16); xe::be<uint32_t> songs_ptr;
uint32_t playlist_name_ptr = xe::load_and_swap<uint32_t>(buffer + 20); xe::be<uint32_t> song_count;
uint32_t flags = xe::load_and_swap<uint32_t>(buffer + 24); xe::be<uint32_t> playlist_name_ptr;
uint32_t song_handles_ptr = xe::be<uint32_t> flags;
xe::load_and_swap<uint32_t>(buffer + 28); // 0? xe::be<uint32_t> song_handles_ptr;
uint32_t playlist_handle_ptr = xe::load_and_swap<uint32_t>(buffer + 32); xe::be<uint32_t> playlist_handle_ptr;
}* args = memory_->TranslateVirtual<decltype(args)>(buffer_ptr);
static_assert_size(decltype(*args), 36);
xe::store_and_swap<uint32_t>( xe::store_and_swap<uint32_t>(
memory_->TranslateVirtual(playlist_handle_ptr), storage_ptr); memory_->TranslateVirtual(args->playlist_handle_ptr),
assert_true(xmp_client == 0x00000002); args->storage_ptr);
assert_true(args->xmp_client == 0x00000002 ||
args->xmp_client == 0x00000000);
std::u16string playlist_name; std::u16string playlist_name;
if (!playlist_name_ptr) { if (!args->playlist_name_ptr) {
playlist_name = u""; playlist_name = u"";
} else { } else {
playlist_name = xe::load_and_swap<std::u16string>( playlist_name = xe::load_and_swap<std::u16string>(
memory_->TranslateVirtual(playlist_name_ptr)); memory_->TranslateVirtual(args->playlist_name_ptr));
} }
// dummy_alloc_ptr is the result of a XamAlloc of storage_size. // dummy_alloc_ptr is the result of a XamAlloc of storage_size.
assert_true(storage_size == 4 + song_count * 128); assert_true(uint32_t(args->storage_size) ==
return XMPCreateTitlePlaylist(songs_ptr, song_count, playlist_name_ptr, 4 + uint32_t(args->song_count) * 128);
playlist_name, flags, song_handles_ptr, return XMPCreateTitlePlaylist(args->songs_ptr, args->song_count,
storage_ptr); args->playlist_name_ptr, playlist_name,
args->flags, args->song_handles_ptr,
args->storage_ptr);
} }
case 0x0007000E: { case 0x0007000E: {
assert_true(!buffer_length || buffer_length == 12); assert_true(!buffer_length || buffer_length == 12);
uint32_t xmp_client = xe::load_and_swap<uint32_t>(buffer + 0); struct {
uint32_t unk_ptr = xe::load_and_swap<uint32_t>(buffer + 4); // 0 xe::be<uint32_t> xmp_client;
uint32_t info_ptr = xe::load_and_swap<uint32_t>(buffer + 8); xe::be<uint32_t> unk_ptr; // 0
auto info = memory_->TranslateVirtual(info_ptr); xe::be<uint32_t> info_ptr;
assert_true(xmp_client == 0x00000002); }* args = memory_->TranslateVirtual<decltype(args)>(buffer_ptr);
assert_zero(unk_ptr); static_assert_size(decltype(*args), 12);
XELOGE("XMPGetInfo?({:08X}, {:08X})", unk_ptr, info_ptr);
auto info = memory_->TranslateVirtual(args->info_ptr);
assert_true(args->xmp_client == 0x00000002);
assert_zero(args->unk_ptr);
XELOGE("XMPGetInfo?({:08X}, {:08X})", uint32_t(args->unk_ptr),
uint32_t(args->info_ptr));
if (!active_playlist_) { if (!active_playlist_) {
return X_STATUS_UNSUCCESSFUL; return X_STATUS_UNSUCCESSFUL;
} }
@ -353,11 +376,16 @@ X_RESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
} }
case 0x00070013: { case 0x00070013: {
assert_true(!buffer_length || buffer_length == 8); assert_true(!buffer_length || buffer_length == 8);
uint32_t xmp_client = xe::load_and_swap<uint32_t>(buffer + 0); struct {
uint32_t storage_ptr = xe::load_and_swap<uint32_t>(buffer + 4); xe::be<uint32_t> xmp_client;
uint32_t playlist_handle = xe::be<uint32_t> storage_ptr;
xe::load_and_swap<uint32_t>(memory_->TranslateVirtual(storage_ptr)); }* args = memory_->TranslateVirtual<decltype(args)>(buffer_ptr);
assert_true(xmp_client == 0x00000002); static_assert_size(decltype(*args), 8);
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);
return XMPDeleteTitlePlaylist(playlist_handle); return XMPDeleteTitlePlaylist(playlist_handle);
} }
case 0x0007001A: { case 0x0007001A: {
@ -368,9 +396,11 @@ X_RESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
xe::be<uint32_t> controller; xe::be<uint32_t> controller;
xe::be<uint32_t> locked; xe::be<uint32_t> locked;
}* args = memory_->TranslateVirtual<decltype(args)>(buffer_ptr); }* args = memory_->TranslateVirtual<decltype(args)>(buffer_ptr);
static_assert_size(decltype(*args), 12);
assert_true(args->xmp_client == 0x00000002); assert_true(
assert_true(args->controller == 0x00000000); (args->xmp_client == 0x00000002 && args->controller == 0x00000000) ||
(args->xmp_client == 0x00000000 && args->controller == 0x00000001));
XELOGD("XMPSetPlaybackController({:08X}, {:08X})", XELOGD("XMPSetPlaybackController({:08X}, {:08X})",
uint32_t(args->controller), uint32_t(args->locked)); uint32_t(args->controller), uint32_t(args->locked));
@ -389,6 +419,7 @@ X_RESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
xe::be<uint32_t> controller_ptr; xe::be<uint32_t> controller_ptr;
xe::be<uint32_t> locked_ptr; xe::be<uint32_t> locked_ptr;
}* args = memory_->TranslateVirtual<decltype(args)>(buffer_ptr); }* args = memory_->TranslateVirtual<decltype(args)>(buffer_ptr);
static_assert_size(decltype(*args), 12);
assert_true(args->xmp_client == 0x00000002); assert_true(args->xmp_client == 0x00000002);
XELOGD("XMPGetPlaybackController({:08X}, {:08X}, {:08X})", XELOGD("XMPGetPlaybackController({:08X}, {:08X}, {:08X})",
@ -406,24 +437,31 @@ X_RESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
case 0x00070029: { case 0x00070029: {
// XMPGetPlaybackBehavior // XMPGetPlaybackBehavior
assert_true(!buffer_length || buffer_length == 16); assert_true(!buffer_length || buffer_length == 16);
uint32_t xmp_client = xe::load_and_swap<uint32_t>(buffer + 0); struct {
uint32_t playback_mode_ptr = xe::load_and_swap<uint32_t>(buffer + 4); xe::be<uint32_t> xmp_client;
uint32_t repeat_mode_ptr = xe::load_and_swap<uint32_t>(buffer + 8); xe::be<uint32_t> playback_mode_ptr;
uint32_t unk3_ptr = xe::load_and_swap<uint32_t>(buffer + 12); xe::be<uint32_t> repeat_mode_ptr;
assert_true(xmp_client == 0x00000002); xe::be<uint32_t> unk3_ptr;
}* args = memory_->TranslateVirtual<decltype(args)>(buffer_ptr);
static_assert_size(decltype(*args), 16);
assert_true(args->xmp_client == 0x00000002 ||
args->xmp_client == 0x00000000);
XELOGD("XMPGetPlaybackBehavior({:08X}, {:08X}, {:08X})", XELOGD("XMPGetPlaybackBehavior({:08X}, {:08X}, {:08X})",
playback_mode_ptr, repeat_mode_ptr, unk3_ptr); uint32_t(args->playback_mode_ptr), uint32_t(args->repeat_mode_ptr),
if (playback_mode_ptr) { uint32_t(args->unk3_ptr));
if (args->playback_mode_ptr) {
xe::store_and_swap<uint32_t>( xe::store_and_swap<uint32_t>(
memory_->TranslateVirtual(playback_mode_ptr), memory_->TranslateVirtual(args->playback_mode_ptr),
static_cast<uint32_t>(playback_mode_)); static_cast<uint32_t>(playback_mode_));
} }
if (repeat_mode_ptr) { if (args->repeat_mode_ptr) {
xe::store_and_swap<uint32_t>(memory_->TranslateVirtual(repeat_mode_ptr), xe::store_and_swap<uint32_t>(
memory_->TranslateVirtual(args->repeat_mode_ptr),
static_cast<uint32_t>(repeat_mode_)); static_cast<uint32_t>(repeat_mode_));
} }
if (unk3_ptr) { if (args->unk3_ptr) {
xe::store_and_swap<uint32_t>(memory_->TranslateVirtual(unk3_ptr), xe::store_and_swap<uint32_t>(memory_->TranslateVirtual(args->unk3_ptr),
unknown_flags_); unknown_flags_);
} }
return X_ERROR_SUCCESS; return X_ERROR_SUCCESS;
@ -432,13 +470,18 @@ X_RESULT XmpApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
assert_true(!buffer_length || buffer_length == 12); assert_true(!buffer_length || buffer_length == 12);
// Query of size for XamAlloc - the result of the alloc is passed to // Query of size for XamAlloc - the result of the alloc is passed to
// 0x0007000D. // 0x0007000D.
uint32_t xmp_client = xe::load_and_swap<uint32_t>(buffer + 0); struct {
uint32_t song_count = xe::load_and_swap<uint32_t>(buffer + 4); xe::be<uint32_t> xmp_client;
uint32_t size_ptr = xe::load_and_swap<uint32_t>(buffer + 8); xe::be<uint32_t> song_count;
assert_true(xmp_client == 0x00000002); xe::be<uint32_t> size_ptr;
}* args = memory_->TranslateVirtual<decltype(args)>(buffer_ptr);
static_assert_size(decltype(*args), 12);
assert_true(args->xmp_client == 0x00000002 ||
args->xmp_client == 0x00000000);
// We don't use the storage, so just fudge the number. // We don't use the storage, so just fudge the number.
xe::store_and_swap<uint32_t>(memory_->TranslateVirtual(size_ptr), xe::store_and_swap<uint32_t>(memory_->TranslateVirtual(args->size_ptr),
4 + song_count * 128); 4 + uint32_t(args->song_count) * 128);
return X_ERROR_SUCCESS; return X_ERROR_SUCCESS;
} }
case 0x0007003D: { case 0x0007003D: {