[Scummvm-cvs-logs] CVS: residual savegame.cpp,NONE,1.1 savegame.h,NONE,1.1 lua.cpp,1.161,1.162 engine.cpp,1.97,1.98 engine.h,1.38,1.39 Makefile.common,1.20,1.21

Erich Edgar Hoover compholio at users.sourceforge.net
Sun Dec 25 18:37:01 CET 2005


Update of /cvsroot/scummvm/residual
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8997

Modified Files:
	lua.cpp engine.cpp engine.h Makefile.common 
Added Files:
	savegame.cpp savegame.h 
Log Message:
Centralized save/restore system, x86-64 fixes for lua_Save and lua_Restore (should be more portable now), stored screenshots for savegames

--- NEW FILE: savegame.cpp ---
// Residual - Virtual machine to run LucasArts' 3D adventure games
// Copyright (C) 2003-2005 The ScummVM-Residual Team (www.scummvm.org)
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library 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
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA

#include "debug.h"
#include "savegame.h"

#define SAVEGAME_HEADERTAG	'RSAV'
#define SAVEGAME_FOOTERTAG	'ESAV'
#define SAVEGAME_VERSION		2

// Constructor. Should create/open a saved game
SaveGame::SaveGame(char *filename, bool saving) :
	_currentSection(0), _saving(saving)
{
	if (_saving) {
		uint32 tag = SAVEGAME_HEADERTAG;
		uint32 version = SAVEGAME_VERSION;
		
		_fileHandle = gzopen(filename, "wb");
		if (_fileHandle == NULL) {
			warning("SaveGame::SaveGame() Error creating savegame file");
			return;
		}
		gzwrite(_fileHandle, &tag, 4);
		gzwrite(_fileHandle, &version, 4);
	} else {
		uint32 tag, version;
		
		_fileHandle = gzopen(filename, "rb");
		if (_fileHandle == NULL) {
			warning("SaveGame::SaveGame() Error opening savegame file");
			return;
		}
		gzread(_fileHandle, &tag, 4);
		assert(tag == SAVEGAME_HEADERTAG);
		gzread(_fileHandle, &version, 4);
		assert(version == SAVEGAME_VERSION);
	}
}

SaveGame::~SaveGame() {
	uint32 tag = SAVEGAME_FOOTERTAG;
	
	gzwrite(_fileHandle, &tag, 4);
	gzclose(_fileHandle);
}

uint32 SaveGame::beginSection(uint32 sectionTag) {
	if (_currentSection != 0)
		error("Tried to begin a new save game section with ending old section!");
	_currentSection = sectionTag;
	_sectionSize = 0;
	_sectionBuffer = (char *) malloc(_sectionSize);
	if (!_saving) {
		uint32 tag = 0;
		
		while (tag != sectionTag) {
			free(_sectionBuffer);
			gzread(_fileHandle, &tag, sizeof(uint32));
			if (tag == SAVEGAME_FOOTERTAG)
				error("Unable to find requested section of savegame!");
			gzread(_fileHandle, &_sectionSize, sizeof(uint32));
			_sectionBuffer = (char *) malloc(_sectionSize);
			gzread(_fileHandle, _sectionBuffer, _sectionSize);
		}
	}
	_sectionPtr = 0;
	return _sectionSize;
}

void SaveGame::endSection() {
	if (_currentSection == 0)
		error("Tried to end a save game section without starting a section!");
	if(_saving) {
		gzwrite(_fileHandle, &_currentSection, sizeof(uint32));
		gzwrite(_fileHandle, &_sectionSize, sizeof(uint32));
		gzwrite(_fileHandle, _sectionBuffer, _sectionSize);
	}
	free(_sectionBuffer);
	_currentSection = 0;
}

void SaveGame::readBlock(void *data, int size) {
	if (_saving)
		error("SaveGame::readBlock called when storing a savegame!");
	if (_currentSection == 0)
		error("Tried to read a block without starting a section!");
	memcpy(data, &_sectionBuffer[_sectionPtr], size);
	_sectionPtr += size;
}

