diff options
-rw-r--r-- | scumm/cursor.cpp | 5 | ||||
-rw-r--r-- | scumm/intern.h | 6 | ||||
-rw-r--r-- | scumm/resource_v7he.cpp | 129 | ||||
-rw-r--r-- | scumm/resource_v7he.h | 48 | ||||
-rw-r--r-- | scumm/scumm.cpp | 6 |
5 files changed, 103 insertions, 91 deletions
diff --git a/scumm/cursor.cpp b/scumm/cursor.cpp index 5eea91fd18..2c5a6f3a9e 100644 --- a/scumm/cursor.cpp +++ b/scumm/cursor.cpp @@ -157,10 +157,7 @@ void ScummEngine::setCursorFromBuffer(byte *ptr, int width, int height, int pitc #ifndef DISABLE_HE void ScummEngine_v70he::setCursorFromImg(uint img, uint room, uint imgindex) { - if (_platform == Common::kPlatformMacintosh && _heversion == 72) - _macResExtractor->setCursor(img); - else - _win32ResExtractor->setCursor(img); + _resExtractor->setCursor(img); } void ScummEngine_v90he::setDefaultCursor() { diff --git a/scumm/intern.h b/scumm/intern.h index aba640f23a..094d702a89 100644 --- a/scumm/intern.h +++ b/scumm/intern.h @@ -757,8 +757,7 @@ protected: #ifndef DISABLE_HE class ScummEngine_v70he : public ScummEngine_v60he { - friend class Win32ResExtractor; - friend class MacResExtractor; + friend class ResExtractor; protected: typedef void (ScummEngine_v70he::*OpcodeProcv70he)(); @@ -769,8 +768,7 @@ protected: const OpcodeEntryv70he *_opcodesv70he; - Win32ResExtractor *_win32ResExtractor; - MacResExtractor *_macResExtractor; + ResExtractor *_resExtractor; byte *_heV7RoomOffsets; diff --git a/scumm/resource_v7he.cpp b/scumm/resource_v7he.cpp index 3243117242..04a3d6ce5d 100644 --- a/scumm/resource_v7he.cpp +++ b/scumm/resource_v7he.cpp @@ -37,29 +37,14 @@ namespace Scumm { -/* - * Static variables - */ -const char *res_types[] = { - /* 0x01: */ - "cursor", "bitmap", "icon", "menu", "dialog", "string", - "fontdir", "font", "accelerator", "rcdata", "messagelist", - "group_cursor", NULL, "group_icon", NULL, - /* the following are not defined in winbase.h, but found in wrc. */ - /* 0x10: */ - "version", "dlginclude", NULL, "plugplay", "vxd", - "anicursor", "aniicon" -}; -#define RES_TYPE_COUNT (sizeof(res_types)/sizeof(char *)) - -Win32ResExtractor::Win32ResExtractor(ScummEngine_v70he *scumm) { +ResExtractor::ResExtractor(ScummEngine_v70he *scumm) { _vm = scumm; _fileName[0] = 0; memset(_cursorCache, 0, sizeof(_cursorCache)); } -Win32ResExtractor::~Win32ResExtractor() { +ResExtractor::~ResExtractor() { for (int i = 0; i < MAX_CACHED_CURSORS; ++i) { CachedCursor *cc = &_cursorCache[i]; if (cc->valid) { @@ -70,7 +55,7 @@ Win32ResExtractor::~Win32ResExtractor() { } } -Win32ResExtractor::CachedCursor *Win32ResExtractor::findCachedCursor(int id) { +ResExtractor::CachedCursor *ResExtractor::findCachedCursor(int id) { for (int i = 0; i < MAX_CACHED_CURSORS; ++i) { CachedCursor *cc = &_cursorCache[i]; if (cc->valid && cc->id == id) { @@ -80,7 +65,7 @@ Win32ResExtractor::CachedCursor *Win32ResExtractor::findCachedCursor(int id) { return NULL; } -Win32ResExtractor::CachedCursor *Win32ResExtractor::getCachedCursorSlot() { +ResExtractor::CachedCursor *ResExtractor::getCachedCursorSlot() { uint32 min_last_used = 0; CachedCursor *r = NULL; for (int i = 0; i < MAX_CACHED_CURSORS; ++i) { @@ -101,8 +86,7 @@ Win32ResExtractor::CachedCursor *Win32ResExtractor::getCachedCursorSlot() { return r; } -void Win32ResExtractor::setCursor(int id) { - char buf[20]; +void ResExtractor::setCursor(int id) { byte *cursorRes = 0; int cursorsize; int keycolor = 0; @@ -110,11 +94,10 @@ void Win32ResExtractor::setCursor(int id) { if (cc != NULL) { debug(7, "Found cursor %d in cache slot %d", id, cc - _cursorCache); } else { - snprintf(buf, sizeof(buf), "%d", id); cc = getCachedCursorSlot(); assert(cc && !cc->valid); - cursorsize = extractResource("group_cursor", buf, &cursorRes); - convertIcons(cursorRes, cursorsize, &cc->bitmap, &cc->w, &cc->h, &cc->hotspot_x, &cc->hotspot_y, &keycolor); + cursorsize = extractResource(id, &cursorRes); + convertIcons(cursorRes, cursorsize, &cc->bitmap, &cc->w, &cc->h, &cc->hotspot_x, &cc->hotspot_y, &keycolor, &cc->palette, &cc->palSize); debug(7, "Adding cursor %d to cache slot %d", id, cc - _cursorCache); free(cursorRes); cc->valid = true; @@ -122,11 +105,41 @@ void Win32ResExtractor::setCursor(int id) { cc->last_used = g_system->getMillis(); } + if (_vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette) && cc->palette) + _vm->_system->setCursorPalette(cc->palette, 0, cc->palSize); + _vm->setCursorHotspot(cc->hotspot_x, cc->hotspot_y); _vm->setCursorFromBuffer(cc->bitmap, cc->w, cc->h, cc->w); } -int Win32ResExtractor::extractResource(const char *resType, char *resName, byte **data) { + +/* + * Static variables + */ +const char *res_types[] = { + /* 0x01: */ + "cursor", "bitmap", "icon", "menu", "dialog", "string", + "fontdir", "font", "accelerator", "rcdata", "messagelist", + "group_cursor", NULL, "group_icon", NULL, + /* the following are not defined in winbase.h, but found in wrc. */ + /* 0x10: */ + "version", "dlginclude", NULL, "plugplay", "vxd", + "anicursor", "aniicon" +}; +#define RES_TYPE_COUNT (sizeof(res_types)/sizeof(char *)) + +Win32ResExtractor::Win32ResExtractor(ScummEngine_v70he *scumm) : ResExtractor(scumm) { +} + +int Win32ResExtractor::extractResource(int resId, byte **data) { + char buf[20]; + + snprintf(buf, sizeof(buf), "%d", resId); + + return extractResource_("group_cursor", buf, data); +} + +int Win32ResExtractor::extractResource_(const char *resType, char *resName, byte **data) { char *arg_language = NULL; const char *arg_type = resType; char *arg_name = resName; @@ -922,7 +935,7 @@ Win32ResExtractor::WinResource *Win32ResExtractor::find_resource(WinLibrary *fi, int Win32ResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, - int *hotspot_x, int *hotspot_y, int *keycolor) { + int *hotspot_x, int *hotspot_y, int *keycolor, byte **pal, int *palSize) { Win32CursorIconFileDir dir; Win32CursorIconFileDirEntry *entries = NULL; uint32 offset; @@ -1267,19 +1280,13 @@ void Win32ResExtractor::fix_win32_image_data_directory(Win32ImageDataDirectory * } -MacResExtractor::MacResExtractor(ScummEngine_v70he *scumm) { - _vm = scumm; - - _fileName[0] = 0; +MacResExtractor::MacResExtractor(ScummEngine_v70he *scumm) : ResExtractor(scumm) { _resOffset = -1; } -void MacResExtractor::setCursor(int id) { - byte *cursorRes = 0, *cursor = 0; - int cursorsize; - int w = 0, h = 0, hotspot_x = 0, hotspot_y = 0; - int keycolor; - Common::File f; +int MacResExtractor::extractResource(int id, byte **buf) { + Common::File in; + int size; if (!_fileName[0]) // We are running for the first time if (_vm->_substResFileNameIndex > 0) { @@ -1289,14 +1296,14 @@ void MacResExtractor::setCursor(int id) { _vm->generateSubstResFileName(buf1, _fileName, sizeof(buf1)); // Some programs write it as .bin. Try that too - if (!f.exists(_fileName)) { + if (!in.exists(_fileName)) { strcpy(buf1, _fileName); snprintf(_fileName, 128, "%s.bin", buf1); - if (!f.exists(_fileName)) { + if (!in.exists(_fileName)) { // And finally check if we have dumped resource fork snprintf(_fileName, 128, "%s.rsrc", buf1); - if (!f.exists(_fileName)) { + if (!in.exists(_fileName)) { error("Cannot open file any of files '%s', '%s.bin', '%s.rsrc", buf1, buf1, buf1); } @@ -1304,19 +1311,6 @@ void MacResExtractor::setCursor(int id) { } } - cursorsize = extractResource(id, &cursorRes); - convertIcons(cursorRes, cursorsize, &cursor, &w, &h, &hotspot_x, &hotspot_y, &keycolor); - - _vm->setCursorHotspot(hotspot_x, hotspot_y); - _vm->setCursorFromBuffer(cursor, w, h, w); - free(cursorRes); - free(cursor); -} - -int MacResExtractor::extractResource(int id, byte **buf) { - Common::File in; - int size; - in.open(_fileName); if (!in.isOpen()) { error("Cannot open file %s", _fileName); @@ -1326,12 +1320,16 @@ int MacResExtractor::extractResource(int id, byte **buf) { if (_resOffset == -1) { if (!init(in)) error("Resource fork is missing in file '%s'", _fileName); + in.close(); + in.open(_fileName); } *buf = getResource(in, "crsr", 1000 + id, &size); + in.close(); + if (*buf == NULL) - error("There is no cursor ID #%d", id); + error("There is no cursor ID #%d", 1000 + id); return size; } @@ -1450,6 +1448,7 @@ void MacResExtractor::readMap(Common::File in) { 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++; @@ -1487,8 +1486,8 @@ void MacResExtractor::readMap(Common::File in) { } } -void MacResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, - int *hotspot_x, int *hotspot_y, int *keycolor) { +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; @@ -1496,7 +1495,6 @@ void MacResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int int numBytes; int pixelsPerByte, bpp; int ctSize; - byte *palette; byte bitmask; int iconRowBytes, iconBounds[4]; int ignored; @@ -1532,7 +1530,7 @@ void MacResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int // Use b/w cursor on backends which don't support cursor palettes if (!_vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette)) - return; + return 1; dis.readUint32BE(); // reserved dis.readUint32BE(); // cursorID @@ -1545,7 +1543,7 @@ void MacResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int iconRowBytes = dis.readByte(); if (!iconRowBytes) - return; + return 1; iconBounds[0] = dis.readUint16BE(); iconBounds[1] = dis.readUint16BE(); @@ -1578,26 +1576,26 @@ void MacResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int dis.readUint16BE(); // ctFlag ctSize = dis.readUint16BE() + 1; - palette = (byte *)malloc(ctSize * 4); + *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[c * 4 + 0] = dis.readByte(); + palette[0][c * 4 + 0] = dis.readByte(); ignored = dis.readByte(); - palette[c * 4 + 1] = dis.readByte(); + palette[0][c * 4 + 1] = dis.readByte(); ignored = dis.readByte(); - palette[c * 4 + 2] = dis.readByte(); + palette[0][c * 4 + 2] = dis.readByte(); ignored = dis.readByte(); - palette[c * 4 + 3] = 0; + palette[0][c * 4 + 3] = 0; } - _vm->_system->setCursorPalette(palette, 0, ctSize); + *palSize = ctSize; numBytes = (iconBounds[2] - iconBounds[0]) * @@ -1623,9 +1621,10 @@ void MacResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int } free(iconData); - free(palette); assert(datasize - dis.pos() == 0); + + return 1; } diff --git a/scumm/resource_v7he.h b/scumm/resource_v7he.h index a4808f1f54..431de85e66 100644 --- a/scumm/resource_v7he.h +++ b/scumm/resource_v7he.h @@ -114,14 +114,17 @@ namespace Scumm { if (!check_offset(fi->memory, fi->total_size, fi->file->name(), x, s)) \ return (r); -class Win32ResExtractor { - public: - Win32ResExtractor(ScummEngine_v70he *scumm); - ~Win32ResExtractor(); - int extractResource(const char *resType, char *resName, byte **data); +class ResExtractor { +public: + ResExtractor(ScummEngine_v70he *scumm); + virtual ~ResExtractor(); + void setCursor(int id); - int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, - int *hotspot_x, int *hotspot_y, int *keycolor); + + virtual int extractResource(int id, byte **buf) { return 0; }; + virtual int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, + int *hotspot_x, int *hotspot_y, int *keycolor, + byte **palette, int *palSize) { return 0; }; enum { MAX_CACHED_CURSORS = 10 @@ -134,19 +137,34 @@ class Win32ResExtractor { int w, h; int hotspot_x, hotspot_y; uint32 last_used; + byte *palette; + int palSize; }; - private: - Win32ResExtractor::CachedCursor *findCachedCursor(int id); - Win32ResExtractor::CachedCursor *getCachedCursorSlot(); + ScummEngine_v70he *_vm; + + ResExtractor::CachedCursor *findCachedCursor(int id); + ResExtractor::CachedCursor *getCachedCursorSlot(); bool _arg_raw; - ScummEngine_v70he *_vm; char _fileName[256]; CachedCursor _cursorCache[MAX_CACHED_CURSORS]; typedef Common::MemoryReadStream MemoryReadStream; +}; + +class Win32ResExtractor : public ResExtractor { + public: + Win32ResExtractor(ScummEngine_v70he *scumm); + ~Win32ResExtractor() {}; + int extractResource(int id, byte **data); + void setCursor(int id); + int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, + int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize); + + private: + int extractResource_(const char *resType, char *resName, byte **data); /* * Structures */ @@ -481,7 +499,7 @@ class Win32ResExtractor { void fix_win32_image_data_directory(Win32ImageDataDirectory *obj); }; -class MacResExtractor { +class MacResExtractor : public ResExtractor { public: MacResExtractor(ScummEngine_v70he *scumm); @@ -493,8 +511,8 @@ private: bool init(Common::File in); void readMap(Common::File in); byte *getResource(Common::File in, const char *typeID, int16 resID, int *size); - void convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, - int *hotspot_x, int *hotspot_y, int *keycolor); + 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; @@ -520,8 +538,6 @@ private: typedef Resource *ResPtr; private: - ScummEngine_v70he *_vm; - char _fileName[256]; int _resOffset; int32 _dataOffset; int32 _dataLength; diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp index 8a1c2b4bcd..16f66af3b4 100644 --- a/scumm/scumm.cpp +++ b/scumm/scumm.cpp @@ -1294,8 +1294,10 @@ ScummEngine_v6::ScummEngine_v6(GameDetector *detector, OSystem *syst, const Scum #ifndef DISABLE_HE ScummEngine_v70he::ScummEngine_v70he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) : ScummEngine_v60he(detector, syst, gs, md5sum) { - _win32ResExtractor = new Win32ResExtractor(this); - _macResExtractor = new MacResExtractor(this); + if (_platform == Common::kPlatformMacintosh && _heversion == 72) + _resExtractor = new MacResExtractor(this); + else + _resExtractor = new Win32ResExtractor(this); _heV7RoomOffsets = NULL; |