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

peres001 at users.sourceforge.net peres001 at users.sourceforge.net
Wed Jan 7 08:35:11 CET 2009


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

Log Message:
-----------
* moved more mask management to BackgroundInfo
* simplified mask management for client code
* reduced the clutter into graphics.h by moving the implementations of BackgroundInfo, MaskBuffer and PathBuffer to graphics.cpp
* preparation for the full implementation of BRA's PathBuffer

Modified Paths:
--------------
    scummvm/trunk/engines/parallaction/callables_ns.cpp
    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/parallaction.cpp
    scummvm/trunk/engines/parallaction/parser_br.cpp
    scummvm/trunk/engines/parallaction/walk.cpp

Modified: scummvm/trunk/engines/parallaction/callables_ns.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/callables_ns.cpp	2009-01-07 07:21:50 UTC (rev 35764)
+++ scummvm/trunk/engines/parallaction/callables_ns.cpp	2009-01-07 07:35:11 UTC (rev 35765)
@@ -288,7 +288,10 @@
 
 void Parallaction_ns::_c_setMask(void *parm) {
 
-	memset(_gfx->_backgroundInfo->mask.data + 3600, 0, 3600);
+	if (!_gfx->_backgroundInfo->hasMask())
+		return;
+
+	memset(_gfx->_backgroundInfo->_mask->data + 3600, 0, 3600);
 	_gfx->_backgroundInfo->layers[1] = 500;
 
 	return;
@@ -446,11 +449,14 @@
 void zeroMask(int x, int y, int color, void *data) {
 	//_vm->_gfx->zeroMaskValue(x, y, color);
 
-	BackgroundInfo* info = (BackgroundInfo*)data;
+	if (!_vm->_gfx->_backgroundInfo->hasMask())
+		return;
 
-	uint16 _ax = x + y * info->width;
-	info->mask.data[_ax >> 2] &= ~(3 << ((_ax & 3) << 1));
+//	BackgroundInfo* info = (BackgroundInfo*)data;
 
+	uint16 _ax = x + y * _vm->_gfx->_backgroundInfo->_mask->w;
+	_vm->_gfx->_backgroundInfo->_mask->data[_ax >> 2] &= ~(3 << ((_ax & 3) << 1));
+
 }
 
 void Parallaction_ns::_c_sketch(void *parm) {
@@ -498,11 +504,11 @@
 		_rightHandAnim->getY()
 	);
 
-	uint16 _di = r.left/4 + r.top * _gfx->_backgroundInfo->mask.internalWidth;
+	uint16 _di = r.left/4 + r.top * _vm->_gfx->_backgroundInfo->_mask->internalWidth;
 
 	for (uint16 _si = r.top; _si < r.bottom; _si++) {
-		memset(_gfx->_backgroundInfo->mask.data + _di, 0, r.width()/4+1);
-		_di += _gfx->_backgroundInfo->mask.internalWidth;
+		memset(_vm->_gfx->_backgroundInfo->_mask->data + _di, 0, r.width()/4+1);
+		_di += _vm->_gfx->_backgroundInfo->_mask->internalWidth;
 	}
 
 	return;

Modified: scummvm/trunk/engines/parallaction/disk_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/disk_br.cpp	2009-01-07 07:21:50 UTC (rev 35764)
+++ scummvm/trunk/engines/parallaction/disk_br.cpp	2009-01-07 07:35:11 UTC (rev 35765)
@@ -339,8 +339,9 @@
 	}
 
 	if (mask) {
-		info.mask.create(info.width, info.height);
-		loadMask(mask, info.mask);
+		info._mask = new MaskBuffer;
+		info._mask->create(info.width, info.height);
+		loadMask(mask, *info._mask);
 	}
 
 	if (path) {

Modified: scummvm/trunk/engines/parallaction/disk_ns.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/disk_ns.cpp	2009-01-07 07:21:50 UTC (rev 35764)
+++ scummvm/trunk/engines/parallaction/disk_ns.cpp	2009-01-07 07:35:11 UTC (rev 35765)
@@ -457,12 +457,13 @@
 	parseBackground(info, *stream);
 
 	info.bg.create(info.width, info.height, 1);
-	info.mask.create(info.width, info.height);
-	info.mask.bigEndian = true;
+	info._mask = new MaskBuffer;
+	info._mask->create(info.width, info.height);
+	info._mask->bigEndian = true;
 	info.path.create(info.width, info.height);
 
 	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;
 }
