Ticket #9112: resfork_macosx.diff

File resfork_macosx.diff, 12.3 KB (added by SF/mthreepwood, 11 years ago)

Patch against r47406

  • 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
    3130#include "common/macresman.h"
    3231
     32#ifdef MACOSX
     33#include "common/config-manager.h"
     34#include "backends/fs/stdiostream.h"
     35#else
     36#include "common/file.h"
     37#endif
     38
    3339namespace Common {
    3440
    35 MacResManager::MacResManager(Common::String fileName) : _fileName(fileName), _resOffset(-1) {
    36         _resFile.open(_fileName);
     41MacResManager::MacResManager() : _resOffset(-1) {
     42}
    3743
    38         if (!_resFile.isOpen()) {
    39                 error("Cannot open file %s", _fileName.c_str());
     44MacResManager::~MacResManager() {
     45        close();
     46}
     47
     48bool MacResManager::open(Common::String fileName) {
     49#ifdef MACOSX
     50        _resFile = StdioStream::makeFromPath(ConfMan.get("path") + "/" + fileName + "/..namedfork/rsrc", false);
     51       
     52        if (!_resFile)
     53                return false;
     54#else
     55        Common::File *file = new Common::File();
     56
     57        file->open(fileName);
     58
     59        if (file->isOpen())
     60                file->open(fileName + ".bin");
     61               
     62        if (file->isOpen())
     63                file->open(fileName + ".rsrc");
     64               
     65        if (!file->isOpen()) {
     66                delete file;
     67                return false;
    4068        }
     69       
     70        _resFile = file;
     71#endif
    4172
    42         if (!init())
    43                 error("Resource fork is missing in file '%s'", _fileName.c_str());
     73        return init();
    4474}
    4575
    46 MacResManager::~MacResManager() {
     76void MacResManager::close() {
    4777        for (int i = 0; i < _resMap.numTypes; i++) {
    4878                for (int j = 0; j < _resTypes[i].items; j++) {
    4979                        if (_resLists[i][j].nameOffset != -1) {
     
    5585
    5686        delete _resLists;
    5787        delete _resTypes;
    58 
    59         _resFile.close();
     88        delete _resFile;
    6089}
    6190
    6291#define MBI_INFOHDR 128
     
    74103        int32 data_size_pad, rsrc_size_pad;
    75104        int filelen;
    76105
    77         filelen = _resFile.size();
    78         _resFile.read(infoHeader, MBI_INFOHDR);
     106        filelen = _resFile->size();
     107        _resFile->read(infoHeader, MBI_INFOHDR);
    79108
    80109        // Maybe we have MacBinary?
    81110        if (infoHeader[MBI_ZERO1] == 0 && infoHeader[MBI_ZERO2] == 0 &&
     
    98127        if (_resOffset == -1) // MacBinary check is failed
    99128                _resOffset = 0; // Maybe we have dumped fork?
    100129
    101         _resFile.seek(_resOffset);
     130        _resFile->seek(_resOffset);
    102131
    103         _dataOffset = _resFile.readUint32BE() + _resOffset;
    104         _mapOffset = _resFile.readUint32BE() + _resOffset;
    105         _dataLength = _resFile.readUint32BE();
    106         _mapLength = _resFile.readUint32BE();
     132        _dataOffset = _resFile->readUint32BE() + _resOffset;
     133        _mapOffset = _resFile->readUint32BE() + _resOffset;
     134        _dataLength = _resFile->readUint32BE();
     135        _mapLength = _resFile->readUint32BE();
    107136
    108137        // do sanity check
    109138        if (_dataOffset >= filelen || _mapOffset >= filelen ||
     
    116145                _dataOffset, _dataLength, _mapOffset, _mapLength);
    117146
    118147        readMap();
    119 
    120148        return true;
    121149}
    122150
    123 MacResIDArray MacResManager::getResIDArray(const char *typeID) {
     151MacResIDArray MacResManager::getResIDArray(uint32 typeID) {
    124152        int typeNum = -1;
    125153        MacResIDArray res;
    126154
    127155        for (int i = 0; i < _resMap.numTypes; i++)
    128                 if (strcmp(_resTypes[i].id, typeID) == 0) {
     156                if (_resTypes[i].id ==  typeID) {
    129157                        typeNum = i;
    130158                        break;
    131159                }
     
    141169        return res;
    142170}
    143171
    144 char *MacResManager::getResName(const char *typeID, int16 resID) {
     172Common::String MacResManager::getResName(uint32 typeID, int16 resID) {
    145173        int i;
    146174        int typeNum = -1;
    147175
    148176        for (i = 0; i < _resMap.numTypes; i++)
    149                 if (strcmp(_resTypes[i].id, typeID) == 0) {
     177                if (_resTypes[i].id == typeID) {
    150178                        typeNum = i;
    151179                        break;
    152180                }
    153181
    154182        if (typeNum == -1)
    155                 return NULL;
     183                return "";
    156184
    157185        for (i = 0; i < _resTypes[typeNum].items; i++)
    158186                if (_resLists[typeNum][i].id == resID)
    159187                        return _resLists[typeNum][i].name;
    160188
    161         return NULL;
     189        return "";
    162190}
    163191
    164 byte *MacResManager::getResource(const char *typeID, int16 resID, int *size) {
    165         int i;
     192Common::SeekableReadStream *MacResManager::getResource(uint32 typeID, int16 resID) {
    166193        int typeNum = -1;
    167194        int resNum = -1;
    168         byte *buf;
    169         int len;
    170195
    171         for (i = 0; i < _resMap.numTypes; i++)
    172                 if (strcmp(_resTypes[i].id, typeID) == 0) {
     196        for (int i = 0; i < _resMap.numTypes; i++)
     197                if (_resTypes[i].id == typeID) {
    173198                        typeNum = i;
    174199                        break;
    175200                }
     
    177202        if (typeNum == -1)
    178203                return NULL;
    179204
    180         for (i = 0; i < _resTypes[typeNum].items; i++)
     205        for (int i = 0; i < _resTypes[typeNum].items; i++)
    181206                if (_resLists[typeNum][i].id == resID) {
    182207                        resNum = i;
    183208                        break;
     
    186211        if (resNum == -1)
    187212                return NULL;
    188213
    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;
     214        _resFile->seek(_dataOffset + _resLists[typeNum][resNum].dataOffset);
     215        uint32 len = _resFile->readUint32BE();
     216        return _resFile->readStream(len);
    199217}
    200218
    201219void MacResManager::readMap() {
    202220        int     i, j, len;
    203221
    204         _resFile.seek(_mapOffset + 22);
     222        _resFile->seek(_mapOffset + 22);
    205223
    206         _resMap.resAttr = _resFile.readUint16BE();
    207         _resMap.typeOffset = _resFile.readUint16BE();
    208         _resMap.nameOffset = _resFile.readUint16BE();
    209         _resMap.numTypes = _resFile.readUint16BE();
     224        _resMap.resAttr = _resFile->readUint16BE();
     225        _resMap.typeOffset = _resFile->readUint16BE();
     226        _resMap.nameOffset = _resFile->readUint16BE();
     227        _resMap.numTypes = _resFile->readUint16BE();
    210228        _resMap.numTypes++;
    211229
    212         _resFile.seek(_mapOffset + _resMap.typeOffset + 2);
     230        _resFile->seek(_mapOffset + _resMap.typeOffset + 2);
    213231        _resTypes = new ResType[_resMap.numTypes];
    214232
    215233        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();
     234                _resTypes[i].id = _resFile->readUint32BE();
     235                _resTypes[i].items = _resFile->readUint16BE();
     236                _resTypes[i].offset = _resFile->readUint16BE();
    220237                _resTypes[i].items++;
    221238
    222                 debug(8, "resType: <%s> items: %d offset: %d (0x%x)", _resTypes[i].id, _resTypes[i].items,  _resTypes[i].offset, _resTypes[i].offset);
     239                debug(8, "resType: <%s> items: %d offset: %d (0x%x)", tag2str(_resTypes[i].id), _resTypes[i].items,  _resTypes[i].offset, _resTypes[i].offset);
    223240        }
    224241
    225242        _resLists = new ResPtr[_resMap.numTypes];
    226243
    227244        for (i = 0; i < _resMap.numTypes; i++) {
    228245                _resLists[i] = new Resource[_resTypes[i].items];
    229                 _resFile.seek(_resTypes[i].offset + _mapOffset + _resMap.typeOffset);
     246                _resFile->seek(_resTypes[i].offset + _mapOffset + _resMap.typeOffset);
    230247
    231248                for (j = 0; j < _resTypes[i].items; j++) {
    232249                        ResPtr resPtr = _resLists[i] + j;
    233250
    234                         resPtr->id = _resFile.readUint16BE();
    235                         resPtr->nameOffset = _resFile.readUint16BE();
    236                         resPtr->dataOffset = _resFile.readUint32BE();
    237                         _resFile.readUint32BE();
     251                        resPtr->id = _resFile->readUint16BE();
     252                        resPtr->nameOffset = _resFile->readUint16BE();
     253                        resPtr->dataOffset = _resFile->readUint32BE();
     254                        _resFile->readUint32BE();
    238255                        resPtr->name = 0;
    239256
    240257                        resPtr->attr = resPtr->dataOffset >> 24;
     
    243260
    244261                for (j = 0; j < _resTypes[i].items; j++) {
    245262                        if (_resLists[i][j].nameOffset != -1) {
    246                                 _resFile.seek(_resLists[i][j].nameOffset + _mapOffset + _resMap.nameOffset);
     263                                _resFile->seek(_resLists[i][j].nameOffset + _mapOffset + _resMap.nameOffset);
    247264
    248                                 len = _resFile.readByte();
     265                                len = _resFile->readByte();
    249266                                _resLists[i][j].name = new char[len + 1];
    250267                                _resLists[i][j].name[len] = 0;
    251                                 _resFile.read(_resLists[i][j].name, len);
     268                                _resFile->read(_resLists[i][j].name, len);
    252269                        }
    253270                }
    254271        }
    255272}
    256273
    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) {
     274void MacResManager::convertCrsrCursor(byte *data, int datasize, byte **cursor, int *w, int *h,
     275                                int *hotspot_x, int *hotspot_y, int *keycolor, bool colored, byte **palette, int *palSize) {
    259276        Common::MemoryReadStream dis(data, datasize);
    260277        int i, b;
    261278        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;