[Scummvm-cvs-logs] SF.net SVN: scummvm:[47258] scummvm/trunk

sev at users.sourceforge.net sev at users.sourceforge.net
Mon Jan 11 21:41:08 CET 2010


Revision: 47258
          http://scummvm.svn.sourceforge.net/scummvm/?rev=47258&view=rev
Author:   sev
Date:     2010-01-11 20:41:07 +0000 (Mon, 11 Jan 2010)

Log Message:
-----------
Move Mac Binary resource loader to common class. Plug tons of memory leaks along the way.

Modified Paths:
--------------
    scummvm/trunk/common/module.mk
    scummvm/trunk/engines/scumm/he/resource_he.cpp
    scummvm/trunk/engines/scumm/he/resource_he.h

Added Paths:
-----------
    scummvm/trunk/common/macresman.cpp
    scummvm/trunk/common/macresman.h

Added: scummvm/trunk/common/macresman.cpp
===================================================================
--- scummvm/trunk/common/macresman.cpp	                        (rev 0)
+++ scummvm/trunk/common/macresman.cpp	2010-01-11 20:41:07 UTC (rev 47258)
@@ -0,0 +1,393 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/scummsys.h"
+#include "common/debug.h"
+#include "common/file.h"
+#include "common/util.h"
+
+#include "common/macresman.h"
+
+namespace Common {
+
+MacResManager::MacResManager(Common::String fileName) : _fileName(fileName), _resOffset(-1) {
+	_resFile.open(_fileName);
+
+	if (!_resFile.isOpen()) {
+		error("Cannot open file %s", _fileName.c_str());
+	}
+
+	if (!init())
+		error("Resource fork is missing in file '%s'", _fileName.c_str());
+}
+
+MacResManager::~MacResManager() {
+	for (int i = 0; i < _resMap.numTypes; i++) {
+		for (int j = 0; j < _resTypes[i].items; j++) {
+			if (_resLists[i][j].nameOffset != -1) {
+				delete _resLists[i][j].name;
+			}
+		}
+		delete _resLists[i];
+	}
+
+	delete _resLists;
+	delete _resTypes;
+
+	_resFile.close();
+}
+
+#define MBI_INFOHDR 128
+#define MBI_ZERO1 0
+#define MBI_NAMELEN 1
+#define MBI_ZERO2 74
+#define MBI_ZERO3 82
+#define MBI_DFLEN 83
+#define MBI_RFLEN 87
+#define MAXNAMELEN 63
+
+bool MacResManager::init() {
+	byte infoHeader[MBI_INFOHDR];
+	int32 data_size, rsrc_size;
+	int32 data_size_pad, rsrc_size_pad;
+	int filelen;
+
+	filelen = _resFile.size();
+	_resFile.read(infoHeader, MBI_INFOHDR);
+
+	// Maybe we have MacBinary?
+	if (infoHeader[MBI_ZERO1] == 0 && infoHeader[MBI_ZERO2] == 0 &&
+		infoHeader[MBI_ZERO3] == 0 && infoHeader[MBI_NAMELEN] <= MAXNAMELEN) {
+
+		// Pull out fork lengths
+		data_size = READ_BE_UINT32(infoHeader + MBI_DFLEN);
+		rsrc_size = READ_BE_UINT32(infoHeader + MBI_RFLEN);
+
+		data_size_pad = (((data_size + 127) >> 7) << 7);
+		rsrc_size_pad = (((rsrc_size + 127) >> 7) << 7);
+
+		// Length check
+		int sumlen =  MBI_INFOHDR + data_size_pad + rsrc_size_pad;
+
+		if (sumlen == filelen)
+			_resOffset = MBI_INFOHDR + data_size_pad;
+	}
+
+	if (_resOffset == -1) // MacBinary check is failed
+		_resOffset = 0; // Maybe we have dumped fork?
+
+	_resFile.seek(_resOffset);
+
+	_dataOffset = _resFile.readUint32BE() + _resOffset;
+	_mapOffset = _resFile.readUint32BE() + _resOffset;
+	_dataLength = _resFile.readUint32BE();
+	_mapLength = _resFile.readUint32BE();
+
+	// do sanity check
+	if (_dataOffset >= filelen || _mapOffset >= filelen ||
+		_dataLength + _mapLength  > filelen) {
+		_resOffset = -1;
+		return false;
+	}
+
+	debug(7, "got header: data %d [%d] map %d [%d]",
+		_dataOffset, _dataLength, _mapOffset, _mapLength);
+
+	readMap();
+
+	return true;
+}
+
+MacResIDArray MacResManager::getResIDArray(const char *typeID) {
+	int typeNum = -1;
+	MacResIDArray res;
+
+	for (int i = 0; i < _resMap.numTypes; i++)
+		if (strcmp(_resTypes[i].id, typeID) == 0) {
+			typeNum = i;
+			break;
+		}
+
+	if (typeNum == -1)
+		return res;
+	
+	res.resize(_resTypes[typeNum].items);
+
+	for (int i = 0; i < _resTypes[typeNum].items; i++)
+		res[i] = _resLists[typeNum][i].id;
+
+	return res;
+}
+
+char *MacResManager::getResName(const char *typeID, int16 resID) {
+	int i;
+	int typeNum = -1;
+
+	for (i = 0; i < _resMap.numTypes; i++)
+		if (strcmp(_resTypes[i].id, typeID) == 0) {
+			typeNum = i;
+			break;
+		}
+
+	if (typeNum == -1)
+		return NULL;
+
+	for (i = 0; i < _resTypes[typeNum].items; i++)
+		if (_resLists[typeNum][i].id == resID)
+			return _resLists[typeNum][i].name;
+
+	return NULL;
+}
+
+byte *MacResManager::getResource(const char *typeID, int16 resID, int *size) {
+	int i;
+	int typeNum = -1;
+	int resNum = -1;
+	byte *buf;
+	int len;
+
+	for (i = 0; i < _resMap.numTypes; i++)
+		if (strcmp(_resTypes[i].id, typeID) == 0) {
+			typeNum = i;
+			break;
+		}
+
+	if (typeNum == -1)
+		return NULL;
+
+	for (i = 0; i < _resTypes[typeNum].items; i++)
+		if (_resLists[typeNum][i].id == resID) {
+			resNum = i;
+			break;
+		}
+
+	if (resNum == -1)
+		return NULL;
+
+	_resFile.seek(_dataOffset + _resLists[typeNum][resNum].dataOffset);
+
+	len = _resFile.readUint32BE();
+	buf = (byte *)malloc(len);
+
+	_resFile.read(buf, len);
+
+	*size = len;
+
+	return buf;
+}
+
+void MacResManager::readMap() {
+	int	i, j, len;
+
+	_resFile.seek(_mapOffset + 22);
+
+	_resMap.resAttr = _resFile.readUint16BE();
+	_resMap.typeOffset = _resFile.readUint16BE();
+	_resMap.nameOffset = _resFile.readUint16BE();
+	_resMap.numTypes = _resFile.readUint16BE();
+	_resMap.numTypes++;
+
+	_resFile.seek(_mapOffset + _resMap.typeOffset + 2);
+	_resTypes = new ResType[_resMap.numTypes];
+
+	for (i = 0; i < _resMap.numTypes; i++) {
+		_resFile.read(_resTypes[i].id, 4);
+		_resTypes[i].id[4] = 0;
+		_resTypes[i].items = _resFile.readUint16BE();
+		_resTypes[i].offset = _resFile.readUint16BE();
+		_resTypes[i].items++;
+
+		debug(8, "resType: <%s> items: %d offset: %d (0x%x)", _resTypes[i].id, _resTypes[i].items,  _resTypes[i].offset, _resTypes[i].offset);
+	}
+
+	_resLists = new ResPtr[_resMap.numTypes];
+
+	for (i = 0; i < _resMap.numTypes; i++) {
+		_resLists[i] = new Resource[_resTypes[i].items];
+		_resFile.seek(_resTypes[i].offset + _mapOffset + _resMap.typeOffset);
+
+		for (j = 0; j < _resTypes[i].items; j++) {
+			ResPtr resPtr = _resLists[i] + j;
+
+			resPtr->id = _resFile.readUint16BE();
+			resPtr->nameOffset = _resFile.readUint16BE();
+			resPtr->dataOffset = _resFile.readUint32BE();
+			_resFile.readUint32BE();
+			resPtr->name = 0;
+
+			resPtr->attr = resPtr->dataOffset >> 24;
+			resPtr->dataOffset &= 0xFFFFFF;
+		}
+
+		for (j = 0; j < _resTypes[i].items; j++) {
+			if (_resLists[i][j].nameOffset != -1) {
+				_resFile.seek(_resLists[i][j].nameOffset + _mapOffset + _resMap.nameOffset);
+
+				len = _resFile.readByte();
+				_resLists[i][j].name = new char[len + 1];
+				_resLists[i][j].name[len] = 0;
+				_resFile.read(_resLists[i][j].name, len);
+			}
+		}
+	}
+}
+
+void MacResManager::convertCursor(byte *data, int datasize, byte **cursor, int *w, int *h,
+					 int *hotspot_x, int *hotspot_y, int *keycolor, bool colored, byte **palette, int *palSize) {
+	Common::MemoryReadStream dis(data, datasize);
+	int i, b;
+	byte imageByte;
+	byte *iconData;
+	int numBytes;
+	int pixelsPerByte, bpp;
+	int ctSize;
+	byte bitmask;
+	int iconRowBytes, iconBounds[4];
+	int ignored;
+	int iconDataSize;
+
+	dis.readUint16BE(); // type
+	dis.readUint32BE(); // offset to pixel map
+	dis.readUint32BE(); // offset to pixel data
+	dis.readUint32BE(); // expanded cursor data
+	dis.readUint16BE(); // expanded data depth
+	dis.readUint32BE(); // reserved
+
+	// Grab B/W icon data
+	*cursor = (byte *)malloc(16 * 16);
+	for (i = 0; i < 32; i++) {
+		imageByte = dis.readByte();
+		for (b = 0; b < 8; b++)
+			cursor[0][i*8+b] = (byte)((imageByte & (0x80 >> b)) > 0? 0x0F: 0x00);
+	}
+
+	// Apply mask data
+	for (i = 0; i < 32; i++) {
+		imageByte = dis.readByte();
+		for (b = 0; b < 8; b++)
+			if ((imageByte & (0x80 >> b)) == 0)
+				cursor[0][i*8+b] = 0xff;
+	}
+
+	*hotspot_y = dis.readUint16BE();
+	*hotspot_x = dis.readUint16BE();
+	*w = *h = 16;
+
+	// Use b/w cursor on backends which don't support cursor palettes
+	if (!colored)
+		return;
+
+	dis.readUint32BE(); // reserved
+	dis.readUint32BE(); // cursorID
+
+	// Color version of cursor
+	dis.readUint32BE(); // baseAddr
+
+	// Keep only lowbyte for now
+	dis.readByte();
+	iconRowBytes = dis.readByte();
+
+	if (!iconRowBytes)
+		return;
+
+	iconBounds[0] = dis.readUint16BE();
+	iconBounds[1] = dis.readUint16BE();
+	iconBounds[2] = dis.readUint16BE();
+	iconBounds[3] = dis.readUint16BE();
+
+	dis.readUint16BE(); // pmVersion
+	dis.readUint16BE(); // packType
+	dis.readUint32BE(); // packSize
+
+	dis.readUint32BE(); // hRes
+	dis.readUint32BE(); // vRes
+
+	dis.readUint16BE(); // pixelType
+	dis.readUint16BE(); // pixelSize
+	dis.readUint16BE(); // cmpCount
+	dis.readUint16BE(); // cmpSize
+
+	dis.readUint32BE(); // planeByte
+	dis.readUint32BE(); // pmTable
+	dis.readUint32BE(); // reserved
+
+	// Pixel data for cursor
+	iconDataSize =  iconRowBytes * (iconBounds[3] - iconBounds[1]);
+	iconData = (byte *)malloc(iconDataSize);
+	dis.read(iconData, iconDataSize);
+
+	// Color table
+	dis.readUint32BE(); // ctSeed
+	dis.readUint16BE(); // ctFlag
+	ctSize = dis.readUint16BE() + 1;
+
+	*palette = (byte *)malloc(ctSize * 4);
+
+	// Read just high byte of 16-bit color
+	for (int c = 0; c < ctSize; c++) {
+		// We just use indices 0..ctSize, so ignore color ID
+		dis.readUint16BE(); // colorID[c]
+
+		palette[0][c * 4 + 0] = dis.readByte();
+		ignored = dis.readByte();
+
+		palette[0][c * 4 + 1] = dis.readByte();
+		ignored = dis.readByte();
+
+		palette[0][c * 4 + 2] = dis.readByte();
+		ignored = dis.readByte();
+
+		palette[0][c * 4 + 3] = 0;
+	}
+
+	*palSize = ctSize;
+
+	numBytes = (iconBounds[2] - iconBounds[0]) * (iconBounds[3] - iconBounds[1]);
+
+	pixelsPerByte = (iconBounds[2] - iconBounds[0]) / iconRowBytes;
+	bpp           = 8 / pixelsPerByte;
+
+	// build a mask to make sure the pixels are properly shifted out
+	bitmask = 0;
+	for (int m = 0; m < bpp; m++) {
+		bitmask <<= 1;
+		bitmask  |= 1;
+	}
+
+	// Extract pixels from bytes
+	for (int j = 0; j < iconDataSize; j++)
+		for (b = 0; b < pixelsPerByte; b++) {
+			int idx = j * pixelsPerByte + (pixelsPerByte - 1 - b);
+
+			if (cursor[0][idx] != 0xff) // if mask is not there
+				cursor[0][idx] = (byte)((iconData[j] >> (b * bpp)) & bitmask);
+		}
+
+	free(iconData);
+
+	assert(datasize - dis.pos() == 0);
+}
+
+} // End of namespace Common


