[Scummvm-cvs-logs] CVS: scummvm/kyra kyra.cpp,1.82,1.83 kyra.h,1.43,1.44 script_v1.cpp,1.36,1.37

Oystein Eftevaag vinterstum at users.sourceforge.net
Sat Dec 10 09:52:01 CET 2005


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

Modified Files:
	kyra.cpp kyra.h script_v1.cpp 
Log Message:
Implemented basic saving and loading. Use Ctrl+(0-9) to save, and
Alt+(0-9) to load. Also extended the FastMode functionality to cover
the main game, hit Ctrl-F to speed animations and chats. Set '.' to skip
Brandon's chats, removed a redundant showMouse() and hideMouse() pair,
and simplified some screen updating code.


Index: kyra.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/kyra.cpp,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -d -r1.82 -r1.83
--- kyra.cpp	10 Dec 2005 15:52:38 -0000	1.82
+++ kyra.cpp	10 Dec 2005 17:51:40 -0000	1.83
@@ -30,6 +30,7 @@
 #include "common/file.h"
 #include "common/system.h"
 #include "common/md5.h"
+#include "common/savefile.h"
 
 #include "sound/mixer.h"
 #include "sound/mididrv.h"
@@ -264,6 +265,8 @@
 	_midi->hasNativeMT32(native_mt32);
 	_midi->setVolume(255);
 	
+	_saveFileMan = _system->getSavefileManager();
+	assert(_saveFileMan);	
 	_res = new Resource(this);
 	assert(_res);
 	_screen = new Screen(this, _system);
@@ -370,6 +373,7 @@
 	delete _screen;
 	delete _res;
 	delete _midi;
+	delete _saveFileMan;
 	delete _seq;
 	delete _scriptInterpreter;
 	
@@ -511,6 +515,8 @@
 
 void KyraEngine::delay(uint32 amount) {
 	OSystem::Event event;
+	char saveLoadSlot[20];
+
 	uint32 start = _system->getMillis();
 	do {
 		while (_system->pollEvent(event)) {
@@ -520,6 +526,15 @@
 					_quitFlag = true;
 				} else if (event.kbd.keycode == 'd' && !_debugger->isAttached()) {
 					_debugger->attach();
+				} else if (event.kbd.keycode >= '0' && event.kbd.keycode <= '9' && 
+						(event.kbd.flags == OSystem::KBD_CTRL || event.kbd.flags == OSystem::KBD_ALT)) {
+					sprintf(saveLoadSlot, "KYRA1.00%i", event.kbd.keycode - '0');
+					if (event.kbd.flags == OSystem::KBD_CTRL)
+						saveGame(saveLoadSlot, saveLoadSlot);
+					else
+						loadGame(saveLoadSlot);
+				}	else if (event.kbd.flags == OSystem::KBD_CTRL && event.kbd.keycode == 'f') {
+						_fastMode = !_fastMode;
 				}
 				break;
 			case OSystem::EVENT_MOUSEMOVE:
@@ -556,7 +571,7 @@
 		if (amount > 0) {
 			_system->delayMillis((amount > 10) ? 10 : amount);
 		}
-	} while (_system->getMillis() < start + amount);
+	} while (!_fastMode && _system->getMillis() < start + amount);
 }
 
 void KyraEngine::mainLoop() {
@@ -1971,9 +1986,7 @@
 	restoreAllObjectBackgrounds();
 	preserveAnyChangedBackgrounds();
 	prepDrawAllObjects();
-	_screen->hideMouse();
 	initSceneScreen(brandonAlive);
-	_screen->showMouse();
 	copyChangedObjectsForward(0);
 }
 
@@ -2255,7 +2268,7 @@
 		while (_system->pollEvent(event)) {
 			switch (event.type) {
 			case OSystem::EVENT_KEYDOWN:
-				if (event.kbd.keycode == 0x20 || event.kbd.keycode == 0xC6)
+				if (event.kbd.keycode == '.')
 					runLoop = false;
 				break;
 			case OSystem::EVENT_QUIT:
@@ -2267,6 +2280,9 @@
 				break;
 			}
 		}
