2013-09-04 00:17:37 -05:00
/* 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 .
2014-02-18 02:34:27 +01:00
*
2013-09-04 00:17:37 -05:00
* 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 .
2014-02-18 02:34:27 +01:00
*
2013-09-04 00:17:37 -05:00
* 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 .
*
*/
# include "common/scummsys.h"
2013-11-01 00:58:43 -05:00
# include "zvision/core/save_manager.h"
2013-10-01 20:08:41 -05:00
# include "zvision/zvision.h"
2013-11-01 00:58:43 -05:00
# include "zvision/scripting/script_manager.h"
# include "zvision/graphics/render_manager.h"
2013-10-01 20:08:41 -05:00
2013-09-04 00:17:37 -05:00
# include "common/system.h"
# include "graphics/surface.h"
# include "graphics/thumbnail.h"
2013-09-17 11:04:41 -05:00
# include "gui/message.h"
2013-09-04 00:17:37 -05:00
namespace ZVision {
const uint32 SaveManager : : SAVEGAME_ID = MKTAG ( ' Z ' , ' E ' , ' N ' , ' G ' ) ;
void SaveManager : : saveGame ( uint slot , const Common : : String & saveName ) {
2013-09-21 00:04:31 -05:00
// The games only support 20 slots
2013-10-01 17:49:33 -05:00
assert ( slot < = 1 & & slot < = 20 ) ;
2013-09-21 00:04:31 -05:00
2013-09-04 00:17:37 -05:00
Common : : SaveFileManager * saveFileManager = g_system - > getSavefileManager ( ) ;
Common : : OutSaveFile * file = saveFileManager - > openForSaving ( _engine - > generateSaveFileName ( slot ) ) ;
// Write out the savegame header
file - > writeUint32BE ( SAVEGAME_ID ) ;
2013-09-16 22:10:26 -05:00
// Write version
2013-09-17 11:03:49 -05:00
file - > writeByte ( SAVE_VERSION ) ;
2013-09-16 22:10:26 -05:00
2013-09-04 00:17:37 -05:00
// Write savegame name
file - > writeString ( saveName ) ;
file - > writeByte ( 0 ) ;
// We can't call writeGameSaveData because the save menu is actually
// a room, so writeGameSaveData would save us in the save menu.
// However, an auto save is performed before each room change, so we
// can copy the data from there. We can guarantee that an auto save file will
// exist before this is called because the save menu can only be accessed
// after the first room (the main menu) has loaded.
Common : : InSaveFile * autoSaveFile = saveFileManager - > openForLoading ( _engine - > generateAutoSaveFileName ( ) ) ;
// Skip over the header info
autoSaveFile - > readSint32BE ( ) ; // SAVEGAME_ID
2013-09-16 22:10:26 -05:00
autoSaveFile - > readByte ( ) ; // Version
2013-09-04 00:17:37 -05:00
autoSaveFile - > seek ( 5 , SEEK_CUR ) ; // The string "auto" with terminating NULL
// Read the rest to a buffer
uint32 size = autoSaveFile - > size ( ) - autoSaveFile - > pos ( ) ;
byte * buffer = new byte [ size ] ;
autoSaveFile - > read ( buffer , size ) ;
// Then write the buffer to the new file
file - > write ( buffer , size ) ;
// Cleanup
delete [ ] buffer ;
file - > finalize ( ) ;
2013-09-22 15:47:16 -05:00
delete file ;
2013-09-04 00:17:37 -05:00
}
void SaveManager : : autoSave ( ) {
Common : : OutSaveFile * file = g_system - > getSavefileManager ( ) - > openForSaving ( _engine - > generateAutoSaveFileName ( ) ) ;
// Write out the savegame header
file - > writeUint32BE ( SAVEGAME_ID ) ;
2013-09-16 22:10:26 -05:00
// Version
2013-09-17 11:03:49 -05:00
file - > writeByte ( SAVE_VERSION ) ;
2013-09-16 22:10:26 -05:00
2013-09-04 00:17:37 -05:00
file - > writeString ( " auto " ) ;
file - > writeByte ( 0 ) ;
writeSaveGameData ( file ) ;
2013-09-22 15:47:16 -05:00
// Cleanup
2013-09-04 00:17:37 -05:00
file - > finalize ( ) ;
2013-09-22 15:47:16 -05:00
delete file ;
2013-09-04 00:17:37 -05:00
}
void SaveManager : : writeSaveGameData ( Common : : OutSaveFile * file ) {
// Create a thumbnail and save it
2013-09-25 02:30:37 -05:00
Graphics : : saveThumbnail ( * file ) ;
2013-09-04 00:17:37 -05:00
// Write out the save date/time
TimeDate td ;
g_system - > getTimeAndDate ( td ) ;
file - > writeSint16LE ( td . tm_year + 1900 ) ;
file - > writeSint16LE ( td . tm_mon + 1 ) ;
file - > writeSint16LE ( td . tm_mday ) ;
file - > writeSint16LE ( td . tm_hour ) ;
file - > writeSint16LE ( td . tm_min ) ;
ScriptManager * scriptManager = _engine - > getScriptManager ( ) ;
// Write out the current location
Location currentLocation = scriptManager - > getCurrentLocation ( ) ;
file - > writeByte ( currentLocation . world ) ;
file - > writeByte ( currentLocation . room ) ;
file - > writeByte ( currentLocation . node ) ;
file - > writeByte ( currentLocation . view ) ;
file - > writeUint32LE ( currentLocation . offset ) ;
// Write out the current state table values
scriptManager - > serializeStateTable ( file ) ;
// Write out any controls needing to save state
scriptManager - > serializeControls ( file ) ;
}
Common : : Error SaveManager : : loadGame ( uint slot ) {
2013-09-21 00:04:31 -05:00
// The games only support 20 slots
assert ( slot < = 1 & & slot < = 20 ) ;
2013-09-04 00:17:37 -05:00
Common : : InSaveFile * saveFile = g_system - > getSavefileManager ( ) - > openForLoading ( _engine - > generateSaveFileName ( slot ) ) ;
if ( saveFile = = 0 ) {
return Common : : kPathDoesNotExist ;
}
// Read the header
SaveGameHeader header ;
if ( ! readSaveGameHeader ( saveFile , header ) ) {
return Common : : kUnknownError ;
}
char world = ( char ) saveFile - > readByte ( ) ;
char room = ( char ) saveFile - > readByte ( ) ;
char node = ( char ) saveFile - > readByte ( ) ;
char view = ( char ) saveFile - > readByte ( ) ;
uint32 offset = ( char ) saveFile - > readUint32LE ( ) ;
ScriptManager * scriptManager = _engine - > getScriptManager ( ) ;
// Update the state table values
scriptManager - > deserializeStateTable ( saveFile ) ;
2013-09-21 00:03:49 -05:00
// Load the room
scriptManager - > changeLocation ( world , room , node , view , offset ) ;
2013-09-04 00:17:37 -05:00
// Update the controls
scriptManager - > deserializeControls ( saveFile ) ;
return Common : : kNoError ;
}
bool SaveManager : : readSaveGameHeader ( Common : : InSaveFile * in , SaveGameHeader & header ) {
2013-09-06 22:48:15 -05:00
if ( in - > readUint32BE ( ) ! = SAVEGAME_ID ) {
2013-09-04 00:17:37 -05:00
warning ( " File is not a ZVision save file. Aborting load " ) ;
return false ;
}
2013-09-16 22:10:26 -05:00
// Read in the version
header . version = in - > readByte ( ) ;
2013-09-17 11:04:41 -05:00
// Check that the save version isn't newer than this binary
if ( header . version > SAVE_VERSION ) {
uint tempVersion = header . version ;
GUI : : MessageDialog dialog ( Common : : String : : format ( " This save file uses version %u, but this engine only supports up to version %d. You will need an updated version of the engine to use this save file. " , tempVersion , SAVE_VERSION ) , " OK " ) ;
dialog . runModal ( ) ;
}
2013-09-04 00:17:37 -05:00
// Read in the save name
header . saveName . clear ( ) ;
char ch ;
while ( ( ch = ( char ) in - > readByte ( ) ) ! = ' \0 ' )
header . saveName + = ch ;
// Get the thumbnail
header . thumbnail = Graphics : : loadThumbnail ( * in ) ;
if ( ! header . thumbnail )
return false ;
// Read in save date/time
header . saveYear = in - > readSint16LE ( ) ;
header . saveMonth = in - > readSint16LE ( ) ;
header . saveDay = in - > readSint16LE ( ) ;
header . saveHour = in - > readSint16LE ( ) ;
header . saveMinutes = in - > readSint16LE ( ) ;
return true ;
}
} // End of namespace ZVision