aboutsummaryrefslogtreecommitdiff
path: root/engines/mutationofjb
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mutationofjb')
-rw-r--r--engines/mutationofjb/commands/endblockcommand.cpp2
-rw-r--r--engines/mutationofjb/commands/ifcommand.cpp19
-rw-r--r--engines/mutationofjb/commands/saycommand.cpp151
-rw-r--r--engines/mutationofjb/commands/saycommand.h56
-rw-r--r--engines/mutationofjb/commands/seqcommand.cpp2
-rw-r--r--engines/mutationofjb/commands/seqcommand.h2
-rw-r--r--engines/mutationofjb/module.mk1
-rw-r--r--engines/mutationofjb/script.cpp2
8 files changed, 232 insertions, 3 deletions
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index be610c7c9a..af9282f81c 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -102,7 +102,7 @@ void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *,
}
if (!_pendingActionInfos.empty() && newCommandParser != this) {
- debug("Fixing pending action info.\n");
+ debug("Fixing pending action info.");
for (Common::Array<ActionInfo *>::iterator it = _pendingActionInfos.begin(); it != _pendingActionInfos.end(); ++it) {
(*it)->_command = newCommand;
}
diff --git a/engines/mutationofjb/commands/ifcommand.cpp b/engines/mutationofjb/commands/ifcommand.cpp
index a41875f33b..0643c3e161 100644
--- a/engines/mutationofjb/commands/ifcommand.cpp
+++ b/engines/mutationofjb/commands/ifcommand.cpp
@@ -26,6 +26,25 @@
#include "common/str.h"
#include "common/translation.h"
+/*
+ "IF" <tag> <sceneId> <objectId> <value> ["!"]
+
+ IF command compares the value of the WX pseudo-register of the object in the specified scene.
+ If the values match, execution continues to the next line.
+ Otherwise execution continues after first "#ELSE" with the same <tag>.
+ The logic can be reversed with exclamation mark at the end.
+
+ <tag> is always 1 character long, <sceneId> and <objectId> 2 characters long.
+
+ Please note that this does not work line you are used to from saner languages.
+ IF does not have any blocks. It only searches for first #ELSE, so you can have stuff like:
+ IF something
+ IF something else
+ #ELSE
+ ...
+ This is effectively logical AND.
+*/
+
namespace MutationOfJB {
bool IfCommandParser::parse(const Common::String &line, ScriptParseContext &parseContext, Command *&command) {
diff --git a/engines/mutationofjb/commands/saycommand.cpp b/engines/mutationofjb/commands/saycommand.cpp
new file mode 100644
index 0000000000..9448203911
--- /dev/null
+++ b/engines/mutationofjb/commands/saycommand.cpp
@@ -0,0 +1,151 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "mutationofjb/commands/saycommand.h"
+#include "mutationofjb/script.h"
+#include "common/str.h"
+#include "common/debug.h"
+#include "common/debug-channels.h"
+
+/*
+ ("SM" | "SLM" | "NM" | "NLM") " " <lineToSay> ["<" <voiceFile> | "<!"]
+ <skipped> " " <lineToSay> ("<" <voiceFile> | "<!")
+
+ Say command comes in four variants: SM, SLM, NM and NLM.
+ Note: In script files, they are usually written as *SM.
+ The asterisk is ignored by the readLine function.
+
+ Each of them plays a voice file (if present) and/or shows a message
+ (if voice file not present or subtitles are enabled).
+
+ The difference between versions starting with "S" and "N" is that
+ the "N" version does not show talking animation.
+
+ The "L" versions are "blocking", i.e. they wait for the previous say command to finish.
+
+ If the line ends with "<!", it means the message continues to the next line.
+ Next line usually has "SM" (or other variant) repeated, but it does not have to.
+ Then we have the rest of the string to say (which is concatenated with the previous line)
+ and possibly the voice file or "<!" again.
+*/
+
+namespace MutationOfJB {
+
+bool SayCommandParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) {
+ bool waitForPrevious = false;
+ bool talkingAnimation = false;
+
+ if (line.hasPrefix("SM")) {
+ waitForPrevious = false;
+ talkingAnimation = true;
+ } else if (line.hasPrefix("SLM")) {
+ waitForPrevious = true;
+ talkingAnimation = true;
+ } else if (line.hasPrefix("NM")) {
+ waitForPrevious = false;
+ talkingAnimation = false;
+ } else if (line.hasPrefix("NLM")) {
+ waitForPrevious = true;
+ talkingAnimation = false;
+ } else {
+ return false;
+ }
+
+ Common::String currentLine = line;
+
+ Common::String lineToSay;
+ Common::String voiceFile;
+
+ bool cont = false;
+ bool firstPass = true;
+
+ do {
+ cont = false;
+
+ uint startPos;
+ for (startPos = 0; startPos < currentLine.size(); ++startPos) {
+ if (currentLine[startPos] == ' ') {
+ break;
+ }
+ }
+ if (startPos == currentLine.size()) {
+ if (!firstPass) {
+ warning("Unable to parse line '%s'", currentLine.c_str());
+ break;
+ }
+ }
+ startPos++;
+
+ uint endPos;
+ for (endPos = startPos; endPos < currentLine.size(); ++endPos) {
+ if (currentLine[endPos] == '<') {
+ break;
+ }
+ }
+
+ Common::String talkStr(currentLine.c_str() + startPos, endPos - startPos);
+
+ if (endPos != currentLine.size()) {
+ const char * end = currentLine.c_str() + endPos + 1;
+ if (end[0] == '!') {
+ cont = true;
+ } else {
+ voiceFile = end;
+ }
+ }
+
+ if (talkStr.lastChar() == '~') {
+ debug("Found say command ending with '~'. Please take a look.");
+ }
+
+ if (lineToSay.empty()) {
+ lineToSay = talkStr;
+ } else {
+ lineToSay = " " + talkStr;
+ }
+
+ if (cont) {
+ if (!parseCtx.readLine(currentLine)) {
+ cont = false;
+ }
+ }
+
+ firstPass = false;
+ } while (cont);
+
+ command = new SayCommand(lineToSay, voiceFile, waitForPrevious, talkingAnimation);
+
+ return true;
+}
+
+
+Command::ExecuteResult SayCommand::execute(GameData &) {
+ // TODO: Actual implementation.
+ debug("%s [%s]", _lineToSay.c_str(), _voiceFile.c_str());
+ return Finished;
+}
+
+Common::String SayCommand::debugString() const {
+ return Common::String::format("SHOWMSG%s%s '%s' '%s'", _waitForPrevious ? "+WAIT" : "", _talkingAnimation ? "+TALKANIM" : "", _lineToSay.c_str(), _voiceFile.c_str());
+}
+
+}
diff --git a/engines/mutationofjb/commands/saycommand.h b/engines/mutationofjb/commands/saycommand.h
new file mode 100644
index 0000000000..16303de467
--- /dev/null
+++ b/engines/mutationofjb/commands/saycommand.h
@@ -0,0 +1,56 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MUTATIONOFJB_SAYCOMMAND_H
+#define MUTATIONOFJB_SAYCOMMAND_H
+
+#include "mutationofjb/commands/seqcommand.h"
+#include "common/str.h"
+
+namespace MutationOfJB {
+
+class SayCommandParser : public SeqCommandParser {
+public:
+ SayCommandParser() {}
+
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+};
+
+class SayCommand : public SeqCommand {
+public:
+ SayCommand(Common::String &lineToSay, Common::String &voiceFile, bool waitForPrevious, bool talkingAnimation) :
+ _lineToSay(lineToSay),
+ _voiceFile(voiceFile),
+ _waitForPrevious(waitForPrevious),
+ _talkingAnimation(talkingAnimation) {}
+ virtual ExecuteResult execute(GameData &gameData) override;
+ virtual Common::String debugString() const override;
+private:
+ Common::String _lineToSay;
+ Common::String _voiceFile;
+ bool _waitForPrevious;
+ bool _talkingAnimation;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/commands/seqcommand.cpp b/engines/mutationofjb/commands/seqcommand.cpp
index 22d1c9051b..6c167e946a 100644
--- a/engines/mutationofjb/commands/seqcommand.cpp
+++ b/engines/mutationofjb/commands/seqcommand.cpp
@@ -25,7 +25,7 @@
namespace MutationOfJB {
-void SeqCommandParser::transition(ScriptParseContext &, Command * oldCommand, Command * newCommand) {
+void SeqCommandParser::transition(ScriptParseContext &, Command * oldCommand, Command * newCommand, CommandParser *) {
if (!oldCommand || !newCommand) {
warning(_("Unexpected empty command in transition"));
return;
diff --git a/engines/mutationofjb/commands/seqcommand.h b/engines/mutationofjb/commands/seqcommand.h
index 90e302836e..0fa30abaad 100644
--- a/engines/mutationofjb/commands/seqcommand.h
+++ b/engines/mutationofjb/commands/seqcommand.h
@@ -31,7 +31,7 @@ namespace MutationOfJB {
class SeqCommandParser : public CommandParser
{
public:
- virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand) override;
+ virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser) override;
};
class SeqCommand : public Command {
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 09f00db9df..2c89988916 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -6,6 +6,7 @@ MODULE_OBJS := \
commands/conditionalcommand.o \
commands/endblockcommand.o \
commands/ifcommand.o \
+ commands/saycommand.o \
commands/seqcommand.o \
debug.o \
detection.o \
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 8985e067fd..4490af537e 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -30,6 +30,7 @@
#include "mutationofjb/commands/ifcommand.h"
#include "mutationofjb/commands/endblockcommand.h"
#include "mutationofjb/commands/changecommand.h"
+#include "mutationofjb/commands/saycommand.h"
namespace MutationOfJB {
@@ -41,6 +42,7 @@ static CommandParser** getParsers() {
new ChangeObjectCommandParser,
new ChangeStaticCommandParser,
new ChangeSceneCommandParser,
+ new SayCommandParser,
nullptr
};