/** ****************************************************************************** * 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 "xenia/base/logging.h" #include "xenia/kernel/kernel_state.h" #include "xenia/kernel/util/shim_utils.h" #include "xenia/kernel/xam_private.h" #include "xenia/xbox.h" 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 = xe::load_and_swap(SHIM_MEM_ADDR(title_ptr)); auto text = xe::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 = xe::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( xe::cpu::ExportResolver* export_resolver, KernelState* state) { SHIM_SET_MAPPING("xam.xex", XamShowMessageBoxUI, state); }