SaveStateList SciMetaEngine::listSaves(const char *target) const { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); Common::StringArray filenames; Common::String pattern = target; pattern += ".???"; filenames = saveFileMan->listSavefiles(pattern); sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..) SaveStateList saveList; int slotNum = 0; for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { // Obtain the last 3 digits of the filename, since they correspond to the save slot slotNum = atoi(file->c_str() + file->size() - 3); if (slotNum >= 0 && slotNum <= 99) { Common::InSaveFile *in = saveFileMan->openForLoading(*file); if (in) { SavegameMetadata meta; if (!get_savegame_metadata(in, &meta)) { // invalid delete in; continue; } saveList.push_back(SaveStateDescriptor(slotNum, meta.name)); delete in; } } } return saveList; }
reg_t kCheckSaveGame(EngineState *s, int funct_nr, int argc, reg_t *argv) { char *game_id = kernel_dereference_char_pointer(s, argv[0], 0); int savedir_nr = argv[1].toUint16(); debug(3, "kCheckSaveGame(%s, %d)", game_id, savedir_nr); Common::Array<SavegameDesc> saves; listSavegames(saves); savedir_nr = saves[savedir_nr].id; if (savedir_nr > MAX_SAVEGAME_NR - 1) { return NULL_REG; } Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); Common::String filename = ((Sci::SciEngine*)g_engine)->getSavegameName(savedir_nr); Common::SeekableReadStream *in; if ((in = saveFileMan->openForLoading(filename))) { // found a savegame file SavegameMetadata meta; if (!get_savegame_metadata(in, &meta)) { // invalid s->r_acc = make_reg(0, 0); } else { s->r_acc = make_reg(0, 1); } delete in; } else { s->r_acc = make_reg(0, 1); } return s->r_acc; }
void listSavegames(Common::Array<SavegameDesc> &saves) { Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); // Load all saves Common::StringList saveNames = saveFileMan->listSavefiles(((SciEngine *)g_engine)->getSavegamePattern()); for (Common::StringList::const_iterator iter = saveNames.begin(); iter != saveNames.end(); ++iter) { Common::String filename = *iter; Common::SeekableReadStream *in; if ((in = saveFileMan->openForLoading(filename))) { SavegameMetadata meta; if (!get_savegame_metadata(in, &meta)) { // invalid delete in; continue; } delete in; SavegameDesc desc; desc.id = strtol(filename.end() - 3, NULL, 10); desc.date = meta.savegame_date; desc.time = meta.savegame_time; debug(3, "Savegame in file %s ok, id %d", filename.c_str(), desc.id); saves.push_back(desc); } } // Sort the list by creation date of the saves qsort(saves.begin(), saves.size(), sizeof(SavegameDesc), _savegame_index_struct_compare); }
reg_t kGetSaveFiles(EngineState *s, int funct_nr, int argc, reg_t *argv) { char *game_id = kernel_dereference_char_pointer(s, argv[0], 0); char *nametarget = kernel_dereference_char_pointer(s, argv[1], 0); reg_t nametarget_base = argv[1]; reg_t *nameoffsets = kernel_dereference_reg_pointer(s, argv[2], 0); debug(3, "kGetSaveFiles(%s,%s)", game_id, nametarget); Common::Array<SavegameDesc> saves; listSavegames(saves); s->r_acc = NULL_REG; Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); for (uint i = 0; i < saves.size(); i++) { Common::String filename = ((Sci::SciEngine*)g_engine)->getSavegameName(saves[i].id); Common::SeekableReadStream *in; if ((in = saveFileMan->openForLoading(filename))) { // found a savegame file SavegameMetadata meta; if (!get_savegame_metadata(in, &meta)) { // invalid delete in; continue; } if (!meta.savegame_name.empty()) { if (meta.savegame_name.lastChar() == '\n') meta.savegame_name.deleteLastChar(); *nameoffsets = s->r_acc; // Store savegame ID ++s->r_acc.offset; // Increase number of files found nameoffsets++; // Make sure the next ID string address is written to the next pointer strncpy(nametarget, meta.savegame_name.c_str(), SCI_MAX_SAVENAME_LENGTH); // Copy identifier string *(nametarget + SCI_MAX_SAVENAME_LENGTH - 1) = 0; // Make sure it's terminated nametarget += SCI_MAX_SAVENAME_LENGTH; // Increase name offset pointer accordingly nametarget_base.offset += SCI_MAX_SAVENAME_LENGTH; } delete in; } } //free(gfname); *nametarget = 0; // Terminate list return s->r_acc; }
SaveStateDescriptor SciMetaEngine::querySaveMetaInfos(const char *target, int slot) const { Common::String fileName = Common::String::format("%s.%03d", target, slot); Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(fileName); if (in) { SavegameMetadata meta; if (!get_savegame_metadata(in, &meta)) { // invalid delete in; SaveStateDescriptor desc(slot, "Invalid"); return desc; } SaveStateDescriptor desc(slot, meta.name); Graphics::Surface *thumbnail = new Graphics::Surface(); assert(thumbnail); if (!Graphics::loadThumbnail(*in, *thumbnail)) { delete thumbnail; thumbnail = 0; } desc.setThumbnail(thumbnail); desc.setDeletableFlag(true); desc.setWriteProtectedFlag(false); int day = (meta.saveDate >> 24) & 0xFF; int month = (meta.saveDate >> 16) & 0xFF; int year = meta.saveDate & 0xFFFF; desc.setSaveDate(year, month, day); int hour = (meta.saveTime >> 16) & 0xFF; int minutes = (meta.saveTime >> 8) & 0xFF; desc.setSaveTime(hour, minutes); desc.setPlayTime(meta.playTime * 1000); delete in; return desc; } return SaveStateDescriptor(); }