[Scummvm-cvs-logs] SF.net SVN: scummvm:[33900] scummvm/trunk/engines/parallaction

peres001 at users.sourceforge.net peres001 at users.sourceforge.net
Fri Aug 15 16:25:44 CEST 2008


Revision: 33900
          http://scummvm.svn.sourceforge.net/scummvm/?rev=33900&view=rev
Author:   peres001
Date:     2008-08-15 14:25:43 +0000 (Fri, 15 Aug 2008)

Log Message:
-----------
Added routines to load and handle item masks: animation are now correctly hidden when they are behind any object. The masks of items that are not explicitly activated (even if visible) still are handled (e.g. the crown in the museum is not visible in the foreground).

Modified Paths:
--------------
    scummvm/trunk/engines/parallaction/disk.h
    scummvm/trunk/engines/parallaction/disk_br.cpp
    scummvm/trunk/engines/parallaction/exec_ns.cpp
    scummvm/trunk/engines/parallaction/graphics.h
    scummvm/trunk/engines/parallaction/objects.h
    scummvm/trunk/engines/parallaction/parser.h
    scummvm/trunk/engines/parallaction/parser_br.cpp

Modified: scummvm/trunk/engines/parallaction/disk.h
===================================================================
--- scummvm/trunk/engines/parallaction/disk.h	2008-08-15 13:50:08 UTC (rev 33899)
+++ scummvm/trunk/engines/parallaction/disk.h	2008-08-15 14:25:43 UTC (rev 33900)
@@ -69,6 +69,7 @@
 	virtual Table* loadTable(const char* name) = 0;
 	virtual Common::SeekableReadStream* loadMusic(const char* name) = 0;
 	virtual Common::ReadStream* loadSound(const char* name) = 0;
+	virtual void loadMask(const char *name, MaskBuffer &buffer) { }
 };
 
 
@@ -248,6 +249,7 @@
 	Table* loadTable(const char* name);
 	Common::SeekableReadStream* loadMusic(const char* name);
 	Common::ReadStream* loadSound(const char* name);
+	void loadMask(const char *name, MaskBuffer &buffer);
 };
 
 class DosDemo_br : public DosDisk_br {

Modified: scummvm/trunk/engines/parallaction/disk_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/disk_br.cpp	2008-08-15 13:50:08 UTC (rev 33899)
+++ scummvm/trunk/engines/parallaction/disk_br.cpp	2008-08-15 14:25:43 UTC (rev 33900)
@@ -357,6 +357,29 @@
 	return;
 }
 
+void DosDisk_br::loadMask(const char *name, MaskBuffer &buffer) {
+	if (!name) {
+		return;
+	}
+
+	Common::String filepath;
+	FilesystemNode node;
+	Common::File stream;
+
+	filepath = Common::String(name) + ".msk";
+	node = _mskDir.getChild(filepath);
+	if (!node.exists()) {
+		errorFileNotFound(_mskDir, filepath);
+	}
+	stream.open(node);
+
+	// NOTE: info.width and info.height are only valid if the background graphics
+	// have already been loaded
+	buffer.bigEndian = false;
+	stream.read(buffer.data, buffer.size);
+	stream.close();
+}
+
 void DosDisk_br::loadScenery(BackgroundInfo& info, const char *name, const char *mask, const char* path) {
 	debugC(5, kDebugDisk, "DosDisk_br::loadScenery");
 

Modified: scummvm/trunk/engines/parallaction/exec_ns.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/exec_ns.cpp	2008-08-15 13:50:08 UTC (rev 33899)
+++ scummvm/trunk/engines/parallaction/exec_ns.cpp	2008-08-15 14:25:43 UTC (rev 33900)
@@ -261,8 +261,13 @@
 
 	if ((z->_type & 0xFFFF) == kZoneGet) {
 		_gfx->showGfxObj(z->u.get->gfxobj, visible);
+
+		GetData *data = z->u.get;
+		if (data->hasMask && _gfx->_backgroundInfo->hasMask) {
+			int frame = visible ? 0 : 1;
+			_gfx->_backgroundInfo->mask.blt(data->gfxobj->x, data->gfxobj->y, data->_mask[frame], 0, 0, data->_mask->w, data->_mask->h);
+		}
 	}
-
 }
 
 DECLARE_COMMAND_OPCODE(on) {

Modified: scummvm/trunk/engines/parallaction/graphics.h
===================================================================
--- scummvm/trunk/engines/parallaction/graphics.h	2008-08-15 13:50:08 UTC (rev 33899)
+++ scummvm/trunk/engines/parallaction/graphics.h	2008-08-15 14:25:43 UTC (rev 33900)
@@ -209,6 +209,32 @@
 		return (m >> n) & 3;
 	}
 
