[Scummvm-git-logs] scummvm master -> 0473591bf82be847cc3b9e820323ca42526d7a04

whoozle noreply at scummvm.org
Thu Jul 23 10:36:22 UTC 2026


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

Summary:
05d7ce6ad4 PHOENIXVR: Handle all CR LF CR + LF cases in script and fix lineno
1aff84d84d PHOENIXVR: V2: implement Stop_AnimBloc
04176e26e5 PHOENIXVR: V2: Close all condition scopes before new warp/test.
62c83015e4 PHOENIXVR: V2: separate top-level script scope into in/out/clic scopes
00a595697c PHOENIXVR: V2: add Stop_Delay stub
fb7dfd38a8 PHOENIXVR: V2: Implement Continue_Game()
0473591bf8 PHOENIXVR: Mark The Cameron Files: Pharaoh's Curse as UNSTABLE


Commit: 05d7ce6ad4892807eb6f48e1cd5e5dc680b99fe1
    https://github.com/scummvm/scummvm/commit/05d7ce6ad4892807eb6f48e1cd5e5dc680b99fe1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2026-07-23T11:30:00+01:00

Commit Message:
PHOENIXVR: Handle all CR LF CR + LF cases in script and fix lineno

Changed paths:
    engines/phoenixvr/script.cpp