Property changes on: scummvm/trunk/common/macresman.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/common/macresman.h
===================================================================
--- scummvm/trunk/common/macresman.h	                        (rev 0)
+++ scummvm/trunk/common/macresman.h	2010-01-11 20:41:07 UTC (rev 47258)
@@ -0,0 +1,127 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/array.h"
+#include "common/file.h"
+
+#ifndef COMMON_MACRESMAN_H
+#define COMMON_MACRESMAN_H
+
+namespace Common {
+
+typedef Common::Array<int16> MacResIDArray;
+
+/**
+ * Class for reading Mac Binary files.
+ * Is able to read dumped resource forks too.
+ */
+class MacResManager {
+
+public:
+	MacResManager(Common::String fileName);
+	~MacResManager();
+
+	/**
+	 * Read resource from the Mac Binary file
+	 * @param typeID FourCC with type ID
+	 * @param resID Resource ID to fetch
+	 * @param size Pointer to int where loaded data size will be stored
+	 * @return Pointer to memory with loaded resource. Malloc()'ed
+	 */
+	byte *getResource(const char *typeID, int16 resID, int *size);
+
+	char *getResName(const char *typeID, int16 resID);
+	/**
+	 * Convert cursor from Mac format to format suitable for feeding to CursorMan
+	 * @param data Pointer to the cursor data
+	 * @param datasize Size of the cursor data
+	 * @param cursor Pointer to memory where result cursor will be stored. The memory
+	 *               block will be malloc()'ed
+	 * @param w Pointer to int where the cursor width will be stored
+	 * @param h Pointer to int where the cursor height will be stored
+	 * @param hotspot_x Storage for cursor hotspot X coordinate
+	 * @param hotspot_Y Storage for cursor hotspot Y coordinate
+	 * @param keycolor Pointer to int where the transpared color value will be stored
+	 * @param colored If set to true then colored cursor will be returned (if any).
+	 *                b/w version will be used otherwise
+	 * @param palette Pointer to memory where the cursor palette will be stored.
+	 *                The memory will be malloc()'ed
+	 * @param palSize Pointer to integer where the palette size will be stored.
+	 */
+	void convertCursor(byte *data, int datasize, byte **cursor, int *w, int *h,
+					  int *hotspot_x, int *hotspot_y, int *keycolor, bool colored, byte **palette, int *palSize);
+
+	/**
+	 * Return list of resource IDs with specified type ID
+	 */
+	MacResIDArray getResIDArray(const char *typeID);
+
+	Common::String getFileName() { return _fileName; }
+
+private:
+	int extractResource(int id, byte **buf);
+	bool init();
+	void readMap();
+
+	struct ResMap {
+		int16 resAttr;
+		int16 typeOffset;
+		int16 nameOffset;
+		int16 numTypes;
+	};
+
+	struct ResType {
+		char  id[5];
+		int16 items;
+		int16 offset;
+	};
+
+	struct Resource {
+		int16 id;
+		int16 nameOffset;
+		byte  attr;
+		int32 dataOffset;
+		char  *name;
+	};
+
+	typedef Resource *ResPtr;
+
+private:
+	int _resOffset;
+	int32 _dataOffset;
+	int32 _dataLength;
+	int32 _mapOffset;
+	int32 _mapLength;
+	ResMap _resMap;
+	ResType *_resTypes;
+	ResPtr  *_resLists;
+
+	Common::String _fileName;
+	Common::File _resFile;
+};
+
+} // End of namespace Common
+
+#endif


