From a5a531ec9f5c6f6f6d550a4f0d7034110ec1c02a Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Fri, 15 Jan 2016 02:48:37 +0200 Subject: SCI: Use the actual segment in the segment manager for SCI3 games --- engines/sci/engine/seg_manager.cpp | 49 +++++++++++++++++++++++++------------- engines/sci/engine/seg_manager.h | 1 + 2 files changed, 33 insertions(+), 17 deletions(-) (limited to 'engines') diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 58c2b8d3e3..23b1fdae23 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -144,11 +144,21 @@ Script *SegManager::allocateScript(int script_nr, SegmentId *segid) { return (Script *)mem; } +SegmentId SegManager::getActualSegment(SegmentId seg) const { + if (getSciVersion() <= SCI_VERSION_2_1_LATE) { + return seg; + } else { + // Return the lower 14 bits of the segment + return (seg & 0x3FFF); + } +} + void SegManager::deallocate(SegmentId seg) { - if (seg < 1 || (uint)seg >= _heap.size()) + SegmentId actualSegment = getActualSegment(seg); + if (actualSegment < 1 || (uint)actualSegment >= _heap.size()) error("Attempt to deallocate an invalid segment ID"); - SegmentObj *mobj = _heap[seg]; + SegmentObj *mobj = _heap[actualSegment]; if (!mobj) error("Attempt to deallocate an already freed segment"); @@ -169,7 +179,7 @@ void SegManager::deallocate(SegmentId seg) { } delete mobj; - _heap[seg] = NULL; + _heap[actualSegment] = NULL; } bool SegManager::isHeapObject(reg_t pos) const { @@ -185,22 +195,24 @@ void SegManager::deallocateScript(int script_nr) { } Script *SegManager::getScript(const SegmentId seg) { - if (seg < 1 || (uint)seg >= _heap.size()) { - error("SegManager::getScript(): seg id %x out of bounds", seg); + SegmentId actualSegment = getActualSegment(seg); + if (actualSegment < 1 || (uint)actualSegment >= _heap.size()) { + error("SegManager::getScript(): seg id %x out of bounds", actualSegment); } - if (!_heap[seg]) { - error("SegManager::getScript(): seg id %x is not in memory", seg); + if (!_heap[actualSegment]) { + error("SegManager::getScript(): seg id %x is not in memory", actualSegment); } - if (_heap[seg]->getType() != SEG_TYPE_SCRIPT) { - error("SegManager::getScript(): seg id %x refers to type %d != SEG_TYPE_SCRIPT", seg, _heap[seg]->getType()); + if (_heap[actualSegment]->getType() != SEG_TYPE_SCRIPT) { + error("SegManager::getScript(): seg id %x refers to type %d != SEG_TYPE_SCRIPT", actualSegment, _heap[actualSegment]->getType()); } - return (Script *)_heap[seg]; + return (Script *)_heap[actualSegment]; } Script *SegManager::getScriptIfLoaded(const SegmentId seg) const { - if (seg < 1 || (uint)seg >= _heap.size() || !_heap[seg] || _heap[seg]->getType() != SEG_TYPE_SCRIPT) + SegmentId actualSegment = getActualSegment(seg); + if (actualSegment < 1 || (uint)actualSegment >= _heap.size() || !_heap[actualSegment] || _heap[actualSegment]->getType() != SEG_TYPE_SCRIPT) return 0; - return (Script *)_heap[seg]; + return (Script *)_heap[actualSegment]; } SegmentId SegManager::findSegmentByType(int type) const { @@ -211,19 +223,22 @@ SegmentId SegManager::findSegmentByType(int type) const { } SegmentObj *SegManager::getSegmentObj(SegmentId seg) const { - if (seg < 1 || (uint)seg >= _heap.size() || !_heap[seg]) + SegmentId actualSegment = getActualSegment(seg); + if (actualSegment < 1 || (uint)actualSegment >= _heap.size() || !_heap[actualSegment]) return 0; - return _heap[seg]; + return _heap[actualSegment]; } SegmentType SegManager::getSegmentType(SegmentId seg) const { - if (seg < 1 || (uint)seg >= _heap.size() || !_heap[seg]) + SegmentId actualSegment = getActualSegment(seg); + if (actualSegment < 1 || (uint)actualSegment >= _heap.size() || !_heap[actualSegment]) return SEG_TYPE_INVALID; - return _heap[seg]->getType(); + return _heap[actualSegment]->getType(); } SegmentObj *SegManager::getSegment(SegmentId seg, SegmentType type) const { - return getSegmentType(seg) == type ? _heap[seg] : NULL; + SegmentId actualSegment = getActualSegment(seg); + return getSegmentType(actualSegment) == type ? _heap[actualSegment] : NULL; } Object *SegManager::getObject(reg_t pos) const { diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index 2d6e624f6f..7a689603a0 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -472,6 +472,7 @@ private: void createClassTable(); SegmentId findFreeSegment() const; + SegmentId getActualSegment(SegmentId seg) const; }; } // End of namespace Sci -- cgit v1.2.3