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

AndywinXp noreply at scummvm.org
Thu Feb 19 22:44:20 UTC 2026


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

Summary:
16b39af3be SCUMM: MI2 NI DOS Demo - Add support for original demo.rec playback file
6a7baa9564 SCUMM: MI2 NI DOS Demo - Flip the toggle from disable demo to enable.
cb2d9ae6d5 SCUMM: MI2 NI Dos Demo - Adjust wording of playback toggle.


Commit: 16b39af3be7643639916655329da2388cece26b8
    https://github.com/scummvm/scummvm/commit/16b39af3be7643639916655329da2388cece26b8
Author: Robert Megone (robert.megone at gmail.com)
Date: 2026-02-19T23:44:15+01:00

Commit Message:
SCUMM: MI2 NI DOS Demo - Add support for original demo.rec playback file

Changed paths:
  A engines/scumm/playback.cpp
    engines/scumm/metaengine.cpp
    engines/scumm/module.mk
    engines/scumm/resource.cpp
    engines/scumm/scumm.cpp
    engines/scumm/scumm.h


diff --git a/engines/scumm/metaengine.cpp b/engines/scumm/metaengine.cpp
index 2f3c9544802..8e41b609ee3 100644
--- a/engines/scumm/metaengine.cpp
+++ b/engines/scumm/metaengine.cpp
@@ -835,6 +835,15 @@ static const ExtraGuiOption mmDemoModeOption = {
 	0
 };
 
+static const ExtraGuiOption mi2NIDemoModeEnable = {
+	_s("Enable Playback"),
+	_s("Enable the rolling playback, disabling the demo is risky as it its missing a lot of data and will crash frequently."),
+	"enable_mi2_ni_demo",
+	true,
+	0,
+	0
+};
+
 static const ExtraGuiOption useRemasteredAudio = {
 	_s("Use remastered audio"),
 	_s("Use the remastered speech and sound effects."),
@@ -953,6 +962,17 @@ const ExtraGuiOptions ScummMetaEngine::getExtraGuiOptions(const Common::String &
 		options.push_back(macV3LowQualityMusic);
 	}
 
+	// The DOS MI2 Demo runs via a pre-recorded stream of input,
+	// disabling this allows you to navigate the demo manually, 
+	// beware, the demo is stripped of a large number of assets 
+	// and the demo will crash frequently due to missing rooms.
+	if (target.empty() || gameid == "monkey2") {
+		bool isValidTarget = extra.contains("Demo") && platform == Common::kPlatformDOS;
+
+		if (isValidTarget)
+			options.push_back(mi2NIDemoModeEnable);
+	}
+
 	return options;
 }
 
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index 3448b103f82..3e59ad2fa07 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -54,6 +54,7 @@ MODULE_OBJS := \
 	midiparser_ro.o \
 	object.o \
 	palette.o \
+	playback.o \
 	players/player_ad.o \
 	players/player_apple2.o \
 	players/player_he.o \
