ALL: synced with scummvm

This commit is contained in:
Pawel Kolodziejski 2013-07-13 14:30:29 +02:00
parent f78a3c0171
commit c68193e3a4
8 changed files with 179 additions and 83 deletions

1
.gitignore vendored
View file

@ -57,6 +57,7 @@ project.xcworkspace
/dists/msvc*/*.SAV
/dists/msvc*/*.dat
/dists/msvc*/*.dll
/dists/msvc*/test_runner.cpp
/doc/*.aux
/doc/*.dvi

View file

@ -102,18 +102,18 @@ String MacResManager::computeResForkMD5AsString(uint32 length) const {
return computeStreamMD5AsString(resForkStream, MIN<uint32>(length, _resForkSize));
}
bool MacResManager::open(String filename) {
bool MacResManager::open(const String &fileName) {
close();
#ifdef MACOSX
// Check the actual fork on a Mac computer
String fullPath = ConfMan.get("path") + "/" + filename + "/..namedfork/rsrc";
String fullPath = ConfMan.get("path") + "/" + fileName + "/..namedfork/rsrc";
FSNode resFsNode = FSNode(fullPath);
if (resFsNode.exists()) {
SeekableReadStream *macResForkRawStream = resFsNode.createReadStream();
if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) {
_baseFileName = filename;
_baseFileName = fileName;
return true;
}
@ -123,38 +123,39 @@ bool MacResManager::open(String filename) {
File *file = new File();
// First, let's try to see if the Mac converted name exists
if (file->open(constructAppleDoubleName(filename)) && loadFromAppleDouble(*file)) {
_baseFileName = filename;
// Prefer standalone files first, starting with raw forks
if (file->open(fileName + ".rsrc") && loadFromRawFork(*file)) {
_baseFileName = fileName;
return true;
}
file->close();
// Check .bin too
if (file->open(filename + ".bin") && loadFromMacBinary(*file)) {
_baseFileName = filename;
// Then try for AppleDouble using Apple's naming
if (file->open(constructAppleDoubleName(fileName)) && loadFromAppleDouble(*file)) {
_baseFileName = fileName;
return true;
}
file->close();
// Maybe we have a dumped fork?
if (file->open(filename + ".rsrc") && loadFromRawFork(*file)) {
_baseFileName = filename;
// Check .bin for MacBinary next
if (file->open(fileName + ".bin") && loadFromMacBinary(*file)) {
_baseFileName = fileName;
return true;
}
file->close();
// Fine, what about just the data fork?
if (file->open(filename)) {
_baseFileName = filename;
// As a last resort, see if just the data fork exists
if (file->open(fileName)) {
_baseFileName = fileName;
// FIXME: Is this really needed?
if (isMacBinary(*file)) {
file->seek(0, SEEK_SET);
file->seek(0);
if (loadFromMacBinary(*file))
return true;
}
file->seek(0, SEEK_SET);
file->seek(0);
_stream = file;
return true;
}
@ -165,18 +166,18 @@ bool MacResManager::open(String filename) {
return false;
}
bool MacResManager::open(FSNode path, String filename) {
bool MacResManager::open(const FSNode &path, const String &fileName) {
close();
#ifdef MACOSX
// Check the actual fork on a Mac computer
String fullPath = path.getPath() + "/" + filename + "/..namedfork/rsrc";
String fullPath = path.getPath() + "/" + fileName + "/..namedfork/rsrc";
FSNode resFsNode = FSNode(fullPath);
if (resFsNode.exists()) {
SeekableReadStream *macResForkRawStream = resFsNode.createReadStream();
if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) {
_baseFileName = filename;
_baseFileName = fileName;
return true;
}
@ -184,52 +185,53 @@ bool MacResManager::open(FSNode path, String filename) {
}
#endif
// First, let's try to see if the Mac converted name exists
FSNode fsNode = path.getChild(constructAppleDoubleName(filename));
if (fsNode.exists() && !fsNode.isDirectory()) {
SeekableReadStream *stream = fsNode.createReadStream();
if (loadFromAppleDouble(*stream)) {
_baseFileName = filename;
return true;
}
delete stream;
}
// Check .bin too
fsNode = path.getChild(filename + ".bin");
if (fsNode.exists() && !fsNode.isDirectory()) {
SeekableReadStream *stream = fsNode.createReadStream();
if (loadFromMacBinary(*stream)) {
_baseFileName = filename;
return true;
}
delete stream;
}
// Maybe we have a dumped fork?
fsNode = path.getChild(filename + ".rsrc");
// Prefer standalone files first, starting with raw forks
FSNode fsNode = path.getChild(fileName + ".rsrc");
if (fsNode.exists() && !fsNode.isDirectory()) {
SeekableReadStream *stream = fsNode.createReadStream();
if (loadFromRawFork(*stream)) {
_baseFileName = filename;
_baseFileName = fileName;
return true;
}
delete stream;
}
// Fine, what about just the data fork?
fsNode = path.getChild(filename);
// Then try for AppleDouble using Apple's naming
fsNode = path.getChild(constructAppleDoubleName(fileName));
if (fsNode.exists() && !fsNode.isDirectory()) {
SeekableReadStream *stream = fsNode.createReadStream();
_baseFileName = filename;
if (loadFromAppleDouble(*stream)) {
_baseFileName = fileName;
return true;
}
delete stream;
}
// Check .bin for MacBinary next
fsNode = path.getChild(fileName + ".bin");
if (fsNode.exists() && !fsNode.isDirectory()) {
SeekableReadStream *stream = fsNode.createReadStream();
if (loadFromMacBinary(*stream)) {
_baseFileName = fileName;
return true;
}
delete stream;
}
// As a last resort, see if just the data fork exists
fsNode = path.getChild(fileName);
if (fsNode.exists() && !fsNode.isDirectory()) {
SeekableReadStream *stream = fsNode.createReadStream();
_baseFileName = fileName;
// FIXME: Is this really needed?
if (isMacBinary(*stream)) {
stream->seek(0, SEEK_SET);
stream->seek(0);
if (loadFromMacBinary(*stream))
return true;
}
stream->seek(0, SEEK_SET);
stream->seek(0);
_stream = stream;
return true;
}
@ -238,22 +240,22 @@ bool MacResManager::open(FSNode path, String filename) {
return false;
}
bool MacResManager::exists(const String &filename) {
bool MacResManager::exists(const String &fileName) {
// Try the file name by itself
if (Common::File::exists(filename))
if (File::exists(fileName))
return true;
// Try the .rsrc extension
if (Common::File::exists(filename + ".rsrc"))
if (File::exists(fileName + ".rsrc"))
return true;
// Check if we have a MacBinary file
Common::File tempFile;
if (tempFile.open(filename + ".bin") && isMacBinary(tempFile))
File tempFile;
if (tempFile.open(fileName + ".bin") && isMacBinary(tempFile))
return true;
// Check if we have an AppleDouble file
if (tempFile.open(constructAppleDoubleName(filename)) && tempFile.readUint32BE() == 0x00051607)
if (tempFile.open(constructAppleDoubleName(fileName)) && tempFile.readUint32BE() == 0x00051607)
return true;
return false;
@ -480,10 +482,10 @@ SeekableReadStream *MacResManager::getResource(uint32 typeID, uint16 resID) {
return _stream->readStream(len);
}
SeekableReadStream *MacResManager::getResource(const String &filename) {
SeekableReadStream *MacResManager::getResource(const String &fileName) {
for (uint32 i = 0; i < _resMap.numTypes; i++) {
for (uint32 j = 0; j < _resTypes[i].items; j++) {
if (_resLists[i][j].nameOffset != -1 && filename.equalsIgnoreCase(_resLists[i][j].name)) {
if (_resLists[i][j].nameOffset != -1 && fileName.equalsIgnoreCase(_resLists[i][j].name)) {
_stream->seek(_dataOffset + _resLists[i][j].dataOffset);
uint32 len = _stream->readUint32BE();
@ -499,13 +501,13 @@ SeekableReadStream *MacResManager::getResource(const String &filename) {
return 0;
}
SeekableReadStream *MacResManager::getResource(uint32 typeID, const String &filename) {
SeekableReadStream *MacResManager::getResource(uint32 typeID, const String &fileName) {
for (uint32 i = 0; i < _resMap.numTypes; i++) {
if (_resTypes[i].id != typeID)
continue;
for (uint32 j = 0; j < _resTypes[i].items; j++) {
if (_resLists[i][j].nameOffset != -1 && filename.equalsIgnoreCase(_resLists[i][j].name)) {
if (_resLists[i][j].nameOffset != -1 && fileName.equalsIgnoreCase(_resLists[i][j].name)) {
_stream->seek(_dataOffset + _resLists[i][j].dataOffset);
uint32 len = _stream->readUint32BE();
@ -574,7 +576,7 @@ void MacResManager::readMap() {
}
}
Common::String MacResManager::constructAppleDoubleName(Common::String name) {
String MacResManager::constructAppleDoubleName(String name) {
// Insert "._" before the last portion of a path name
for (int i = name.size() - 1; i >= 0; i--) {
if (i == 0) {

View file

@ -54,27 +54,32 @@ public:
/**
* Open a Mac data/resource fork pair.
*
* This uses SearchMan to find the data/resource forks. This should only be used
* from inside an engine.
*
* @param filename The base file name of the file
* @note This will check for the raw resource fork, MacBinary, and AppleDouble formats.
* @return True on success
*/
bool open(String filename);
bool open(const String &fileName);
/**
* Open a Mac data/resource fork pair.
*
* @param path The path that holds the forks
* @param filename The base file name of the file
* @note This will check for the raw resource fork, MacBinary, and AppleDouble formats.
* @return True on success
*/
bool open(FSNode path, String filename);
bool open(const FSNode &path, const String &fileName);
/**
* See if a Mac data/resource fork pair exists.
* @param filename The base file name of the file
* @return True if either a data fork or resource fork with this name exists
*/
static bool exists(const String &filename);
static bool exists(const String &fileName);
/**
* Close the Mac data/resource fork pair.
@ -93,12 +98,6 @@ public:
*/
bool hasResFork() const;
/**
* Check if the given stream is in the MacBinary format.
* @param stream The stream we're checking
*/
static bool isMacBinary(SeekableReadStream &stream);
/**
* Read resource from the MacBinary file
* @param typeID FourCC of the type
@ -176,7 +175,13 @@ private:
bool loadFromMacBinary(SeekableReadStream &stream);
bool loadFromAppleDouble(SeekableReadStream &stream);
static Common::String constructAppleDoubleName(Common::String name);
static String constructAppleDoubleName(String name);
/**
* Check if the given stream is in the MacBinary format.
* @param stream The stream we're checking
*/
static bool isMacBinary(SeekableReadStream &stream);
enum {
kResForkNone = 0,

15
configure vendored
View file

@ -2373,7 +2373,8 @@ if test -n "$_host"; then
DEFINES="$DEFINES -DDISABLE_DEFAULT_SAVEFILEMANAGER"
DEFINES="$DEFINES -DDISABLE_TEXT_CONSOLE"
DEFINES="$DEFINES -DDISABLE_COMMAND_LINE"
if test "$_release_build" = yes; then
# Enable serial debugging output only when --enable-debug is passed
if test "$_release_build" = yes -o "$_debug_build" != yes; then
DEFINES="$DEFINES -DNOSERIAL"
fi
_optimization_level=-O3
@ -2708,7 +2709,8 @@ case $_backend in
LDFLAGS="$LDFLAGS -nostartfiles"
LDFLAGS="$LDFLAGS "'$(ronindir)/lib/crt0.o'
LDFLAGS="$LDFLAGS "'-L$(ronindir)/lib'
if test "$_release_build" = yes; then
# Enable serial debugging output only when --enable-debug is passed
if test "$_release_build" = yes -o "$_debug_build" != yes; then
LIBS="$LIBS -lronin-noserial -lm"
else
LIBS="$LIBS -lronin -lm"
@ -3993,7 +3995,14 @@ fi
test "x$prefix" = xNONE && prefix=/usr/local
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
DEFINES="$DEFINES -DDATA_PATH=\\\"$datadir\\\""
case $_host_os in
mingw*)
# Windows stores all the external data files in executable file.
;;
*)
DEFINES="$DEFINES -DDATA_PATH=\\\"$datadir\\\""
;;
esac
case $_backend in
openpandora)

