aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorFilippos Karapetis2010-09-13 13:17:55 +0000
committerFilippos Karapetis2010-09-13 13:17:55 +0000
commite242814990862998c2af9289f88f0cbc8060fb13 (patch)
tree80dda8835c811d870797941516fad1b4e850df02 /engines
parentc2fb737950bd27d8f86a66a08d3c17b7b734fc1c (diff)
downloadscummvm-rg350-e242814990862998c2af9289f88f0cbc8060fb13.tar.gz
scummvm-rg350-e242814990862998c2af9289f88f0cbc8060fb13.tar.bz2
scummvm-rg350-e242814990862998c2af9289f88f0cbc8060fb13.zip
SCI: Proper fix for bug #3038837 - "HOYLE3: EGA/VGA Crashes" and some cleanup
System scripts (i.e. 0 and 900-999) are now protected and never destroyed during a game svn-id: r52702
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/engine/script.cpp26
-rw-r--r--engines/sci/engine/script.h23
-rw-r--r--engines/sci/engine/seg_manager.cpp15
3 files changed, 29 insertions, 35 deletions
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index 81094c6f59..da9ab5106d 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -310,25 +310,6 @@ void Script::incrementLockers() {
void Script::decrementLockers() {
if (_lockers > 0)
_lockers--;
-
- // WORKAROUND for bug #3038837: HOYLE3: EGA/VGA Crashes
- // This is caused by script 0 lockers reaching zero. Since
- // this should never happen, I'm confident in making this a
- // non-specific fix. We can't just reset lockers to 1, because
- // the objects associated with the script are already marked
- // to be deleted at this point, thus we need to reload the
- // script itself. If we don't, the game will surely error
- // out later on, because of objects associated with this
- // script which are incorrectly marked to be deleted. For
- // example, in Hoyle 3, if you exit Checkers and reenter
- // checkers, the game will crash when selecting a player.
- //
- // TODO: Figure out why this happens, and fix it properly!
- if (_nr == 0 && _lockers == 0) {
- init(0, g_sci->getResMan());
- load(g_sci->getResMan());
- }
-
}
int Script::getLockers() const {
@@ -577,6 +558,13 @@ void Script::initialiseObjectsSci11(SegManager *segMan, SegmentId segmentId) {
relocate(make_reg(segmentId, READ_SCI11ENDIAN_UINT16(_heapStart)));
}
+void Script::initialiseObjects(SegManager *segMan, SegmentId segmentId) {
+ if (getSciVersion() >= SCI_VERSION_1_1)
+ initialiseObjectsSci11(segMan, segmentId);
+ else
+ initialiseObjectsSci0(segMan, segmentId);
+}
+
reg_t Script::findCanonicAddress(SegManager *segMan, reg_t addr) const {
addr.offset = 0;
return addr;
diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h
index c60cc4b19f..e316fc0c8d 100644
--- a/engines/sci/engine/script.h
+++ b/engines/sci/engine/script.h
@@ -159,14 +159,7 @@ public:
* @param segMan A reference to the segment manager
* @param segmentId The script's segment id
*/
- void initialiseObjectsSci0(SegManager *segMan, SegmentId segmentId);
-
- /**
- * Initializes the script's objects (SCI1.1+)
- * @param segMan A reference to the segment manager
- * @param segmentId The script's segment id
- */
- void initialiseObjectsSci11(SegManager *segMan, SegmentId segmentId);
+ void initialiseObjects(SegManager *segMan, SegmentId segmentId);
// script lock operations
@@ -260,6 +253,20 @@ private:
void relocate(reg_t block);
bool relocateLocal(SegmentId segment, int location);
+
+ /**
+ * Initializes the script's objects (SCI0)
+ * @param segMan A reference to the segment manager
+ * @param segmentId The script's segment id
+ */
+ void initialiseObjectsSci0(SegManager *segMan, SegmentId segmentId);
+
+ /**
+ * Initializes the script's objects (SCI1.1+)
+ * @param segMan A reference to the segment manager
+ * @param segmentId The script's segment id
+ */
+ void initialiseObjectsSci11(SegManager *segMan, SegmentId segmentId);
};
} // End of namespace Sci
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 7fdd2d25ac..43e572d071 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -1004,12 +1004,7 @@ int SegManager::instantiateScript(int scriptNum) {
scr->load(_resMan);
scr->initialiseLocals(this);
scr->initialiseClasses(this);
-
- if (getSciVersion() >= SCI_VERSION_1_1) {
- scr->initialiseObjectsSci11(this, segmentId);
- } else {
- scr->initialiseObjectsSci0(this, segmentId);
- }
+ scr->initialiseObjects(this, segmentId);
return segmentId;
}
@@ -1074,8 +1069,12 @@ void SegManager::uninstantiateScriptSci0(int script_nr) {
if (superclass_script == script_nr) {
if (scr->getLockers())
scr->decrementLockers(); // Decrease lockers if this is us ourselves
- } else
- uninstantiateScript(superclass_script);
+ } else {
+ // Uninstantiate superclass, but never uninstantiate
+ // system scripts, i.e. script 0 and scripts 900-999 - bug #3038837
+ if (superclass_script != 0 && superclass_script < 900)
+ uninstantiateScript(superclass_script);
+ }
// Recurse to assure that the superclass lockers number gets decreased
}