diff --git a/engines/scumm/playback.cpp b/engines/scumm/playback.cpp
new file mode 100644
index 00000000000..625be4e6793
--- /dev/null
+++ b/engines/scumm/playback.cpp
@@ -0,0 +1,405 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/file.h"
+#include "common/system.h"
+#include "scumm/actor.h"
+#include "scumm/scumm.h"
+
+namespace Scumm {
+
+void ScummEngine::Playback::parseStream(const Common::Array<byte> &stream, Common::Array<FrameEvent> &outEvents) {
+	outEvents.clear();
+
+	uint32 off = 0;
+	while (off < stream.size()) {
+		const byte ctl = stream[off++];
+		if ((ctl & 0x0F) != 0)
+			break;
+
+		FrameEvent ev;
+		ev.mbs = 0;
+		ev.key = 0;
+
+		if (ctl & 0x20) {
+			if (off + 2 > stream.size())
+				break;
+			ev.hasPos = true;
+			ev.x = (uint16)((uint16)stream[off] << 1);
+			ev.y = (uint16)stream[off + 1];
+			off += 2;
+		}
+
+		if (ctl & 0x10) {
+			if (off + 2 > stream.size())
+				break;
+			ev.key = (uint16)(stream[off] | (stream[off + 1] << 8));
+			off += 2;
+		}
+
+		if (ctl & 0x80)
+			ev.mbs |= MBS_LEFT_CLICK;
+		if (ctl & 0x40)
+			ev.mbs |= MBS_RIGHT_CLICK;
+
+		outEvents.push_back(ev);
+	}
+}
+
+bool ScummEngine::applyMi2NiDemoOverride() {
+	if (!_scummVars || _numVariables <= 0)
+		return false;
+
+	const uint32 numVars = (uint32)_numVariables;
+
+	if (56 < numVars)
+		_scummVars[56] = 203;
+
+	const byte ov = VAR_OVERRIDE;
+	if (ov != 0xFF)
+		scummVar(ov, "VAR_OVERRIDE", "Playback Override", 0) = 1;
+
+	return true;
+}
+
+
+bool ScummEngine::Playback::tryLoadPlayback(ScummEngine *engine) {
+	if (_loaded || _attempted)
+		return _loaded;
+
+	_attempted = true;
+
+	if (!engine || engine->_targetName.empty())
+		return false;
+
+	Common::File f;
+	if (!f.open(Common::Path("demo.rec"))) {
+		warning("Playback: couldn't find demo.rec");
+		return false;
+	}
+
+	const uint32 fileSize = (uint32)f.size();
+	Common::Array<byte> buf;
+	buf.resize(fileSize);
+	if (fileSize > 0)
+		f.read(buf.begin(), fileSize);
+	f.close();
+
+	const byte marker0 = 0x01;
+	const byte marker1 = 0xFF;
+
+	uint32 streamOff = 0;
+	bool foundPlaybackStream = false;
+
+	for (uint32 i = 0; i + 1 < buf.size(); i++) {
+		if (buf[i] != marker0 || buf[i + 1] != marker1)
+			continue;
+
+		const uint32 candOff = i + 2;
+
+		uint32 off = candOff;
+		uint32 count = 0;
+		bool ok = true;
+
+		while (off < buf.size()) {
+			const byte ctrl = buf[off];
+
+			if ((ctrl & 0x0F) != 0) {
+				ok = false;
+				break;
+			}
+
+			if ((ctrl & ~(0x80 | 0x40 | 0x20 | 0x10)) != 0) {
+				ok = false;
+				break;
+			}
+
+			uint32 recLen = 1;
+			if (ctrl & 0x20)
+				recLen += 2;
+			if (ctrl & 0x10)
+				recLen += 2;
+
+			if (off + recLen > buf.size()) {
+				ok = false;
+				break;
+			}
+
+			off += recLen;
+			count++;
+		}
+
+		if (ok && off == buf.size() && count > 0) {
+			streamOff = candOff;
+			foundPlaybackStream = true;
+		}
+	}
+
+	if (!foundPlaybackStream) {
+		warning("Playback: demo.rec stream marker 0x01 0xFF not found");
+		return false;
+	}
+
+	_streamOff = streamOff;
+	_streamBytes = buf.size() - _streamOff;
+
+	Common::Array<byte> stream;
+	stream.resize(_streamBytes);
+	memcpy(stream.begin(), buf.begin() + _streamOff, _streamBytes);
+
+	parseStream(stream, _events);
+
+	_loaded = !_events.empty();
+	return _loaded;
+}
+
+void ScummEngine::Playback::mi2DemoArmPlaybackByRoom(ScummEngine *engine) {
+	if (!engine)
+		return;
+
+	if (!_loaded)
+		tryLoadPlayback(engine);
+
+	if (!_loaded)
+		return;
+
+	const int room = (int)engine->_currentRoom;
+
+	if (!_mi2DemoVarsApplied && room == 3) {
+		engine->applyMi2NiDemoOverride();
+
+		_mi2DemoVarsApplied = true;
+	}
+
+	if (room == 4) {
+		_active = true;
+
+		if (!_mi2DemoVarsApplied) {
+			engine->applyMi2NiDemoOverride();
+			_mi2DemoVarsApplied = true;
+		}
+	}
+}
+
+// The MI2 NI DOS Demo used the SPUTM debugger to jump rooms, we don't have that so we have to fake room jumps.
+void ScummEngine::Playback::mi2DemoPlaybackJumpRoom(ScummEngine *engine, int room) {
+	if (!engine)
+		return;
+	if (room <= 0)
+		return;
+
+	if (engine->_objectRoomTable) {
+		engine->_objectRoomTable[7] = (byte)room;
+	}
+
+	if (engine->VAR_EGO != 0xFF) {
+		const int egoActorIdx = engine->VAR(engine->VAR_EGO);
+		if (egoActorIdx >= 0 && egoActorIdx < engine->_numActors) {
+			Actor *ego = engine->_actors[egoActorIdx];
+			if (ego)
+				ego->_room = room;
+		}
+	}
+
+	engine->startScene(room, nullptr, 7);
+
+	engine->_cameraIsFrozen = false;
+	if (engine->VAR_EGO != 0xFF) {
+		const int egoActorIdx = engine->VAR(engine->VAR_EGO);
+		if (egoActorIdx >= 0 && egoActorIdx < engine->_numActors) {
+			Actor *ego = engine->_actors[egoActorIdx];
+			if (ego) {
+				engine->setCameraFollows(ego, true);
+				engine->actorFollowCamera(egoActorIdx);
+				engine->moveCamera();
+			}
+		}
+	}
+
+	engine->_fullRedraw = true;
+}
+
+// MI2's 'demo.rec' has some keypresses destined for the SPUTM debugger.
+bool ScummEngine::Playback::handleMi2NIDemoSputmDebugKey(ScummEngine *engine, uint16 rawKey) {
+	if (rawKey == 0)
+		return false;
+
+	if (rawKey == 7) {
+		_sputmCmdActive = true;
+		_sputmCmdEnterCount = 0;
+		_sputmCmdBuf.clear();
+		return true;
+	}
+
+	if (!_sputmCmdActive)
+		return false;
+
+	if (rawKey == 27) {
+		_sputmCmdActive = false;
+		_sputmCmdEnterCount = 0;
+		_sputmCmdBuf.clear();
+		return true;
+	}
+
+	if (rawKey == 13) {
+		if (_sputmCmdEnterCount < 2)
+			_sputmCmdEnterCount++;
+
+		if (_sputmCmdEnterCount >= 2) {
+			const Common::String cmd = _sputmCmdBuf;
+			_sputmCmdActive = false;
+			_sputmCmdEnterCount = 0;
+			_sputmCmdBuf.clear();
+
+			//Special case, we should jump to to room 47 or 27.
+			int targetRoom = -1;
+			if (cmd.equalsIgnoreCase("vill"))
+				targetRoom = 47;
+			else if (cmd.equalsIgnoreCase("whar"))
+				targetRoom = 27;
+
+			if (targetRoom >= 0) {
+				mi2DemoPlaybackJumpRoom(engine, targetRoom);
+			}
+		}
+		return true;
+	}
+
+	if (rawKey >= 32 && rawKey <= 126) {
+		if (_sputmCmdBuf.size() < 32)
+			_sputmCmdBuf += (char)rawKey;
+		return true;
+	}
+
+	_sputmCmdActive = false;
+	_sputmCmdEnterCount = 0;
+	_sputmCmdBuf.clear();
+	return true;
+}
+
+void ScummEngine::Playback::playbackPump(ScummEngine *engine) {
+	if (!engine || !_active)
+		return;
+
+	if (_nextIndex >= _events.size()) {
+		_active = false;
+		return;
+	}
+
+	if (_pendingLUp) {
+		Common::Event ev;
+		ev.type = Common::EVENT_LBUTTONUP;
+		ev.mouse.x = _curX;
+		ev.mouse.y = _curY;
+		engine->parseEvent(ev);
+		_pendingLUp = false;
+	}
+	if (_pendingRUp) {
+		Common::Event ev;
+		ev.type = Common::EVENT_RBUTTONUP;
+		ev.mouse.x = _curX;
+		ev.mouse.y = _curY;
+		engine->parseEvent(ev);
+		_pendingRUp = false;
+	}
+
+	if (_nextIndex >= _events.size()) {
+		_active = false;
+		return;
+	}
+
+	const FrameEvent &fev = _events[_nextIndex];
+
+	if (fev.hasPos) {
+		_curX = (int16)fev.x;
+		_curY = (int16)fev.y;
+	}
+
+	{
+		Common::Event mv;
+		mv.type = Common::EVENT_MOUSEMOVE;
+		mv.mouse.x = _curX;
+		mv.mouse.y = _curY;
+		engine->parseEvent(mv);
+	}
+
+	engine->_mouse.x = _curX;
+	engine->_mouse.y = _curY;
+	g_system->warpMouse(_curX, _curY);
+
+	if (engine->_currentRoom == 4) {
+		engine->_virtualMouse.x = _curX;
+		engine->_virtualMouse.y = _curY;
+	} else {
+		engine->_virtualMouse.x = _curX + (engine->_screenStartStrip * 8);
+		engine->_virtualMouse.y = _curY + engine->_screenTop;
+	}
+
+	const uint16 prev = _hasPrevMbs ? _prevMbs : 0;
+	const uint16 cur = fev.mbs;
+
+	const bool prevL = (prev & MBS_LEFT_CLICK) != 0;
+	const bool curL = (cur & MBS_LEFT_CLICK) != 0;
+	const bool prevR = (prev & MBS_RIGHT_CLICK) != 0;
+	const bool curR = (cur & MBS_RIGHT_CLICK) != 0;
+
+	if (!prevL && curL) {
+		Common::Event ev;
+		ev.type = Common::EVENT_LBUTTONDOWN;
+		ev.mouse.x = _curX;
+		ev.mouse.y = _curY;
+		engine->parseEvent(ev);
+		_pendingLUp = true;
+	}
+	if (!prevR && curR) {
+		Common::Event ev;
+		ev.type = Common::EVENT_RBUTTONDOWN;
+		ev.mouse.x = _curX;
+		ev.mouse.y = _curY;
+		engine->parseEvent(ev);
+		_pendingRUp = true;
+	}
+
+	if (fev.key != 0) {
+		if (!handleMi2NIDemoSputmDebugKey(engine, fev.key)) {
+			Common::Event kev;
+			kev.type = Common::EVENT_KEYDOWN;
+			kev.kbd.flags = 0;
+			kev.kbd.ascii = (uint16)fev.key;
+			kev.kbd.keycode = (Common::KeyCode)((fev.key == 27) ? Common::KEYCODE_ESCAPE : (int)Common::KEYCODE_INVALID);
+			engine->parseEvent(kev);
+
+			Common::Event kup;
+			kup.type = Common::EVENT_KEYUP;
+			kup.kbd = kev.kbd;
+			engine->parseEvent(kup);
+		}
+	}
+
+	engine->_mouseAndKeyboardStat = (engine->_mouseAndKeyboardStat & ~MBS_MOUSE_MASK) | (cur & MBS_MOUSE_MASK);
+
+	_prevMbs = cur;
+	_hasPrevMbs = true;
+
+	++_nextIndex;
+}
+
+} // namespace Scumm
diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index d13e4641e03..e77ef62a3db 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -1764,63 +1764,6 @@ void ScummEngine::applyWorkaroundIfNeeded(ResType type, int idx) {
 			}
 		}
 	}
