[Scummvm-git-logs] scummvm master -> b928f84e19fbdb5b0785df77f03a7b6447754a7e

mduggan noreply at scummvm.org
Fri Oct 4 10:04:28 UTC 2024


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

Summary:
87418c61f2 DGDS: Fix sound and scrolling partly in Willy Beamish intro
d26ee617d4 DGDS: Run scene ops to completion after scene change
cf9bde35b6 DGDS: Better message for 'missing' beamish sound data
b928f84e19 DGDS: Drop missing global back to warning


Commit: 87418c61f2416a26b7a440ca17e34719bdece3f5
    https://github.com/scummvm/scummvm/commit/87418c61f2416a26b7a440ca17e34719bdece3f5
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-10-04T15:54:32+10:00

Commit Message:
DGDS: Fix sound and scrolling partly in Willy Beamish intro

Changed paths:
    engines/dgds/sound.cpp
    engines/dgds/sound.h
    engines/dgds/ttm.cpp


diff --git a/engines/dgds/sound.cpp b/engines/dgds/sound.cpp
index 5fade1d0747..41987bb2e5e 100644
--- a/engines/dgds/sound.cpp
+++ b/engines/dgds/sound.cpp
@@ -276,10 +276,11 @@ void Sound::loadMacMusic(const Common::String &filename) {
 			uint16 type = stream->readUint16LE();
 			uint16 count = stream->readUint16LE();
 
-			debug("        %u [%u]:", type, count);
+			debug("  SX INF %u [%u]:  (%s)", type, count, filename.c_str());
 			for (uint16 k = 0; k < count; k++) {
 				uint16 idx = stream->readUint16LE();
 				debug("        %2u: %u", k, idx);
+				_musicIdMap[idx] = k;
 			}
 		} else if (chunk.isSection(ID_TAG) || chunk.isSection(ID_FNM)) {
 			_readStrings(stream);
@@ -336,7 +337,7 @@ void Sound::loadPCSound(const Common::String &filename, Common::Array<uint32> &s
 			dataArray.push_back(data);
 		} else if (chunk.isSection(ID_INF)) {
 			uint32 count = stream->size() / 2;
-			debug("        [%u]", count);
+			debug("  SNG INF [%u]", count);
 			for (uint32 k = 0; k < count; k++) {
 				uint16 idx = stream->readUint16LE();
 				debug("        %2u: %u", k, idx);
@@ -352,11 +353,18 @@ void Sound::playSFX(uint num) {
 	playPCSound(num, _sfxSizes, _sfxData, _midiSoundPlayer);
 }
 
+void Sound::stopSfxByNum(uint num) {
+	warning("TODO: Implement me! Sound::stopSfxById(%d)", num);
+}
+
 void Sound::playMusic(uint num) {
 	playPCSound(num, _musicSizes, _musicData, _midiMusicPlayer);
 }
 
 void Sound::playPCSound(uint num, const Common::Array<uint32> &sizeArray, const Common::Array<byte *> &dataArray, DgdsMidiPlayer *midiPlayer) {
+	if (_musicIdMap.size()) {
+		num = _musicIdMap[num];
+	}
 	if (num < dataArray.size()) {
 		uint32 tracks = _availableSndTracks(dataArray[num], sizeArray[num]);
 		if (midiPlayer && (tracks & TRACK_MT32))
diff --git a/engines/dgds/sound.h b/engines/dgds/sound.h
index a6aa2bf2b95..07993296d33 100644
--- a/engines/dgds/sound.h
+++ b/engines/dgds/sound.h
@@ -55,6 +55,7 @@ public:
 	void playSFX(uint num);
 
 	void stopSfx(byte channel);
+	void stopSfxByNum(uint num);
 	void stopAllSfx();
 
 	bool playPCM(const byte *data, uint32 size);
@@ -70,10 +71,12 @@ private:
 
 	Common::Array<uint32> _musicSizes;
 	Common::Array<byte *> _musicData;
+	Common::HashMap<uint16, uint16> _musicIdMap;
 
 	Common::Array<uint32> _sfxSizes;
 	Common::Array<byte *> _sfxData;
 
+
 	Audio::Mixer *_mixer;
 	DgdsMidiPlayer *_midiMusicPlayer;
 	DgdsMidiPlayer *_midiSoundPlayer;
diff --git a/engines/dgds/ttm.cpp b/engines/dgds/ttm.cpp
index 9c3625dc0dc..7cd928421ff 100644
--- a/engines/dgds/ttm.cpp
+++ b/engines/dgds/ttm.cpp
@@ -139,10 +139,14 @@ static const char *ttmOpName(uint16 op) {
 	case 0x0080: return "FREE SHAPE";
 	case 0x0090: return "FREE FONT";
 	case 0x00B0: return "NULLOP";
+	case 0x00C0: return "FREE BACKGROUND";
 	case 0x0110: return "PURGE";
-	case 0x0400: return "PALETTE RESET ?";
-	case 0x0500: return "UNKNOWN 0x0500 (flip mode ?)";
-	case 0x0510: return "UNKNOWN 0x0510 (flip mode off?)";
+	case 0x0210: return "song something?";
+	case 0x0220: return "STOP CURRENT MUSIC";
+	case 0x0230: return "FADE CURRENT MUSIC";
+	case 0x0400: return "PALETTE RESET / STOP PAL BLOCK SWAP";
+	case 0x0500: return "UNKNOWN 0x0500 (flip mode ON?)";
+	case 0x0510: return "UNKNOWN 0x0510 (flip mode OFF?)";
 	case 0x0ff0: return "FINISH FRAME / DRAW";
 	case 0x1020: return "SET DELAY";
 	case 0x1030: return "SET BRUSH";
@@ -156,6 +160,7 @@ static const char *ttmOpName(uint16 op) {
 	case 0x1120: return "SET GETPUT NUM";
 	case 0x1200: return "GOTO";
 	case 0x1300: return "PLAY SFX";
+	case 0x1310: return "STOP SFX";
 	case 0x2000: return "SET DRAW COLORS";
 	case 0x2010: return "SET FRAME";
 	case 0x2020: return "SET RANDOM DELAY";
@@ -165,7 +170,7 @@ static const char *ttmOpName(uint16 op) {
 	case 0x2320: return "PAL SET BLOCK SWAP 2";
 	case 0x2400: return "PAL DO BLOCK SWAP";
 	case 0x3000: return "GOSUB";
-	case 0x3100: return "SCROLL 3100??";
+	case 0x3100: return "SCROLL";
 	case 0x4000: return "SET CLIP WINDOW";
 	case 0x4110: return "FADE OUT";
 	case 0x4120: return "FADE IN";
@@ -227,11 +232,6 @@ static const char *ttmOpName(uint16 op) {
 	case 0xf170: return "SET STRING 7";
 	case 0xf180: return "SET STRING 8";
 	case 0xf190: return "SET STRING 9";
-	case 0x0220: return "STOP CURRENT MUSIC";
-
-	case 0x00C0: return "FREE BACKGROUND";
-	case 0x0230: return "reset current music?";
-	case 0x1310: return "STOP SFX";
 
 	case 0xc020: return "LOAD SAMPLE";
 	case 0xc030: return "SELECT SAMPLE";
@@ -314,6 +314,56 @@ static void _dissolveToScreen(const Graphics::ManagedSurface &src, const Common:
 	g_system->unlockScreen();
 }
 
+static void _doScroll(Graphics::ManagedSurface &compBuf, int16 dir, int16 steps, int16 offset) {
+	// Scroll the contents of the composition buffer on to the screen
+	// Dir 0/1 means y (scroll toward bottom / top)
+	// Dir 2 means x (scroll toward right)
+	//
+	// This is not at all how the original does it, but we have a bit
+	// more memory and cpu to play with so an extra 64k screen buffer
+	// and more copies is ok for simpler code.
+	//
+	Graphics::Surface *screen = g_system->lockScreen();
+	Graphics::Surface screenCopy;
+
+	screenCopy.copyFrom(*screen);
+	steps = CLIP(steps, (int16)1, offset);
+	const Common::Rect screenRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+	for (int16 i = 1; i <= steps; i++) {
+		int stepval = ((int)i * offset) / steps;
+		int xoff = (dir == 2 ? stepval : 0);
+		int yoff = (dir == 2 ? 0 : (dir == 1 ? stepval : -stepval));
+		Common::Rect srcRectFromOrigScreen(Common::Point(xoff, yoff), SCREEN_WIDTH, SCREEN_HEIGHT);
+		srcRectFromOrigScreen.clip(screenRect);
+		screen->copyRectToSurface(screenCopy, MAX(0, -xoff), MAX(0, -yoff), srcRectFromOrigScreen);
+
+		switch (dir) {
+		case 0: {
+			// Draw composition buf to the top of screen buf
+			error("TODO: Implement TTM scroll direction 0");
+			break;
+		}
+		case 1: {
+			// Draw composition buf below the screen buf
+			error("TODO: Implement TTM scroll direction 1");
+			break;
+		}
+		case 2: {
+			// Draw composition buf to right of screen buf
+			Common::Rect rectFromCompBuf(0, 0, SCREEN_WIDTH - srcRectFromOrigScreen.width(), SCREEN_HEIGHT);
+			screen->copyRectToSurface(compBuf, srcRectFromOrigScreen.width(), 0, rectFromCompBuf);
+			break;
+		}
+		default:
+			error("TTM scroll invalid scroll direction: %d", dir);
+			break;
+		}
+		g_system->unlockScreen();
+		g_system->updateScreen();
+		screen = g_system->lockScreen();
+	}
+	g_system->unlockScreen();
+}
 
 void TTMInterpreter::doWipeOp(uint16 code, TTMEnviro &env, TTMSeq &seq, const Common::Rect &r) {
 	//
@@ -331,7 +381,6 @@ void TTMInterpreter::doWipeOp(uint16 code, TTMEnviro &env, TTMSeq &seq, const Co
 	//
 	switch(code) {
 	case 0xa010:
-		warning("TODO: Implement TTM 0xa010 wipe (dissolve) op");
 		_dissolveToScreen(_vm->_compositionBuffer, r);
 		break;
 
@@ -571,7 +620,7 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
 	case 0x0400: // RESET PALETTE?
 		if (seq._executed) // this is a one-shot op
 			break;
-		warning("TODO: 0x0400 Reset palette");
+		warning("TODO: 0x0400 Reset palette / stop pal cycle");
 		break;
 	case 0x0500: // FLIP MODE ON
 		DgdsEngine::getInstance()->setFlipMode(true);
@@ -626,9 +675,7 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
 	case 0x1310: // STOP SFX    i:int   eg [107]
 		if (seq._executed) // this is a one-shot op.
 			break;
-		warning("TODO: Implement TTM 0x1310 stop SFX %d", ivals[0]);
-		// Implement this:
-		//_vm->_soundPlayer->stopSfxById(ivals[0])
+		_vm->_soundPlayer->stopSfxByNum(ivals[0]);
 		break;
 	case 0x2000: // SET (DRAW) COLORS: fgcol,bgcol:int [0..255]
 		seq._drawColFG = static_cast<byte>(ivals[0]);
@@ -678,7 +725,7 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
 			break;
 		warning("TODO: 0x%04x Palette do block swaps 0x%x, 0x%x", op, ivals[0], ivals[1]);
 		break;
-	case 0x3000: { // GOSUB ??,??,frame
+	case 0x3000: { // GOSUB xoff,yoff,frame
 		_stackDepth++;
 		bool prevHitOp0110Val = _vm->adsInterpreter()->getHitTTMOp0110();
 		int32 target = findGOTOTarget(env, seq, ivals[2]);
@@ -699,10 +746,16 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
 		_stackDepth--;
 		break;
 	}
-	case 0x3100: { // SCROLL ??,??,??
+	case 0x3100: { // SCROLL dir,steps,distance eg (2, 100, 185) in beamish intro
 		if (seq._executed) // this is a one-shot op.
 			break;
-		warning("TODO: TTM 0x3100 SCROLL %d %d %d", ivals[0], ivals[1], ivals[2]);
+		_doScroll(_vm->_compositionBuffer, ivals[0], ivals[1], ivals[2]);
+		// After scroll, we need to store the screen contents into the
+		// stored area buffer, and copy the background to the front?
+		Graphics::Surface *screen = g_system->lockScreen();
+		_vm->getStoredAreaBuffer().blitFrom(*screen);
+		g_system->unlockScreen();
+		_vm->_compositionBuffer.blitFrom(_vm->getBackgroundBuffer());
 		break;
 	}
 	case 0x4000: // SET CLIP WINDOW x,y,x2,y2:int	[0..320,0..200]
@@ -988,7 +1041,8 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
 			break;
 		if (!env._soundRaw)
 			warning("TODO: Trying to play raw SFX but nothing loaded");
-		env._soundRaw->play();
+		else
+			env._soundRaw->play();
 		break;
 	}
 	case 0xf010: { // LOAD SCR:	filename:str
@@ -1060,18 +1114,6 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
 		break;
 	}
 
-	// Unimplemented / unknown
-	case 0x0010: // (one-shot) ??
-	case 0x0230: // (one-shot) reset current music? (0 args) - found in HoC intro.  Sets params about current music.
-	case 0x1040: // Sets some global? i:int
-	case 0x10B0: // null op?
-	case 0x2010: // SET FRAME?? x,y
-	case 0xa400: // DRAW FILLED CIRCLE
-	case 0xa420: // DRAW EMPTY CIRCLE
-	case 0xc040: // DESELECT_SAMPLE				// SQ5 demo onward
-	case 0xc060: // STOP_SAMPLE					// SQ5 demo onward
-	case 0xc0e0: // FADE SONG songnum, destvol, ticks (1/60th sec)
-
 	default:
 		if (count < 15)
 			warning("Unimplemented TTM opcode: 0x%04X (%s, %d args) (ivals: %d %d %d %d)",


Commit: d26ee617d4d29d780e2fc5fe4b8351772df4dfd8
    https://github.com/scummvm/scummvm/commit/d26ee617d4d29d780e2fc5fe4b8351772df4dfd8
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-10-04T16:59:48+10:00

Commit Message:
DGDS: Run scene ops to completion after scene change

This was the bug that required a workaround for the ticket vendor in Heart of
China.  The scene opened inventory (which makes the scene change) and then set
a global.  We were never setting that global as expected.

This required a slight refactor in the way the scene ops are run.

Changed paths:
    engines/dgds/scene.cpp
    engines/dgds/scene.h


diff --git a/engines/dgds/scene.cpp b/engines/dgds/scene.cpp
index 33621b93897..3436f52744f 100644
--- a/engines/dgds/scene.cpp
+++ b/engines/dgds/scene.cpp
@@ -621,37 +621,37 @@ static void _drawDragonCountdown(FontManager::FontType fontType, int16 x, int16
 }
 
 
-bool Scene::runSceneOp(const SceneOp &op) {
+bool Scene::runSceneOp(const SceneOp &op, bool sceneChanged) {
 	DgdsEngine *engine = DgdsEngine::getInstance();
 	switch (op._opCode) {
 	case kSceneOpChangeScene:
 		if (engine->changeScene(op._args[0]))
-			// This probably reset the list - stop now.
-			return false;
+			return true;
 		break;
 	case kSceneOpNoop:
 		break;
 	case kSceneOpGlobal:
-		globalOps(op._args);
+		// The globals are held by the GDS scene
+		engine->getGDSScene()->globalOps(op._args);
 		break;
 	case kSceneOpSegmentStateOps:
-		segmentStateOps(op._args);
+		SDSScene::segmentStateOps(op._args);
 		break;
 	case kSceneOpSetItemAttr:
-		setItemAttrOp(op._args);
+		SDSScene::setItemAttrOp(op._args);
 		break;
 	case kSceneOpSetDragItem:
-		setDragItemOp(op._args);
+		SDSScene::setDragItemOp(op._args);
 		break;
 	case kSceneOpOpenInventory:
 		engine->getInventory()->open();
 		// This implicitly changes scene num
-		return false;
+		return true;
 	case kSceneOpShowDlg:
 		if (op._args.size() == 1)
-			showDialog(0, op._args[0]);
+			engine->getScene()->showDialog(0, op._args[0]);
 		else if (op._args.size() > 1)
-			showDialog(op._args[0], op._args[1]);
+			engine->getScene()->showDialog(op._args[0], op._args[1]);
 		break;
 	case kSceneOpShowInvButton:
 		engine->getScene()->addInvButtonToHotAreaList();
@@ -660,13 +660,12 @@ bool Scene::runSceneOp(const SceneOp &op) {
 		engine->getScene()->removeInvButtonFromHotAreaList();
 		break;
 	case kSceneOpEnableTrigger:
-		enableTrigger(op._args[0]);
+		engine->getScene()->enableTrigger(op._args[0]);
 		break;
 	case kSceneOpChangeSceneToStored: {
 		uint16 sceneNo = engine->getGameGlobals()->getGlobal(0x61);
 		if (engine->changeScene(sceneNo))
-			// This probably reset the list - stop now.
-			return false;
+			return true;
 		break;
 	}
 	case kSceneOpAddFlagToDragItem: {
@@ -683,7 +682,7 @@ bool Scene::runSceneOp(const SceneOp &op) {
 	case kSceneOpOpenInventoryZoom:
 		engine->getInventory()->setShowZoomBox(true);
 		engine->getInventory()->open();
-		return false;
+		return true;
 	case kSceneOpMoveItemsBetweenScenes: {
 		int16 fromScene = engine->getGameGlobals()->getGlobal(0x55);
 		int16 toScene = engine->getGameGlobals()->getGlobal(0x54);
@@ -729,10 +728,11 @@ bool Scene::runSceneOp(const SceneOp &op) {
 		warning("TODO: Implement generic scene op %d", op._opCode);
 		break;
 	}
-	return true;
+	return false;
 }
 
-bool Scene::runDragonOp(const SceneOp &op) {
+/*static*/
+bool Scene::runDragonOp(const SceneOp &op, bool sceneChanged) {
 	DgdsEngine *engine = DgdsEngine::getInstance();
 	switch (op._opCode) {
 	case kSceneOpPasscode:
@@ -772,11 +772,11 @@ bool Scene::runDragonOp(const SceneOp &op) {
 		error("Unexpected Dragon scene opcode %d", op._opCode);
 		break;
 	}
-	return true;
+	return false;
 }
 
-
-bool Scene::runChinaOp(const SceneOp &op) {
+/*static*/
+bool Scene::runChinaOp(const SceneOp &op, bool sceneChanged) {
 	DgdsEngine *engine = DgdsEngine::getInstance();
 	switch (op._opCode) {
 	case kSceneOpOpenChinaOpenGameOverMenu:
@@ -798,26 +798,28 @@ bool Scene::runChinaOp(const SceneOp &op) {
 	case kSceneOpOpenChinaStartIntro:
 		// The game first jumps to scene 100, and then to 98
 		engine->changeScene(98);
-		return false;
+		return true;
 	default:
 		warning("TODO: Implement china-specific scene opcode %d", op._opCode);
 		break;
 	}
-	return true;
+	return false;
 }
 
-bool Scene::runBeamishOp(const SceneOp &op) {
+bool Scene::runBeamishOp(const SceneOp &op, bool sceneChanged) {
 	DgdsEngine *engine = DgdsEngine::getInstance();
+
 	if (op._opCode & 0x8000) {
 		uint16 opcode = op._opCode & 0x7fff;
-		for (const ConditionalSceneOp &cop : _conditionalOps) {
+		for (const ConditionalSceneOp &cop : engine->getScene()->getConditionalOps()) {
 			if (cop._opCode == opcode && checkConditions(cop._conditionList)) {
 				if (!runOps(cop._opList))
-					return false;
+					return true;
 			}
 		}
-		return true;
+		return false;
 	}
+
 	switch (op._opCode) {
 	case kSceneOpOpenBeamishGameOverMenu:
 		engine->setMenuToTrigger(kMenuGameOver);
@@ -829,11 +831,21 @@ bool Scene::runBeamishOp(const SceneOp &op) {
 		warning("TODO: Implement beamish-specific scene opcode %d", op._opCode);
 		break;
 	}
-	return true;
+	return false;
 }
 
-bool Scene::runOps(const Common::Array<SceneOp> &ops, int16 addMinuites /* = 0 */) {
+//
+// Note: ops list here is not a reference on purpose, it must be copied.
+// The underlying list might be freed during execution if the scene changes, but
+// we have to finish executing the whole list.
+//
+// Scene change can also invalidate the `this` pointer, which is why
+// this is static and the runOp functions fetch the scene through the engine.
+//
+/*static*/
+bool Scene::runOps(const Common::Array<SceneOp> ops, int16 addMinuites /* = 0 */) {
 	DgdsEngine *engine = DgdsEngine::getInstance();
+	bool sceneChanged = false;
 	for (const SceneOp &op : ops) {
 		if (!checkConditions(op._conditionList))
 			continue;
@@ -842,32 +854,31 @@ bool Scene::runOps(const Common::Array<SceneOp> &ops, int16 addMinuites /* = 0 *
 			engine->getClock().addGameTime(addMinuites);
 			addMinuites = 0;
 		}
-		bool keepGoing = true;
 		if (op._opCode < 100) {
-			keepGoing = runSceneOp(op);
+			sceneChanged |= runSceneOp(op, sceneChanged);
+			// NOTE: After executing op, `this` may no longer be valid.
 		} else {
 			// Game-specific opcode
 			switch (engine->getGameId()) {
 			case GID_DRAGON:
-				keepGoing = runDragonOp(op);
+				sceneChanged |= runDragonOp(op, sceneChanged);
 				break;
 			case GID_HOC:
-				keepGoing = runChinaOp(op);
+				sceneChanged |= runChinaOp(op, sceneChanged);
 				break;
 			case GID_WILLY:
-				keepGoing = runBeamishOp(op);
+				sceneChanged |= runBeamishOp(op, sceneChanged);
 				break;
 			default:
 				error("TODO: Implement game-specific scene op for this game");
 			}
 		}
-		if (!keepGoing)
-			return false;
 	}
-	return true;
+	return !sceneChanged;
 }
 
-bool Scene::checkConditions(const Common::Array<SceneConditions> &conds) const {
+/*static*/
+bool Scene::checkConditions(const Common::Array<SceneConditions> &conds) {
 	DgdsEngine *engine = DgdsEngine::getInstance();
 
 	uint cnum = 0;
@@ -1653,11 +1664,6 @@ bool SDSScene::drawAndUpdateDialogs(Graphics::ManagedSurface *dst) {
 	return retval;
 }
 
-void SDSScene::globalOps(const Common::Array<uint16> &args) {
-	// The globals are held by the GDS scene
-	DgdsEngine::getInstance()->getGDSScene()->globalOps(args);
-}
-
 void SDSScene::mouseMoved(const Common::Point &pt) {
 	Dialog *dlg = getVisibleDialog();
 	const HotArea *area = findAreaUnderMouse(pt);
@@ -1849,11 +1855,6 @@ void SDSScene::onDragFinish(const Common::Point &pt) {
 			const ObjectInteraction *i = _findInteraction(scene->getObjInteractions1(), dragItem->_num, area._num);
 			if (i) {
 				debug(" --> exec %d drag ops for area %d", i->opList.size(), area._num);
-				if (engine->getGameId() == GID_HOC && dragItem->_num == 98 && area._num == 25 && gdsScene->getGlobal(355) == 0) {
-					// FIXME: Why is that not executed by the runOps() call below?
-					warning("HACK for giving money to the ticket agent");
-					gdsScene->setGlobal(355, 1);
-				}
 				if (!runOps(i->opList, globals->getGameMinsToAddOnObjInteraction()))
 					return;
 			}
diff --git a/engines/dgds/scene.h b/engines/dgds/scene.h
index 4da130d1adf..5811319f7d5 100644
--- a/engines/dgds/scene.h
+++ b/engines/dgds/scene.h
@@ -310,9 +310,10 @@ public:
 	bool runPreTickOps() { return runOps(_preTickOps); }
 	bool runPostTickOps() { return runOps(_postTickOps); }
 
-	bool runOps(const Common::Array<SceneOp> &ops, int16 addMinutes = 0);
+	static bool runOps(const Common::Array<SceneOp> ops, int16 addMinutes = 0);
 	virtual Common::Error syncState(Common::Serializer &s) = 0;
 	virtual void enableTrigger(uint16 numm, bool enable = true) {}
+	virtual void showDialog(uint16 fileNum, uint16 dlgNum) {}
 
 protected:
 	bool readConditionList(Common::SeekableReadStream *s, Common::Array<SceneConditions> &list) const;
@@ -327,19 +328,16 @@ protected:
 	bool readDialogActionList(Common::SeekableReadStream *s, Common::Array<DialogAction> &list) const;
 	bool readConditionalSceneOpList(Common::SeekableReadStream *s, Common::Array<ConditionalSceneOp> &list) const;
 
-	bool checkConditions(const Common::Array<SceneConditions> &cond) const;
-
-	virtual void showDialog(uint16 fileNum, uint16 dlgNum) {}
-	virtual void globalOps(const Common::Array<uint16> &args) {}
-	virtual void segmentStateOps(const Common::Array<uint16> &args);
-
-	void setItemAttrOp(const Common::Array<uint16> &args);
-	void setDragItemOp(const Common::Array<uint16> &args);
+	static void segmentStateOps(const Common::Array<uint16> &args);
+	static void setItemAttrOp(const Common::Array<uint16> &args);
+	static void setDragItemOp(const Common::Array<uint16> &args);
 
-	bool runSceneOp(const SceneOp &op);
-	bool runDragonOp(const SceneOp &op);
-	bool runChinaOp(const SceneOp &op);
-	bool runBeamishOp(const SceneOp &op);
+	// These are all static as they are potentially run over scene changes.
+	static bool checkConditions(const Common::Array<SceneConditions> &cond);
+	static bool runSceneOp(const SceneOp &op, bool sceneChanged);
+	static bool runDragonOp(const SceneOp &op, bool sceneChanged);
+	static bool runChinaOp(const SceneOp &op, bool sceneChanged);
+	static bool runBeamishOp(const SceneOp &op, bool sceneChanged);
 
 	uint32 _magic;
 	Common::String _version;
@@ -366,7 +364,7 @@ public:
 	void runStartGameOps() { runOps(_startGameOps); }
 	void runQuitGameOps() { runOps(_quitGameOps); }
 	void runChangeSceneOps() { runOps(_onChangeSceneOps); }
-	void globalOps(const Common::Array<uint16> &args) override;
+	void globalOps(const Common::Array<uint16> &args);
 	int16 getGlobal(uint16 num);
 	int16 setGlobal(uint16 num, int16 val);
 
@@ -426,8 +424,6 @@ public:
 	bool drawAndUpdateDialogs(Graphics::ManagedSurface *dst);
 	bool checkForClearedDialogs();
 
-	void globalOps(const Common::Array<uint16> &args) override;
-
 	void mouseMoved(const Common::Point &pt);
 	void mouseLDown(const Common::Point &pt);
 	void mouseLUp(const Common::Point &pt);
@@ -472,12 +468,13 @@ public:
 	bool isTriggerEnabled(uint16 num);
 	bool isLButtonDown() const { return _lbuttonDown; }
 	bool isRButtonDown() const { return _rbuttonDown; }
+	void showDialog(uint16 fileNum, uint16 dlgNum) override;
+	const Common::Array<ConditionalSceneOp> &getConditionalOps() { return _conditionalOps; }
 
 protected:
 	HotArea *findAreaUnderMouse(const Common::Point &pt);
 
 private:
-	void showDialog(uint16 fileNum, uint16 dlgNum) override;
 	Dialog *getVisibleDialog();
 	bool readTalkData(Common::SeekableReadStream *s, TalkData &dst);
 	void updateHead(TalkDataHead &head);


Commit: cf9bde35b649211b584506bdaa59e212c0a76849
    https://github.com/scummvm/scummvm/commit/cf9bde35b649211b584506bdaa59e212c0a76849
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-10-04T17:02:15+10:00

Commit Message:
DGDS: Better message for 'missing' beamish sound data

Changed paths:
    engines/dgds/resource.cpp


diff --git a/engines/dgds/resource.cpp b/engines/dgds/resource.cpp
index ee4d7e24409..c9517e225fd 100644
--- a/engines/dgds/resource.cpp
+++ b/engines/dgds/resource.cpp
@@ -55,7 +55,7 @@ ResourceManager::ResourceManager() {
 		return;
 	}
 
-	indexFile.skip(4); // salt for file hash, TODO
+	indexFile.readUint32LE(); // salt for file hash, TODO
 	int nvolumes = indexFile.readUint16LE();
 
 	char fnbuf[FILENAME_LENGTH + 1];
@@ -70,7 +70,7 @@ ResourceManager::ResourceManager() {
 		if (!_volumes[i].isOpen())
 			error("Couldn't open volume data %s", volumeName.toString().c_str());
 
-		indexFile.skip(1); // unknown
+		indexFile.readSByte(); // unknown byte
 		int entries = indexFile.readUint16LE();
 
 		for (int j = 0; j < entries; j++) {
@@ -86,13 +86,17 @@ ResourceManager::ResourceManager() {
 			Common::String fileName(fnbuf);
 			fileName.toLowercase();
 
-			_volumes[i].skip(1); // unknown
+			_volumes[i].readSByte(); // unknown byte
 			res.size = _volumes[i].readUint32LE();
 
-			// Some sounds in Beamish FDD have size -1, which I think just means they don't exist.
-			if (res.size > (uint32)1 << 31 || fileName.empty() || res.size == 0)
+			if (fileName.empty() || res.size == 0)
 				continue;
 
+			// Some sounds in Beamish have size -1 but are needed for the game.. where are they?
+			if (res.size > (uint32)1 << 31) {
+				warning("Res %s : %s at pos %d has negative size??", volumeName.toString().c_str(), fileName.c_str(), res.pos);
+			}
+
 			_resources[fileName] = res;
 		}
 	}


Commit: b928f84e19fbdb5b0785df77f03a7b6447754a7e
    https://github.com/scummvm/scummvm/commit/b928f84e19fbdb5b0785df77f03a7b6447754a7e
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-10-04T19:58:23+10:00

Commit Message:
DGDS: Drop missing global back to warning

It happens in RoTD and also HoC, so this is a common enough error that we
have to just make it a warning for now.

Changed paths:
    engines/dgds/globals.cpp


diff --git a/engines/dgds/globals.cpp b/engines/dgds/globals.cpp
index 36169815a4f..fc7e23c40c8 100644
--- a/engines/dgds/globals.cpp
+++ b/engines/dgds/globals.cpp
@@ -98,8 +98,9 @@ int16 Globals::getGlobal(uint16 num) {
 		return 0;
 	}
 
+	// This happens in a couple of places in RotD
 	if (num)
-		error("getGlobal: requested non-existing global %d", num);
+		warning("getGlobal: requested non-existing global %d", num);
 
 	// Bug in HoC?
 	//warning("getGlobal: requested global 0");




More information about the Scummvm-git-logs mailing list