[Base/Win] Add cvars to enable a console window to be shown with xenia

This commit is contained in:
Satori 2020-09-07 12:22:23 +01:00 committed by Rick Gibbed
parent 42b10209fe
commit 446837edb1
2 changed files with 26 additions and 34 deletions

View File

@ -36,10 +36,8 @@
#include "third_party/fmt/include/fmt/format.h" #include "third_party/fmt/include/fmt/format.h"
DEFINE_path( DEFINE_path(log_file, "", "Logs are written to the given file", "Logging");
log_file, "", DEFINE_bool(log_to_stdout, false, "Write log output to stdout", "Logging");
"Logs are written to the given file (specify stdout for command line)",
"Logging");
DEFINE_bool(log_to_debugprint, false, "Dump the log to DebugPrint.", "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.", DEFINE_bool(flush_log, true, "Flush log file after each log line batch.",
"Logging"); "Logging");
@ -66,10 +64,8 @@ struct LogLine {
thread_local char thread_log_buffer_[64 * 1024]; thread_local char thread_log_buffer_[64 * 1024];
void FileLogSink::Write(const char* buf, size_t size) { void FileLogSink::Write(const char* buf, size_t size) {
if (file_) { if (file_) {
fwrite(buf, 1, size, file_);
} }
} }
@ -82,15 +78,12 @@ void FileLogSink::Flush() {
class Logger { class Logger {
public: public:
explicit Logger(const std::string_view app_name) explicit Logger(const std::string_view app_name)
: : wait_strategy_(),
wait_strategy_(),
claim_strategy_(kBlockCount, wait_strategy_), claim_strategy_(kBlockCount, wait_strategy_),
consumed_(wait_strategy_), consumed_(wait_strategy_),
running_(true) { running_(true) {
claim_strategy_.add_claim_barrier(consumed_); claim_strategy_.add_claim_barrier(consumed_);
write_thread_ = write_thread_ =
xe::threading::Thread::Create({}, [this]() { WriteThread(); }); xe::threading::Thread::Create({}, [this]() { WriteThread(); });
write_thread_->set_name("Logging Writer"); write_thread_->set_name("Logging Writer");
@ -296,25 +289,26 @@ void InitializeLogging(const std::string_view app_name) {
auto mem = memory::AlignedAlloc<Logger>(0x10); auto mem = memory::AlignedAlloc<Logger>(0x10);
logger_ = new (mem) Logger(app_name); 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. // Default to app name.
auto file_name = fmt::format("{}.log", app_name); auto file_name = fmt::format("{}.log", app_name);
auto file_path = std::filesystem::path(file_name); auto file_path = std::filesystem::path(file_name);
xe::filesystem::CreateParentFolder(file_path); xe::filesystem::CreateParentFolder(file_path);
file = xe::filesystem::OpenFile(file_path, "wt"); log_file = xe::filesystem::OpenFile(file_path, "wt");
} else { } else {
if (cvars::log_file == "stdout") { xe::filesystem::CreateParentFolder(cvars::log_file);
file = stdout; log_file = xe::filesystem::OpenFile(cvars::log_file, "wt");
} else {
xe::filesystem::CreateParentFolder(cvars::log_file);
file = xe::filesystem::OpenFile(cvars::log_file, "wt");
}
} }
auto sink = std::make_unique<FileLogSink>(file); auto sink = std::make_unique<FileLogSink>(log_file);
logger_->AddLogSink(std::move(sink)); logger_->AddLogSink(std::move(sink));
if (cvars::log_to_stdout) {
auto stdout_sink = std::make_unique<FileLogSink>(stdout);
logger_->AddLogSink(std::move(stdout_sink));
}
} }
void ShutdownLogging() { void ShutdownLogging() {

View File

@ -29,6 +29,8 @@
DEFINE_bool(win32_high_freq, true, DEFINE_bool(win32_high_freq, true,
"Requests high performance from the NT kernel", "Kernel"); "Requests high performance from the NT kernel", "Kernel");
DEFINE_bool(enable_console, false, "Open a console window with the main window",
"General");
namespace xe { namespace xe {
@ -37,27 +39,23 @@ bool has_console_attached_ = true;
bool has_console_attached() { return has_console_attached_; } bool has_console_attached() { return has_console_attached_; }
void AttachConsole() { void AttachConsole() {
bool has_console = ::AttachConsole(ATTACH_PARENT_PROCESS) == TRUE; if (!cvars::enable_console) {
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;
return; return;
} }
AllocConsole();
has_console_attached_ = true; has_console_attached_ = true;
auto std_handle = (intptr_t)GetStdHandle(STD_OUTPUT_HANDLE); auto std_handle = (intptr_t)GetStdHandle(STD_OUTPUT_HANDLE);
auto con_handle = _open_osfhandle(std_handle, _O_TEXT); auto con_handle = _open_osfhandle(std_handle, _O_TEXT);
auto fp = _fdopen(con_handle, "w"); auto fp = _fdopen(con_handle, "w");
*stdout = *fp; freopen_s(&fp, "CONOUT$", "w", stdout);
setvbuf(stdout, nullptr, _IONBF, 0);
std_handle = (intptr_t)GetStdHandle(STD_ERROR_HANDLE); std_handle = (intptr_t)GetStdHandle(STD_ERROR_HANDLE);
con_handle = _open_osfhandle(std_handle, _O_TEXT); con_handle = _open_osfhandle(std_handle, _O_TEXT);
fp = _fdopen(con_handle, "w"); fp = _fdopen(con_handle, "w");
*stderr = *fp; freopen_s(&fp, "CONOUT$", "w", stderr);
setvbuf(stderr, nullptr, _IONBF, 0);
} }
static void RequestHighPerformance() { static void RequestHighPerformance() {
@ -125,6 +123,10 @@ int Main() {
return 1; 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. // Setup COM on the main thread.
// NOTE: this may fail if COM has already been initialized - that's OK. // NOTE: this may fail if COM has already been initialized - that's OK.
#pragma warning(suppress : 6031) #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. // Used in windowed apps; automatically picked based on subsystem.
int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR command_line, int) { 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. // Run normal entry point.
return xe::Main(); return xe::Main();
} }