-	
-	// WORKAROUND: The MI2 DOS NI demo relies on a prerecorded save file ("demo.rec") to start correctly.
-	// Without it, the demo can select an invalid path and attempt to load missing rooms.
-	// We patch script 77 to force the intended startup behavior so the demo begins in a valid scene.
-	// ScummVM does not currently support playback of the 'demo.rec' file so it will crash in other places.
-	if (_game.id == GID_MONKEY2 &&
-		(_game.features & GF_DEMO) &&
-		_game.platform == Common::kPlatformDOS &&
-		_game.version == 5 &&
-		enhancementEnabled(kEnhRestoredContent)) {
-
-		if (type == rtScript && idx == 77) {
-			byte *scriptRes = getResourceAddress(type, idx);
-			const uint32 scriptResSize = (size > 0) ? (uint32)size : 0;
-
-			byte *code = scriptRes + 8;
-			const uint32 codeSize = scriptResSize - 8;
-
-			const byte putActorInRoom4Pattern[] = { 0x2D, 0x01, 0x04, 0x01, 0x01 };
-
-			if (codeSize >= (uint32)sizeof(putActorInRoom4Pattern)) {
-				for (uint32 i = 0; i + (uint32)sizeof(putActorInRoom4Pattern) <= codeSize; ++i) {
-					if (memcmp(code + i, putActorInRoom4Pattern, sizeof(putActorInRoom4Pattern)) == 0) {
-						code[i + 2] = 0x03;
-						break;
-					}
-				}
-			}
-
-			const byte overrideInstallPattern[] = { 0x58, 0x01, 0x18, 0x1E, 0x00 };
-
-			if (codeSize >= (uint32)sizeof(overrideInstallPattern)) {
-				for (uint32 i = 0; i + (uint32)sizeof(overrideInstallPattern) <= codeSize; ++i) {
-					if (memcmp(code + i, overrideInstallPattern, sizeof(overrideInstallPattern)) == 0) {
-						code[i + 0] = 0x58;
-						code[i + 1] = 0x00;
-						code[i + 2] = 0x80;
-						code[i + 3] = 0x80;
-						code[i + 4] = 0x80;
-						break;
-					}
-				}
-			}
-
-			const byte overrideDecisionTestPattern[] = { 0xA8, 0x05, 0x00, 0x2D, 0x00 };
-			const byte setOverrideVarTrue[] = { 0x1A, 0x05, 0x00, 0x01, 0x00 };
-
-			if (codeSize >= (uint32)sizeof(overrideDecisionTestPattern)) {
-				for (uint32 i = 0; i + (uint32)sizeof(overrideDecisionTestPattern) <= codeSize; ++i) {
-					if (memcmp(code + i, overrideDecisionTestPattern, sizeof(overrideDecisionTestPattern)) == 0) {
-						memcpy(code + i, setOverrideVarTrue, sizeof(setOverrideVarTrue));
-						break;
-					}
-				}
-			}
-		}
-	}
 
 
 	// WORKAROUND: FM-TOWNS Zak used the extra 40 pixels at the bottom to increase the inventory to 10 items
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index ee17a31da01..fbecfa829da 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1770,6 +1770,10 @@ void ScummEngine::setupScumm(const Common::Path &macResourceFile) {
 
 	free(_compositeBuf);
 	_compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier * _outputPixelFormat.bytesPerPixel);
