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

peres001 at users.sourceforge.net peres001 at users.sourceforge.net
Wed Jan 7 09:16:18 CET 2009


Revision: 35766
          http://scummvm.svn.sourceforge.net/scummvm/?rev=35766&view=rev
Author:   peres001
Date:     2009-01-07 08:16:18 +0000 (Wed, 07 Jan 2009)

Log Message:
-----------
Extended PathBuffer to support BRA.

Modified Paths:
--------------
    scummvm/trunk/engines/parallaction/disk.h
    scummvm/trunk/engines/parallaction/disk_br.cpp
    scummvm/trunk/engines/parallaction/disk_ns.cpp
    scummvm/trunk/engines/parallaction/gfxbase.cpp
    scummvm/trunk/engines/parallaction/graphics.cpp
    scummvm/trunk/engines/parallaction/graphics.h
    scummvm/trunk/engines/parallaction/parser_br.cpp
    scummvm/trunk/engines/parallaction/walk.cpp

Modified: scummvm/trunk/engines/parallaction/disk.h
===================================================================
--- scummvm/trunk/engines/parallaction/disk.h	2009-01-07 07:35:11 UTC (rev 35765)
+++ scummvm/trunk/engines/parallaction/disk.h	2009-01-07 08:16:18 UTC (rev 35766)
@@ -75,6 +75,7 @@
 	virtual Common::SeekableReadStream* loadMusic(const char* name) = 0;
 	virtual Common::ReadStream* loadSound(const char* name) = 0;
 	virtual void loadMask(const char *name, MaskBuffer &buffer) { }
+	virtual void loadPath(const char *name, PathBuffer &buffer) { }
 };
 
 
@@ -230,6 +231,7 @@
 	Common::SeekableReadStream* loadMusic(const char* name);
 	Common::ReadStream* loadSound(const char* name);
 	void loadMask(const char *name, MaskBuffer &buffer);
+	void loadPath(const char *name, PathBuffer &buffer);
 };
 
 class DosDemoDisk_br : public DosDisk_br {

Modified: scummvm/trunk/engines/parallaction/disk_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/disk_br.cpp	2009-01-07 07:35:11 UTC (rev 35765)
+++ scummvm/trunk/engines/parallaction/disk_br.cpp	2009-01-07 08:16:18 UTC (rev 35766)
@@ -318,6 +318,20 @@
 	delete stream;
 }
 
+void DosDisk_br::loadPath(const char *name, PathBuffer &buffer) {
+	if (!name) {
+		return;
+	}
+
+	Common::SeekableReadStream *stream = openFile("pth/" + Common::String(name), ".pth");
+
+	// 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);
+	delete stream;
+}
+
 void DosDisk_br::loadScenery(BackgroundInfo& info, const char *name, const char *mask, const char* path) {
 	debugC(5, kDebugDisk, "DosDisk_br::loadScenery");
 
@@ -345,13 +359,9 @@
 	}
 
 	if (path) {
-		stream = openFile("pth/" + Common::String(path), ".pth");
-
-		// NOTE: info.width and info.height are only valid if the background graphics
-		// have already been loaded
-		info.path.create(info.width, info.height);
-		stream->read(info.path.data, info.path.size);
-		delete stream;
+		info._path = new PathBuffer;
+		info._path->create(info.width, info.height);
+		loadPath(path, *info._path);
 	}
 
 	return;
