aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorbjörn Andersson2005-10-17 06:45:54 +0000
committerTorbjörn Andersson2005-10-17 06:45:54 +0000
commit290c8114de0b5ce09689253b4a9d8825a5c79c21 (patch)
tree54f4c0877db80fa66e095d1aad32bb34b6b2bf52
parent1a717471ba30aabff6bf442666676a8ad2dbce16 (diff)
downloadscummvm-rg350-290c8114de0b5ce09689253b4a9d8825a5c79c21.tar.gz
scummvm-rg350-290c8114de0b5ce09689253b4a9d8825a5c79c21.tar.bz2
scummvm-rg350-290c8114de0b5ce09689253b4a9d8825a5c79c21.zip
Fixed end credits crash. (See bug #1327650). Actually, there were several
more or less serious bugs here: * The fnResetGlobals() function returned IR_CONT. Since it potentially kills its own script resource, this can lead to illegal read accesses. Not it returns IR_STOP instead. This was probably a bug in the original interpreter as well, but it handled memory allocation quite differently so it was probably never an issue. * Since fnResetGlobals() forcibly closes resources, I've changed the closeResource() function to silently ignore requests to close resources where the data pointer is NULL. While it could signify an error, it isn't necessarily so. * Don't force the screen to fade up after the credits -- let the script do it instead. This prevents it from fading up the wrong image. svn-id: r19127
-rw-r--r--sword2/build_display.cpp3
-rw-r--r--sword2/function.cpp5
-rw-r--r--sword2/resman.cpp7
-rw-r--r--sword2/sword2.cpp5
4 files changed, 15 insertions, 5 deletions
diff --git a/sword2/build_display.cpp b/sword2/build_display.cpp
index c95c176f41..594da882bb 100644
--- a/sword2/build_display.cpp
+++ b/sword2/build_display.cpp
@@ -653,7 +653,6 @@ struct CreditsLine {
#define CREDITS_LINE_SPACING 20
void Screen::rollCredits() {
- ScreenInfo *screenInfo = getScreenInfo();
uint32 loopingMusicId = _vm->_sound->getLoopingMusicId();
// Prepare for the credits by fading down, stoping the music, etc.
@@ -976,8 +975,6 @@ void Screen::rollCredits() {
else
_vm->_sound->stopMusic(false);
- screenInfo->new_palette = 99;
-
if (!_vm->_mouse->getMouseStatus() || _vm->_mouse->isChoosing())
_vm->_mouse->setMouse(NORMAL_MOUSE_ID);
diff --git a/sword2/function.cpp b/sword2/function.cpp
index 3c93df22f6..4f267f021a 100644
--- a/sword2/function.cpp
+++ b/sword2/function.cpp
@@ -2295,7 +2295,10 @@ int32 Logic::fnResetGlobals(int32 *params) {
// switch on scrolling (2 means first time on screen)
screenInfo->scroll_flag = 2;
- return IR_CONT;
+ // Used to be IR_CONT, but that's a bad idea. We may just have killed
+ // our own script resource -- continuing will cause a bad memory read
+ // access.
+ return IR_STOP;
}
int32 Logic::fnSetPalette(int32 *params) {
diff --git a/sword2/resman.cpp b/sword2/resman.cpp
index 60ea6cbc85..fc8b5f4eb9 100644
--- a/sword2/resman.cpp
+++ b/sword2/resman.cpp
@@ -522,6 +522,13 @@ byte *ResourceManager::openResource(uint32 res, bool dump) {
void ResourceManager::closeResource(uint32 res) {
assert(res < _totalResFiles);
+
+ // Don't try to close the resource if it has already been forcibly
+ // closed, e.g. by fnResetGlobals().
+
+ if (_resList[res].ptr == NULL)
+ return;
+
assert(_resList[res].refCount > 0);
_resList[res].refCount--;
diff --git a/sword2/sword2.cpp b/sword2/sword2.cpp
index 1d7927936c..fa31cf946e 100644
--- a/sword2/sword2.cpp
+++ b/sword2/sword2.cpp
@@ -332,8 +332,11 @@ int Sword2Engine::go() {
pauseGame();
break;
case 'c':
- if (!Logic::_scriptVars[DEMO] && !_mouse->isChoosing())
+ if (!Logic::_scriptVars[DEMO] && !_mouse->isChoosing()) {
+ ScreenInfo *screenInfo = _screen->getScreenInfo();
_logic->fnPlayCredits(NULL);
+ screenInfo->new_palette = 99;
+ }
break;
#ifdef SWORD2_DEBUG
case ' ':