Logo Search packages:      
Sourcecode: scummvm version File versions  Download package

saveload_v2.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-11-1/engines/gob/saveload_v2.cpp $
 * $Id: saveload_v2.cpp 30944 2008-02-23 22:50:18Z sev $
 *
 */

#include "common/endian.h"
#include "common/file.h"

#include "gob/gob.h"
#include "gob/saveload.h"
#include "gob/global.h"
#include "gob/game.h"

namespace Gob {

SaveLoad_v2::SaveLoad_v2(GobEngine *vm, const char *targetName) :
      SaveLoad(vm, targetName) {

      _stagesCount = 1;
}

SaveType SaveLoad_v2::getSaveType(const char *fileName) {
      const char *backSlash;
      if ((backSlash = strrchr(fileName, '\\')))
            fileName = backSlash + 1;

      if (!scumm_stricmp(fileName, "cat.inf"))
            return kSaveGame;
      if (!scumm_stricmp(fileName, "cat.cat"))
            return kSaveGame;
      if (!scumm_stricmp(fileName, "save.inf"))
            return kSaveTempSprite;
      if (!scumm_stricmp(fileName, "bloc.inf"))
            return kSaveNotes;

      return kSaveNone;
}

uint32 SaveLoad_v2::getSaveGameSize() {
      return 80 + (READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4) * 2;
}

int32 SaveLoad_v2::getSizeNotes() {
      Common::SaveFileManager *saveMan = g_system->getSavefileManager();
      Common::InSaveFile *in;
      int32 size = -1;

      in = saveMan->openForLoading(_saveFiles[(int) kSaveNotes]);
      if (in) {
            size = in->size();
            delete in;
      }

      return size;
}

int32 SaveLoad_v2::getSizeGame() {
      Common::SaveFileManager *saveMan = g_system->getSavefileManager();
      Common::InSaveFile *in;

      for (int i = 14; i >= 0; i--) {
            in = saveMan->openForLoading(setCurSlot(i));
            if (in) {
                  delete in;
                  return (i + 1) * READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) *
                        4 + 600;
            }
      }

      return -1;
}

int32 SaveLoad_v2::getSizeScreenshot() {
      return -1;
}

bool SaveLoad_v2::loadGame(int16 dataVar, int32 size, int32 offset) {
      Common::SaveFileManager *saveMan = g_system->getSavefileManager();
      Common::InSaveFile *in;
      int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;

      if (size == 0) {
            dataVar = 0;
            size = varSize;
      }

      int slot = (offset - 600) / varSize;
      int slotR = (offset - 600) % varSize;

      if ((offset == 0) && (size == 600)) {

            byte *varBuf = _vm->_global->_inter_variables + dataVar;
            for (int i = 0; i < 15; i++, varBuf += 40) {
                  in = saveMan->openForLoading(setCurSlot(i));
                  if (in) {
                        in->read(varBuf, 40);
                        delete in;
                  } else
                        memset(varBuf, 0, 40);
            }
            memset(_vm->_global->_inter_variablesSizes + dataVar, 0, 600);
            return true;

      } else if ((offset > 0) && (slot < 15) &&
                  (slotR == 0) && (size == varSize)) {

            in = saveMan->openForLoading(setCurSlot(slot));
            if (!in) {
                  warning("Can't open file for slot %d", slot);
                  return false;
            }

            uint32 sGameSize = getSaveGameSize();
            uint32 fSize = in->size();
            if (fSize != sGameSize) {
                  warning("Can't load from slot %d: Wrong size (%d, %d)", slot,
                              fSize, sGameSize);
                  delete in;
                  return false;
            }

            in->seek(80);
            if (loadDataEndian(*in, dataVar, size)) {
                  delete in;
                  debugC(1, kDebugFileIO, "Loading from slot %d", slot);
                  return true;
            }
            delete in;

      } else
            warning("Invalid loading procedure (%d, %d, %d, %d)",
                        offset, size, slot, slotR);

      return false;
}

