Ticket #9112: resfork_macosx.diff
File resfork_macosx.diff, 12.3 KB (added by , 14 years ago) |
---|
-
common/macresman.cpp
25 25 26 26 #include "common/scummsys.h" 27 27 #include "common/debug.h" 28 #include "common/file.h"29 28 #include "common/util.h" 30 29 31 30 #include "common/macresman.h" 32 31 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 33 39 namespace Common { 34 40 35 MacResManager::MacResManager( Common::String fileName) : _fileName(fileName),_resOffset(-1) {36 _resFile.open(_fileName); 41 MacResManager::MacResManager() : _resOffset(-1) { 42 } 37 43 38 if (!_resFile.isOpen()) { 39 error("Cannot open file %s", _fileName.c_str()); 44 MacResManager::~MacResManager() { 45 close(); 46 } 47 48 bool 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; 40 68 } 69 70 _resFile = file; 71 #endif 41 72 42 if (!init()) 43 error("Resource fork is missing in file '%s'", _fileName.c_str()); 73 return init(); 44 74 } 45 75 46 MacResManager::~MacResManager() {76 void MacResManager::close() { 47 77 for (int i = 0; i < _resMap.numTypes; i++) { 48 78 for (int j = 0; j < _resTypes[i].items; j++) { 49 79 if (_resLists[i][j].nameOffset != -1) { … … 55 85 56 86 delete _resLists; 57 87 delete _resTypes; 58 59 _resFile.close(); 88 delete _resFile; 60 89 } 61 90 62 91 #define MBI_INFOHDR 128 … … 74 103 int32 data_size_pad, rsrc_size_pad; 75 104 int filelen; 76 105 77 filelen = _resFile .size();78 _resFile .read(infoHeader, MBI_INFOHDR);106 filelen = _resFile->size(); 107 _resFile->read(infoHeader, MBI_INFOHDR); 79 108 80 109 // Maybe we have MacBinary? 81 110 if (infoHeader[MBI_ZERO1] == 0 && infoHeader[MBI_ZERO2] == 0 && … … 98 127 if (_resOffset == -1) // MacBinary check is failed 99 128 _resOffset = 0; // Maybe we have dumped fork? 100 129 101 _resFile .seek(_resOffset);130 _resFile->seek(_resOffset); 102 131 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(); 107 136 108 137 // do sanity check 109 138 if (_dataOffset >= filelen || _mapOffset >= filelen || … … 116 145 _dataOffset, _dataLength, _mapOffset, _mapLength); 117 146 118 147 readMap(); 119 120 148 return true; 121 149 } 122 150 123 MacResIDArray MacResManager::getResIDArray( const char *typeID) {151 MacResIDArray MacResManager::getResIDArray(uint32 typeID) { 124 152 int typeNum = -1; 125 153 MacResIDArray res; 126 154 127 155 for (int i = 0; i < _resMap.numTypes; i++) 128 if ( strcmp(_resTypes[i].id, typeID) == 0) {156 if (_resTypes[i].id == typeID) { 129 157 typeNum = i; 130 158 break; 131 159 } … … 141 169 return res; 142 170 } 143 171 144 char *MacResManager::getResName(const char *typeID, int16 resID) {172 Common::String MacResManager::getResName(uint32 typeID, int16 resID) { 145 173 int i; 146 174 int typeNum = -1; 147 175 148 176 for (i = 0; i < _resMap.numTypes; i++) 149 if ( strcmp(_resTypes[i].id, typeID) == 0) {177 if (_resTypes[i].id == typeID) { 150 178 typeNum = i; 151 179 break; 152 180 } 153 181 154 182 if (typeNum == -1) 155 return NULL;183 return ""; 156 184 157 185 for (i = 0; i < _resTypes[typeNum].items; i++) 158 186 if (_resLists[typeNum][i].id == resID) 159 187 return _resLists[typeNum][i].name; 160 188 161 return NULL;189 return ""; 162 190 } 163 191 164 byte *MacResManager::getResource(const char *typeID, int16 resID, int *size) { 165 int i; 192 Common::SeekableReadStream *MacResManager::getResource(uint32 typeID, int16 resID) { 166 193 int typeNum = -1; 167 194 int resNum = -1; 168 byte *buf;169 int len;170 195 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) { 173 198 typeNum = i; 174 199 break; 175 200 } … … 177 202 if (typeNum == -1) 178 203 return NULL; 179 204 180 for (i = 0; i < _resTypes[typeNum].items; i++)205 for (int i = 0; i < _resTypes[typeNum].items; i++) 181 206 if (_resLists[typeNum][i].id == resID) { 182 207 resNum = i; 183 208 break; … … 186 211 if (resNum == -1) 187 212 return NULL; 188 213 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); 199 217 } 200 218 201 219 void MacResManager::readMap() { 202 220 int i, j, len; 203 221 204 _resFile .seek(_mapOffset + 22);222 _resFile->seek(_mapOffset + 22); 205 223 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(); 210 228 _resMap.numTypes++; 211 229 212 _resFile .seek(_mapOffset + _resMap.typeOffset + 2);230 _resFile->seek(_mapOffset + _resMap.typeOffset + 2); 213 231 _resTypes = new ResType[_resMap.numTypes]; 214 232 215 233 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(); 220 237 _resTypes[i].items++; 221 238 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); 223 240 } 224 241 225 242 _resLists = new ResPtr[_resMap.numTypes]; 226 243 227 244 for (i = 0; i < _resMap.numTypes; i++) { 228 245 _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); 230 247 231 248 for (j = 0; j < _resTypes[i].items; j++) { 232 249 ResPtr resPtr = _resLists[i] + j; 233 250 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(); 238 255 resPtr->name = 0; 239 256 240 257 resPtr->attr = resPtr->dataOffset >> 24; … … 243 260 244 261 for (j = 0; j < _resTypes[i].items; j++) { 245 262 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); 247 264 248 len = _resFile .readByte();265 len = _resFile->readByte(); 249 266 _resLists[i][j].name = new char[len + 1]; 250 267 _resLists[i][j].name[len] = 0; 251 _resFile .read(_resLists[i][j].name, len);268 _resFile->read(_resLists[i][j].name, len); 252 269 } 253 270 } 254 271 } 255 272 } 256 273 257 void MacResManager::convertC ursor(byte *data, int datasize, byte **cursor, int *w, int *h,258 274 void 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) { 259 276 Common::MemoryReadStream dis(data, datasize); 260 277 int i, b; 261 278 byte imageByte; -
common/macresman.h
40 40 class MacResManager { 41 41 42 42 public: 43 MacResManager( Common::String fileName);43 MacResManager(); 44 44 ~MacResManager(); 45 46 bool open(Common::String fileName); 47 void close(); 45 48 46 49 /** 47 50 * Read resource from the Mac Binary file 48 51 * @param typeID FourCC with type ID 49 52 * @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 52 54 */ 53 byte *getResource(const char *typeID, int16 resID, int *size);55 Common::SeekableReadStream *getResource(uint32 typeID, int16 resID); 54 56 55 char *getResName(const char *typeID, int16 resID); 57 Common::String getResName(uint32 typeID, int16 resID); 58 56 59 /** 57 * Convert cursor from Macformat to format suitable for feeding to CursorMan60 * Convert cursor from crsr format to format suitable for feeding to CursorMan 58 61 * @param data Pointer to the cursor data 59 62 * @param datasize Size of the cursor data 60 63 * @param cursor Pointer to memory where result cursor will be stored. The memory … … 70 73 * The memory will be malloc()'ed 71 74 * @param palSize Pointer to integer where the palette size will be stored. 72 75 */ 73 void convertC ursor(byte *data, int datasize, byte **cursor, int *w, int *h,76 void convertCrsrCursor(byte *data, int datasize, byte **cursor, int *w, int *h, 74 77 int *hotspot_x, int *hotspot_y, int *keycolor, bool colored, byte **palette, int *palSize); 75 78 76 79 /** 77 80 * Return list of resource IDs with specified type ID 78 81 */ 79 MacResIDArray getResIDArray( const char *typeID);82 MacResIDArray getResIDArray(uint32 typeID); 80 83 81 Common::String getFileName() { return _fileName; }82 83 84 private: 84 85 int extractResource(int id, byte **buf); 85 86 bool init(); … … 93 94 }; 94 95 95 96 struct ResType { 96 char id[5];97 uint32 id; 97 98 int16 items; 98 99 int16 offset; 99 100 }; … … 118 119 ResType *_resTypes; 119 120 ResPtr *_resLists; 120 121 121 Common::String _fileName; 122 Common::File _resFile; 122 Common::SeekableReadStream *_resFile; 123 123 }; 124 124 125 125 } // End of namespace Common -
engines/scumm/he/resource_he.cpp
1144 1144 } 1145 1145 1146 1146 int 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()); 1174 1152 } 1175 in.close();1176 1153 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) 1184 1157 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; 1185 1163 1186 1164 return size; 1187 1165 } 1188 1166 1189 1167 int MacResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, 1190 1168 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); 1195 1172 return 1; 1196 1173 } 1197 1174 1198 1199 1200 1175 void ScummEngine_v70he::readRoomsOffsets() { 1201 1176 int num, i; 1202 1177 byte *ptr;