From: Laszlo T. <ave...@us...> - 2004-04-18 14:26:15
|
Update of /cvsroot/gemrb/gemrb/gemrb/plugins/Core In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19966/Core Modified Files: ArchiveImporter.h CachedFileStream.cpp CachedFileStream.h DataStream.cpp DataStream.h FileStream.cpp FileStream.h Interface.cpp Interface.h Inventory.cpp MemoryStream.cpp MemoryStream.h Log Message: Rewritten low level file handling, streams no longer allow partial reading or reading past the file boundary, stream->Remains() will return the remaining bytes modified code that relied on partial reads fixed setting filesize for tilesets minor tweak in acm sound unpacker to be sure we read one byte rewritten bif handler added itemtype.2da handler to Interface Index: CachedFileStream.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/CachedFileStream.cpp,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** CachedFileStream.cpp 17 Apr 2004 12:43:07 -0000 1.25 --- CachedFileStream.cpp 18 Apr 2004 14:25:58 -0000 1.26 *************** *** 68,72 **** #endif startpos = 0; ! _fseek( str, 0, SEEK_END ); size = _ftell( str ); _fseek( str, 0, SEEK_SET ); --- 68,72 ---- #endif startpos = 0; ! _fseek( str, 0, SEEK_END ); size = _ftell( str ); _fseek( str, 0, SEEK_SET ); *************** *** 111,121 **** } ! int CachedFileStream::Read(void* dest, int length) { size_t c = _fread( dest, 1, length, str ); if (c != length) { - if (_feof( str )) { - return GEM_EOF; - } return GEM_ERROR; } --- 111,124 ---- } ! int CachedFileStream::Read(void* dest, unsigned int length) { + //we don't allow partial reads anyway, so it isn't a problem that + //i don't adjust length here (partial reads are evil) + if(Pos+length>size ) { + return GEM_ERROR; + } + size_t c = _fread( dest, 1, length, str ); if (c != length) { return GEM_ERROR; } *************** *** 127,141 **** } ! int CachedFileStream::Seek(int pos, int startpos) { ! switch (startpos) { case GEM_CURRENT_POS: ! _fseek( str, pos, SEEK_CUR ); ! Pos += pos; break; case GEM_STREAM_START: ! _fseek( str, this->startpos + pos, SEEK_SET ); ! Pos = pos; break; --- 130,144 ---- } ! int CachedFileStream::Seek(int newpos, int type) { ! switch (type) { case GEM_CURRENT_POS: ! _fseek( str, newpos, SEEK_CUR ); ! Pos += newpos; break; case GEM_STREAM_START: ! _fseek( str, startpos + newpos, SEEK_SET ); ! Pos = newpos; break; *************** *** 143,146 **** --- 146,154 ---- return GEM_ERROR; } + //we went past the buffer + if(Pos>=size) { + abort(); + return GEM_ERROR; + } return GEM_OK; } Index: DataStream.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/DataStream.h,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** DataStream.h 17 Apr 2004 12:28:21 -0000 1.9 --- DataStream.h 18 Apr 2004 14:25:58 -0000 1.10 *************** *** 42,52 **** class GEM_EXPORT DataStream { public: ! int Pos; bool Encrypted; DataStream(void); virtual ~DataStream(void); ! virtual int Read(void* dest, int len) = 0; virtual int Seek(int pos, int startpos) = 0; virtual unsigned long Size() = 0; /** Returns true if the stream is encrypted */ bool CheckEncrypted(); --- 42,53 ---- class GEM_EXPORT DataStream { public: ! unsigned long Pos; bool Encrypted; DataStream(void); virtual ~DataStream(void); ! virtual int Read(void* dest, unsigned int len) = 0; virtual int Seek(int pos, int startpos) = 0; virtual unsigned long Size() = 0; + unsigned long Remains(); /** Returns true if the stream is encrypted */ bool CheckEncrypted(); Index: DataStream.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/DataStream.cpp,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** DataStream.cpp 14 Apr 2004 22:53:50 -0000 1.10 --- DataStream.cpp 18 Apr 2004 14:25:58 -0000 1.11 *************** *** 53,54 **** --- 53,58 ---- ( ( unsigned char * ) buf )[i] ^= GEM_ENCRYPTION_KEY[( Pos + i ) & 63]; } + unsigned long DataStream::Remains() + { + return Size()-Pos; + } Index: MemoryStream.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/MemoryStream.h,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** MemoryStream.h 17 Apr 2004 11:44:41 -0000 1.8 --- MemoryStream.h 18 Apr 2004 14:26:03 -0000 1.9 *************** *** 40,49 **** private: void* ptr; ! int length; bool autoFree; public: MemoryStream(void* buffer, int length, bool autoFree = true); ~MemoryStream(void); ! int Read(void* dest, int length); int Seek(int pos, int startpos); unsigned long Size(); --- 40,49 ---- private: void* ptr; ! unsigned long length; bool autoFree; public: MemoryStream(void* buffer, int length, bool autoFree = true); ~MemoryStream(void); ! int Read(void* dest, unsigned int length); int Seek(int pos, int startpos); unsigned long Size(); Index: MemoryStream.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/MemoryStream.cpp,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** MemoryStream.cpp 17 Apr 2004 11:44:41 -0000 1.14 --- MemoryStream.cpp 18 Apr 2004 14:26:03 -0000 1.15 *************** *** 39,43 **** } ! int MemoryStream::Read(void* dest, int length) { if (length + Pos > this->length) { --- 39,43 ---- } ! int MemoryStream::Read(void* dest, unsigned int length) { if (length + Pos > this->length) { *************** *** 53,75 **** } ! int MemoryStream::Seek(int arg_pos, int startpos) { ! switch (startpos) { case GEM_CURRENT_POS: ! { ! if (( Pos + arg_pos ) < 0) ! return GEM_ERROR; ! if (( Pos + arg_pos ) >= length) ! return GEM_ERROR; ! Pos += arg_pos; ! } break; case GEM_STREAM_START: ! { ! if (arg_pos >= length) ! return GEM_ERROR; ! Pos = arg_pos; ! } break; --- 53,69 ---- } ! int MemoryStream::Seek(int newpos, int type) { ! switch (type) { case GEM_CURRENT_POS: ! if (( Pos + newpos ) >= length) ! return GEM_ERROR; ! Pos += newpos; break; case GEM_STREAM_START: ! if ((unsigned long) newpos >= length) ! return GEM_ERROR; ! Pos = newpos; break; Index: CachedFileStream.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/CachedFileStream.h,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** CachedFileStream.h 17 Apr 2004 12:43:07 -0000 1.11 --- CachedFileStream.h 18 Apr 2004 14:25:58 -0000 1.12 *************** *** 41,46 **** private: bool autoFree; ! int startpos; ! int size; char originalfile[_MAX_PATH]; _FILE* str; --- 41,46 ---- private: bool autoFree; ! unsigned long startpos; ! unsigned long size; char originalfile[_MAX_PATH]; _FILE* str; *************** *** 50,54 **** bool autoFree = true); ~CachedFileStream(void); ! int Read(void* dest, int length); int Seek(int pos, int startpos); unsigned long Size(); --- 50,54 ---- bool autoFree = true); ~CachedFileStream(void); ! int Read(void* dest, unsigned int length); int Seek(int pos, int startpos); unsigned long Size(); Index: ArchiveImporter.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/ArchiveImporter.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ArchiveImporter.h 24 Feb 2004 22:20:36 -0000 1.3 --- ArchiveImporter.h 18 Apr 2004 14:25:58 -0000 1.4 *************** *** 42,46 **** ArchiveImporter(void); virtual ~ArchiveImporter(void); ! virtual int OpenArchive(char* filename, bool cacheCheck = true) = 0; virtual DataStream* GetStream(ulong Resource, ulong Type) = 0; }; --- 42,46 ---- ArchiveImporter(void); virtual ~ArchiveImporter(void); ! virtual int OpenArchive(char* filename) = 0; virtual DataStream* GetStream(ulong Resource, ulong Type) = 0; }; Index: Interface.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Interface.h,v retrieving revision 1.89 retrieving revision 1.90 diff -C2 -d -r1.89 -r1.90 *** Interface.h 17 Apr 2004 11:28:10 -0000 1.89 --- Interface.h 18 Apr 2004 14:26:03 -0000 1.90 *************** *** 120,123 **** --- 120,127 ---- char ButtonFont[9]; char CursorBam[9]; + unsigned int* slotmatrix; //itemtype vs slottype + unsigned int* slottypes; //slottype vs slot mapping + int ItemTypes; + int SlotTypes; //this is the same as the inventory size public: char GlobalScript[9]; *************** *** 306,314 **** /*reads the filenames of the sounds folder into a list */ int GetCharSounds(TextArea *ta); ! private: bool LoadConfig(void); bool LoadConfig(const char *filename); bool LoadINI(const char * filename); public: char GameData[9]; --- 310,320 ---- /*reads the filenames of the sounds folder into a list */ int GetCharSounds(TextArea *ta); ! /*returns true if an itemtype is acceptable for a slottype */ ! bool CanUseItemType(int itype, int slottype); private: bool LoadConfig(void); bool LoadConfig(const char *filename); bool LoadINI(const char * filename); + bool InitItemTypes(); public: char GameData[9]; Index: Inventory.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Inventory.cpp,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** Inventory.cpp 17 Apr 2004 22:23:00 -0000 1.13 --- Inventory.cpp 18 Apr 2004 14:26:03 -0000 1.14 *************** *** 24,29 **** #include "Inventory.h" - static int Inited=-1; - Inventory::Inventory() { --- 24,27 ---- Index: Interface.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Interface.cpp,v retrieving revision 1.157 retrieving revision 1.158 diff -C2 -d -r1.157 -r1.158 *** Interface.cpp 17 Apr 2004 19:37:26 -0000 1.157 --- Interface.cpp 18 Apr 2004 14:25:58 -0000 1.158 *************** *** 83,86 **** --- 83,88 ---- timer = NULL; console = NULL; + slotmatrix = NULL; + slottypes = NULL; pal256 = NULL; *************** *** 156,159 **** --- 158,164 ---- Interface::~Interface(void) { + if (slotmatrix) { + free( slotmatrix ); + } if (game) { delete( game ); *************** *** 329,337 **** DataStream* fstr = key->GetResource( ResRef, IE_BAM_CLASS_ID ); if (!anim->Open( fstr, true )) { - printStatus( "ERROR", LIGHT_RED ); delete( fstr ); continue; } Font* fnt = anim->GetFont(); strncpy( fnt->ResRef, ResRef, 8 ); if (needpalette) { --- 334,344 ---- DataStream* fstr = key->GetResource( ResRef, IE_BAM_CLASS_ID ); if (!anim->Open( fstr, true )) { delete( fstr ); continue; } Font* fnt = anim->GetFont(); + if (!fnt) { + continue; + } strncpy( fnt->ResRef, ResRef, 8 ); if (needpalette) { *************** *** 375,380 **** strcpy( NextScript, "Start" ); AnimationFactory* af = ( AnimationFactory* ) ! GetResourceMgr()->GetFactoryResource( CursorBam, ! IE_BAM_CLASS_ID ); printMessage( "Core", "Setting up the Console...", WHITE ); ChangeScript = true; --- 382,386 ---- strcpy( NextScript, "Start" ); AnimationFactory* af = ( AnimationFactory* ) ! GetResourceMgr()->GetFactoryResource( CursorBam, IE_BAM_CLASS_ID ); printMessage( "Core", "Setting up the Console...", WHITE ); ChangeScript = true; *************** *** 428,433 **** GameNameResRef[i] = 0; } - // FIXME: ugly hack - // vars->SetAt( strdup( "SkipIntroVideos" ), (unsigned long)SkipIntroVideos ); //no need of strdup, variables do copy the key! vars->SetAt( "SkipIntroVideos", (unsigned long)SkipIntroVideos ); --- 434,437 ---- *************** *** 522,525 **** --- 526,538 ---- } printStatus( "OK", LIGHT_GREEN ); + bool ret = InitItemTypes(); + printMessage( "Core", "Initializing Inventory Management...", WHITE ); + if(ret) { + printStatus( "OK", LIGHT_GREEN ); + } + else { + printStatus( "ERROR", LIGHT_RED ); + } + printMessage( "Core", "Core Initialization Complete!\n", WHITE ); return GEM_OK; *************** *** 970,978 **** for (unsigned int i = 0; i < fonts.size(); i++) { if (strncmp( fonts[i]->ResRef, ResRef, 8 ) == 0) { - //printf("[FOUND]\n"); return fonts[i]; } } - //printf("[NOT FOUND]\n"); return NULL; } --- 983,989 ---- *************** *** 1777,1778 **** --- 1788,1859 ---- return (GameControl *) gc; } + + bool Interface::InitItemTypes() + { + if (slotmatrix) { + free(slotmatrix); + } + int ItemTypeTable = core->LoadTable( "itemtype" ); + TableMgr *it = core->GetTable(ItemTypeTable); + + ItemTypes = 0; + if(it) { + ItemTypes = it->GetRowCount(); //number of itemtypes + if (ItemTypes<0) { + ItemTypes = 0; + } + int InvSlotTypes = it->GetColumnCount(); + if (InvSlotTypes > 32) { //bit count limit + InvSlotTypes = 32; + } + //make sure unsigned int is 32 bits + slotmatrix = (unsigned int *) malloc(ItemTypes * sizeof(unsigned int) ); + for (int i=0;i<ItemTypes;i++) { + unsigned int value = 0; + unsigned int k = 1; + for (int j=0;j<InvSlotTypes;j++) { + if (strtol(it->QueryField(i,j),NULL,0) ) { + value |= k; + } + k <<= 1; + } + slotmatrix[i] = value; + } + core->DelTable(ItemTypeTable); + } + + //slottype describes the inventory structure + int SlotTypeTable = core->LoadTable( "slottype" ); + TableMgr *st = core->GetTable(SlotTypeTable); + if (slottypes) { + free(slottypes); + } + SlotTypes = 0; + if(st) { + SlotTypes = st->GetColumnCount(); + //make sure unsigned int is 32 bits + slottypes = (unsigned int *) malloc(SlotTypes * sizeof(unsigned int) ); + // FIXME: read in slottype info + // + for (int i=0;i<SlotTypes;i++) { + slottypes[i] = strtol(it->QueryField(i),NULL,0 ); + } + core->DelTable(SlotTypeTable); + } + return (it && st); + } + + bool Interface::CanUseItemType(int itype, int slottype) + { + if( !slottype ) { + //inventory slot, can hold any item, including invalid + return true; + } + if( itype>=ItemTypes ) { + //invalid itemtype + return false; + } + //if any bit is true, we return true (int->bool conversion) + return slotmatrix[itype]&slottype; + } + Index: FileStream.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/FileStream.h,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** FileStream.h 17 Apr 2004 12:28:21 -0000 1.7 --- FileStream.h 18 Apr 2004 14:25:58 -0000 1.8 *************** *** 40,44 **** private: _FILE* str; ! ulong startpos; bool autoFree; bool opened; --- 40,44 ---- private: _FILE* str; ! unsigned long startpos; bool autoFree; bool opened; *************** *** 50,54 **** bool Open(const char* filename, bool autoFree = true); bool Open(_FILE* stream, int startpos, int size, bool autoFree = false); ! int Read(void* dest, int length); int Seek(int pos, int startpos); unsigned long Size(); --- 50,54 ---- bool Open(const char* filename, bool autoFree = true); bool Open(_FILE* stream, int startpos, int size, bool autoFree = false); ! int Read(void* dest, unsigned int length); int Seek(int pos, int startpos); unsigned long Size(); Index: FileStream.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/FileStream.cpp,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** FileStream.cpp 17 Apr 2004 12:28:21 -0000 1.25 --- FileStream.cpp 18 Apr 2004 14:25:58 -0000 1.26 *************** *** 64,68 **** opened = true; _fseek( str, 0, SEEK_END ); ! size = _ftell( str ) + 1; _fseek( str, 0, SEEK_SET ); ExtractFileFromPath( this->filename, filename ); --- 64,68 ---- opened = true; _fseek( str, 0, SEEK_END ); ! size = _ftell( str ); _fseek( str, 0, SEEK_SET ); ExtractFileFromPath( this->filename, filename ); *************** *** 96,108 **** } ! int FileStream::Read(void* dest, int length) { if (!opened) { return GEM_ERROR; } size_t c = _fread( dest, 1, length, str ); - //if(feof(str)) { /* slightly modified by brian oct 11 2003*/ - // return GEM_EOF; - //} if (c != length) { return GEM_ERROR; --- 96,110 ---- } ! int FileStream::Read(void* dest, unsigned int length) { if (!opened) { return GEM_ERROR; } + //we don't allow partial reads anyway, so it isn't a problem that + //i don't adjust length here (partial reads are evil) + if(Pos+length>size ) { + return GEM_ERROR; + } size_t c = _fread( dest, 1, length, str ); if (c != length) { return GEM_ERROR; *************** *** 115,132 **** } ! int FileStream::Seek(int pos, int startpos) { if (!opened) { return GEM_ERROR; } ! switch (startpos) { case GEM_CURRENT_POS: ! _fseek( str, pos, SEEK_CUR ); ! Pos += pos; break; case GEM_STREAM_START: ! _fseek( str, this->startpos + pos, SEEK_SET ); ! Pos = pos; break; --- 117,134 ---- } ! int FileStream::Seek(int newpos, int type) { if (!opened) { return GEM_ERROR; } ! switch (type) { case GEM_CURRENT_POS: ! _fseek( str, newpos, SEEK_CUR ); ! Pos += newpos; break; case GEM_STREAM_START: ! _fseek( str, startpos + newpos, SEEK_SET ); ! Pos = newpos; break; *************** *** 134,137 **** --- 136,143 ---- return GEM_ERROR; } + if (Pos>=size) { + abort(); + return GEM_ERROR; + } return GEM_OK; } |