aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm
diff options
context:
space:
mode:
Diffstat (limited to 'engines/scumm')
-rw-r--r--engines/scumm/he/resource_he.cpp303
-rw-r--r--engines/scumm/he/resource_he.h41
2 files changed, 11 insertions, 333 deletions
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