diff options
| -rw-r--r-- | common/macresman.cpp | 393 | ||||
| -rw-r--r-- | common/macresman.h | 127 | ||||
| -rw-r--r-- | common/module.mk | 1 | ||||
| -rw-r--r-- | engines/scumm/he/resource_he.cpp | 303 | ||||
| -rw-r--r-- | engines/scumm/he/resource_he.h | 41 | 
5 files changed, 532 insertions, 333 deletions
diff --git a/common/macresman.cpp b/common/macresman.cpp new file mode 100644 index 0000000000..af9d89268a --- /dev/null +++ b/common/macresman.cpp @@ -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 diff --git a/common/macresman.h b/common/macresman.h new file mode 100644 index 0000000000..fd4557f92c --- /dev/null +++ b/common/macresman.h @@ -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 diff --git a/common/module.mk b/common/module.mk index a619b5c54f..23d7b326f0 100644 --- a/common/module.mk +++ b/common/module.mk @@ -11,6 +11,7 @@ MODULE_OBJS := \  	file.o \  	fs.o \  	hashmap.o \ +	macresman.o \  	memorypool.o \  	md5.o \  	mutex.o \ diff --git a/engines/scumm/he/resource_he.cpp b/engines/scumm/he/resource_he.cpp index 824f998def..9fc9dd4baf 100644 --- a/engines/scumm/he/resource_he.cpp +++ b/engines/scumm/he/resource_he.cpp @@ -1140,7 +1140,7 @@ void Win32ResExtractor::fix_win32_image_data_directory(Win32ImageDataDirectory *  MacResExtractor::MacResExtractor(ScummEngine_v70he *scumm) : ResExtractor(scumm) { -	_resOffset = -1; +	_resMgr = NULL;  }  int MacResExtractor::extractResource(int id, byte **buf) { @@ -1172,18 +1172,13 @@ int MacResExtractor::extractResource(int id, byte **buf) {  	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,295 +1186,11 @@ int MacResExtractor::extractResource(int id, byte **buf) {  	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 - -	// 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); +	_resMgr->convertCursor(data, datasize, cursor, w, h, hotspot_x, hotspot_y, keycolor, +						   _vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette), palette, palSize);  	return 1;  } diff --git a/engines/scumm/he/resource_he.h b/engines/scumm/he/resource_he.h index cbe19a4fdf..4567c598a3 100644 --- a/engines/scumm/he/resource_he.h +++ b/engines/scumm/he/resource_he.h @@ -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 @@ class MacResExtractor : public ResExtractor {  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  | 