View file

@ -10,6 +10,8 @@ if "%~1"=="/all" goto all
if "%~1"=="/ALL" goto all
if "%~1"=="/tools" goto tools
if "%~1"=="/TOOLS" goto tools
if "%~1"=="/tests" goto tests
if "%~1"=="/TESTS" goto tests
if "%~1"=="/clean" goto clean_check
if "%~1"=="/CLEAN" goto clean_check
if "%~1"=="/help" goto command_help
@ -70,6 +72,13 @@ echo.
create_project ..\.. --tools --msvc --msvc-version 10
goto done
:tests
echo.
echo Creating tests project files
echo.
create_project ..\.. --tests --msvc --msvc-version 10
goto done
:clean_check
echo.
set cleananswer=N
@ -86,8 +95,9 @@ echo Removing all project files
del /Q *.vcxproj* > NUL 2>&1
del /Q *.props > NUL 2>&1
del /Q *.sln* > NUL 2>&1
del /Q residual* > NUL 2>&1
del /Q residualvm* > NUL 2>&1
del /Q devtools* > NUL 2>&1
del /Q test_runner.cpp > NUL 2>&1
goto done
:done

View file

@ -10,6 +10,8 @@ if "%~1"=="/all" goto all
if "%~1"=="/ALL" goto all
if "%~1"=="/tools" goto tools
if "%~1"=="/TOOLS" goto tools
if "%~1"=="/tests" goto tests
if "%~1"=="/TESTS" goto tests
if "%~1"=="/clean" goto clean_check
if "%~1"=="/CLEAN" goto clean_check
if "%~1"=="/help" goto command_help
@ -70,6 +72,13 @@ echo.
create_project ..\.. --tools --msvc --msvc-version 8
goto done
:tests
echo.
echo Creating tests project files
echo.
create_project ..\.. --tests --msvc --msvc-version 8
goto done
:clean_check
echo.
set cleananswer=N
@ -86,8 +95,9 @@ echo Removing all project files
del /Q *.vcproj* > NUL 2>&1
del /Q *.vsprops > NUL 2>&1
del /Q *.sln* > NUL 2>&1
del /Q residual* > NUL 2>&1
del /Q residualvm* > NUL 2>&1
del /Q devtools* > NUL 2>&1
del /Q test_runner.cpp
goto done
:done

