r5sdk/r5dev/windows/console.cpp
Kawe Mazidjatari 9e6b0e567f Port everything to CCommandLine
Before, we had to do a hack of capturing the command line using GetCommandLineA, and then checking if a certain argument is present. This was required due to how early the GameSDK dll was loaded (the g_CmdLine object was far from initialized in the engine). Due to the loader refactor, the commandline can be used directly after creation in the game's entry point (which is the time the SDK is getting loaded). Therefore, no copies of the command line are required anymore.
This commit contains the following changes:

- Correctly ordered the initialization, and deinitialization of systems (first init = last shutdown).
- Factored out command line string copy in favor of game's implementation.
- Factored the R5Reloaded emblem print into its own function.
- Removed 'SpdLog_PostInit()', we can now directly call DevMsg() once SpdLog_Init() has been called, the logger callback sink deals with the formatting of the output.
- Fixed a bug where the logger did not print the correct color for 'SYSTEM_WARNING' and 'SYSTEM_ERROR' in the external console.
- Fixed a bug where the command line did not work when the game wasn't launched with the '-launcher' parameter.
- Logs now equally appear on the external, and in-game console windows.
2023-07-01 01:20:47 +02:00

164 lines
4.8 KiB
C++

//=============================================================================//
//
// Purpose: Windows terminal utilities
//
//=============================================================================//
#include "core/stdafx.h"
#ifndef NETCONSOLE
#include "core/init.h"
#include "core/logdef.h"
#include "tier0/frametask.h"
#include "engine/cmd.h"
#ifndef DEDICATED
#include "windows/id3dx.h"
#endif // !DEDICATED
#endif // !NETCONSOLE
#include "windows/system.h"
#include "windows/console.h"
static std::string s_ConsoleInput;
//-----------------------------------------------------------------------------
// Purpose: sets the windows terminal background color
// Input : color -
//-----------------------------------------------------------------------------
void SetConsoleBackgroundColor(COLORREF color)
{
CONSOLE_SCREEN_BUFFER_INFOEX sbInfoEx{};
sbInfoEx.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
HANDLE consoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfoEx(consoleOut, &sbInfoEx);
sbInfoEx.ColorTable[0] = color;
SetConsoleScreenBufferInfoEx(consoleOut, &sbInfoEx);
}
//-----------------------------------------------------------------------------
// Purpose: flashes the windows terminal background color
// Input : nFlashCount -
// nFlashInterval -
// color -
//-----------------------------------------------------------------------------
void FlashConsoleBackground(int nFlashCount, int nFlashInterval, COLORREF color)
{
CONSOLE_SCREEN_BUFFER_INFOEX sbInfoEx{};
sbInfoEx.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
HANDLE consoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfoEx(consoleOut, &sbInfoEx);
COLORREF storedBG = sbInfoEx.ColorTable[0];
for (int i = 0; i < nFlashCount; ++i)
{
//-- set BG color
Sleep(nFlashInterval);
sbInfoEx.ColorTable[0] = color;
SetConsoleScreenBufferInfoEx(consoleOut, &sbInfoEx);
//-- restore previous color
Sleep(nFlashInterval);
sbInfoEx.ColorTable[0] = storedBG;
SetConsoleScreenBufferInfoEx(consoleOut, &sbInfoEx);
}
}
//-----------------------------------------------------------------------------
// Purpose: terminal window setup
// Input : bAnsiColor -
//-----------------------------------------------------------------------------
void Console_Init(const bool bAnsiColor)
{
#ifndef NETCONSOLE
///////////////////////////////////////////////////////////////////////////
// Create the console window
if (AllocConsole() == FALSE)
{
OutputDebugStringA("Failed to create console window!\n");
return;
}
//-- Set the window title
SetConsoleTitleA("R5");
//-- Open input/output streams
FILE* fDummy;
freopen_s(&fDummy, "CONIN$", "r", stdin);
freopen_s(&fDummy, "CONOUT$", "w", stdout);
freopen_s(&fDummy, "CONOUT$", "w", stderr);
//-- Create a worker thread to process console commands
DWORD dwThreadId = NULL;
DWORD __stdcall ProcessConsoleWorker(LPVOID);
HANDLE hThread = CreateThread(NULL, 0, ProcessConsoleWorker, NULL, 0, &dwThreadId);
if (hThread)
{
CloseHandle(hThread);
}
#endif // !NETCONSOLE
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD dwMode = NULL;
if (bAnsiColor)
{
GetConsoleMode(hOutput, &dwMode);
dwMode |= ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (!SetConsoleMode(hOutput, dwMode)) // Some editions of Windows have 'VirtualTerminalLevel' disabled by default.
{
// Warn the user if 'VirtualTerminalLevel' could not be set on users environment.
MessageBoxA(NULL, "Failed to set console mode 'VirtualTerminalLevel'.\n"
"Please omit the '-ansicolor' parameter and restart \nthe program if output logging appears distorted.", "SDK Warning", MB_ICONEXCLAMATION | MB_OK);
}
SetConsoleBackgroundColor(0x00000000);
AnsiColors_Init();
}
#ifndef NETCONSOLE
SetConsoleCtrlHandler(ConsoleHandlerRoutine, true);
#endif // !NETCONSOLE
}
//-----------------------------------------------------------------------------
// Purpose: terminal window shutdown
//-----------------------------------------------------------------------------
void Console_Shutdown()
{
///////////////////////////////////////////////////////////////////////////
// Destroy the console window
if (FreeConsole() == FALSE)
{
OutputDebugStringA("Failed to destroy console window!\n");
return;
}
}
#ifndef NETCONSOLE
//#############################################################################
// CONSOLE WORKER
//#############################################################################
DWORD __stdcall ProcessConsoleWorker(LPVOID)
{
while (true)
{
//printf("] ");
//-- Get the user input on the debug console
std::getline(std::cin, s_ConsoleInput);
// Execute the command.
Cbuf_AddText(Cbuf_GetCurrentPlayer(), s_ConsoleInput.c_str(), cmd_source_t::kCommandSrcCode);
if (!s_ConsoleInput.empty())
s_ConsoleInput.clear();
Sleep(50);
}
return NULL;
}
#endif // !NETCONSOLE