Ticket #9112: resfork_macosx_alt.diff
File resfork_macosx_alt.diff, 12.5 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 30 #include "common/file.h" 31 31 #include "common/macresman.h" 32 32 33 #ifdef MACOSX 34 #include "common/config-manager.h" 35 #include "backends/fs/stdiostream.h" 36 #endif 37 33 38 namespace Common { 34 39 35 MacResManager::MacResManager( Common::String fileName) : _fileName(fileName),_resOffset(-1) {36 _resFile.open(_fileName); 40 MacResManager::MacResManager() : _resOffset(-1) { 41 } 37 42 38 if (!_resFile.isOpen()) { 39 error("Cannot open file %s", _fileName.c_str()); 43 MacResManager::~MacResManager() { 44 close(); 45 } 46 47 bool 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; 40 69 } 41 42 if (!init())43 error("Resource fork is missing in file '%s'", _fileName.c_str());70 71 _resFile = file; 72 return init(); 44 73 } 45 74 46 MacResManager::~MacResManager() {75 void MacResManager::close() { 47 76 for (int i = 0; i < _resMap.numTypes; i++) { 48 77 for (int j = 0; j < _resTypes[i].items; j++) { 49 78 if (_resLists[i][j].nameOffset != -1) { … … 55 84 56 85 delete _resLists; 57 86 delete _resTypes; 58 59 _resFile.close(); 87 delete _resFile; 60 88 } 61 89 62 90 #define MBI_INFOHDR 128 … … 74 102 int32 data_size_pad, rsrc_size_pad; 75 103 int filelen; 76 104 77 filelen = _resFile .size();78 _resFile .read(infoHeader, MBI_INFOHDR);105 filelen = _resFile->size(); 106 _resFile->read(infoHeader, MBI_INFOHDR); 79 107 80 108 // Maybe we have MacBinary? 81 109 if (infoHeader[MBI_ZERO1] == 0 && infoHeader[MBI_ZERO2] == 0 && … … 98 126 if (_resOffset == -1) // MacBinary check is failed 99 127 _resOffset = 0; // Maybe we have dumped fork? 100 128 101 _resFile .seek(_resOffset);129 _resFile->seek(_resOffset); 102 130 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(); 107 135 108 136 // do sanity check 109 137 if (_dataOffset >= filelen || _mapOffset >= filelen || … … 116 144 _dataOffset, _dataLength, _mapOffset, _mapLength); 117 145 118 146 readMap(); 119 120 147 return true; 121 148 } 122 149 123 MacResIDArray MacResManager::getResIDArray( const char *typeID) {150 MacResIDArray MacResManager::getResIDArray(uint32 typeID) { 124 151 int typeNum = -1; 125 152 MacResIDArray res; 126 153 127 154 for (int i = 0; i < _resMap.numTypes; i++) 128 if ( strcmp(_resTypes[i].id, typeID) == 0) {155 if (_resTypes[i].id == typeID) { 129 156 typeNum = i; 130 157 break; 131 158 } … … 141 168 return res; 142 169 } 143 170 144 char *MacResManager::getResName(const char *typeID, int16 resID) {171 Common::String MacResManager::getResName(uint32 typeID, int16 resID) { 145 172 int i; 146 173 int typeNum = -1; 147 174 148 175 for (i = 0; i < _resMap.numTypes; i++) 149 if ( strcmp(_resTypes[i].id, typeID) == 0) {176 if (_resTypes[i].id == typeID) { 150 177 typeNum = i; 151 178 break; 152 179 } 153 180 154 181 if (typeNum == -1) 155 return NULL;182 return ""; 156 183 157 184 for (i = 0; i < _resTypes[typeNum].items; i++) 158 185 if (_resLists[typeNum][i].id == resID) 159 186 return _resLists[typeNum][i].name; 160 187 161 return NULL;188 return ""; 162 189 } 163 190 164 byte *MacResManager::getResource(const char *typeID, int16 resID, int *size) { 165 int i; 191 Common::SeekableReadStream *MacResManager::getResource(uint32 typeID, int16 resID) { 166 192 int typeNum = -1; 167 193 int resNum = -1; 168 byte *buf;169 int len;170 194 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) { 173 197 typeNum = i; 174 198 break; 175 199 } … … 177 201 if (typeNum == -1) 178 202 return NULL; 179 203 180 for (i = 0; i < _resTypes[typeNum].items; i++)204 for (int i = 0; i < _resTypes[typeNum].items; i++) 181 205 if (_resLists[typeNum][i].id == resID) { 182 206 resNum = i; 183 207 break; … … 186 210 if (resNum == -1) 187 211 return NULL; 188 212 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); 199 216 } 200 217 201 218 void MacResManager::readMap() { 202 219 int i, j, len; 203 220 204 _resFile .seek(_mapOffset + 22);221 _resFile->seek(_mapOffset + 22); 205 222 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(); 210 227 _resMap.numTypes++; 211 228 212 _resFile .seek(_mapOffset + _resMap.typeOffset + 2);229 _resFile->seek(_mapOffset + _resMap.typeOffset + 2); 213 230 _resTypes = new ResType[_resMap.numTypes]; 214 231 215 232 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(); 220 236 _resTypes[i].items++; 221 237 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); 223 239 } 224 240 225 241 _resLists = new ResPtr[_resMap.numTypes]; 226 242 227 243 for (i = 0; i < _resMap.numTypes; i++) { 228 244 _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); 230 246 231 247 for (j = 0; j < _resTypes[i].items; j++) { 232 248 ResPtr resPtr = _resLists[i] + j; 233 249 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(); 238 254 resPtr->name = 0; 239 255 240 256 resPtr->attr = resPtr->dataOffset >> 24; … … 243 259 244 260 for (j = 0; j < _resTypes[i].items; j++) { 245 261 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); 247 263 248 len = _resFile .readByte();264 len = _resFile->readByte(); 249 265 _resLists[i][j].name = new char[len + 1]; 250 266 _resLists[i][j].name[len] = 0; 251 _resFile .read(_resLists[i][j].name, len);267 _resFile->read(_resLists[i][j].name, len); 252 268 } 253 269 } 254 270 } 255 271 } 256 272 257 void MacResManager::convertC ursor(byte *data, int datasize, byte **cursor, int *w, int *h,258 273 void 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) { 259 275 Common::MemoryReadStream dis(data, datasize); 260 276 int i, b; 261 277 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;