diff options
Diffstat (limited to 'source/cl_aastat.c')
-rw-r--r-- | source/cl_aastat.c | 360 |
1 files changed, 360 insertions, 0 deletions
diff --git a/source/cl_aastat.c b/source/cl_aastat.c new file mode 100644 index 0000000..f864a97 --- /dev/null +++ b/source/cl_aastat.c @@ -0,0 +1,360 @@ +/* +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. + +*/ + +#include "cl_local.h" + +/* +=============================================================================== + +STAT PROGRAMS TO TEXT + +=============================================================================== +*/ + +#define TH_WIDTH 80 +#define TH_HEIGHT 40 + +static void TH_DrawString( char *dst, int x, int y, char *src, size_t len ) { + int c; + + if( x + len > TH_WIDTH ) { + len = TH_WIDTH - x; + } + + dst += y * ( TH_WIDTH + 1 ) + x; + while( len-- ) { + c = *src++; + c &= 127; + switch( c ) { + case 13: c = '>'; break; + case 16: c = '['; break; + case 17: c = ']'; break; + case 29: c = '<'; break; + case 30: c = '='; break; + case 31: c = '>'; break; + default: + if( c < 32 ) { + c = 32; + } + break; + } + *dst++ = c; + } +} + +static void TH_DrawCenterString( char *dst, int x, int y, char *src, size_t len ) { + x -= len / 2; + if( x < 0 ) { + src -= x; + x = 0; + } + + TH_DrawString( dst, x, y, src, len ); +} + +static void TH_DrawNumber( char *dst, int x, int y, int width, int value ) { + char num[16]; + int l; + + if( width < 1 ) + return; + + // draw number string + if( width > 5 ) + width = 5; + + l = Com_sprintf( num, sizeof( num ), "%d", value ); + if( l > width ) + l = width; + x += width - l; + + TH_DrawString( dst, x, y, num, l ); +} + +static void TH_DrawLayoutString( char *dst, const char *s ) { + char buffer[MAX_QPATH]; + int x, y; + int value; + char *token; + size_t len; + int width, index; + clientinfo_t *ci; + + if( !s[0] ) + return; + + x = 0; + y = 0; + width = 3; + + while( s ) { + token = COM_Parse( &s ); + if( token[2] == 0 ) { + if( token[0] == 'x' ) { + if( token[1] == 'l' ) { + token = COM_Parse( &s ); + x = atoi( token ) / 8; + continue; + } + + if( token[1] == 'r' ) { + token = COM_Parse( &s ); + x = TH_WIDTH + atoi( token ) / 8; + continue; + } + + if( token[1] == 'v' ) { + token = COM_Parse( &s ); + x = TH_WIDTH / 2 - 20 + atoi( token ) / 8; + continue; + } + } + + if( token[0] == 'y' ) { + if( token[1] == 't' ) { + token = COM_Parse( &s ); + y = atoi( token ) / 8; + continue; + } + + if( token[1] == 'b' ) { + token = COM_Parse( &s ); + y = TH_HEIGHT + atoi( token ) / 8; + continue; + } + + if( token[1] == 'v' ) { + token = COM_Parse( &s ); + y = TH_HEIGHT / 2 - 15 + atoi( token ) / 8; + continue; + } + } + } + + if( !strcmp( token, "pic" ) ) { + // draw a pic from a stat number + COM_Parse( &s ); + continue; + } + + if( !strcmp( token, "client" ) ) { + // draw a deathmatch client block + int score, ping, time; + + token = COM_Parse( &s ); + x = TH_WIDTH / 2 - 20 + atoi( token ) / 8; + token = COM_Parse( &s ); + y = TH_HEIGHT / 2 - 15 + atoi( token ) / 8; + + token = COM_Parse( &s ); + value = atoi( token ); + if( value < 0 || value >= MAX_CLIENTS ) { + Com_Error( ERR_DROP, "%s: invalid client index", __func__ ); + } + ci = &cl.clientinfo[value]; + + token = COM_Parse( &s ); + score = atoi( token ); + + token = COM_Parse( &s ); + ping = atoi( token ); + + token = COM_Parse( &s ); + time = atoi( token ); + + len = strlen( ci->name ); + TH_DrawString( dst, x + 4, y, ci->name, len ); + len = Com_sprintf( buffer, sizeof( buffer ), "Score: %i", score ); + TH_DrawString( dst, x + 4, y + 1, buffer, len ); + len = Com_sprintf( buffer, sizeof( buffer ), "Ping: %i", ping ); + TH_DrawString( dst, x + 4, y + 2, buffer, len ); + len = Com_sprintf( buffer, sizeof( buffer ), "Time: %i", time ); + TH_DrawString( dst, x + 4, y + 3, buffer, len ); + continue; + } + + if( !strcmp( token, "ctf" ) ) { + // draw a ctf client block + int score, ping; + + token = COM_Parse( &s ); + x = TH_WIDTH / 2 - 20 + atoi( token ) / 8; + token = COM_Parse( &s ); + y = TH_HEIGHT / 2 - 15 + atoi( token ) / 8; + + token = COM_Parse( &s ); + value = atoi( token ); + if( value < 0 || value >= MAX_CLIENTS ) { + Com_Error( ERR_DROP, "%s: invalid client index", __func__ ); + } + ci = &cl.clientinfo[value]; + + token = COM_Parse( &s ); + score = atoi( token ); + + token = COM_Parse( &s ); + ping = atoi( token ); + if( ping > 999 ) + ping = 999; + + len = Com_sprintf( buffer, sizeof( buffer ), "%3d %3d %-12.12s", + score, ping, ci->name ); + TH_DrawString( dst, x, y, buffer, len ); + continue; + } + + if( !strcmp( token, "picn" ) ) { + // draw a pic from a name + COM_Parse( &s ); + continue; + } + + if( !strcmp( token, "num" ) ) { + // draw a number + token = COM_Parse( &s ); + width = atoi( token ); + token = COM_Parse( &s ); + value = atoi( token ); + if( value < 0 || value >= MAX_STATS ) { + Com_Error( ERR_DROP, "%s: invalid stat index", __func__ ); + } + value = cl.frame.ps.stats[value]; + TH_DrawNumber( dst, x, y, width, value ); + continue; + } + + if( !strcmp( token, "stat_string" ) ) { + token = COM_Parse( &s ); + index = atoi( token ); + if( index < 0 || index >= MAX_STATS ) { + Com_Error( ERR_DROP, "%s: invalid string index", __func__ ); + } + index = cl.frame.ps.stats[index]; + if( index < 0 || index >= MAX_CONFIGSTRINGS ) { + Com_Error( ERR_DROP, "%s: invalid string index", __func__ ); + } + len = strlen( cl.configstrings[index] ); + TH_DrawString( dst, x, y, cl.configstrings[index], len ); + continue; + } + + if( !strncmp( token, "cstring", 7 ) ) { + token = COM_Parse( &s ); + len = strlen( token ); + TH_DrawCenterString( dst, x + 40 / 2, y, token, len ); + continue; + } + + if( !strncmp( token, "string", 6 ) ) { + token = COM_Parse( &s ); + len = strlen( token ); + TH_DrawString( dst, x, y, token, len ); + continue; + } + + if( !strcmp( token, "if" ) ) { + token = COM_Parse( &s ); + value = atoi( token ); + if( value < 0 || value >= MAX_STATS ) { + Com_Error( ERR_DROP, "%s: invalid stat index", __func__ ); + } + value = cl.frame.ps.stats[value]; + if( !value ) { // skip to endif + while( strcmp( token, "endif" ) ) { + token = COM_Parse( &s ); + if( !s ) { + break; + } + } + } + continue; + } + } +} + +static void SCR_ScoreShot_f( void ) { + char buffer[( TH_WIDTH + 1 ) * TH_HEIGHT]; + char path[MAX_QPATH]; + fileHandle_t f; + int i; + + if( cls.state != ca_active ) { + Com_Printf( "Must be in a level.\n" ); + return; + } + + if( Cmd_Argc() > 1 ) { + Q_concat( path, sizeof( path ), SCORESHOTS_DIRECTORY "/", Cmd_Argv( 1 ), NULL ); + COM_AppendExtension( path, ".txt", sizeof( path ) ); + } else { + for( i = 0; i < 1000; i++ ) { + Com_sprintf( path, sizeof( path ), SCORESHOTS_DIRECTORY "/quake%03d.txt", i ); + if( FS_LoadFileEx( path, NULL, FS_PATH_GAME, TAG_FREE ) == INVALID_LENGTH ) { + break; // file doesn't exist + } + } + + if( i == 1000 ) { + Com_Printf( "All scoreshot slots are full.\n" ); + return; + } + } + + FS_FOpenFile( path, &f, FS_MODE_WRITE ); + if( !f ) { + Com_EPrintf( "Couldn't open %s for writing.\n", path ); + return; + } + + memset( buffer, ' ', sizeof( buffer ) ); + for( i = 0; i < TH_HEIGHT; i++ ) { + buffer[ i * ( TH_WIDTH + 1 ) + TH_WIDTH ] = '\n'; + } + + TH_DrawLayoutString( buffer, cl.configstrings[CS_STATUSBAR] ); + TH_DrawLayoutString( buffer, cl.layout ); + + FS_Write( buffer, sizeof( buffer ), f ); + + FS_FCloseFile( f ); + + Com_Printf( "Wrote %s.\n", path ); +} + +static void SCR_ScoreDump_f( void ) { + char buffer[( TH_WIDTH + 1 ) * TH_HEIGHT]; + int i; + + memset( buffer, ' ', sizeof( buffer ) ); + for( i = 0; i < TH_HEIGHT; i++ ) { + buffer[ i * ( TH_WIDTH + 1 ) + TH_WIDTH ] = '\n'; + } + + TH_DrawLayoutString( buffer, cl.configstrings[CS_STATUSBAR] ); + TH_DrawLayoutString( buffer, cl.layout ); + + Com_Printf( "%s", buffer ); +} + +void CL_InitAscii( void ) { + Cmd_AddCommand( "aashot", SCR_ScoreShot_f ); + Cmd_AddCommand( "aadump", SCR_ScoreDump_f ); +} + |