void finalize() { if (_zlibErr != Z_OK) return; // Process whatever remaining data there is. processData(Z_FINISH); // Since processData only writes out blocks of size BUFSIZE, // we may have to flush some stragglers. uint remainder = BUFSIZE - _stream.avail_out; if (remainder > 0) { if (_wrapped->write(_buf, remainder) != remainder) { _zlibErr = Z_ERRNO; } } // Finalize the wrapped savefile, too _wrapped->finalize(); }
reg_t kFileIOExists(EngineState *s, int argc, reg_t *argv) { Common::String name = s->_segMan->getString(argv[0]); #ifdef ENABLE_SCI32 // Cache the file existence result for the Phantasmagoria // save index file, as the game scripts keep checking for // its existence. if (name == PHANTASMAGORIA_SAVEGAME_INDEX && s->_virtualIndexFile) return TRUE_REG; #endif bool exists = false; // Check for regular file exists = Common::File::exists(name); // Check for a savegame with the name Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); if (!exists) exists = !saveFileMan->listSavefiles(name).empty(); // Try searching for the file prepending "target-" const Common::String wrappedName = g_sci->wrapFilename(name); if (!exists) { exists = !saveFileMan->listSavefiles(wrappedName).empty(); } // SCI2+ debug mode if (DebugMan.isDebugChannelEnabled(kDebugLevelDebugMode)) { if (!exists && name == "1.scr") // PQ4 exists = true; if (!exists && name == "18.scr") // QFG4 exists = true; if (!exists && name == "99.scr") // GK1, KQ7 exists = true; if (!exists && name == "classes") // GK2, SQ6, LSL7 exists = true; } // Special case for non-English versions of LSL5: The English version of // LSL5 calls kFileIO(), case K_FILEIO_OPEN for reading to check if // memory.drv exists (which is where the game's password is stored). If // it's not found, it calls kFileIO() again, case K_FILEIO_OPEN for // writing and creates a new file. Non-English versions call kFileIO(), // case K_FILEIO_FILE_EXISTS instead, and fail if memory.drv can't be // found. We create a default memory.drv file with no password, so that // the game can continue. if (!exists && name == "memory.drv") { // Create a new file, and write the bytes for the empty password // string inside byte defaultContent[] = { 0xE9, 0xE9, 0xEB, 0xE1, 0x0D, 0x0A, 0x31, 0x30, 0x30, 0x30 }; Common::WriteStream *outFile = saveFileMan->openForSaving(wrappedName); for (int i = 0; i < 10; i++) outFile->writeByte(defaultContent[i]); outFile->finalize(); exists = !outFile->err(); // check whether we managed to create the file. delete outFile; } // Special case for KQ6 Mac: The game checks for two video files to see // if they exist before it plays them. Since we support multiple naming // schemes for resource fork files, we also need to support that here in // case someone has a "HalfDome.bin" file, etc. if (!exists && g_sci->getGameId() == GID_KQ6 && g_sci->getPlatform() == Common::kPlatformMacintosh && (name == "HalfDome" || name == "Kq6Movie")) exists = Common::MacResManager::exists(name); debugC(kDebugLevelFile, "kFileIO(fileExists) %s -> %d", name.c_str(), exists); return make_reg(0, exists); }