[Scummvm-cvs-logs] scummvm master -> f6e4312665614d7b5b626f997194fbbcb00ddbb0
bluegr
md5 at scummvm.org
Mon Jul 2 11:50:09 CEST 2012
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
44935117f4 SCI: Fix a workaround for an uninitialized variable in SQ4CD
f6e4312665 SCI: Add a hack for a bug in the script handling code
Commit: 44935117f493b2e256b5a2c701b63cef57d872af
https://github.com/scummvm/scummvm/commit/44935117f493b2e256b5a2c701b63cef57d872af
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2012-07-02T02:49:08-07:00
Commit Message:
SCI: Fix a workaround for an uninitialized variable in SQ4CD
This makes sure that the workaround works for subclassed objects as well,
such as "theProfessor" talker. Fixes bug #3539350 - "SCI: SQ4 CD -
Crash in sewer when text and speech enabled"
Changed paths:
engines/sci/engine/workarounds.cpp
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index ecb1e4c..15fca03 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -162,7 +162,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_SQ1, -1, 703, 0, "", "export 1", -1, 0, { WORKAROUND_FAKE, 0 } }, // sub that's called from several objects while on sarien battle cruiser
{ GID_SQ1, -1, 703, 0, "firePulsar", "changeState", 0x18a, 0, { WORKAROUND_FAKE, 0 } }, // export 1, but called locally (when shooting at aliens)
{ GID_SQ4, -1, 398, 0, "showBox", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // CD: called when rummaging in Software Excess bargain bin
- { GID_SQ4, -1, 928, 0, "Narrator", "startText", -1, 1000, { WORKAROUND_FAKE, 1 } }, // CD: method returns this to the caller
+ { GID_SQ4, -1, 928, -1, "Narrator", "startText", -1, 1000, { WORKAROUND_FAKE, 1 } }, // CD: happens in the options dialog and in-game when speech and subtitles are used simultaneously
{ GID_SQ5, 201, 201, 0, "buttonPanel", "doVerb", -1, 0, { WORKAROUND_FAKE, 1 } }, // when looking at the orange or red button - bug #3038563
{ GID_SQ6, -1, 0, 0, "SQ6", "init", -1, 2, { WORKAROUND_FAKE, 0 } }, // Demo and full version: called when the game starts (demo: room 0, full: room 100)
{ GID_SQ6, 100, 64950, 0, "View", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // called when pressing "Start game" in the main menu
Commit: f6e4312665614d7b5b626f997194fbbcb00ddbb0
https://github.com/scummvm/scummvm/commit/f6e4312665614d7b5b626f997194fbbcb00ddbb0
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2012-07-02T02:49:10-07:00
Commit Message:
SCI: Add a hack for a bug in the script handling code
When resetting the segment manager, sometimes the locals block for a
script is placed in a segment smaller than the script itself. This
shouldn't be happening, but it isn't fatal, however it should be resolved
in a proper manner
Changed paths:
engines/sci/engine/seg_manager.cpp
engines/sci/engine/seg_manager.h
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index a6c1459..d425e17 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -143,16 +143,34 @@ Script *SegManager::allocateScript(int script_nr, SegmentId *segid) {
}
void SegManager::deallocate(SegmentId seg) {
- if (!check(seg))
- error("SegManager::deallocate(): invalid segment ID");
+ if (seg < 1 || (uint)seg >= _heap.size())
+ error("Attempt to deallocate an invalid segment ID");
SegmentObj *mobj = _heap[seg];
+ if (!mobj)
+ error("Attempt to deallocate an already freed segment");
if (mobj->getType() == SEG_TYPE_SCRIPT) {
Script *scr = (Script *)mobj;
_scriptSegMap.erase(scr->getScriptNumber());
- if (scr->getLocalsSegment())
- deallocate(scr->getLocalsSegment());
+ if (scr->getLocalsSegment()) {
+ // HACK: Check if the locals segment has already been deallocated.
+ // This happens sometimes in SQ4CD when resetting the segment
+ // manager: the locals for script 808 are somehow stored in a
+ // smaller segment than the script itself, so by the time the script
+ // is about to be freed, the locals block has already been freed.
+ // This isn't fatal, but it shouldn't be happening at all.
+ // FIXME: Check why this happens. Perhaps there's a bug in the
+ // script handling code?
+ if (!_heap[scr->getLocalsSegment()]) {
+ warning("SegManager::deallocate(): The locals block of script "
+ "%d has already been deallocated. Script segment: %d, "
+ "locals segment: %d", scr->getScriptNumber(), seg,
+ scr->getLocalsSegment());
+ } else {
+ deallocate(scr->getLocalsSegment());
+ }
+ }
}
delete mobj;
@@ -307,21 +325,6 @@ reg_t SegManager::findObjectByName(const Common::String &name, int index) {
return result[index];
}
-// validate the seg
-// return:
-// false - invalid seg
-// true - valid seg
-bool SegManager::check(SegmentId seg) {
- if (seg < 1 || (uint)seg >= _heap.size()) {
- return false;
- }
- if (!_heap[seg]) {
- warning("SegManager: seg %x is removed from memory, but not removed from hash_map", seg);
- return false;
- }
- return true;
-}
-
// return the seg if script_id is valid and in the map, else 0
SegmentId SegManager::getScriptSegment(int script_id) const {
return _scriptSegMap.getVal(script_id, 0);
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index 356a1b0..074d3f6 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -471,14 +471,6 @@ private:
void createClassTable();
SegmentId findFreeSegment() const;
-
- /**
- * Check segment validity
- * @param[in] seg The segment to validate
- * @return false if 'seg' is an invalid segment, true if
- * 'seg' is a valid segment
- */
- bool check(SegmentId seg);
};
} // End of namespace Sci
More information about the Scummvm-git-logs
mailing list