From d0d18ff5703a9d8734d34719cf1da4cc70dae797 Mon Sep 17 00:00:00 2001 From: gibbed Date: Fri, 19 Apr 2019 10:45:47 -0500 Subject: [PATCH 01/11] [APU] Proper register file for XMA. --- src/xenia/apu/xma_decoder.cc | 99 +++++++++++++++++----------- src/xenia/apu/xma_decoder.h | 26 ++------ src/xenia/apu/xma_register_file.cc | 39 +++++++++++ src/xenia/apu/xma_register_file.h | 54 +++++++++++++++ src/xenia/apu/xma_register_table.inc | 51 ++++++++++++++ 5 files changed, 211 insertions(+), 58 deletions(-) create mode 100644 src/xenia/apu/xma_register_file.cc create mode 100644 src/xenia/apu/xma_register_file.h create mode 100644 src/xenia/apu/xma_register_table.inc diff --git a/src/xenia/apu/xma_decoder.cc b/src/xenia/apu/xma_decoder.cc index 9767d66c7..778e0105d 100644 --- a/src/xenia/apu/xma_decoder.cc +++ b/src/xenia/apu/xma_decoder.cc @@ -109,18 +109,18 @@ X_STATUS XmaDecoder::Setup(kernel::KernelState* kernel_state) { sizeof(XMA_CONTEXT_DATA) * kContextCount, 256, kSystemHeapPhysical); context_data_last_ptr_ = context_data_first_ptr_ + (sizeof(XMA_CONTEXT_DATA) * kContextCount - 1); - registers_.context_array_ptr = context_data_first_ptr_; + register_file_[XE_XMA_REG_CONTEXT_ARRAY_ADDRESS].u32 = + context_data_first_ptr_; // Setup XMA contexts. for (int i = 0; i < kContextCount; ++i) { - uint32_t guest_ptr = - registers_.context_array_ptr + i * sizeof(XMA_CONTEXT_DATA); + uint32_t guest_ptr = context_data_first_ptr_ + i * sizeof(XMA_CONTEXT_DATA); XmaContext& context = contexts_[i]; if (context.Setup(i, memory(), guest_ptr)) { assert_always(); } } - registers_.next_context = 1; + register_file_[XE_XMA_REG_NEXT_CONTEXT_INDEX].u32 = 1; context_bitmap_.Resize(kContextCount); worker_running_ = true; @@ -185,11 +185,16 @@ void XmaDecoder::Shutdown() { xe::threading::Wait(worker_thread_->thread(), false); worker_thread_.reset(); - memory()->SystemHeapFree(registers_.context_array_ptr); + if (context_data_first_ptr_) { + memory()->SystemHeapFree(context_data_first_ptr_); + } + + context_data_first_ptr_ = 0; + context_data_last_ptr_ = 0; } int XmaDecoder::GetContextId(uint32_t guest_ptr) { - static_assert(sizeof(XMA_CONTEXT_DATA) == 64, "FIXME"); + static_assert_size(XMA_CONTEXT_DATA, 64); if (guest_ptr < context_data_first_ptr_ || guest_ptr > context_data_last_ptr_) { return -1; @@ -229,51 +234,70 @@ bool XmaDecoder::BlockOnContext(uint32_t guest_ptr, bool poll) { return context.Block(poll); } -// free60 may be useful here, however it looks like it's using a different -// piece of hardware: -// https://github.com/Free60Project/libxenon/blob/master/libxenon/drivers/xenon_sound/sound.c - uint32_t XmaDecoder::ReadRegister(uint32_t addr) { - uint32_t r = addr & 0xFFFF; - // 1800h is read on startup and stored -- context? buffers? - // 1818h is read during a lock? + uint32_t r = (addr & 0xFFFF) / 4; - assert_true(r % 4 == 0); - uint32_t value = register_file_[r / 4]; - - // 1818 is rotating context processing # set to hardware ID of context being - // processed. - // If bit 200h is set, the locking code will possibly collide on hardware IDs - // and error out, so we should never set it (I think?). - if (r == 0x1818) { - // To prevent games from seeing a stuck XMA context, return a rotating - // number - registers_.current_context = registers_.next_context; - registers_.next_context = (registers_.next_context + 1) % kContextCount; + switch (r) { + default: { + if (!register_file_.GetRegisterInfo(r)) { + XELOGE("XMA: Read from unknown register (%.4X)", r); + } + } +#pragma warning(suppress : 4065) } - value = xe::byte_swap(value); - return value; + assert_true(r < XmaRegisterFile::kRegisterCount); + + // 0606h (1818h) is rotating context processing # set to hardware ID of + // context being processed. + // If bit 200h is set, the locking code will possibly collide on hardware IDs + // and error out, so we should never set it (I think?). + if (r == XE_XMA_REG_CURRENT_CONTEXT_INDEX) { + // To prevent games from seeing a stuck XMA context, return a rotating + // number + uint32_t next_context_index = + register_file_[XE_XMA_REG_NEXT_CONTEXT_INDEX].u32; + register_file_[XE_XMA_REG_CURRENT_CONTEXT_INDEX].u32 = next_context_index; + register_file_[XE_XMA_REG_NEXT_CONTEXT_INDEX].u32 = + (next_context_index + 1) % kContextCount; + } + + return xe::byte_swap(register_file_.values[r].u32); } void XmaDecoder::WriteRegister(uint32_t addr, uint32_t value) { SCOPE_profile_cpu_f("apu"); - uint32_t r = addr & 0xFFFF; + uint32_t r = (addr & 0xFFFF) / 4; value = xe::byte_swap(value); - // 1804h is written to with 0x02000000 and 0x03000000 around a lock operation - assert_true(r % 4 == 0); - register_file_[r / 4] = uint32_t(value); + if ((r >= XE_XMA_REG_CONTEXT_KICK_0 && r <= XE_XMA_REG_CONTEXT_KICK_9) || + (r >= XE_XMA_REG_CONTEXT_LOCK_0 && r <= XE_XMA_REG_CONTEXT_LOCK_9) || + (r >= XE_XMA_REG_CONTEXT_CLEAR_0 && r <= XE_XMA_REG_CONTEXT_CLEAR_9)) { + } else { + switch (r) { + default: { + XELOGE("XMA: Write to unhandled register (%.4X): %.8X", r, value); + break; + } +#pragma warning(suppress : 4065) + } + } - if (r >= 0x1940 && r <= 0x1940 + 9 * 4) { + // 0601h (1804h) is written to with 0x02000000 and 0x03000000 around a lock + // operation + + assert_true(r < XmaRegisterFile::kRegisterCount); + register_file_.values[r].u32 = value; + + if (r >= XE_XMA_REG_CONTEXT_KICK_0 && r <= XE_XMA_REG_CONTEXT_KICK_9) { // Context kick command. // This will kick off the given hardware contexts. // Basically, this kicks the SPU and says "hey, decode that audio!" // XMAEnableContext // The context ID is a bit in the range of the entire context array. - uint32_t base_context_id = (r - 0x1940) / 4 * 32; + uint32_t base_context_id = (r - XE_XMA_REG_CONTEXT_KICK_0) * 32; for (int i = 0; value && i < 32; ++i, value >>= 1) { if (value & 1) { uint32_t context_id = base_context_id + i; @@ -284,11 +308,11 @@ void XmaDecoder::WriteRegister(uint32_t addr, uint32_t value) { // Signal the decoder thread to start processing. work_event_->Set(); - } else if (r >= 0x1A40 && r <= 0x1A40 + 9 * 4) { + } else if (r >= XE_XMA_REG_CONTEXT_LOCK_0 && r <= XE_XMA_REG_CONTEXT_LOCK_9) { // Context lock command. // This requests a lock by flagging the context. // XMADisableContext - uint32_t base_context_id = (r - 0x1A40) / 4 * 32; + uint32_t base_context_id = (r - XE_XMA_REG_CONTEXT_LOCK_0) * 32; for (int i = 0; value && i < 32; ++i, value >>= 1) { if (value & 1) { uint32_t context_id = base_context_id + i; @@ -299,10 +323,11 @@ void XmaDecoder::WriteRegister(uint32_t addr, uint32_t value) { // Signal the decoder thread to start processing. work_event_->Set(); - } else if (r >= 0x1A80 && r <= 0x1A80 + 9 * 4) { + } else if (r >= XE_XMA_REG_CONTEXT_CLEAR_0 && + r <= XE_XMA_REG_CONTEXT_CLEAR_9) { // Context clear command. // This will reset the given hardware contexts. - uint32_t base_context_id = (r - 0x1A80) / 4 * 32; + uint32_t base_context_id = (r - XE_XMA_REG_CONTEXT_CLEAR_0) * 32; for (int i = 0; value && i < 32; ++i, value >>= 1) { if (value & 1) { uint32_t context_id = base_context_id + i; diff --git a/src/xenia/apu/xma_decoder.h b/src/xenia/apu/xma_decoder.h index 8312b820d..228a7290d 100644 --- a/src/xenia/apu/xma_decoder.h +++ b/src/xenia/apu/xma_decoder.h @@ -15,6 +15,7 @@ #include #include "xenia/apu/xma_context.h" +#include "xenia/apu/xma_register_file.h" #include "xenia/base/bit_map.h" #include "xenia/kernel/xthread.h" #include "xenia/xbox.h" @@ -35,7 +36,9 @@ class XmaDecoder { X_STATUS Setup(kernel::KernelState* kernel_state); void Shutdown(); - uint32_t context_array_ptr() const { return registers_.context_array_ptr; } + uint32_t context_array_ptr() const { + return register_file_.values[XE_XMA_REG_CONTEXT_ARRAY_ADDRESS].u32; + } uint32_t AllocateContext(); void ReleaseContext(uint32_t guest_ptr); @@ -75,26 +78,7 @@ class XmaDecoder { xe::threading::Fence pause_fence_; // Signaled when worker paused. xe::threading::Fence resume_fence_; // Signaled when resume requested. - // Stored little endian, accessed through 0x7FEA.... - union { - struct { - union { - struct { - uint8_t ignored0[0x1800]; - // 1800h; points to guest-space physical block of 320 contexts. - uint32_t context_array_ptr; - }; - struct { - uint8_t ignored1[0x1818]; - // 1818h; current context ID. - uint32_t current_context; - // 181Ch; next context ID to process. - uint32_t next_context; - }; - }; - } registers_; - uint32_t register_file_[0xFFFF / 4]; - }; + XmaRegisterFile register_file_; static const uint32_t kContextCount = 320; XmaContext contexts_[kContextCount]; diff --git a/src/xenia/apu/xma_register_file.cc b/src/xenia/apu/xma_register_file.cc new file mode 100644 index 000000000..d3383b9cb --- /dev/null +++ b/src/xenia/apu/xma_register_file.cc @@ -0,0 +1,39 @@ +/** + ****************************************************************************** + * 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/apu/xma_register_file.h" + +#include + +#include "xenia/base/math.h" + +namespace xe { +namespace apu { + +XmaRegisterFile::XmaRegisterFile() { std::memset(values, 0, sizeof(values)); } + +const XmaRegisterInfo* XmaRegisterFile::GetRegisterInfo(uint32_t index) { + switch (index) { +#define XE_XMA_REGISTER(index, type, name) \ + case index: { \ + static const XmaRegisterInfo reg_info = { \ + XmaRegisterInfo::Type::type, \ + #name, \ + }; \ + return ®_info; \ + } +#include "xenia/apu/xma_register_table.inc" +#undef XE_XMA_REGISTER + default: + return nullptr; + } +} + +} // namespace apu +} // namespace xe diff --git a/src/xenia/apu/xma_register_file.h b/src/xenia/apu/xma_register_file.h new file mode 100644 index 000000000..09154b9ad --- /dev/null +++ b/src/xenia/apu/xma_register_file.h @@ -0,0 +1,54 @@ +/** + ****************************************************************************** + * 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_APU_XMA_REGISTER_FILE_H_ +#define XENIA_APU_XMA_REGISTER_FILE_H_ + +#include +#include + +namespace xe { +namespace apu { + +enum XmaRegister { +#define XE_XMA_REGISTER(index, type, name) XE_XMA_REG_##name = index, +#include "xenia/apu/xma_register_table.inc" +#undef XE_XMA_REGISTER +}; + +struct XmaRegisterInfo { + enum class Type { + kDword, + kFloat, + }; + Type type; + const char* name; +}; + +class XmaRegisterFile { + public: + XmaRegisterFile(); + + static const XmaRegisterInfo* GetRegisterInfo(uint32_t index); + + static const size_t kRegisterCount = (0xFFFF + 1) / 4; + union RegisterValue { + uint32_t u32; + float f32; + }; + RegisterValue values[kRegisterCount]; + + RegisterValue& operator[](int reg) { return values[reg]; } + RegisterValue& operator[](XmaRegister reg) { return values[reg]; } +}; + +} // namespace apu +} // namespace xe + +#endif // XENIA_APU_XMA_REGISTER_FILE_H_ diff --git a/src/xenia/apu/xma_register_table.inc b/src/xenia/apu/xma_register_table.inc new file mode 100644 index 000000000..49b32e26f --- /dev/null +++ b/src/xenia/apu/xma_register_table.inc @@ -0,0 +1,51 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +// This is a partial file designed to be included by other files when +// constructing various tables. + +//#define XE_XMA_REGISTER(index, type, name) + +XE_XMA_REGISTER(0x0600, kDword, CONTEXT_ARRAY_ADDRESS) + +XE_XMA_REGISTER(0x0606, kDword, CURRENT_CONTEXT_INDEX) +XE_XMA_REGISTER(0x0607, kDword, NEXT_CONTEXT_INDEX) + +XE_XMA_REGISTER(0x0650, kDword, CONTEXT_KICK_0) +XE_XMA_REGISTER(0x0651, kDword, CONTEXT_KICK_1) +XE_XMA_REGISTER(0x0652, kDword, CONTEXT_KICK_2) +XE_XMA_REGISTER(0x0653, kDword, CONTEXT_KICK_3) +XE_XMA_REGISTER(0x0654, kDword, CONTEXT_KICK_4) +XE_XMA_REGISTER(0x0655, kDword, CONTEXT_KICK_5) +XE_XMA_REGISTER(0x0656, kDword, CONTEXT_KICK_6) +XE_XMA_REGISTER(0x0657, kDword, CONTEXT_KICK_7) +XE_XMA_REGISTER(0x0658, kDword, CONTEXT_KICK_8) +XE_XMA_REGISTER(0x0659, kDword, CONTEXT_KICK_9) + +XE_XMA_REGISTER(0x0690, kDword, CONTEXT_LOCK_0) +XE_XMA_REGISTER(0x0691, kDword, CONTEXT_LOCK_1) +XE_XMA_REGISTER(0x0692, kDword, CONTEXT_LOCK_2) +XE_XMA_REGISTER(0x0693, kDword, CONTEXT_LOCK_3) +XE_XMA_REGISTER(0x0694, kDword, CONTEXT_LOCK_4) +XE_XMA_REGISTER(0x0695, kDword, CONTEXT_LOCK_5) +XE_XMA_REGISTER(0x0696, kDword, CONTEXT_LOCK_6) +XE_XMA_REGISTER(0x0697, kDword, CONTEXT_LOCK_7) +XE_XMA_REGISTER(0x0698, kDword, CONTEXT_LOCK_8) +XE_XMA_REGISTER(0x0699, kDword, CONTEXT_LOCK_9) + +XE_XMA_REGISTER(0x06A0, kDword, CONTEXT_CLEAR_0) +XE_XMA_REGISTER(0x06A1, kDword, CONTEXT_CLEAR_1) +XE_XMA_REGISTER(0x06A2, kDword, CONTEXT_CLEAR_2) +XE_XMA_REGISTER(0x06A3, kDword, CONTEXT_CLEAR_3) +XE_XMA_REGISTER(0x06A4, kDword, CONTEXT_CLEAR_4) +XE_XMA_REGISTER(0x06A5, kDword, CONTEXT_CLEAR_5) +XE_XMA_REGISTER(0x06A6, kDword, CONTEXT_CLEAR_6) +XE_XMA_REGISTER(0x06A7, kDword, CONTEXT_CLEAR_7) +XE_XMA_REGISTER(0x06A8, kDword, CONTEXT_CLEAR_8) +XE_XMA_REGISTER(0x06A9, kDword, CONTEXT_CLEAR_9) From 4ceafcdf684ca6a9a179c58db7d7f95d30a94b22 Mon Sep 17 00:00:00 2001 From: gibbed Date: Sat, 20 Apr 2019 13:21:36 -0500 Subject: [PATCH 02/11] [UI] Reduce SetProcessDpiAwareness failure to warning. --- src/xenia/ui/window_win.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xenia/ui/window_win.cc b/src/xenia/ui/window_win.cc index 68c13c94b..f1016a65e 100644 --- a/src/xenia/ui/window_win.cc +++ b/src/xenia/ui/window_win.cc @@ -63,7 +63,7 @@ bool Win32Window::OnCreate() { auto spda = (decltype(&SetProcessDpiAwareness))SetProcessDpiAwareness_; auto res = spda(PROCESS_PER_MONITOR_DPI_AWARE); if (res != S_OK) { - XELOGE("Failed to set process DPI awareness. (code = 0x%.8X)", res); + XELOGW("Failed to set process DPI awareness. (code = 0x%.8X)", res); } } From b69dd271df6aa8db88322e654e62137e064b67f8 Mon Sep 17 00:00:00 2001 From: Rick Gibbed Date: Sun, 21 Apr 2019 00:00:16 -0500 Subject: [PATCH 03/11] Fix link to compat labeled-issues. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 69c32dfc0..4e323263a 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ is wide open greenfield fun. Fixes and optimizations are always welcome (please!), but in addition to that there are some major work areas still untouched: -* Help work through missing functionality/bugs in game [compat](https://github.com/xenia-project/xenia/issues?labels=compat) +* Help work through [missing functionality/bugs in games](https://github.com/xenia-project/xenia/labels/compat) * Add input drivers for [PS4 controllers](https://github.com/xenia-project/xenia/issues/60) (or anything else) * Skilled with Linux? A strong contributor is needed to [help with porting](https://github.com/xenia-project/xenia/labels/cross%20platform) From 3b421f0811925b86c84a15f872e51c681f10ec00 Mon Sep 17 00:00:00 2001 From: gibbed Date: Sun, 21 Apr 2019 22:17:16 -0500 Subject: [PATCH 04/11] Update building requirements in documentation. --- README.md | 2 +- docs/building.md | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4e323263a..7f2ba63be 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ legally purchased devices and games and information made public on the internet ## Quickstart -Windows 8.1+ with Python 3.4 and [Visual Studio 2017](https://www.visualstudio.com/downloads/) and the Windows SDKs installed: +With Windows 8+, Python 3.4+, and [Visual Studio 2017 or 2019](https://www.visualstudio.com/downloads/) and the Windows SDKs installed: > git clone https://github.com/xenia-project/xenia.git > cd xenia diff --git a/docs/building.md b/docs/building.md index 6552de6a4..58b89bc22 100644 --- a/docs/building.md +++ b/docs/building.md @@ -9,10 +9,9 @@ video drivers for your card. ### Windows * Windows 8 or later -* Visual Studio 2017 -* Windows Universal CRT SDK +* [Visual Studio 2017 or Visual Studio 2019](https://www.visualstudio.com/downloads/) * [Python 3.4+](https://www.python.org/downloads/) -* You will also need the [Windows 8.1 SDK](https://msdn.microsoft.com/en-us/windows/desktop/bg162891) +* You may also need the [Windows 8.1 SDK](https://msdn.microsoft.com/en-us/windows/desktop/bg162891) * (for VS2017 just click the Windows 8.1 SDK option in the Individual Components section in the Visual Studio Installer) Ensure Python is in your PATH. From 2c3207e5cce05452cd9a89dbda555383015ee75d Mon Sep 17 00:00:00 2001 From: gibbed Date: Tue, 30 Apr 2019 16:30:17 -0500 Subject: [PATCH 05/11] [Base] Widen LaunchBrowser. --- src/xenia/base/platform.h | 2 +- src/xenia/base/platform_linux.cc | 4 ++-- src/xenia/base/platform_win.cc | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/xenia/base/platform.h b/src/xenia/base/platform.h index 55b8c59e7..54caae98f 100644 --- a/src/xenia/base/platform.h +++ b/src/xenia/base/platform.h @@ -103,7 +103,7 @@ const size_t kMaxPath = 1024; // PATH_MAX #endif // XE_PLATFORM_WIN32 // Launches a web browser to the given URL. -void LaunchBrowser(const char* url); +void LaunchBrowser(const wchar_t* url); } // namespace xe diff --git a/src/xenia/base/platform_linux.cc b/src/xenia/base/platform_linux.cc index b90c6f78e..45c52b22a 100644 --- a/src/xenia/base/platform_linux.cc +++ b/src/xenia/base/platform_linux.cc @@ -13,8 +13,8 @@ namespace xe { -void LaunchBrowser(const char* url) { - auto cmd = std::string("xdg-open " + std::string(url)); +void LaunchBrowser(const wchar_t* url) { + auto cmd = std::string("xdg-open " + xe::to_string(url)); system(cmd.c_str()); } diff --git a/src/xenia/base/platform_win.cc b/src/xenia/base/platform_win.cc index 157fefd52..5b1b9c7e5 100644 --- a/src/xenia/base/platform_win.cc +++ b/src/xenia/base/platform_win.cc @@ -11,8 +11,8 @@ namespace xe { -void LaunchBrowser(const char* url) { - ShellExecuteA(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL); +void LaunchBrowser(const wchar_t* url) { + ShellExecuteW(NULL, L"open", url, NULL, NULL, SW_SHOWNORMAL); } } // namespace xe From cfa0a403434aea36d476382053c0ce213b9a661b Mon Sep 17 00:00:00 2001 From: gibbed Date: Tue, 30 Apr 2019 16:30:47 -0500 Subject: [PATCH 06/11] [App] Add "Show content directory..." menu item. --- src/xenia/app/emulator_window.cc | 43 ++++++++++++++++++++++++++------ src/xenia/app/emulator_window.h | 1 + 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/xenia/app/emulator_window.cc b/src/xenia/app/emulator_window.cc index 333d854f7..98bb3bf5d 100644 --- a/src/xenia/app/emulator_window.cc +++ b/src/xenia/app/emulator_window.cc @@ -181,6 +181,11 @@ bool EmulatorWindow::Initialize() { file_menu->AddChild( MenuItem::Create(MenuItem::Type::kString, L"Close", std::bind(&EmulatorWindow::FileClose, this))); + file_menu->AddChild(MenuItem::Create(MenuItem::Type::kSeparator)); + file_menu->AddChild(MenuItem::Create( + MenuItem::Type::kString, L"Show content directory...", + std::bind(&EmulatorWindow::ShowContentDirectory, this))); + file_menu->AddChild(MenuItem::Create(MenuItem::Type::kSeparator)); file_menu->AddChild(MenuItem::Create(MenuItem::Type::kString, L"E&xit", L"Alt+F4", [this]() { window_->Close(); })); @@ -251,16 +256,17 @@ bool EmulatorWindow::Initialize() { { help_menu->AddChild(MenuItem::Create( MenuItem::Type::kString, L"Build commit on GitHub...", [this]() { - std::string url = - std::string("https://github.com/benvanik/xenia/tree/") + - XE_BUILD_COMMIT + "/"; + std::wstring url = + std::wstring(L"https://github.com/xenia-project/xenia/tree/") + + xe::to_wstring(XE_BUILD_COMMIT) + L"/"; LaunchBrowser(url.c_str()); })); help_menu->AddChild(MenuItem::Create( MenuItem::Type::kString, L"Recent changes on GitHub...", [this]() { - std::string url = - std::string("https://github.com/benvanik/xenia/compare/") + - XE_BUILD_COMMIT + "..." + XE_BUILD_BRANCH; + std::wstring url = + std::wstring(L"https://github.com/xenia-project/xenia/compare/") + + xe::to_wstring(XE_BUILD_COMMIT) + L"..." + + xe::to_wstring(XE_BUILD_BRANCH); LaunchBrowser(url.c_str()); })); help_menu->AddChild(MenuItem::Create(MenuItem::Type::kSeparator)); @@ -269,7 +275,7 @@ bool EmulatorWindow::Initialize() { std::bind(&EmulatorWindow::ShowHelpWebsite, this))); help_menu->AddChild(MenuItem::Create( MenuItem::Type::kString, L"&About...", - [this]() { LaunchBrowser("https://xenia.jp/about/"); })); + [this]() { LaunchBrowser(L"https://xenia.jp/about/"); })); } main_menu->AddChild(std::move(help_menu)); @@ -331,6 +337,27 @@ void EmulatorWindow::FileClose() { } } +void EmulatorWindow::ShowContentDirectory() { + std::wstring target_path; + + auto content_root = emulator_->content_root(); + if (!emulator_->is_title_open() || !emulator_->kernel_state()) { + target_path = content_root; + } else { + // TODO(gibbed): expose this via ContentManager? + wchar_t title_id[9] = L"00000000"; + std::swprintf(title_id, 9, L"%.8X", emulator_->kernel_state()->title_id()); + auto package_root = xe::join_paths(content_root, title_id); + target_path = package_root; + } + + if (!xe::filesystem::PathExists(target_path)) { + xe::filesystem::CreateFolder(target_path); + } + + LaunchBrowser(target_path.c_str()); +} + void EmulatorWindow::CheckHideCursor() { if (!window_->is_fullscreen()) { // Only hide when fullscreen. @@ -395,7 +422,7 @@ void EmulatorWindow::ToggleFullscreen() { } } -void EmulatorWindow::ShowHelpWebsite() { LaunchBrowser("https://xenia.jp"); } +void EmulatorWindow::ShowHelpWebsite() { LaunchBrowser(L"https://xenia.jp"); } void EmulatorWindow::UpdateTitle() { std::wstring title(base_title_); diff --git a/src/xenia/app/emulator_window.h b/src/xenia/app/emulator_window.h index 758f079f1..897bc2293 100644 --- a/src/xenia/app/emulator_window.h +++ b/src/xenia/app/emulator_window.h @@ -46,6 +46,7 @@ class EmulatorWindow { void FileDrop(wchar_t* filename); void FileOpen(); void FileClose(); + void ShowContentDirectory(); void CheckHideCursor(); void CpuTimeScalarReset(); void CpuTimeScalarSetHalf(); From 6b772c01b94f366539807a9f5e6f48edcb4375d4 Mon Sep 17 00:00:00 2001 From: gibbed Date: Tue, 30 Apr 2019 16:44:00 -0500 Subject: [PATCH 07/11] [Base] Oops. Fix missing include. --- src/xenia/base/platform_linux.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xenia/base/platform_linux.cc b/src/xenia/base/platform_linux.cc index 45c52b22a..25946de87 100644 --- a/src/xenia/base/platform_linux.cc +++ b/src/xenia/base/platform_linux.cc @@ -8,6 +8,7 @@ */ #include "xenia/base/platform_linux.h" +#include "xenia/base/string.h" #include #include From 179883dc0ab11ac0b08911080acfe931fe67d3d9 Mon Sep 17 00:00:00 2001 From: gibbed Date: Tue, 30 Apr 2019 16:44:44 -0500 Subject: [PATCH 08/11] [App] Fix "Open" menu item text. --- src/xenia/app/emulator_window.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xenia/app/emulator_window.cc b/src/xenia/app/emulator_window.cc index 98bb3bf5d..e15a97da9 100644 --- a/src/xenia/app/emulator_window.cc +++ b/src/xenia/app/emulator_window.cc @@ -176,7 +176,7 @@ bool EmulatorWindow::Initialize() { auto file_menu = MenuItem::Create(MenuItem::Type::kPopup, L"&File"); { file_menu->AddChild( - MenuItem::Create(MenuItem::Type::kString, L"&Open", L"Ctrl+O", + MenuItem::Create(MenuItem::Type::kString, L"&Open...", L"Ctrl+O", std::bind(&EmulatorWindow::FileOpen, this))); file_menu->AddChild( MenuItem::Create(MenuItem::Type::kString, L"Close", From bc0ebcb26e2fe1bace4d274d1c957e2abac76ff2 Mon Sep 17 00:00:00 2001 From: gibbed Date: Tue, 30 Apr 2019 17:40:24 -0500 Subject: [PATCH 09/11] - Clean up log level names, no need for LOG_LEVEL_ prefix when it is an enum class. - Clarify usage of log level in comment. --- src/xenia/apu/xma_decoder.cc | 10 +++---- src/xenia/base/logging.cc | 2 +- src/xenia/base/logging.h | 36 +++++++++++++----------- src/xenia/cpu/backend/x64/x64_tracers.cc | 7 ++--- src/xenia/kernel/util/shim_utils.h | 4 +-- 5 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/xenia/apu/xma_decoder.cc b/src/xenia/apu/xma_decoder.cc index 778e0105d..bb8e46756 100644 --- a/src/xenia/apu/xma_decoder.cc +++ b/src/xenia/apu/xma_decoder.cc @@ -69,23 +69,23 @@ void av_log_callback(void* avcl, int level, const char* fmt, va_list va) { switch (level) { case AV_LOG_ERROR: level_char = '!'; - log_level = xe::LogLevel::LOG_LEVEL_ERROR; + log_level = xe::LogLevel::Error; break; case AV_LOG_WARNING: level_char = 'w'; - log_level = xe::LogLevel::LOG_LEVEL_WARNING; + log_level = xe::LogLevel::Warning; break; case AV_LOG_INFO: level_char = 'i'; - log_level = xe::LogLevel::LOG_LEVEL_INFO; + log_level = xe::LogLevel::Info; break; case AV_LOG_VERBOSE: level_char = 'v'; - log_level = xe::LogLevel::LOG_LEVEL_DEBUG; + log_level = xe::LogLevel::Debug; break; case AV_LOG_DEBUG: level_char = 'd'; - log_level = xe::LogLevel::LOG_LEVEL_DEBUG; + log_level = xe::LogLevel::Debug; break; } diff --git a/src/xenia/base/logging.cc b/src/xenia/base/logging.cc index 10f3065d5..dc4520e9d 100644 --- a/src/xenia/base/logging.cc +++ b/src/xenia/base/logging.cc @@ -315,7 +315,7 @@ void LogLine(LogLevel log_level, const char prefix_char, void FatalError(const char* fmt, ...) { va_list args; va_start(args, fmt); - LogLineVarargs(LogLevel::LOG_LEVEL_ERROR, 'X', fmt, args); + LogLineVarargs(LogLevel::Error, 'X', fmt, args); va_end(args); #if XE_PLATFORM_WIN32 diff --git a/src/xenia/base/logging.h b/src/xenia/base/logging.h index 2a2d67284..a029dee96 100644 --- a/src/xenia/base/logging.h +++ b/src/xenia/base/logging.h @@ -19,11 +19,17 @@ namespace xe { #define XE_OPTION_ENABLE_LOGGING 1 +// Log level is a general indication of the importance of a given log line. +// +// While log levels are named, they are a rough correlation of what the log line +// may be related to. These names should not be taken as fact as what a given +// log line from any log level actually is. enum class LogLevel { - LOG_LEVEL_ERROR, - LOG_LEVEL_WARNING, - LOG_LEVEL_INFO, - LOG_LEVEL_DEBUG, + Error = 0, + Warning, + Info, + Debug, + Trace, }; // Initializes the logging system and any outputs requested. @@ -56,25 +62,21 @@ void FatalError(const std::string& str); } while (false) #endif // ENABLE_LOGGING -#define XELOGE(fmt, ...) \ - XELOGCORE(xe::LogLevel::LOG_LEVEL_ERROR, '!', fmt, ##__VA_ARGS__) +#define XELOGE(fmt, ...) XELOGCORE(xe::LogLevel::Error, '!', fmt, ##__VA_ARGS__) #define XELOGW(fmt, ...) \ - XELOGCORE(xe::LogLevel::LOG_LEVEL_WARNING, 'w', fmt, ##__VA_ARGS__) -#define XELOGI(fmt, ...) \ - XELOGCORE(xe::LogLevel::LOG_LEVEL_INFO, 'i', fmt, ##__VA_ARGS__) -#define XELOGD(fmt, ...) \ - XELOGCORE(xe::LogLevel::LOG_LEVEL_DEBUG, 'd', fmt, ##__VA_ARGS__) + XELOGCORE(xe::LogLevel::Warning, 'w', fmt, ##__VA_ARGS__) +#define XELOGI(fmt, ...) XELOGCORE(xe::LogLevel::Info, 'i', fmt, ##__VA_ARGS__) +#define XELOGD(fmt, ...) XELOGCORE(xe::LogLevel::Debug, 'd', fmt, ##__VA_ARGS__) #define XELOGCPU(fmt, ...) \ - XELOGCORE(xe::LogLevel::LOG_LEVEL_INFO, 'C', fmt, ##__VA_ARGS__) + XELOGCORE(xe::LogLevel::Info, 'C', fmt, ##__VA_ARGS__) #define XELOGAPU(fmt, ...) \ - XELOGCORE(xe::LogLevel::LOG_LEVEL_INFO, 'A', fmt, ##__VA_ARGS__) + XELOGCORE(xe::LogLevel::Info, 'A', fmt, ##__VA_ARGS__) #define XELOGGPU(fmt, ...) \ - XELOGCORE(xe::LogLevel::LOG_LEVEL_INFO, 'G', fmt, ##__VA_ARGS__) + XELOGCORE(xe::LogLevel::Info, 'G', fmt, ##__VA_ARGS__) #define XELOGKERNEL(fmt, ...) \ - XELOGCORE(xe::LogLevel::LOG_LEVEL_INFO, 'K', fmt, ##__VA_ARGS__) -#define XELOGFS(fmt, ...) \ - XELOGCORE(xe::LogLevel::LOG_LEVEL_INFO, 'F', fmt, ##__VA_ARGS__) + XELOGCORE(xe::LogLevel::Info, 'K', fmt, ##__VA_ARGS__) +#define XELOGFS(fmt, ...) XELOGCORE(xe::LogLevel::Info, 'F', fmt, ##__VA_ARGS__) } // namespace xe diff --git a/src/xenia/cpu/backend/x64/x64_tracers.cc b/src/xenia/cpu/backend/x64/x64_tracers.cc index 1b30aa16f..061728494 100644 --- a/src/xenia/cpu/backend/x64/x64_tracers.cc +++ b/src/xenia/cpu/backend/x64/x64_tracers.cc @@ -32,13 +32,12 @@ bool trace_enabled = true; #define THREAD_MATCH \ (!TARGET_THREAD || thread_state->thread_id() == TARGET_THREAD) #define IFLUSH() -#define IPRINT(s) \ - if (trace_enabled && THREAD_MATCH) \ - xe::LogLine(xe::LogLevel::LOG_LEVEL_DEBUG, 't', s) +#define IPRINT(s) \ + if (trace_enabled && THREAD_MATCH) xe::LogLine(xe::LogLevel::Debug, 't', s) #define DFLUSH() #define DPRINT(...) \ if (trace_enabled && THREAD_MATCH) \ - xe::LogLineFormat(xe::LogLevel::LOG_LEVEL_DEBUG, 't', __VA_ARGS__) + xe::LogLineFormat(xe::LogLevel::Debug, 't', __VA_ARGS__) uint32_t GetTracingMode() { uint32_t mode = 0; diff --git a/src/xenia/kernel/util/shim_utils.h b/src/xenia/kernel/util/shim_utils.h index 0809a660e..73c4ca62f 100644 --- a/src/xenia/kernel/util/shim_utils.h +++ b/src/xenia/kernel/util/shim_utils.h @@ -451,10 +451,10 @@ void PrintKernelCall(cpu::Export* export_entry, const Tuple& params) { AppendKernelCallParams(string_buffer, export_entry, params); string_buffer.Append(')'); if (export_entry->tags & xe::cpu::ExportTag::kImportant) { - xe::LogLine(xe::LogLevel::LOG_LEVEL_INFO, 'i', string_buffer.GetString(), + xe::LogLine(xe::LogLevel::Info, 'i', string_buffer.GetString(), string_buffer.length()); } else { - xe::LogLine(xe::LogLevel::LOG_LEVEL_DEBUG, 'd', string_buffer.GetString(), + xe::LogLine(xe::LogLevel::Debug, 'd', string_buffer.GetString(), string_buffer.length()); } } From 7ddcd4e32d90ad7adf543909219dc0828a31fe01 Mon Sep 17 00:00:00 2001 From: gibbed Date: Tue, 30 Apr 2019 17:45:45 -0500 Subject: [PATCH 10/11] Oops. Missed a log line for previous two commits. --- src/xenia/kernel/user_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xenia/kernel/user_module.cc b/src/xenia/kernel/user_module.cc index 7d0b6dbe6..6a4bb846d 100644 --- a/src/xenia/kernel/user_module.cc +++ b/src/xenia/kernel/user_module.cc @@ -804,7 +804,7 @@ void UserModule::Dump() { sb.AppendFormat("\n"); } - xe::LogLine(xe::LogLevel::LOG_LEVEL_INFO, 'i', sb.GetString()); + xe::LogLine(xe::LogLevel::Info, 'i', sb.GetString()); } } // namespace kernel From bc9d82e2b0a6d3ccc899f4588857a6913326a024 Mon Sep 17 00:00:00 2001 From: gibbed Date: Tue, 30 Apr 2019 18:16:20 -0500 Subject: [PATCH 11/11] [Base] Fix Travis whining. --- src/xenia/base/platform_linux.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xenia/base/platform_linux.cc b/src/xenia/base/platform_linux.cc index 25946de87..aae0c7e21 100644 --- a/src/xenia/base/platform_linux.cc +++ b/src/xenia/base/platform_linux.cc @@ -8,9 +8,9 @@ */ #include "xenia/base/platform_linux.h" -#include "xenia/base/string.h" #include #include +#include "xenia/base/string.h" namespace xe {