[Scummvm-cvs-logs] scummvm master -> c340159486b499783c297453a14b4df76b4aa535

DrMcCoy drmccoy at drmccoy.de
Sun Mar 11 21:07:19 CET 2012


This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
17e3bfd42c GOB: Add a class for CMP sprites with RXY coordinates
b928d6dcb1 GOB: Use the CMPFile class in DECFile
4db94f805c GOB: Use the CMPFile class in ANIFile
c340159486 GOB: Extend ANIObject to also handle CMP sprite "animations"


Commit: 17e3bfd42c4c66b9bd3ac199f63b8c20c63e8517
    https://github.com/scummvm/scummvm/commit/17e3bfd42c4c66b9bd3ac199f63b8c20c63e8517
Author: Sven Hesse (drmccoy at users.sourceforge.net)
Date: 2012-03-11T13:05:57-07:00

Commit Message:
GOB: Add a class for CMP sprites with RXY coordinates

Changed paths:
  A engines/gob/cmpfile.cpp
  A engines/gob/cmpfile.h
    engines/gob/module.mk
    engines/gob/rxyfile.cpp
    engines/gob/rxyfile.h



diff --git a/engines/gob/cmpfile.cpp b/engines/gob/cmpfile.cpp
new file mode 100644
index 0000000..62ac9f3
--- /dev/null
+++ b/engines/gob/cmpfile.cpp
@@ -0,0 +1,233 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/stream.h"
+#include "common/str.h"
+
+#include "gob/gob.h"
+#include "gob/util.h"
+#include "gob/surface.h"
+#include "gob/video.h"
+#include "gob/dataio.h"
+#include "gob/rxyfile.h"
+#include "gob/cmpfile.h"
+
+namespace Gob {
+
+CMPFile::CMPFile(GobEngine *vm, const Common::String &baseName,
+                 uint16 width, uint16 height, uint8 bpp) :
+	_vm(vm), _width(width), _height(height), _bpp(bpp), _maxWidth(0), _maxHeight(0),
+	_surface(0), _coordinates(0) {
+
+	if (baseName.empty())
+		return;
+
+	const Common::String rxyFile = Util::setExtension(baseName, ".RXY");
+	const Common::String cmpFile = Util::setExtension(baseName, ".CMP");
+
+	if (!_vm->_dataIO->hasFile(cmpFile))
+		return;
+
+	loadRXY(rxyFile);
+	createSurface();
+
+	loadCMP(cmpFile);
+}
+
+CMPFile::CMPFile(GobEngine *vm, const Common::String &cmpFile, const Common::String &rxyFile,
+                 uint16 width, uint16 height, uint8 bpp) :
+	_vm(vm), _width(width), _height(height), _bpp(bpp), _maxWidth(0), _maxHeight(0),
+	_surface(0), _coordinates(0) {
+
+	if (cmpFile.empty() || !_vm->_dataIO->hasFile(cmpFile))
+		return;
+
+	loadRXY(rxyFile);
+	createSurface();
+
+	loadCMP(cmpFile);
+}
+
+CMPFile::CMPFile(GobEngine *vm, Common::SeekableReadStream &cmp, Common::SeekableReadStream &rxy,
+                 uint16 width, uint16 height, uint8 bpp) :
+	_vm(vm), _width(width), _height(height), _bpp(bpp), _maxWidth(0), _maxHeight(0),
+	_surface(0), _coordinates(0) {
+
+	loadRXY(rxy);
+	createSurface();
+
+	loadCMP(cmp);
+}
+
+CMPFile::CMPFile(GobEngine *vm, Common::SeekableReadStream &cmp,
+                 uint16 width, uint16 height, uint8 bpp) :
+	_vm(vm), _width(width), _height(height), _bpp(bpp), _maxWidth(0), _maxHeight(0),
+	_surface(0), _coordinates(0) {
+
+	createRXY();
+	createSurface();
+
+	loadCMP(cmp);
+}
+
+CMPFile::~CMPFile() {
+	delete _surface;
+	delete _coordinates;
+}
+
+bool CMPFile::empty() const {
+	return (_surface == 0) || (_coordinates == 0);
+}
+
+uint16 CMPFile::getSpriteCount() const {
+	if (empty())
+		return 0;
+
+	return _coordinates->size();
+}
+
+void CMPFile::loadCMP(const Common::String &cmp) {
+	Common::SeekableReadStream *dataCMP = _vm->_dataIO->getFile(cmp);
+	if (!dataCMP)
+		return;
+
+	loadCMP(*dataCMP);
+
+	delete dataCMP;
+}
+
+void CMPFile::loadRXY(const Common::String &rxy) {
+	Common::SeekableReadStream *dataRXY = 0;
+	if (!rxy.empty())
+		dataRXY = _vm->_dataIO->getFile(rxy);
+
+	if (dataRXY)
+		loadRXY(*dataRXY);
+	else
+		createRXY();
+
+	_height = _coordinates->getHeight();
+
+	delete dataRXY;
+}
+
+void CMPFile::loadCMP(Common::SeekableReadStream &cmp) {
+	uint32 size = cmp.size();
+	byte  *data = new byte[size];
+
+	if (cmp.read(data, size) != size)
+		return;
+
+	_vm->_video->drawPackedSprite(data, _surface->getWidth(), _surface->getHeight(), 0, 0, 0, *_surface);
+
+	delete[] data;
+}
+
+void CMPFile::loadRXY(Common::SeekableReadStream &rxy) {
+	_coordinates = new RXYFile(rxy);
+
+	for (uint i = 0; i < _coordinates->size(); i++) {
+		const RXYFile::Coordinates &c = (*_coordinates)[i];
+
+		if (c.left == 0xFFFF)
+			continue;
+
+		const uint16 width  = c.right  - c.left + 1;
+		const uint16 height = c.bottom - c.top  + 1;
+
+		_maxWidth  = MAX(_maxWidth , width);
+		_maxHeight = MAX(_maxHeight, height);
+	}
+}
+
+void CMPFile::createRXY() {
+	_coordinates = new RXYFile(_width, _height);
+
+	_maxWidth  = _width;
+	_maxHeight = _height;
+}
+
+void CMPFile::createSurface() {
+	if (_width == 0)
+		_width = 320;
+	if (_height == 0)
+		_height = 200;
+
+	_surface = new Surface(_width, _height, _bpp);
+}
+
+bool CMPFile::getCoordinates(uint16 sprite, uint16 &left, uint16 &top, uint16 &right, uint16 &bottom) const {
+	if (empty() || (sprite >= _coordinates->size()))
+		return false;
+
+	left   = (*_coordinates)[sprite].left;
+	top    = (*_coordinates)[sprite].top;
+	right  = (*_coordinates)[sprite].right;
+	bottom = (*_coordinates)[sprite].bottom;
+
+	return left != 0xFFFF;
+}
+
+uint16 CMPFile::getWidth(uint16 sprite) const {
+	if (empty() || (sprite >= _coordinates->size()))
+		return 0;
+
+	return (*_coordinates)[sprite].right  - (*_coordinates)[sprite].left + 1;
+}
+
+uint16 CMPFile::getHeight(uint16 sprite) const {
+	if (empty() || (sprite >= _coordinates->size()))
+		return 0;
+
+	return (*_coordinates)[sprite].bottom - (*_coordinates)[sprite].top  + 1;
+}
+
+void CMPFile::getMaxSize(uint16 &width, uint16 &height) const {
+	width  = _maxWidth;
+	height = _maxHeight;
+}
+
+void CMPFile::draw(Surface &dest, uint16 sprite, uint16 x, uint16 y, int32 transp) const {
+	if (empty())
+		return;
+
+	if (sprite >= _coordinates->size())
+		return;
+
+	const RXYFile::Coordinates &coords = (*_coordinates)[sprite];
+
+	draw(dest, coords.left, coords.top, coords.right, coords.bottom, x, y, transp);
+}
+
+void CMPFile::draw(Surface &dest, uint16 left, uint16 top, uint16 right, uint16 bottom,
+                   uint16 x, uint16 y, int32 transp) const {
+
+	if (!_surface)
+		return;
+
+	if (left == 0xFFFF)
+		return;
+
+	dest.blit(*_surface, left, top, right, bottom, x, y, transp);
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/cmpfile.h b/engines/gob/cmpfile.h
new file mode 100644
index 0000000..d409e15
--- /dev/null
+++ b/engines/gob/cmpfile.h
@@ -0,0 +1,96 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GOB_CMPFILE_H
+#define GOB_CMPFILE_H
+
+#include "common/system.h"
+#include "common/array.h"
+
+namespace Common {
+	class String;
+	class SeekableReadStream;
+}
+
+namespace Gob {
+
+class GobEngine;
+class Surface;
+class RXYFile;
+
+/** A CMP file, containing a sprite.
+ *
+ *  Used in hardcoded "actiony" parts of gob games.
+ */
+class CMPFile {
+public:
+	CMPFile(GobEngine *vm, const Common::String &baseName,
+	        uint16 width, uint16 height, uint8 bpp = 1);
+	CMPFile(GobEngine *vm, const Common::String &cmpFile, const Common::String &rxyFile,
+	        uint16 width, uint16 height, uint8 bpp = 1);
+	CMPFile(GobEngine *vm, Common::SeekableReadStream &cmp, Common::SeekableReadStream &rxy,
+	        uint16 width, uint16 height, uint8 bpp = 1);
+	CMPFile(GobEngine *vm, Common::SeekableReadStream &cmp,
+	        uint16 width, uint16 height, uint8 bpp = 1);
+	~CMPFile();
+
+	bool empty() const;
+
+	uint16 getSpriteCount() const;
+
+	bool getCoordinates(uint16 sprite, uint16 &left, uint16 &top, uint16 &right, uint16 &bottom) const;
+
+	uint16 getWidth (uint16 sprite) const;
+	uint16 getHeight(uint16 sprite) const;
+
+	void getMaxSize(uint16 &width, uint16 &height) const;
+
+	void draw(Surface &dest, uint16 sprite, uint16 x, uint16 y, int32 transp = -1) const;
+	void draw(Surface &dest, uint16 left, uint16 top, uint16 right, uint16 bottom,
+	          uint16 x, uint16 y, int32 transp = -1) const;
+
+private:
+	GobEngine *_vm;
+
+	uint16 _width;
+	uint16 _height;
+	uint16 _bpp;
+
+	uint16 _maxWidth;
+	uint16 _maxHeight;
+
+	Surface *_surface;
+	RXYFile *_coordinates;
+
+	void loadCMP(const Common::String &cmp);
+	void loadRXY(const Common::String &rxy);
+
+	void loadCMP(Common::SeekableReadStream &cmp);
+	void loadRXY(Common::SeekableReadStream &rxy);
+
+	void createRXY();
+	void createSurface();
+};
+
+} // End of namespace Gob
+
+#endif // GOB_CMPFILE_H
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index 1c83b4a..9da5a82 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS := \
 	aniobject.o \
 	cheater.o \
 	cheater_geisha.o \
+	cmpfile.o \
 	console.o \
 	dataio.o \
 	databases.o \
diff --git a/engines/gob/rxyfile.cpp b/engines/gob/rxyfile.cpp
index 5311eec..06a07bd 100644
--- a/engines/gob/rxyfile.cpp
+++ b/engines/gob/rxyfile.cpp
@@ -30,6 +30,15 @@ RXYFile::RXYFile(Common::SeekableReadStream &rxy) : _width(0), _height(0) {
 	load(rxy);
 }
 
+RXYFile::RXYFile(uint16 width, uint16 height) : _realCount(1), _width(width), _height(height) {
+	_coords.resize(1);
+
+	_coords[0].left   = 0;
+	_coords[0].top    = 0;
+	_coords[0].right  = _width  - 1;
+	_coords[0].bottom = _height - 1;
+}
+
 RXYFile::~RXYFile() {
 }
 
diff --git a/engines/gob/rxyfile.h b/engines/gob/rxyfile.h
index 828f8b7..3b4d3de 100644
--- a/engines/gob/rxyfile.h
+++ b/engines/gob/rxyfile.h
@@ -46,6 +46,7 @@ public:
 	};
 
 	RXYFile(Common::SeekableReadStream &rxy);
+	RXYFile(uint16 width, uint16 height);
 	~RXYFile();
 
 	uint size() const;


Commit: b928d6dcb1749a140bf26d23211bfae6f4585ba3
    https://github.com/scummvm/scummvm/commit/b928d6dcb1749a140bf26d23211bfae6f4585ba3
Author: Sven Hesse (drmccoy at users.sourceforge.net)
Date: 2012-03-11T13:05:57-07:00

Commit Message:
GOB: Use the CMPFile class in DECFile

Changed paths:
    engines/gob/decfile.cpp
    engines/gob/decfile.h



diff --git a/engines/gob/decfile.cpp b/engines/gob/decfile.cpp
index f5910f0..fb67c52 100644
--- a/engines/gob/decfile.cpp
+++ b/engines/gob/decfile.cpp
@@ -29,25 +29,14 @@
 #include "gob/dataio.h"
 #include "gob/surface.h"
 #include "gob/video.h"
-#include "gob/rxyfile.h"
+#include "gob/cmpfile.h"
 #include "gob/decfile.h"
 
 namespace Gob {
 
-DECFile::Layer::Layer() : surface(0), coordinates(0) {
-}
-
-DECFile::Layer::~Layer() {
-	delete coordinates;
-	delete surface;
-}
-
-
 DECFile::DECFile(GobEngine *vm, const Common::String &fileName,
                  uint16 width, uint16 height, uint8 bpp) : _vm(vm),
-	_width(width), _height(height), _bpp(bpp), _hasPadding(false) {
-
-	_backdrop = new Surface(_width, _height, _bpp);
+	_width(width), _height(height), _bpp(bpp), _hasPadding(false), _backdrop(0) {
 
 	Common::SeekableReadStream *dec = _vm->_dataIO->getFile(fileName);
 	if (dec) {
@@ -77,6 +66,9 @@ DECFile::DECFile(GobEngine *vm, const Common::String &fileName,
 
 DECFile::~DECFile() {
 	delete _backdrop;
+
+	for (LayerArray::iterator l = _layers.begin(); l != _layers.end(); ++l)
+		delete *l;
 }
 
 void DECFile::load(Common::SeekableSubReadStreamEndian &dec, const Common::String &fileName) {
@@ -102,9 +94,9 @@ void DECFile::load(Common::SeekableSubReadStreamEndian &dec, const Common::Strin
 	}
 
 	// Load the layers
-	_layers.resize(MAX(0, layerCount - 1));
-	for (LayerArray::iterator l = _layers.begin(); l != _layers.end(); ++l)
-		loadLayer(*l, dec);
+	_layers.reserve(MAX(0, layerCount - 1));
+	for (int i = 0; i < layerCount - 1; i++)
+		_layers.push_back(loadLayer(dec));
 
 	// Load the backdrop parts
 	if (backdropCount > 0)
@@ -113,43 +105,19 @@ void DECFile::load(Common::SeekableSubReadStreamEndian &dec, const Common::Strin
 
 void DECFile::loadBackdrop(Common::SeekableSubReadStreamEndian &dec) {
 	// Interestingly, DEC files reference "FOO.LBM" instead of "FOO.CMP"
-	Common::String file = Util::setExtension(Util::readString(dec, 13), ".CMP");
+	Common::String file = Util::setExtension(Util::readString(dec, 13), "");
 	if (_hasPadding)
 		dec.skip(1);
 
-	if (file.empty() || !_vm->_dataIO->hasFile(file))
-		return;
-
-	_vm->_video->drawPackedSprite(file.c_str(), *_backdrop);
+	_backdrop = new CMPFile(_vm, file, _width, _height, _bpp);
 }
 
-void DECFile::loadLayer(Layer &layer, Common::SeekableSubReadStreamEndian &dec) {
-	Common::String file = Util::readString(dec, 13);
+CMPFile *DECFile::loadLayer(Common::SeekableSubReadStreamEndian &dec) {
+	Common::String file = Util::setExtension(Util::readString(dec, 13), "");
 	if (_hasPadding)
 		dec.skip(1);
 
-	if (file.empty())
-		return;
-
-	Common::String fileRXY = Util::setExtension(file, ".RXY");
-	Common::String fileCMP = Util::setExtension(file, ".CMP");
-	if (!_vm->_dataIO->hasFile(fileRXY) || !_vm->_dataIO->hasFile(fileCMP))
-		return;
-
-	loadLayer(layer, fileRXY, fileCMP);
-}
-
-void DECFile::loadLayer(Layer &layer, const Common::String &fileRXY,
-                                      const Common::String &fileCMP) {
-
-	Common::SeekableReadStream *dataRXY = _vm->_dataIO->getFile(fileRXY);
-	if (!dataRXY)
-		return;
-
-	layer.coordinates = new RXYFile(*dataRXY);
-	layer.surface     = new Surface(_width, layer.coordinates->getHeight(), _bpp);
-
-	_vm->_video->drawPackedSprite(fileCMP.c_str(), *layer.surface);
+	return new CMPFile(_vm, file, _width, _height, _bpp);
 }
 
 void DECFile::loadParts(Common::SeekableSubReadStreamEndian &dec) {
@@ -188,7 +156,10 @@ void DECFile::draw(Surface &dest) const {
 }
 
 void DECFile::drawBackdrop(Surface &dest) const {
-	dest.blit(*_backdrop);
+	if (!_backdrop)
+		return;
+
+	_backdrop->draw(dest, 0, 0, 0);
 }
 
 void DECFile::drawLayer(Surface &dest, uint16 layer, uint16 part,
@@ -197,18 +168,7 @@ void DECFile::drawLayer(Surface &dest, uint16 layer, uint16 part,
 	if (layer >= _layers.size())
 		return;
 
-	const Layer &l = _layers[layer];
-	if (!l.surface || !l.coordinates)
-		return;
-
-	if (part >= l.coordinates->size())
-		return;
-
-	const RXYFile::Coordinates &c = (*l.coordinates)[part];
-	if (c.left == 0xFFFF)
-		return;
-
-	dest.blit(*l.surface, c.left, c.top, c.right, c.bottom, x, y, transp);
+	_layers[layer]->draw(dest, part, x, y, transp);
 }
 
 } // End of namespace Gob
diff --git a/engines/gob/decfile.h b/engines/gob/decfile.h
index 31d9018..48af740 100644
--- a/engines/gob/decfile.h
+++ b/engines/gob/decfile.h
@@ -34,7 +34,7 @@ namespace Gob {
 
 class GobEngine;
 class Surface;
-class RXYFile;
+class CMPFile;
 
 /** A DEC file, describing a "decal" (background).
  *
@@ -60,14 +60,6 @@ public:
 	               uint16 x, uint16 y, int32 transp = -1) const;
 
 private:
-	struct Layer {
-		Surface *surface;     ///< The surface containing the layer sprite.
-		RXYFile *coordinates; ///< The coordinates describing the layer sprite parts.
-
-		Layer();
-		~Layer();
-	};
-
 	struct Part {
 		uint8 layer;
 		uint8 part;
@@ -77,8 +69,8 @@ private:
 		bool transp;
 	};
 
-	typedef Common::Array<Layer> LayerArray;
-	typedef Common::Array<Part>  PartArray;
+	typedef Common::Array<CMPFile *> LayerArray;
+	typedef Common::Array<Part>      PartArray;
 
 	GobEngine *_vm;
 
@@ -88,7 +80,7 @@ private:
 
 	byte _hasPadding;
 
-	Surface *_backdrop;
+	CMPFile *_backdrop;
 
 	LayerArray _layers;
 	PartArray  _parts;
@@ -98,9 +90,7 @@ private:
 
 	void loadBackdrop(Common::SeekableSubReadStreamEndian &dec);
 
-	void loadLayer(Layer &layer, Common::SeekableSubReadStreamEndian &dec);
-	void loadLayer(Layer &layer, const Common::String &fileRXY,
-	                             const Common::String &fileCMP);
+	CMPFile *loadLayer(Common::SeekableSubReadStreamEndian &dec);
 
 	void loadParts(Common::SeekableSubReadStreamEndian &dec);
 	void loadPart(Part &part, Common::SeekableSubReadStreamEndian &dec);


Commit: 4db94f805c0d73b80d93526b5a696fa1248a9754
    https://github.com/scummvm/scummvm/commit/4db94f805c0d73b80d93526b5a696fa1248a9754
Author: Sven Hesse (drmccoy at users.sourceforge.net)
Date: 2012-03-11T13:05:57-07:00

Commit Message:
GOB: Use the CMPFile class in ANIFile

Changed paths:
    engines/gob/anifile.cpp
    engines/gob/anifile.h



diff --git a/engines/gob/anifile.cpp b/engines/gob/anifile.cpp
index 1a905f1..2671fe0 100644
--- a/engines/gob/anifile.cpp
+++ b/engines/gob/anifile.cpp
@@ -28,19 +28,11 @@
 #include "gob/dataio.h"
 #include "gob/surface.h"
 #include "gob/video.h"
+#include "gob/cmpfile.h"
 #include "gob/anifile.h"
 
 namespace Gob {
 
-ANIFile::Layer::Layer() : surface(0), coordinates(0) {
-}
-
-ANIFile::Layer::~Layer() {
-	delete coordinates;
-	delete surface;
-}
-
-
 ANIFile::ANIFile(GobEngine *vm, const Common::String &fileName,
                  uint16 width, uint8 bpp) : _vm(vm),
 	_width(width), _bpp(bpp), _hasPadding(false) {
@@ -72,6 +64,8 @@ ANIFile::ANIFile(GobEngine *vm, const Common::String &fileName,
 }
 
 ANIFile::~ANIFile() {
+	for (LayerArray::iterator l = _layers.begin(); l != _layers.end(); ++l)
+		delete *l;
 }
 
 void ANIFile::load(Common::SeekableSubReadStreamEndian &ani, const Common::String &fileName) {
@@ -90,9 +84,9 @@ void ANIFile::load(Common::SeekableSubReadStreamEndian &ani, const Common::Strin
 		if (_hasPadding)
 			ani.skip(1);
 
-		_layers.resize(layerCount - 1);
-		for (LayerArray::iterator l = _layers.begin(); l != _layers.end(); ++l)
-			loadLayer(*l, ani);
+		_layers.reserve(layerCount - 1);
+		for (int i = 0; i < layerCount - 1; i++)
+			_layers.push_back(loadLayer(ani));
 	}
 
 	_maxWidth  = 0;
@@ -158,14 +152,13 @@ void ANIFile::loadAnimation(Animation &animation, FrameArray &frames,
 		area.right = area.bottom = -0x7FFF;
 
 		for (ChunkList::const_iterator c = frame.begin(); c != frame.end(); c++) {
-			const Layer *layer;
-			const RXYFile::Coordinates *coords;
+			uint16 cL, cT, cR, cB;
 
-			if (!getPart(c->layer, c->part, layer, coords))
+			if (!getCoordinates(c->layer, c->part, cL, cT, cR, cB))
 				continue;
 
-			const uint16 width  = coords->right  - coords->left + 1;
-			const uint16 height = coords->bottom - coords->top  + 1;
+			const uint16 width  = cR - cL + 1;
+			const uint16 height = cB - cT + 1;
 
 			const uint16 l = c->x;
 			const uint16 t = c->y;
@@ -233,33 +226,12 @@ void ANIFile::loadFrames(FrameArray &frames, Common::SeekableSubReadStreamEndian
 	}
 }
 
-void ANIFile::loadLayer(Layer &layer, Common::SeekableSubReadStreamEndian &ani) {
-	Common::String file = Util::readString(ani, 13);
+CMPFile *ANIFile::loadLayer(Common::SeekableSubReadStreamEndian &ani) {
+	Common::String file = Util::setExtension(Util::readString(ani, 13), "");
 	if (_hasPadding)
 		ani.skip(1);
 
-	if (file.empty())
-		return;
-
-	Common::String fileRXY = Util::setExtension(file, ".RXY");
-	Common::String fileCMP = Util::setExtension(file, ".CMP");
-	if (!_vm->_dataIO->hasFile(fileRXY) || !_vm->_dataIO->hasFile(fileCMP))
-		return;
-
-	loadLayer(layer, fileRXY, fileCMP);
-}
-
-void ANIFile::loadLayer(Layer &layer, const Common::String &fileRXY,
-                                      const Common::String &fileCMP) {
-
-	Common::SeekableReadStream *dataRXY = _vm->_dataIO->getFile(fileRXY);
-	if (!dataRXY)
-		return;
-
-	layer.coordinates = new RXYFile(*dataRXY);
-	layer.surface     = new Surface(_width, layer.coordinates->getHeight(), _bpp);
-
-	_vm->_video->drawPackedSprite(fileCMP.c_str(), *layer.surface);
+	return new CMPFile(_vm, file, _width, 0, _bpp);
 }
 
 uint16 ANIFile::getAnimationCount() const {
@@ -277,24 +249,13 @@ const ANIFile::Animation &ANIFile::getAnimationInfo(uint16 animation) const {
 	return _animations[animation];
 }
 
-bool ANIFile::getPart(uint16 layer, uint16 part,
-                      const Layer *&l, const RXYFile::Coordinates *&c) const {
+bool ANIFile::getCoordinates(uint16 layer, uint16 part,
+                             uint16 &left, uint16 &top, uint16 &right, uint16 &bottom) const {
 
 	if (layer >= _layers.size())
 		return false;
 
-	l = &_layers[layer];
-	if (!l->surface || !l->coordinates)
-		return false;
-
-	if (part >= l->coordinates->size())
-		return false;
-
-	c = &(*l->coordinates)[part];
-	if (c->left == 0xFFFF)
-		return false;
-
-	return true;
+	return _layers[layer]->getCoordinates(part, left, top, right, bottom);
 }
 
 void ANIFile::draw(Surface &dest, uint16 animation, uint16 frame, int16 x, int16 y) const {
@@ -314,13 +275,10 @@ void ANIFile::draw(Surface &dest, uint16 animation, uint16 frame, int16 x, int16
 void ANIFile::drawLayer(Surface &dest, uint16 layer, uint16 part,
                         int16 x, int16 y, int32 transp) const {
 
-	const Layer *l;
-	const RXYFile::Coordinates *c;
-
-	if (!getPart(layer, part, l, c))
+	if (layer >= _layers.size())
 		return;
 
-	dest.blit(*l->surface, c->left, c->top, c->right, c->bottom, x, y, transp);
+	_layers[layer]->draw(dest, part, x, y, transp);
 }
 
 } // End of namespace Gob
diff --git a/engines/gob/anifile.h b/engines/gob/anifile.h
index 1e10da6..b6d9c73 100644
--- a/engines/gob/anifile.h
+++ b/engines/gob/anifile.h
@@ -28,8 +28,6 @@
 #include "common/array.h"
 #include "common/list.h"
 
-#include "gob/rxyfile.h"
-
 namespace Common {
 	class SeekableSubReadStreamEndian;
 }
@@ -38,6 +36,7 @@ namespace Gob {
 
 class GobEngine;
 class Surface;
+class CMPFile;
 
 /** An ANI file, describing an animation.
  *
@@ -94,16 +93,7 @@ public:
 	void draw(Surface &dest, uint16 animation, uint16 frame, int16 x, int16 y) const;
 
 private:
-	/** A sprite layer. */
-	struct Layer {
-		Surface *surface;     ///< The surface containing the layer sprite.
-		RXYFile *coordinates; ///< The coordinates describing the layer sprite parts.
-
-		Layer();
-		~Layer();
-	};
-
-	typedef Common::Array<Layer> LayerArray;
+	typedef Common::Array<CMPFile *> LayerArray;
 	typedef Common::Array<Animation> AnimationArray;
 
 	/** A "chunk" of an animation frame. */
@@ -139,9 +129,7 @@ private:
 
 	void load(Common::SeekableSubReadStreamEndian &ani, const Common::String &fileName);
 
-	void loadLayer(Layer &layer, Common::SeekableSubReadStreamEndian &ani);
-	void loadLayer(Layer &layer, const Common::String &fileRXY,
-	                             const Common::String &fileCMP);
+	CMPFile *loadLayer(Common::SeekableSubReadStreamEndian &ani);
 
 	void loadAnimation(Animation &animation, FrameArray &frames,
 	                   Common::SeekableSubReadStreamEndian &ani);
@@ -149,8 +137,8 @@ private:
 
 	// Drawing helpers
 
-	bool getPart(uint16 layer, uint16 part,
-	             const Layer *&l, const RXYFile::Coordinates *&c) const;
+	bool getCoordinates(uint16 layer, uint16 part,
+	                    uint16 &left, uint16 &top, uint16 &right, uint16 &bottom) const;
 
 	void drawLayer(Surface &dest, uint16 layer, uint16 part,
 	              int16 x, int16 y, int32 transp) const;


Commit: c340159486b499783c297453a14b4df76b4aa535
    https://github.com/scummvm/scummvm/commit/c340159486b499783c297453a14b4df76b4aa535
Author: Sven Hesse (drmccoy at users.sourceforge.net)
Date: 2012-03-11T13:05:57-07:00

Commit Message:
GOB: Extend ANIObject to also handle CMP sprite "animations"

Changed paths:
    engines/gob/aniobject.cpp
    engines/gob/aniobject.h



diff --git a/engines/gob/aniobject.cpp b/engines/gob/aniobject.cpp
index 0ca850d..154f8e0 100644
--- a/engines/gob/aniobject.cpp
+++ b/engines/gob/aniobject.cpp
@@ -22,11 +22,20 @@
 
 #include "gob/surface.h"
 #include "gob/anifile.h"
+#include "gob/cmpfile.h"
 #include "gob/aniobject.h"
 
 namespace Gob {
 
-ANIObject::ANIObject(const ANIFile &ani) : _ani(&ani),
+ANIObject::ANIObject(const ANIFile &ani) : _ani(&ani), _cmp(0),
+	_visible(false), _paused(false), _mode(kModeContinuous),
+	_x(0), _y(0), _background(0), _drawn(false) {
+
+	setAnimation(0);
+	setPosition();
+}
+
+ANIObject::ANIObject(const CMPFile &cmp) : _ani(0), _cmp(&cmp),
 	_visible(false), _paused(false), _mode(kModeContinuous),
 	_x(0), _y(0), _background(0), _drawn(false) {
 
@@ -68,6 +77,10 @@ void ANIObject::rewind() {
 }
 
 void ANIObject::setPosition() {
+	// CMP "animations" have no default position
+	if (_cmp)
+		return;
+
 	if (_animation >= _ani->getAnimationCount())
 		return;
 
@@ -88,6 +101,12 @@ void ANIObject::getPosition(int16 &x, int16 &y) const {
 }
 
 void ANIObject::getFramePosition(int16 &x, int16 &y) const {
+	// CMP "animations" have no specific frame positions
+	if (_cmp) {
+		getPosition(x, y);
+		return;
+	}
+
 	if (_animation >= _ani->getAnimationCount())
 		return;
 
@@ -100,6 +119,13 @@ void ANIObject::getFramePosition(int16 &x, int16 &y) const {
 }
 
 void ANIObject::getFrameSize(int16 &width, int16 &height) const {
+	if (_cmp) {
+		width  = _cmp->getWidth (_animation);
+		height = _cmp->getHeight(_animation);
+
+		return;
+	}
+
 	if (_animation >= _ani->getAnimationCount())
 		return;
 
@@ -147,6 +173,47 @@ void ANIObject::draw(Surface &dest, int16 &left, int16 &top,
 	if (!_visible)
 		return;
 
+	if      (_cmp)
+		drawCMP(dest, left, top, right, bottom);
+	else if (_ani)
+		drawANI(dest, left, top, right, bottom);
+}
+
+void ANIObject::drawCMP(Surface &dest, int16 &left, int16 &top,
+                                       int16 &right, int16 &bottom) {
+
+	if (!_background) {
+		uint16 width, height;
+
+		_cmp->getMaxSize(width, height);
+
+		_background = new Surface(width, height, dest.getBPP());
+	}
+
+	const uint16 cR = _cmp->getWidth (_animation) - 1;
+	const uint16 cB = _cmp->getHeight(_animation) - 1;
+
+	_backgroundLeft   = CLIP<int16>(   + _x, 0, dest.getWidth () - 1);
+	_backgroundTop    = CLIP<int16>(   + _y, 0, dest.getHeight() - 1);
+	_backgroundRight  = CLIP<int16>(cR + _x, 0, dest.getWidth () - 1);
+	_backgroundBottom = CLIP<int16>(cB + _y, 0, dest.getHeight() - 1);
+
+	_background->blit(dest, _backgroundLeft , _backgroundTop,
+	                        _backgroundRight, _backgroundBottom, 0, 0);
+
+	_cmp->draw(dest, _animation, _x, _y, 0);
+
+	_drawn = true;
+
+	left   = _backgroundLeft;
+	top    = _backgroundTop;
+	right  = _backgroundRight;
+	bottom = _backgroundBottom;
+}
+
+void ANIObject::drawANI(Surface &dest, int16 &left, int16 &top,
+                                       int16 &right, int16 &bottom) {
+
 	if (!_background) {
 		uint16 width, height;
 
@@ -202,6 +269,10 @@ void ANIObject::advance() {
 	if (_paused)
 		return;
 
+	// CMP "animations" have only one frame
+	if (_cmp)
+		return;
+
 	if (_animation >= _ani->getAnimationCount())
 		return;
 
@@ -229,6 +300,10 @@ uint16 ANIObject::getFrame() const {
 }
 
 bool ANIObject::lastFrame() const {
+	// CMP "animations" have only one frame
+	if (_cmp)
+		return true;
+
 	if (_animation >= _ani->getAnimationCount())
 		return true;
 
diff --git a/engines/gob/aniobject.h b/engines/gob/aniobject.h
index e3fe301..c101d74 100644
--- a/engines/gob/aniobject.h
+++ b/engines/gob/aniobject.h
@@ -28,6 +28,7 @@
 namespace Gob {
 
 class ANIFile;
+class CMPFile;
 class Surface;
 
 /** An ANI object, controlling an animation within an ANI file. */
@@ -38,7 +39,10 @@ public:
 		kModeOnce        ///< Play the animation only once.
 	};
 
+	/** Create an animation object from an ANI file. */
 	ANIObject(const ANIFile &ani);
+	/** Create an animation object from a CMP sprite. */
+	ANIObject(const CMPFile &cmp);
 	virtual ~ANIObject();
 
 	/** Make the object visible/invisible. */
@@ -98,6 +102,7 @@ public:
 
 private:
 	const ANIFile *_ani; ///< The managed ANI file.
+	const CMPFile *_cmp; ///< The managed CMP file.
 
 	uint16 _animation; ///< The current animation number
 	uint16 _frame;     ///< The current frame.
@@ -117,6 +122,9 @@ private:
 	int16 _backgroundTop;    ///< The top of the saved background.
 	int16 _backgroundRight;  ///< The right position of the saved background.
 	int16 _backgroundBottom; ///< The bottom position of the saved background.
+
+	void drawCMP(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom);
+	void drawANI(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom);
 };
 
 } // End of namespace Gob






More information about the Scummvm-git-logs mailing list