reg_t kFileIOUnlink(EngineState *s, int argc, reg_t *argv) { Common::String name = s->_segMan->getString(argv[0]); Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); bool result; // SQ4 floppy prepends /\ to the filenames if (name.hasPrefix("/\\")) { name.deleteChar(0); name.deleteChar(0); } // Special case for SQ4 floppy: This game has hardcoded names for all of // its savegames, and they are all named "sq4sg.xxx", where xxx is the // slot. We just take the slot number here, and delete the appropriate // save game. if (name.hasPrefix("sq4sg.")) { // Special handling for SQ4... get the slot number and construct the // save game name. int slotNum = atoi(name.c_str() + name.size() - 3); Common::Array<SavegameDesc> saves; listSavegames(saves); int savedir_nr = saves[slotNum].id; name = g_sci->getSavegameName(savedir_nr); result = saveFileMan->removeSavefile(name); } else if (getSciVersion() >= SCI_VERSION_2) { // The file name may be already wrapped, so check both cases result = saveFileMan->removeSavefile(name); if (!result) { const Common::String wrappedName = g_sci->wrapFilename(name); result = saveFileMan->removeSavefile(wrappedName); } #ifdef ENABLE_SCI32 if (name == PHANTASMAGORIA_SAVEGAME_INDEX) { delete s->_virtualIndexFile; s->_virtualIndexFile = 0; } #endif } else { const Common::String wrappedName = g_sci->wrapFilename(name); result = saveFileMan->removeSavefile(wrappedName); } debugC(kDebugLevelFile, "kFileIO(unlink): %s", name.c_str()); if (result) return NULL_REG; return make_reg(0, 2); // DOS - file not found error code }
Common::Error saveSavegameData(int saveGameIdx, const Common::String &saveName, DraciEngine &vm) { Common::String filename = vm.getSavegameFile(saveGameIdx); Common::SaveFileManager *saveMan = g_system->getSavefileManager(); Common::OutSaveFile *f = saveMan->openForSaving(filename); if (f == NULL) return Common::kNoGameDataFoundError; TimeDate curTime; vm._system->getTimeAndDate(curTime); // Save the savegame header DraciSavegameHeader header; header.saveName = saveName; header.date = ((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF); header.time = ((curTime.tm_hour & 0xFF) << 8) | ((curTime.tm_min) & 0xFF); header.playtime = vm.getTotalPlayTime() / 1000; writeSavegameHeader(f, header); if (f->err()) { delete f; saveMan->removeSavefile(filename); return Common::kWritingFailed; } else { // Create the remainder of the savegame Common::Serializer s(NULL, f); vm._game->DoSync(s); f->finalize(); delete f; return Common::kNoError; } }
Common::Error saveSavegameData(int saveGameIdx, const Common::String &saveName) { const char *filename = _vm->getSavegameFile(saveGameIdx); Common::SaveFileManager *saveMan = g_system->getSavefileManager(); Common::OutSaveFile *f = saveMan->openForSaving(filename); if (f == NULL) return Common::kNoGameDataFoundError; // Save the savegame header CruiseSavegameHeader header; header.saveName = saveName; writeSavegameHeader(f, header); if (f->err()) { delete f; saveMan->removeSavefile(filename); return Common::kWritingFailed; } else { // Create the remainder of the savegame Common::Serializer s(NULL, f); DoSync(s); f->finalize(); delete f; return Common::kNoError; } }
void PictureMetaEngine::removeSaveState(const char *target, int slot) const { // Slot 0 can't be deleted, it's for restarting the game(s) if (slot == 0) return; Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); Common::String filename = Picture::PictureEngine::getSavegameFilename(target, slot); saveFileMan->removeSavefile(filename.c_str()); Common::StringArray filenames; Common::String pattern = target; pattern += ".???"; filenames = saveFileMan->listSavefiles(pattern.c_str()); Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..) 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 int slotNum = atoi(file->c_str() + file->size() - 3); // Rename every slot greater than the deleted slot, // Also do not rename quicksaves. if (slotNum > slot && slotNum < 990) { // FIXME: Our savefile renaming done here is inconsitent with what we do in // GUI_v2::deleteMenu. While here we rename every slot with a greater equal // number of the deleted slot to deleted slot, deleted slot + 1 etc., // we only rename the following slots in GUI_v2::deleteMenu until a slot // is missing. saveFileMan->renameSavefile(file->c_str(), filename.c_str()); filename = Picture::PictureEngine::getSavegameFilename(target, ++slot); } } }
void delete_savegame(EngineState *s, int savedir_nr) { Common::String filename = ((Sci::SciEngine*)g_engine)->getSavegameName(savedir_nr); //printf("Deleting savegame '%s'\n", filename.c_str()); Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); saveFileMan->removeSavefile(filename); }
void SkyMetaEngine::removeSaveState(const char *target, int slot) const { if (slot == 0) // do not delete the auto save return; Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); char fName[20]; sprintf(fName,"SKY-VM.%03d", slot - 1); saveFileMan->removeSavefile(fName); // Load current save game descriptions Common::StringArray savenames; savenames.resize(MAX_SAVE_GAMES+1); Common::InSaveFile *inf; inf = saveFileMan->openForLoading("SKY-VM.SAV"); if (inf != NULL) { char *tmpBuf = new char[MAX_SAVE_GAMES * MAX_TEXT_LEN]; char *tmpPtr = tmpBuf; inf->read(tmpBuf, MAX_SAVE_GAMES * MAX_TEXT_LEN); for (int i = 0; i < MAX_SAVE_GAMES; ++i) { savenames[i] = tmpPtr; tmpPtr += savenames[i].size() + 1; } delete inf; delete[] tmpBuf; } // Update the save game description at the given slot savenames[slot - 1] = ""; // Save the updated descriptions Common::OutSaveFile *outf; outf = saveFileMan->openForSaving("SKY-VM.SAV"); bool ioFailed = true; if (outf) { for (uint16 cnt = 0; cnt < MAX_SAVE_GAMES; cnt++) { outf->write(savenames[cnt].c_str(), savenames[cnt].size() + 1); } outf->finalize(); if (!outf->err()) ioFailed = false; delete outf; } if (ioFailed) warning("Unable to store Savegame names to file SKY-VM.SAV. (%s)", saveFileMan->popErrorDesc().c_str()); }
TestExitStatus SaveGametests::testRemovingSavefile() { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); // Create a dummy savefile if (!writeDataToFile("tBedSavefileToRemove.0", "Dummy Savefile!")) { Testsuite::logDetailedPrintf("Writing data to savefile failed\n"); return kTestFailed; } // Remove it saveFileMan->removeSavefile("tBedSavefileToRemove.0"); // Try opening it Now Common::InSaveFile *loadFile = saveFileMan->openForLoading("saveFile.0"); if (loadFile) { // Removing failed Testsuite::logDetailedPrintf("Removing savefile failed\n"); return kTestFailed; } return kTestPassed; }
void ToltecsMetaEngine::removeSaveState(const char *target, int slot) const { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); Common::String filename = Toltecs::ToltecsEngine::getSavegameFilename(target, slot); saveFileMan->removeSavefile(filename.c_str()); Common::StringArray filenames; Common::String pattern = target; pattern += ".###"; filenames = saveFileMan->listSavefiles(pattern.c_str()); Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..) 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 int slotNum = atoi(file->c_str() + file->size() - 3); // Rename every slot greater than the deleted slot, if (slotNum > slot) { saveFileMan->renameSavefile(file->c_str(), filename.c_str()); filename = Toltecs::ToltecsEngine::getSavegameFilename(target, ++slot); } } }
Common::Error NeverhoodEngine::removeGameState(int slot) { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); Common::String filename = Neverhood::NeverhoodEngine::getSavegameFilename(_targetName, slot); saveFileMan->removeSavefile(filename.c_str()); return Common::kNoError; }
void NeverhoodMetaEngine::removeSaveState(const char *target, int slot) const { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); Common::String filename = Neverhood::NeverhoodEngine::getSavegameFilename(target, slot); saveFileMan->removeSavefile(filename.c_str()); }
reg_t kDeviceInfo(EngineState *s, int argc, reg_t *argv) { if (g_sci->getGameId() == GID_FANMADE && argc == 1) { // WORKAROUND: The fan game script library calls kDeviceInfo with one parameter. // According to the scripts, it wants to call CurDevice. However, it fails to // provide the subop to the function. s->_segMan->strcpy(argv[0], "/"); return s->r_acc; } int mode = argv[0].toUint16(); switch (mode) { case K_DEVICE_INFO_GET_DEVICE: { Common::String input_str = s->_segMan->getString(argv[1]); s->_segMan->strcpy(argv[2], "/"); debug(3, "K_DEVICE_INFO_GET_DEVICE(%s) -> %s", input_str.c_str(), "/"); break; } case K_DEVICE_INFO_GET_CURRENT_DEVICE: s->_segMan->strcpy(argv[1], "/"); debug(3, "K_DEVICE_INFO_GET_CURRENT_DEVICE() -> %s", "/"); break; case K_DEVICE_INFO_PATHS_EQUAL: { Common::String path1_s = s->_segMan->getString(argv[1]); Common::String path2_s = s->_segMan->getString(argv[2]); debug(3, "K_DEVICE_INFO_PATHS_EQUAL(%s,%s)", path1_s.c_str(), path2_s.c_str()); return make_reg(0, Common::matchString(path2_s.c_str(), path1_s.c_str(), false, true)); } break; case K_DEVICE_INFO_IS_FLOPPY: { Common::String input_str = s->_segMan->getString(argv[1]); debug(3, "K_DEVICE_INFO_IS_FLOPPY(%s)", input_str.c_str()); return NULL_REG; /* Never */ } case K_DEVICE_INFO_GET_CONFIG_PATH: { // Early versions return drive letter, later versions a path string // FIXME: Implement if needed, for now return NULL_REG return NULL_REG; } /* SCI uses these in a less-than-portable way to delete savegames. ** Read http://www-plan.cs.colorado.edu/creichen/freesci-logs/2005.10/log20051019.html ** for more information on our workaround for this. */ case K_DEVICE_INFO_GET_SAVECAT_NAME: { Common::String game_prefix = s->_segMan->getString(argv[2]); s->_segMan->strcpy(argv[1], "__throwaway"); debug(3, "K_DEVICE_INFO_GET_SAVECAT_NAME(%s) -> %s", game_prefix.c_str(), "__throwaway"); } break; case K_DEVICE_INFO_GET_SAVEFILE_NAME: { Common::String game_prefix = s->_segMan->getString(argv[2]); uint virtualId = argv[3].toUint16(); s->_segMan->strcpy(argv[1], "__throwaway"); debug(3, "K_DEVICE_INFO_GET_SAVEFILE_NAME(%s,%d) -> %s", game_prefix.c_str(), virtualId, "__throwaway"); if ((virtualId < SAVEGAMEID_OFFICIALRANGE_START) || (virtualId > SAVEGAMEID_OFFICIALRANGE_END)) error("kDeviceInfo(deleteSave): invalid savegame ID specified"); uint savegameId = virtualId - SAVEGAMEID_OFFICIALRANGE_START; Common::Array<SavegameDesc> saves; listSavegames(saves); if (findSavegame(saves, savegameId) != -1) { // Confirmed that this id still lives... Common::String filename = g_sci->getSavegameName(savegameId); Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); saveFileMan->removeSavefile(filename); } break; } default: error("Unknown DeviceInfo() sub-command: %d", mode); break; } return s->r_acc; }
void LabMetaEngine::removeSaveState(const char *target, int slot) const { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); saveFileMan->removeSavefile(Common::String::format("%s.%03u", target, slot)); }
reg_t kFileIO(EngineState *s, int funct_nr, int argc, reg_t *argv) { int func_nr = argv[0].toUint16(); switch (func_nr) { case K_FILEIO_OPEN : { char *name = kernel_dereference_char_pointer(s, argv[1], 0); int mode = argv[2].toUint16(); file_open(s, name, mode); debug(3, "K_FILEIO_OPEN(%s,0x%x)", name, mode); break; } case K_FILEIO_CLOSE : { int handle = argv[1].toUint16(); debug(3, "K_FILEIO_CLOSE(%d)", handle); file_close(s, handle); break; } case K_FILEIO_READ_RAW : { int handle = argv[1].toUint16(); char *dest = kernel_dereference_char_pointer(s, argv[2], 0); int size = argv[3].toUint16(); debug(3, "K_FILEIO_READ_RAW(%d,%d)", handle, size); fread_wrapper(s, dest, size, handle); break; } case K_FILEIO_WRITE_RAW : { int handle = argv[1].toUint16(); char *buf = kernel_dereference_char_pointer(s, argv[2], 0); int size = argv[3].toUint16(); debug(3, "K_FILEIO_WRITE_RAW(%d,%d)", handle, size); fwrite_wrapper(s, handle, buf, size); break; } case K_FILEIO_UNLINK : { char *name = kernel_dereference_char_pointer(s, argv[1], 0); debug(3, "K_FILEIO_UNLINK(%s)", name); Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); const Common::String wrappedName = ((Sci::SciEngine*)g_engine)->wrapFilename(name); saveFileMan->removeSavefile(wrappedName); // TODO/FIXME: Should we return something (like, a bool indicating // whether deleting the save succeeded or failed)? break; } case K_FILEIO_READ_STRING : { char *dest = kernel_dereference_char_pointer(s, argv[1], 0); int size = argv[2].toUint16(); int handle = argv[3].toUint16(); debug(3, "K_FILEIO_READ_STRING(%d,%d)", handle, size); fgets_wrapper(s, dest, size, handle); return argv[1]; } case K_FILEIO_WRITE_STRING : { int handle = argv[1].toUint16(); int size = argv[3].toUint16(); char *buf = kernel_dereference_char_pointer(s, argv[2], size); debug(3, "K_FILEIO_WRITE_STRING(%d,%d)", handle, size); // FIXME: What is the difference between K_FILEIO_WRITE_STRING and // K_FILEIO_WRITE_RAW? Normally, I would expect the difference to // be that the former doesn't receive a 'size' parameter. But here // it does. Are we missing something? if (buf) fwrite_wrapper(s, handle, buf, size); break; } case K_FILEIO_SEEK : { int handle = argv[1].toUint16(); int offset = argv[2].toUint16(); int whence = argv[3].toUint16(); debug(3, "K_FILEIO_SEEK(%d,%d,%d)", handle, offset, whence); fseek_wrapper(s, handle, offset, whence); break; } case K_FILEIO_FIND_FIRST : { char *mask = kernel_dereference_char_pointer(s, argv[1], 0); reg_t buf = argv[2]; int attr = argv[3].toUint16(); // We won't use this, Win32 might, though... debug(3, "K_FILEIO_FIND_FIRST(%s,0x%x)", mask, attr); #ifndef WIN32 if (strcmp(mask, "*.*") == 0) strcpy(mask, "*"); // For UNIX #endif s->_dirseeker.firstFile(mask, buf); break; } case K_FILEIO_FIND_NEXT : { debug(3, "K_FILEIO_FIND_NEXT()"); s->_dirseeker.nextFile(); break; } case K_FILEIO_FILE_EXISTS : { char *name = kernel_dereference_char_pointer(s, argv[1], 0); // Check for regular file bool exists = Common::File::exists(name); if (!exists) { // TODO: Transform the name given by the scripts to us, e.g. by // prepending TARGET- Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); exists = !saveFileMan->listSavefiles(name).empty(); } debug(3, "K_FILEIO_FILE_EXISTS(%s) -> %d", name, exists); return make_reg(0, exists); } default : error("Unknown FileIO() sub-command: %d", func_nr); } return s->r_acc; }