void SaveGame::writeBlock(void *data, int size) {
	if (!_saving)
		error("SaveGame::writeBlock called when restoring a savegame!");
	if (_currentSection == 0)
		error("Tried to write a block without starting a section!");
	_sectionBuffer = (char *) realloc(_sectionBuffer, _sectionSize + size);
	if (_sectionBuffer == NULL)
		error("Failed to allocate space for buffer!");
	memcpy(&_sectionBuffer[_sectionSize], data, size);
	_sectionSize += size;
}

--- NEW FILE: savegame.h ---
// Residual - Virtual machine to run LucasArts' 3D adventure games
// Copyright (C) 2003-2005 The ScummVM-Residual Team (www.scummvm.org)
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library 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
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA

#ifndef SAVEGAME_H
#define SAVEGAME_H

#include "debug.h"
#include <zlib.h>

class SaveGame {
public:
	SaveGame(char *filename, bool saving);
	~SaveGame();
	
	uint32 beginSection(uint32 sectionTag);
	void endSection();
	void readBlock(void *data, int size);
	void writeBlock(void *data, int size);

protected:
	bool _saving;
	gzFile _fileHandle;
	uint32 _currentSection;
	uint32 _sectionSize;
	uint32 _sectionPtr;
	char *_sectionBuffer;
};

#endif

Index: lua.cpp
===================================================================
RCS file: /cvsroot/scummvm/residual/lua.cpp,v
retrieving revision 1.161
retrieving revision 1.162
diff -u -d -r1.161 -r1.162
--- lua.cpp	25 Dec 2005 06:06:37 -0000	1.161
+++ lua.cpp	26 Dec 2005 02:35:59 -0000	1.162
@@ -31,6 +31,7 @@
 #include "colormap.h"
 #include "font.h"
 #include "primitives.h"
+#include "savegame.h"
 
 #include "imuse/imuse.h"
 
@@ -1958,27 +1959,18 @@
 
 static void SaveIMuse() {
 	DEBUG_FUNCTION();
-	gzFile file = gzopen("grim.tmp", "wb");
-	if (file == NULL) {
-		warning("SaveIMuse() Error creating temp savegame file");
-		return;
-	}
-	g_engine->_savegameFileHandle = file;
-	g_imuse->saveState(g_engine->savegameGzwrite);
-	gzclose(file);
+	SaveGame *savedIMuse = new SaveGame("grim.tmp", true);
+	g_imuse->saveState(savedIMuse);
+	delete savedIMuse;
 }
 
 static void RestoreIMuse() {
 	DEBUG_FUNCTION();
-	gzFile file = gzopen("grim.tmp", "rb");
-	if (file == NULL) {
-		return;
-	}
-	g_engine->_savegameFileHandle = file;
+	SaveGame *savedIMuse = new SaveGame("grim.tmp", false);
 	g_imuse->stopAllSounds();
 	g_imuse->resetState();
-	g_imuse->restoreState(g_engine->savegameGzread);
-	gzclose(file);
+	g_imuse->restoreState(savedIMuse);
+	delete savedIMuse;
 	unlink("grim.tmp");
 }
 
@@ -2809,29 +2801,83 @@
 	}
 }
 
