mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
- rewrote Windows console code for Windows 10's new terminal.
This allows dumping a lot of shit code using deprecated Windows functionality and bringing the code in line with Microsoft's roadmap for terminal/console functionality. Note that this will cause garbled output of non-ASCII characters on Windows 7 and 8.1, but proper handling on these declining systems is of far lesser importance than future-proofing the feature.
This commit is contained in:
parent
595975fcc7
commit
0e90098de8
2 changed files with 30 additions and 92 deletions
|
@ -43,6 +43,7 @@
|
||||||
|
|
||||||
#include <processenv.h>
|
#include <processenv.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
|
#include <VersionHelpers.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable:4244)
|
#pragma warning(disable:4244)
|
||||||
|
@ -179,7 +180,7 @@ int DoMain (HINSTANCE hInstance)
|
||||||
StdOut = NULL;
|
StdOut = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (StdOut == NULL)
|
if (StdOut == nullptr)
|
||||||
{
|
{
|
||||||
if (AttachConsole(ATTACH_PARENT_PROCESS))
|
if (AttachConsole(ATTACH_PARENT_PROCESS))
|
||||||
{
|
{
|
||||||
|
@ -187,25 +188,21 @@ int DoMain (HINSTANCE hInstance)
|
||||||
DWORD foo; WriteFile(StdOut, "\n", 1, &foo, NULL);
|
DWORD foo; WriteFile(StdOut, "\n", 1, &foo, NULL);
|
||||||
AttachedStdOut = true;
|
AttachedStdOut = true;
|
||||||
}
|
}
|
||||||
if (StdOut == NULL && AllocConsole())
|
if (StdOut == nullptr && AllocConsole())
|
||||||
{
|
{
|
||||||
StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
}
|
}
|
||||||
|
if (StdOut != nullptr)
|
||||||
// Deprecated stuff for legacy consoles. As of now this is still relevant, but this code can be removed once Windows 7 is no longer relevant.
|
|
||||||
CONSOLE_FONT_INFOEX cfi;
|
|
||||||
cfi.cbSize = sizeof(cfi);
|
|
||||||
if (GetCurrentConsoleFontEx(StdOut, false, &cfi))
|
|
||||||
{
|
{
|
||||||
if (*cfi.FaceName == 0) // If the face name is empty, the default (useless) raster font is actoive.
|
SetConsoleCP(CP_UTF8);
|
||||||
|
SetConsoleOutputCP(CP_UTF8);
|
||||||
|
DWORD mode;
|
||||||
|
if (GetConsoleMode(StdOut, &mode))
|
||||||
{
|
{
|
||||||
//cfi.dwFontSize = { 8, 14 };
|
if (SetConsoleMode(StdOut, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING))
|
||||||
wcscpy(cfi.FaceName, L"Lucida Console");
|
FancyStdOut = IsWindows10OrGreater(); // Windows 8.1 and lower do not understand ANSI formatting.
|
||||||
cfi.FontFamily = FF_DONTCARE;
|
|
||||||
SetCurrentConsoleFontEx(StdOut, false, &cfi);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FancyStdOut = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -278,97 +278,38 @@ void CalculateCPUSpeed()
|
||||||
|
|
||||||
static void PrintToStdOut(const char *cpt, HANDLE StdOut)
|
static void PrintToStdOut(const char *cpt, HANDLE StdOut)
|
||||||
{
|
{
|
||||||
if (StdOut == nullptr && !con_debugoutput)
|
const char* srcp = cpt;
|
||||||
return;
|
FString printData = "";
|
||||||
|
bool terminal = FancyStdOut;
|
||||||
|
|
||||||
wchar_t wbuf[256];
|
while (*srcp != 0)
|
||||||
int bpos = 0;
|
|
||||||
|
|
||||||
const uint8_t *cptr = (const uint8_t*)cpt;
|
|
||||||
|
|
||||||
auto outputIt = [&]()
|
|
||||||
{
|
{
|
||||||
wbuf[bpos] = 0;
|
if (*srcp == 0x1c && terminal)
|
||||||
if (con_debugoutput)
|
|
||||||
{
|
{
|
||||||
OutputDebugStringW(wbuf);
|
srcp += 1;
|
||||||
}
|
const uint8_t* scratch = (const uint8_t*)srcp; // GCC does not like direct casting of the parameter.
|
||||||
if (StdOut != nullptr)
|
EColorRange range = V_ParseFontColor(scratch, CR_UNTRANSLATED, CR_YELLOW);
|
||||||
{
|
srcp = (char*)scratch;
|
||||||
// Convert back to UTF-8.
|
|
||||||
DWORD bytes_written;
|
|
||||||
if (!FancyStdOut)
|
|
||||||
{
|
|
||||||
FString conout(wbuf);
|
|
||||||
WriteFile(StdOut, conout.GetChars(), (DWORD)conout.Len(), &bytes_written, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteConsoleW(StdOut, wbuf, bpos, &bytes_written, nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bpos = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
while (int chr = GetCharFromString(cptr))
|
|
||||||
{
|
|
||||||
if ((chr == TEXTCOLOR_ESCAPE && bpos != 0) || bpos == 255)
|
|
||||||
{
|
|
||||||
outputIt();
|
|
||||||
}
|
|
||||||
if (chr != TEXTCOLOR_ESCAPE)
|
|
||||||
{
|
|
||||||
if (chr >= 0x1D && chr <= 0x1F)
|
|
||||||
{ // The bar characters, most commonly used to indicate map changes
|
|
||||||
chr = 0x2550; // Box Drawings Double Horizontal
|
|
||||||
}
|
|
||||||
wbuf[bpos++] = chr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EColorRange range = V_ParseFontColor(cptr, CR_UNTRANSLATED, CR_YELLOW);
|
|
||||||
|
|
||||||
if (range != CR_UNDEFINED)
|
if (range != CR_UNDEFINED)
|
||||||
{
|
{
|
||||||
// Change the color of future text added to the control.
|
|
||||||
PalEntry color = V_LogColorFromColorRange(range);
|
PalEntry color = V_LogColorFromColorRange(range);
|
||||||
if (StdOut != NULL && FancyStdOut)
|
printData.AppendFormat("\033[38;2;%u;%u;%um", color.r, color.g, color.b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*srcp != 0x1c && *srcp != 0x1d && *srcp != 0x1e && *srcp != 0x1f)
|
||||||
{
|
{
|
||||||
// Unfortunately, we are pretty limited here: There are only
|
printData += *srcp++;
|
||||||
// eight basic colors, and each comes in a dark and a bright
|
|
||||||
// variety.
|
|
||||||
float h, s, v, r, g, b;
|
|
||||||
int attrib = 0;
|
|
||||||
|
|
||||||
RGBtoHSV(color.r / 255.f, color.g / 255.f, color.b / 255.f, &h, &s, &v);
|
|
||||||
if (s != 0)
|
|
||||||
{ // color
|
|
||||||
HSVtoRGB(&r, &g, &b, h, 1, 1);
|
|
||||||
if (r == 1) attrib = FOREGROUND_RED;
|
|
||||||
if (g == 1) attrib |= FOREGROUND_GREEN;
|
|
||||||
if (b == 1) attrib |= FOREGROUND_BLUE;
|
|
||||||
if (v > 0.6) attrib |= FOREGROUND_INTENSITY;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // gray
|
|
||||||
if (v < 0.33) attrib = FOREGROUND_INTENSITY;
|
|
||||||
else if (v < 0.90) attrib = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
|
|
||||||
else attrib = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
|
|
||||||
}
|
|
||||||
SetConsoleTextAttribute(StdOut, (WORD)attrib);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bpos != 0)
|
|
||||||
{
|
{
|
||||||
outputIt();
|
if (srcp[1] != 0) srcp += 2;
|
||||||
|
else break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StdOut != NULL && FancyStdOut)
|
|
||||||
{ // Set text back to gray, in case it was changed.
|
|
||||||
SetConsoleTextAttribute(StdOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
|
||||||
}
|
}
|
||||||
|
DWORD bytes_written;
|
||||||
|
WriteFile(StdOut, printData.GetChars(), (DWORD)printData.Len(), &bytes_written, NULL);
|
||||||
|
if (terminal)
|
||||||
|
WriteFile(StdOut, "\033[0m", 4, &bytes_written, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_PrintStr(const char *cp)
|
void I_PrintStr(const char *cp)
|
||||||
|
|
Loading…
Reference in a new issue