Property changes on: scummvm/trunk/common/macresman.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Modified: scummvm/trunk/common/module.mk
===================================================================
--- scummvm/trunk/common/module.mk	2010-01-11 20:31:12 UTC (rev 47257)
+++ scummvm/trunk/common/module.mk	2010-01-11 20:41:07 UTC (rev 47258)
@@ -11,6 +11,7 @@
 	file.o \
 	fs.o \
 	hashmap.o \
+	macresman.o \
 	memorypool.o \
 	md5.o \
 	mutex.o \

Modified: scummvm/trunk/engines/scumm/he/resource_he.cpp
===================================================================
--- scummvm/trunk/engines/scumm/he/resource_he.cpp	2010-01-11 20:31:12 UTC (rev 47257)
+++ scummvm/trunk/engines/scumm/he/resource_he.cpp	2010-01-11 20:41:07 UTC (rev 47258)
@@ -1140,7 +1140,7 @@
 
 
 MacResExtractor::MacResExtractor(ScummEngine_v70he *scumm) : ResExtractor(scumm) {
-	_resOffset = -1;
+	_resMgr = NULL;
 }
 
 int MacResExtractor::extractResource(int id, byte **buf) {
@@ -1172,18 +1172,13 @@
 	if (!in.isOpen()) {
 		error("Cannot open file %s", _fileName.c_str());
 	}
+	in.close();
 
-	// we haven't calculated it
-	if (_resOffset == -1) {
-		if (!init(in))
-			error("Resource fork is missing in file '%s'", _fileName.c_str());
-		in.close();
-		in.open(_fileName);
-	}
+	if (_resMgr == NULL)
+		_resMgr = new Common::MacResManager(_fileName);
 
-	*buf = getResource(in, "crsr", 1000 + id, &size);
 
-	in.close();
+	*buf = _resMgr->getResource("crsr", 1000 + id, &size);
 
 	if (*buf == NULL)
 		error("There is no cursor ID #%d", 1000 + id);
@@ -1191,296 +1186,12 @@
 	return size;
 }
 
