diff --git a/src/openrct2/interface/StdInOutConsole.cpp b/src/openrct2/interface/StdInOutConsole.cpp index b9512859aa..6da9ac4866 100644 --- a/src/openrct2/interface/StdInOutConsole.cpp +++ b/src/openrct2/interface/StdInOutConsole.cpp @@ -1,5 +1,6 @@ #include "../thirdparty/linenoise.hpp" #include "../OpenRCT2.h" +#include "../platform/Platform2.h" #include "Console.h" void StdInOutConsole::Start() @@ -80,7 +81,7 @@ void StdInOutConsole::WriteLine(const std::string &s, uint32 colourFormat) } } - if (formatBegin.empty()) + if (formatBegin.empty() || !Platform::IsColourTerminalSupported()) { std::printf("%s\n", s.c_str()); } diff --git a/src/openrct2/platform/Platform.Posix.cpp b/src/openrct2/platform/Platform.Posix.cpp index 038406cdb4..1214b9a22d 100644 --- a/src/openrct2/platform/Platform.Posix.cpp +++ b/src/openrct2/platform/Platform.Posix.cpp @@ -89,6 +89,22 @@ namespace Platform std::strftime(time, sizeof(time), "%X", std::gmtime(×tamp)); return std::string(time); } + + bool IsColourTerminalSupported() + { + static bool hasChecked = false; + static bool isSupported = false; + if (!hasChecked) + { + auto term = GetEnvironmentVariable("TERM"); + isSupported = + term != "cons25" && + term != "dumb" && + term != "emacs"; + hasChecked = true; + } + return isSupported; + } } #endif diff --git a/src/openrct2/platform/Platform.Win32.cpp b/src/openrct2/platform/Platform.Win32.cpp index 4dd9559b1a..7df674aca1 100644 --- a/src/openrct2/platform/Platform.Win32.cpp +++ b/src/openrct2/platform/Platform.Win32.cpp @@ -17,8 +17,6 @@ #ifdef _WIN32 #include - -#define WIN32_LEAN_AND_MEAN #include #include #include @@ -197,7 +195,75 @@ namespace Platform return result; } -#ifdef __USE_SHGETKNOWNFOLDERPATH__ + /** + * Checks if the current version of Windows supports ANSI colour codes. + * From Windows 10, build 10586 ANSI escape colour codes can be used on stdout. + */ + static bool HasANSIColourSupport() + { + const DWORD MINV_MAJOR = 10, MINV_MINOR = 0, MINV_BUILD = 10586; + bool result = false; + HMODULE hModule = GetModuleHandleA("ntdll.dll"); + if (hModule != nullptr) + { + using RtlGetVersionPtr = NTSTATUS(WINAPI *)(PRTL_OSVERSIONINFOW); + auto fn = (RtlGetVersionPtr)GetProcAddress(hModule, "RtlGetVersion"); + if (fn != nullptr) + { + RTL_OSVERSIONINFOW rovi{}; + rovi.dwOSVersionInfoSize = sizeof(rovi); + if (fn(&rovi) == 0) + { + if (rovi.dwMajorVersion > MINV_MAJOR || + (rovi.dwMajorVersion == MINV_MAJOR && + (rovi.dwMinorVersion > MINV_MINOR || + (rovi.dwMinorVersion == MINV_MINOR && + rovi.dwBuildNumber >= MINV_BUILD)))) + { + result = true; + } + } + } + } + return result; + } + + static void EnableANSIConsole() + { + if (HasANSIColourSupport()) + { + auto handle = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD mode; + GetConsoleMode(handle, &mode); + if (!(mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING)) + { + mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + SetConsoleMode(handle, mode); + } + } + } + + bool IsColourTerminalSupported() + { + static bool hasChecked = false; + static bool isSupported = false; + if (!hasChecked) + { + if (HasANSIColourSupport()) + { + EnableANSIConsole(); + isSupported = true; + } + else + { + isSupported = false; + } + hasChecked = true; + } + return isSupported; + } + + #ifdef __USE_SHGETKNOWNFOLDERPATH__ static std::string WIN32_GetKnownFolderPath(REFKNOWNFOLDERID rfid) { std::string path; diff --git a/src/openrct2/platform/Platform2.h b/src/openrct2/platform/Platform2.h index 50510a4ee1..35ae4450e7 100644 --- a/src/openrct2/platform/Platform2.h +++ b/src/openrct2/platform/Platform2.h @@ -44,4 +44,6 @@ namespace Platform std::string FormatShortDate(std::time_t timestamp); std::string FormatTime(std::time_t timestamp); + + bool IsColourTerminalSupported(); }