+		
+		if (_fastMode)
+			runLoop = false;
 
 		delayTime = (loopStart + _gameSpeed) - _system->getMillis();
 		if (delayTime > 0)
@@ -2285,6 +2301,7 @@
 
 	if (charNum > 4 && charNum < 11) {
 		//TODO: weird _game_inventory stuff here
+		warning("STUB: endCharacterChat() for high charnums");
 	}
 
 	if (convoInitialized != 0) {
@@ -2364,6 +2381,7 @@
 
 	if (charNum > 4 && charNum < 11) {
 		// TODO: Fill in weird _game_inventory stuff here
+		warning("STUB: initCharacterChat() for high charnums");
 	}
 
 	flagAllObjectsForRefresh();
@@ -3377,7 +3395,6 @@
 void KyraEngine::copyChangedObjectsForward(int refreshFlag) {
 	debug(9, "copyChangedObjectsForward(%d)", refreshFlag);
 	AnimObject *curObject = _objectQueue;
-	bool changed = false;
 
 	while (curObject) {
 		if (curObject->active) {
@@ -3402,13 +3419,15 @@
 				
 				_screen->copyRegion(xpos, ypos, xpos, ypos, width, height, 2, 0, Screen::CR_CLIPPED);
 				curObject->refreshFlag = 0;
-				changed = true;
+				_updateScreen = true;
 			}
 		}
 		curObject = curObject->nextAnimObject;
 	}
-	if (changed)
+	if (_updateScreen) {
 		_screen->updateScreen();
+		_updateScreen = false;
+	}
 }
 
 void KyraEngine::updateAllObjectShapes() {
@@ -4941,4 +4960,156 @@
 	}
 }
 