@@ -480,9 +481,10 @@
 	parseDepths(info, *stream);
 	info.path.create(info.width, info.height);
 	stream->read(info.path.data, info.path.size);
-	info.mask.create(info.width, info.height);
-	info.mask.bigEndian = true;
-	stream->read(info.mask.data, info.mask.size);
+	info._mask = new MaskBuffer;
+	info._mask->create(info.width, info.height);
+	info._mask->bigEndian = true;
+	stream->read(info._mask->data, info._mask->size);
 	delete stream;
 }
 
@@ -1049,9 +1051,10 @@
 	s->seek(0x126, SEEK_SET);	// HACK: skipping IFF/ILBM header should be done by analysis, not magic
 	Graphics::PackBitsReadStream stream(*s);
 
-	info.mask.create(info.width, info.height);
-	stream.read(info.mask.data, info.mask.size);
-	buildMask(info.mask.data);
+	info._mask = new MaskBuffer;
+	info._mask->create(info.width, info.height);
+	stream.read(info._mask->data, info._mask->size);
+	buildMask(info._mask->data);
 
 	delete s;
 

Modified: scummvm/trunk/engines/parallaction/gfxbase.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/gfxbase.cpp	2009-01-07 07:21:50 UTC (rev 35764)
+++ scummvm/trunk/engines/parallaction/gfxbase.cpp	2009-01-07 07:35:11 UTC (rev 35765)
@@ -46,7 +46,6 @@
 GfxObj::~GfxObj() {
 	delete _frames;
 	free(_name);
-	_mask.free();
 }
 
 void GfxObj::release() {
@@ -157,12 +156,15 @@
 	clearGfxObjects(kGfxObjCharacter);
 }
 
-
 void Gfx::loadGfxObjMask(const char *name, GfxObj *obj) {
 	Common::Rect rect;
 	obj->getRect(0, rect);
-	obj->_mask.create(rect.width(), rect.height());
-	_vm->_disk->loadMask(name, obj->_mask);
+
+	MaskBuffer *buf = new MaskBuffer;
+	buf->create(rect.width(), rect.height());
+	_vm->_disk->loadMask(name, *buf);
+
+	obj->_maskId = _backgroundInfo->addMaskPatch(buf);
 	obj->_hasMask = true;
 }
 
@@ -177,12 +179,9 @@
 		obj->clearFlags(kGfxObjVisible);
 	}
 
-	if (obj->_hasMask && _backgroundInfo->hasMask) {
-		if (visible) {
-			_backgroundInfo->mask.bltOr(obj->x, obj->y, obj->_mask, 0, 0, obj->_mask.w, obj->_mask.h);
-		} else {
-			_backgroundInfo->mask.bltCopy(obj->x, obj->y, _backgroundInfo->maskBackup, obj->x, obj->y, obj->_mask.w, obj->_mask.h);
-		}
+	//TODO: move handling of mask existence inside MaskManager
+	if (obj->_hasMask) {
+		_backgroundInfo->toggleMaskPatch(obj->_maskId, obj->x, obj->y, visible);
 	}
 }
 
@@ -334,7 +333,7 @@
 			}
 
 			if (*s != transparentColor) {
-				byte v = _backgroundInfo->mask.getValue(dp.x + col, dp.y + line);
+				byte v = _backgroundInfo->_mask->getValue(dp.x + col, dp.y + line);
 				if (z >= v) *d2 = *s;
 			}
 
