[Scummvm-cvs-logs] SF.net SVN: scummvm:[46068] scummvm/trunk/engines/draci

spalek at users.sourceforge.net spalek at users.sourceforge.net
Sun Nov 22 10:13:05 CET 2009


Revision: 46068
          http://scummvm.svn.sourceforge.net/scummvm/?rev=46068&view=rev
Author:   spalek
Date:     2009-11-22 09:13:05 +0000 (Sun, 22 Nov 2009)

Log Message:
-----------
Fix SIGSEGV by an absolutely brutally horrible hack

I have thoroughly documented why this hack is needed and added ideas how to
fix it properly.

Modified Paths:
--------------
    scummvm/trunk/engines/draci/game.cpp
    scummvm/trunk/engines/draci/walking.h

Modified: scummvm/trunk/engines/draci/game.cpp
===================================================================
--- scummvm/trunk/engines/draci/game.cpp	2009-11-22 09:01:57 UTC (rev 46067)
+++ scummvm/trunk/engines/draci/game.cpp	2009-11-22 09:13:05 UTC (rev 46068)
@@ -1155,12 +1155,73 @@
 }
 
 void Game::deleteObjectAnimations() {
-	for (uint i = 0; i < _info._numObjects; ++i) {
+	for (uint i = 1; i < _info._numObjects; ++i) {
 		GameObject *obj = &_objects[i];
-		if (i != 0 && (obj->_location == getPreviousRoomNum())) {
+		if (obj->_location == getPreviousRoomNum()) {
 			obj->deleteAnims();
 		}
 	}
+	
+	// WORKAROUND
+	//
+	// An absolutely horrible hack follows.  The current memory management
+	// is completely broken and it needs to be seriously hacked to work at
+	// all.  The problem is caching sound samples in BArchive and clearing
+	// all caches when entering a new location.  The animation sequences
+	// store pointers to samples owned by the BArchive cache, which gets
+	// invalidated during the location change.  If an animation sequence
+	// survives location change and refers to any sound sample, we get
+	// SIGSEGV when next played, because this sound sample will have been
+	// deallocated by the cache although still referred to by the animation.
+	//
+	// Caveat: when I tried to perform a deep copy and make the animation
+	// object own the sound samples and deallocate them when the animation
+	// has been deleted, I get an almost immediate SIGSEGV in runWrapper()
+	// on many objects, because often an animation graphically ends and is
+	// stopped, but the last sound sample still plays for a short while
+	// afterwards.  If the sound sample is cached, it's OK, but if it's
+	// deallocated with releaseAnims==true, we get SIGSEGV in the sound
+	// mixer.  This problem doesn't occur when changing locations, because
+	// there we first explicitly stop all playing sounds.
+	//
+	// The loop above deallocates all animations corresponding to non-hero
+	// objects.  Hero is special, because the first ~20 animations are
+	// standard and loaded for the whole game (standing, walking, etc.).
+	// They are loaded by the GPL2 init routine for object hero.  Luckily
+	// the animations don't refer to any sound samples.  The remaining
+	// animations thus must be deallocated manually, otherwise they won't
+	// be re-loaded next time assuming that they are already correctly
+	// loaded.
+	//
+	// mini-TODO: integrate this deletion into deleteAnim() an optional
+	// parameter with starting index for deletion.
+	//
+	// Why this only occurs for sound samples and not sprites?  This bug is
+	// concealed by a complete coincidence, that all sprites are stored
+	// column-wise and our class Sprite detects this and creates a local
+	// copy.  If this wasn't the case, each animation (not just with sound
+	// samples) would fail and preserving the ~20 hero animations wouldn't
+	// work either.
+	//
+	// TODO: maybe simply deallocate everything except for those ~20 hero
+	// animations instead of listing what to deallocate.  maybe simply
+	// deallocate everything; reloading isn't that expensive.
+	//
+	// TODO: completely rewrite the resource management.  maybe implement
+	// usage counters?  maybe completely ignore the GPL2 hints and manage
+	// memory completely on my own?
+	//
+	// URGENT TODO: if a game item is in the hero's hands when changing
+	// locations, its animations survive and we get assert in
+	// AnimationManager::load().
+	GameObject *dragon = &_objects[kDragonObject];
+	for (uint i = dragon->_anim.size() - 1; i >= kFirstTemporaryAnimation; --i) {
+		dragon->_anim.back()->del();
+		dragon->_anim.pop_back();
+	}
+	if (dragon->_playingAnim >= kFirstTemporaryAnimation) {
+		dragon->_playingAnim = 0;
+	}
 }
 
 bool Game::enterNewRoom() {

Modified: scummvm/trunk/engines/draci/walking.h
===================================================================
--- scummvm/trunk/engines/draci/walking.h	2009-11-22 09:01:57 UTC (rev 46067)
+++ scummvm/trunk/engines/draci/walking.h	2009-11-22 09:13:05 UTC (rev 46068)
@@ -96,7 +96,9 @@
 	kMoveLeftRight, kMoveRightLeft, kMoveUpStopLeft, kMoveUpStopRight,
 	kLastTurning = kMoveUpStopRight,
 
-	kSpeakRight, kSpeakLeft, kStopRight, kStopLeft
+	kSpeakRight, kSpeakLeft, kStopRight, kStopLeft,
+
+	kFirstTemporaryAnimation
 };
 
 class DraciEngine;


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list