123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554 |
- /*
- ===========================================================================
- Doom 3 BFG Edition GPL Source Code
- Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
- Doom 3 BFG Edition Source Code 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 3 of the License, or
- (at your option) any later version.
- Doom 3 BFG Edition Source Code 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 Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
- If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- ===========================================================================
- */
- #pragma hdrstop
- #include "../../idlib/precompiled.h"
- #include <errno.h>
- #include <float.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <direct.h>
- #include <io.h>
- #include <conio.h>
- #include "win_local.h"
- #include "rc/doom_resource.h"
- #define COPY_ID 1
- #define QUIT_ID 2
- #define CLEAR_ID 3
- #define ERRORBOX_ID 10
- #define ERRORTEXT_ID 11
- #define EDIT_ID 100
- #define INPUT_ID 101
- #define COMMAND_HISTORY 64
- typedef struct {
- HWND hWnd;
- HWND hwndBuffer;
- HWND hwndButtonClear;
- HWND hwndButtonCopy;
- HWND hwndButtonQuit;
- HWND hwndErrorBox;
- HWND hwndErrorText;
- HBITMAP hbmLogo;
- HBITMAP hbmClearBitmap;
- HBRUSH hbrEditBackground;
- HBRUSH hbrErrorBackground;
- HFONT hfBufferFont;
- HFONT hfButtonFont;
- HWND hwndInputLine;
- char errorString[80];
- char consoleText[512], returnedText[512];
- bool quitOnClose;
- int windowWidth, windowHeight;
-
- WNDPROC SysInputLineWndProc;
- idEditField historyEditLines[COMMAND_HISTORY];
- int nextHistoryLine;// the last line in the history buffer, not masked
- int historyLine; // the line being displayed from history buffer
- // will be <= nextHistoryLine
- idEditField consoleField;
- } WinConData;
- static WinConData s_wcd;
- static LONG WINAPI ConWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- char *cmdString;
- static bool s_timePolarity;
- switch (uMsg) {
- case WM_ACTIVATE:
- if ( LOWORD( wParam ) != WA_INACTIVE ) {
- SetFocus( s_wcd.hwndInputLine );
- }
- break;
- case WM_CLOSE:
- if ( s_wcd.quitOnClose ) {
- PostQuitMessage( 0 );
- } else {
- Sys_ShowConsole( 0, false );
- win32.win_viewlog.SetBool( false );
- }
- return 0;
- case WM_CTLCOLORSTATIC:
- if ( ( HWND ) lParam == s_wcd.hwndBuffer ) {
- SetBkColor( ( HDC ) wParam, RGB( 0x00, 0x00, 0x80 ) );
- SetTextColor( ( HDC ) wParam, RGB( 0xff, 0xff, 0x00 ) );
- return ( long ) s_wcd.hbrEditBackground;
- } else if ( ( HWND ) lParam == s_wcd.hwndErrorBox ) {
- if ( s_timePolarity & 1 ) {
- SetBkColor( ( HDC ) wParam, RGB( 0x80, 0x80, 0x80 ) );
- SetTextColor( ( HDC ) wParam, RGB( 0xff, 0x0, 0x00 ) );
- } else {
- SetBkColor( ( HDC ) wParam, RGB( 0x80, 0x80, 0x80 ) );
- SetTextColor( ( HDC ) wParam, RGB( 0x00, 0x0, 0x00 ) );
- }
- return ( long ) s_wcd.hbrErrorBackground;
- }
- break;
- case WM_SYSCOMMAND:
- if ( wParam == SC_CLOSE ) {
- PostQuitMessage( 0 );
- }
- break;
- case WM_COMMAND:
- if ( wParam == COPY_ID ) {
- SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 );
- SendMessage( s_wcd.hwndBuffer, WM_COPY, 0, 0 );
- } else if ( wParam == QUIT_ID ) {
- if ( s_wcd.quitOnClose ) {
- PostQuitMessage( 0 );
- } else {
- cmdString = Mem_CopyString( "quit" );
- Sys_QueEvent( SE_CONSOLE, 0, 0, strlen( cmdString ) + 1, cmdString, 0 );
- }
- } else if ( wParam == CLEAR_ID ) {
- SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 );
- SendMessage( s_wcd.hwndBuffer, EM_REPLACESEL, FALSE, ( LPARAM ) "" );
- UpdateWindow( s_wcd.hwndBuffer );
- }
- break;
- case WM_CREATE:
- s_wcd.hbrEditBackground = CreateSolidBrush( RGB( 0x00, 0x00, 0x80 ) );
- s_wcd.hbrErrorBackground = CreateSolidBrush( RGB( 0x80, 0x80, 0x80 ) );
- SetTimer( hWnd, 1, 1000, NULL );
- break;
- /*
- case WM_ERASEBKGND:
- HGDIOBJ oldObject;
- HDC hdcScaled;
- hdcScaled = CreateCompatibleDC( ( HDC ) wParam );
- assert( hdcScaled != 0 );
- if ( hdcScaled ) {
- oldObject = SelectObject( ( HDC ) hdcScaled, s_wcd.hbmLogo );
- assert( oldObject != 0 );
- if ( oldObject )
- {
- StretchBlt( ( HDC ) wParam, 0, 0, s_wcd.windowWidth, s_wcd.windowHeight,
- hdcScaled, 0, 0, 512, 384,
- SRCCOPY );
- }
- DeleteDC( hdcScaled );
- hdcScaled = 0;
- }
- return 1;
- */
- case WM_TIMER:
- if ( wParam == 1 ) {
- s_timePolarity = (bool)!s_timePolarity;
- if ( s_wcd.hwndErrorBox ) {
- InvalidateRect( s_wcd.hwndErrorBox, NULL, FALSE );
- }
- }
- break;
- }
- return DefWindowProc( hWnd, uMsg, wParam, lParam );
- }
- LONG WINAPI InputLineWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- int key, cursor;
- switch ( uMsg ) {
- case WM_KILLFOCUS:
- if ( ( HWND ) wParam == s_wcd.hWnd || ( HWND ) wParam == s_wcd.hwndErrorBox ) {
- SetFocus( hWnd );
- return 0;
- }
- break;
- case WM_KEYDOWN:
- key = ( ( lParam >> 16 ) & 0xFF ) | ( ( ( lParam >> 24 ) & 1 ) << 7 );
- // command history
- if ( ( key == K_UPARROW ) || ( key == K_KP_8 ) ) {
- if ( s_wcd.nextHistoryLine - s_wcd.historyLine < COMMAND_HISTORY && s_wcd.historyLine > 0 ) {
- s_wcd.historyLine--;
- }
- s_wcd.consoleField = s_wcd.historyEditLines[ s_wcd.historyLine % COMMAND_HISTORY ];
- SetWindowText( s_wcd.hwndInputLine, s_wcd.consoleField.GetBuffer() );
- SendMessage( s_wcd.hwndInputLine, EM_SETSEL, s_wcd.consoleField.GetCursor(), s_wcd.consoleField.GetCursor() );
- return 0;
- }
- if ( ( key == K_DOWNARROW ) || ( key == K_KP_2 ) ) {
- if ( s_wcd.historyLine == s_wcd.nextHistoryLine ) {
- return 0;
- }
- s_wcd.historyLine++;
- s_wcd.consoleField = s_wcd.historyEditLines[ s_wcd.historyLine % COMMAND_HISTORY ];
- SetWindowText( s_wcd.hwndInputLine, s_wcd.consoleField.GetBuffer() );
- SendMessage( s_wcd.hwndInputLine, EM_SETSEL, s_wcd.consoleField.GetCursor(), s_wcd.consoleField.GetCursor() );
- return 0;
- }
- break;
- case WM_CHAR:
- key = ( ( lParam >> 16 ) & 0xFF ) | ( ( ( lParam >> 24 ) & 1 ) << 7 );
- GetWindowText( s_wcd.hwndInputLine, s_wcd.consoleField.GetBuffer(), MAX_EDIT_LINE );
- SendMessage( s_wcd.hwndInputLine, EM_GETSEL, (WPARAM) NULL, (LPARAM) &cursor );
- s_wcd.consoleField.SetCursor( cursor );
- // enter the line
- if ( key == K_ENTER || key == K_KP_ENTER ) {
- strncat( s_wcd.consoleText, s_wcd.consoleField.GetBuffer(), sizeof( s_wcd.consoleText ) - strlen( s_wcd.consoleText ) - 5 );
- strcat( s_wcd.consoleText, "\n" );
- SetWindowText( s_wcd.hwndInputLine, "" );
- Sys_Printf( "]%s\n", s_wcd.consoleField.GetBuffer() );
- // copy line to history buffer
- s_wcd.historyEditLines[s_wcd.nextHistoryLine % COMMAND_HISTORY] = s_wcd.consoleField;
- s_wcd.nextHistoryLine++;
- s_wcd.historyLine = s_wcd.nextHistoryLine;
- s_wcd.consoleField.Clear();
- return 0;
- }
- // command completion
- if ( key == K_TAB ) {
- s_wcd.consoleField.AutoComplete();
- SetWindowText( s_wcd.hwndInputLine, s_wcd.consoleField.GetBuffer() );
- //s_wcd.consoleField.SetWidthInChars( strlen( s_wcd.consoleField.GetBuffer() ) );
- SendMessage( s_wcd.hwndInputLine, EM_SETSEL, s_wcd.consoleField.GetCursor(), s_wcd.consoleField.GetCursor() );
- return 0;
- }
- // clear autocompletion buffer on normal key input
- if ( ( key >= K_SPACE && key <= K_BACKSPACE ) ||
- ( key >= K_KP_SLASH && key <= K_KP_PLUS ) || ( key >= K_KP_STAR && key <= K_KP_EQUALS ) ) {
- s_wcd.consoleField.ClearAutoComplete();
- }
- break;
- }
- return CallWindowProc( s_wcd.SysInputLineWndProc, hWnd, uMsg, wParam, lParam );
- }
- /*
- ** Sys_CreateConsole
- */
- void Sys_CreateConsole() {
- HDC hDC;
- WNDCLASS wc;
- RECT rect;
- const char *DEDCLASS = WIN32_CONSOLE_CLASS;
- int nHeight;
- int swidth, sheight;
- int DEDSTYLE = WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX;
- int i;
- memset( &wc, 0, sizeof( wc ) );
- wc.style = 0;
- wc.lpfnWndProc = (WNDPROC) ConWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = win32.hInstance;
- wc.hIcon = LoadIcon( win32.hInstance, MAKEINTRESOURCE(IDI_ICON1));
- wc.hCursor = LoadCursor (NULL,IDC_ARROW);
- wc.hbrBackground = (struct HBRUSH__ *)COLOR_WINDOW;
- wc.lpszMenuName = 0;
- wc.lpszClassName = DEDCLASS;
- if ( !RegisterClass (&wc) ) {
- return;
- }
- rect.left = 0;
- rect.right = 540;
- rect.top = 0;
- rect.bottom = 450;
- AdjustWindowRect( &rect, DEDSTYLE, FALSE );
- hDC = GetDC( GetDesktopWindow() );
- swidth = GetDeviceCaps( hDC, HORZRES );
- sheight = GetDeviceCaps( hDC, VERTRES );
- ReleaseDC( GetDesktopWindow(), hDC );
- s_wcd.windowWidth = rect.right - rect.left + 1;
- s_wcd.windowHeight = rect.bottom - rect.top + 1;
- //s_wcd.hbmLogo = LoadBitmap( win32.hInstance, MAKEINTRESOURCE( IDB_BITMAP_LOGO) );
- s_wcd.hWnd = CreateWindowEx( 0,
- DEDCLASS,
- GAME_NAME,
- DEDSTYLE,
- ( swidth - 600 ) / 2, ( sheight - 450 ) / 2 , rect.right - rect.left + 1, rect.bottom - rect.top + 1,
- NULL,
- NULL,
- win32.hInstance,
- NULL );
- if ( s_wcd.hWnd == NULL ) {
- return;
- }
- //
- // create fonts
- //
- hDC = GetDC( s_wcd.hWnd );
- nHeight = -MulDiv( 8, GetDeviceCaps( hDC, LOGPIXELSY ), 72 );
- s_wcd.hfBufferFont = CreateFont( nHeight, 0, 0, 0, FW_LIGHT, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_MODERN | FIXED_PITCH, "Courier New" );
- ReleaseDC( s_wcd.hWnd, hDC );
- //
- // create the input line
- //
- s_wcd.hwndInputLine = CreateWindow( "edit", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER |
- ES_LEFT | ES_AUTOHSCROLL,
- 6, 400, 528, 20,
- s_wcd.hWnd,
- ( HMENU ) INPUT_ID, // child window ID
- win32.hInstance, NULL );
- //
- // create the buttons
- //
- s_wcd.hwndButtonCopy = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
- 5, 425, 72, 24,
- s_wcd.hWnd,
- ( HMENU ) COPY_ID, // child window ID
- win32.hInstance, NULL );
- SendMessage( s_wcd.hwndButtonCopy, WM_SETTEXT, 0, ( LPARAM ) "copy" );
- s_wcd.hwndButtonClear = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
- 82, 425, 72, 24,
- s_wcd.hWnd,
- ( HMENU ) CLEAR_ID, // child window ID
- win32.hInstance, NULL );
- SendMessage( s_wcd.hwndButtonClear, WM_SETTEXT, 0, ( LPARAM ) "clear" );
- s_wcd.hwndButtonQuit = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
- 462, 425, 72, 24,
- s_wcd.hWnd,
- ( HMENU ) QUIT_ID, // child window ID
- win32.hInstance, NULL );
- SendMessage( s_wcd.hwndButtonQuit, WM_SETTEXT, 0, ( LPARAM ) "quit" );
- //
- // create the scrollbuffer
- //
- s_wcd.hwndBuffer = CreateWindow( "edit", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER |
- ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY,
- 6, 40, 526, 354,
- s_wcd.hWnd,
- ( HMENU ) EDIT_ID, // child window ID
- win32.hInstance, NULL );
- SendMessage( s_wcd.hwndBuffer, WM_SETFONT, ( WPARAM ) s_wcd.hfBufferFont, 0 );
- s_wcd.SysInputLineWndProc = ( WNDPROC ) SetWindowLong( s_wcd.hwndInputLine, GWL_WNDPROC, ( long ) InputLineWndProc );
- SendMessage( s_wcd.hwndInputLine, WM_SETFONT, ( WPARAM ) s_wcd.hfBufferFont, 0 );
- // don't show it now that we have a splash screen up
- if ( win32.win_viewlog.GetBool() ) {
- ShowWindow( s_wcd.hWnd, SW_SHOWDEFAULT);
- UpdateWindow( s_wcd.hWnd );
- SetForegroundWindow( s_wcd.hWnd );
- SetFocus( s_wcd.hwndInputLine );
- }
- s_wcd.consoleField.Clear();
- for ( i = 0 ; i < COMMAND_HISTORY ; i++ ) {
- s_wcd.historyEditLines[i].Clear();
- }
- }
- /*
- ** Sys_DestroyConsole
- */
- void Sys_DestroyConsole() {
- if ( s_wcd.hWnd ) {
- ShowWindow( s_wcd.hWnd, SW_HIDE );
- CloseWindow( s_wcd.hWnd );
- DestroyWindow( s_wcd.hWnd );
- s_wcd.hWnd = 0;
- }
- }
- /*
- ** Sys_ShowConsole
- */
- void Sys_ShowConsole( int visLevel, bool quitOnClose ) {
- s_wcd.quitOnClose = quitOnClose;
- if ( !s_wcd.hWnd ) {
- return;
- }
- switch ( visLevel ) {
- case 0:
- ShowWindow( s_wcd.hWnd, SW_HIDE );
- break;
- case 1:
- ShowWindow( s_wcd.hWnd, SW_SHOWNORMAL );
- SendMessage( s_wcd.hwndBuffer, EM_LINESCROLL, 0, 0xffff );
- break;
- case 2:
- ShowWindow( s_wcd.hWnd, SW_MINIMIZE );
- break;
- default:
- Sys_Error( "Invalid visLevel %d sent to Sys_ShowConsole\n", visLevel );
- break;
- }
- }
- /*
- ** Sys_ConsoleInput
- */
- char *Sys_ConsoleInput() {
-
- if ( s_wcd.consoleText[0] == 0 ) {
- return NULL;
- }
-
- strcpy( s_wcd.returnedText, s_wcd.consoleText );
- s_wcd.consoleText[0] = 0;
-
- return s_wcd.returnedText;
- }
- /*
- ** Conbuf_AppendText
- */
- void Conbuf_AppendText( const char *pMsg )
- {
- #define CONSOLE_BUFFER_SIZE 16384
- char buffer[CONSOLE_BUFFER_SIZE*2];
- char *b = buffer;
- const char *msg;
- int bufLen;
- int i = 0;
- static unsigned long s_totalChars;
- //
- // if the message is REALLY long, use just the last portion of it
- //
- if ( strlen( pMsg ) > CONSOLE_BUFFER_SIZE - 1 ) {
- msg = pMsg + strlen( pMsg ) - CONSOLE_BUFFER_SIZE + 1;
- } else {
- msg = pMsg;
- }
- //
- // copy into an intermediate buffer
- //
- while ( msg[i] && ( ( b - buffer ) < sizeof( buffer ) - 1 ) ) {
- if ( msg[i] == '\n' && msg[i+1] == '\r' ) {
- b[0] = '\r';
- b[1] = '\n';
- b += 2;
- i++;
- } else if ( msg[i] == '\r' ) {
- b[0] = '\r';
- b[1] = '\n';
- b += 2;
- } else if ( msg[i] == '\n' ) {
- b[0] = '\r';
- b[1] = '\n';
- b += 2;
- } else if ( idStr::IsColor( &msg[i] ) ) {
- i++;
- } else {
- *b= msg[i];
- b++;
- }
- i++;
- }
- *b = 0;
- bufLen = b - buffer;
- s_totalChars += bufLen;
- //
- // replace selection instead of appending if we're overflowing
- //
- if ( s_totalChars > 0x7000 ) {
- SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 );
- s_totalChars = bufLen;
- }
- //
- // put this text into the windows console
- //
- SendMessage( s_wcd.hwndBuffer, EM_LINESCROLL, 0, 0xffff );
- SendMessage( s_wcd.hwndBuffer, EM_SCROLLCARET, 0, 0 );
- SendMessage( s_wcd.hwndBuffer, EM_REPLACESEL, 0, (LPARAM) buffer );
- }
- /*
- ** Win_SetErrorText
- */
- void Win_SetErrorText( const char *buf ) {
- idStr::Copynz( s_wcd.errorString, buf, sizeof( s_wcd.errorString ) );
- if ( !s_wcd.hwndErrorBox ) {
- s_wcd.hwndErrorBox = CreateWindow( "static", NULL, WS_CHILD | WS_VISIBLE | SS_SUNKEN,
- 6, 5, 526, 30,
- s_wcd.hWnd,
- ( HMENU ) ERRORBOX_ID, // child window ID
- win32.hInstance, NULL );
- SendMessage( s_wcd.hwndErrorBox, WM_SETFONT, ( WPARAM ) s_wcd.hfBufferFont, 0 );
- SetWindowText( s_wcd.hwndErrorBox, s_wcd.errorString );
- DestroyWindow( s_wcd.hwndInputLine );
- s_wcd.hwndInputLine = NULL;
- }
- }
|