@@ -351,7 +350,7 @@
 }
 
 void Gfx::bltMaskNoScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, byte transparentColor) {
-	if (!_backgroundInfo->mask.data || (z == LAYER_FOREGROUND)) {
+	if (!_backgroundInfo->hasMask() || (z == LAYER_FOREGROUND)) {
 		// use optimized path
 		bltNoMaskNoScale(r, data, surf, transparentColor);
 		return;
@@ -380,7 +379,7 @@
 
 		for (uint16 j = 0; j < q.width(); j++) {
 			if (*s != transparentColor) {
-				byte v = _backgroundInfo->mask.getValue(dp.x + j, dp.y + i);
+				byte v = _backgroundInfo->_mask->getValue(dp.x + j, dp.y + i);
 				if (z >= v) *d = *s;
 			}
 

Modified: scummvm/trunk/engines/parallaction/graphics.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/graphics.cpp	2009-01-07 07:21:50 UTC (rev 35764)
+++ scummvm/trunk/engines/parallaction/graphics.cpp	2009-01-07 07:35:11 UTC (rev 35765)
@@ -464,7 +464,7 @@
 	Common::Rect r(surf.w, surf.h);
 	r.moveTo(x, y);
 
-	uint16 z = (mask) ? _backgroundInfo->getLayer(y) : LAYER_FOREGROUND;
+	uint16 z = (mask) ? _backgroundInfo->getMaskLayer(y) : LAYER_FOREGROUND;
 	blt(r, (byte*)surf.pixels, &_backgroundInfo->bg, z, 100, 0);
 }
 
@@ -687,7 +687,7 @@
 
 
 Gfx::Gfx(Parallaction* vm) :
-	_vm(vm), _disk(vm->_disk), _scrollPos(0), _minScroll(0), _maxScroll(0) {
+	_vm(vm), _disk(vm->_disk), _backgroundInfo(0), _scrollPos(0), _minScroll(0), _maxScroll(0) {
 
 	_gameType = _vm->getGameType();
 	_doubleBuffering = _gameType != GType_Nippon;
@@ -778,6 +778,11 @@
 }
 
 void Gfx::setBackground(uint type, BackgroundInfo *info) {
+	if (!info) {
+		warning("Gfx::setBackground() called with an null BackgroundInfo");
+		return;
+	}
+
 	delete _backgroundInfo;
 	_backgroundInfo = info;
 
@@ -801,9 +806,7 @@
 		setPalette(_backgroundInfo->palette);
 	}
 
-	if (_backgroundInfo->hasMask) {
-		_backgroundInfo->maskBackup.clone(_backgroundInfo->mask);
-	}
+	_backgroundInfo->finalizeMask();
 
 	if (_gameType == GType_BRA) {
 		int width = CLIP(info->width, (int)_vm->_screenWidth, info->width);
@@ -818,4 +821,201 @@
 	_maxScroll = MAX<int>(0, _backgroundInfo->width - _vm->_screenWidth);
 }
 
+
+BackgroundInfo::BackgroundInfo() : x(0), y(0), width(0), height(0), _mask(0) {
+	layers[0] = layers[1] = layers[2] = layers[3] = 0;
+	memset(ranges, 0, sizeof(ranges));
+}
+
+BackgroundInfo::~BackgroundInfo() {
+	bg.free();
+	clearMaskData();
+	path.free();
+}
+
+bool BackgroundInfo::hasMask() {
+	return _mask != 0;
+}
+
+void BackgroundInfo::clearMaskData() {
+	// free mask data
+	MaskPatchMap::iterator it = _maskPatches.begin();
+	for ( ; it != _maskPatches.end(); it++) {
+		delete (*it)._value;
+	}
+	_maskPatches.clear();
+	delete _mask;
+	_mask = 0;
+	_maskBackup.free();
+}
+
+void BackgroundInfo::finalizeMask() {
+	if (_mask) {
+		_maskBackup.clone(*_mask);
+	} else {
+		clearMaskData();
+	}
+}
+
+int BackgroundInfo::addMaskPatch(MaskBuffer *patch) {
+	int id = _maskPatches.size();
+	_maskPatches.setVal(id, patch);
+	return id;
+}
+
+void BackgroundInfo::toggleMaskPatch(int id, int x, int y, bool apply) {
+	if (!hasMask()) {
+		return;
+	}
+	if (!_maskPatches.contains(id)) {
+		return;
+	}
+	MaskBuffer *patch = _maskPatches.getVal(id);
+	if (apply) {
+		_mask->bltOr(x, y, *patch, 0, 0, patch->w, patch->h);
+	} else {
+		_mask->bltCopy(x, y, _maskBackup, x, y, patch->w, patch->h);
+	}
+}
+
+uint16 BackgroundInfo::getMaskLayer(uint16 z) const {
+	for (uint16 i = 0; i < 3; i++) {
+		if (layers[i+1] > z) return i;
+	}
+	return LAYER_FOREGROUND;
+}
+
+void BackgroundInfo::setPaletteRange(int index, const PaletteFxRange& range) {
+	assert(index < 6);
+	memcpy(&ranges[index], &range, sizeof(PaletteFxRange));
+}
+
+MaskBuffer::MaskBuffer() : w(0), internalWidth(0), h(0), size(0), data(0), bigEndian(true) {
+}
+
+MaskBuffer::~MaskBuffer() {
+	free();
+}
+
+byte* MaskBuffer::getPtr(uint16 x, uint16 y) const {
+	return data + (x >> 2) + y * internalWidth;
+}
+
+void MaskBuffer::clone(const MaskBuffer &buf) {
+	if (!buf.data)
+		return;
+
+	create(buf.w, buf.h);
+	bigEndian = buf.bigEndian;
+	memcpy(data, buf.data, size);
+}
+
+void MaskBuffer::create(uint16 width, uint16 height) {
+	free();
+
+	w = width;
+	internalWidth = w >> 2;
+	h = height;
+	size = (internalWidth * h);
+	data = (byte*)calloc(size, 1);
+}
+
+void MaskBuffer::free() {
+	::free(data);
+	data = 0;
+	w = 0;
+	h = 0;
+	internalWidth = 0;
+	size = 0;
+}
+
+byte MaskBuffer::getValue(uint16 x, uint16 y) const {
+	byte m = data[(x >> 2) + y * internalWidth];
+	uint n;
+	if (bigEndian) {
+		n = (x & 3) << 1;
+	} else {
+		n = (3 - (x & 3)) << 1;
+	}
+	return (m >> n) & 3;
+}
+
+void MaskBuffer::bltOr(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);
+
+	// 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++) {
+			*d++ |= *s++;
+		}
+		d += internalWidth - linewidth;
+		s += src.internalWidth - linewidth;
+	}
+}
+
+void MaskBuffer::bltCopy(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);
+
+	// 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 >> 2));
+		d += internalWidth;
+		s += src.internalWidth;
+	}
+}
+
+
+
+PathBuffer::PathBuffer() : w(0), internalWidth(0), h(0), size(0), data(0) {
+}
+
+PathBuffer::~PathBuffer() {
+	free();
+}
+
+void PathBuffer::create(uint16 width, uint16 height) {
+	free();
+
+	w = width;
+	internalWidth = w >> 3;
+	h = height;
+	size = (internalWidth * h);
+	data = (byte*)calloc(size, 1);
+}
+
+void PathBuffer::free() {
+	::free(data);
+	data = 0;
+	w = 0;
+	h = 0;
+	internalWidth = 0;
+	size = 0;
+}
+
+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;
+
+	case GType_BRA:
+		// Amiga and PC versions pack the path bits the same way in BRA
+		bit = 7 - (x & 7);
+		break;
+
+	default:
+		error("path mask not yet implemented for this game type");
+	}
+	return ((1 << bit) & m) >> bit;
+}
+
 } // namespace Parallaction

