void saveAnimDataTable(Common::OutSaveFile &out) { out.writeUint16BE(NUM_MAX_ANIMDATA); // Entry count out.writeUint16BE(0x1E); // Entry size for (int i = 0; i < NUM_MAX_ANIMDATA; i++) { g_cine->_animDataTable[i].save(out); } }
void saveScreenParams(Common::OutSaveFile &out) { // Screen parameters, unhandled out.writeUint16BE(0); out.writeUint16BE(0); out.writeUint16BE(0); out.writeUint16BE(0); out.writeUint16BE(0); out.writeUint16BE(0); }
void saveObjectScripts(Common::OutSaveFile &out) { ScriptList::const_iterator it; out.writeUint16BE(g_cine->_objectScripts.size()); for (it = g_cine->_objectScripts.begin(); it != g_cine->_objectScripts.end(); ++it) { (*it)->save(out); } }
void saveOverlayList(Common::OutSaveFile &out) { Common::List<overlay>::const_iterator it; out.writeUint16BE(g_cine->_overlayList.size()); for (it = g_cine->_overlayList.begin(); it != g_cine->_overlayList.end(); ++it) { out.writeUint32BE(0); // next out.writeUint32BE(0); // previous? out.writeUint16BE(it->objIdx); out.writeUint16BE(it->type); out.writeSint16BE(it->x); out.writeSint16BE(it->y); out.writeSint16BE(it->width); out.writeSint16BE(it->color); } }
void saveSeqList(Common::OutSaveFile &out) { Common::List<SeqListElement>::const_iterator it; out.writeUint16BE(g_cine->_seqList.size()); for (it = g_cine->_seqList.begin(); it != g_cine->_seqList.end(); ++it) { out.writeSint16BE(it->var4); out.writeUint16BE(it->objIdx); out.writeSint16BE(it->var8); out.writeSint16BE(it->frame); out.writeSint16BE(it->varC); out.writeSint16BE(it->varE); out.writeSint16BE(it->var10); out.writeSint16BE(it->var12); out.writeSint16BE(it->var14); out.writeSint16BE(it->var16); out.writeSint16BE(it->var18); out.writeSint16BE(it->var1A); out.writeSint16BE(it->var1C); out.writeSint16BE(it->var1E); } }
void saveObjectTable(Common::OutSaveFile &out) { out.writeUint16BE(NUM_MAX_OBJECT); // Entry count out.writeUint16BE(0x20); // Entry size for (int i = 0; i < NUM_MAX_OBJECT; i++) { out.writeUint16BE(g_cine->_objectTable[i].x); out.writeUint16BE(g_cine->_objectTable[i].y); out.writeUint16BE(g_cine->_objectTable[i].mask); out.writeUint16BE(g_cine->_objectTable[i].frame); out.writeUint16BE(g_cine->_objectTable[i].costume); out.write(g_cine->_objectTable[i].name, 20); out.writeUint16BE(g_cine->_objectTable[i].part); } }
void saveBgIncrustList(Common::OutSaveFile &out) { Common::List<BGIncrust>::const_iterator it; out.writeUint16BE(g_cine->_bgIncrustList.size()); for (it = g_cine->_bgIncrustList.begin(); it != g_cine->_bgIncrustList.end(); ++it) { out.writeUint32BE(0); // next out.writeUint32BE(0); // previous? out.writeUint16BE(it->objIdx); out.writeUint16BE(it->param); out.writeUint16BE(it->x); out.writeUint16BE(it->y); out.writeUint16BE(it->frame); out.writeUint16BE(it->part); } }
/** * 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); }
void CineEngine::makeSaveFW(Common::OutSaveFile &out) { out.writeUint16BE(currentDisk); out.write(currentPartName, 13); out.write(currentDatName, 13); out.writeUint16BE(musicIsPlaying); 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); out.writeUint16BE(renderer->_cmdY); out.writeUint16BE(bgVar0); 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); saveAnimDataTable(out); saveScreenParams(out); saveGlobalScripts(out); saveObjectScripts(out); saveOverlayList(out); saveBgIncrustList(out); }
void saveZoneQuery(Common::OutSaveFile &out) { for (int i = 0; i < 16; i++) { out.writeUint16BE(g_cine->_zoneQuery[i]); } }
bool DMEngine::writeCompleteSaveFile(int16 saveSlot, Common::String& saveDescription, int16 saveAndPlayChoice) { Common::String savefileName = getSavefileName(saveSlot); Common::SaveFileManager *saveFileManager = _system->getSavefileManager(); Common::OutSaveFile *file = saveFileManager->openForSaving(savefileName); if (!file) return false; writeSaveGameHeader(file, saveDescription); file->writeSint32BE(_gameVersion->_saveTargetToWrite); file->writeSint32BE(1); // save version file->writeSint32BE(_gameVersion->_origSaveFormatToWrite); file->writeSint32BE(_gameVersion->_origPlatformToWrite); // Was _gameID, useless. file->writeSint32BE(0); file->writeUint16BE(_dungeonId); // write C0_SAVE_PART_GLOBAL_DATA part file->writeSint32BE(_gameTime); //L1348_s_GlobalData.LastRandomNumber = G0349_ul_LastRandomNumber; file->writeUint16BE(_championMan->_partyChampionCount); file->writeSint16BE(_dungeonMan->_partyMapX); file->writeSint16BE(_dungeonMan->_partyMapY); file->writeUint16BE(_dungeonMan->_partyDir); file->writeByte(_dungeonMan->_partyMapIndex); file->writeSint16BE(_championMan->_leaderIndex); file->writeSint16BE(_championMan->_magicCasterChampionIndex); file->writeUint16BE(_timeline->_eventCount); file->writeUint16BE(_timeline->_firstUnusedEventIndex); file->writeUint16BE(_timeline->_eventMaxCount); file->writeUint16BE(_groupMan->_currActiveGroupCount); file->writeSint32BE(_projexpl->_lastCreatureAttackTime); file->writeSint32BE(_projexpl->_lastPartyMovementTime); file->writeSint16BE(_disabledMovementTicks); file->writeSint16BE(_projectileDisableMovementTicks); file->writeSint16BE(_lastProjectileDisabledMovementDirection); file->writeUint16BE(_championMan->_leaderHandObject.toUint16()); file->writeUint16BE(_groupMan->_maxActiveGroupCount); // write C1_SAVE_PART_ACTIVE_GROUP part _groupMan->saveActiveGroupPart(file); // write C2_SAVE_PART_PARTY part _championMan->savePartyPart2(file); // write C3_SAVE_PART_EVENTS part _timeline->saveEventsPart(file); // write C4_SAVE_PART_TIMELINE part _timeline->saveTimelinePart(file); // write sentinel file->writeUint32BE(0x6f85e3d3); // save _g278_dungeonFileHeader DungeonFileHeader &header = _dungeonMan->_dungeonFileHeader; file->writeUint16BE(header._ornamentRandomSeed); file->writeUint16BE(header._rawMapDataSize); file->writeByte(header._mapCount); file->writeByte(0); // to match the structure of dungeon.dat, will be discarded file->writeUint16BE(header._textDataWordCount); file->writeUint16BE(header._partyStartLocation); file->writeUint16BE(header._squareFirstThingCount); for (uint16 i = 0; i < 16; ++i) file->writeUint16BE(header._thingCounts[i]); // save _g277_dungeonMaps for (uint16 i = 0; i < _dungeonMan->_dungeonFileHeader._mapCount; ++i) { Map &map = _dungeonMan->_dungeonMaps[i]; file->writeUint16BE(map._rawDunDataOffset); file->writeUint32BE(0); // to match the structure of dungeon.dat, will be discarded file->writeByte(map._offsetMapX); file->writeByte(map._offsetMapY); uint16 tmp; tmp = ((map._height & 0x1F) << 11) | ((map._width & 0x1F) << 6) | (map._level & 0x3F); file->writeUint16BE(tmp); tmp = ((map._randFloorOrnCount & 0xF) << 12) | ((map._floorOrnCount & 0xF) << 8) | ((map._randWallOrnCount & 0xF) << 4) | (map._wallOrnCount & 0xF); file->writeUint16BE(tmp); tmp = ((map._difficulty & 0xF) << 12) | ((map._creatureTypeCount & 0xF) << 4) | (map._doorOrnCount & 0xF); file->writeUint16BE(tmp); tmp = ((map._doorSet1 & 0xF) << 12) | ((map._doorSet0 & 0xF) << 8) | ((map._wallSet & 0xF) << 4) | (map._floorSet & 0xF); file->writeUint16BE(tmp); } // save _g280_dungeonColumnsCumulativeSquareThingCount for (uint16 i = 0; i < _dungeonMan->_dungeonColumCount; ++i) file->writeUint16BE(_dungeonMan->_dungeonColumnsCumulativeSquareThingCount[i]); // save _g283_squareFirstThings for (uint16 i = 0; i < _dungeonMan->_dungeonFileHeader._squareFirstThingCount; ++i) file->writeUint16BE(_dungeonMan->_squareFirstThings[i].toUint16()); // save _g260_dungeonTextData for (uint16 i = 0; i < _dungeonMan->_dungeonFileHeader._textDataWordCount; ++i) file->writeUint16BE(_dungeonMan->_dungeonTextData[i]); // save _g284_thingData for (uint16 thingIndex = 0; thingIndex < 16; ++thingIndex) for (uint16 i = 0; i < _dungeonMan->_thingDataWordCount[thingIndex] * _dungeonMan->_dungeonFileHeader._thingCounts[thingIndex]; ++i) file->writeUint16BE(_dungeonMan->_thingData[thingIndex][i]); // save _g276_dungeonRawMapData for (uint32 i = 0; i < _dungeonMan->_dungeonFileHeader._rawMapDataSize; ++i) file->writeByte(_dungeonMan->_dungeonRawMapData[i]); file->flush(); file->finalize(); delete file; return true; }
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; }
void saveCommandVariables(Common::OutSaveFile &out) { for (int i = 0; i < 4; i++) { out.writeUint16BE(commandVar3[i]); } }
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(); }
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; }
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; }
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; }
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; }
/** * 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; }
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; }