+
+	// MI2 NI DOS Demo, load demo.rec playback file if present
+	if ((_game.id == GID_MONKEY2) && (_game.features & GF_DEMO) && (_game.platform == Common::kPlatformDOS) && ConfMan.getBool("enable_mi2_ni_demo"))
+		_playback.tryLoadPlayback(this);
 }
 
 #ifdef ENABLE_SCUMM_7_8
@@ -3227,6 +3231,12 @@ void ScummEngine_v90he::scummLoop(int delta) {
 #endif
 
 void ScummEngine::scummLoop_updateScummVars() {
+	// MI2 NI DOS Demo, start playback if demo.rec was loaded succesfully.
+	if ((_game.id == GID_MONKEY2) && (_game.features & GF_DEMO) && (_game.platform == Common::kPlatformDOS) && ConfMan.getBool("enable_mi2_ni_demo")) {
+		_playback.mi2DemoArmPlaybackByRoom(this);
+		if (_playback._active)
+			_playback.playbackPump(this);
+	}
 	if (_game.version == 7) {
 		VAR(VAR_CAMERA_POS_X) = camera._cur.x;
 		VAR(VAR_CAMERA_POS_Y) = camera._cur.y;
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 9563158a6bd..77fb62bf74c 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -835,6 +835,58 @@ public:
 		return _scummVars[var];
 	}
 
+	bool applyMi2NiDemoOverride();
+	struct Playback {
+		struct FrameEvent {
+			bool hasPos = false;
+			uint16 x = 0;
+			uint16 y = 0;
+
+			uint16 mbs = 0;
+			uint16 key = 0;
+		};
+
+		static void parseStream(const Common::Array<byte> &stream, Common::Array<FrameEvent> &outEvents);
+
+		bool _loaded = false;
+		bool _attempted = false;
+		bool _active = false;
+
+		bool _mi2DemoVarsApplied = false;
+
+		Common::Array<FrameEvent> _events;
+
+		uint32 _streamOff = 0;
+		uint32 _streamBytes = 0;
+
+		uint32 _nextIndex = 0;
+		int _lastRoom = -1;
+
+		bool _hasPrevMbs = false;
+		uint16 _prevMbs = 0;
+		uint32 _firstInteractIndex = 0;
+		bool _firstInteractValid = false;
+
+		int16 _curX = 0;
+		int16 _curY = 0;
+		bool _pendingLUp = false;
+		bool _pendingRUp = false;
+
+		bool _sputmCmdActive = false;
+		byte _sputmCmdEnterCount = 0;
+		Common::String _sputmCmdBuf;
+		
+		bool tryLoadPlayback(ScummEngine *engine);
+		void playbackPump(ScummEngine *engine);
+		
+		//MI2 DOS NI Demo specific playback helpers
+		void mi2DemoArmPlaybackByRoom(ScummEngine *engine);
+		void mi2DemoPlaybackJumpRoom(ScummEngine *engine, int room);
+		bool handleMi2NIDemoSputmDebugKey(ScummEngine *engine, uint16 rawKey);
+	};
+
+	Playback _playback;
+
 protected:
 	int16 _varwatch = 0;
 	int32 *_roomVars = nullptr;


Commit: 6a7baa95641b91b06c6096f2bb3e1d6639940982
    https://github.com/scummvm/scummvm/commit/6a7baa95641b91b06c6096f2bb3e1d6639940982
Author: Robert Megone (robert.megone at gmail.com)
Date: 2026-02-19T23:44:15+01:00

Commit Message:
SCUMM: MI2 NI DOS Demo - Flip the toggle from disable demo to enable.

Changed paths:
    engines/scumm/metaengine.cpp
    engines/scumm/scumm.cpp


diff --git a/engines/scumm/metaengine.cpp b/engines/scumm/metaengine.cpp
index 8e41b609ee3..aac8282d306 100644
--- a/engines/scumm/metaengine.cpp
+++ b/engines/scumm/metaengine.cpp
@@ -835,11 +835,11 @@ static const ExtraGuiOption mmDemoModeOption = {
 	0
 };
 
-static const ExtraGuiOption mi2NIDemoModeEnable = {
-	_s("Enable Playback"),
-	_s("Enable the rolling playback, disabling the demo is risky as it its missing a lot of data and will crash frequently."),
-	"enable_mi2_ni_demo",
-	true,
+static const ExtraGuiOption mi2NIDemoModeDisable = {
+	_s("Disable Playback"),
+	_s("Disable the rolling playback, disabling the demo is risky as it its missing a lot of data and will crash frequently."),
+	"disable_mi2_ni_demo",
+	false,
 	0,
 	0
 };
@@ -970,7 +970,7 @@ const ExtraGuiOptions ScummMetaEngine::getExtraGuiOptions(const Common::String &
 		bool isValidTarget = extra.contains("Demo") && platform == Common::kPlatformDOS;
 
 		if (isValidTarget)
-			options.push_back(mi2NIDemoModeEnable);
+			options.push_back(mi2NIDemoModeDisable);
 	}
 
 	return options;
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index fbecfa829da..859d02de8a8 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1772,7 +1772,7 @@ void ScummEngine::setupScumm(const Common::Path &macResourceFile) {
 	_compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier * _outputPixelFormat.bytesPerPixel);
 
 	// MI2 NI DOS Demo, load demo.rec playback file if present
-	if ((_game.id == GID_MONKEY2) && (_game.features & GF_DEMO) && (_game.platform == Common::kPlatformDOS) && ConfMan.getBool("enable_mi2_ni_demo"))
+	if ((_game.id == GID_MONKEY2) && (_game.features & GF_DEMO) && (_game.platform == Common::kPlatformDOS) && !ConfMan.getBool("disable_mi2_ni_demo"))
 		_playback.tryLoadPlayback(this);
 }
 
@@ -3232,7 +3232,7 @@ void ScummEngine_v90he::scummLoop(int delta) {
 
 void ScummEngine::scummLoop_updateScummVars() {
 	// MI2 NI DOS Demo, start playback if demo.rec was loaded succesfully.
-	if ((_game.id == GID_MONKEY2) && (_game.features & GF_DEMO) && (_game.platform == Common::kPlatformDOS) && ConfMan.getBool("enable_mi2_ni_demo")) {
+	if ((_game.id == GID_MONKEY2) && (_game.features & GF_DEMO) && (_game.platform == Common::kPlatformDOS) && !ConfMan.getBool("disable_mi2_ni_demo")) {
 		_playback.mi2DemoArmPlaybackByRoom(this);
 		if (_playback._active)
 			_playback.playbackPump(this);


Commit: cb2d9ae6d54a4b3b9d7af475422124f7bfee2aa6
    https://github.com/scummvm/scummvm/commit/cb2d9ae6d54a4b3b9d7af475422124f7bfee2aa6
Author: Robert Megone (robert.megone at gmail.com)
Date: 2026-02-19T23:44:15+01:00

Commit Message:
SCUMM: MI2 NI Dos Demo - Adjust wording of playback toggle.

Co-authored-by: dwa <contrib at dwatteau.fr>

Changed paths:
    engines/scumm/metaengine.cpp


diff --git a/engines/scumm/metaengine.cpp b/engines/scumm/metaengine.cpp
index aac8282d306..6254aec88a0 100644
--- a/engines/scumm/metaengine.cpp
+++ b/engines/scumm/metaengine.cpp
@@ -837,7 +837,7 @@ static const ExtraGuiOption mmDemoModeOption = {
 
 static const ExtraGuiOption mi2NIDemoModeDisable = {
 	_s("Disable Playback"),
-	_s("Disable the rolling playback, disabling the demo is risky as it its missing a lot of data and will crash frequently."),
+	_s("Disable the scripted part of the demo (dangerous!). This makes it interactive, but as this was never intended, expect frequent crashes!"),
 	"disable_mi2_ni_demo",
 	false,
 	0,




More information about the Scummvm-git-logs mailing list