From 6e07e3e6424750d8d6d8536dd67d4962f2ea9db4 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 25 Feb 2010 15:22:26 +0000 Subject: [PATCH] Fixing problems with the texts table in TOT files when the order of the texts and resources tables are switched in the TOT file svn-id: r48124 --- engines/gob/resources.cpp | 22 ++++++------------ engines/gob/totfile.cpp | 49 +++++++++++++++++++++++++++++++++++---- engines/gob/totfile.h | 2 ++ 3 files changed, 53 insertions(+), 20 deletions(-) diff --git a/engines/gob/resources.cpp b/engines/gob/resources.cpp index 6acaf224f8a..1dae2016d65 100644 --- a/engines/gob/resources.cpp +++ b/engines/gob/resources.cpp @@ -350,16 +350,13 @@ bool Resources::loadTOTTextTable(const Common::String &fileBase) { _totTextTable = new TOTTextTable; - bool fromTOT; if (totProps.textsOffset == 0) { - fromTOT = false; _totTextTable->data = loadTOTLocTexts(fileBase, _totTextTable->size); _totTextTable->needFree = true; } else { - fromTOT = true; _totTextTable->data = _totData + totProps.textsOffset - _totResStart; _totTextTable->needFree = false; - _totTextTable->size = _totSize - totProps.textsOffset; + _totTextTable->size = totProps.textsSize; } if (_totTextTable->data) { @@ -372,9 +369,6 @@ bool Resources::loadTOTTextTable(const Common::String &fileBase) { item.offset = totTextTable.readSint16LE(); item.size = totTextTable.readSint16LE(); - - if (fromTOT) - item.offset -= (totProps.textsOffset - _totResStart); } } @@ -572,14 +566,11 @@ TextItem *Resources::getTextItem(uint16 id) const { if ((totItem.offset == 0xFFFF) || (totItem.size == 0)) return 0; + if ((totItem.offset + totItem.size) > (_totTextTable->size)) { -// HACK: Some Fascination versions (Amiga, Atari and first PC floppies) have a different header, which is a problem here. -// Playtoons also have the same problem (and workaround). -// TODO: Handle that in a proper way - if (((_vm->getGameType() == kGameTypeFascination) || (_vm->getGameType() == kGameTypePlaytoons)) && (_totTextTable->size < 0)) - warning("totTextTable with negative size id:%d offset:%d in file %s : (size: %d)", id, totItem.offset, _totFile.c_str(), _totTextTable->size); - else - return 0; + warning("TOT text %d offset %d out of range (%s, %d, %d)", + id, totItem.offset, _totFile.c_str(), _totSize, totItem.size); + return 0; } return new TextItem(_totTextTable->data + totItem.offset, totItem.size); @@ -710,7 +701,8 @@ byte *Resources::getTOTData(TOTResourceItem &totItem) const { int32 offset = _totResourceTable->dataOffset + totItem.offset - _totResStart; if ((offset < 0) || (((uint32) (offset + totItem.size)) > _totSize)) { - warning("Skipping data id:%d offset:%d size :%d in file %s : out of _totTextTable", totItem.index, totItem.offset, totItem.size, _totFile.c_str()); + warning("TOT data %d offset %d out of range (%s, %d, %d)", + totItem.index, totItem.offset, _totFile.c_str(), _totSize, totItem.size); return 0; } diff --git a/engines/gob/totfile.cpp b/engines/gob/totfile.cpp index bbf62c143bb..5cc723ba7da 100644 --- a/engines/gob/totfile.cpp +++ b/engines/gob/totfile.cpp @@ -97,11 +97,50 @@ bool TOTFile::getProperties(Properties &props) const { for (int i = 0; i < 14; i++) props.functions[i] = READ_LE_UINT16(_header + 100 + i * 2); - props.scriptEnd = _stream->size(); - if (props.textsOffset > 0) - props.scriptEnd = MIN(props.scriptEnd, props.textsOffset); - if (props.resourcesOffset > 0) - props.scriptEnd = MIN(props.scriptEnd, props.resourcesOffset); + uint32 fileSize = _stream->size(); + uint32 textsOffset = props.textsOffset; + uint32 resourcesOffset = props.resourcesOffset; + + if (textsOffset == 0xFFFFFFFF) + textsOffset = 0; + if (resourcesOffset == 0xFFFFFFFF) + resourcesOffset = 0; + + props.scriptEnd = fileSize; + if (textsOffset > 0) + props.scriptEnd = MIN(props.scriptEnd, textsOffset); + if (resourcesOffset > 0) + props.scriptEnd = MIN(props.scriptEnd, resourcesOffset); + + // Calculate the sizes of the texts and resources tables for every possible order + if ((textsOffset > 0) && (resourcesOffset > 0)) { + // Both exists + + if (props.textsOffset > resourcesOffset) { + // First resources, then texts + props.textsSize = fileSize - textsOffset; + props.resourcesSize = textsOffset - resourcesOffset; + } else { + // First texts, then resources + props.textsSize = resourcesOffset - textsOffset; + props.resourcesSize = fileSize - resourcesOffset; + } + } else if (textsOffset > 0) { + // Only the texts table exists + + props.textsSize = fileSize - textsOffset; + props.resourcesSize = 0; + } else if (resourcesOffset > 0) { + // Only the resources table exists + + props.textsSize = 0; + props.resourcesSize = fileSize - resourcesOffset; + } else { + // Both don't exists + + props.textsSize = 0; + props.resourcesSize = 0; + } return true; } diff --git a/engines/gob/totfile.h b/engines/gob/totfile.h index 00963d36a27..211232f870f 100644 --- a/engines/gob/totfile.h +++ b/engines/gob/totfile.h @@ -53,6 +53,8 @@ public: uint8 communHandling; uint16 functions[14]; uint32 scriptEnd; + uint32 textsSize; + uint32 resourcesSize; }; TOTFile(GobEngine *vm);