aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/mutationofjb/commands/newroomcommand.cpp83
-rw-r--r--engines/mutationofjb/commands/newroomcommand.h56
-rw-r--r--engines/mutationofjb/game.cpp42
-rw-r--r--engines/mutationofjb/game.h3
-rw-r--r--engines/mutationofjb/gamedata.cpp4
-rw-r--r--engines/mutationofjb/gamedata.h1
-rw-r--r--engines/mutationofjb/module.mk1
-rw-r--r--engines/mutationofjb/script.cpp15
-rw-r--r--engines/mutationofjb/script.h1
9 files changed, 194 insertions, 12 deletions
diff --git a/engines/mutationofjb/commands/newroomcommand.cpp b/engines/mutationofjb/commands/newroomcommand.cpp
new file mode 100644
index 0000000000..818ef7d5ee
--- /dev/null
+++ b/engines/mutationofjb/commands/newroomcommand.cpp
@@ -0,0 +1,83 @@
+/* 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/newroomcommand.h"
+#include "mutationofjb/script.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
+#include "common/str.h"
+
+/*
+ "NEWROOM " <sceneId> " " <x> " " <y> " " <frame>
+
+ NEWROOM changes the current scene. While doing that, it also executes STARTUP section for the new room.
+ However, after that, the execution goes back to the old script to finish commands after NEWROOM.
+
+ All parameters are supposed to be 3 characters long.
+ SceneId is the scene to load, x and y are the player's new position and frame is the player's new frame (orientation).
+*/
+
+namespace MutationOfJB {
+
+bool NewRoomCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
+ if (line.size() < 23 || !line.hasPrefix("NEWROOM")) {
+ return false;
+ }
+
+ const uint8 sceneId = atoi(line.c_str() + 8);
+ const uint16 x = atoi(line.c_str() + 12);
+ const uint16 y = atoi(line.c_str() + 16);
+ const uint8 frame = atoi(line.c_str() + 20);
+ command = new NewRoomCommand(sceneId, x, y, frame);
+ return true;
+}
+
+
+NewRoomCommand::NewRoomCommand(uint8 sceneId, uint16 x, uint16 y, uint8 frame) : _sceneId(sceneId), _x(x), _y(y), _frame(frame), _innerExecCtx(nullptr) {}
+
+Command::ExecuteResult NewRoomCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ Game &game = scriptExecCtx.getGame();
+
+ // Execute new startup section.
+ ExecuteResult res;
+ if (!_innerExecCtx) {
+ Script *newScript = game.changeSceneDelayScript(_sceneId, game.getGameData()._partB);
+ _innerExecCtx = new ScriptExecutionContext(scriptExecCtx.getGame(), newScript);
+ res =_innerExecCtx->startStartupSection();
+ } else {
+ res = _innerExecCtx->runActiveCommand();
+ }
+
+ if (res == Finished) {
+ delete _innerExecCtx;
+ _innerExecCtx = nullptr;
+ }
+
+ return res;
+}
+
+Common::String NewRoomCommand::debugString() const {
+ return Common::String::format("NEWROOM %u %u %u %u", (unsigned int) _sceneId, (unsigned int) _x, (unsigned int) _y, (unsigned int) _frame);
+}
+
+}
+
diff --git a/engines/mutationofjb/commands/newroomcommand.h b/engines/mutationofjb/commands/newroomcommand.h
new file mode 100644
index 0000000000..f224e44299
--- /dev/null
+++ b/engines/mutationofjb/commands/newroomcommand.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_NEWROOMCOMMAND_H
+#define MUTATIONOFJB_NEWROOMCOMMAND_H
+
+#include "mutationofjb/commands/seqcommand.h"
+
+namespace MutationOfJB {
+
+class ScriptExecutionContext;
+
+class NewRoomCommandParser : public SeqCommandParser {
+public:
+ NewRoomCommandParser() {}
+
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
+};
+
+class NewRoomCommand : public SeqCommand {
+public:
+ NewRoomCommand(uint8 sceneId, uint16 x, uint16 y, uint8 frame);
+
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
+ virtual Common::String debugString() const override;
+private:
+ uint8 _sceneId;
+ uint16 _x;
+ uint16 _y;
+ uint8 _frame;
+
+ ScriptExecutionContext *_innerExecCtx;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 6436c7ad74..c5fa7b3342 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -35,7 +35,7 @@
namespace MutationOfJB {
Game::Game(MutationOfJBEngine *vm)
-: _vm(vm), _scriptExecCtx(*this) {
+: _vm(vm), _delayedLocalScript(nullptr), _scriptExecCtx(*this) {
_gameData = new GameData;
loadGameData(false);
@@ -79,23 +79,18 @@ bool Game::loadGameData(bool partB) {
return true;
}
-
-void Game::changeScene(uint8 sceneId, bool partB) {
+Script *Game::changeSceneLoadScript(uint8 sceneId, bool partB) {
_gameData->_lastScene = _gameData->_currentScene;
_gameData->_currentScene = sceneId;
+ _gameData->_partB = partB;
_room->load(_gameData->_currentScene, partB);
- if (_localScript) {
- delete _localScript;
- _localScript = nullptr;
- }
-
EncryptedFile scriptFile;
Common::String fileName = Common::String::format("scrn%d%s.atn", sceneId, partB ? "b" : "");
scriptFile.open(fileName);
if (!scriptFile.isOpen()) {
reportFileMissingError(fileName.c_str());
- return;
+ return nullptr;
}
// TODO Actually parse this.
@@ -103,14 +98,37 @@ void Game::changeScene(uint8 sceneId, bool partB) {
dummy = scriptFile.readLine(); // Skip first line.
scriptFile.seek(126, SEEK_CUR); // Skip 126 bytes.
- _localScript = new Script;
- _localScript->loadFromStream(scriptFile);
+ Script *localScript = new Script;
+ localScript->loadFromStream(scriptFile);
scriptFile.close();
+
+ return localScript;
}
+void Game::changeScene(uint8 sceneId, bool partB) {
+ if (_localScript) {
+ delete _localScript;
+ _localScript = nullptr;
+ }
+
+ _localScript = changeSceneLoadScript(sceneId, partB);
+ if (_localScript) {
+ _scriptExecCtx.startStartupSection();
+ }
+}
+
+Script *Game::changeSceneDelayScript(uint8 sceneId, bool partB) {
+ _delayedLocalScript = changeSceneLoadScript(sceneId, partB);
+ return _delayedLocalScript;
+}
void Game::update() {
- _scriptExecCtx.runActiveCommand();
+ Command::ExecuteResult res = _scriptExecCtx.runActiveCommand();
+ if (res == Command::Finished && _delayedLocalScript) {
+ delete _localScript;
+ _localScript = _delayedLocalScript;
+ _delayedLocalScript = nullptr;
+ }
}
}
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index b44929df45..2855704b3b 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -47,6 +47,7 @@ public:
Script *getLocalScript() const;
void changeScene(uint8 sceneId, bool partB);
+ Script *changeSceneDelayScript(uint8 sceneId, bool partB);
void update();
@@ -54,12 +55,14 @@ private:
bool loadGameData(bool partB);
void runActiveCommand();
void startCommand(Command *cmd);
+ Script *changeSceneLoadScript(uint8 sceneId, bool partB);
MutationOfJBEngine *_vm;
GameData *_gameData;
Script *_globalScript;
Script *_localScript;
+ Script *_delayedLocalScript;
Room *_room;
ScriptExecutionContext _scriptExecCtx;
diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp
index a181510371..314eb569b5 100644
--- a/engines/mutationofjb/gamedata.cpp
+++ b/engines/mutationofjb/gamedata.cpp
@@ -183,6 +183,10 @@ Scene *GameData::getScene(uint8 sceneId) {
return &_scenes[sceneId - 1];
}
+Scene *GameData::getCurrentScene() {
+ return getScene(_currentScene);
+}
+
bool GameData::loadFromStream(Common::ReadStream &stream) {
for (int i = 0; i < ARRAYSIZE(_scenes); ++i) {
_scenes[i].loadFromStream(stream);
diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h
index ca70cd7588..eb474f8478 100644
--- a/engines/mutationofjb/gamedata.h
+++ b/engines/mutationofjb/gamedata.h
@@ -148,6 +148,7 @@ struct GameData {
public:
GameData();
Scene *getScene(uint8 sceneId);
+ Scene *getCurrentScene();
bool loadFromStream(Common::ReadStream &stream);
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 447f9a920c..917ab3c4c7 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -13,6 +13,7 @@ MODULE_OBJS := \
commands/ifitemcommand.o \
commands/ifpiggycommand.o \
commands/labelcommand.o \
+ commands/newroomcommand.o \
commands/removeallitemscommand.o \
commands/removeitemcommand.o \
commands/saycommand.o \
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 8dc5e40fe7..b9b1515414 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -41,6 +41,7 @@
#include "mutationofjb/commands/gotocommand.h"
#include "mutationofjb/commands/camefromcommand.h"
#include "mutationofjb/commands/callmacrocommand.h"
+#include "mutationofjb/commands/newroomcommand.h"
#include "mutationofjb/game.h"
namespace MutationOfJB {
@@ -61,6 +62,7 @@ static CommandParser **getParsers() {
new AddItemCommandParser,
new RemoveItemCommandParser,
new RemoveAllItemsCommandParser,
+ new NewRoomCommandParser,
new GotoCommandParser,
new LabelCommandParser,
nullptr
@@ -147,6 +149,19 @@ Command::ExecuteResult ScriptExecutionContext::startCommand(Command *cmd) {
return runActiveCommand();
}
+Command::ExecuteResult ScriptExecutionContext::startStartupSection() {
+ Script *localScript = _localScriptOverride ? _localScriptOverride : _game.getLocalScript();
+
+ if (localScript) {
+ Command *const startupCmd = localScript->getStartup(_game.getGameData().getCurrentScene()->_startup);
+ if (startupCmd) {
+ return startCommand(startupCmd);
+ }
+ }
+
+ return Command::Finished;
+}
+
Command *ScriptExecutionContext::getMacro(const Common::String &name) const {
Command *cmd = nullptr;
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 316aab52ea..09aa9425de 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -105,6 +105,7 @@ public:
Command::ExecuteResult runActiveCommand();
Command::ExecuteResult startCommand(Command *cmd);
+ Command::ExecuteResult startStartupSection();
void pushReturnCommand(Command *);
Command *popReturnCommand();