diff --git a/README.md b/README.md index 69c32dfc0..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 @@ -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) 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. diff --git a/src/xenia/app/emulator_window.cc b/src/xenia/app/emulator_window.cc index 333d854f7..e15a97da9 100644 --- a/src/xenia/app/emulator_window.cc +++ b/src/xenia/app/emulator_window.cc @@ -176,11 +176,16 @@ 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", 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(); diff --git a/src/xenia/apu/xma_decoder.cc b/src/xenia/apu/xma_decoder.cc index 9767d66c7..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; } @@ -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) 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/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..aae0c7e21 100644 --- a/src/xenia/base/platform_linux.cc +++ b/src/xenia/base/platform_linux.cc @@ -10,11 +10,12 @@ #include "xenia/base/platform_linux.h" #include #include +#include "xenia/base/string.h" 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 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/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 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()); } } 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); } }