+	inline byte* getPtr(uint16 x, uint16 y) const {
+		return data + (x >> 2) + y * internalWidth;
+	}
+
+	void blt(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height) {
+		assert((width <= w) && (width <= src.w) && (height <= h) && (height <= src.h));
+
+		byte *s = src.getPtr(sx, sy);
+		byte *d = getPtr(dx, dy);
+
+		uint diffs = 0;
+
+		// this code assumes buffers are aligned on 4-pixels boundaries, as the original does
+		uint16 linewidth = width >> 2;
+		for (uint16 i = 0; i < height; i++) {
+			for (uint16 j = 0; j < linewidth; j++) {
+				if (*s) diffs++;
+				*d++ |= *s++;
+			}
+			d += internalWidth - linewidth;
+			s += src.internalWidth - linewidth;
+		}
+
+		printf("MaskBuffer::blt() diffs = %i\n", diffs);
+	}
+
 };
 
 
@@ -419,7 +445,9 @@
 	int 				layers[4];
 	PaletteFxRange		ranges[6];
 
-	BackgroundInfo() : x(0), y(0), width(0), height(0) {
+	bool				hasMask;
+
+	BackgroundInfo() : x(0), y(0), width(0), height(0), hasMask(false) {
 		layers[0] = layers[1] = layers[2] = layers[3] = 0;
 		memset(ranges, 0, sizeof(ranges));
 	}

Modified: scummvm/trunk/engines/parallaction/objects.h
===================================================================
--- scummvm/trunk/engines/parallaction/objects.h	2008-08-15 13:50:08 UTC (rev 33899)
+++ scummvm/trunk/engines/parallaction/objects.h	2008-08-15 14:25:43 UTC (rev 33900)
@@ -198,11 +198,14 @@
 	byte		   *_backup;
 	uint16			field_14;		// unused
 	uint16			field_16;		// unused
+	MaskBuffer		_mask[2];
+	bool			hasMask;
 
 	GetData() {
 		_icon = 0;
 		_backup = NULL;
 		gfxobj = NULL;
+		hasMask = false;
 	}
 };
 struct SpeakData {	// size = 36

Modified: scummvm/trunk/engines/parallaction/parser.h
===================================================================
--- scummvm/trunk/engines/parallaction/parser.h	2008-08-15 13:50:08 UTC (rev 33899)
+++ scummvm/trunk/engines/parallaction/parser.h	2008-08-15 14:25:43 UTC (rev 33900)
@@ -131,9 +131,6 @@
 		// BRA specific
 		int numZones;
 		BackgroundInfo	*info;
-		char *bgName;
-		char *maskName;
-		char *pathName;
 		char *characterName;
 	} ctxt;
 
@@ -306,6 +303,7 @@
 
 	virtual void	parseZoneTypeBlock(ZonePtr z);
 	void			parsePathData(ZonePtr z);
+	void 			parseGetData(ZonePtr z);
 
 public:
 	LocationParser_br(Parallaction_br *vm) : LocationParser_ns((Parallaction_ns*)vm), _vm(vm) {

Modified: scummvm/trunk/engines/parallaction/parser_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parser_br.cpp	2008-08-15 13:50:08 UTC (rev 33899)
+++ scummvm/trunk/engines/parallaction/parser_br.cpp	2008-08-15 14:25:43 UTC (rev 33900)
@@ -316,7 +316,6 @@
 	debugC(7, kDebugParser, "LOCATION_PARSER(location) ");
 
 	strcpy(_vm->_location._name, _tokens[1]);
-	ctxt.bgName = strdup(_tokens[1]);
 
 	bool flip = false;
 	int nextToken;
@@ -340,6 +339,8 @@
 	if (_tokens[nextToken][0] != '\0') {
 		_vm->_char._ani->setF(atoi(_tokens[nextToken]));
 	}
+
+	_vm->_disk->loadScenery(*ctxt.info, _tokens[1], 0, 0);
 }
 
 
