From 6530b9dc4915d220fca471b1662ee58a11aa3a71 Mon Sep 17 00:00:00 2001 From: x1nixmzeng Date: Sat, 9 Jan 2016 17:36:46 +0000 Subject: [PATCH] Added callback when new module is launched This avoids having to guess the display window title format Also manually fixed the linting errors picked out by travis which do not get picked up using xb format locally --- src/xenia/app/emulator_window.h | 3 +- src/xenia/app/xenia_main.cc | 3 +- src/xenia/cpu/xex_module.cc | 4 +-- src/xenia/emulator.cc | 49 +++++++++++++++---------------- src/xenia/emulator.h | 16 +++++----- src/xenia/kernel/kernel_module.cc | 4 +-- src/xenia/ui/window.h | 2 +- src/xenia/ui/window_win.cc | 2 +- src/xenia/ui/window_win.h | 2 +- src/xenia/xdbf/xdbf_utils.cc | 18 ++++++------ src/xenia/xdbf/xdbf_utils.h | 6 ++-- 11 files changed, 56 insertions(+), 53 deletions(-) diff --git a/src/xenia/app/emulator_window.h b/src/xenia/app/emulator_window.h index 54ddae867..fa8db88b3 100644 --- a/src/xenia/app/emulator_window.h +++ b/src/xenia/app/emulator_window.h @@ -35,11 +35,12 @@ class EmulatorWindow { ui::Loop* loop() const { return loop_.get(); } ui::Window* window() const { return window_.get(); } + void UpdateTitle(); + private: explicit EmulatorWindow(Emulator* emulator); bool Initialize(); - void UpdateTitle(); void CpuTimeScalarReset(); void CpuTimeScalarSetHalf(); diff --git a/src/xenia/app/xenia_main.cc b/src/xenia/app/xenia_main.cc index 865d28cf3..ab4934666 100644 --- a/src/xenia/app/xenia_main.cc +++ b/src/xenia/app/xenia_main.cc @@ -195,7 +195,8 @@ int xenia_main(const std::vector& args) { // Normalize the path and make absolute. std::wstring abs_path = xe::to_absolute_path(path); - result = emulator->LaunchPath(abs_path); + result = emulator->LaunchPath(abs_path, + [&]() { emulator_window->UpdateTitle(); }); if (XFAILED(result)) { XELOGE("Failed to launch target: %.8X", result); emulator.reset(); diff --git a/src/xenia/cpu/xex_module.cc b/src/xenia/cpu/xex_module.cc index 860b204b5..da3d79773 100644 --- a/src/xenia/cpu/xex_module.cc +++ b/src/xenia/cpu/xex_module.cc @@ -465,8 +465,8 @@ bool XexModule::SetupLibraryImports(const char* name, GuestFunction::ExternHandler handler = nullptr; if (kernel_export) { if (kernel_export->function_data.trampoline) { - handler = (GuestFunction::ExternHandler)kernel_export - ->function_data.trampoline; + handler = (GuestFunction::ExternHandler) + kernel_export->function_data.trampoline; } else { handler = (GuestFunction::ExternHandler)kernel_export->function_data.shim; diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index ca36a53bf..f2182f62f 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -192,7 +192,8 @@ X_STATUS Emulator::Setup( return result; } -X_STATUS Emulator::LaunchPath(std::wstring path) { +X_STATUS Emulator::LaunchPath(std::wstring path, + std::function on_launch) { // Launch based on file type. // This is a silly guess based on file extension. auto last_slash = path.find_last_of(xe::kPathSeparator); @@ -202,18 +203,19 @@ X_STATUS Emulator::LaunchPath(std::wstring path) { } if (last_dot == std::wstring::npos) { // Likely an STFS container. - return LaunchStfsContainer(path); + return LaunchStfsContainer(path, on_launch); } else if (path.substr(last_dot) == L".xex" || path.substr(last_dot) == L".elf") { // Treat as a naked xex file. - return LaunchXexFile(path); + return LaunchXexFile(path, on_launch); } else { // Assume a disc image. - return LaunchDiscImage(path); + return LaunchDiscImage(path, on_launch); } } -X_STATUS Emulator::LaunchXexFile(std::wstring path) { +X_STATUS Emulator::LaunchXexFile(std::wstring path, + std::function on_launch) { // We create a virtual filesystem pointing to its directory and symlink // that to the game filesystem. // e.g., /my/files/foo.xex will get a local fs at: @@ -245,10 +247,11 @@ X_STATUS Emulator::LaunchXexFile(std::wstring path) { // Launch the game. std::string fs_path = "game:\\" + xe::to_string(file_name); - return CompleteLaunch(path, fs_path); + return CompleteLaunch(path, fs_path, on_launch); } -X_STATUS Emulator::LaunchDiscImage(std::wstring path) { +X_STATUS Emulator::LaunchDiscImage(std::wstring path, + std::function on_launch) { auto mount_path = "\\Device\\Cdrom0"; // Register the disc image in the virtual filesystem. @@ -267,10 +270,11 @@ X_STATUS Emulator::LaunchDiscImage(std::wstring path) { file_system_->RegisterSymbolicLink("d:", mount_path); // Launch the game. - return CompleteLaunch(path, "game:\\default.xex"); + return CompleteLaunch(path, "game:\\default.xex", on_launch); } -X_STATUS Emulator::LaunchStfsContainer(std::wstring path) { +X_STATUS Emulator::LaunchStfsContainer(std::wstring path, + std::function on_launch) { auto mount_path = "\\Device\\Cdrom0"; // Register the container in the virtual filesystem. @@ -289,7 +293,7 @@ X_STATUS Emulator::LaunchStfsContainer(std::wstring path) { file_system_->RegisterSymbolicLink("d:", mount_path); // Launch the game. - return CompleteLaunch(path, "game:\\default.xex"); + return CompleteLaunch(path, "game:\\default.xex", on_launch); } void Emulator::Pause() { @@ -494,8 +498,9 @@ void Emulator::WaitUntilExit() { } } -X_STATUS Emulator::CompleteLaunch(const std::wstring& path, - const std::string& module_path) { +X_STATUS Emulator::CompleteLaunch(const std::wstring &path, + const std::string &module_path, + std::function on_launch) { // Allow xam to request module loads. auto xam = kernel_state()->GetKernelModule("xam.xex"); @@ -510,10 +515,6 @@ X_STATUS Emulator::CompleteLaunch(const std::wstring& path, } kernel_state_->SetExecutableModule(module); - auto main_xthread = module->Launch(); - if (!main_xthread) { - return X_STATUS_UNSUCCESSFUL; - } // Try and load the resource database (xex only) char title[9] = {0}; @@ -526,15 +527,7 @@ X_STATUS Emulator::CompleteLaunch(const std::wstring& path, if (xdb_ptr != nullptr) { xe::xdbf::XdbfWrapper db; if (db.initialize(xdb_ptr, static_cast(resource_size))) { - - std::string game_title(xe::xdbf::get_title(db)); - if (!game_title.empty()) { - game_title_ = xe::to_wstring(game_title); - // TODO(x1nixmzeng): Need to somehow callback to - // EmulatorWindow::UpdateTitle - display_window_->set_title(game_title_ + L" - " + - display_window_->title()); - } + game_title_ = xe::to_wstring(xe::xdbf::get_title(db)); xe::xdbf::XdbfBlock icon_block = xe::xdbf::get_icon(db); if (icon_block.buffer != nullptr) { display_window_->SetIconFromBuffer(icon_block.buffer, @@ -544,6 +537,12 @@ X_STATUS Emulator::CompleteLaunch(const std::wstring& path, } } + auto main_xthread = module->Launch(); + if (!main_xthread) { + return X_STATUS_UNSUCCESSFUL; + } + + on_launch(); main_thread_ = main_xthread->thread(); WaitUntilExit(); diff --git a/src/xenia/emulator.h b/src/xenia/emulator.h index 72a943371..23a71561f 100644 --- a/src/xenia/emulator.h +++ b/src/xenia/emulator.h @@ -54,7 +54,7 @@ class Emulator { const std::wstring& command_line() const { return command_line_; } // Title of the game in the default language. - const std::wstring &game_title() const { return game_title_; } + const std::wstring& game_title() const { return game_title_; } // Window used for displaying graphical output. ui::Window* display_window() const { return display_window_; } @@ -109,17 +109,18 @@ class Emulator { // Launches a game from the given file path. // This will attempt to infer the type of the given file (such as an iso, etc) // using heuristics. - X_STATUS LaunchPath(std::wstring path); + X_STATUS LaunchPath(std::wstring path, std::function on_launch); // Launches a game from a .xex file by mounting the containing folder as if it // was an extracted STFS container. - X_STATUS LaunchXexFile(std::wstring path); + X_STATUS LaunchXexFile(std::wstring path, std::function on_launch); // Launches a game from a disc image file (.iso, etc). - X_STATUS LaunchDiscImage(std::wstring path); + X_STATUS LaunchDiscImage(std::wstring path, std::function on_launch); // Launches a game from an STFS container file. - X_STATUS LaunchStfsContainer(std::wstring path); + X_STATUS LaunchStfsContainer(std::wstring path, + std::function on_launch); void Pause(); void Resume(); @@ -134,8 +135,9 @@ class Emulator { static bool ExceptionCallbackThunk(Exception* ex, void* data); bool ExceptionCallback(Exception* ex); - X_STATUS CompleteLaunch(const std::wstring& path, - const std::string& module_path); + X_STATUS CompleteLaunch(const std::wstring &path, + const std::string &module_path, + std::function on_launch); std::wstring command_line_; std::wstring game_title_; diff --git a/src/xenia/kernel/kernel_module.cc b/src/xenia/kernel/kernel_module.cc index befa08d33..fdad0256f 100644 --- a/src/xenia/kernel/kernel_module.cc +++ b/src/xenia/kernel/kernel_module.cc @@ -105,8 +105,8 @@ uint32_t KernelModule::GetProcAddressByOrdinal(uint16_t ordinal) { cpu::GuestFunction::ExternHandler handler = nullptr; if (export_entry->function_data.trampoline) { - handler = (cpu::GuestFunction::ExternHandler)export_entry - ->function_data.trampoline; + handler = (cpu::GuestFunction::ExternHandler) + export_entry->function_data.trampoline; } else { handler = (cpu::GuestFunction::ExternHandler)export_entry->function_data.shim; diff --git a/src/xenia/ui/window.h b/src/xenia/ui/window.h index ee6cd9ac9..d894d9276 100644 --- a/src/xenia/ui/window.h +++ b/src/xenia/ui/window.h @@ -53,7 +53,7 @@ class Window { return true; } - virtual bool SetIconFromBuffer(void *buffer, size_t size) = 0; + virtual bool SetIconFromBuffer(void* buffer, size_t size) = 0; virtual bool is_fullscreen() const { return false; } virtual void ToggleFullscreen(bool fullscreen) {} diff --git a/src/xenia/ui/window_win.cc b/src/xenia/ui/window_win.cc index 9a03b5a3c..d3c6224b7 100644 --- a/src/xenia/ui/window_win.cc +++ b/src/xenia/ui/window_win.cc @@ -167,7 +167,7 @@ bool Win32Window::set_title(const std::wstring& title) { return true; } -bool Win32Window::SetIconFromBuffer(void *buffer, size_t size) { +bool Win32Window::SetIconFromBuffer(void* buffer, size_t size) { if (icon_ != nullptr) { DestroyIcon(icon_); } diff --git a/src/xenia/ui/window_win.h b/src/xenia/ui/window_win.h index 36cc38b95..296baba45 100644 --- a/src/xenia/ui/window_win.h +++ b/src/xenia/ui/window_win.h @@ -31,7 +31,7 @@ class Win32Window : public Window { HWND hwnd() const { return hwnd_; } bool set_title(const std::wstring& title) override; - bool SetIconFromBuffer(void *buffer, size_t size) override; + bool SetIconFromBuffer(void* buffer, size_t size) override; bool is_fullscreen() const override; void ToggleFullscreen(bool fullscreen) override; diff --git a/src/xenia/xdbf/xdbf_utils.cc b/src/xenia/xdbf/xdbf_utils.cc index 100a57926..e60a88d80 100644 --- a/src/xenia/xdbf/xdbf_utils.cc +++ b/src/xenia/xdbf/xdbf_utils.cc @@ -84,14 +84,14 @@ XdbfBlock XdbfWrapper::get_entry(XdbfSection section, uint64_t id) const { return block; } -XdbfBlock get_icon(const XdbfWrapper &ref) { +XdbfBlock get_icon(const XdbfWrapper& ref) { return ref.get_entry(kSectionImage, kIdTitle); } -XdbfLocale get_default_language(const XdbfWrapper &ref) { +XdbfLocale get_default_language(const XdbfWrapper& ref) { XdbfBlock block = ref.get_entry(kSectionMetadata, kIdXSTC); if (block.buffer != nullptr) { - XDBF_XSTC *xstc = reinterpret_cast(block.buffer); + XDBF_XSTC* xstc = reinterpret_cast(block.buffer); assert_true(xstc->magic == kMagicXSTC); uint32_t default_language = xstc->default_language; @@ -101,7 +101,7 @@ XdbfLocale get_default_language(const XdbfWrapper &ref) { return kLocaleEnglish; } -std::string get_title(const XdbfWrapper &ref) { +std::string get_title(const XdbfWrapper& ref) { std::string title_str; uint64_t language_id = static_cast(get_default_language(ref)); @@ -109,19 +109,19 @@ std::string get_title(const XdbfWrapper &ref) { XdbfBlock lang_block = ref.get_entry(kSectionStringTable, language_id); if (lang_block.buffer != nullptr) { - XDBF_XSTR_HEADER *xstr_head = - reinterpret_cast(lang_block.buffer); + XDBF_XSTR_HEADER* xstr_head = + reinterpret_cast(lang_block.buffer); assert_true(xstr_head->magic == kMagicXSTR); assert_true(xstr_head->version == 1); uint16_t str_count = xstr_head->string_count; - uint8_t *currentAddress = lang_block.buffer + sizeof(XDBF_XSTR_HEADER); + uint8_t* currentAddress = lang_block.buffer + sizeof(XDBF_XSTR_HEADER); uint16_t s = 0; while (s < str_count && title_str.empty()) { - XDBF_STRINGTABLE_ENTRY *entry = - reinterpret_cast(currentAddress); + XDBF_STRINGTABLE_ENTRY* entry = + reinterpret_cast(currentAddress); currentAddress += sizeof(XDBF_STRINGTABLE_ENTRY); uint16_t len = entry->string_length; diff --git a/src/xenia/xdbf/xdbf_utils.h b/src/xenia/xdbf/xdbf_utils.h index be6db4541..4431eeda1 100644 --- a/src/xenia/xdbf/xdbf_utils.h +++ b/src/xenia/xdbf/xdbf_utils.h @@ -119,9 +119,9 @@ class XdbfWrapper { XdbfState state_; }; -XdbfBlock get_icon(const XdbfWrapper &ref); -XdbfLocale get_default_language(const XdbfWrapper &ref); -std::string get_title(const XdbfWrapper &ref); +XdbfBlock get_icon(const XdbfWrapper& ref); +XdbfLocale get_default_language(const XdbfWrapper& ref); +std::string get_title(const XdbfWrapper& ref); } // namespace xdbf } // namespace xe