@@ -477,8 +487,10 @@
 		if (stream) {
 			// NOTE: info.width and info.height are only valid if the background graphics
 			// have already been loaded
-			info.path.create(info.width, info.height);
-			stream->read(info.path.data, info.path.size);
+			info._path = new PathBuffer;
+			info._path->bigEndian = false;
+			info._path->create(info.width, info.height);
+			stream->read(info._path->data, info._path->size);
 			delete stream;
 		} else {
 			debugC(1, kDebugDisk, "AmigaDisk_br::loadScenery: (%s) not found", path);

Modified: scummvm/trunk/engines/parallaction/disk_ns.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/disk_ns.cpp	2009-01-07 07:35:11 UTC (rev 35765)
+++ scummvm/trunk/engines/parallaction/disk_ns.cpp	2009-01-07 08:16:18 UTC (rev 35766)
@@ -460,10 +460,13 @@
 	info._mask = new MaskBuffer;
 	info._mask->create(info.width, info.height);
 	info._mask->bigEndian = true;
-	info.path.create(info.width, info.height);
 
+	info._path = new PathBuffer;
+	info._path->create(info.width, info.height);
+	info._path->bigEndian = true;
+
 	Graphics::PackBitsReadStream pbstream(*stream);
-	unpackBackground(&pbstream, (byte*)info.bg.pixels, info._mask->data, info.path.data);
+	unpackBackground(&pbstream, (byte*)info.bg.pixels, info._mask->data, info._path->data);
 
 	delete stream;
 }
@@ -479,8 +482,10 @@
 	sprintf(path, "%s.msk", name);
 	Common::SeekableReadStream *stream = openFile(path);
 	parseDepths(info, *stream);
-	info.path.create(info.width, info.height);
-	stream->read(info.path.data, info.path.size);
+	info._path = new PathBuffer;
+	info._path->create(info.width, info.height);
+	info._path->bigEndian = true;
+	stream->read(info._path->data, info._path->size);
 	info._mask = new MaskBuffer;
 	info._mask->create(info.width, info.height);
 	info._mask->bigEndian = true;
@@ -1075,8 +1080,10 @@
 
 	Graphics::PackBitsReadStream stream(*s);
 
-	info.path.create(info.width, info.height);
-	stream.read(info.path.data, info.path.size);
+	info._path = new PathBuffer;
+	info._path->create(info.width, info.height);
+	info._path->bigEndian = false;
+	stream.read(info._path->data, info._path->size);
 
 	delete s;
 

Modified: scummvm/trunk/engines/parallaction/gfxbase.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/gfxbase.cpp	2009-01-07 07:35:11 UTC (rev 35765)
+++ scummvm/trunk/engines/parallaction/gfxbase.cpp	2009-01-07 08:16:18 UTC (rev 35766)
@@ -168,6 +168,18 @@
 	obj->_hasMask = true;
 }
 
+void Gfx::loadGfxObjPath(const char *name, GfxObj *obj) {
+	Common::Rect rect;
+	obj->getRect(0, rect);
+
+	PathBuffer *buf = new PathBuffer;
+	buf->create(rect.width(), rect.height());
+	_vm->_disk->loadPath(name, *buf);
+
+	obj->_pathId = _backgroundInfo->addPathPatch(buf);
+	obj->_hasPath = true;
+}
+
 void Gfx::showGfxObj(GfxObj* obj, bool visible) {
 	if (!obj) {
 		return;
@@ -179,10 +191,12 @@
 		obj->clearFlags(kGfxObjVisible);
 	}
 
-	//TODO: move handling of mask existence inside MaskManager
 	if (obj->_hasMask) {
 		_backgroundInfo->toggleMaskPatch(obj->_maskId, obj->x, obj->y, visible);
 	}
+	if (obj->_hasPath) {
+		_backgroundInfo->togglePathPatch(obj->_pathId, obj->x, obj->y, visible);
+	}
 }
 
 

Modified: scummvm/trunk/engines/parallaction/graphics.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/graphics.cpp	2009-01-07 07:35:11 UTC (rev 35765)
+++ scummvm/trunk/engines/parallaction/graphics.cpp	2009-01-07 08:16:18 UTC (rev 35766)
@@ -807,6 +807,7 @@
 	}
 
 	_backgroundInfo->finalizeMask();
+	_backgroundInfo->finalizePath();
 
 	if (_gameType == GType_BRA) {
 		int width = CLIP(info->width, (int)_vm->_screenWidth, info->width);
@@ -822,7 +823,7 @@
 }
 
 