diff --git a/engines/phoenixvr/script.cpp b/engines/phoenixvr/script.cpp
index 3875e81e600..d5bffb211d5 100644
--- a/engines/phoenixvr/script.cpp
+++ b/engines/phoenixvr/script.cpp
@@ -65,7 +65,27 @@ Script *Script::load(Common::SeekableReadStream &s, int version) {
 	auto textSize = text.size();
 	while (lineStartOffset < textSize) {
 		auto lineStart = text.begin() + lineStartOffset;
-		auto lineEnd = Common::find(lineStart, text.end(), '\n');
+		auto lineEndCR = Common::find(lineStart, text.end(), '\r');
+		auto lineEndLF = Common::find(lineStart, text.end(), '\n');
+		bool hasCR = lineEndCR != text.end();
+		bool hasLF = lineEndLF != text.end();
+		char *lineEnd;
+		if (hasCR && hasLF) {
+			if (lineEndCR + 1 == lineEndLF) {
+				// CR LF
+				lineEnd = lineEndLF;
+			} else if (lineEndCR < lineEndLF) {
+				// CR first, but not followed by LF
+				lineEnd = lineEndCR;
+			} else
+				lineEnd = lineEndLF;
+		} else if (hasCR) {
+			lineEnd = lineEndCR;
+		} else if (hasLF) {
+			lineEnd = lineEndLF;
+		} else {
+			lineEnd = text.end();
+		}
 		lineStartOffset += Common::distance(lineStart, lineEnd) + 1;
 		while (lineEnd > lineStart && Common::isSpace(lineEnd[-1]))
 			--lineEnd;


Commit: 1aff84d84dc390d0c7c696fe8907d6a110155b43
    https://github.com/scummvm/scummvm/commit/1aff84d84dc390d0c7c696fe8907d6a110155b43
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2026-07-23T11:30:00+01:00

Commit Message:
PHOENIXVR: V2: implement Stop_AnimBloc

Changed paths:
    engines/phoenixvr/commands_v2.cpp


diff --git a/engines/phoenixvr/commands_v2.cpp b/engines/phoenixvr/commands_v2.cpp
index cf51d6e2a79..32e583f406f 100644
--- a/engines/phoenixvr/commands_v2.cpp
+++ b/engines/phoenixvr/commands_v2.cpp
@@ -120,11 +120,22 @@ struct Play_AnimBloc : public Command {
 	}
 };
 
+struct Stop_AnimBloc : public Command {
+	Common::String name;
+
+	Stop_AnimBloc(const Common::Array<Common::String> &args) : name(args[0]) {}
+	void exec(ExecutionContext &ctx) const override {
+		debug("Stop_AnimBloc %s", name.c_str());
+		g_engine->stopAnimation(name);
+	}
+};
+
 struct Play_Amb : public Command {
 	Common::String path;
 	int volume;
 	int loops;
-	Play_Amb(const Common::Array<Common::String> &args) : path(args[0]), volume(atoi(args[1].c_str())), loops(atoi(args[2].c_str())) {}
+	Play_Amb(const Common::Array<Common::String> &args) : path(args[0]),
+														  volume(args.size() > 1 ? atoi(args[1].c_str()) : 100), loops(args.size() > 2 ? atoi(args[2].c_str()) : 0) {}
 	void exec(ExecutionContext &ctx) const override {
 		g_engine->playSound(path, Audio::Mixer::kMusicSoundType, volume, loops);
 	}
@@ -471,7 +482,6 @@ static const char *const kUnhandledV2Commands[] = {
 	"SPRITE_SCREEN_MODE",
 	"SPRITE_WARP",
 	"SPRITE_WARP_MODE",
-	"STOP_ANIMBLOC",
 	"STOP_DELAY",
 	"STOP_MUSIC",
 	"UNDERWATER_EFFECT",
@@ -510,6 +520,7 @@ static const char *const kUnhandledV2Commands[] = {
 	E(Start_Light)      \
 	E(Start_Timer)      \
 	E(Stop_All_Sounds)  \
+	E(Stop_AnimBloc)    \
 	E(Stop_Light)       \
 	E(Stop_Sound)       \
 	E(Stop_Timer)       \


Commit: 04176e26e5d4bf30bb62e60fe44d6adda3c02acc
    https://github.com/scummvm/scummvm/commit/04176e26e5d4bf30bb62e60fe44d6adda3c02acc
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2026-07-23T11:30:00+01:00

Commit Message:
PHOENIXVR: V2: Close all condition scopes before new warp/test.

Changed paths:
    engines/phoenixvr/script_v2.cpp
    engines/phoenixvr/script_v2.h


diff --git a/engines/phoenixvr/script_v2.cpp b/engines/phoenixvr/script_v2.cpp
index a86fd64f11a..1da5fa559a0 100644
--- a/engines/phoenixvr/script_v2.cpp
+++ b/engines/phoenixvr/script_v2.cpp
@@ -122,6 +122,18 @@ int ScriptV2::Condition::value() const {
 	error("invalid condition %s %s %s", arg1.c_str(), op.c_str(), arg2.c_str());
 }
 
+void ScriptV2::closeScope() {
+	assert(!_conditionals.empty());
+	auto conditional = _conditionals.back();
+	_conditionals.pop_back();
+	topScope().commands.push_back(Common::move(conditional.conditional));
+}
+
+void ScriptV2::closeAllScopes() {
+	while (!_conditionals.empty())
+		closeScope();
+}
+
 void ScriptV2::parseLine(const Common::String &line, uint lineno) {
 	if (line.empty())
 		return;
@@ -147,6 +159,13 @@ void ScriptV2::parseLine(const Common::String &line, uint lineno) {
 			Common::String test;
 			if (p.maybe(','))
 				test = p.nextWord();
+
+			if (!_conditionals.empty()) {
+				warning("condition didn't have endif at the last test at line %d", lineno);
+				assert(_currentTest);
+				closeAllScopes();
+			}
+
 			_currentWarp.reset(new Warp{vr, Common::move(test), {}});
 			if (!_warpsIndex.contains(vr))
 				_warpsIndex[vr] = _warps.size();
@@ -154,16 +173,20 @@ void ScriptV2::parseLine(const Common::String &line, uint lineno) {
 				warning("duplicate warp %s", vr.c_str());
 			_warps.push_back(_currentWarp);
 			_warpNames.push_back(vr);
+			_currentTest.reset();
 		} else if (p.maybe("test]:")) {
 			if (!_currentWarp)
 				error("test without warp");
 			auto idx = p.nextInt();
 			if (!_currentWarp)
 				error("text must have parent wrap section");
+			if (!_conditionals.empty()) {
+				warning("condition didn't have endif at the last test at line %d", lineno);
+				assert(_currentTest);
+				closeAllScopes();
+			}
 			_currentTest.reset(new Test{idx, 0, {}, {}, {}});
 			_currentWarp->tests.push_back(_currentTest);
-			if (!_conditionals.empty())
-				error("condition didn't have endif at the last test at line %d", lineno);
 		} else if (p.maybe("ifand]:")) {
 			if (!_currentTest)
 				error("ifand without test at line %d", lineno);
@@ -189,11 +212,10 @@ void ScriptV2::parseLine(const Common::String &line, uint lineno) {
 		} else if (p.maybe("endif]")) {
 			if (!_currentTest)
 				error("endif without test at line %d", lineno);
-			if (_conditionals.empty())
-				error("endif without conditional at line %d", lineno);
-			auto conditional = _conditionals.back();
-			_conditionals.pop_back();
-			topScope().commands.push_back(Common::move(conditional.conditional));
+			if (!_conditionals.empty()) {
+				closeScope();
+			} else
+				warning("endif without conditional at line %d", lineno);
 		} else if (p.maybe("clic]")) {
 			if (!_conditionals.empty())
 				error("[clic] inside conditional at line %d", lineno);
diff --git a/engines/phoenixvr/script_v2.h b/engines/phoenixvr/script_v2.h
index e6622caf8ea..2cb8a192d17 100644
--- a/engines/phoenixvr/script_v2.h
+++ b/engines/phoenixvr/script_v2.h
@@ -58,8 +58,11 @@ private:
 	Common::Array<ConditionalScope> _conditionals;
 
 	Scope &topScope() const {
+		assert(_currentTest);
 		return !_conditionals.empty() ? *_conditionals.back().scope : _currentTest->scope;
 	}
+	void closeScope();
+	void closeAllScopes();
 
 private:
 	void parseLine(const Common::String &line, uint lineno) override;


Commit: 62c83015e4e3f0e93f34a0a9535d1dfce9c8a6d3
    https://github.com/scummvm/scummvm/commit/62c83015e4e3f0e93f34a0a9535d1dfce9c8a6d3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2026-07-23T11:30:00+01:00

Commit Message:
PHOENIXVR: V2: separate top-level script scope into in/out/clic scopes

Changed paths:
    engines/phoenixvr/script_v2.cpp
    engines/phoenixvr/script_v2.h


diff --git a/engines/phoenixvr/script_v2.cpp b/engines/phoenixvr/script_v2.cpp
index 1da5fa559a0..6afae4bf6a5 100644
--- a/engines/phoenixvr/script_v2.cpp
+++ b/engines/phoenixvr/script_v2.cpp
@@ -134,6 +134,14 @@ void ScriptV2::closeAllScopes() {
 		closeScope();
 }
 
+void ScriptV2::closeAllScopesWithWarning(int lineno) {
+	if (_conditionals.empty())
+		return;
+	warning("condition didn't have endif at the last test at line %d", lineno);
+	assert(_currentTestScope);
+	closeAllScopes();
+}
+
 void ScriptV2::parseLine(const Common::String &line, uint lineno) {
 	if (line.empty())
 		return;
@@ -142,7 +150,7 @@ void ScriptV2::parseLine(const Common::String &line, uint lineno) {
 	if (p.atEnd())
 		return;
 
-	if (p.maybe("//"))
+	if (p.maybe("//") || p.maybe("--"))
 		return;
 
 	if (p.maybe('[')) {
@@ -160,11 +168,7 @@ void ScriptV2::parseLine(const Common::String &line, uint lineno) {
 			if (p.maybe(','))
 				test = p.nextWord();
 
-			if (!_conditionals.empty()) {
-				warning("condition didn't have endif at the last test at line %d", lineno);
-				assert(_currentTest);
-				closeAllScopes();
-			}
+			closeAllScopesWithWarning(lineno);
 
 			_currentWarp.reset(new Warp{vr, Common::move(test), {}});
 			if (!_warpsIndex.contains(vr))
@@ -174,19 +178,19 @@ void ScriptV2::parseLine(const Common::String &line, uint lineno) {
 			_warps.push_back(_currentWarp);
 			_warpNames.push_back(vr);
 			_currentTest.reset();
+			_currentTestScope = nullptr;
 		} else if (p.maybe("test]:")) {
 			if (!_currentWarp)
 				error("test without warp");
 			auto idx = p.nextInt();
 			if (!_currentWarp)
 				error("text must have parent wrap section");
-			if (!_conditionals.empty()) {
-				warning("condition didn't have endif at the last test at line %d", lineno);
-				assert(_currentTest);
-				closeAllScopes();
-			}
+
+			closeAllScopesWithWarning(lineno);
+
 			_currentTest.reset(new Test{idx, 0, {}, {}, {}});
 			_currentWarp->tests.push_back(_currentTest);
+			_currentTestScope = &_currentTest->scope;
 		} else if (p.maybe("ifand]:")) {
 			if (!_currentTest)
 				error("ifand without test at line %d", lineno);
@@ -205,10 +209,11 @@ void ScriptV2::parseLine(const Common::String &line, uint lineno) {
 			if (_conditionals.empty())
 				error("else without conditional at line %d", lineno);
 			auto &top = _conditionals.back();
-			if (top.conditional->falseScope)
-				error("double else in condition at line %d", lineno);
-			top.conditional->falseScope.reset(new Scope());
-			top.scope = top.conditional->falseScope;
+			if (!top.conditional->falseScope) {
+				top.conditional->falseScope.reset(new Scope());
+				top.scope = top.conditional->falseScope;
+			} else
+				warning("double else in condition at line %d", lineno);
 		} else if (p.maybe("endif]")) {
 			if (!_currentTest)
 				error("endif without test at line %d", lineno);
@@ -217,10 +222,10 @@ void ScriptV2::parseLine(const Common::String &line, uint lineno) {
 			} else
 				warning("endif without conditional at line %d", lineno);
 		} else if (p.maybe("clic]")) {
-			if (!_conditionals.empty())
-				error("[clic] inside conditional at line %d", lineno);
 			if (!_currentTest)
 				error("[clic] without test at line %d", lineno);
+			closeAllScopesWithWarning(lineno);
+			_currentTestScope = &_currentTest->scope;
 		} else if (p.maybe("in]")) {
 			if (!_conditionals.empty())
 				error("[in] inside conditional at line %d", lineno);
@@ -228,7 +233,9 @@ void ScriptV2::parseLine(const Common::String &line, uint lineno) {
 				error("[in] without test at line %d", lineno);
 			if (_currentTest->enter)
 				error("duplicate [in] handler");
+			closeAllScopesWithWarning(lineno);
 			_currentTest->enter.reset(new Scope);
+			_currentTestScope = _currentTest->enter.get();
 		} else if (p.maybe("out]")) {
 			if (!_conditionals.empty())
 				error("[out] inside conditional at line %d", lineno);
@@ -236,7 +243,9 @@ void ScriptV2::parseLine(const Common::String &line, uint lineno) {
 				error("out without test at line %d", lineno);
 			if (_currentTest->leave)
 				error("duplicate [out] handler");
+			closeAllScopesWithWarning(lineno);
 			_currentTest->leave.reset(new Scope);
+			_currentTestScope = _currentTest->leave.get();
 		} else {
 			error("invalid [] directive on line %u: %s", lineno, line.c_str());
 		}
diff --git a/engines/phoenixvr/script_v2.h b/engines/phoenixvr/script_v2.h
index 2cb8a192d17..f726c074a07 100644
--- a/engines/phoenixvr/script_v2.h
+++ b/engines/phoenixvr/script_v2.h
@@ -51,6 +51,7 @@ public:
 private:
 	WarpPtr _currentWarp;
 	TestPtr _currentTest;
+	Scope *_currentTestScope = nullptr;
 	struct ConditionalScope {
 		ConditionalPtr conditional;
 		ScopePtr scope;
@@ -58,11 +59,12 @@ private:
 	Common::Array<ConditionalScope> _conditionals;
 
 	Scope &topScope() const {
-		assert(_currentTest);
-		return !_conditionals.empty() ? *_conditionals.back().scope : _currentTest->scope;
+		assert(_currentTestScope);
+		return !_conditionals.empty() ? *_conditionals.back().scope : *_currentTestScope;
 	}
 	void closeScope();
 	void closeAllScopes();
+	void closeAllScopesWithWarning(int lineno);
 
 private:
 	void parseLine(const Common::String &line, uint lineno) override;


Commit: 00a595697cf6bd02732ef6430fff6864f1633985
    https://github.com/scummvm/scummvm/commit/00a595697cf6bd02732ef6430fff6864f1633985
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2026-07-23T11:30:00+01:00

Commit Message:
PHOENIXVR: V2: add Stop_Delay stub

Changed paths:
    engines/phoenixvr/commands_v2.cpp


diff --git a/engines/phoenixvr/commands_v2.cpp b/engines/phoenixvr/commands_v2.cpp
index 32e583f406f..8147b4724bc 100644
--- a/engines/phoenixvr/commands_v2.cpp
+++ b/engines/phoenixvr/commands_v2.cpp
@@ -153,6 +153,16 @@ struct Delay_Sound : public Command {
 	}
 };
 
+struct Stop_Delay : public Command {
+	Common::String name;
+	Stop_Delay(const Common::Array<Common::String> &args) : name(args[0]) {}
+
+	void exec(ExecutionContext &ctx) const override {
+		warning("stop delay %s stub", name.c_str());
+		g_engine->stopSound(name);
+	}
+};
+
 struct Play_3DSound : public Command {
 	Common::String path;
 	int angle1;
@@ -482,7 +492,6 @@ static const char *const kUnhandledV2Commands[] = {
 	"SPRITE_SCREEN_MODE",
 	"SPRITE_WARP",
 	"SPRITE_WARP_MODE",
-	"STOP_DELAY",
 	"STOP_MUSIC",
 	"UNDERWATER_EFFECT",
 	"ZONES_CLICK_MODE"};
@@ -521,6 +530,7 @@ static const char *const kUnhandledV2Commands[] = {
 	E(Start_Timer)      \
 	E(Stop_All_Sounds)  \
 	E(Stop_AnimBloc)    \
+	E(Stop_Delay)       \
 	E(Stop_Light)       \
 	E(Stop_Sound)       \
 	E(Stop_Timer)       \


Commit: fb7dfd38a80576c0e283d4c3b4ba2964f4578f74
    https://github.com/scummvm/scummvm/commit/fb7dfd38a80576c0e283d4c3b4ba2964f4578f74
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2026-07-23T11:30:00+01:00

Commit Message:
PHOENIXVR: V2: Implement Continue_Game()

Changed paths:
    engines/phoenixvr/commands_v2.cpp


diff --git a/engines/phoenixvr/commands_v2.cpp b/engines/phoenixvr/commands_v2.cpp
index 8147b4724bc..ed9fe2d0857 100644
--- a/engines/phoenixvr/commands_v2.cpp
+++ b/engines/phoenixvr/commands_v2.cpp
@@ -434,6 +434,14 @@ struct Set_View_Angle : public Command {
 	}
 };
 
+struct Continue_Game : public Command {
+	Continue_Game(const Common::Array<Common::String> &args) {}
+	void exec(ExecutionContext &ctx) const override {
+		debug("continue game");
+		g_engine->setNextLevel();
+	}
+};
+
 struct Exit_Game : public Command {
 	Exit_Game(const Common::Array<Common::String> &args) {}
 	void exec(ExecutionContext &ctx) const override {
@@ -462,7 +470,6 @@ struct UnhandledV2Command : public Command {
 static const char *const kUnhandledV2Commands[] = {
 	"AND",
 	"BREAK",
-	"CONTINUE_GAME",
 	"CURSOR_CLOSE",
 	"CURSOR_MODE",
 	"CURSOR_SET",
@@ -500,6 +507,7 @@ static const char *const kUnhandledV2Commands[] = {
 
 #define COMMAND_LIST(E) \
 	E(Add)              \
+	E(Continue_Game)    \
 	E(Cursor_Load)      \
 	E(Cursor_Set)       \
 	E(Delay_Sound)      \


Commit: 0473591bf82be847cc3b9e820323ca42526d7a04
    https://github.com/scummvm/scummvm/commit/0473591bf82be847cc3b9e820323ca42526d7a04
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2026-07-23T11:35:05+01:00

Commit Message:
PHOENIXVR: Mark The Cameron Files: Pharaoh's Curse as UNSTABLE

Brief play test shows all levels are playable with no major issues.
No level transition has been tested so far.

Changed paths:
    engines/phoenixvr/detection_tables.h


diff --git a/engines/phoenixvr/detection_tables.h b/engines/phoenixvr/detection_tables.h
index 3f5146e6d6d..8d991830ff3 100644
--- a/engines/phoenixvr/detection_tables.h
+++ b/engines/phoenixvr/detection_tables.h
@@ -35,7 +35,7 @@ const PlainGameDescriptor phoenixvrGames[] = {
 	{"amerzone", "Amerzone: The Explorer's Legacy"},
 	// V2 games
 	{"mysteryofmummy", "Sherlock Holmes: The Mystery of the Mummy"},
-	{"pharaoncurse", "The Cameron Files: Pharaoh's Curse "},
+	{"pharaoncurse", "The Cameron Files: Pharaoh's Curse"},
 	{0, 0}
 };
 
@@ -631,7 +631,7 @@ const ADGameDescription gameDescriptions[] = {
 		GUIO1(GUIO_NONE)
 	},
 	{"pharaoncurse",
-		"USA CD release - V2 games are not yet supported",
+		"USA CD release",
 		AD_ENTRY3s(
 			"Level_1/script.lst", "1bacc45e3ca6eea715ba5abd73986577", 211816,
 			"install/Start/script.lst", "40b17997a4d319605f024303d1513039", 17142,
@@ -639,18 +639,18 @@ const ADGameDescription gameDescriptions[] = {
 		),
 		Common::EN_ANY,
 		Common::kPlatformWindows,
-		ADGF_DROPPLATFORM | ADGF_CD | PHOENIXVR_V2 | ADGF_UNSUPPORTED,
+		ADGF_DROPPLATFORM | ADGF_CD | PHOENIXVR_V2 | ADGF_UNSTABLE,
 		GUIO1(GUIO_NONE)
 	},
 	{"pharaoncurse",
-		"Retail CD release - V2 games are not yet supported",
+		"Retail CD release",
 		AD_ENTRY2s(
 			"script.lst", "559f73dabf49f60afa5983b75ed7a317", 850,
 			"L0P01R01S00.vr", "92ca961d87b8bcdfefefb5e37773a19e", 207721
 		),
 		Common::RU_RUS,
 		Common::kPlatformWindows,
-		ADGF_DROPPLATFORM | ADGF_CD | PHOENIXVR_V2 | ADGF_UNSUPPORTED,
+		ADGF_DROPPLATFORM | ADGF_CD | PHOENIXVR_V2 | ADGF_UNSTABLE,
 		GUIO1(GUIO_NONE)
 	},
 




More information about the Scummvm-git-logs mailing list