View file

@ -10,6 +10,8 @@ if "%~1"=="/all" goto all
if "%~1"=="/ALL" goto all
if "%~1"=="/tools" goto tools
if "%~1"=="/TOOLS" goto tools
if "%~1"=="/tests" goto tests
if "%~1"=="/TESTS" goto tests
if "%~1"=="/clean" goto clean_check
if "%~1"=="/CLEAN" goto clean_check
if "%~1"=="/help" goto command_help
@ -70,6 +72,13 @@ echo.
create_project ..\.. --tools --msvc --msvc-version 9
goto done
:tests
echo.
echo Creating tests project files
echo.
create_project ..\.. --tests --msvc --msvc-version 9
goto done
:clean_check
echo.
set cleananswer=N
@ -88,6 +97,7 @@ del /Q *.vsprops > NUL 2>&1
del /Q *.sln* > NUL 2>&1
del /Q residualvm* > NUL 2>&1
del /Q devtools* > NUL 2>&1
del /Q test_runner.cpp
goto done
:done

View file

@ -43,7 +43,16 @@ struct ThumbnailHeader {
#define ThumbnailHeaderSize (4+4+1+2+2+(1+4+4))
bool loadHeader(Common::SeekableReadStream &in, ThumbnailHeader &header, bool outputWarnings) {
enum HeaderState {
/// There is no header present
kHeaderNone,
/// The header present only has reliable values for version and size
kHeaderUnsupported,
/// The header is present and the version is supported
kHeaderPresent
};
HeaderState loadHeader(Common::SeekableReadStream &in, ThumbnailHeader &header, bool outputWarnings) {
header.type = in.readUint32BE();
// We also accept the bad 'BMHT' header here, for the sake of compatibility
// with some older savegames which were written incorrectly due to a bug in
@ -51,16 +60,28 @@ bool loadHeader(Common::SeekableReadStream &in, ThumbnailHeader &header, bool ou
if (header.type != MKTAG('T','H','M','B') && header.type != MKTAG('B','M','H','T')) {
if (outputWarnings)
warning("couldn't find thumbnail header type");
return false;
return kHeaderNone;
}
header.size = in.readUint32BE();
header.version = in.readByte();
// Do a check whether any read errors had occured. If so we cannot use the
// values obtained for size and version because they might be bad.
if (in.err() || in.eos()) {
// TODO: We fake that there is no header. This is actually not quite
// correct since we found the start of the header and then things
// started to break. Right no we leave detection of this to the client.
// Since this case is caused by broken files, the client code should
// catch it anyway... If there is a nicer solution here, we should
// implement it.
return kHeaderNone;
}
if (header.version > THMB_VERSION) {
if (outputWarnings)
warning("trying to load a newer thumbnail version: %d instead of %d", header.version, THMB_VERSION);
return false;
return kHeaderUnsupported;
}
header.width = in.readUint16BE();
@ -82,7 +103,15 @@ bool loadHeader(Common::SeekableReadStream &in, ThumbnailHeader &header, bool ou
header.format = createPixelFormat<565>();
}
return true;
if (in.err() || in.eos()) {
// When we reached this point we know that at least the size and
// version field was loaded successfully, thus we tell this header
// is not supported and silently hope that the client code is
// prepared to handle read errors.
return kHeaderUnsupported;
} else {
return kHeaderPresent;
}
}
} // end of anonymous namespace
@ -90,7 +119,12 @@ bool checkThumbnailHeader(Common::SeekableReadStream &in) {
uint32 position = in.pos();
ThumbnailHeader header;
bool hasHeader = loadHeader(in, header, false);
// TODO: It is not clear whether this is the best semantics. Now
// checkThumbnailHeader will return true even when the thumbnail header
// found is actually not usable. However, most engines seem to use this
// to detect the presence of any header and if there is none it wont even
// try to skip it. Thus, this looks like the best solution for now...
bool hasHeader = (loadHeader(in, header, false) != kHeaderNone);
in.seek(position, SEEK_SET);
@ -101,7 +135,9 @@ bool skipThumbnail(Common::SeekableReadStream &in) {
uint32 position = in.pos();
ThumbnailHeader header;
if (!loadHeader(in, header, false)) {
// We can skip unsupported and supported headers. So we only seek back
// to the old position in case there is no header at all.
if (loadHeader(in, header, false) == kHeaderNone) {
in.seek(position, SEEK_SET);
return false;
}
@ -111,10 +147,23 @@ bool skipThumbnail(Common::SeekableReadStream &in) {
}
Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in) {
const uint32 position = in.pos();
ThumbnailHeader header;
HeaderState headerState = loadHeader(in, header, true);
if (!loadHeader(in, header, true))
// Try to handle unsupported/broken headers gracefully. If there is no
// header at all, we seek back and return at this point. If there is an
// unsupported/broken header, we skip the actual data and return. The
// downside is that we might reset the end of stream flag with this and
// the client code would not be able to notice a read past the end of the
// stream at this point then.
if (headerState == kHeaderNone) {
in.seek(position, SEEK_SET);
return 0;
} else if (headerState == kHeaderUnsupported) {
in.seek(header.size - (in.pos() - position), SEEK_CUR);
return 0;
}
if (header.format.bytesPerPixel != 2 && header.format.bytesPerPixel != 4) {
warning("trying to load thumbnail with unsupported bit depth %d", header.format.bytesPerPixel);