Modified: scummvm/trunk/engines/parallaction/graphics.h
===================================================================
--- scummvm/trunk/engines/parallaction/graphics.h	2009-01-07 07:21:50 UTC (rev 35764)
+++ scummvm/trunk/engines/parallaction/graphics.h	2009-01-07 07:35:11 UTC (rev 35765)
@@ -28,6 +28,7 @@
 
 #include "common/list.h"
 #include "common/rect.h"
+#include "common/hashmap.h"
 #include "common/hash-str.h"
 #include "common/stream.h"
 
@@ -124,97 +125,85 @@
 
 };
 
+struct Cnv : public Frames {
+	uint16	_count;		// # of frames
+	uint16	_width;		//
+	uint16	_height;	//
+	byte**	field_8;	// unused
+	byte*	_data;
+	bool 	_freeData;
 
-
-struct MaskBuffer {
-	// handles a 2-bit depth buffer used for z-buffering
-
-	uint16	w;
-	uint16  internalWidth;
-	uint16	h;
-	uint	size;
-	byte	*data;
-	bool	bigEndian;
-
 public:
-	MaskBuffer() : w(0), internalWidth(0), h(0), size(0), data(0), bigEndian(true) {
+	Cnv() {
+		_width = _height = _count = 0;
+		_data = NULL;
 	}
 
-	void clone(const MaskBuffer &buf) {
-		if (!buf.data)
-			return;
+	Cnv(uint16 numFrames, uint16 width, uint16 height, byte* data, bool freeData = false)
+		: _count(numFrames), _width(width), _height(height), _data(data), _freeData(freeData) {
 
-		create(buf.w, buf.h);
-		bigEndian = buf.bigEndian;
-		memcpy(data, buf.data, size);
 	}
 
-	void create(uint16 width, uint16 height) {
-		free();
+	~Cnv() {
+		if (_freeData)
+			delete []_data;
+	}
 
-		w = width;
-		internalWidth = w >> 2;
-		h = height;
-		size = (internalWidth * h);
-		data = (byte*)calloc(size, 1);
+	byte* getFramePtr(uint16 index) {
+		if (index >= _count)
+			return NULL;
+		return &_data[index * _width * _height];
 	}
 
-	void free() {
-		::free(data);
-		data = 0;
-		w = 0;
-		h = 0;
-		internalWidth = 0;
-		size = 0;
+	uint16	getNum() {
+		return _count;
 	}
 
-	inline byte getValue(uint16 x, uint16 y) {
-		byte m = data[(x >> 2) + y * internalWidth];
-		uint n;
-		if (bigEndian) {
-			n = (x & 3) << 1;
-		} else {
-			n = (3 - (x & 3)) << 1;
-		}
-		return (m >> n) & 3;
+	byte	*getData(uint16 index) {
+		return getFramePtr(index);
 	}
 
-	inline byte* getPtr(uint16 x, uint16 y) const {
-		return data + (x >> 2) + y * internalWidth;
+	void getRect(uint16 index, Common::Rect &r) {
+		r.left = 0;
+		r.top = 0;
+		r.setWidth(_width);
+		r.setHeight(_height);
 	}
+	uint	getRawSize(uint16 index) {
+		assert(index < _count);
+		return getSize(index);
+	}
+	uint	getSize(uint16 index) {
+		assert(index < _count);
+		return _width * _height;
+	}
 
-	void bltOr(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);
 
-		// 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++) {
-				*d++ |= *s++;
-			}
-			d += internalWidth - linewidth;
-			s += src.internalWidth - linewidth;
-		}
-	}
+struct MaskBuffer {
+	// handles a 2-bit depth buffer used for z-buffering
 
-	void bltCopy(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));
+	uint16	w;
+	uint16  internalWidth;
+	uint16	h;
+	uint	size;
+	byte	*data;
+	bool	bigEndian;
 
-		byte *s = src.getPtr(sx, sy);
-		byte *d = getPtr(dx, dy);
+	byte* getPtr(uint16 x, uint16 y) const;
 
-		// 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 >> 2));
-			d += internalWidth;
-			s += src.internalWidth;
-		}
-	}
+public:
+	MaskBuffer();
+	~MaskBuffer();
 
+	void clone(const MaskBuffer &buf);
+	void create(uint16 width, uint16 height);
+	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);
 };
 
 
@@ -228,29 +217,12 @@
 	byte	*data;
 
 public:
-	PathBuffer() : w(0), internalWidth(0), h(0), size(0), data(0) {
-	}
+	PathBuffer();
+	~PathBuffer();
 
-	void create(uint16 width, uint16 height) {
-		free();
-
-		w = width;
-		internalWidth = w >> 3;
-		h = height;
-		size = (internalWidth * h);
-		data = (byte*)calloc(size, 1);
-	}
-
-	void free() {
-		::free(data);
-		data = 0;
-		w = 0;
-		h = 0;
-		internalWidth = 0;
-		size = 0;
-	}
-
-	inline byte getValue(uint16 x, uint16 y);
+	void create(uint16 width, uint16 height);
+	void free();
+	byte getValue(uint16 x, uint16 y) const;
 };
 
 
