The "eaarly console" widnow is now back for Windows

- can be defined off to windowless behavior
- X still doesn't close it
- Still some makefile-related and other cleanup/implementation to do. i sleepcoded this :(
This commit is contained in:
leilei-
2016-05-28 08:35:11 -04:00
parent 5c4712f192
commit 601a5ec701
5 changed files with 639 additions and 1 deletions

View File

@@ -232,6 +232,10 @@ ifndef USE_RENDERER_DLOPEN
USE_RENDERER_DLOPEN=1
endif
ifndef USE_CONSOLE_WINDOW
USE_CONSOLE_WINDOW=1
endif
ifndef DEBUG_CFLAGS
DEBUG_CFLAGS=-g -O0
endif
@@ -604,6 +608,13 @@ ifeq ($(PLATFORM),mingw32)
CLIENT_LIBS = -lgdi32 -lole32
RENDERER_LIBS = -lgdi32 -lole32 -lopengl32
#ifeq ($(USE_CONSOLE_WINDOW),0)
CLIENT_CFLAGS += -DUSE_CONSOLE_WINDOW
CLIENT_LIBS += -lcomdlg32 -lcomctl32
LIBS += -lcomdlg32 -lcomctl32
LIBS += -lgdi32 -lole32 -lcomctl32 -lcomdlg32 #leilei - for console. if it works. :/
#endif
ifeq ($(USE_FREETYPE),1)
BASE_CFLAGS += -Ifreetype2
endif

View File

@@ -34,6 +34,8 @@ BUILD_RENDERER_OPENGL2=0
# You can disable the renderer libraries and build in the OA renderer by default
USE_RENDERER_DLOPEN=0
USE_CONSOLE_WINDOW=1 # use an early console window (WIN32 only)
# renderer_oa - This causes compiling issues on Linux and does not work yet.
USE_FALLBACK_GLSL=0
@@ -42,6 +44,9 @@ GLSL_POSTPROCESSING =1 # for r_ntsc/leifx/anime/retroAA/palletize/postprocess
GLSL_TEXTURES =1 # for shaders on models, leifxdither, etc
GLSL_BACKEND =1 # for the entire backend.
# You can change these although you probably don't need to
CLIENTBIN=openarena
SERVERBIN=oa_ded

View File

@@ -769,6 +769,11 @@ static void GLimp_InitExtensions( void )
#define R_MODE_FALLBACK 3 // 640 * 480
#if defined( _WIN32 ) && defined( USE_CONSOLE_WINDOW )
void Sys_DestroyConsole(void);
void Sys_ShowConsole( int visLevel, qboolean quitOnClose );
#endif
/*
===============
GLimp_Init
@@ -861,6 +866,11 @@ success:
// This depends on SDL_INIT_VIDEO, hence having it here
ri.IN_Init( );
#if defined( _WIN32 ) && defined( USE_CONSOLE_WINDOW )
// leilei - hide our console window
Sys_ShowConsole(0, 0 );
#endif
}

View File

@@ -337,6 +337,10 @@ void Sys_AnsiColorPrint( const char *msg )
}
}
#if defined( _WIN32 ) && defined( USE_CONSOLE_WINDOW )
void Conbuf_AppendText( const char *pMsg );// leilei - console restoration
#endif
/*
=================
Sys_Print
@@ -344,6 +348,9 @@ Sys_Print
*/
void Sys_Print( const char *msg )
{
#if defined( _WIN32 ) && defined( USE_CONSOLE_WINDOW )
Conbuf_AppendText (msg); // leilei - console restoration
#endif
CON_LogWrite( msg );
CON_Print( msg );
}

View File

@@ -39,6 +39,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <psapi.h>
#include <float.h>
#ifdef USE_CONSOLE_WINDOW
// windowstuff
void Sys_ShowConsole( int visLevel, qboolean quitOnClose );
void Conbuf_AppendText( const char *pMsg );
void Sys_DestroyConsole( void );
#endif
// Used to determine where to store user-specific files
static char homePath[ MAX_OSPATH ] = { 0 };
@@ -579,6 +587,35 @@ Display an error message
*/
void Sys_ErrorDialog( const char *error )
{
#ifdef USE_CONSOLE_WINDOW
// leilei - console restoration
//va_list argptr;
//char text[4096];
MSG msg;
Conbuf_AppendText( error );
Conbuf_AppendText( "\n" );
Sys_SetErrorText( error );
Sys_ShowConsole( 1, qtrue );
timeEndPeriod( 1 );
IN_Shutdown();
// wait for the user to quit
while ( 1 ) {
if (!GetMessage (&msg, NULL, 0, 0))
Com_Quit_f ();
TranslateMessage (&msg);
DispatchMessage (&msg);
}
Sys_DestroyConsole();
exit (1);
#else
if( Sys_Dialog( DT_YES_NO, va( "%s. Copy console log to clipboard?", error ),
"Error" ) == DR_YES )
{
@@ -609,6 +646,7 @@ void Sys_ErrorDialog( const char *error )
CloseClipboard( );
}
}
#endif
}
/*
@@ -694,7 +732,11 @@ void Sys_GLimpInit( void )
}
#endif
}
#ifndef DEDICATED
#ifdef USE_CONSOLE_WINDOW
void Sys_CreateConsole( void );
#endif
#endif
/*
==============
Sys_PlatformInit
@@ -712,6 +754,16 @@ void Sys_PlatformInit( void )
Sys_SetFloatEnv();
#ifndef DEDICATED
#ifdef USE_CONSOLE_WINDOW
// leilei - console restoration
// done before Com/Sys_Init since we need this for error output
Sys_CreateConsole();
#endif
if( SDL_VIDEODRIVER )
{
Com_Printf( "SDL_VIDEODRIVER is externally set to \"%s\", "
@@ -803,3 +855,556 @@ qboolean Sys_PIDIsRunning( int pid )
return qfalse;
}
// leilei - win32 console restoration
#ifdef USE_CONSOLE_WINDOW
#include "../sys/win_resource.h"
#include "../qcommon/q_shared.h"
#include "../qcommon/qcommon.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <olectl.h>
#include <wingdi.h>
#include <math.h>
#include "../renderercommon/tr_common.h"
#include "../sys/sys_local.h"
typedef struct
{
HINSTANCE reflib_library; // Handle to refresh DLL
qboolean reflib_active;
HWND hWnd;
HINSTANCE hInstance;
qboolean activeApp;
qboolean isMinimized;
OSVERSIONINFO osversion;
// when we get a windows message, we store the time off so keyboard processing
// can know the exact time of an event
unsigned sysMsgTime;
} WinVars_t;
WinVars_t g_wv;
#define CONSOLE_WINDOW_TITLE "OpenArena3 Console"
#define CONSOLE_WINDOW_ICON CLIENT_WINDOW_ICON
#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
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];
int visLevel;
qboolean quitOnClose;
int windowWidth, windowHeight;
WNDPROC SysInputLineWndProc;
} WinConData;
static WinConData s_wcd;
static LONG WINAPI ConWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
//char *cmdString; // TODO: Reimplement Quit
static qboolean s_timePolarity;
switch (uMsg)
{
case WM_ACTIVATE:
if ( LOWORD( wParam ) != WA_INACTIVE )
{
SetFocus( s_wcd.hwndInputLine );
}
/* if ( com_viewlog && ( com_dedicated && !com_dedicated->integer ) )
{
// if the viewlog is open, check to see if it's being minimized
if ( com_viewlog->integer == 1 )
{
if ( HIWORD( wParam ) ) // minimized flag
{
// ri.Cvar_Set( "viewlog", "2" );
}
}
else if ( com_viewlog->integer == 2 )
{
if ( !HIWORD( wParam ) ) // minimized flag
{
// ri.Cvar_Set( "viewlog", "1" );
}
}
}
*/
break;
case WM_CLOSE:
// if ( ( com_dedicated && com_dedicated->integer ) )
// {
// cmdString = CopyString( "quit" );
// Sys_QueEvent( 0, SE_CONSOLE, 0, 0, strlen( cmdString ) + 1, cmdString );
// }
// else if ( s_wcd.quitOnClose )
// {
// PostQuitMessage( 0 );
// }
// else
{
// Sys_ShowConsole( 0, qfalse );
// ri.Cvar_Set( "viewlog", "0" );
}
return 0;
case WM_CTLCOLORSTATIC:
if ( ( HWND ) lParam == s_wcd.hwndBuffer )
{
// SetBkColor( ( HDC ) wParam, RGB( 0x00, 0x00, 0xB0 ) ); // old colors
// SetTextColor( ( HDC ) wParam, RGB( 0xff, 0xff, 0x00 ) );
SetBkColor( ( HDC ) wParam, RGB( 0x09, 0x29, 0x35 ) );
SetTextColor( ( HDC ) wParam, RGB( 0xC3, 0xDA, 0xF3 ) );
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_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 = CopyString( "quit" ); // TODO: Reimplement quit
// Sys_QueEvent( 0, SE_CONSOLE, 0, 0, strlen( cmdString ) + 1, cmdString );
}
}
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.hbmLogo = LoadBitmap( g_wv.hInstance, MAKEINTRESOURCE( IDB_BITMAP1 ) );
// s_wcd.hbmClearBitmap = LoadBitmap( g_wv.hInstance, MAKEINTRESOURCE( IDB_BITMAP2 ) ); // could use one later for test throwbacks
// s_wcd.hbrEditBackground = CreateSolidBrush( RGB( 0x00, 0x00, 0xB0 ) );
s_wcd.hbrEditBackground = CreateSolidBrush( RGB( 0x09, 0x29, 0x35 ) );
s_wcd.hbrErrorBackground = CreateSolidBrush( RGB( 0x80, 0x80, 0x80 ) );
SetTimer( hWnd, 1, 1000, NULL );
break;
case WM_ERASEBKGND:
return DefWindowProc( hWnd, uMsg, wParam, lParam );
case WM_TIMER:
if ( wParam == 1 )
{
s_timePolarity = !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)
{
char inputBuffer[1024];
switch ( uMsg )
{
case WM_KILLFOCUS:
if ( ( HWND ) wParam == s_wcd.hWnd ||
( HWND ) wParam == s_wcd.hwndErrorBox )
{
SetFocus( hWnd );
return 0;
}
break;
case WM_CHAR:
if ( wParam == 13 )
{
GetWindowText( s_wcd.hwndInputLine, inputBuffer, sizeof( inputBuffer ) );
strncat( s_wcd.consoleText, inputBuffer, sizeof( s_wcd.consoleText ) - strlen( s_wcd.consoleText ) - 5 );
strcat( s_wcd.consoleText, "\n" );
SetWindowText( s_wcd.hwndInputLine, "" );
Sys_Print( va( "]%s\n", inputBuffer ) );
return 0;
}
}
return CallWindowProc( s_wcd.SysInputLineWndProc, hWnd, uMsg, wParam, lParam );
}
/*
** Sys_CreateConsole
*/
void Sys_CreateConsole( void )
{
HDC hDC;
WNDCLASS wc;
RECT rect;
const char *DEDCLASS = "Q3 WinConsole";
int nHeight;
int swidth, sheight;
int DEDSTYLE = WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX;
memset( &wc, 0, sizeof( wc ) );
wc.style = 0;
wc.lpfnWndProc = (WNDPROC) ConWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_wv.hInstance;
wc.hIcon = LoadIcon( g_wv.hInstance, MAKEINTRESOURCE(IDI_ICON1));
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
wc.hbrBackground = (void *)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.hWnd = CreateWindowEx( 0,
DEDCLASS,
CONSOLE_WINDOW_TITLE,
DEDSTYLE,
( swidth - 600 ) / 2, ( sheight - 450 ) / 2 , rect.right - rect.left + 1, rect.bottom - rect.top + 1,
NULL,
NULL,
g_wv.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
g_wv.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
g_wv.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
g_wv.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
g_wv.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
g_wv.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 );
ShowWindow( s_wcd.hWnd, SW_SHOWDEFAULT);
UpdateWindow( s_wcd.hWnd );
SetForegroundWindow( s_wcd.hWnd );
SetFocus( s_wcd.hwndInputLine );
s_wcd.visLevel = 1;
}
/*
** Sys_DestroyConsole
*/
void Sys_DestroyConsole( void ) {
if ( s_wcd.hWnd ) {
ShowWindow( s_wcd.hWnd, SW_HIDE );
CloseWindow( s_wcd.hWnd );
DestroyWindow( s_wcd.hWnd );
s_wcd.hWnd = 0;
}
}
void Conbuf_AppendText( const char *pMsg );
/*
** Sys_ShowConsole
*/
void Sys_ShowConsole( int visLevel, qboolean quitOnClose )
{
s_wcd.quitOnClose = quitOnClose;
if ( visLevel == s_wcd.visLevel )
{
return;
}
s_wcd.visLevel = visLevel;
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;
}
}
/*
** 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 ( Q_IsColorString( &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 > 0x7fff )
{
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 );
}
/*
** Sys_SetErrorText
*/
void Sys_SetErrorText( const char *buf )
{
Q_strncpyz( 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
g_wv.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;
}
}
#endif