-BackgroundInfo::BackgroundInfo() : x(0), y(0), width(0), height(0), _mask(0) {
+BackgroundInfo::BackgroundInfo() : x(0), y(0), width(0), height(0), _mask(0), _path(0) {
 	layers[0] = layers[1] = layers[2] = layers[3] = 0;
 	memset(ranges, 0, sizeof(ranges));
 }
@@ -830,7 +831,7 @@
 BackgroundInfo::~BackgroundInfo() {
 	bg.free();
 	clearMaskData();
-	path.free();
+	clearPathData();
 }
 
 bool BackgroundInfo::hasMask() {
@@ -851,7 +852,11 @@
 
 void BackgroundInfo::finalizeMask() {
 	if (_mask) {
-		_maskBackup.clone(*_mask);
+		if (_maskPatches.size() > 0) {
+			// since no more patches can be added after finalization,
+			// avoid creating the backup if there is none
+			_maskBackup.clone(*_mask);
+		}
 	} else {
 		clearMaskData();
 	}
@@ -890,6 +895,55 @@
 	memcpy(&ranges[index], &range, sizeof(PaletteFxRange));
 }
 
+bool BackgroundInfo::hasPath() {
+	return _path != 0;
+}
+
+void BackgroundInfo::clearPathData() {
+	// free mask data
+	PathPatchMap::iterator it = _pathPatches.begin();
+	for ( ; it != _pathPatches.end(); it++) {
+		delete (*it)._value;
+	}
+	_pathPatches.clear();
+	delete _path;
+	_path = 0;
+	_pathBackup.free();
+}
+
+void BackgroundInfo::finalizePath() {
+	if (_path) {
+		if (_pathPatches.size() > 0) {
+			// since no more patches can be added after finalization,
+			// avoid creating the backup if there is none
+			_pathBackup.clone(*_path);
+		}
+	} else {
+		clearPathData();
+	}
+}
+
+int BackgroundInfo::addPathPatch(PathBuffer *patch) {
+	int id = _pathPatches.size();
+	_pathPatches.setVal(id, patch);
+	return id;
+}
+
+void BackgroundInfo::togglePathPatch(int id, int x, int y, bool apply) {
+	if (!hasPath()) {
+		return;
+	}
+	if (!_pathPatches.contains(id)) {
+		return;
+	}
+	PathBuffer *patch = _pathPatches.getVal(id);
+	if (apply) {
+		_path->bltOr(x, y, *patch, 0, 0, patch->w, patch->h);
+	} else {
+		_path->bltCopy(x, y, _pathBackup, x, y, patch->w, patch->h);
+	}
+}
+
 MaskBuffer::MaskBuffer() : w(0), internalWidth(0), h(0), size(0), data(0), bigEndian(true) {
 }
 
@@ -973,13 +1027,22 @@
 
 
 
-PathBuffer::PathBuffer() : w(0), internalWidth(0), h(0), size(0), data(0) {
+PathBuffer::PathBuffer() : w(0), internalWidth(0), h(0), size(0), data(0), bigEndian(true) {
 }
 
 PathBuffer::~PathBuffer() {
 	free();
 }
 
+void PathBuffer::clone(const PathBuffer &buf) {
+	if (!buf.data)
+		return;
+
+	create(buf.w, buf.h);
+	bigEndian = buf.bigEndian;
+	memcpy(data, buf.data, size);
+}
+
 void PathBuffer::create(uint16 width, uint16 height) {
 	free();
 
@@ -1001,21 +1064,43 @@
 
 byte PathBuffer::getValue(uint16 x, uint16 y) const {
 	byte m = data[(x >> 3) + y * internalWidth];
-	uint bit = 0;
-	switch (_vm->getGameType()) {
-	case GType_Nippon:
-		bit = (_vm->getPlatform() == Common::kPlatformPC) ? (x & 7) : (7 - (x & 7));
-		break;
+	uint bit = bigEndian ? (x & 7) : (7 - (x & 7));
+	return ((1 << bit) & m) >> bit;
+}
 
-	case GType_BRA:
-		// Amiga and PC versions pack the path bits the same way in BRA
-		bit = 7 - (x & 7);
-		break;
+byte* PathBuffer::getPtr(uint16 x, uint16 y) const {
+	return data + (x >> 3) + y * internalWidth;
+}
 
-	default:
-		error("path mask not yet implemented for this game type");
+void PathBuffer::bltOr(uint16 dx, uint16 dy, const PathBuffer &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);
+
+	// this code assumes buffers are aligned on 4-pixels boundaries, as the original does
+	uint16 linewidth = width >> 3;
+	for (uint16 i = 0; i < height; i++) {
+		for (uint16 j = 0; j < linewidth; j++) {
+			*d++ |= *s++;
+		}
+		d += internalWidth - linewidth;
+		s += src.internalWidth - linewidth;
 	}
-	return ((1 << bit) & m) >> bit;
 }
 
+void PathBuffer::bltCopy(uint16 dx, uint16 dy, const PathBuffer &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);
+
+	// this code assumes buffers are aligned on 4-pixels boundaries, as the original does
+	for (uint16 i = 0; i < height; i++) {
+		memcpy(d, s, (width >> 3));
+		d += internalWidth;
+		s += src.internalWidth;
+	}
+}
+
 } // namespace Parallaction

Modified: scummvm/trunk/engines/parallaction/graphics.h
===================================================================
--- scummvm/trunk/engines/parallaction/graphics.h	2009-01-07 07:35:11 UTC (rev 35765)
+++ scummvm/trunk/engines/parallaction/graphics.h	2009-01-07 08:16:18 UTC (rev 35766)
@@ -192,6 +192,8 @@
 	bool	bigEndian;
 
 	byte* getPtr(uint16 x, uint16 y) const;
+	void bltOr(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height);
+	void bltCopy(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height);
 
 public:
 	MaskBuffer();
@@ -202,8 +204,6 @@
 	void free();
 
 	byte getValue(uint16 x, uint16 y) const;
-	void bltOr(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height);
-	void bltCopy(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height);
 };
 
 
@@ -215,11 +215,17 @@
 	uint16	h;
 	uint	size;
 	byte	*data;
+	bool	bigEndian;
 
+	byte* getPtr(uint16 x, uint16 y) const;
+	void bltOr(uint16 dx, uint16 dy, const PathBuffer &src, uint16 sx, uint16 sy, uint width, uint height);
+	void bltCopy(uint16 dx, uint16 dy, const PathBuffer &src, uint16 sx, uint16 sy, uint width, uint height);
+
 public:
 	PathBuffer();
 	~PathBuffer();
 
+	void clone(const PathBuffer &buf);
 	void create(uint16 width, uint16 height);
 	void free();
 	byte getValue(uint16 x, uint16 y) const;
@@ -304,7 +310,9 @@
 	uint scale;
 
 	int	_maskId;
-	bool			_hasMask;
+	bool _hasMask;
+	int _pathId;
+	bool _hasPath;
 
 
 	GfxObj(uint type, Frames *frames, const char *name = NULL);
@@ -340,9 +348,13 @@
 	typedef Common::HashMap<int, MaskBuffer*> MaskPatchMap;
 	MaskPatchMap _maskPatches;
 	MaskBuffer		_maskBackup;
-
 	void clearMaskData();
 
+	typedef Common::HashMap<int, PathBuffer*> PathPatchMap;
+	PathPatchMap 	_pathPatches;
+	PathBuffer		_pathBackup;
+	void clearPathData();
+
 public:
 	int x, y;		// used to display bitmaps smaller than the screen
 	int width;
@@ -350,7 +362,7 @@
 
 	Graphics::Surface	bg;
 	MaskBuffer			*_mask;
-	PathBuffer			path;
+	PathBuffer			*_path;
 
 	Palette				palette;
 
@@ -374,6 +386,7 @@
 	bool hasPath();
 	int addPathPatch(PathBuffer *patch);
 	void togglePathPatch(int id, int x, int y, bool apply);
+	void finalizePath();
 };
 
 
