From 64d8ee386b1bc5d657903ad3f093923ced7a1b8c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 4 Aug 2014 20:24:08 -0700 Subject: [PATCH] XamShowMessageBoxUI (that auto-advances). --- src/poly/memory.h | 28 +++++++++++++ src/xenia/kernel/sources.gypi | 2 + src/xenia/kernel/xam_module.cc | 1 + src/xenia/kernel/xam_private.h | 1 + src/xenia/kernel/xam_ui.cc | 76 ++++++++++++++++++++++++++++++++++ src/xenia/kernel/xam_ui.h | 28 +++++++++++++ src/xenia/kernel/xam_user.cc | 2 +- 7 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 src/xenia/kernel/xam_ui.cc create mode 100644 src/xenia/kernel/xam_ui.h diff --git a/src/poly/memory.h b/src/poly/memory.h index a8a26c95f..531c0ea4d 100644 --- a/src/poly/memory.h +++ b/src/poly/memory.h @@ -10,6 +10,8 @@ #ifndef POLY_MEMORY_H_ #define POLY_MEMORY_H_ +#include + #include namespace poly { @@ -101,6 +103,32 @@ template <> inline double load_and_swap(const void* mem) { return byte_swap(*reinterpret_cast(mem)); } +template <> +inline std::string load_and_swap(const void* mem) { + std::string value; + for (int i = 0;; ++i) { + auto c = + poly::load_and_swap(reinterpret_cast(mem) + i); + if (!c) { + break; + } + value.push_back(static_cast(c)); + } + return value; +} +template <> +inline std::wstring load_and_swap(const void* mem) { + std::wstring value; + for (int i = 0;; ++i) { + auto c = poly::load_and_swap( + reinterpret_cast(mem) + i); + if (!c) { + break; + } + value.push_back(static_cast(c)); + } + return value; +} template void store(void* mem, T value); diff --git a/src/xenia/kernel/sources.gypi b/src/xenia/kernel/sources.gypi index 2a7cb929b..f6f5356d0 100644 --- a/src/xenia/kernel/sources.gypi +++ b/src/xenia/kernel/sources.gypi @@ -34,6 +34,8 @@ 'xam_ordinals.h', 'xam_private.h', 'xam_table.inc', + 'xam_ui.cc', + 'xam_ui.h', 'xam_user.cc', 'xam_user.h', 'xam_video.cc', diff --git a/src/xenia/kernel/xam_module.cc b/src/xenia/kernel/xam_module.cc index d8f85547e..2a5aa6217 100644 --- a/src/xenia/kernel/xam_module.cc +++ b/src/xenia/kernel/xam_module.cc @@ -37,6 +37,7 @@ XamModule::XamModule(Emulator* emulator, KernelState* kernel_state) : RegisterMsgExports(export_resolver_, kernel_state); RegisterNetExports(export_resolver_, kernel_state); RegisterNotifyExports(export_resolver_, kernel_state); + RegisterUIExports(export_resolver_, kernel_state); RegisterUserExports(export_resolver_, kernel_state); RegisterVideoExports(export_resolver_, kernel_state); RegisterVoiceExports(export_resolver_, kernel_state); diff --git a/src/xenia/kernel/xam_private.h b/src/xenia/kernel/xam_private.h index 715fc44e6..1884397e1 100644 --- a/src/xenia/kernel/xam_private.h +++ b/src/xenia/kernel/xam_private.h @@ -29,6 +29,7 @@ void RegisterInputExports(ExportResolver* export_resolver, KernelState* state); void RegisterMsgExports(ExportResolver* export_resolver, KernelState* state); void RegisterNetExports(ExportResolver* export_resolver, KernelState* state); void RegisterNotifyExports(ExportResolver* export_resolver, KernelState* state); +void RegisterUIExports(ExportResolver* export_resolver, KernelState* state); void RegisterUserExports(ExportResolver* export_resolver, KernelState* state); void RegisterVideoExports(ExportResolver* export_resolver, KernelState* state); void RegisterVoiceExports(ExportResolver* export_resolver, KernelState* state); diff --git a/src/xenia/kernel/xam_ui.cc b/src/xenia/kernel/xam_ui.cc new file mode 100644 index 000000000..803934fd6 --- /dev/null +++ b/src/xenia/kernel/xam_ui.cc @@ -0,0 +1,76 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include +#include + + +using namespace xe; +using namespace xe::kernel; +using namespace xe::kernel::xam; + + +namespace xe { +namespace kernel { + +// http://www.se7ensins.com/forums/threads/working-xshowmessageboxui.844116/?jdfwkey=sb0vm +SHIM_CALL XamShowMessageBoxUI_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t user_index = SHIM_GET_ARG_32(0); + uint32_t title_ptr = SHIM_GET_ARG_32(1); + uint32_t text_ptr = SHIM_GET_ARG_32(2); + uint32_t button_count = SHIM_GET_ARG_32(3); + uint32_t button_ptrs = SHIM_GET_ARG_32(4); + uint32_t active_button = SHIM_GET_ARG_32(5); + uint32_t flags = SHIM_GET_ARG_32(6); + uint32_t result_ptr = SHIM_GET_ARG_32(7); + // arg8 is in stack! + uint32_t sp = (uint32_t)ppc_state->r[1]; + uint32_t overlapped_ptr = SHIM_MEM_32(sp + 0x54); + + auto title = poly::load_and_swap(SHIM_MEM_ADDR(title_ptr)); + auto text = poly::load_and_swap(SHIM_MEM_ADDR(text_ptr)); + std::vector buttons; + std::wstring all_buttons; + for (uint32_t j = 0; j < button_count; ++j) { + uint32_t button_ptr = SHIM_MEM_32(button_ptrs + j * 4); + auto button = poly::load_and_swap(SHIM_MEM_ADDR(button_ptr)); + all_buttons.append(button); + if (j + 1 < button_count) { + all_buttons.append(L" | "); + } + buttons.push_back(button); + } + + XELOGD( + "XamShowMessageBoxUI(%d, %.8X(%S), %.8X(%S), %d, %.8X(%S), %d, %X, %.8X, " + "%.8X)", + user_index, title_ptr, title.c_str(), text_ptr, text.c_str(), + button_count, button_ptrs, all_buttons.c_str(), active_button, flags, + result_ptr, overlapped_ptr); + + // Auto-pick the focused button. + SHIM_SET_MEM_32(result_ptr, active_button); + + state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); + SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); +} + + +} // namespace kernel +} // namespace xe + + +void xe::kernel::xam::RegisterUIExports( + ExportResolver* export_resolver, KernelState* state) { + SHIM_SET_MAPPING("xam.xex", XamShowMessageBoxUI, state); +} diff --git a/src/xenia/kernel/xam_ui.h b/src/xenia/kernel/xam_ui.h new file mode 100644 index 000000000..629491ec4 --- /dev/null +++ b/src/xenia/kernel/xam_ui.h @@ -0,0 +1,28 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_XAM_UI_H_ +#define XENIA_KERNEL_XAM_UI_H_ + +#include +#include + +#include + + +namespace xe { +namespace kernel { + + + +} // namespace kernel +} // namespace xe + + +#endif // XENIA_KERNEL_XAM_UI_H_ diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index 268b912fb..0c7c3ea4c 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -60,7 +60,7 @@ SHIM_CALL XamUserGetSigninState_shim( // Lie and say we are signed in, but local-only. // This should keep games from asking us to sign in and also keep them // from initializing the network. - if (user_index == 0) { + if (user_index == 0 || (user_index & 0xFF) == 0xFF) { const auto& user_profile = state->user_profile(); SHIM_SET_RETURN_64(user_profile->signin_state()); } else {