Пример #1
0
uint32 Sword2Engine::saveData(uint16 slotNo, byte *buffer, uint32 bufferSize) {
    Common::String saveFileName = getSaveFileName(slotNo);

    Common::OutSaveFile *out;

    if (!(out = _saveFileMan->openForSaving(saveFileName))) {
        return SR_ERR_FILEOPEN;
    }

    out->write(buffer, bufferSize);
    out->finalize();

    if (!out->err()) {
        delete out;
        return SR_OK;
    }

    delete out;
    return SR_ERR_WRITEFAIL;
}
Пример #2
0
void CineMetaEngine::removeSaveState(const char *target, int slot) const {
	// Load savegame descriptions from index file
	typedef char CommandeType[20];
	CommandeType saveNames[10];

	// Initialize all savegames' descriptions to empty strings
	// so that if the savegames' descriptions can only be partially read from file
	// then the missing ones are correctly set to empty strings.
	memset(saveNames, 0, sizeof(saveNames));

	Common::InSaveFile *in;
	in = g_system->getSavefileManager()->openForLoading(Common::String::format("%s.dir", target));

	if (!in)
		return;

	in->read(saveNames, 10 * 20);
	delete in;

	// Set description for selected slot
	char slotName[20];
	slotName[0] = 0;
	strncpy(saveNames[slot], slotName, 20);

	// Update savegame descriptions
	Common::String indexFile = Common::String::format("%s.dir", target);
	Common::OutSaveFile *out = g_system->getSavefileManager()->openForSaving(indexFile);
	if (!out) {
		warning("Unable to open file %s for saving", indexFile.c_str());
		return;
	}

	out->write(saveNames, 10 * 20);
	delete out;

	// Delete save file
	char saveFileName[256];
	sprintf(saveFileName, "%s.%1d", target, slot);

	g_system->getSavefileManager()->removeSavefile(saveFileName);
}
Пример #3
0
void Script::savegame(uint slot) {
	char save[15];
	char newchar;
	Common::OutSaveFile *file = SaveLoad::openForSaving(ConfMan.getActiveDomainName(), slot);

	// Saving the variables. It is endian safe because they're byte variables
	file->write(_variables, 0x400);
	delete file;

	// Cache the saved name
	for (int i = 0; i < 15; i++) {
		newchar = _variables[i] + 0x30;
		if ((newchar < 0x30 || newchar > 0x39) && (newchar < 0x41 || newchar > 0x7A)) {
			save[i] = '\0';
			break;
		} else {
			save[i] = newchar;
		}
	}
	_saveNames[slot] = save;
}
Пример #4
0
bool NeverhoodEngine::savegame(const char *filename, const char *description) {

	Common::OutSaveFile *out;
	if (!(out = g_system->getSavefileManager()->openForSaving(filename))) {
		warning("Can't create file '%s', game not saved", filename);
		return false;
	}

	TimeDate curTime;
	g_system->getTimeAndDate(curTime);

	// Header start
	out->writeUint32LE(NEVERHOOD_SAVEGAME_VERSION);

	byte descriptionLen = strlen(description);
	out->writeByte(descriptionLen);
	out->write(description, descriptionLen);

	Graphics::saveThumbnail(*out);

	// Not used yet, reserved for future usage
	out->writeByte(0);
	out->writeUint32LE(0);
	uint32 saveDate = ((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF);
	uint32 saveTime = ((curTime.tm_hour & 0xFF) << 16) | (((curTime.tm_min) & 0xFF) << 8) | ((curTime.tm_sec) & 0xFF);
	uint32 playTime = g_engine->getTotalPlayTime() / 1000;
	out->writeUint32LE(saveDate);
	out->writeUint32LE(saveTime);
	out->writeUint32LE(playTime);
	// Header end

	_gameVars->setGlobalVar(V_CURRENT_SCENE, _gameState.sceneNum);
	_gameVars->setGlobalVar(V_CURRENT_SCENE_WHICH, _gameState.which);

	_gameVars->saveState(out);

	out->finalize();
	delete out;
	return true;
}
Пример #5
0
Common::Error ToucheEngine::saveGameState(int num, const Common::String &description) {
	bool saveOk = false;
	Common::String gameStateFileName = generateGameStateFileName(_targetName.c_str(), num);
	Common::OutSaveFile *f = _saveFileMan->openForSaving(gameStateFileName);
	if (f) {
		f->writeUint16LE(kCurrentGameStateVersion);
		f->writeUint16LE(0);
		char headerDescription[kGameStateDescriptionLen];
		memset(headerDescription, 0, kGameStateDescriptionLen);
		strncpy(headerDescription, description.c_str(), kGameStateDescriptionLen - 1);
		f->write(headerDescription, kGameStateDescriptionLen);
		saveGameStateData(f);
		f->finalize();
		if (!f->err()) {
			saveOk = true;
		} else {
			warning("Can't write file '%s'", gameStateFileName.c_str());
		}
		delete f;
	}
	return saveOk ? Common::kNoError : Common::kUnknownError;
}
Пример #6
0
void SaveManager::saveGame(uint slot, const Common::String &saveName, bool useSaveBuffer) {
	if (!_tempSave && useSaveBuffer)
		return;

	Common::SaveFileManager *saveFileManager = g_system->getSavefileManager();
	Common::OutSaveFile *file = saveFileManager->openForSaving(_engine->generateSaveFileName(slot));

	writeSaveGameHeader(file, saveName, useSaveBuffer);

	if (useSaveBuffer)
		file->write(_tempSave->getData(), _tempSave->size());
	else
		_engine->getScriptManager()->serialize(file);

	file->finalize();
	delete file;

	if (useSaveBuffer)
		flushSaveBuffer();

	_lastSaveTime = g_system->getMillis();
}
Пример #7
0
/**
 * Save game to supplied slot
 */
bool FileManager::saveGame(const int16 slot, const Common::String &descrip) {
	debugC(1, kDebugFile, "saveGame(%d, %s)", slot, descrip.c_str());

	int16 savegameId;
	Common::String savegameDescription;

	if (slot == -1) {
		GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save", true);
		savegameId = dialog->runModalWithCurrentTarget();
		savegameDescription = dialog->getResultString();
		delete dialog;
	} else {
		savegameId = slot;
		if (!descrip.empty()) {
			savegameDescription = descrip;
		} else {
			savegameDescription = Common::String::format("Quick save #%d", slot);
		}
	}

	if (savegameId < 0)                             // dialog aborted
		return false;

	Common::String savegameFile = _vm->getSavegameFilename(savegameId);
	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
	Common::OutSaveFile *out = saveMan->openForSaving(savegameFile);

	if (!out) {
		warning("Can't create file '%s', game not saved", savegameFile.c_str());
		return false;
	}

	// Write version.  We can't restore from obsolete versions
	out->writeByte(kSavegameVersion);

	if (savegameDescription == "") {
		savegameDescription = "Untitled savegame";
	}

	out->writeSint16BE(savegameDescription.size() + 1);
	out->write(savegameDescription.c_str(), savegameDescription.size() + 1);

	Graphics::saveThumbnail(*out);

	TimeDate curTime;
	_vm->_system->getTimeAndDate(curTime);

	uint32 saveDate = (curTime.tm_mday & 0xFF) << 24 | ((curTime.tm_mon + 1) & 0xFF) << 16 | ((curTime.tm_year + 1900) & 0xFFFF);
	uint16 saveTime = (curTime.tm_hour & 0xFF) << 8 | ((curTime.tm_min) & 0xFF);

	out->writeUint32BE(saveDate);
	out->writeUint16BE(saveTime);

	_vm->_object->saveObjects(out);

	const Status &gameStatus = _vm->getGameStatus();

	// Save whether hero image is swapped
	out->writeByte(_vm->_heroImage);

	// Save score
	out->writeSint16BE(_vm->getScore());

	// Save story mode
	out->writeByte((gameStatus._storyModeFl) ? 1 : 0);

	// Save jumpexit mode
	out->writeByte((_vm->_mouse->getJumpExitFl()) ? 1 : 0);

	// Save gameover status
	out->writeByte((gameStatus._gameOverFl) ? 1 : 0);

	// Save screen states
	for (int i = 0; i < _vm->_numStates; i++)
		out->writeByte(_vm->_screenStates[i]);

	_vm->_scheduler->saveSchedulerData(out);
	// Save palette table
	_vm->_screen->savePal(out);

	// Save maze status
	out->writeByte((_vm->_maze._enabledFl) ? 1 : 0);
	out->writeByte(_vm->_maze._size);
	out->writeSint16BE(_vm->_maze._x1);
	out->writeSint16BE(_vm->_maze._y1);
	out->writeSint16BE(_vm->_maze._x2);
	out->writeSint16BE(_vm->_maze._y2);
	out->writeSint16BE(_vm->_maze._x3);
	out->writeSint16BE(_vm->_maze._x4);
	out->writeByte(_vm->_maze._firstScreenIndex);

	out->writeByte((byte)_vm->getGameStatus()._viewState);

	out->finalize();

	delete out;

	return true;
}
Пример #8
0
Common::Error KyraEngine_MR::saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumb) {
	const char *fileName = getSavegameFilename(slot);

	Common::OutSaveFile *out = openSaveForWriting(fileName, saveName, thumb);
	if (!out)
		return _saveFileMan->getError();

	_timer->saveDataToFile(*out);

	out->writeUint32BE(sizeof(_flagsTable));
	out->write(_flagsTable, sizeof(_flagsTable));

	out->writeSint16BE(_lastMusicCommand);
	out->writeByte(_currentChapter);
	out->writeByte(_characterShapeFile);
	out->writeByte(_album.curPage);
	out->writeSint16BE(_score);
	out->writeSint16BE(_scoreMax);
	out->writeByte(_malcolmsMood);
	for (int i = 0; i < 30; ++i)
		out->write(_conversationState[i], 30);
	out->write(_newSceneDlgState, 40);
	for (int i = 0; i < 100; ++i)
		out->writeSint16BE(_hiddenItems[i]);
	out->write(_scoreFlagTable, 26);

	out->writeUint16BE(_mainCharacter.sceneId);
	out->writeSint16BE(_mainCharacter.dlgIndex);
	out->writeByte(_mainCharacter.height);
	out->writeByte(_mainCharacter.facing);
	out->writeUint16BE(_mainCharacter.animFrame);
	out->writeByte(_mainCharacter.walkspeed);
	for (int i = 0; i < 10; ++i)
		out->writeUint16BE(_mainCharacter.inventory[i]);
	out->writeSint16BE(_mainCharacter.x1);
	out->writeSint16BE(_mainCharacter.y1);
	out->writeSint16BE(_mainCharacter.x2);
	out->writeSint16BE(_mainCharacter.y2);
	out->writeSint16BE(_mainCharacter.x3);
	out->writeSint16BE(_mainCharacter.y3);

	for (int i = 0; i < 50; ++i) {
		out->writeSint16BE(_itemList[i].id);
		out->writeUint16BE(_itemList[i].sceneId);
		out->writeSint16BE(_itemList[i].x);
		out->writeSint16BE(_itemList[i].y);
	}

	for (int i = 0; i < 88; ++i) {
		out->write(_talkObjectList[i].filename, 13);
		out->writeByte(_talkObjectList[i].sceneAnim);
		out->writeByte(_talkObjectList[i].sceneScript);
		out->writeSint16BE(_talkObjectList[i].x);
		out->writeSint16BE(_talkObjectList[i].y);
		out->writeByte(_talkObjectList[i].color);
		out->writeByte(_talkObjectList[i].sceneId);
	}

	for (int i = 0; i < 98; ++i) {
		out->write(_sceneList[i].filename1, 10);
		out->write(_sceneList[i].filename2, 10);
		out->writeUint16BE(_sceneList[i].exit1);
		out->writeUint16BE(_sceneList[i].exit2);
		out->writeUint16BE(_sceneList[i].exit3);
		out->writeUint16BE(_sceneList[i].exit4);
		out->writeByte(_sceneList[i].flags);
		out->writeByte(_sceneList[i].sound);
	}

	out->writeSint16BE(_itemInHand);
	out->writeUint16BE(_sceneExit1);
	out->writeUint16BE(_sceneExit2);
	out->writeUint16BE(_sceneExit3);
	out->writeUint16BE(_sceneExit4);

	out->finalize();

	// check for errors
	if (out->err()) {
		warning("Can't write file '%s'. (Disk full?)", fileName);
		return Common::kUnknownError;
	} else {
		debugC(1, kDebugLevelMain, "Saved game '%s.'", saveName);
	}

	delete out;
	return Common::kNoError;
}
Пример #9
0
void FWRenderer::saveBgNames(Common::OutSaveFile &fHandle) {
	fHandle.write(_bgName, 13);
}
Пример #10
0
void OSRenderer::saveBgNames(Common::OutSaveFile &fHandle) {
	for (int i = 0; i < 8; i++) {
		fHandle.write(_bgTable[i].name, 13);
	}
}
Пример #11
0
bool GameLoader::writeSavegame(Scene *sc, const char *fname) {
	GameVar *v = _gameVar->getSubVarByName("OBJSTATES")->getSubVarByName("SAVEGAME");

	if (!v) {
		v = _gameVar->getSubVarByName("OBJSTATES")->addSubVarAsInt("SAVEGAME", 0);

		if (!v) {
			warning("No state to save");
			return false;
		}
	}

	SaveHeader header;

	v->setSubVarAsInt("Scene", sc->_sceneId);

	saveScenePicAniInfos(sc->_sceneId);
	memset(&header, 0, sizeof(header));

	header.version = 48; // '0'
	strcpy(header.magic, "FullPipe Savegame");
	header.updateCounter = _updateCounter;
	header.unkField = 1;

	Common::MemoryWriteStreamDynamic stream;

	MfcArchive *archive = new MfcArchive(&stream);

	v = _gameVar->getSubVarByName("OBJSTATES");

	GameVar *nxt = 0;
	GameVar *prv = 0;
	GameVar *par;
	if (v) {
		nxt = v->_nextVarObj;
		prv = v->_prevVarObj;
		par = v->_parentVarObj;
		v->_parentVarObj = 0;
		v->_nextVarObj = 0;
		v->_prevVarObj = 0;
	}

	archive->writeObject(v);

	if (v) {
		v->_parentVarObj = par;
		v->_nextVarObj = nxt;
		v->_prevVarObj = prv;
	}

	getGameLoaderInventory()->savePartial(*archive);

	archive->writeUint32LE(_sc2array.size());

	debugC(3, kDebugLoading, "Saving %d infos", _sc2array.size());

	for (uint i = 0; i < _sc2array.size(); i++) {
		archive->writeUint32LE(_sc2array[i]._picAniInfosCount);

		if (_sc2array[i]._picAniInfosCount)
			debugC(3, kDebugLoading, "Count %d: %d", i, _sc2array[i]._picAniInfosCount);

		for (uint j = 0; j < _sc2array[i]._picAniInfosCount; j++) {
			_sc2array[i]._picAniInfos[j]->save(*archive);
		}
	}

	header.encSize = stream.size();

	// Now obfuscate the data
	for (uint i = 0; i < header.encSize; i++)
		stream.getData()[i] += i & 0x7f;

	if (_savegameCallback)
		_savegameCallback(archive, true);

	// Now dump it into save file
	Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(fname);

	if (!saveFile) {
		warning("Cannot open file for writing: %s", fname);
		return false;
	}

	saveFile->writeUint32LE(header.version);
	saveFile->write(header.magic, 32);
	saveFile->writeUint32LE(header.updateCounter);
	saveFile->writeUint32LE(header.unkField);
	saveFile->writeUint32LE(header.encSize);

	debugC(3, kDebugLoading, "version: %d magic: %s updateCounter: %d unkField: %d encSize: %d, pos: %d",
			header.version, header.magic, header.updateCounter, header.unkField, header.encSize, saveFile->pos());

	saveFile->write(stream.getData(), stream.size());

	uint headerPos = saveFile->pos();
	FullpipeSavegameHeader header2;

	strcpy(header2.id, "SVMCR");
	header2.version = FULLPIPE_SAVEGAME_VERSION;

	TimeDate curTime;
	g_system->getTimeAndDate(curTime);

	header2.date = ((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF);
	header2.time = ((curTime.tm_hour & 0xFF) << 8) | ((curTime.tm_min) & 0xFF);

	header2.playtime = g_fp->getTotalPlayTime() / 1000;

	saveFile->write(header2.id, 6);
	saveFile->writeByte(header2.version);
	saveFile->writeUint32LE(header2.date);
	saveFile->writeUint16LE(header2.time);
	saveFile->writeUint32LE(header2.playtime);

	g_fp->_currentScene->draw();

	Graphics::saveThumbnail(*saveFile); // FIXME. Render proper screen

	saveFile->writeUint32LE(headerPos);	// Store where the header starts

	saveFile->finalize();

	delete saveFile;
	delete archive;

	return true;
}
Пример #12
0
bool PersistenceService::saveGame(uint slotID, const Common::String &screenshotFilename) {
	// FIXME: This code is a hack which bypasses the savefile API,
	// and should eventually be removed.

	// Überprüfen, ob die Slot-ID zulässig ist.
	if (slotID >= SLOT_COUNT) {
		error("Tried to save to an invalid slot (%d). Only slot ids form 0 to %d are allowed.", slotID, SLOT_COUNT - 1);
		return false;
	}

	// Dateinamen erzeugen.
	Common::String filename = generateSavegameFilename(slotID);

	// Spielstanddatei öffnen und die Headerdaten schreiben.
	Common::SaveFileManager *sfm = g_system->getSavefileManager();
	Common::OutSaveFile *file = sfm->openForSaving(filename);

	file->writeString(FILE_MARKER);
	file->writeByte(0);
	file->writeString(VERSIONID);
	file->writeByte(0);

	char buf[20];
	snprintf(buf, 20, "%d", VERSIONNUM);
	file->writeString(buf);
	file->writeByte(0);

	TimeDate dt;
	g_system->getTimeAndDate(dt);
	file->writeString(formatTimestamp(dt));
	file->writeByte(0);

	if (file->err()) {
		error("Unable to write header data to savegame file \"%s\".", filename.c_str());
	}

	// Alle notwendigen Module persistieren.
	OutputPersistenceBlock writer;
	bool success = true;
	success &= Kernel::getInstance()->getScript()->persist(writer);
	success &= RegionRegistry::instance().persist(writer);
	success &= Kernel::getInstance()->getGfx()->persist(writer);
	success &= Kernel::getInstance()->getSfx()->persist(writer);
	success &= Kernel::getInstance()->getInput()->persist(writer);
	if (!success) {
		error("Unable to persist modules for savegame file \"%s\".", filename.c_str());
	}

	// Write the save game data uncompressed, since the final saved game will be
	// compressed anyway.
	char sBuffer[10];
	snprintf(sBuffer, 10, "%u", writer.getDataSize());
	file->writeString(sBuffer);
	file->writeByte(0);
	snprintf(sBuffer, 10, "%u", writer.getDataSize());
	file->writeString(sBuffer);
	file->writeByte(0);
	file->write(writer.getData(), writer.getDataSize());

	// Get the screenshot
	Common::SeekableReadStream *thumbnail = Kernel::getInstance()->getGfx()->getThumbnail();

	if (thumbnail) {
		byte *buffer = new byte[FILE_COPY_BUFFER_SIZE];
		thumbnail->seek(0, SEEK_SET);
		while (!thumbnail->eos()) {
			int bytesRead = thumbnail->read(&buffer[0], FILE_COPY_BUFFER_SIZE);
			file->write(&buffer[0], bytesRead);
		}

		delete[] buffer;
	} else {
		warning("The screenshot file \"%s\" does not exist. Savegame is written without a screenshot.", filename.c_str());
	}

	file->finalize();
	delete file;

	// Savegameinformationen für diesen Slot aktualisieren.
	_impl->readSlotSavegameInformation(slotID);

	// Empty the cache, to remove old thumbnails
	Kernel::getInstance()->getResourceManager()->emptyThumbnailCache();

	// Erfolg signalisieren.
	return true;
}
Пример #13
0
/**
 * Save an Operation Stealth type savegame. WIP!
 *
 * NOTE: This is going to be very much a work in progress so the Operation Stealth's
 *       savegame formats that are going to be tried are extremely probably not going
 *       to be supported at all after Operation Stealth becomes officially supported.
 *       This means that the savegame format will hopefully change to something nicer
 *       when official support for Operation Stealth begins.
 */
void CineEngine::makeSaveOS(Common::OutSaveFile &out) {
    int i;

    // Make a temporary Operation Stealth savegame format chunk header and save it.
    ChunkHeader header;
    header.id = TEMP_OS_FORMAT_ID;
    header.version = CURRENT_OS_SAVE_VER;
    header.size = 0; // No data is currently put inside the chunk, all the plain data comes right after it.
    writeChunkHeader(out, header);

    // Start outputting the plain savegame data right after the chunk header.
    out.writeUint16BE(currentDisk);
    out.write(currentPartName, 13);
    out.write(currentPrcName, 13);
    out.write(currentRelName, 13);
    out.write(currentMsgName, 13);
    renderer->saveBgNames(out);
    out.write(currentCtName, 13);

    saveObjectTable(out);
    renderer->savePalette(out);
    g_cine->_globalVars.save(out, NUM_MAX_VAR);
    saveZoneData(out);
    saveCommandVariables(out);
    saveCommandBuffer(out);
    saveZoneQuery(out);

    // FIXME: Save a proper name here, saving an empty string currently.
    // 0x2925: Current music name (String, 13 bytes).
    for (i = 0; i < 13; i++) {
        out.writeByte(0);
    }
    // FIXME: Save proper value for this variable, currently writing zero
    // 0x2932: Is music loaded? (Uint16BE, Boolean).
    out.writeUint16BE(0);
    // FIXME: Save proper value for this variable, currently writing zero
    // 0x2934: Is music playing? (Uint16BE, Boolean).
    out.writeUint16BE(0);

    out.writeUint16BE(renderer->_cmdY);
    out.writeUint16BE(0); // Some unknown variable that seems to always be zero
    out.writeUint16BE(allowPlayerInput);
    out.writeUint16BE(playerCommand);
    out.writeUint16BE(commandVar1);
    out.writeUint16BE(isDrawCommandEnabled);
    out.writeUint16BE(var5);
    out.writeUint16BE(var4);
    out.writeUint16BE(var3);
    out.writeUint16BE(var2);
    out.writeUint16BE(commandVar2);
    out.writeUint16BE(renderer->_messageBg);

    // FIXME: Save proper value for this variable, currently writing zero.
    // An unknown variable at 0x295E: adBgVar1 (Uint16BE).
    out.writeUint16BE(0);
    out.writeSint16BE(currentAdditionalBgIdx);
    out.writeSint16BE(currentAdditionalBgIdx2);
    // FIXME: Save proper value for this variable, currently writing zero.
    // 0x2954: additionalBgVScroll (Uint16BE). This probably means renderer->_bgShift.
    out.writeUint16BE(0);
    // FIXME: Save proper value for this variable, currently writing zero.
    // An unknown variable at 0x2956: adBgVar0 (Uint16BE). Maybe this means bgVar0?
    out.writeUint16BE(0);
    out.writeUint16BE(disableSystemMenu);

    saveAnimDataTable(out);
    saveScreenParams(out);
    saveGlobalScripts(out);
    saveObjectScripts(out);
    saveSeqList(out);
    saveOverlayList(out);
    saveBgIncrustList(out);
}
Пример #14
0
bool BladeRunnerEngine::saveGame(const Common::String &filename, byte *thumbnail) {
	warning("BladeRunnerEngine::saveGame not finished");

	if (!playerHasControl() || _sceneScript->isInsideScript() || _aiScripts->isInsideScript()) {
		return false;
	}

	Common::OutSaveFile *commonSaveFile = getSaveFileManager()->openForSaving(filename, false);
	if (commonSaveFile->err()) {
		return false;
	}

	SaveFileWriteStream s;

	s.padBytes(9600); // TODO: thumbnail
	s.writeFloat(-1.0f);
	_settings->save(s);
	_scene->save(s);
	_scene->_exits->save(s);
	_scene->_regions->save(s);
	_scene->_set->save(s);
	for (uint i = 0; i != _gameInfo->getGlobalVarCount(); ++i) {
		s.writeInt(_gameVars[i]);
	}
	_music->save(s);
	// _audioPlayer->save(s) // zero func
	// _audioSpeech->save(s) // zero func
	_combat->save(s);
	_gameFlags->save(s);
	_items->save(s);
	_sceneObjects->save(s);
	_ambientSounds->save(s);
	_overlays->save(s);
	_spinner->save(s);
	_scores->save(s);
	_dialogueMenu->save(s);
	_obstacles->save(s);
	_actorDialogueQueue->save(s);
	_waypoints->save(s);

	for (uint i = 0; i != _gameInfo->getActorCount(); ++i) {
		_actors[i]->save(s);

		int animationState, animationFrame, animationStateNext, nextAnimation;
		_aiScripts->queryAnimationState(i, &animationState, &animationFrame, &animationStateNext, &nextAnimation);
		s.writeInt(animationState);
		s.writeInt(animationFrame);
		s.writeInt(animationStateNext);
		s.writeInt(nextAnimation);
	}
	_actors[kActorVoiceOver]->save(s);

	_policeMaze->save(s);
	_crimesDatabase->save(s);

	s.finalize();
	assert(0 && "ok");

	commonSaveFile->writeUint32LE(s.size() + 4);
	commonSaveFile->write(s.getData(), s.size());

	return !commonSaveFile->err();
}
Пример #15
0
Common::Error LoLEngine::saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) {
	const char *fileName = getSavegameFilename(slot);

	Common::OutSaveFile *out = openSaveForWriting(fileName, saveName, thumbnail);
	if (!out)
		return _saveFileMan->getError();

	completeDoorOperations();
	generateTempData();

	for (int i = 0; i < 4; i++) {
		LoLCharacter *c = &_characters[i];
		out->writeUint16BE(c->flags);
		out->write(c->name, 11);
		out->writeByte(c->raceClassSex);
		out->writeSint16BE(c->id);
		out->writeByte(c->curFaceFrame);
		out->writeByte(c->tempFaceFrame);
		out->writeByte(c->screamSfx);
		for (int ii = 0; ii < 8; ii++)
			out->writeUint16BE(c->itemsMight[ii]);
		for (int ii = 0; ii < 8; ii++)
			out->writeUint16BE(c->protectionAgainstItems[ii]);
		out->writeUint16BE(c->itemProtection);
		out->writeSint16BE(c->hitPointsCur);
		out->writeUint16BE(c->hitPointsMax);
		out->writeSint16BE(c->magicPointsCur);
		out->writeUint16BE(c->magicPointsMax);
		out->writeByte(c->field_41);
		out->writeUint16BE(c->damageSuffered);
		out->writeUint16BE(c->weaponHit);
		out->writeUint16BE(c->totalMightModifier);
		out->writeUint16BE(c->totalProtectionModifier);
		out->writeUint16BE(c->might);
		out->writeUint16BE(c->protection);
		out->writeSint16BE(c->nextAnimUpdateCountdown);
		for (int ii = 0; ii < 11; ii++)
			out->writeUint16BE(c->items[ii]);
		for (int ii = 0; ii < 3; ii++)
			out->writeByte(c->skillLevels[ii]);
		for (int ii = 0; ii < 3; ii++)
			out->writeSByte(c->skillModifiers[ii]);
		for (int ii = 0; ii < 3; ii++)
			out->writeUint32BE(c->experiencePts[ii]);
		for (int ii = 0; ii < 5; ii++)
			out->writeByte(c->characterUpdateEvents[ii]);
		for (int ii = 0; ii < 5; ii++)
			out->writeByte(c->characterUpdateDelay[ii]);
	}

	out->write(_wllBuffer4, 80);

	out->writeUint16BE(_currentBlock);
	out->writeUint16BE(_partyPosX);
	out->writeUint16BE(_partyPosY);
	out->writeUint16BE(_updateFlags);
	out->writeByte(_scriptDirection);
	out->writeByte(_selectedSpell);
	out->writeByte(_sceneDefaultUpdate);
	out->writeByte(_compassBroken);
	out->writeByte(_drainMagic);
	out->writeUint16BE(_currentDirection);
	out->writeUint16BE(_compassDirection);
	out->writeSByte(_selectedCharacter);
	out->writeByte(_currentLevel);
	for (int i = 0; i < 48; i++)
		out->writeSint16BE(_inventory[i]);
	out->writeSint16BE(_inventoryCurItem);
	out->writeSint16BE(_itemInHand);
	out->writeSint16BE(_lastMouseRegion);
	out->writeUint32BE(ARRAYSIZE(_flagsTable));
	out->write(_flagsTable, ARRAYSIZE(_flagsTable));
	for (int i = 0; i < 24; i++)
		out->writeUint16BE(_globalScriptVars[i]);
	out->writeByte(_brightness);
	out->writeByte(_lampOilStatus);
	out->writeSByte(_lampEffect);
	out->writeUint16BE(_credits);
	for (int i = 0; i < 8; i++)
		out->writeUint16BE(_globalScriptVars2[i]);
	out->write(_availableSpells, 7);
	out->writeUint32BE(_hasTempDataFlags);

	resetItems(0);

	for (int i = 0; i < 400; i++) {
		ItemInPlay *t = &_itemsInPlay[i];
		out->writeUint16BE(t->nextAssignedObject);
		out->writeUint16BE(t->nextDrawObject);
		out->writeByte(t->flyingHeight);
		out->writeUint16BE(t->block);
		out->writeUint16BE(t->x);
		out->writeUint16BE(t->y);
		out->writeSByte(t->level);
		out->writeUint16BE(t->itemPropertyIndex);
		out->writeUint16BE(t->shpCurFrame_flg);
		out->writeByte(t->destDirection);
		out->writeSByte(t->hitOffsX);
		out->writeSByte(t->hitOffsY);
		out->writeByte(t->currentSubFrame);
	}

	addLevelItems();

	for (int i = 0; i < 29; i++) {
		LevelTempData *l = _lvlTempData[i];
		if (!l || !(_hasTempDataFlags & (1 << i)))
			continue;

		out->write(l->wallsXorData, 4096);
		out->write(l->flags, 1024);

		for (int ii = 0; ii < 30; ii++) {
			MonsterInPlay *m = &l->monsters[ii];
			out->writeUint16BE(m->nextAssignedObject);
			out->writeUint16BE(m->nextDrawObject);
			out->writeByte(m->flyingHeight);
			out->writeUint16BE(m->block);
			out->writeUint16BE(m->x);
			out->writeUint16BE(m->y);
			out->writeSByte(m->shiftStep);
			out->writeUint16BE(m->destX);
			out->writeUint16BE(m->destY);
			out->writeByte(m->destDirection);
			out->writeSByte(m->hitOffsX);
			out->writeSByte(m->hitOffsY);
			out->writeByte(m->currentSubFrame);
			out->writeByte(m->mode);
			out->writeSByte(m->fightCurTick);
			out->writeByte(m->id);
			out->writeByte(m->direction);
			out->writeByte(m->facing);
			out->writeUint16BE(m->flags);
			out->writeUint16BE(m->damageReceived);
			out->writeSint16BE(m->hitPoints);
			out->writeByte(m->speedTick);
			out->writeByte(m->type);
			out->writeByte(m->numDistAttacks);
			out->writeByte(m->curDistWeapon);
			out->writeSByte(m->distAttackTick);
			out->writeUint16BE(m->assignedItems);
			out->write(m->equipmentShapes, 4);
		}

		for (int ii = 0; ii < 8; ii++) {
			FlyingObject *m = &l->flyingObjects[ii];
			out->writeByte(m->enable);
			out->writeByte(m->objectType);
			out->writeUint16BE(m->attackerId);
			out->writeSint16BE(m->item);
			out->writeUint16BE(m->x);
			out->writeUint16BE(m->y);
			out->writeByte(m->flyingHeight);
			out->writeByte(m->direction);
			out->writeByte(m->distance);
			out->writeSByte(m->field_D);
			out->writeByte(m->c);
			out->writeByte(m->flags);
			out->writeByte(m->wallFlags);
		}
		out->writeByte(l->monsterDifficulty);
	}

	out->finalize();

	// check for errors
	if (out->err()) {
		warning("Can't write file '%s'. (Disk full?)", fileName);
		return Common::kUnknownError;
	} else {
		debugC(1, kDebugLevelMain, "Saved game '%s.'", saveName);
	}

	delete out;
	return Common::kNoError;
}
Пример #16
0
Common::Error KyraEngine_HoF::saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumb) {
	const char *fileName = getSavegameFilename(slot);

	Common::OutSaveFile *out = openSaveForWriting(fileName, saveName, thumb);
	if (!out)
		return _saveFileMan->getError();

	_timer->saveDataToFile(*out);

	out->writeUint32BE(sizeof(_flagsTable));
	out->write(_flagsTable, sizeof(_flagsTable));

	// usually we have to save the flag set by opcode 10 here
	//out->writeUint16BE(word_2AB05);
	out->writeSint16BE(_lastMusicCommand);
	out->writeByte(_newChapterFile);
	out->writeByte(_characterShapeFile);
	out->writeByte(_cauldronState);
	out->writeByte(_colorCodeFlag1);
	out->writeByte(_colorCodeFlag2);
	out->writeByte(_bookCurPage);
	out->writeByte(_bookMaxPage);
	for (int i = 0; i < 7; ++i)
		out->writeByte(_presetColorCode[i]);
	for (int i = 0; i < 7; ++i)
		out->writeByte(_inputColorCode[i]);
	for (int i = 0; i < 25; ++i)
		out->writeSint16BE(_cauldronTable[i]);
	for (int i = 0; i < 20; ++i)
		out->writeSint16BE(_hiddenItems[i]);
	for (int i = 0; i < 19; ++i)
		out->write(_conversationState[i], 14);
	out->write(_newSceneDlgState, 32);
	out->writeSint16BE(_cauldronUseCount);

	out->writeUint16BE(_mainCharacter.sceneId);
	out->writeSint16BE(_mainCharacter.dlgIndex);
	out->writeByte(_mainCharacter.height);
	out->writeByte(_mainCharacter.facing);
	out->writeUint16BE(_mainCharacter.animFrame);
	for (int i = 0; i < 20; ++i)
		out->writeUint16BE(_mainCharacter.inventory[i]);
	out->writeSint16BE(_mainCharacter.x1);
	out->writeSint16BE(_mainCharacter.y1);
	out->writeSint16BE(_mainCharacter.x2);
	out->writeSint16BE(_mainCharacter.y2);

	for (int i = 0; i < 30; ++i) {
		out->writeSint16BE(_itemList[i].id);
		out->writeUint16BE(_itemList[i].sceneId);
		out->writeSint16BE(_itemList[i].x);
		out->writeByte(_itemList[i].y);
	}

	for (int i = 0; i < 72; ++i) {
		out->write(_talkObjectList[i].filename, 13);
		out->writeByte(_talkObjectList[i].scriptId);
		out->writeSint16BE(_talkObjectList[i].x);
		out->writeSint16BE(_talkObjectList[i].y);
		out->writeByte(_talkObjectList[i].color);
	}

	for (int i = 0; i < 86; ++i) {
		out->write(_sceneList[i].filename1, 10);
		out->writeUint16BE(_sceneList[i].exit1);
		out->writeUint16BE(_sceneList[i].exit2);
		out->writeUint16BE(_sceneList[i].exit3);
		out->writeUint16BE(_sceneList[i].exit4);
		out->writeByte(_sceneList[i].flags);
		out->writeByte(_sceneList[i].sound);
	}

	out->writeSint16BE(_itemInHand);
	out->writeUint16BE(_sceneExit1);
	out->writeUint16BE(_sceneExit2);
	out->writeUint16BE(_sceneExit3);
	out->writeUint16BE(_sceneExit4);

	out->finalize();

	// check for errors
	if (out->err()) {
		warning("Can't write file '%s'. (Disk full?)", fileName);
		return Common::kUnknownError;
	} else {
		debugC(1, kDebugLevelMain, "Saved game '%s.'", saveName);
	}

	delete out;
	return Common::kNoError;
}
Пример #17
0
Common::Error EoBCoreEngine::saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) {
	Common::String saveNameTmp;
	const char *fileName = 0;

	// Special slot id -1 to create final save for party transfer
	if (slot == -1) {
		_savegameFilename = _targetName + Common::String(".fin");
		fileName = _savegameFilename.c_str();
		saveNameTmp = _targetName + Common::String(" final");
		saveNameTmp.toUppercase();
		saveName = saveNameTmp.c_str();
	} else {
		fileName = getSavegameFilename(slot);
	}

	Common::OutSaveFile *out = openSaveForWriting(fileName, saveName, thumbnail);
	if (!out)
		return _saveFileMan->getError();

	completeDoorOperations();
	generateTempData();
	advanceTimers(_restPartyElapsedTime);
	_restPartyElapsedTime = 0;

	for (int i = 0; i < 6; i++)
		timerSpecialCharacterUpdate(0x30 + i);

	for (int i = 0; i < 6; i++) {
		EoBCharacter *c = &_characters[i];

		out->writeByte(c->id);
		out->writeByte(c->flags);
		out->write(c->name, 11);
		out->writeSByte(c->strengthCur);
		out->writeSByte(c->strengthMax);
		out->writeSByte(c->strengthExtCur);
		out->writeSByte(c->strengthExtMax);
		out->writeSByte(c->intelligenceCur);
		out->writeSByte(c->intelligenceMax);
		out->writeSByte(c->wisdomCur);
		out->writeSByte(c->wisdomMax);
		out->writeSByte(c->dexterityCur);
		out->writeSByte(c->dexterityMax);
		out->writeSByte(c->constitutionCur);
		out->writeSByte(c->constitutionMax);
		out->writeSByte(c->charismaCur);
		out->writeSByte(c->charismaMax);
		out->writeSint16BE(c->hitPointsCur);
		out->writeSint16BE(c->hitPointsMax);
		out->writeSByte(c->armorClass);
		out->writeByte(c->disabledSlots);
		out->writeByte(c->raceSex);
		out->writeByte(c->cClass);
		out->writeByte(c->alignment);
		out->writeByte(c->portrait);
		out->writeByte(c->food);
		out->write(c->level, 3);
		for (int ii = 0; ii < 3; ii++)
			out->writeUint32BE(c->experience[ii]);
		out->write(c->mageSpells, 80);
		out->write(c->clericSpells, 80);
		out->writeUint32BE(c->mageSpellsAvailableFlags);
		for (int ii = 0; ii < 27; ii++)
			out->writeSint16BE(c->inventory[ii]);
		uint32 ct = _system->getMillis();
		for (int ii = 0; ii < 10; ii++)
			out->writeUint32BE((c->timers[ii] && c->timers[ii] > ct) ? c->timers[ii] - ct : 0);

		out->write(c->events, 10);
		out->write(c->effectsRemainder, 4);
		out->writeUint32BE(c->effectFlags);
		out->writeByte(c->damageTaken);
		out->write(c->slotStatus, 5);
	}

	out->writeByte(_currentLevel);
	out->writeSByte(_currentSub);
	out->writeUint16BE(_currentBlock);
	out->writeUint16BE(_currentDirection);
	out->writeSint16BE(_itemInHand);
	out->writeUint32BE(_hasTempDataFlags);
	out->writeUint32BE(_partyEffectFlags);

	out->writeUint16BE(_updateFlags);
	out->writeUint16BE(_compassDirection);
	out->writeUint16BE(_currentControlMode);
	out->writeUint16BE(_updateCharNum);
	out->writeSByte(_openBookSpellLevel);
	out->writeSByte(_openBookSpellSelectedItem);
	out->writeSByte(_openBookSpellListOffset);
	out->writeByte(_openBookChar);
	out->writeByte(_openBookType);
	out->writeByte(_openBookCharBackup);
	out->writeByte(_openBookTypeBackup);
	out->writeByte(_activeSpellCharId);
	out->writeByte(_activeSpellCharacterPos);
	out->writeByte(_activeSpell);
	out->writeByte(_returnAfterSpellCallback ? 1 : 0);

	_inf->saveState(out);

	for (int i = 0; i < 600; i++) {
		EoBItem *t = &_items[i];
		out->writeByte(t->nameUnid);
		out->writeByte(t->nameId);
		out->writeByte(t->flags);
		out->writeSByte(t->icon);
		out->writeSByte(t->type);
		out->writeSByte(t->pos);
		out->writeSint16BE(t->block);
		out->writeSint16BE(t->next);
		out->writeSint16BE(t->prev);
		out->writeByte(t->level);
		out->writeSByte(t->value);
	}

	for (int i = 51; i < 65; i++) {
		EoBItemType *t = &_itemTypes[i];
		out->writeUint16BE(t->invFlags);
		out->writeUint16BE(t->handFlags);
		out->writeSByte(t->armorClass);
		out->writeSByte(t->allowedClasses);
		out->writeSByte(t->requiredHands);
		out->writeSByte(t->dmgNumDiceS);
		out->writeSByte(t->dmgNumPipsS);
		out->writeSByte(t->dmgIncS);
		out->writeSByte(t->dmgNumDiceL);
		out->writeSByte(t->dmgNumPipsL);
		out->writeSByte(t->dmgIncL);
		out->writeByte(t->unk1);
		out->writeUint16BE(t->extraProperties);
	}

	for (int i = 0; i < 18; i++) {
		LevelTempData *l = _lvlTempData[i];
		if (!l || !(_hasTempDataFlags & (1 << i)))
			continue;

		out->write(l->wallsXorData, 4096);
		for (int ii = 0; ii < 1024; ii++)
			out->writeByte(l->flags[ii] & 0xff);

		EoBMonsterInPlay *lm = (EoBMonsterInPlay *)_lvlTempData[i]->monsters;
		EoBFlyingObject *lf = (EoBFlyingObject *)_lvlTempData[i]->flyingObjects;
		WallOfForce *lw = (WallOfForce *)_lvlTempData[i]->wallsOfForce;

		for (int ii = 0; ii < 30; ii++) {
			EoBMonsterInPlay *m = &lm[ii];
			out->writeByte(m->type);
			out->writeByte(m->unit);
			out->writeUint16BE(m->block);
			out->writeByte(m->pos);
			out->writeSByte(m->dir);
			out->writeByte(m->animStep);
			out->writeByte(m->shpIndex);
			out->writeSByte(m->mode);
			out->writeSByte(m->f_9);
			out->writeSByte(m->curAttackFrame);
			out->writeSByte(m->spellStatusLeft);
			out->writeSint16BE(m->hitPointsMax);
			out->writeSint16BE(m->hitPointsCur);
			out->writeUint16BE(m->dest);
			out->writeUint16BE(m->randItem);
			out->writeUint16BE(m->fixedItem);
			out->writeByte(m->flags);
			out->writeByte(m->idleAnimState);
			out->writeByte(m->curRemoteWeapon);
			out->writeByte(m->numRemoteAttacks);
			out->writeSByte(m->palette);
			out->writeByte(m->directionChanged);
			out->writeByte(m->stepsTillRemoteAttack);
			out->writeByte(m->sub);
		}

		for (int ii = 0; ii < _numFlyingObjects; ii++) {
			EoBFlyingObject *m = &lf[ii];
			out->writeByte(m->enable);
			out->writeByte(m->objectType);
			out->writeSint16BE(m->attackerId);
			out->writeSint16BE(m->item);
			out->writeUint16BE(m->curBlock);
			out->writeUint16BE(m->u2);
			out->writeByte(m->u1);
			out->writeByte(m->direction);
			out->writeByte(m->distance);
			out->writeSByte(m->callBackIndex);
			out->writeByte(m->curPos);
			out->writeByte(m->flags);
			out->writeByte(m->unused);
		}

		for (int ii = 0; ii < 5; ii++) {
			WallOfForce *w = &lw[ii];
			out->writeUint16BE(w->block);
			out->writeUint32BE(w->duration);
		}
	}

	out->finalize();

	// check for errors
	if (out->err()) {
		warning("Can't write file '%s'. (Disk full?)", fileName);
		return Common::kUnknownError;
	} else {
		debugC(1, kDebugLevelMain, "Saved game '%s.'", saveName);
	}

	delete out;

	_gui->notifyUpdateSaveSlotsList();

	return Common::kNoError;
}
Пример #18
0
void ToltecsEngine::savegame(const char *filename, const char *description) {
	Common::OutSaveFile *out;
	if (!(out = g_system->getSavefileManager()->openForSaving(filename))) {
		warning("Can't create file '%s', game not saved", filename);
		return;
	}

	TimeDate curTime;
	g_system->getTimeAndDate(curTime);

	// Header start
	out->writeUint32LE(TOLTECS_SAVEGAME_VERSION);

	byte descriptionLen = strlen(description);
	out->writeByte(descriptionLen);
	out->write(description, descriptionLen);
	
	Graphics::saveThumbnail(*out);

	// Not used yet, reserved for future usage
	out->writeByte(0);
	out->writeUint32LE(0);
	uint32 saveDate = ((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF);
	uint32 saveTime = ((curTime.tm_hour & 0xFF) << 16) | (((curTime.tm_min) & 0xFF) << 8) | ((curTime.tm_sec) & 0xFF);
	uint32 playTime = g_engine->getTotalPlayTime() / 1000;
	out->writeUint32LE(saveDate);
	out->writeUint32LE(saveTime);
	out->writeUint32LE(playTime);
	// Header end

	out->writeUint16LE(_cameraX);
	out->writeUint16LE(_cameraY);
	out->writeUint16LE(_cameraHeight);

	out->writeUint16LE(_guiHeight);

	out->writeUint16LE(_sceneWidth);
	out->writeUint16LE(_sceneHeight);
	out->writeUint32LE(_sceneResIndex);

	out->writeUint16LE(_walkSpeedX);
	out->writeUint16LE(_walkSpeedY);

	out->writeUint32LE(_counter01);
	out->writeUint32LE(_counter02);
	out->writeByte(_movieSceneFlag ? 1 : 0);
	out->writeByte(_flag01);

	out->writeUint16LE(_mouseX);
	out->writeUint16LE(_mouseY);
	out->writeUint16LE(_mouseDisabled);

	_palette->saveState(out);
	_script->saveState(out);
	_anim->saveState(out);
	_screen->saveState(out);
	_sound->saveState(out);
	_music->saveState(out);

	out->finalize();
	delete out;
}
Пример #19
0
void RMGfxEngine::saveState(const Common::String &fn, byte *curThumb, const Common::String &name) {
	Common::OutSaveFile *f;
	byte *state;
	char buf[4];
	RMPoint tp = _tony.position();

	// Saving: MPAL variables, current location, and Tony inventory position

	// For now, we only save the MPAL state
	uint size = mpalGetSaveStateSize();
	state = new byte[size];
	mpalSaveState(state);

	uint thumbsize = 160 * 120 * 2;

	buf[0] = 'R';
	buf[1] = 'M';
	buf[2] = 'S';
	buf[3] = TONY_SAVEGAME_VERSION;

	f = g_system->getSavefileManager()->openForSaving(fn);
	if (f == NULL)
		return;

	f->write(buf, 4);
	f->writeUint32LE(thumbsize);
	f->write(curThumb, thumbsize);

	// Difficulty level
	int i = mpalQueryGlobalVar("VERSIONEFACILE");
	f->writeByte(i);

	i = strlen(name.c_str());
	f->writeByte(i);
	f->write(name.c_str(), i);
	f->writeUint32LE(_nCurLoc);
	f->writeUint32LE(tp._x);
	f->writeUint32LE(tp._y);

	f->writeUint32LE(size);
	f->write(state, size);
	delete[] state;

	// Inventory
	size = _inv.getSaveStateSize();
	state = new byte[size];
	_inv.saveState(state);
	f->writeUint32LE(size);
	f->write(state, size);
	delete[] state;

	// boxes
	size = g_vm->_theBoxes.getSaveStateSize();
	state = new byte[size];
	g_vm->_theBoxes.saveState(state);
	f->writeUint32LE(size);
	f->write(state, size);
	delete[] state;

	// New Ver5
	// Saves the state of the shepherdess and show yourself
	bool bStat = _tony.getShepherdess();
	f->writeByte(bStat);
	bStat = _inter.getPerorate();
	f->writeByte(bStat);

	// Save the chars
	charsSaveAll(f);

	// Save the options
	f->writeByte(GLOBALS._bCfgInvLocked);
	f->writeByte(GLOBALS._bCfgInvNoScroll);
	f->writeByte(GLOBALS._bCfgTimerizedText);
	f->writeByte(GLOBALS._bCfgInvUp);
	f->writeByte(GLOBALS._bCfgAnni30);
	f->writeByte(GLOBALS._bCfgAntiAlias);
	f->writeByte(GLOBALS._bShowSubtitles);
	f->writeByte(GLOBALS._bCfgTransparence);
	f->writeByte(GLOBALS._bCfgInterTips);
	f->writeByte(GLOBALS._bCfgDubbing);
	f->writeByte(GLOBALS._bCfgMusic);
	f->writeByte(GLOBALS._bCfgSFX);
	f->writeByte(GLOBALS._nCfgTonySpeed);
	f->writeByte(GLOBALS._nCfgTextSpeed);
	f->writeByte(GLOBALS._nCfgDubbingVolume);
	f->writeByte(GLOBALS._nCfgMusicVolume);
	f->writeByte(GLOBALS._nCfgSFXVolume);

	// Save the hotspots
	saveChangedHotspot(f);

	// Save the music
	saveMusic(f);

	f->finalize();
	delete f;
}
Пример #20
0
bool saveGame(const Common::String &fname) {
	Common::OutSaveFile *fp = g_system->getSavefileManager()->openForSaving(fname);

	if (fp == NULL)
		return false;

	fp->writeString("SLUDSA");
	fp->writeByte(0);
	fp->writeByte(0);
	fp->writeByte(MAJOR_VERSION);
	fp->writeByte(MINOR_VERSION);

	if (!g_sludge->_gfxMan->saveThumbnail(fp))
		return false;

	fp->write(&fileTime, sizeof(FILETIME));

	// DON'T ADD ANYTHING NEW BEFORE THIS POINT!

	fp->writeByte(allowAnyFilename);
	fp->writeByte(captureAllKeys);
	fp->writeByte(true);
	g_sludge->_txtMan->saveFont(fp);

	// Save backdrop
	fp->writeUint16BE(g_sludge->_gfxMan->getCamX());
	fp->writeUint16BE(g_sludge->_gfxMan->getCamY());
	fp->writeFloatLE(g_sludge->_gfxMan->getCamZoom());

	fp->writeByte(brightnessLevel);
	g_sludge->_gfxMan->saveHSI(fp);

	// Save event handlers
	g_sludge->_evtMan->saveHandlers(fp);

	// Save regions
	saveRegions(fp);

	g_sludge->_cursorMan->saveCursor(fp);

	// Save functions
	LoadedFunction *thisFunction = allRunningFunctions;
	int countFunctions = 0;
	while (thisFunction) {
		countFunctions++;
		thisFunction = thisFunction->next;
	}
	fp->writeUint16BE(countFunctions);

	thisFunction = allRunningFunctions;
	while (thisFunction) {
		saveFunction(thisFunction, fp);
		thisFunction = thisFunction->next;
	}

	for (int a = 0; a < numGlobals; a++) {
		saveVariable(&globalVars[a], fp);
	}

	savePeople(fp);

	if (currentFloor->numPolygons) {
		fp->writeByte(1);
		fp->writeUint16BE(currentFloor->originalNum);
	} else {
		fp->writeByte(0);
	}

	g_sludge->_gfxMan->saveZBuffer(fp);
	g_sludge->_gfxMan->saveLightMap(fp);

	fp->writeByte(fadeMode);

	g_sludge->_speechMan->save(fp);
	saveStatusBars(fp);
	g_sludge->_soundMan->saveSounds(fp);

	fp->writeUint16BE(saveEncoding);

	blur_saveSettings(fp);

	g_sludge->_gfxMan->saveColors(fp);

	g_sludge->_gfxMan->saveParallax(fp);
	fp->writeByte(0);

	g_sludge->_languageMan->saveLanguageSetting(fp);

	g_sludge->_gfxMan->saveSnapshot(fp);

	fp->flush();
	fp->finalize();
	delete fp;

	clearStackLib();
	return true;
}
Пример #21
0
void SagaEngine::save(const char *fileName, const char *saveName) {
	Common::OutSaveFile *out;
	char title[TITLESIZE];

	if (!(out = _saveFileMan->openForSaving(fileName))) {
		return;
	}

	_saveHeader.type = MKTAG('S','A','G','A');
	_saveHeader.size = 0;
	_saveHeader.version = CURRENT_SAGA_VER;
	// Note that IHNM has a smaller save title size than ITE
	// We allocate the ITE save title size here, to preserve
	// savegame backwards compatibility
	Common::strlcpy(_saveHeader.name, saveName, SAVE_TITLE_SIZE);

	out->writeUint32BE(_saveHeader.type);
	out->writeUint32LE(_saveHeader.size);
	out->writeUint32LE(_saveHeader.version);
	out->write(_saveHeader.name, sizeof(_saveHeader.name));

	// Original game title
	memset(title, 0, TITLESIZE);
	Common::strlcpy(title, _gameTitle.c_str(), TITLESIZE);
	out->write(title, TITLESIZE);

	// Thumbnail
	// First draw scene without save dialog
	int oldMode = _interface->getMode();
	_interface->setMode(kPanelMain);
	_render->drawScene();

	Graphics::saveThumbnail(*out);

	_interface->setMode(oldMode);

	// Date / time
	TimeDate curTime;
	_system->getTimeAndDate(curTime);

	uint32 saveDate = ((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF);
	uint16 saveTime = ((curTime.tm_hour & 0xFF) << 8) | ((curTime.tm_min) & 0xFF);
	uint32 playTime = g_engine->getTotalPlayTime() / 1000;

	out->writeUint32BE(saveDate);
	out->writeUint16BE(saveTime);
	out->writeUint32BE(playTime);

	// Surrounding scene
	out->writeSint32LE(_scene->getOutsetSceneNumber());
#ifdef ENABLE_IHNM
	if (getGameId() == GID_IHNM) {
		out->writeSint32LE(_scene->currentChapterNumber());
		out->writeSint32LE(0);	// obsolete, was used for the protagonist
		out->writeSint32LE(_scene->getCurrentMusicTrack());
		out->writeSint32LE(_scene->getCurrentMusicRepeat());
	}
#endif
	// Inset scene
	out->writeSint32LE(_scene->currentSceneNumber());

#ifdef ENABLE_IHNM
	if (getGameId() == GID_IHNM) {
		out->writeUint32LE(_globalFlags);
		for (int i = 0; i < ARRAYSIZE(_ethicsPoints); i++)
			out->writeSint16LE(_ethicsPoints[i]);
	}
#endif

	_interface->saveState(out);

	_actor->saveState(out);

	out->writeSint16LE(_script->_commonBuffer.size());

	out->write(_script->_commonBuffer.getBuffer(), _script->_commonBuffer.size());

	// ISO map x, y coordinates for ITE
	if (getGameId() == GID_ITE) {
		out->writeSint16LE(_isoMap->getMapPosition().x);
		out->writeSint16LE(_isoMap->getMapPosition().y);
	}

	out->finalize();

	if (out->err())
		warning("Can't write file '%s'. (Disk full?)", fileName);

	delete out;

	_interface->resetSaveReminder();
}
Пример #22
0
int AgiEngine::saveGame(const Common::String &fileName, const Common::String &description) {
	char gameIDstring[8] = "gameIDX";
	int i;
	Common::OutSaveFile *out;
	int result = errOK;

	debugC(3, kDebugLevelMain | kDebugLevelSavegame, "AgiEngine::saveGame(%s, %s)", fileName.c_str(), description.c_str());
	if (!(out = _saveFileMan->openForSaving(fileName))) {
		warning("Can't create file '%s', game not saved", fileName.c_str());
		return errBadFileOpen;
	} else {
		debugC(3, kDebugLevelMain | kDebugLevelSavegame, "Successfully opened %s for writing", fileName.c_str());
	}

	out->writeUint32BE(AGIflag);
	out->write(description.c_str(), 31);

	out->writeByte(SAVEGAME_VERSION);
	debugC(5, kDebugLevelMain | kDebugLevelSavegame, "Writing save game version (%d)", SAVEGAME_VERSION);

	// Thumbnail
	Graphics::saveThumbnail(*out);

	// Creation date/time
	TimeDate curTime;
	_system->getTimeAndDate(curTime);

	uint32 saveDate = ((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF);
	uint16 saveTime = ((curTime.tm_hour & 0xFF) << 8) | ((curTime.tm_min) & 0xFF);

	out->writeUint32BE(saveDate);
	debugC(5, kDebugLevelMain | kDebugLevelSavegame, "Writing save date (%d)", saveDate);
	out->writeUint16BE(saveTime);
	debugC(5, kDebugLevelMain | kDebugLevelSavegame, "Writing save time (%d)", saveTime);
	// TODO: played time

	out->writeByte(_game.state);
	debugC(5, kDebugLevelMain | kDebugLevelSavegame, "Writing game state (%d)", _game.state);

	strcpy(gameIDstring, _game.id);
	out->write(gameIDstring, 8);
	debugC(5, kDebugLevelMain | kDebugLevelSavegame, "Writing game id (%s, %s)", gameIDstring, _game.id);

	const char *tmp = getGameMD5();
	// As reported in bug report #2849084 "AGI: Crash when saving fallback-matched game"
	// getGameMD5 will return NULL for fallback matched games. Since there is also no
	// filename available we can not compute any MD5 here either. Thus we will just set
	// the MD5 sum in the savegame to all zero, when getGameMD5 returns NULL.
	if (!tmp) {
		for (i = 0; i < 32; ++i)
			out->writeByte(0);
	} else {
		for (i = 0; i < 32; ++i)
			out->writeByte(tmp[i]);
	}

	for (i = 0; i < MAX_FLAGS; i++)
		out->writeByte(_game.flags[i]);
	for (i = 0; i < MAX_VARS; i++)
		out->writeByte(_game.vars[i]);

	out->writeSint16BE((int8)_game.horizon);
	out->writeSint16BE((int16)_game.lineStatus);
	out->writeSint16BE((int16)_game.lineUserInput);
	out->writeSint16BE((int16)_game.lineMinPrint);

	out->writeSint16BE((int16)_game.inputMode);
	out->writeSint16BE((int16)_game.lognum);

	out->writeSint16BE((int16)_game.playerControl);
	out->writeSint16BE((int16)shouldQuit());
	out->writeSint16BE((int16)_game.statusLine);
	out->writeSint16BE((int16)_game.clockEnabled);
	out->writeSint16BE((int16)_game.exitAllLogics);
	out->writeSint16BE((int16)_game.pictureShown);
	out->writeSint16BE((int16)_game.hasPrompt);
	out->writeSint16BE((int16)_game.gameFlags);

	out->writeSint16BE(_game.inputEnabled);

	for (i = 0; i < _HEIGHT; i++)
		out->writeByte(_game.priTable[i]);

	out->writeSint16BE((int16)_game.gfxMode);
	out->writeByte(_game.cursorChar);
	out->writeSint16BE((int16)_game.colorFg);
	out->writeSint16BE((int16)_game.colorBg);

	// game.hires
	// game.sbuf
	// game.ego_words
	// game.num_ego_words

	out->writeSint16BE((int16)_game.numObjects);
	for (i = 0; i < (int16)_game.numObjects; i++)
		out->writeSint16BE((int16)objectGetLocation(i));

	// game.ev_keyp
	for (i = 0; i < MAX_STRINGS; i++)
		out->write(_game.strings[i], MAX_STRINGLEN);

	// record info about loaded resources
	for (i = 0; i < MAX_DIRS; i++) {
		out->writeByte(_game.dirLogic[i].flags);
		out->writeSint16BE((int16)_game.logics[i].sIP);
		out->writeSint16BE((int16)_game.logics[i].cIP);
	}
	for (i = 0; i < MAX_DIRS; i++)
		out->writeByte(_game.dirPic[i].flags);
	for (i = 0; i < MAX_DIRS; i++)
		out->writeByte(_game.dirView[i].flags);
	for (i = 0; i < MAX_DIRS; i++)
		out->writeByte(_game.dirSound[i].flags);

	// game.pictures
	// game.logics
	// game.views
	// game.sounds

	for (i = 0; i < MAX_VIEWTABLE; i++) {
		VtEntry *v = &_game.viewTable[i];

		out->writeByte(v->stepTime);
		out->writeByte(v->stepTimeCount);
		out->writeByte(v->entry);
		out->writeSint16BE(v->xPos);
		out->writeSint16BE(v->yPos);
		out->writeByte(v->currentView);

		// v->view_data

		out->writeByte(v->currentLoop);
		out->writeByte(v->numLoops);

		// v->loop_data

		out->writeByte(v->currentCel);
		out->writeByte(v->numCels);

		// v->cel_data
		// v->cel_data_2

		out->writeSint16BE(v->xPos2);
		out->writeSint16BE(v->yPos2);

		// v->s

		out->writeSint16BE(v->xSize);
		out->writeSint16BE(v->ySize);
		out->writeByte(v->stepSize);
		out->writeByte(v->cycleTime);
		out->writeByte(v->cycleTimeCount);
		out->writeByte(v->direction);

		out->writeByte(v->motion);
		out->writeByte(v->cycle);
		out->writeByte(v->priority);

		out->writeUint16BE(v->flags);

		out->writeByte(v->parm1);
		out->writeByte(v->parm2);
		out->writeByte(v->parm3);
		out->writeByte(v->parm4);
	}

	// Save image stack

	for (i = 0; i < _imageStack.size(); i++) {
		ImageStackElement ise = _imageStack[i];
		out->writeByte(ise.type);
		out->writeSint16BE(ise.parm1);
		out->writeSint16BE(ise.parm2);
		out->writeSint16BE(ise.parm3);
		out->writeSint16BE(ise.parm4);
		out->writeSint16BE(ise.parm5);
		out->writeSint16BE(ise.parm6);
		out->writeSint16BE(ise.parm7);
	}
	out->writeByte(0);

	//Write which file number AGIPAL is using (0 if not being used)
	out->writeSint16BE(_gfx->getAGIPalFileNum());

	out->finalize();
	if (out->err()) {
		warning("Can't write file '%s'. (Disk full?)", fileName.c_str());
		result = errIOError;
	} else
		debugC(1, kDebugLevelMain | kDebugLevelSavegame, "Saved game %s in file %s", description.c_str(), fileName.c_str());

	delete out;
	debugC(3, kDebugLevelMain | kDebugLevelSavegame, "Closed %s", fileName.c_str());

	_lastSaveTime = _system->getMillis();

	return result;
}