@@ -425,6 +438,7 @@
 	void showGfxObj(GfxObj* obj, bool visible);
 	void clearGfxObjects(uint filter);
 	void loadGfxObjMask(const char *name, GfxObj *obj);
+	void loadGfxObjPath(const char *name, GfxObj *obj);
 	void sortScene();
     void blt(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, uint scale, byte transparentColor);
 	void unpackBlt(const Common::Rect& r, byte *data, uint size, Graphics::Surface *surf, uint16 z, uint scale, byte transparentColor);

Modified: scummvm/trunk/engines/parallaction/parser_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parser_br.cpp	2009-01-07 07:35:11 UTC (rev 35765)
+++ scummvm/trunk/engines/parallaction/parser_br.cpp	2009-01-07 08:16:18 UTC (rev 35766)
@@ -792,7 +792,7 @@
 		}
 
 		if (!scumm_stricmp(_tokens[0], "path")) {
-
+			_vm->_gfx->loadGfxObjPath(_tokens[1], data->gfxobj);
 		}
 
 		if (!scumm_stricmp(_tokens[0], "icon")) {

Modified: scummvm/trunk/engines/parallaction/walk.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/walk.cpp	2009-01-07 07:35:11 UTC (rev 35765)
+++ scummvm/trunk/engines/parallaction/walk.cpp	2009-01-07 08:16:18 UTC (rev 35766)
@@ -27,7 +27,7 @@
 
 namespace Parallaction {
 
-#define IS_PATH_CLEAR(x,y) _vm->_gfx->_backgroundInfo->path.getValue((x), (y))
+#define IS_PATH_CLEAR(x,y) _vm->_gfx->_backgroundInfo->_path->getValue((x), (y))
 
 // adjusts position towards nearest walkable point
 //
@@ -35,8 +35,8 @@
 
 	if (IS_PATH_CLEAR(to.x, to.y)) return;
 
-	int maxX = _vm->_gfx->_backgroundInfo->path.w;
-	int maxY = _vm->_gfx->_backgroundInfo->path.h;
+	int maxX = _vm->_gfx->_backgroundInfo->_path->w;
+	int maxY = _vm->_gfx->_backgroundInfo->_path->h;
 
 	int16 right = to.x;
 	int16 left = to.x;
@@ -229,7 +229,7 @@
 
 void PathWalker_NS::clipMove(Common::Point& pos, const Common::Point& to) {
 
-	if ((pos.x < to.x) && (pos.x < _vm->_gfx->_backgroundInfo->path.w) && IS_PATH_CLEAR(pos.x + 2, pos.y)) {
+	if ((pos.x < to.x) && (pos.x < _vm->_gfx->_backgroundInfo->_path->w) && IS_PATH_CLEAR(pos.x + 2, pos.y)) {
 		pos.x = (pos.x + 2 < to.x) ? pos.x + 2 : to.x;
 	}
 
@@ -237,7 +237,7 @@
 		pos.x = (pos.x - 2 > to.x) ? pos.x - 2 : to.x;
 	}
 
-	if ((pos.y < to.y) && (pos.y < _vm->_gfx->_backgroundInfo->path.h) && IS_PATH_CLEAR(pos.x, pos.y + 2)) {
+	if ((pos.y < to.y) && (pos.y < _vm->_gfx->_backgroundInfo->_path->h) && IS_PATH_CLEAR(pos.x, pos.y + 2)) {
 		pos.y = (pos.y + 2 <= to.y) ? pos.y + 2 : to.y;
 	}
 


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