bool SaveLoad_v2::loadNotes(int16 dataVar, int32 size, int32 offset) {
      bool retVal;

      if ((size <= 0) || (offset != 0)) {
            warning("Invalid attempt at loading the notes (%d, %d)", size, offset);
            return false;
      }

      Common::SaveFileManager *saveMan = g_system->getSavefileManager();
      char *sName = _saveFiles[(int) kSaveNotes];

      Common::InSaveFile *in = saveMan->openForLoading(sName);
      if (!in) {
            warning("Can't open file \"%s\" for reading", sName);
            return false;
      }

      retVal = loadDataEndian(*in, dataVar, size);
      delete in;
      return retVal;
}

bool SaveLoad_v2::loadScreenshot(int16 dataVar, int32 size, int32 offset) {
      return false;
}

bool SaveLoad_v2::saveGame(int16 dataVar, int32 size, int32 offset) {
      int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;

      initBuffer();

      if (size == 0) {
            dataVar = 0;
            size = varSize;
      }

      int slot = (offset - 600) / varSize;
      int slotR = (offset - 600) % varSize;

      if ((offset == 0) && (size == 600)) {

            delete[] _buffer[0];
            _buffer[0] = new byte[1200];
            assert(_buffer[0]);

            memcpy(_buffer[0], _vm->_global->_inter_variables + dataVar, 600);
            memset(_buffer[0] + 600, 0, 600);

            return true;

      } else if ((offset > 0) && (slot < 15) &&
                  (slotR == 0) && (size == varSize)) {

            if (!_buffer[0]) {
                  warning("Tried to save without writing the index first");
                  return false;
            }

            Common::SaveFileManager *saveMan = g_system->getSavefileManager();
            Common::OutSaveFile *out;

            out = saveMan->openForSaving(setCurSlot(slot));
            if (!out) {
                  warning("Can't open file for slot %d for writing", slot);
                  delete[] _buffer[0];
                  _buffer[0] = 0;
                  return false;
            }

            bool retVal = false;

            if (out->write(_buffer[0] + slot * 40, 40) == 40)
                  if (out->write(_buffer[0] + 600 + slot * 40, 40) == 40)
                        if (saveDataEndian(*out, dataVar, size)) {
                              out->finalize();
                              if (!out->ioFailed())
                                    retVal = true;
                        }

            if (!retVal)
                  warning("Can't save to slot %d", slot);
            else
                  debugC(1, kDebugFileIO, "Saved to slot %d", slot);

            delete[] _buffer[0];
            _buffer[0] = 0;
            delete out;

            return retVal;

      } else
            warning("Invalid saving procedure (%d, %d, %d, %d)",
                        offset, size, slot, slotR);

      return false;
}

bool SaveLoad_v2::saveNotes(int16 dataVar, int32 size, int32 offset) {
      bool retVal;

      if ((size <= 0) || (offset != 0)) {
            warning("Invalid attempt at saving the notes (%d, %d)", size, offset);
            return false;
      }

      Common::SaveFileManager *saveMan = g_system->getSavefileManager();
      char *sName = _saveFiles[(int) kSaveNotes];

      Common::OutSaveFile *out = saveMan->openForSaving(sName);
      if (!out) {
            warning("Can't open file \"%s\" for writing", sName);
            return false;
      }

      retVal = saveDataEndian(*out, dataVar, size);

      out->finalize();
      if (out->ioFailed()) {
            warning("Can't save notes");
            retVal = false;
      }

      delete out;
      return retVal;
}

bool SaveLoad_v2::saveScreenshot(int16 dataVar, int32 size, int32 offset) {
      return false;
}

void SaveLoad_v2::initBuffer() {
      if (_buffer)
            return;

      _buffer = new byte*[_stagesCount];
      assert(_buffer);
      _buffer[0] = 0;
}

} // End of namespace Gob

Generated by  Doxygen 1.6.0   Back to index