+/*
+ * Store a screenshot into a savegame file
+ *
+ * TODO: Width and height are currently hardcoded,
+ * find a fix
+ */
+static void StoreSaveGameImage(SaveGame *savedState) {
+	int width = 250, height = 188;
+	Bitmap *screenshot;
+	
+	printf("StoreSaveGameImage() started.\n");
+	
+	DEBUG_FUNCTION();
+
+	int mode = g_engine->getMode();
+	g_engine->setMode(ENGINE_MODE_NORMAL);
+	g_engine->updateDisplayScene();
+	screenshot = g_driver->getScreenshot(width, height);
+	g_engine->setMode(mode);
+	savedState->beginSection('SIMG');
+	if (screenshot) {
+		int size = screenshot->width() * screenshot->height() * sizeof(uint16);
+		screenshot->setNumber(0);
+		char *data = screenshot->getData();
+		
+		savedState->writeBlock(data, size);
+	} else {
+		error("Unable to store screenshot!");
+	}
+	savedState->endSection();
+	printf("StoreSaveGameImage() finished.\n");
+}
+
+/*
+ * Restore a screenshot from a savegame file
+ *
+ * TODO: Width and height are currently hardcoded,
+ * find a fix
+ */
+static void GetSaveGameImage() {
+	int width = 250, height = 188;
+	char *filename, *data;
+	Bitmap *screenshot;
+	int dataSize;
+	
+	printf("GetSaveGameImage() started.\n");
+	DEBUG_FUNCTION();
+	filename = luaL_check_string(1);
+	SaveGame *savedState = new SaveGame(filename, false);
+	dataSize = savedState->beginSection('SIMG');
+	data = (char *) malloc(dataSize);
+	savedState->readBlock(data, dataSize);
+	screenshot = new Bitmap(data, width, height, "screenshot");
+	if (screenshot) {
+		lua_pushusertag(screenshot, MKID('VBUF'));
+	} else {
+		lua_pushnil();
+		error("Could not restore screenshot from file!");
+	}
+	savedState->endSection();
+	printf("GetSaveGameImage() finished.\n");
+}
+
 static void SubmitSaveGameData() {
 	lua_Object table, table2;
-	int dataSize = 0;
+	SaveGame *savedState;
 	int count = 0;
 	char *str;
 	
+	printf("SubmitSaveGameData() started.\n");
 	DEBUG_FUNCTION();
 	table = lua_getparam(1);
-	for (;;) {
-		lua_pushobject(table);
-		lua_pushnumber(count);
-		count++;
-		table2 = lua_gettable();
-		if (lua_isnil(table2))
-			break;
-		str = lua_getstring(table2);
-		dataSize += strlen(str) + 1;
-		dataSize += 4;
-	}
-	if (dataSize == 0)
-		return;
 
-	g_engine->savegameGzwrite(&dataSize, sizeof(int));
+	savedState = g_engine->savedState();
+	if (savedState == NULL)
+		error("Cannot obtain saved game!");
+	savedState->beginSection('SUBS');
 	count = 0;
 	for (;;) {
 		lua_pushobject(table);
@@ -2841,26 +2887,30 @@
 		if (lua_isnil(table2))
 			break;
 		str = lua_getstring(table2);
+		// Leave out an apparently bogus option
+		if (!strcmp(str, "000000000000000000000000000000000000000000000000000000000000"))
+			continue;
 		int len = strlen(str) + 1;
-		g_engine->savegameGzwrite(&len, sizeof(int));
-		g_engine->savegameGzwrite(str, len);
+		savedState->writeBlock(&len, sizeof(int));
+		savedState->writeBlock(str, len);
 	}
+	savedState->endSection();
+	printf("SubmitSaveGameData() finished.\n");
+	StoreSaveGameImage(savedState);
 }
 
 static void GetSaveGameData() {
 	lua_Object result;
 	char *filename;
 	int dataSize;
-	gzFile file;
 	
+	printf("GetSaveGameData() started.\n");
 	DEBUG_FUNCTION();
 	filename = luaL_check_string(1);
-	file = gzopen(filename, "rb");
-	if (!file)
-		return;
+	SaveGame *savedState = new SaveGame(filename, false);
+	dataSize = savedState->beginSection('SUBS');
 
 	result = lua_createtable();
-	gzread(file, &dataSize, sizeof(int));
 
 	char str[128];
 	int strSize;
@@ -2875,8 +2925,8 @@
 	for (;;) {
 		if (dataSize <= 0)
 			break;
-		gzread(file, &strSize, sizeof(int));
-		gzread(file, str, strSize);
+		savedState->readBlock(&strSize, sizeof(int));
+		savedState->readBlock(str, strSize);
 		lua_pushobject(result);
 		lua_pushnumber(count);
 		lua_pushstring(str);
@@ -2885,10 +2935,11 @@
 		dataSize -= 4;
 		count++;
 	}
-
+	savedState->endSection();
 	lua_pushobject(result);
 
-	gzclose(file);
+	delete savedState;
+	printf("GetSaveGameData() finished.\n");
 }
 
 static void Load() {
@@ -2925,12 +2976,12 @@
 	g_engine->_savegameSaveRequest = true;
 }
 
