[Scummvm-git-logs] scummvm master -> bd997f5abff2fb1bad57a5289a1bb8afb7716b5e
whoozle
noreply at scummvm.org
Sun Jul 19 14:42:40 UTC 2026
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
ceec833d19 PHOENIXVR: add stop sound command
bd997f5abf PHOENIXVR: implement conditionals/hover blocks in V2 script
Commit: ceec833d19cba17fcb1895d904aa3bfe1da1161c
https://github.com/scummvm/scummvm/commit/ceec833d19cba17fcb1895d904aa3bfe1da1161c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2026-07-19T15:22:22+01:00
Commit Message:
PHOENIXVR: add stop sound command
Changed paths:
engines/phoenixvr/commands_v2.cpp
engines/phoenixvr/phoenixvr.cpp
diff --git a/engines/phoenixvr/commands_v2.cpp b/engines/phoenixvr/commands_v2.cpp
index c2ebb09d0ba..c5a40d4f01f 100644
--- a/engines/phoenixvr/commands_v2.cpp
+++ b/engines/phoenixvr/commands_v2.cpp
@@ -79,6 +79,15 @@ struct Play_Sound : public Command {
}
};
+struct Stop_Sound : public Command {
+ Common::String name;
+ Stop_Sound(const Common::Array<Common::String> &args) : name(args[0]) {}
+
+ void exec(ExecutionContext &ctx) const override {
+ g_engine->stopSound(name);
+ }
+};
+
struct Stop_All_Sounds : public Command {
Stop_All_Sounds(const Common::Array<Common::String> &args) {}
@@ -125,6 +134,7 @@ struct Cursor_Set : public Command {
E(Play_Sound) \
E(Play_AnimBloc) \
E(Stop_All_Sounds) \
+ E(Stop_Sound) \
E(Sub)
#define ADD_COMMAND(NAME) \
diff --git a/engines/phoenixvr/phoenixvr.cpp b/engines/phoenixvr/phoenixvr.cpp
index 75872c4c28b..05958d53eb1 100644
--- a/engines/phoenixvr/phoenixvr.cpp
+++ b/engines/phoenixvr/phoenixvr.cpp
@@ -917,6 +917,7 @@ void PhoenixVREngine::stopSound(const Common::String &sound) {
}
void PhoenixVREngine::stopAllSounds() {
+ debug("stop all sounds");
_mixer->stopAll();
_currentMusic.clear();
for (auto &kv : _sounds) {
Commit: bd997f5abff2fb1bad57a5289a1bb8afb7716b5e
https://github.com/scummvm/scummvm/commit/bd997f5abff2fb1bad57a5289a1bb8afb7716b5e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2026-07-19T15:40:17+01:00
Commit Message:
PHOENIXVR: implement conditionals/hover blocks in V2 script
Changed paths:
engines/phoenixvr/script.h
engines/phoenixvr/script_v1.cpp
engines/phoenixvr/script_v2.cpp
engines/phoenixvr/script_v2.h
diff --git a/engines/phoenixvr/script.h b/engines/phoenixvr/script.h
index 5db007f9a26..b61583db58f 100644
--- a/engines/phoenixvr/script.h
+++ b/engines/phoenixvr/script.h
@@ -40,6 +40,8 @@ public:
int idx;
int hover;
Scope scope;
+ ScopePtr enter;
+ ScopePtr leave;
};
using TestPtr = Common::SharedPtr<Test>;
diff --git a/engines/phoenixvr/script_v1.cpp b/engines/phoenixvr/script_v1.cpp
index b6d02ea701c..96f400440bb 100644
--- a/engines/phoenixvr/script_v1.cpp
+++ b/engines/phoenixvr/script_v1.cpp
@@ -101,7 +101,7 @@ void ScriptV1::parseLine(const Common::String &line, uint lineno) {
if (p.maybe(',')) {
hover = p.nextInt();
}
- _currentTest.reset(new Test{idx, hover, {}});
+ _currentTest.reset(new Test{idx, hover, {}, {}, {}});
_currentWarp->tests.push_back(_currentTest);
} else {
error("invalid [] directive on line %u: %s", lineno, line.c_str());
diff --git a/engines/phoenixvr/script_v2.cpp b/engines/phoenixvr/script_v2.cpp
index 958a3923ca3..265e5ebc4cf 100644
--- a/engines/phoenixvr/script_v2.cpp
+++ b/engines/phoenixvr/script_v2.cpp
@@ -34,8 +34,90 @@ struct SetVariable : public Command {
g_engine->setVariable(name, valueOf(value));
}
};
+
+struct IfAnd : public ScriptV2::Conditional {
+ IfAnd(const Common::Array<Common::String> &args) : ScriptV2::Conditional(args) {}
+ void exec(ExecutionContext &ctx) const override {
+ bool result = true;
+ for (auto &c : conditions) {
+ if (!c->value()) {
+ result = false;
+ break;
+ }
+ }
+ branch(ctx, result);
+ }
+};
+
+struct IfOr : public ScriptV2::Conditional {
+ IfOr(const Common::Array<Common::String> &args) : ScriptV2::Conditional(args) {}
+ void exec(ExecutionContext &ctx) const override {
+ bool result = false;
+ for (auto &c : conditions) {
+ if (c->value()) {
+ result = true;
+ break;
+ }
+ }
+ branch(ctx, result);
+ }
+};
} // namespace
+ScriptV2::Conditional::Conditional(const Common::Array<Common::String> &args) {
+ conditions.reserve(args.size());
+ for (auto &arg : args) {
+ conditions.push_back(ConditionPtr{new Condition(arg)});
+ }
+}
+
+void ScriptV2::Conditional::branch(ExecutionContext &ctx, bool branch) const {
+ if (branch && trueScope)
+ trueScope->exec(ctx);
+ if (!branch && falseScope)
+ falseScope->exec(ctx);
+}
+
+ScriptV2::Condition::Condition(const Common::String &text) {
+ if (
+ !parse(text, "!=") &&
+ !parse(text, "<>") &&
+ !parse(text, "<=") &&
+ !parse(text, ">=") &&
+ !parse(text, "<") &&
+ !parse(text, ">") &&
+ !parse(text, "="))
+ error("unknown condition %s", text.c_str());
+}
+
+bool ScriptV2::Condition::parse(const Common::String &text, const Common::String &maybeOp) {
+ auto opPos = text.find(maybeOp);
+ if (opPos == text.npos)
+ return false;
+ arg1 = text.substr(0, opPos);
+ op = maybeOp;
+ arg2 = text.substr(opPos + maybeOp.size());
+ return true;
+}
+
+int ScriptV2::Condition::value() const {
+ auto val1 = Command::valueOf(arg1);
+ auto val2 = Command::valueOf(arg2);
+ if (op == "=")
+ return val1 == val2;
+ else if (op == "!=" || op == "<>")
+ return val1 != val2;
+ else if (op == "<")
+ return val1 < val2;
+ else if (op == "<=")
+ return val1 <= val2;
+ else if (op == ">")
+ return val1 > val2;
+ else if (op == ">=")
+ return val1 >= val2;
+ error("invalid condition %s %s %s", arg1.c_str(), op.c_str(), arg2.c_str());
+}
+
void ScriptV2::parseLine(const Common::String &line, uint lineno) {
if (line.empty())
return;
@@ -72,31 +154,64 @@ void ScriptV2::parseLine(const Common::String &line, uint lineno) {
if (!_currentWarp)
error("test without warp");
auto idx = p.nextInt();
- auto hover = 0;
if (!_currentWarp)
error("text must have parent wrap section");
- if (p.maybe(',')) {
- hover = p.nextInt();
- }
- _currentTest.reset(new Test{idx, hover, {}});
+ _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);
+ _testScope.reset();
} else if (p.maybe("ifand]:")) {
if (!_currentTest)
- error("ifand without test");
+ error("ifand without test at line %d", lineno);
+ ConditionalPtr conditional(new IfAnd(p.readStringList()));
+ conditional->trueScope.reset(new Scope);
+ _conditionalScope = conditional->trueScope;
+ _conditionals.push_back(Common::move(conditional));
} else if (p.maybe("ifor]:")) {
if (!_currentTest)
- error("ifor without test");
+ error("ifor without test at line %d", lineno);
+ ConditionalPtr conditional(new IfOr(p.readStringList()));
+ conditional->trueScope.reset(new Scope);
+ _conditionalScope = conditional->trueScope;
+ _conditionals.push_back(Common::move(conditional));
} else if (p.maybe("else]")) {
+ if (!_currentTest)
+ error("else without test at line %d", lineno);
+ if (_conditionals.empty())
+ error("else without conditional at line %d", lineno);
+ auto &conditional = _conditionals.back();
+ if (conditional->falseScope)
+ error("double else in condition at line %d", lineno);
+ conditional->falseScope.reset(new Scope());
+ _conditionalScope = conditional->falseScope;
} 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();
+ _conditionalScope.reset();
+ _currentTest->scope.commands.push_back(Common::move(conditional));
} else if (p.maybe("clic]")) {
if (!_currentTest)
- error("clic without test");
+ error("clic without test at line %d", lineno);
+ _testScope.reset();
} else if (p.maybe("in]")) {
if (!_currentTest)
- error("clic without test");
+ error("in without test at line %d", lineno);
+ if (_currentTest->enter)
+ error("duplicate [in] handler");
+ _currentTest->enter.reset(new Scope);
+ _testScope = _currentTest->enter;
} else if (p.maybe("out]")) {
if (!_currentTest)
- error("clic without test");
+ error("out without test at line %d", lineno);
+ if (_currentTest->leave)
+ error("duplicate [out] handler");
+ _currentTest->leave.reset(new Scope);
+ _testScope = _currentTest->leave;
} else {
error("invalid [] directive on line %u: %s", lineno, line.c_str());
}
@@ -115,12 +230,14 @@ void ScriptV2::parseLine(const Common::String &line, uint lineno) {
} else
error("invalid syntax at %d", lineno);
- auto &commands = _currentTest->scope.commands;
+ auto &commands = _testScope ? _testScope->commands : _currentTest->scope.commands;
if (command)
commands.push_back(command);
else {
warning("unimplemented command %s at line %d", name.c_str(), lineno);
}
+ } else {
+ error("command %s is out of the test block at line %d", line.c_str(), lineno);
}
}
diff --git a/engines/phoenixvr/script_v2.h b/engines/phoenixvr/script_v2.h
index b56090d3477..f1b6b8b2190 100644
--- a/engines/phoenixvr/script_v2.h
+++ b/engines/phoenixvr/script_v2.h
@@ -27,18 +27,33 @@
namespace PhoenixVR {
class ScriptV2 : public Script {
public:
+ struct Condition {
+ Common::String op;
+ Common::String arg1;
+ Common::String arg2;
+
+ Condition(const Common::String &text);
+ bool parse(const Common::String &text, const Common::String &maybeOp);
+ int value() const;
+ };
+ using ConditionPtr = Common::SharedPtr<Condition>;
+
struct Conditional : public Command {
- Common::Array<Common::String> conditions;
- CommandPtr target;
- Conditional(Common::Array<Common::String> args) : conditions(Common::move(args)) {}
+ Common::Array<ConditionPtr> conditions;
+ ScopePtr trueScope;
+ ScopePtr falseScope;
+
+ Conditional(const Common::Array<Common::String> &args);
+ void branch(ExecutionContext &ctx, bool branch) const;
};
using ConditionalPtr = Common::SharedPtr<Conditional>;
private:
WarpPtr _currentWarp;
TestPtr _currentTest;
- ScopePtr _pluginScope;
- ConditionalPtr _conditional;
+ Common::Array<ConditionalPtr> _conditionals;
+ ScopePtr _conditionalScope;
+ ScopePtr _testScope;
private:
void parseLine(const Common::String &line, uint lineno) override;
More information about the Scummvm-git-logs
mailing list