@@ -465,18 +466,20 @@
 DECLARE_LOCATION_PARSER(mask)  {
 	debugC(7, kDebugParser, "LOCATION_PARSER(mask) ");
 
-	ctxt.maskName = strdup(_tokens[1]);
 	ctxt.info->layers[0] = 0;
 	ctxt.info->layers[1] = atoi(_tokens[2]);
 	ctxt.info->layers[2] = atoi(_tokens[3]);
 	ctxt.info->layers[3] = atoi(_tokens[4]);
+
+	_vm->_disk->loadScenery(*ctxt.info, 0, _tokens[1], 0);
+	ctxt.info->hasMask = true;
 }
 
 
 DECLARE_LOCATION_PARSER(path)  {
 	debugC(7, kDebugParser, "LOCATION_PARSER(path) ");
 
-	ctxt.pathName = strdup(_tokens[1]);
+	_vm->_disk->loadScenery(*ctxt.info, 0, 0, _tokens[1]);
 }
 
 
@@ -768,6 +771,54 @@
 	z->u.path = data;
 }
 
+void LocationParser_br::parseGetData(ZonePtr z) {
+
+	GetData *data = new GetData;
+
+	do {
+
+		if (!scumm_stricmp(_tokens[0], "file")) {
+
+			GfxObj *obj = _vm->_gfx->loadGet(_tokens[1]);
+			obj->frame = 0;
+			obj->x = z->getX();
+			obj->y = z->getY();
+			data->gfxobj = obj;
+		}
+
+		if (!scumm_stricmp(_tokens[0], "mask")) {
+			if (ctxt.info->hasMask) {
+				Common::Rect rect;
+				data->gfxobj->getRect(0, rect);
+				data->_mask[0].create(rect.width(), rect.height());
+				_vm->_disk->loadMask(_tokens[1], data->_mask[0]);
+				data->_mask[1].create(rect.width(), rect.height());
+				data->_mask[1].blt(0, 0, ctxt.info->mask, data->gfxobj->x, data->gfxobj->y, data->_mask->w, data->_mask->h);
+				data->hasMask = true;
+			} else {
+				warning("Mask for zone '%s' ignored, since background doesn't have one", z->_name);
+			}
+		}
+
+		if (!scumm_stricmp(_tokens[0], "path")) {
+
+		}
+
+		if (!scumm_stricmp(_tokens[0], "icon")) {
+			data->_icon = 4 + _vm->_objectsNames->lookup(_tokens[1]);
+		}
+
+		_script->readLineToken(true);
+	} while (scumm_stricmp(_tokens[0], "endzone"));
+
+	z->u.get = data;
+
+	// FIXME: right now showZone doesn't work properly when called during location
+	// parsing. In fact, the main backgroundInfo is not properly set yet.
+	bool visible = (z->_flags & kFlagsRemove) == 0;
+	_vm->showZone(z, visible);
+}
+
 void LocationParser_br::parseZoneTypeBlock(ZonePtr z) {
 	debugC(7, kDebugParser, "parseZoneTypeBlock(name: %s, type: %x)", z->_name, z->_type);
 
@@ -1192,15 +1243,11 @@
 	Script *script2 = new Script(getStream(list), true);
 
 	ctxt.numZones = 0;
-	ctxt.bgName = 0;
-	ctxt.maskName = 0;
-	ctxt.pathName = 0;
 	ctxt.characterName = 0;
 	ctxt.info = new BackgroundInfo;
 
 	LocationParser_ns::parse(script2);
 
-	_vm->_disk->loadScenery(*ctxt.info, ctxt.bgName, ctxt.maskName, ctxt.pathName);
 	_vm->_gfx->setBackground(kBackgroundLocation, ctxt.info);
 	_vm->_pathBuffer = &ctxt.info->path;
 
@@ -1209,9 +1256,6 @@
 		_vm->changeCharacter(ctxt.characterName);
 	}
 
-	free(ctxt.bgName);
-	free(ctxt.maskName);
-	free(ctxt.pathName);
 	free(ctxt.characterName);
 
 	delete script2;


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