Logo Search packages:      
Sourcecode: scummvm version File versions

saveload.cpp

/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-0-13-0/engines/cruise/saveload.cpp $
 * $Id: saveload.cpp 35870 2009-01-16 02:43:41Z fingolfin $
 *
 */

#include "cruise/cruise_main.h"

#include "common/savefile.h"
#include "common/system.h"

namespace Cruise {

struct overlayRestoreTemporary {
      int _sBssSize;
      uint8* _pBss;
      int _sNumObj;
      objectParams* _pObj;
};

overlayRestoreTemporary ovlRestoreData[90];

void resetPreload() {
      for (unsigned long int i = 0; i < 64; i++) {
            if (strlen(preloadData[i].name)) {
                  if (preloadData[i].ptr) {
                        free(preloadData[i].ptr);
                        preloadData[i].ptr = NULL;
                  }
                  strcpy(preloadData[i].name, "");
                  preloadData[i].nofree = 0;
            }
      }
}

void unloadOverlay(const char*name, int overlayNumber) {
      releaseOverlay(name);

      strcpy(overlayTable[overlayNumber].overlayName, "");
      overlayTable[overlayNumber].ovlData = NULL;
      overlayTable[overlayNumber].alreadyLoaded = 0;
}

void initVars(void) {
      closeAllMenu();
      resetFileEntryRange(0, 257);

      resetPreload();
      freeCTP();

      freezeCell(&cellHead, -1, -1, -1, -1, -1, 0);
      // TODO: unfreeze anims

      freeObjectList(&cellHead);
      removeAnimation(&actorHead, -1, -1, -1);

      changeScriptParamInList(-1, -1, &procHead, -1, 0);
      removeFinishedScripts(&procHead);

      changeScriptParamInList(-1, -1, &relHead, -1, 0);
      removeFinishedScripts(&relHead);

      for (unsigned long int i = 0; i < 90; i++) {
            if (strlen(overlayTable[i].overlayName) && overlayTable[i].alreadyLoaded) {
                  unloadOverlay(overlayTable[i].overlayName, i);
            }
      }

      // TODO:
      // stopSound();
      // removeSound();

      closeBase();
      closeCnf();

      initOverlayTable();

      stateID = 0;
      masterScreen = 0;

      freeDisk();

      initVar5[0] = -1;
      initVar5[3] = -1;
      initVar5[6] = -1;
      initVar5[9] = -1;

      for (unsigned long int i = 0; i < 8; i++) {
            menuTable[i] = NULL;
      }

      for (unsigned long int i = 0; i < 2000; i++) {
            globalVars[i] = 0;
      }

      for (unsigned long int i = 0; i < 8; i++) {
            backgroundTable[i].name[0] = 0;
      }

      for (unsigned long int i = 0; i < 257; i++) {
            filesDatabase[i].subData.ptr = NULL;
            filesDatabase[i].subData.ptrMask = NULL;
      }

      initBigVar3();

      resetPtr2(&procHead);
      resetPtr2(&relHead);

      resetPtr(&cellHead);

      resetActorPtr(&actorHead);
      resetBackgroundIncrustList(&backgroundIncrustHead);

      vblLimit = 0;
      remdo = 0;
      songLoaded = 0;
      songPlayed = 0;
      songLoop = 1;
      activeMouse = 0;
      userEnabled = 1;
      dialogueEnabled = 0;
      dialogueOvl = 0;
      dialogueObj = 0;
      userDelay = 0;
      sysKey = -1;
      sysX = 0;
      sysY = 0;
      automoveInc = 0;
      automoveMax = 0;
      displayOn = true;

      // here used to init clip

      isMessage = 0;
      fadeFlag = 0;
      playMusic = 0;
      playMusic2 = 0;
      automaticMode = 0;

      // video param (vga and mcga mode)

      titleColor = 2;
      itemColor = 1;
      selectColor = 3;
      subColor = 5;

      //

      narratorOvl = 0;
      narratorIdx = 0;
      aniX = 0;
      aniY = 0;
      animationStart = false;
      selectDown = 0;
      menuDown = 0;
      buttonDown = 0;
      var41 = 0;
      entrerMenuJoueur = 0;
      PCFadeFlag = 0;
}

void saveOverlay(Common::OutSaveFile& currentSaveFile) {

      for (int i = 1; i < numOfLoadedOverlay; i++) {
            if (overlayTable[i].alreadyLoaded) {

                  ovlDataStruct* ovlData = overlayTable[i].ovlData;

                  // save BSS
                  currentSaveFile.writeSint16LE(ovlData->sizeOfData4);
                  if (ovlData->sizeOfData4)
                        currentSaveFile.write(ovlData->data4Ptr, ovlData->sizeOfData4);

                  // save variables
                  currentSaveFile.writeSint16LE(ovlData->size9);
                  for (int j = 0; j < ovlData->size9; j++) {
                        currentSaveFile.writeSint16LE(ovlData->arrayObjVar[j].X);
                        currentSaveFile.writeSint16LE(ovlData->arrayObjVar[j].Y);
                        currentSaveFile.writeSint16LE(ovlData->arrayObjVar[j].Z);
                        currentSaveFile.writeSint16LE(ovlData->arrayObjVar[j].frame);
                        currentSaveFile.writeSint16LE(ovlData->arrayObjVar[j].scale);
                        currentSaveFile.writeSint16LE(ovlData->arrayObjVar[j].state);
                  }
            }
      }
}

void loadSavegameDataSub1(Common::InSaveFile& currentSaveFile) {

      for (int i = 1; i < numOfLoadedOverlay; i++) {
            ovlRestoreData[i]._sBssSize = ovlRestoreData[i]._sNumObj = 0;
            ovlRestoreData[i]._pBss = NULL;
            ovlRestoreData[i]._pObj = NULL;

            if (overlayTable[i].alreadyLoaded) {
                  ovlRestoreData[i]._sBssSize = currentSaveFile.readSint16LE();

                  if (ovlRestoreData[i]._sBssSize) {
                        ovlRestoreData[i]._pBss = (uint8 *) mallocAndZero(ovlRestoreData[i]._sBssSize);
                        ASSERT(ovlRestoreData[i]._pBss);

                        currentSaveFile.read(ovlRestoreData[i]._pBss, ovlRestoreData[i]._sBssSize);
                  }

                  ovlRestoreData[i]._sNumObj = currentSaveFile.readSint16LE();

                  if (ovlRestoreData[i]._sNumObj) {
                        ovlRestoreData[i]._pObj = (objectParams *) mallocAndZero(ovlRestoreData[i]._sNumObj * sizeof(objectParams));
                        ASSERT(ovlRestoreData[i]._pObj);

                        for (int j = 0; j < ovlRestoreData[i]._sNumObj; j++) {
                              ovlRestoreData[i]._pObj[j].X = currentSaveFile.readSint16LE();
                              ovlRestoreData[i]._pObj[j].Y = currentSaveFile.readSint16LE();
                              ovlRestoreData[i]._pObj[j].Z = currentSaveFile.readSint16LE();
                              ovlRestoreData[i]._pObj[j].frame = currentSaveFile.readSint16LE();
                              ovlRestoreData[i]._pObj[j].scale = currentSaveFile.readSint16LE();
                              ovlRestoreData[i]._pObj[j].state = currentSaveFile.readSint16LE();
                        }
                  }
            }
      }
}

void saveScript(Common::OutSaveFile& currentSaveFile, scriptInstanceStruct *entry) {
      int count = 0;

      scriptInstanceStruct* pCurrent = entry->nextScriptPtr;
      while (pCurrent) {
            count ++;
            pCurrent = pCurrent->nextScriptPtr;
      }

      currentSaveFile.writeSint16LE(count);

      pCurrent = entry->nextScriptPtr;
      while (pCurrent) {
            char dummy[4] = { 0, 0, 0, 0 };
            currentSaveFile.write(dummy, 2);

            currentSaveFile.writeSint16LE(pCurrent->ccr);
            currentSaveFile.writeSint16LE(pCurrent->var4);
            currentSaveFile.write(dummy, 4);
            currentSaveFile.writeSint16LE(pCurrent->varA);
            currentSaveFile.writeSint16LE(pCurrent->scriptNumber);
            currentSaveFile.writeSint16LE(pCurrent->overlayNumber);
            currentSaveFile.writeSint16LE(pCurrent->sysKey);
            currentSaveFile.writeSint16LE(pCurrent->freeze);
            currentSaveFile.writeSint16LE(pCurrent->type);
            currentSaveFile.writeSint16LE(pCurrent->var16);
            currentSaveFile.writeSint16LE(pCurrent->var18);
            currentSaveFile.writeSint16LE(pCurrent->var1A);

            currentSaveFile.writeSint16LE(pCurrent->varA);

            if (pCurrent->varA) {
                  currentSaveFile.write(pCurrent->var6, pCurrent->varA);
            }

            pCurrent = pCurrent->nextScriptPtr;
      }
}

void loadScriptsFromSave(Common::InSaveFile& currentSaveFile, scriptInstanceStruct *entry) {
      short int numScripts;
      int i;

      numScripts = currentSaveFile.readSint16LE();

      for (i = 0; i < numScripts; i++) {
            scriptInstanceStruct *ptr = (scriptInstanceStruct *)mallocAndZero(sizeof(scriptInstanceStruct));

            currentSaveFile.skip(2);

            ptr->ccr = currentSaveFile.readSint16LE();
            ptr->var4 = currentSaveFile.readSint16LE();
            currentSaveFile.skip(4);
            ptr->varA = currentSaveFile.readSint16LE();
            ptr->scriptNumber = currentSaveFile.readSint16LE();
            ptr->overlayNumber = currentSaveFile.readSint16LE();
            ptr->sysKey = currentSaveFile.readSint16LE();
            ptr->freeze = currentSaveFile.readSint16LE();
            ptr->type = (scriptTypeEnum)currentSaveFile.readSint16LE();
            ptr->var16 = currentSaveFile.readSint16LE();
            ptr->var18 = currentSaveFile.readSint16LE();
            ptr->var1A = currentSaveFile.readSint16LE();

            ptr->varA = currentSaveFile.readUint16LE();

            if (ptr->varA) {
                  ptr->var6 = (uint8 *) mallocAndZero(ptr->varA);

                  // FIXME: This code is not endian safe, and breaks if struct
                  // packing changes. Read/write the members one by one instead.
                  currentSaveFile.read(ptr->var6, ptr->varA);
            }

            ptr->nextScriptPtr = 0;

            entry->nextScriptPtr = ptr;
            entry = ptr;
      }
}

void saveAnim(Common::OutSaveFile& currentSaveFile) {
      int count = 0;

      actorStruct *ptr = actorHead.next;
      while (ptr) {
            count ++;
            ptr = ptr->next;
      }

      currentSaveFile.writeSint16LE(count);

      ptr = actorHead.next;
      while (ptr) {
            char dummy[2] = {0, 0};
            currentSaveFile.write(dummy, 2);
            currentSaveFile.write(dummy, 2);

            currentSaveFile.writeSint16LE(ptr->idx);
            currentSaveFile.writeSint16LE(ptr->type);
            currentSaveFile.writeSint16LE(ptr->overlayNumber);
            currentSaveFile.writeSint16LE(ptr->x_dest);
            currentSaveFile.writeSint16LE(ptr->y_dest);
            currentSaveFile.writeSint16LE(ptr->x);
            currentSaveFile.writeSint16LE(ptr->y);
            currentSaveFile.writeSint16LE(ptr->startDirection);
            currentSaveFile.writeSint16LE(ptr->nextDirection);
            currentSaveFile.writeSint16LE(ptr->endDirection);
            currentSaveFile.writeSint16LE(ptr->stepX);
            currentSaveFile.writeSint16LE(ptr->stepY);
            currentSaveFile.writeSint16LE(ptr->pathId);
            currentSaveFile.writeSint16LE(ptr->phase);
            currentSaveFile.writeSint16LE(ptr->counter);
            currentSaveFile.writeSint16LE(ptr->poly);
            currentSaveFile.writeSint16LE(ptr->flag);
            currentSaveFile.writeSint16LE(ptr->start);
            currentSaveFile.writeSint16LE(ptr->freeze);

            ptr = ptr->next;
      }
}

void loadSavegameActor(Common::InSaveFile& currentSaveFile) {
      short int numEntry;
      actorStruct *ptr;
      int i;

      numEntry = currentSaveFile.readSint16LE();

      ptr = &actorHead;

      for (i = 0; i < numEntry; i++) {
            actorStruct *current = (actorStruct *) mallocAndZero(sizeof(actorStruct));
            currentSaveFile.skip(2);
            currentSaveFile.skip(2);

            current->idx = currentSaveFile.readSint16LE();
            current->type = currentSaveFile.readSint16LE();
            current->overlayNumber = currentSaveFile.readSint16LE();
            current->x_dest = currentSaveFile.readSint16LE();
            current->y_dest = currentSaveFile.readSint16LE();
            current->x = currentSaveFile.readSint16LE();
            current->y = currentSaveFile.readSint16LE();
            current->startDirection = currentSaveFile.readSint16LE();
            current->nextDirection = currentSaveFile.readSint16LE();
            current->endDirection = currentSaveFile.readSint16LE();
            current->stepX = currentSaveFile.readSint16LE();
            current->stepY = currentSaveFile.readSint16LE();
            current->pathId = currentSaveFile.readSint16LE();
            current->phase = (animPhase)currentSaveFile.readSint16LE();
            current->counter = currentSaveFile.readSint16LE();
            current->poly = currentSaveFile.readSint16LE();
            current->flag = currentSaveFile.readSint16LE();
            current->start = currentSaveFile.readSint16LE();
            current->freeze = currentSaveFile.readSint16LE();

            current->next = NULL;
            ptr->next = current;
            current->prev = actorHead.prev;
            actorHead.prev = current;
            ptr = current->next;
      }
}

void saveSong(Common::OutSaveFile& currentSaveFile) {
      if (songLoaded) {
            // TODO: implement
            currentSaveFile.writeByte(0);
      } else {
            currentSaveFile.writeByte(0);
      }
}

void loadSavegameDataSub5(Common::InSaveFile& currentSaveFile) {
      if (songLoaded) {
            saveVar1 = currentSaveFile.readByte();

            if (saveVar1) {
                  currentSaveFile.read(saveVar2, saveVar1);
            }
      } else {
            saveVar1 = currentSaveFile.readByte();
      }

}

void saveCT(Common::OutSaveFile& currentSaveFile) {
      if (polyStruct) {
            currentSaveFile.writeSint32LE(1);

            currentSaveFile.writeSint16LE(numberOfWalkboxes);

            if (numberOfWalkboxes) {
                  // FIXME: This code is not endian safe, and breaks if struct
                  // packing changes. Read/write the members one by one instead.
                  currentSaveFile.write(walkboxColor, numberOfWalkboxes * 2);
                  currentSaveFile.write(walkboxState, numberOfWalkboxes * 2);
            }

            for (unsigned long int i = 0; i < 10; i++) {

                  if (persoTable[i]) {
                        currentSaveFile.writeSint32LE(1);
                        assert(sizeof(persoStruct) == 0x6AA);
                        currentSaveFile.write(persoTable[i], 0x6AA);
                  } else {
                        currentSaveFile.writeSint32LE(0);
                  }
            }

      } else {
            currentSaveFile.writeSint32LE(0);
      }
}

void loadSavegameDataSub6(Common::InSaveFile& currentSaveFile) {
      int32 var;

      var = currentSaveFile.readUint32BE();

      if (var) {
            int i;

            numberOfWalkboxes = currentSaveFile.readUint16LE();

            if (numberOfWalkboxes) {
                  // FIXME: This code is not endian safe, and breaks if struct
                  // packing changes. Read/write the members one by one instead.
                  currentSaveFile.read(walkboxColor, numberOfWalkboxes * 2);
                  currentSaveFile.read(walkboxState, numberOfWalkboxes * 2);
            }

            for (i = 0; i < 10; i++) {
                  persoTable[i] = (persoStruct*)currentSaveFile.readSint32LE();

                  if (persoTable[i]) {
                        // FIXME: This code is not endian safe, and breaks if struct
                        // packing changes. Read/write the members one by one instead.
                        assert(sizeof(persoStruct) == 0x6AA);
                        persoTable[i] = (persoStruct *)mallocAndZero(sizeof(persoStruct));
                        currentSaveFile.read(persoTable[i], 0x6AA);
                  }
            }
      }
}

int saveSavegameData(int saveGameIdx) {
      char buffer[256];

      sprintf(buffer, "CR.%d", saveGameIdx);

      Common::SaveFileManager *saveMan = g_system->getSavefileManager();
      Common::OutSaveFile *currentSaveFile;
      currentSaveFile = saveMan->openForSaving(buffer);

      char saveIdentBuffer[6];
      strcpy(saveIdentBuffer, "SAVPC");

      currentSaveFile->write(saveIdentBuffer, 6);
      currentSaveFile->writeSint16LE(songLoaded);
      currentSaveFile->writeSint16LE(songPlayed);
      currentSaveFile->writeSint16LE(songLoop);
      currentSaveFile->writeSint16LE(activeMouse);
      currentSaveFile->writeSint16LE(userEnabled);
      currentSaveFile->writeSint16LE(dialogueEnabled);
      currentSaveFile->writeSint16LE(dialogueOvl);
      currentSaveFile->writeSint16LE(dialogueObj);
      currentSaveFile->writeSint16LE(userDelay);
      currentSaveFile->writeSint16LE(sysKey);
      currentSaveFile->writeSint16LE(sysX);
      currentSaveFile->writeSint16LE(sysY);
      currentSaveFile->writeSint16LE(automoveInc);
      currentSaveFile->writeSint16LE(automoveMax);
      currentSaveFile->writeSint16LE(displayOn);
      currentSaveFile->writeSint16LE(isMessage);
      currentSaveFile->writeSint16LE(fadeFlag);
      currentSaveFile->writeSint16LE(playMusic);
      currentSaveFile->writeSint16LE(playMusic2);
      currentSaveFile->writeSint16LE(automaticMode);
      currentSaveFile->writeSint16LE(titleColor);
      currentSaveFile->writeSint16LE(itemColor);
      currentSaveFile->writeSint16LE(selectColor);
      currentSaveFile->writeSint16LE(subColor);
      currentSaveFile->writeSint16LE(narratorOvl);
      currentSaveFile->writeSint16LE(narratorIdx);
      currentSaveFile->writeSint16LE(aniX);
      currentSaveFile->writeSint16LE(aniY);

      if (animationStart)
            currentSaveFile->writeSint16LE(1);
      else
            currentSaveFile->writeSint16LE(0);

      currentSaveFile->writeSint16LE(masterScreen);
      currentSaveFile->writeSint16LE(switchPal);
      currentSaveFile->writeSint16LE(scroll);
      currentSaveFile->writeSint16LE(fadeFlag);
      currentSaveFile->writeSint16LE(doFade);
      currentSaveFile->writeSint16LE(numOfLoadedOverlay);
      currentSaveFile->writeSint16LE(stateID);
      currentSaveFile->writeSint16LE(fontFileIndex);
      currentSaveFile->writeSint16LE(currentActiveMenu);
      currentSaveFile->writeSint16LE(userWait);
      currentSaveFile->writeSint16LE(autoOvl);
      currentSaveFile->writeSint16LE(autoMsg);
      currentSaveFile->writeSint16LE(autoTrack);
      currentSaveFile->writeSint16LE(var39);
      currentSaveFile->writeSint16LE(var42);
      currentSaveFile->writeSint16LE(var45);
      currentSaveFile->writeSint16LE(var46);
      currentSaveFile->writeSint16LE(var47);
      currentSaveFile->writeSint16LE(var48);
      currentSaveFile->writeSint16LE(flagCt);
      currentSaveFile->writeSint16LE(var41);
      currentSaveFile->writeSint16LE(entrerMenuJoueur);

      currentSaveFile->write(newPal, sizeof(int16) * NBCOLORS);
      currentSaveFile->write(workpal, sizeof(int16) * NBCOLORS);

      currentSaveFile->write(musicName, 15);

      const char dummy[6] = { 0, 0, 0, 0, 0, 0 };
      currentSaveFile->write(dummy, 6);

      currentSaveFile->write(currentCtpName, 40);

      // restore backgroundTable
      for (int i = 0; i < 8; i++) {
            currentSaveFile->write(backgroundTable[i].name, 9);
            currentSaveFile->write(backgroundTable[i].extention, 6);
      }

      currentSaveFile->write(palScreen, sizeof(int16) * NBCOLORS * NBSCREENS);
      currentSaveFile->write(initVar5, 24);
      currentSaveFile->write(globalVars, stateID * 2); // ok
      for (int i = 0; i < 257; i++) {
            currentSaveFile->writeUint16LE(filesDatabase[i].widthInColumn);
            currentSaveFile->writeUint16LE(filesDatabase[i].width);
            currentSaveFile->writeUint16LE(filesDatabase[i].resType);
            currentSaveFile->writeUint16LE(filesDatabase[i].height);
            if (filesDatabase[i].subData.ptr) {
                  currentSaveFile->writeUint32LE(1);
            } else {
                  currentSaveFile->writeUint32LE(0);
            }
            currentSaveFile->writeUint16LE(filesDatabase[i].subData.index);
            currentSaveFile->write(filesDatabase[i].subData.name, 13);
            currentSaveFile->write(dummy, 1);
            currentSaveFile->writeUint16LE(filesDatabase[i].subData.transparency);
            if (filesDatabase[i].subData.ptrMask) {
                  currentSaveFile->writeUint32LE(1);
            } else {
                  currentSaveFile->writeUint32LE(0);
            }
            currentSaveFile->writeByte(filesDatabase[i].subData.resourceType);
            currentSaveFile->write(dummy, 1);
            currentSaveFile->writeUint16LE(filesDatabase[i].subData.compression);
      }

      for (int i = 0; i < numOfLoadedOverlay; i++) {
            currentSaveFile->write(overlayTable[i].overlayName, 13);
            currentSaveFile->write(dummy, 1);
            currentSaveFile->write(dummy, 4);
            currentSaveFile->writeUint16LE(overlayTable[i].alreadyLoaded);
            currentSaveFile->writeUint16LE(overlayTable[i].state);
            currentSaveFile->write(dummy, 4);
            currentSaveFile->write(dummy, 4);
            currentSaveFile->write(dummy, 4);
            currentSaveFile->write(dummy, 4);
            currentSaveFile->writeUint16LE(overlayTable[i].executeScripts);
      }

      for (int i = 0; i < 64; i++) {
            currentSaveFile->write(preloadData[i].name, 15);
            currentSaveFile->write(dummy, 1);
            currentSaveFile->writeUint32LE(preloadData[i].size);
            currentSaveFile->writeUint32LE(preloadData[i].sourceSize);
            currentSaveFile->write(dummy, 4);
            currentSaveFile->writeUint16LE(preloadData[i].nofree);
            currentSaveFile->writeUint16LE(preloadData[i].protect);
            currentSaveFile->writeUint16LE(preloadData[i].ovl);
      }

      saveOverlay(*currentSaveFile);
      saveScript(*currentSaveFile, &procHead);
      saveScript(*currentSaveFile, &relHead);
      saveCell(*currentSaveFile);
      saveIncrust(*currentSaveFile);
      saveAnim(*currentSaveFile);
      saveSong(*currentSaveFile);
      saveCT(*currentSaveFile);

      currentSaveFile->finalize();
      delete currentSaveFile;
      return 0;
}

int loadSavegameData(int saveGameIdx) {
      char buffer[256];
      char saveIdentBuffer[6];
      int lowMemorySave;
      cellStruct *currentcellHead;

      sprintf(buffer, "CR.%d", saveGameIdx);

      Common::SaveFileManager *saveMan = g_system->getSavefileManager();
      Common::InSaveFile *currentSaveFile;
      currentSaveFile = saveMan->openForLoading(buffer);

      if (currentSaveFile == NULL) {
            printInfoBlackBox("Savegame not found...");
            waitForPlayerInput();
            return (-1);
      }

      printInfoBlackBox("Loading in progress...");

      currentSaveFile->read(saveIdentBuffer, 6);

      if (strcmp(saveIdentBuffer, "SAVPC")) {
            delete currentSaveFile;
            return (-1);
      }
      initVars();

      songLoaded = currentSaveFile->readSint16LE();
      songPlayed = currentSaveFile->readSint16LE();
      songLoop = currentSaveFile->readSint16LE();
      activeMouse = currentSaveFile->readSint16LE();
      userEnabled = currentSaveFile->readSint16LE();
      dialogueEnabled = currentSaveFile->readSint16LE();

      dialogueOvl = currentSaveFile->readSint16LE();
      dialogueObj = currentSaveFile->readSint16LE();
      userDelay = currentSaveFile->readSint16LE();
      sysKey = currentSaveFile->readSint16LE();
      sysX = currentSaveFile->readSint16LE();
      sysY = currentSaveFile->readSint16LE();
      automoveInc = currentSaveFile->readSint16LE();
      automoveMax = currentSaveFile->readSint16LE();
      displayOn = currentSaveFile->readSint16LE();
      isMessage = currentSaveFile->readSint16LE();
      fadeFlag = currentSaveFile->readSint16LE();
      playMusic = currentSaveFile->readSint16LE();
      playMusic2 = currentSaveFile->readSint16LE();
      automaticMode = currentSaveFile->readSint16LE();

      // video param (not loaded in EGA mode)

      titleColor = currentSaveFile->readSint16LE();
      itemColor = currentSaveFile->readSint16LE();
      selectColor = currentSaveFile->readSint16LE();
      subColor = currentSaveFile->readSint16LE();

      //

      narratorOvl = currentSaveFile->readSint16LE();
      narratorIdx = currentSaveFile->readSint16LE();
      aniX = currentSaveFile->readSint16LE();
      aniY = currentSaveFile->readSint16LE();

      if (currentSaveFile->readSint16LE()) // cast to bool
            animationStart = true;
      else
            animationStart = false;

      masterScreen = currentSaveFile->readSint16LE();
      switchPal = currentSaveFile->readSint16LE();
      scroll = currentSaveFile->readSint16LE();
      fadeFlag = currentSaveFile->readSint16LE();
      doFade = currentSaveFile->readSint16LE();
      numOfLoadedOverlay = currentSaveFile->readSint16LE();
      stateID = currentSaveFile->readSint16LE();
      fontFileIndex = currentSaveFile->readSint16LE();
      currentActiveMenu = currentSaveFile->readSint16LE();
      userWait = currentSaveFile->readSint16LE();
      autoOvl = currentSaveFile->readSint16LE();
      autoMsg = currentSaveFile->readSint16LE();
      autoTrack = currentSaveFile->readSint16LE();
      var39 = currentSaveFile->readSint16LE();
      var42 = currentSaveFile->readSint16LE();
      var45 = currentSaveFile->readSint16LE();
      var46 = currentSaveFile->readSint16LE();
      var47 = currentSaveFile->readSint16LE();
      var48 = currentSaveFile->readSint16LE();
      flagCt = currentSaveFile->readSint16LE();
      var41 = currentSaveFile->readSint16LE();
      entrerMenuJoueur = currentSaveFile->readSint16LE();

      // FIXME: This code is not endian safe, and breaks if struct
      // packing changes. Read/write the members one by one instead.
      currentSaveFile->read(newPal, sizeof(int16) * NBCOLORS);
      currentSaveFile->read(newPal, sizeof(int16) * NBCOLORS);    // FIXME: Should this read into workpal ?

      // here code seems bogus... this should read music name and it may be a buffer overrun
      currentSaveFile->skip(21);

      currentSaveFile->read(currentCtpName, 40);

      // restore backgroundTable
      for (int i = 0; i < 8; i++) {
            currentSaveFile->read(backgroundTable[i].name, 9);
            currentSaveFile->read(backgroundTable[i].extention, 6);
      }

      // FIXME: This code is not endian safe, and breaks if struct
      // packing changes. Read/write the members one by one instead.
      currentSaveFile->read(palScreen, sizeof(int16) * NBCOLORS * NBSCREENS);
      currentSaveFile->read(initVar5, 24);
      currentSaveFile->read(globalVars, stateID * 2); // ok
      for (int i = 0; i < 257; i++) {
            filesDatabase[i].widthInColumn = currentSaveFile->readUint16LE();
            filesDatabase[i].width = currentSaveFile->readUint16LE();
            filesDatabase[i].resType = currentSaveFile->readUint16LE();
            filesDatabase[i].height = currentSaveFile->readUint16LE();
            filesDatabase[i].subData.ptr = (uint8*)currentSaveFile->readSint32LE();
            filesDatabase[i].subData.index = currentSaveFile->readSint16LE();
            currentSaveFile->read(filesDatabase[i].subData.name, 13);
            currentSaveFile->skip(1);
            filesDatabase[i].subData.transparency = currentSaveFile->readSint16LE();
            filesDatabase[i].subData.ptrMask = (uint8*)currentSaveFile->readSint32LE();
            filesDatabase[i].subData.resourceType = currentSaveFile->readByte();
            currentSaveFile->skip(1);
            filesDatabase[i].subData.compression = currentSaveFile->readSint16LE();
      }

      for (int i = 0; i < numOfLoadedOverlay; i++) {
            currentSaveFile->read(overlayTable[i].overlayName, 13);
            currentSaveFile->skip(1);
            currentSaveFile->skip(4);
            overlayTable[i].alreadyLoaded = currentSaveFile->readSint16LE();
            overlayTable[i].state = currentSaveFile->readSint16LE();
            currentSaveFile->skip(4);
            currentSaveFile->skip(4);
            currentSaveFile->skip(4);
            currentSaveFile->skip(4);
            overlayTable[i].executeScripts = currentSaveFile->readSint16LE();
      }

      for (int i = 0; i < 64; i++) {
            currentSaveFile->read(preloadData[i].name, 15);
            currentSaveFile->skip(1);
            preloadData[i].size = currentSaveFile->readSint32LE();
            preloadData[i].sourceSize = currentSaveFile->readSint32LE();
            currentSaveFile->skip(4);
            preloadData[i].nofree = currentSaveFile->readSint16LE();
            preloadData[i].protect = currentSaveFile->readSint16LE();
            preloadData[i].ovl = currentSaveFile->readSint16LE();
      }

      loadSavegameDataSub1(*currentSaveFile);
      loadScriptsFromSave(*currentSaveFile, &procHead);
      loadScriptsFromSave(*currentSaveFile, &relHead);

      loadSavegameDataSub2(*currentSaveFile);
      loadBackgroundIncrustFromSave(*currentSaveFile);
      loadSavegameActor(*currentSaveFile);
      loadSavegameDataSub5(*currentSaveFile);
      loadSavegameDataSub6(*currentSaveFile);

      delete currentSaveFile;

      for (int j = 0; j < 64; j++) {
            preloadData[j].ptr = NULL;
      }

      for (int j = 1; j < numOfLoadedOverlay; j++) {
            if (overlayTable[j].alreadyLoaded) {
                  overlayTable[j].alreadyLoaded = 0;
                  loadOverlay(overlayTable[j].overlayName);

                  if (overlayTable[j].alreadyLoaded) {
                        ovlDataStruct *ovlData = overlayTable[j].ovlData;

                        // overlay BSS

                        if (ovlRestoreData[j]._sBssSize) {
                              if (ovlData->data4Ptr) {
                                    free(ovlData->data4Ptr);
                              }

                              ovlData->data4Ptr = ovlRestoreData[j]._pBss;
                              ovlData->sizeOfData4 = ovlRestoreData[j]._sBssSize;
                        }

                        // overlay object data

                        if (ovlRestoreData[j]._sNumObj) {
                              if (ovlData->arrayObjVar) {
                                    free(ovlData->arrayObjVar);
                              }

                              ovlData->arrayObjVar = ovlRestoreData[j]._pObj;
                              ovlData->size9 = ovlRestoreData[j]._sNumObj;
                        }

                  }
            }
      }

      updateAllScriptsImports();

      lastAni[0] = 0;

      lowMemorySave = lowMemory;

      for (int i = 0; i < 257; i++) {
            if (filesDatabase[i].subData.ptr) {
                  int j;
                  int k;

                  for (j = i + 1; j < 257 && filesDatabase[j].subData.ptr && !strcmp(filesDatabase[i].subData.name, filesDatabase[j].subData.name) && (filesDatabase[j].subData.index == (j - i)); j++);

                  for (k = i; k < j; k++) {
                        if (filesDatabase[k].subData.ptrMask)
                              lowMemory = 0;

                        filesDatabase[k].subData.ptr = NULL;
                        filesDatabase[k].subData.ptrMask = NULL;
                  }

                  /*if (j < 2) {
                        printf("Unsupported mono file load!\n");
                        ASSERT(0);
                        //loadFileMode1(filesDatabase[j].subData.name,filesDatabase[j].subData.var4);
                  } else */{
                        loadFileRange(filesDatabase[i].subData.name, filesDatabase[i].subData.index, i, j - i);
                        i = j - 1;
                  }

                  lowMemory = lowMemorySave;
            }
      }

      lastAni[0] = 0;

      currentcellHead = cellHead.next;

      while (currentcellHead) {
            if (currentcellHead->type == 5) {
                  uint8 *ptr = mainProc14(currentcellHead->overlay, currentcellHead->idx);

                  ASSERT(0);

                  if (ptr) {
                        ASSERT(0);
                        //*(int16*)(currentcellHead->datas+0x2E) = getSprite(ptr,*(int16*)(currentcellHead->datas+0xE));
                  } else {
                        ASSERT(0);
                        //*(int16*)(currentcellHead->datas+0x2E) = 0;
                  }
            }

            currentcellHead = currentcellHead->next;
      }

      //TODO: here, restart music

      if (strlen(currentCtpName)) {
            loadCtFromSave = 1;
            initCt(currentCtpName);
            loadCtFromSave = 0;
      }
      //prepareFadeOut();
      //gfxModuleData.gfxFunction8();

      for (int j = 0; j < 8; j++) {
            if (strlen((char *)backgroundTable[j].name)) {
                  loadBackground(backgroundTable[j].name, j);
            }
      }

      //regenerateBackgroundIncrust(&backgroundIncrustHead);

      // to finish

      changeCursor(CURSOR_NORMAL);
      mainDraw(1);
      flipScreen();

      return (0);
}

} // End of namespace Cruise

Generated by  Doxygen 1.6.0   Back to index