diff --git a/src/xenia/base/logging.cc b/src/xenia/base/logging.cc index 9a565fd64..ffb9d049b 100644 --- a/src/xenia/base/logging.cc +++ b/src/xenia/base/logging.cc @@ -36,10 +36,8 @@ #include "third_party/fmt/include/fmt/format.h" -DEFINE_path( - log_file, "", - "Logs are written to the given file (specify stdout for command line)", - "Logging"); +DEFINE_path(log_file, "", "Logs are written to the given file", "Logging"); +DEFINE_bool(log_to_stdout, false, "Write log output to stdout", "Logging"); DEFINE_bool(log_to_debugprint, false, "Dump the log to DebugPrint.", "Logging"); DEFINE_bool(flush_log, true, "Flush log file after each log line batch.", "Logging"); @@ -66,10 +64,8 @@ struct LogLine { thread_local char thread_log_buffer_[64 * 1024]; - void FileLogSink::Write(const char* buf, size_t size) { if (file_) { - fwrite(buf, 1, size, file_); } } @@ -82,15 +78,12 @@ void FileLogSink::Flush() { class Logger { public: explicit Logger(const std::string_view app_name) - : - wait_strategy_(), + : wait_strategy_(), claim_strategy_(kBlockCount, wait_strategy_), consumed_(wait_strategy_), running_(true) { claim_strategy_.add_claim_barrier(consumed_); - - write_thread_ = xe::threading::Thread::Create({}, [this]() { WriteThread(); }); write_thread_->set_name("Logging Writer"); @@ -296,25 +289,26 @@ void InitializeLogging(const std::string_view app_name) { auto mem = memory::AlignedAlloc(0x10); logger_ = new (mem) Logger(app_name); - FILE* file = nullptr; + FILE* log_file = nullptr; - if (cvars::log_file.empty()) { + if (cvars::log_file.empty()) { // Default to app name. auto file_name = fmt::format("{}.log", app_name); auto file_path = std::filesystem::path(file_name); xe::filesystem::CreateParentFolder(file_path); - file = xe::filesystem::OpenFile(file_path, "wt"); + log_file = xe::filesystem::OpenFile(file_path, "wt"); } else { - if (cvars::log_file == "stdout") { - file = stdout; - } else { - xe::filesystem::CreateParentFolder(cvars::log_file); - file = xe::filesystem::OpenFile(cvars::log_file, "wt"); - } + xe::filesystem::CreateParentFolder(cvars::log_file); + log_file = xe::filesystem::OpenFile(cvars::log_file, "wt"); } - auto sink = std::make_unique(file); + auto sink = std::make_unique(log_file); logger_->AddLogSink(std::move(sink)); + + if (cvars::log_to_stdout) { + auto stdout_sink = std::make_unique(stdout); + logger_->AddLogSink(std::move(stdout_sink)); + } } void ShutdownLogging() { diff --git a/src/xenia/base/main_win.cc b/src/xenia/base/main_win.cc index 927b3ae5d..d61fe607b 100644 --- a/src/xenia/base/main_win.cc +++ b/src/xenia/base/main_win.cc @@ -29,6 +29,8 @@ DEFINE_bool(win32_high_freq, true, "Requests high performance from the NT kernel", "Kernel"); +DEFINE_bool(enable_console, false, "Open a console window with the main window", + "General"); namespace xe { @@ -37,27 +39,23 @@ bool has_console_attached_ = true; bool has_console_attached() { return has_console_attached_; } void AttachConsole() { - bool has_console = ::AttachConsole(ATTACH_PARENT_PROCESS) == TRUE; - if (!has_console) { - // We weren't launched from a console, so just return. - // We could alloc our own console, but meh: - // has_console = AllocConsole() == TRUE; - has_console_attached_ = false; + if (!cvars::enable_console) { return; } + + AllocConsole(); + has_console_attached_ = true; auto std_handle = (intptr_t)GetStdHandle(STD_OUTPUT_HANDLE); auto con_handle = _open_osfhandle(std_handle, _O_TEXT); auto fp = _fdopen(con_handle, "w"); - *stdout = *fp; - setvbuf(stdout, nullptr, _IONBF, 0); + freopen_s(&fp, "CONOUT$", "w", stdout); std_handle = (intptr_t)GetStdHandle(STD_ERROR_HANDLE); con_handle = _open_osfhandle(std_handle, _O_TEXT); fp = _fdopen(con_handle, "w"); - *stderr = *fp; - setvbuf(stderr, nullptr, _IONBF, 0); + freopen_s(&fp, "CONOUT$", "w", stderr); } static void RequestHighPerformance() { @@ -125,6 +123,10 @@ int Main() { return 1; } + // Attach a console so we can write output to stdout. If the user hasn't + // redirected output themselves it'll pop up a window. + xe::AttachConsole(); + // Setup COM on the main thread. // NOTE: this may fail if COM has already been initialized - that's OK. #pragma warning(suppress : 6031) @@ -163,10 +165,6 @@ int main(int argc_ignored, char** argv_ignored) { return xe::Main(); } // Used in windowed apps; automatically picked based on subsystem. int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR command_line, int) { - // Attach a console so we can write output to stdout. If the user hasn't - // redirected output themselves it'll pop up a window. - xe::AttachConsole(); - // Run normal entry point. return xe::Main(); }