Update of /cvsroot/gemrb/gemrb/gemrb/plugins/Core In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4816/gemrb/plugins/Core Modified Files: Game.cpp Game.h Interface.cpp Interface.h SaveGameIterator.cpp SaveGameIterator.h Log Message: Changed loading of saved games: - cleaned up SaveGameIterator, made it cache the directory names - changes in GUIScript - first load the save game, THEN open GameControl - load more parts of GAM files - core->GetPartySize() should look into game, not actors - some demo code for PST to display PC portraits in GameControl - new option in config file and in core object: SavePath is a root for save & mpsave folders - will allow per-user saves Index: Game.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Game.cpp,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** Game.cpp 27 Feb 2004 19:46:25 -0000 1.18 --- Game.cpp 29 Feb 2004 19:32:34 -0000 1.19 *************** *** 251,252 **** --- 251,269 ---- } + void Game::AddJournalEntry(GAMJournalEntry* entry) + { + Journals.push_back( entry ); + } + + int Game::GetJournalCount() + { + return Journals.size(); + } + + GAMJournalEntry* Game::GetJournalEntry(unsigned int Index) + { + if (Index >= Journals.size()) { + return NULL; + } + return Journals[Index]; + } Index: Game.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Game.h,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** Game.h 27 Feb 2004 19:46:26 -0000 1.14 --- Game.h 29 Feb 2004 19:32:34 -0000 1.15 *************** *** 38,44 **** --- 38,76 ---- #include <vector> + #include "../../includes/ie_types.h" #include "Actor.h" #include "Map.h" + typedef struct PCStruct { + unsigned short Unknown0; + unsigned short PartyOrder; + unsigned long OffsetToCRE; + unsigned long CRESize; + ieResRef CREResRef; + unsigned long Orientation; + ieResRef Area; + unsigned short XPos; + unsigned short YPos; + unsigned short ViewXPos; + unsigned short ViewYPos; + unsigned char Unknown28[100]; + unsigned short QuickWeaponSlot[4]; + unsigned char Unknown94[8]; + ieResRef QuickSpellResRef[3]; + unsigned short QuickItemSlot[3]; + unsigned char UnknownBA[6]; + } PCStruct; + + + typedef struct GAMJournalEntry { + ieStrRef JournalText; + ieDword Time; // in seconds + ieDword ChapterNumber; + ieByte Unknown0C; + ieByte Section; + ieByte ChapterNumber2; + } GAMJournalEntry; + + class GEM_EXPORT Game : public Scriptable { public: *************** *** 49,54 **** --- 81,115 ---- std::vector< Actor*> NPCs; std::vector< Map*> Maps; + std::vector< GAMJournalEntry*> Journals; public: int PartySize; + + unsigned int GameTime; + unsigned short WhichFormation; + unsigned short Formations[5]; + unsigned long PartyGold; + unsigned long Unknown1c; + unsigned long PCOffset; + unsigned long PCCount; + unsigned long UnknownOffset; + unsigned long UnknownCount; + unsigned long NPCOffset; + unsigned long NPCCount; + unsigned long GLOBALOffset; + unsigned long GLOBALCount; + char AREResRef[9]; + unsigned long Unknown48; + unsigned long JournalCount; + unsigned long JournalOffset; + unsigned long Unknown54; + unsigned long UnknownOffset54; + unsigned long UnknownCount58; + unsigned long KillVarsOffset; + unsigned long KillVarsCount; + unsigned long SomeBytesArrayOffset; + char AnotherArea[9]; + char CurrentArea[9]; + unsigned char Unknowns[84]; + public: /* returns actor by slot */ *************** *** 76,79 **** --- 137,143 ---- int AddNPC(Actor* npc); Actor* GetNPC(unsigned int Index); + void AddJournalEntry(GAMJournalEntry* entry); + int GetJournalCount(); + GAMJournalEntry* GetJournalEntry(unsigned int Index); }; Index: Interface.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Interface.cpp,v retrieving revision 1.132 retrieving revision 1.133 diff -C2 -d -r1.132 -r1.133 *** Interface.cpp 29 Feb 2004 17:31:59 -0000 1.132 --- Interface.cpp 29 Feb 2004 19:32:34 -0000 1.133 *************** *** 91,94 **** --- 91,95 ---- GUIScriptsPath[0] = 0; GamePath[0] = 0; + SavePath[0] = 0; GemRBPath[0] = 0; PluginsPath[0] = 0; *************** *** 816,819 **** --- 817,825 ---- ResolveFilePath( GamePath ); #endif + } else if (stricmp( name, "SavePath" ) == 0) { + strcpy( SavePath, value ); + #ifndef WIN32 + ResolveFilePath( SavePath ); + #endif } else if (stricmp( name, "INIConfig" ) == 0) { strcpy( INIConfig, value ); *************** *** 874,877 **** --- 880,887 ---- GEMRB_API_NUM, GEMRB_SDK_REV ); } + if (!SavePath[0]) { + // FIXME: maybe should use UserDir instead of GamePath + memcpy( SavePath, GamePath, sizeof( GamePath ) ); + } printf( "Loaded config file %s\n", filename ); *************** *** 962,965 **** --- 972,977 ---- int Interface::GetPartySize() { + return game->GetPartySize(); + #if 0 int count = 0; int i = actors.size(); *************** *** 970,973 **** --- 982,986 ---- } return count; + #endif } *************** *** 1712,1715 **** --- 1725,1729 ---- DataStream* ds; + printf("XXXXXXXX: Interface::LoadGame: %d\n", index); if (index == -1) { //Load the Default Game *************** *** 1735,1738 **** --- 1749,1753 ---- } game = sgm->GetGame(); + printf ("XXXXX: GAME: %p\n", game); FreeInterface( sgm ); } Index: Interface.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/Interface.h,v retrieving revision 1.79 retrieving revision 1.80 diff -C2 -d -r1.79 -r1.80 *** Interface.h 28 Feb 2004 01:36:53 -0000 1.79 --- Interface.h 29 Feb 2004 19:32:34 -0000 1.80 *************** *** 299,303 **** int argc; char **argv; ! char GameName[_MAX_PATH], GameType[_MAX_PATH], GemRBPath[_MAX_PATH], PluginsPath[_MAX_PATH], CachePath[_MAX_PATH], GUIScriptsPath[_MAX_PATH], GamePath[_MAX_PATH], INIConfig[_MAX_PATH], CD1[_MAX_PATH], CD2[_MAX_PATH], CD3[_MAX_PATH], CD4[_MAX_PATH], CD5[_MAX_PATH], CD6[_MAX_PATH]; int Width, Height, Bpp, ForceStereo; bool FullScreen, CaseSensitive, GameOnCD; --- 299,317 ---- int argc; char **argv; ! char GameName[_MAX_PATH]; ! char GameType[_MAX_PATH]; ! char GemRBPath[_MAX_PATH]; ! char PluginsPath[_MAX_PATH]; ! char CachePath[_MAX_PATH]; ! char GUIScriptsPath[_MAX_PATH]; ! char GamePath[_MAX_PATH]; ! char SavePath[_MAX_PATH]; ! char INIConfig[_MAX_PATH]; ! char CD1[_MAX_PATH]; ! char CD2[_MAX_PATH]; ! char CD3[_MAX_PATH]; ! char CD4[_MAX_PATH]; ! char CD5[_MAX_PATH]; ! char CD6[_MAX_PATH]; int Width, Height, Bpp, ForceStereo; bool FullScreen, CaseSensitive, GameOnCD; Index: SaveGameIterator.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/SaveGameIterator.cpp,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** SaveGameIterator.cpp 29 Feb 2004 15:24:59 -0000 1.17 --- SaveGameIterator.cpp 29 Feb 2004 19:32:34 -0000 1.18 *************** *** 28,31 **** --- 28,32 ---- SaveGameIterator::SaveGameIterator(void) { + loaded = false; } *************** *** 72,208 **** } ! int SaveGameIterator::GetSaveGameCount() { ! int count = 0; char Path[_MAX_PATH]; ! const char* SaveFolder = PlayMode(); ! sprintf( Path, "%s%s", core->GamePath, SaveFolder ); DIR* dir = opendir( Path ); if (dir == NULL) //If we cannot open the Directory { ! return -1; } struct dirent* de = readdir( dir ); //Lookup the first entry in the Directory if (de == NULL) { closedir( dir ); ! return -1; } do { ! //Iterate through all the available modules to load ! char dtmp[_MAX_PATH]; ! struct stat fst; ! sprintf( dtmp, "%s%s%s", Path, SPathDelimiter, de->d_name ); ! stat( dtmp, &fst ); ! if (S_ISDIR( fst.st_mode )) { ! if (de->d_name[0] == '.') ! continue; ! char ftmp[_MAX_PATH]; ! sprintf( ftmp, "%s%s%s.bmp", dtmp, SPathDelimiter, ! core->GameNameResRef ); ! #ifndef WIN32 ! ResolveFilePath( ftmp ); ! #endif ! FILE* exist = fopen( ftmp, "rb" ); ! if (!exist) ! continue; ! fclose( exist ); ! char savegameName[_MAX_PATH]; ! int savegameNumber = 0; ! int cnt = sscanf( de->d_name, SAVEGAME_DIRECTORY_MATCHER, &savegameNumber, savegameName ); ! if (cnt == 2) { //The matcher got matched correctly. ! printf( "[Number = %d, Name = %s]\n", savegameNumber, savegameName ); ! count++; ! } ! else { //The matcher didn't match: either this is not a valid directory or the SAVEGAME_DIRECTORY_MATCHER needs updating. ! printf( "[Invalid savegame directory '%s' in %s.\n", de->d_name, Path); ! } } } while (( de = readdir( dir ) ) != NULL); closedir( dir ); //No other files in the directory, close it ! return count; } ! SaveGame* SaveGameIterator::GetSaveGame(int index, bool Remove) { ! int count = -1, prtrt = 0; char Path[_MAX_PATH]; ! char dtmp[_MAX_PATH]; ! const char* SaveFolder = PlayMode(); ! sprintf( Path, "%s%s", core->GamePath, SaveFolder ); ! DIR* dir = opendir( Path ); ! if (dir == NULL) //If we cannot open the Directory ! { return NULL; } ! struct dirent* de = readdir( dir ); //Lookup the first entry in the Directory ! if (de == NULL) //If no entry exists just return ! { return NULL; } - char savegameName[_MAX_PATH]; - int savegameNumber = 0; do { ! //Iterate through all the available modules to load ! struct stat fst; ! sprintf( dtmp, "%s%s%s", Path, SPathDelimiter, de->d_name ); ! stat( dtmp, &fst ); ! if (S_ISDIR( fst.st_mode )) { ! if (de->d_name[0] == '.') ! continue; ! char ftmp[_MAX_PATH]; ! sprintf( ftmp, "%s%s%s.bmp", dtmp, SPathDelimiter, ! core->GameNameResRef ); ! #ifndef WIN32 ! ResolveFilePath( ftmp ); ! #endif ! FILE* exist = fopen( ftmp, "rb" ); ! if (!exist) ! continue; ! fclose( exist ); ! int cnt = sscanf( de->d_name, SAVEGAME_DIRECTORY_MATCHER, &savegameNumber, savegameName ); ! if (cnt == 2) { ! printf( "[Number = %d, Name = %s]\n", savegameNumber, savegameName ); ! count++; ! } ! else { ! printf( "[Invalid savegame directory '%s' in %s.\n", de->d_name, Path); ! } ! if (count == index) { ! if (Remove) { ! sprintf( Path, "%s%s%s%s", core->GamePath, SaveFolder, ! SPathDelimiter, de->d_name ); ! DelTree( Path ); ! rmdir( Path ); ! break; ! } ! sprintf( Path, "%s%s%s%s", core->GamePath, SaveFolder, ! SPathDelimiter, de->d_name ); ! DIR* ndir = opendir( Path ); ! //If we cannot open the Directory ! if (ndir == NULL) { ! closedir( dir ); ! return NULL; ! } ! struct dirent* de2 = readdir( ndir ); //Lookup the first entry in the Directory ! if (de2 == NULL) { ! // No first entry!!! ! closedir( dir ); ! closedir( ndir ); ! return NULL; ! } ! do { ! if (strnicmp( de2->d_name, "PORTRT", 6 ) == 0) ! prtrt++; ! } while (( de2 = readdir( ndir ) ) != NULL); ! closedir( ndir ); //No other files in the directory, close it ! break; ! } ! } ! } while (( de = readdir( dir ) ) != NULL); ! closedir( dir ); //No other files in the directory, close it ! if (Remove || ( de == NULL )) { ! return NULL; ! } ! SaveGame* sg = new SaveGame( dtmp, savegameName, core->GameNameResRef, prtrt ); return sg; } --- 73,226 ---- } ! /* ! * Return true if directory Path/slotname is a potential save game ! * slot, otherwise return false. ! */ ! static bool IsSaveGameSlot(const char* Path, const char* slotname) { ! char savegameName[_MAX_PATH]; ! int savegameNumber = 0; ! ! if (slotname[0] == '.') ! return false; ! ! int cnt = sscanf( slotname, SAVEGAME_DIRECTORY_MATCHER, &savegameNumber, savegameName ); ! if (cnt != 2) { ! //The matcher didn't match: either this is not a valid dir ! // or the SAVEGAME_DIRECTORY_MATCHER needs updating. ! printf( "Invalid savegame directory '%s' in %s.\n", slotname, Path ); ! return false; ! } ! ! //The matcher got matched correctly. ! printf( "[Number = %d, Name = %s]\n", savegameNumber, savegameName ); ! ! ! char dtmp[_MAX_PATH]; ! sprintf( dtmp, "%s%s%s", Path, SPathDelimiter, slotname ); ! ! struct stat fst; ! if (stat( dtmp, &fst )) ! return false; ! ! if (! S_ISDIR( fst.st_mode )) ! return false; ! ! char ftmp[_MAX_PATH]; ! sprintf( ftmp, "%s%s%s.bmp", dtmp, SPathDelimiter, ! core->GameNameResRef ); ! ! #ifndef WIN32 ! ResolveFilePath( ftmp ); ! #endif ! //FILE* exist = fopen( ftmp, "rb" ); ! //if (!exist) ! // return false; ! //fclose( exist ); ! if (access( ftmp, R_OK )) ! return false; ! ! return true; ! } ! ! bool SaveGameIterator::RescanSaveGames() ! { ! loaded = true; ! ! // delete old entries ! for (int i = save_slots.size() - 1; i >= 0; i--) { ! delete( save_slots[i] ); ! } ! char Path[_MAX_PATH]; ! sprintf( Path, "%s%s", core->SavePath, PlayMode() ); ! DIR* dir = opendir( Path ); if (dir == NULL) //If we cannot open the Directory { ! return false; } struct dirent* de = readdir( dir ); //Lookup the first entry in the Directory if (de == NULL) { closedir( dir ); ! return false; } do { ! if (IsSaveGameSlot( Path, de->d_name )) { ! save_slots.push_back( strdup( de->d_name ) ); } + } while (( de = readdir( dir ) ) != NULL); closedir( dir ); //No other files in the directory, close it ! ! return true; } ! int SaveGameIterator::GetSaveGameCount() { ! if (! loaded && ! RescanSaveGames()) ! return -1; ! ! return save_slots.size(); ! } ! ! SaveGame* SaveGameIterator::GetSaveGame(int index) ! { ! if (index < 0 || index >= GetSaveGameCount()) ! return NULL; ! ! char* slotname = save_slots[index]; ! ! ! int prtrt = 0; char Path[_MAX_PATH]; ! sprintf( Path, "%s%s%s%s", core->SavePath, PlayMode(), ! SPathDelimiter, slotname ); ! ! ! char savegameName[_MAX_PATH]; ! int savegameNumber = 0; ! ! int cnt = sscanf( slotname, SAVEGAME_DIRECTORY_MATCHER, &savegameNumber, savegameName ); ! printf( "[Number = %d, Name = %s]\n", savegameNumber, savegameName ); ! ! DIR* ndir = opendir( Path ); ! //If we cannot open the Directory ! if (ndir == NULL) { return NULL; } ! struct dirent* de2 = readdir( ndir ); //Lookup the first entry in the Directory ! if (de2 == NULL) { ! // No first entry!!! ! closedir( ndir ); return NULL; } do { ! if (strnicmp( de2->d_name, "PORTRT", 6 ) == 0) ! prtrt++; ! } while (( de2 = readdir( ndir ) ) != NULL); ! closedir( ndir ); //No other files in the directory, close it ! ! SaveGame* sg = new SaveGame( Path, savegameName, core->GameNameResRef, prtrt ); return sg; } + + void SaveGameIterator::DeleteSaveGame(int index) + { + if (index < 0 || index >= GetSaveGameCount()) + return; + + char* slotname = save_slots[index]; + + + char Path[_MAX_PATH]; + sprintf( Path, "%s%s%s%s", core->SavePath, PlayMode(), + SPathDelimiter, slotname ); + DelTree( Path ); + rmdir( Path ); + + // FIXME: maybe do just: delete save_slots[index] + // instead of full rescan + + loaded = false; + } Index: SaveGameIterator.h =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/Core/SaveGameIterator.h,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** SaveGameIterator.h 29 Feb 2004 15:24:59 -0000 1.12 --- SaveGameIterator.h 29 Feb 2004 19:32:34 -0000 1.13 *************** *** 138,146 **** class GEM_EXPORT SaveGameIterator { public: SaveGameIterator(void); ~SaveGameIterator(void); int GetSaveGameCount(); ! SaveGame* GetSaveGame(int index, bool Remove = false); }; --- 138,152 ---- class GEM_EXPORT SaveGameIterator { + private: + bool loaded; + std::vector<char*> save_slots; + public: SaveGameIterator(void); ~SaveGameIterator(void); + bool RescanSaveGames(); int GetSaveGameCount(); ! SaveGame* GetSaveGame(int index); ! void DeleteSaveGame(int index); }; |