26 #include "../../common/common.h"
29 #define CONSOLE_WINDOW_STYLE (WS_OVERLAPPED|WS_BORDER|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_CLIPCHILDREN|WS_GROUP)
30 #define CONSOLE_WINDOW_CLASS_NAME GAME_TITLE" Console"
33 #define CONSOLE_WINDOW_NAME GAME_TITLE" Dedicated Server Console"
35 #define CONSOLE_WINDOW_NAME CONSOLE_WINDOW_CLASS_NAME
38 #define MAX_OUTPUT 32768
39 #define MAX_PRINTMSG 8192
75 while (PeekMessage(&msg,
nullptr, 0, 0, PM_NOREMOVE)) {
76 if (!GetMessage(&msg,
nullptr, 0, 0)) {
83 TranslateMessage(&msg);
84 DispatchMessage(&msg);
127 buffer[len++] =
'\r';
128 buffer[len++] =
'\n';
130 buffer[len++] = *text;
143 SendMessage(sys_console.
hWndOutput, EM_SETSEL, 0, -1);
148 SendMessage(sys_console.
hWndOutput, EM_LINESCROLL, 0, 0xFFFF);
149 SendMessage(sys_console.
hWndOutput, EM_SCROLLCARET, 0, 0);
151 SendMessage(sys_console.
hWndOutput, EM_REPLACESEL, FALSE, (LPARAM)buffer);
154 SendMessage(sys_console.
hWndOutput, EM_LINESCROLL, 0, 0xFFFF);
155 SendMessage(sys_console.
hWndOutput, EM_SCROLLCARET, 0, 0);
180 va_start(argptr, error);
190 SetWindowText(sys_console.
hWndMsg, text);
191 SetTimer(sys_console.
hWnd, 1, 1000,
nullptr);
196 ShowWindow(sys_console.
hWndMsg, SW_SHOW);
197 ShowWindow(sys_console.
hWndInput, SW_HIDE);
212 ShowWindow(sys_console.
hWnd, SW_HIDE);
216 ShowWindow(sys_console.
hWnd, SW_SHOW);
217 UpdateWindow(sys_console.
hWnd);
218 SetForegroundWindow(sys_console.
hWnd);
219 SetFocus(sys_console.
hWnd);
225 SendMessage(sys_console.
hWndOutput, EM_LINESCROLL, 0, 0xFFFF);
226 SendMessage(sys_console.
hWndOutput, EM_SCROLLCARET, 0, 0);
229 static LRESULT CALLBACK
Sys_ConsoleProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
233 if (LOWORD(wParam) != WA_INACTIVE) {
241 const int ays = MessageBox(hWnd,
"There are still players on the server! Really shut it down?",
"WARNING!", MB_YESNO + MB_ICONEXCLAMATION);
249 if (HIWORD(wParam) == BN_CLICKED) {
250 if ((HWND)lParam == sys_console.
hWndCopy) {
251 SendMessage(sys_console.
hWndOutput, EM_SETSEL, 0, -1);
252 SendMessage(sys_console.
hWndOutput, WM_COPY, 0, 0);
253 }
else if ((HWND)lParam == sys_console.
hWndClear) {
254 SendMessage(sys_console.
hWndOutput, EM_SETSEL, 0, -1);
255 SendMessage(sys_console.
hWndOutput, WM_CLEAR, 0, 0);
256 }
else if ((HWND)lParam == sys_console.
hWndQuit)
258 }
else if (HIWORD(wParam) == EN_VSCROLL)
259 InvalidateRect(sys_console.
hWndOutput,
nullptr, TRUE);
262 case WM_CTLCOLOREDIT:
264 SetBkMode((HDC)wParam, TRANSPARENT);
265 SetBkColor((HDC)wParam, RGB(255, 255, 255));
266 SetTextColor((HDC)wParam, RGB(0, 0, 0));
268 }
else if ((HWND)lParam == sys_console.
hWndInput) {
269 SetBkMode((HDC)wParam, TRANSPARENT);
270 SetBkColor((HDC)wParam, RGB(255, 255, 255));
271 SetTextColor((HDC)wParam, RGB(0, 0, 0));
276 case WM_CTLCOLORSTATIC:
277 if ((HWND)lParam == sys_console.
hWndMsg) {
278 SetBkMode((HDC)wParam, TRANSPARENT);
279 SetBkColor((HDC)wParam, RGB(127, 127, 127));
282 SetTextColor((HDC)wParam, RGB(255, 0, 0));
284 SetTextColor((HDC)wParam, RGB(0, 0, 0));
292 InvalidateRect(sys_console.
hWndMsg,
nullptr, TRUE);
296 SetTimer(sys_console.
hWnd, 1, 500,
nullptr);
300 return DefWindowProc(hWnd, uMsg, wParam, lParam);
312 SetWindowText(sys_console.
hWndInput,
"");
320 uint32_t inputpos = 0;
335 if (LOWORD(wParam) == SB_THUMBTRACK)
341 return CallWindowProc(sys_console.
defOutputProc, hWnd, uMsg, wParam, lParam);
343 return CallWindowProc(sys_console.
defInputProc, hWnd, uMsg, wParam, lParam);
354 KillTimer(sys_console.
hWnd, 1);
363 if (sys_console.
hFont)
364 DeleteObject(sys_console.
hFont);
373 ShowWindow(sys_console.
hWnd, SW_HIDE);
374 DestroyWindow(sys_console.
hWnd);
388 const HDC hDC = GetDC(0);
389 int w = GetDeviceCaps(hDC, HORZRES);
390 int h = GetDeviceCaps(hDC, VERTRES);
393 r.left = (w - 540) / 2;
394 r.top = (h - 455) / 2;
395 r.right = r.left + 540;
396 r.bottom = r.top + 455;
400 const int x = r.left;
402 w = r.right - r.left;
403 h = r.bottom - r.top;
412 wc.hCursor = LoadCursor(
nullptr, IDC_ARROW);
413 wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
416 wc.cbSize =
sizeof(WNDCLASSEX);
418 if (!RegisterClassEx(&wc)) {
419 MessageBox(
nullptr,
"Could not register console window class",
"ERROR", MB_OK | MB_ICONERROR | MB_TASKMODAL);
423 sys_console.
hWnd = CreateWindowEx(0,
CONSOLE_WINDOW_CLASS_NAME,
CONSOLE_WINDOW_NAME,
CONSOLE_WINDOW_STYLE, x, y, w, h,
nullptr,
nullptr,
global_hInstance,
nullptr);
424 if (!sys_console.
hWnd) {
426 MessageBox(
nullptr,
"Could not create console window",
"ERROR", MB_OK | MB_ICONERROR | MB_TASKMODAL);
430 sys_console.
hWndMsg = CreateWindowEx(0,
"STATIC",
"", WS_CHILD | SS_SUNKEN, 5, 5, 530, 30, sys_console.
hWnd,
nullptr,
global_hInstance,
nullptr);
431 sys_console.
hWndOutput = CreateWindowEx(0,
"EDIT",
"", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | ES_MULTILINE, 5, 40, 530, 350, sys_console.
hWnd,
nullptr,
global_hInstance,
nullptr);
432 sys_console.
hWndInput = CreateWindowEx(0,
"EDIT",
"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL, 5, 395, 530, 20, sys_console.
hWnd,
nullptr,
global_hInstance,
nullptr);
433 sys_console.
hWndCopy = CreateWindowEx(0,
"BUTTON",
"copy", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 5, 425, 70, 25, sys_console.
hWnd,
nullptr,
global_hInstance,
nullptr);
434 sys_console.
hWndClear = CreateWindowEx(0,
"BUTTON",
"clear", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 80, 425, 70, 25, sys_console.
hWnd,
nullptr,
global_hInstance,
nullptr);
435 sys_console.
hWndQuit = CreateWindowEx(0,
"BUTTON",
"quit", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 465, 425, 70, 25, sys_console.
hWnd,
nullptr,
global_hInstance,
nullptr);
438 sys_console.
hFont = CreateFont(14, 0, 0, 0, FW_LIGHT, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
"Courier New");
439 sys_console.
hFontBold = CreateFont(20, 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
"System");
441 SendMessage(sys_console.
hWndMsg, WM_SETFONT, (WPARAM)sys_console.
hFont, FALSE);
442 SendMessage(sys_console.
hWndOutput, WM_SETFONT, (WPARAM)sys_console.
hFont, FALSE);
443 SendMessage(sys_console.
hWndInput, WM_SETFONT, (WPARAM)sys_console.
hFont, FALSE);
444 SendMessage(sys_console.
hWndCopy, WM_SETFONT, (WPARAM)sys_console.
hFontBold, FALSE);
446 SendMessage(sys_console.
hWndQuit, WM_SETFONT, (WPARAM)sys_console.
hFontBold, FALSE);
449 sys_console.
hBrushMsg = CreateSolidBrush(RGB(127, 127, 127));
450 sys_console.
hBrushOutput = CreateSolidBrush(RGB(255, 255, 255));
451 sys_console.
hBrushInput = CreateSolidBrush(RGB(255, 255, 255));
void Com_BreakIntoDebugger(void)
int Q_vsnprintf(char *str, size_t size, const char *format, va_list ap)
Safe (null terminating) vsnprintf implementation.
void Sys_Backtrace(void)
On platforms supporting it, print a backtrace.
static void Sys_ConsoleLoop(bool error)
Dispatch window messages.
void Sys_ShowConsole(bool show)
void Sys_Error(const char *error,...)
#define CONSOLE_WINDOW_CLASS_NAME
void Sys_ConsoleOutput(const char *text)
static LRESULT CALLBACK Sys_ConsoleProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
void Com_Printf(const char *const fmt,...)
HINSTANCE global_hInstance
#define CONSOLE_WINDOW_NAME
void Sys_ConsoleShutdown(void)
Shutdown the console.
void Sys_BacktraceInit(void)
#define CONSOLE_WINDOW_STYLE
void Sys_Sleep(int milliseconds)
Calls the win32 sleep function.
Win32-specific UFO header file.
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
const char * Sys_ConsoleInput(void)
Handles input for the console window.
static LONG WINAPI Sys_ConsoleEditProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
int SV_CountPlayers(void)
Returns the number of spawned players.
bool Com_ConsoleCompleteCommand(const char *s, char *target, size_t bufSize, uint32_t *pos, uint32_t offset)
Console completion for command and variables.
QGL_EXTERN GLuint GLchar GLuint * len
void Sys_ConsoleInit(void)
Initialize the console input (tty mode if possible)
char cmdBuffer[MAXCMDLINE]
void Sys_BacktraceShutdown(void)
static sysConsole_t sys_console