Ticket #9112: resfork_macosx_alt.diff

File resfork_macosx_alt.diff, 12.5 KB (added by SF/mthreepwood, 11 years ago)

Patch with dumped forks on OSX too (r47618)

  • common/macresman.cpp

     
    2525
    2626#include "common/scummsys.h"
    2727#include "common/debug.h"
    28 #include "common/file.h"
    2928#include "common/util.h"
    3029
     30#include "common/file.h"
    3131#include "common/macresman.h"
    3232
     33#ifdef MACOSX
     34#include "common/config-manager.h"
     35#include "backends/fs/stdiostream.h"
     36#endif
     37
    3338namespace Common {
    3439
    35 MacResManager::MacResManager(Common::String fileName) : _fileName(fileName), _resOffset(-1) {
    36         _resFile.open(_fileName);
     40MacResManager::MacResManager() : _resOffset(-1) {
     41}
    3742
    38         if (!_resFile.isOpen()) {
    39                 error("Cannot open file %s", _fileName.c_str());
     43MacResManager::~MacResManager() {
     44        close();
     45}
     46
     47bool MacResManager::open(Common::String fileName) {
     48#ifdef MACOSX
     49        // On Mac OS X, attempt to load the resource fork directly
     50        _resFile = StdioStream::makeFromPath(ConfMan.get("path") + "/" + fileName + "/..namedfork/rsrc", false);
     51       
     52        if (_resFile)
     53                return init();
     54#endif
     55        // On other platforms, and as fallback on Mac OS X, try to look for a dumped fork
     56        Common::File *file = new Common::File();
     57
     58        file->open(fileName);
     59
     60        if (file->isOpen())
     61                file->open(fileName + ".bin");
     62               
     63        if (file->isOpen())
     64                file->open(fileName + ".rsrc");
     65               
     66        if (!file->isOpen()) {
     67                delete file;
     68                return false;
    4069        }
    41 
    42         if (!init())
    43                 error("Resource fork is missing in file '%s'", _fileName.c_str());
     70       
     71        _resFile = file;
     72        return init();
    4473}
    4574
    46 MacResManager::~MacResManager() {
     75void MacResManager::close() {
    4776        for (int i = 0; i < _resMap.numTypes; i++) {
    4877                for (int j = 0; j < _resTypes[i].items; j++) {
    4978                        if (_resLists[i][j].nameOffset != -1) {
     
    5584
    5685        delete _resLists;
    5786        delete _resTypes;
    58 
    59         _resFile.close();
     87        delete _resFile;
    6088}
    6189
    6290#define MBI_INFOHDR 128
     
    74102        int32 data_size_pad, rsrc_size_pad;
    75103        int filelen;
    76104
    77         filelen = _resFile.size();
    78         _resFile.read(infoHeader, MBI_INFOHDR);
     105        filelen = _resFile->size();
     106        _resFile->read(infoHeader, MBI_INFOHDR);
    79107
    80108        // Maybe we have MacBinary?
    81109        if (infoHeader[MBI_ZERO1] == 0 && infoHeader[MBI_ZERO2] == 0 &&
     
    98126        if (_resOffset == -1) // MacBinary check is failed
    99127                _resOffset = 0; // Maybe we have dumped fork?
    100128
    101         _resFile.seek(_resOffset);
     129        _resFile->seek(_resOffset);
    102130
    103         _dataOffset = _resFile.readUint32BE() + _resOffset;
    104         _mapOffset = _resFile.readUint32BE() + _resOffset;
    105         _dataLength = _resFile.readUint32BE();
    106         _mapLength = _resFile.readUint32BE();
     131        _dataOffset = _resFile->readUint32BE() + _resOffset;
     132        _mapOffset = _resFile->readUint32BE() + _resOffset;
     133        _dataLength = _resFile->readUint32BE();
     134        _mapLength = _resFile->readUint32BE();
    107135
    108136        // do sanity check
    109137        if (_dataOffset >= filelen || _mapOffset >= filelen ||
     
    116144                _dataOffset, _dataLength, _mapOffset, _mapLength);
    117145
    118146        readMap();
    119 
    120147        return true;
    121148}
    122149
    123 MacResIDArray MacResManager::getResIDArray(const char *typeID) {
     150MacResIDArray MacResManager::getResIDArray(uint32 typeID) {
    124151        int typeNum = -1;
    125152        MacResIDArray res;
    126153
    127154        for (int i = 0; i < _resMap.numTypes; i++)
    128                 if (strcmp(_resTypes[i].id, typeID) == 0) {
     155                if (_resTypes[i].id ==  typeID) {
    129156                        typeNum = i;
    130157                        break;
    131158                }
     
    141168        return res;
    142169}
    143170
    144 char *MacResManager::getResName(const char *typeID, int16 resID) {
     171Common::String MacResManager::getResName(uint32 typeID, int16 resID) {
    145172        int i;
    146173        int typeNum = -1;
    147174
    148175        for (i = 0; i < _resMap.numTypes; i++)
    149                 if (strcmp(_resTypes[i].id, typeID) == 0) {
     176                if (_resTypes[i].id == typeID) {
    150177                        typeNum = i;
    151178                        break;
    152179                }
    153180
    154181        if (typeNum == -1)
    155                 return NULL;
     182                return "";
    156183
    157184        for (i = 0; i < _resTypes[typeNum].items; i++)
    158185                if (_resLists[typeNum][i].id == resID)
    159186                        return _resLists[typeNum][i].name;
    160187
    161         return NULL;
     188        return "";
    162189}
    163190
    164 byte *MacResManager::getResource(const char *typeID, int16 resID, int *size) {
    165         int i;
     191Common::SeekableReadStream *MacResManager::getResource(uint32 typeID, int16 resID) {
    166192        int typeNum = -1;
    167193        int resNum = -1;
    168         byte *buf;
    169         int len;
    170194
    171         for (i = 0; i < _resMap.numTypes; i++)
    172                 if (strcmp(_resTypes[i].id, typeID) == 0) {
     195        for (int i = 0; i < _resMap.numTypes; i++)
     196                if (_resTypes[i].id == typeID) {
    173197                        typeNum = i;
    174198                        break;
    175199                }
     
    177201        if (typeNum == -1)
    178202                return NULL;
    179203
    180         for (i = 0; i < _resTypes[typeNum].items; i++)
     204        for (int i = 0; i < _resTypes[typeNum].items; i++)
    181205                if (_resLists[typeNum][i].id == resID) {
    182206                        resNum = i;
    183207                        break;
     
    186210        if (resNum == -1)
    187211                return NULL;
    188212
    189         _resFile.seek(_dataOffset + _resLists[typeNum][resNum].dataOffset);
    190 
    191         len = _resFile.readUint32BE();
    192         buf = (byte *)malloc(len);
    193 
    194         _resFile.read(buf, len);
    195 
    196         *size = len;
    197 
    198         return buf;
     213        _resFile->seek(_dataOffset + _resLists[typeNum][resNum].dataOffset);
     214        uint32 len = _resFile->readUint32BE();
     215        return _resFile->readStream(len);
    199216}
    200217
    201218void MacResManager::readMap() {
    202219        int     i, j, len;
    203220
    204         _resFile.seek(_mapOffset + 22);
     221        _resFile->seek(_mapOffset + 22);
    205222
    206         _resMap.resAttr = _resFile.readUint16BE();
    207         _resMap.typeOffset = _resFile.readUint16BE();
    208         _resMap.nameOffset = _resFile.readUint16BE();
    209         _resMap.numTypes = _resFile.readUint16BE();
     223        _resMap.resAttr = _resFile->readUint16BE();
     224        _resMap.typeOffset = _resFile->readUint16BE();
     225        _resMap.nameOffset = _resFile->readUint16BE();
     226        _resMap.numTypes = _resFile->readUint16BE();
    210227        _resMap.numTypes++;
    211228
    212         _resFile.seek(_mapOffset + _resMap.typeOffset + 2);
     229        _resFile->seek(_mapOffset + _resMap.typeOffset + 2);
    213230        _resTypes = new ResType[_resMap.numTypes];
    214231
    215232        for (i = 0; i < _resMap.numTypes; i++) {
    216                 _resFile.read(_resTypes[i].id, 4);
    217                 _resTypes[i].id[4] = 0;
    218                 _resTypes[i].items = _resFile.readUint16BE();
    219                 _resTypes[i].offset = _resFile.readUint16BE();
     233                _resTypes[i].id = _resFile->readUint32BE();
     234                _resTypes[i].items = _resFile->readUint16BE();
     235                _resTypes[i].offset = _resFile->readUint16BE();
    220236                _resTypes[i].items++;
    221237
    222                 debug(8, "resType: <%s> items: %d offset: %d (0x%x)", _resTypes[i].id, _resTypes[i].items,  _resTypes[i].offset, _resTypes[i].offset);
     238                debug(8, "resType: <%s> items: %d offset: %d (0x%x)", tag2str(_resTypes[i].id), _resTypes[i].items,  _resTypes[i].offset, _resTypes[i].offset);
    223239        }
    224240
    225241        _resLists = new ResPtr[_resMap.numTypes];
    226242
    227243        for (i = 0; i < _resMap.numTypes; i++) {
    228244                _resLists[i] = new Resource[_resTypes[i].items];
    229                 _resFile.seek(_resTypes[i].offset + _mapOffset + _resMap.typeOffset);
     245                _resFile->seek(_resTypes[i].offset + _mapOffset + _resMap.typeOffset);
    230246
    231247                for (j = 0; j < _resTypes[i].items; j++) {
    232248                        ResPtr resPtr = _resLists[i] + j;
    233249
    234                         resPtr->id = _resFile.readUint16BE();
    235                         resPtr->nameOffset = _resFile.readUint16BE();
    236                         resPtr->dataOffset = _resFile.readUint32BE();
    237                         _resFile.readUint32BE();
     250                        resPtr->id = _resFile->readUint16BE();
     251                        resPtr->nameOffset = _resFile->readUint16BE();
     252                        resPtr->dataOffset = _resFile->readUint32BE();
     253                        _resFile->readUint32BE();
    238254                        resPtr->name = 0;
    239255
    240256                        resPtr->attr = resPtr->dataOffset >> 24;
     
    243259
    244260                for (j = 0; j < _resTypes[i].items; j++) {
    245261                        if (_resLists[i][j].nameOffset != -1) {
    246                                 _resFile.seek(_resLists[i][j].nameOffset + _mapOffset + _resMap.nameOffset);
     262                                _resFile->seek(_resLists[i][j].nameOffset + _mapOffset + _resMap.nameOffset);
    247263
    248                                 len = _resFile.readByte();
     264                                len = _resFile->readByte();
    249265                                _resLists[i][j].name = new char[len + 1];
    250266                                _resLists[i][j].name[len] = 0;
    251                                 _resFile.read(_resLists[i][j].name, len);
     267                                _resFile->read(_resLists[i][j].name, len);
    252268                        }
    253269                }
    254270        }
    255271}
    256272
    257 void MacResManager::convertCursor(byte *data, int datasize, byte **cursor, int *w, int *h,
    258                                          int *hotspot_x, int *hotspot_y, int *keycolor, bool colored, byte **palette, int *palSize) {
     273void MacResManager::convertCrsrCursor(byte *data, int datasize, byte **cursor, int *w, int *h,
     274                                int *hotspot_x, int *hotspot_y, int *keycolor, bool colored, byte **palette, int *palSize) {
    259275        Common::MemoryReadStream dis(data, datasize);
    260276        int i, b;
    261277        byte imageByte;
  • common/macresman.h

     
    4040class MacResManager {
    4141
    4242public:
    43         MacResManager(Common::String fileName);
     43        MacResManager();
    4444        ~MacResManager();
     45       
     46        bool open(Common::String fileName);
     47        void close();
    4548
    4649        /**
    4750         * Read resource from the Mac Binary file
    4851         * @param typeID FourCC with type ID
    4952         * @param resID Resource ID to fetch
    50          * @param size Pointer to int where loaded data size will be stored
    51          * @return Pointer to memory with loaded resource. Malloc()'ed
     53         * @return Pointer to a SeekableReadStream with loaded resource
    5254         */
    53         byte *getResource(const char *typeID, int16 resID, int *size);
     55        Common::SeekableReadStream *getResource(uint32 typeID, int16 resID);
    5456
    55         char *getResName(const char *typeID, int16 resID);
     57        Common::String getResName(uint32 typeID, int16 resID);
     58       
    5659        /**
    57          * Convert cursor from Mac format to format suitable for feeding to CursorMan
     60         * Convert cursor from crsr format to format suitable for feeding to CursorMan
    5861         * @param data Pointer to the cursor data
    5962         * @param datasize Size of the cursor data
    6063         * @param cursor Pointer to memory where result cursor will be stored. The memory
     
    7073         *                The memory will be malloc()'ed
    7174         * @param palSize Pointer to integer where the palette size will be stored.
    7275         */
    73         void convertCursor(byte *data, int datasize, byte **cursor, int *w, int *h,
     76        void convertCrsrCursor(byte *data, int datasize, byte **cursor, int *w, int *h,
    7477                                          int *hotspot_x, int *hotspot_y, int *keycolor, bool colored, byte **palette, int *palSize);
    7578
    7679        /**
    7780         * Return list of resource IDs with specified type ID
    7881         */
    79         MacResIDArray getResIDArray(const char *typeID);
     82        MacResIDArray getResIDArray(uint32 typeID);
    8083
    81         Common::String getFileName() { return _fileName; }
    82 
    8384private:
    8485        int extractResource(int id, byte **buf);
    8586        bool init();
     
    9394        };
    9495
    9596        struct ResType {
    96                 char  id[5];
     97                uint32 id;
    9798                int16 items;
    9899                int16 offset;
    99100        };
     
    118119        ResType *_resTypes;
    119120        ResPtr  *_resLists;
    120121
    121         Common::String _fileName;
    122         Common::File _resFile;
     122        Common::SeekableReadStream *_resFile;
    123123};
    124124
    125125} // End of namespace Common
  • engines/scumm/he/resource_he.cpp

     
    11441144}
    11451145
    11461146int MacResExtractor::extractResource(int id, byte **buf) {
    1147         Common::File in;
    1148         int size;
    1149 
    1150         if (_fileName.empty()) { // We are running for the first time
    1151                 _fileName = _vm->generateFilename(-3);
    1152 
    1153                 // Some programs write it as .bin. Try that too
    1154                 if (!in.open(_fileName)) {
    1155                         Common::String tmp(_fileName);
    1156 
    1157                         _fileName += ".bin";
    1158 
    1159                         if (!in.open(_fileName)) {
    1160                                 // And finally check if we have dumped resource fork
    1161                                 _fileName = tmp;
    1162                                 _fileName += ".bin";
    1163                                 if (!in.open(_fileName)) {
    1164                                         error("Cannot open file any of files '%s', '%s.bin', '%s.rsrc",
    1165                                                   tmp.c_str(), tmp.c_str(), tmp.c_str());
    1166                                 }
    1167                         }
    1168                 }
    1169         } else
    1170                 in.open(_fileName);
    1171 
    1172         if (!in.isOpen()) {
    1173                 error("Cannot open file %s", _fileName.c_str());
     1147        // Create the MacResManager if not created already
     1148        if (_resMgr == NULL) {
     1149                _resMgr = new Common::MacResManager();
     1150                if (!_resMgr->open(_vm->generateFilename(-3)))
     1151                        error("Cannot open file %s", _fileName.c_str());
    11741152        }
    1175         in.close();
    11761153
    1177         if (_resMgr == NULL)
    1178                 _resMgr = new Common::MacResManager(_fileName);
    1179 
    1180 
    1181         *buf = _resMgr->getResource("crsr", 1000 + id, &size);
    1182 
    1183         if (*buf == NULL)
     1154        Common::SeekableReadStream *dataStream = _resMgr->getResource('crsr', 1000 + id);
     1155       
     1156        if (!dataStream)
    11841157                error("There is no cursor ID #%d", 1000 + id);
     1158       
     1159        uint32 size = dataStream->size();
     1160        *buf = (byte *)malloc(size);
     1161        dataStream->read(*buf, size);
     1162        delete dataStream;
    11851163
    11861164        return size;
    11871165}
    11881166
    11891167int MacResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
    11901168                          int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize) {
    1191 
    1192         _resMgr->convertCursor(data, datasize, cursor, w, h, hotspot_x, hotspot_y, keycolor,
    1193                                                    _vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette), palette, palSize);
    1194 
     1169                         
     1170        _resMgr->convertCrsrCursor(data, datasize, cursor, w, h, hotspot_x, hotspot_y, keycolor,
     1171                                                _vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette), palette, palSize);
    11951172        return 1;
    11961173}
    11971174
    1198 
    1199 
    12001175void ScummEngine_v70he::readRoomsOffsets() {
    12011176        int num, i;
    12021177        byte *ptr;