-#define MBI_INFOHDR 128
-#define MBI_ZERO1 0
-#define MBI_NAMELEN 1
-#define MBI_ZERO2 74
-#define MBI_ZERO3 82
-#define MBI_DFLEN 83
-#define MBI_RFLEN 87
-#define MAXNAMELEN 63
-
-bool MacResExtractor::init(Common::File &in) {
-	byte infoHeader[MBI_INFOHDR];
-	int32 data_size, rsrc_size;
-	int32 data_size_pad, rsrc_size_pad;
-	int filelen;
-
-	filelen = in.size();
-	in.read(infoHeader, MBI_INFOHDR);
-
-	// Maybe we have MacBinary?
-	if (infoHeader[MBI_ZERO1] == 0 && infoHeader[MBI_ZERO2] == 0 &&
-		infoHeader[MBI_ZERO3] == 0 && infoHeader[MBI_NAMELEN] <= MAXNAMELEN) {
-
-		// Pull out fork lengths
-		data_size = READ_BE_UINT32(infoHeader + MBI_DFLEN);
-		rsrc_size = READ_BE_UINT32(infoHeader + MBI_RFLEN);
-
-		data_size_pad = (((data_size + 127) >> 7) << 7);
-		rsrc_size_pad = (((rsrc_size + 127) >> 7) << 7);
-
-		// Length check
-		int sumlen =  MBI_INFOHDR + data_size_pad + rsrc_size_pad;
-
-		if (sumlen == filelen)
-			_resOffset = MBI_INFOHDR + data_size_pad;
-	}
-
-	if (_resOffset == -1) // MacBinary check is failed
-		_resOffset = 0; // Maybe we have dumped fork?
-
-	in.seek(_resOffset);
-
-	_dataOffset = in.readUint32BE() + _resOffset;
-	_mapOffset = in.readUint32BE() + _resOffset;
-	_dataLength = in.readUint32BE();
-	_mapLength = in.readUint32BE();
-
-	// do sanity check
-	if (_dataOffset >= filelen || _mapOffset >= filelen ||
-		_dataLength + _mapLength  > filelen) {
-		_resOffset = -1;
-		return false;
-	}
-
-	debug(7, "got header: data %d [%d] map %d [%d]",
-		_dataOffset, _dataLength, _mapOffset, _mapLength);
-
-	readMap(in);
-
-	return true;
-}
-
-byte *MacResExtractor::getResource(Common::File &in, const char *typeID, int16 resID, int *size) {
-	int i;
-	int typeNum = -1;
-	int resNum = -1;
-	byte *buf;
-	int len;
-
-	for (i = 0; i < _resMap.numTypes; i++)
-		if (strcmp(_resTypes[i].id, typeID) == 0) {
-			typeNum = i;
-			break;
-		}
-
-	if (typeNum == -1)
-		return NULL;
-
-	for (i = 0; i < _resTypes[typeNum].items; i++)
-		if (_resLists[typeNum][i].id == resID) {
-			resNum = i;
-			break;
-		}
-
-	if (resNum == -1)
-		return NULL;
-
-	in.seek(_dataOffset + _resLists[typeNum][resNum].dataOffset);
-
-	len = in.readUint32BE();
-	buf = (byte *)malloc(len);
-
-	in.read(buf, len);
-
-	*size = len;
-
-	return buf;
-}
-
-void MacResExtractor::readMap(Common::File &in) {
-	int	i, j, len;
-
-	in.seek(_mapOffset + 22);
-
-	_resMap.resAttr = in.readUint16BE();
-	_resMap.typeOffset = in.readUint16BE();
-	_resMap.nameOffset = in.readUint16BE();
-	_resMap.numTypes = in.readUint16BE();
-	_resMap.numTypes++;
-
-	in.seek(_mapOffset + _resMap.typeOffset + 2);
-	_resTypes = new ResType[_resMap.numTypes];
-
-	for (i = 0; i < _resMap.numTypes; i++) {
-		in.read(_resTypes[i].id, 4);
-		_resTypes[i].id[4] = 0;
-		_resTypes[i].items = in.readUint16BE();
-		_resTypes[i].offset = in.readUint16BE();
-		_resTypes[i].items++;
-	}
-
-	_resLists = new ResPtr[_resMap.numTypes];
-
-	for (i = 0; i < _resMap.numTypes; i++) {
-		_resLists[i] = new Resource[_resTypes[i].items];
-		in.seek(_resTypes[i].offset + _mapOffset + _resMap.typeOffset);
-
-		for (j = 0; j < _resTypes[i].items; j++) {
-			ResPtr resPtr = _resLists[i] + j;
-
-			resPtr->id = in.readUint16BE();
-			resPtr->nameOffset = in.readUint16BE();
-			resPtr->dataOffset = in.readUint32BE();
-			in.readUint32BE();
-			resPtr->name = 0;
-
-			resPtr->attr = resPtr->dataOffset >> 24;
-			resPtr->dataOffset &= 0xFFFFFF;
-		}
-
-		for (j = 0; j < _resTypes[i].items; j++) {
-			if (_resLists[i][j].nameOffset != -1) {
-				in.seek(_resLists[i][j].nameOffset + _mapOffset + _resMap.nameOffset);
-
-				len = in.readByte();
-				_resLists[i][j].name = new byte[len + 1];
-				_resLists[i][j].name[len] = 0;
-				in.read(_resLists[i][j].name, len);
-			}
-		}
-	}
-}
-
 int MacResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
 			  int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize) {
-	Common::MemoryReadStream dis(data, datasize);
-	int i, b;
-	byte imageByte;
-	byte *iconData;
-	int numBytes;
-	int pixelsPerByte, bpp;
-	int ctSize;
-	byte bitmask;
-	int iconRowBytes, iconBounds[4];
-	int ignored;
-	int iconDataSize;
 
-	dis.readUint16BE(); // type
-	dis.readUint32BE(); // offset to pixel map
-	dis.readUint32BE(); // offset to pixel data
-	dis.readUint32BE(); // expanded cursor data
-	dis.readUint16BE(); // expanded data depth
-	dis.readUint32BE(); // reserved
+	_resMgr->convertCursor(data, datasize, cursor, w, h, hotspot_x, hotspot_y, keycolor,
+						   _vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette), palette, palSize);
 
