mirror of
https://github.com/rehlds/metamod-r.git
synced 2024-12-31 00:55:47 +03:00
283 lines
6.8 KiB
C++
283 lines
6.8 KiB
C++
|
/*
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or modify it
|
||
|
* under the terms of the GNU General Public License as published by the
|
||
|
* Free Software Foundation; either version 2 of the License, or (at
|
||
|
* your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful, but
|
||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software Foundation,
|
||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
*
|
||
|
* In addition, as a special exception, the author gives permission to
|
||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||
|
* respects for all of the code used other than the HL Engine and MODs
|
||
|
* from Valve. If you modify this file, you may extend this exception
|
||
|
* to your version of the file, but you are not obligated to do so. If
|
||
|
* you do not wish to do so, delete this exception statement from your
|
||
|
* version.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include "precompiled.h"
|
||
|
|
||
|
#if defined(_WIN32)
|
||
|
|
||
|
CTextConsoleWin32 console;
|
||
|
#pragma comment(lib, "user32.lib")
|
||
|
|
||
|
BOOL WINAPI ConsoleHandlerRoutine(DWORD CtrlType)
|
||
|
{
|
||
|
// TODO ?
|
||
|
/*if (CtrlType != CTRL_C_EVENT && CtrlType != CTRL_BREAK_EVENT)
|
||
|
{
|
||
|
// don't quit on break or ctrl+c
|
||
|
m_System->Stop();
|
||
|
}*/
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
// GetConsoleHwnd() helper function from MSDN Knowledge Base Article Q124103
|
||
|
// needed, because HWND GetConsoleWindow(VOID) is not avaliable under Win95/98/ME
|
||
|
HWND GetConsoleHwnd()
|
||
|
{
|
||
|
HWND hwndFound; // This is what is returned to the caller.
|
||
|
char pszNewWindowTitle[1024]; // Contains fabricated WindowTitle
|
||
|
char pszOldWindowTitle[1024]; // Contains original WindowTitle
|
||
|
|
||
|
// Fetch current window title.
|
||
|
GetConsoleTitle(pszOldWindowTitle, sizeof(pszOldWindowTitle));
|
||
|
|
||
|
// Format a "unique" NewWindowTitle.
|
||
|
wsprintf(pszNewWindowTitle, "%d/%d", GetTickCount(), GetCurrentProcessId());
|
||
|
|
||
|
// Change current window title.
|
||
|
SetConsoleTitle(pszNewWindowTitle);
|
||
|
|
||
|
// Ensure window title has been updated.
|
||
|
Sleep(40);
|
||
|
|
||
|
// Look for NewWindowTitle.
|
||
|
hwndFound = FindWindow(nullptr, pszNewWindowTitle);
|
||
|
|
||
|
// Restore original window title.
|
||
|
SetConsoleTitle(pszOldWindowTitle);
|
||
|
|
||
|
return hwndFound;
|
||
|
}
|
||
|
|
||
|
CTextConsoleWin32::~CTextConsoleWin32()
|
||
|
{
|
||
|
CTextConsoleWin32::ShutDown();
|
||
|
}
|
||
|
|
||
|
bool CTextConsoleWin32::Init(IBaseSystem *system)
|
||
|
{
|
||
|
if (!AllocConsole())
|
||
|
m_System = system;
|
||
|
|
||
|
SetTitle(m_System ? m_System->GetName() : "Console");
|
||
|
|
||
|
hinput = GetStdHandle(STD_INPUT_HANDLE);
|
||
|
houtput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||
|
|
||
|
if (!SetConsoleCtrlHandler(&ConsoleHandlerRoutine, TRUE)) {
|
||
|
Print("WARNING! TextConsole::Init: Could not attach console hook.\n");
|
||
|
}
|
||
|
|
||
|
Attrib = FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
|
||
|
SetWindowPos(GetConsoleHwnd(), HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOREPOSITION | SWP_SHOWWINDOW);
|
||
|
|
||
|
return CTextConsole::Init(system);
|
||
|
}
|
||
|
|
||
|
void CTextConsoleWin32::ShutDown()
|
||
|
{
|
||
|
FreeConsole();
|
||
|
CTextConsole::ShutDown();
|
||
|
}
|
||
|
|
||
|
void CTextConsoleWin32::SetVisible(bool visible)
|
||
|
{
|
||
|
ShowWindow(GetConsoleHwnd(), visible ? SW_SHOW : SW_HIDE);
|
||
|
m_ConsoleVisible = visible;
|
||
|
}
|
||
|
|
||
|
char *CTextConsoleWin32::GetLine()
|
||
|
{
|
||
|
while (true)
|
||
|
{
|
||
|
INPUT_RECORD recs[1024];
|
||
|
unsigned long numread;
|
||
|
unsigned long numevents;
|
||
|
|
||
|
if (!GetNumberOfConsoleInputEvents(hinput, &numevents))
|
||
|
{
|
||
|
if (m_System) {
|
||
|
m_System->Errorf("CTextConsoleWin32::GetLine: !GetNumberOfConsoleInputEvents\n");
|
||
|
}
|
||
|
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
if (numevents <= 0)
|
||
|
break;
|
||
|
|
||
|
if (!ReadConsoleInput(hinput, recs, ARRAYSIZE(recs), &numread))
|
||
|
{
|
||
|
if (m_System) {
|
||
|
m_System->Errorf("CTextConsoleWin32::GetLine: !ReadConsoleInput\n");
|
||
|
}
|
||
|
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
if (numread == 0)
|
||
|
return nullptr;
|
||
|
|
||
|
for (int i = 0; i < (int)numread; i++)
|
||
|
{
|
||
|
INPUT_RECORD *pRec = &recs[i];
|
||
|
if (pRec->EventType != KEY_EVENT)
|
||
|
continue;
|
||
|
|
||
|
if (pRec->Event.KeyEvent.bKeyDown)
|
||
|
{
|
||
|
// check for cursor keys
|
||
|
if (pRec->Event.KeyEvent.wVirtualKeyCode == VK_UP)
|
||
|
{
|
||
|
ReceiveUpArrow();
|
||
|
}
|
||
|
else if (pRec->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)
|
||
|
{
|
||
|
ReceiveDownArrow();
|
||
|
}
|
||
|
else if (pRec->Event.KeyEvent.wVirtualKeyCode == VK_LEFT)
|
||
|
{
|
||
|
ReceiveLeftArrow();
|
||
|
}
|
||
|
else if (pRec->Event.KeyEvent.wVirtualKeyCode == VK_RIGHT)
|
||
|
{
|
||
|
ReceiveRightArrow();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int nLen;
|
||
|
char ch = pRec->Event.KeyEvent.uChar.AsciiChar;
|
||
|
switch (ch)
|
||
|
{
|
||
|
case '\r': // Enter
|
||
|
nLen = ReceiveNewline();
|
||
|
if (nLen)
|
||
|
{
|
||
|
return m_szConsoleText;
|
||
|
}
|
||
|
break;
|
||
|
case '\b': // Backspace
|
||
|
ReceiveBackspace();
|
||
|
break;
|
||
|
case '\t': // TAB
|
||
|
ReceiveTab();
|
||
|
break;
|
||
|
default:
|
||
|
// dont' accept nonprintable chars
|
||
|
if ((ch >= ' ') && (ch <= '~'))
|
||
|
{
|
||
|
ReceiveStandardChar(ch);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
void CTextConsoleWin32::PrintRaw(char *pszMsg, int nChars)
|
||
|
{
|
||
|
#ifdef LAUNCHER_FIXES
|
||
|
char outputStr[2048];
|
||
|
WCHAR unicodeStr[1024];
|
||
|
|
||
|
DWORD nSize = MultiByteToWideChar(CP_UTF8, 0, pszMsg, -1, NULL, 0);
|
||
|
if (nSize > sizeof(unicodeStr))
|
||
|
return;
|
||
|
|
||
|
MultiByteToWideChar(CP_UTF8, 0, pszMsg, -1, unicodeStr, nSize);
|
||
|
DWORD nLength = WideCharToMultiByte(CP_OEMCP, 0, unicodeStr, -1, 0, 0, NULL, NULL);
|
||
|
if (nLength > sizeof(outputStr))
|
||
|
return;
|
||
|
|
||
|
WideCharToMultiByte(CP_OEMCP, 0, unicodeStr, -1, outputStr, nLength, NULL, NULL);
|
||
|
WriteFile(houtput, outputStr, nChars ? nChars : Q_strlen(outputStr), NULL, NULL);
|
||
|
#else
|
||
|
WriteFile(houtput, pszMsg, nChars ? nChars : Q_strlen(pszMsg), NULL, NULL);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void CTextConsoleWin32::Echo(char *pszMsg, int nChars)
|
||
|
{
|
||
|
PrintRaw(pszMsg, nChars);
|
||
|
}
|
||
|
|
||
|
int CTextConsoleWin32::GetWidth()
|
||
|
{
|
||
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||
|
int nWidth = 0;
|
||
|
|
||
|
if (GetConsoleScreenBufferInfo(houtput, &csbi)) {
|
||
|
nWidth = csbi.dwSize.X;
|
||
|
}
|
||
|
|
||
|
if (nWidth <= 1)
|
||
|
nWidth = 80;
|
||
|
|
||
|
return nWidth;
|
||
|
}
|
||
|
|
||
|
void CTextConsoleWin32::SetStatusLine(char *pszStatus)
|
||
|
{
|
||
|
Q_strncpy(statusline, pszStatus, sizeof(statusline) - 1);
|
||
|
statusline[sizeof(statusline) - 2] = '\0';
|
||
|
UpdateStatus();
|
||
|
}
|
||
|
|
||
|
void CTextConsoleWin32::UpdateStatus()
|
||
|
{
|
||
|
COORD coord;
|
||
|
DWORD dwWritten = 0;
|
||
|
WORD wAttrib[ 80 ];
|
||
|
|
||
|
for (int i = 0; i < 80; i++)
|
||
|
{
|
||
|
wAttrib[i] = Attrib; // FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
|
||
|
}
|
||
|
|
||
|
coord.X = coord.Y = 0;
|
||
|
|
||
|
WriteConsoleOutputAttribute(houtput, wAttrib, 80, coord, &dwWritten);
|
||
|
WriteConsoleOutputCharacter(houtput, statusline, 80, coord, &dwWritten);
|
||
|
}
|
||
|
|
||
|
void CTextConsoleWin32::SetTitle(char *pszTitle)
|
||
|
{
|
||
|
SetConsoleTitle(pszTitle);
|
||
|
}
|
||
|
|
||
|
void CTextConsoleWin32::SetColor(WORD attrib)
|
||
|
{
|
||
|
Attrib = attrib;
|
||
|
}
|
||
|
|
||
|
#endif // defined(_WIN32)
|