mirror of
https://github.com/ioquake/ioq3.git
synced 2024-11-10 07:11:46 +00:00
* Add con_log.c to log all console output
* Add con_passive.c to cut down on #ifdef DEDICATED in sys_main.c * Add Sys_ErrorDialog to report ERR_FATALs to the user + On Windows use a MessageBox and offer to copy the console log to the clipboard + On everything else print to the terminal and save the console log as crashlog.txt
This commit is contained in:
parent
ccc66aadff
commit
3cde9bf0dc
10 changed files with 340 additions and 95 deletions
3
Makefile
3
Makefile
|
@ -1221,6 +1221,8 @@ Q3OBJ = \
|
|||
$(B)/client/sdl_input.o \
|
||||
$(B)/client/sdl_snd.o \
|
||||
\
|
||||
$(B)/client/con_passive.o \
|
||||
$(B)/client/con_log.o \
|
||||
$(B)/client/sys_main.o
|
||||
|
||||
ifeq ($(ARCH),i386)
|
||||
|
@ -1358,6 +1360,7 @@ Q3DOBJ = \
|
|||
$(B)/ded/null_input.o \
|
||||
$(B)/ded/null_snddma.o \
|
||||
\
|
||||
$(B)/ded/con_log.o \
|
||||
$(B)/ded/sys_main.o
|
||||
|
||||
ifeq ($(ARCH),i386)
|
||||
|
|
|
@ -2872,7 +2872,7 @@ static void FS_CheckPak0( void )
|
|||
if(!fs_gamedirvar->string[0]
|
||||
|| !Q_stricmp( fs_gamedirvar->string, BASEGAME )
|
||||
|| !Q_stricmp( fs_gamedirvar->string, "missionpack" ))
|
||||
Com_Error(ERR_FATAL, "\n*** you need to install Quake III Arena in order to play ***");
|
||||
Com_Error(ERR_FATAL, "You need to install Quake III Arena in order to play");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
129
code/sys/con_log.c
Normal file
129
code/sys/con_log.c
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena 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 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena 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 Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
#include "sys_local.h"
|
||||
|
||||
#define MAX_LOG 32768
|
||||
|
||||
static char consoleLog[ MAX_LOG ];
|
||||
static unsigned int write = 0;
|
||||
static unsigned int read = 0;
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_LogSize
|
||||
==================
|
||||
*/
|
||||
unsigned int CON_LogSize( void )
|
||||
{
|
||||
if( read <= write )
|
||||
return write - read;
|
||||
else
|
||||
return write + MAX_LOG - read;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_LogFree
|
||||
==================
|
||||
*/
|
||||
static unsigned int CON_LogFree( void )
|
||||
{
|
||||
return MAX_LOG - CON_LogSize( ) - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_LogWrite
|
||||
==================
|
||||
*/
|
||||
unsigned int CON_LogWrite( const char *in )
|
||||
{
|
||||
unsigned int length = strlen( in );
|
||||
unsigned int firstChunk;
|
||||
unsigned int secondChunk;
|
||||
|
||||
while( CON_LogFree( ) < length && CON_LogSize( ) > 0 )
|
||||
{
|
||||
// Free enough space
|
||||
while( consoleLog[ read ] != '\n' && CON_LogSize( ) > 1 )
|
||||
read = ( read + 1 ) % MAX_LOG;
|
||||
|
||||
// Skip past the '\n'
|
||||
read = ( read + 1 ) % MAX_LOG;
|
||||
}
|
||||
|
||||
if( CON_LogFree( ) < length )
|
||||
return 0;
|
||||
|
||||
if( write + length > MAX_LOG )
|
||||
{
|
||||
firstChunk = MAX_LOG - write;
|
||||
secondChunk = length - firstChunk;
|
||||
}
|
||||
else
|
||||
{
|
||||
firstChunk = length;
|
||||
secondChunk = 0;
|
||||
}
|
||||
|
||||
Com_Memcpy( consoleLog + write, in, firstChunk );
|
||||
Com_Memcpy( consoleLog, in + firstChunk, secondChunk );
|
||||
|
||||
write = ( write + length ) % MAX_LOG;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_LogRead
|
||||
==================
|
||||
*/
|
||||
unsigned int CON_LogRead( char *out, unsigned int outSize )
|
||||
{
|
||||
unsigned int firstChunk;
|
||||
unsigned int secondChunk;
|
||||
|
||||
if( CON_LogSize( ) < outSize )
|
||||
outSize = CON_LogSize( );
|
||||
|
||||
if( read + outSize > MAX_LOG )
|
||||
{
|
||||
firstChunk = MAX_LOG - read;
|
||||
secondChunk = outSize - firstChunk;
|
||||
}
|
||||
else
|
||||
{
|
||||
firstChunk = outSize;
|
||||
secondChunk = 0;
|
||||
}
|
||||
|
||||
Com_Memcpy( out, consoleLog + read, firstChunk );
|
||||
Com_Memcpy( out + firstChunk, out, secondChunk );
|
||||
|
||||
read = ( read + outSize ) % MAX_LOG;
|
||||
|
||||
return outSize;
|
||||
}
|
68
code/sys/con_passive.c
Normal file
68
code/sys/con_passive.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena 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 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena 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 Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
#include "sys_local.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_Shutdown
|
||||
==================
|
||||
*/
|
||||
void CON_Shutdown( void )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_Init
|
||||
==================
|
||||
*/
|
||||
void CON_Init( void )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_Input
|
||||
==================
|
||||
*/
|
||||
char *CON_Input( void )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_Print
|
||||
==================
|
||||
*/
|
||||
void CON_Print( const char *msg )
|
||||
{
|
||||
if( com_ansiColor && com_ansiColor->integer )
|
||||
Sys_AnsiColorPrint( msg );
|
||||
else
|
||||
fputs( msg, stderr );
|
||||
}
|
|
@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
#include "sys_local.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
@ -101,7 +102,7 @@ Clear the display of the line currently edited
|
|||
bring cursor back to beginning of line
|
||||
==================
|
||||
*/
|
||||
void CON_Hide( void )
|
||||
static void CON_Hide( void )
|
||||
{
|
||||
if( ttycon_on )
|
||||
{
|
||||
|
@ -131,7 +132,7 @@ Show the current line
|
|||
FIXME need to position the cursor if needed?
|
||||
==================
|
||||
*/
|
||||
void CON_Show( void )
|
||||
static void CON_Show( void )
|
||||
{
|
||||
if( ttycon_on )
|
||||
{
|
||||
|
@ -296,10 +297,10 @@ void CON_Init( void )
|
|||
|
||||
/*
|
||||
==================
|
||||
CON_ConsoleInput
|
||||
CON_Input
|
||||
==================
|
||||
*/
|
||||
char *CON_ConsoleInput( void )
|
||||
char *CON_Input( void )
|
||||
{
|
||||
// we use this when sending back commands
|
||||
static char text[256];
|
||||
|
@ -439,3 +440,20 @@ char *CON_ConsoleInput( void )
|
|||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_Print
|
||||
==================
|
||||
*/
|
||||
void CON_Print( const char *msg )
|
||||
{
|
||||
CON_Hide( );
|
||||
|
||||
if( com_ansiColor && com_ansiColor->integer )
|
||||
Sys_AnsiColorPrint( msg );
|
||||
else
|
||||
fputs( msg, stderr );
|
||||
|
||||
CON_Show( );
|
||||
}
|
||||
|
|
|
@ -130,21 +130,12 @@ static void CON_HistNext( void )
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_Hide
|
||||
==================
|
||||
*/
|
||||
void CON_Hide( void )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_Show
|
||||
==================
|
||||
*/
|
||||
void CON_Show( void )
|
||||
static void CON_Show( void )
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO binfo;
|
||||
COORD writeSize = { MAX_EDIT_LINE, 1 };
|
||||
|
@ -155,7 +146,7 @@ void CON_Show( void )
|
|||
|
||||
GetConsoleScreenBufferInfo( qconsole_hout, &binfo );
|
||||
|
||||
// if we' re in the middle of printf, don't bother writing the buffer
|
||||
// if we're in the middle of printf, don't bother writing the buffer
|
||||
if( binfo.dwCursorPosition.X != 0 )
|
||||
return;
|
||||
|
||||
|
@ -249,10 +240,10 @@ void CON_Init( void )
|
|||
|
||||
/*
|
||||
==================
|
||||
CON_ConsoleInput
|
||||
CON_Input
|
||||
==================
|
||||
*/
|
||||
char *CON_ConsoleInput( void )
|
||||
char *CON_Input( void )
|
||||
{
|
||||
INPUT_RECORD buff[ MAX_EDIT_LINE ];
|
||||
DWORD count = 0, events = 0;
|
||||
|
@ -353,3 +344,15 @@ char *CON_ConsoleInput( void )
|
|||
|
||||
return qconsole_line;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_Print
|
||||
==================
|
||||
*/
|
||||
void CON_Print( const char *msg )
|
||||
{
|
||||
fputs( msg, stderr );
|
||||
|
||||
CON_Show( );
|
||||
}
|
||||
|
|
|
@ -29,19 +29,24 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define MINSDL_PATCH 7
|
||||
|
||||
// Input subsystem
|
||||
void IN_Init (void);
|
||||
void IN_Frame (void);
|
||||
void IN_Shutdown (void);
|
||||
void IN_Init( void );
|
||||
void IN_Frame( void );
|
||||
void IN_Shutdown( void );
|
||||
|
||||
// Console
|
||||
void CON_Hide( void );
|
||||
void CON_Show( void );
|
||||
void CON_Shutdown( void );
|
||||
void CON_Init( void );
|
||||
char *CON_ConsoleInput(void);
|
||||
char *CON_Input( void );
|
||||
void CON_Print( const char *message );
|
||||
|
||||
unsigned int CON_LogSize( void );
|
||||
unsigned int CON_LogWrite( const char *in );
|
||||
unsigned int CON_LogRead( char *out, unsigned int outSize );
|
||||
|
||||
#ifdef MACOS_X
|
||||
char *Sys_StripAppBundle( char *pwd );
|
||||
#endif
|
||||
|
||||
void Sys_SigHandler( int signal );
|
||||
void Sys_ErrorDialog( const char *error );
|
||||
void Sys_AnsiColorPrint( const char *msg );
|
||||
|
|
|
@ -106,34 +106,6 @@ void Sys_In_Restart_f( void )
|
|||
IN_Init();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_ConsoleInputInit
|
||||
|
||||
Start the console input subsystem
|
||||
=================
|
||||
*/
|
||||
void Sys_ConsoleInputInit( void )
|
||||
{
|
||||
#ifdef DEDICATED
|
||||
CON_Init( );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_ConsoleInputShutdown
|
||||
|
||||
Shutdown the console input subsystem
|
||||
=================
|
||||
*/
|
||||
void Sys_ConsoleInputShutdown( void )
|
||||
{
|
||||
#ifdef DEDICATED
|
||||
CON_Shutdown( );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_ConsoleInput
|
||||
|
@ -143,11 +115,7 @@ Handle new console input
|
|||
*/
|
||||
char *Sys_ConsoleInput(void)
|
||||
{
|
||||
#ifdef DEDICATED
|
||||
return CON_ConsoleInput( );
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
return CON_Input( );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -159,18 +127,18 @@ Single exit point (regular exit or in case of error)
|
|||
*/
|
||||
void Sys_Exit( int ex )
|
||||
{
|
||||
Sys_ConsoleInputShutdown();
|
||||
CON_Shutdown( );
|
||||
|
||||
#ifndef DEDICATED
|
||||
SDL_Quit( );
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
exit(ex);
|
||||
exit( ex );
|
||||
#else
|
||||
// Cause a backtrace on error exits
|
||||
assert( ex == 0 );
|
||||
exit(ex);
|
||||
exit( ex );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -179,10 +147,10 @@ void Sys_Exit( int ex )
|
|||
Sys_Quit
|
||||
=================
|
||||
*/
|
||||
void Sys_Quit (void)
|
||||
void Sys_Quit( void )
|
||||
{
|
||||
CL_Shutdown ();
|
||||
Sys_Exit(0);
|
||||
CL_Shutdown( );
|
||||
Sys_Exit( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -227,7 +195,7 @@ Sys_AnsiColorPrint
|
|||
Transform Q3 colour codes to ANSI escape sequences
|
||||
=================
|
||||
*/
|
||||
static void Sys_AnsiColorPrint( const char *msg )
|
||||
void Sys_AnsiColorPrint( const char *msg )
|
||||
{
|
||||
static char buffer[ MAXPRINTMSG ];
|
||||
int length = 0;
|
||||
|
@ -296,18 +264,8 @@ Sys_Print
|
|||
*/
|
||||
void Sys_Print( const char *msg )
|
||||
{
|
||||
#ifdef DEDICATED
|
||||
CON_Hide();
|
||||
#endif
|
||||
|
||||
if( com_ansiColor && com_ansiColor->integer )
|
||||
Sys_AnsiColorPrint( msg );
|
||||
else
|
||||
fputs(msg, stderr);
|
||||
|
||||
#ifdef DEDICATED
|
||||
CON_Show();
|
||||
#endif
|
||||
CON_LogWrite( msg );
|
||||
CON_Print( msg );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -320,16 +278,13 @@ void Sys_Error( const char *error, ... )
|
|||
va_list argptr;
|
||||
char string[1024];
|
||||
|
||||
#ifdef DEDICATED
|
||||
CON_Hide();
|
||||
#endif
|
||||
|
||||
CL_Shutdown ();
|
||||
|
||||
va_start (argptr,error);
|
||||
Q_vsnprintf (string, sizeof(string), error, argptr);
|
||||
va_end (argptr);
|
||||
fprintf(stderr, "Sys_Error: %s\n", string);
|
||||
|
||||
Sys_ErrorDialog( string );
|
||||
|
||||
Sys_Exit( 1 );
|
||||
}
|
||||
|
@ -348,15 +303,7 @@ void Sys_Warn( char *warning, ... )
|
|||
Q_vsnprintf (string, sizeof(string), warning, argptr);
|
||||
va_end (argptr);
|
||||
|
||||
#ifdef DEDICATED
|
||||
CON_Hide();
|
||||
#endif
|
||||
|
||||
fprintf(stderr, "Warning: %s", string);
|
||||
|
||||
#ifdef DEDICATED
|
||||
CON_Show();
|
||||
#endif
|
||||
CON_Print( va( "Warning: %s", string ) );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -624,9 +571,9 @@ int main( int argc, char **argv )
|
|||
}
|
||||
|
||||
Com_Init( commandLine );
|
||||
NET_Init();
|
||||
NET_Init( );
|
||||
|
||||
Sys_ConsoleInputInit();
|
||||
CON_Init( );
|
||||
|
||||
#ifndef _WIN32
|
||||
// Windows doesn't have these signals
|
||||
|
|
|
@ -19,6 +19,11 @@ along with Quake III Arena source code; if not, write to the Free Software
|
|||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
#include "sys_local.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
@ -30,9 +35,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include <pwd.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
|
||||
// Used to determine where to store user-specific files
|
||||
static char homePath[ MAX_OSPATH ] = { 0 };
|
||||
|
||||
|
@ -476,3 +478,33 @@ void Sys_Sleep( int msec )
|
|||
select((fileno(stdin) + 1), &fdset, NULL, NULL, &timeout);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_ErrorDialog
|
||||
|
||||
Display an error message
|
||||
==============
|
||||
*/
|
||||
void Sys_ErrorDialog( const char *error )
|
||||
{
|
||||
char buffer[ 1024 ];
|
||||
unsigned int size;
|
||||
fileHandle_t f;
|
||||
const char *fileName = "crashlog.txt";
|
||||
|
||||
Sys_Print( va( "%s\n", error ) );
|
||||
|
||||
// Write console log to file
|
||||
f = FS_FOpenFileWrite( fileName );
|
||||
if( !f )
|
||||
{
|
||||
Com_Printf( "ERROR: couldn't open %s\n", fileName );
|
||||
return;
|
||||
}
|
||||
|
||||
while( ( size = CON_LogRead( buffer, sizeof( buffer ) ) ) > 0 )
|
||||
FS_Write( buffer, size, f );
|
||||
|
||||
FS_FCloseFile( f );
|
||||
}
|
||||
|
|
|
@ -525,3 +525,43 @@ void Sys_Sleep( int msec )
|
|||
WaitForSingleObject( GetStdHandle( STD_INPUT_HANDLE ), msec );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_ErrorDialog
|
||||
|
||||
Display an error message
|
||||
==============
|
||||
*/
|
||||
void Sys_ErrorDialog( const char *error )
|
||||
{
|
||||
if( MessageBox( NULL, va( "%s. Copy console log to clipboard?", error ),
|
||||
NULL, MB_YESNO|MB_ICONERROR ) == IDYES )
|
||||
{
|
||||
HGLOBAL memoryHandle;
|
||||
char *clipMemory;
|
||||
|
||||
memoryHandle = GlobalAlloc( GMEM_MOVEABLE|GMEM_DDESHARE, CON_LogSize( ) + 1 );
|
||||
clipMemory = (char *)GlobalLock( memoryHandle );
|
||||
|
||||
if( clipMemory )
|
||||
{
|
||||
char *p = clipMemory;
|
||||
char buffer[ 1024 ];
|
||||
unsigned int size;
|
||||
|
||||
while( ( size = CON_LogRead( buffer, sizeof( buffer ) ) ) > 0 )
|
||||
{
|
||||
Com_Memcpy( p, buffer, size );
|
||||
p += size;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
|
||||
if( OpenClipboard( NULL ) && EmptyClipboard( ) )
|
||||
SetClipboardData( CF_TEXT, memoryHandle );
|
||||
|
||||
GlobalUnlock( clipMemory );
|
||||
CloseClipboard( );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue