[Scummvm-cvs-logs] SF.net SVN: scummvm: [31794] scummvm/trunk/engines/made

john_doe at users.sourceforge.net john_doe at users.sourceforge.net
Wed Apr 30 22:36:20 CEST 2008


Revision: 31794
          http://scummvm.svn.sourceforge.net/scummvm/?rev=31794&view=rev
Author:   john_doe
Date:     2008-04-30 13:36:19 -0700 (Wed, 30 Apr 2008)

Log Message:
-----------
Implemented savegame loading/saving and sprite clipping
Fixed bug in Screen::printTextEx
Implemented opcodes:
- o1_DRAWTEXT
- o1_DRAWMENU
- o1_MENUCOUNT
- o1_SAVEGAME
- o1_LOADGAME
- o1_GAMENAME

Modified Paths:
--------------
    scummvm/trunk/engines/made/database.cpp
    scummvm/trunk/engines/made/database.h
    scummvm/trunk/engines/made/screen.cpp
    scummvm/trunk/engines/made/scriptfuncs.cpp

Modified: scummvm/trunk/engines/made/database.cpp
===================================================================
--- scummvm/trunk/engines/made/database.cpp	2008-04-30 20:08:08 UTC (rev 31793)
+++ scummvm/trunk/engines/made/database.cpp	2008-04-30 20:36:19 UTC (rev 31794)
@@ -23,8 +23,10 @@
  *
  */
 
+#include "common/system.h"
 #include "common/endian.h"
 #include "common/util.h"
+#include "common/savefile.h"
 
 #include "made/database.h"
 
@@ -222,8 +224,7 @@
 	uint32 objectsSize = sourceS.readUint32LE();
 	_mainCodeObjectIndex = sourceS.readUint16LE();
 	
-	debug(2, "objectIndexOffs = %08X; objectCount = %d; gameStateOffs = %08X; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d\n",
-		objectIndexOffs, objectCount, gameStateOffs, _gameStateSize, objectsOffs, objectsSize);
+	//debug(2, "objectIndexOffs = %08X; objectCount = %d; gameStateOffs = %08X; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d\n", objectIndexOffs, objectCount, gameStateOffs, _gameStateSize, objectsOffs, objectsSize);
 
 	_gameState = new byte[_gameStateSize];
 	sourceS.seek(gameStateOffs);
@@ -241,14 +242,14 @@
 		// Constant objects are loaded from disk, while variable objects exist
 		// in the _gameState buffer.
 		
-		debug(2, "obj(%04X) ofs = %08X\n", i, objectOffsets[i]);
+		//debug(2, "obj(%04X) ofs = %08X\n", i, objectOffsets[i]);
 		
 		if (objectOffsets[i] & 1) {
-			debug(2, "-> const %08X\n", objectsOffs + objectOffsets[i] - 1);
+			//debug(2, "-> const %08X\n", objectsOffs + objectOffsets[i] - 1);
 			sourceS.seek(objectsOffs + objectOffsets[i] - 1);
 			obj->load(sourceS);
 		} else {
-			debug(2, "-> var\n");
+			//debug(2, "-> var\n");
 			obj->load(_gameState + objectOffsets[i]);
 		}
 		_objects.push_back(obj);
@@ -256,6 +257,79 @@
 
 }
 
+bool GameDatabase::getSavegameDescription(const char *filename, Common::String &description) {
+
+	Common::InSaveFile *in;
+
+	if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
+		return false;
+	}
+
+	char desc[64];
+
+	in->skip(4); // TODO: Verify marker 'SGAM'
+	in->skip(4); // TODO: Verify size
+	in->skip(2); // TODO: Verify version
+	in->read(desc, 64);
+	description = desc;
+
+	printf("description = %s\n", description.c_str()); fflush(stdout);
+
+	delete in;
+	
+	return true;
+	
+}
+
+int16 GameDatabase::savegame(const char *filename, const char *description, int16 version) {
+
+	Common::OutSaveFile *out;
+
+	if (!(out = g_system->getSavefileManager()->openForSaving(filename))) {
+		warning("Can't create file '%s', game not saved", filename);
+		return 6;
+	}
+	
+	uint32 size = 4 + 4 + 2 + _gameStateSize;
+	char desc[64];
+	
+	strncpy(desc, description, 64);
+	
+	out->writeUint32BE(MKID_BE('SGAM'));
+	out->writeUint32LE(size);
+	out->writeUint16LE(version);
+	out->write(desc, 64);
+	out->write(_gameState, _gameStateSize);
+
+	delete out;
+
+	return 0;
+
+}
+
+int16 GameDatabase::loadgame(const char *filename, int16 version) {
+
+	Common::InSaveFile *in;
+
+	if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
+		warning("Can't open file '%s', game not loaded", filename);
+		return 1;
+	}
+
+	//uint32 expectedSize = 4 + 4 + 2 + _gameStateSize;
+
+	in->skip(4); // TODO: Verify marker 'SGAM'
+	in->skip(4); // TODO: Verify size
+	in->skip(2); // TODO: Verify version
+	in->skip(64); // skip savegame description
+	in->read(_gameState, _gameStateSize);
+
+	delete in;
+
+	return 0;
+
+}
+
 int16 GameDatabase::getVar(int16 index) {
 	return (int16)READ_LE_UINT16(_gameState + index * 2);
 }

Modified: scummvm/trunk/engines/made/database.h
===================================================================
--- scummvm/trunk/engines/made/database.h	2008-04-30 20:08:08 UTC (rev 31793)
+++ scummvm/trunk/engines/made/database.h	2008-04-30 20:36:19 UTC (rev 31794)
@@ -30,6 +30,7 @@
 #include "common/util.h"
 #include "common/file.h"
 #include "common/stream.h"
+#include "common/str.h"
 
 #include "made/redreader.h"
 
@@ -78,6 +79,10 @@
 	void open(const char *filename);
 	void openFromRed(const char *redFilename, const char *filename);
 
