aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorMatthew Hoops2010-05-10 18:23:54 +0000
committerMatthew Hoops2010-05-10 18:23:54 +0000
commitb9813063ad3cfca5f7ff7a731eccca0bb32159e0 (patch)
tree1a64e130c5184a22ef4251b2b00c44d7903ddfd7 /common
parentbe0885e9d1edd6963a3060a41fa3b705c84c41f1 (diff)
downloadscummvm-rg350-b9813063ad3cfca5f7ff7a731eccca0bb32159e0.tar.gz
scummvm-rg350-b9813063ad3cfca5f7ff7a731eccca0bb32159e0.tar.bz2
scummvm-rg350-b9813063ad3cfca5f7ff7a731eccca0bb32159e0.zip
Add support to the MacResManager and AdvancedDetector to take the md5 of a resource fork. This introduces a new flag, ADGF_MACRESFORK, which when set will take the md5 and size from the resource fork instead of the data fork.
svn-id: r48997
Diffstat (limited to 'common')
-rw-r--r--common/macresman.cpp110
-rw-r--r--common/macresman.h14
2 files changed, 110 insertions, 14 deletions
diff --git a/common/macresman.cpp b/common/macresman.cpp
index 24099475a7..f36f8b2fe3 100644
--- a/common/macresman.cpp
+++ b/common/macresman.cpp
@@ -26,9 +26,10 @@
#include "common/scummsys.h"
#include "common/debug.h"
#include "common/util.h"
-
#include "common/file.h"
+#include "common/fs.h"
#include "common/macresman.h"
+#include "common/md5.h"
#ifdef MACOSX
#include "common/config-manager.h"
@@ -37,6 +38,15 @@
namespace Common {
+#define MBI_INFOHDR 128
+#define MBI_ZERO1 0
+#define MBI_NAMELEN 1
+#define MBI_ZERO2 74
+#define MBI_ZERO3 82
+#define MBI_DFLEN 83
+#define MBI_RFLEN 87
+#define MAXNAMELEN 63
+
MacResManager::MacResManager() {
memset(this, 0, sizeof(MacResManager));
close();
@@ -72,14 +82,32 @@ bool MacResManager::hasResFork() {
return !_baseFileName.empty() && _mode != kResForkNone;
}
+uint32 MacResManager::getResForkSize() {
+ if (!hasResFork())
+ return 0;
+
+ return _resForkSize;
+}
+
+bool MacResManager::getResForkMD5(char *md5str, uint32 length) {
+ if (!hasResFork())
+ return false;
+
+ ReadStream *stream = new SeekableSubReadStream(_stream, _resForkOffset, _resForkOffset + _resForkSize);
+ bool retVal = md5_file_string(*stream, md5str, MIN<uint32>(length, _resForkSize));
+ delete stream;
+ return retVal;
+}
+
bool MacResManager::open(Common::String filename) {
close();
#ifdef MACOSX
// Check the actual fork on a Mac computer
Common::String fullPath = ConfMan.get("path") + "/" + filename + "/..namedfork/rsrc";
+ Common::SeekableReadStream *macResForkRawStream = StdioStream::makeFromPath(fullPath, false);
- if (loadFromRawFork(*StdioStream::makeFromPath(fullPath, false))) {
+ if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) {
_baseFileName = filename;
return true;
}
@@ -118,6 +146,53 @@ bool MacResManager::open(Common::String filename) {
return false;
}
+bool MacResManager::open(Common::FSNode path, Common::String filename) {
+ close();
+
+#ifdef MACOSX
+ // Check the actual fork on a Mac computer
+ Common::String fullPath = path.getPath() + "/" + filename + "/..namedfork/rsrc";
+ Common::SeekableReadStream *macResForkRawStream = StdioStream::makeFromPath(fullPath, false);
+
+ if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) {
+ _baseFileName = filename;
+ return true;
+ }
+#endif
+
+ // First, let's try to see if the Mac converted name exists
+ Common::FSNode fsNode = path.getChild("._" + filename);
+ if (fsNode.exists() && !fsNode.isDirectory() && loadFromAppleDouble(*fsNode.createReadStream())) {
+ _baseFileName = filename;
+ return true;
+ }
+
+ // Check .bin too
+ fsNode = path.getChild(filename + ".bin");
+ if (fsNode.exists() && !fsNode.isDirectory() && loadFromMacBinary(*fsNode.createReadStream())) {
+ _baseFileName = filename;
+ return true;
+ }
+
+ // Maybe we have a dumped fork?
+ fsNode = path.getChild(filename + ".rsrc");
+ if (fsNode.exists() && !fsNode.isDirectory() && loadFromRawFork(*fsNode.createReadStream())) {
+ _baseFileName = filename;
+ return true;
+ }
+
+ // Fine, what about just the data fork?
+ fsNode = path.getChild(filename);
+ if (fsNode.exists() && !fsNode.isDirectory()) {
+ _baseFileName = filename;
+ _stream = fsNode.createReadStream();
+ return true;
+ }
+
+ // The file doesn't exist
+ return false;
+}
+
bool MacResManager::loadFromAppleDouble(Common::SeekableReadStream &stream) {
if (stream.readUint32BE() != 0x00051607) // tag
return false;
@@ -129,12 +204,13 @@ bool MacResManager::loadFromAppleDouble(Common::SeekableReadStream &stream) {
for (uint16 i = 0; i < entryCount; i++) {
uint32 id = stream.readUint32BE();
uint32 offset = stream.readUint32BE();
- stream.readUint32BE(); // length
+ uint32 length = stream.readUint32BE(); // length
if (id == 1) {
// Found the data fork!
_resForkOffset = offset;
_mode = kResForkAppleDouble;
+ _resForkSize = length;
return load(stream);
}
}
@@ -142,15 +218,6 @@ bool MacResManager::loadFromAppleDouble(Common::SeekableReadStream &stream) {
return false;
}
-#define MBI_INFOHDR 128
-#define MBI_ZERO1 0
-#define MBI_NAMELEN 1
-#define MBI_ZERO2 74
-#define MBI_ZERO3 82
-#define MBI_DFLEN 83
-#define MBI_RFLEN 87
-#define MAXNAMELEN 63
-
bool MacResManager::loadFromMacBinary(Common::SeekableReadStream &stream) {
byte infoHeader[MBI_INFOHDR];
stream.read(infoHeader, MBI_INFOHDR);
@@ -167,8 +234,10 @@ bool MacResManager::loadFromMacBinary(Common::SeekableReadStream &stream) {
uint32 rsrcSizePad = (((rsrcSize + 127) >> 7) << 7);
// Length check
- if (MBI_INFOHDR + dataSizePad + rsrcSizePad == (uint32)stream.size())
+ if (MBI_INFOHDR + dataSizePad + rsrcSizePad == (uint32)stream.size()) {
_resForkOffset = MBI_INFOHDR + dataSizePad;
+ _resForkSize = rsrcSize;
+ }
}
if (_resForkOffset < 0)
@@ -181,6 +250,7 @@ bool MacResManager::loadFromMacBinary(Common::SeekableReadStream &stream) {
bool MacResManager::loadFromRawFork(Common::SeekableReadStream &stream) {
_mode = kResForkRaw;
_resForkOffset = 0;
+ _resForkSize = stream.size();
return load(stream);
}
@@ -251,6 +321,20 @@ MacResIDArray MacResManager::getResIDArray(uint32 typeID) {
return res;
}
+MacResTagArray MacResManager::getResTagArray() {
+ MacResTagArray tagArray;
+
+ if (!hasResFork())
+ return tagArray;
+
+ tagArray.resize(_resMap.numTypes);
+
+ for (uint32 i = 0; i < _resMap.numTypes; i++)
+ tagArray[i] = _resTypes[i].id;
+
+ return tagArray;
+}
+
Common::String MacResManager::getResName(uint32 typeID, uint16 resID) {
int typeNum = -1;
diff --git a/common/macresman.h b/common/macresman.h
index 2f47a67fa2..4afd2eebab 100644
--- a/common/macresman.h
+++ b/common/macresman.h
@@ -31,7 +31,10 @@
namespace Common {
+class FSNode;
+
typedef Common::Array<uint16> MacResIDArray;
+typedef Common::Array<uint32> MacResTagArray;
/**
* Class for reading Mac Binary files.
@@ -43,7 +46,8 @@ public:
MacResManager();
~MacResManager();
- bool open(Common::String fileName);
+ bool open(Common::String filename);
+ bool open(Common::FSNode path, Common::String filename);
void close();
bool hasDataFork();
@@ -59,6 +63,8 @@ public:
Common::SeekableReadStream *getDataFork();
Common::String getResName(uint32 typeID, uint16 resID);
+ uint32 getResForkSize();
+ bool getResForkMD5(char *md5str, uint32 length);
/**
* Convert cursor from crsr format to format suitable for feeding to CursorMan
@@ -85,6 +91,11 @@ public:
*/
MacResIDArray getResIDArray(uint32 typeID);
+ /**
+ * Return list of resource tags
+ */
+ MacResTagArray getResTagArray();
+
private:
Common::SeekableReadStream *_stream;
Common::String _baseFileName;
@@ -128,6 +139,7 @@ private:
typedef Resource *ResPtr;
int32 _resForkOffset;
+ uint32 _resForkSize;
uint32 _dataOffset;
uint32 _dataLength;