29 #include "../idlib/precompiled.h"
64 #define USE_COMPRESSED_DECLS
90 virtual const char *
GetName(
void )
const;
94 virtual bool IsValid(
void )
const;
96 virtual void Reload(
void );
98 virtual int Index(
void )
const;
101 virtual size_t Size(
void )
const;
102 virtual void GetText(
char *text )
const;
104 virtual void SetText(
const char *text );
115 virtual void List(
void )
const;
116 virtual void Print(
void )
const;
161 void Reload(
bool force );
180 virtual void Init(
void );
182 virtual void Reload(
bool force );
196 virtual void ReloadFile(
const char* filename,
bool force );
274 static int huffmanFrequencies[] = {
275 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
276 0x00000001, 0x00078fb6, 0x000352a7, 0x00000002, 0x00000001, 0x0002795e, 0x00000001, 0x00000001,
277 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
278 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
279 0x00049600, 0x000000dd, 0x00018732, 0x0000005a, 0x00000007, 0x00000092, 0x0000000a, 0x00000919,
280 0x00002dcf, 0x00002dda, 0x00004dfc, 0x0000039a, 0x000058be, 0x00002d13, 0x00014d8c, 0x00023c60,
281 0x0002ddb0, 0x0000d1fc, 0x000078c4, 0x00003ec7, 0x00003113, 0x00006b59, 0x00002499, 0x0000184a,
282 0x0000250b, 0x00004e38, 0x000001ca, 0x00000011, 0x00000020, 0x000023da, 0x00000012, 0x00000091,
283 0x0000000b, 0x00000b14, 0x0000035d, 0x0000137e, 0x000020c9, 0x00000e11, 0x000004b4, 0x00000737,
284 0x000006b8, 0x00001110, 0x000006b3, 0x000000fe, 0x00000f02, 0x00000d73, 0x000005f6, 0x00000be4,
285 0x00000d86, 0x0000014d, 0x00000d89, 0x0000129b, 0x00000db3, 0x0000015a, 0x00000167, 0x00000375,
286 0x00000028, 0x00000112, 0x00000018, 0x00000678, 0x0000081a, 0x00000677, 0x00000003, 0x00018112,
287 0x00000001, 0x000441ee, 0x000124b0, 0x0001fa3f, 0x00026125, 0x0005a411, 0x0000e50f, 0x00011820,
288 0x00010f13, 0x0002e723, 0x00003518, 0x00005738, 0x0002cc26, 0x0002a9b7, 0x0002db81, 0x0003b5fa,
289 0x000185d2, 0x00001299, 0x00030773, 0x0003920d, 0x000411cd, 0x00018751, 0x00005fbd, 0x000099b0,
290 0x00009242, 0x00007cf2, 0x00002809, 0x00005a1d, 0x00000001, 0x00005a1d, 0x00000001, 0x00000001,
292 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
293 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
294 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
295 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
296 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
297 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
298 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
299 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
300 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
301 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
302 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
303 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
304 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
305 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
306 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
307 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
312 static int totalUncompressedLength = 0;
313 static int totalCompressedLength = 0;
314 static int maxHuffmanBits = 0;
326 huffmanFrequencies[
i] = 1;
339 for ( n = firstNode;
n; n = n->
next ) {
340 if ( node->frequency <= n->frequency ) {
347 lastNode->
next = node;
349 node->
next = firstNode;
361 if ( node->
symbol == -1 ) {
365 if ( code.
numBits > maxHuffmanBits ) {
366 maxHuffmanBits = newCode.
numBits;
373 codes[node->
symbol] = code;
383 if ( node->
symbol == -1 ) {
396 if ( node ==
NULL ) {
401 if ( left > right ) {
421 node->frequency = huffmanFrequencies[
i];
423 node->children[0] =
NULL;
424 node->children[1] =
NULL;
431 node->frequency = firstNode->frequency + firstNode->
next->frequency;
433 node->children[0] = firstNode;
434 node->children[1] = firstNode->
next;
439 memset( &code, 0,
sizeof( code ) );
442 huffmanTree = firstNode;
445 assert( maxHuffmanBits == height );
468 totalUncompressedLength += textLength;
470 msg.
Init( compressed, maxCompressedSize );
472 for ( i = 0; i < textLength; i++ ) {
473 const huffmanCode_t &code = huffmanCodes[(
unsigned char)text[i]];
474 for ( j = 0; j < ( code.
numBits >> 5 ); j++ ) {
482 totalCompressedLength += msg.
GetSize();
497 msg.
Init( compressed, compressedSize );
500 for ( i = 0; i < textLength; i++ ) {
504 node = node->children[bit];
505 }
while( node->
symbol == -1 );
520 compression = !totalUncompressedLength ? 100 : 100 * totalCompressedLength / totalUncompressedLength;
521 common->
Printf(
"// compression ratio = %d%%\n", (
int)compression );
522 common->
Printf(
"static int huffmanFrequencies[] = {\n" );
524 common->
Printf(
"\t0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x,\n",
525 huffmanFrequencies[i+0], huffmanFrequencies[i+1],
526 huffmanFrequencies[i+2], huffmanFrequencies[i+3],
527 huffmanFrequencies[i+4], huffmanFrequencies[i+5],
528 huffmanFrequencies[i+6], huffmanFrequencies[i+7]);
581 ID_TIME_T testTimeStamp;
617 if ( length == -1 ) {
630 decl->redefinedInReload =
false;
654 for ( i = 0; i < numTypes; i++ ) {
656 if ( typeInfo && typeInfo->
typeName.
Icmp( token ) == 0 ) {
662 if ( i >= numTypes ) {
664 if ( token.
Icmp(
"{" ) == 0 ) {
667 src.
Warning(
"Missing decl name" );
685 src.
Warning(
"Type without definition at end of file" );
689 if ( !token.
Icmp(
"{" ) ) {
691 src.
Warning(
"Missing decl name" );
706 src.
Warning(
"Type without definition at end of file" );
709 if ( token !=
"{" ) {
710 src.
Warning(
"Expecting '{' but found '%s'", token.
c_str() );
736 this->
decls = newDecl;
765 if ( decl->redefinedInReload ==
false ) {
767 decl->sourceTextOffset = decl->sourceFile->fileSize;
768 decl->sourceTextLength = 0;
769 decl->sourceLine = decl->sourceFile->numLines;
797 #ifdef USE_COMPRESSED_DECLS
801 #ifdef GET_HUFFMAN_FREQUENCIES
832 cmdSystem->
AddCommand(
"listMaterials", idListDecls_f<DECL_MATERIAL>,
CMD_FL_SYSTEM,
"lists materials", idCmdSystem::ArgCompletion_String<listDeclStrings> );
834 cmdSystem->
AddCommand(
"listSoundShaders", idListDecls_f<DECL_SOUND>,
CMD_FL_SYSTEM,
"lists sound shaders", idCmdSystem::ArgCompletion_String<listDeclStrings> );
836 cmdSystem->
AddCommand(
"listEntityDefs", idListDecls_f<DECL_ENTITYDEF>,
CMD_FL_SYSTEM,
"lists entity defs", idCmdSystem::ArgCompletion_String<listDeclStrings> );
838 cmdSystem->
AddCommand(
"listParticles", idListDecls_f<DECL_PARTICLE>,
CMD_FL_SYSTEM,
"lists particle systems", idCmdSystem::ArgCompletion_String<listDeclStrings> );
847 cmdSystem->
AddCommand(
"printMaterial", idPrintDecls_f<DECL_MATERIAL>,
CMD_FL_SYSTEM,
"prints a material", idCmdSystem::ArgCompletion_Decl<DECL_MATERIAL> );
849 cmdSystem->
AddCommand(
"printSoundShader", idPrintDecls_f<DECL_SOUND>,
CMD_FL_SYSTEM,
"prints a sound shader", idCmdSystem::ArgCompletion_Decl<DECL_SOUND> );
851 cmdSystem->
AddCommand(
"printEntityDef", idPrintDecls_f<DECL_ENTITYDEF>,
CMD_FL_SYSTEM,
"prints an entity def", idCmdSystem::ArgCompletion_Decl<DECL_ENTITYDEF> );
853 cmdSystem->
AddCommand(
"printParticle", idPrintDecls_f<DECL_PARTICLE>,
CMD_FL_SYSTEM,
"prints a particle system", idCmdSystem::ArgCompletion_Decl<DECL_PARTICLE> );
900 #ifdef USE_COMPRESSED_DECLS
928 for (
int j = 0 ;
j <
num ;
j++ ) {
956 common->
Warning(
"idDeclManager::RegisterDeclType: type '%s' already exists", typeName );
993 declFolder->
folder = folder;
1004 fileName = declFolder->
folder +
"/" + fileList->
GetFile( i );
1015 df =
new idDeclFile( fileName, defaultType );
1030 int i,
j, total,
num;
1039 checksumData = (
int *) _alloca16( total * 2 *
sizeof(
int ) );
1051 for ( j = 0; j <
num; j++ ) {
1058 checksumData[total*2+0] = total;
1059 checksumData[total*2+1] = decl->
checksum;
1083 int typeIndex = (
int)type;
1086 common->
FatalError(
"idDeclManager::GetDeclNameFromType: bad type: %i", typeIndex );
1117 if ( !name || !name[0] ) {
1118 name =
"_emptyName";
1179 int typeIndex = (
int)type;
1182 common->
FatalError(
"idDeclManager::GetNumDecls: bad type: %i", typeIndex );
1193 int typeIndex = (
int)type;
1196 common->
FatalError(
"idDeclManager::DeclByIndex: bad type: %i", typeIndex );
1199 common->
Error(
"idDeclManager::DeclByIndex: out of range" );
1245 for (
int i = 0 ;
i <
count ;
i++ ) {
1289 if ( args.
Argc() < 2 ) {
1290 common->
Printf(
"USAGE: Print<decl type> <decl name> [type specific parms]\n" );
1306 char *declText = (
char *)_alloca( decl->
textLength + 1 );
1326 common->
Printf(
"Currently referenced this level.\n" );
1345 int typeIndex = (
int)type;
1349 common->
FatalError(
"idDeclManager::CreateNewDecl: bad type: %i", typeIndex );
1356 idStr fileName = _fileName;
1362 if (
linearLists[typeIndex][i]->name.Icmp( canonicalName ) == 0 ) {
1379 sourceFile =
new idDeclFile( fileName, type );
1384 decl->
name = canonicalName;
1393 char *declText = (
char * ) _alloca( size + 1 );
1395 memcpy( declText, header, header.
Length() );
1396 declText[header.
Length()] =
' ';
1411 sourceFile->
decls = decl;
1436 int typeIndex = (
int)type;
1440 if (
linearLists[typeIndex][i]->
name.Icmp( canonicalOldName ) == 0 ) {
1454 decl->
name = canonicalNewName;
1484 va_start (argptr,fmt);
1487 buffer[
sizeof(
buffer)-1] =
'\0';
1507 for (
int j = 0 ;
j <
num ;
j++ ) {
1561 for ( i = 0; i < maxLength && name[
i] !=
'\0'; i++ ) {
1565 }
else if ( c ==
'.' ) {
1572 if ( lastDot != -1 ) {
1573 result[lastDot] =
'\0';
1588 int totalStructs = 0;
1590 for ( i = 0; i < declManagerLocal.
declTypes.
Num(); i++ ) {
1601 for ( j = 0; j <
num; j++ ) {
1607 totalStructs +=
size;
1609 common->
Printf(
"%4ik %4i %s\n", size >> 10, num, declManagerLocal.
declTypes[i]->typeName.c_str() );
1618 common->
Printf(
"%iKB in text, %iKB in structures\n", totalText >> 10, totalStructs >> 10 );
1644 declManagerLocal.
Reload( force );
1657 if ( args.
Argc() != 3 ) {
1660 for (
int i = 0 ; i < declManagerLocal.
declTypes.
Num() ; i++ ) {
1669 for ( i = 0; i < declManagerLocal.
declTypes.
Num(); i++ ) {
1670 if ( declManagerLocal.
declTypes[i] && declManagerLocal.
declTypes[i]->typeName.Icmp( args.
Argv( 1 ) ) == 0 ) {
1693 int typeIndex = (
int)type;
1697 common->
FatalError(
"idDeclManager::FindTypeWithoutParsing: bad type: %i", typeIndex );
1707 if (
linearLists[typeIndex][i]->name.Icmp( canonicalName ) == 0 ) {
1716 if ( !makeDefault ) {
1722 decl->
name = canonicalName;
1779 return name.c_str();
1880 #ifdef USE_COMPRESSED_DECLS
1916 #ifdef GET_HUFFMAN_FREQUENCIES
1918 huffmanFrequencies[((
const unsigned char *)text)[
i]]++;
1922 #ifdef USE_COMPRESSED_DECLS
1923 int maxBytesPerCode = ( maxHuffmanBits + 7 ) >> 3;
1924 byte *compressed = (
byte *)_alloca( length * maxBytesPerCode );
1943 int oldFileLength, newFileLength;
1957 buffer = (
char *)
Mem_Alloc(
Max( newFileLength, oldFileLength ) );
1975 file->
Read( buffer, oldFileLength );
1986 char *declText = (
char *) _alloca( textLength + 1 );
1998 file->
Write( buffer, newFileLength );
2029 ID_TIME_T newTimestamp;
2050 static int recursionLevel;
2051 const char *defaultText;
2053 declManagerLocal.
MediaPrint(
"DEFAULTED\n" );
2058 defaultText =
self->DefaultDefinition();
2064 if ( ++recursionLevel > 100 ) {
2065 common->
FatalError(
"idDecl::MakeDefault: bad DefaultDefinition(): %s", defaultText );
2072 self->Parse( defaultText, strlen( defaultText ) );
2151 if (
self ==
NULL ) {
2163 bool generatedDefaultText =
false;
2170 declManagerLocal.
MediaPrint(
"parsing %s %s\n", declManagerLocal.
declTypes[type]->typeName.c_str(),
name.c_str() );
2174 generatedDefaultText =
self->SetDefaultText();
2178 declManagerLocal.
indent++;
2183 declManagerLocal.
indent--;
2190 char *declText = (
char *) _alloca( (
GetTextLength() + 1 ) *
sizeof( char ) );
2195 if ( generatedDefaultText ) {
2201 declManagerLocal.
indent--;
struct huffmanNode_s * children[2]
virtual idFile * OpenFileRead(const char *relativePath, bool allowCopyFiles=true, const char *gamedir=NULL)=0
virtual void GetText(char *text) const
int GetReadCount(void) const
idList< idDeclFile * > loadedFiles
virtual idFileList * ListFiles(const char *relativePath, const char *extension, bool sort=false, bool fullRelativePath=false, const char *gamedir=NULL)=0
assert(prefInfo.fullscreenBtn)
idDeclLocal * FindTypeWithoutParsing(declType_t type, const char *name, bool makeDefault=true)
virtual bool SourceFileChanged(void) const
int Next(const int index) const
const int DECL_LEXER_FLAGS
void SetTextLocal(const char *text, const int length)
virtual void SetText(const char *text)
void Remove(const int key, const int index)
GLenum GLsizei GLenum format
virtual int Index(void) const
virtual void virtual void WritePrecacheCommands(idFile *f)
virtual const idDecl * DeclByIndex(declType_t type, int index, bool forceParse=true)
virtual bool RenameDecl(declType_t type, const char *oldName, const char *newName)
idDeclManagerLocal declManagerLocal
ID_INLINE T Max(T x, T y)
virtual int ReadFile(const char *relativePath, void **buffer, ID_TIME_T *timestamp=NULL)=0
int GetNumFiles(void) const
void AssureSize(int newSize)
virtual void Reload(bool force)
idFileSystem * fileSystem
int SkipBracedSection(bool parseFirstBrace=true)
static void TouchDecl_f(const idCmdArgs &args)
virtual const char * GetFileName(void) const
virtual const idDeclSkin * SkinByIndex(int index, bool forceParse=true)
virtual void BeginLevelLoad()
static void ListDecls_f(const idCmdArgs &args)
huffmanNode_t * InsertHuffmanNode(huffmanNode_t *firstNode, huffmanNode_t *node)
GLuint GLuint GLsizei GLenum type
virtual const idDecl * FindType(declType_t type, const char *name, bool makeDefault=true)
void BuildHuffmanCode_r(huffmanNode_t *node, huffmanCode_t code, huffmanCode_t codes[MAX_HUFFMAN_SYMBOLS])
idList< idDeclFolder * > declFolders
virtual declState_t GetState(void) const
virtual int GetLineNum(void) const
virtual size_t Size(void) const
int Icmp(const char *text) const
void ListHuffmanFrequencies_f(const idCmdArgs &args)
virtual bool Parse(const char *text, const int textLength)
idStr & BackSlashesToSlashes(void)
void Init(byte *data, int length)
virtual void EndLevelLoad()
const int GetFileOffset(void)
virtual const idDeclSkin * FindSkin(const char *name, bool makeDefault=true)
virtual const char * DefaultDefinition(void) const
const int GetLineNum(void)
bool parsedOutsideLevelLoad
virtual void MediaPrint(const char *fmt,...) id_attribute((format(printf
GLuint GLuint GLsizei count
virtual void FreeData(void)
virtual const idMaterial * FindMaterial(const char *name, bool makeDefault=true)
idDeclType * GetDeclType(int type) const
virtual idDecl * CreateNewDecl(declType_t type, const char *name, const char *fileName)
virtual void EnsureNotPurged(void)
virtual void FreeData(void)
virtual bool IsValid(void) const
void BeginReading(void) const
virtual int GetNumDecls(declType_t type)
void LittleRevBytes(void *bp, int elsize, int elcount)
virtual void MakeDefault(void)
int GetInteger(void) const
void FreeHuffmanTree_r(huffmanNode_t *node)
struct huffmanNode_s * next
virtual void virtual void FatalError(const char *fmt,...) id_attribute((format(printf
virtual idFile * OpenFileWrite(const char *relativePath, const char *basePath="fs_savepath")=0
const char * GetFile(int index) const
struct huffmanNode_s huffmanNode_t
virtual int Read(void *buffer, int len)
virtual const char * GetName(void) const
virtual void Print(void) const
void DeleteContents(bool clear)
virtual const idDecl * FindDeclWithoutParsing(declType_t type, const char *name, bool makeDefault=true)
int HuffmanDecompressText(char *text, int textLength, const byte *compressed, int compressedSize)
virtual void FreeFileList(idFileList *fileList)=0
void UnreadToken(const idToken *token)
virtual declType_t GetType(void) const
virtual void Printf(const char *fmt,...) id_attribute((format(printf
int LoadMemory(const char *ptr, int length, const char *name, int startLine=1)
unsigned long MD5_BlockChecksum(const void *data, int length)
virtual void ListType(const idCmdArgs &args, declType_t type)
virtual ID_TIME_T Timestamp(void)
GLenum GLsizei GLsizei height
idDeclManager * declManager
int GenerateKey(const char *string, bool caseSensitive=true) const
virtual void Print(void) const
int HuffmanHeight_r(huffmanNode_t *node)
virtual void List(void) const
virtual void SetMute(bool mute)=0
virtual const idSoundShader * SoundByIndex(int index, bool forceParse=true)
idList< idDeclType * > declTypes
int Append(const type &obj)
void void Warning(const char *str,...) id_attribute((format(printf
idList< idDeclLocal * > linearLists[DECL_MAX_TYPES]
int HuffmanCompressText(const char *text, int textLength, byte *compressed, int maxCompressedSize)
virtual void RegisterDeclFolder(const char *folder, const char *extension, declType_t defaultType)
virtual void Reload(void)
static int static int vsnPrintf(char *dest, int size, const char *fmt, va_list argptr)
const int MAX_HUFFMAN_SYMBOLS
idSoundSystem * soundSystem
virtual void Invalidate(void)
virtual const idMaterial * MaterialByIndex(int index, bool forceParse=true)
virtual int Write(const void *buffer, int len)
virtual void PrintType(const idCmdArgs &args, declType_t type)
GLsizei const GLcharARB const GLint * length
const char * listDeclStrings[]
virtual bool SetDefaultText(void)
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
const char * c_str(void) const
int SkipUntilString(const char *string)
virtual bool EverReferenced(void) const
const char * Argv(int arg) const
idHashIndex hashTables[DECL_MAX_TYPES]
virtual bool ReplaceSourceFileText(void)
void Add(const int key, const int index)
void * Mem_Alloc(const int size)
virtual const char * GetDeclNameFromType(declType_t type) const
const idDeclFile * GetImplicitDeclFile(void) const
virtual void ReloadFile(const char *filename, bool force)
virtual bool IsImplicit(void) const
void WriteBits(int value, int numBits)
virtual void CloseFile(idFile *f)=0
virtual int GetNumDeclTypes(void) const
virtual void DPrintf(const char *fmt,...) id_attribute((format(printf
virtual void RegisterDeclType(const char *typeName, declType_t type, idDecl *(*allocator)(void))
virtual void Error(const char *fmt,...) id_attribute((format(printf
virtual const idSoundShader * FindSound(const char *name, bool makeDefault=true)
virtual int GetTextLength(void) const
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
static void MakeNameCanonical(const char *name, char *result, int maxLength)
virtual const char * DefaultDefinition(void) const
int ReadToken(idToken *token)
virtual void List(void) const
int ReadBits(int numBits) const
int sprintf(idStr &string, const char *fmt,...)
void ClearHuffmanFrequencies(void)
virtual declType_t GetDeclTypeFromName(const char *typeName) const
virtual int Printf(const char *fmt,...) id_attribute((format(printf
virtual void Shutdown(void)
void ShutdownHuffman(void)
virtual void AddCommand(const char *cmdName, cmdFunction_t function, int flags, const char *description, argCompletion_t argCompletion=NULL)=0
virtual int GetChecksum(void) const
struct huffmanCode_s huffmanCode_t
idDecl *(* allocator)(void)
static void ReloadDecls_f(const idCmdArgs &args)