+#pragma mark -
+#pragma mark - Saving/loading
+#pragma mark -
+
+void KyraEngine::loadGame(const char *fileName) {
+	debug(9, "loadGame('%s')", fileName);
+	Common::InSaveFile *in;
+
+	if (!(in = _saveFileMan->openForLoading(fileName))) {
+		warning("Can't open file '%s', game not loaded", fileName);
+		return;
+	}
+
+	if (in->readByte() != 1) {
+		warning("Savegame is not the right version");
+		delete in;
+		return;
+	}
+
+	char saveName[31];
+	in->read(saveName, 31);
+
+	for (int i = 0; i < 11; i++) {
+		_characterList[i].sceneId = in->readUint16BE();
+		_characterList[i].height = in->readByte();
+		_characterList[i].facing = in->readByte();
+		_characterList[i].currentAnimFrame = in->readUint16BE();
+		_characterList[i].unk6 = in->readUint32BE();
+		in->read(_characterList[i].inventoryItems, 10);
+		_characterList[i].x1 = in->readSint16BE();
+		_characterList[i].y1 = in->readSint16BE();
+		_characterList[i].x2 = in->readSint16BE();
+		_characterList[i].y1 = in->readSint16BE();
+		_characterList[i].field_20 = in->readUint16BE();
+		_characterList[i].field_23 = in->readUint16BE();
+	}
+
+	_marbleVaseItem = in->readSint16BE();
+	_itemInHand = in->readByte();
+
+	for (int i = 0; i < 32; i++) {
+		_timers[i].countdown = in->readSint32BE();
+		_timers[i].nextRun = in->readUint32BE();
+	}
+	_timerNextRun = 0;
+
+	in->read(_flagsTable, sizeof(_flagsTable));
+
+	for (int i = 0; i < _roomTableSize; ++i) {
+		for (int item = 0; item < 12; ++item) {
+			_roomTable[i].itemsTable[item] = 0xFF;
+			_roomTable[i].itemsXPos[item] = 0xFFFF;
+			_roomTable[i].itemsYPos[item] = 0xFF;
+			_roomTable[i].unkField3[item] = 0;
+		}
+	}
+
+	uint16 sceneId;
+	uint8 itemCount;
+
+	while (!in->eos()) {
+		sceneId = in->readUint16BE();
+		if (sceneId == 0xffff)
+			break;
+
+		itemCount = in->readByte();
+		for (int i = 0; i < itemCount; i++) {
+			_roomTable[sceneId].itemsTable[i] = in->readByte();
+			_roomTable[sceneId].itemsXPos[i] = in->readUint16BE();
+			_roomTable[sceneId].itemsYPos[i] = in->readUint16BE();
+			_roomTable[sceneId].unkField3[i] = in->readUint32BE();
+			
+		}
+	}
+
+	createMouseItem(_itemInHand);
+	enterNewScene(_currentCharacter->sceneId, _currentCharacter->facing, 0, 0, 1);
+
+	if (in->ioFailed())
+		error("Load failed.");
+	else
+		debug(1, "Loaded savegame '%s.'", saveName);
+
+	delete in;
+}
+
+void KyraEngine::saveGame(const char *fileName, const char *saveName) {
+	debug(9, "saveGame('%s', '%s')", fileName, saveName);
+	Common::OutSaveFile *out;
+
+	if (!(out = _saveFileMan->openForSaving(fileName))) {
+		warning("Can't create file '%s', game not saved", fileName);
+		return;
+	}
+
+	// Savegame version
+	out->writeByte(1);
+	out->write(saveName, 31);
+
+	for (int i = 0; i < 11; i++) {
+		out->writeUint16BE(_characterList[i].sceneId);
+		out->writeByte(_characterList[i].height);
+		out->writeByte(_characterList[i].facing);
+		out->writeUint16BE(_characterList[i].currentAnimFrame);
+		out->writeUint32BE(_characterList[i].unk6);
+		out->write(_characterList[i].inventoryItems, 10);
+		out->writeSint16BE(_characterList[i].x1);
+		out->writeSint16BE(_characterList[i].y1);
+		out->writeSint16BE(_characterList[i].x2);
+		out->writeSint16BE(_characterList[i].y1);
+		out->writeUint16BE(_characterList[i].field_20);
+		out->writeUint16BE(_characterList[i].field_23);
+	}
+	
+	out->writeSint16BE(_marbleVaseItem);
+	out->writeByte(_itemInHand);
+
+	for (int i = 0; i < 32; i++) {
+		out->writeSint32BE(_timers[i].countdown);
+		out->writeUint32BE(_timers[i].nextRun);
+	}
+
+	out->write(_flagsTable, sizeof(_flagsTable));
+
+	uint8 itemCount;
+	for (int i = 0; i < _roomTableSize; i++) {
+		itemCount = countItemsInScene(i);
+		if (itemCount > 0) {
+			out->writeUint16BE(i);
+			out->writeByte(itemCount);
+			for (int a = 0; a < 12; a++) {
+				if (_roomTable[i].itemsTable[a] != 0xff) {
+					out->writeByte(_roomTable[i].itemsTable[a]);
+					out->writeUint16BE(_roomTable[i].itemsXPos[a]);
+					out->writeUint16BE(_roomTable[i].itemsYPos[a]);
+					out->writeUint32BE(_roomTable[i].unkField3[a]);
+				}
+			}
+		}	
+	}
+
+	out->flush();
+
+	// check for errors
+	if (out->ioFailed())
+		warning("Can't write file '%s'. (Disk full?)", fileName);
+	else
+		debug(1, "Saved game '%s.'", saveName);
+
+	delete out;
+}
+
 } // End of namespace Kyra

Index: kyra.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/kyra.h,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- kyra.h	10 Dec 2005 15:52:38 -0000	1.43
+++ kyra.h	10 Dec 2005 17:51:40 -0000	1.44
@@ -228,6 +228,9 @@
 	int16 fetchAnimWidth(const uint8 *shape, int16 mult);
 	int16 fetchAnimHeight(const uint8 *shape, int16 mult);
 	
