diff options
author | Torbjörn Andersson | 2005-10-17 06:45:54 +0000 |
---|---|---|
committer | Torbjörn Andersson | 2005-10-17 06:45:54 +0000 |
commit | 290c8114de0b5ce09689253b4a9d8825a5c79c21 (patch) | |
tree | 54f4c0877db80fa66e095d1aad32bb34b6b2bf52 | |
parent | 1a717471ba30aabff6bf442666676a8ad2dbce16 (diff) | |
download | scummvm-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.cpp | 3 | ||||
-rw-r--r-- | sword2/function.cpp | 5 | ||||
-rw-r--r-- | sword2/resman.cpp | 7 | ||||
-rw-r--r-- | sword2/sword2.cpp | 5 |
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 ' ': |