-	// Grab B/W icon data
-	*cursor = (byte *)malloc(16 * 16);
-	for (i = 0; i < 32; i++) {
-		imageByte = dis.readByte();
-		for (b = 0; b < 8; b++)
-			cursor[0][i*8+b] = (byte)((imageByte &
-									  (0x80 >> b)) > 0? 0x0F: 0x00);
-	}
-
-	// Apply mask data
-	for (i = 0; i < 32; i++) {
-		imageByte = dis.readByte();
-		for (b = 0; b < 8; b++)
-			if ((imageByte & (0x80 >> b)) == 0)
-				cursor[0][i*8+b] = 0xff;
-	}
-
-	*hotspot_y = dis.readUint16BE();
-	*hotspot_x = dis.readUint16BE();
-	*w = *h = 16;
-
-	// Use b/w cursor on backends which don't support cursor palettes
-	if (!_vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette))
-		return 1;
-
-	dis.readUint32BE(); // reserved
-	dis.readUint32BE(); // cursorID
-
-	// Color version of cursor
-	dis.readUint32BE(); // baseAddr
-
-	// Keep only lowbyte for now
-	dis.readByte();
-	iconRowBytes = dis.readByte();
-
-	if (!iconRowBytes)
-		return 1;
-
-	iconBounds[0] = dis.readUint16BE();
-	iconBounds[1] = dis.readUint16BE();
-	iconBounds[2] = dis.readUint16BE();
-	iconBounds[3] = dis.readUint16BE();
-
-	dis.readUint16BE(); // pmVersion
-	dis.readUint16BE(); // packType
-	dis.readUint32BE(); // packSize
-
-	dis.readUint32BE(); // hRes
-	dis.readUint32BE(); // vRes
-
-	dis.readUint16BE(); // pixelType
-	dis.readUint16BE(); // pixelSize
-	dis.readUint16BE(); // cmpCount
-	dis.readUint16BE(); // cmpSize
-
-	dis.readUint32BE(); // planeByte
-	dis.readUint32BE(); // pmTable
-	dis.readUint32BE(); // reserved
-
-	// Pixel data for cursor
-	iconDataSize =  iconRowBytes * (iconBounds[3] - iconBounds[1]);
-	iconData = (byte *)malloc(iconDataSize);
-	dis.read(iconData, iconDataSize);
-
-	// Color table
-	dis.readUint32BE(); // ctSeed
-	dis.readUint16BE(); // ctFlag
-	ctSize = dis.readUint16BE() + 1;
-
-	*palette = (byte *)malloc(ctSize * 4);
-
-	// Read just high byte of 16-bit color
-	for (int c = 0; c < ctSize; c++) {
-		// We just use indices 0..ctSize, so ignore color ID
-		dis.readUint16BE(); // colorID[c]
-
-		palette[0][c * 4 + 0] = dis.readByte();
-		ignored = dis.readByte();
-
-		palette[0][c * 4 + 1] = dis.readByte();
-		ignored = dis.readByte();
-
-		palette[0][c * 4 + 2] = dis.readByte();
-		ignored = dis.readByte();
-
-		palette[0][c * 4 + 3] = 0;
-	}
-
-	*palSize = ctSize;
-
-	numBytes =
-         (iconBounds[2] - iconBounds[0]) *
-         (iconBounds[3] - iconBounds[1]);
-
-	pixelsPerByte = (iconBounds[2] - iconBounds[0]) / iconRowBytes;
-	bpp           = 8 / pixelsPerByte;
-
-	// build a mask to make sure the pixels are properly shifted out
-	bitmask = 0;
-	for (int m = 0; m < bpp; m++) {
-		bitmask <<= 1;
-		bitmask  |= 1;
-	}
-
-	// Extract pixels from bytes
-	for (int j = 0; j < iconDataSize; j++)
-		for (b = 0; b < pixelsPerByte; b++) {
-			int idx = j * pixelsPerByte + (pixelsPerByte - 1 - b);
-
-			if (cursor[0][idx] != 0xff) // if mask is not there
-				cursor[0][idx] = (byte)((iconData[j] >> (b * bpp)) & bitmask);
-		}
-
-	free(iconData);
-
-	assert(datasize - dis.pos() == 0);
-
 	return 1;
 }
 