-static int SaveCallback(int /*tag*/, int value, SaveRestoreFunc /*saveFunc*/) {
+static int SaveCallback(int /*tag*/, int value, SaveGame * /*savedState*/) {
 	DEBUG_FUNCTION();
 	return value;
 }
 
-static int RestoreCallback(int /*tag*/, int value, SaveRestoreFunc /*saveFunc*/) {
+static int RestoreCallback(int /*tag*/, int value, SaveGame * /*savedState*/) {
 	DEBUG_FUNCTION();
 	return value;
 }
@@ -3120,7 +3171,6 @@
 STUB_FUNC(ResetTextures)
 STUB_FUNC(AttachToResources)
 STUB_FUNC(DetachFromResources)
-STUB_FUNC(GetSaveGameImage)
 STUB_FUNC(IrisUp)
 STUB_FUNC(IrisDown)
 STUB_FUNC(FadeInChore)

Index: engine.cpp
===================================================================
RCS file: /cvsroot/scummvm/residual/engine.cpp,v
retrieving revision 1.97
retrieving revision 1.98
diff -u -d -r1.97 -r1.98
--- engine.cpp	28 Aug 2005 23:25:14 -0000	1.97
+++ engine.cpp	26 Dec 2005 02:36:00 -0000	1.98
@@ -24,6 +24,7 @@
 #include "textobject.h"
 #include "smush.h"
 #include "driver.h"
+#include "savegame.h"
 
 #include "imuse/imuse.h"
 
@@ -63,6 +64,7 @@
 	_flipEnable = true;
 	_refreshDrawNeeded = true;
 	g_searchFile = NULL;
+	_savedState = NULL;
 
 	textObjectDefaults.x = 0;
 	textObjectDefaults.y = 200;
@@ -393,14 +395,6 @@
 	}
 }
 
-void Engine::savegameGzread(void *data, int size) {
-	gzread(g_engine->_savegameFileHandle, data, size);
-}
-
-void Engine::savegameGzwrite(void *data, int size) {
-	gzwrite(g_engine->_savegameFileHandle, data, size);
-}
-
 void Engine::savegameRestore() {
 	printf("Engine::savegameRestore() started.\n");
 	_savegameLoadRequest = false;
@@ -410,11 +404,7 @@
 	} else {
 		strcpy(filename, _savegameFileName);
 	}
-	_savegameFileHandle = gzopen(filename, "rb");
-	if (_savegameFileHandle == NULL) {
-		warning("savegameRestore() Error opening savegame file");
-		return;
-	}
+	_savedState = new SaveGame(filename, false);
 
 	g_imuse->stopAllSounds();
 	g_imuse->resetState();
@@ -425,25 +415,18 @@
 	//  free all resource
 	//  lock resources
 
-	uint32 tag;
-	uint32 version;
-	savegameGzread(&tag, 4);
-	assert(tag == 'RSAV');
-	savegameGzread(&version, 4);
-	assert(version == 1);
-
-	//Chore_Restore(savegameGzread);
-	//Resource_Restore(savegameGzread);
-	//Text_Restore(savegameGzread);
-	//Room_Restore(savegameGzread);
-	//Actor_Restore(savegameGzread);
-	//Render_Restore(savegameGzread);
-	//Primitive_Restore(savegameGzread);
-	//Smush_Restore(savegameGzread);
-	g_imuse->restoreState(savegameGzread);
-	lua_Restore(savegameGzread);
+	//Chore_Restore(_savedState);
+	//Resource_Restore(_savedState);
+	//Text_Restore(_savedState);
+	//Room_Restore(_savedState);
+	//Actor_Restore(_savedState);
+	//Render_Restore(_savedState);
+	//Primitive_Restore(_savedState);
+	//Smush_Restore(_savedState);
+	g_imuse->restoreState(_savedState);
+	lua_Restore(_savedState);
 	//  unlock resources
