From ae9c3ae7287c2a86df384c60a40dd319b3a0dec3 Mon Sep 17 00:00:00 2001 From: invertego Date: Sat, 4 Mar 2023 10:54:17 -0800 Subject: [PATCH] desktop-ui: improve terminal support on windows Previously, terminal (console) support on Windows required opting in at compile time. Now, the runtime behavior is largely the same regardless of how ares is compiled. - ares will attach to the terminal of the parent process (if present) by default and redirect any unset stdio streams. - If the --terminal argument is provided, ares will always create a new terminal window and stdio will be redirected to it. - Otherwise, if stdio handles were already valid on launch they will be left alone (to support redirection to/from files). --- desktop-ui/desktop-ui.cpp | 8 ++++++++ nall/nall.cpp | 1 + nall/terminal.cpp | 21 +++++++++++++++++++++ nall/terminal.hpp | 6 ++++++ 4 files changed, 36 insertions(+) create mode 100644 nall/terminal.cpp diff --git a/desktop-ui/desktop-ui.cpp b/desktop-ui/desktop-ui.cpp index fceaccc10..ec30167a6 100644 --- a/desktop-ui/desktop-ui.cpp +++ b/desktop-ui/desktop-ui.cpp @@ -39,6 +39,11 @@ auto locate(const string& name) -> string { #include auto nall::main(Arguments arguments) -> void { +#if defined(PLATFORM_WINDOWS) + bool createTerminal = arguments.take("--terminal"); + terminal::redirectStdioToTerminal(createTerminal); +#endif + Application::setName("ares"); Application::setScreenSaver(false); @@ -74,6 +79,9 @@ auto nall::main(Arguments arguments) -> void { print("Usage: ares [OPTIONS]... game\n\n"); print("Options:\n"); print(" --help Displays available options and exit\n"); +#if defined(PLATFORM_WINDOWS) + print(" --terminal Create new terminal window\n"); +#endif print(" --fullscreen Start in full screen mode\n"); print(" --system name Specifiy the system name\n"); print("\n"); diff --git a/nall/nall.cpp b/nall/nall.cpp index e0a650055..db1ca7fde 100644 --- a/nall/nall.cpp +++ b/nall/nall.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include //currently unused by ares //#include diff --git a/nall/terminal.cpp b/nall/terminal.cpp new file mode 100644 index 000000000..063d96da7 --- /dev/null +++ b/nall/terminal.cpp @@ -0,0 +1,21 @@ +#include + +namespace nall::terminal { + +NALL_HEADER_INLINE auto redirectStdioToTerminal(bool create) -> void { +#if defined(PLATFORM_WINDOWS) + if(create) { + FreeConsole(); + if(!AllocConsole()) return; + } else if(!AttachConsole(ATTACH_PARENT_PROCESS)) { + return; + } + + //unless a new terminal was requested, do not reopen already valid handles (allow redirection to/from file) + if(create || _get_osfhandle(_fileno(stdin )) < 0) freopen("CONIN$" , "r", stdin ); + if(create || _get_osfhandle(_fileno(stdout)) < 0) freopen("CONOUT$", "w", stdout); + if(create || _get_osfhandle(_fileno(stderr)) < 0) freopen("CONOUT$", "w", stderr); +#endif +} + +} diff --git a/nall/terminal.hpp b/nall/terminal.hpp index 6006b3feb..69b6f2eb3 100644 --- a/nall/terminal.hpp +++ b/nall/terminal.hpp @@ -4,6 +4,8 @@ namespace nall::terminal { +auto redirectStdioToTerminal(bool create) -> void; + inline auto escapable() -> bool { #if defined(PLATFORM_WINDOWS) //todo: colors are supported by Windows 10+ and with alternate terminals (eg msys) @@ -63,3 +65,7 @@ template inline auto gray(P&&... p) -> string { } } + +#if defined(NALL_HEADER_ONLY) + #include +#endif