mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-25 22:10:59 +00:00
Add conproc.c and the coresponding header
conproc.c implements support functions for the console windows used by the dedicated server. It was taken from ioQuake2 and cleaned up for the inclusion in Yamagi Quake II.
This commit is contained in:
parent
4adc6a2ca2
commit
0eb042555b
4 changed files with 492 additions and 2 deletions
4
Makefile
4
Makefile
|
@ -474,7 +474,9 @@ SERVER_OBJS_ := \
|
|||
src/server/sv_world.o
|
||||
|
||||
ifeq ($(OS), Windows)
|
||||
SERVER_OBJS_ +=
|
||||
SERVER_OBJS_ += \
|
||||
src/windows/conproc.o \
|
||||
src/windows/system.o
|
||||
else
|
||||
SERVER_OBJS_ += \
|
||||
src/unix/glob.o \
|
||||
|
|
459
src/windows/conproc.c
Normal file
459
src/windows/conproc.c
Normal file
|
@ -0,0 +1,459 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* The "qhost" subsystem, hosting the console window.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <process.h>
|
||||
#include <windows.h>
|
||||
#include "header/conproc.h"
|
||||
|
||||
#define CCOM_WRITE_TEXT 0x2
|
||||
#define CCOM_GET_TEXT 0x3
|
||||
#define CCOM_GET_SCR_LINES 0x4
|
||||
#define CCOM_SET_SCR_LINES 0x5
|
||||
|
||||
HANDLE heventDone;
|
||||
HANDLE hfileBuffer;
|
||||
HANDLE heventChildSend;
|
||||
HANDLE heventParentSend;
|
||||
HANDLE hStdout;
|
||||
HANDLE hStdin;
|
||||
|
||||
LPVOID GetMappedBuffer(HANDLE hfileBuffer);
|
||||
BOOL GetScreenBufferLines(int *piLines);
|
||||
BOOL SetScreenBufferLines(int iLines);
|
||||
BOOL ReadText(LPTSTR pszText, int iBeginLine, int iEndLine);
|
||||
BOOL WriteText(LPCTSTR szText);
|
||||
BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy);
|
||||
int CharToCode(char c);
|
||||
unsigned int _stdcall RequestProc(void *arg);
|
||||
void ReleaseMappedBuffer(LPVOID pBuffer);
|
||||
|
||||
int ccom_argc;
|
||||
char **ccom_argv;
|
||||
|
||||
/*
|
||||
* Returns the position (1 to argc-1) in the
|
||||
* program's argument list where the given
|
||||
* parameter apears, or 0 if not present
|
||||
*/
|
||||
int
|
||||
CCheckParm(char *parm)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < ccom_argc; i++)
|
||||
{
|
||||
if (!ccom_argv[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(parm, ccom_argv[i]))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
InitConProc(int argc, char **argv)
|
||||
{
|
||||
unsigned threadAddr;
|
||||
HANDLE hFile;
|
||||
HANDLE heventParent;
|
||||
HANDLE heventChild;
|
||||
int t;
|
||||
|
||||
ccom_argc = argc;
|
||||
ccom_argv = argv;
|
||||
|
||||
/* give QHOST a chance to hook into the console */
|
||||
if ((t = CCheckParm("-HFILE")) > 0)
|
||||
{
|
||||
if (t < argc)
|
||||
{
|
||||
hFile = (HANDLE)atoi(ccom_argv[t + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
if ((t = CCheckParm("-HPARENT")) > 0)
|
||||
{
|
||||
if (t < argc)
|
||||
{
|
||||
heventParent = (HANDLE)atoi(ccom_argv[t + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
if ((t = CCheckParm("-HCHILD")) > 0)
|
||||
{
|
||||
if (t < argc)
|
||||
{
|
||||
heventChild = (HANDLE)atoi(ccom_argv[t + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
/* ignore if we don't have all the events. */
|
||||
if (!hFile || !heventParent || !heventChild)
|
||||
{
|
||||
printf("Qhost not present.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Initializing for qhost.\n");
|
||||
|
||||
hfileBuffer = hFile;
|
||||
heventParentSend = heventParent;
|
||||
heventChildSend = heventChild;
|
||||
|
||||
/* so we'll know when to go away. */
|
||||
heventDone = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
|
||||
if (!heventDone)
|
||||
{
|
||||
printf("Couldn't create heventDone\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_beginthreadex(NULL, 0, RequestProc, NULL, 0, &threadAddr))
|
||||
{
|
||||
CloseHandle(heventDone);
|
||||
printf("Couldn't create QHOST thread\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* save off the input/output handles. */
|
||||
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
hStdin = GetStdHandle(STD_INPUT_HANDLE);
|
||||
|
||||
/* force 80 character width,
|
||||
at least 25 character height */
|
||||
SetConsoleCXCY(hStdout, 80, 25);
|
||||
}
|
||||
|
||||
void
|
||||
DeinitConProc(void)
|
||||
{
|
||||
if (heventDone)
|
||||
{
|
||||
SetEvent(heventDone);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
printf("Invalid hfileBuffer\n");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (pBuffer[0])
|
||||
{
|
||||
case CCOM_WRITE_TEXT:
|
||||
pBuffer[0] = WriteText((LPCTSTR)(pBuffer + 1));
|
||||
break;
|
||||
|
||||
case CCOM_GET_TEXT:
|
||||
iBeginLine = pBuffer[1];
|
||||
iEndLine = pBuffer[2];
|
||||
pBuffer[0] = ReadText((LPTSTR)(pBuffer + 1), iBeginLine,
|
||||
iEndLine);
|
||||
break;
|
||||
|
||||
case CCOM_GET_SCR_LINES:
|
||||
pBuffer[0] = GetScreenBufferLines(&pBuffer[1]);
|
||||
break;
|
||||
|
||||
case CCOM_SET_SCR_LINES:
|
||||
pBuffer[0] = SetScreenBufferLines(pBuffer[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
ReleaseMappedBuffer(pBuffer);
|
||||
SetEvent(heventChildSend);
|
||||
}
|
||||
|
||||
_endthreadex(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LPVOID
|
||||
GetMappedBuffer(HANDLE hfileBuffer)
|
||||
{
|
||||
LPVOID pBuffer;
|
||||
|
||||
pBuffer = MapViewOfFile(hfileBuffer,
|
||||
FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
|
||||
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
void
|
||||
ReleaseMappedBuffer(LPVOID pBuffer)
|
||||
{
|
||||
UnmapViewOfFile(pBuffer);
|
||||
}
|
||||
|
||||
BOOL
|
||||
GetScreenBufferLines(int *piLines)
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||
BOOL bRet;
|
||||
|
||||
bRet = GetConsoleScreenBufferInfo(hStdout, &info);
|
||||
|
||||
if (bRet)
|
||||
{
|
||||
*piLines = info.dwSize.Y;
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
BOOL
|
||||
SetScreenBufferLines(int iLines)
|
||||
{
|
||||
return SetConsoleCXCY(hStdout, 80, iLines);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 = isupper(*sz) ? 0x80 : 0x0;
|
||||
|
||||
WriteConsoleInput(hStdin, &rec, 1, &dwWritten);
|
||||
|
||||
rec.Event.KeyEvent.bKeyDown = FALSE;
|
||||
|
||||
WriteConsoleInput(hStdin, &rec, 1, &dwWritten);
|
||||
|
||||
sz++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
CharToCode(char c)
|
||||
{
|
||||
char upper;
|
||||
|
||||
upper = toupper(c);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 13:
|
||||
return 28;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (isalpha(c))
|
||||
{
|
||||
return 30 + upper - 65;
|
||||
}
|
||||
|
||||
if (isdigit(c))
|
||||
{
|
||||
return 1 + upper - 47;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
29
src/windows/header/conproc.h
Normal file
29
src/windows/header/conproc.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Header file to the "qhost" subsystem.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
void InitConProc(int argc, char **argv);
|
||||
void DeinitConProc(void);
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
#include <conio.h>
|
||||
|
||||
#include "../common/header/common.h"
|
||||
#include "conproc.h"
|
||||
#include "header/conproc.h"
|
||||
#include "resource.h"
|
||||
#include "winquake.h"
|
||||
|
||||
|
|
Loading…
Reference in a new issue