+	void saveGame(const char *fileName, const char *saveName);
+	void loadGame(const char *fileName);
+
 	int mouseX() { return _mouseX; }
 	int mouseY() { return _mouseY; }
 	
@@ -570,10 +573,11 @@
 	uint16 _tickLength;
 	uint32 _features;
 	int _mouseX, _mouseY;
-	int _itemInHand;
+	int8 _itemInHand;
 	int _mouseState;
 	bool _handleInput;
-	
+	bool _updateScreen;
+
 	WSAMovieV1 *_wsaObjects[10];
 	uint16 _entranceMouseCursorTracks[8];
 	uint16 _walkBlockNorth;
@@ -648,7 +652,8 @@
 	Sprites *_sprites;
 	ScriptHelper *_scriptInterpreter;
 	Debugger *_debugger;
-	
+	Common::SaveFileManager *_saveFileMan;
+
 	ScriptState *_scriptMain;
 	
 	ScriptState *_npcScript;

Index: script_v1.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/script_v1.cpp,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- script_v1.cpp	10 Dec 2005 15:52:38 -0000	1.36
+++ script_v1.cpp	10 Dec 2005 17:51:40 -0000	1.37
@@ -314,10 +314,8 @@
 
 	if (_features & GF_TALKIE) {
 		debug(3, "cmd_characterSays(0x%X) (%d, '%s', %d, %d)", script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3));
-		while (snd_voicePlaying()) {
-			_sprites->updateSceneAnims();
-			updateAllObjectShapes();
-			_system->delayMillis(10);
+		while (snd_voicePlaying() && !_fastMode) {
+			delay(10);
 		}
 		snd_playVoiceFile(stackPos(0));
 		characterSays(stackPosString(1), stackPos(2), stackPos(3));
@@ -667,7 +665,7 @@
 			_sprites->updateSceneAnims();
 			updateAllObjectShapes();
 		}
-		_screen->updateScreen();
+		_updateScreen = true;
 	}
 	
 	_screen->showMouse();
@@ -685,7 +683,7 @@
 	_screen->hideMouse();
 	wsa_play(_wsaObjects[wsaIndex], frame, xpos, ypos, 0);
 	delay(waitTime * _tickLength);
-	_screen->updateScreen();
+	_updateScreen = true;
 	_screen->showMouse();
 	return 0;
 }
@@ -779,10 +777,8 @@
 int KyraEngine::cmd_customPrintTalkString(ScriptState *script) {
 	if (_features & GF_TALKIE) {
 		debug(3, "cmd_customPrintTalkString(0x%X) ('%s', %d, %d, %d)", script, stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF);
-		while (snd_voicePlaying()) {
-			_sprites->updateSceneAnims();
-			updateAllObjectShapes();
-			_system->delayMillis(10);
+		while (snd_voicePlaying() && !_fastMode) {
+			delay(10);
 		}
 		snd_playVoiceFile(stackPos(0));
 		printTalkTextMessage(stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF, 0, 2);
@@ -790,7 +786,7 @@
 		debug(3, "cmd_customPrintTalkString(0x%X) ('%s', %d, %d, %d)", script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF);
 		printTalkTextMessage(stackPosString(0), stackPos(1), stackPos(2), stackPos(3) & 0xFF, 0, 2);
 	}
-
+	_updateScreen = true;
 	return 0;
 }
 
@@ -907,7 +903,7 @@
 			while (endFrame >= frame) {
 				wsa_play(_wsaObjects[wsaIndex], frame, xpos, ypos, 0);
 				delay(waitTime * _tickLength);
-				_screen->updateScreen();
+				_updateScreen = true;
 				++frame;
 			}
 		} else {
@@ -915,7 +911,7 @@
 			while (startFrame <= frame) {
 				wsa_play(_wsaObjects[wsaIndex], frame, xpos, ypos, 0);
 				delay(waitTime * _tickLength);
-				_screen->updateScreen();
+				_updateScreen = true;
 				--frame;
 			}
 		}





More information about the Scummvm-git-logs mailing list