This repository has been archived on 2022-06-27. You can view files and clone it, but cannot push or open issues or pull requests.
Xash3DArchive/engine/common/con_utils.c

898 lines
24 KiB
C
Raw Normal View History

2008-08-03 22:00:00 +02:00
//=======================================================================
// Copyright XashXT Group 2008 <20>
// con_utils.c - console helpers
//=======================================================================
#include "common.h"
#include "client.h"
#include "byteorder.h"
2008-11-22 22:00:00 +01:00
#include "const.h"
2010-06-28 22:00:00 +02:00
#include "bspfile.h"
2008-08-03 22:00:00 +02:00
/*
=======================================================================
FILENAME AUTOCOMPLETION
=======================================================================
*/
/*
=====================================
Cmd_GetMapList
Prints or complete map filename
=====================================
*/
bool Cmd_GetMapList( const char *s, char *completedname, int length )
{
search_t *t;
2009-07-12 22:00:00 +02:00
file_t *f;
2008-08-03 22:00:00 +02:00
string message;
string matchbuf;
byte buf[MAX_SYSPATH]; // 1 kb
int i, nummaps;
2008-11-22 22:00:00 +01:00
t = FS_Search( va( "maps/%s*.bsp", s ), true );
2008-08-03 22:00:00 +02:00
if( !t ) return false;
2008-11-22 22:00:00 +01:00
FS_FileBase( t->filenames[0], matchbuf );
2008-08-03 22:00:00 +02:00
com.strncpy( completedname, matchbuf, length );
2008-11-22 22:00:00 +01:00
if( t->numfilenames == 1 ) return true;
2008-08-03 22:00:00 +02:00
2008-11-22 22:00:00 +01:00
for( i = 0, nummaps = 0; i < t->numfilenames; i++ )
2008-08-03 22:00:00 +02:00
{
2009-07-12 22:00:00 +02:00
const char *data = NULL;
char entfilename[CS_SIZE];
int ver = -1, lumpofs = 0, lumplen = 0;
2008-08-03 22:00:00 +02:00
const char *ext = FS_FileExtension( t->filenames[i] );
2009-07-12 22:00:00 +02:00
script_t *ents = NULL;
2010-05-31 22:00:00 +02:00
bool gearbox;
2008-11-01 22:00:00 +01:00
if( com.stricmp( ext, "bsp" )) continue;
com.strncpy( message, "^1error^7", sizeof( message ));
2009-11-16 22:00:00 +01:00
f = FS_Open( t->filenames[i], "rb" );
2008-08-03 22:00:00 +02:00
2009-07-12 22:00:00 +02:00
if( f )
2008-08-03 22:00:00 +02:00
{
2009-11-03 22:00:00 +01:00
dheader_t *header;
2009-07-12 22:00:00 +02:00
2009-11-03 22:00:00 +01:00
Mem_Set( buf, 0, MAX_SYSPATH );
FS_Read( f, buf, MAX_SYSPATH );
2010-05-22 22:00:00 +02:00
ver = LittleLong(*(uint *)buf);
2009-11-03 22:00:00 +01:00
2010-05-22 22:00:00 +02:00
switch( ver )
2008-08-03 22:00:00 +02:00
{
2010-05-22 22:00:00 +02:00
case Q1BSP_VERSION:
case HLBSP_VERSION:
2009-11-03 22:00:00 +01:00
header = (dheader_t *)buf;
2010-05-31 22:00:00 +02:00
if( LittleLong( header->lumps[LUMP_PLANES].filelen ) % sizeof( dplane_t ))
{
lumpofs = LittleLong( header->lumps[LUMP_PLANES].fileofs );
lumplen = LittleLong( header->lumps[LUMP_PLANES].filelen );
gearbox = true;
}
else
{
lumpofs = LittleLong( header->lumps[LUMP_ENTITIES].fileofs );
lumplen = LittleLong( header->lumps[LUMP_ENTITIES].filelen );
gearbox = false;
}
2009-11-03 22:00:00 +01:00
break;
2009-07-12 22:00:00 +02:00
}
com.strncpy( entfilename, t->filenames[i], sizeof( entfilename ));
FS_StripExtension( entfilename );
FS_DefaultExtension( entfilename, ".ent" );
ents = Com_OpenScript( entfilename, NULL, 0 );
if( !ents && lumplen >= 10 )
{
char *entities = NULL;
FS_Seek( f, lumpofs, SEEK_SET );
2010-02-18 22:00:00 +01:00
entities = (char *)Mem_Alloc( host.mempool, lumplen + 1 );
2009-07-12 22:00:00 +02:00
FS_Read( f, entities, lumplen );
ents = Com_OpenScript( "ents", entities, lumplen + 1 );
Mem_Free( entities ); // no reason to keep it
}
if( ents )
{
// if there are entities to parse, a missing message key just
// means there is no title, so clear the message string now
token_t token;
message[0] = 0;
2010-06-08 22:00:00 +02:00
while( Com_ReadToken( ents, SC_ALLOW_NEWLINES|SC_ALLOW_PATHNAMES2, &token ))
2009-07-12 22:00:00 +02:00
{
if( !com.strcmp( token.string, "{" )) continue;
else if(!com.strcmp( token.string, "}" )) break;
else if(!com.strcmp( token.string, "message" ))
{
// get the message contents
2010-06-08 22:00:00 +02:00
Com_ReadString( ents, SC_ALLOW_PATHNAMES2, message );
2009-07-12 22:00:00 +02:00
}
}
Com_CloseScript( ents );
2008-08-03 22:00:00 +02:00
}
}
2009-07-12 22:00:00 +02:00
if( f ) FS_Close(f);
2008-11-01 22:00:00 +01:00
FS_FileBase( t->filenames[i], matchbuf );
switch( ver )
2008-08-03 22:00:00 +02:00
{
2010-05-22 22:00:00 +02:00
case Q1BSP_VERSION:
com.strncpy( buf, "Quake", sizeof( buf ));
2009-07-12 22:00:00 +02:00
break;
2010-05-22 22:00:00 +02:00
case HLBSP_VERSION:
2010-05-31 22:00:00 +02:00
if( gearbox ) com.strncpy( buf, "Blue-Shift", sizeof( buf ));
else com.strncpy( buf, "Half-Life", sizeof( buf ));
2009-11-03 22:00:00 +01:00
break;
2009-07-03 22:00:00 +02:00
default: com.strncpy( buf, "??", sizeof( buf )); break;
2008-08-03 22:00:00 +02:00
}
2009-07-03 22:00:00 +02:00
Msg( "%16s (%s) ^3%s^7\n", matchbuf, buf, message );
2008-08-03 22:00:00 +02:00
nummaps++;
}
2009-07-03 22:00:00 +02:00
Msg( "\n^3 %i maps found.\n", nummaps );
2008-08-03 22:00:00 +02:00
Mem_Free( t );
// cut shortestMatch to the amount common with s
for( i = 0; matchbuf[i]; i++ )
{
2009-07-03 22:00:00 +02:00
if(com.tolower( completedname[i] ) != com.tolower( matchbuf[i] ))
2008-08-03 22:00:00 +02:00
completedname[i] = 0;
}
return true;
}
/*
=====================================
Cmd_GetFontList
Prints or complete font filename
=====================================
*/
bool Cmd_GetFontList( const char *s, char *completedname, int length )
{
search_t *t;
string matchbuf;
int i, numfonts;
2010-04-12 22:00:00 +02:00
t = FS_Search( va( "gfx/fonts/%s*.*", s ), true);
if( !t ) return false;
2008-08-03 22:00:00 +02:00
2009-07-03 22:00:00 +02:00
FS_FileBase( t->filenames[0], matchbuf );
if( completedname && length ) com.strncpy( completedname, matchbuf, length );
2008-08-28 22:00:00 +02:00
if( t->numfilenames == 1 ) return true;
2008-08-03 22:00:00 +02:00
2009-07-03 22:00:00 +02:00
for( i = 0, numfonts = 0; i < t->numfilenames; i++ )
2008-08-03 22:00:00 +02:00
{
const char *ext = FS_FileExtension( t->filenames[i] );
2009-07-03 22:00:00 +02:00
if( com.stricmp( ext, "png" ) && com.stricmp( ext, "dds" ) && com.stricmp( ext, "tga" ))
2008-08-28 22:00:00 +02:00
continue;
2009-07-03 22:00:00 +02:00
FS_FileBase( t->filenames[i], matchbuf );
Msg( "%16s\n", matchbuf );
2008-08-03 22:00:00 +02:00
numfonts++;
}
2009-07-03 22:00:00 +02:00
Msg( "\n^3 %i fonts found.\n", numfonts );
Mem_Free( t );
2008-08-03 22:00:00 +02:00
// cut shortestMatch to the amount common with s
2009-07-03 22:00:00 +02:00
if( completedname && length )
2008-08-03 22:00:00 +02:00
{
for( i = 0; matchbuf[i]; i++ )
{
2009-07-03 22:00:00 +02:00
if(com.tolower( completedname[i] ) != com.tolower( matchbuf[i] ))
2008-08-03 22:00:00 +02:00
completedname[i] = 0;
}
}
return true;
}
/*
=====================================
Cmd_GetDemoList
Prints or complete demo filename
=====================================
*/
bool Cmd_GetDemoList( const char *s, char *completedname, int length )
{
search_t *t;
string matchbuf;
int i, numdems;
2010-06-06 22:00:00 +02:00
t = FS_Search( va( "<EFBFBD>demos/%s*.dem", s ), true );
2009-07-03 22:00:00 +02:00
if( !t ) return false;
2008-08-03 22:00:00 +02:00
2009-07-03 22:00:00 +02:00
FS_FileBase( t->filenames[0], matchbuf );
if( completedname && length ) com.strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true;
2008-08-03 22:00:00 +02:00
2009-07-03 22:00:00 +02:00
for( i = 0, numdems = 0; i < t->numfilenames; i++ )
2008-08-03 22:00:00 +02:00
{
const char *ext = FS_FileExtension( t->filenames[i] );
2009-07-03 22:00:00 +02:00
if( com.stricmp( ext, "dem" )) continue;
FS_FileBase( t->filenames[i], matchbuf );
Msg( "%16s\n", matchbuf );
2008-08-03 22:00:00 +02:00
numdems++;
}
2009-07-03 22:00:00 +02:00
Msg( "\n^3 %i demos found.\n", numdems );
Mem_Free( t );
2008-08-03 22:00:00 +02:00
// cut shortestMatch to the amount common with s
2009-07-03 22:00:00 +02:00
if( completedname && length )
2008-08-03 22:00:00 +02:00
{
for( i = 0; matchbuf[i]; i++ )
{
2009-07-03 22:00:00 +02:00
if( com.tolower( completedname[i] ) != com.tolower( matchbuf[i] ))
2008-08-03 22:00:00 +02:00
completedname[i] = 0;
}
}
return true;
}
/*
=====================================
Cmd_GetMovieList
Prints or complete movie filename
=====================================
*/
bool Cmd_GetMovieList( const char *s, char *completedname, int length )
{
search_t *t;
string matchbuf;
int i, nummovies;
2010-04-12 22:00:00 +02:00
t = FS_Search( va( "media/%s*.roq", s ), true );
if( !t ) return false;
2008-08-03 22:00:00 +02:00
FS_FileBase(t->filenames[0], matchbuf );
if(completedname && length) com.strncpy( completedname, matchbuf, length );
if(t->numfilenames == 1) return true;
for(i = 0, nummovies = 0; i < t->numfilenames; i++)
{
const char *ext = FS_FileExtension( t->filenames[i] );
2009-11-23 22:00:00 +01:00
if( com.stricmp( ext, "roq" )) continue;
2008-08-03 22:00:00 +02:00
FS_FileBase(t->filenames[i], matchbuf );
Msg("%16s\n", matchbuf );
nummovies++;
}
Msg("\n^3 %i movies found.\n", nummovies );
Mem_Free(t);
// cut shortestMatch to the amount common with s
if(completedname && length)
{
for( i = 0; matchbuf[i]; i++ )
{
if(com.tolower(completedname[i]) != com.tolower(matchbuf[i]))
completedname[i] = 0;
}
}
return true;
}
/*
=====================================
Cmd_GetMusicList
Prints or complete background track filename
=====================================
*/
bool Cmd_GetMusicList( const char *s, char *completedname, int length )
{
search_t *t;
string matchbuf;
int i, numtracks;
2010-04-12 22:00:00 +02:00
t = FS_Search( va( "media/%s*.ogg", s ), true );
if( !t ) return false;
2008-08-03 22:00:00 +02:00
FS_FileBase(t->filenames[0], matchbuf );
if(completedname && length) com.strncpy( completedname, matchbuf, length );
if(t->numfilenames == 1) return true;
for(i = 0, numtracks = 0; i < t->numfilenames; i++)
{
const char *ext = FS_FileExtension( t->filenames[i] );
if( com.stricmp(ext, "ogg" )) continue;
FS_FileBase(t->filenames[i], matchbuf );
Msg("%16s\n", matchbuf );
numtracks++;
}
Msg("\n^3 %i soundtracks found.\n", numtracks );
Mem_Free(t);
// cut shortestMatch to the amount common with s
if(completedname && length)
{
for( i = 0; matchbuf[i]; i++ )
{
if(com.tolower(completedname[i]) != com.tolower(matchbuf[i]))
completedname[i] = 0;
}
}
return true;
}
2009-09-28 22:00:00 +02:00
/*
=====================================
Cmd_GetSavesList
Prints or complete movie filename
=====================================
*/
bool Cmd_GetSavesList( const char *s, char *completedname, int length )
{
search_t *t;
string matchbuf;
int i, numsaves;
2010-06-06 22:00:00 +02:00
t = FS_Search( va( "<EFBFBD>save/%s*.sav", s ), true );
2009-09-28 22:00:00 +02:00
if( !t ) return false;
FS_FileBase( t->filenames[0], matchbuf );
if( completedname && length ) com.strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true;
for( i = 0, numsaves = 0; i < t->numfilenames; i++ )
{
const char *ext = FS_FileExtension( t->filenames[i] );
2010-07-19 22:00:00 +02:00
if( com.stricmp( ext, "sav" )) continue;
2009-09-28 22:00:00 +02:00
FS_FileBase( t->filenames[i], matchbuf );
Msg( "%16s\n", matchbuf );
numsaves++;
}
Msg( "\n^3 %i saves found.\n", numsaves );
Mem_Free( t );
// cut shortestMatch to the amount common with s
if( completedname && length )
{
for( i = 0; matchbuf[i]; i++ )
{
if( com.tolower( completedname[i] ) != com.tolower( matchbuf[i] ))
completedname[i] = 0;
}
}
return true;
}
2008-08-03 22:00:00 +02:00
/*
=====================================
Cmd_GetSoundList
Prints or complete sound filename
=====================================
*/
bool Cmd_GetSoundList( const char *s, char *completedname, int length )
{
search_t *t;
string matchbuf;
int i, numsounds;
const char *snddir = "sound/"; // constant
2010-03-22 22:00:00 +01:00
t = FS_Search( va( "%s%s*.*", snddir, s ), true );
if( !t ) return false;
2008-08-03 22:00:00 +02:00
2010-03-22 22:00:00 +01:00
com.strncpy( matchbuf, t->filenames[0] + com.strlen( snddir ), MAX_STRING );
2008-08-03 22:00:00 +02:00
FS_StripExtension( matchbuf );
if( completedname && length ) com.strncpy( completedname, matchbuf, length );
2010-03-22 22:00:00 +01:00
if( t->numfilenames == 1 ) return true;
2008-08-03 22:00:00 +02:00
for(i = 0, numsounds = 0; i < t->numfilenames; i++)
{
const char *ext = FS_FileExtension( t->filenames[i] );
2010-03-22 22:00:00 +01:00
if( com.stricmp( ext, "wav" ) && com.stricmp( ext, "ogg" )) continue;
2008-08-03 22:00:00 +02:00
com.strncpy( matchbuf, t->filenames[i] + com.strlen(snddir), MAX_STRING );
FS_StripExtension( matchbuf );
2010-03-22 22:00:00 +01:00
Msg( "%16s\n", matchbuf );
2008-08-03 22:00:00 +02:00
numsounds++;
}
2010-03-22 22:00:00 +01:00
Msg( "\n^3 %i sounds found.\n", numsounds );
Mem_Free( t );
2008-08-03 22:00:00 +02:00
// cut shortestMatch to the amount common with s
if( completedname && length )
{
for( i = 0; matchbuf[i]; i++ )
{
if(com.tolower(completedname[i]) != com.tolower(matchbuf[i]))
completedname[i] = 0;
}
}
return true;
}
2009-01-04 22:00:00 +01:00
bool Cmd_GetStringTablesList( const char *s, char *completedname, int length )
{
int i, numtables;
string tables[MAX_STRING_TABLES];
string matchbuf;
const char *name;
// compare gamelist with current keyword
for( i = 0, numtables = 0; i < MAX_STRING_TABLES; i++ )
{
name = StringTable_GetName( i );
if( name && ( *s == '*' || !com.strnicmp( name, s, com.strlen( s ))))
com.strcpy( tables[numtables++], name );
}
if( !numtables ) return false;
com.strncpy( matchbuf, tables[0], MAX_STRING );
if( completedname && length ) com.strncpy( completedname, matchbuf, length );
if( numtables == 1 ) return true;
for( i = 0; i < numtables; i++ )
{
com.strncpy( matchbuf, tables[i], MAX_STRING );
Msg("%16s\n", matchbuf );
}
Msg( "\n^3 %i stringtables found.\n", numtables );
// cut shortestMatch to the amount common with s
if( completedname && length )
{
for( i = 0; matchbuf[i]; i++ )
{
if( com.tolower( completedname[i]) != com.tolower( matchbuf[i] ))
completedname[i] = 0;
}
}
return true;
}
2008-08-03 22:00:00 +02:00
2009-01-23 22:00:00 +01:00
/*
=====================================
Cmd_GetItemsList
Prints or complete item classname
=====================================
*/
bool Cmd_GetItemsList( const char *s, char *completedname, int length )
{
search_t *t;
string matchbuf;
int i, numitems;
2010-07-08 22:00:00 +02:00
if( !clgame.itemspath[0] ) return false; // not in game yet
t = FS_Search( va( "%s/%s*.txt", clgame.itemspath, s ), true );
2009-01-23 22:00:00 +01:00
if( !t ) return false;
FS_FileBase( t->filenames[0], matchbuf );
if( completedname && length ) com.strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true;
for(i = 0, numitems = 0; i < t->numfilenames; i++)
{
const char *ext = FS_FileExtension( t->filenames[i] );
if( com.stricmp(ext, "txt" )) continue;
FS_FileBase( t->filenames[i], matchbuf );
Msg( "%16s\n", matchbuf );
numitems++;
}
Msg("\n^3 %i items found.\n", numitems );
Mem_Free( t );
// cut shortestMatch to the amount common with s
if( completedname && length )
{
for( i = 0; matchbuf[i]; i++ )
{
if(com.tolower(completedname[i]) != com.tolower(matchbuf[i]))
completedname[i] = 0;
}
}
return true;
}
2008-08-04 22:00:00 +02:00
/*
=====================================
2009-10-06 22:00:00 +02:00
Cmd_GetTexturemodes
2008-08-04 22:00:00 +02:00
Prints or complete sound filename
=====================================
*/
2009-10-06 22:00:00 +02:00
bool Cmd_GetTexturemodes( const char *s, char *completedname, int length )
{
int i, numtexturemodes;
string texturemodes[6]; // keep an actual ( sizeof( gl_texturemode) / sizeof( gl_texturemode[0] ))
string matchbuf;
const char *gl_texturemode[] =
{
"GL_LINEAR",
"GL_LINEAR_MIPMAP_LINEAR",
"GL_LINEAR_MIPMAP_NEAREST",
"GL_NEAREST",
"GL_NEAREST_MIPMAP_LINEAR",
"GL_NEAREST_MIPMAP_NEAREST",
};
// compare gamelist with current keyword
for( i = 0, numtexturemodes = 0; i < 6; i++ )
{
if(( *s == '*' ) || !com.strnicmp( gl_texturemode[i], s, com.strlen( s )))
com.strcpy( texturemodes[numtexturemodes++], gl_texturemode[i] );
}
if( !numtexturemodes ) return false;
com.strncpy( matchbuf, gl_texturemode[0], MAX_STRING );
if( completedname && length ) com.strncpy( completedname, matchbuf, length );
if( numtexturemodes == 1 ) return true;
for( i = 0; i < numtexturemodes; i++ )
{
com.strncpy( matchbuf, texturemodes[i], MAX_STRING );
Msg( "%16s\n", matchbuf );
}
Msg("\n^3 %i filters found.\n", numtexturemodes );
// cut shortestMatch to the amount common with s
if( completedname && length )
{
for( i = 0; matchbuf[i]; i++ )
{
if( com.tolower( completedname[i] ) != com.tolower( matchbuf[i] ))
completedname[i] = 0;
}
}
return true;
}
/*
=====================================
Cmd_GetGameList
Prints or complete gamedir name
=====================================
*/
2008-08-04 22:00:00 +02:00
bool Cmd_GetGamesList( const char *s, char *completedname, int length )
{
int i, numgamedirs;
2010-07-19 22:00:00 +02:00
string gamedirs[MAX_MODS];
2008-08-04 22:00:00 +02:00
string matchbuf;
// compare gamelist with current keyword
2009-09-10 22:00:00 +02:00
for( i = 0, numgamedirs = 0; i < SI->numgames; i++ )
2008-08-04 22:00:00 +02:00
{
2009-09-10 22:00:00 +02:00
if(( *s == '*' ) || !com.strnicmp( SI->games[i]->gamefolder, s, com.strlen( s )))
com.strcpy( gamedirs[numgamedirs++], SI->games[i]->gamefolder );
2008-08-04 22:00:00 +02:00
}
if( !numgamedirs ) return false;
com.strncpy( matchbuf, gamedirs[0], MAX_STRING );
if( completedname && length ) com.strncpy( completedname, matchbuf, length );
if( numgamedirs == 1) return true;
for( i = 0; i < numgamedirs; i++ )
{
com.strncpy( matchbuf, gamedirs[i], MAX_STRING );
Msg("%16s\n", matchbuf );
}
Msg("\n^3 %i games found.\n", numgamedirs );
// cut shortestMatch to the amount common with s
if( completedname && length )
{
for( i = 0; matchbuf[i]; i++ )
{
if(com.tolower(completedname[i]) != com.tolower(matchbuf[i]))
completedname[i] = 0;
}
}
return true;
}
2010-07-18 22:00:00 +02:00
bool Cmd_CheckMapsList( bool fRefresh )
2008-08-03 22:00:00 +02:00
{
2009-07-12 22:00:00 +02:00
byte buf[MAX_SYSPATH]; // 1 kb
char *buffer;
string result;
2008-08-03 22:00:00 +02:00
search_t *t;
2009-07-12 22:00:00 +02:00
file_t *f;
int i;
2008-08-03 22:00:00 +02:00
2010-07-30 22:00:00 +02:00
if( FS_FileExists( "<EFBFBD>maps.lst" ) && !fRefresh )
2008-08-03 22:00:00 +02:00
return true; // exist
t = FS_Search( "maps/*.bsp", false );
2008-11-22 22:00:00 +01:00
if( !t ) return false;
2008-08-03 22:00:00 +02:00
2010-02-18 22:00:00 +01:00
buffer = Mem_Alloc( host.mempool, t->numfilenames * 2 * sizeof( result ));
2008-08-03 22:00:00 +02:00
for( i = 0; i < t->numfilenames; i++ )
{
2009-07-12 22:00:00 +02:00
script_t *ents = NULL;
int ver = -1, lumpofs = 0, lumplen = 0;
string mapname, message, entfilename;
2008-11-22 22:00:00 +01:00
const char *ext = FS_FileExtension( t->filenames[i] );
2008-08-03 22:00:00 +02:00
2008-11-22 22:00:00 +01:00
if( com.stricmp( ext, "bsp" )) continue;
2009-07-12 22:00:00 +02:00
f = FS_Open( t->filenames[i], "rb" );
2008-08-03 22:00:00 +02:00
FS_FileBase( t->filenames[i], mapname );
2009-07-12 22:00:00 +02:00
if( f )
2008-08-03 22:00:00 +02:00
{
2009-11-03 22:00:00 +01:00
int num_spawnpoints = 0;
dheader_t *header;
2009-07-12 22:00:00 +02:00
Mem_Set( buf, 0, MAX_SYSPATH );
FS_Read( f, buf, MAX_SYSPATH );
2010-05-22 22:00:00 +02:00
ver = LittleLong(*(uint *)buf);
2009-11-03 22:00:00 +01:00
2010-05-22 22:00:00 +02:00
switch( ver )
2009-07-12 22:00:00 +02:00
{
2010-05-22 22:00:00 +02:00
case Q1BSP_VERSION:
case HLBSP_VERSION:
2009-11-03 22:00:00 +01:00
header = (dheader_t *)buf;
2010-05-31 22:00:00 +02:00
if( LittleLong( header->lumps[LUMP_PLANES].filelen ) % sizeof( dplane_t ))
{
lumpofs = LittleLong( header->lumps[LUMP_PLANES].fileofs );
lumplen = LittleLong( header->lumps[LUMP_PLANES].filelen );
}
else
{
lumpofs = LittleLong( header->lumps[LUMP_ENTITIES].fileofs );
lumplen = LittleLong( header->lumps[LUMP_ENTITIES].filelen );
}
2009-11-03 22:00:00 +01:00
break;
2008-08-03 22:00:00 +02:00
}
2008-11-22 22:00:00 +01:00
2009-07-12 22:00:00 +02:00
com.strncpy( entfilename, t->filenames[i], sizeof( entfilename ));
FS_StripExtension( entfilename );
FS_DefaultExtension( entfilename, ".ent" );
ents = Com_OpenScript( entfilename, NULL, 0 );
if( !ents && lumplen >= 10 )
{
char *entities = NULL;
FS_Seek( f, lumpofs, SEEK_SET );
2010-02-18 22:00:00 +01:00
entities = (char *)Mem_Alloc( host.mempool, lumplen + 1 );
2009-07-12 22:00:00 +02:00
FS_Read( f, entities, lumplen );
ents = Com_OpenScript( "ents", entities, lumplen + 1 );
Mem_Free( entities ); // no reason to keep it
}
2008-08-03 22:00:00 +02:00
2008-11-01 22:00:00 +01:00
if( ents )
2008-08-03 22:00:00 +02:00
{
// if there are entities to parse, a missing message key just
// means there is no title, so clear the message string now
2008-11-01 22:00:00 +01:00
token_t token;
2009-07-12 22:00:00 +02:00
message[0] = 0;
com.strncpy( message, "No Title", MAX_STRING );
2010-06-08 22:00:00 +02:00
while( Com_ReadToken( ents, SC_ALLOW_NEWLINES|SC_ALLOW_PATHNAMES2, &token ))
2008-08-03 22:00:00 +02:00
{
2009-07-12 22:00:00 +02:00
if( !com.strcmp( token.string, "{" )) continue;
else if( !com.strcmp( token.string, "}" )) break;
else if( !com.strcmp( token.string, "message" ))
{
// get the message contents
2010-06-08 22:00:00 +02:00
Com_ReadString( ents, SC_ALLOW_PATHNAMES2, message );
2009-07-12 22:00:00 +02:00
}
else if( !com.strcmp( token.string, "classname" ))
2008-08-03 22:00:00 +02:00
{
2010-06-08 22:00:00 +02:00
Com_ReadToken( ents, SC_ALLOW_PATHNAMES2, &token );
2009-07-12 22:00:00 +02:00
if( !com.strcmp( token.string, GI->dm_entity ))
2008-08-03 22:00:00 +02:00
num_spawnpoints++;
2009-07-12 22:00:00 +02:00
else if( !com.strcmp( token.string, GI->sp_entity ))
2008-08-03 22:00:00 +02:00
num_spawnpoints++;
}
2009-09-10 22:00:00 +02:00
if( num_spawnpoints > 1 ) break; // valid map
2008-08-03 22:00:00 +02:00
}
2008-11-01 22:00:00 +01:00
Com_CloseScript( ents );
2008-08-03 22:00:00 +02:00
}
2009-07-12 22:00:00 +02:00
if( f ) FS_Close(f);
2008-08-03 22:00:00 +02:00
// format: mapname "maptitle"\n
2009-07-12 22:00:00 +02:00
com.sprintf( result, "%s \"%s\"\n", mapname, message );
com.strcat( buffer, result ); // add new string
2008-08-03 22:00:00 +02:00
}
}
2008-11-01 22:00:00 +01:00
if( t ) Mem_Free( t ); // free search result
2008-08-03 22:00:00 +02:00
// write generated maps.lst
2010-07-30 22:00:00 +02:00
if( FS_WriteFile( "maps.lst", buffer, com.strlen( buffer )))
2008-08-03 22:00:00 +02:00
{
2008-11-01 22:00:00 +01:00
if( buffer ) Mem_Free( buffer );
2008-08-03 22:00:00 +02:00
return true;
}
return false;
}
autocomplete_list_t cmd_list[] =
{
2009-10-06 22:00:00 +02:00
{ "gl_texturemode", Cmd_GetTexturemodes },
{ "stringlist", Cmd_GetStringTablesList },
2008-08-03 22:00:00 +02:00
{ "changelevel", Cmd_GetMapList },
{ "playdemo", Cmd_GetDemoList, },
2009-12-20 22:00:00 +01:00
{ "menufont", Cmd_GetFontList, },
2008-08-03 22:00:00 +02:00
{ "setfont", Cmd_GetFontList, },
{ "music", Cmd_GetSoundList, },
{ "movie", Cmd_GetMovieList },
2009-01-23 22:00:00 +01:00
{ "give", Cmd_GetItemsList },
2009-09-24 22:00:00 +02:00
{ "drop", Cmd_GetItemsList },
2008-08-04 22:00:00 +02:00
{ "game", Cmd_GetGamesList },
2009-09-28 22:00:00 +02:00
{ "save", Cmd_GetSavesList },
{ "load", Cmd_GetSavesList },
2010-06-27 22:00:00 +02:00
{ "play", Cmd_GetSoundList },
2008-08-03 22:00:00 +02:00
{ "map", Cmd_GetMapList },
{ NULL }, // termiantor
};
/*
============
Cmd_WriteVariables
Appends lines containing "set variable value" for all variables
with the archive flag set to true.
============
*/
static void Cmd_WriteCvar(const char *name, const char *string, const char *desc, void *f )
{
2010-07-30 22:00:00 +02:00
if( !desc || !*desc ) return; // ignore cvars without description (fantom variables)
2008-08-03 22:00:00 +02:00
FS_Printf(f, "seta %s \"%s\"\n", name, string );
}
2010-01-30 22:00:00 +01:00
static void Cmd_WriteServerCvar(const char *name, const char *string, const char *desc, void *f )
{
2010-07-30 22:00:00 +02:00
if( !desc || !*desc ) return; // ignore cvars without description (fantom variables)
2010-01-30 22:00:00 +01:00
FS_Printf(f, "sets %s \"%s\"\n", name, string );
}
2010-07-30 22:00:00 +02:00
static void Cmd_WriteOpenGLCvar( const char *name, const char *string, const char *desc, void *f )
{
if( !desc || !*desc ) return; // ignore cvars without description (fantom variables)
FS_Printf( f, "setr %s \"%s\"\n", name, string );
}
2008-08-05 22:00:00 +02:00
static void Cmd_WriteHelp(const char *name, const char *unused, const char *desc, void *f )
{
if( !desc ) return; // ignore fantom cmds
if( !com.strcmp( desc, "" )) return; // blank description
if( name[0] == '+' || name[0] == '-' ) return; // key bindings
FS_Printf( f, "%s\t\t\t\"%s\"\n", name, desc );
}
2008-08-03 22:00:00 +02:00
void Cmd_WriteVariables( file_t *f )
{
FS_Printf( f, "unsetall\n" );
Cvar_LookupVars( CVAR_ARCHIVE, NULL, f, Cmd_WriteCvar );
}
2010-01-30 22:00:00 +01:00
void Cmd_WriteServerVariables( file_t *f )
{
Cvar_LookupVars( CVAR_SERVERINFO, NULL, f, Cmd_WriteServerCvar );
}
2010-07-30 22:00:00 +02:00
void Cmd_WriteOpenGLVariables( file_t *f )
{
Cvar_LookupVars( CVAR_RENDERINFO, NULL, f, Cmd_WriteOpenGLCvar );
}
2008-08-03 22:00:00 +02:00
/*
===============
2009-09-10 22:00:00 +02:00
Host_WriteConfig
2008-08-03 22:00:00 +02:00
2010-07-30 22:00:00 +02:00
Writes key bindings and archived cvars to config.cfg
2008-08-03 22:00:00 +02:00
===============
*/
2009-09-10 22:00:00 +02:00
void Host_WriteConfig( void )
2008-08-03 22:00:00 +02:00
{
file_t *f;
2008-08-05 22:00:00 +02:00
if( !cls.initialized ) return;
2008-08-03 22:00:00 +02:00
2010-07-30 22:00:00 +02:00
f = FS_Open( "config.cfg", "w" );
2008-11-12 22:00:00 +01:00
if( f )
2008-08-03 22:00:00 +02:00
{
2010-07-30 22:00:00 +02:00
FS_Printf( f, "//=======================================================================\n");
2009-09-10 22:00:00 +02:00
FS_Printf( f, "//\t\t\tCopyright XashXT Group %s <20>\n", timestamp( TIME_YEAR_ONLY ));
2010-07-30 22:00:00 +02:00
FS_Printf( f, "//\t\t\tconfig.cfg - archive of cvars\n" );
2009-09-10 22:00:00 +02:00
FS_Printf( f, "//=======================================================================\n" );
Key_WriteBindings( f );
2010-07-30 22:00:00 +02:00
Cmd_WriteVariables( f );
2009-09-10 22:00:00 +02:00
FS_Close( f );
2008-08-03 22:00:00 +02:00
}
2010-07-30 22:00:00 +02:00
else MsgDev( D_ERROR, "Couldn't write config.cfg.\n" );
2009-09-10 22:00:00 +02:00
}
/*
===============
2010-07-30 22:00:00 +02:00
Host_WriteServerConfig
2009-09-10 22:00:00 +02:00
2010-07-30 22:00:00 +02:00
save serverinfo variables into server.cfg (using for dedicated server too)
2009-09-10 22:00:00 +02:00
===============
*/
2010-07-30 22:00:00 +02:00
void Host_WriteServerConfig( const char *name )
2009-09-10 22:00:00 +02:00
{
file_t *f;
2010-07-30 22:00:00 +02:00
SV_InitGameProgs(); // collect user variables
if(( f = FS_Open( name, "w" )) != NULL )
2009-09-10 22:00:00 +02:00
{
FS_Printf( f, "//=======================================================================\n" );
FS_Printf( f, "//\t\t\tCopyright XashXT Group %s <20>\n", timestamp( TIME_YEAR_ONLY ));
2010-07-30 22:00:00 +02:00
FS_Printf( f, "//\t\t\tserver.cfg - server temporare config\n" );
2009-09-10 22:00:00 +02:00
FS_Printf( f, "//=======================================================================\n" );
2010-07-30 22:00:00 +02:00
Cmd_WriteServerVariables( f );
2009-09-10 22:00:00 +02:00
FS_Close( f );
2009-11-16 22:00:00 +01:00
}
2010-07-30 22:00:00 +02:00
else MsgDev( D_ERROR, "Couldn't write %s.\n", name );
2008-08-05 22:00:00 +02:00
}
2010-07-30 22:00:00 +02:00
2010-01-30 22:00:00 +01:00
/*
===============
2010-07-30 22:00:00 +02:00
Host_WriteOpenGLConfig
2010-01-30 22:00:00 +01:00
2010-07-30 22:00:00 +02:00
save renderinfo variables into opengl.cfg
2010-01-30 22:00:00 +01:00
===============
*/
2010-07-30 22:00:00 +02:00
void Host_WriteOpenGLConfig( void )
2010-01-30 22:00:00 +01:00
{
2010-07-22 22:00:00 +02:00
file_t *f;
2010-07-30 22:00:00 +02:00
f = FS_Open( "opengl.cfg", "w" );
if( f )
2010-01-30 22:00:00 +01:00
{
FS_Printf( f, "//=======================================================================\n" );
FS_Printf( f, "//\t\t\tCopyright XashXT Group %s <20>\n", timestamp( TIME_YEAR_ONLY ));
2010-07-30 22:00:00 +02:00
FS_Printf( f, "//\t\t opengl.cfg - archive of opengl extension cvars\n");
2010-01-30 22:00:00 +01:00
FS_Printf( f, "//=======================================================================\n" );
2010-07-30 22:00:00 +02:00
Cmd_WriteOpenGLVariables( f );
FS_Close( f );
}
else MsgDev( D_ERROR, "can't update opengl.cfg.\n" );
2010-01-30 22:00:00 +01:00
}
2008-08-05 22:00:00 +02:00
void Key_EnumCmds_f( void )
{
2010-01-30 22:00:00 +01:00
file_t *f;
FS_AllowDirectPaths( true );
if( FS_FileExists( "../help.txt" ))
{
Msg( "help.txt already exist\n" );
FS_AllowDirectPaths( false );
return;
}
f = FS_Open( "../help.txt", "w" );
2008-08-05 22:00:00 +02:00
if( f )
{
FS_Printf( f, "//=======================================================================\n");
2008-11-12 22:00:00 +01:00
FS_Printf( f, "//\t\t\tCopyright XashXT Group %s <20>\n", timestamp( TIME_YEAR_ONLY ));
2008-08-05 22:00:00 +02:00
FS_Printf( f, "//\t\thelp.txt - xash commands and console variables\n");
FS_Printf( f, "//=======================================================================\n");
FS_Printf( f, "\n\n\t\t\tconsole variables\n\n");
Cvar_LookupVars( 0, NULL, f, Cmd_WriteHelp );
FS_Printf( f, "\n\n\t\t\tconsole commands\n\n");
Cmd_LookupCmds( NULL, f, Cmd_WriteHelp );
FS_Printf( f, "\n\n");
FS_Close( f );
2010-01-30 22:00:00 +01:00
Msg( "help.txt created\n" );
2008-08-05 22:00:00 +02:00
}
else MsgDev( D_ERROR, "Couldn't write help.txt.\n");
2010-01-30 22:00:00 +01:00
FS_AllowDirectPaths( false );
2008-08-03 22:00:00 +02:00
}