[Scummvm-git-logs] scummvm master -> 69dc56ad0f0f8418e0e971b48ad24cd0d4a9d33c

bgK bastien.bouclet at gmail.com
Fri Jul 14 08:25:32 CEST 2017


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

Summary:
69dc56ad0f MOHAWK: Riven: Patch prison island dome switch sound change


Commit: 69dc56ad0f0f8418e0e971b48ad24cd0d4a9d33c
    https://github.com/scummvm/scummvm/commit/69dc56ad0f0f8418e0e971b48ad24cd0d4a9d33c
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2017-07-14T08:16:01+02:00

Commit Message:
MOHAWK: Riven: Patch prison island dome switch sound change

Fixes #9958.

Changed paths:
    engines/mohawk/riven.cpp
    engines/mohawk/riven.h
    engines/mohawk/riven_card.cpp
    engines/mohawk/riven_scripts.cpp
    engines/mohawk/riven_scripts.h


diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp
index 21cc701..495f399 100644
--- a/engines/mohawk/riven.cpp
+++ b/engines/mohawk/riven.cpp
@@ -72,6 +72,7 @@ MohawkEngine_Riven::MohawkEngine_Riven(OSystem *syst, const MohawkGameDescriptio
 	_inventory = nullptr;
 
 	DebugMan.addDebugChannel(kRivenDebugScript, "Script", "Track Script Execution");
+	DebugMan.addDebugChannel(kRivenDebugPatches, "Patches", "Track Script Patching");
 
 	// NOTE: We can never really support CD swapping. All of the music files
 	// (*_Sounds.mhk) are stored on disc 1. They are copied to the hard drive
diff --git a/engines/mohawk/riven.h b/engines/mohawk/riven.h
index 0bd6fc6..608ebdd 100644
--- a/engines/mohawk/riven.h
+++ b/engines/mohawk/riven.h
@@ -65,7 +65,8 @@ enum {
 
 // Engine Debug Flags
 enum {
-	kRivenDebugScript   = (1 << 0)
+	kRivenDebugScript   = (1 << 0),
+	kRivenDebugPatches  = (1 << 1)
 };
 
 struct ZipMode {
diff --git a/engines/mohawk/riven_card.cpp b/engines/mohawk/riven_card.cpp
index 1d08cf5..ed3f739 100644
--- a/engines/mohawk/riven_card.cpp
+++ b/engines/mohawk/riven_card.cpp
@@ -63,6 +63,12 @@ void RivenCard::loadCardResource(uint16 id) {
 	_zipModePlace = inStream->readUint16BE();
 	_scripts = _vm->_scriptMan->readScripts(inStream);
 
+	// Apply script patches for this card
+	uint32 globalId = _vm->getStack()->getCardGlobalId(id);
+	for (uint i = 0; i < _scripts.size(); i++) {
+		_scripts[i].script->applyCardPatches(_vm, globalId, _scripts[i].type);
+	}
+
 	delete inStream;
 }
 
diff --git a/engines/mohawk/riven_scripts.cpp b/engines/mohawk/riven_scripts.cpp
index f9da8a1..3086b68 100644
--- a/engines/mohawk/riven_scripts.cpp
+++ b/engines/mohawk/riven_scripts.cpp
@@ -249,6 +249,53 @@ const char *RivenScript::getTypeName(uint16 type) {
 	return names[type];
 }
 
+void RivenScript::applyCardPatches(MohawkEngine_Riven *vm, uint32 cardGlobalId, int scriptType) {
+	bool shouldApplyPatches = false;
+
+	// On Prison Island when pressing the dome viewer switch to close the dome,
+	// the game schedules an ambient sound change using kRivenCommandStoreMovieOpcode
+	// but does not play the associated video in a blocking way. The stored opcode
+	// is not immediately used, stays in memory and may be triggered by some
+	// other action. (Bug #9958)
+	// We replace kRivenCommandStoreMovieOpcode by kRivenCommandActivateSLST
+	// to make the ambient sound change happen immediately.
+	//
+	// Script before patch:
+	// playMovieBlocking(3); // Dome closing
+	// playMovie(4);         // Dome spinning up
+	// activatePLST(2);      // Dome closed
+	// playMovieBlocking(4); // Dome spinning up
+	// storeMovieOpcode(1, 0, 0, 40, 2); // Schedule ambient sound change to "dome spinning"
+	//                                      after movie 1 finishes blocking playback
+	// playMovie(1);         // Dome spinning
+	//
+	// Script after patch:
+	// playMovieBlocking(3); // Dome closing
+	// playMovie(4);         // Dome spinning up
+	// activatePLST(2);      // Dome closed
+	// playMovieBlocking(4); // Dome spinning up
+	// activateSLST(2);      // Ambient sound change to "dome spinning"
+	// playMovie(1);         // Dome spinning
+	if (cardGlobalId == 0x1AC1 && scriptType == kCardEnterScript) {
+		shouldApplyPatches = true;
+		for (uint i = 0; i < _commands.size(); i++) {
+			if (_commands[i]->getType() == kRivenCommandStoreMovieOpcode) {
+				RivenSimpleCommand::ArgumentArray arguments;
+				arguments.push_back(2);
+				_commands[i] = RivenCommandPtr(new RivenSimpleCommand(vm, kRivenCommandActivateSLST, arguments));
+				debugC(kRivenDebugPatches, "Applied immediate ambient sound patch to card %x", cardGlobalId);
+				break;
+			}
+		}
+	}
+
+	if (shouldApplyPatches) {
+		for (uint i = 0; i < _commands.size(); i++) {
+			_commands[i]->applyCardPatches(cardGlobalId, scriptType);
+		}
+	}
+}
+
 RivenScriptPtr &operator+=(RivenScriptPtr &lhs, const RivenScriptPtr &rhs) {
 	if (rhs) {
 		*lhs += *rhs;
@@ -691,6 +738,10 @@ void RivenSimpleCommand::execute() {
 	(this->*(_opcodes[_type].proc)) (_type, _arguments);
 }
 
+RivenCommandType RivenSimpleCommand::getType() const {
+	return _type;
+}
+
 RivenSwitchCommand::RivenSwitchCommand(MohawkEngine_Riven *vm) :
 		RivenCommand(vm),
 		_variableId(0) {
@@ -768,6 +819,16 @@ void RivenSwitchCommand::execute() {
 	}
 }
 
+RivenCommandType RivenSwitchCommand::getType() const {
+	return kRivenCommandSwitch;
+}
+
+void RivenSwitchCommand::applyCardPatches(uint32 globalId, int scriptType) {
+	for (uint i = 0; i < _branches.size(); i++) {
+		_branches[i].script->applyCardPatches(_vm, globalId, scriptType);
+	}
+}
+
 RivenStackChangeCommand::RivenStackChangeCommand(MohawkEngine_Riven *vm, uint16 stackId, uint32 globalCardId, bool byStackId) :
 		RivenCommand(vm),
 		_stackId(stackId),
@@ -813,6 +874,10 @@ void RivenStackChangeCommand::dump(byte tabs) {
 	debugN("changeStack(%d, %d);\n", _stackId, _cardId);
 }
 
+RivenCommandType RivenStackChangeCommand::getType() const {
+	return kRivenCommandChangeStack;
+}
+
 RivenTimerCommand::RivenTimerCommand(MohawkEngine_Riven *vm, const Common::SharedPtr<RivenStack::TimerProc> &timerProc) :
 	RivenCommand(vm),
 	_timerProc(timerProc) {
@@ -828,4 +893,8 @@ void RivenTimerCommand::dump(byte tabs) {
 	debugN("doTimer();\n");
 }
 
+RivenCommandType RivenTimerCommand::getType() const {
+	return kRivenCommandTimer;
+}
+
 } // End of namespace Mohawk
diff --git a/engines/mohawk/riven_scripts.h b/engines/mohawk/riven_scripts.h
index d5bce5b..c3e9542 100644
--- a/engines/mohawk/riven_scripts.h
+++ b/engines/mohawk/riven_scripts.h
@@ -87,7 +87,8 @@ enum RivenCommandType {
 	kRivenCommandActivateBLST        = 43,
 	kRivenCommandActivateFLST        = 44,
 	kRivenCommandZipMode             = 45,
-	kRivenCommandActivateMLST        = 46
+	kRivenCommandActivateMLST        = 46,
+	kRivenCommandTimer               = 1001
 };
 
 class MohawkEngine_Riven;
@@ -127,6 +128,9 @@ public:
 	/** Print script details to the standard output */
 	void dumpScript(byte tabs);
 
+	/** Apply patches to card script to fix bugs in the original game scripts */
+	void applyCardPatches(MohawkEngine_Riven *vm, uint32 cardGlobalId, int scriptType);
+
 	/** Append the commands of the other script to this script */
 	RivenScript &operator+=(const RivenScript &other);
 
@@ -249,6 +253,12 @@ public:
 	/** Execute the command */
 	virtual void execute() = 0;
 
+	/** Get the command's type */
+	virtual RivenCommandType getType() const = 0;
+
+	/** Apply card patches for the command's sub-scripts */
+	virtual void applyCardPatches(uint32 globalId, int scriptType) {}
+
 protected:
 	MohawkEngine_Riven *_vm;
 };
@@ -263,21 +273,24 @@ protected:
 class RivenSimpleCommand : public RivenCommand {
 public:
 	static RivenSimpleCommand *createFromStream(MohawkEngine_Riven *vm, RivenCommandType type, Common::ReadStream *stream);
+
+	typedef Common::Array<uint16> ArgumentArray;
+
+	RivenSimpleCommand(MohawkEngine_Riven *vm, RivenCommandType type, const ArgumentArray &arguments);
 	virtual ~RivenSimpleCommand();
 
 	// RivenCommand API
 	virtual void dump(byte tabs) override;
 	virtual void execute() override;
+	virtual RivenCommandType getType() const override;
 
 private:
-	typedef Common::Array<uint16> ArgumentArray;
 	typedef void (RivenSimpleCommand::*OpcodeProcRiven)(uint16 op, const ArgumentArray &args);
 	struct RivenOpcode {
 		OpcodeProcRiven proc;
 		const char *desc;
 	};
 
-	RivenSimpleCommand(MohawkEngine_Riven *vm, RivenCommandType type, const ArgumentArray &arguments);
 
 	void setupOpcodes();
 	Common::String describe() const;
@@ -342,6 +355,8 @@ public:
 	// RivenCommand API
 	virtual void dump(byte tabs) override;
 	virtual void execute() override;
+	virtual RivenCommandType getType() const override;
+	virtual void applyCardPatches(uint32 globalId, int scriptType) override;
 
 private:
 	RivenSwitchCommand(MohawkEngine_Riven *vm);
@@ -372,6 +387,7 @@ public:
 	// RivenCommand API
 	virtual void dump(byte tabs) override;
 	virtual void execute() override;
+	virtual RivenCommandType getType() const override;
 
 private:
 	uint16 _stackId;
@@ -392,6 +408,7 @@ public:
 	// RivenCommand API
 	virtual void dump(byte tabs) override;
 	virtual void execute() override;
+	virtual RivenCommandType getType() const override;
 
 private:
 	Common::SharedPtr<RivenStack::TimerProc> _timerProc;





More information about the Scummvm-git-logs mailing list