Modified: scummvm/trunk/engines/scumm/he/resource_he.h
===================================================================
--- scummvm/trunk/engines/scumm/he/resource_he.h	2010-01-11 20:31:12 UTC (rev 47257)
+++ scummvm/trunk/engines/scumm/he/resource_he.h	2010-01-11 20:41:07 UTC (rev 47258)
@@ -26,6 +26,8 @@
 #ifndef SCUMM_HE_RESOURCE_HE_H
 #define SCUMM_HE_RESOURCE_HE_H
 
+#include "common/macresman.h"
+
 namespace Scumm {
 
 #define WINRES_ID_MAXLEN (256)
@@ -419,48 +421,13 @@
 public:
 	MacResExtractor(ScummEngine_v70he *scumm);
 	~MacResExtractor() { }
-	void setCursor(int id) ;
 
 private:
+	Common::MacResManager *_resMgr;
+
 	int extractResource(int id, byte **buf);
-	bool init(Common::File &in);
-	void readMap(Common::File &in);
-	byte *getResource(Common::File &in, const char *typeID, int16 resID, int *size);
 	int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
 			 int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize);
-
-	struct ResMap {
-		int16 resAttr;
-		int16 typeOffset;
-		int16 nameOffset;
-		int16 numTypes;
-	};
-
-	struct ResType {
-		char  id[5];
-		int16 items;
-		int16 offset;
-	};
-
-	struct Resource {
-		int16 id;
-		int16 nameOffset;
-		byte  attr;
-		int32 dataOffset;
-		byte  *name;
-	};
-
-	typedef Resource *ResPtr;
-
-private:
-	int _resOffset;
-	int32 _dataOffset;
-	int32 _dataLength;
-	int32 _mapOffset;
-	int32 _mapLength;
-	ResMap _resMap;
-	ResType *_resTypes;
-	ResPtr  *_resLists;
 };
 
 } // End of namespace Scumm


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