-	gzclose(_savegameFileHandle);
+	delete _savedState;
 
 	//bundle_dofile("patch05.bin");
 
@@ -461,34 +444,25 @@
 	} else {
 		strcpy(filename, _savegameFileName);
 	}
-	_savegameFileHandle = gzopen(filename, "wb");
-	if (_savegameFileHandle == NULL) {
-		warning("savegameSave() Error creating savegame file");
-		return;
-	}
+	_savedState = new SaveGame(filename, true);
 
 	g_imuse->pause(true);
 	g_smush->pause(true);
 
-	uint32 tag = 'RSAV';
-	uint32 version = 1;
-	savegameGzwrite(&tag, 4);
-	savegameGzwrite(&version, 4);
-
 	savegameCallback();
 
-	//Chore_Save(savegameGzwrite);
-	//Resource_Save(savegameGzwrite);
-	//Text_Save(savegameGzwrite);
-	//Room_Save(savegameGzwrite);
-	//Actor_Save(savegameGzwrite);
-	//Render_Save(savegameGzwrite);
-	//Primitive_Save(savegameGzwrite);
-	//Smush_Save(savegameGzwrite);
-	g_imuse->saveState(savegameGzwrite);
-	lua_Save(savegameGzwrite);
+	//Chore_Save(_savedState);
+	//Resource_Save(_savedState);
+	//Text_Save(_savedState);
+	//Room_Save(_savedState);
+	//Actor_Save(_savedState);
+	//Render_Save(_savedState);
+	//Primitive_Save(_savedState);
+	//Smush_Save(_savedState);
+	g_imuse->saveState(_savedState);
+	lua_Save(_savedState);
 
-	gzclose(_savegameFileHandle);
+	delete _savedState;
 
 	g_imuse->pause(false);
 	g_smush->pause(false);

Index: engine.h
===================================================================
RCS file: /cvsroot/scummvm/residual/engine.h,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -d -r1.38 -r1.39
--- engine.h	28 Aug 2005 23:25:14 -0000	1.38
+++ engine.h	26 Dec 2005 02:36:00 -0000	1.39
@@ -28,7 +28,6 @@
 #include <cstdlib>
 #include <list>
 #include <SDL_keysym.h>
-#include <zlib.h>
 
 class Actor;
 
@@ -103,6 +102,7 @@
 	int getPreviousMode() { return _previousMode; }
 	void setSpeechMode(int mode) { _speechMode = mode; }
 	int getSpeechMode() { return _speechMode; }
+	SaveGame *savedState() { return _savedState; }
 
 	void handleDebugLoadResource();
 	void luaUpdate();
@@ -201,14 +201,12 @@
 
 	void savegameSave();
 	void savegameRestore();
-	static void savegameGzread(void *data, int size);
-	static void savegameGzwrite(void *data, int size);
 	void savegameCallback();
 
 	bool _savegameLoadRequest;
 	bool _savegameSaveRequest;
 	char *_savegameFileName;
-	gzFile _savegameFileHandle;
+	SaveGame *_savedState;
 
 	Engine();
 	~Engine() {}

Index: Makefile.common
===================================================================
RCS file: /cvsroot/scummvm/residual/Makefile.common,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- Makefile.common	7 Apr 2005 19:30:30 -0000	1.20
+++ Makefile.common	26 Dec 2005 02:36:00 -0000	1.21
@@ -64,6 +64,7 @@
 	driver_gl.o \
 	driver_tinygl.o \
 	engine.o \
+	savegame.o \
 	font.o \
 	keyframe.o \
 	lab.o \





More information about the Scummvm-git-logs mailing list