diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /dedicated/console/conproc.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'dedicated/console/conproc.cpp')
| -rw-r--r-- | dedicated/console/conproc.cpp | 428 |
1 files changed, 428 insertions, 0 deletions
diff --git a/dedicated/console/conproc.cpp b/dedicated/console/conproc.cpp new file mode 100644 index 0000000..2156450 --- /dev/null +++ b/dedicated/console/conproc.cpp @@ -0,0 +1,428 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#ifdef _WIN32 +// conproc.c -- support for qhost +#include <stdio.h> +#include <process.h> +#include <windows.h> +#include "conproc.h" +#include "isys.h" +#include "tier0/icommandline.h" +#include "tier1/strtools.h" + +static HANDLE heventDone; +static HANDLE hfileBuffer; +static HANDLE heventChildSend; +static HANDLE heventParentSend; +static HANDLE hStdout; +static HANDLE hStdin; + +/* +============== +SetConsoleCXCY + +============== +*/ +BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy) +{ + CONSOLE_SCREEN_BUFFER_INFO info; + COORD coordMax; + + coordMax = GetLargestConsoleWindowSize(hStdout); + + if (cy > coordMax.Y) + cy = coordMax.Y; + + if (cx > coordMax.X) + cx = coordMax.X; + + if (!GetConsoleScreenBufferInfo(hStdout, &info)) + return FALSE; + +// height + info.srWindow.Left = 0; + info.srWindow.Right = info.dwSize.X - 1; + info.srWindow.Top = 0; + info.srWindow.Bottom = cy - 1; + + if (cy < info.dwSize.Y) + { + if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) + return FALSE; + + info.dwSize.Y = cy; + + if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) + return FALSE; + } + else if (cy > info.dwSize.Y) + { + info.dwSize.Y = cy; + + if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) + return FALSE; + + if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) + return FALSE; + } + + if (!GetConsoleScreenBufferInfo(hStdout, &info)) + return FALSE; + +// width + info.srWindow.Left = 0; + info.srWindow.Right = cx - 1; + info.srWindow.Top = 0; + info.srWindow.Bottom = info.dwSize.Y - 1; + + if (cx < info.dwSize.X) + { + if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) + return FALSE; + + info.dwSize.X = cx; + + if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) + return FALSE; + } + else if (cx > info.dwSize.X) + { + info.dwSize.X = cx; + + if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) + return FALSE; + + if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) + return FALSE; + } + + return TRUE; +} + +/* +============== +GetMappedBuffer + +============== +*/ +LPVOID GetMappedBuffer (HANDLE hfileBuffer) +{ + LPVOID pBuffer; + + pBuffer = MapViewOfFile (hfileBuffer, + FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); + + return pBuffer; +} + +/* +============== +ReleaseMappedBuffer + +============== +*/ +void ReleaseMappedBuffer (LPVOID pBuffer) +{ + UnmapViewOfFile (pBuffer); +} + +/* +============== +GetScreenBufferLines + +============== +*/ +BOOL GetScreenBufferLines (int *piLines) +{ + CONSOLE_SCREEN_BUFFER_INFO info; + BOOL bRet; + + bRet = GetConsoleScreenBufferInfo (hStdout, &info); + + if (bRet) + *piLines = info.dwSize.Y; + + return bRet; +} + +/* +============== +SetScreenBufferLines + +============== +*/ +BOOL SetScreenBufferLines (int iLines) +{ + return SetConsoleCXCY (hStdout, 80, iLines); +} + +/* +============== +ReadText + +============== +*/ +BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine) +{ + COORD coord; + DWORD dwRead; + BOOL bRet; + + coord.X = 0; + coord.Y = iBeginLine; + + bRet = ReadConsoleOutputCharacter( + hStdout, + pszText, + 80 * (iEndLine - iBeginLine + 1), + coord, + &dwRead); + + // Make sure it's null terminated. + if (bRet) + pszText[dwRead] = '\0'; + + return bRet; +} + +/* +============== +CharToCode + +============== +*/ +int CharToCode (char c) +{ + char upper; + + upper = toupper(c); + + switch (c) + { + case 13: + return 28; + + default: + break; + } + + if (V_isalpha(c)) + return (30 + upper - 65); + + if (V_isdigit(c)) + return (1 + upper - 47); + + return c; +} + +/* +============== +WriteText + +============== +*/ +BOOL WriteText (LPCTSTR szText) +{ + DWORD dwWritten; + INPUT_RECORD rec; + char upper, *sz; + + sz = (LPTSTR) szText; + + while (*sz) + { + // 13 is the code for a carriage return (\n) instead of 10. + if (*sz == 10) + *sz = 13; + + upper = toupper(*sz); + + rec.EventType = KEY_EVENT; + rec.Event.KeyEvent.bKeyDown = TRUE; + rec.Event.KeyEvent.wRepeatCount = 1; + rec.Event.KeyEvent.wVirtualKeyCode = upper; + rec.Event.KeyEvent.wVirtualScanCode = CharToCode (*sz); + rec.Event.KeyEvent.uChar.AsciiChar = *sz; + rec.Event.KeyEvent.uChar.UnicodeChar = *sz; + rec.Event.KeyEvent.dwControlKeyState = V_isupper(*sz) ? 0x80 : 0x0; + + WriteConsoleInput( + hStdin, + &rec, + 1, + &dwWritten); + + rec.Event.KeyEvent.bKeyDown = FALSE; + + WriteConsoleInput( + hStdin, + &rec, + 1, + &dwWritten); + + sz++; + } + + return TRUE; +} + +/* +============== +RequestProc + +============== +*/ +unsigned _stdcall RequestProc (void *arg) +{ + int *pBuffer; + DWORD dwRet; + HANDLE heventWait[2]; + int iBeginLine, iEndLine; + + heventWait[0] = heventParentSend; + heventWait[1] = heventDone; + + while (1) + { + dwRet = WaitForMultipleObjects (2, heventWait, FALSE, INFINITE); + + // heventDone fired, so we're exiting. + if (dwRet == WAIT_OBJECT_0 + 1) + break; + + pBuffer = (int *) GetMappedBuffer (hfileBuffer); + + // hfileBuffer is invalid. Just leave. + if (!pBuffer) + { + sys->Printf ("Request Proc: Invalid -HFILE handle\n"); + break; + } + + switch (pBuffer[0]) + { + case CCOM_WRITE_TEXT: + // Param1 : Text + pBuffer[0] = WriteText ((LPCTSTR) (pBuffer + 1)); + break; + + case CCOM_GET_TEXT: + // Param1 : Begin line + // Param2 : End line + iBeginLine = pBuffer[1]; + iEndLine = pBuffer[2]; + pBuffer[0] = ReadText ((LPTSTR) (pBuffer + 1), iBeginLine, + iEndLine); + break; + + case CCOM_GET_SCR_LINES: + // No params + pBuffer[0] = GetScreenBufferLines (&pBuffer[1]); + break; + + case CCOM_SET_SCR_LINES: + // Param1 : Number of lines + pBuffer[0] = SetScreenBufferLines (pBuffer[1]); + break; + } + + ReleaseMappedBuffer (pBuffer); + SetEvent (heventChildSend); + } + + _endthreadex (0); + return 0; +} + +/* +============== +DeinitConProc + +============== +*/ +void DeinitConProc (void) +{ + if ( heventDone ) + { + SetEvent ( heventDone ); + } +} + +/* +============== +InitConProc + +============== +*/ +void InitConProc ( void ) +{ + unsigned threadAddr; + HANDLE hFile = (HANDLE)0; + HANDLE heventParent = (HANDLE)0; + HANDLE heventChild = (HANDLE)0; + int WantHeight = 50; + const char *p; + + // give external front ends a chance to hook into the console + if ( CommandLine()->CheckParm ( "-HFILE", &p ) && p ) + { + hFile = (HANDLE)atoi ( p ); + } + + if ( CommandLine()->CheckParm ( "-HPARENT", &p ) && p ) + { + heventParent = (HANDLE)atoi ( p ); + } + + if ( CommandLine()->CheckParm ( "-HCHILD", &p ) && p ) + { + heventChild = (HANDLE)atoi ( p ); + } + + // ignore if we don't have all the events. + if ( !hFile || !heventParent || !heventChild ) + { + //sys->Printf ("\n\nNo external front end present.\n" ); + return; + } + + sys->Printf( "\n\nInitConProc: Setting up external control.\n" ); + + hfileBuffer = hFile; + heventParentSend = heventParent; + heventChildSend = heventChild; + + // So we'll know when to go away. + heventDone = CreateEvent (NULL, FALSE, FALSE, NULL); + if (!heventDone) + { + sys->Printf ("InitConProc: Couldn't create heventDone\n"); + return; + } + + if (!_beginthreadex (NULL, 0, RequestProc, NULL, 0, &threadAddr)) + { + CloseHandle (heventDone); + sys->Printf ("InitConProc: Couldn't create third party thread\n"); + return; + } + + // save off the input/output handles. + hStdout = GetStdHandle (STD_OUTPUT_HANDLE); + hStdin = GetStdHandle (STD_INPUT_HANDLE); + + if ( CommandLine()->CheckParm( "-conheight", &p ) && p ) + { + WantHeight = atoi( p ); + } + + // Force 80 character width, at least 25 character height + SetConsoleCXCY( hStdout, 80, WantHeight ); +} +#endif // _WIN32 + |