@@ -279,62 +251,6 @@
 };
 
 
-struct Cnv : public Frames {
-	uint16	_count;		// # of frames
-	uint16	_width;		//
-	uint16	_height;	//
-	byte**	field_8;	// unused
-	byte*	_data;
-	bool 	_freeData;
-
-public:
-	Cnv() {
-		_width = _height = _count = 0;
-		_data = NULL;
-	}
-
-	Cnv(uint16 numFrames, uint16 width, uint16 height, byte* data, bool freeData = false)
-		: _count(numFrames), _width(width), _height(height), _data(data), _freeData(freeData) {
-
-	}
-
-	~Cnv() {
-		if (_freeData)
-			delete []_data;
-	}
-
-	byte* getFramePtr(uint16 index) {
-		if (index >= _count)
-			return NULL;
-		return &_data[index * _width * _height];
-	}
-
-	uint16	getNum() {
-		return _count;
-	}
-
-	byte	*getData(uint16 index) {
-		return getFramePtr(index);
-	}
-
-	void getRect(uint16 index, Common::Rect &r) {
-		r.left = 0;
-		r.top = 0;
-		r.setWidth(_width);
-		r.setHeight(_height);
-	}
-	uint	getRawSize(uint16 index) {
-		assert(index < _count);
-		return getSize(index);
-	}
-	uint	getSize(uint16 index) {
-		assert(index < _count);
-		return _width * _height;
-	}
-
-};
-
-
 #define CENTER_LABEL_HORIZONTAL	-1
 #define CENTER_LABEL_VERTICAL	-1
 
