aboutsummaryrefslogtreecommitdiff
path: root/engines/cine/various.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/cine/various.cpp')
-rw-r--r--engines/cine/various.cpp942
1 files changed, 0 insertions, 942 deletions
diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp
index 4d928456d4..3a826fab97 100644
--- a/engines/cine/various.cpp
+++ b/engines/cine/various.cpp
@@ -26,7 +26,6 @@
#include "common/endian.h"
#include "common/events.h"
-#include "common/savefile.h"
#include "cine/cine.h"
#include "cine/main_loop.h"
@@ -91,8 +90,6 @@ char currentCtName[15];
char currentPartName[15];
char currentDatName[30];
-int16 saveVar2;
-
byte isInPause = 0;
/*! \brief Values used by the xMoveKeyb variable */
@@ -116,7 +113,6 @@ uint16 yMoveKeyb = kKeybMoveCenterY;
SelectedObjStruct currentSelectedObject;
CommandeType currentSaveName[10];
-int16 currentDisk;
static const int16 choiceResultTable[] = { 1, 1, 1, 2, 1, 1, 1 };
static const int16 subObjectUseTable[] = { 3, 3, 3, 3, 3, 0, 0 };
@@ -276,347 +272,6 @@ int16 getObjectUnderCursor(uint16 x, uint16 y) {
return -1;
}
-bool writeChunkHeader(Common::OutSaveFile &out, const ChunkHeader &header) {
- out.writeUint32BE(header.id);
- out.writeUint32BE(header.version);
- out.writeUint32BE(header.size);
- return !out.ioFailed();
-}
-
-bool loadChunkHeader(Common::SeekableReadStream &in, ChunkHeader &header) {
- header.id = in.readUint32BE();
- header.version = in.readUint32BE();
- header.size = in.readUint32BE();
- return !in.ioFailed();
-}
-
-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(objectTable[i].x);
- out.writeUint16BE(objectTable[i].y);
- out.writeUint16BE(objectTable[i].mask);
- out.writeUint16BE(objectTable[i].frame);
- out.writeUint16BE(objectTable[i].costume);
- out.write(objectTable[i].name, 20);
- out.writeUint16BE(objectTable[i].part);
- }
-}
-
-void saveZoneData(Common::OutSaveFile &out) {
- for (int i = 0; i < 16; i++) {
- out.writeUint16BE(zoneData[i]);
- }
-}
-
-void saveCommandVariables(Common::OutSaveFile &out) {
- for (int i = 0; i < 4; i++) {
- out.writeUint16BE(commandVar3[i]);
- }
-}
-
-/*! \brief Save the 80 bytes long command buffer padded to that length with zeroes. */
-void saveCommandBuffer(Common::OutSaveFile &out) {
- // Let's make sure there's space for the trailing zero
- // (That's why we subtract one from the maximum command buffer size here).
- uint32 size = MIN<uint32>(commandBuffer.size(), kMaxCommandBufferSize - 1);
- out.write(commandBuffer.c_str(), size);
- // Write the rest as zeroes (Here we also write the string's trailing zero)
- for (uint i = 0; i < kMaxCommandBufferSize - size; i++) {
- out.writeByte(0);
- }
-}
-
-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++) {
- 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 saveGlobalScripts(Common::OutSaveFile &out) {
- ScriptList::const_iterator it;
- out.writeUint16BE(globalScripts.size());
- for (it = globalScripts.begin(); it != globalScripts.end(); ++it) {
- (*it)->save(out);
- }
-}
-
-void saveObjectScripts(Common::OutSaveFile &out) {
- ScriptList::const_iterator it;
- out.writeUint16BE(objectScripts.size());
- for (it = objectScripts.begin(); it != objectScripts.end(); ++it) {
- (*it)->save(out);
- }
-}
-
-void saveOverlayList(Common::OutSaveFile &out) {
- Common::List<overlay>::const_iterator it;
-
- out.writeUint16BE(overlayList.size());
-
- for (it = overlayList.begin(); it != 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 saveBgIncrustList(Common::OutSaveFile &out) {
- Common::List<BGIncrust>::const_iterator it;
- out.writeUint16BE(bgIncrustList.size());
-
- for (it = bgIncrustList.begin(); it != 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);
- }
-}
-
-void saveZoneQuery(Common::OutSaveFile &out) {
- for (int i = 0; i < 16; i++) {
- out.writeUint16BE(zoneQuery[i]);
- }
-}
-
-void saveSeqList(Common::OutSaveFile &out) {
- Common::List<SeqListElement>::const_iterator it;
- out.writeUint16BE(seqList.size());
-
- for (it = seqList.begin(); it != 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);
- }
-}
-
-bool CineEngine::loadSaveDirectory(void) {
- Common::InSaveFile *fHandle;
- char tmp[80];
-
- snprintf(tmp, 80, "%s.dir", _targetName.c_str());
- fHandle = g_saveFileMan->openForLoading(tmp);
-
- if (!fHandle) {
- return false;
- }
-
- fHandle->read(currentSaveName, 10 * 20);
- delete fHandle;
-
- return true;
-}
-
-/*! \brief Savegame format detector
- * \param fHandle Savefile to check
- * \return Savegame format on success, ANIMSIZE_UNKNOWN on failure
- *
- * This function seeks through the savefile and tries to determine the
- * savegame format it uses. There's a miniscule chance that the detection
- * algorithm could get confused and think that the file uses both the older
- * and the newer format but that is such a remote possibility that I wouldn't
- * worry about it at all.
- *
- * Also detects the temporary Operation Stealth savegame format now.
- */
-enum CineSaveGameFormat detectSaveGameFormat(Common::SeekableReadStream &fHandle) {
- const uint32 prevStreamPos = fHandle.pos();
-
- // First check for the temporary Operation Stealth savegame format.
- fHandle.seek(0);
- ChunkHeader hdr;
- loadChunkHeader(fHandle, hdr);
- fHandle.seek(prevStreamPos);
- if (hdr.id == TEMP_OS_FORMAT_ID) {
- return TEMP_OS_FORMAT;
- }
-
- // Ok, so the savegame isn't using the temporary Operation Stealth savegame format.
- // Let's check for the plain Future Wars savegame format and its different versions then.
- // The animDataTable begins at savefile position 0x2315.
- // Each animDataTable entry takes 23 bytes in older saves (Revisions 21772-31443)
- // and 30 bytes in the save format after that (Revision 31444 and onwards).
- // There are 255 entries in the animDataTable in both of the savefile formats.
- static const uint animDataTableStart = 0x2315;
- static const uint animEntriesCount = 255;
- static const uint oldAnimEntrySize = 23;
- static const uint newAnimEntrySize = 30;
- static const uint animEntrySizeChoices[] = {oldAnimEntrySize, newAnimEntrySize};
- Common::Array<uint> animEntrySizeMatches;
-
- // Try to walk through the savefile using different animDataTable entry sizes
- // and make a list of all the successful entry sizes.
- for (uint i = 0; i < ARRAYSIZE(animEntrySizeChoices); i++) {
- // 206 = 2 * 50 * 2 + 2 * 3 (Size of global and object script entries)
- // 20 = 4 * 2 + 2 * 6 (Size of overlay and background incrust entries)
- static const uint sizeofScreenParams = 2 * 6;
- static const uint globalScriptEntrySize = 206;
- static const uint objectScriptEntrySize = 206;
- static const uint overlayEntrySize = 20;
- static const uint bgIncrustEntrySize = 20;
- static const uint chainEntrySizes[] = {
- globalScriptEntrySize,
- objectScriptEntrySize,
- overlayEntrySize,
- bgIncrustEntrySize
- };
-
- uint animEntrySize = animEntrySizeChoices[i];
- // Jump over the animDataTable entries and the screen parameters
- int32 newPos = animDataTableStart + animEntrySize * animEntriesCount + sizeofScreenParams;
- // Check that there's data left after the point we're going to jump to
- if (newPos >= fHandle.size()) {
- continue;
- }
- fHandle.seek(newPos);
-
- // Jump over the remaining items in the savegame file
- // (i.e. the global scripts, object scripts, overlays and background incrusts).
- bool chainWalkSuccess = true;
- for (uint chainIndex = 0; chainIndex < ARRAYSIZE(chainEntrySizes); chainIndex++) {
- // Read entry count and jump over the entries
- int entryCount = fHandle.readSint16BE();
- newPos = fHandle.pos() + chainEntrySizes[chainIndex] * entryCount;
- // Check that we didn't go past the end of file.
- // Note that getting exactly to the end of file is acceptable.
- if (newPos > fHandle.size()) {
- chainWalkSuccess = false;
- break;
- }
- fHandle.seek(newPos);
- }
-
- // If we could walk the chain successfully and
- // got exactly to the end of file then we've got a match.
- if (chainWalkSuccess && fHandle.pos() == fHandle.size()) {
- // We found a match, let's save it
- animEntrySizeMatches.push_back(animEntrySize);
- }
- }
-
- // Check that we got only one entry size match.
- // If we didn't, then return an error.
- enum CineSaveGameFormat result = ANIMSIZE_UNKNOWN;
- if (animEntrySizeMatches.size() == 1) {
- const uint animEntrySize = animEntrySizeMatches[0];
- assert(animEntrySize == oldAnimEntrySize || animEntrySize == newAnimEntrySize);
- if (animEntrySize == oldAnimEntrySize) {
- result = ANIMSIZE_23;
- } else { // animEntrySize == newAnimEntrySize
- // Check data and mask pointers in all of the animDataTable entries
- // to see whether we've got the version with the broken data and mask pointers or not.
- // In the broken format all data and mask pointers were always zero.
- static const uint relativeDataPos = 2 * 4;
- bool pointersIntact = false;
- for (uint i = 0; i < animEntriesCount; i++) {
- fHandle.seek(animDataTableStart + i * animEntrySize + relativeDataPos);
- uint32 data = fHandle.readUint32BE();
- uint32 mask = fHandle.readUint32BE();
- if ((data != 0) || (mask != 0)) {
- pointersIntact = true;
- break;
- }
- }
- result = (pointersIntact ? ANIMSIZE_30_PTRS_INTACT : ANIMSIZE_30_PTRS_BROKEN);
- }
- } else if (animEntrySizeMatches.size() > 1) {
- warning("Savegame format detector got confused by input data. Detecting savegame to be using an unknown format");
- } else { // animEtrySizeMatches.size() == 0
- debug(3, "Savegame format detector was unable to detect savegame's format");
- }
-
- fHandle.seek(prevStreamPos);
- return result;
-}
-
-/*! \brief Restore script list item from savefile
- * \param fHandle Savefile handle open for reading
- * \param isGlobal Restore object or global script?
- */
-void loadScriptFromSave(Common::SeekableReadStream &fHandle, bool isGlobal) {
- ScriptVars localVars, labels;
- uint16 compare, pos;
- int16 idx;
-
- labels.load(fHandle);
- localVars.load(fHandle);
-
- compare = fHandle.readUint16BE();
- pos = fHandle.readUint16BE();
- idx = fHandle.readUint16BE();
-
- // no way to reinitialize these
- if (idx < 0) {
- return;
- }
-
- // original code loaded everything into globalScripts, this should be
- // the correct behavior
- if (isGlobal) {
- ScriptPtr tmp(scriptInfo->create(*scriptTable[idx], idx, labels, localVars, compare, pos));
- assert(tmp);
- globalScripts.push_back(tmp);
- } else {
- ScriptPtr tmp(scriptInfo->create(*relTable[idx], idx, labels, localVars, compare, pos));
- assert(tmp);
- objectScripts.push_back(tmp);
- }
-}
-
-/*! \brief Restore overlay sprites from savefile
- * \param fHandle Savefile open for reading
- */
-void loadOverlayFromSave(Common::SeekableReadStream &fHandle) {
- overlay tmp;
-
- fHandle.readUint32BE();
- fHandle.readUint32BE();
-
- tmp.objIdx = fHandle.readUint16BE();
- tmp.type = fHandle.readUint16BE();
- tmp.x = fHandle.readSint16BE();
- tmp.y = fHandle.readSint16BE();
- tmp.width = fHandle.readSint16BE();
- tmp.color = fHandle.readSint16BE();
-
- overlayList.push_back(tmp);
-}
-
void CineEngine::resetEngine() {
g_sound->stopMusic();
freeAnimDataTable();
@@ -668,520 +323,6 @@ void CineEngine::resetEngine() {
}
}
-bool loadObjectTable(Common::SeekableReadStream &in) {
- in.readUint16BE(); // Entry count
- in.readUint16BE(); // Entry size
-
- for (int i = 0; i < NUM_MAX_OBJECT; i++) {
- objectTable[i].x = in.readSint16BE();
- objectTable[i].y = in.readSint16BE();
- objectTable[i].mask = in.readUint16BE();
- objectTable[i].frame = in.readSint16BE();
- objectTable[i].costume = in.readSint16BE();
- in.read(objectTable[i].name, 20);
- objectTable[i].part = in.readUint16BE();
- }
- return !in.ioFailed();
-}
-
-bool loadZoneData(Common::SeekableReadStream &in) {
- for (int i = 0; i < 16; i++) {
- zoneData[i] = in.readUint16BE();
- }
- return !in.ioFailed();
-}
-
-bool loadCommandVariables(Common::SeekableReadStream &in) {
- for (int i = 0; i < 4; i++) {
- commandVar3[i] = in.readUint16BE();
- }
- return !in.ioFailed();
-}
-
-bool loadScreenParams(Common::SeekableReadStream &in) {
- // TODO: handle screen params (really required ?)
- in.readUint16BE();
- in.readUint16BE();
- in.readUint16BE();
- in.readUint16BE();
- in.readUint16BE();
- in.readUint16BE();
- return !in.ioFailed();
-}
-
-bool loadGlobalScripts(Common::SeekableReadStream &in) {
- int size = in.readSint16BE();
- for (int i = 0; i < size; i++) {
- loadScriptFromSave(in, true);
- }
- return !in.ioFailed();
-}
-
-bool loadObjectScripts(Common::SeekableReadStream &in) {
- int size = in.readSint16BE();
- for (int i = 0; i < size; i++) {
- loadScriptFromSave(in, false);
- }
- return !in.ioFailed();
-}
-
-bool loadOverlayList(Common::SeekableReadStream &in) {
- int size = in.readSint16BE();
- for (int i = 0; i < size; i++) {
- loadOverlayFromSave(in);
- }
- return !in.ioFailed();
-}
-
-bool loadSeqList(Common::SeekableReadStream &in) {
- uint size = in.readUint16BE();
- SeqListElement tmp;
- for (uint i = 0; i < size; i++) {
- tmp.var4 = in.readSint16BE();
- tmp.objIdx = in.readUint16BE();
- tmp.var8 = in.readSint16BE();
- tmp.frame = in.readSint16BE();
- tmp.varC = in.readSint16BE();
- tmp.varE = in.readSint16BE();
- tmp.var10 = in.readSint16BE();
- tmp.var12 = in.readSint16BE();
- tmp.var14 = in.readSint16BE();
- tmp.var16 = in.readSint16BE();
- tmp.var18 = in.readSint16BE();
- tmp.var1A = in.readSint16BE();
- tmp.var1C = in.readSint16BE();
- tmp.var1E = in.readSint16BE();
- seqList.push_back(tmp);
- }
- return !in.ioFailed();
-}
-
-bool loadZoneQuery(Common::SeekableReadStream &in) {
- for (int i = 0; i < 16; i++) {
- zoneQuery[i] = in.readUint16BE();
- }
- return !in.ioFailed();
-}
-
-bool CineEngine::loadTempSaveOS(Common::SeekableReadStream &in) {
- char musicName[13];
- char bgNames[8][13];
-
- // First check the temporary Operation Stealth savegame format header.
- ChunkHeader hdr;
- loadChunkHeader(in, hdr);
- if (hdr.id != TEMP_OS_FORMAT_ID) {
- warning("loadTempSaveOS: File has incorrect identifier. Not loading savegame");
- return false;
- } else if (hdr.version > CURRENT_OS_SAVE_VER) {
- warning("loadTempSaveOS: Detected newer format version. Not loading savegame");
- return false;
- } else if ((int)hdr.version < (int)CURRENT_OS_SAVE_VER) {
- warning("loadTempSaveOS: Detected older format version. Trying to load nonetheless. Things may break");
- } else { // hdr.id == TEMP_OS_FORMAT_ID && hdr.version == CURRENT_OS_SAVE_VER
- debug(3, "loadTempSaveOS: Found correct header (Both the identifier and version number match).");
- }
-
- // There shouldn't be any data in the header's chunk currently so it's an error if there is.
- if (hdr.size > 0) {
- warning("loadTempSaveOS: Format header's chunk seems to contain data so format is incorrect. Not loading savegame");
- return false;
- }
-
- // Ok, so we've got a correct header for a temporary Operation Stealth savegame.
- // Let's start loading the plain savegame data then.
- currentDisk = in.readUint16BE();
- in.read(currentPartName, 13);
- in.read(currentPrcName, 13);
- in.read(currentRelName, 13);
- in.read(currentMsgName, 13);
-
- // Load the 8 background names.
- for (uint i = 0; i < 8; i++) {
- in.read(bgNames[i], 13);
- }
-
- in.read(currentCtName, 13);
-
- // Moved the loading of current procedure, relation,
- // backgrounds and Ct here because if they were at the
- // end of this function then the global scripts loading
- // made an array out of bounds access. In the original
- // game's disassembly these aren't here but at the end.
- // The difference is probably in how we handle loading
- // the global scripts and some other things (i.e. the
- // loading routines aren't exactly the same and subtle
- // semantic differences result in having to do things
- // in a different order).
- {
- // Not sure if this is needed with Operation Stealth...
- checkDataDisk(currentDisk);
-
- if (strlen(currentPrcName)) {
- loadPrc(currentPrcName);
- }
-
- if (strlen(currentRelName)) {
- loadRel(currentRelName);
- }
-
- // Load first background (Uses loadBg)
- if (strlen(bgNames[0])) {
- loadBg(bgNames[0]);
- }
-
- // Add backgrounds 1-7 (Uses addBackground)
- for (int i = 1; i < 8; i++) {
- if (strlen(bgNames[i])) {
- addBackground(bgNames[i], i);
- }
- }
-
- if (strlen(currentCtName)) {
- loadCtOS(currentCtName);
- }
- }
-
- loadObjectTable(in);
- renderer->restorePalette(in);
- globalVars.load(in, NUM_MAX_VAR);
- loadZoneData(in);
- loadCommandVariables(in);
- char tempCommandBuffer[kMaxCommandBufferSize];
- in.read(tempCommandBuffer, kMaxCommandBufferSize);
- commandBuffer = tempCommandBuffer;
- renderer->setCommand(commandBuffer);
- loadZoneQuery(in);
-
- // TODO: Use the loaded string (Current music name (String, 13 bytes)).
- in.read(musicName, 13);
-
- // TODO: Use the loaded value (Is music loaded? (Uint16BE, Boolean)).
- in.readUint16BE();
-
- // TODO: Use the loaded value (Is music playing? (Uint16BE, Boolean)).
- in.readUint16BE();
-
- renderer->_cmdY = in.readUint16BE();
- in.readUint16BE(); // Some unknown variable that seems to always be zero
- allowPlayerInput = in.readUint16BE();
- playerCommand = in.readUint16BE();
- commandVar1 = in.readUint16BE();
- isDrawCommandEnabled = in.readUint16BE();
- var5 = in.readUint16BE();
- var4 = in.readUint16BE();
- var3 = in.readUint16BE();
- var2 = in.readUint16BE();
- commandVar2 = in.readUint16BE();
- renderer->_messageBg = in.readUint16BE();
-
- // TODO: Use the loaded value (adBgVar1 (Uint16BE)).
- in.readUint16BE();
-
- currentAdditionalBgIdx = in.readSint16BE();
- currentAdditionalBgIdx2 = in.readSint16BE();
-
- // TODO: Check whether the scroll value really gets used correctly after this.
- // Note that the backgrounds are loaded only later than this value is set.
- renderer->setScroll(in.readUint16BE());
-
- // TODO: Use the loaded value (adBgVar0 (Uint16BE). Maybe this means bgVar0?).
- in.readUint16BE();
-
- disableSystemMenu = in.readUint16BE();
-
- // TODO: adBgVar1 = 1 here
-
- // Load the animDataTable entries
- in.readUint16BE(); // Entry count (255 in the PC version of Operation Stealth).
- in.readUint16BE(); // Entry size (36 in the PC version of Operation Stealth).
- loadResourcesFromSave(in, ANIMSIZE_30_PTRS_INTACT);
-
- loadScreenParams(in);
- loadGlobalScripts(in);
- loadObjectScripts(in);
- loadSeqList(in);
- loadOverlayList(in);
- loadBgIncrustFromSave(in);
-
- // Left this here instead of moving it earlier in this function with
- // the other current value loadings (e.g. loading of current procedure,
- // current backgrounds etc). Mostly emulating the way we've handled
- // Future Wars savegames and hoping that things work out.
- if (strlen(currentMsgName)) {
- loadMsg(currentMsgName);
- }
-
- // TODO: Add current music loading and playing here
- // TODO: Palette handling?
-
- if (in.pos() == in.size()) {
- debug(3, "loadTempSaveOS: Loaded the whole savefile.");
- } else {
- warning("loadTempSaveOS: Loaded the savefile but didn't exhaust it completely. Something was left over");
- }
-
- return !in.ioFailed();
-}
-
-bool CineEngine::loadPlainSaveFW(Common::SeekableReadStream &in, CineSaveGameFormat saveGameFormat) {
- char bgName[13];
-
- // At savefile position 0x0000:
- currentDisk = in.readUint16BE();
-
- // At 0x0002:
- in.read(currentPartName, 13);
- // At 0x000F:
- in.read(currentDatName, 13);
-
- // At 0x001C:
- saveVar2 = in.readSint16BE();
-
- // At 0x001E:
- in.read(currentPrcName, 13);
- // At 0x002B:
- in.read(currentRelName, 13);
- // At 0x0038:
- in.read(currentMsgName, 13);
- // At 0x0045:
- in.read(bgName, 13);
- // At 0x0052:
- in.read(currentCtName, 13);
-
- checkDataDisk(currentDisk);
-
- if (strlen(currentPartName)) {
- loadPart(currentPartName);
- }
-
- if (strlen(currentPrcName)) {
- loadPrc(currentPrcName);
- }
-
- if (strlen(currentRelName)) {
- loadRel(currentRelName);
- }
-
- if (strlen(bgName)) {
- loadBg(bgName);
- }
-
- if (strlen(currentCtName)) {
- loadCtFW(currentCtName);
- }
-
- // At 0x005F:
- loadObjectTable(in);
-
- // At 0x2043 (i.e. 0x005F + 2 * 2 + 255 * 32):
- renderer->restorePalette(in);
-
- // At 0x2083 (i.e. 0x2043 + 16 * 2 * 2):
- globalVars.load(in, NUM_MAX_VAR);
-
- // At 0x2281 (i.e. 0x2083 + 255 * 2):
- loadZoneData(in);
-
- // At 0x22A1 (i.e. 0x2281 + 16 * 2):
- loadCommandVariables(in);
-
- // At 0x22A9 (i.e. 0x22A1 + 4 * 2):
- char tempCommandBuffer[kMaxCommandBufferSize];
- in.read(tempCommandBuffer, kMaxCommandBufferSize);
- commandBuffer = tempCommandBuffer;
- renderer->setCommand(commandBuffer);
-
- // At 0x22F9 (i.e. 0x22A9 + 0x50):
- renderer->_cmdY = in.readUint16BE();
-
- // At 0x22FB:
- bgVar0 = in.readUint16BE();
- // At 0x22FD:
- allowPlayerInput = in.readUint16BE();
- // At 0x22FF:
- playerCommand = in.readSint16BE();
- // At 0x2301:
- commandVar1 = in.readSint16BE();
- // At 0x2303:
- isDrawCommandEnabled = in.readUint16BE();
- // At 0x2305:
- var5 = in.readUint16BE();
- // At 0x2307:
- var4 = in.readUint16BE();
- // At 0x2309:
- var3 = in.readUint16BE();
- // At 0x230B:
- var2 = in.readUint16BE();
- // At 0x230D:
- commandVar2 = in.readSint16BE();
-
- // At 0x230F:
- renderer->_messageBg = in.readUint16BE();
-
- // At 0x2311:
- in.readUint16BE();
- // At 0x2313:
- in.readUint16BE();
-
- // At 0x2315:
- loadResourcesFromSave(in, saveGameFormat);
-
- loadScreenParams(in);
- loadGlobalScripts(in);
- loadObjectScripts(in);
- loadOverlayList(in);
- loadBgIncrustFromSave(in);
-
- if (strlen(currentMsgName)) {
- loadMsg(currentMsgName);
- }
-
- if (strlen(currentDatName)) {
-/* i = saveVar2;
- saveVar2 = 0;
- loadMusic();
- if (i) {
- playMusic();
- }*/
- }
-
- return !in.ioFailed();
-}
-
-bool CineEngine::makeLoad(char *saveName) {
- Common::SharedPtr<Common::InSaveFile> saveFile(g_saveFileMan->openForLoading(saveName));
-
- if (!saveFile) {
- drawString(otherMessages[0], 0);
- waitPlayerInput();
- // restoreScreen();
- checkDataDisk(-1);
- return false;
- }
-
- setMouseCursor(MOUSE_CURSOR_DISK);
-
- uint32 saveSize = saveFile->size();
- // TODO: Evaluate the maximum savegame size for the temporary Operation Stealth savegame format.
- if (saveSize == 0) { // Savefile's compressed using zlib format can't tell their unpacked size, test for it
- // Can't get information about the savefile's size so let's try
- // reading as much as we can from the file up to a predefined upper limit.
- //
- // Some estimates for maximum savefile sizes (All with 255 animDataTable entries of 30 bytes each):
- // With 256 global scripts, object scripts, overlays and background incrusts:
- // 0x2315 + (255 * 30) + (2 * 6) + (206 + 206 + 20 + 20) * 256 = ~129kB
- // With 512 global scripts, object scripts, overlays and background incrusts:
- // 0x2315 + (255 * 30) + (2 * 6) + (206 + 206 + 20 + 20) * 512 = ~242kB
- //
- // I think it extremely unlikely that there would be over 512 global scripts, object scripts,
- // overlays and background incrusts so 256kB seems like quite a safe upper limit.
- // NOTE: If the savegame format is changed then this value might have to be re-evaluated!
- // Hopefully devices with more limited memory can also cope with this memory allocation.
- saveSize = 256 * 1024;
- }
- Common::SharedPtr<Common::MemoryReadStream> in(saveFile->readStream(saveSize));
-
- // Try to detect the used savegame format
- enum CineSaveGameFormat saveGameFormat = detectSaveGameFormat(*in);
-
- // Handle problematic savegame formats
- bool load = true; // Should we try to load the savegame?
- bool result = false;
- if (saveGameFormat == ANIMSIZE_30_PTRS_BROKEN) {
- // One might be able to load the ANIMSIZE_30_PTRS_BROKEN format but
- // that's not implemented here because it was never used in a stable
- // release of ScummVM but only during development (From revision 31453,
- // which introduced the problem, until revision 32073, which fixed it).
- // Therefore we bail out if we detect this particular savegame format.
- warning("Detected a known broken savegame format, not loading savegame");
- load = false; // Don't load the savegame
- } else if (saveGameFormat == ANIMSIZE_UNKNOWN) {
- // If we can't detect the savegame format
- // then let's try the default format and hope for the best.
- warning("Couldn't detect the used savegame format, trying default savegame format. Things may break");
- saveGameFormat = ANIMSIZE_30_PTRS_INTACT;
- }
-
- if (load) {
- // Reset the engine's state
- resetEngine();
-
- if (saveGameFormat == TEMP_OS_FORMAT) {
- // Load the temporary Operation Stealth savegame format
- result = loadTempSaveOS(*in);
- } else {
- // Load the plain Future Wars savegame format
- result = loadPlainSaveFW(*in, saveGameFormat);
- }
- }
-
- setMouseCursor(MOUSE_CURSOR_NORMAL);
-
- return result;
-}
-
-void CineEngine::makeSaveFW(Common::OutSaveFile &out) {
- out.writeUint16BE(currentDisk);
- out.write(currentPartName, 13);
- out.write(currentDatName, 13);
- out.writeUint16BE(saveVar2);
- out.write(currentPrcName, 13);
- out.write(currentRelName, 13);
- out.write(currentMsgName, 13);
- renderer->saveBgNames(out);
- out.write(currentCtName, 13);
-
- saveObjectTable(out);
- renderer->savePalette(out);
- 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 CineEngine::makeSave(char *saveFileName) {
- Common::SharedPtr<Common::OutSaveFile> fHandle(g_saveFileMan->openForSaving(saveFileName));
-
- setMouseCursor(MOUSE_CURSOR_DISK);
-
- if (!fHandle) {
- drawString(otherMessages[1], 0);
- waitPlayerInput();
- // restoreScreen();
- checkDataDisk(-1);
- } else {
- if (g_cine->getGameType() == GType_FW) {
- makeSaveFW(*fHandle);
- } else {
- makeSaveOS(*fHandle);
- }
- }
-
- setMouseCursor(MOUSE_CURSOR_NORMAL);
-}
-
void CineEngine::makeSystemMenu(void) {
int16 numEntry, systemCommand;
int16 mouseX, mouseY, mouseButton;
@@ -1319,89 +460,6 @@ void CineEngine::makeSystemMenu(void) {
}
}
-/**
- * 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);
- 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 drawMessageBox(int16 x, int16 y, int16 width, int16 currentY, int16 offset, int16 color, byte* page) {
gfxDrawLine(x + offset, y + offset, x + width - offset, y + offset, color, page); // top
gfxDrawLine(x + offset, currentY + 4 - offset, x + width - offset, currentY + 4 - offset, color, page); // bottom