From abf7b794e6e1528dfc19010663a8863b87cae18b Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 14 May 2015 16:20:49 -0700 Subject: [PATCH] Adding --headless and basic message box UI. --- build/Xenia.Cpp.x64.Common.props | 2 +- src/xenia/kernel/kernel_state.cc | 2 ++ src/xenia/kernel/kernel_state.h | 4 +++ src/xenia/kernel/xam_ui.cc | 54 ++++++++++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/build/Xenia.Cpp.x64.Common.props b/build/Xenia.Cpp.x64.Common.props index 922f3cfc5..dc716d5a0 100644 --- a/build/Xenia.Cpp.x64.Common.props +++ b/build/Xenia.Cpp.x64.Common.props @@ -18,7 +18,7 @@ $(SolutionDir)build\bin\$(Configuration)\ - ntdll.lib;wsock32.lib;ws2_32.lib;xinput.lib;xaudio2.lib;glu32.lib;opengl32.lib;%(AdditionalDependencies) + ntdll.lib;wsock32.lib;ws2_32.lib;xinput.lib;xaudio2.lib;glu32.lib;opengl32.lib;comctl32.lib;%(AdditionalDependencies) $(SolutionDir)build\bin\$(Configuration)\ diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index 453eb2dcb..a49cd0f5e 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -27,6 +27,8 @@ #include "xenia/kernel/objects/xthread.h" #include "xenia/kernel/objects/xuser_module.h" +DEFINE_bool(headless, false, + "Don't display any UI, using defaults for prompts as needed."); DEFINE_string(content_root, "content", "Root path for content (save/etc) storage."); diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index 18bcdc3e5..f718b182f 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -10,6 +10,8 @@ #ifndef XENIA_KERNEL_KERNEL_STATE_H_ #define XENIA_KERNEL_KERNEL_STATE_H_ +#include + #include #include @@ -29,6 +31,8 @@ class Processor; } // namespace cpu } // namespace xe +DECLARE_bool(headless); + namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_ui.cc b/src/xenia/kernel/xam_ui.cc index ebd24b513..bab247f4b 100644 --- a/src/xenia/kernel/xam_ui.cc +++ b/src/xenia/kernel/xam_ui.cc @@ -8,11 +8,14 @@ */ #include "xenia/base/logging.h" +#include "xenia/emulator.h" #include "xenia/kernel/kernel_state.h" #include "xenia/kernel/util/shim_utils.h" #include "xenia/kernel/xam_private.h" #include "xenia/xbox.h" +#include + namespace xe { namespace kernel { @@ -51,8 +54,55 @@ SHIM_CALL XamShowMessageBoxUI_shim(PPCContext* ppc_state, KernelState* state) { 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); + uint32_t chosen_button; + if (FLAGS_headless) { + // Auto-pick the focused button. + chosen_button = active_button; + } else { + TASKDIALOGCONFIG config = {0}; + config.cbSize = sizeof(config); + config.hInstance = GetModuleHandle(nullptr); + config.hwndParent = state->emulator()->main_window()->hwnd(); + config.dwFlags = TDF_ALLOW_DIALOG_CANCELLATION | // esc to exit + TDF_POSITION_RELATIVE_TO_WINDOW; // center in window + config.dwCommonButtons = 0; + config.pszWindowTitle = title.c_str(); + switch (flags & 0xF) { + case 0: + config.pszMainIcon = nullptr; + break; + case 1: + config.pszMainIcon = TD_ERROR_ICON; + break; + case 2: + config.pszMainIcon = TD_WARNING_ICON; + break; + case 3: + config.pszMainIcon = TD_INFORMATION_ICON; + break; + } + config.pszMainInstruction = text.c_str(); + config.pszContent = nullptr; + std::vector taskdialog_buttons; + for (uint32_t i = 0; i < button_count; ++i) { + taskdialog_buttons.push_back({1000 + int(i), buttons[i].c_str()}); + } + config.pButtons = taskdialog_buttons.data(); + config.cButtons = button_count; + config.nDefaultButton = active_button; + int button_pressed = 0; + TaskDialogIndirect(&config, &button_pressed, nullptr, nullptr); + switch (button_pressed) { + default: + chosen_button = button_pressed - 1000; + break; + case IDCANCEL: + // User cancelled, just pick default. + chosen_button = active_button; + break; + } + } + SHIM_SET_MEM_32(result_ptr, chosen_button); state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); SHIM_SET_RETURN_32(X_ERROR_IO_PENDING);