@@ -387,7 +303,7 @@
 	uint transparentKey;
 	uint scale;
 
-	MaskBuffer		_mask;
+	int	_maskId;
 	bool			_hasMask;
 
 
@@ -420,13 +336,20 @@
 	being the most common options.
 */
 struct BackgroundInfo {
+protected:
+	typedef Common::HashMap<int, MaskBuffer*> MaskPatchMap;
+	MaskPatchMap _maskPatches;
+	MaskBuffer		_maskBackup;
+
+	void clearMaskData();
+
+public:
 	int x, y;		// used to display bitmaps smaller than the screen
 	int width;
 	int height;
 
 	Graphics::Surface	bg;
-	MaskBuffer			mask;
-	MaskBuffer			maskBackup;
+	MaskBuffer			*_mask;
 	PathBuffer			path;
 
 	Palette				palette;
@@ -434,39 +357,28 @@
 	int 				layers[4];
 	PaletteFxRange		ranges[6];
 
-	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));
-	}
+	BackgroundInfo();
+	~BackgroundInfo();
 
-	void setPaletteRange(int index, const PaletteFxRange& range) {
-		assert(index < 6);
-		memcpy(&ranges[index], &range, sizeof(PaletteFxRange));
-	}
+	void setPaletteRange(int index, const PaletteFxRange& range);
 
-	uint16 getLayer(uint16 z) {
-		for (uint16 i = 0; i < 3; i++) {
-			if (layers[i+1] > z) return i;
-		}
-		return LAYER_FOREGROUND;
-	}
+	// mask management
+	bool hasMask();
+	int addMaskPatch(MaskBuffer *patch);
+	void toggleMaskPatch(int id, int x, int y, bool apply);
+	uint16 getMaskLayer(uint16 z) const;
+	void finalizeMask();
 
