[Scummvm-cvs-logs] scummvm master -> 0f7dcac15591c4ea3def6ff16bb8cf0d6321809c

lskovlun lskovlun at sprogklog.dk
Mon Feb 28 20:59:59 CET 2011


This automated email contains information about 9 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
b680a46208 SCI: Add workaround for PQ:SWAT
f418a39684 SCI: Reverted rc7bfbc3 and fixed the actual cause of bug #3106107
be05ca1f50 HUGO: rewrite saveEvents() and restoreEvents() in order to be endian and platform safe
98ee6ca8bb HUGO: Remove forgotten debug message
c4a68629a0 SCI: Add FIXME comment to workaround
0b50322cf5 SCI: Moved hunk pointer handling to the GC, and removed some related workarounds
acbdee55c9 SWORD2: Plug a memory leak in psx version
ea33190de1 SWORD2: fix leak of previous commit properly
0f7dcac155 Merge branch 'master' of github.com:scummvm/scummvm


Commit: b680a462083ddecb5023079d6d5e7d5764feea58
    https://github.com/scummvm/scummvm/commit/b680a462083ddecb5023079d6d5e7d5764feea58
Author: Lars Skovlund (lskovlun at sprogklog.dk)
Date: 2011-02-28T10:58:55-08:00

Commit Message:
SCI: Add workaround for PQ:SWAT
This is a bug in the class library; there are identical ones for other SCI games.

Changed paths:
    engines/sci/engine/workarounds.cpp



diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index 64cbc5e..d99f8ce 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -120,6 +120,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
 	{ GID_MOTHERGOOSEHIRES,-1,64950,  1,               "View", "handleEvent",    -1,    0, { WORKAROUND_FAKE,   0 } }, // see above
 	{ GID_PEPPER,         -1,   894,  0,            "Package", "doVerb",         -1,    3, { WORKAROUND_FAKE,   0 } }, // using the hand on the book in the inventory - bug #3040012
 	{ GID_PEPPER,        150,   928,  0,           "Narrator", "startText",      -1,    0, { WORKAROUND_FAKE,   0 } }, // happens during the non-interactive demo of Pepper
+	{ GID_PQSWAT,         -1, 64950,  0,               "View", "handleEvent",    -1,    0, { WORKAROUND_FAKE,   0 } }, // see above
 	{ GID_QFG1,           -1,   210,  0,          "Encounter", "init",        0xbd0,    0, { WORKAROUND_FAKE,   0 } }, // hq1: going to the brigands hideout
 	{ GID_QFG1,           -1,   210,  0,          "Encounter", "init",        0xbe4,    0, { WORKAROUND_FAKE,   0 } }, // qfg1: going to the brigands hideout
 	{ GID_QFG1VGA,        16,    16,  0,        "lassoFailed", "changeState",    -1,   -1, { WORKAROUND_FAKE,   0 } }, // qfg1vga: casting the "fetch" spell in the screen with the flowers, temps 0 and 1 - bug #3053268


Commit: f418a39684b79ba9bed4ecaba0c747e3673a8b44
    https://github.com/scummvm/scummvm/commit/f418a39684b79ba9bed4ecaba0c747e3673a8b44
Author: md5 (md5 at scummvm.org)
Date: 2011-02-28T11:01:12-08:00

Commit Message:
SCI: Reverted rc7bfbc3 and fixed the actual cause of bug #3106107

While fast forwarding a song, disable its hold value together with any possible
sound looping, so that the song won't loop forever.

Changed paths:
    engines/sci/sound/music.cpp
    engines/sci/sound/soundcmd.cpp



diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index a08525d..2331f2f 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -441,10 +441,15 @@ void SciMusic::soundPlay(MusicEntry *pSnd) {
 				// when loading a saved game. Fixes bug #3083151.
 				uint16 prevLoop = pSnd->loop;
 				pSnd->loop = 0;
+				// Same for hold. Fixes bug #3106107.
+				int16 prevHold = pSnd->hold;
+				pSnd->hold = -1;
 				// Fast forward to the last position and perform associated events when loading
 				pSnd->pMidiParser->jumpToTick(pSnd->ticker, true, true, true);
 				// Restore looping
 				pSnd->loop = prevLoop;
+				// Restore hold
+				pSnd->hold = prevHold;
 			}
 			pSnd->pMidiParser->mainThreadEnd();
 			_mutex.unlock();
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index 33be8f4..1e6d0ae 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -318,9 +318,6 @@ reg_t SoundCommandParser::kDoSoundFade(int argc, reg_t *argv, reg_t acc) {
 
 	int volume = musicSlot->volume;
 
-	// Reset hold so that the song can actually stop
-	musicSlot->hold = -1;
-
 	// If sound is not playing currently, set signal directly
 	if (musicSlot->status != kSoundPlaying) {
 		debugC(kDebugLevelSound, "kDoSound(fade): %04x:%04x fading requested, but sound is currently not playing", PRINT_REG(obj));
@@ -534,12 +531,6 @@ reg_t SoundCommandParser::kDoSoundSetHold(int argc, reg_t *argv, reg_t acc) {
 		return acc;
 	}
 
-	// Is the song being faded? If yes, don't set a hold value, otherwise the
-	// song will never actually stop. Fixes bug #3106107.
-	if (musicSlot->fadeStep && argv[1].toSint16() != -1) {
-		warning("kDoSound(setHold): Attempt to set a hold value (%d) to a song being faded, ignoring", argv[1].toSint16());
-		return acc;
-	}
 	// Set the special hold marker ID where the song should be looped at.
 	musicSlot->hold = argv[1].toSint16();
 	return acc;


Commit: be05ca1f50cdf01f1795f65c91ebde8408baa170
    https://github.com/scummvm/scummvm/commit/be05ca1f50cdf01f1795f65c91ebde8408baa170
Author: strangerke (arnaud.boutonne at gmail.com)
Date: 2011-02-28T11:01:12-08:00

Commit Message:
HUGO: rewrite saveEvents() and restoreEvents() in order to be endian and platform safe

Changed paths:
    engines/hugo/schedule.cpp
    engines/hugo/schedule.h



diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp
index 5843c23..c48f6db 100644
--- a/engines/hugo/schedule.cpp
+++ b/engines/hugo/schedule.cpp
@@ -707,22 +707,22 @@ void Scheduler::saveEvents(Common::WriteStream *f) {
 	f->writeSint16BE(headIndex);
 	f->writeSint16BE(tailIndex);
 
+	warning("save - %ld %ld %ld", freeIndex, headIndex, tailIndex);
+
 	// Convert event ptrs to indexes
-	event_t  saveEventArr[kMaxEvents];              // Convert event ptrs to indexes
 	for (int16 i = 0; i < kMaxEvents; i++) {
 		event_t *wrkEvent = &_events[i];
-		saveEventArr[i] = *wrkEvent;
 
- 		// fix up action pointer (to do better)
+		// fix up action pointer (to do better)
 		int16 index, subElem;
-		findAction(saveEventArr[i].action, &index, &subElem);
-		saveEventArr[i].action = (act*)((index << 16)| subElem);
-
-		saveEventArr[i].prevEvent = (wrkEvent->prevEvent == 0) ? (event_t *) - 1 : (event_t *)(wrkEvent->prevEvent - _events);
-		saveEventArr[i].nextEvent = (wrkEvent->nextEvent == 0) ? (event_t *) - 1 : (event_t *)(wrkEvent->nextEvent - _events);
+		findAction(wrkEvent[i].action, &index, &subElem);
+		f->writeSint16BE(index);
+		f->writeSint16BE(subElem);
+		f->writeByte((wrkEvent[i].localActionFl) ? 1 : 0);
+		f->writeUint32BE(wrkEvent[i].time);
+		f->writeSint16BE((wrkEvent->prevEvent == 0) ? -1 : (wrkEvent->prevEvent - _events));
+		f->writeSint16BE((wrkEvent->nextEvent == 0) ? -1 : (wrkEvent->nextEvent - _events));
 	}
-
-	f->write(saveEventArr, sizeof(saveEventArr));
 }
 
 /**
@@ -780,7 +780,7 @@ void Scheduler::saveActions(Common::WriteStream* f) const {
 * Find the index in the action list to be able to serialize the action to save game
 */
 
-void Scheduler::findAction(act* action, int16* index, int16* subElem) {
+void Scheduler::findAction(const act* action, int16* index, int16* subElem) {
 	
 	assert(index && subElem);
 	if (!action) {
@@ -837,22 +837,30 @@ void Scheduler::restoreEvents(Common::ReadStream *f) {
 	int16 freeIndex = f->readSint16BE();            // Free list index
 	int16 headIndex = f->readSint16BE();            // Head of list index
 	int16 tailIndex = f->readSint16BE();            // Tail of list index
-	f->read(savedEvents, sizeof(savedEvents));
 
 	event_t *wrkEvent;
 	// Restore events indexes to pointers
 	for (int i = 0; i < kMaxEvents; i++) {
 		wrkEvent = &savedEvents[i];
 		_events[i] = *wrkEvent;
+
+		int16 index = f->readSint16BE();
+		int16 subElem = f->readSint16BE();
+
 		// fix up action pointer (to do better)
-		int32 val = (size_t)_events[i].action;
-		if ((val & 0xffff) == 0xffff) {
+		if ((index == -1) && (subElem == -1))
 			_events[i].action = 0;
-		} else {
-			_events[i].action = (act*)&_actListArr[val >> 16][val & 0xffff];
-		}
-		_events[i].prevEvent = (wrkEvent->prevEvent == (event_t *) - 1) ? (event_t *)0 : &_events[(size_t)wrkEvent->prevEvent ];
-		_events[i].nextEvent = (wrkEvent->nextEvent == (event_t *) - 1) ? (event_t *)0 : &_events[(size_t)wrkEvent->nextEvent ];
+		else
+			_events[i].action = (act*)&_actListArr[index][subElem];
+
+		_events[i].localActionFl = (f->readByte() == 1) ? true : false; 
+		_events[i].time = f->readUint32BE();
+
+		int16 prevIndex = f->readSint16BE();
+		int16 nextIndex = f->readSint16BE();
+
+		_events[i].prevEvent = (prevIndex == -1) ? (event_t *)0 : &_events[prevIndex];
+		_events[i].nextEvent = (nextIndex == -1) ? (event_t *)0 : &_events[nextIndex];
 	}
 	_freeEvent = (freeIndex == -1) ? 0 : &_events[freeIndex];
 	_headEvent = (headIndex == -1) ? 0 : &_events[headIndex];
@@ -860,7 +868,7 @@ void Scheduler::restoreEvents(Common::ReadStream *f) {
 
 	// Adjust times to fit our time
 	uint32 curTime = getTicks();
-	wrkEvent = _headEvent;                              // The earliest event
+	wrkEvent = _headEvent;                          // The earliest event
 	while (wrkEvent) {                              // While mature events found
 		wrkEvent->time = wrkEvent->time - saveTime + curTime;
 		wrkEvent = wrkEvent->nextEvent;
diff --git a/engines/hugo/schedule.h b/engines/hugo/schedule.h
index 953e9af..a066fc6 100644
--- a/engines/hugo/schedule.h
+++ b/engines/hugo/schedule.h
@@ -583,7 +583,7 @@ protected:
 
 	void delEventType(const action_t actTypeDel);
 	void delQueue(event_t *curEvent);
-	void findAction(act* action, int16* index, int16* subElem);
+	void findAction(const act* action, int16* index, int16* subElem);
 	void insertAction(act *action);
 	void readAct(Common::ReadStream &in, act &curAct);
 	void restoreActions(Common::ReadStream *f);


Commit: 98ee6ca8bb5a6fa5050a77a86dd0a465e52bfaeb
    https://github.com/scummvm/scummvm/commit/98ee6ca8bb5a6fa5050a77a86dd0a465e52bfaeb
Author: strangerke (arnaud.boutonne at gmail.com)
Date: 2011-02-28T11:01:12-08:00

Commit Message:
HUGO: Remove forgotten debug message

Changed paths:
    engines/hugo/schedule.cpp



diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp
index c48f6db..c7d932d 100644
--- a/engines/hugo/schedule.cpp
+++ b/engines/hugo/schedule.cpp
@@ -707,8 +707,6 @@ void Scheduler::saveEvents(Common::WriteStream *f) {
 	f->writeSint16BE(headIndex);
 	f->writeSint16BE(tailIndex);
 
-	warning("save - %ld %ld %ld", freeIndex, headIndex, tailIndex);
-
 	// Convert event ptrs to indexes
 	for (int16 i = 0; i < kMaxEvents; i++) {
 		event_t *wrkEvent = &_events[i];


Commit: c4a68629a0146b2b9077f59ca247e2bc459e2d8a
    https://github.com/scummvm/scummvm/commit/c4a68629a0146b2b9077f59ca247e2bc459e2d8a
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2011-02-28T11:01:13-08:00

Commit Message:
SCI: Add FIXME comment to workaround

Changed paths:
    engines/sci/engine/script_patches.cpp



diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index a5679fa..33ec5ef 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -826,16 +826,22 @@ const uint16 qfg1vgaPatchFightEvents[] = {
 	PATCH_END
 };
 
+// FIXME:
 // When QFG1VGA and QFG3 dispose of a child window. For example, when choosing
 // a spell (parent window), if the spell can't be casted, a subsequent window
 // opens, notifying that it can't be casted. When showing the child window, the
 // scripts restore the area below the parent window, draw the child window, and
 // then attempt to redraw the parent window, which leads to the background
-// picture (which has just been restored) overwriting the child window. It
-// appers that kGraph(redrawBox) is different in QFG1VGA and QFG3. However, we
-// can just remove the window redraw and update calls when the window is
-// supposed to be disposed, and the window is disposed of correctly. Fixes bug
-// #3053093.
+// picture (which has just been restored) overwriting the child window.
+//
+// This faulty redraw is caused by a used and freed SaveBits handle that is
+// still stored in spellWin::pUnderBits being re-assigned with a SaveBits
+// call for the child window. We should ensure that invalidated SaveBits handles
+// can't (soon?) become valid again.
+//
+// However, we can just remove the window redraw and update calls when the
+// window is supposed to be disposed, and the window is disposed of correctly.
+// This is a workaround for bug #3053093.
 const byte qfg1vgaWindowDispose[] = {
 	17,
 	0x39, 0x05,       // pushi 05


Commit: 0b50322cf5b5cea75d124b5c2a0fceeb533005b7
    https://github.com/scummvm/scummvm/commit/0b50322cf5b5cea75d124b5c2a0fceeb533005b7
Author: md5 (md5 at scummvm.org)
Date: 2011-02-28T11:01:13-08:00

Commit Message:
SCI: Moved hunk pointer handling to the GC, and removed some related workarounds

SCI scripts can contain stale pointers, which are used later on. We now delete
the contents of hunk entries without invalidating the relevant pointers and let
the GC clear the references. Many thanks to waltervn and wjp for all their work
and help on this.

Changed paths:
    engines/sci/engine/gc.cpp
    engines/sci/engine/script_patches.cpp
    engines/sci/engine/seg_manager.cpp
    engines/sci/engine/segment.cpp
    engines/sci/engine/segment.h
    engines/sci/engine/workarounds.cpp
    engines/sci/graphics/paint16.cpp
    engines/sci/graphics/ports.h



diff --git a/engines/sci/engine/gc.cpp b/engines/sci/engine/gc.cpp
index 7692613..e080ad6 100644
--- a/engines/sci/engine/gc.cpp
+++ b/engines/sci/engine/gc.cpp
@@ -25,6 +25,7 @@
 
 #include "sci/engine/gc.h"
 #include "common/array.h"
+#include "sci/graphics/ports.h"
 
 namespace Sci {
 
@@ -84,6 +85,18 @@ static void processWorkList(SegManager *segMan, WorklistManager &wm, const Commo
 	}
 }
 
+static void processEngineHunkList(WorklistManager &wm) {
+	PortList windowList = g_sci->_gfxPorts->_windowList;
+
+	for (PortList::const_iterator it = windowList.begin(); it != windowList.end(); ++it) {
+		// FIXME: We also store Port objects in the window list.
+		// We should add a check that we really only pass windows here...
+		Window *wnd = ((Window *)*it);
+		wm.push(wnd->hSaved1);
+		wm.push(wnd->hSaved2);
+	}
+}
+
 AddrSet *findAllActiveReferences(EngineState *s) {
 	assert(!s->_executionStack.empty());
 
@@ -142,6 +155,7 @@ AddrSet *findAllActiveReferences(EngineState *s) {
 	debugC(kDebugLevelGC, "[GC] -- Finished explicitly loaded scripts, done with root set");
 
 	processWorkList(s->_segMan, wm, heap);
+	processEngineHunkList(wm);
 
 	return normalizeAddresses(s->_segMan, wm._map);
 }
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 33ec5ef..7431707 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -60,55 +60,6 @@ struct SciScriptSignature {
 //  - if not EOS, an adjust offset and the actual bytes
 //  - rinse and repeat
 
-#if 0
-
-// ===========================================================================
-// Castle of Dr. Brain
-// cipher::init (script 391) is called on room 380 init. This resets the word
-//  cipher puzzle. The puzzle sadly operates on some hep strings, which aren't
-//  saved in our sci. So saving/restoring in this room will break the puzzle
-//  Because of this issue, we just init the puzzle each time it's accessed.
-//  this is not 100% sierra behaviour, in fact we will actually reset the puzzle
-//  during each access which makes it impossible to cheat.
-const byte castlebrainSignatureCipherPuzzle[] = {
-	22,
-	0x35, 0x00,        // ldi 00
-	0xa3, 0x26,        // sal local[26]
-	0xa3, 0x25,        // sal local[25]
-	0x35, 0x00,        // ldi 00
-	0xa3, 0x2a,        // sal local[2a] (local is not used)
-	0xa3, 0x29,        // sal local[29] (local is not used)
-	0x35, 0xff,        // ldi ff
-	0xa3, 0x2c,        // sal local[2c]
-	0xa3, 0x2b,        // sal local[2b]
-	0x35, 0x00,        // ldi 00
-	0x65, 0x16,        // aTop highlightedIcon
-	0
-};
-
-const uint16 castlebrainPatchCipherPuzzle[] = {
-	0x39, 0x6b,        // pushi 6b (selector init)
-	0x76,              // push0
-	0x55, 0x04,        // self 04
-	0x35, 0x00,        // ldi 00
-	0xa3, 0x25,        // sal local[25]
-	0xa3, 0x26,        // sal local[26]
-	0xa3, 0x29,        // sal local[29]
-	0x65, 0x16,        // aTop highlightedIcon
-	0x34, 0xff, 0xff,  // ldi ffff
-	0xa3, 0x2b,        // sal local[2b]
-	0xa3, 0x2c,        // sal local[2c]
-	PATCH_END
-};
-
-//    script, description,                                      magic DWORD,                             adjust
-const SciScriptSignature castlebrainSignatures[] = {
-	{    391, "cipher puzzle save/restore break",            1, PATCH_MAGICDWORD(0xa3, 0x26, 0xa3, 0x25),    -2, castlebrainSignatureCipherPuzzle, castlebrainPatchCipherPuzzle },
-	SCI_SIGNATUREENTRY_TERMINATOR
-};
-
-#endif
-
 // ===========================================================================
 // stayAndHelp::changeState (0) is called when ego swims to the left or right
 //  boundaries of room 660. Normally a textbox is supposed to get on screen
@@ -497,74 +448,6 @@ const SciScriptSignature gk1Signatures[] = {
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
-#if 0
-
-// ===========================================================================
-// this here gets called on entry and when going out of game windows
-//  uEvt::port will not get changed after kDisposeWindow but a bit later, so
-//  we would get an invalid port handle to a kSetPort call. We just patch in
-//  resetting of the port selector. We destroy the stop/fade code in there,
-//  it seems it isn't used at all in the game.
-const byte hoyle4SignaturePortFix[] = {
-	28,
-	0x39, 0x09,        // pushi 09
-	0x89, 0x0b,        // lsg 0b
-	0x39, 0x64,        // pushi 64
-	0x38, 0xc8, 0x00,  // pushi 00c8
-	0x38, 0x2c, 0x01,  // pushi 012c
-	0x38, 0x90, 0x01,  // pushi 0190
-	0x38, 0xf4, 0x01,  // pushi 01f4
-	0x38, 0x58, 0x02,  // pushi 0258
-	0x38, 0xbc, 0x02,  // pushi 02bc
-	0x38, 0x20, 0x03,  // pushi 0320
-	0x46,              // calle [xxxx] [xxxx] [xx]
-	+5, 43,            // [skip 5 bytes]
-	0x30, 0x27, 0x00,  // bnt 0027 -> end of routine
-	0x87, 0x00,        // lap 00
-	0x30, 0x19, 0x00,  // bnt 0019 -> fade out
-	0x87, 0x01,        // lap 01
-	0x30, 0x14, 0x00,  // bnt 0014 -> fade out
-	0x38, 0xa7, 0x00,  // pushi 00a7
-	0x76,              // push0
-	0x80, 0x29, 0x01,  // lag 0129
-	0x4a, 0x04,        // send 04 - call song::stop
-	0x39, 0x27,        // pushi 27
-	0x78,              // push1
-	0x8f, 0x01,        // lsp 01
-	0x51, 0x54,        // class 54
-	0x4a, 0x06,        // send 06 - call PlaySong::play
-	0x33, 0x09,        // jmp 09 -> end of routine
-	0x38, 0xaa, 0x00,  // pushi 00aa
-	0x76,              // push0
-	0x80, 0x29, 0x01,  // lag 0129
-	0x4a, 0x04,        // send 04
-	0x48,              // ret
-	0
-};
-
-const uint16 hoyle4PatchPortFix[] = {
-	PATCH_ADDTOOFFSET | +33,
-	0x38, 0x31, 0x01,  // pushi 0131 (selector curEvent)
-	0x76,              // push0
-	0x80, 0x50, 0x00,  // lag 0050 (global var 80h, "User")
-	0x4a, 0x04,        // send 04 - read User::curEvent
-
-	0x38, 0x93, 0x00,  // pushi 0093 (selector port)
-	0x78,              // push1
-	0x76,              // push0
-	0x4a, 0x06,        // send 06 - write 0 to that object::port
-	0x48,              // ret
-	PATCH_END
-};
-
-//    script, description,                                   magic DWORD,                                 adjust
-const SciScriptSignature hoyle4Signatures[] = {
-    {      0, "port fix when disposing windows",             PATCH_MAGICDWORD(0x64, 0x38, 0xC8, 0x00),    -5, hoyle4SignaturePortFix,   hoyle4PatchPortFix },
-    {      0, NULL,                                          0,                                            0, NULL,                     NULL }
-};
-
-#endif
-
 // ===========================================================================
 // at least during harpy scene export 29 of script 0 is called in kq5cd and
 //  has an issue for those calls, where temp 3 won't get inititialized, but
@@ -826,50 +709,10 @@ const uint16 qfg1vgaPatchFightEvents[] = {
 	PATCH_END
 };
 
-// FIXME:
-// When QFG1VGA and QFG3 dispose of a child window. For example, when choosing
-// a spell (parent window), if the spell can't be casted, a subsequent window
-// opens, notifying that it can't be casted. When showing the child window, the
-// scripts restore the area below the parent window, draw the child window, and
-// then attempt to redraw the parent window, which leads to the background
-// picture (which has just been restored) overwriting the child window.
-//
-// This faulty redraw is caused by a used and freed SaveBits handle that is
-// still stored in spellWin::pUnderBits being re-assigned with a SaveBits
-// call for the child window. We should ensure that invalidated SaveBits handles
-// can't (soon?) become valid again.
-//
-// However, we can just remove the window redraw and update calls when the
-// window is supposed to be disposed, and the window is disposed of correctly.
-// This is a workaround for bug #3053093.
-const byte qfg1vgaWindowDispose[] = {
-	17,
-	0x39, 0x05,       // pushi 05
-	0x39, 0x0d,       // pushi 0d
-	0x67, 0x2e,       // pTos 2e
-	0x67, 0x30,       // pTos 30
-	0x67, 0x32,       // pTos 32
-	0x67, 0x34,       // pTos 34
-	0x43, 0x6c, 0x0a, // callk kGraph 10
-	0x39, 0x06,       // pushi 06
-	0
-};
-
-const uint16 qfg1vgaPatchWindowDispose[] = {
-	0x34, 0x00, 0x00, // ldi 0000 (dummy)
-	0x34, 0x00, 0x00, // ldi 0000 (dummy)
-	0x34, 0x00, 0x00, // ldi 0000 (dummy)
-	0x34, 0x00, 0x00, // ldi 0000 (dummy)
-	0x34, 0x00, 0x00, // ldi 0000 (dummy)
-	0x33, 0x3e,       // jmp 0x3e (skip 62 bytes - this skips the subsequent 2 kGraph(update) calls, before kDisposeWindow is invoked)
-	PATCH_END
-};
-
 //    script, description,                                      magic DWORD,                                  adjust
 const SciScriptSignature qfg1vgaSignatures[] = {
 	{    215, "fight event issue",                           1, PATCH_MAGICDWORD(0x6d, 0x76, 0x51, 0x07),    -1, qfg1vgaSignatureFightEvents,       qfg1vgaPatchFightEvents },
 	{    216, "weapon master event issue",                   1, PATCH_MAGICDWORD(0x6d, 0x76, 0x51, 0x07),    -1, qfg1vgaSignatureFightEvents,       qfg1vgaPatchFightEvents },
-	{    559, "window dispose",                              1, PATCH_MAGICDWORD(0x39, 0x05, 0x39, 0x0d),     0,        qfg1vgaWindowDispose,     qfg1vgaPatchWindowDispose },
 	SCI_SIGNATUREENTRY_TERMINATOR
 };
 
@@ -933,37 +776,6 @@ const uint16 qfg3PatchImportDialog[] = {
 	PATCH_END
 };
 
-// When QFG1VGA and QFG3 dispose of a child window. For example, when choosing
-// a spell (parent window), if the spell can't be casted, a subsequent window
-// opens, notifying that it can't be casted. When showing the child window, the
-// scripts restore the area below the parent window, draw the child window, and
-// then attempt to redraw the parent window, which leads to the background
-// picture (which has just been restored) overwriting the child window. It
-// appers that kGraph(redrawBox) is different in QFG1VGA and QFG3. However, we
-// can just remove the window redraw and update calls when the window is
-// supposed to be disposed, and the window is disposed of correctly. Fixes bug
-// #3053093.
-const byte qfg3WindowDispose[] = {
-	15,
-	0x39, 0x05,       // pushi 05
-	0x39, 0x0d,       // pushi 0d
-	0x67, 0x2e,       // pTos 2e
-	0x67, 0x30,       // pTos 30
-	0x67, 0x32,       // pTos 32
-	0x67, 0x34,       // pTos 34
-	0x43, 0x6c, 0x0a, // callk kGraph 10
-	0
-};
-
-const uint16 qfg3PatchWindowDispose[] = {
-	0x34, 0x00, 0x00, // ldi 0000 (dummy)
-	0x34, 0x00, 0x00, // ldi 0000 (dummy)
-	0x34, 0x00, 0x00, // ldi 0000 (dummy)
-	0x34, 0x00, 0x00, // ldi 0000 (dummy)
-	0x34, 0x00, 0x00, // ldi 0000 (dummy)
-	PATCH_END
-};
-
 // Script 23 in QFG3 has a typo/bug which makes it loop endlessly and
 // read garbage. Fixes bug #3040722.
 const byte qfg3DialogCrash[] = {
@@ -982,7 +794,6 @@ const uint16 qfg3PatchDialogCrash[] = {
 
 //    script, description,                                      magic DWORD,                                  adjust
 const SciScriptSignature qfg3Signatures[] = {
-	{     22, "window dispose",                                 1, PATCH_MAGICDWORD(0x39, 0x05, 0x39, 0x0d),   0,         qfg3WindowDispose,        qfg3PatchWindowDispose },
 	{     23, "dialog crash",                                   1, PATCH_MAGICDWORD(0xe7, 0x03, 0x22, 0x33),  -1,           qfg3DialogCrash,          qfg3PatchDialogCrash },
 	{    944, "import dialog continuous calls",                 1, PATCH_MAGICDWORD(0x2a, 0x31, 0x0b, 0x7a),  -1, qfg3SignatureImportDialog,         qfg3PatchImportDialog },
 	SCI_SIGNATUREENTRY_TERMINATOR
@@ -1242,12 +1053,6 @@ int32 Script::findSignature(const SciScriptSignature *signature, const byte *scr
 void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uint32 scriptSize) {
 	const SciScriptSignature *signatureTable = NULL;
 	switch (g_sci->getGameId()) {
-	// Dr. Brain now works because we properly maintain the state of the string heap in savegames
-#if 0
-	case GID_CASTLEBRAIN:
-		signatureTable = castlebrainSignatures;
-		break;
-#endif
 	case GID_ECOQUEST:
 		signatureTable = ecoquest1Signatures;
 		break;
@@ -1263,12 +1068,6 @@ void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uin
 	case GID_GK1:
 		signatureTable = gk1Signatures;
 		break;
-	// hoyle4 now works due to workaround inside GfxPorts
-#if 0
-	case GID_HOYLE4:
-		signatureTable = hoyle4Signatures;
-		break;
-#endif
 	case GID_KQ5:
 		signatureTable = kq5Signatures;
 		break;
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index ffc81f0..f77bdf6 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -403,7 +403,7 @@ void SegManager::freeHunkEntry(reg_t addr) {
 		return;
 	}
 
-	ht->freeEntry(addr.offset);
+	ht->freeEntryContents(addr.offset);
 }
 
 reg_t SegManager::allocateHunkEntry(const char *hunk_type, int size) {
diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp
index 05d914c..d1f56f0 100644
--- a/engines/sci/engine/segment.cpp
+++ b/engines/sci/engine/segment.cpp
@@ -275,6 +275,11 @@ Common::Array<reg_t> DataStack::listAllOutgoingReferences(reg_t object) const {
 }
 
 
+//-------------------- hunk ---------------------
+void HunkTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) {
+	freeEntry(sub_addr.offset);
+}
+
 //-------------------- lists --------------------
 void ListTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) {
 	freeEntry(sub_addr.offset);
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index 9aaa3a4..56a6c71 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -315,15 +315,18 @@ struct ListTable : public Table<List> {
 struct HunkTable : public Table<Hunk> {
 	HunkTable() : Table<Hunk>(SEG_TYPE_HUNK) {}
 
-	virtual void freeEntry(int idx) {
-		Table<Hunk>::freeEntry(idx);
-
-		if (!_table[idx].mem)
-			warning("Attempt to free an already freed hunk");
+	void freeEntryContents(int idx) {
 		free(_table[idx].mem);
 		_table[idx].mem = 0;
 	}
 
+	virtual void freeEntry(int idx) {
+		Table<Hunk>::freeEntry(idx);
+		freeEntryContents(idx);
+	}
+
+	virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr);
+
 	virtual void saveLoadWithSerializer(Common::Serializer &ser);
 };
 
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index d99f8ce..639fd9b 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -387,10 +387,7 @@ const SciWorkaroundEntry kStrLen_workarounds[] = {
 
 //    gameID,           room,script,lvl,          object-name, method-name,    call,index,                workaround
 const SciWorkaroundEntry kUnLoad_workarounds[] = {
-	{ GID_CAMELOT,       921,   921,  1,             "Script", "changeState",  0x36,    0, { WORKAROUND_IGNORE, 0 } }, // DEMO: While showing Camelot (and other places), the reference is invalid - bug #3035000
-	{ GID_CAMELOT,       921,   921,  1,             "Script", "init",         0x36,    0, { WORKAROUND_IGNORE, 0 } }, // DEMO: When being attacked by the boar (and other places), the reference is invalid - bug #3035000
-	{ GID_CASTLEBRAIN,   320,   377,  0,              "SWord", "upDate",         -1,    0, { WORKAROUND_IGNORE, 0 } }, // after solving the cross-word-puzzle, trying to unload invalid reference
-	{ GID_CASTLEBRAIN,   320,   377,  0,            "theWord", "show",           -1,    0, { WORKAROUND_IGNORE, 0 } }, // 2nd word puzzle, when exiting before solving, trying to unload invalid reference - bug #3034473
+	// TODO: Some of these workarounds for invalid references can now be removed, test which ones
 	{ GID_ECOQUEST,      380,    61,  0,              "gotIt", "changeState",    -1,    0, { WORKAROUND_IGNORE, 0 } }, // after talking to the dolphin the first time
 	{ GID_ECOQUEST,      380,    69,  0,   "lookAtBlackBoard", "changeState",    -1,    0, { WORKAROUND_IGNORE, 0 } }, // German version, when closing the blackboard closeup in the dolphin room - bug #3098353
 	{ GID_LAURABOW2,       1,     1,  0,           "sCartoon", "changeState",    -1,    0, { WORKAROUND_IGNORE, 0 } }, // DEMO: during the intro, a 3rd parameter is passed by accident - bug #3034902
@@ -401,7 +398,6 @@ const SciWorkaroundEntry kUnLoad_workarounds[] = {
 	{ GID_LSL6,          130,   130,  0,    "recruitLarryScr", "changeState",    -1,    0, { WORKAROUND_IGNORE, 0 } }, // during intro, a 3rd parameter is passed by accident
 	{ GID_LSL6,          740,   740,  0,        "showCartoon", "changeState",    -1,    0, { WORKAROUND_IGNORE, 0 } }, // during ending, 4 additional parameters are passed by accident
 	{ GID_LSL6HIRES,     130,   130,  0,    "recruitLarryScr", "changeState",    -1,    0, { WORKAROUND_IGNORE, 0 } }, // during intro, a 3rd parameter is passed by accident
-	{ GID_PQ3,           877,   998,  0,               "View", "delete",         -1,    0, { WORKAROUND_IGNORE, 0 } }, // when getting run over on the freeway, the reference is invalid
 	{ GID_SQ1,            43,   303,  0,            "slotGuy", "dispose",        -1,    0, { WORKAROUND_IGNORE, 0 } }, // when leaving ulence flats bar, parameter 1 is not passed - script error
 	{ GID_SQ3,             2,   998,  0,               "View", "delete",         -1,    0, { WORKAROUND_IGNORE, 0 } }, // clicking the mouse button during the intro, after the escape pod gets pulled into the garbage freighter, the reference is invalid - bug #3050856
 	SCI_WORKAROUNDENTRY_TERMINATOR
diff --git a/engines/sci/graphics/paint16.cpp b/engines/sci/graphics/paint16.cpp
index 935dd4e..53c43d9 100644
--- a/engines/sci/graphics/paint16.cpp
+++ b/engines/sci/graphics/paint16.cpp
@@ -360,7 +360,7 @@ void GfxPaint16::bitsRestore(reg_t memoryHandle) {
 
 		if (memoryPtr) {
 			_screen->bitsRestore(memoryPtr);
-			_segMan->freeHunkEntry(memoryHandle);
+			bitsFree(memoryHandle);
 		}
 	}
 }
@@ -532,20 +532,7 @@ reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) {
 		case SCI_DISPLAY_RESTOREUNDER:
 			bitsGetRect(argv[0], &rect);
 			rect.translate(-_ports->getPort()->left, -_ports->getPort()->top);
-			if (g_sci->getGameId() == GID_PQ3 && g_sci->getEngineState()->currentRoomNumber() == 29) {
-				// WORKAROUND: PQ3 calls this without calling the associated
-				// kDisplay(SCI_DISPLAY_SAVEUNDER) call before. Theoretically,
-				// this would result in no rect getting restored. However, we
-				// still maintain a pointer from the previous room, resulting
-				// in invalidated content being restored on screen, and causing
-				// graphics glitches. Thus, we simply don't restore a rect in
-				// that room. The correct fix for this would be to erase hunk
-				// pointers when changing rooms, but this will suffice for now,
-				// as restoring from a totally invalid pointer is very rare.
-				// Fixes bug #3037945.
-			} else {
-				bitsRestore(argv[0]);
-			}
+			bitsRestore(argv[0]);
 			kernelGraphRedrawBox(rect);
 			// finishing loop
 			argc = 0;
diff --git a/engines/sci/graphics/ports.h b/engines/sci/graphics/ports.h
index 21c6d31..b94d54a 100644
--- a/engines/sci/graphics/ports.h
+++ b/engines/sci/graphics/ports.h
@@ -49,6 +49,9 @@ enum {
 	SCI_WINDOWMGR_STYLE_USER        = (1 << 7)
 };
 
+typedef Common::List<Port *> PortList;
+typedef Common::Array<Port *> PortArray;
+
 /**
  * Ports class, includes all port managment for SCI0->SCI1.1 games. Ports are some sort of windows in SCI
  *  this class also handles adjusting coordinates to a specific port
@@ -115,8 +118,12 @@ public:
 
 	virtual void saveLoadWithSerializer(Common::Serializer &ser);
 
+	/** The list of open 'windows' (and ports), in visual order. */
+	PortList _windowList;
+
 private:
-	typedef Common::List<Port *> PortList;
+	/** The list of all open 'windows' (and ports), ordered by their id. */
+	PortArray _windowsById;
 
 	SegManager *_segMan;
 	GfxPaint16 *_paint16;
@@ -130,12 +137,6 @@ private:
 	// counts windows that got disposed but are not freed yet
 	uint16 _freeCounter;
 
-	/** The list of open 'windows' (and ports), in visual order. */
-	PortList _windowList;
-
-	/** The list of all open 'windows' (and ports), ordered by their id. */
-	Common::Array<Port *> _windowsById;
-
 	Common::Rect _bounds;
 
 	// Priority Bands related variables


Commit: acbdee55c9b467cbce8587dc8497ac1745ad9a4d
    https://github.com/scummvm/scummvm/commit/acbdee55c9b467cbce8587dc8497ac1745ad9a4d
Author: Fabio Battaglia (hkzlabnet at gmail.com)
Date: 2011-02-28T11:01:13-08:00

Commit Message:
SWORD2: Plug a memory leak in psx version

Free buffer used to resize psx sprite in drawTextObject

Changed paths:
    engines/sword2/animation.cpp



diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp
index 2fafb70..e75e38a 100644
--- a/engines/sword2/animation.cpp
+++ b/engines/sword2/animation.cpp
@@ -237,6 +237,10 @@ void MoviePlayer::drawTextObject(uint32 index, byte *screen, uint16 pitch) {
 			src += width;
 			dst += pitch;
 		}
+
+		// Free buffer used to resize psx sprite
+		if (Sword2Engine::isPsx())
+			free(src);
 	}
 }
 


Commit: ea33190de188ae71f7a55979f58b964abbc25e86
    https://github.com/scummvm/scummvm/commit/ea33190de188ae71f7a55979f58b964abbc25e86
Author: Fabio Battaglia (hkzlabnet at gmail.com)
Date: 2011-02-28T11:01:13-08:00

Commit Message:
SWORD2: fix leak of previous commit properly

Memorize psx sprite buffer pointer to properly free it

Changed paths:
    engines/sword2/animation.cpp



diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp
index e75e38a..c47b73e 100644
--- a/engines/sword2/animation.cpp
+++ b/engines/sword2/animation.cpp
@@ -218,11 +218,12 @@ void MoviePlayer::drawTextObject(uint32 index, byte *screen, uint16 pitch) {
 		uint16 height = text->_textSprite.h;
 
 		// Resize text sprites for PSX version
+		byte *psxSpriteBuffer;
 		if (Sword2Engine::isPsx()) {
 			height *= 2;
-			byte *buffer = (byte *)malloc(width * height);
-			Screen::resizePsxSprite(buffer, src, width, height);
-			src = buffer;
+			psxSpriteBuffer = (byte *)malloc(width * height);
+			Screen::resizePsxSprite(psxSpriteBuffer, src, width, height);
+			src = psxSpriteBuffer;
 		}
 
 		byte *dst = screen + _textY * pitch + _textX;
@@ -240,7 +241,7 @@ void MoviePlayer::drawTextObject(uint32 index, byte *screen, uint16 pitch) {
 
 		// Free buffer used to resize psx sprite
 		if (Sword2Engine::isPsx())
-			free(src);
+			free(psxSpriteBuffer);
 	}
 }
 


Commit: 0f7dcac15591c4ea3def6ff16bb8cf0d6321809c
    https://github.com/scummvm/scummvm/commit/0f7dcac15591c4ea3def6ff16bb8cf0d6321809c
Author: Lars Skovlund (lskovlun at sprogklog.dk)
Date: 2011-02-28T11:41:39-08:00

Commit Message:
Merge branch 'master' of github.com:scummvm/scummvm

Changed paths:









More information about the Scummvm-git-logs mailing list