diff options
Diffstat (limited to 'engines/mutationofjb')
-rw-r--r-- | engines/mutationofjb/commands/endblockcommand.cpp | 2 | ||||
-rw-r--r-- | engines/mutationofjb/commands/ifcommand.cpp | 19 | ||||
-rw-r--r-- | engines/mutationofjb/commands/saycommand.cpp | 151 | ||||
-rw-r--r-- | engines/mutationofjb/commands/saycommand.h | 56 | ||||
-rw-r--r-- | engines/mutationofjb/commands/seqcommand.cpp | 2 | ||||
-rw-r--r-- | engines/mutationofjb/commands/seqcommand.h | 2 | ||||
-rw-r--r-- | engines/mutationofjb/module.mk | 1 | ||||
-rw-r--r-- | engines/mutationofjb/script.cpp | 2 |
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 }; |