-	~BackgroundInfo() {
-		bg.free();
-		mask.free();
-		maskBackup.free();
-		path.free();
-		x = 0;
-		y = 0;
-		width = 0;
-		height = 0;
-	}
-
+	// path management
+	bool hasPath();
+	int addPathPatch(PathBuffer *patch);
+	void togglePathPatch(int id, int x, int y, bool apply);
 };
 
 
+
+
 enum {
 	kBackgroundLocation = 1,
 	kBackgroundSlide = 2
@@ -611,9 +523,6 @@
 	void bltMaskScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, uint scale, byte transparentColor);
 	void bltMaskNoScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, byte transparentColor);
 	void bltNoMaskNoScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, byte transparentColor);
-
-public:
-
 };
 
 

Modified: scummvm/trunk/engines/parallaction/parallaction.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.cpp	2009-01-07 07:21:50 UTC (rev 35764)
+++ scummvm/trunk/engines/parallaction/parallaction.cpp	2009-01-07 07:35:11 UTC (rev 35765)
@@ -456,12 +456,12 @@
 			} else {
 				if (getGameType() == GType_Nippon) {
 					// Layer in NS depends on where the animation is on the screen, for each animation.
-					layer = _gfx->_backgroundInfo->getLayer(anim->getBottom());
+					layer = _gfx->_backgroundInfo->getMaskLayer(anim->getBottom());
 				} else {
 					// Layer in BRA is calculated from Z value. For characters it is the same as NS,
 					// but other animations can have Z set from scripts independently from their
 					// position on the screen.
-					layer = _gfx->_backgroundInfo->getLayer(anim->getZ());
+					layer = _gfx->_backgroundInfo->getMaskLayer(anim->getZ());
 				}
 			}
 

Modified: scummvm/trunk/engines/parallaction/parser_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parser_br.cpp	2009-01-07 07:21:50 UTC (rev 35764)
+++ scummvm/trunk/engines/parallaction/parser_br.cpp	2009-01-07 07:35:11 UTC (rev 35765)
@@ -472,7 +472,6 @@
 	ctxt.info->layers[3] = atoi(_tokens[4]);
 
 	_vm->_disk->loadScenery(*ctxt.info, 0, _tokens[1], 0);
-	ctxt.info->hasMask = true;
 }
 
 
@@ -789,11 +788,7 @@
 		}
 
 		if (!scumm_stricmp(_tokens[0], "mask")) {
-			if (ctxt.info->hasMask) {
-				_vm->_gfx->loadGfxObjMask(_tokens[1], data->gfxobj);
-			} else {
-				warning("Mask for zone '%s' ignored, since background doesn't have one", z->_name);
-			}
+			_vm->_gfx->loadGfxObjMask(_tokens[1], data->gfxobj);
 		}
 
 		if (!scumm_stricmp(_tokens[0], "path")) {

Modified: scummvm/trunk/engines/parallaction/walk.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/walk.cpp	2009-01-07 07:21:50 UTC (rev 35764)
+++ scummvm/trunk/engines/parallaction/walk.cpp	2009-01-07 07:35:11 UTC (rev 35765)
@@ -27,29 +27,8 @@
 
 namespace Parallaction {
 
-
-
 #define IS_PATH_CLEAR(x,y) _vm->_gfx->_backgroundInfo->path.getValue((x), (y))
 
-inline byte PathBuffer::getValue(uint16 x, uint16 y) {
-	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;
-
-	case GType_BRA:
-		// Amiga and PC versions pack the path bits the same way in BRA
-		bit = 7 - (x & 7);
-		break;
-
-	default:
-		error("path mask not yet implemented for this game type");
-	}
-	return ((1 << bit) & m) >> bit;
-}
-
 // adjusts position towards nearest walkable point
 //
 void PathBuilder_NS::correctPathPoint(Common::Point &to) {


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