+	bool getSavegameDescription(const char *filename, Common::String &description);
+	int16 savegame(const char *filename, const char *description, int16 version);
+	int16 loadgame(const char *filename, int16 version);
+
 	Object *getObject(int16 index) const { 
 		if (index >= 1)
 			return _objects[index - 1];

Modified: scummvm/trunk/engines/made/screen.cpp
===================================================================
--- scummvm/trunk/engines/made/screen.cpp	2008-04-30 20:08:08 UTC (rev 31793)
+++ scummvm/trunk/engines/made/screen.cpp	2008-04-30 20:36:19 UTC (rev 31794)
@@ -92,23 +92,41 @@
 	_screen1->fillRect(Common::Rect(0, 0, 320, 200), 0);
 	_screen2->fillRect(Common::Rect(0, 0, 320, 200), 0);
 	_needPalette = true;
-	//_vm->_system->clearScreen();
 }
 
 void Screen::drawSurface(Graphics::Surface *sourceSurface, int x, int y, const ClipInfo &clipInfo) {
 
-	byte *source = (byte*)sourceSurface->getBasePtr(0, 0);
-	byte *dest = (byte*)clipInfo.destSurface->getBasePtr(x, y);
+	byte *source, *dest;
+	int startX = 0;
+	int startY = 0;
+	int clipWidth = sourceSurface->w;
+	int clipHeight = sourceSurface->h;
+	
+	if (x < 0) {
+		startX = -x;
+		clipWidth -= startX;
+		x = 0;
+	}
 
-	// FIXME: Implement actual clipping
-	if (x + sourceSurface->w > clipInfo.destSurface->w || y + sourceSurface->h > clipInfo.destSurface->h) {
-		debug(2, "CLIPPING PROBLEM: x = %d; y = %d; w = %d; h = %d; x+w = %d; y+h = %d\n",
-			x, y, sourceSurface->w, sourceSurface->h, x + sourceSurface->w, y + sourceSurface->h);
-		return;
+	if (y < 0) {
+		startY = -y;
+		clipHeight -= startY;
+		y = 0;
 	}
 
-	for (int16 yc = 0; yc < sourceSurface->h; yc++) {
-		for (int16 xc = 0; xc < sourceSurface->w; xc++) {
+	if (x + clipWidth > clipInfo.x + clipInfo.w) {
+		clipWidth = clipInfo.x + clipInfo.w - x;
+	}
+
+	if (y + clipHeight > clipInfo.y + clipInfo.h) {
+		clipHeight = clipInfo.y + clipInfo.h - y;
+	}
+
+	source = (byte*)sourceSurface->getBasePtr(startX, startY);
+	dest = (byte*)clipInfo.destSurface->getBasePtr(x, y);
+
+	for (int16 yc = 0; yc < clipHeight; yc++) {
+		for (int16 xc = 0; xc < clipWidth; xc++) {
 			if (source[xc])
 				dest[xc] = source[xc];
 		}
@@ -133,7 +151,7 @@
 }
 
 uint16 Screen::updateChannel(uint16 channelIndex) {
-	return 0;
+	return channelIndex;
 }
 
 void Screen::deleteChannel(uint16 channelIndex) {
@@ -303,10 +321,6 @@
 }
 
 uint16 Screen::drawPic(uint16 index, int16 x, int16 y, uint16 flag1, uint16 flag2) {
-
-	//HACK (until clipping is implemented)
-	if (y > 200) y = 0;
-
 	drawFlex(index, x, y, flag1, flag2, _clipInfo1);
 	return 0;
 }
@@ -624,7 +638,6 @@
 			linePos = 1;
 			x = _textRect.left;
 		} else if (c == 32) {
-			// TODO: Word-wrap
 			int wrapPos = textPos + 1;
 			int wrapX = x + charWidth;
 			while (wrapPos < textLen && text[wrapPos] != 0 && text[wrapPos] != 32 && text[wrapPos] >= 28) {
@@ -682,6 +695,7 @@
 
 	int16 oldFontNum = _currentFontNum;
 	Common::Rect oldTextRect;
+	ClipInfo oldFontDrawCtx = _fontDrawCtx;
 
 	_fontDrawCtx = clipInfo;
 	
@@ -693,6 +707,7 @@
 	printText(text);
 	setTextRect(oldTextRect);
 	setFont(oldFontNum);
+	_fontDrawCtx = oldFontDrawCtx;
 	
 }
 

Modified: scummvm/trunk/engines/made/scriptfuncs.cpp
===================================================================
--- scummvm/trunk/engines/made/scriptfuncs.cpp	2008-04-30 20:08:08 UTC (rev 31793)
+++ scummvm/trunk/engines/made/scriptfuncs.cpp	2008-04-30 20:36:19 UTC (rev 31794)
@@ -408,9 +408,9 @@
 }
 
 int16 ScriptFunctionsRtz::o1_DRAWTEXT(int16 argc, int16 *argv) {
-	warning("Unimplemented opcode: o1_DRAWTEXT");
 	Object *obj = _vm->_dat->getObject(argv[argc - 1]);
-	warning("argc = %d; drawText = %s", argc, obj->getString());
+	const char *text = obj->getString();
+	_vm->_screen->printText(text);
 	return 0;
 }
 
@@ -420,7 +420,6 @@
 }
 
 int16 ScriptFunctionsRtz::o1_TEXTRECT(int16 argc, int16 *argv) {
-	warning("Unimplemented opcode: o1_TEXTRECT");
 	int16 x1 = CLIP<int16>(argv[4], 1, 318);
 	int16 y1 = CLIP<int16>(argv[3], 1, 198);
 	int16 x2 = CLIP<int16>(argv[2], 1, 318);
@@ -536,7 +535,9 @@
 }
 
 int16 ScriptFunctionsRtz::o1_PRINTF(int16 argc, int16 *argv) {
-	warning("Unimplemented opcode: o1_PRINTF");
+	Object *obj = _vm->_dat->getObject(argv[argc - 1]);
+	const char *text = obj->getString();
+	debug(4, "--> text = %s", text);
 	return 0;
 }
 
@@ -556,7 +557,7 @@
 
 int16 ScriptFunctionsRtz::o1_CLEARTEXT(int16 argc, int16 *argv) {
 	warning("Unimplemented opcode: o1_CLEARTEXT");
-	return 0;
+	return 1;
 }
 
 int16 ScriptFunctionsRtz::o1_ANIMTEXT(int16 argc, int16 *argv) {
@@ -746,33 +747,89 @@
 }
 
 int16 ScriptFunctionsRtz::o1_DRAWMENU(int16 argc, int16 *argv) {
-	warning("Unimplemented opcode: o1_DRAWMENU");
+	int16 menuIndex = argv[1];
+	int16 textIndex = argv[0];
+	MenuResource *menu = _vm->_res->getMenu(menuIndex);
+	if (menu) {
+		const char *text = menu->getString(textIndex);
+		if (text)
+			_vm->_screen->printText(text);
+		_vm->_res->freeResource(menu);
+	}
 	return 0;
 }
 
 int16 ScriptFunctionsRtz::o1_MENUCOUNT(int16 argc, int16 *argv) {
-	warning("Unimplemented opcode: o1_MENUCOUNT");
-	return 0;
+	int16 menuIndex = argv[0];
+	int16 count = 0;
+	MenuResource *menu = _vm->_res->getMenu(menuIndex);
+	if (menu) {
+		count = menu->getCount();
+		_vm->_res->freeResource(menu);
+	}
+	return count;
 }
 
 int16 ScriptFunctionsRtz::o1_SAVEGAME(int16 argc, int16 *argv) {
-	warning("Unimplemented opcode: o1_SAVEGAME");
-	return 0;
+	
+	int16 saveNum = argv[2];
+	int16 descObjectIndex = argv[1];
+	int16 version = argv[0];
+	
+	if (saveNum > 999)
+		return 6;
+
+	Object *obj = _vm->_dat->getObject(descObjectIndex);
+	const char *description = obj->getString();
+
+	// TODO: Use better filename
+	char filename[256];
+	snprintf(filename, 256, "rtz.%03d", saveNum);
+	
+	return _vm->_dat->savegame(filename, description, version);
+	
 }
 
 int16 ScriptFunctionsRtz::o1_LOADGAME(int16 argc, int16 *argv) {
-	warning("Unimplemented opcode: o1_LOADGAME");
-	return 0;
+
+	int16 saveNum = argv[1];
+	int16 version = argv[0];
+
+	if (saveNum > 999)
+		return 1;
+
+	// TODO: Use better filename
+	char filename[256];
+	snprintf(filename, 256, "rtz.%03d", saveNum);
+
+	return _vm->_dat->loadgame(filename, version);
+	
 }
 
 int16 ScriptFunctionsRtz::o1_GAMENAME(int16 argc, int16 *argv) {
-	warning("Unimplemented opcode: o1_GAMENAME");
 	
-	warning("GAMENAME: 1) %d\n", argv[2]);
-	warning("GAMENAME: 2) %d\n", argv[1]);
-	warning("GAMENAME: 3) %d\n", argv[0]);
+	int16 descObjectIndex = argv[2];
+	int16 saveNum = argv[1];
+	int16 version = argv[0];
+	Common::String description;
 
-	return 0;
+	if (saveNum > 999)
+		return 1;
+
+	// TODO: Use better filename
+	char filename[256];
+	snprintf(filename, 256, "rtz.%03d", saveNum);
+
+	Object *obj = _vm->_dat->getObject(descObjectIndex);
+
+	if (_vm->_dat->getSavegameDescription(filename, description)) {
+		obj->setString(description.c_str());
+		return 0;
+	} else {
+		obj->setString("");
+		return 1;
+	}
+
 }
 
 int16 ScriptFunctionsRtz::o1_SHAKESCREEN(int16 argc, int16 *argv) {


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list