r5sdk/r5dev/windows/console.cpp
Kawe Mazidjatari f120354e96 Initial port to CMake
* All libraries have been isolated from each other, and build into separate artifacts.
* Project has been restructured to support isolating libraries.
* CCrashHandler now calls a callback on crash (setup from core/dllmain.cpp, this can be setup in any way for any project. This callback is getting called when the apllication crashes. Useful for flushing buffers before closing handles to logging files for example).
* Tier0 'CoreMsgV' function now calls a callback sink, which could be set by the user (currently setup to the SDK's internal logger in core/dllmain.cpp).

TODO:
* Add a batch file to autogenerate all projects.
* Add support for dedicated server.
* Add support for client dll.

Bugs:
* Game crashes on the title screen after the UI script compiler has finished (root cause unknown).
* Curl error messages are getting logged twice for the dedicated server due to the removal of all "DEDICATED" preprocessor directives to support isolating projects. This has to be fixed properly!
2023-05-10 00:05:38 +02:00

163 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
//-----------------------------------------------------------------------------
void Console_Init()
{
#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 (g_svCmdLine.find("-ansicolor") != string::npos)
{
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