[Scummvm-git-logs] scummvm master -> b00395b0b976b869cb83c1181481f1ad7ba16b1e
sev-
sev at scummvm.org
Sat Aug 25 23:12:48 CEST 2018
This automated email contains information about 75 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
764ee3a5a3 MUTATIONOFJB: Base for new engine
95cd6b7442 MUTATIONOFJB: Load and draw scene background
3696865e69 MUTATIONOFJB: Load initial game state and allow room change
356a6809c3 MUTATIONOFJB: Fix loading room 11 (and possibly some others).
f7d5a825a0 MUTATIONOFJB: Start implementation of ATN scripts (IF command).
3672ea5572 MUTATIONOFJB: Continue implementation of if/else script commands.
6d926ff55b MUTATIONOFJB: Add support for CHANGED, CHANGEO and CHANGES commands.
bbd3750aee MUTATIONOFJB: Add change scene command, implement listsections and showsection debug console commands.
5d29112f1c MUTATIONOFJB: Add say command with dummy implementation.
bdb6582bb2 MUTATIONOFJB: Implement data model for inventory.
dae522f63c MUTATIONOFJB: Implement inventory commands.
b4dad9bca7 MUTATIONOFJB: Show multiple script commands in showsection debug command.
d3e281e24c MUTATIONOFJB: Fix uninitialized ChangeOperation, fix parsing tag in IF command and add some comments.
5854d310ee MUTATIONOFJB: Fix some code formatting issues.
37ae32e1d3 MUTATIONOFJB: Don't store ActionInfo pointers, because they might be invalidated, and parse/show actions with two object
fa9c8be129 MUTATIONOFJB: Convert section names to 7bit ASCII in debug console.
ae979a8310 MUTATIONOFJB: Add support for IFITEM command and fix parsing conditional commands that are right after #ELSE.
523f973e0a MUTATIONOFJB: Add support of IFPIGGY command.
54c2c0aee6 MUTATIONOFJB: Add support for labels and goto.
fb75e483e4 MUTATIONOFJB: Fix GOTO command.
1d84041508 MUTATIONOFJB: Add Game class.
7a081f0605 MUTATIONOFJB: Load local (room) scripts.
3928c52c0e MUTATIONOFJB: Add support for CAMEFROM command.
63c0dac961 MUTATIONOFJB: Add support for macro definitions.
e1d173ed75 MUTATIONOFJB: Add changescene debug command and fix macro debug commands.
938f222d48 MUTATIONOFJB: Add support for calling macros.
7a18987301 MUTATIONOFJB: Support for running commands.
e93e20dbe8 MUTATIONOFJB: Parse startup sections in scripts and fix change scene command.
574bb83b97 MUTATIONOFJB: Add support for NEWROOM command.
128d30c91c MUTATIONOFJB: Run action when clicking on static or door.
2b94873694 MUTATIONOFJB: Introduce better animation loader that supports diff frames.
99d9055e20 MUTATIONOFJB: Load object frames and implement special handling for map scenes.
9a3a66ab68 MUTATIONOFJB: Fix object animatation loader.
9af3d8a238 MUTATIONOFJB: Implement UI for inventory.
c25ed89572 MUTATIONOFJB: Refactor inventory UI into separate widget, add button widgets.
29a809d691 MUTATIONOFJB: Add rename command.
5290d9a74b MUTATIONOFJB: Draw HUD background.
61c106b330 MUTATIONOFJB: Add font support and conversation widget.
2fb867b2f5 MUTATIONOFJB: Fix issue with parsing #MACRO and #STARTUP right after end block command.
f102667fc2 MUTATIONOFJB: Add support for DEFINE_STRUCT script command.
20d6d71ec9 MUTATIONOFJB: Basic conversation support.
d2e354b51f MUTATIONOFJB: Implement scroll buttons.
febff83a4e MUTATIONOFJB: Draw objects (first frame only) and improve conversation support.
3b614f0832 MUTATIONOFJB: Implement RANDOM command.
296835f84a MUTATIONOFJB: Draw object animations on map scene.
d22da95282 MUTATIONOFJB: Fix multiple RANDOM commands in one script.
d358a65bbc MUTATIONOFJB: Run extra sections from conversation.
eaba12cecd MUTATIONOFJB: Use the vanilla cursor.
2cd1728f42 MUTATIONOFJB: Add support for repeating choices.
2ee0a90059 MUTATIONOFJB: Change cursor color when it's under entity.
74ef0d9cfe MUTATIONOFJB: Correctly handle empty animation frames.
f70eb01061 MUTATIONOFJB: Add null check.
f94ff7aa8e MUTATIONOFJB: Implement word wrapping for subtitles.
cda1f0dd3a MUTATIONOFJB: Animate objects.
578a6794de MUTATIONOFJB: Improve documentation, rename cryptic variables.
9aa911314f MUTATIONOFJB: Handle hardcoded animations.
96fbe2f881 MUTATIONOFJB: Fix crash when static/door name is set to empty string.
215b87ccca MUTATIONOFJB: When redrawing room, draw object animations at their current frame instead of their first frame.
6c4ae7f198 MUTATIONOFJB: Implement multiple speeches in one response line.
2e656e69b3 MUTATIONOFJB: Blit with threshold.
3306cbfeaa MUTATIONOFJB: Implement SayCommand::execute.
32df911b4d MUTATIONOFJB: Implement SETCOL command.
4fbbaf944a MUTATIONOFJB: Extend blit_if to support both ManagedSurface and Surface.
cd15dd82a2 MUTATIONOFJB: Check for out of bounds destination in blit_if.
298bfc3d10 MUTATIONOFJB: Subclass Graphics::Font to reuse existing code.
6ff609c514 MUTATIONOFJB: Improve documentation for statics.
a25715a29b MUTATIONOFJB: Fix code formatting issues (with astyle).
4633b83986 MUTATIONOFJB: Improve documentation and naming.
9f1c628d4b MUTATIONOFJB: Fix forward declarations of structs.
561309eaa2 MUTATIONOFJB: Fix missing lines between block ends.
959f37dfe4 MUTATIONOFJB: Don't mark internal strings as translatable.
cf878d8777 MUTATIONOFJB: Change old-style C casts to static_cast.
696b61c146 MUTATIONOFJB: Move method comments to headers.
0e90d6eae3 MUTATIONOFJB: Use advanced detector.
b00395b0b9 MUTATIONOFJB: Fix MSVC warnings.
Commit: 764ee3a5a3f9f600b8d369d8474d2702b22f73f7
https://github.com/scummvm/scummvm/commit/764ee3a5a3f9f600b8d369d8474d2702b22f73f7
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Base for new engine
Changed paths:
A engines/mutationofjb/configure.engine
A engines/mutationofjb/detection.cpp
A engines/mutationofjb/module.mk
A engines/mutationofjb/mutationofjb.cpp
A engines/mutationofjb/mutationofjb.h
diff --git a/engines/mutationofjb/configure.engine b/engines/mutationofjb/configure.engine
new file mode 100644
index 0000000..499e078
--- /dev/null
+++ b/engines/mutationofjb/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine mutationofjb "Mutation of JB" no
diff --git a/engines/mutationofjb/detection.cpp b/engines/mutationofjb/detection.cpp
new file mode 100644
index 0000000..f95f696
--- /dev/null
+++ b/engines/mutationofjb/detection.cpp
@@ -0,0 +1,113 @@
+/* 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/mutationofjb.h"
+
+#include "common/config-manager.h"
+
+#include "engines/metaengine.h"
+
+static const PlainGameDescriptor mutationofjb_setting[] = {
+ {"mutationofjb", "Mutation of J.B."},
+ {0, 0}
+};
+
+class MutationOfJBMetaEngine : public MetaEngine {
+public:
+ virtual const char *getName() const {
+ return "Mutation of J.B.";
+ }
+
+ virtual const char *getOriginalCopyright() const {
+ return "Mutation of J.B. (C) 1996 RIKI Computer Games";
+ }
+
+ virtual PlainGameList getSupportedGames() const {
+ PlainGameList games;
+ const PlainGameDescriptor *g = mutationofjb_setting;
+ while (g->gameId) {
+ games.push_back(*g);
+ g++;
+ }
+
+ return games;
+ }
+
+ virtual PlainGameDescriptor findGame(const char *gameid) const {
+ const PlainGameDescriptor *g = mutationofjb_setting;
+ while (g->gameId) {
+ if (0 == scumm_stricmp(gameid, g->gameId))
+ return *g;
+ g++;
+ }
+ return PlainGameDescriptor::empty();
+ }
+
+ virtual DetectedGames detectGames(const Common::FSList &fslist) const {
+ DetectedGames detectedGames;
+
+ for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
+ if (!file->isDirectory()) {
+ const char *gameName = file->getName().c_str();
+
+ if (0 == scumm_stricmp("startup.dat", gameName)) {
+ detectedGames.push_back(DetectedGame(mutationofjb_setting[0]));
+ break;
+ }
+ }
+ }
+ return detectedGames;
+ }
+
+ virtual Common::Error createInstance(OSystem *syst, Engine **engine) const {
+ assert(syst);
+ assert(engine);
+
+ Common::FSList fslist;
+ Common::FSNode dir(ConfMan.get("path"));
+ if (!dir.getChildren(fslist, Common::FSNode::kListAll)) {
+ return Common::kNoGameDataFoundError;
+ }
+
+ // Invoke the detector
+ Common::String gameid = ConfMan.get("gameid");
+ DetectedGames detectedGames = detectGames(fslist);
+
+ for (uint i = 0; i < detectedGames.size(); i++) {
+ if (detectedGames[i].gameId == gameid) {
+ // At this point you may want to perform additional sanity checks.
+ *engine = new MutationOfJB::MutationOfJBEngine(syst);
+ return Common::kNoError;
+ }
+ }
+
+ // Failed to find any game data
+ return Common::kNoGameDataFoundError;
+ }
+};
+
+#if PLUGIN_ENABLED_DYNAMIC(MUTATIONOFJB)
+ REGISTER_PLUGIN_DYNAMIC(MUTATIONOFJB, PLUGIN_TYPE_ENGINE, MutationOfJBMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(MUTATIONOFJB, PLUGIN_TYPE_ENGINE, MutationOfJBMetaEngine);
+#endif
+
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
new file mode 100644
index 0000000..2e28d41
--- /dev/null
+++ b/engines/mutationofjb/module.mk
@@ -0,0 +1,13 @@
+MODULE := engines/mutationofjb
+
+MODULE_OBJS := \
+ detection.o \
+ mutationofjb.o
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_MUTATIONOFJB), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
new file mode 100644
index 0000000..f50ba70
--- /dev/null
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -0,0 +1,50 @@
+/* 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 "common/scummsys.h"
+
+#include "common/debug.h"
+#include "common/error.h"
+
+#include "engines/util.h"
+
+#include "mutationofjb/mutationofjb.h"
+
+namespace MutationOfJB {
+
+MutationOfJBEngine::MutationOfJBEngine(OSystem *syst)
+: Engine(syst), _console(nullptr) {
+ debug("MutationOfJBEngine::MutationOfJBEngine");
+}
+
+MutationOfJBEngine::~MutationOfJBEngine() {
+ debug("MutationOfJBEngine::~MutationOfJBEngine");
+}
+
+Common::Error MutationOfJBEngine::run() {
+ initGraphics(320, 200, false);
+ _console = new Console(this);
+ debug("MutationOfJBEngine::run");
+
+ return Common::kNoError;
+}
+}
diff --git a/engines/mutationofjb/mutationofjb.h b/engines/mutationofjb/mutationofjb.h
new file mode 100644
index 0000000..1c87fe4
--- /dev/null
+++ b/engines/mutationofjb/mutationofjb.h
@@ -0,0 +1,51 @@
+/* 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_MUTATIONOFJB_H
+#define MUTATIONOFJB_MUTATIONOFJB_H
+
+#include "engines/engine.h"
+#include "gui/debugger.h"
+
+namespace MutationOfJB {
+
+class Console;
+
+class MutationOfJBEngine : public Engine {
+public:
+ MutationOfJBEngine(OSystem *syst);
+ ~MutationOfJBEngine();
+
+ virtual Common::Error run();
+private:
+ Console *_console;
+};
+
+class Console : public GUI::Debugger {
+public:
+ Console(MutationOfJBEngine *vm) {}
+ virtual ~Console(void) {}
+};
+
+}
+
+#endif
Commit: 95cd6b74426b555e58577be0c46006a60fd77979
https://github.com/scummvm/scummvm/commit/95cd6b74426b555e58577be0c46006a60fd77979
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Load and draw scene background
Changed paths:
A engines/mutationofjb/encryptedfile.cpp
A engines/mutationofjb/encryptedfile.h
A engines/mutationofjb/room.cpp
A engines/mutationofjb/room.h
engines/mutationofjb/module.mk
engines/mutationofjb/mutationofjb.cpp
engines/mutationofjb/mutationofjb.h
diff --git a/engines/mutationofjb/encryptedfile.cpp b/engines/mutationofjb/encryptedfile.cpp
new file mode 100644
index 0000000..0796811
--- /dev/null
+++ b/engines/mutationofjb/encryptedfile.cpp
@@ -0,0 +1,64 @@
+/* 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 "encryptedfile.h"
+
+static const uint8 XOR_TABLE[] = {
+ 0x41, 0x2b, 0x7a, 0x0c, 0xc8, 0xe5, 0x0c, 0xde, 0x45, 0xa8, 0x00, 0xad,
+ 0x70, 0xac, 0x23, 0xe0, 0x0c, 0xde, 0xac, 0x16, 0xa1, 0x1a, 0x70, 0x17,
+ 0x1b, 0x90, 0x34, 0x6e, 0x53, 0xfe, 0xdd, 0x3c, 0xef, 0x74, 0x75, 0x3e,
+ 0x2e, 0xb0, 0x3d, 0x2b, 0x74, 0x6d, 0x59, 0xde, 0xc6, 0x20, 0xb8, 0xf3,
+ 0x7d, 0xfa, 0x4d, 0xbd, 0xdb, 0x3c, 0xc5, 0xcb, 0x57, 0x13, 0x40, 0x6b,
+ 0xb8, 0xad, 0xb9, 0xc1, 0x6a, 0x37, 0x39, 0x80, 0x94, 0xd3, 0xdf, 0x4b,
+ 0xe4, 0xe4, 0x7a, 0x4c, 0x0f, 0x21, 0x27, 0x9a, 0x7e, 0x52, 0x35, 0x58,
+ 0xb4, 0xbc, 0x5a, 0xc9, 0x48, 0x7f, 0xcc, 0xb6, 0x97, 0x7b, 0xf1, 0xd5,
+ 0x88, 0x8c, 0xa9, 0x27, 0xf7, 0x20, 0x68, 0x65, 0xad, 0x6f, 0x9e, 0x07,
+ 0xf8, 0xf6, 0x2c, 0x65, 0x4a, 0xe9, 0xd8, 0x13, 0x6a, 0xb5, 0x14, 0x6f,
+ 0x29, 0xdc, 0x68, 0xf8, 0xa0, 0xb6, 0x73, 0x03, 0x69, 0xe3, 0x4f, 0xb6,
+ 0x59, 0x79, 0xae, 0x93, 0xad, 0x40, 0x27, 0xd0, 0xb5, 0x7a, 0x68, 0x5d,
+ 0x5e, 0x19, 0x53, 0x4f, 0x40, 0x56, 0x3d, 0x10, 0xf8, 0x0a, 0xc6, 0x90,
+ 0x06, 0x45, 0x13, 0x4a, 0x6a, 0xfe, 0x56, 0xeb, 0xbc, 0xd9, 0xee, 0xe0,
+ 0x85, 0x5e, 0x98, 0x23, 0xf9, 0x19, 0x60, 0xf9, 0x7e, 0x8d, 0x61, 0xa0,
+ 0x7c, 0xe1, 0x84, 0xf2, 0x7a, 0xb8, 0xbe, 0x8e, 0x81, 0x9e, 0x87, 0x20,
+ 0x32, 0xf3, 0x8c, 0xb4, 0x2c, 0x4d, 0xc8, 0x50, 0x9b, 0xa5, 0x9c, 0x27,
+ 0x02, 0xd6, 0x7f, 0x2a, 0xaf, 0x46, 0x65, 0xd0, 0x6a, 0xae, 0xfa, 0x53,
+ 0x37, 0x6c, 0x49, 0xb9, 0x4d, 0xcd, 0x6c, 0x6b, 0xa7, 0x2d, 0x66, 0x32,
+ 0xb4, 0xf5, 0x41, 0xd5, 0x18, 0xc4, 0xfd, 0xbe, 0x8a, 0x47, 0x11, 0x50,
+ 0x3d, 0x97, 0x64, 0xda, 0x5a, 0x27, 0x18, 0x60, 0x78, 0x80, 0x86, 0x8a,
+ 0x2a, 0x72, 0x40, 0x89
+};
+
+namespace MutationOfJB {
+
+uint32 EncryptedFile::read(void *dataPtr, uint32 dataSize) {
+ uint8 xorPos = pos() % 256;
+ const uint32 readBytes = Common::File::read(dataPtr, dataSize);
+
+ for (uint32 i = 0; i < readBytes; ++i) {
+ static_cast<uint8 *>(dataPtr)[i] ^= XOR_TABLE[xorPos];
+ xorPos++;
+ }
+
+ return readBytes;
+}
+
+}
diff --git a/engines/mutationofjb/encryptedfile.h b/engines/mutationofjb/encryptedfile.h
new file mode 100644
index 0000000..69f6f62
--- /dev/null
+++ b/engines/mutationofjb/encryptedfile.h
@@ -0,0 +1,32 @@
+/* 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 "common/file.h"
+
+namespace MutationOfJB {
+
+class EncryptedFile : public Common::File {
+public:
+ virtual uint32 read(void *dataPtr, uint32 dataSize) override;
+};
+
+}
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 2e28d41..fcb9478 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -1,8 +1,10 @@
MODULE := engines/mutationofjb
MODULE_OBJS := \
+ encryptedfile.o \
detection.o \
- mutationofjb.o
+ mutationofjb.o \
+ room.o
# This module can be built as a plugin
ifeq ($(ENABLE_MUTATIONOFJB), DYNAMIC_PLUGIN)
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index f50ba70..0406864 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -24,15 +24,23 @@
#include "common/debug.h"
#include "common/error.h"
+#include "common/system.h"
+#include "common/events.h"
+#include "graphics/screen.h"
#include "engines/util.h"
#include "mutationofjb/mutationofjb.h"
+#include "mutationofjb/room.h"
namespace MutationOfJB {
MutationOfJBEngine::MutationOfJBEngine(OSystem *syst)
-: Engine(syst), _console(nullptr) {
+: Engine(syst),
+ _console(nullptr),
+ _room(nullptr),
+ _screen(nullptr)
+{
debug("MutationOfJBEngine::MutationOfJBEngine");
}
@@ -41,10 +49,20 @@ MutationOfJBEngine::~MutationOfJBEngine() {
}
Common::Error MutationOfJBEngine::run() {
- initGraphics(320, 200, false);
- _console = new Console(this);
debug("MutationOfJBEngine::run");
+ initGraphics(320, 200);
+ _console = new Console(this);
+ _screen = new Graphics::Screen;
+ _room = new Room(_screen);
+ _room->load(13, false);
+
+ while(!shouldQuit()) {
+ Common::Event event;
+ while (_eventMan->pollEvent(event));
+ _system->delayMillis(100);
+ }
+
return Common::kNoError;
}
}
diff --git a/engines/mutationofjb/mutationofjb.h b/engines/mutationofjb/mutationofjb.h
index 1c87fe4..815baf8 100644
--- a/engines/mutationofjb/mutationofjb.h
+++ b/engines/mutationofjb/mutationofjb.h
@@ -26,9 +26,14 @@
#include "engines/engine.h"
#include "gui/debugger.h"
+namespace Graphics {
+ class Screen;
+}
+
namespace MutationOfJB {
class Console;
+class Room;
class MutationOfJBEngine : public Engine {
public:
@@ -38,6 +43,8 @@ public:
virtual Common::Error run();
private:
Console *_console;
+ Room *_room;
+ Graphics::Screen *_screen;
};
class Console : public GUI::Debugger {
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
new file mode 100644
index 0000000..e927971
--- /dev/null
+++ b/engines/mutationofjb/room.cpp
@@ -0,0 +1,129 @@
+/* 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/room.h"
+#include "mutationofjb/encryptedfile.h"
+#include "graphics/screen.h"
+#include "engines/engine.h"
+#include "common/translation.h"
+
+namespace MutationOfJB {
+
+Room::Room(Graphics::Screen *screen) : _screen(screen) {}
+
+bool Room::load(uint8 roomNumber, bool roomB) {
+ EncryptedFile file;
+ Common::String fileName = Common::String::format("room%d%s.dat", roomNumber, roomB ? "b" : "");
+
+ file.open(fileName);
+
+ if (!file.isOpen()) {
+ Common::String errorMessage = Common::String::format(_("Unable to locate the '%s' engine data file."), fileName.c_str());
+ GUIErrorMessage(errorMessage);
+ warning("%s", errorMessage.c_str());
+
+ return false;
+ }
+
+ file.seek(0x80);
+
+ while (!file.eos()) {
+ // Record.
+ const uint32 length = file.readUint32LE();
+ uint8 info[4] = {0};
+ file.read(info, 4);
+
+ // TODO Find out what these are.
+ uint32 unknown;
+ unknown = file.readUint32LE();
+ unknown = file.readUint32LE();
+
+ // Subrecords.
+ if (info[0] == 0xFA && info[1] == 0xF1) {
+ for (int i = 0; i < info[2]; ++i) {
+ const uint32 subLength = file.readUint32LE();
+ const uint16 type = file.readUint16LE();
+
+ if (type == 0x0B) {
+ loadPalette(file);
+ } else if (type == 0x0F) {
+ loadBackground(file, subLength - 6);
+ }
+ }
+ }
+ }
+
+ file.close();
+
+ return true;
+}
+
+void Room::loadPalette(EncryptedFile &file) {
+ uint32 unknown;
+
+ // TODO Find out what this is.
+ unknown = file.readUint32LE();
+
+ uint8 palette[PALETTE_SIZE];
+ file.read(palette, PALETTE_SIZE);
+
+ for (int j = 0; j < PALETTE_SIZE; ++j) {
+ palette[j] <<= 2; // Uses 6-bit colors.
+ }
+
+ _screen->setPalette(palette);
+}
+
+void Room::loadBackground(EncryptedFile &file, uint32 size) {
+ _screen->clear();
+
+ uint8 * const pixels = static_cast<uint8 *>(_screen->getPixels());
+ uint8 *ptr = pixels;
+ uint32 readBytes = 0;
+
+ while (readBytes != size) {
+ uint8 no = file.readByte();
+ readBytes++;
+ while (no--) {
+ uint8 n = file.readByte();
+ readBytes++;
+ if (n < 0x80) {
+ // RLE - Copy color n times.
+ uint8 color = file.readByte();
+ readBytes++;
+ while(n--) {
+ *ptr++ = color;
+ }
+ } else {
+ // Take next 0x100 - n bytes as they are.
+ const uint32 rawlen = 0x100 - n;
+ file.read(ptr, rawlen);
+ readBytes += rawlen;
+ ptr += rawlen;
+ }
+ }
+ }
+
+ _screen->update();
+}
+
+}
diff --git a/engines/mutationofjb/room.h b/engines/mutationofjb/room.h
new file mode 100644
index 0000000..7158580
--- /dev/null
+++ b/engines/mutationofjb/room.h
@@ -0,0 +1,49 @@
+/* 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_ROOM_H
+#define MUTATIONOFJB_ROOM_H
+
+#include "common/scummsys.h"
+
+namespace Graphics {
+ class Screen;
+}
+
+namespace MutationOfJB {
+
+class EncryptedFile;
+
+class Room {
+public:
+ Room(Graphics::Screen *screen);
+ bool load(uint8 roomNumber, bool roomB);
+private:
+ void loadPalette(EncryptedFile &file);
+ void loadBackground(EncryptedFile &file, uint32 size);
+
+ Graphics::Screen *_screen;
+};
+
+}
+
+#endif
Commit: 3696865e6910067e011500d09e0d0e44bab796c1
https://github.com/scummvm/scummvm/commit/3696865e6910067e011500d09e0d0e44bab796c1
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Load initial game state and allow room change
Changed paths:
A engines/mutationofjb/game.cpp
A engines/mutationofjb/game.h
A engines/mutationofjb/util.cpp
A engines/mutationofjb/util.h
engines/mutationofjb/module.mk
engines/mutationofjb/mutationofjb.cpp
engines/mutationofjb/mutationofjb.h
engines/mutationofjb/room.cpp
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
new file mode 100644
index 0000000..581077a
--- /dev/null
+++ b/engines/mutationofjb/game.cpp
@@ -0,0 +1,152 @@
+/* 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/game.h"
+#include "common/stream.h"
+#include "common/util.h"
+
+namespace MutationOfJB {
+
+static bool readString(Common::ReadStream &stream, char *str)
+{
+ char buf[MAX_STR_LENGTH];
+ memset(str, 0, MAX_STR_LENGTH + 1);
+
+ uint8 len = stream.readByte();
+ stream.read(buf, MAX_STR_LENGTH);
+
+ len = MIN(len, MAX_STR_LENGTH);
+ memcpy(str, buf, len);
+
+ return true;
+}
+
+bool Door::loadFromStream(Common::ReadStream &stream) {
+ readString(stream, _name);
+
+ _destSceneId = stream.readByte();
+ _destX = stream.readUint16LE();
+ _destY = stream.readUint16LE();
+ _x = stream.readUint16LE();
+ _y = stream.readByte();
+ _width = stream.readUint16LE();
+ _height = stream.readByte();
+ _walkToX = stream.readUint16LE();
+ _walkToY = stream.readByte();
+ _SP = stream.readByte();
+
+ return true;
+}
+
+bool Object::loadFromStream(Common::ReadStream &stream) {
+ _AC = stream.readByte();
+ _FA = stream.readByte();
+ _FR = stream.readByte();
+ _NA = stream.readByte();
+ _FS = stream.readByte();
+ _unknown = stream.readByte();
+ _CA = stream.readByte();
+ _x = stream.readUint16LE();
+ _y = stream.readByte();
+ _XL = stream.readUint16LE();
+ _YL = stream.readByte();
+ _WX = stream.readUint16LE();
+ _WY = stream.readByte();
+ _SP = stream.readByte();
+
+ return true;
+}
+
+bool Static::loadFromStream(Common::ReadStream &stream) {
+ _active = stream.readByte();
+ readString(stream, _name);
+ _x = stream.readUint16LE();
+ _y = stream.readByte();
+ _width = stream.readUint16LE();
+ _height = stream.readByte();
+ _walkToX = stream.readUint16LE();
+ _walkToY = stream.readByte();
+ _SP = stream.readByte();
+
+ return true;
+}
+
+bool Bitmap::loadFromStream(Common::ReadStream &stream) {
+ _unknown = stream.readByte();
+ _isVisible = stream.readByte();
+ _x1 = stream.readUint16LE();
+ _y1 = stream.readByte();
+ _x2 = stream.readUint16LE();
+ _y2 = stream.readByte();
+
+ return true;
+}
+
+bool SceneInfo::loadFromStream(Common::ReadStream &stream) {
+ int i;
+
+ _startup = stream.readByte();
+ _unknown001 = stream.readByte();
+ _unknown002 = stream.readByte();
+ _unknown003 = stream.readByte();
+ _DL = stream.readByte();
+
+ _noDoors = stream.readByte();
+ for (i = 0; i < ARRAYSIZE(_doors); ++i) {
+ _doors[i].loadFromStream(stream);
+ }
+
+ _noObjects = stream.readByte();
+ for (i = 0; i < ARRAYSIZE(_objects); ++i) {
+ _objects[i].loadFromStream(stream);
+ }
+
+ _noStatics = stream.readByte();
+ for (i = 0; i < ARRAYSIZE(_statics); ++i) {
+ _statics[i].loadFromStream(stream);
+ }
+
+ for (i = 0; i < ARRAYSIZE(_bitmaps); ++i) {
+ _bitmaps[i].loadFromStream(stream);
+ }
+
+ _obstacleY1 = stream.readByte();
+ _unknown386 = stream.readByte();
+ _palRotStart = stream.readByte();
+ _palRotEnd = stream.readByte();
+ _palRotPeriod = stream.readByte();
+ stream.read(_unknown38A, 80);
+
+ return true;
+}
+
+GameData::GameData() : _currentScene(0) {}
+
+bool GameData::loadFromStream(Common::ReadStream &stream) {
+ for (int i = 0; i < ARRAYSIZE(_scenes); ++i) {
+ _scenes[i].loadFromStream(stream);
+ }
+
+ return true;
+}
+
+}
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
new file mode 100644
index 0000000..d8f2079
--- /dev/null
+++ b/engines/mutationofjb/game.h
@@ -0,0 +1,134 @@
+/* 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 "common/scummsys.h"
+
+namespace Common
+{
+ class ReadStream;
+}
+
+namespace MutationOfJB
+{
+
+static const uint8 MAX_STR_LENGTH = 0x14;
+
+struct Door {
+ char _name[MAX_STR_LENGTH + 1];
+ uint8 _destSceneId;
+ uint16 _destX;
+ uint16 _destY;
+ uint16 _x;
+ uint8 _y;
+ uint16 _width;
+ uint8 _height;
+ uint16 _walkToX;
+ uint8 _walkToY;
+ uint8 _SP;
+
+ bool loadFromStream(Common::ReadStream &stream);
+};
+
+struct Object {
+ uint8 _AC;
+ uint8 _FA;
+ uint8 _FR;
+ uint8 _NA;
+ uint8 _FS;
+ uint8 _unknown;
+ uint8 _CA;
+ uint16 _x;
+ uint8 _y;
+ uint16 _XL;
+ uint8 _YL;
+ uint16 _WX;
+ uint8 _WY;
+ uint8 _SP;
+
+ bool loadFromStream(Common::ReadStream &stream);
+};
+
+struct Static {
+ uint8 _active;
+ char _name[MAX_STR_LENGTH + 1];
+ uint16 _x;
+ uint8 _y;
+ uint16 _width;
+ uint8 _height;
+ uint16 _walkToX;
+ uint8 _walkToY;
+ uint8 _SP;
+
+ bool loadFromStream(Common::ReadStream &stream);
+};
+
+struct Bitmap {
+ uint8 _unknown;
+ uint8 _isVisible;
+ uint16 _x1;
+ uint8 _y1;
+ uint16 _x2;
+ uint8 _y2;
+
+ bool loadFromStream(Common::ReadStream &stream);
+};
+
+
+struct SceneInfo {
+ uint8 _startup;
+ uint8 _unknown001;
+ uint8 _unknown002;
+ uint8 _unknown003;
+ uint8 _DL;
+
+ uint8 _noDoors;
+ Door _doors[5];
+
+ uint8 _noObjects;
+ Object _objects[9];
+
+ uint8 _noStatics;
+ Static _statics[15];
+
+ Bitmap _bitmaps[10];
+
+ uint8 _obstacleY1;
+ uint8 _unknown386;
+ uint8 _palRotStart;
+ uint8 _palRotEnd;
+ uint8 _palRotPeriod;
+ uint8 _unknown38A[80];
+
+ bool loadFromStream(Common::ReadStream &stream);
+};
+
+struct GameData
+{
+ GameData();
+
+ SceneInfo _scenes[45];
+ uint8 _currentScene;
+
+ bool loadFromStream(Common::ReadStream &stream);
+};
+
+}
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index fcb9478..7baea82 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -1,10 +1,12 @@
MODULE := engines/mutationofjb
MODULE_OBJS := \
- encryptedfile.o \
detection.o \
+ encryptedfile.o \
+ game.o \
mutationofjb.o \
- room.o
+ room.o \
+ util.o
# This module can be built as a plugin
ifeq ($(ENABLE_MUTATIONOFJB), DYNAMIC_PLUGIN)
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index 0406864..dc7f518 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -27,11 +27,15 @@
#include "common/system.h"
#include "common/events.h"
#include "graphics/screen.h"
+#include "graphics/cursorman.h"
#include "engines/util.h"
#include "mutationofjb/mutationofjb.h"
#include "mutationofjb/room.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/encryptedfile.h"
+#include "mutationofjb/util.h"
namespace MutationOfJB {
@@ -48,19 +52,73 @@ MutationOfJBEngine::~MutationOfJBEngine() {
debug("MutationOfJBEngine::~MutationOfJBEngine");
}
+bool MutationOfJBEngine::loadGameData(bool partB) {
+ EncryptedFile file;
+ const char *fileName = !partB ? "startup.dat" : "startupb.dat";
+ file.open(fileName);
+ if (!file.isOpen()) {
+ reportFileMissingError(fileName);
+ return false;
+ }
+
+ _gameData->loadFromStream(file);
+
+ file.close();
+
+ return true;
+}
+
+void MutationOfJBEngine::setupCursor()
+{
+ const uint8 white[] = {0xFF, 0xFF, 0xFF};
+ const uint8 cursor[] = {0xFF};
+
+ _screen->setPalette(white, 0xFF, 1);
+
+ CursorMan.disableCursorPalette(true);
+ CursorMan.pushCursor(cursor, 1, 1, 0, 0, 0);
+ CursorMan.showMouse(true);
+}
+
Common::Error MutationOfJBEngine::run() {
debug("MutationOfJBEngine::run");
initGraphics(320, 200);
+
_console = new Console(this);
_screen = new Graphics::Screen;
+ setupCursor();
+
+ _gameData = new GameData;
+ _gameData->_currentScene = 13;
+ loadGameData(false);
+
_room = new Room(_screen);
- _room->load(13, false);
+ _room->load(_gameData->_currentScene, false);
while(!shouldQuit()) {
Common::Event event;
- while (_eventMan->pollEvent(event));
- _system->delayMillis(100);
+ while (_eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ {
+ const SceneInfo &sceneInfo = _gameData->_scenes[_gameData->_currentScene - 1];
+ for (int i = 0; i < MIN(ARRAYSIZE(sceneInfo._doors), (int) sceneInfo._noDoors); ++i) {
+ const Door &door = sceneInfo._doors[i];
+ if ((event.mouse.x >= door._x) && (event.mouse.x < door._x + door._width) && (event.mouse.y >= door._y) && (event.mouse.y < door._y + door._height)) {
+ _gameData->_currentScene = door._destSceneId;
+ _room->load(_gameData->_currentScene, false);
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ _system->delayMillis(40);
+ _screen->update();
}
return Common::kNoError;
diff --git a/engines/mutationofjb/mutationofjb.h b/engines/mutationofjb/mutationofjb.h
index 815baf8..75bd678 100644
--- a/engines/mutationofjb/mutationofjb.h
+++ b/engines/mutationofjb/mutationofjb.h
@@ -34,6 +34,7 @@ namespace MutationOfJB {
class Console;
class Room;
+struct GameData;
class MutationOfJBEngine : public Engine {
public:
@@ -42,8 +43,12 @@ public:
virtual Common::Error run();
private:
+ bool loadGameData(bool partB);
+ void setupCursor();
+
Console *_console;
Room *_room;
+ GameData *_gameData;
Graphics::Screen *_screen;
};
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
index e927971..298a54b 100644
--- a/engines/mutationofjb/room.cpp
+++ b/engines/mutationofjb/room.cpp
@@ -22,9 +22,9 @@
#include "mutationofjb/room.h"
#include "mutationofjb/encryptedfile.h"
+#include "mutationofjb/util.h"
+#include "common/str.h"
#include "graphics/screen.h"
-#include "engines/engine.h"
-#include "common/translation.h"
namespace MutationOfJB {
@@ -37,9 +37,7 @@ bool Room::load(uint8 roomNumber, bool roomB) {
file.open(fileName);
if (!file.isOpen()) {
- Common::String errorMessage = Common::String::format(_("Unable to locate the '%s' engine data file."), fileName.c_str());
- GUIErrorMessage(errorMessage);
- warning("%s", errorMessage.c_str());
+ reportFileMissingError(fileName.c_str());
return false;
}
@@ -90,7 +88,7 @@ void Room::loadPalette(EncryptedFile &file) {
palette[j] <<= 2; // Uses 6-bit colors.
}
- _screen->setPalette(palette);
+ _screen->setPalette(palette, 0x00, 0xBF); // Load only 0xBF colors.
}
void Room::loadBackground(EncryptedFile &file, uint32 size) {
diff --git a/engines/mutationofjb/util.cpp b/engines/mutationofjb/util.cpp
new file mode 100644
index 0000000..41d2a3a
--- /dev/null
+++ b/engines/mutationofjb/util.cpp
@@ -0,0 +1,35 @@
+/* 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/util.h"
+#include "common/str.h"
+#include "common/translation.h"
+#include "engines/engine.h"
+
+namespace MutationOfJB {
+ void reportFileMissingError(const char *fileName) {
+ Common::String errorMessage = Common::String::format(_("Unable to locate the '%s' engine data file."), fileName);
+ GUIErrorMessage(errorMessage);
+ warning("%s", errorMessage.c_str());
+ }
+}
+
diff --git a/engines/mutationofjb/util.h b/engines/mutationofjb/util.h
new file mode 100644
index 0000000..3059d51
--- /dev/null
+++ b/engines/mutationofjb/util.h
@@ -0,0 +1,25 @@
+/* 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.
+ *
+ */
+
+namespace MutationOfJB {
+ void reportFileMissingError(const char *fileName);
+}
Commit: 356a6809c31224f4ed2bfcc5e6bacd131f144026
https://github.com/scummvm/scummvm/commit/356a6809c31224f4ed2bfcc5e6bacd131f144026
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Fix loading room 11 (and possibly some others).
Changed paths:
engines/mutationofjb/room.cpp
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
index 298a54b..95a1a49 100644
--- a/engines/mutationofjb/room.cpp
+++ b/engines/mutationofjb/room.cpp
@@ -24,6 +24,7 @@
#include "mutationofjb/encryptedfile.h"
#include "mutationofjb/util.h"
#include "common/str.h"
+#include "common/translation.h"
#include "graphics/screen.h"
namespace MutationOfJB {
@@ -65,6 +66,9 @@ bool Room::load(uint8 roomNumber, bool roomB) {
loadPalette(file);
} else if (type == 0x0F) {
loadBackground(file, subLength - 6);
+ } else {
+ debug(_("Unsupported record type %02X."), type);
+ file.seek(subLength - 6, SEEK_CUR);
}
}
}
@@ -88,7 +92,7 @@ void Room::loadPalette(EncryptedFile &file) {
palette[j] <<= 2; // Uses 6-bit colors.
}
- _screen->setPalette(palette, 0x00, 0xBF); // Load only 0xBF colors.
+ _screen->setPalette(palette, 0x00, 0xC0); // Load only 0xC0 colors.
}
void Room::loadBackground(EncryptedFile &file, uint32 size) {
@@ -97,8 +101,15 @@ void Room::loadBackground(EncryptedFile &file, uint32 size) {
uint8 * const pixels = static_cast<uint8 *>(_screen->getPixels());
uint8 *ptr = pixels;
uint32 readBytes = 0;
+ uint32 lines = 0;
while (readBytes != size) {
+ if (lines == 200) {
+ // Some background files have an unknown byte at the end,
+ // so break when we encounter all 200 lines.
+ break;
+ }
+
uint8 no = file.readByte();
readBytes++;
while (no--) {
@@ -119,6 +130,7 @@ void Room::loadBackground(EncryptedFile &file, uint32 size) {
ptr += rawlen;
}
}
+ lines++;
}
_screen->update();
Commit: f7d5a825a053199ddbf4d7c564e84e9f9709d958
https://github.com/scummvm/scummvm/commit/f7d5a825a053199ddbf4d7c564e84e9f9709d958
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Start implementation of ATN scripts (IF command).
Changed paths:
A engines/mutationofjb/commands/command.cpp
A engines/mutationofjb/commands/command.h
A engines/mutationofjb/commands/conditionalcommand.cpp
A engines/mutationofjb/commands/conditionalcommand.h
A engines/mutationofjb/commands/ifcommand.cpp
A engines/mutationofjb/commands/ifcommand.h
A engines/mutationofjb/commands/seqcommand.cpp
A engines/mutationofjb/commands/seqcommand.h
A engines/mutationofjb/script.cpp
A engines/mutationofjb/script.h
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/module.mk
engines/mutationofjb/mutationofjb.cpp
engines/mutationofjb/room.cpp
diff --git a/engines/mutationofjb/commands/command.cpp b/engines/mutationofjb/commands/command.cpp
new file mode 100644
index 0000000..d0b3f82
--- /dev/null
+++ b/engines/mutationofjb/commands/command.cpp
@@ -0,0 +1,33 @@
+/* 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/command.h"
+#include "common/scummsys.h"
+
+namespace MutationOfJB {
+Command::~Command() {}
+
+SeqCommand *Command::asSeqCommand() {
+ return nullptr;
+}
+
+}
diff --git a/engines/mutationofjb/commands/command.h b/engines/mutationofjb/commands/command.h
new file mode 100644
index 0000000..beae9d2
--- /dev/null
+++ b/engines/mutationofjb/commands/command.h
@@ -0,0 +1,58 @@
+/* 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_COMMAND_H
+#define MUTATIONOFJB_COMMAND_H
+
+namespace Common {
+ class String;
+}
+
+namespace MutationOfJB {
+
+class GameData;
+class SeqCommand;
+class IfCommand;
+class CallMacroCommand;
+class ScriptParseContext;
+class Command;
+
+typedef bool (*CommandParseFunc)(const Common::String &line, ScriptParseContext &parseContext, Command *&command);
+
+class Command {
+public:
+ enum ExecuteResult {
+ None,
+ Finished,
+ InProgress
+ };
+
+ virtual ~Command();
+
+ virtual ExecuteResult execute(GameData &gameData) = 0;
+ virtual Command *next() const = 0;
+
+ virtual SeqCommand *asSeqCommand();
+};
+}
+
+#endif
diff --git a/engines/mutationofjb/commands/conditionalcommand.cpp b/engines/mutationofjb/commands/conditionalcommand.cpp
new file mode 100644
index 0000000..3118e6d
--- /dev/null
+++ b/engines/mutationofjb/commands/conditionalcommand.cpp
@@ -0,0 +1,41 @@
+/* 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/conditionalcommand.h"
+#include "common/scummsys.h"
+
+namespace MutationOfJB {
+
+ConditionalCommand::ConditionalCommand() :
+ _trueCommand(nullptr),
+ _falseCommand(nullptr),
+ _cachedResult(false)
+{}
+
+Command *ConditionalCommand::next() const {
+ if (_cachedResult) {
+ return _trueCommand;
+ } else {
+ return _falseCommand;
+ }
+}
+};
diff --git a/engines/mutationofjb/commands/conditionalcommand.h b/engines/mutationofjb/commands/conditionalcommand.h
new file mode 100644
index 0000000..e355662
--- /dev/null
+++ b/engines/mutationofjb/commands/conditionalcommand.h
@@ -0,0 +1,41 @@
+/* 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/command.h"
+#include "common/scummsys.h"
+
+namespace MutationOfJB {
+
+class ConditionalCommand : public Command {
+public:
+ ConditionalCommand();
+ void setTrueCommand(Command *command);
+ void setFalseCommand(Command *command);
+
+ virtual Command *next() const override;
+protected:
+ Command *_trueCommand;
+ Command *_falseCommand;
+ bool _cachedResult;
+};
+
+}
diff --git a/engines/mutationofjb/commands/ifcommand.cpp b/engines/mutationofjb/commands/ifcommand.cpp
new file mode 100644
index 0000000..18b8081
--- /dev/null
+++ b/engines/mutationofjb/commands/ifcommand.cpp
@@ -0,0 +1,88 @@
+/* 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/ifcommand.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/script.h"
+#include "common/str.h"
+#include "common/translation.h"
+
+namespace MutationOfJB {
+
+bool IfCommand::ParseFunc(const Common::String &line, ScriptParseContext &parseContext, Command *&command)
+{
+ // IFtss oo val!
+ // <t> 1B Tag.
+ // <ss> 2B Scene.
+ // <oo> 2B Object ID.
+ // <val> VL Value.
+ // ! 1B Negation (optional).
+
+ if (line.size() < 10) {
+ return false;
+ }
+
+ if (strncmp(line.c_str(), "IF", 2) != 0) {
+ return false;
+ }
+
+ const char *const cstr = line.c_str();
+ const char tag = cstr[2];
+ const uint8 sceneId = atoi(cstr + 3);
+ const uint8 objectId = atoi(cstr + 6);
+ const uint8 value = atoi(cstr + 9);
+ const bool negative = (line.lastChar() == '!');
+
+ IfCommand *ifCommand = new IfCommand(sceneId, objectId, value, negative);
+
+ command = ifCommand;
+ parseContext.addConditionalCommand(ifCommand, tag);
+ return true;
+}
+
+IfCommand::IfCommand(uint8 sceneId, uint8 objectId, uint16 value, bool negative) :
+ _sceneId(sceneId),
+ _objectId(objectId),
+ _value(value),
+ _negative(negative)
+{}
+
+Command::ExecuteResult IfCommand::execute(GameData &gameData) {
+ Scene* const scene = gameData.getScene(_sceneId);
+ if (!scene) {
+ return Finished;
+ }
+
+ Object* const object = scene->getObject(_objectId);
+ if (!object) {
+ return Finished;
+ }
+
+ _cachedResult = (object->_WX == _value);
+ if (_negative) {
+ _cachedResult = !_cachedResult;
+ }
+
+ return Finished;
+}
+}
+
diff --git a/engines/mutationofjb/commands/ifcommand.h b/engines/mutationofjb/commands/ifcommand.h
new file mode 100644
index 0000000..d33f34f
--- /dev/null
+++ b/engines/mutationofjb/commands/ifcommand.h
@@ -0,0 +1,52 @@
+/* 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_IFCOMMAND_H
+#define MUTATIONOFJB_IFCOMMAND_H
+
+#include "mutationofjb/commands/conditionalcommand.h"
+#include "common/scummsys.h"
+
+namespace MutationOfJB {
+
+class ScriptParseContext;
+
+class IfCommand : public ConditionalCommand {
+public:
+ static bool ParseFunc(const Common::String &line, ScriptParseContext &parseContext, Command *&command);
+
+ IfCommand(uint8 sceneId, uint8 objectId, uint16 value, bool negative);
+
+ virtual ExecuteResult execute(GameData &gameData) override;
+
+private:
+ uint8 _sceneId;
+ uint8 _objectId;
+ uint16 _value;
+ bool _negative;
+
+ bool _cachedResult;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/commands/seqcommand.cpp b/engines/mutationofjb/commands/seqcommand.cpp
new file mode 100644
index 0000000..ab98497
--- /dev/null
+++ b/engines/mutationofjb/commands/seqcommand.cpp
@@ -0,0 +1,40 @@
+/* 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 "seqcommand.h"
+
+namespace MutationOfJB {
+
+void SeqCommand::setNextCommand(Command *nextCommand)
+{
+ _nextCommand = nextCommand;
+}
+
+Command *SeqCommand::next() const {
+ return _nextCommand;
+}
+
+SeqCommand *SeqCommand::asSeqCommand() {
+ return this;
+}
+
+}
diff --git a/engines/mutationofjb/commands/seqcommand.h b/engines/mutationofjb/commands/seqcommand.h
new file mode 100644
index 0000000..b247fb2
--- /dev/null
+++ b/engines/mutationofjb/commands/seqcommand.h
@@ -0,0 +1,44 @@
+/* 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_SEQCOMMAND_H
+#define MUTATIONOFJB_SEQCOMMAND_H
+
+#include "mutationofjb/commands/command.h"
+#include "common/scummsys.h"
+
+namespace MutationOfJB {
+
+class SeqCommand : public Command {
+public:
+ void setNextCommand(Command *nextCommand);
+ virtual Command *next() const override;
+ virtual SeqCommand *asSeqCommand();
+
+private:
+ Command *_nextCommand;
+};
+
+}
+
+#endif
+
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 581077a..740fb1c 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -23,6 +23,7 @@
#include "mutationofjb/game.h"
#include "common/stream.h"
#include "common/util.h"
+#include "common/translation.h"
namespace MutationOfJB {
@@ -101,7 +102,7 @@ bool Bitmap::loadFromStream(Common::ReadStream &stream) {
return true;
}
-bool SceneInfo::loadFromStream(Common::ReadStream &stream) {
+bool Scene::loadFromStream(Common::ReadStream &stream) {
int i;
_startup = stream.readByte();
@@ -111,16 +112,19 @@ bool SceneInfo::loadFromStream(Common::ReadStream &stream) {
_DL = stream.readByte();
_noDoors = stream.readByte();
+ _noDoors = MIN(_noDoors, (uint8) ARRAYSIZE(_doors));
for (i = 0; i < ARRAYSIZE(_doors); ++i) {
_doors[i].loadFromStream(stream);
}
_noObjects = stream.readByte();
+ _noObjects = MIN(_noObjects, (uint8) ARRAYSIZE(_objects));
for (i = 0; i < ARRAYSIZE(_objects); ++i) {
_objects[i].loadFromStream(stream);
}
_noStatics = stream.readByte();
+ _noStatics = MIN(_noStatics, (uint8) ARRAYSIZE(_statics));
for (i = 0; i < ARRAYSIZE(_statics); ++i) {
_statics[i].loadFromStream(stream);
}
@@ -139,8 +143,27 @@ bool SceneInfo::loadFromStream(Common::ReadStream &stream) {
return true;
}
+Object *Scene::getObject(uint8 objectId) {
+ if (objectId == 0 || objectId > _noObjects) {
+ warning(_("Object %d does not exist"), objectId);
+ return nullptr;
+ }
+
+ return &_objects[objectId - 1];
+}
+
GameData::GameData() : _currentScene(0) {}
+Scene *GameData::getScene(uint8 sceneId)
+{
+ if (sceneId == 0 || sceneId > ARRAYSIZE(_scenes)) {
+ warning(_("Scene %d does not exist"), sceneId);
+ return nullptr;
+ }
+
+ return &_scenes[sceneId - 1];
+}
+
bool GameData::loadFromStream(Common::ReadStream &stream) {
for (int i = 0; i < ARRAYSIZE(_scenes); ++i) {
_scenes[i].loadFromStream(stream);
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index d8f2079..d49a966 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -22,13 +22,11 @@
#include "common/scummsys.h"
-namespace Common
-{
+namespace Common {
class ReadStream;
}
-namespace MutationOfJB
-{
+namespace MutationOfJB {
static const uint8 MAX_STR_LENGTH = 0x14;
@@ -93,7 +91,10 @@ struct Bitmap {
};
-struct SceneInfo {
+struct Scene {
+
+ Object *getObject(uint8 objectId);
+
uint8 _startup;
uint8 _unknown001;
uint8 _unknown002;
@@ -123,12 +124,16 @@ struct SceneInfo {
struct GameData
{
+public:
GameData();
+ Scene *getScene(uint8 sceneId);
+
+ bool loadFromStream(Common::ReadStream &stream);
- SceneInfo _scenes[45];
uint8 _currentScene;
+private:
+ Scene _scenes[45];
- bool loadFromStream(Common::ReadStream &stream);
};
}
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 7baea82..e6c539a 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -1,11 +1,16 @@
MODULE := engines/mutationofjb
MODULE_OBJS := \
+ commands/command.o \
+ commands/conditionalcommand.o \
+ commands/ifcommand.o \
+ commands/seqcommand.o \
detection.o \
encryptedfile.o \
game.o \
mutationofjb.o \
room.o \
+ script.o \
util.o
# This module can be built as a plugin
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index dc7f518..cdefbb9 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -102,12 +102,14 @@ Common::Error MutationOfJBEngine::run() {
switch (event.type) {
case Common::EVENT_LBUTTONDOWN:
{
- const SceneInfo &sceneInfo = _gameData->_scenes[_gameData->_currentScene - 1];
- for (int i = 0; i < MIN(ARRAYSIZE(sceneInfo._doors), (int) sceneInfo._noDoors); ++i) {
- const Door &door = sceneInfo._doors[i];
- if ((event.mouse.x >= door._x) && (event.mouse.x < door._x + door._width) && (event.mouse.y >= door._y) && (event.mouse.y < door._y + door._height)) {
- _gameData->_currentScene = door._destSceneId;
- _room->load(_gameData->_currentScene, false);
+ const Scene* const scene = _gameData->getScene(_gameData->_currentScene);
+ if (scene) {
+ for (int i = 0; i < MIN(ARRAYSIZE(scene->_doors), (int) scene->_noDoors); ++i) {
+ const Door &door = scene->_doors[i];
+ if ((event.mouse.x >= door._x) && (event.mouse.x < door._x + door._width) && (event.mouse.y >= door._y) && (event.mouse.y < door._y + door._height)) {
+ _gameData->_currentScene = door._destSceneId;
+ _room->load(_gameData->_currentScene, false);
+ }
}
}
break;
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
index 95a1a49..eae430a 100644
--- a/engines/mutationofjb/room.cpp
+++ b/engines/mutationofjb/room.cpp
@@ -132,6 +132,9 @@ void Room::loadBackground(EncryptedFile &file, uint32 size) {
}
lines++;
}
+ if (readBytes < size) {
+ file.seek(size - readBytes, SEEK_CUR);
+ }
_screen->update();
}
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
new file mode 100644
index 0000000..0280c86
--- /dev/null
+++ b/engines/mutationofjb/script.cpp
@@ -0,0 +1,75 @@
+/* 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 "script.h"
+
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+#include "common/stream.h"
+#include "mutationofjb/commands/command.h"
+
+namespace MutationOfJB {
+
+static CommandParseFunc* getParseFuncs() {
+ static CommandParseFunc funcs[] = {
+ nullptr
+ };
+
+ return funcs;
+}
+
+
+ScriptParseContext::ScriptParseContext(Common::SeekableReadStream &stream) : _stream(stream) {}
+
+bool ScriptParseContext::readLine(Common::String &line) {
+ do {
+ Common::String str = _stream.readLine();
+ if (str.empty() || str[0] != '.') {
+ line = str;
+ if (line[0] == '*') {
+ line.deleteChar(0);
+ }
+ return true;
+ }
+ } while(_stream.eos());
+
+ return false;
+}
+
+void ScriptParseContext::addConditionalCommand(ConditionalCommand *command, char tag) {
+ ConditionalCommandInfo cmi = {command, tag};
+ _pendingCondCommands.push_back(cmi);
+}
+
+bool Script::loadFromStream(Common::SeekableReadStream &stream) {
+
+ CommandParseFunc * const parseFuncs = getParseFuncs();
+
+ ScriptParseContext parseCtx(stream);
+
+ Common::HashMap<Common::String, Command *> macros;
+ Common::HashMap<Common::String, Command *> labels;
+
+ return true;
+}
+
+}
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
new file mode 100644
index 0000000..9c0f0f3
--- /dev/null
+++ b/engines/mutationofjb/script.h
@@ -0,0 +1,64 @@
+/* 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_SCRIPT_H
+#define MUTATIONOFJB_SCRIPT_H
+
+#include "common/array.h"
+
+namespace Common {
+ class SeekableReadStream;
+ class String;
+}
+
+namespace MutationOfJB {
+
+class ConditionalCommand;
+
+class ScriptParseContext
+{
+public:
+ ScriptParseContext(Common::SeekableReadStream &stream);
+ bool readLine(Common::String &line);
+ void addConditionalCommand(ConditionalCommand *command, char tag);
+ //void setLastIfCommand(IfCommand *command);
+
+private:
+ Common::SeekableReadStream &_stream;
+
+ struct ConditionalCommandInfo {
+ ConditionalCommand *command;
+ char tag;
+ };
+ Common::Array<ConditionalCommandInfo> _pendingCondCommands;
+};
+
+class Script {
+public:
+ bool loadFromStream(Common::SeekableReadStream &stream);
+private:
+
+};
+
+}
+
+#endif
Commit: 3672ea55720666acfd64b6df01b35d0727d6be78
https://github.com/scummvm/scummvm/commit/3672ea55720666acfd64b6df01b35d0727d6be78
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Continue implementation of if/else script commands.
Changed paths:
A engines/mutationofjb/commands/endblockcommand.cpp
A engines/mutationofjb/commands/endblockcommand.h
engines/mutationofjb/commands/command.cpp
engines/mutationofjb/commands/command.h
engines/mutationofjb/commands/conditionalcommand.cpp
engines/mutationofjb/commands/conditionalcommand.h
engines/mutationofjb/commands/ifcommand.cpp
engines/mutationofjb/commands/ifcommand.h
engines/mutationofjb/commands/seqcommand.cpp
engines/mutationofjb/commands/seqcommand.h
engines/mutationofjb/module.mk
engines/mutationofjb/mutationofjb.cpp
engines/mutationofjb/script.cpp
engines/mutationofjb/script.h
diff --git a/engines/mutationofjb/commands/command.cpp b/engines/mutationofjb/commands/command.cpp
index d0b3f82..af4c28e 100644
--- a/engines/mutationofjb/commands/command.cpp
+++ b/engines/mutationofjb/commands/command.cpp
@@ -24,6 +24,10 @@
#include "common/scummsys.h"
namespace MutationOfJB {
+
+void CommandParser::transition(ScriptParseContext &, Command *, Command *) {}
+CommandParser::~CommandParser() {}
+
Command::~Command() {}
SeqCommand *Command::asSeqCommand() {
diff --git a/engines/mutationofjb/commands/command.h b/engines/mutationofjb/commands/command.h
index beae9d2..ab0ebc6 100644
--- a/engines/mutationofjb/commands/command.h
+++ b/engines/mutationofjb/commands/command.h
@@ -38,6 +38,15 @@ class Command;
typedef bool (*CommandParseFunc)(const Common::String &line, ScriptParseContext &parseContext, Command *&command);
+class CommandParser {
+public:
+ virtual ~CommandParser();
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) = 0;
+
+ /* Old command - created by this parser. */
+ virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand);
+};
+
class Command {
public:
enum ExecuteResult {
diff --git a/engines/mutationofjb/commands/conditionalcommand.cpp b/engines/mutationofjb/commands/conditionalcommand.cpp
index 3118e6d..13ea674 100644
--- a/engines/mutationofjb/commands/conditionalcommand.cpp
+++ b/engines/mutationofjb/commands/conditionalcommand.cpp
@@ -31,6 +31,23 @@ ConditionalCommand::ConditionalCommand() :
_cachedResult(false)
{}
+
+Command *ConditionalCommand::getTrueCommand() const {
+ return _trueCommand;
+}
+
+Command *ConditionalCommand::getFalseCommand() const {
+ return _falseCommand;
+}
+
+void ConditionalCommand::setTrueCommand(Command *command) {
+ _trueCommand = command;
+}
+
+void ConditionalCommand::setFalseCommand(Command *command) {
+ _falseCommand = command;
+}
+
Command *ConditionalCommand::next() const {
if (_cachedResult) {
return _trueCommand;
@@ -38,4 +55,4 @@ Command *ConditionalCommand::next() const {
return _falseCommand;
}
}
-};
+}
diff --git a/engines/mutationofjb/commands/conditionalcommand.h b/engines/mutationofjb/commands/conditionalcommand.h
index e355662..27a8ac1 100644
--- a/engines/mutationofjb/commands/conditionalcommand.h
+++ b/engines/mutationofjb/commands/conditionalcommand.h
@@ -28,6 +28,10 @@ namespace MutationOfJB {
class ConditionalCommand : public Command {
public:
ConditionalCommand();
+
+ Command *getTrueCommand() const;
+ Command *getFalseCommand() const;
+
void setTrueCommand(Command *command);
void setFalseCommand(Command *command);
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
new file mode 100644
index 0000000..218be1a
--- /dev/null
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -0,0 +1,108 @@
+/* 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/endblockcommand.h"
+#include "mutationofjb/script.h"
+#include "mutationofjb/commands/conditionalcommand.h"
+#include "common/str.h"
+#include "common/debug.h"
+
+namespace MutationOfJB {
+
+bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *& command) {
+ if (line.empty()) {
+ return false;
+ }
+
+ const char firstChar = line.firstChar();
+ if (firstChar != '#' && firstChar != '=' && firstChar != '-') {
+ return false;
+ }
+
+ // This is the start or end of section/block.
+
+ if (line.size() >= 4 && (line.hasPrefix("#L ") || line.hasPrefix("-L "))) {
+ ScriptParseContext::ActionInfo ai = {ScriptParseContext::Look, line.c_str() + 3, "", firstChar == '#'};
+ parseCtx._actionInfos.push_back(ai);
+ debug("# Look: %s", line.c_str() + 3);
+ } else if (line.size() >= 4 && (line.hasPrefix("#W ") || line.hasPrefix("-W "))) {
+ ScriptParseContext::ActionInfo ai = {ScriptParseContext::Walk, line.c_str() + 3, "", firstChar == '#'};
+ parseCtx._actionInfos.push_back(ai);
+ } else if (line.size() >= 4 && (line.hasPrefix("#T ") || line.hasPrefix("-T "))) {
+ ScriptParseContext::ActionInfo ai = {ScriptParseContext::Talk, line.c_str() + 3, "", firstChar == '#'};
+ parseCtx._actionInfos.push_back(ai);
+ } else if (line.size() >= 4 && (line.hasPrefix("#U ") || line.hasPrefix("-U "))) {
+ int secondObjPos = -1;
+ for (int i = 3; i < (int) line.size(); ++i) {
+ if (line[i] == ' ') {
+ secondObjPos = i + 1;
+ break;
+ }
+ }
+ ScriptParseContext::ActionInfo ai = {
+ ScriptParseContext::Talk,
+ line.c_str() + 3,
+ (secondObjPos != -1) ? line.c_str() + secondObjPos : "",
+ firstChar == '#'
+ };
+ parseCtx._actionInfos.push_back(ai);
+ } else if ((line.hasPrefix("#ELSE") || line.hasPrefix("=ELSE"))) {
+ _elseFound = true;
+ _ifTag = 0;
+ if (line.size() >= 6) {
+ _ifTag = line[5];
+ }
+ }
+
+ command = new EndBlockCommand();
+
+ return true;
+}
+
+void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *, Command *newCommand) {
+ if (_elseFound) {
+ if (newCommand) {
+ ScriptParseContext::ConditionalCommandInfos::iterator it = parseCtx._pendingCondCommands.begin();
+
+ while (it != parseCtx._pendingCondCommands.end()) {
+ if (it->_tag == _ifTag) {
+ it->_command->setFalseCommand(newCommand);
+ it = parseCtx._pendingCondCommands.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+
+ _elseFound = false;
+ _ifTag = 0;
+ }
+}
+
+Command::ExecuteResult EndBlockCommand::execute(GameData &) {
+ return Finished;
+}
+
+Command *EndBlockCommand::next() const {
+ return nullptr;
+}
+}
diff --git a/engines/mutationofjb/commands/endblockcommand.h b/engines/mutationofjb/commands/endblockcommand.h
new file mode 100644
index 0000000..1ac636c
--- /dev/null
+++ b/engines/mutationofjb/commands/endblockcommand.h
@@ -0,0 +1,53 @@
+/* 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_ENDBLOCKCOMMAND_H
+#define MUTATIONOFJB_ENDBLOCKCOMMAND_H
+
+#include "mutationofjb/commands/command.h"
+#include "common/scummsys.h"
+
+namespace MutationOfJB {
+
+class EndBlockCommandParser : public CommandParser {
+public:
+ EndBlockCommandParser() : _elseFound(false), _ifTag(0) {}
+
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+ virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand);
+
+private:
+ bool _elseFound;
+ char _ifTag;
+};
+
+class EndBlockCommand : public Command {
+public:
+ static bool ParseFunc(const Common::String &line, ScriptParseContext &parseContext, Command *&command);
+
+ virtual ExecuteResult execute(GameData &gameData) override;
+ virtual Command *next() const override;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/commands/ifcommand.cpp b/engines/mutationofjb/commands/ifcommand.cpp
index 18b8081..5ba35bc 100644
--- a/engines/mutationofjb/commands/ifcommand.cpp
+++ b/engines/mutationofjb/commands/ifcommand.cpp
@@ -28,8 +28,7 @@
namespace MutationOfJB {
-bool IfCommand::ParseFunc(const Common::String &line, ScriptParseContext &parseContext, Command *&command)
-{
+bool IfCommandParser::parse(const Common::String &line, ScriptParseContext &parseContext, Command *&command) {
// IFtss oo val!
// <t> 1B Tag.
// <ss> 2B Scene.
@@ -59,6 +58,15 @@ bool IfCommand::ParseFunc(const Common::String &line, ScriptParseContext &parseC
return true;
}
+void IfCommandParser::transition(ScriptParseContext &, Command *oldCommand, Command *newCommand) {
+ if (!oldCommand || !newCommand) {
+ warning(_("Unexpected empty command in transition"));
+ return;
+ }
+
+ static_cast<IfCommand *>(oldCommand)->setTrueCommand(newCommand);
+}
+
IfCommand::IfCommand(uint8 sceneId, uint8 objectId, uint16 value, bool negative) :
_sceneId(sceneId),
_objectId(objectId),
diff --git a/engines/mutationofjb/commands/ifcommand.h b/engines/mutationofjb/commands/ifcommand.h
index d33f34f..290260b 100644
--- a/engines/mutationofjb/commands/ifcommand.h
+++ b/engines/mutationofjb/commands/ifcommand.h
@@ -30,6 +30,12 @@ namespace MutationOfJB {
class ScriptParseContext;
+class IfCommandParser : public CommandParser {
+public:
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+ virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand);
+};
+
class IfCommand : public ConditionalCommand {
public:
static bool ParseFunc(const Common::String &line, ScriptParseContext &parseContext, Command *&command);
diff --git a/engines/mutationofjb/commands/seqcommand.cpp b/engines/mutationofjb/commands/seqcommand.cpp
index ab98497..22d1c90 100644
--- a/engines/mutationofjb/commands/seqcommand.cpp
+++ b/engines/mutationofjb/commands/seqcommand.cpp
@@ -20,10 +20,20 @@
*
*/
-#include "seqcommand.h"
+#include "mutationofjb/commands/seqcommand.h"
+#include "common/translation.h"
namespace MutationOfJB {
+void SeqCommandParser::transition(ScriptParseContext &, Command * oldCommand, Command * newCommand) {
+ if (!oldCommand || !newCommand) {
+ warning(_("Unexpected empty command in transition"));
+ return;
+ }
+
+ static_cast<SeqCommand *>(oldCommand)->setNextCommand(newCommand);
+}
+
void SeqCommand::setNextCommand(Command *nextCommand)
{
_nextCommand = nextCommand;
diff --git a/engines/mutationofjb/commands/seqcommand.h b/engines/mutationofjb/commands/seqcommand.h
index b247fb2..1d21f66 100644
--- a/engines/mutationofjb/commands/seqcommand.h
+++ b/engines/mutationofjb/commands/seqcommand.h
@@ -28,6 +28,11 @@
namespace MutationOfJB {
+class SeqCommandParser : public CommandParser
+{
+ virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand) override;
+};
+
class SeqCommand : public Command {
public:
void setNextCommand(Command *nextCommand);
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index e6c539a..132d869 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -3,6 +3,7 @@ MODULE := engines/mutationofjb
MODULE_OBJS := \
commands/command.o \
commands/conditionalcommand.o \
+ commands/endblockcommand.o \
commands/ifcommand.o \
commands/seqcommand.o \
detection.o \
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index cdefbb9..59553d4 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -36,6 +36,7 @@
#include "mutationofjb/game.h"
#include "mutationofjb/encryptedfile.h"
#include "mutationofjb/util.h"
+#include "mutationofjb/script.h"
namespace MutationOfJB {
@@ -96,10 +97,24 @@ Common::Error MutationOfJBEngine::run() {
_room = new Room(_screen);
_room->load(_gameData->_currentScene, false);
+ EncryptedFile globalScriptFile;
+ globalScriptFile.open("global.atn");
+ Script *script = new Script;
+ script->loadFromStream(globalScriptFile);
+ globalScriptFile.close();
+
while(!shouldQuit()) {
Common::Event event;
while (_eventMan->pollEvent(event)) {
switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+ {
+ if ((event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_d) ||
+ event.kbd.ascii == '~' || event.kbd.ascii == '#') {
+ _console->attach();
+ }
+ break;
+ }
case Common::EVENT_LBUTTONDOWN:
{
const Scene* const scene = _gameData->getScene(_gameData->_currentScene);
@@ -119,6 +134,7 @@ Common::Error MutationOfJBEngine::run() {
}
}
+ _console->onFrame();
_system->delayMillis(40);
_screen->update();
}
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 0280c86..a20c11e 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -25,25 +25,37 @@
#include "common/hashmap.h"
#include "common/hash-str.h"
#include "common/stream.h"
+#include "common/debug.h"
#include "mutationofjb/commands/command.h"
+#include "mutationofjb/commands/ifcommand.h"
+#include "mutationofjb/commands/endblockcommand.h"
namespace MutationOfJB {
-static CommandParseFunc* getParseFuncs() {
- static CommandParseFunc funcs[] = {
+static CommandParser** getParsers() {
+ static CommandParser* parsers[] = {
+ new IfCommandParser,
+ new EndBlockCommandParser,
nullptr
};
- return funcs;
+ return parsers;
}
-ScriptParseContext::ScriptParseContext(Common::SeekableReadStream &stream) : _stream(stream) {}
+ScriptParseContext::ScriptParseContext(Common::SeekableReadStream &stream) :
+ _stream(stream),
+ _currentCommand(nullptr),
+ _lastCommand(nullptr)
+{}
bool ScriptParseContext::readLine(Common::String &line) {
do {
Common::String str = _stream.readLine();
- if (str.empty() || str[0] != '.') {
+ if (str.empty())
+ continue;
+
+ if (str[0] != '.') {
line = str;
if (line[0] == '*') {
line.deleteChar(0);
@@ -61,15 +73,52 @@ void ScriptParseContext::addConditionalCommand(ConditionalCommand *command, char
}
bool Script::loadFromStream(Common::SeekableReadStream &stream) {
+ destroy();
- CommandParseFunc * const parseFuncs = getParseFuncs();
+ CommandParser **parsers = getParsers();
ScriptParseContext parseCtx(stream);
+ Common::String line;
+
+ Command *lastCmd = nullptr;
+ CommandParser *lastParser = nullptr;
+ while (parseCtx.readLine(line)) {
+ Command *currentCmd = nullptr;
+ CommandParser *currentParser = nullptr;
+
+ for (CommandParser **parser = parsers; *parser; ++parser) {
+ if ((*parser)->parse(line, parseCtx, currentCmd)) {
+ currentParser = *parser;
+ break;
+ }
+ }
+ if (lastParser) {
+ lastParser->transition(parseCtx, lastCmd, currentCmd);
+ }
+
+ if (currentCmd) {
+ _allCommands.push_back(currentCmd);
+ }
+
+ lastParser = currentParser;
+ }
+
Common::HashMap<Common::String, Command *> macros;
Common::HashMap<Common::String, Command *> labels;
return true;
}
+void Script::destroy() {
+ for (Commands::iterator it = _allCommands.begin(); it != _allCommands.end(); ++it) {
+ delete *it;
+ }
+ _allCommands.clear();
+}
+
+Script::~Script() {
+ destroy();
+}
+
}
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 9c0f0f3..da90a24 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -32,7 +32,9 @@ namespace Common {
namespace MutationOfJB {
+class Command;
class ConditionalCommand;
+typedef Common::Array<Command*> Commands;
class ScriptParseContext
{
@@ -40,23 +42,45 @@ public:
ScriptParseContext(Common::SeekableReadStream &stream);
bool readLine(Common::String &line);
void addConditionalCommand(ConditionalCommand *command, char tag);
- //void setLastIfCommand(IfCommand *command);
+ void addLookSection(const Common::String & item, bool walkTo);
-private:
Common::SeekableReadStream &_stream;
+ Command *_currentCommand;
+ Command *_lastCommand;
struct ConditionalCommandInfo {
- ConditionalCommand *command;
- char tag;
+ ConditionalCommand *_command;
+ char _tag;
+ };
+ typedef Common::Array<ConditionalCommandInfo> ConditionalCommandInfos;
+
+ ConditionalCommandInfos _pendingCondCommands;
+
+ enum Action {
+ Walk,
+ Talk,
+ Look,
+ Use
};
- Common::Array<ConditionalCommandInfo> _pendingCondCommands;
+
+ struct ActionInfo {
+ Action _action;
+ Common::String _object1Name;
+ Common::String _object2Name;
+ bool walkTo;
+ };
+ typedef Common::Array<ActionInfo> ActionInfos;
+ ActionInfos _actionInfos;
+private:
};
class Script {
public:
bool loadFromStream(Common::SeekableReadStream &stream);
+ ~Script();
private:
-
+ void destroy();
+ Commands _allCommands;
};
}
Commit: 6d926ff55b2fccbf8e96495f88b3d4dda6e906d7
https://github.com/scummvm/scummvm/commit/6d926ff55b2fccbf8e96495f88b3d4dda6e906d7
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add support for CHANGED, CHANGEO and CHANGES commands.
Changed paths:
A engines/mutationofjb/commands/changecommand.cpp
A engines/mutationofjb/commands/changecommand.h
engines/mutationofjb/commands/command.h
engines/mutationofjb/commands/ifcommand.cpp
engines/mutationofjb/commands/seqcommand.h
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/module.mk
engines/mutationofjb/script.cpp
diff --git a/engines/mutationofjb/commands/changecommand.cpp b/engines/mutationofjb/commands/changecommand.cpp
new file mode 100644
index 0000000..54c6d1e
--- /dev/null
+++ b/engines/mutationofjb/commands/changecommand.cpp
@@ -0,0 +1,334 @@
+/* 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/changecommand.h"
+#include "common/translation.h"
+
+namespace MutationOfJB {
+
+// CHANGEe rr ss ii val
+// <e> 1B Entity to change register for.
+// D door
+// O object
+// S static
+// <rr> 2B Register name.
+// <ss> 2B Scene ID.
+// <ii> 2B Entity ID.
+// <val> VL Value.
+
+bool ChangeCommandParser::parseValueString(const Common::String &valueString, uint8 &sceneId, uint8 &entityId, ChangeCommand::ChangeRegister ®, ChangeCommand::ChangeOperation &op, ChangeCommandValue &ccv) {
+ if (valueString.size() < 8) {
+ return false;
+ }
+
+ sceneId = atoi(valueString.c_str() + 3);
+ entityId = atoi(valueString.c_str() + 6);
+ const char *val = nullptr;
+ if (valueString.size() >= 9) {
+ val = valueString.c_str() + 9;
+ }
+
+ if (valueString.hasPrefix("NM")) {
+ reg = ChangeCommand::NM;
+ op = ChangeCommand::SetValue;
+ strncpy(ccv._strVal, val, MAX_STR_LENGTH);
+ } else if (valueString.hasPrefix("LT")) {
+ reg = ChangeCommand::LT;
+ ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("SX")) {
+ reg = ChangeCommand::SX;
+ ccv._wordVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("SY")) {
+ reg = ChangeCommand::SY;
+ ccv._wordVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("XX")) {
+ reg = ChangeCommand::XX;
+ ccv._wordVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("YY")) {
+ reg = ChangeCommand::YY;
+ ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("XL")) {
+ reg = ChangeCommand::XL;
+ ccv._wordVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("YL")) {
+ reg = ChangeCommand::YL;
+ ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("WX")) {
+ reg = ChangeCommand::WX;
+ ccv._wordVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("WY")) {
+ reg = ChangeCommand::WY;
+ ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("AC")) {
+ reg = ChangeCommand::AC;
+ ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("FA")) {
+ reg = ChangeCommand::FA;
+ ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("FR")) {
+ reg = ChangeCommand::FR;
+ ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("NA")) {
+ reg = ChangeCommand::NA;
+ ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("FS")) {
+ reg = ChangeCommand::FS;
+ ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("CA")) {
+ reg = ChangeCommand::CA;
+ ccv._byteVal = parseInteger(val, op);
+ }
+
+ return true;
+}
+
+
+bool ChangeDoorCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
+ if (!line.hasPrefix("CHANGED ")) {
+ return false;
+ }
+ uint8 sceneId = 0;
+ uint8 objectId = 0;
+ ChangeCommand::ChangeRegister reg;
+ ChangeCommand::ChangeOperation op;
+ ChangeCommandValue val;
+ if (!parseValueString(line.c_str() + 8, sceneId, objectId, reg, op, val)) {
+ return false;
+ }
+
+ command = new ChangeObjectCommand(sceneId, objectId, reg, op, val);
+ return true;
+}
+
+bool ChangeObjectCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
+ if (!line.hasPrefix("CHANGEO ")) {
+ return false;
+ }
+ uint8 sceneId = 0;
+ uint8 objectId = 0;
+ ChangeCommand::ChangeRegister reg;
+ ChangeCommand::ChangeOperation op;
+ ChangeCommandValue val;
+ if (!parseValueString(line.c_str() + 8, sceneId, objectId, reg, op, val)) {
+ return false;
+ }
+
+ command = new ChangeObjectCommand(sceneId, objectId, reg, op, val);
+ return true;
+}
+
+bool ChangeStaticCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
+ if (!line.hasPrefix("CHANGES ")) {
+ return false;
+ }
+ uint8 sceneId = 0;
+ uint8 objectId = 0;
+ ChangeCommand::ChangeRegister reg;
+ ChangeCommand::ChangeOperation op;
+ ChangeCommandValue val;
+ if (!parseValueString(line.c_str() + 8, sceneId, objectId, reg, op, val)) {
+ return false;
+ }
+
+ command = new ChangeObjectCommand(sceneId, objectId, reg, op, val);
+ return true;
+}
+
+int ChangeCommandParser::parseInteger(const char *val, ChangeCommand::ChangeOperation &op) {
+ if (!val || !(*val)) {
+ op = ChangeCommand::SetValue;
+ return 0;
+ }
+
+ if (val[0] == '\\') {
+ op = ChangeCommand::SetValue;
+ val++;
+ } else if (val[0] == '+') {
+ op = ChangeCommand::AddValue;
+ val++;
+ } else if (val[0] == '-') {
+ op = ChangeCommand::SubtractValue;
+ val++;
+ }
+
+ return atoi(val);
+}
+
+Command::ExecuteResult ChangeDoorCommand::execute(GameData &gameData) {
+ Scene *const scene = gameData.getScene(_sceneId);
+ if (!scene) {
+ return Finished;
+ }
+
+ Door *const door = scene->getDoor(_entityId);
+ if (!door) {
+ return Finished;
+ }
+
+ switch (_register) {
+ case NM:
+ strncpy(door->_name, _value._strVal, MAX_STR_LENGTH);
+ break;
+ case LT:
+ door->_destSceneId = _value._byteVal;
+ break;
+ case SX:
+ door->_destX = _value._wordVal;
+ break;
+ case SY:
+ door->_destY = _value._wordVal;
+ break;
+ case XX:
+ door->_x = _value._wordVal;
+ break;
+ case YY:
+ door->_y = _value._byteVal;
+ break;
+ case XL:
+ door->_width = _value._wordVal;
+ break;
+ case YL:
+ door->_height = _value._byteVal;
+ break;
+ case WX:
+ door->_walkToX = _value._wordVal;
+ break;
+ case WY:
+ door->_walkToY = _value._byteVal;
+ break;
+ case SP:
+ door->_SP = _value._byteVal;
+ break;
+ default:
+ warning("Object does not support changing this register.");
+ break;
+ }
+
+ return Finished;
+}
+
+Command::ExecuteResult ChangeObjectCommand::execute(GameData &gameData) {
+ Scene *const scene = gameData.getScene(_sceneId);
+ if (!scene) {
+ return Finished;
+ }
+
+ Object *const object = scene->getObject(_entityId);
+ if (!object) {
+ return Finished;
+ }
+
+ switch (_register) {
+ case AC:
+ object->_AC = _value._byteVal;
+ break;
+ case FA:
+ object->_FA = _value._byteVal;
+ break;
+ case FR:
+ object->_FR = _value._byteVal;
+ break;
+ case NA:
+ object->_NA = _value._byteVal;
+ break;
+ case FS:
+ object->_FS = _value._byteVal;
+ break;
+ case CA:
+ object->_CA = _value._byteVal;
+ break;
+ case XX:
+ object->_x = _value._wordVal;
+ break;
+ case YY:
+ object->_y = _value._byteVal;
+ break;
+ case XL:
+ object->_XL = _value._wordVal;
+ break;
+ case YL:
+ object->_YL = _value._byteVal;
+ break;
+ case WX:
+ object->_WX = _value._wordVal;
+ break;
+ case WY:
+ object->_WY = _value._byteVal;
+ break;
+ case SP:
+ object->_SP = _value._byteVal;
+ break;
+ default:
+ warning("Object does not support changing this register.");
+ break;
+ }
+
+ return Finished;
+}
+
+Command::ExecuteResult ChangeStaticCommand::execute(GameData &gameData) {
+ Scene *const scene = gameData.getScene(_sceneId);
+ if (!scene) {
+ return Finished;
+ }
+
+ Static *const stat = scene->getStatic(_entityId);
+ if (!stat) {
+ return Finished;
+ }
+
+ switch (_register) {
+ case AC:
+ stat->_active = _value._byteVal;
+ break;
+ case NM:
+ strncpy(stat->_name, _value._strVal, MAX_STR_LENGTH);
+ break;
+ case XX:
+ stat->_x = _value._wordVal;
+ break;
+ case YY:
+ stat->_y = _value._byteVal;
+ break;
+ case XL:
+ stat->_width = _value._wordVal;
+ break;
+ case YL:
+ stat->_height = _value._byteVal;
+ break;
+ case WX:
+ stat->_walkToX = _value._wordVal;
+ break;
+ case WY:
+ stat->_walkToY = _value._byteVal;
+ break;
+ case SP:
+ stat->_SP = _value._byteVal;
+ break;
+ default:
+ warning("Object does not support changing this register.");
+ break;
+ }
+
+ return Finished;
+}
+}
diff --git a/engines/mutationofjb/commands/changecommand.h b/engines/mutationofjb/commands/changecommand.h
new file mode 100644
index 0000000..5b9a91e
--- /dev/null
+++ b/engines/mutationofjb/commands/changecommand.h
@@ -0,0 +1,120 @@
+/* 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/seqcommand.h"
+#include "mutationofjb/game.h"
+
+namespace MutationOfJB {
+
+union ChangeCommandValue {
+ uint8 _byteVal;
+ uint16 _wordVal;
+ char _strVal[MAX_STR_LENGTH + 1];
+};
+
+class ChangeCommand : public SeqCommand {
+public:
+ enum ChangeRegister {
+ NM, // Name
+ LT, // Destination scene ID
+ SX, // Destination X
+ SY, // Destination Y
+ XX, // X
+ YY, // Y
+ XL, // Width
+ YL, // Height
+ WX, // Walk to X
+ WY, // Walk to Y
+ SP, //
+ AC, // Active
+ FA, // First animation
+ FR,
+ NA,
+ FS,
+ CA
+ };
+
+ enum ChangeOperation {
+ SetValue,
+ AddValue,
+ SubtractValue
+ };
+
+ ChangeCommand(uint8 sceneId, uint8 entityId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue& val) :
+ _sceneId(sceneId), _entityId(entityId), _register(reg), _operation(op), _value(val)
+ {}
+protected:
+ uint8 _sceneId;
+ uint8 _entityId;
+ ChangeRegister _register;
+ ChangeOperation _operation;
+ ChangeCommandValue _value;
+};
+
+class ChangeCommandParser : public SeqCommandParser {
+protected:
+ bool parseValueString(const Common::String &valueString, uint8 &sceneId, uint8 &entityId, ChangeCommand::ChangeRegister ®, ChangeCommand::ChangeOperation &op, ChangeCommandValue &ccv);
+ int parseInteger(const char *val, ChangeCommand::ChangeOperation &op);
+};
+
+class ChangeObjectCommandParser : public ChangeCommandParser {
+public:
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
+};
+
+class ChangeDoorCommandParser : public ChangeCommandParser {
+public:
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
+};
+
+class ChangeStaticCommandParser : public ChangeCommandParser {
+public:
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
+};
+
+
+
+class ChangeDoorCommand : public ChangeCommand {
+public:
+ ChangeDoorCommand(uint8 sceneId, uint8 doorId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue& val)
+ : ChangeCommand(sceneId, doorId, reg, op, val)
+ {}
+ virtual ExecuteResult execute(GameData &gameData) override;
+};
+
+class ChangeObjectCommand : public ChangeCommand {
+public:
+ ChangeObjectCommand(uint8 sceneId, uint8 objectId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue& val)
+ : ChangeCommand(sceneId, objectId, reg, op, val)
+ {}
+ virtual ExecuteResult execute(GameData &gameData) override;
+};
+
+class ChangeStaticCommand : public ChangeCommand {
+public:
+ ChangeStaticCommand(uint8 sceneId, uint8 staticId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue& val)
+ : ChangeCommand(sceneId, staticId, reg, op, val)
+ {}
+ virtual ExecuteResult execute(GameData &gameData) override;
+};
+
+}
diff --git a/engines/mutationofjb/commands/command.h b/engines/mutationofjb/commands/command.h
index ab0ebc6..f8c160e 100644
--- a/engines/mutationofjb/commands/command.h
+++ b/engines/mutationofjb/commands/command.h
@@ -36,8 +36,6 @@ class CallMacroCommand;
class ScriptParseContext;
class Command;
-typedef bool (*CommandParseFunc)(const Common::String &line, ScriptParseContext &parseContext, Command *&command);
-
class CommandParser {
public:
virtual ~CommandParser();
diff --git a/engines/mutationofjb/commands/ifcommand.cpp b/engines/mutationofjb/commands/ifcommand.cpp
index 5ba35bc..8026c84 100644
--- a/engines/mutationofjb/commands/ifcommand.cpp
+++ b/engines/mutationofjb/commands/ifcommand.cpp
@@ -40,7 +40,7 @@ bool IfCommandParser::parse(const Common::String &line, ScriptParseContext &pars
return false;
}
- if (strncmp(line.c_str(), "IF", 2) != 0) {
+ if (!line.hasPrefix("IF")) {
return false;
}
diff --git a/engines/mutationofjb/commands/seqcommand.h b/engines/mutationofjb/commands/seqcommand.h
index 1d21f66..90e3028 100644
--- a/engines/mutationofjb/commands/seqcommand.h
+++ b/engines/mutationofjb/commands/seqcommand.h
@@ -30,6 +30,7 @@ namespace MutationOfJB {
class SeqCommandParser : public CommandParser
{
+public:
virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand) override;
};
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 740fb1c..9f517d6 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -143,6 +143,15 @@ bool Scene::loadFromStream(Common::ReadStream &stream) {
return true;
}
+Door *Scene::getDoor(uint8 doorId) {
+ if (doorId == 0 || doorId > _noDoors) {
+ warning(_("Door %d does not exist"), doorId);
+ return nullptr;
+ }
+
+ return &_doors[doorId - 1];
+}
+
Object *Scene::getObject(uint8 objectId) {
if (objectId == 0 || objectId > _noObjects) {
warning(_("Object %d does not exist"), objectId);
@@ -152,6 +161,15 @@ Object *Scene::getObject(uint8 objectId) {
return &_objects[objectId - 1];
}
+Static *Scene::getStatic(uint8 staticId) {
+ if (staticId == 0 || staticId > _noStatics) {
+ warning(_("Static %d does not exist"), staticId);
+ return nullptr;
+ }
+
+ return &_statics[staticId - 1];
+}
+
GameData::GameData() : _currentScene(0) {}
Scene *GameData::getScene(uint8 sceneId)
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index d49a966..eda178b 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -93,7 +93,9 @@ struct Bitmap {
struct Scene {
+ Door *getDoor(uint8 objectId);
Object *getObject(uint8 objectId);
+ Static *getStatic(uint8 staticId);
uint8 _startup;
uint8 _unknown001;
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 132d869..16a0c3b 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -1,6 +1,7 @@
MODULE := engines/mutationofjb
MODULE_OBJS := \
+ commands/changecommand.o \
commands/command.o \
commands/conditionalcommand.o \
commands/endblockcommand.o \
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index a20c11e..0deeccb 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -29,6 +29,7 @@
#include "mutationofjb/commands/command.h"
#include "mutationofjb/commands/ifcommand.h"
#include "mutationofjb/commands/endblockcommand.h"
+#include "mutationofjb/commands/changecommand.h"
namespace MutationOfJB {
@@ -36,6 +37,9 @@ static CommandParser** getParsers() {
static CommandParser* parsers[] = {
new IfCommandParser,
new EndBlockCommandParser,
+ new ChangeDoorCommandParser,
+ new ChangeObjectCommandParser,
+ new ChangeStaticCommandParser,
nullptr
};
@@ -101,6 +105,7 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) {
_allCommands.push_back(currentCmd);
}
+ lastCmd = currentCmd;
lastParser = currentParser;
}
Commit: bbd3750aeec2bdb91a8ab31eca8672c34ce61f83
https://github.com/scummvm/scummvm/commit/bbd3750aeec2bdb91a8ab31eca8672c34ce61f83
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add change scene command, implement listsections and showsection debug console commands.
Changed paths:
A engines/mutationofjb/debug.cpp
A engines/mutationofjb/debug.h
engines/mutationofjb/commands/changecommand.cpp
engines/mutationofjb/commands/changecommand.h
engines/mutationofjb/commands/command.cpp
engines/mutationofjb/commands/command.h
engines/mutationofjb/commands/endblockcommand.cpp
engines/mutationofjb/commands/endblockcommand.h
engines/mutationofjb/commands/ifcommand.cpp
engines/mutationofjb/commands/ifcommand.h
engines/mutationofjb/module.mk
engines/mutationofjb/mutationofjb.cpp
engines/mutationofjb/mutationofjb.h
engines/mutationofjb/script.cpp
engines/mutationofjb/script.h
diff --git a/engines/mutationofjb/commands/changecommand.cpp b/engines/mutationofjb/commands/changecommand.cpp
index 54c6d1e..e9bb9cc 100644
--- a/engines/mutationofjb/commands/changecommand.cpp
+++ b/engines/mutationofjb/commands/changecommand.cpp
@@ -96,6 +96,30 @@ bool ChangeCommandParser::parseValueString(const Common::String &valueString, ui
} else if (valueString.hasPrefix("CA")) {
reg = ChangeCommand::CA;
ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("DS")) {
+ reg = ChangeCommand::DS;
+ ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("DL")) {
+ reg = ChangeCommand::DL;
+ ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("ND")) {
+ reg = ChangeCommand::ND;
+ ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("NO")) {
+ reg = ChangeCommand::NO;
+ ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("NS")) {
+ reg = ChangeCommand::NS;
+ ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("PF")) {
+ reg = ChangeCommand::PF;
+ ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("PL")) {
+ reg = ChangeCommand::PL;
+ ccv._byteVal = parseInteger(val, op);
+ } else if (valueString.hasPrefix("PD")) {
+ reg = ChangeCommand::PD;
+ ccv._byteVal = parseInteger(val, op);
}
return true;
@@ -115,7 +139,7 @@ bool ChangeDoorCommandParser::parse(const Common::String &line, ScriptParseConte
return false;
}
- command = new ChangeObjectCommand(sceneId, objectId, reg, op, val);
+ command = new ChangeDoorCommand(sceneId, objectId, reg, op, val);
return true;
}
@@ -149,7 +173,24 @@ bool ChangeStaticCommandParser::parse(const Common::String &line, ScriptParseCon
return false;
}
- command = new ChangeObjectCommand(sceneId, objectId, reg, op, val);
+ command = new ChangeStaticCommand(sceneId, objectId, reg, op, val);
+ return true;
+}
+
+bool ChangeSceneCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
+ if (!line.hasPrefix("CHANGE ")) {
+ return false;
+ }
+ uint8 sceneId = 0;
+ uint8 objectId = 0;
+ ChangeCommand::ChangeRegister reg;
+ ChangeCommand::ChangeOperation op;
+ ChangeCommandValue val;
+ if (!parseValueString(line.c_str() + 8, sceneId, objectId, reg, op, val)) {
+ return false;
+ }
+
+ command = new ChangeSceneCommand(sceneId, objectId, reg, op, val);
return true;
}
@@ -173,6 +214,86 @@ int ChangeCommandParser::parseInteger(const char *val, ChangeCommand::ChangeOper
return atoi(val);
}
+
+const char *ChangeCommand::getRegisterAsString() const {
+ switch (_register) {
+ case NM: return "NM";
+ case LT: return "LT";
+ case SX: return "SX";
+ case SY: return "SY";
+ case XX: return "XX";
+ case YY: return "YY";
+ case XL: return "XL";
+ case YL: return "YL";
+ case WX: return "WX";
+ case WY: return "WY";
+ case SP: return "SP";
+ case AC: return "AC";
+ case FA: return "FA";
+ case FR: return "FR";
+ case NA: return "NA";
+ case FS: return "FS";
+ case CA: return "CA";
+ case DS: return "DS";
+ case DL: return "DL";
+ case ND: return "ND";
+ case NO: return "NO";
+ case NS: return "NS";
+ case PF: return "PF";
+ case PL: return "PL";
+ case PD: return "PD";
+ default: return "(unknown)";
+ }
+}
+
+Common::String ChangeCommand::getValueAsString() const {
+ switch (_register) {
+ case NM:
+ return Common::String::format("\"%s\"", _value._strVal);
+ case LT:
+ case YY:
+ case YL:
+ case WY:
+ case SP:
+ case AC:
+ case FA:
+ case FR:
+ case NA:
+ case FS:
+ case CA:
+ case DS:
+ case DL:
+ case ND:
+ case NO:
+ case NS:
+ case PF:
+ case PL:
+ case PD:
+ return Common::String::format("%d", (int)_value._byteVal);
+ case SX:
+ case SY:
+ case XX:
+ case XL:
+ case WX:
+ return Common::String::format("%d", (int)_value._wordVal);
+ default:
+ return "(unknown)";
+ }
+}
+
+const char *ChangeCommand::getOperationAsString() const {
+ switch (_operation) {
+ case SetValue:
+ return "=";
+ case AddValue:
+ return "+=";
+ case SubtractValue:
+ return "-=";
+ default:
+ return "(unknown)";
+ }
+}
+
Command::ExecuteResult ChangeDoorCommand::execute(GameData &gameData) {
Scene *const scene = gameData.getScene(_sceneId);
if (!scene) {
@@ -226,6 +347,10 @@ Command::ExecuteResult ChangeDoorCommand::execute(GameData &gameData) {
return Finished;
}
+Common::String ChangeDoorCommand::debugString() const {
+ return Common::String::format("scene%d.door%d.%s %s %s", _sceneId, _entityId, getRegisterAsString(), getOperationAsString(), getValueAsString().c_str());
+}
+
Command::ExecuteResult ChangeObjectCommand::execute(GameData &gameData) {
Scene *const scene = gameData.getScene(_sceneId);
if (!scene) {
@@ -285,6 +410,10 @@ Command::ExecuteResult ChangeObjectCommand::execute(GameData &gameData) {
return Finished;
}
+Common::String ChangeObjectCommand::debugString() const {
+ return Common::String::format("scene%d.object%d.%s %s %s", _sceneId, _entityId, getRegisterAsString(), getOperationAsString(), getValueAsString().c_str());
+}
+
Command::ExecuteResult ChangeStaticCommand::execute(GameData &gameData) {
Scene *const scene = gameData.getScene(_sceneId);
if (!scene) {
@@ -331,4 +460,51 @@ Command::ExecuteResult ChangeStaticCommand::execute(GameData &gameData) {
return Finished;
}
+
+Common::String ChangeStaticCommand::debugString() const {
+ return Common::String::format("scene%d.static%d.%s %s %s", _sceneId, _entityId, getRegisterAsString(), getOperationAsString(), getValueAsString().c_str());
+}
+
+Command::ExecuteResult ChangeSceneCommand::execute(GameData &gameData) {
+ Scene *const scene = gameData.getScene(_sceneId);
+ if (!scene) {
+ return Finished;
+ }
+
+ switch (_register) {
+ case DS:
+ scene->_startup = _value._byteVal;
+ break;
+ case DL:
+ scene->_DL = _value._byteVal;
+ break;
+ case ND:
+ scene->_noDoors = _value._byteVal;
+ break;
+ case NO:
+ scene->_noObjects = _value._byteVal;
+ break;
+ case NS:
+ scene->_noStatics = _value._byteVal;
+ break;
+ case PF:
+ scene->_palRotStart = _value._byteVal;
+ break;
+ case PL:
+ scene->_palRotEnd = _value._byteVal;
+ break;
+ case PD:
+ scene->_palRotPeriod = _value._byteVal;
+ break;
+ default:
+ warning("Scene does not support changing this register.");
+ break;
+ }
+
+ return Finished;
+}
+
+Common::String ChangeSceneCommand::debugString() const {
+ return Common::String::format("scene%d.%s %s %s", _sceneId, getRegisterAsString(), getOperationAsString(), getValueAsString().c_str());
+}
}
diff --git a/engines/mutationofjb/commands/changecommand.h b/engines/mutationofjb/commands/changecommand.h
index 5b9a91e..d590fa5 100644
--- a/engines/mutationofjb/commands/changecommand.h
+++ b/engines/mutationofjb/commands/changecommand.h
@@ -50,7 +50,15 @@ public:
FR,
NA,
FS,
- CA
+ CA,
+ DS, // Startup
+ DL,
+ ND, // Number of doors
+ NO, // Number of objects
+ NS, // Number of statics
+ PF, // Palette rotation first
+ PL, // Palette rotation last
+ PD // Palette rotation delay
};
enum ChangeOperation {
@@ -63,6 +71,10 @@ public:
_sceneId(sceneId), _entityId(entityId), _register(reg), _operation(op), _value(val)
{}
protected:
+ const char *getRegisterAsString() const;
+ Common::String getValueAsString() const;
+ const char *getOperationAsString() const;
+
uint8 _sceneId;
uint8 _entityId;
ChangeRegister _register;
@@ -91,7 +103,10 @@ public:
virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
};
-
+class ChangeSceneCommandParser : public ChangeCommandParser {
+public:
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
+};
class ChangeDoorCommand : public ChangeCommand {
public:
@@ -99,6 +114,7 @@ public:
: ChangeCommand(sceneId, doorId, reg, op, val)
{}
virtual ExecuteResult execute(GameData &gameData) override;
+ virtual Common::String debugString() const;
};
class ChangeObjectCommand : public ChangeCommand {
@@ -107,6 +123,7 @@ public:
: ChangeCommand(sceneId, objectId, reg, op, val)
{}
virtual ExecuteResult execute(GameData &gameData) override;
+ virtual Common::String debugString() const;
};
class ChangeStaticCommand : public ChangeCommand {
@@ -115,6 +132,16 @@ public:
: ChangeCommand(sceneId, staticId, reg, op, val)
{}
virtual ExecuteResult execute(GameData &gameData) override;
+ virtual Common::String debugString() const;
+};
+
+class ChangeSceneCommand : public ChangeCommand {
+public:
+ ChangeSceneCommand(uint8 sceneId, uint8 staticId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue& val)
+ : ChangeCommand(sceneId, staticId, reg, op, val)
+ {}
+ virtual ExecuteResult execute(GameData &gameData) override;
+ virtual Common::String debugString() const;
};
}
diff --git a/engines/mutationofjb/commands/command.cpp b/engines/mutationofjb/commands/command.cpp
index af4c28e..943986e 100644
--- a/engines/mutationofjb/commands/command.cpp
+++ b/engines/mutationofjb/commands/command.cpp
@@ -25,7 +25,7 @@
namespace MutationOfJB {
-void CommandParser::transition(ScriptParseContext &, Command *, Command *) {}
+void CommandParser::transition(ScriptParseContext &, Command *, Command *, CommandParser *) {}
CommandParser::~CommandParser() {}
Command::~Command() {}
diff --git a/engines/mutationofjb/commands/command.h b/engines/mutationofjb/commands/command.h
index f8c160e..ccfdea2 100644
--- a/engines/mutationofjb/commands/command.h
+++ b/engines/mutationofjb/commands/command.h
@@ -42,7 +42,7 @@ public:
virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) = 0;
/* Old command - created by this parser. */
- virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand);
+ virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser);
};
class Command {
@@ -59,6 +59,7 @@ public:
virtual Command *next() const = 0;
virtual SeqCommand *asSeqCommand();
+ virtual Common::String debugString() const = 0;
};
}
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index 218be1a..be610c7 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -41,15 +41,17 @@ bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext
// This is the start or end of section/block.
if (line.size() >= 4 && (line.hasPrefix("#L ") || line.hasPrefix("-L "))) {
- ScriptParseContext::ActionInfo ai = {ScriptParseContext::Look, line.c_str() + 3, "", firstChar == '#'};
- parseCtx._actionInfos.push_back(ai);
- debug("# Look: %s", line.c_str() + 3);
+ ActionInfo ai = {ActionInfo::Look, line.c_str() + 3, "", firstChar == '#', nullptr};
+ parseCtx._lookActionInfos.push_back(ai);
+ _pendingActionInfos.push_back(&parseCtx._lookActionInfos.back());
} else if (line.size() >= 4 && (line.hasPrefix("#W ") || line.hasPrefix("-W "))) {
- ScriptParseContext::ActionInfo ai = {ScriptParseContext::Walk, line.c_str() + 3, "", firstChar == '#'};
- parseCtx._actionInfos.push_back(ai);
+ ActionInfo ai = {ActionInfo::Walk, line.c_str() + 3, "", firstChar == '#', nullptr};
+ parseCtx._walkActionInfos.push_back(ai);
+ _pendingActionInfos.push_back(&parseCtx._walkActionInfos.back());
} else if (line.size() >= 4 && (line.hasPrefix("#T ") || line.hasPrefix("-T "))) {
- ScriptParseContext::ActionInfo ai = {ScriptParseContext::Talk, line.c_str() + 3, "", firstChar == '#'};
- parseCtx._actionInfos.push_back(ai);
+ ActionInfo ai = {ActionInfo::Talk, line.c_str() + 3, "", firstChar == '#', nullptr};
+ parseCtx._talkActionInfos.push_back(ai);
+ _pendingActionInfos.push_back(&parseCtx._talkActionInfos.back());
} else if (line.size() >= 4 && (line.hasPrefix("#U ") || line.hasPrefix("-U "))) {
int secondObjPos = -1;
for (int i = 3; i < (int) line.size(); ++i) {
@@ -58,13 +60,15 @@ bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext
break;
}
}
- ScriptParseContext::ActionInfo ai = {
- ScriptParseContext::Talk,
+ ActionInfo ai = {
+ ActionInfo::Use,
line.c_str() + 3,
(secondObjPos != -1) ? line.c_str() + secondObjPos : "",
- firstChar == '#'
+ firstChar == '#',
+ nullptr
};
- parseCtx._actionInfos.push_back(ai);
+ parseCtx._useActionInfos.push_back(ai);
+ _pendingActionInfos.push_back(&parseCtx._useActionInfos.back());
} else if ((line.hasPrefix("#ELSE") || line.hasPrefix("=ELSE"))) {
_elseFound = true;
_ifTag = 0;
@@ -78,7 +82,7 @@ bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext
return true;
}
-void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *, Command *newCommand) {
+void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *, Command *newCommand, CommandParser *newCommandParser) {
if (_elseFound) {
if (newCommand) {
ScriptParseContext::ConditionalCommandInfos::iterator it = parseCtx._pendingCondCommands.begin();
@@ -96,6 +100,14 @@ void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *,
_elseFound = false;
_ifTag = 0;
}
+
+ if (!_pendingActionInfos.empty() && newCommandParser != this) {
+ debug("Fixing pending action info.\n");
+ for (Common::Array<ActionInfo *>::iterator it = _pendingActionInfos.begin(); it != _pendingActionInfos.end(); ++it) {
+ (*it)->_command = newCommand;
+ }
+ _pendingActionInfos.clear();
+ }
}
Command::ExecuteResult EndBlockCommand::execute(GameData &) {
@@ -105,4 +117,9 @@ Command::ExecuteResult EndBlockCommand::execute(GameData &) {
Command *EndBlockCommand::next() const {
return nullptr;
}
+
+Common::String EndBlockCommand::debugString() const {
+ return "ENDBLOCK";
+}
+
}
diff --git a/engines/mutationofjb/commands/endblockcommand.h b/engines/mutationofjb/commands/endblockcommand.h
index 1ac636c..51f7993 100644
--- a/engines/mutationofjb/commands/endblockcommand.h
+++ b/engines/mutationofjb/commands/endblockcommand.h
@@ -25,19 +25,23 @@
#include "mutationofjb/commands/command.h"
#include "common/scummsys.h"
+#include "common/array.h"
namespace MutationOfJB {
+class ActionInfo;
+
class EndBlockCommandParser : public CommandParser {
public:
EndBlockCommandParser() : _elseFound(false), _ifTag(0) {}
virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
- virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand);
+ virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser);
private:
bool _elseFound;
char _ifTag;
+ Common::Array<ActionInfo*> _pendingActionInfos;
};
class EndBlockCommand : public Command {
@@ -46,6 +50,7 @@ public:
virtual ExecuteResult execute(GameData &gameData) override;
virtual Command *next() const override;
+ virtual Common::String debugString() const;
};
}
diff --git a/engines/mutationofjb/commands/ifcommand.cpp b/engines/mutationofjb/commands/ifcommand.cpp
index 8026c84..a41875f 100644
--- a/engines/mutationofjb/commands/ifcommand.cpp
+++ b/engines/mutationofjb/commands/ifcommand.cpp
@@ -58,7 +58,7 @@ bool IfCommandParser::parse(const Common::String &line, ScriptParseContext &pars
return true;
}
-void IfCommandParser::transition(ScriptParseContext &, Command *oldCommand, Command *newCommand) {
+void IfCommandParser::transition(ScriptParseContext &, Command *oldCommand, Command *newCommand, CommandParser *) {
if (!oldCommand || !newCommand) {
warning(_("Unexpected empty command in transition"));
return;
@@ -92,5 +92,10 @@ Command::ExecuteResult IfCommand::execute(GameData &gameData) {
return Finished;
}
+
+Common::String IfCommand::debugString() const {
+ return Common::String::format("IF scene%d.object%d.WX %s %d", _sceneId, _objectId, _negative ? "!=" : "==", _value);
+}
+
}
diff --git a/engines/mutationofjb/commands/ifcommand.h b/engines/mutationofjb/commands/ifcommand.h
index 290260b..9462278 100644
--- a/engines/mutationofjb/commands/ifcommand.h
+++ b/engines/mutationofjb/commands/ifcommand.h
@@ -33,7 +33,7 @@ class ScriptParseContext;
class IfCommandParser : public CommandParser {
public:
virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
- virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand);
+ virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser);
};
class IfCommand : public ConditionalCommand {
@@ -43,6 +43,7 @@ public:
IfCommand(uint8 sceneId, uint8 objectId, uint16 value, bool negative);
virtual ExecuteResult execute(GameData &gameData) override;
+ virtual Common::String debugString() const;
private:
uint8 _sceneId;
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
new file mode 100644
index 0000000..4861ab1
--- /dev/null
+++ b/engines/mutationofjb/debug.cpp
@@ -0,0 +1,162 @@
+/* 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/debug.h"
+#include "mutationofjb/mutationofjb.h"
+#include "mutationofjb/script.h"
+#include "mutationofjb/commands/command.h"
+#include "common/debug-channels.h"
+#include "common/translation.h"
+#include "common/scummsys.h"
+
+namespace MutationOfJB {
+
+/*
+TODO
+static Common::String convertTo7bitASCII() {
+ return Common::String();
+}
+*/
+
+Console::Console(MutationOfJBEngine *vm) : _vm(vm) {
+ registerCmd("listsections", WRAP_METHOD(Console, cmd_listsections));
+ registerCmd("showsection", WRAP_METHOD(Console, cmd_showsection));
+}
+
+bool Console::cmd_listsections(int argc, const char **argv) {
+ if (argc == 3) {
+ Script *script = nullptr;
+ if (strcmp(argv[1], "G") == 0) {
+ script = _vm->getGlobalScript();
+ } else if (strcmp(argv[1], "L") == 0) {
+ script = _vm->getLocalScript();
+ }
+ if (!script) {
+ debugPrintf(_("Choose 'G' (global) or 'L' (local) script.\n"));
+ } else {
+ if (strcmp(argv[2], "L") == 0) {
+ const ActionInfos &actionInfos = script->getLookActionInfos();
+ for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
+ const ActionInfo &actionInfo = *it;
+ debugPrintf(_("Look %s\n"), actionInfo._object1Name.c_str());
+ }
+ } else if (strcmp(argv[2], "W") == 0) {
+ const ActionInfos &actionInfos = script->getWalkActionInfos();
+ for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
+ const ActionInfo &actionInfo = *it;
+ debugPrintf(_("Walk %s\n"), actionInfo._object1Name.c_str());
+ }
+ } else if (strcmp(argv[2], "T") == 0) {
+ const ActionInfos &actionInfos = script->getTalkActionInfos();
+ for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
+ const ActionInfo &actionInfo = *it;
+ debugPrintf(_("Talk %s\n"), actionInfo._object1Name.c_str());
+ }
+ } else if (strcmp(argv[2], "U") == 0) {
+ const ActionInfos &actionInfos = script->getUseActionInfos();
+ for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
+ const ActionInfo &actionInfo = *it;
+ debugPrintf(_("Use %s\n"), actionInfo._object1Name.c_str());
+ }
+ } else {
+ debugPrintf(_("Choose 'L' (look), 'W' (walk), 'T' (talk) or 'U' (use).\n"));
+ }
+ }
+ } else {
+ debugPrintf(_("listsections <G|L> <L|W|T|U>\n"));
+ }
+ return true;
+}
+
+bool Console::cmd_showsection(int argc, const char **argv) {
+ if (argc == 4) {
+ Script *script = nullptr;
+ if (strcmp(argv[1], "G") == 0) {
+ script = _vm->getGlobalScript();
+ } else if (strcmp(argv[1], "L") == 0) {
+ script = _vm->getLocalScript();
+ }
+ if (!script) {
+ debugPrintf(_("Choose 'G' (global) or 'L' (local) script.\n"));
+ } else {
+ Command *command = nullptr;
+ bool found = false;
+ if (strcmp(argv[2], "L") == 0) {
+ const ActionInfos &actionInfos = script->getLookActionInfos();
+ for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
+ const ActionInfo &actionInfo = *it;
+ if (actionInfo._object1Name == argv[3]) {
+ found = true;
+ command = actionInfo._command;
+ break;
+ }
+ }
+ } else if (strcmp(argv[2], "W") == 0) {
+ const ActionInfos &actionInfos = script->getWalkActionInfos();
+ for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
+ const ActionInfo &actionInfo = *it;
+ if (actionInfo._object1Name == argv[3]) {
+ found = true;
+ command = actionInfo._command;
+ break;
+ }
+ }
+ } else if (strcmp(argv[2], "T") == 0) {
+ const ActionInfos &actionInfos = script->getTalkActionInfos();
+ for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
+ const ActionInfo &actionInfo = *it;
+ if (actionInfo._object1Name == argv[3]) {
+ found = true;
+ command = actionInfo._command;
+ break;
+ }
+ }
+ } else if (strcmp(argv[2], "U") == 0) {
+ const ActionInfos &actionInfos = script->getUseActionInfos();
+ for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
+ const ActionInfo &actionInfo = *it;
+ if (actionInfo._object1Name == argv[3]) {
+ found = true;
+ command = actionInfo._command;
+ break;
+ }
+ }
+ } else {
+ debugPrintf(_("Choose 'L' (look), 'W' (walk), 'T' (talk) or 'U' (use).\n"));
+ }
+
+ if (found) {
+ if (command) {
+ debugPrintf("%s\n", command->debugString().c_str());
+ }
+ } else {
+ debugPrintf("Section not found.\n");
+ }
+ }
+ } else {
+ debugPrintf(_("showsection <G|L> <L|W|T|U> <sectionname>\n"));
+ }
+
+ return true;
+}
+
+}
diff --git a/engines/mutationofjb/debug.h b/engines/mutationofjb/debug.h
new file mode 100644
index 0000000..86ee844
--- /dev/null
+++ b/engines/mutationofjb/debug.h
@@ -0,0 +1,40 @@
+/* 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 "gui/debugger.h"
+
+namespace MutationOfJB {
+
+class MutationOfJBEngine;
+
+class Console : public GUI::Debugger {
+public:
+ Console(MutationOfJBEngine *vm);
+ virtual ~Console(void) {}
+private:
+ bool cmd_listsections(int argc, const char **argv);
+ bool cmd_showsection(int argc, const char **argv);
+ MutationOfJBEngine *_vm;
+};
+
+}
+
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 16a0c3b..09f00db 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS := \
commands/endblockcommand.o \
commands/ifcommand.o \
commands/seqcommand.o \
+ debug.o \
detection.o \
encryptedfile.o \
game.o \
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index 59553d4..3576fd5 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -37,14 +37,17 @@
#include "mutationofjb/encryptedfile.h"
#include "mutationofjb/util.h"
#include "mutationofjb/script.h"
+#include "mutationofjb/debug.h"
namespace MutationOfJB {
MutationOfJBEngine::MutationOfJBEngine(OSystem *syst)
: Engine(syst),
- _console(nullptr),
- _room(nullptr),
- _screen(nullptr)
+ _console(nullptr),
+ _room(nullptr),
+ _screen(nullptr),
+ _globalScript(nullptr),
+ _localScript(nullptr)
{
debug("MutationOfJBEngine::MutationOfJBEngine");
}
@@ -99,8 +102,8 @@ Common::Error MutationOfJBEngine::run() {
EncryptedFile globalScriptFile;
globalScriptFile.open("global.atn");
- Script *script = new Script;
- script->loadFromStream(globalScriptFile);
+ _globalScript = new Script;
+ _globalScript->loadFromStream(globalScriptFile);
globalScriptFile.close();
while(!shouldQuit()) {
@@ -141,4 +144,13 @@ Common::Error MutationOfJBEngine::run() {
return Common::kNoError;
}
+
+Script *MutationOfJBEngine::getGlobalScript() {
+ return _globalScript;
+}
+
+Script *MutationOfJBEngine::getLocalScript() {
+ return _localScript;
+}
+
}
diff --git a/engines/mutationofjb/mutationofjb.h b/engines/mutationofjb/mutationofjb.h
index 75bd678..efd8898 100644
--- a/engines/mutationofjb/mutationofjb.h
+++ b/engines/mutationofjb/mutationofjb.h
@@ -24,7 +24,6 @@
#define MUTATIONOFJB_MUTATIONOFJB_H
#include "engines/engine.h"
-#include "gui/debugger.h"
namespace Graphics {
class Screen;
@@ -35,6 +34,7 @@ namespace MutationOfJB {
class Console;
class Room;
struct GameData;
+class Script;
class MutationOfJBEngine : public Engine {
public:
@@ -42,6 +42,9 @@ public:
~MutationOfJBEngine();
virtual Common::Error run();
+ Script *getGlobalScript();
+ Script *getLocalScript();
+
private:
bool loadGameData(bool partB);
void setupCursor();
@@ -50,13 +53,10 @@ private:
Room *_room;
GameData *_gameData;
Graphics::Screen *_screen;
+ Script *_globalScript;
+ Script *_localScript;
};
-class Console : public GUI::Debugger {
-public:
- Console(MutationOfJBEngine *vm) {}
- virtual ~Console(void) {}
-};
}
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 0deeccb..8985e06 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -40,6 +40,7 @@ static CommandParser** getParsers() {
new ChangeDoorCommandParser,
new ChangeObjectCommandParser,
new ChangeStaticCommandParser,
+ new ChangeSceneCommandParser,
nullptr
};
@@ -97,8 +98,12 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) {
break;
}
}
+ if (!currentParser) {
+ continue;
+ }
+
if (lastParser) {
- lastParser->transition(parseCtx, lastCmd, currentCmd);
+ lastParser->transition(parseCtx, lastCmd, currentCmd, currentParser);
}
if (currentCmd) {
@@ -109,6 +114,11 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) {
lastParser = currentParser;
}
+ _lookActionInfos = parseCtx._lookActionInfos;
+ _walkActionInfos = parseCtx._walkActionInfos;
+ _talkActionInfos = parseCtx._talkActionInfos;
+ _useActionInfos = parseCtx._useActionInfos;
+
Common::HashMap<Common::String, Command *> macros;
Common::HashMap<Common::String, Command *> labels;
@@ -126,4 +136,20 @@ Script::~Script() {
destroy();
}
+const ActionInfos &Script::getLookActionInfos() const {
+ return _lookActionInfos;
+}
+
+const ActionInfos &Script::getWalkActionInfos() const {
+ return _walkActionInfos;
+}
+
+const ActionInfos &Script::getTalkActionInfos() const {
+ return _talkActionInfos;
+}
+
+const ActionInfos &Script::getUseActionInfos() const {
+ return _useActionInfos;
+}
+
}
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index da90a24..be04dc5 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -36,6 +36,24 @@ class Command;
class ConditionalCommand;
typedef Common::Array<Command*> Commands;
+
+struct ActionInfo {
+ enum Action {
+ Walk,
+ Talk,
+ Look,
+ Use
+ };
+
+ Action _action;
+ Common::String _object1Name;
+ Common::String _object2Name;
+ bool _walkTo;
+ Command *_command;
+};
+
+typedef Common::Array<ActionInfo> ActionInfos;
+
class ScriptParseContext
{
public:
@@ -56,21 +74,11 @@ public:
ConditionalCommandInfos _pendingCondCommands;
- enum Action {
- Walk,
- Talk,
- Look,
- Use
- };
+ ActionInfos _lookActionInfos;
+ ActionInfos _walkActionInfos;
+ ActionInfos _talkActionInfos;
+ ActionInfos _useActionInfos;
- struct ActionInfo {
- Action _action;
- Common::String _object1Name;
- Common::String _object2Name;
- bool walkTo;
- };
- typedef Common::Array<ActionInfo> ActionInfos;
- ActionInfos _actionInfos;
private:
};
@@ -78,9 +86,19 @@ class Script {
public:
bool loadFromStream(Common::SeekableReadStream &stream);
~Script();
+
+ const ActionInfos &getLookActionInfos() const;
+ const ActionInfos &getWalkActionInfos() const;
+ const ActionInfos &getTalkActionInfos() const;
+ const ActionInfos &getUseActionInfos() const;
+
private:
void destroy();
Commands _allCommands;
+ ActionInfos _lookActionInfos;
+ ActionInfos _walkActionInfos;
+ ActionInfos _talkActionInfos;
+ ActionInfos _useActionInfos;
};
}
Commit: 5d29112f1c06dea3a789b36b0d109e6529f8cd61
https://github.com/scummvm/scummvm/commit/5d29112f1c06dea3a789b36b0d109e6529f8cd61
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add say command with dummy implementation.
Changed paths:
A engines/mutationofjb/commands/saycommand.cpp
A engines/mutationofjb/commands/saycommand.h
engines/mutationofjb/commands/endblockcommand.cpp
engines/mutationofjb/commands/ifcommand.cpp
engines/mutationofjb/commands/seqcommand.cpp
engines/mutationofjb/commands/seqcommand.h
engines/mutationofjb/module.mk
engines/mutationofjb/script.cpp
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index be610c7..af9282f 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 a41875f..0643c3e 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 0000000..9448203
--- /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 0000000..16303de
--- /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 22d1c90..6c167e9 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 90e3028..0fa30ab 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 09f00db..2c89988 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 8985e06..4490af5 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
};
Commit: bdb6582bb2523f6216f92bbc79a602b33137d023
https://github.com/scummvm/scummvm/commit/bdb6582bb2523f6216f92bbc79a602b33137d023
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Implement data model for inventory.
Changed paths:
A engines/mutationofjb/inventory.cpp
A engines/mutationofjb/inventory.h
engines/mutationofjb/commands/conditionalcommand.h
engines/mutationofjb/debug.h
engines/mutationofjb/encryptedfile.h
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/module.mk
engines/mutationofjb/script.cpp
engines/mutationofjb/util.h
diff --git a/engines/mutationofjb/commands/conditionalcommand.h b/engines/mutationofjb/commands/conditionalcommand.h
index 27a8ac1..6f64720 100644
--- a/engines/mutationofjb/commands/conditionalcommand.h
+++ b/engines/mutationofjb/commands/conditionalcommand.h
@@ -20,6 +20,9 @@
*
*/
+#ifndef MUTATIONOFJB_CONDITIONALCOMMAND_H
+#define MUTATIONOFJB_CONDITIONALCOMMAND_H
+
#include "mutationofjb/commands/command.h"
#include "common/scummsys.h"
@@ -43,3 +46,5 @@ protected:
};
}
+
+#endif
diff --git a/engines/mutationofjb/debug.h b/engines/mutationofjb/debug.h
index 86ee844..a41baca 100644
--- a/engines/mutationofjb/debug.h
+++ b/engines/mutationofjb/debug.h
@@ -20,6 +20,9 @@
*
*/
+#ifndef MUTATIONOFJB_DEBUG_H
+#define MUTATIONOFJB_DEBUG_H
+
#include "gui/debugger.h"
namespace MutationOfJB {
@@ -38,3 +41,5 @@ private:
}
+#endif
+
diff --git a/engines/mutationofjb/encryptedfile.h b/engines/mutationofjb/encryptedfile.h
index 69f6f62..2053f1f 100644
--- a/engines/mutationofjb/encryptedfile.h
+++ b/engines/mutationofjb/encryptedfile.h
@@ -20,6 +20,9 @@
*
*/
+#ifndef MUTATIONOFJB_ENCRYPTEDFILE_H
+#define MUTATIONOFJB_ENCRYPTEDFILE_H
+
#include "common/file.h"
namespace MutationOfJB {
@@ -30,3 +33,5 @@ public:
};
}
+
+#endif
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 9f517d6..15fbd03 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -170,6 +170,7 @@ Static *Scene::getStatic(uint8 staticId) {
return &_statics[staticId - 1];
}
+
GameData::GameData() : _currentScene(0) {}
Scene *GameData::getScene(uint8 sceneId)
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index eda178b..77e336f 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -20,7 +20,11 @@
*
*/
+#ifndef MUTATIONOFJB_GAME_H
+#define MUTATIONOFJB_GAME_H
+
#include "common/scummsys.h"
+#include "mutationofjb/inventory.h"
namespace Common {
class ReadStream;
@@ -133,9 +137,12 @@ public:
bool loadFromStream(Common::ReadStream &stream);
uint8 _currentScene;
+ Inventory _inventory;
private:
Scene _scenes[45];
};
}
+
+#endif
diff --git a/engines/mutationofjb/inventory.cpp b/engines/mutationofjb/inventory.cpp
new file mode 100644
index 0000000..0f91a93
--- /dev/null
+++ b/engines/mutationofjb/inventory.cpp
@@ -0,0 +1,92 @@
+/* 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/inventory.h"
+#include "common/algorithm.h"
+#include "common/debug.h"
+
+namespace MutationOfJB {
+
+static const uint VISIBLE_ITEMS = 6;
+
+const Inventory::Items &Inventory::getItems() const {
+ return _items;
+}
+
+void Inventory::addItem(const Common::String &item) {
+ _items.push_back(item);
+
+ if (_items.size() > VISIBLE_ITEMS) {
+ rotateItemsRight(VISIBLE_ITEMS);
+ }
+}
+
+void Inventory::removeItem(const Common::String &item) {
+ Items::iterator it = find(_items.begin(), _items.end(), item);
+ if (it == _items.end()) {
+ debug("Item '%s' not in inventory.", item.c_str());
+ return;
+ }
+
+ _items.remove_at(it - _items.begin());
+}
+
+void Inventory::removeAllItems() {
+ _items.clear();
+}
+
+void Inventory::rotateItemsRight(uint n) {
+ if (_items.size() < 2) {
+ return;
+ }
+
+ n %= _items.size();
+
+ reverseItems(0, _items.size() - 1);
+ reverseItems(0, n - 1);
+ reverseItems(n, _items.size() - 1);
+}
+
+void Inventory::rotateItemsLeft(uint n) {
+ if (_items.size() < 2) {
+ return;
+ }
+
+ n %= _items.size();
+ reverseItems(0, _items.size() - 1);
+ reverseItems(_items.size() - n, _items.size() - 1);
+ reverseItems(0, _items.size() - n - 1);
+}
+
+void Inventory::reverseItems(uint from, uint to) {
+ assert(from <= to);
+ if (from == to) {
+ return;
+ }
+
+ const uint size = to - from + 1;
+ for (uint i = 0; i < size / 2; ++i) {
+ SWAP(_items[i], _items[size - i - 1]);
+ }
+}
+
+}
diff --git a/engines/mutationofjb/inventory.h b/engines/mutationofjb/inventory.h
new file mode 100644
index 0000000..02cccc0
--- /dev/null
+++ b/engines/mutationofjb/inventory.h
@@ -0,0 +1,52 @@
+/* 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_INVENTORY_H
+#define MUTATIONOFJB_INVENTORY_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/str.h"
+
+namespace MutationOfJB {
+
+class Inventory {
+public:
+ typedef Common::Array<Common::String> Items;
+
+ const Items &getItems() const;
+ void addItem(const Common::String &item);
+ void removeItem(const Common::String &item);
+ void removeAllItems();
+
+ void rotateItemsRight(uint n);
+ void rotateItemsLeft(uint n);
+
+private:
+ void reverseItems(uint from, uint to);
+
+ Items _items;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 2c89988..f719ae0 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -12,6 +12,7 @@ MODULE_OBJS := \
detection.o \
encryptedfile.o \
game.o \
+ inventory.o \
mutationofjb.o \
room.o \
script.o \
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 4490af5..98b1727 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -69,7 +69,7 @@ bool ScriptParseContext::readLine(Common::String &line) {
}
return true;
}
- } while(_stream.eos());
+ } while(!_stream.eos());
return false;
}
diff --git a/engines/mutationofjb/util.h b/engines/mutationofjb/util.h
index 3059d51..7dd7495 100644
--- a/engines/mutationofjb/util.h
+++ b/engines/mutationofjb/util.h
@@ -20,6 +20,11 @@
*
*/
+#ifndef MUTATIONOFJB_UTIL_H
+#define MUTATIONOFJB_UTIL_H
+
namespace MutationOfJB {
void reportFileMissingError(const char *fileName);
}
+
+#endif
Commit: dae522f63c05029298da1694038af9b24655ac05
https://github.com/scummvm/scummvm/commit/dae522f63c05029298da1694038af9b24655ac05
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Implement inventory commands.
Changed paths:
A engines/mutationofjb/commands/additemcommand.cpp
A engines/mutationofjb/commands/additemcommand.h
A engines/mutationofjb/commands/removeallitemscommand.cpp
A engines/mutationofjb/commands/removeallitemscommand.h
A engines/mutationofjb/commands/removeitemcommand.cpp
A engines/mutationofjb/commands/removeitemcommand.h
engines/mutationofjb/module.mk
diff --git a/engines/mutationofjb/commands/additemcommand.cpp b/engines/mutationofjb/commands/additemcommand.cpp
new file mode 100644
index 0000000..b0c7d21
--- /dev/null
+++ b/engines/mutationofjb/commands/additemcommand.cpp
@@ -0,0 +1,52 @@
+/* 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/additemcommand.h"
+#include "mutationofjb/game.h"
+
+/*
+ "ADDITEM" " " <item>
+
+ Adds item to inventory.
+*/
+
+namespace MutationOfJB {
+
+bool AddItemCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
+ if (!line.hasPrefix("ADDITEM") || line.size() < 9) {
+ return false;
+ }
+
+ command = new AddItemCommand(line.c_str() + 8);
+ return true;
+}
+
+Command::ExecuteResult AddItemCommand::execute(GameData &gameData) {
+ gameData._inventory.addItem(_item);
+ return Finished;
+}
+
+Common::String AddItemCommand::debugString() const {
+ return Common::String::format("ADDITEM '%s'", _item.c_str());
+}
+
+}
diff --git a/engines/mutationofjb/commands/additemcommand.h b/engines/mutationofjb/commands/additemcommand.h
new file mode 100644
index 0000000..cb4c131
--- /dev/null
+++ b/engines/mutationofjb/commands/additemcommand.h
@@ -0,0 +1,50 @@
+/* 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_ADDITEMCOMMAND_H
+#define MUTATIONOFJB_ADDITEMCOMMAND_H
+
+#include "mutationofjb/commands/seqcommand.h"
+#include "common/str.h"
+
+namespace MutationOfJB {
+
+class AddItemCommandParser : public SeqCommandParser {
+public:
+ AddItemCommandParser() {}
+
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+};
+
+class AddItemCommand : public SeqCommand {
+public:
+ AddItemCommand(const Common::String &item) : _item(item) {}
+
+ virtual ExecuteResult execute(GameData &gameData) override;
+ virtual Common::String debugString() const override;
+private:
+ Common::String _item;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/commands/removeallitemscommand.cpp b/engines/mutationofjb/commands/removeallitemscommand.cpp
new file mode 100644
index 0000000..8c6309f
--- /dev/null
+++ b/engines/mutationofjb/commands/removeallitemscommand.cpp
@@ -0,0 +1,52 @@
+/* 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/removeallitemscommand.h"
+#include "mutationofjb/game.h"
+
+/*
+ "DELALLITEMS"
+
+ Removes all items from inventory.
+*/
+
+namespace MutationOfJB {
+
+bool RemoveAllItemsCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
+ if (line != "DELALLITEMS") {
+ return false;
+ }
+
+ command = new RemoveAllItemsCommand();
+ return true;
+}
+
+Command::ExecuteResult RemoveAllItemsCommand::execute(GameData &gameData) {
+ gameData._inventory.removeAllItems();
+ return Finished;
+}
+
+Common::String RemoveAllItemsCommand::debugString() const {
+ return "DELALLITEM";
+}
+
+}
diff --git a/engines/mutationofjb/commands/removeallitemscommand.h b/engines/mutationofjb/commands/removeallitemscommand.h
new file mode 100644
index 0000000..166aed8
--- /dev/null
+++ b/engines/mutationofjb/commands/removeallitemscommand.h
@@ -0,0 +1,48 @@
+/* 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_REMOVEALLITEMSCOMMAND_H
+#define MUTATIONOFJB_REMOVEALLITEMSCOMMAND_H
+
+#include "mutationofjb/commands/seqcommand.h"
+
+namespace MutationOfJB {
+
+class RemoveAllItemsCommandParser : public SeqCommandParser {
+public:
+ RemoveAllItemsCommandParser() {}
+
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+};
+
+class RemoveAllItemsCommand : public SeqCommand {
+public:
+ RemoveAllItemsCommand() {}
+
+ virtual ExecuteResult execute(GameData &gameData) override;
+ virtual Common::String debugString() const override;
+private:
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/commands/removeitemcommand.cpp b/engines/mutationofjb/commands/removeitemcommand.cpp
new file mode 100644
index 0000000..c6aad0e
--- /dev/null
+++ b/engines/mutationofjb/commands/removeitemcommand.cpp
@@ -0,0 +1,52 @@
+/* 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/removeitemcommand.h"
+#include "mutationofjb/game.h"
+
+/*
+ "DELITEM" " " <item>
+
+ Removes item from inventory.
+*/
+
+namespace MutationOfJB {
+
+bool RemoveItemCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
+ if (!line.hasPrefix("DELITEM") || line.size() < 9) {
+ return false;
+ }
+
+ command = new RemoveItemCommand(line.c_str() + 8);
+ return true;
+}
+
+Command::ExecuteResult RemoveItemCommand::execute(GameData &gameData) {
+ gameData._inventory.removeItem(_item);
+ return Finished;
+}
+
+Common::String RemoveItemCommand::debugString() const {
+ return Common::String::format("DELITEM '%s'", _item.c_str());
+}
+
+}
diff --git a/engines/mutationofjb/commands/removeitemcommand.h b/engines/mutationofjb/commands/removeitemcommand.h
new file mode 100644
index 0000000..452a3b2
--- /dev/null
+++ b/engines/mutationofjb/commands/removeitemcommand.h
@@ -0,0 +1,50 @@
+/* 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_REMOVEITEMCOMMAND_H
+#define MUTATIONOFJB_REMOVEITEMCOMMAND_H
+
+#include "mutationofjb/commands/seqcommand.h"
+#include "common/str.h"
+
+namespace MutationOfJB {
+
+class RemoveItemCommandParser : public SeqCommandParser {
+public:
+ RemoveItemCommandParser() {}
+
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+};
+
+class RemoveItemCommand : public SeqCommand {
+public:
+ RemoveItemCommand(const Common::String &item) : _item(item) {}
+
+ virtual ExecuteResult execute(GameData &gameData) override;
+ virtual Common::String debugString() const override;
+private:
+ Common::String _item;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index f719ae0..27c4f4b 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -1,11 +1,14 @@
MODULE := engines/mutationofjb
MODULE_OBJS := \
+ commands/additemcommand.o \
commands/changecommand.o \
commands/command.o \
commands/conditionalcommand.o \
commands/endblockcommand.o \
commands/ifcommand.o \
+ commands/removeallitemscommand.o \
+ commands/removeitemcommand.o \
commands/saycommand.o \
commands/seqcommand.o \
debug.o \
Commit: b4dad9bca7593029ab368bc99f7bd96c71cbf4d8
https://github.com/scummvm/scummvm/commit/b4dad9bca7593029ab368bc99f7bd96c71cbf4d8
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Show multiple script commands in showsection debug command.
Changed paths:
engines/mutationofjb/commands/saycommand.cpp
engines/mutationofjb/commands/saycommand.h
engines/mutationofjb/debug.cpp
engines/mutationofjb/debug.h
engines/mutationofjb/script.cpp
diff --git a/engines/mutationofjb/commands/saycommand.cpp b/engines/mutationofjb/commands/saycommand.cpp
index 9448203..a0c9c79 100644
--- a/engines/mutationofjb/commands/saycommand.cpp
+++ b/engines/mutationofjb/commands/saycommand.cpp
@@ -93,7 +93,9 @@ bool SayCommandParser::parse(const Common::String &line, ScriptParseContext &par
break;
}
}
- startPos++;
+ if (startPos != currentLine.size()) {
+ startPos++;
+ }
uint endPos;
for (endPos = startPos; endPos < currentLine.size(); ++endPos) {
@@ -120,7 +122,7 @@ bool SayCommandParser::parse(const Common::String &line, ScriptParseContext &par
if (lineToSay.empty()) {
lineToSay = talkStr;
} else {
- lineToSay = " " + talkStr;
+ lineToSay += " " + talkStr;
}
if (cont) {
diff --git a/engines/mutationofjb/commands/saycommand.h b/engines/mutationofjb/commands/saycommand.h
index 16303de..e2a1207 100644
--- a/engines/mutationofjb/commands/saycommand.h
+++ b/engines/mutationofjb/commands/saycommand.h
@@ -37,7 +37,7 @@ public:
class SayCommand : public SeqCommand {
public:
- SayCommand(Common::String &lineToSay, Common::String &voiceFile, bool waitForPrevious, bool talkingAnimation) :
+ SayCommand(const Common::String &lineToSay, const Common::String &voiceFile, bool waitForPrevious, bool talkingAnimation) :
_lineToSay(lineToSay),
_voiceFile(voiceFile),
_waitForPrevious(waitForPrevious),
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index 4861ab1..cf96fc6 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -24,6 +24,8 @@
#include "mutationofjb/mutationofjb.h"
#include "mutationofjb/script.h"
#include "mutationofjb/commands/command.h"
+#include "mutationofjb/commands/seqcommand.h"
+#include "mutationofjb/commands/conditionalcommand.h"
#include "common/debug-channels.h"
#include "common/translation.h"
#include "common/scummsys.h"
@@ -87,6 +89,31 @@ bool Console::cmd_listsections(int argc, const char **argv) {
return true;
}
+void Console::showIndent(int indentLevel) {
+ for (int i = 0; i < indentLevel; ++i) {
+ debugPrintf(" ");
+ }
+}
+
+void Console::showCommands(Command *command, int indentLevel) {
+ while (command) {
+ showIndent(indentLevel);
+ debugPrintf("%s\n", command->debugString().c_str());
+
+ if (SeqCommand *const seqCmd = dynamic_cast<SeqCommand *>(command)) {
+ command = seqCmd->next();
+ } else if (ConditionalCommand *const condCmd = dynamic_cast<ConditionalCommand *>(command)) {
+ showCommands(condCmd->getTrueCommand(), indentLevel + 1);
+ showIndent(indentLevel);
+ debugPrintf("ELSE\n");
+ showCommands(condCmd->getFalseCommand(), indentLevel + 1);
+ command = nullptr;
+ } else {
+ command = nullptr;
+ }
+ }
+}
+
bool Console::cmd_showsection(int argc, const char **argv) {
if (argc == 4) {
Script *script = nullptr;
@@ -146,7 +173,7 @@ bool Console::cmd_showsection(int argc, const char **argv) {
if (found) {
if (command) {
- debugPrintf("%s\n", command->debugString().c_str());
+ showCommands(command);
}
} else {
debugPrintf("Section not found.\n");
diff --git a/engines/mutationofjb/debug.h b/engines/mutationofjb/debug.h
index a41baca..ee187cb 100644
--- a/engines/mutationofjb/debug.h
+++ b/engines/mutationofjb/debug.h
@@ -28,6 +28,7 @@
namespace MutationOfJB {
class MutationOfJBEngine;
+class Command;
class Console : public GUI::Debugger {
public:
@@ -36,6 +37,10 @@ public:
private:
bool cmd_listsections(int argc, const char **argv);
bool cmd_showsection(int argc, const char **argv);
+
+ void showIndent(int indentLevel);
+ void showCommands(Command *command, int indentLevel = 0);
+
MutationOfJBEngine *_vm;
};
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 98b1727..1b11545 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -31,6 +31,9 @@
#include "mutationofjb/commands/endblockcommand.h"
#include "mutationofjb/commands/changecommand.h"
#include "mutationofjb/commands/saycommand.h"
+#include "mutationofjb/commands/additemcommand.h"
+#include "mutationofjb/commands/removeitemcommand.h"
+#include "mutationofjb/commands/removeallitemscommand.h"
namespace MutationOfJB {
@@ -43,6 +46,9 @@ static CommandParser** getParsers() {
new ChangeStaticCommandParser,
new ChangeSceneCommandParser,
new SayCommandParser,
+ new AddItemCommandParser,
+ new RemoveItemCommandParser,
+ new RemoveAllItemsCommandParser,
nullptr
};
Commit: d3e281e24cb0ce522dc943b2d2a6bdde0766b62c
https://github.com/scummvm/scummvm/commit/d3e281e24cb0ce522dc943b2d2a6bdde0766b62c
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Fix uninitialized ChangeOperation, fix parsing tag in IF command and add some comments.
Changed paths:
engines/mutationofjb/commands/changecommand.cpp
engines/mutationofjb/commands/ifcommand.cpp
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
diff --git a/engines/mutationofjb/commands/changecommand.cpp b/engines/mutationofjb/commands/changecommand.cpp
index e9bb9cc..e4699eb 100644
--- a/engines/mutationofjb/commands/changecommand.cpp
+++ b/engines/mutationofjb/commands/changecommand.cpp
@@ -195,8 +195,9 @@ bool ChangeSceneCommandParser::parse(const Common::String &line, ScriptParseCont
}
int ChangeCommandParser::parseInteger(const char *val, ChangeCommand::ChangeOperation &op) {
+ op = ChangeCommand::SetValue;
+
if (!val || !(*val)) {
- op = ChangeCommand::SetValue;
return 0;
}
diff --git a/engines/mutationofjb/commands/ifcommand.cpp b/engines/mutationofjb/commands/ifcommand.cpp
index 0643c3e..a2816c7 100644
--- a/engines/mutationofjb/commands/ifcommand.cpp
+++ b/engines/mutationofjb/commands/ifcommand.cpp
@@ -64,7 +64,7 @@ bool IfCommandParser::parse(const Common::String &line, ScriptParseContext &pars
}
const char *const cstr = line.c_str();
- const char tag = cstr[2];
+ const char tag = cstr[2] == ' ' ? 0 : cstr[2];
const uint8 sceneId = atoi(cstr + 3);
const uint8 objectId = atoi(cstr + 6);
const uint8 value = atoi(cstr + 9);
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 15fbd03..c79f8d9 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -92,7 +92,7 @@ bool Static::loadFromStream(Common::ReadStream &stream) {
}
bool Bitmap::loadFromStream(Common::ReadStream &stream) {
- _unknown = stream.readByte();
+ _frame = stream.readByte();
_isVisible = stream.readByte();
_x1 = stream.readUint16LE();
_y1 = stream.readByte();
@@ -133,8 +133,7 @@ bool Scene::loadFromStream(Common::ReadStream &stream) {
_bitmaps[i].loadFromStream(stream);
}
- _obstacleY1 = stream.readByte();
- _unknown386 = stream.readByte();
+ _obstacleY1 = stream.readUint16LE();
_palRotStart = stream.readByte();
_palRotEnd = stream.readByte();
_palRotPeriod = stream.readByte();
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index 77e336f..550be2e 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -35,16 +35,33 @@ namespace MutationOfJB {
static const uint8 MAX_STR_LENGTH = 0x14;
struct Door {
+ /*
+ Door name.
+ Can be empty - deactivates door completely.
+ */
char _name[MAX_STR_LENGTH + 1];
+ /*
+ Scene ID where the door leads.
+ Can be 0 - you can hover your mouse over it, but clicking it doesn't do anything (unless scripted).
+ */
uint8 _destSceneId;
+ /* X coordinate for player's position after going through the door. */
uint16 _destX;
+ /* Y coordinate for player's position after going through the door. */
uint16 _destY;
+ /* X coordinate of the door rectangle. */
uint16 _x;
+ /* Y coordinate of the door rectangle. */
uint8 _y;
+ /* Width of the door rectangle. */
uint16 _width;
+ /* Height of the door rectangle. */
uint8 _height;
+ /* X coordinate for position towards player will walk after clicking the door. */
uint16 _walkToX;
+ /* Y coordinate for position towards player will walk after clicking the door. */
uint8 _walkToY;
+ /* Unknown for now - likely not even used. */
uint8 _SP;
bool loadFromStream(Common::ReadStream &stream);
@@ -84,7 +101,7 @@ struct Static {
};
struct Bitmap {
- uint8 _unknown;
+ uint8 _frame;
uint8 _isVisible;
uint16 _x1;
uint8 _y1;
@@ -118,8 +135,7 @@ struct Scene {
Bitmap _bitmaps[10];
- uint8 _obstacleY1;
- uint8 _unknown386;
+ uint16 _obstacleY1;
uint8 _palRotStart;
uint8 _palRotEnd;
uint8 _palRotPeriod;
Commit: 5854d310eee2c4a6fc4d189009631d4042ce0df8
https://github.com/scummvm/scummvm/commit/5854d310eee2c4a6fc4d189009631d4042ce0df8
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Fix some code formatting issues.
Changed paths:
engines/mutationofjb/commands/changecommand.h
engines/mutationofjb/commands/endblockcommand.cpp
engines/mutationofjb/commands/ifcommand.cpp
engines/mutationofjb/commands/seqcommand.cpp
engines/mutationofjb/commands/seqcommand.h
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/inventory.cpp
engines/mutationofjb/mutationofjb.cpp
engines/mutationofjb/room.cpp
engines/mutationofjb/script.cpp
engines/mutationofjb/script.h
engines/mutationofjb/util.cpp
engines/mutationofjb/util.h
diff --git a/engines/mutationofjb/commands/changecommand.h b/engines/mutationofjb/commands/changecommand.h
index d590fa5..af9a608 100644
--- a/engines/mutationofjb/commands/changecommand.h
+++ b/engines/mutationofjb/commands/changecommand.h
@@ -110,7 +110,7 @@ public:
class ChangeDoorCommand : public ChangeCommand {
public:
- ChangeDoorCommand(uint8 sceneId, uint8 doorId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue& val)
+ ChangeDoorCommand(uint8 sceneId, uint8 doorId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue &val)
: ChangeCommand(sceneId, doorId, reg, op, val)
{}
virtual ExecuteResult execute(GameData &gameData) override;
@@ -119,7 +119,7 @@ public:
class ChangeObjectCommand : public ChangeCommand {
public:
- ChangeObjectCommand(uint8 sceneId, uint8 objectId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue& val)
+ ChangeObjectCommand(uint8 sceneId, uint8 objectId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue &val)
: ChangeCommand(sceneId, objectId, reg, op, val)
{}
virtual ExecuteResult execute(GameData &gameData) override;
@@ -128,7 +128,7 @@ public:
class ChangeStaticCommand : public ChangeCommand {
public:
- ChangeStaticCommand(uint8 sceneId, uint8 staticId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue& val)
+ ChangeStaticCommand(uint8 sceneId, uint8 staticId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue &val)
: ChangeCommand(sceneId, staticId, reg, op, val)
{}
virtual ExecuteResult execute(GameData &gameData) override;
@@ -137,7 +137,7 @@ public:
class ChangeSceneCommand : public ChangeCommand {
public:
- ChangeSceneCommand(uint8 sceneId, uint8 staticId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue& val)
+ ChangeSceneCommand(uint8 sceneId, uint8 staticId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue &val)
: ChangeCommand(sceneId, staticId, reg, op, val)
{}
virtual ExecuteResult execute(GameData &gameData) override;
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index af9282f..2f1901d 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -28,7 +28,7 @@
namespace MutationOfJB {
-bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *& command) {
+bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) {
if (line.empty()) {
return false;
}
diff --git a/engines/mutationofjb/commands/ifcommand.cpp b/engines/mutationofjb/commands/ifcommand.cpp
index a2816c7..da8efc1 100644
--- a/engines/mutationofjb/commands/ifcommand.cpp
+++ b/engines/mutationofjb/commands/ifcommand.cpp
@@ -94,12 +94,12 @@ IfCommand::IfCommand(uint8 sceneId, uint8 objectId, uint16 value, bool negative)
{}
Command::ExecuteResult IfCommand::execute(GameData &gameData) {
- Scene* const scene = gameData.getScene(_sceneId);
+ Scene *const scene = gameData.getScene(_sceneId);
if (!scene) {
return Finished;
}
- Object* const object = scene->getObject(_objectId);
+ Object *const object = scene->getObject(_objectId);
if (!object) {
return Finished;
}
diff --git a/engines/mutationofjb/commands/seqcommand.cpp b/engines/mutationofjb/commands/seqcommand.cpp
index 6c167e9..03d9538 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, CommandParser *) {
+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 0fa30ab..c3455ce 100644
--- a/engines/mutationofjb/commands/seqcommand.h
+++ b/engines/mutationofjb/commands/seqcommand.h
@@ -28,8 +28,7 @@
namespace MutationOfJB {
-class SeqCommandParser : public CommandParser
-{
+class SeqCommandParser : public CommandParser {
public:
virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser) override;
};
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index c79f8d9..4b6d98e 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -27,8 +27,7 @@
namespace MutationOfJB {
-static bool readString(Common::ReadStream &stream, char *str)
-{
+static bool readString(Common::ReadStream &stream, char *str) {
char buf[MAX_STR_LENGTH];
memset(str, 0, MAX_STR_LENGTH + 1);
@@ -172,8 +171,7 @@ Static *Scene::getStatic(uint8 staticId) {
GameData::GameData() : _currentScene(0) {}
-Scene *GameData::getScene(uint8 sceneId)
-{
+Scene *GameData::getScene(uint8 sceneId) {
if (sceneId == 0 || sceneId > ARRAYSIZE(_scenes)) {
warning(_("Scene %d does not exist"), sceneId);
return nullptr;
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index 550be2e..26f4d38 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -144,8 +144,7 @@ struct Scene {
bool loadFromStream(Common::ReadStream &stream);
};
-struct GameData
-{
+struct GameData {
public:
GameData();
Scene *getScene(uint8 sceneId);
diff --git a/engines/mutationofjb/inventory.cpp b/engines/mutationofjb/inventory.cpp
index 0f91a93..8dcec8d 100644
--- a/engines/mutationofjb/inventory.cpp
+++ b/engines/mutationofjb/inventory.cpp
@@ -60,7 +60,6 @@ void Inventory::rotateItemsRight(uint n) {
}
n %= _items.size();
-
reverseItems(0, _items.size() - 1);
reverseItems(0, n - 1);
reverseItems(n, _items.size() - 1);
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index 3576fd5..17ff7b5 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -47,8 +47,7 @@ MutationOfJBEngine::MutationOfJBEngine(OSystem *syst)
_room(nullptr),
_screen(nullptr),
_globalScript(nullptr),
- _localScript(nullptr)
-{
+ _localScript(nullptr) {
debug("MutationOfJBEngine::MutationOfJBEngine");
}
@@ -72,8 +71,7 @@ bool MutationOfJBEngine::loadGameData(bool partB) {
return true;
}
-void MutationOfJBEngine::setupCursor()
-{
+void MutationOfJBEngine::setupCursor() {
const uint8 white[] = {0xFF, 0xFF, 0xFF};
const uint8 cursor[] = {0xFF};
@@ -120,7 +118,7 @@ Common::Error MutationOfJBEngine::run() {
}
case Common::EVENT_LBUTTONDOWN:
{
- const Scene* const scene = _gameData->getScene(_gameData->_currentScene);
+ const Scene *const scene = _gameData->getScene(_gameData->_currentScene);
if (scene) {
for (int i = 0; i < MIN(ARRAYSIZE(scene->_doors), (int) scene->_noDoors); ++i) {
const Door &door = scene->_doors[i];
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
index eae430a..8d8fbdb 100644
--- a/engines/mutationofjb/room.cpp
+++ b/engines/mutationofjb/room.cpp
@@ -98,7 +98,7 @@ void Room::loadPalette(EncryptedFile &file) {
void Room::loadBackground(EncryptedFile &file, uint32 size) {
_screen->clear();
- uint8 * const pixels = static_cast<uint8 *>(_screen->getPixels());
+ uint8 *const pixels = static_cast<uint8 *>(_screen->getPixels());
uint8 *ptr = pixels;
uint32 readBytes = 0;
uint32 lines = 0;
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 1b11545..5f4b526 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -37,8 +37,8 @@
namespace MutationOfJB {
-static CommandParser** getParsers() {
- static CommandParser* parsers[] = {
+static CommandParser **getParsers() {
+ static CommandParser *parsers[] = {
new IfCommandParser,
new EndBlockCommandParser,
new ChangeDoorCommandParser,
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index be04dc5..275ed78 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -34,7 +34,7 @@ namespace MutationOfJB {
class Command;
class ConditionalCommand;
-typedef Common::Array<Command*> Commands;
+typedef Common::Array<Command *> Commands;
struct ActionInfo {
diff --git a/engines/mutationofjb/util.cpp b/engines/mutationofjb/util.cpp
index 41d2a3a..0878748 100644
--- a/engines/mutationofjb/util.cpp
+++ b/engines/mutationofjb/util.cpp
@@ -26,10 +26,12 @@
#include "engines/engine.h"
namespace MutationOfJB {
- void reportFileMissingError(const char *fileName) {
- Common::String errorMessage = Common::String::format(_("Unable to locate the '%s' engine data file."), fileName);
- GUIErrorMessage(errorMessage);
- warning("%s", errorMessage.c_str());
- }
+
+void reportFileMissingError(const char *fileName) {
+ Common::String errorMessage = Common::String::format(_("Unable to locate the '%s' engine data file."), fileName);
+ GUIErrorMessage(errorMessage);
+ warning("%s", errorMessage.c_str());
+}
+
}
diff --git a/engines/mutationofjb/util.h b/engines/mutationofjb/util.h
index 7dd7495..95a896d 100644
--- a/engines/mutationofjb/util.h
+++ b/engines/mutationofjb/util.h
@@ -24,7 +24,9 @@
#define MUTATIONOFJB_UTIL_H
namespace MutationOfJB {
- void reportFileMissingError(const char *fileName);
+
+void reportFileMissingError(const char *fileName);
+
}
#endif
Commit: 37ae32e1d376aa672e3f0b45f3820fe244c7772b
https://github.com/scummvm/scummvm/commit/37ae32e1d376aa672e3f0b45f3820fe244c7772b
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Don't store ActionInfo pointers, because they might be invalidated, and parse/show actions with two objects correctly.
Changed paths:
engines/mutationofjb/commands/endblockcommand.cpp
engines/mutationofjb/commands/endblockcommand.h
engines/mutationofjb/debug.cpp
engines/mutationofjb/script.cpp
engines/mutationofjb/script.h
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index 2f1901d..019c3b5 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -42,33 +42,43 @@ bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext
if (line.size() >= 4 && (line.hasPrefix("#L ") || line.hasPrefix("-L "))) {
ActionInfo ai = {ActionInfo::Look, line.c_str() + 3, "", firstChar == '#', nullptr};
- parseCtx._lookActionInfos.push_back(ai);
- _pendingActionInfos.push_back(&parseCtx._lookActionInfos.back());
+ parseCtx._actionInfos.push_back(ai);
+ _pendingActionInfos.push_back(parseCtx._actionInfos.size() - 1);
} else if (line.size() >= 4 && (line.hasPrefix("#W ") || line.hasPrefix("-W "))) {
ActionInfo ai = {ActionInfo::Walk, line.c_str() + 3, "", firstChar == '#', nullptr};
- parseCtx._walkActionInfos.push_back(ai);
- _pendingActionInfos.push_back(&parseCtx._walkActionInfos.back());
+ parseCtx._actionInfos.push_back(ai);
+ _pendingActionInfos.push_back(parseCtx._actionInfos.size() - 1);
} else if (line.size() >= 4 && (line.hasPrefix("#T ") || line.hasPrefix("-T "))) {
ActionInfo ai = {ActionInfo::Talk, line.c_str() + 3, "", firstChar == '#', nullptr};
- parseCtx._talkActionInfos.push_back(ai);
- _pendingActionInfos.push_back(&parseCtx._talkActionInfos.back());
+ parseCtx._actionInfos.push_back(ai);
+ _pendingActionInfos.push_back(parseCtx._actionInfos.size() - 1);
} else if (line.size() >= 4 && (line.hasPrefix("#U ") || line.hasPrefix("-U "))) {
int secondObjPos = -1;
- for (int i = 3; i < (int) line.size(); ++i) {
+ for (uint i = 3; i < line.size(); ++i) {
if (line[i] == ' ') {
secondObjPos = i + 1;
break;
}
}
+
+ Common::String obj1;
+ Common::String obj2;
+ if (secondObjPos == -1) {
+ obj1 = line.c_str() + 3;
+ } else {
+ obj1 = Common::String(line.c_str() + 3, secondObjPos - 4);
+ obj2 = line.c_str() + secondObjPos;
+ }
+
ActionInfo ai = {
ActionInfo::Use,
- line.c_str() + 3,
- (secondObjPos != -1) ? line.c_str() + secondObjPos : "",
+ obj1,
+ obj2,
firstChar == '#',
nullptr
};
- parseCtx._useActionInfos.push_back(ai);
- _pendingActionInfos.push_back(&parseCtx._useActionInfos.back());
+ parseCtx._actionInfos.push_back(ai);
+ _pendingActionInfos.push_back(parseCtx._actionInfos.size() - 1);
} else if ((line.hasPrefix("#ELSE") || line.hasPrefix("=ELSE"))) {
_elseFound = true;
_ifTag = 0;
@@ -101,12 +111,13 @@ void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *,
_ifTag = 0;
}
- if (!_pendingActionInfos.empty() && newCommandParser != this) {
- debug("Fixing pending action info.");
- for (Common::Array<ActionInfo *>::iterator it = _pendingActionInfos.begin(); it != _pendingActionInfos.end(); ++it) {
- (*it)->_command = newCommand;
+ if (newCommandParser != this) {
+ if (!_pendingActionInfos.empty()) {
+ for (Common::Array<uint>::iterator it = _pendingActionInfos.begin(); it != _pendingActionInfos.end(); ++it) {
+ parseCtx._actionInfos[*it]._command = newCommand;
+ }
+ _pendingActionInfos.clear();
}
- _pendingActionInfos.clear();
}
}
diff --git a/engines/mutationofjb/commands/endblockcommand.h b/engines/mutationofjb/commands/endblockcommand.h
index 51f7993..24c4e5c 100644
--- a/engines/mutationofjb/commands/endblockcommand.h
+++ b/engines/mutationofjb/commands/endblockcommand.h
@@ -41,7 +41,8 @@ public:
private:
bool _elseFound;
char _ifTag;
- Common::Array<ActionInfo*> _pendingActionInfos;
+
+ Common::Array<uint> _pendingActionInfos;
};
class EndBlockCommand : public Command {
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index cf96fc6..92758af 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -77,7 +77,11 @@ bool Console::cmd_listsections(int argc, const char **argv) {
const ActionInfos &actionInfos = script->getUseActionInfos();
for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
const ActionInfo &actionInfo = *it;
- debugPrintf(_("Use %s\n"), actionInfo._object1Name.c_str());
+ if (actionInfo._object2Name.empty()) {
+ debugPrintf(_("Use %s\n"), actionInfo._object1Name.c_str());
+ } else {
+ debugPrintf(_("Use %s %s\n"), actionInfo._object1Name.c_str(), actionInfo._object2Name.c_str());
+ }
}
} else {
debugPrintf(_("Choose 'L' (look), 'W' (walk), 'T' (talk) or 'U' (use).\n"));
@@ -115,7 +119,7 @@ void Console::showCommands(Command *command, int indentLevel) {
}
bool Console::cmd_showsection(int argc, const char **argv) {
- if (argc == 4) {
+ if (argc >= 4) {
Script *script = nullptr;
if (strcmp(argv[1], "G") == 0) {
script = _vm->getGlobalScript();
@@ -161,7 +165,7 @@ bool Console::cmd_showsection(int argc, const char **argv) {
const ActionInfos &actionInfos = script->getUseActionInfos();
for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
const ActionInfo &actionInfo = *it;
- if (actionInfo._object1Name == argv[3]) {
+ if (actionInfo._object1Name == argv[3] && ((argc == 4 && actionInfo._object2Name.empty()) || (argc > 4 && actionInfo._object2Name == argv[4]))) {
found = true;
command = actionInfo._command;
break;
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 5f4b526..1df6c91 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -122,10 +122,20 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) {
lastParser = currentParser;
}
- _lookActionInfos = parseCtx._lookActionInfos;
- _walkActionInfos = parseCtx._walkActionInfos;
- _talkActionInfos = parseCtx._talkActionInfos;
- _useActionInfos = parseCtx._useActionInfos;
+ for (ActionInfos::iterator it = parseCtx._actionInfos.begin(); it != parseCtx._actionInfos.end(); ++it) {
+ if (it->_action == ActionInfo::Look) {
+ _lookActionInfos.push_back(*it);
+ }
+ if (it->_action == ActionInfo::Walk) {
+ _walkActionInfos.push_back(*it);
+ }
+ if (it->_action == ActionInfo::Talk) {
+ _talkActionInfos.push_back(*it);
+ }
+ if (it->_action == ActionInfo::Use) {
+ _useActionInfos.push_back(*it);
+ }
+ }
Common::HashMap<Common::String, Command *> macros;
Common::HashMap<Common::String, Command *> labels;
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 275ed78..563dbc7 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -74,10 +74,7 @@ public:
ConditionalCommandInfos _pendingCondCommands;
- ActionInfos _lookActionInfos;
- ActionInfos _walkActionInfos;
- ActionInfos _talkActionInfos;
- ActionInfos _useActionInfos;
+ ActionInfos _actionInfos;
private:
};
Commit: fa9c8be1292e1f0174454193807f39b5c3ee52bf
https://github.com/scummvm/scummvm/commit/fa9c8be1292e1f0174454193807f39b5c3ee52bf
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Convert section names to 7bit ASCII in debug console.
Changed paths:
engines/mutationofjb/debug.cpp
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index 92758af..c4eb0a3 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -32,12 +32,25 @@
namespace MutationOfJB {
-/*
-TODO
-static Common::String convertTo7bitASCII() {
- return Common::String();
+/* Converts CP895 string to 7bit ASCII, so we can show it in the console. */
+static Common::String convertToASCII(const Common::String &str) {
+ static const char conversionTable[] = {
+ 'C', 'u', 'e', 'd', 'a', 'D', 'T', 'c', 'e', 'E', 'L', 'I', 'l', 'l', 'A', 'A', /* 0x80-0x8F */
+ 'E', 'z', 'Z', 'o', 'o', 'O', 'u', 'U', 'y', 'O', 'U', 'S', 'L', 'Y', 'R', 't', /* 0x90-0x9F */
+ 'a', 'i', 'o', 'u', 'n', 'N', 'U', 'O', 's', 'r', 'r', 'R' /* 0xA0-0xAB */
+ };
+
+ Common::String ret = str;
+ for (Common::String::iterator it = ret.begin(); it != ret.end(); ++it) {
+ const byte cp895Byte = reinterpret_cast<const byte &>(*it);
+ if (cp895Byte >= 0x80 && cp895Byte <= 0xAB) {
+ *it = conversionTable[cp895Byte - 0x80];
+ } else if (cp895Byte == 0xE1) { // ß
+ *it = 's';
+ }
+ }
+ return ret;
}
-*/
Console::Console(MutationOfJBEngine *vm) : _vm(vm) {
registerCmd("listsections", WRAP_METHOD(Console, cmd_listsections));
@@ -59,28 +72,28 @@ bool Console::cmd_listsections(int argc, const char **argv) {
const ActionInfos &actionInfos = script->getLookActionInfos();
for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
const ActionInfo &actionInfo = *it;
- debugPrintf(_("Look %s\n"), actionInfo._object1Name.c_str());
+ debugPrintf(_("Look %s\n"), convertToASCII(actionInfo._object1Name).c_str());
}
} else if (strcmp(argv[2], "W") == 0) {
const ActionInfos &actionInfos = script->getWalkActionInfos();
for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
const ActionInfo &actionInfo = *it;
- debugPrintf(_("Walk %s\n"), actionInfo._object1Name.c_str());
+ debugPrintf(_("Walk %s\n"), convertToASCII(actionInfo._object1Name).c_str());
}
} else if (strcmp(argv[2], "T") == 0) {
const ActionInfos &actionInfos = script->getTalkActionInfos();
for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
const ActionInfo &actionInfo = *it;
- debugPrintf(_("Talk %s\n"), actionInfo._object1Name.c_str());
+ debugPrintf(_("Talk %s\n"), convertToASCII(actionInfo._object1Name).c_str());
}
} else if (strcmp(argv[2], "U") == 0) {
const ActionInfos &actionInfos = script->getUseActionInfos();
for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
const ActionInfo &actionInfo = *it;
if (actionInfo._object2Name.empty()) {
- debugPrintf(_("Use %s\n"), actionInfo._object1Name.c_str());
+ debugPrintf(_("Use %s\n"), convertToASCII(actionInfo._object1Name).c_str());
} else {
- debugPrintf(_("Use %s %s\n"), actionInfo._object1Name.c_str(), actionInfo._object2Name.c_str());
+ debugPrintf(_("Use %s %s\n"), convertToASCII(actionInfo._object1Name).c_str(), convertToASCII(actionInfo._object2Name).c_str());
}
}
} else {
@@ -135,7 +148,7 @@ bool Console::cmd_showsection(int argc, const char **argv) {
const ActionInfos &actionInfos = script->getLookActionInfos();
for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
const ActionInfo &actionInfo = *it;
- if (actionInfo._object1Name == argv[3]) {
+ if (convertToASCII(actionInfo._object1Name) == argv[3]) {
found = true;
command = actionInfo._command;
break;
@@ -145,7 +158,7 @@ bool Console::cmd_showsection(int argc, const char **argv) {
const ActionInfos &actionInfos = script->getWalkActionInfos();
for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
const ActionInfo &actionInfo = *it;
- if (actionInfo._object1Name == argv[3]) {
+ if (convertToASCII(actionInfo._object1Name) == argv[3]) {
found = true;
command = actionInfo._command;
break;
@@ -155,7 +168,7 @@ bool Console::cmd_showsection(int argc, const char **argv) {
const ActionInfos &actionInfos = script->getTalkActionInfos();
for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
const ActionInfo &actionInfo = *it;
- if (actionInfo._object1Name == argv[3]) {
+ if (convertToASCII(actionInfo._object1Name) == argv[3]) {
found = true;
command = actionInfo._command;
break;
@@ -165,7 +178,7 @@ bool Console::cmd_showsection(int argc, const char **argv) {
const ActionInfos &actionInfos = script->getUseActionInfos();
for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
const ActionInfo &actionInfo = *it;
- if (actionInfo._object1Name == argv[3] && ((argc == 4 && actionInfo._object2Name.empty()) || (argc > 4 && actionInfo._object2Name == argv[4]))) {
+ if (convertToASCII(actionInfo._object1Name) == argv[3] && ((argc == 4 && actionInfo._object2Name.empty()) || (argc > 4 && convertToASCII(actionInfo._object2Name) == argv[4]))) {
found = true;
command = actionInfo._command;
break;
Commit: ae979a831091e04797f19d0c80210d745cd60f62
https://github.com/scummvm/scummvm/commit/ae979a831091e04797f19d0c80210d745cd60f62
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add support for IFITEM command and fix parsing conditional commands that are right after #ELSE.
Changed paths:
A engines/mutationofjb/commands/ifitemcommand.cpp
A engines/mutationofjb/commands/ifitemcommand.h
engines/mutationofjb/commands/conditionalcommand.cpp
engines/mutationofjb/commands/conditionalcommand.h
engines/mutationofjb/commands/ifcommand.cpp
engines/mutationofjb/commands/ifcommand.h
engines/mutationofjb/debug.cpp
engines/mutationofjb/inventory.cpp
engines/mutationofjb/inventory.h
engines/mutationofjb/module.mk
engines/mutationofjb/script.cpp
diff --git a/engines/mutationofjb/commands/conditionalcommand.cpp b/engines/mutationofjb/commands/conditionalcommand.cpp
index 13ea674..1e0b755 100644
--- a/engines/mutationofjb/commands/conditionalcommand.cpp
+++ b/engines/mutationofjb/commands/conditionalcommand.cpp
@@ -21,10 +21,24 @@
*/
#include "mutationofjb/commands/conditionalcommand.h"
+#include "mutationofjb/script.h"
#include "common/scummsys.h"
+#include "common/translation.h"
namespace MutationOfJB {
+void ConditionalCommandParser::transition(ScriptParseContext &parseContext, Command *oldCommand, Command *newCommand, CommandParser *) {
+ if (!oldCommand || !newCommand) {
+ warning(_("Unexpected empty command in transition"));
+ return;
+ }
+
+ ConditionalCommand *const condCommand = static_cast<ConditionalCommand *>(oldCommand);
+ parseContext.addConditionalCommand(condCommand, _lastTag);
+ condCommand->setTrueCommand(newCommand);
+}
+
+
ConditionalCommand::ConditionalCommand() :
_trueCommand(nullptr),
_falseCommand(nullptr),
diff --git a/engines/mutationofjb/commands/conditionalcommand.h b/engines/mutationofjb/commands/conditionalcommand.h
index 6f64720..4a4e7e1 100644
--- a/engines/mutationofjb/commands/conditionalcommand.h
+++ b/engines/mutationofjb/commands/conditionalcommand.h
@@ -28,6 +28,13 @@
namespace MutationOfJB {
+class ConditionalCommandParser : public CommandParser {
+public:
+ virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser);
+protected:
+ char _lastTag;
+};
+
class ConditionalCommand : public Command {
public:
ConditionalCommand();
diff --git a/engines/mutationofjb/commands/ifcommand.cpp b/engines/mutationofjb/commands/ifcommand.cpp
index da8efc1..44c6b18 100644
--- a/engines/mutationofjb/commands/ifcommand.cpp
+++ b/engines/mutationofjb/commands/ifcommand.cpp
@@ -31,12 +31,12 @@
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>.
+ Otherwise execution continues after first "#ELSE" or "=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.
+ Please note that this does not work like 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
@@ -70,20 +70,11 @@ bool IfCommandParser::parse(const Common::String &line, ScriptParseContext &pars
const uint8 value = atoi(cstr + 9);
const bool negative = (line.lastChar() == '!');
- IfCommand *ifCommand = new IfCommand(sceneId, objectId, value, negative);
+ _lastTag = tag;
- command = ifCommand;
- parseContext.addConditionalCommand(ifCommand, tag);
- return true;
-}
+ command = new IfCommand(sceneId, objectId, value, negative);
-void IfCommandParser::transition(ScriptParseContext &, Command *oldCommand, Command *newCommand, CommandParser *) {
- if (!oldCommand || !newCommand) {
- warning(_("Unexpected empty command in transition"));
- return;
- }
-
- static_cast<IfCommand *>(oldCommand)->setTrueCommand(newCommand);
+ return true;
}
IfCommand::IfCommand(uint8 sceneId, uint8 objectId, uint16 value, bool negative) :
diff --git a/engines/mutationofjb/commands/ifcommand.h b/engines/mutationofjb/commands/ifcommand.h
index 9462278..51350ce 100644
--- a/engines/mutationofjb/commands/ifcommand.h
+++ b/engines/mutationofjb/commands/ifcommand.h
@@ -30,16 +30,14 @@ namespace MutationOfJB {
class ScriptParseContext;
-class IfCommandParser : public CommandParser {
+class IfCommandParser : public ConditionalCommandParser {
public:
virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
- virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser);
+private:
};
class IfCommand : public ConditionalCommand {
public:
- static bool ParseFunc(const Common::String &line, ScriptParseContext &parseContext, Command *&command);
-
IfCommand(uint8 sceneId, uint8 objectId, uint16 value, bool negative);
virtual ExecuteResult execute(GameData &gameData) override;
@@ -50,8 +48,6 @@ private:
uint8 _objectId;
uint16 _value;
bool _negative;
-
- bool _cachedResult;
};
}
diff --git a/engines/mutationofjb/commands/ifitemcommand.cpp b/engines/mutationofjb/commands/ifitemcommand.cpp
new file mode 100644
index 0000000..6f467da
--- /dev/null
+++ b/engines/mutationofjb/commands/ifitemcommand.cpp
@@ -0,0 +1,90 @@
+/* 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/ifitemcommand.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/script.h"
+#include "mutationofjb/util.h"
+#include "common/str.h"
+#include "common/translation.h"
+
+/*
+ "IFITEM" <item> ["!"]
+
+ IFITEM command tests whether an item is in the inventory.
+ If it is, execution continues to the next line.
+ Otherwise execution continues after first "#ELSE" or "=ELSE".
+ The logic can be reversed with exclamation mark at the end.
+
+ Please note that this does not work like you are used to from saner languages.
+ IFITEM does not have any blocks. It only searches for first #ELSE, so you can have stuff like:
+ IFITEM item1
+ IFITEM item2
+ #ELSE
+ ...
+ This is effectively logical AND.
+*/
+
+namespace MutationOfJB {
+
+bool IfItemCommandParser::parse(const Common::String &line, ScriptParseContext &parseContext, Command *&command) {
+ if (line.size() < 8) {
+ return false;
+ }
+
+ if (!line.hasPrefix("IFITEM")) {
+ return false;
+ }
+
+ const bool negative = (line.lastChar() == '!');
+ Common::String item(line.c_str() + 7);
+ if (negative) {
+ item.deleteLastChar(); // Remove '!'.
+ }
+
+ _lastTag = 0;
+ command = new IfItemCommand(item, negative);
+
+ return true;
+}
+
+
+IfItemCommand::IfItemCommand(const Common::String &item, bool negative) :
+ _item(item),
+ _negative(negative)
+{}
+
+Command::ExecuteResult IfItemCommand::execute(GameData &gameData) {
+ _cachedResult = gameData._inventory.hasItem(_item);
+ if (_negative) {
+ _cachedResult = !_cachedResult;
+ }
+
+ return Finished;
+}
+
+Common::String IfItemCommand::debugString() const {
+ return Common::String::format("IFITEM %s%s", _negative ? "NOT " : "", _item.c_str());
+}
+
+}
+
diff --git a/engines/mutationofjb/commands/ifitemcommand.h b/engines/mutationofjb/commands/ifitemcommand.h
new file mode 100644
index 0000000..0451786
--- /dev/null
+++ b/engines/mutationofjb/commands/ifitemcommand.h
@@ -0,0 +1,53 @@
+/* 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_IFITEMCOMMAND_H
+#define MUTATIONOFJB_IFITEMCOMMAND_H
+
+#include "mutationofjb/commands/conditionalcommand.h"
+#include "common/scummsys.h"
+#include "common/str.h"
+
+namespace MutationOfJB {
+
+class ScriptParseContext;
+
+class IfItemCommandParser : public ConditionalCommandParser {
+public:
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+};
+
+class IfItemCommand : public ConditionalCommand {
+public:
+ IfItemCommand(const Common::String &item, bool negative);
+
+ virtual ExecuteResult execute(GameData &gameData) override;
+ virtual Common::String debugString() const;
+
+private:
+ Common::String _item;
+ bool _negative;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index c4eb0a3..87f0091 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -115,7 +115,7 @@ void Console::showIndent(int indentLevel) {
void Console::showCommands(Command *command, int indentLevel) {
while (command) {
showIndent(indentLevel);
- debugPrintf("%s\n", command->debugString().c_str());
+ debugPrintf("%s\n", convertToASCII(command->debugString()).c_str());
if (SeqCommand *const seqCmd = dynamic_cast<SeqCommand *>(command)) {
command = seqCmd->next();
diff --git a/engines/mutationofjb/inventory.cpp b/engines/mutationofjb/inventory.cpp
index 8dcec8d..4a46548 100644
--- a/engines/mutationofjb/inventory.cpp
+++ b/engines/mutationofjb/inventory.cpp
@@ -32,6 +32,11 @@ const Inventory::Items &Inventory::getItems() const {
return _items;
}
+bool Inventory::hasItem(const Common::String &item) const {
+ Items::const_iterator it = find(_items.begin(), _items.end(), item);
+ return (it != _items.end());
+}
+
void Inventory::addItem(const Common::String &item) {
_items.push_back(item);
diff --git a/engines/mutationofjb/inventory.h b/engines/mutationofjb/inventory.h
index 02cccc0..fe7ca67 100644
--- a/engines/mutationofjb/inventory.h
+++ b/engines/mutationofjb/inventory.h
@@ -34,6 +34,7 @@ public:
typedef Common::Array<Common::String> Items;
const Items &getItems() const;
+ bool hasItem(const Common::String &item) const;
void addItem(const Common::String &item);
void removeItem(const Common::String &item);
void removeAllItems();
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 27c4f4b..0dfe130 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS := \
commands/conditionalcommand.o \
commands/endblockcommand.o \
commands/ifcommand.o \
+ commands/ifitemcommand.o \
commands/removeallitemscommand.o \
commands/removeitemcommand.o \
commands/saycommand.o \
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 1df6c91..c959f0f 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -28,6 +28,7 @@
#include "common/debug.h"
#include "mutationofjb/commands/command.h"
#include "mutationofjb/commands/ifcommand.h"
+#include "mutationofjb/commands/ifitemcommand.h"
#include "mutationofjb/commands/endblockcommand.h"
#include "mutationofjb/commands/changecommand.h"
#include "mutationofjb/commands/saycommand.h"
@@ -39,6 +40,7 @@ namespace MutationOfJB {
static CommandParser **getParsers() {
static CommandParser *parsers[] = {
+ new IfItemCommandParser,
new IfCommandParser,
new EndBlockCommandParser,
new ChangeDoorCommandParser,
Commit: 523f973e0a4ba16b278d546da9267a693924f957
https://github.com/scummvm/scummvm/commit/523f973e0a4ba16b278d546da9267a693924f957
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add support of IFPIGGY command.
Changed paths:
A engines/mutationofjb/commands/ifpiggycommand.cpp
A engines/mutationofjb/commands/ifpiggycommand.h
engines/mutationofjb/game.h
engines/mutationofjb/module.mk
engines/mutationofjb/script.cpp
diff --git a/engines/mutationofjb/commands/ifpiggycommand.cpp b/engines/mutationofjb/commands/ifpiggycommand.cpp
new file mode 100644
index 0000000..2ecd437
--- /dev/null
+++ b/engines/mutationofjb/commands/ifpiggycommand.cpp
@@ -0,0 +1,71 @@
+/* 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/ifpiggycommand.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/script.h"
+#include "mutationofjb/util.h"
+#include "common/str.h"
+#include "common/translation.h"
+
+/*
+ "IFPIGGY"
+
+ IFPIGGY command tests whether current loaded APK file (character animation) is "piggy.apk".
+ If it is, execution continues to the next line.
+ Otherwise execution continues after first "#ELSE" or "=ELSE".
+
+ Please note that this does not work like you are used to from saner languages.
+ IFPIGGY does not have any blocks. It only searches for first #ELSE, so you can have stuff like:
+ IFPIGGY
+ IFITEM someitem
+ #ELSE
+ ...
+ This is effectively logical AND.
+*/
+
+namespace MutationOfJB {
+
+bool IfPiggyCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
+ if (line != "IFPIGGY") {
+ return false;
+ }
+
+ _lastTag = 0;
+ command = new IfPiggyCommand();
+
+ return true;
+}
+
+
+Command::ExecuteResult IfPiggyCommand::execute(GameData &gameData) {
+ _cachedResult = gameData._currentAPK == "piggy.apk";
+
+ return Finished;
+}
+
+Common::String IfPiggyCommand::debugString() const {
+ return "IFPIGGY";
+}
+
+}
+
diff --git a/engines/mutationofjb/commands/ifpiggycommand.h b/engines/mutationofjb/commands/ifpiggycommand.h
new file mode 100644
index 0000000..3fb6826
--- /dev/null
+++ b/engines/mutationofjb/commands/ifpiggycommand.h
@@ -0,0 +1,49 @@
+/* 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_IFPIGGYCOMMAND_H
+#define MUTATIONOFJB_IFPIGGYCOMMAND_H
+
+#include "mutationofjb/commands/conditionalcommand.h"
+#include "common/scummsys.h"
+#include "common/str.h"
+
+namespace MutationOfJB {
+
+class ScriptParseContext;
+
+class IfPiggyCommandParser : public ConditionalCommandParser {
+public:
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+};
+
+class IfPiggyCommand : public ConditionalCommand {
+public:
+ virtual ExecuteResult execute(GameData &gameData) override;
+ virtual Common::String debugString() const;
+
+private:
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index 26f4d38..6eafc79 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -153,6 +153,7 @@ public:
uint8 _currentScene;
Inventory _inventory;
+ Common::String _currentAPK;
private:
Scene _scenes[45];
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 0dfe130..e66a4c8 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -8,6 +8,7 @@ MODULE_OBJS := \
commands/endblockcommand.o \
commands/ifcommand.o \
commands/ifitemcommand.o \
+ commands/ifpiggycommand.o \
commands/removeallitemscommand.o \
commands/removeitemcommand.o \
commands/saycommand.o \
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index c959f0f..771a990 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -29,6 +29,7 @@
#include "mutationofjb/commands/command.h"
#include "mutationofjb/commands/ifcommand.h"
#include "mutationofjb/commands/ifitemcommand.h"
+#include "mutationofjb/commands/ifpiggycommand.h"
#include "mutationofjb/commands/endblockcommand.h"
#include "mutationofjb/commands/changecommand.h"
#include "mutationofjb/commands/saycommand.h"
@@ -40,6 +41,7 @@ namespace MutationOfJB {
static CommandParser **getParsers() {
static CommandParser *parsers[] = {
+ new IfPiggyCommandParser,
new IfItemCommandParser,
new IfCommandParser,
new EndBlockCommandParser,
Commit: 54c2c0aee6e371f8058c50e0a4113f5b5492169e
https://github.com/scummvm/scummvm/commit/54c2c0aee6e371f8058c50e0a4113f5b5492169e
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add support for labels and goto.
Changed paths:
A engines/mutationofjb/commands/gotocommand.cpp
A engines/mutationofjb/commands/gotocommand.h
A engines/mutationofjb/commands/labelcommand.cpp
A engines/mutationofjb/commands/labelcommand.h
engines/mutationofjb/module.mk
engines/mutationofjb/script.cpp
engines/mutationofjb/script.h
diff --git a/engines/mutationofjb/commands/gotocommand.cpp b/engines/mutationofjb/commands/gotocommand.cpp
new file mode 100644
index 0000000..77c474b
--- /dev/null
+++ b/engines/mutationofjb/commands/gotocommand.cpp
@@ -0,0 +1,80 @@
+/* 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/gotocommand.h"
+#include "mutationofjb/commands/labelcommand.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/script.h"
+
+/*
+ GOTO <label>
+
+ Jumps to a label.
+*/
+
+namespace MutationOfJB {
+
+bool GotoCommandParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) {
+ if (line.firstChar() != '_') {
+ return false;
+ }
+
+ Common::String label = line.c_str() + 1;
+ GotoCommand *gotoCmd = new GotoCommand();
+
+ if (parseCtx._labels.contains(label)) {
+ // We already have the label, set it.
+ gotoCmd->setLabelCommand(parseCtx._labels[label]);
+ } else {
+ // Label is after goto, add to pending list.
+ parseCtx._pendingGotos[label].push_back(gotoCmd);
+ }
+
+ command = gotoCmd;
+
+ return true;
+}
+
+
+void GotoCommand::setLabelCommand(LabelCommand *labelCmd) {
+ _labelCommand = labelCmd;
+}
+
+Command::ExecuteResult GotoCommand::execute(GameData &) {
+ // Intentionally empty.
+
+ return Finished;
+}
+
+Command *GotoCommand::next() const {
+ return _labelCommand;
+}
+
+Common::String GotoCommand::debugString() const {
+ if (!_labelCommand) {
+ return "GOTO (null)";
+ }
+
+ return Common::String::format("GOTO %s", _labelCommand->getName().c_str());
+}
+
+}
diff --git a/engines/mutationofjb/commands/gotocommand.h b/engines/mutationofjb/commands/gotocommand.h
new file mode 100644
index 0000000..436dd44
--- /dev/null
+++ b/engines/mutationofjb/commands/gotocommand.h
@@ -0,0 +1,55 @@
+/* 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_GOTOCOMMAND_H
+#define MUTATIONOFJB_GOTOCOMMAND_H
+
+#include "mutationofjb/commands/command.h"
+#include "common/str.h"
+
+namespace MutationOfJB {
+
+class LabelCommand;
+
+class GotoCommandParser : public CommandParser {
+public:
+ GotoCommandParser() {}
+
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+};
+
+class GotoCommand : public Command {
+public:
+ GotoCommand() : _labelCommand(nullptr) {}
+
+ void setLabelCommand(LabelCommand *labelCmd);
+
+ virtual ExecuteResult execute(GameData &gameData) override;
+ virtual Command *next() const override;
+ virtual Common::String debugString() const override;
+private:
+ LabelCommand *_labelCommand;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/commands/labelcommand.cpp b/engines/mutationofjb/commands/labelcommand.cpp
new file mode 100644
index 0000000..4540a83
--- /dev/null
+++ b/engines/mutationofjb/commands/labelcommand.cpp
@@ -0,0 +1,78 @@
+/* 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/labelcommand.h"
+#include "mutationofjb/commands/gotocommand.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/script.h"
+
+/*
+ <label> ":"
+
+ Creates a label.
+*/
+
+namespace MutationOfJB {
+
+bool LabelCommandParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) {
+ if (line.lastChar() != ':') {
+ return false;
+ }
+
+ Common::String label = line;
+ label.deleteLastChar();
+
+ LabelCommand *labelCmd = new LabelCommand(label);
+ if (!parseCtx._labels.contains(line)) {
+ parseCtx._labels[line] = labelCmd;
+ } else {
+ warning("Label '%s' already exists", label.c_str());
+ }
+
+ if (parseCtx._pendingGotos.contains(label)) {
+ GotoCommands &gotos = parseCtx._pendingGotos[label];
+ for (GotoCommands::const_iterator it = gotos.begin(); it != gotos.end(); ++it) {
+ (*it)->setLabelCommand(labelCmd);
+ }
+ gotos.clear();
+ }
+
+ command = labelCmd;
+ return true;
+}
+
+const Common::String &LabelCommand::getName() const
+{
+ return _name;
+}
+
+Command::ExecuteResult LabelCommand::execute(GameData &) {
+ // Intentionally empty.
+
+ return Finished;
+}
+
+Common::String LabelCommand::debugString() const {
+ return Common::String::format("LABEL %s", _name.c_str());
+}
+
+}
diff --git a/engines/mutationofjb/commands/labelcommand.h b/engines/mutationofjb/commands/labelcommand.h
new file mode 100644
index 0000000..389c759
--- /dev/null
+++ b/engines/mutationofjb/commands/labelcommand.h
@@ -0,0 +1,51 @@
+/* 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_LABELCOMMAND_H
+#define MUTATIONOFJB_LABELCOMMAND_H
+
+#include "mutationofjb/commands/seqcommand.h"
+#include "common/str.h"
+
+namespace MutationOfJB {
+
+class LabelCommandParser : public SeqCommandParser {
+public:
+ LabelCommandParser() {}
+
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+};
+
+class LabelCommand : public SeqCommand {
+public:
+ LabelCommand(const Common::String &name) : _name(name) {}
+ const Common::String &getName() const;
+
+ virtual ExecuteResult execute(GameData &gameData) override;
+ virtual Common::String debugString() const override;
+private:
+ Common::String _name;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index e66a4c8..8ad1507 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -6,9 +6,11 @@ MODULE_OBJS := \
commands/command.o \
commands/conditionalcommand.o \
commands/endblockcommand.o \
+ commands/gotocommand.o \
commands/ifcommand.o \
commands/ifitemcommand.o \
commands/ifpiggycommand.o \
+ commands/labelcommand.o \
commands/removeallitemscommand.o \
commands/removeitemcommand.o \
commands/saycommand.o \
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 771a990..95c2bdc 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -36,6 +36,8 @@
#include "mutationofjb/commands/additemcommand.h"
#include "mutationofjb/commands/removeitemcommand.h"
#include "mutationofjb/commands/removeallitemscommand.h"
+#include "mutationofjb/commands/labelcommand.h"
+#include "mutationofjb/commands/gotocommand.h"
namespace MutationOfJB {
@@ -53,6 +55,8 @@ static CommandParser **getParsers() {
new AddItemCommandParser,
new RemoveItemCommandParser,
new RemoveAllItemsCommandParser,
+ new GotoCommandParser,
+ new LabelCommandParser,
nullptr
};
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 563dbc7..7c5e569 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -24,15 +24,19 @@
#define MUTATIONOFJB_SCRIPT_H
#include "common/array.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
namespace Common {
- class SeekableReadStream;
- class String;
+class SeekableReadStream;
+class String;
}
namespace MutationOfJB {
class Command;
+class LabelCommand;
+class GotoCommand;
class ConditionalCommand;
typedef Common::Array<Command *> Commands;
@@ -53,6 +57,7 @@ struct ActionInfo {
};
typedef Common::Array<ActionInfo> ActionInfos;
+typedef Common::Array<GotoCommand *> GotoCommands;
class ScriptParseContext
{
@@ -71,9 +76,14 @@ public:
char _tag;
};
typedef Common::Array<ConditionalCommandInfo> ConditionalCommandInfos;
-
ConditionalCommandInfos _pendingCondCommands;
+ typedef Common::HashMap<Common::String, LabelCommand *> LabelMap;
+ LabelMap _labels;
+
+ typedef Common::HashMap<Common::String, GotoCommands> PendingGotoMap;
+ PendingGotoMap _pendingGotos;
+
ActionInfos _actionInfos;
private:
Commit: fb75e483e43a00bb20329dd0b5db92a3588a2d2e
https://github.com/scummvm/scummvm/commit/fb75e483e43a00bb20329dd0b5db92a3588a2d2e
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Fix GOTO command.
Changed paths:
engines/mutationofjb/commands/gotocommand.cpp
diff --git a/engines/mutationofjb/commands/gotocommand.cpp b/engines/mutationofjb/commands/gotocommand.cpp
index 77c474b..92cce14 100644
--- a/engines/mutationofjb/commands/gotocommand.cpp
+++ b/engines/mutationofjb/commands/gotocommand.cpp
@@ -34,11 +34,11 @@
namespace MutationOfJB {
bool GotoCommandParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) {
- if (line.firstChar() != '_') {
+ if (line.size() < 6 || !line.hasPrefix("GOTO")) {
return false;
}
- Common::String label = line.c_str() + 1;
+ Common::String label = line.c_str() + 6;
GotoCommand *gotoCmd = new GotoCommand();
if (parseCtx._labels.contains(label)) {
Commit: 1d84041508b3acaf7a47fde81e7e334c004507b8
https://github.com/scummvm/scummvm/commit/1d84041508b3acaf7a47fde81e7e334c004507b8
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add Game class.
Changed paths:
A engines/mutationofjb/gamedata.cpp
A engines/mutationofjb/gamedata.h
engines/mutationofjb/commands/additemcommand.cpp
engines/mutationofjb/commands/changecommand.h
engines/mutationofjb/commands/gotocommand.cpp
engines/mutationofjb/commands/ifcommand.cpp
engines/mutationofjb/commands/ifitemcommand.cpp
engines/mutationofjb/commands/ifpiggycommand.cpp
engines/mutationofjb/commands/labelcommand.cpp
engines/mutationofjb/commands/removeallitemscommand.cpp
engines/mutationofjb/commands/removeitemcommand.cpp
engines/mutationofjb/debug.cpp
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/module.mk
engines/mutationofjb/mutationofjb.cpp
engines/mutationofjb/mutationofjb.h
engines/mutationofjb/script.h
diff --git a/engines/mutationofjb/commands/additemcommand.cpp b/engines/mutationofjb/commands/additemcommand.cpp
index b0c7d21..58ec567 100644
--- a/engines/mutationofjb/commands/additemcommand.cpp
+++ b/engines/mutationofjb/commands/additemcommand.cpp
@@ -21,7 +21,7 @@
*/
#include "mutationofjb/commands/additemcommand.h"
-#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
/*
"ADDITEM" " " <item>
diff --git a/engines/mutationofjb/commands/changecommand.h b/engines/mutationofjb/commands/changecommand.h
index af9a608..5ba386b 100644
--- a/engines/mutationofjb/commands/changecommand.h
+++ b/engines/mutationofjb/commands/changecommand.h
@@ -21,7 +21,7 @@
*/
#include "mutationofjb/commands/seqcommand.h"
-#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
namespace MutationOfJB {
diff --git a/engines/mutationofjb/commands/gotocommand.cpp b/engines/mutationofjb/commands/gotocommand.cpp
index 92cce14..40560f3 100644
--- a/engines/mutationofjb/commands/gotocommand.cpp
+++ b/engines/mutationofjb/commands/gotocommand.cpp
@@ -22,7 +22,7 @@
#include "mutationofjb/commands/gotocommand.h"
#include "mutationofjb/commands/labelcommand.h"
-#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
#include "mutationofjb/script.h"
/*
diff --git a/engines/mutationofjb/commands/ifcommand.cpp b/engines/mutationofjb/commands/ifcommand.cpp
index 44c6b18..f78335a 100644
--- a/engines/mutationofjb/commands/ifcommand.cpp
+++ b/engines/mutationofjb/commands/ifcommand.cpp
@@ -21,7 +21,7 @@
*/
#include "mutationofjb/commands/ifcommand.h"
-#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
#include "mutationofjb/script.h"
#include "common/str.h"
#include "common/translation.h"
diff --git a/engines/mutationofjb/commands/ifitemcommand.cpp b/engines/mutationofjb/commands/ifitemcommand.cpp
index 6f467da..7512ba5 100644
--- a/engines/mutationofjb/commands/ifitemcommand.cpp
+++ b/engines/mutationofjb/commands/ifitemcommand.cpp
@@ -21,7 +21,7 @@
*/
#include "mutationofjb/commands/ifitemcommand.h"
-#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
#include "mutationofjb/script.h"
#include "mutationofjb/util.h"
#include "common/str.h"
diff --git a/engines/mutationofjb/commands/ifpiggycommand.cpp b/engines/mutationofjb/commands/ifpiggycommand.cpp
index 2ecd437..cad0a14 100644
--- a/engines/mutationofjb/commands/ifpiggycommand.cpp
+++ b/engines/mutationofjb/commands/ifpiggycommand.cpp
@@ -21,7 +21,7 @@
*/
#include "mutationofjb/commands/ifpiggycommand.h"
-#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
#include "mutationofjb/script.h"
#include "mutationofjb/util.h"
#include "common/str.h"
diff --git a/engines/mutationofjb/commands/labelcommand.cpp b/engines/mutationofjb/commands/labelcommand.cpp
index 4540a83..15a10ca 100644
--- a/engines/mutationofjb/commands/labelcommand.cpp
+++ b/engines/mutationofjb/commands/labelcommand.cpp
@@ -22,7 +22,6 @@
#include "mutationofjb/commands/labelcommand.h"
#include "mutationofjb/commands/gotocommand.h"
-#include "mutationofjb/game.h"
#include "mutationofjb/script.h"
/*
diff --git a/engines/mutationofjb/commands/removeallitemscommand.cpp b/engines/mutationofjb/commands/removeallitemscommand.cpp
index 8c6309f..8043864 100644
--- a/engines/mutationofjb/commands/removeallitemscommand.cpp
+++ b/engines/mutationofjb/commands/removeallitemscommand.cpp
@@ -21,7 +21,7 @@
*/
#include "mutationofjb/commands/removeallitemscommand.h"
-#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
/*
"DELALLITEMS"
diff --git a/engines/mutationofjb/commands/removeitemcommand.cpp b/engines/mutationofjb/commands/removeitemcommand.cpp
index c6aad0e..e4d9601 100644
--- a/engines/mutationofjb/commands/removeitemcommand.cpp
+++ b/engines/mutationofjb/commands/removeitemcommand.cpp
@@ -21,7 +21,7 @@
*/
#include "mutationofjb/commands/removeitemcommand.h"
-#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
/*
"DELITEM" " " <item>
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index 87f0091..e639324 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -21,6 +21,7 @@
*/
#include "mutationofjb/debug.h"
+#include "mutationofjb/game.h"
#include "mutationofjb/mutationofjb.h"
#include "mutationofjb/script.h"
#include "mutationofjb/commands/command.h"
@@ -61,9 +62,9 @@ bool Console::cmd_listsections(int argc, const char **argv) {
if (argc == 3) {
Script *script = nullptr;
if (strcmp(argv[1], "G") == 0) {
- script = _vm->getGlobalScript();
+ script = _vm->getGame().getGlobalScript();
} else if (strcmp(argv[1], "L") == 0) {
- script = _vm->getLocalScript();
+ script = _vm->getGame().getLocalScript();
}
if (!script) {
debugPrintf(_("Choose 'G' (global) or 'L' (local) script.\n"));
@@ -135,9 +136,9 @@ bool Console::cmd_showsection(int argc, const char **argv) {
if (argc >= 4) {
Script *script = nullptr;
if (strcmp(argv[1], "G") == 0) {
- script = _vm->getGlobalScript();
+ script = _vm->getGame().getGlobalScript();
} else if (strcmp(argv[1], "L") == 0) {
- script = _vm->getLocalScript();
+ script = _vm->getGame().getLocalScript();
}
if (!script) {
debugPrintf(_("Choose 'G' (global) or 'L' (local) script.\n"));
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 4b6d98e..6fe6b95 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -21,171 +21,64 @@
*/
#include "mutationofjb/game.h"
-#include "common/stream.h"
+#include "mutationofjb/gamedata.h"
+#include "mutationofjb/encryptedfile.h"
+#include "mutationofjb/mutationofjb.h"
+#include "mutationofjb/room.h"
+#include "mutationofjb/script.h"
+#include "mutationofjb/util.h"
#include "common/util.h"
-#include "common/translation.h"
namespace MutationOfJB {
-static bool readString(Common::ReadStream &stream, char *str) {
- char buf[MAX_STR_LENGTH];
- memset(str, 0, MAX_STR_LENGTH + 1);
+Game::Game(MutationOfJBEngine* vm) : _vm(vm) {
+ _gameData = new GameData;
+ loadGameData(false);
- uint8 len = stream.readByte();
- stream.read(buf, MAX_STR_LENGTH);
+ EncryptedFile globalScriptFile;
+ globalScriptFile.open("global.atn");
+ _globalScript = new Script;
+ _globalScript->loadFromStream(globalScriptFile);
+ globalScriptFile.close();
- len = MIN(len, MAX_STR_LENGTH);
- memcpy(str, buf, len);
+ _localScript = nullptr;
+ _room = new Room(_vm->getScreen());
- return true;
-}
-
-bool Door::loadFromStream(Common::ReadStream &stream) {
- readString(stream, _name);
-
- _destSceneId = stream.readByte();
- _destX = stream.readUint16LE();
- _destY = stream.readUint16LE();
- _x = stream.readUint16LE();
- _y = stream.readByte();
- _width = stream.readUint16LE();
- _height = stream.readByte();
- _walkToX = stream.readUint16LE();
- _walkToY = stream.readByte();
- _SP = stream.readByte();
-
- return true;
+ changeScene(13, false); // Initial scene.
}
-bool Object::loadFromStream(Common::ReadStream &stream) {
- _AC = stream.readByte();
- _FA = stream.readByte();
- _FR = stream.readByte();
- _NA = stream.readByte();
- _FS = stream.readByte();
- _unknown = stream.readByte();
- _CA = stream.readByte();
- _x = stream.readUint16LE();
- _y = stream.readByte();
- _XL = stream.readUint16LE();
- _YL = stream.readByte();
- _WX = stream.readUint16LE();
- _WY = stream.readByte();
- _SP = stream.readByte();
-
- return true;
+GameData &Game::getGameData() {
+ return *_gameData;
}
-bool Static::loadFromStream(Common::ReadStream &stream) {
- _active = stream.readByte();
- readString(stream, _name);
- _x = stream.readUint16LE();
- _y = stream.readByte();
- _width = stream.readUint16LE();
- _height = stream.readByte();
- _walkToX = stream.readUint16LE();
- _walkToY = stream.readByte();
- _SP = stream.readByte();
-
- return true;
+Script *Game::getGlobalScript() const {
+ return _globalScript;
}
-bool Bitmap::loadFromStream(Common::ReadStream &stream) {
- _frame = stream.readByte();
- _isVisible = stream.readByte();
- _x1 = stream.readUint16LE();
- _y1 = stream.readByte();
- _x2 = stream.readUint16LE();
- _y2 = stream.readByte();
-
- return true;
+Script *Game::getLocalScript() const {
+ return _localScript;
}
-bool Scene::loadFromStream(Common::ReadStream &stream) {
- int i;
-
- _startup = stream.readByte();
- _unknown001 = stream.readByte();
- _unknown002 = stream.readByte();
- _unknown003 = stream.readByte();
- _DL = stream.readByte();
-
- _noDoors = stream.readByte();
- _noDoors = MIN(_noDoors, (uint8) ARRAYSIZE(_doors));
- for (i = 0; i < ARRAYSIZE(_doors); ++i) {
- _doors[i].loadFromStream(stream);
- }
-
- _noObjects = stream.readByte();
- _noObjects = MIN(_noObjects, (uint8) ARRAYSIZE(_objects));
- for (i = 0; i < ARRAYSIZE(_objects); ++i) {
- _objects[i].loadFromStream(stream);
+bool Game::loadGameData(bool partB) {
+ EncryptedFile file;
+ const char *fileName = !partB ? "startup.dat" : "startupb.dat";
+ file.open(fileName);
+ if (!file.isOpen()) {
+ reportFileMissingError(fileName);
+ return false;
}
- _noStatics = stream.readByte();
- _noStatics = MIN(_noStatics, (uint8) ARRAYSIZE(_statics));
- for (i = 0; i < ARRAYSIZE(_statics); ++i) {
- _statics[i].loadFromStream(stream);
- }
+ _gameData->loadFromStream(file);
- for (i = 0; i < ARRAYSIZE(_bitmaps); ++i) {
- _bitmaps[i].loadFromStream(stream);
- }
-
- _obstacleY1 = stream.readUint16LE();
- _palRotStart = stream.readByte();
- _palRotEnd = stream.readByte();
- _palRotPeriod = stream.readByte();
- stream.read(_unknown38A, 80);
+ file.close();
return true;
}
-Door *Scene::getDoor(uint8 doorId) {
- if (doorId == 0 || doorId > _noDoors) {
- warning(_("Door %d does not exist"), doorId);
- return nullptr;
- }
- return &_doors[doorId - 1];
-}
-
-Object *Scene::getObject(uint8 objectId) {
- if (objectId == 0 || objectId > _noObjects) {
- warning(_("Object %d does not exist"), objectId);
- return nullptr;
- }
-
- return &_objects[objectId - 1];
-}
-
-Static *Scene::getStatic(uint8 staticId) {
- if (staticId == 0 || staticId > _noStatics) {
- warning(_("Static %d does not exist"), staticId);
- return nullptr;
- }
-
- return &_statics[staticId - 1];
-}
-
-
-GameData::GameData() : _currentScene(0) {}
-
-Scene *GameData::getScene(uint8 sceneId) {
- if (sceneId == 0 || sceneId > ARRAYSIZE(_scenes)) {
- warning(_("Scene %d does not exist"), sceneId);
- return nullptr;
- }
-
- return &_scenes[sceneId - 1];
-}
-
-bool GameData::loadFromStream(Common::ReadStream &stream) {
- for (int i = 0; i < ARRAYSIZE(_scenes); ++i) {
- _scenes[i].loadFromStream(stream);
- }
-
- return true;
+void Game::changeScene(uint8 sceneId, bool partB) {
+ _gameData->_currentScene = sceneId;
+ _room->load(_gameData->_currentScene, partB);
}
}
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index 6eafc79..4b4ab43 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -24,139 +24,33 @@
#define MUTATIONOFJB_GAME_H
#include "common/scummsys.h"
-#include "mutationofjb/inventory.h"
-
-namespace Common {
- class ReadStream;
-}
namespace MutationOfJB {
-static const uint8 MAX_STR_LENGTH = 0x14;
-
-struct Door {
- /*
- Door name.
- Can be empty - deactivates door completely.
- */
- char _name[MAX_STR_LENGTH + 1];
- /*
- Scene ID where the door leads.
- Can be 0 - you can hover your mouse over it, but clicking it doesn't do anything (unless scripted).
- */
- uint8 _destSceneId;
- /* X coordinate for player's position after going through the door. */
- uint16 _destX;
- /* Y coordinate for player's position after going through the door. */
- uint16 _destY;
- /* X coordinate of the door rectangle. */
- uint16 _x;
- /* Y coordinate of the door rectangle. */
- uint8 _y;
- /* Width of the door rectangle. */
- uint16 _width;
- /* Height of the door rectangle. */
- uint8 _height;
- /* X coordinate for position towards player will walk after clicking the door. */
- uint16 _walkToX;
- /* Y coordinate for position towards player will walk after clicking the door. */
- uint8 _walkToY;
- /* Unknown for now - likely not even used. */
- uint8 _SP;
-
- bool loadFromStream(Common::ReadStream &stream);
-};
-
-struct Object {
- uint8 _AC;
- uint8 _FA;
- uint8 _FR;
- uint8 _NA;
- uint8 _FS;
- uint8 _unknown;
- uint8 _CA;
- uint16 _x;
- uint8 _y;
- uint16 _XL;
- uint8 _YL;
- uint16 _WX;
- uint8 _WY;
- uint8 _SP;
-
- bool loadFromStream(Common::ReadStream &stream);
-};
-
-struct Static {
- uint8 _active;
- char _name[MAX_STR_LENGTH + 1];
- uint16 _x;
- uint8 _y;
- uint16 _width;
- uint8 _height;
- uint16 _walkToX;
- uint8 _walkToY;
- uint8 _SP;
-
- bool loadFromStream(Common::ReadStream &stream);
-};
-
-struct Bitmap {
- uint8 _frame;
- uint8 _isVisible;
- uint16 _x1;
- uint8 _y1;
- uint16 _x2;
- uint8 _y2;
-
- bool loadFromStream(Common::ReadStream &stream);
-};
+class MutationOfJBEngine;
+class GameData;
+class Script;
+class Room;
-
-struct Scene {
-
- Door *getDoor(uint8 objectId);
- Object *getObject(uint8 objectId);
- Static *getStatic(uint8 staticId);
-
- uint8 _startup;
- uint8 _unknown001;
- uint8 _unknown002;
- uint8 _unknown003;
- uint8 _DL;
-
- uint8 _noDoors;
- Door _doors[5];
-
- uint8 _noObjects;
- Object _objects[9];
-
- uint8 _noStatics;
- Static _statics[15];
-
- Bitmap _bitmaps[10];
-
- uint16 _obstacleY1;
- uint8 _palRotStart;
- uint8 _palRotEnd;
- uint8 _palRotPeriod;
- uint8 _unknown38A[80];
-
- bool loadFromStream(Common::ReadStream &stream);
-};
-
-struct GameData {
+class Game {
public:
- GameData();
- Scene *getScene(uint8 sceneId);
+ Game(MutationOfJBEngine* vm);
+ GameData &getGameData();
+
+ Script *getGlobalScript() const;
+ Script *getLocalScript() const;
- bool loadFromStream(Common::ReadStream &stream);
+ void changeScene(uint8 sceneId, bool partB);
- uint8 _currentScene;
- Inventory _inventory;
- Common::String _currentAPK;
private:
- Scene _scenes[45];
+ bool loadGameData(bool partB);
+
+ MutationOfJBEngine *_vm;
+ GameData *_gameData;
+ Script *_globalScript;
+ Script *_localScript;
+ Room *_room;
};
}
diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp
new file mode 100644
index 0000000..cc85da3
--- /dev/null
+++ b/engines/mutationofjb/gamedata.cpp
@@ -0,0 +1,193 @@
+/* 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/gamedata.h"
+#include "common/stream.h"
+#include "common/util.h"
+#include "common/translation.h"
+
+namespace MutationOfJB {
+
+static bool readString(Common::ReadStream &stream, char *str) {
+ char buf[MAX_STR_LENGTH];
+ memset(str, 0, MAX_STR_LENGTH + 1);
+
+ uint8 len = stream.readByte();
+ stream.read(buf, MAX_STR_LENGTH);
+
+ len = MIN(len, MAX_STR_LENGTH);
+ memcpy(str, buf, len);
+
+ return true;
+}
+
+bool Door::loadFromStream(Common::ReadStream &stream) {
+ readString(stream, _name);
+
+ _destSceneId = stream.readByte();
+ _destX = stream.readUint16LE();
+ _destY = stream.readUint16LE();
+ _x = stream.readUint16LE();
+ _y = stream.readByte();
+ _width = stream.readUint16LE();
+ _height = stream.readByte();
+ _walkToX = stream.readUint16LE();
+ _walkToY = stream.readByte();
+ _SP = stream.readByte();
+
+ return true;
+}
+
+bool Object::loadFromStream(Common::ReadStream &stream) {
+ _AC = stream.readByte();
+ _FA = stream.readByte();
+ _FR = stream.readByte();
+ _NA = stream.readByte();
+ _FS = stream.readByte();
+ _unknown = stream.readByte();
+ _CA = stream.readByte();
+ _x = stream.readUint16LE();
+ _y = stream.readByte();
+ _XL = stream.readUint16LE();
+ _YL = stream.readByte();
+ _WX = stream.readUint16LE();
+ _WY = stream.readByte();
+ _SP = stream.readByte();
+
+ return true;
+}
+
+bool Static::loadFromStream(Common::ReadStream &stream) {
+ _active = stream.readByte();
+ readString(stream, _name);
+ _x = stream.readUint16LE();
+ _y = stream.readByte();
+ _width = stream.readUint16LE();
+ _height = stream.readByte();
+ _walkToX = stream.readUint16LE();
+ _walkToY = stream.readByte();
+ _SP = stream.readByte();
+
+ return true;
+}
+
+bool Bitmap::loadFromStream(Common::ReadStream &stream) {
+ _frame = stream.readByte();
+ _isVisible = stream.readByte();
+ _x1 = stream.readUint16LE();
+ _y1 = stream.readByte();
+ _x2 = stream.readUint16LE();
+ _y2 = stream.readByte();
+
+ return true;
+}
+
+bool Scene::loadFromStream(Common::ReadStream &stream) {
+ int i;
+
+ _startup = stream.readByte();
+ _unknown001 = stream.readByte();
+ _unknown002 = stream.readByte();
+ _unknown003 = stream.readByte();
+ _DL = stream.readByte();
+
+ _noDoors = stream.readByte();
+ _noDoors = MIN(_noDoors, (uint8) ARRAYSIZE(_doors));
+ for (i = 0; i < ARRAYSIZE(_doors); ++i) {
+ _doors[i].loadFromStream(stream);
+ }
+
+ _noObjects = stream.readByte();
+ _noObjects = MIN(_noObjects, (uint8) ARRAYSIZE(_objects));
+ for (i = 0; i < ARRAYSIZE(_objects); ++i) {
+ _objects[i].loadFromStream(stream);
+ }
+
+ _noStatics = stream.readByte();
+ _noStatics = MIN(_noStatics, (uint8) ARRAYSIZE(_statics));
+ for (i = 0; i < ARRAYSIZE(_statics); ++i) {
+ _statics[i].loadFromStream(stream);
+ }
+
+ for (i = 0; i < ARRAYSIZE(_bitmaps); ++i) {
+ _bitmaps[i].loadFromStream(stream);
+ }
+
+ _obstacleY1 = stream.readUint16LE();
+ _palRotStart = stream.readByte();
+ _palRotEnd = stream.readByte();
+ _palRotPeriod = stream.readByte();
+ stream.read(_unknown38A, 80);
+
+ return true;
+}
+
+Door *Scene::getDoor(uint8 doorId) {
+ if (doorId == 0 || doorId > _noDoors) {
+ warning(_("Door %d does not exist"), doorId);
+ return nullptr;
+ }
+
+ return &_doors[doorId - 1];
+}
+
+Object *Scene::getObject(uint8 objectId) {
+ if (objectId == 0 || objectId > _noObjects) {
+ warning(_("Object %d does not exist"), objectId);
+ return nullptr;
+ }
+
+ return &_objects[objectId - 1];
+}
+
+Static *Scene::getStatic(uint8 staticId) {
+ if (staticId == 0 || staticId > _noStatics) {
+ warning(_("Static %d does not exist"), staticId);
+ return nullptr;
+ }
+
+ return &_statics[staticId - 1];
+}
+
+
+GameData::GameData()
+ : _currentScene(0),
+ _partB(false) {}
+
+Scene *GameData::getScene(uint8 sceneId) {
+ if (sceneId == 0 || sceneId > ARRAYSIZE(_scenes)) {
+ warning(_("Scene %d does not exist"), sceneId);
+ return nullptr;
+ }
+
+ return &_scenes[sceneId - 1];
+}
+
+bool GameData::loadFromStream(Common::ReadStream &stream) {
+ for (int i = 0; i < ARRAYSIZE(_scenes); ++i) {
+ _scenes[i].loadFromStream(stream);
+ }
+
+ return true;
+}
+
+}
diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h
new file mode 100644
index 0000000..23e238a
--- /dev/null
+++ b/engines/mutationofjb/gamedata.h
@@ -0,0 +1,165 @@
+/* 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_GAMEDATA_H
+#define MUTATIONOFJB_GAMEDATA_H
+
+#include "common/scummsys.h"
+#include "mutationofjb/inventory.h"
+
+namespace Common {
+class ReadStream;
+}
+
+namespace MutationOfJB {
+
+static const uint8 MAX_STR_LENGTH = 0x14;
+
+struct Door {
+ /*
+ Door name.
+ Can be empty - deactivates door completely.
+ */
+ char _name[MAX_STR_LENGTH + 1];
+ /*
+ Scene ID where the door leads.
+ Can be 0 - you can hover your mouse over it, but clicking it doesn't do anything (unless scripted).
+ */
+ uint8 _destSceneId;
+ /* X coordinate for player's position after going through the door. */
+ uint16 _destX;
+ /* Y coordinate for player's position after going through the door. */
+ uint16 _destY;
+ /* X coordinate of the door rectangle. */
+ uint16 _x;
+ /* Y coordinate of the door rectangle. */
+ uint8 _y;
+ /* Width of the door rectangle. */
+ uint16 _width;
+ /* Height of the door rectangle. */
+ uint8 _height;
+ /* X coordinate for position towards player will walk after clicking the door. */
+ uint16 _walkToX;
+ /* Y coordinate for position towards player will walk after clicking the door. */
+ uint8 _walkToY;
+ /* Unknown for now - likely not even used. */
+ uint8 _SP;
+
+ bool loadFromStream(Common::ReadStream &stream);
+};
+
+struct Object {
+ uint8 _AC;
+ uint8 _FA;
+ uint8 _FR;
+ uint8 _NA;
+ uint8 _FS;
+ uint8 _unknown;
+ uint8 _CA;
+ uint16 _x;
+ uint8 _y;
+ uint16 _XL;
+ uint8 _YL;
+ uint16 _WX;
+ uint8 _WY;
+ uint8 _SP;
+
+ bool loadFromStream(Common::ReadStream &stream);
+};
+
+struct Static {
+ uint8 _active;
+ char _name[MAX_STR_LENGTH + 1];
+ uint16 _x;
+ uint8 _y;
+ uint16 _width;
+ uint8 _height;
+ uint16 _walkToX;
+ uint8 _walkToY;
+ uint8 _SP;
+
+ bool loadFromStream(Common::ReadStream &stream);
+};
+
+struct Bitmap {
+ uint8 _frame;
+ uint8 _isVisible;
+ uint16 _x1;
+ uint8 _y1;
+ uint16 _x2;
+ uint8 _y2;
+
+ bool loadFromStream(Common::ReadStream &stream);
+};
+
+
+struct Scene {
+
+ Door *getDoor(uint8 objectId);
+ Object *getObject(uint8 objectId);
+ Static *getStatic(uint8 staticId);
+
+ uint8 _startup;
+ uint8 _unknown001;
+ uint8 _unknown002;
+ uint8 _unknown003;
+ uint8 _DL;
+
+ uint8 _noDoors;
+ Door _doors[5];
+
+ uint8 _noObjects;
+ Object _objects[9];
+
+ uint8 _noStatics;
+ Static _statics[15];
+
+ Bitmap _bitmaps[10];
+
+ uint16 _obstacleY1;
+ uint8 _palRotStart;
+ uint8 _palRotEnd;
+ uint8 _palRotPeriod;
+ uint8 _unknown38A[80];
+
+ bool loadFromStream(Common::ReadStream &stream);
+};
+
+struct GameData {
+public:
+ GameData();
+ Scene *getScene(uint8 sceneId);
+
+ bool loadFromStream(Common::ReadStream &stream);
+
+ uint8 _currentScene;
+ bool _partB;
+ Inventory _inventory;
+ Common::String _currentAPK;
+private:
+ Scene _scenes[45];
+
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 8ad1507..4137581 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -19,6 +19,7 @@ MODULE_OBJS := \
detection.o \
encryptedfile.o \
game.o \
+ gamedata.o \
inventory.o \
mutationofjb.o \
room.o \
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index 17ff7b5..66de1f7 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -32,11 +32,8 @@
#include "engines/util.h"
#include "mutationofjb/mutationofjb.h"
-#include "mutationofjb/room.h"
#include "mutationofjb/game.h"
-#include "mutationofjb/encryptedfile.h"
-#include "mutationofjb/util.h"
-#include "mutationofjb/script.h"
+#include "mutationofjb/gamedata.h"
#include "mutationofjb/debug.h"
namespace MutationOfJB {
@@ -44,10 +41,7 @@ namespace MutationOfJB {
MutationOfJBEngine::MutationOfJBEngine(OSystem *syst)
: Engine(syst),
_console(nullptr),
- _room(nullptr),
- _screen(nullptr),
- _globalScript(nullptr),
- _localScript(nullptr) {
+ _screen(nullptr) {
debug("MutationOfJBEngine::MutationOfJBEngine");
}
@@ -55,21 +49,6 @@ MutationOfJBEngine::~MutationOfJBEngine() {
debug("MutationOfJBEngine::~MutationOfJBEngine");
}
-bool MutationOfJBEngine::loadGameData(bool partB) {
- EncryptedFile file;
- const char *fileName = !partB ? "startup.dat" : "startupb.dat";
- file.open(fileName);
- if (!file.isOpen()) {
- reportFileMissingError(fileName);
- return false;
- }
-
- _gameData->loadFromStream(file);
-
- file.close();
-
- return true;
-}
void MutationOfJBEngine::setupCursor() {
const uint8 white[] = {0xFF, 0xFF, 0xFF};
@@ -82,27 +61,24 @@ void MutationOfJBEngine::setupCursor() {
CursorMan.showMouse(true);
}
+Graphics::Screen *MutationOfJBEngine::getScreen() const {
+ return _screen;
+}
+
+Game &MutationOfJBEngine::getGame() {
+ return *_game;
+}
+
Common::Error MutationOfJBEngine::run() {
debug("MutationOfJBEngine::run");
initGraphics(320, 200);
_console = new Console(this);
- _screen = new Graphics::Screen;
- setupCursor();
-
- _gameData = new GameData;
- _gameData->_currentScene = 13;
- loadGameData(false);
+ _screen = new Graphics::Screen();
+ _game = new Game(this);
- _room = new Room(_screen);
- _room->load(_gameData->_currentScene, false);
-
- EncryptedFile globalScriptFile;
- globalScriptFile.open("global.atn");
- _globalScript = new Script;
- _globalScript->loadFromStream(globalScriptFile);
- globalScriptFile.close();
+ setupCursor();
while(!shouldQuit()) {
Common::Event event;
@@ -118,13 +94,12 @@ Common::Error MutationOfJBEngine::run() {
}
case Common::EVENT_LBUTTONDOWN:
{
- const Scene *const scene = _gameData->getScene(_gameData->_currentScene);
+ const Scene *const scene = _game->getGameData().getScene(_game->getGameData()._currentScene);
if (scene) {
for (int i = 0; i < MIN(ARRAYSIZE(scene->_doors), (int) scene->_noDoors); ++i) {
const Door &door = scene->_doors[i];
if ((event.mouse.x >= door._x) && (event.mouse.x < door._x + door._width) && (event.mouse.y >= door._y) && (event.mouse.y < door._y + door._height)) {
- _gameData->_currentScene = door._destSceneId;
- _room->load(_gameData->_currentScene, false);
+ _game->changeScene(door._destSceneId, false);
}
}
}
@@ -143,12 +118,4 @@ Common::Error MutationOfJBEngine::run() {
return Common::kNoError;
}
-Script *MutationOfJBEngine::getGlobalScript() {
- return _globalScript;
-}
-
-Script *MutationOfJBEngine::getLocalScript() {
- return _localScript;
-}
-
}
diff --git a/engines/mutationofjb/mutationofjb.h b/engines/mutationofjb/mutationofjb.h
index efd8898..893cca9 100644
--- a/engines/mutationofjb/mutationofjb.h
+++ b/engines/mutationofjb/mutationofjb.h
@@ -32,9 +32,7 @@ namespace Graphics {
namespace MutationOfJB {
class Console;
-class Room;
-struct GameData;
-class Script;
+class Game;
class MutationOfJBEngine : public Engine {
public:
@@ -42,19 +40,16 @@ public:
~MutationOfJBEngine();
virtual Common::Error run();
- Script *getGlobalScript();
- Script *getLocalScript();
+ Graphics::Screen *getScreen() const;
+ Game &getGame();
private:
bool loadGameData(bool partB);
void setupCursor();
Console *_console;
- Room *_room;
- GameData *_gameData;
Graphics::Screen *_screen;
- Script *_globalScript;
- Script *_localScript;
+ Game *_game;
};
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 7c5e569..66d137c 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -59,13 +59,12 @@ struct ActionInfo {
typedef Common::Array<ActionInfo> ActionInfos;
typedef Common::Array<GotoCommand *> GotoCommands;
-class ScriptParseContext
-{
+class ScriptParseContext {
public:
ScriptParseContext(Common::SeekableReadStream &stream);
bool readLine(Common::String &line);
void addConditionalCommand(ConditionalCommand *command, char tag);
- void addLookSection(const Common::String & item, bool walkTo);
+ void addLookSection(const Common::String &item, bool walkTo);
Common::SeekableReadStream &_stream;
Command *_currentCommand;
Commit: 7a081f0605f2282fdce907bedfc9cae55dc67ab7
https://github.com/scummvm/scummvm/commit/7a081f0605f2282fdce907bedfc9cae55dc67ab7
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Load local (room) scripts.
Changed paths:
engines/mutationofjb/commands/command.cpp
engines/mutationofjb/commands/command.h
engines/mutationofjb/commands/conditionalcommand.cpp
engines/mutationofjb/commands/conditionalcommand.h
engines/mutationofjb/commands/endblockcommand.cpp
engines/mutationofjb/commands/endblockcommand.h
engines/mutationofjb/commands/gotocommand.cpp
engines/mutationofjb/game.cpp
engines/mutationofjb/script.cpp
engines/mutationofjb/util.cpp
diff --git a/engines/mutationofjb/commands/command.cpp b/engines/mutationofjb/commands/command.cpp
index 943986e..6c4dc47 100644
--- a/engines/mutationofjb/commands/command.cpp
+++ b/engines/mutationofjb/commands/command.cpp
@@ -26,6 +26,7 @@
namespace MutationOfJB {
void CommandParser::transition(ScriptParseContext &, Command *, Command *, CommandParser *) {}
+void CommandParser::finish(ScriptParseContext &parseCtx) {}
CommandParser::~CommandParser() {}
Command::~Command() {}
diff --git a/engines/mutationofjb/commands/command.h b/engines/mutationofjb/commands/command.h
index ccfdea2..c6fce1e 100644
--- a/engines/mutationofjb/commands/command.h
+++ b/engines/mutationofjb/commands/command.h
@@ -43,6 +43,9 @@ public:
/* Old command - created by this parser. */
virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser);
+
+ /* Called after parsing. */
+ virtual void finish(ScriptParseContext &parseCtx);
};
class Command {
diff --git a/engines/mutationofjb/commands/conditionalcommand.cpp b/engines/mutationofjb/commands/conditionalcommand.cpp
index 1e0b755..aa42d1c 100644
--- a/engines/mutationofjb/commands/conditionalcommand.cpp
+++ b/engines/mutationofjb/commands/conditionalcommand.cpp
@@ -38,6 +38,10 @@ void ConditionalCommandParser::transition(ScriptParseContext &parseContext, Comm
condCommand->setTrueCommand(newCommand);
}
+void ConditionalCommandParser::finish(ScriptParseContext &) {
+ _lastTag = 0;
+}
+
ConditionalCommand::ConditionalCommand() :
_trueCommand(nullptr),
diff --git a/engines/mutationofjb/commands/conditionalcommand.h b/engines/mutationofjb/commands/conditionalcommand.h
index 4a4e7e1..d64efbf 100644
--- a/engines/mutationofjb/commands/conditionalcommand.h
+++ b/engines/mutationofjb/commands/conditionalcommand.h
@@ -30,7 +30,9 @@ namespace MutationOfJB {
class ConditionalCommandParser : public CommandParser {
public:
+ ConditionalCommandParser() : _lastTag(0) {}
virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser);
+ virtual void finish(ScriptParseContext &parseCtx) override;
protected:
char _lastTag;
};
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index 019c3b5..2d2ebe3 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -121,6 +121,16 @@ void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *,
}
}
+void EndBlockCommandParser::finish(ScriptParseContext &) {
+ _elseFound = false;
+ _ifTag = 0;
+
+ if (!_pendingActionInfos.empty()) {
+ debug("Problem: Pending action infos from end block parser is not empty!");
+ }
+ _pendingActionInfos.clear();
+}
+
Command::ExecuteResult EndBlockCommand::execute(GameData &) {
return Finished;
}
diff --git a/engines/mutationofjb/commands/endblockcommand.h b/engines/mutationofjb/commands/endblockcommand.h
index 24c4e5c..3af86a3 100644
--- a/engines/mutationofjb/commands/endblockcommand.h
+++ b/engines/mutationofjb/commands/endblockcommand.h
@@ -35,9 +35,9 @@ class EndBlockCommandParser : public CommandParser {
public:
EndBlockCommandParser() : _elseFound(false), _ifTag(0) {}
- virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
- virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser);
-
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
+ virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser) override;
+ virtual void finish(ScriptParseContext &parseCtx) override;
private:
bool _elseFound;
char _ifTag;
diff --git a/engines/mutationofjb/commands/gotocommand.cpp b/engines/mutationofjb/commands/gotocommand.cpp
index 40560f3..a1d1a9d 100644
--- a/engines/mutationofjb/commands/gotocommand.cpp
+++ b/engines/mutationofjb/commands/gotocommand.cpp
@@ -26,7 +26,7 @@
#include "mutationofjb/script.h"
/*
- GOTO <label>
+ "GOTO " <label>
Jumps to a label.
*/
@@ -38,7 +38,7 @@ bool GotoCommandParser::parse(const Common::String &line, ScriptParseContext &pa
return false;
}
- Common::String label = line.c_str() + 6;
+ Common::String label = line.c_str() + 5;
GotoCommand *gotoCmd = new GotoCommand();
if (parseCtx._labels.contains(label)) {
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 6fe6b95..cc7dab7 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -79,6 +79,28 @@ bool Game::loadGameData(bool partB) {
void Game::changeScene(uint8 sceneId, bool partB) {
_gameData->_currentScene = sceneId;
_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;
+ }
+
+ // TODO Actually parse this.
+ Common::String dummy;
+ dummy = scriptFile.readLine(); // Skip first line.
+ scriptFile.seek(126, SEEK_CUR); // Skip 126 bytes.
+
+ _localScript = new Script;
+ _localScript->loadFromStream(scriptFile);
+ scriptFile.close();
}
}
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 95c2bdc..3c34660 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -130,6 +130,10 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) {
lastParser = currentParser;
}
+ for (CommandParser **parser = parsers; *parser; ++parser) {
+ (*parser)->finish(parseCtx);
+ }
+
for (ActionInfos::iterator it = parseCtx._actionInfos.begin(); it != parseCtx._actionInfos.end(); ++it) {
if (it->_action == ActionInfo::Look) {
_lookActionInfos.push_back(*it);
diff --git a/engines/mutationofjb/util.cpp b/engines/mutationofjb/util.cpp
index 0878748..1a56a62 100644
--- a/engines/mutationofjb/util.cpp
+++ b/engines/mutationofjb/util.cpp
@@ -28,7 +28,7 @@
namespace MutationOfJB {
void reportFileMissingError(const char *fileName) {
- Common::String errorMessage = Common::String::format(_("Unable to locate the '%s' engine data file."), fileName);
+ Common::String errorMessage = Common::String::format(_("Unable to locate the '%s' engine data file"), fileName);
GUIErrorMessage(errorMessage);
warning("%s", errorMessage.c_str());
}
Commit: 3928c52c0ee2a930431a807d0b4262440ab75725
https://github.com/scummvm/scummvm/commit/3928c52c0ee2a930431a807d0b4262440ab75725
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add support for CAMEFROM command.
Changed paths:
A engines/mutationofjb/commands/camefromcommand.cpp
A engines/mutationofjb/commands/camefromcommand.h
engines/mutationofjb/commands/command.cpp
engines/mutationofjb/commands/conditionalcommand.cpp
engines/mutationofjb/commands/conditionalcommand.h
engines/mutationofjb/commands/endblockcommand.cpp
engines/mutationofjb/commands/endblockcommand.h
engines/mutationofjb/commands/labelcommand.cpp
engines/mutationofjb/game.cpp
engines/mutationofjb/gamedata.cpp
engines/mutationofjb/gamedata.h
engines/mutationofjb/module.mk
engines/mutationofjb/script.cpp
engines/mutationofjb/script.h
diff --git a/engines/mutationofjb/commands/camefromcommand.cpp b/engines/mutationofjb/commands/camefromcommand.cpp
new file mode 100644
index 0000000..2c232c1
--- /dev/null
+++ b/engines/mutationofjb/commands/camefromcommand.cpp
@@ -0,0 +1,57 @@
+/* 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/camefromcommand.h"
+#include "mutationofjb/gamedata.h"
+#include "common/str.h"
+
+/*
+ "CAMEFROM" <sceneId>
+
+ This command tests whether last scene (the scene player came from) is sceneId.
+ If true, the execution continues after this command.
+ Otherwise the execution continues after first '#' found.
+*/
+
+namespace MutationOfJB {
+
+bool CameFromCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
+ if (line.size() < 10 || !line.hasPrefix("CAMEFROM")) {
+ return false;
+ }
+
+ const uint8 sceneId = atoi(line.c_str() + 9);
+ command = new CameFromCommand(sceneId);
+ return true;
+}
+
+Command::ExecuteResult CameFromCommand::execute(GameData &gameData) {
+ _cachedResult = (gameData._lastScene == _sceneId);
+
+ return Finished;
+}
+
+Common::String CameFromCommand::debugString() const {
+ return Common::String::format("CAMEFROM %d", _sceneId);
+}
+
+}
diff --git a/engines/mutationofjb/commands/camefromcommand.h b/engines/mutationofjb/commands/camefromcommand.h
new file mode 100644
index 0000000..c097ca1
--- /dev/null
+++ b/engines/mutationofjb/commands/camefromcommand.h
@@ -0,0 +1,49 @@
+/* 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_CAMEFROMCOMMAND_H
+#define MUTATIONOFJB_CAMEFROMCOMMAND_H
+
+#include "mutationofjb/commands/conditionalcommand.h"
+#include "common/scummsys.h"
+
+namespace MutationOfJB {
+
+class CameFromCommandParser : public ConditionalCommandParser {
+public:
+ CameFromCommandParser() : ConditionalCommandParser(true) {}
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+};
+
+class CameFromCommand : public ConditionalCommand {
+public:
+ CameFromCommand(uint8 sceneId) : _sceneId(sceneId) {}
+ virtual ExecuteResult execute(GameData &gameData) override;
+ virtual Common::String debugString() const;
+private:
+ uint8 _sceneId;
+};
+
+}
+
+#endif
+
diff --git a/engines/mutationofjb/commands/command.cpp b/engines/mutationofjb/commands/command.cpp
index 6c4dc47..d1e92f8 100644
--- a/engines/mutationofjb/commands/command.cpp
+++ b/engines/mutationofjb/commands/command.cpp
@@ -26,7 +26,7 @@
namespace MutationOfJB {
void CommandParser::transition(ScriptParseContext &, Command *, Command *, CommandParser *) {}
-void CommandParser::finish(ScriptParseContext &parseCtx) {}
+void CommandParser::finish(ScriptParseContext &) {}
CommandParser::~CommandParser() {}
Command::~Command() {}
diff --git a/engines/mutationofjb/commands/conditionalcommand.cpp b/engines/mutationofjb/commands/conditionalcommand.cpp
index aa42d1c..27b2714 100644
--- a/engines/mutationofjb/commands/conditionalcommand.cpp
+++ b/engines/mutationofjb/commands/conditionalcommand.cpp
@@ -34,7 +34,7 @@ void ConditionalCommandParser::transition(ScriptParseContext &parseContext, Comm
}
ConditionalCommand *const condCommand = static_cast<ConditionalCommand *>(oldCommand);
- parseContext.addConditionalCommand(condCommand, _lastTag);
+ parseContext.addConditionalCommand(condCommand, _lastTag, _firstHash);
condCommand->setTrueCommand(newCommand);
}
diff --git a/engines/mutationofjb/commands/conditionalcommand.h b/engines/mutationofjb/commands/conditionalcommand.h
index d64efbf..ea1a66a 100644
--- a/engines/mutationofjb/commands/conditionalcommand.h
+++ b/engines/mutationofjb/commands/conditionalcommand.h
@@ -30,11 +30,13 @@ namespace MutationOfJB {
class ConditionalCommandParser : public CommandParser {
public:
- ConditionalCommandParser() : _lastTag(0) {}
+ ConditionalCommandParser(bool firstHash = false) : _lastTag(0), _firstHash(firstHash) {}
virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser);
virtual void finish(ScriptParseContext &parseCtx) override;
protected:
char _lastTag;
+private:
+ bool _firstHash;
};
class ConditionalCommand : public Command {
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index 2d2ebe3..c8adaaa 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -87,18 +87,22 @@ bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext
}
}
+ if (firstChar == '#') {
+ _hashFound = true;
+ }
+
command = new EndBlockCommand();
return true;
}
void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *, Command *newCommand, CommandParser *newCommandParser) {
- if (_elseFound) {
+ if (_elseFound || _hashFound) {
if (newCommand) {
ScriptParseContext::ConditionalCommandInfos::iterator it = parseCtx._pendingCondCommands.begin();
while (it != parseCtx._pendingCondCommands.end()) {
- if (it->_tag == _ifTag) {
+ if ((it->_firstHash && _hashFound) || (!it->_firstHash && it->_tag == _ifTag)) {
it->_command->setFalseCommand(newCommand);
it = parseCtx._pendingCondCommands.erase(it);
} else {
@@ -108,6 +112,7 @@ void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *,
}
_elseFound = false;
+ _hashFound = false;
_ifTag = 0;
}
@@ -123,6 +128,7 @@ void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *,
void EndBlockCommandParser::finish(ScriptParseContext &) {
_elseFound = false;
+ _hashFound = false;
_ifTag = 0;
if (!_pendingActionInfos.empty()) {
diff --git a/engines/mutationofjb/commands/endblockcommand.h b/engines/mutationofjb/commands/endblockcommand.h
index 3af86a3..140fb21 100644
--- a/engines/mutationofjb/commands/endblockcommand.h
+++ b/engines/mutationofjb/commands/endblockcommand.h
@@ -33,13 +33,14 @@ class ActionInfo;
class EndBlockCommandParser : public CommandParser {
public:
- EndBlockCommandParser() : _elseFound(false), _ifTag(0) {}
+ EndBlockCommandParser() : _elseFound(false), _hashFound(false), _ifTag(0) {}
virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser) override;
virtual void finish(ScriptParseContext &parseCtx) override;
private:
bool _elseFound;
+ bool _hashFound;
char _ifTag;
Common::Array<uint> _pendingActionInfos;
diff --git a/engines/mutationofjb/commands/labelcommand.cpp b/engines/mutationofjb/commands/labelcommand.cpp
index 15a10ca..87c78f9 100644
--- a/engines/mutationofjb/commands/labelcommand.cpp
+++ b/engines/mutationofjb/commands/labelcommand.cpp
@@ -41,8 +41,8 @@ bool LabelCommandParser::parse(const Common::String &line, ScriptParseContext &p
label.deleteLastChar();
LabelCommand *labelCmd = new LabelCommand(label);
- if (!parseCtx._labels.contains(line)) {
- parseCtx._labels[line] = labelCmd;
+ if (!parseCtx._labels.contains(label)) {
+ parseCtx._labels[label] = labelCmd;
} else {
warning("Label '%s' already exists", label.c_str());
}
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index cc7dab7..397b86c 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -77,6 +77,7 @@ bool Game::loadGameData(bool partB) {
void Game::changeScene(uint8 sceneId, bool partB) {
+ _gameData->_lastScene = _gameData->_currentScene;
_gameData->_currentScene = sceneId;
_room->load(_gameData->_currentScene, partB);
diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp
index cc85da3..a181510 100644
--- a/engines/mutationofjb/gamedata.cpp
+++ b/engines/mutationofjb/gamedata.cpp
@@ -171,6 +171,7 @@ Static *Scene::getStatic(uint8 staticId) {
GameData::GameData()
: _currentScene(0),
+ _lastScene(0),
_partB(false) {}
Scene *GameData::getScene(uint8 sceneId) {
diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h
index 23e238a..ca70cd7 100644
--- a/engines/mutationofjb/gamedata.h
+++ b/engines/mutationofjb/gamedata.h
@@ -152,6 +152,7 @@ public:
bool loadFromStream(Common::ReadStream &stream);
uint8 _currentScene;
+ uint8 _lastScene;
bool _partB;
Inventory _inventory;
Common::String _currentAPK;
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 4137581..a81e2a3 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/mutationofjb
MODULE_OBJS := \
commands/additemcommand.o \
+ commands/camefromcommand.o \
commands/changecommand.o \
commands/command.o \
commands/conditionalcommand.o \
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 3c34660..dfb6886 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -38,6 +38,7 @@
#include "mutationofjb/commands/removeallitemscommand.h"
#include "mutationofjb/commands/labelcommand.h"
#include "mutationofjb/commands/gotocommand.h"
+#include "mutationofjb/commands/camefromcommand.h"
namespace MutationOfJB {
@@ -46,6 +47,7 @@ static CommandParser **getParsers() {
new IfPiggyCommandParser,
new IfItemCommandParser,
new IfCommandParser,
+ new CameFromCommandParser,
new EndBlockCommandParser,
new ChangeDoorCommandParser,
new ChangeObjectCommandParser,
@@ -88,8 +90,8 @@ bool ScriptParseContext::readLine(Common::String &line) {
return false;
}
-void ScriptParseContext::addConditionalCommand(ConditionalCommand *command, char tag) {
- ConditionalCommandInfo cmi = {command, tag};
+void ScriptParseContext::addConditionalCommand(ConditionalCommand *command, char tag, bool firstHash) {
+ ConditionalCommandInfo cmi = {command, tag, firstHash};
_pendingCondCommands.push_back(cmi);
}
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 66d137c..9589968 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -63,7 +63,7 @@ class ScriptParseContext {
public:
ScriptParseContext(Common::SeekableReadStream &stream);
bool readLine(Common::String &line);
- void addConditionalCommand(ConditionalCommand *command, char tag);
+ void addConditionalCommand(ConditionalCommand *command, char tag, bool firstHash);
void addLookSection(const Common::String &item, bool walkTo);
Common::SeekableReadStream &_stream;
@@ -73,6 +73,7 @@ public:
struct ConditionalCommandInfo {
ConditionalCommand *_command;
char _tag;
+ bool _firstHash;
};
typedef Common::Array<ConditionalCommandInfo> ConditionalCommandInfos;
ConditionalCommandInfos _pendingCondCommands;
Commit: 63c0dac9613caef3778a4cb9765bb8b628e5a1c2
https://github.com/scummvm/scummvm/commit/63c0dac9613caef3778a4cb9765bb8b628e5a1c2
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add support for macro definitions.
Changed paths:
engines/mutationofjb/commands/command.h
engines/mutationofjb/commands/endblockcommand.cpp
engines/mutationofjb/commands/endblockcommand.h
engines/mutationofjb/debug.cpp
engines/mutationofjb/debug.h
engines/mutationofjb/script.cpp
engines/mutationofjb/script.h
diff --git a/engines/mutationofjb/commands/command.h b/engines/mutationofjb/commands/command.h
index c6fce1e..1303242 100644
--- a/engines/mutationofjb/commands/command.h
+++ b/engines/mutationofjb/commands/command.h
@@ -24,7 +24,7 @@
#define MUTATIONOFJB_COMMAND_H
namespace Common {
- class String;
+class String;
}
namespace MutationOfJB {
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index c8adaaa..4a6e608 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -26,6 +26,26 @@
#include "common/str.h"
#include "common/debug.h"
+/*
+ ("#L " | "-L ") <object>
+ ("#W " | "-W ") <object>
+ ("#T " | "-T ") <object>
+ ("#U " | "-U ") <object1> [<object2>]
+ ("#ELSE" | "-ELSE") [<tag>]
+ "#MACRO " <name>
+
+ If a line starts with '#', '=', '-', it is treated as the end of a section.
+ However, at the same time it can also start a new section depending on what follows.
+
+ #L (look), #W (walk), #T (talk), #U (use) sections are executed
+ when the user starts corresponding action on the object or in case of "use" up to two objects.
+ The difference between '#' and '-' version is whether the player walks towards the object ('#') or not ('-').
+
+ #ELSE is used by conditional commands (see comments for IfCommand and others).
+
+ #MACRO starts a new macro. Global script can call macros from local script and vice versa.
+*/
+
namespace MutationOfJB {
bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) {
@@ -85,6 +105,8 @@ bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext
if (line.size() >= 6) {
_ifTag = line[5];
}
+ } else if (line.size() >= 8 && line.hasPrefix("#MACRO")) {
+ _foundMacro = line.c_str() + 7;
}
if (firstChar == '#') {
@@ -116,6 +138,13 @@ void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *,
_ifTag = 0;
}
+ if (!_foundMacro.empty() && newCommand) {
+ if (!parseCtx._macros.contains(_foundMacro)) {
+ parseCtx._macros[_foundMacro] = newCommand;
+ }
+ _foundMacro = "";
+ }
+
if (newCommandParser != this) {
if (!_pendingActionInfos.empty()) {
for (Common::Array<uint>::iterator it = _pendingActionInfos.begin(); it != _pendingActionInfos.end(); ++it) {
@@ -135,6 +164,7 @@ void EndBlockCommandParser::finish(ScriptParseContext &) {
debug("Problem: Pending action infos from end block parser is not empty!");
}
_pendingActionInfos.clear();
+ _foundMacro = "";
}
Command::ExecuteResult EndBlockCommand::execute(GameData &) {
diff --git a/engines/mutationofjb/commands/endblockcommand.h b/engines/mutationofjb/commands/endblockcommand.h
index 140fb21..1b22d75 100644
--- a/engines/mutationofjb/commands/endblockcommand.h
+++ b/engines/mutationofjb/commands/endblockcommand.h
@@ -44,6 +44,7 @@ private:
char _ifTag;
Common::Array<uint> _pendingActionInfos;
+ Common::String _foundMacro;
};
class EndBlockCommand : public Command {
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index e639324..99c4c7b 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -204,4 +204,55 @@ bool Console::cmd_showsection(int argc, const char **argv) {
return true;
}
+bool Console::cmd_listmacros(int argc, const char **argv) {
+ if (argc == 2) {
+ Script *script = nullptr;
+ if (strcmp(argv[1], "G") == 0) {
+ script = _vm->getGame().getGlobalScript();
+ } else if (strcmp(argv[1], "L") == 0) {
+ script = _vm->getGame().getLocalScript();
+ }
+ if (!script) {
+ debugPrintf(_("Choose 'G' (global) or 'L' (local) script.\n"));
+ } else {
+ const Macros ¯os = script->getMacros();
+ for (Macros::const_iterator it = macros.begin(); it != macros.end(); ++it) {
+ debugPrintf("%s\n", it->_key.c_str());
+ }
+ }
+ } else {
+ debugPrintf(_("listmacros <G|L>\n"));
+ }
+
+ return true;
+}
+
+bool Console::cmd_showmacro(int argc, const char **argv) {
+ if (argc == 3) {
+ Script *script = nullptr;
+ if (strcmp(argv[1], "G") == 0) {
+ script = _vm->getGame().getGlobalScript();
+ } else if (strcmp(argv[1], "L") == 0) {
+ script = _vm->getGame().getLocalScript();
+ }
+ if (!script) {
+ debugPrintf(_("Choose 'G' (global) or 'L' (local) script.\n"));
+ } else {
+ const Macros ¯os = script->getMacros();
+ Macros::const_iterator itMacro = macros.find(argv[2]);
+ if (itMacro != macros.end()) {
+ if (itMacro->_value) {
+ showCommands(itMacro->_value);
+ }
+ } else {
+ debugPrintf("Macro not found.\n");
+ }
+ }
+ } else {
+ debugPrintf(_("showmacro <G|L> <macroname>\n"));
+ }
+
+ return true;
+}
+
}
diff --git a/engines/mutationofjb/debug.h b/engines/mutationofjb/debug.h
index ee187cb..1dcc0fb 100644
--- a/engines/mutationofjb/debug.h
+++ b/engines/mutationofjb/debug.h
@@ -37,6 +37,8 @@ public:
private:
bool cmd_listsections(int argc, const char **argv);
bool cmd_showsection(int argc, const char **argv);
+ bool cmd_listmacros(int argc, const char **argv);
+ bool cmd_showmacro(int argc, const char **argv);
void showIndent(int indentLevel);
void showCommands(Command *command, int indentLevel = 0);
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index dfb6886..7a39127 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -151,8 +151,7 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) {
}
}
- Common::HashMap<Common::String, Command *> macros;
- Common::HashMap<Common::String, Command *> labels;
+ _macros = parseCtx._macros;
return true;
}
@@ -184,4 +183,8 @@ const ActionInfos &Script::getUseActionInfos() const {
return _useActionInfos;
}
+const Macros &Script::getMacros() const {
+ return _macros;
+}
+
}
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 9589968..64adda8 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -58,6 +58,7 @@ struct ActionInfo {
typedef Common::Array<ActionInfo> ActionInfos;
typedef Common::Array<GotoCommand *> GotoCommands;
+typedef Common::HashMap<Common::String, Command *> Macros;
class ScriptParseContext {
public:
@@ -85,6 +86,7 @@ public:
PendingGotoMap _pendingGotos;
ActionInfos _actionInfos;
+ Macros _macros;
private:
};
@@ -98,6 +100,7 @@ public:
const ActionInfos &getWalkActionInfos() const;
const ActionInfos &getTalkActionInfos() const;
const ActionInfos &getUseActionInfos() const;
+ const Macros &getMacros() const;
private:
void destroy();
@@ -106,6 +109,7 @@ private:
ActionInfos _walkActionInfos;
ActionInfos _talkActionInfos;
ActionInfos _useActionInfos;
+ Macros _macros;
};
}
Commit: e1d173ed7541f9da79f60a65d974da3ebbb29e7a
https://github.com/scummvm/scummvm/commit/e1d173ed7541f9da79f60a65d974da3ebbb29e7a
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add changescene debug command and fix macro debug commands.
Changed paths:
engines/mutationofjb/commands/additemcommand.cpp
engines/mutationofjb/commands/additemcommand.h
engines/mutationofjb/commands/camefromcommand.cpp
engines/mutationofjb/commands/camefromcommand.h
engines/mutationofjb/commands/changecommand.cpp
engines/mutationofjb/commands/changecommand.h
engines/mutationofjb/commands/command.cpp
engines/mutationofjb/commands/command.h
engines/mutationofjb/commands/endblockcommand.cpp
engines/mutationofjb/commands/endblockcommand.h
engines/mutationofjb/commands/gotocommand.cpp
engines/mutationofjb/commands/gotocommand.h
engines/mutationofjb/commands/ifcommand.cpp
engines/mutationofjb/commands/ifcommand.h
engines/mutationofjb/commands/ifitemcommand.cpp
engines/mutationofjb/commands/ifitemcommand.h
engines/mutationofjb/commands/ifpiggycommand.cpp
engines/mutationofjb/commands/ifpiggycommand.h
engines/mutationofjb/commands/labelcommand.cpp
engines/mutationofjb/commands/labelcommand.h
engines/mutationofjb/commands/removeallitemscommand.cpp
engines/mutationofjb/commands/removeallitemscommand.h
engines/mutationofjb/commands/removeitemcommand.cpp
engines/mutationofjb/commands/removeitemcommand.h
engines/mutationofjb/commands/saycommand.cpp
engines/mutationofjb/commands/saycommand.h
engines/mutationofjb/commands/seqcommand.cpp
engines/mutationofjb/commands/seqcommand.h
engines/mutationofjb/debug.cpp
engines/mutationofjb/debug.h
engines/mutationofjb/script.cpp
engines/mutationofjb/script.h
diff --git a/engines/mutationofjb/commands/additemcommand.cpp b/engines/mutationofjb/commands/additemcommand.cpp
index 58ec567..1a670f7 100644
--- a/engines/mutationofjb/commands/additemcommand.cpp
+++ b/engines/mutationofjb/commands/additemcommand.cpp
@@ -22,6 +22,7 @@
#include "mutationofjb/commands/additemcommand.h"
#include "mutationofjb/gamedata.h"
+#include "mutationofjb/script.h"
/*
"ADDITEM" " " <item>
@@ -40,8 +41,8 @@ bool AddItemCommandParser::parse(const Common::String &line, ScriptParseContext
return true;
}
-Command::ExecuteResult AddItemCommand::execute(GameData &gameData) {
- gameData._inventory.addItem(_item);
+Command::ExecuteResult AddItemCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ scriptExecCtx.getGameData()._inventory.addItem(_item);
return Finished;
}
diff --git a/engines/mutationofjb/commands/additemcommand.h b/engines/mutationofjb/commands/additemcommand.h
index cb4c131..4e2ea2b 100644
--- a/engines/mutationofjb/commands/additemcommand.h
+++ b/engines/mutationofjb/commands/additemcommand.h
@@ -39,7 +39,7 @@ class AddItemCommand : public SeqCommand {
public:
AddItemCommand(const Common::String &item) : _item(item) {}
- virtual ExecuteResult execute(GameData &gameData) override;
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const override;
private:
Common::String _item;
diff --git a/engines/mutationofjb/commands/camefromcommand.cpp b/engines/mutationofjb/commands/camefromcommand.cpp
index 2c232c1..0583187 100644
--- a/engines/mutationofjb/commands/camefromcommand.cpp
+++ b/engines/mutationofjb/commands/camefromcommand.cpp
@@ -22,6 +22,7 @@
#include "mutationofjb/commands/camefromcommand.h"
#include "mutationofjb/gamedata.h"
+#include "mutationofjb/script.h"
#include "common/str.h"
/*
@@ -44,8 +45,8 @@ bool CameFromCommandParser::parse(const Common::String &line, ScriptParseContext
return true;
}
-Command::ExecuteResult CameFromCommand::execute(GameData &gameData) {
- _cachedResult = (gameData._lastScene == _sceneId);
+Command::ExecuteResult CameFromCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ _cachedResult = (scriptExecCtx.getGameData()._lastScene == _sceneId);
return Finished;
}
diff --git a/engines/mutationofjb/commands/camefromcommand.h b/engines/mutationofjb/commands/camefromcommand.h
index c097ca1..c4048cb 100644
--- a/engines/mutationofjb/commands/camefromcommand.h
+++ b/engines/mutationofjb/commands/camefromcommand.h
@@ -37,7 +37,7 @@ public:
class CameFromCommand : public ConditionalCommand {
public:
CameFromCommand(uint8 sceneId) : _sceneId(sceneId) {}
- virtual ExecuteResult execute(GameData &gameData) override;
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const;
private:
uint8 _sceneId;
diff --git a/engines/mutationofjb/commands/changecommand.cpp b/engines/mutationofjb/commands/changecommand.cpp
index e4699eb..a4316bd 100644
--- a/engines/mutationofjb/commands/changecommand.cpp
+++ b/engines/mutationofjb/commands/changecommand.cpp
@@ -21,6 +21,8 @@
*/
#include "mutationofjb/commands/changecommand.h"
+#include "mutationofjb/script.h"
+#include "mutationofjb/gamedata.h"
#include "common/translation.h"
namespace MutationOfJB {
@@ -295,8 +297,8 @@ const char *ChangeCommand::getOperationAsString() const {
}
}
-Command::ExecuteResult ChangeDoorCommand::execute(GameData &gameData) {
- Scene *const scene = gameData.getScene(_sceneId);
+Command::ExecuteResult ChangeDoorCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ Scene *const scene = scriptExecCtx.getGameData().getScene(_sceneId);
if (!scene) {
return Finished;
}
@@ -352,8 +354,8 @@ Common::String ChangeDoorCommand::debugString() const {
return Common::String::format("scene%d.door%d.%s %s %s", _sceneId, _entityId, getRegisterAsString(), getOperationAsString(), getValueAsString().c_str());
}
-Command::ExecuteResult ChangeObjectCommand::execute(GameData &gameData) {
- Scene *const scene = gameData.getScene(_sceneId);
+Command::ExecuteResult ChangeObjectCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ Scene *const scene = scriptExecCtx.getGameData().getScene(_sceneId);
if (!scene) {
return Finished;
}
@@ -415,8 +417,8 @@ Common::String ChangeObjectCommand::debugString() const {
return Common::String::format("scene%d.object%d.%s %s %s", _sceneId, _entityId, getRegisterAsString(), getOperationAsString(), getValueAsString().c_str());
}
-Command::ExecuteResult ChangeStaticCommand::execute(GameData &gameData) {
- Scene *const scene = gameData.getScene(_sceneId);
+Command::ExecuteResult ChangeStaticCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ Scene *const scene = scriptExecCtx.getGameData().getScene(_sceneId);
if (!scene) {
return Finished;
}
@@ -466,8 +468,8 @@ Common::String ChangeStaticCommand::debugString() const {
return Common::String::format("scene%d.static%d.%s %s %s", _sceneId, _entityId, getRegisterAsString(), getOperationAsString(), getValueAsString().c_str());
}
-Command::ExecuteResult ChangeSceneCommand::execute(GameData &gameData) {
- Scene *const scene = gameData.getScene(_sceneId);
+Command::ExecuteResult ChangeSceneCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ Scene *const scene = scriptExecCtx.getGameData().getScene(_sceneId);
if (!scene) {
return Finished;
}
diff --git a/engines/mutationofjb/commands/changecommand.h b/engines/mutationofjb/commands/changecommand.h
index 5ba386b..dde5cd1 100644
--- a/engines/mutationofjb/commands/changecommand.h
+++ b/engines/mutationofjb/commands/changecommand.h
@@ -113,7 +113,7 @@ public:
ChangeDoorCommand(uint8 sceneId, uint8 doorId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue &val)
: ChangeCommand(sceneId, doorId, reg, op, val)
{}
- virtual ExecuteResult execute(GameData &gameData) override;
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const;
};
@@ -122,7 +122,7 @@ public:
ChangeObjectCommand(uint8 sceneId, uint8 objectId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue &val)
: ChangeCommand(sceneId, objectId, reg, op, val)
{}
- virtual ExecuteResult execute(GameData &gameData) override;
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const;
};
@@ -131,7 +131,7 @@ public:
ChangeStaticCommand(uint8 sceneId, uint8 staticId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue &val)
: ChangeCommand(sceneId, staticId, reg, op, val)
{}
- virtual ExecuteResult execute(GameData &gameData) override;
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const;
};
@@ -140,7 +140,7 @@ public:
ChangeSceneCommand(uint8 sceneId, uint8 staticId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue &val)
: ChangeCommand(sceneId, staticId, reg, op, val)
{}
- virtual ExecuteResult execute(GameData &gameData) override;
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const;
};
diff --git a/engines/mutationofjb/commands/command.cpp b/engines/mutationofjb/commands/command.cpp
index d1e92f8..1e546ff 100644
--- a/engines/mutationofjb/commands/command.cpp
+++ b/engines/mutationofjb/commands/command.cpp
@@ -31,8 +31,4 @@ CommandParser::~CommandParser() {}
Command::~Command() {}
-SeqCommand *Command::asSeqCommand() {
- return nullptr;
-}
-
}
diff --git a/engines/mutationofjb/commands/command.h b/engines/mutationofjb/commands/command.h
index 1303242..0133d52 100644
--- a/engines/mutationofjb/commands/command.h
+++ b/engines/mutationofjb/commands/command.h
@@ -29,12 +29,9 @@ class String;
namespace MutationOfJB {
-class GameData;
-class SeqCommand;
-class IfCommand;
-class CallMacroCommand;
-class ScriptParseContext;
class Command;
+class ScriptExecutionContext;
+class ScriptParseContext;
class CommandParser {
public:
@@ -58,10 +55,9 @@ public:
virtual ~Command();
- virtual ExecuteResult execute(GameData &gameData) = 0;
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) = 0;
virtual Command *next() const = 0;
- virtual SeqCommand *asSeqCommand();
virtual Common::String debugString() const = 0;
};
}
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index 4a6e608..53ea74a 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -167,12 +167,13 @@ void EndBlockCommandParser::finish(ScriptParseContext &) {
_foundMacro = "";
}
-Command::ExecuteResult EndBlockCommand::execute(GameData &) {
+Command::ExecuteResult EndBlockCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ _nextCmd = scriptExecCtx.popReturnCommand();
return Finished;
}
Command *EndBlockCommand::next() const {
- return nullptr;
+ return _nextCmd;
}
Common::String EndBlockCommand::debugString() const {
diff --git a/engines/mutationofjb/commands/endblockcommand.h b/engines/mutationofjb/commands/endblockcommand.h
index 1b22d75..4c0d23b 100644
--- a/engines/mutationofjb/commands/endblockcommand.h
+++ b/engines/mutationofjb/commands/endblockcommand.h
@@ -49,11 +49,14 @@ private:
class EndBlockCommand : public Command {
public:
+ EndBlockCommand() : _nextCmd(nullptr) {}
static bool ParseFunc(const Common::String &line, ScriptParseContext &parseContext, Command *&command);
- virtual ExecuteResult execute(GameData &gameData) override;
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Command *next() const override;
virtual Common::String debugString() const;
+private:
+ Command *_nextCmd;
};
}
diff --git a/engines/mutationofjb/commands/gotocommand.cpp b/engines/mutationofjb/commands/gotocommand.cpp
index a1d1a9d..bc24e2c 100644
--- a/engines/mutationofjb/commands/gotocommand.cpp
+++ b/engines/mutationofjb/commands/gotocommand.cpp
@@ -59,7 +59,7 @@ void GotoCommand::setLabelCommand(LabelCommand *labelCmd) {
_labelCommand = labelCmd;
}
-Command::ExecuteResult GotoCommand::execute(GameData &) {
+Command::ExecuteResult GotoCommand::execute(ScriptExecutionContext &) {
// Intentionally empty.
return Finished;
diff --git a/engines/mutationofjb/commands/gotocommand.h b/engines/mutationofjb/commands/gotocommand.h
index 436dd44..09d426f 100644
--- a/engines/mutationofjb/commands/gotocommand.h
+++ b/engines/mutationofjb/commands/gotocommand.h
@@ -43,7 +43,7 @@ public:
void setLabelCommand(LabelCommand *labelCmd);
- virtual ExecuteResult execute(GameData &gameData) override;
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Command *next() const override;
virtual Common::String debugString() const override;
private:
diff --git a/engines/mutationofjb/commands/ifcommand.cpp b/engines/mutationofjb/commands/ifcommand.cpp
index f78335a..b5f03fc 100644
--- a/engines/mutationofjb/commands/ifcommand.cpp
+++ b/engines/mutationofjb/commands/ifcommand.cpp
@@ -47,7 +47,7 @@
namespace MutationOfJB {
-bool IfCommandParser::parse(const Common::String &line, ScriptParseContext &parseContext, Command *&command) {
+bool IfCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
// IFtss oo val!
// <t> 1B Tag.
// <ss> 2B Scene.
@@ -84,8 +84,8 @@ IfCommand::IfCommand(uint8 sceneId, uint8 objectId, uint16 value, bool negative)
_negative(negative)
{}
-Command::ExecuteResult IfCommand::execute(GameData &gameData) {
- Scene *const scene = gameData.getScene(_sceneId);
+Command::ExecuteResult IfCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ Scene *const scene = scriptExecCtx.getGameData().getScene(_sceneId);
if (!scene) {
return Finished;
}
diff --git a/engines/mutationofjb/commands/ifcommand.h b/engines/mutationofjb/commands/ifcommand.h
index 51350ce..b04d8a3 100644
--- a/engines/mutationofjb/commands/ifcommand.h
+++ b/engines/mutationofjb/commands/ifcommand.h
@@ -40,7 +40,7 @@ class IfCommand : public ConditionalCommand {
public:
IfCommand(uint8 sceneId, uint8 objectId, uint16 value, bool negative);
- virtual ExecuteResult execute(GameData &gameData) override;
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const;
private:
diff --git a/engines/mutationofjb/commands/ifitemcommand.cpp b/engines/mutationofjb/commands/ifitemcommand.cpp
index 7512ba5..7a58cee 100644
--- a/engines/mutationofjb/commands/ifitemcommand.cpp
+++ b/engines/mutationofjb/commands/ifitemcommand.cpp
@@ -73,8 +73,8 @@ IfItemCommand::IfItemCommand(const Common::String &item, bool negative) :
_negative(negative)
{}
-Command::ExecuteResult IfItemCommand::execute(GameData &gameData) {
- _cachedResult = gameData._inventory.hasItem(_item);
+Command::ExecuteResult IfItemCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ _cachedResult = scriptExecCtx.getGameData()._inventory.hasItem(_item);
if (_negative) {
_cachedResult = !_cachedResult;
}
diff --git a/engines/mutationofjb/commands/ifitemcommand.h b/engines/mutationofjb/commands/ifitemcommand.h
index 0451786..f11ba7c 100644
--- a/engines/mutationofjb/commands/ifitemcommand.h
+++ b/engines/mutationofjb/commands/ifitemcommand.h
@@ -40,7 +40,7 @@ class IfItemCommand : public ConditionalCommand {
public:
IfItemCommand(const Common::String &item, bool negative);
- virtual ExecuteResult execute(GameData &gameData) override;
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const;
private:
diff --git a/engines/mutationofjb/commands/ifpiggycommand.cpp b/engines/mutationofjb/commands/ifpiggycommand.cpp
index cad0a14..e30213a 100644
--- a/engines/mutationofjb/commands/ifpiggycommand.cpp
+++ b/engines/mutationofjb/commands/ifpiggycommand.cpp
@@ -57,8 +57,8 @@ bool IfPiggyCommandParser::parse(const Common::String &line, ScriptParseContext
}
-Command::ExecuteResult IfPiggyCommand::execute(GameData &gameData) {
- _cachedResult = gameData._currentAPK == "piggy.apk";
+Command::ExecuteResult IfPiggyCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ _cachedResult = scriptExecCtx.getGameData()._currentAPK == "piggy.apk";
return Finished;
}
diff --git a/engines/mutationofjb/commands/ifpiggycommand.h b/engines/mutationofjb/commands/ifpiggycommand.h
index 3fb6826..d10788c 100644
--- a/engines/mutationofjb/commands/ifpiggycommand.h
+++ b/engines/mutationofjb/commands/ifpiggycommand.h
@@ -38,7 +38,7 @@ public:
class IfPiggyCommand : public ConditionalCommand {
public:
- virtual ExecuteResult execute(GameData &gameData) override;
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const;
private:
diff --git a/engines/mutationofjb/commands/labelcommand.cpp b/engines/mutationofjb/commands/labelcommand.cpp
index 87c78f9..de6de02 100644
--- a/engines/mutationofjb/commands/labelcommand.cpp
+++ b/engines/mutationofjb/commands/labelcommand.cpp
@@ -64,7 +64,7 @@ const Common::String &LabelCommand::getName() const
return _name;
}
-Command::ExecuteResult LabelCommand::execute(GameData &) {
+Command::ExecuteResult LabelCommand::execute(ScriptExecutionContext &) {
// Intentionally empty.
return Finished;
diff --git a/engines/mutationofjb/commands/labelcommand.h b/engines/mutationofjb/commands/labelcommand.h
index 389c759..f4acad6 100644
--- a/engines/mutationofjb/commands/labelcommand.h
+++ b/engines/mutationofjb/commands/labelcommand.h
@@ -40,7 +40,7 @@ public:
LabelCommand(const Common::String &name) : _name(name) {}
const Common::String &getName() const;
- virtual ExecuteResult execute(GameData &gameData) override;
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const override;
private:
Common::String _name;
diff --git a/engines/mutationofjb/commands/removeallitemscommand.cpp b/engines/mutationofjb/commands/removeallitemscommand.cpp
index 8043864..d9ebe45 100644
--- a/engines/mutationofjb/commands/removeallitemscommand.cpp
+++ b/engines/mutationofjb/commands/removeallitemscommand.cpp
@@ -21,6 +21,7 @@
*/
#include "mutationofjb/commands/removeallitemscommand.h"
+#include "mutationofjb/script.h"
#include "mutationofjb/gamedata.h"
/*
@@ -40,8 +41,8 @@ bool RemoveAllItemsCommandParser::parse(const Common::String &line, ScriptParseC
return true;
}
-Command::ExecuteResult RemoveAllItemsCommand::execute(GameData &gameData) {
- gameData._inventory.removeAllItems();
+Command::ExecuteResult RemoveAllItemsCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ scriptExecCtx.getGameData()._inventory.removeAllItems();
return Finished;
}
diff --git a/engines/mutationofjb/commands/removeallitemscommand.h b/engines/mutationofjb/commands/removeallitemscommand.h
index 166aed8..92fe93f 100644
--- a/engines/mutationofjb/commands/removeallitemscommand.h
+++ b/engines/mutationofjb/commands/removeallitemscommand.h
@@ -38,7 +38,7 @@ class RemoveAllItemsCommand : public SeqCommand {
public:
RemoveAllItemsCommand() {}
- virtual ExecuteResult execute(GameData &gameData) override;
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const override;
private:
};
diff --git a/engines/mutationofjb/commands/removeitemcommand.cpp b/engines/mutationofjb/commands/removeitemcommand.cpp
index e4d9601..48dbda9 100644
--- a/engines/mutationofjb/commands/removeitemcommand.cpp
+++ b/engines/mutationofjb/commands/removeitemcommand.cpp
@@ -21,6 +21,7 @@
*/
#include "mutationofjb/commands/removeitemcommand.h"
+#include "mutationofjb/script.h"
#include "mutationofjb/gamedata.h"
/*
@@ -40,8 +41,8 @@ bool RemoveItemCommandParser::parse(const Common::String &line, ScriptParseConte
return true;
}
-Command::ExecuteResult RemoveItemCommand::execute(GameData &gameData) {
- gameData._inventory.removeItem(_item);
+Command::ExecuteResult RemoveItemCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ scriptExecCtx.getGameData()._inventory.removeItem(_item);
return Finished;
}
diff --git a/engines/mutationofjb/commands/removeitemcommand.h b/engines/mutationofjb/commands/removeitemcommand.h
index 452a3b2..0aa13f5 100644
--- a/engines/mutationofjb/commands/removeitemcommand.h
+++ b/engines/mutationofjb/commands/removeitemcommand.h
@@ -39,7 +39,7 @@ class RemoveItemCommand : public SeqCommand {
public:
RemoveItemCommand(const Common::String &item) : _item(item) {}
- virtual ExecuteResult execute(GameData &gameData) override;
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const override;
private:
Common::String _item;
diff --git a/engines/mutationofjb/commands/saycommand.cpp b/engines/mutationofjb/commands/saycommand.cpp
index a0c9c79..854c957 100644
--- a/engines/mutationofjb/commands/saycommand.cpp
+++ b/engines/mutationofjb/commands/saycommand.cpp
@@ -140,7 +140,7 @@ bool SayCommandParser::parse(const Common::String &line, ScriptParseContext &par
}
-Command::ExecuteResult SayCommand::execute(GameData &) {
+Command::ExecuteResult SayCommand::execute(ScriptExecutionContext &) {
// TODO: Actual implementation.
debug("%s [%s]", _lineToSay.c_str(), _voiceFile.c_str());
return Finished;
diff --git a/engines/mutationofjb/commands/saycommand.h b/engines/mutationofjb/commands/saycommand.h
index e2a1207..e41d10f 100644
--- a/engines/mutationofjb/commands/saycommand.h
+++ b/engines/mutationofjb/commands/saycommand.h
@@ -42,7 +42,7 @@ public:
_voiceFile(voiceFile),
_waitForPrevious(waitForPrevious),
_talkingAnimation(talkingAnimation) {}
- virtual ExecuteResult execute(GameData &gameData) override;
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const override;
private:
Common::String _lineToSay;
diff --git a/engines/mutationofjb/commands/seqcommand.cpp b/engines/mutationofjb/commands/seqcommand.cpp
index 03d9538..02164dc 100644
--- a/engines/mutationofjb/commands/seqcommand.cpp
+++ b/engines/mutationofjb/commands/seqcommand.cpp
@@ -43,8 +43,4 @@ Command *SeqCommand::next() const {
return _nextCommand;
}
-SeqCommand *SeqCommand::asSeqCommand() {
- return this;
-}
-
}
diff --git a/engines/mutationofjb/commands/seqcommand.h b/engines/mutationofjb/commands/seqcommand.h
index c3455ce..241932a 100644
--- a/engines/mutationofjb/commands/seqcommand.h
+++ b/engines/mutationofjb/commands/seqcommand.h
@@ -37,7 +37,6 @@ class SeqCommand : public Command {
public:
void setNextCommand(Command *nextCommand);
virtual Command *next() const override;
- virtual SeqCommand *asSeqCommand();
private:
Command *_nextCommand;
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index 99c4c7b..867a021 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -56,6 +56,9 @@ static Common::String convertToASCII(const Common::String &str) {
Console::Console(MutationOfJBEngine *vm) : _vm(vm) {
registerCmd("listsections", WRAP_METHOD(Console, cmd_listsections));
registerCmd("showsection", WRAP_METHOD(Console, cmd_showsection));
+ registerCmd("listmacros", WRAP_METHOD(Console, cmd_listmacros));
+ registerCmd("showmacro", WRAP_METHOD(Console, cmd_showmacro));
+ registerCmd("changescene", WRAP_METHOD(Console, cmd_changescene));
}
bool Console::cmd_listsections(int argc, const char **argv) {
@@ -255,4 +258,17 @@ bool Console::cmd_showmacro(int argc, const char **argv) {
return true;
}
+bool Console::cmd_changescene(int argc, const char **argv) {
+ if (argc == 2) {
+ const uint8 sceneId = atoi(argv[1]);
+ const bool partB = argv[1][strlen(argv[1]) - 1] == 'B';
+
+ _vm->getGame().changeScene(sceneId, partB);
+ } else {
+ debugPrintf(_("changescene <scenename>\n"));
+ }
+
+ return true;
+}
+
}
diff --git a/engines/mutationofjb/debug.h b/engines/mutationofjb/debug.h
index 1dcc0fb..2f35a9c 100644
--- a/engines/mutationofjb/debug.h
+++ b/engines/mutationofjb/debug.h
@@ -39,6 +39,7 @@ private:
bool cmd_showsection(int argc, const char **argv);
bool cmd_listmacros(int argc, const char **argv);
bool cmd_showmacro(int argc, const char **argv);
+ bool cmd_changescene(int argc, const char **argv);
void showIndent(int indentLevel);
void showCommands(Command *command, int indentLevel = 0);
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 7a39127..699daeb 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -20,7 +20,7 @@
*
*/
-#include "script.h"
+#include "mutationofjb/script.h"
#include "common/hashmap.h"
#include "common/hash-str.h"
@@ -39,6 +39,7 @@
#include "mutationofjb/commands/labelcommand.h"
#include "mutationofjb/commands/gotocommand.h"
#include "mutationofjb/commands/camefromcommand.h"
+#include "mutationofjb/game.h"
namespace MutationOfJB {
@@ -95,6 +96,24 @@ void ScriptParseContext::addConditionalCommand(ConditionalCommand *command, char
_pendingCondCommands.push_back(cmi);
}
+
+void ScriptExecutionContext::pushReturnCommand(Command *cmd) {
+ _stack.push(cmd);
+}
+
+Command *ScriptExecutionContext::popReturnCommand() {
+ if (_stack.empty()) {
+ return nullptr;
+ }
+
+ return _stack.pop();
+}
+
+GameData &ScriptExecutionContext::getGameData() {
+ return _game.getGameData();
+}
+
+
bool Script::loadFromStream(Common::SeekableReadStream &stream) {
destroy();
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 64adda8..477181b 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -26,6 +26,7 @@
#include "common/array.h"
#include "common/hashmap.h"
#include "common/hash-str.h"
+#include "common/stack.h"
namespace Common {
class SeekableReadStream;
@@ -36,6 +37,8 @@ namespace MutationOfJB {
class Command;
class LabelCommand;
+class Game;
+class GameData;
class GotoCommand;
class ConditionalCommand;
typedef Common::Array<Command *> Commands;
@@ -91,6 +94,18 @@ public:
private:
};
+class ScriptExecutionContext {
+public:
+ ScriptExecutionContext(Game &game) : _game(game) {}
+ void pushReturnCommand(Command *);
+ Command *popReturnCommand();
+ GameData &getGameData();
+
+private:
+ Game &_game;
+ Common::Stack<Command *> _stack;
+};
+
class Script {
public:
bool loadFromStream(Common::SeekableReadStream &stream);
Commit: 938f222d4857b45e0f1f7e4726040ab0bf1d9b67
https://github.com/scummvm/scummvm/commit/938f222d4857b45e0f1f7e4726040ab0bf1d9b67
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add support for calling macros.
Changed paths:
A engines/mutationofjb/commands/callmacrocommand.cpp
A engines/mutationofjb/commands/callmacrocommand.h
engines/mutationofjb/commands/additemcommand.h
engines/mutationofjb/debug.cpp
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/module.mk
engines/mutationofjb/script.cpp
engines/mutationofjb/script.h
diff --git a/engines/mutationofjb/commands/additemcommand.h b/engines/mutationofjb/commands/additemcommand.h
index 4e2ea2b..d740d35 100644
--- a/engines/mutationofjb/commands/additemcommand.h
+++ b/engines/mutationofjb/commands/additemcommand.h
@@ -32,7 +32,7 @@ class AddItemCommandParser : public SeqCommandParser {
public:
AddItemCommandParser() {}
- virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
};
class AddItemCommand : public SeqCommand {
diff --git a/engines/mutationofjb/commands/callmacrocommand.cpp b/engines/mutationofjb/commands/callmacrocommand.cpp
new file mode 100644
index 0000000..b1c59eb
--- /dev/null
+++ b/engines/mutationofjb/commands/callmacrocommand.cpp
@@ -0,0 +1,85 @@
+/* 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/callmacrocommand.h"
+#include "mutationofjb/script.h"
+#include "mutationofjb/game.h"
+#include "common/translation.h"
+
+/*
+ "_" <name>
+
+ Calls macro with the specified name.
+*/
+
+namespace MutationOfJB {
+
+bool CallMacroCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
+ if (line.size() < 2 || line.firstChar() != '_') {
+ return false;
+ }
+
+ const Common::String macroName = line.c_str() + 1;
+ command = new CallMacroCommand(macroName);
+ return true;
+}
+
+void CallMacroCommandParser::transition(ScriptParseContext &, Command *oldCommand, Command *newCommand, CommandParser *) {
+ if (!oldCommand || !newCommand) {
+ warning(_("Unexpected empty command in transition"));
+ return;
+ }
+
+ static_cast<CallMacroCommand *>(oldCommand)->setReturnCommand(newCommand);
+}
+
+
+void CallMacroCommand::setReturnCommand(Command *cmd) {
+ _returnCommand = cmd;
+}
+
+Command *CallMacroCommand::getReturnCommand() const {
+ return _returnCommand;
+}
+
+Command::ExecuteResult CallMacroCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ Game &game = scriptExecCtx.getGame();
+ _callCommand = game.getMacro(_macroName);
+ if (_callCommand) {
+ scriptExecCtx.pushReturnCommand(_returnCommand);
+ } else {
+ warning("Macro '%s' not found.", _macroName.c_str());
+ }
+
+ return Finished;
+}
+
+Command *CallMacroCommand::next() const {
+ return _callCommand;
+}
+
+Common::String CallMacroCommand::debugString() const {
+ return Common::String::format("CALL '%s'", _macroName.c_str());
+}
+
+}
+
diff --git a/engines/mutationofjb/commands/callmacrocommand.h b/engines/mutationofjb/commands/callmacrocommand.h
new file mode 100644
index 0000000..0486bcd
--- /dev/null
+++ b/engines/mutationofjb/commands/callmacrocommand.h
@@ -0,0 +1,58 @@
+/* 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_CALLMACROCOMMAND_H
+#define MUTATIONOFJB_CALLMACROCOMMAND_H
+
+#include "mutationofjb/commands/command.h"
+#include "common/scummsys.h"
+#include "common/str.h"
+
+namespace MutationOfJB {
+
+class CallMacroCommandParser : public CommandParser {
+public:
+ CallMacroCommandParser() {}
+
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
+ virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser) override;
+};
+
+class CallMacroCommand : public Command {
+public:
+ CallMacroCommand(const Common::String ¯oName) : _macroName(macroName), _returnCommand(nullptr), _callCommand(nullptr) {}
+ void setReturnCommand(Command *);
+
+ Command *getReturnCommand() const;
+
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
+ Command *next() const override;
+ virtual Common::String debugString() const override;
+private:
+ Common::String _macroName;
+ Command *_returnCommand;
+ Command *_callCommand;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index 867a021..b4c2e77 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -27,6 +27,7 @@
#include "mutationofjb/commands/command.h"
#include "mutationofjb/commands/seqcommand.h"
#include "mutationofjb/commands/conditionalcommand.h"
+#include "mutationofjb/commands/callmacrocommand.h"
#include "common/debug-channels.h"
#include "common/translation.h"
#include "common/scummsys.h"
@@ -129,6 +130,8 @@ void Console::showCommands(Command *command, int indentLevel) {
debugPrintf("ELSE\n");
showCommands(condCmd->getFalseCommand(), indentLevel + 1);
command = nullptr;
+ } else if (CallMacroCommand* const callMacroCmd = dynamic_cast<CallMacroCommand *>(command)) {
+ command = callMacroCmd->getReturnCommand();
} else {
command = nullptr;
}
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 397b86c..047971b 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -28,10 +28,11 @@
#include "mutationofjb/script.h"
#include "mutationofjb/util.h"
#include "common/util.h"
+#include "common/str.h"
namespace MutationOfJB {
-Game::Game(MutationOfJBEngine* vm) : _vm(vm) {
+Game::Game(MutationOfJBEngine *vm) : _vm(vm) {
_gameData = new GameData;
loadGameData(false);
@@ -104,4 +105,18 @@ void Game::changeScene(uint8 sceneId, bool partB) {
scriptFile.close();
}
+Command *Game::getMacro(const Common::String &name) const {
+ Command *cmd = nullptr;
+
+ if (_localScript) {
+ cmd = _localScript->getMacro(name);
+ }
+
+ if (!cmd && _globalScript) {
+ cmd = _globalScript->getMacro(name);
+ }
+
+ return cmd;
+}
+
}
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index 4b4ab43..5ed65f1 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -25,8 +25,13 @@
#include "common/scummsys.h"
+namespace Common {
+class String;
+}
+
namespace MutationOfJB {
+class Command;
class MutationOfJBEngine;
class GameData;
class Script;
@@ -34,7 +39,7 @@ class Room;
class Game {
public:
- Game(MutationOfJBEngine* vm);
+ Game(MutationOfJBEngine *vm);
GameData &getGameData();
Script *getGlobalScript() const;
@@ -42,6 +47,8 @@ public:
void changeScene(uint8 sceneId, bool partB);
+ Command *getMacro(const Common::String &name) const;
+
private:
bool loadGameData(bool partB);
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index a81e2a3..447f9a9 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/mutationofjb
MODULE_OBJS := \
commands/additemcommand.o \
+ commands/callmacrocommand.o \
commands/camefromcommand.o \
commands/changecommand.o \
commands/command.o \
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 699daeb..1291bd8 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -39,6 +39,7 @@
#include "mutationofjb/commands/labelcommand.h"
#include "mutationofjb/commands/gotocommand.h"
#include "mutationofjb/commands/camefromcommand.h"
+#include "mutationofjb/commands/callmacrocommand.h"
#include "mutationofjb/game.h"
namespace MutationOfJB {
@@ -49,6 +50,7 @@ static CommandParser **getParsers() {
new IfItemCommandParser,
new IfCommandParser,
new CameFromCommandParser,
+ new CallMacroCommandParser,
new EndBlockCommandParser,
new ChangeDoorCommandParser,
new ChangeObjectCommandParser,
@@ -109,6 +111,10 @@ Command *ScriptExecutionContext::popReturnCommand() {
return _stack.pop();
}
+Game &ScriptExecutionContext::getGame() {
+ return _game;
+}
+
GameData &ScriptExecutionContext::getGameData() {
return _game.getGameData();
}
@@ -206,4 +212,13 @@ const Macros &Script::getMacros() const {
return _macros;
}
+Command *Script::getMacro(const Common::String &name) const {
+ Macros::const_iterator it = _macros.find(name);
+ if (it == _macros.end()) {
+ return nullptr;
+ }
+
+ return it->_value;
+}
+
}
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 477181b..940a274 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -99,6 +99,7 @@ public:
ScriptExecutionContext(Game &game) : _game(game) {}
void pushReturnCommand(Command *);
Command *popReturnCommand();
+ Game &getGame();
GameData &getGameData();
private:
@@ -116,6 +117,7 @@ public:
const ActionInfos &getTalkActionInfos() const;
const ActionInfos &getUseActionInfos() const;
const Macros &getMacros() const;
+ Command *getMacro(const Common::String &name) const;
private:
void destroy();
Commit: 7a1898730155dce824451d98bbe65b430832d575
https://github.com/scummvm/scummvm/commit/7a1898730155dce824451d98bbe65b430832d575
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Support for running commands.
Changed paths:
engines/mutationofjb/commands/callmacrocommand.cpp
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/mutationofjb.cpp
engines/mutationofjb/script.cpp
engines/mutationofjb/script.h
diff --git a/engines/mutationofjb/commands/callmacrocommand.cpp b/engines/mutationofjb/commands/callmacrocommand.cpp
index b1c59eb..49b948c 100644
--- a/engines/mutationofjb/commands/callmacrocommand.cpp
+++ b/engines/mutationofjb/commands/callmacrocommand.cpp
@@ -62,8 +62,7 @@ Command *CallMacroCommand::getReturnCommand() const {
}
Command::ExecuteResult CallMacroCommand::execute(ScriptExecutionContext &scriptExecCtx) {
- Game &game = scriptExecCtx.getGame();
- _callCommand = game.getMacro(_macroName);
+ _callCommand = scriptExecCtx.getMacro(_macroName);
if (_callCommand) {
scriptExecCtx.pushReturnCommand(_returnCommand);
} else {
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 047971b..6436c7a 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -27,12 +27,15 @@
#include "mutationofjb/room.h"
#include "mutationofjb/script.h"
#include "mutationofjb/util.h"
+#include "mutationofjb/commands/command.h"
#include "common/util.h"
#include "common/str.h"
+#include "common/translation.h"
namespace MutationOfJB {
-Game::Game(MutationOfJBEngine *vm) : _vm(vm) {
+Game::Game(MutationOfJBEngine *vm)
+: _vm(vm), _scriptExecCtx(*this) {
_gameData = new GameData;
loadGameData(false);
@@ -105,18 +108,9 @@ void Game::changeScene(uint8 sceneId, bool partB) {
scriptFile.close();
}
-Command *Game::getMacro(const Common::String &name) const {
- Command *cmd = nullptr;
- if (_localScript) {
- cmd = _localScript->getMacro(name);
- }
-
- if (!cmd && _globalScript) {
- cmd = _globalScript->getMacro(name);
- }
-
- return cmd;
+void Game::update() {
+ _scriptExecCtx.runActiveCommand();
}
}
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index 5ed65f1..b44929d 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -24,6 +24,7 @@
#define MUTATIONOFJB_GAME_H
#include "common/scummsys.h"
+#include "mutationofjb/script.h"
namespace Common {
class String;
@@ -47,10 +48,12 @@ public:
void changeScene(uint8 sceneId, bool partB);
- Command *getMacro(const Common::String &name) const;
+ void update();
private:
bool loadGameData(bool partB);
+ void runActiveCommand();
+ void startCommand(Command *cmd);
MutationOfJBEngine *_vm;
@@ -58,6 +61,8 @@ private:
Script *_globalScript;
Script *_localScript;
Room *_room;
+
+ ScriptExecutionContext _scriptExecCtx;
};
}
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index 66de1f7..1bd08dd 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -111,6 +111,7 @@ Common::Error MutationOfJBEngine::run() {
}
_console->onFrame();
+ _game->update();
_system->delayMillis(40);
_screen->update();
}
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 1291bd8..e3aa3e6 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -26,6 +26,7 @@
#include "common/hash-str.h"
#include "common/stream.h"
#include "common/debug.h"
+#include "common/translation.h"
#include "mutationofjb/commands/command.h"
#include "mutationofjb/commands/ifcommand.h"
#include "mutationofjb/commands/ifitemcommand.h"
@@ -100,15 +101,15 @@ void ScriptParseContext::addConditionalCommand(ConditionalCommand *command, char
void ScriptExecutionContext::pushReturnCommand(Command *cmd) {
- _stack.push(cmd);
+ _callStack.push(cmd);
}
Command *ScriptExecutionContext::popReturnCommand() {
- if (_stack.empty()) {
+ if (_callStack.empty()) {
return nullptr;
}
- return _stack.pop();
+ return _callStack.pop();
}
Game &ScriptExecutionContext::getGame() {
@@ -119,6 +120,49 @@ GameData &ScriptExecutionContext::getGameData() {
return _game.getGameData();
}
+void ScriptExecutionContext::clear() {
+ _callStack.clear();
+}
+
+Command::ExecuteResult ScriptExecutionContext::runActiveCommand() {
+ while (_activeCommand) {
+ const Command::ExecuteResult result = _activeCommand->execute(*this);
+ if (result == Command::Finished) {
+ _activeCommand = _activeCommand->next();
+ } else {
+ return result;
+ }
+ }
+
+ return Command::Finished;
+}
+
+Command::ExecuteResult ScriptExecutionContext::startCommand(Command *cmd) {
+ if (_activeCommand) {
+ warning(_("Trying to start command while another one is running."));
+ return Command::Finished;
+ }
+ clear();
+ _activeCommand = cmd;
+ return runActiveCommand();
+}
+
+Command *ScriptExecutionContext::getMacro(const Common::String &name) const {
+ Command *cmd = nullptr;
+
+ Script *const localScript = _localScriptOverride ? _localScriptOverride : _game.getLocalScript();
+ Script *const globalScript = _game.getGlobalScript();
+
+ if (localScript) {
+ cmd = localScript->getMacro(name);
+ }
+
+ if (!cmd && globalScript) {
+ cmd = globalScript->getMacro(name);
+ }
+
+ return cmd;
+}
bool Script::loadFromStream(Common::SeekableReadStream &stream) {
destroy();
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 940a274..8232106 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -23,6 +23,7 @@
#ifndef MUTATIONOFJB_SCRIPT_H
#define MUTATIONOFJB_SCRIPT_H
+#include "mutationofjb/commands/command.h"
#include "common/array.h"
#include "common/hashmap.h"
#include "common/hash-str.h"
@@ -41,6 +42,7 @@ class Game;
class GameData;
class GotoCommand;
class ConditionalCommand;
+class Script;
typedef Common::Array<Command *> Commands;
@@ -96,15 +98,23 @@ private:
class ScriptExecutionContext {
public:
- ScriptExecutionContext(Game &game) : _game(game) {}
+ ScriptExecutionContext(Game &game, Script *localScriptOverride = nullptr) : _game(game), _activeCommand(nullptr), _localScriptOverride(localScriptOverride) {}
+ void clear();
+
+ Command::ExecuteResult runActiveCommand();
+ Command::ExecuteResult startCommand(Command *cmd);
+
void pushReturnCommand(Command *);
Command *popReturnCommand();
Game &getGame();
GameData &getGameData();
+ Command *getMacro(const Common::String &name) const;
private:
Game &_game;
- Common::Stack<Command *> _stack;
+ Command *_activeCommand;
+ Common::Stack<Command *> _callStack;
+ Script *_localScriptOverride;
};
class Script {
Commit: e93e20dbe869f2d3906ec1d0a151a21de29e9714
https://github.com/scummvm/scummvm/commit/e93e20dbe869f2d3906ec1d0a151a21de29e9714
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Parse startup sections in scripts and fix change scene command.
Changed paths:
engines/mutationofjb/commands/changecommand.cpp
engines/mutationofjb/commands/changecommand.h
engines/mutationofjb/commands/endblockcommand.cpp
engines/mutationofjb/commands/endblockcommand.h
engines/mutationofjb/debug.cpp
engines/mutationofjb/debug.h
engines/mutationofjb/script.cpp
engines/mutationofjb/script.h
diff --git a/engines/mutationofjb/commands/changecommand.cpp b/engines/mutationofjb/commands/changecommand.cpp
index a4316bd..f2639b6 100644
--- a/engines/mutationofjb/commands/changecommand.cpp
+++ b/engines/mutationofjb/commands/changecommand.cpp
@@ -37,16 +37,30 @@ namespace MutationOfJB {
// <ii> 2B Entity ID.
// <val> VL Value.
-bool ChangeCommandParser::parseValueString(const Common::String &valueString, uint8 &sceneId, uint8 &entityId, ChangeCommand::ChangeRegister ®, ChangeCommand::ChangeOperation &op, ChangeCommandValue &ccv) {
- if (valueString.size() < 8) {
- return false;
+bool ChangeCommandParser::parseValueString(const Common::String &valueString, bool changeEntity, uint8 &sceneId, uint8 &entityId, ChangeCommand::ChangeRegister ®, ChangeCommand::ChangeOperation &op, ChangeCommandValue &ccv) {
+ if (changeEntity) {
+ if (valueString.size() < 8) {
+ return false;
+ }
+ } else {
+ if (valueString.size() < 7) {
+ return false;
+ }
}
sceneId = atoi(valueString.c_str() + 3);
- entityId = atoi(valueString.c_str() + 6);
+ if (changeEntity) {
+ entityId = atoi(valueString.c_str() + 6);
+ }
const char *val = nullptr;
- if (valueString.size() >= 9) {
- val = valueString.c_str() + 9;
+ if (changeEntity) {
+ if (valueString.size() >= 9) {
+ val = valueString.c_str() + 9;
+ }
+ } else {
+ if (valueString.size() >= 6) {
+ val = valueString.c_str() + 6;
+ }
}
if (valueString.hasPrefix("NM")) {
@@ -137,7 +151,7 @@ bool ChangeDoorCommandParser::parse(const Common::String &line, ScriptParseConte
ChangeCommand::ChangeRegister reg;
ChangeCommand::ChangeOperation op;
ChangeCommandValue val;
- if (!parseValueString(line.c_str() + 8, sceneId, objectId, reg, op, val)) {
+ if (!parseValueString(line.c_str() + 8, true, sceneId, objectId, reg, op, val)) {
return false;
}
@@ -154,7 +168,7 @@ bool ChangeObjectCommandParser::parse(const Common::String &line, ScriptParseCon
ChangeCommand::ChangeRegister reg;
ChangeCommand::ChangeOperation op;
ChangeCommandValue val;
- if (!parseValueString(line.c_str() + 8, sceneId, objectId, reg, op, val)) {
+ if (!parseValueString(line.c_str() + 8, true, sceneId, objectId, reg, op, val)) {
return false;
}
@@ -171,7 +185,7 @@ bool ChangeStaticCommandParser::parse(const Common::String &line, ScriptParseCon
ChangeCommand::ChangeRegister reg;
ChangeCommand::ChangeOperation op;
ChangeCommandValue val;
- if (!parseValueString(line.c_str() + 8, sceneId, objectId, reg, op, val)) {
+ if (!parseValueString(line.c_str() + 8, true, sceneId, objectId, reg, op, val)) {
return false;
}
@@ -188,7 +202,7 @@ bool ChangeSceneCommandParser::parse(const Common::String &line, ScriptParseCont
ChangeCommand::ChangeRegister reg;
ChangeCommand::ChangeOperation op;
ChangeCommandValue val;
- if (!parseValueString(line.c_str() + 8, sceneId, objectId, reg, op, val)) {
+ if (!parseValueString(line.c_str() + 7, false, sceneId, objectId, reg, op, val)) {
return false;
}
@@ -351,7 +365,7 @@ Command::ExecuteResult ChangeDoorCommand::execute(ScriptExecutionContext &script
}
Common::String ChangeDoorCommand::debugString() const {
- return Common::String::format("scene%d.door%d.%s %s %s", _sceneId, _entityId, getRegisterAsString(), getOperationAsString(), getValueAsString().c_str());
+ return Common::String::format("SCENE%d.DOOR%d.%s %s %s", _sceneId, _entityId, getRegisterAsString(), getOperationAsString(), getValueAsString().c_str());
}
Command::ExecuteResult ChangeObjectCommand::execute(ScriptExecutionContext &scriptExecCtx) {
@@ -414,7 +428,7 @@ Command::ExecuteResult ChangeObjectCommand::execute(ScriptExecutionContext &scri
}
Common::String ChangeObjectCommand::debugString() const {
- return Common::String::format("scene%d.object%d.%s %s %s", _sceneId, _entityId, getRegisterAsString(), getOperationAsString(), getValueAsString().c_str());
+ return Common::String::format("SCENE%d.OBJECT%d.%s %s %s", _sceneId, _entityId, getRegisterAsString(), getOperationAsString(), getValueAsString().c_str());
}
Command::ExecuteResult ChangeStaticCommand::execute(ScriptExecutionContext &scriptExecCtx) {
@@ -465,7 +479,7 @@ Command::ExecuteResult ChangeStaticCommand::execute(ScriptExecutionContext &scri
}
Common::String ChangeStaticCommand::debugString() const {
- return Common::String::format("scene%d.static%d.%s %s %s", _sceneId, _entityId, getRegisterAsString(), getOperationAsString(), getValueAsString().c_str());
+ return Common::String::format("SCENE%d.STATIC%d.%s %s %s", _sceneId, _entityId, getRegisterAsString(), getOperationAsString(), getValueAsString().c_str());
}
Command::ExecuteResult ChangeSceneCommand::execute(ScriptExecutionContext &scriptExecCtx) {
@@ -508,6 +522,6 @@ Command::ExecuteResult ChangeSceneCommand::execute(ScriptExecutionContext &scrip
}
Common::String ChangeSceneCommand::debugString() const {
- return Common::String::format("scene%d.%s %s %s", _sceneId, getRegisterAsString(), getOperationAsString(), getValueAsString().c_str());
+ return Common::String::format("SCENE%d.%s %s %s", _sceneId, getRegisterAsString(), getOperationAsString(), getValueAsString().c_str());
}
}
diff --git a/engines/mutationofjb/commands/changecommand.h b/engines/mutationofjb/commands/changecommand.h
index dde5cd1..f5d7cf5 100644
--- a/engines/mutationofjb/commands/changecommand.h
+++ b/engines/mutationofjb/commands/changecommand.h
@@ -84,7 +84,7 @@ protected:
class ChangeCommandParser : public SeqCommandParser {
protected:
- bool parseValueString(const Common::String &valueString, uint8 &sceneId, uint8 &entityId, ChangeCommand::ChangeRegister ®, ChangeCommand::ChangeOperation &op, ChangeCommandValue &ccv);
+ bool parseValueString(const Common::String &valueString, bool changeEntity, uint8 &sceneId, uint8 &entityId, ChangeCommand::ChangeRegister ®, ChangeCommand::ChangeOperation &op, ChangeCommandValue &ccv);
int parseInteger(const char *val, ChangeCommand::ChangeOperation &op);
};
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index 53ea74a..492a424 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -25,6 +25,7 @@
#include "mutationofjb/commands/conditionalcommand.h"
#include "common/str.h"
#include "common/debug.h"
+#include "common/translation.h"
/*
("#L " | "-L ") <object>
@@ -107,6 +108,8 @@ bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext
}
} else if (line.size() >= 8 && line.hasPrefix("#MACRO")) {
_foundMacro = line.c_str() + 7;
+ } else if (line.size() >= 10 && line.hasPrefix("#STARTUP")) {
+ _foundStartup = line.c_str() + 9;
}
if (firstChar == '#') {
@@ -138,11 +141,26 @@ void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *,
_ifTag = 0;
}
- if (!_foundMacro.empty() && newCommand) {
- if (!parseCtx._macros.contains(_foundMacro)) {
- parseCtx._macros[_foundMacro] = newCommand;
+ if (!_foundMacro.empty()) {
+ if (newCommand) {
+ if (!parseCtx._macros.contains(_foundMacro)) {
+ parseCtx._macros[_foundMacro] = newCommand;
+ } else {
+ warning(_("Macro '%s' already exists."), _foundMacro.c_str());
+ }
+ }
+ _foundMacro.clear();
+ }
+ if (!_foundStartup.empty()) {
+ if (newCommand) {
+ const uint8 startupId = atoi(_foundStartup.c_str());
+ if (!parseCtx._startups.contains(startupId)) {
+ parseCtx._startups[startupId] = newCommand;
+ } else {
+ warning(_("Startup %u already exists."), (unsigned int) startupId);
+ }
}
- _foundMacro = "";
+ _foundStartup.clear();
}
if (newCommandParser != this) {
diff --git a/engines/mutationofjb/commands/endblockcommand.h b/engines/mutationofjb/commands/endblockcommand.h
index 4c0d23b..eb77f43 100644
--- a/engines/mutationofjb/commands/endblockcommand.h
+++ b/engines/mutationofjb/commands/endblockcommand.h
@@ -45,6 +45,7 @@ private:
Common::Array<uint> _pendingActionInfos;
Common::String _foundMacro;
+ Common::String _foundStartup;
};
class EndBlockCommand : public Command {
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index b4c2e77..e533339 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -55,24 +55,37 @@ static Common::String convertToASCII(const Common::String &str) {
}
Console::Console(MutationOfJBEngine *vm) : _vm(vm) {
+ registerCmd("showallcommands", WRAP_METHOD(Console, cmd_showallcommands));
registerCmd("listsections", WRAP_METHOD(Console, cmd_listsections));
registerCmd("showsection", WRAP_METHOD(Console, cmd_showsection));
registerCmd("listmacros", WRAP_METHOD(Console, cmd_listmacros));
registerCmd("showmacro", WRAP_METHOD(Console, cmd_showmacro));
+ registerCmd("liststartups", WRAP_METHOD(Console, cmd_liststartups));
+ registerCmd("showstartup", WRAP_METHOD(Console, cmd_showstartup));
registerCmd("changescene", WRAP_METHOD(Console, cmd_changescene));
}
+bool Console::cmd_showallcommands(int argc, const char **argv) {
+ if (argc == 2) {
+ Script *const script = getScriptFromArg(argv[1]);
+ if (script) {
+ const Commands &commands = script->getAllCommands();
+
+ for (Commands::const_iterator it = commands.begin(); it != commands.end(); ++it) {
+ debugPrintf("%s\n", convertToASCII((*it)->debugString()).c_str());
+ }
+ }
+ } else {
+ debugPrintf(_("showallcommands <G|L>\n"));
+ }
+
+ return true;
+}
+
bool Console::cmd_listsections(int argc, const char **argv) {
if (argc == 3) {
- Script *script = nullptr;
- if (strcmp(argv[1], "G") == 0) {
- script = _vm->getGame().getGlobalScript();
- } else if (strcmp(argv[1], "L") == 0) {
- script = _vm->getGame().getLocalScript();
- }
- if (!script) {
- debugPrintf(_("Choose 'G' (global) or 'L' (local) script.\n"));
- } else {
+ Script *const script = getScriptFromArg(argv[1]);
+ if (script) {
if (strcmp(argv[2], "L") == 0) {
const ActionInfos &actionInfos = script->getLookActionInfos();
for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
@@ -140,15 +153,8 @@ void Console::showCommands(Command *command, int indentLevel) {
bool Console::cmd_showsection(int argc, const char **argv) {
if (argc >= 4) {
- Script *script = nullptr;
- if (strcmp(argv[1], "G") == 0) {
- script = _vm->getGame().getGlobalScript();
- } else if (strcmp(argv[1], "L") == 0) {
- script = _vm->getGame().getLocalScript();
- }
- if (!script) {
- debugPrintf(_("Choose 'G' (global) or 'L' (local) script.\n"));
- } else {
+ Script *const script = getScriptFromArg(argv[1]);
+ if (script) {
Command *command = nullptr;
bool found = false;
if (strcmp(argv[2], "L") == 0) {
@@ -212,15 +218,8 @@ bool Console::cmd_showsection(int argc, const char **argv) {
bool Console::cmd_listmacros(int argc, const char **argv) {
if (argc == 2) {
- Script *script = nullptr;
- if (strcmp(argv[1], "G") == 0) {
- script = _vm->getGame().getGlobalScript();
- } else if (strcmp(argv[1], "L") == 0) {
- script = _vm->getGame().getLocalScript();
- }
- if (!script) {
- debugPrintf(_("Choose 'G' (global) or 'L' (local) script.\n"));
- } else {
+ Script *const script = getScriptFromArg(argv[1]);
+ if (script) {
const Macros ¯os = script->getMacros();
for (Macros::const_iterator it = macros.begin(); it != macros.end(); ++it) {
debugPrintf("%s\n", it->_key.c_str());
@@ -261,6 +260,43 @@ bool Console::cmd_showmacro(int argc, const char **argv) {
return true;
}
+bool Console::cmd_liststartups(int argc, const char **argv) {
+ if (argc == 2) {
+ Script *const script = getScriptFromArg(argv[1]);
+ if (script) {
+ const Startups &startups = script->getStartups();
+ for (Startups::const_iterator it = startups.begin(); it != startups.end(); ++it) {
+ debugPrintf("%u\n", (unsigned int) it->_key);
+ }
+ }
+ } else {
+ debugPrintf(_("liststartups <G|L>\n"));
+ }
+
+ return true;
+}
+
+bool Console::cmd_showstartup(int argc, const char **argv) {
+ if (argc == 3) {
+ Script *const script = getScriptFromArg(argv[1]);
+ if (script) {
+ const Startups &startups = script->getStartups();
+ Startups::const_iterator itMacro = startups.find((uint8) atoi(argv[2]));
+ if (itMacro != startups.end()) {
+ if (itMacro->_value) {
+ showCommands(itMacro->_value);
+ }
+ } else {
+ debugPrintf("Startup not found.\n");
+ }
+ }
+ } else {
+ debugPrintf(_("showstartup <G|L> <startupid>\n"));
+ }
+
+ return true;
+}
+
bool Console::cmd_changescene(int argc, const char **argv) {
if (argc == 2) {
const uint8 sceneId = atoi(argv[1]);
@@ -274,4 +310,18 @@ bool Console::cmd_changescene(int argc, const char **argv) {
return true;
}
+Script *Console::getScriptFromArg(const char *arg) {
+ Script *script = nullptr;
+ if (strcmp(arg, "G") == 0) {
+ script = _vm->getGame().getGlobalScript();
+ } else if (strcmp(arg, "L") == 0) {
+ script = _vm->getGame().getLocalScript();
+ }
+ if (!script) {
+ debugPrintf(_("Choose 'G' (global) or 'L' (local) script.\n"));
+ }
+
+ return script;
+}
+
}
diff --git a/engines/mutationofjb/debug.h b/engines/mutationofjb/debug.h
index 2f35a9c..8df5167 100644
--- a/engines/mutationofjb/debug.h
+++ b/engines/mutationofjb/debug.h
@@ -29,20 +29,25 @@ namespace MutationOfJB {
class MutationOfJBEngine;
class Command;
+class Script;
class Console : public GUI::Debugger {
public:
Console(MutationOfJBEngine *vm);
virtual ~Console(void) {}
private:
+ bool cmd_showallcommands(int argc, const char **argv);
bool cmd_listsections(int argc, const char **argv);
bool cmd_showsection(int argc, const char **argv);
bool cmd_listmacros(int argc, const char **argv);
bool cmd_showmacro(int argc, const char **argv);
+ bool cmd_liststartups(int argc, const char **argv);
+ bool cmd_showstartup(int argc, const char **argv);
bool cmd_changescene(int argc, const char **argv);
void showIndent(int indentLevel);
void showCommands(Command *command, int indentLevel = 0);
+ Script *getScriptFromArg(const char *arg);
MutationOfJBEngine *_vm;
};
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index e3aa3e6..8dc5e40 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -221,6 +221,7 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) {
}
_macros = parseCtx._macros;
+ _startups = parseCtx._startups;
return true;
}
@@ -252,6 +253,10 @@ const ActionInfos &Script::getUseActionInfos() const {
return _useActionInfos;
}
+const Commands &Script::getAllCommands() const {
+ return _allCommands;
+}
+
const Macros &Script::getMacros() const {
return _macros;
}
@@ -265,4 +270,17 @@ Command *Script::getMacro(const Common::String &name) const {
return it->_value;
}
+const Startups &Script::getStartups() const {
+ return _startups;
+}
+
+Command *Script::getStartup(uint8 startupId) const {
+ Startups::const_iterator it = _startups.find(startupId);
+ if (it == _startups.end()) {
+ return nullptr;
+ }
+
+ return it->_value;
+}
+
}
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 8232106..316aab5 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -64,6 +64,7 @@ struct ActionInfo {
typedef Common::Array<ActionInfo> ActionInfos;
typedef Common::Array<GotoCommand *> GotoCommands;
typedef Common::HashMap<Common::String, Command *> Macros;
+typedef Common::HashMap<uint8, Command *> Startups;
class ScriptParseContext {
public:
@@ -92,6 +93,7 @@ public:
ActionInfos _actionInfos;
Macros _macros;
+ Startups _startups;
private:
};
@@ -126,8 +128,11 @@ public:
const ActionInfos &getWalkActionInfos() const;
const ActionInfos &getTalkActionInfos() const;
const ActionInfos &getUseActionInfos() const;
+ const Commands &getAllCommands() const;
const Macros &getMacros() const;
+ const Startups &getStartups() const;
Command *getMacro(const Common::String &name) const;
+ Command *getStartup(uint8 startupId) const;
private:
void destroy();
@@ -137,6 +142,7 @@ private:
ActionInfos _talkActionInfos;
ActionInfos _useActionInfos;
Macros _macros;
+ Startups _startups;
};
}
Commit: 574bb83b9760ff7a92da2b43146d245c0331d8ad
https://github.com/scummvm/scummvm/commit/574bb83b9760ff7a92da2b43146d245c0331d8ad
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add support for NEWROOM command.
Changed paths:
A engines/mutationofjb/commands/newroomcommand.cpp
A engines/mutationofjb/commands/newroomcommand.h
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/gamedata.cpp
engines/mutationofjb/gamedata.h
engines/mutationofjb/module.mk
engines/mutationofjb/script.cpp
engines/mutationofjb/script.h
diff --git a/engines/mutationofjb/commands/newroomcommand.cpp b/engines/mutationofjb/commands/newroomcommand.cpp
new file mode 100644
index 0000000..818ef7d
--- /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 0000000..f224e44
--- /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 6436c7a..c5fa7b3 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 b44929d..2855704 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 a181510..314eb56 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 ca70cd7..eb474f8 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 447f9a9..917ab3c 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 8dc5e40..b9b1515 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 316aab5..09aa942 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();
Commit: 128d30c91c114d771e7777963716d3625be8cfeb
https://github.com/scummvm/scummvm/commit/128d30c91c114d771e7777963716d3625be8cfeb
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Run action when clicking on static or door.
Changed paths:
engines/mutationofjb/debug.cpp
engines/mutationofjb/debug.h
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/gamedata.cpp
engines/mutationofjb/gamedata.h
engines/mutationofjb/mutationofjb.cpp
engines/mutationofjb/script.cpp
engines/mutationofjb/script.h
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index e533339..f533a94 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -22,6 +22,7 @@
#include "mutationofjb/debug.h"
#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
#include "mutationofjb/mutationofjb.h"
#include "mutationofjb/script.h"
#include "mutationofjb/commands/command.h"
@@ -63,6 +64,9 @@ Console::Console(MutationOfJBEngine *vm) : _vm(vm) {
registerCmd("liststartups", WRAP_METHOD(Console, cmd_liststartups));
registerCmd("showstartup", WRAP_METHOD(Console, cmd_showstartup));
registerCmd("changescene", WRAP_METHOD(Console, cmd_changescene));
+ registerCmd("dumpsceneinfo", WRAP_METHOD(Console, cmd_dumpsceneinfo));
+ registerCmd("dumpobjectinfo", WRAP_METHOD(Console, cmd_dumpobjectinfo));
+ registerCmd("dumpstaticinfo", WRAP_METHOD(Console, cmd_dumpstaticinfo));
}
bool Console::cmd_showallcommands(int argc, const char **argv) {
@@ -86,40 +90,40 @@ bool Console::cmd_listsections(int argc, const char **argv) {
if (argc == 3) {
Script *const script = getScriptFromArg(argv[1]);
if (script) {
+ ActionInfo::Action action;
+ const char *word = nullptr;
if (strcmp(argv[2], "L") == 0) {
- const ActionInfos &actionInfos = script->getLookActionInfos();
- for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
- const ActionInfo &actionInfo = *it;
- debugPrintf(_("Look %s\n"), convertToASCII(actionInfo._object1Name).c_str());
- }
+ action = ActionInfo::Look;
+ word = _("Look");
} else if (strcmp(argv[2], "W") == 0) {
- const ActionInfos &actionInfos = script->getWalkActionInfos();
- for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
- const ActionInfo &actionInfo = *it;
- debugPrintf(_("Walk %s\n"), convertToASCII(actionInfo._object1Name).c_str());
- }
+ action = ActionInfo::Walk;
+ word = _("Walk");
} else if (strcmp(argv[2], "T") == 0) {
- const ActionInfos &actionInfos = script->getTalkActionInfos();
- for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
- const ActionInfo &actionInfo = *it;
- debugPrintf(_("Talk %s\n"), convertToASCII(actionInfo._object1Name).c_str());
- }
+ action = ActionInfo::Talk;
+ word = _("Talk");
} else if (strcmp(argv[2], "U") == 0) {
- const ActionInfos &actionInfos = script->getUseActionInfos();
+ action = ActionInfo::Use;
+ word = _("Use");
+ } else if (strcmp(argv[2], "P") == 0) {
+ action = ActionInfo::PickUp;
+ word = _("Pick up");
+ } else {
+ debugPrintf(_("Choose 'L' (look), 'W' (walk), 'T' (talk), 'U' (use) or 'P' (pick up).\n"));
+ }
+ if (word) {
+ const ActionInfos &actionInfos = script->getActionInfos(action);
for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
const ActionInfo &actionInfo = *it;
- if (actionInfo._object2Name.empty()) {
- debugPrintf(_("Use %s\n"), convertToASCII(actionInfo._object1Name).c_str());
+ if (action != ActionInfo::Use || actionInfo._entity2Name.empty()) {
+ debugPrintf("%s %s\n", word, convertToASCII(actionInfo._entity1Name).c_str());
} else {
- debugPrintf(_("Use %s %s\n"), convertToASCII(actionInfo._object1Name).c_str(), convertToASCII(actionInfo._object2Name).c_str());
+ debugPrintf("%s %s %s\n", word, convertToASCII(actionInfo._entity1Name).c_str(), convertToASCII(actionInfo._entity2Name).c_str());
}
}
- } else {
- debugPrintf(_("Choose 'L' (look), 'W' (walk), 'T' (talk) or 'U' (use).\n"));
}
}
} else {
- debugPrintf(_("listsections <G|L> <L|W|T|U>\n"));
+ debugPrintf(_("listsections <G|L> <L|W|T|U|P>\n"));
}
return true;
}
@@ -156,61 +160,47 @@ bool Console::cmd_showsection(int argc, const char **argv) {
Script *const script = getScriptFromArg(argv[1]);
if (script) {
Command *command = nullptr;
+ ActionInfo::Action action;
+ bool correctAction = true;
bool found = false;
+
if (strcmp(argv[2], "L") == 0) {
- const ActionInfos &actionInfos = script->getLookActionInfos();
- for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
- const ActionInfo &actionInfo = *it;
- if (convertToASCII(actionInfo._object1Name) == argv[3]) {
- found = true;
- command = actionInfo._command;
- break;
- }
- }
+ action = ActionInfo::Look;
} else if (strcmp(argv[2], "W") == 0) {
- const ActionInfos &actionInfos = script->getWalkActionInfos();
- for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
- const ActionInfo &actionInfo = *it;
- if (convertToASCII(actionInfo._object1Name) == argv[3]) {
- found = true;
- command = actionInfo._command;
- break;
- }
- }
+ action = ActionInfo::Walk;
} else if (strcmp(argv[2], "T") == 0) {
- const ActionInfos &actionInfos = script->getTalkActionInfos();
- for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
- const ActionInfo &actionInfo = *it;
- if (convertToASCII(actionInfo._object1Name) == argv[3]) {
- found = true;
- command = actionInfo._command;
- break;
- }
- }
+ action = ActionInfo::Talk;
} else if (strcmp(argv[2], "U") == 0) {
- const ActionInfos &actionInfos = script->getUseActionInfos();
+ action = ActionInfo::Use;
+ } else if (strcmp(argv[2], "P") == 0) {
+ action = ActionInfo::PickUp;
+ } else {
+ debugPrintf(_("Choose 'L' (look), 'W' (walk), 'T' (talk), 'U' (use) or 'P' (pick up).\n"));
+ correctAction = false;
+ }
+
+ if (correctAction) {
+ const ActionInfos &actionInfos = script->getActionInfos(action);
for (ActionInfos::const_iterator it = actionInfos.begin(); it != actionInfos.end(); ++it) {
const ActionInfo &actionInfo = *it;
- if (convertToASCII(actionInfo._object1Name) == argv[3] && ((argc == 4 && actionInfo._object2Name.empty()) || (argc > 4 && convertToASCII(actionInfo._object2Name) == argv[4]))) {
+ if (convertToASCII(actionInfo._entity1Name) == argv[3] && (action != ActionInfo::Use || ((argc == 4 && actionInfo._entity2Name.empty()) || (argc > 4 && convertToASCII(actionInfo._entity2Name) == argv[4])))) {
found = true;
command = actionInfo._command;
break;
}
}
- } else {
- debugPrintf(_("Choose 'L' (look), 'W' (walk), 'T' (talk) or 'U' (use).\n"));
- }
- if (found) {
- if (command) {
- showCommands(command);
+ if (found) {
+ if (command) {
+ showCommands(command);
+ }
+ } else {
+ debugPrintf("Section not found.\n");
}
- } else {
- debugPrintf("Section not found.\n");
}
}
} else {
- debugPrintf(_("showsection <G|L> <L|W|T|U> <sectionname>\n"));
+ debugPrintf(_("showsection <G|L> <L|W|T|U|P> <sectionname>\n"));
}
return true;
@@ -310,6 +300,97 @@ bool Console::cmd_changescene(int argc, const char **argv) {
return true;
}
+bool Console::cmd_dumpsceneinfo(int argc, const char **argv) {
+ if (argc == 2) {
+ const uint8 sceneId = atoi(argv[1]);
+ Scene *scene = _vm->getGame().getGameData().getScene(sceneId);
+ if (scene) {
+ debugPrintf("Startup: %u\n", (unsigned int) scene->_startup);
+ debugPrintf("Delay: %u\n", (unsigned int) scene->_DL);
+ debugPrintf("Doors: %u\n", (unsigned int) scene->_noDoors);
+ debugPrintf("Objects: %u\n", (unsigned int) scene->_noObjects);
+ debugPrintf("Statics: %u\n", (unsigned int) scene->_noStatics);
+ debugPrintf("ObstacleY1: %u\n", (unsigned int) scene->_obstacleY1);
+ debugPrintf("PalRotStart: %u\n", (unsigned int) scene->_palRotStart);
+ debugPrintf("PalRotEnd: %u\n", (unsigned int) scene->_palRotEnd);
+ debugPrintf("PalRotPeriod: %u\n", (unsigned int) scene->_palRotPeriod);
+ } else {
+ debugPrintf(_("Scene %u not found.\n"), (unsigned int) sceneId);
+ }
+ } else {
+ debugPrintf(_("dumpsceneinfo <sceneid>\n"));
+ }
+
+ return true;
+}
+
+bool Console::cmd_dumpobjectinfo(int argc, const char **argv) {
+ if (argc == 3) {
+ const uint8 sceneId = atoi(argv[1]);
+ const uint8 objectId = atoi(argv[2]);
+
+ Scene *const scene = _vm->getGame().getGameData().getScene(sceneId);
+ if (scene) {
+ Object *const object = scene->getObject(objectId);
+ if (object) {
+ debugPrintf("AC: %u\n", (unsigned int) object->_AC);
+ debugPrintf("FA: %u\n", (unsigned int) object->_FA);
+ debugPrintf("FR: %u\n", (unsigned int) object->_FR);
+ debugPrintf("NA: %u\n", (unsigned int) object->_NA);
+ debugPrintf("FS: %u\n", (unsigned int) object->_FS);
+ debugPrintf("Unknown: %u\n", (unsigned int) object->_unknown);
+ debugPrintf("CA: %u\n", (unsigned int) object->_CA);
+ debugPrintf("X: %u\n", (unsigned int) object->_x);
+ debugPrintf("Y: %u\n", (unsigned int) object->_y);
+ debugPrintf("XL: %u\n", (unsigned int) object->_XL);
+ debugPrintf("YL: %u\n", (unsigned int) object->_YL);
+ debugPrintf("WX: %u\n", (unsigned int) object->_WX);
+ debugPrintf("WY: %u\n", (unsigned int) object->_WY);
+ debugPrintf("SP: %u\n", (unsigned int) object->_SP);
+ } else {
+ debugPrintf(_("Object %u not found.\n"), (unsigned int) objectId);
+ }
+ } else {
+ debugPrintf(_("Scene %u not found.\n"), (unsigned int) sceneId);
+ }
+ } else {
+ debugPrintf(_("dumpobjectinfo <sceneid> <objectid>\n"));
+ }
+
+ return true;
+}
+
+bool Console::cmd_dumpstaticinfo(int argc, const char **argv) {
+ if (argc == 3) {
+ const uint8 sceneId = atoi(argv[1]);
+ const uint8 staticId = atoi(argv[2]);
+
+ Scene *const scene = _vm->getGame().getGameData().getScene(sceneId);
+ if (scene) {
+ Static *const stat = scene->getStatic(staticId, true);
+ if (stat) {
+ debugPrintf("Active: %u\n", (unsigned int) stat->_active);
+ debugPrintf("Name: '%s'\n", convertToASCII(stat->_name).c_str());
+ debugPrintf("X: %u\n", (unsigned int) stat->_x);
+ debugPrintf("Y: %u\n", (unsigned int) stat->_y);
+ debugPrintf("Width: %u\n", (unsigned int) stat->_width);
+ debugPrintf("Height: %u\n", (unsigned int) stat->_height);
+ debugPrintf("WalkToX: %u\n", (unsigned int) stat->_walkToY);
+ debugPrintf("WalkToY: %u\n", (unsigned int) stat->_walkToX);
+ debugPrintf("WalkToFrame: %u\n", (unsigned int) stat->_SP);
+ } else {
+ debugPrintf(_("Static %u not found.\n"), (unsigned int) staticId);
+ }
+ } else {
+ debugPrintf(_("Scene %u not found.\n"), (unsigned int) sceneId);
+ }
+ } else {
+ debugPrintf(_("dumpstaticinfo <sceneid> <staticid>\n"));
+ }
+
+ return true;
+}
+
Script *Console::getScriptFromArg(const char *arg) {
Script *script = nullptr;
if (strcmp(arg, "G") == 0) {
diff --git a/engines/mutationofjb/debug.h b/engines/mutationofjb/debug.h
index 8df5167..e57b787 100644
--- a/engines/mutationofjb/debug.h
+++ b/engines/mutationofjb/debug.h
@@ -44,6 +44,9 @@ private:
bool cmd_liststartups(int argc, const char **argv);
bool cmd_showstartup(int argc, const char **argv);
bool cmd_changescene(int argc, const char **argv);
+ bool cmd_dumpsceneinfo(int argc, const char **argv);
+ bool cmd_dumpobjectinfo(int argc, const char **argv);
+ bool cmd_dumpstaticinfo(int argc, const char **argv);
void showIndent(int indentLevel);
void showCommands(Command *command, int indentLevel = 0);
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index c5fa7b3..156c020 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -122,6 +122,64 @@ Script *Game::changeSceneDelayScript(uint8 sceneId, bool partB) {
return _delayedLocalScript;
}
+Door *Game::findDoor(int16 x, int16 y) {
+ Scene *scene = _gameData->getCurrentScene();
+ if (!scene)
+ return nullptr;
+
+ for (int i = 0; i < MIN(ARRAYSIZE(scene->_doors), (int) scene->_noDoors); ++i) {
+ Door &door = scene->_doors[i];
+ if ((x >= door._x) && (x < door._x + door._width) && (y >= door._y) && (y < door._y + door._height)) {
+ return &door;
+ }
+ }
+
+ return nullptr;
+}
+
+Static *Game::findStatic(int16 x, int16 y) {
+ Scene *scene = _gameData->getCurrentScene();
+ if (!scene)
+ return nullptr;
+
+ for (int i = 0; i < MIN(ARRAYSIZE(scene->_statics), (int) scene->_noStatics); ++i) {
+ Static &stat = scene->_statics[i];
+ if ((x >= stat._x) && (x < stat._x + stat._width) && (y >= stat._y) && (y < stat._y + stat._height)) {
+ return &stat;
+ }
+ }
+
+ return nullptr;
+}
+
+static Command *findActionInfoCommand(const ActionInfos &infos, const Common::String &entity1Name, const Common::String &entity2Name = Common::String()) {
+ for (ActionInfos::const_iterator it = infos.begin(); it != infos.end(); ++it) {
+ if (it->_entity1Name == entity1Name && it->_entity2Name == entity2Name) {
+ return it->_command;
+ }
+ }
+ return nullptr;
+}
+
+bool Game::startActionSection(ActionInfo::Action action, const Common::String &entity1Name, const Common::String &entity2Name) {
+ Script *const localScript = getLocalScript();
+ Script *const globalScript = getGlobalScript();
+
+ Command *command = nullptr;
+ if (localScript) {
+ command = findActionInfoCommand(localScript->getActionInfos(action), entity1Name, entity2Name);
+ }
+ if (!command && globalScript) {
+ command = findActionInfoCommand(globalScript->getActionInfos(action), entity1Name, entity2Name);
+ }
+ if (command) {
+ _scriptExecCtx.startCommand(command);
+ return true;
+ }
+
+ return false;
+}
+
void Game::update() {
Command::ExecuteResult res = _scriptExecCtx.runActiveCommand();
if (res == Command::Finished && _delayedLocalScript) {
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index 2855704..503cde9 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -37,6 +37,8 @@ class MutationOfJBEngine;
class GameData;
class Script;
class Room;
+class Door;
+class Static;
class Game {
public:
@@ -49,6 +51,10 @@ public:
void changeScene(uint8 sceneId, bool partB);
Script *changeSceneDelayScript(uint8 sceneId, bool partB);
+ Door *findDoor(int16 x, int16 y);
+ Static *findStatic(int16 x, int16 y);
+ bool startActionSection(ActionInfo::Action action, const Common::String &entity1Name, const Common::String &entity2Name = Common::String());
+
void update();
private:
diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp
index 314eb56..acca555 100644
--- a/engines/mutationofjb/gamedata.cpp
+++ b/engines/mutationofjb/gamedata.cpp
@@ -150,8 +150,8 @@ Door *Scene::getDoor(uint8 doorId) {
return &_doors[doorId - 1];
}
-Object *Scene::getObject(uint8 objectId) {
- if (objectId == 0 || objectId > _noObjects) {
+Object *Scene::getObject(uint8 objectId, bool ignoreNo) {
+ if (objectId == 0 || objectId > (!ignoreNo ? MIN(_noObjects, (uint8) ARRAYSIZE(_objects)) : ARRAYSIZE(_objects))) {
warning(_("Object %d does not exist"), objectId);
return nullptr;
}
@@ -159,8 +159,8 @@ Object *Scene::getObject(uint8 objectId) {
return &_objects[objectId - 1];
}
-Static *Scene::getStatic(uint8 staticId) {
- if (staticId == 0 || staticId > _noStatics) {
+Static *Scene::getStatic(uint8 staticId, bool ignoreNo) {
+ if (staticId == 0 || staticId > (!ignoreNo ? MIN(_noStatics, (uint8) ARRAYSIZE(_statics)) : ARRAYSIZE(_statics))) {
warning(_("Static %d does not exist"), staticId);
return nullptr;
}
diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h
index eb474f8..4735753 100644
--- a/engines/mutationofjb/gamedata.h
+++ b/engines/mutationofjb/gamedata.h
@@ -34,6 +34,14 @@ namespace MutationOfJB {
static const uint8 MAX_STR_LENGTH = 0x14;
+/*
+ There are 4 types of entities present in the game data:
+ - Door
+ - Object
+ - Static
+ - Bitmap
+*/
+
struct Door {
/*
Door name.
@@ -115,8 +123,8 @@ struct Bitmap {
struct Scene {
Door *getDoor(uint8 objectId);
- Object *getObject(uint8 objectId);
- Static *getStatic(uint8 staticId);
+ Object *getObject(uint8 objectId, bool ignoreNo = false);
+ Static *getStatic(uint8 staticId, bool ignoreNo = false);
uint8 _startup;
uint8 _unknown001;
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index 1bd08dd..622be67 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -77,6 +77,7 @@ Common::Error MutationOfJBEngine::run() {
_console = new Console(this);
_screen = new Graphics::Screen();
_game = new Game(this);
+ ActionInfo::Action currentAction = ActionInfo::Walk;
setupCursor();
@@ -94,17 +95,35 @@ Common::Error MutationOfJBEngine::run() {
}
case Common::EVENT_LBUTTONDOWN:
{
- const Scene *const scene = _game->getGameData().getScene(_game->getGameData()._currentScene);
- if (scene) {
- for (int i = 0; i < MIN(ARRAYSIZE(scene->_doors), (int) scene->_noDoors); ++i) {
- const Door &door = scene->_doors[i];
- if ((event.mouse.x >= door._x) && (event.mouse.x < door._x + door._width) && (event.mouse.y >= door._y) && (event.mouse.y < door._y + door._height)) {
- _game->changeScene(door._destSceneId, false);
- }
+ if (Door *const door = _game->findDoor(event.mouse.x, event.mouse.y)) {
+ if (!_game->startActionSection(currentAction, door->_name) && currentAction == ActionInfo::Walk && door->_destSceneId != 0) {
+ _game->changeScene(door->_destSceneId, _game->getGameData()._partB);
}
+ } else if (Static *const stat = _game->findStatic(event.mouse.x, event.mouse.y)) {
+ _game->startActionSection(currentAction, stat->_name);
}
break;
}
+ case Common::EVENT_KEYUP:
+ {
+ switch (event.kbd.ascii) {
+ case 'g':
+ currentAction = ActionInfo::Walk;
+ break;
+ case 'r':
+ currentAction = ActionInfo::Talk;
+ break;
+ case 's':
+ currentAction = ActionInfo::Look;
+ break;
+ case 'b':
+ currentAction = ActionInfo::Use;
+ break;
+ case 'n':
+ currentAction = ActionInfo::PickUp;
+ break;
+ }
+ }
default:
break;
}
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index b9b1515..f213de9 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -221,18 +221,7 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) {
}
for (ActionInfos::iterator it = parseCtx._actionInfos.begin(); it != parseCtx._actionInfos.end(); ++it) {
- if (it->_action == ActionInfo::Look) {
- _lookActionInfos.push_back(*it);
- }
- if (it->_action == ActionInfo::Walk) {
- _walkActionInfos.push_back(*it);
- }
- if (it->_action == ActionInfo::Talk) {
- _talkActionInfos.push_back(*it);
- }
- if (it->_action == ActionInfo::Use) {
- _useActionInfos.push_back(*it);
- }
+ _actionInfos[it->_action].push_back(*it);
}
_macros = parseCtx._macros;
@@ -252,20 +241,8 @@ Script::~Script() {
destroy();
}
-const ActionInfos &Script::getLookActionInfos() const {
- return _lookActionInfos;
-}
-
-const ActionInfos &Script::getWalkActionInfos() const {
- return _walkActionInfos;
-}
-
-const ActionInfos &Script::getTalkActionInfos() const {
- return _talkActionInfos;
-}
-
-const ActionInfos &Script::getUseActionInfos() const {
- return _useActionInfos;
+const ActionInfos &Script::getActionInfos(ActionInfo::Action action) {
+ return _actionInfos[action];
}
const Commands &Script::getAllCommands() const {
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 09aa942..8a15a48 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -48,15 +48,16 @@ typedef Common::Array<Command *> Commands;
struct ActionInfo {
enum Action {
+ Look,
Walk,
Talk,
- Look,
- Use
+ Use,
+ PickUp
};
Action _action;
- Common::String _object1Name;
- Common::String _object2Name;
+ Common::String _entity1Name;
+ Common::String _entity2Name;
bool _walkTo;
Command *_command;
};
@@ -125,10 +126,7 @@ public:
bool loadFromStream(Common::SeekableReadStream &stream);
~Script();
- const ActionInfos &getLookActionInfos() const;
- const ActionInfos &getWalkActionInfos() const;
- const ActionInfos &getTalkActionInfos() const;
- const ActionInfos &getUseActionInfos() const;
+ const ActionInfos &getActionInfos(ActionInfo::Action action);
const Commands &getAllCommands() const;
const Macros &getMacros() const;
const Startups &getStartups() const;
@@ -138,10 +136,7 @@ public:
private:
void destroy();
Commands _allCommands;
- ActionInfos _lookActionInfos;
- ActionInfos _walkActionInfos;
- ActionInfos _talkActionInfos;
- ActionInfos _useActionInfos;
+ ActionInfos _actionInfos[5];
Macros _macros;
Startups _startups;
};
Commit: 2b94873694619272f79f6b358d4a18c8bce13cd8
https://github.com/scummvm/scummvm/commit/2b94873694619272f79f6b358d4a18c8bce13cd8
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Introduce better animation loader that supports diff frames.
Changed paths:
A engines/mutationofjb/animationdecoder.cpp
A engines/mutationofjb/animationdecoder.h
engines/mutationofjb/module.mk
engines/mutationofjb/room.cpp
engines/mutationofjb/room.h
diff --git a/engines/mutationofjb/animationdecoder.cpp b/engines/mutationofjb/animationdecoder.cpp
new file mode 100644
index 0000000..585ad91
--- /dev/null
+++ b/engines/mutationofjb/animationdecoder.cpp
@@ -0,0 +1,191 @@
+/* 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/animationdecoder.h"
+#include "mutationofjb/encryptedfile.h"
+#include "mutationofjb/util.h"
+#include "common/debug.h"
+#include "common/translation.h"
+
+namespace MutationOfJB {
+
+AnimationDecoder::AnimationDecoder(const Common::String &fileName) : _fileName(fileName) {
+ _surface.create(IMAGE_WIDTH, IMAGE_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
+}
+
+bool AnimationDecoder::decode(AnimationDecoderCallback *callback) {
+ EncryptedFile file;
+ file.open(_fileName);
+
+ if (!file.isOpen()) {
+ reportFileMissingError(_fileName.c_str());
+
+ return false;
+ }
+
+ file.seek(0, SEEK_END);
+ const int32 endPos = file.pos();
+
+ // Skip header - we don't need it anyway.
+ file.seek(0x80);
+
+ int frameNo = 0;
+
+ while (file.pos() != endPos) {
+ // Record.
+ const uint32 length = file.readUint32LE();
+ const uint16 recordId = file.readUint16LE();
+ const uint16 subrecords = file.readUint16LE();
+
+ // Skip 8 empty bytes.
+ file.seek(8, SEEK_CUR);
+
+ // Subrecords.
+ if (recordId == 0xF1FA) {
+ for (int i = 0; i < subrecords; ++i) {
+ int32 filePos = file.pos();
+
+ const uint32 subLength = file.readUint32LE();
+ const uint16 type = file.readUint16LE();
+
+ if (type == 0x0B) {
+ loadPalette(file);
+ if (callback) {
+ callback->onPaletteUpdated(_palette);
+ }
+ } else if (type == 0x0F) {
+ loadFullFrame(file, subLength - 6);
+ if (callback) {
+ callback->onFrame(frameNo, _surface);
+ }
+ } else if (type == 0x0C) {
+ loadDiffFrame(file, subLength - 6);
+ if (callback) {
+ callback->onFrame(frameNo, _surface);
+ }
+ } else {
+ debug(_("Unsupported record type %02X."), type);
+ file.seek(subLength - 6, SEEK_CUR);
+ }
+
+ // Makes decoding more robust, because for some reason records might have extra data at the end.
+ file.seek(filePos + subLength, SEEK_SET);
+ }
+ frameNo++;
+ } else {
+ file.seek(length - 16, SEEK_CUR);
+ }
+ }
+ file.close();
+
+ return true;
+}
+
+void AnimationDecoder::loadPalette(Common::SeekableReadStream &file) {
+ uint16 packets = file.readUint16LE();
+ const uint8 skipCount = file.readByte();
+ int copyCount = file.readByte();
+ if (copyCount == 0) {
+ copyCount = PALETTE_COLORS;
+ }
+
+ while(packets--) {
+ file.read(_palette + skipCount * 3, copyCount * 3);
+
+ for (int j = skipCount * 3; j < (skipCount + copyCount) * 3; ++j) {
+ _palette[j] <<= 2; // Uses 6-bit colors.
+ }
+ }
+}
+
+void AnimationDecoder::loadFullFrame(EncryptedFile &file, uint32 size) {
+ uint8 *const pixels = reinterpret_cast<uint8 *>(_surface.getPixels());
+ uint8 *ptr = pixels;
+ uint32 readBytes = 0;
+ uint32 lines = 0;
+
+ while (readBytes != size) {
+ if (lines == 200) {
+ // Some full frames have an unknown byte at the end,
+ // so break when we encounter all 200 lines.
+ break;
+ }
+
+ uint8 no = file.readByte();
+ readBytes++;
+ while (no--) {
+ uint8 n = file.readByte();
+ readBytes++;
+ if (n < 0x80) {
+ // RLE - Copy color n times.
+ uint8 color = file.readByte();
+ readBytes++;
+ while(n--) {
+ *ptr++ = color;
+ }
+ } else {
+ // Take next 0x100 - n bytes as they are.
+ const uint32 rawlen = 0x100 - n;
+ file.read(ptr, rawlen);
+ readBytes += rawlen;
+ ptr += rawlen;
+ }
+ }
+ lines++;
+ }
+}
+
+void AnimationDecoder::loadDiffFrame(EncryptedFile &file, uint32) {
+ const uint16 firstLine = file.readUint16LE();
+ const uint16 numLines = file.readUint16LE();
+
+ for (uint16 line = firstLine; line < firstLine + numLines; ++line) {
+ uint8 *imageData = reinterpret_cast<uint8 *>(_surface.getBasePtr(0, firstLine));
+
+ uint8 runs = file.readByte();
+ while (runs--) {
+ uint8 localOffset = file.readByte();
+ uint8 num = file.readByte();
+
+ imageData += localOffset;
+ if (num == 0) {
+ // Ignore?
+ debug("Zero RLE number found.");
+ } else if (num < 0x80) {
+ file.read(imageData, num);
+ imageData += num;
+ } else {
+ const uint8 color = file.readByte();
+ const int no = 0x100 - num;
+ memset(imageData, color, no);
+ imageData += no;
+ }
+
+ }
+ }
+}
+
+AnimationDecoder::~AnimationDecoder() {
+ _surface.free();
+}
+
+}
diff --git a/engines/mutationofjb/animationdecoder.h b/engines/mutationofjb/animationdecoder.h
new file mode 100644
index 0000000..050aa3b
--- /dev/null
+++ b/engines/mutationofjb/animationdecoder.h
@@ -0,0 +1,69 @@
+/* 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_ANIMATIONDECODER_H
+#define MUTATIONOFJB_ANIMATIONDECODER_H
+
+#include "common/scummsys.h"
+#include "common/str.h"
+#include "graphics/surface.h"
+#include "mutationofjb/encryptedfile.h"
+
+namespace Common {
+class SeekableReadStream;
+}
+
+namespace MutationOfJB {
+
+enum {
+ PALETTE_COLORS = 256,
+ PALETTE_SIZE = PALETTE_COLORS * 3,
+ IMAGE_WIDTH = 320,
+ IMAGE_HEIGHT = 200
+};
+
+class AnimationDecoderCallback {
+public:
+ virtual void onFrame(int frameNo, Graphics::Surface &surface) = 0;
+ virtual void onPaletteUpdated(byte palette[PALETTE_SIZE]) = 0;
+ virtual ~AnimationDecoderCallback() {}
+};
+
+class AnimationDecoder {
+public:
+ AnimationDecoder(const Common::String &fileName);
+ ~AnimationDecoder();
+ bool decode(AnimationDecoderCallback *callback);
+
+private:
+ void loadPalette(Common::SeekableReadStream &stream);
+ void loadFullFrame(EncryptedFile &file, uint32 size);
+ void loadDiffFrame(EncryptedFile &file, uint32 size);
+
+ Common::String _fileName;
+ Graphics::Surface _surface;
+ byte _palette[PALETTE_SIZE];
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 917ab3c..b796698 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -18,6 +18,7 @@ MODULE_OBJS := \
commands/removeitemcommand.o \
commands/saycommand.o \
commands/seqcommand.o \
+ animationdecoder.o \
debug.o \
detection.o \
encryptedfile.o \
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
index 8d8fbdb..547cda4 100644
--- a/engines/mutationofjb/room.cpp
+++ b/engines/mutationofjb/room.cpp
@@ -21,6 +21,7 @@
*/
#include "mutationofjb/room.h"
+#include "mutationofjb/animationdecoder.h"
#include "mutationofjb/encryptedfile.h"
#include "mutationofjb/util.h"
#include "common/str.h"
@@ -29,114 +30,34 @@
namespace MutationOfJB {
-Room::Room(Graphics::Screen *screen) : _screen(screen) {}
-
-bool Room::load(uint8 roomNumber, bool roomB) {
- EncryptedFile file;
- Common::String fileName = Common::String::format("room%d%s.dat", roomNumber, roomB ? "b" : "");
-
- file.open(fileName);
-
- if (!file.isOpen()) {
- reportFileMissingError(fileName.c_str());
-
- return false;
- }
-
- file.seek(0x80);
-
- while (!file.eos()) {
- // Record.
- const uint32 length = file.readUint32LE();
- uint8 info[4] = {0};
- file.read(info, 4);
-
- // TODO Find out what these are.
- uint32 unknown;
- unknown = file.readUint32LE();
- unknown = file.readUint32LE();
-
- // Subrecords.
- if (info[0] == 0xFA && info[1] == 0xF1) {
- for (int i = 0; i < info[2]; ++i) {
- const uint32 subLength = file.readUint32LE();
- const uint16 type = file.readUint16LE();
-
- if (type == 0x0B) {
- loadPalette(file);
- } else if (type == 0x0F) {
- loadBackground(file, subLength - 6);
- } else {
- debug(_("Unsupported record type %02X."), type);
- file.seek(subLength - 6, SEEK_CUR);
- }
- }
- }
- }
-
- file.close();
-
- return true;
+class RoomAnimationDecoderCallback : public AnimationDecoderCallback {
+public:
+ RoomAnimationDecoderCallback(Room &room) : _room(room) {}
+ virtual void onFrame(int frameNo, Graphics::Surface &surface) override;
+ virtual void onPaletteUpdated(byte palette[PALETTE_SIZE]) override;
+private:
+ Room &_room;
+};
+
+void RoomAnimationDecoderCallback::onPaletteUpdated(byte palette[PALETTE_SIZE]) {
+ _room._screen->setPalette(palette, 0x00, 0xC0); // Load only 0xC0 colors.
}
-void Room::loadPalette(EncryptedFile &file) {
- uint32 unknown;
-
- // TODO Find out what this is.
- unknown = file.readUint32LE();
-
- uint8 palette[PALETTE_SIZE];
- file.read(palette, PALETTE_SIZE);
-
- for (int j = 0; j < PALETTE_SIZE; ++j) {
- palette[j] <<= 2; // Uses 6-bit colors.
+void RoomAnimationDecoderCallback::onFrame(int frameNo, Graphics::Surface &surface) {
+ if (frameNo != 0) {
+ return;
}
- _screen->setPalette(palette, 0x00, 0xC0); // Load only 0xC0 colors.
+ _room._screen->blitFrom(surface);
}
-void Room::loadBackground(EncryptedFile &file, uint32 size) {
- _screen->clear();
-
- uint8 *const pixels = static_cast<uint8 *>(_screen->getPixels());
- uint8 *ptr = pixels;
- uint32 readBytes = 0;
- uint32 lines = 0;
-
- while (readBytes != size) {
- if (lines == 200) {
- // Some background files have an unknown byte at the end,
- // so break when we encounter all 200 lines.
- break;
- }
-
- uint8 no = file.readByte();
- readBytes++;
- while (no--) {
- uint8 n = file.readByte();
- readBytes++;
- if (n < 0x80) {
- // RLE - Copy color n times.
- uint8 color = file.readByte();
- readBytes++;
- while(n--) {
- *ptr++ = color;
- }
- } else {
- // Take next 0x100 - n bytes as they are.
- const uint32 rawlen = 0x100 - n;
- file.read(ptr, rawlen);
- readBytes += rawlen;
- ptr += rawlen;
- }
- }
- lines++;
- }
- if (readBytes < size) {
- file.seek(size - readBytes, SEEK_CUR);
- }
+Room::Room(Graphics::Screen *screen) : _screen(screen) {}
- _screen->update();
+bool Room::load(uint8 roomNumber, bool roomB) {
+ const Common::String fileName = Common::String::format("room%d%s.dat", roomNumber, roomB ? "b" : "");
+ AnimationDecoder decoder(fileName);
+ RoomAnimationDecoderCallback callback(*this);
+ return decoder.decode(&callback);
}
}
diff --git a/engines/mutationofjb/room.h b/engines/mutationofjb/room.h
index 7158580..e8f4440 100644
--- a/engines/mutationofjb/room.h
+++ b/engines/mutationofjb/room.h
@@ -35,12 +35,11 @@ class EncryptedFile;
class Room {
public:
+ friend class RoomAnimationDecoderCallback;
+
Room(Graphics::Screen *screen);
bool load(uint8 roomNumber, bool roomB);
private:
- void loadPalette(EncryptedFile &file);
- void loadBackground(EncryptedFile &file, uint32 size);
-
Graphics::Screen *_screen;
};
Commit: 99d9055e201b0518baad741f4f46cb86c2f7e172
https://github.com/scummvm/scummvm/commit/99d9055e201b0518baad741f4f46cb86c2f7e172
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Load object frames and implement special handling for map scenes.
Changed paths:
engines/mutationofjb/animationdecoder.cpp
engines/mutationofjb/debug.cpp
engines/mutationofjb/debug.h
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/gamedata.cpp
engines/mutationofjb/gamedata.h
engines/mutationofjb/mutationofjb.cpp
engines/mutationofjb/mutationofjb.h
engines/mutationofjb/room.cpp
engines/mutationofjb/room.h
diff --git a/engines/mutationofjb/animationdecoder.cpp b/engines/mutationofjb/animationdecoder.cpp
index 585ad91..5b20153 100644
--- a/engines/mutationofjb/animationdecoder.cpp
+++ b/engines/mutationofjb/animationdecoder.cpp
@@ -159,7 +159,7 @@ void AnimationDecoder::loadDiffFrame(EncryptedFile &file, uint32) {
const uint16 numLines = file.readUint16LE();
for (uint16 line = firstLine; line < firstLine + numLines; ++line) {
- uint8 *imageData = reinterpret_cast<uint8 *>(_surface.getBasePtr(0, firstLine));
+ uint8 *imageData = reinterpret_cast<uint8 *>(_surface.getBasePtr(0, line));
uint8 runs = file.readByte();
while (runs--) {
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index f533a94..4ce2418 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -65,6 +65,7 @@ Console::Console(MutationOfJBEngine *vm) : _vm(vm) {
registerCmd("showstartup", WRAP_METHOD(Console, cmd_showstartup));
registerCmd("changescene", WRAP_METHOD(Console, cmd_changescene));
registerCmd("dumpsceneinfo", WRAP_METHOD(Console, cmd_dumpsceneinfo));
+ registerCmd("dumpdoorinfo", WRAP_METHOD(Console, cmd_dumpdoorinfo));
registerCmd("dumpobjectinfo", WRAP_METHOD(Console, cmd_dumpobjectinfo));
registerCmd("dumpstaticinfo", WRAP_METHOD(Console, cmd_dumpstaticinfo));
}
@@ -324,6 +325,38 @@ bool Console::cmd_dumpsceneinfo(int argc, const char **argv) {
return true;
}
+bool Console::cmd_dumpdoorinfo(int argc, const char **argv) {
+ if (argc == 3) {
+ const uint8 sceneId = atoi(argv[1]);
+ const uint8 doorId = atoi(argv[2]);
+
+ Scene *const scene = _vm->getGame().getGameData().getScene(sceneId);
+ if (scene) {
+ Door *const door = scene->getDoor(doorId);
+ if (door) {
+ debugPrintf("Name: '%s'\n", convertToASCII(door->_name).c_str());
+ debugPrintf("DestSceneId: %u\n", (unsigned int) door->_destSceneId);
+ debugPrintf("DestX: %u\n", (unsigned int) door->_destX);
+ debugPrintf("DestY: %u\n", (unsigned int) door->_destY);
+ debugPrintf("X: %u\n", (unsigned int) door->_x);
+ debugPrintf("Y: %u\n", (unsigned int) door->_y);
+ debugPrintf("Width: %u\n", (unsigned int) door->_width);
+ debugPrintf("Height: %u\n", (unsigned int) door->_height);
+ debugPrintf("WalkToX: %u\n", (unsigned int) door->_walkToX);
+ debugPrintf("WalkToY: %u\n", (unsigned int) door->_walkToY);
+ debugPrintf("SP: %u\n", (unsigned int) door->_SP);
+ } else {
+ debugPrintf(_("Door %u not found.\n"), (unsigned int) doorId);
+ }
+ } else {
+ debugPrintf(_("Scene %u not found.\n"), (unsigned int) sceneId);
+ }
+ } else {
+ debugPrintf(_("dumpdoorinfo <sceneid> <doorid>\n"));
+ }
+
+ return true;
+}
bool Console::cmd_dumpobjectinfo(int argc, const char **argv) {
if (argc == 3) {
const uint8 sceneId = atoi(argv[1]);
diff --git a/engines/mutationofjb/debug.h b/engines/mutationofjb/debug.h
index e57b787..0cd7257 100644
--- a/engines/mutationofjb/debug.h
+++ b/engines/mutationofjb/debug.h
@@ -45,6 +45,7 @@ private:
bool cmd_showstartup(int argc, const char **argv);
bool cmd_changescene(int argc, const char **argv);
bool cmd_dumpsceneinfo(int argc, const char **argv);
+ bool cmd_dumpdoorinfo(int argc, const char **argv);
bool cmd_dumpobjectinfo(int argc, const char **argv);
bool cmd_dumpstaticinfo(int argc, const char **argv);
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 156c020..a46ca63 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -46,7 +46,7 @@ Game::Game(MutationOfJBEngine *vm)
globalScriptFile.close();
_localScript = nullptr;
- _room = new Room(_vm->getScreen());
+ _room = new Room(this, _vm->getScreen());
changeScene(13, false); // Initial scene.
}
@@ -55,6 +55,10 @@ GameData &Game::getGameData() {
return *_gameData;
}
+Room &Game::getRoom() {
+ return *_room;
+}
+
Script *Game::getGlobalScript() const {
return _globalScript;
}
@@ -122,36 +126,6 @@ Script *Game::changeSceneDelayScript(uint8 sceneId, bool partB) {
return _delayedLocalScript;
}
-Door *Game::findDoor(int16 x, int16 y) {
- Scene *scene = _gameData->getCurrentScene();
- if (!scene)
- return nullptr;
-
- for (int i = 0; i < MIN(ARRAYSIZE(scene->_doors), (int) scene->_noDoors); ++i) {
- Door &door = scene->_doors[i];
- if ((x >= door._x) && (x < door._x + door._width) && (y >= door._y) && (y < door._y + door._height)) {
- return &door;
- }
- }
-
- return nullptr;
-}
-
-Static *Game::findStatic(int16 x, int16 y) {
- Scene *scene = _gameData->getCurrentScene();
- if (!scene)
- return nullptr;
-
- for (int i = 0; i < MIN(ARRAYSIZE(scene->_statics), (int) scene->_noStatics); ++i) {
- Static &stat = scene->_statics[i];
- if ((x >= stat._x) && (x < stat._x + stat._width) && (y >= stat._y) && (y < stat._y + stat._height)) {
- return &stat;
- }
- }
-
- return nullptr;
-}
-
static Command *findActionInfoCommand(const ActionInfos &infos, const Common::String &entity1Name, const Common::String &entity2Name = Common::String()) {
for (ActionInfos::const_iterator it = infos.begin(); it != infos.end(); ++it) {
if (it->_entity1Name == entity1Name && it->_entity2Name == entity2Name) {
@@ -180,6 +154,10 @@ bool Game::startActionSection(ActionInfo::Action action, const Common::String &e
return false;
}
+bool Game::isCurrentSceneMap() const {
+ return _gameData->_currentScene == 12;
+}
+
void Game::update() {
Command::ExecuteResult res = _scriptExecCtx.runActiveCommand();
if (res == Command::Finished && _delayedLocalScript) {
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index 503cde9..c71b5f1 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -39,22 +39,23 @@ class Script;
class Room;
class Door;
class Static;
+class Bitmap;
class Game {
public:
Game(MutationOfJBEngine *vm);
GameData &getGameData();
-
+ Room &getRoom();
Script *getGlobalScript() const;
Script *getLocalScript() const;
void changeScene(uint8 sceneId, bool partB);
Script *changeSceneDelayScript(uint8 sceneId, bool partB);
- Door *findDoor(int16 x, int16 y);
- Static *findStatic(int16 x, int16 y);
bool startActionSection(ActionInfo::Action action, const Common::String &entity1Name, const Common::String &entity2Name = Common::String());
+ bool isCurrentSceneMap() const;
+
void update();
private:
diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp
index acca555..fb9e642 100644
--- a/engines/mutationofjb/gamedata.cpp
+++ b/engines/mutationofjb/gamedata.cpp
@@ -151,7 +151,7 @@ Door *Scene::getDoor(uint8 doorId) {
}
Object *Scene::getObject(uint8 objectId, bool ignoreNo) {
- if (objectId == 0 || objectId > (!ignoreNo ? MIN(_noObjects, (uint8) ARRAYSIZE(_objects)) : ARRAYSIZE(_objects))) {
+ if (objectId == 0 || objectId > getNoObjects(ignoreNo)) {
warning(_("Object %d does not exist"), objectId);
return nullptr;
}
@@ -168,6 +168,60 @@ Static *Scene::getStatic(uint8 staticId, bool ignoreNo) {
return &_statics[staticId - 1];
}
+uint8 Scene::getNoDoors(bool ignoreNo) const {
+ return (!ignoreNo ? MIN(_noDoors, (uint8) ARRAYSIZE(_doors)) : ARRAYSIZE(_doors));
+}
+
+uint8 Scene::getNoObjects(bool ignoreNo) const {
+ return (!ignoreNo ? MIN(_noObjects, (uint8) ARRAYSIZE(_objects)) : ARRAYSIZE(_objects));
+}
+
+uint8 Scene::getNoStatics(bool ignoreNo) const {
+ return (!ignoreNo ? MIN(_noStatics, (uint8) ARRAYSIZE(_statics)) : ARRAYSIZE(_statics));
+}
+
+Door *Scene::findDoor(int16 x, int16 y, int *index) {
+ for (int i = 0; i < getNoDoors(); ++i) {
+ Door &door = _doors[i];
+ if ((x >= door._x) && (x < door._x + door._width) && (y >= door._y) && (y < door._y + door._height)) {
+ if (index) {
+ *index = i + 1;
+ }
+ return &door;
+ }
+ }
+
+ return nullptr;
+}
+
+Static *Scene::findStatic(int16 x, int16 y, int *index) {
+ for (int i = 0; i < getNoStatics(); ++i) {
+ Static &stat = _statics[i];
+ if ((x >= stat._x) && (x < stat._x + stat._width) && (y >= stat._y) && (y < stat._y + stat._height)) {
+ if (index) {
+ *index = i + 1;
+ }
+ return &stat;
+ }
+ }
+
+ return nullptr;
+}
+
+Bitmap *Scene::findBitmap(int16 x, int16 y, int *index) {
+ for (int i = 0; i < ARRAYSIZE(_bitmaps); ++i) {
+ Bitmap &bitmap = _bitmaps[i];
+ if ((x >= bitmap._x1) && (x <= bitmap._x2) && (y >= bitmap._y1) && (y <= bitmap._y2)) {
+ if (index) {
+ *index = i + 1;
+ }
+ return &bitmap;
+ }
+ }
+
+ return nullptr;
+}
+
GameData::GameData()
: _currentScene(0),
diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h
index 4735753..b0c64c5 100644
--- a/engines/mutationofjb/gamedata.h
+++ b/engines/mutationofjb/gamedata.h
@@ -121,11 +121,18 @@ struct Bitmap {
struct Scene {
-
Door *getDoor(uint8 objectId);
Object *getObject(uint8 objectId, bool ignoreNo = false);
Static *getStatic(uint8 staticId, bool ignoreNo = false);
+ uint8 getNoDoors(bool ignoreNo = false) const;
+ uint8 getNoObjects(bool ignoreNo = false) const;
+ uint8 getNoStatics(bool ignoreNo = false) const;
+
+ Door *findDoor(int16 x, int16 y, int *index = nullptr);
+ Static *findStatic(int16 x, int16 y, int *index = nullptr);
+ Bitmap *findBitmap(int16 x, int16 y, int *index = nullptr);
+
uint8 _startup;
uint8 _unknown001;
uint8 _unknown002;
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index 622be67..df8ad11 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -35,13 +35,16 @@
#include "mutationofjb/game.h"
#include "mutationofjb/gamedata.h"
#include "mutationofjb/debug.h"
+#include "mutationofjb/room.h"
namespace MutationOfJB {
MutationOfJBEngine::MutationOfJBEngine(OSystem *syst)
: Engine(syst),
_console(nullptr),
- _screen(nullptr) {
+ _screen(nullptr),
+ _currentAction(ActionInfo::Walk),
+ _mapObjectId(0) {
debug("MutationOfJBEngine::MutationOfJBEngine");
}
@@ -69,6 +72,94 @@ Game &MutationOfJBEngine::getGame() {
return *_game;
}
+void MutationOfJBEngine::handleNormalScene(const Common::Event &event) {
+ Scene *const scene = _game->getGameData().getCurrentScene();
+
+ switch (event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ {
+ const int16 x = event.mouse.x;
+ const int16 y = event.mouse.y;
+
+ if (Door *const door = scene->findDoor(x, y)) {
+ if (!_game->startActionSection(_currentAction, door->_name) && _currentAction == ActionInfo::Walk && door->_destSceneId != 0) {
+ _game->changeScene(door->_destSceneId, _game->getGameData()._partB);
+ }
+ } else if (Static *const stat = scene->findStatic(x, y)) {
+ if (stat->_active == 1) {
+ _game->startActionSection(_currentAction, stat->_name);
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/*
+ Special handling for map scenes.
+
+ Bitmaps define mouse clickable areas.
+ Statics are used to start actions.
+ Objects are used for showing labels.
+
+*/
+void MutationOfJBEngine::handleMapScene(const Common::Event &event) {
+ Scene *const scene = _game->getGameData().getCurrentScene();
+
+ switch (event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ {
+ const int16 x = event.mouse.x;
+ const int16 y = event.mouse.y;
+
+ int index = 0;
+ if (Bitmap *const bitmap = scene->findBitmap(x, y, &index)) {
+ Static *const stat = scene->getStatic(index);
+ if (stat && stat->_active == 1) {
+ _game->startActionSection(ActionInfo::Walk, stat->_name);
+ }
+ }
+ break;
+ }
+ case Common::EVENT_MOUSEMOVE:
+ {
+ const int16 x = event.mouse.x;
+ const int16 y = event.mouse.y;
+
+ int index = 0;
+ bool found = false;
+ if (Bitmap *const bitmap = scene->findBitmap(x, y, &index)) {
+ Static *const stat = scene->getStatic(index);
+ if (stat && stat->_active == 1) {
+ Object *const object = scene->getObject(index);
+ if (object) {
+ found = true;
+ if (index != _mapObjectId) {
+ if (_mapObjectId) {
+ _game->getRoom().drawObjectAnimation(_mapObjectId, 1);
+ _mapObjectId = 0;
+ }
+
+ _mapObjectId = index;
+ _game->getRoom().drawObjectAnimation(_mapObjectId, 0);
+ }
+ }
+ }
+ }
+
+ if (!found && _mapObjectId != 0) {
+ _game->getRoom().drawObjectAnimation(_mapObjectId, 1);
+ _mapObjectId = 0;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
Common::Error MutationOfJBEngine::run() {
debug("MutationOfJBEngine::run");
@@ -77,11 +168,10 @@ Common::Error MutationOfJBEngine::run() {
_console = new Console(this);
_screen = new Graphics::Screen();
_game = new Game(this);
- ActionInfo::Action currentAction = ActionInfo::Walk;
setupCursor();
- while(!shouldQuit()) {
+ while (!shouldQuit()) {
Common::Event event;
while (_eventMan->pollEvent(event)) {
switch (event.type) {
@@ -93,45 +183,40 @@ Common::Error MutationOfJBEngine::run() {
}
break;
}
- case Common::EVENT_LBUTTONDOWN:
- {
- if (Door *const door = _game->findDoor(event.mouse.x, event.mouse.y)) {
- if (!_game->startActionSection(currentAction, door->_name) && currentAction == ActionInfo::Walk && door->_destSceneId != 0) {
- _game->changeScene(door->_destSceneId, _game->getGameData()._partB);
- }
- } else if (Static *const stat = _game->findStatic(event.mouse.x, event.mouse.y)) {
- _game->startActionSection(currentAction, stat->_name);
- }
- break;
- }
case Common::EVENT_KEYUP:
{
switch (event.kbd.ascii) {
case 'g':
- currentAction = ActionInfo::Walk;
+ _currentAction = ActionInfo::Walk;
break;
case 'r':
- currentAction = ActionInfo::Talk;
+ _currentAction = ActionInfo::Talk;
break;
case 's':
- currentAction = ActionInfo::Look;
+ _currentAction = ActionInfo::Look;
break;
case 'b':
- currentAction = ActionInfo::Use;
+ _currentAction = ActionInfo::Use;
break;
case 'n':
- currentAction = ActionInfo::PickUp;
+ _currentAction = ActionInfo::PickUp;
break;
}
}
default:
break;
}
+
+ if (!_game->isCurrentSceneMap()) {
+ handleNormalScene(event);
+ } else {
+ handleMapScene(event);
+ }
}
_console->onFrame();
_game->update();
- _system->delayMillis(40);
+ _system->delayMillis(10);
_screen->update();
}
diff --git a/engines/mutationofjb/mutationofjb.h b/engines/mutationofjb/mutationofjb.h
index 893cca9..ef0c973 100644
--- a/engines/mutationofjb/mutationofjb.h
+++ b/engines/mutationofjb/mutationofjb.h
@@ -24,9 +24,14 @@
#define MUTATIONOFJB_MUTATIONOFJB_H
#include "engines/engine.h"
+#include "mutationofjb/script.h"
+
+namespace Common {
+class Event;
+}
namespace Graphics {
- class Screen;
+class Screen;
}
namespace MutationOfJB {
@@ -46,10 +51,14 @@ public:
private:
bool loadGameData(bool partB);
void setupCursor();
+ void handleNormalScene(const Common::Event &event);
+ void handleMapScene(const Common::Event &event);
Console *_console;
Graphics::Screen *_screen;
Game *_game;
+ ActionInfo::Action _currentAction;
+ uint8 _mapObjectId;
};
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
index 547cda4..66da3ac 100644
--- a/engines/mutationofjb/room.cpp
+++ b/engines/mutationofjb/room.cpp
@@ -23,6 +23,8 @@
#include "mutationofjb/room.h"
#include "mutationofjb/animationdecoder.h"
#include "mutationofjb/encryptedfile.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
#include "mutationofjb/util.h"
#include "common/str.h"
#include "common/translation.h"
@@ -44,20 +46,75 @@ void RoomAnimationDecoderCallback::onPaletteUpdated(byte palette[PALETTE_SIZE])
}
void RoomAnimationDecoderCallback::onFrame(int frameNo, Graphics::Surface &surface) {
- if (frameNo != 0) {
- return;
+ if (frameNo == 0) {
+ _room._screen->blitFrom(surface);
}
- _room._screen->blitFrom(surface);
+ const int frameNo1 = frameNo + 1;
+
+ Scene *scene = _room._game->getGameData().getCurrentScene();
+ if (scene) {
+ const uint8 noObjects = scene->getNoObjects();
+ for (int i = 0; i < noObjects; ++i) {
+ Object &object = scene->_objects[i];
+ const uint16 startFrame = (object._WY << 8) + object._FS;
+ if (frameNo1 >= startFrame && frameNo1 < startFrame + object._NA) {
+ const int x = object._x;
+ const int y = object._y;
+ const int w = object._XL / 4 * 4;
+ const int h = object._YL / 4 * 4;
+ Common::Rect rect(x, y, x + w, y + h);
+
+ const Graphics::Surface sharedSurface = surface.getSubArea(rect);
+ Graphics::Surface outSurface;
+ outSurface.copyFrom(sharedSurface);
+ _room._surfaces[_room._objectsStart[i] + frameNo1 - startFrame] = outSurface;
+ }
+ }
+ }
}
-Room::Room(Graphics::Screen *screen) : _screen(screen) {}
+Room::Room(Game *game, Graphics::Screen *screen) : _game(game), _screen(screen) {}
bool Room::load(uint8 roomNumber, bool roomB) {
+ _objectsStart.clear();
+
+ Scene *const scene = _game->getGameData().getCurrentScene();
+ if (scene) {
+ const uint8 noObjects = scene->getNoObjects();
+ for (int i = 0; i < noObjects; ++i) {
+ uint8 firstIndex = 0;
+ if (i != 0) {
+ firstIndex = _objectsStart[i - 1] + scene->_objects[i - 1]._NA;
+ }
+ _objectsStart.push_back(firstIndex);
+
+ uint8 numAnims = scene->_objects[i]._NA;
+ while (numAnims--) {
+ _surfaces.push_back(Graphics::Surface());
+ }
+ }
+ }
+
const Common::String fileName = Common::String::format("room%d%s.dat", roomNumber, roomB ? "b" : "");
AnimationDecoder decoder(fileName);
RoomAnimationDecoderCallback callback(*this);
return decoder.decode(&callback);
}
+void Room::drawObjectAnimation(uint8 objectId, int animOffset) {
+ Scene *const scene = _game->getGameData().getCurrentScene();
+ if (!scene) {
+ return;
+ }
+ Object *const object = scene->getObject(objectId);
+ if (!object) {
+ return;
+ }
+
+ const int startFrame = _objectsStart[objectId - 1];
+ const int animFrame = startFrame + animOffset;
+ _screen->blitFrom(_surfaces[animFrame], Common::Point(object->_x, object->_y));
+}
+
}
diff --git a/engines/mutationofjb/room.h b/engines/mutationofjb/room.h
index e8f4440..a2be2fc 100644
--- a/engines/mutationofjb/room.h
+++ b/engines/mutationofjb/room.h
@@ -24,23 +24,30 @@
#define MUTATIONOFJB_ROOM_H
#include "common/scummsys.h"
+#include "common/array.h"
+#include "graphics/surface.h"
namespace Graphics {
- class Screen;
+class Screen;
}
namespace MutationOfJB {
class EncryptedFile;
+class Game;
class Room {
public:
friend class RoomAnimationDecoderCallback;
- Room(Graphics::Screen *screen);
+ Room(Game *game, Graphics::Screen *screen);
bool load(uint8 roomNumber, bool roomB);
+ void drawObjectAnimation(uint8 objectId, int animOffset);
private:
+ Game *_game;
Graphics::Screen *_screen;
+ Common::Array<Graphics::Surface> _surfaces;
+ Common::Array<int> _objectsStart;
};
}
Commit: 9a3a66ab685c33dab1a85cf2aae73d1df7e45c29
https://github.com/scummvm/scummvm/commit/9a3a66ab685c33dab1a85cf2aae73d1df7e45c29
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Fix object animatation loader.
Changed paths:
engines/mutationofjb/room.cpp
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
index 66da3ac..5ed6ca3 100644
--- a/engines/mutationofjb/room.cpp
+++ b/engines/mutationofjb/room.cpp
@@ -61,8 +61,8 @@ void RoomAnimationDecoderCallback::onFrame(int frameNo, Graphics::Surface &surfa
if (frameNo1 >= startFrame && frameNo1 < startFrame + object._NA) {
const int x = object._x;
const int y = object._y;
- const int w = object._XL / 4 * 4;
- const int h = object._YL / 4 * 4;
+ const int w = (object._XL + 3) / 4 * 4; // Original code uses this to round up width to a multiple of 4.
+ const int h = object._YL;
Common::Rect rect(x, y, x + w, y + h);
const Graphics::Surface sharedSurface = surface.getSubArea(rect);
Commit: 9af3d8a2381fe7c7440330a9aa338f51cd734990
https://github.com/scummvm/scummvm/commit/9af3d8a2381fe7c7440330a9aa338f51cd734990
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Implement UI for inventory.
Changed paths:
A engines/mutationofjb/gui.cpp
A engines/mutationofjb/gui.h
engines/mutationofjb/commands/seqcommand.h
engines/mutationofjb/debug.cpp
engines/mutationofjb/debug.h
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/gamedata.cpp
engines/mutationofjb/gamedata.h
engines/mutationofjb/inventory.cpp
engines/mutationofjb/inventory.h
engines/mutationofjb/module.mk
engines/mutationofjb/room.cpp
diff --git a/engines/mutationofjb/commands/seqcommand.h b/engines/mutationofjb/commands/seqcommand.h
index 241932a..04731c2 100644
--- a/engines/mutationofjb/commands/seqcommand.h
+++ b/engines/mutationofjb/commands/seqcommand.h
@@ -35,6 +35,7 @@ public:
class SeqCommand : public Command {
public:
+ SeqCommand() : _nextCommand(nullptr) {}
void setNextCommand(Command *nextCommand);
virtual Command *next() const override;
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index 4ce2418..171eca5 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -23,6 +23,7 @@
#include "mutationofjb/debug.h"
#include "mutationofjb/game.h"
#include "mutationofjb/gamedata.h"
+#include "mutationofjb/inventory.h"
#include "mutationofjb/mutationofjb.h"
#include "mutationofjb/script.h"
#include "mutationofjb/commands/command.h"
@@ -68,6 +69,7 @@ Console::Console(MutationOfJBEngine *vm) : _vm(vm) {
registerCmd("dumpdoorinfo", WRAP_METHOD(Console, cmd_dumpdoorinfo));
registerCmd("dumpobjectinfo", WRAP_METHOD(Console, cmd_dumpobjectinfo));
registerCmd("dumpstaticinfo", WRAP_METHOD(Console, cmd_dumpstaticinfo));
+ registerCmd("listinventory", WRAP_METHOD(Console, cmd_listinventory));
}
bool Console::cmd_showallcommands(int argc, const char **argv) {
@@ -438,4 +440,13 @@ Script *Console::getScriptFromArg(const char *arg) {
return script;
}
+bool Console::cmd_listinventory(int, const char **) {
+ Inventory &inventory =_vm->getGame().getGameData().getInventory();
+ const Inventory::Items &items = inventory.getItems();
+ for (Inventory::Items::const_iterator it = items.begin(); it != items.end(); ++it) {
+ debugPrintf("%s\n", convertToASCII(*it).c_str());
+ }
+ return true;
+}
+
}
diff --git a/engines/mutationofjb/debug.h b/engines/mutationofjb/debug.h
index 0cd7257..24b1e95 100644
--- a/engines/mutationofjb/debug.h
+++ b/engines/mutationofjb/debug.h
@@ -48,6 +48,7 @@ private:
bool cmd_dumpdoorinfo(int argc, const char **argv);
bool cmd_dumpobjectinfo(int argc, const char **argv);
bool cmd_dumpstaticinfo(int argc, const char **argv);
+ bool cmd_listinventory(int argc, const char **argv);
void showIndent(int indentLevel);
void showCommands(Command *command, int indentLevel = 0);
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index a46ca63..b7f1893 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -35,7 +35,7 @@
namespace MutationOfJB {
Game::Game(MutationOfJBEngine *vm)
-: _vm(vm), _delayedLocalScript(nullptr), _scriptExecCtx(*this) {
+: _vm(vm), _delayedLocalScript(nullptr), _gui(*this, _vm->getScreen()), _scriptExecCtx(*this) {
_gameData = new GameData;
loadGameData(false);
@@ -48,6 +48,8 @@ Game::Game(MutationOfJBEngine *vm)
_localScript = nullptr;
_room = new Room(this, _vm->getScreen());
+ _gui.init();
+
changeScene(13, false); // Initial scene.
}
@@ -84,6 +86,10 @@ bool Game::loadGameData(bool partB) {
}
Script *Game::changeSceneLoadScript(uint8 sceneId, bool partB) {
+ if (isCurrentSceneMap()) {
+ _gui.markInventoryDirty();
+ }
+
_gameData->_lastScene = _gameData->_currentScene;
_gameData->_currentScene = sceneId;
_gameData->_partB = partB;
@@ -165,6 +171,12 @@ void Game::update() {
_localScript = _delayedLocalScript;
_delayedLocalScript = nullptr;
}
+
+ _gui.update();
+}
+
+Gui &Game::getGui() {
+ return _gui;
}
}
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index c71b5f1..71dadf2 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "mutationofjb/script.h"
+#include "mutationofjb/gui.h"
namespace Common {
class String;
@@ -58,6 +59,8 @@ public:
void update();
+ Gui &getGui();
+
private:
bool loadGameData(bool partB);
void runActiveCommand();
@@ -71,6 +74,7 @@ private:
Script *_localScript;
Script *_delayedLocalScript;
Room *_room;
+ Gui _gui;
ScriptExecutionContext _scriptExecCtx;
};
diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp
index fb9e642..099cea7 100644
--- a/engines/mutationofjb/gamedata.cpp
+++ b/engines/mutationofjb/gamedata.cpp
@@ -226,7 +226,9 @@ Bitmap *Scene::findBitmap(int16 x, int16 y, int *index) {
GameData::GameData()
: _currentScene(0),
_lastScene(0),
- _partB(false) {}
+ _partB(false),
+ _inventory()
+ {}
Scene *GameData::getScene(uint8 sceneId) {
if (sceneId == 0 || sceneId > ARRAYSIZE(_scenes)) {
@@ -241,6 +243,10 @@ Scene *GameData::getCurrentScene() {
return getScene(_currentScene);
}
+Inventory &GameData::getInventory() {
+ return _inventory;
+}
+
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 b0c64c5..64de01e 100644
--- a/engines/mutationofjb/gamedata.h
+++ b/engines/mutationofjb/gamedata.h
@@ -164,6 +164,7 @@ public:
GameData();
Scene *getScene(uint8 sceneId);
Scene *getCurrentScene();
+ Inventory &getInventory();
bool loadFromStream(Common::ReadStream &stream);
@@ -174,7 +175,6 @@ public:
Common::String _currentAPK;
private:
Scene _scenes[45];
-
};
}
diff --git a/engines/mutationofjb/gui.cpp b/engines/mutationofjb/gui.cpp
new file mode 100644
index 0000000..5ceed67
--- /dev/null
+++ b/engines/mutationofjb/gui.cpp
@@ -0,0 +1,181 @@
+/* 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/gui.h"
+#include "mutationofjb/animationdecoder.h"
+#include "mutationofjb/encryptedfile.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
+#include "mutationofjb/inventory.h"
+#include "mutationofjb/util.h"
+#include "common/rect.h"
+#include "graphics/screen.h"
+
+namespace MutationOfJB {
+
+enum ButtonType {
+ BUTTON_WALK,
+ BUTTON_TALK,
+ BUTTON_LOOK,
+ BUTTON_USE,
+ BUTTON_PICKUP,
+ BUTTON_SCROLL_LEFT,
+ BUTTON_SCROLL_RIGHT,
+ BUTTON_SETTINGS
+};
+
+enum {
+ INVENTORY_START_X = 88,
+ INVENTORY_START_Y = 149,
+ INVENTORY_ITEM_WIDTH = 34,
+ INVENTORY_ITEM_HEIGHT = 33,
+ INVENTORY_ITEMS_PER_LINE = 8,
+ INVENTORY_ITEMS_LINES = 5
+};
+
+static Common::Rect ButtonRects[] = {
+ Common::Rect(0, 148, 67, 158), // Walk
+ Common::Rect(0, 158, 67, 168), // Talk
+ Common::Rect(0, 168, 67, 178), // Look
+ Common::Rect(0, 178, 67, 188), // Use
+ Common::Rect(0, 188, 67, 198), // PickUp
+ Common::Rect(67, 149, 88, 174), // ScrollLeft
+ Common::Rect(67, 174, 88, 199), // ScrollRight
+ Common::Rect(301, 148, 320, 200) // Settings
+};
+
+Gui::Gui(Game &game, Graphics::Screen *screen)
+ : _game(game),
+ _screen(screen),
+ _inventoryDirty(false) {
+}
+
+bool Gui::init() {
+ const bool result1 = loadInventoryList();
+ const bool result2 = loadInventoryGfx();
+
+ _game.getGameData().getInventory().setObserver(this);
+
+ return result1 && result2;
+}
+
+void Gui::markInventoryDirty() {
+ _inventoryDirty = true;
+}
+
+void Gui::update() {
+ if (_inventoryDirty) {
+ drawInventory();
+ _inventoryDirty = false;
+ }
+}
+
+class InventoryAnimationDecoderCallback : public AnimationDecoderCallback {
+public:
+ InventoryAnimationDecoderCallback(Gui &gui) : _gui(gui) {}
+ virtual void onFrame(int frameNo, Graphics::Surface &surface) override;
+ virtual void onPaletteUpdated(byte palette[PALETTE_SIZE]) override;
+private:
+ Gui &_gui;
+};
+
+void InventoryAnimationDecoderCallback::onPaletteUpdated(byte palette[PALETTE_SIZE]) {
+ _gui._screen->setPalette(palette + 0xC0 * 3, 0xC0, 0x20); // Load only 0x20 colors.
+}
+
+void InventoryAnimationDecoderCallback::onFrame(int frameNo, Graphics::Surface &surface) {
+ if (frameNo < 3) {
+ Graphics::Surface outSurface;
+ outSurface.copyFrom(surface);
+ _gui._inventorySurfaces.push_back(outSurface);
+ }
+}
+
+bool Gui::loadInventoryGfx() {
+ AnimationDecoder decoder("icons.dat");
+ InventoryAnimationDecoderCallback callback(*this);
+ return decoder.decode(&callback);
+}
+
+bool Gui::loadInventoryList() {
+ EncryptedFile file;
+ const char *fileName = "fixitems.dat";
+ file.open(fileName);
+ if (!file.isOpen()) {
+ reportFileMissingError(fileName);
+ return false;
+ }
+
+ int itemIndex = 0;
+ while (!file.eos()) {
+ Common::String line = file.readLine();
+ if (line.empty() || line.hasPrefix("#")) {
+ continue;
+ }
+ const char *firstSpace = strchr(line.c_str(), ' ');
+ if (!firstSpace) {
+ continue;
+ }
+ const int len = firstSpace - line.c_str();
+ if (!len) {
+ continue;
+ }
+ Common::String item(line.c_str(), len);
+ _inventoryItems[item] = itemIndex;
+ itemIndex++;
+ }
+
+ return true;
+}
+
+void Gui::drawInventoryItem(const Common::String &item, int pos) {
+ InventoryMap::iterator it = _inventoryItems.find(item);
+ if (it == _inventoryItems.end()) {
+ return;
+ }
+
+ const int index = it->_value;
+ const int surfaceNo = index / (INVENTORY_ITEMS_LINES * INVENTORY_ITEMS_PER_LINE);
+ const int indexInSurface = index % (INVENTORY_ITEMS_LINES * INVENTORY_ITEMS_PER_LINE);
+ const int itemX = indexInSurface % INVENTORY_ITEMS_PER_LINE;
+ const int itemY = indexInSurface / INVENTORY_ITEMS_PER_LINE;
+
+ Common::Point destStartPos(INVENTORY_START_X + pos * INVENTORY_ITEM_WIDTH, INVENTORY_START_Y);
+ Common::Rect sourceRect(itemX * INVENTORY_ITEM_WIDTH, itemY * INVENTORY_ITEM_HEIGHT, (itemX + 1) * INVENTORY_ITEM_WIDTH, (itemY + 1) * INVENTORY_ITEM_HEIGHT);
+ _screen->blitFrom(_inventorySurfaces[surfaceNo], sourceRect, destStartPos);
+}
+
+void Gui::drawInventory() {
+ Inventory &inventory = _game.getGameData().getInventory();
+ const Inventory::Items &items = inventory.getItems();
+ Common::Rect fullRect(INVENTORY_START_X, INVENTORY_START_Y, INVENTORY_START_X + Inventory::VISIBLE_ITEMS * INVENTORY_ITEM_WIDTH, INVENTORY_START_Y + INVENTORY_ITEM_HEIGHT);
+ _screen->fillRect(fullRect, 0x00);
+ for (int i = 0; i < MIN((int) items.size(), (int) Inventory::VISIBLE_ITEMS); ++i) {
+ drawInventoryItem(items[i], i);
+ }
+}
+
+void Gui::onInventoryChanged() {
+ markInventoryDirty();
+}
+
+}
diff --git a/engines/mutationofjb/gui.h b/engines/mutationofjb/gui.h
new file mode 100644
index 0000000..27e0b0c
--- /dev/null
+++ b/engines/mutationofjb/gui.h
@@ -0,0 +1,67 @@
+/* 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_GUI_H
+#define MUTATIONOFJB_GUI_H
+
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+#include "graphics/surface.h"
+#include "mutationofjb/inventory.h"
+
+namespace Graphics {
+class Screen;
+}
+
+namespace MutationOfJB {
+
+class Game;
+
+class Gui : public InventoryObserver {
+public:
+ friend class InventoryAnimationDecoderCallback;
+ Gui(Game &game, Graphics::Screen *screen);
+ bool init();
+ void update();
+
+ void markInventoryDirty();
+
+ virtual void onInventoryChanged() override;
+
+private:
+ bool loadInventoryGfx();
+ bool loadInventoryList();
+ void drawInventoryItem(const Common::String &item, int pos);
+ void drawInventory();
+
+ typedef Common::HashMap<Common::String, int> InventoryMap;
+
+ Game &_game;
+ Graphics::Screen *_screen;
+ InventoryMap _inventoryItems;
+ Common::Array<Graphics::Surface> _inventorySurfaces;
+ bool _inventoryDirty;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/inventory.cpp b/engines/mutationofjb/inventory.cpp
index 4a46548..b6561b2 100644
--- a/engines/mutationofjb/inventory.cpp
+++ b/engines/mutationofjb/inventory.cpp
@@ -21,13 +21,13 @@
*/
#include "mutationofjb/inventory.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/gui.h"
#include "common/algorithm.h"
#include "common/debug.h"
namespace MutationOfJB {
-static const uint VISIBLE_ITEMS = 6;
-
const Inventory::Items &Inventory::getItems() const {
return _items;
}
@@ -43,6 +43,9 @@ void Inventory::addItem(const Common::String &item) {
if (_items.size() > VISIBLE_ITEMS) {
rotateItemsRight(VISIBLE_ITEMS);
}
+ if (_observer) {
+ _observer->onInventoryChanged();
+ }
}
void Inventory::removeItem(const Common::String &item) {
@@ -53,10 +56,16 @@ void Inventory::removeItem(const Common::String &item) {
}
_items.remove_at(it - _items.begin());
+ if (_observer) {
+ _observer->onInventoryChanged();
+ }
}
void Inventory::removeAllItems() {
_items.clear();
+ if (_observer) {
+ _observer->onInventoryChanged();
+ }
}
void Inventory::rotateItemsRight(uint n) {
@@ -68,6 +77,9 @@ void Inventory::rotateItemsRight(uint n) {
reverseItems(0, _items.size() - 1);
reverseItems(0, n - 1);
reverseItems(n, _items.size() - 1);
+ if (_observer) {
+ _observer->onInventoryChanged();
+ }
}
void Inventory::rotateItemsLeft(uint n) {
@@ -79,6 +91,13 @@ void Inventory::rotateItemsLeft(uint n) {
reverseItems(0, _items.size() - 1);
reverseItems(_items.size() - n, _items.size() - 1);
reverseItems(0, _items.size() - n - 1);
+ if (_observer) {
+ _observer->onInventoryChanged();
+ }
+}
+
+void Inventory::setObserver(InventoryObserver *observer) {
+ _observer = observer;
}
void Inventory::reverseItems(uint from, uint to) {
diff --git a/engines/mutationofjb/inventory.h b/engines/mutationofjb/inventory.h
index fe7ca67..91c2932 100644
--- a/engines/mutationofjb/inventory.h
+++ b/engines/mutationofjb/inventory.h
@@ -29,8 +29,20 @@
namespace MutationOfJB {
+class Game;
+
+class InventoryObserver {
+public:
+ virtual void onInventoryChanged() = 0;
+ virtual ~InventoryObserver() {}
+};
+
class Inventory {
public:
+ enum {
+ VISIBLE_ITEMS = 6
+ };
+
typedef Common::Array<Common::String> Items;
const Items &getItems() const;
@@ -42,10 +54,13 @@ public:
void rotateItemsRight(uint n);
void rotateItemsLeft(uint n);
+ void setObserver(InventoryObserver *observer);
+
private:
void reverseItems(uint from, uint to);
Items _items;
+ InventoryObserver *_observer;
};
}
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index b796698..729ea44 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -24,6 +24,7 @@ MODULE_OBJS := \
encryptedfile.o \
game.o \
gamedata.o \
+ gui.o \
inventory.o \
mutationofjb.o \
room.o \
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
index 5ed6ca3..62af983 100644
--- a/engines/mutationofjb/room.cpp
+++ b/engines/mutationofjb/room.cpp
@@ -47,7 +47,11 @@ void RoomAnimationDecoderCallback::onPaletteUpdated(byte palette[PALETTE_SIZE])
void RoomAnimationDecoderCallback::onFrame(int frameNo, Graphics::Surface &surface) {
if (frameNo == 0) {
- _room._screen->blitFrom(surface);
+ Common::Rect rect(0, 0, 320, 139);
+ if (_room._game->isCurrentSceneMap()) {
+ rect = Common::Rect(0, 0, 320, 200);
+ }
+ _room._screen->blitFrom(surface, rect, Common::Point(0, 0));
}
const int frameNo1 = frameNo + 1;
Commit: c25ed8957228cfd580216383c3391ccc7e512bb5
https://github.com/scummvm/scummvm/commit/c25ed8957228cfd580216383c3391ccc7e512bb5
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Refactor inventory UI into separate widget, add button widgets.
Changed paths:
A engines/mutationofjb/widgets/buttonwidget.cpp
A engines/mutationofjb/widgets/buttonwidget.h
A engines/mutationofjb/widgets/inventorywidget.cpp
A engines/mutationofjb/widgets/inventorywidget.h
A engines/mutationofjb/widgets/widget.cpp
A engines/mutationofjb/widgets/widget.h
engines/mutationofjb/commands/endblockcommand.cpp
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/gui.cpp
engines/mutationofjb/gui.h
engines/mutationofjb/module.mk
engines/mutationofjb/mutationofjb.cpp
engines/mutationofjb/room.h
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index 492a424..cc6a455 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -31,6 +31,7 @@
("#L " | "-L ") <object>
("#W " | "-W ") <object>
("#T " | "-T ") <object>
+ ("#P " | "-P ") <object1>
("#U " | "-U ") <object1> [<object2>]
("#ELSE" | "-ELSE") [<tag>]
"#MACRO " <name>
@@ -73,6 +74,10 @@ bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext
ActionInfo ai = {ActionInfo::Talk, line.c_str() + 3, "", firstChar == '#', nullptr};
parseCtx._actionInfos.push_back(ai);
_pendingActionInfos.push_back(parseCtx._actionInfos.size() - 1);
+ } else if (line.size() >= 4 && (line.hasPrefix("#P ") || line.hasPrefix("-P "))) {
+ ActionInfo ai = {ActionInfo::PickUp, line.c_str() + 3, "", firstChar == '#', nullptr};
+ parseCtx._actionInfos.push_back(ai);
+ _pendingActionInfos.push_back(parseCtx._actionInfos.size() - 1);
} else if (line.size() >= 4 && (line.hasPrefix("#U ") || line.hasPrefix("-U "))) {
int secondObjPos = -1;
for (uint i = 3; i < line.size(); ++i) {
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index b7f1893..af0b76b 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -35,7 +35,12 @@
namespace MutationOfJB {
Game::Game(MutationOfJBEngine *vm)
-: _vm(vm), _delayedLocalScript(nullptr), _gui(*this, _vm->getScreen()), _scriptExecCtx(*this) {
+ : _vm(vm),
+ _delayedLocalScript(nullptr),
+ _gui(*this, _vm->getScreen()),
+ _scriptExecCtx(*this),
+ _currentAction(ActionInfo::Walk) {
+
_gameData = new GameData;
loadGameData(false);
@@ -87,7 +92,7 @@ bool Game::loadGameData(bool partB) {
Script *Game::changeSceneLoadScript(uint8 sceneId, bool partB) {
if (isCurrentSceneMap()) {
- _gui.markInventoryDirty();
+ _gui.markDirty();
}
_gameData->_lastScene = _gameData->_currentScene;
@@ -179,4 +184,12 @@ Gui &Game::getGui() {
return _gui;
}
+ActionInfo::Action Game::getCurrentAction() const {
+ return _currentAction;
+}
+
+void Game::setCurrentAction(ActionInfo::Action action) {
+ _currentAction = action;
+}
+
}
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index 71dadf2..19cf406 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -61,6 +61,9 @@ public:
Gui &getGui();
+ ActionInfo::Action getCurrentAction() const;
+ void setCurrentAction(ActionInfo::Action);
+
private:
bool loadGameData(bool partB);
void runActiveCommand();
@@ -75,6 +78,7 @@ private:
Script *_delayedLocalScript;
Room *_room;
Gui _gui;
+ ActionInfo::Action _currentAction;
ScriptExecutionContext _scriptExecCtx;
};
diff --git a/engines/mutationofjb/gui.cpp b/engines/mutationofjb/gui.cpp
index 5ceed67..76e9305 100644
--- a/engines/mutationofjb/gui.cpp
+++ b/engines/mutationofjb/gui.cpp
@@ -27,20 +27,23 @@
#include "mutationofjb/gamedata.h"
#include "mutationofjb/inventory.h"
#include "mutationofjb/util.h"
+#include "mutationofjb/widgets/widget.h"
+#include "mutationofjb/widgets/inventorywidget.h"
#include "common/rect.h"
#include "graphics/screen.h"
namespace MutationOfJB {
enum ButtonType {
- BUTTON_WALK,
+ BUTTON_WALK = 0,
BUTTON_TALK,
BUTTON_LOOK,
BUTTON_USE,
BUTTON_PICKUP,
BUTTON_SCROLL_LEFT,
BUTTON_SCROLL_RIGHT,
- BUTTON_SETTINGS
+ BUTTON_SETTINGS,
+ NUM_BUTTONS
};
enum {
@@ -52,40 +55,78 @@ enum {
INVENTORY_ITEMS_LINES = 5
};
-static Common::Rect ButtonRects[] = {
- Common::Rect(0, 148, 67, 158), // Walk
- Common::Rect(0, 158, 67, 168), // Talk
- Common::Rect(0, 168, 67, 178), // Look
- Common::Rect(0, 178, 67, 188), // Use
- Common::Rect(0, 188, 67, 198), // PickUp
- Common::Rect(67, 149, 88, 174), // ScrollLeft
- Common::Rect(67, 174, 88, 199), // ScrollRight
- Common::Rect(301, 148, 320, 200) // Settings
-};
Gui::Gui(Game &game, Graphics::Screen *screen)
: _game(game),
- _screen(screen),
- _inventoryDirty(false) {
+ _screen(screen) {}
+
+Gui::~Gui() {
+ for (Common::Array<Widget *>::iterator it = _widgets.begin(); it != _widgets.end(); ++it) {
+ delete *it;
+ }
+}
+
+Game &Gui::getGame() {
+ return _game;
}
bool Gui::init() {
- const bool result1 = loadInventoryList();
- const bool result2 = loadInventoryGfx();
+ if (!loadInventoryList()) {
+ return false;
+ }
+
+ if (!loadInventoryGfx()) {
+ return false;
+ }
+
+ if (!loadHudGfx()) {
+ return false;
+ }
_game.getGameData().getInventory().setObserver(this);
- return result1 && result2;
+ // Init widgets.
+ _inventoryWidget = new InventoryWidget(*this, _inventoryItems, _inventorySurfaces);
+ _widgets.push_back(_inventoryWidget);
+
+ const Common::Rect ButtonRects[] = {
+ Common::Rect(0, 148, 67, 158), // Walk
+ Common::Rect(0, 158, 67, 168), // Talk
+ Common::Rect(0, 168, 67, 178), // Look
+ Common::Rect(0, 178, 67, 188), // Use
+ Common::Rect(0, 188, 67, 198), // PickUp
+ Common::Rect(67, 149, 88, 174), // ScrollLeft
+ Common::Rect(67, 174, 88, 199), // ScrollRight
+ Common::Rect(301, 148, 320, 200) // Settings
+ };
+
+ for (int i = 0; i < NUM_BUTTONS; ++i) {
+ const Graphics::Surface normalSurface = _hudSurfaces[0].getSubArea(ButtonRects[i]);
+ const Graphics::Surface pressedSurface = _hudSurfaces[1].getSubArea(ButtonRects[i]);
+ ButtonWidget *button = new ButtonWidget(*this, ButtonRects[i], normalSurface, pressedSurface);
+ button->setId(i);
+ button->setCallback(this);
+ _widgets.push_back(button);
+ }
+
+ return true;
}
-void Gui::markInventoryDirty() {
- _inventoryDirty = true;
+void Gui::markDirty() {
+ for (Common::Array<Widget *>::iterator it = _widgets.begin(); it != _widgets.end(); ++it) {
+ (*it)->markDirty();
+ }
+}
+
+void Gui::handleEvent(const Common::Event &event) {
+ for (Common::Array<Widget *>::iterator it = _widgets.begin(); it != _widgets.end(); ++it) {
+ (*it)->handleEvent(event);
+ }
}
void Gui::update() {
- if (_inventoryDirty) {
- drawInventory();
- _inventoryDirty = false;
+ for (Common::Array<Widget *>::iterator it = _widgets.begin(); it != _widgets.end(); ++it) {
+ (*it)->update(*_screen);
}
}
@@ -116,6 +157,32 @@ bool Gui::loadInventoryGfx() {
return decoder.decode(&callback);
}
+class HudAnimationDecoderCallback : public AnimationDecoderCallback {
+public:
+ HudAnimationDecoderCallback(Gui &gui) : _gui(gui) {}
+ virtual void onFrame(int frameNo, Graphics::Surface &surface) override;
+ virtual void onPaletteUpdated(byte palette[PALETTE_SIZE]) override;
+private:
+ Gui &_gui;
+};
+
+void HudAnimationDecoderCallback::onPaletteUpdated(byte [PALETTE_SIZE]) {
+}
+
+void HudAnimationDecoderCallback::onFrame(int frameNo, Graphics::Surface &surface) {
+ if (frameNo == 0 || frameNo == 1 || frameNo == 3) {
+ Graphics::Surface outSurface;
+ outSurface.copyFrom(surface);
+ _gui._hudSurfaces.push_back(outSurface);
+ }
+}
+
+bool Gui::loadHudGfx() {
+ AnimationDecoder decoder("room0.dat");
+ HudAnimationDecoderCallback callback(*this);
+ return decoder.decode(&callback);
+}
+
bool Gui::loadInventoryList() {
EncryptedFile file;
const char *fileName = "fixitems.dat";
@@ -147,35 +214,16 @@ bool Gui::loadInventoryList() {
return true;
}
-void Gui::drawInventoryItem(const Common::String &item, int pos) {
- InventoryMap::iterator it = _inventoryItems.find(item);
- if (it == _inventoryItems.end()) {
- return;
- }
-
- const int index = it->_value;
- const int surfaceNo = index / (INVENTORY_ITEMS_LINES * INVENTORY_ITEMS_PER_LINE);
- const int indexInSurface = index % (INVENTORY_ITEMS_LINES * INVENTORY_ITEMS_PER_LINE);
- const int itemX = indexInSurface % INVENTORY_ITEMS_PER_LINE;
- const int itemY = indexInSurface / INVENTORY_ITEMS_PER_LINE;
-
- Common::Point destStartPos(INVENTORY_START_X + pos * INVENTORY_ITEM_WIDTH, INVENTORY_START_Y);
- Common::Rect sourceRect(itemX * INVENTORY_ITEM_WIDTH, itemY * INVENTORY_ITEM_HEIGHT, (itemX + 1) * INVENTORY_ITEM_WIDTH, (itemY + 1) * INVENTORY_ITEM_HEIGHT);
- _screen->blitFrom(_inventorySurfaces[surfaceNo], sourceRect, destStartPos);
+void Gui::onInventoryChanged() {
+ _inventoryWidget->markDirty();
}
-void Gui::drawInventory() {
- Inventory &inventory = _game.getGameData().getInventory();
- const Inventory::Items &items = inventory.getItems();
- Common::Rect fullRect(INVENTORY_START_X, INVENTORY_START_Y, INVENTORY_START_X + Inventory::VISIBLE_ITEMS * INVENTORY_ITEM_WIDTH, INVENTORY_START_Y + INVENTORY_ITEM_HEIGHT);
- _screen->fillRect(fullRect, 0x00);
- for (int i = 0; i < MIN((int) items.size(), (int) Inventory::VISIBLE_ITEMS); ++i) {
- drawInventoryItem(items[i], i);
+void Gui::onButtonClicked(ButtonWidget *button) {
+ const int buttonId = button->getId();
+ if (buttonId <= BUTTON_PICKUP) {
+ const ActionInfo::Action actions[] = {ActionInfo::Walk, ActionInfo::Talk, ActionInfo::Look, ActionInfo::Use, ActionInfo::PickUp};
+ _game.setCurrentAction(actions[buttonId]);
}
}
-void Gui::onInventoryChanged() {
- markInventoryDirty();
-}
-
}
diff --git a/engines/mutationofjb/gui.h b/engines/mutationofjb/gui.h
index 27e0b0c..5d8358b 100644
--- a/engines/mutationofjb/gui.h
+++ b/engines/mutationofjb/gui.h
@@ -23,10 +23,16 @@
#ifndef MUTATIONOFJB_GUI_H
#define MUTATIONOFJB_GUI_H
+#include "common/array.h"
#include "common/hashmap.h"
#include "common/hash-str.h"
#include "graphics/surface.h"
#include "mutationofjb/inventory.h"
+#include "mutationofjb/widgets/buttonwidget.h"
+
+namespace Common {
+class Event;
+}
namespace Graphics {
class Screen;
@@ -35,31 +41,44 @@ class Screen;
namespace MutationOfJB {
class Game;
+class Widget;
+class InventoryWidget;
-class Gui : public InventoryObserver {
+class Gui : public InventoryObserver, public ButtonWidgetCallback {
public:
+ typedef Common::HashMap<Common::String, int> InventoryMap;
+
friend class InventoryAnimationDecoderCallback;
+ friend class HudAnimationDecoderCallback;
+
Gui(Game &game, Graphics::Screen *screen);
+ ~Gui();
+ Game &getGame();
+
bool init();
void update();
- void markInventoryDirty();
+ void markDirty();
+ void handleEvent(const Common::Event &event);
virtual void onInventoryChanged() override;
+ virtual void onButtonClicked(ButtonWidget *) override;
private:
bool loadInventoryGfx();
+ bool loadHudGfx();
bool loadInventoryList();
void drawInventoryItem(const Common::String &item, int pos);
void drawInventory();
- typedef Common::HashMap<Common::String, int> InventoryMap;
-
Game &_game;
Graphics::Screen *_screen;
InventoryMap _inventoryItems;
Common::Array<Graphics::Surface> _inventorySurfaces;
- bool _inventoryDirty;
+ Common::Array<Graphics::Surface> _hudSurfaces;
+
+ InventoryWidget *_inventoryWidget;
+ Common::Array<Widget *> _widgets;
};
}
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 729ea44..2352ae9 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -18,6 +18,9 @@ MODULE_OBJS := \
commands/removeitemcommand.o \
commands/saycommand.o \
commands/seqcommand.o \
+ widgets/buttonwidget.o \
+ widgets/inventorywidget.o \
+ widgets/widget.o \
animationdecoder.o \
debug.o \
detection.o \
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index df8ad11..e7f534e 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -43,7 +43,6 @@ MutationOfJBEngine::MutationOfJBEngine(OSystem *syst)
: Engine(syst),
_console(nullptr),
_screen(nullptr),
- _currentAction(ActionInfo::Walk),
_mapObjectId(0) {
debug("MutationOfJBEngine::MutationOfJBEngine");
}
@@ -82,12 +81,12 @@ void MutationOfJBEngine::handleNormalScene(const Common::Event &event) {
const int16 y = event.mouse.y;
if (Door *const door = scene->findDoor(x, y)) {
- if (!_game->startActionSection(_currentAction, door->_name) && _currentAction == ActionInfo::Walk && door->_destSceneId != 0) {
+ if (!_game->startActionSection(_game->getCurrentAction(), door->_name) && _game->getCurrentAction() == ActionInfo::Walk && door->_destSceneId != 0) {
_game->changeScene(door->_destSceneId, _game->getGameData()._partB);
}
} else if (Static *const stat = scene->findStatic(x, y)) {
if (stat->_active == 1) {
- _game->startActionSection(_currentAction, stat->_name);
+ _game->startActionSection(_game->getCurrentAction(), stat->_name);
}
}
break;
@@ -95,6 +94,7 @@ void MutationOfJBEngine::handleNormalScene(const Common::Event &event) {
default:
break;
}
+ _game->getGui().handleEvent(event);
}
/*
@@ -187,19 +187,19 @@ Common::Error MutationOfJBEngine::run() {
{
switch (event.kbd.ascii) {
case 'g':
- _currentAction = ActionInfo::Walk;
+ _game->setCurrentAction(ActionInfo::Walk);
break;
case 'r':
- _currentAction = ActionInfo::Talk;
+ _game->setCurrentAction(ActionInfo::Talk);
break;
case 's':
- _currentAction = ActionInfo::Look;
+ _game->setCurrentAction(ActionInfo::Look);
break;
case 'b':
- _currentAction = ActionInfo::Use;
+ _game->setCurrentAction(ActionInfo::Use);
break;
case 'n':
- _currentAction = ActionInfo::PickUp;
+ _game->setCurrentAction(ActionInfo::PickUp);
break;
}
}
diff --git a/engines/mutationofjb/room.h b/engines/mutationofjb/room.h
index a2be2fc..e57d2eb 100644
--- a/engines/mutationofjb/room.h
+++ b/engines/mutationofjb/room.h
@@ -39,6 +39,7 @@ class Game;
class Room {
public:
friend class RoomAnimationDecoderCallback;
+ friend class GuiAnimationDecoderCallback;
Room(Game *game, Graphics::Screen *screen);
bool load(uint8 roomNumber, bool roomB);
diff --git a/engines/mutationofjb/widgets/buttonwidget.cpp b/engines/mutationofjb/widgets/buttonwidget.cpp
new file mode 100644
index 0000000..9f9a401
--- /dev/null
+++ b/engines/mutationofjb/widgets/buttonwidget.cpp
@@ -0,0 +1,70 @@
+/* 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/widgets/buttonwidget.h"
+#include "common/events.h"
+#include "graphics/managed_surface.h"
+
+namespace MutationOfJB {
+
+ButtonWidget::ButtonWidget(Gui &gui, const Common::Rect &area, const Graphics::Surface &normalSurface, const Graphics::Surface &pressedSurface) :
+ Widget(gui, area),
+ _normalSurface(normalSurface),
+ _pressedSurface(pressedSurface),
+ _callback(nullptr),
+ _pressed(false) {}
+
+void ButtonWidget::setCallback(ButtonWidgetCallback *callback) {
+ _callback = callback;
+}
+
+void ButtonWidget::handleEvent(const Common::Event &event) {
+ switch(event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ {
+ const int16 x = event.mouse.x;
+ const int16 y = event.mouse.y;
+ if (_area.contains(x, y)) {
+ _pressed = true;
+ markDirty();
+ }
+ break;
+ }
+ case Common::EVENT_LBUTTONUP:
+ {
+ if (_pressed) {
+ _pressed = false;
+ markDirty();
+ if (_callback) {
+ _callback->onButtonClicked(this);
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+void ButtonWidget::_draw(Graphics::ManagedSurface &surface) {
+ surface.blitFrom(_pressed ? _pressedSurface : _normalSurface, Common::Point(_area.left, _area.top));
+}
+}
diff --git a/engines/mutationofjb/widgets/buttonwidget.h b/engines/mutationofjb/widgets/buttonwidget.h
new file mode 100644
index 0000000..de8cb63
--- /dev/null
+++ b/engines/mutationofjb/widgets/buttonwidget.h
@@ -0,0 +1,58 @@
+/* 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_BUTTONWIDGET_H
+#define MUTATIONOFJB_BUTTONWIDGET_H
+
+#include "mutationofjb/widgets/widget.h"
+#include "graphics/surface.h"
+
+namespace MutationOfJB {
+
+class ButtonWidget;
+
+class ButtonWidgetCallback {
+public:
+ virtual ~ButtonWidgetCallback() {}
+ virtual void onButtonClicked(ButtonWidget *) = 0;
+};
+
+class ButtonWidget : public Widget {
+public:
+ ButtonWidget(Gui &gui, const Common::Rect &area, const Graphics::Surface &normalSurface, const Graphics::Surface &pressedSurface);
+ void setCallback(ButtonWidgetCallback *callback);
+
+ virtual void handleEvent(const Common::Event &event) override;
+
+protected:
+ virtual void _draw(Graphics::ManagedSurface &) override;
+
+private:
+ Graphics::Surface _normalSurface;
+ Graphics::Surface _pressedSurface;
+ ButtonWidgetCallback *_callback;
+ bool _pressed;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/widgets/inventorywidget.cpp b/engines/mutationofjb/widgets/inventorywidget.cpp
new file mode 100644
index 0000000..d78ef10
--- /dev/null
+++ b/engines/mutationofjb/widgets/inventorywidget.cpp
@@ -0,0 +1,75 @@
+/* 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/widgets/inventorywidget.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
+#include "mutationofjb/gui.h"
+#include "mutationofjb/inventory.h"
+#include "common/str.h"
+#include "common/rect.h"
+#include "common/util.h"
+#include "graphics/managed_surface.h"
+
+namespace MutationOfJB {
+
+enum {
+ INVENTORY_START_X = 88,
+ INVENTORY_START_Y = 149,
+ INVENTORY_ITEM_WIDTH = 34,
+ INVENTORY_ITEM_HEIGHT = 33,
+ INVENTORY_ITEMS_PER_LINE = 8,
+ INVENTORY_ITEMS_LINES = 5
+};
+
+InventoryWidget::InventoryWidget(Gui &gui, Gui::InventoryMap &inventoryMap, const Common::Array<Graphics::Surface>& inventorySurfaces) :
+ Widget(gui, Common::Rect(INVENTORY_START_X, INVENTORY_START_Y, INVENTORY_START_X + Inventory::VISIBLE_ITEMS * INVENTORY_ITEM_WIDTH, INVENTORY_START_Y + INVENTORY_ITEM_HEIGHT)),
+ _inventoryMap(inventoryMap),
+ _surfaces(inventorySurfaces) {}
+
+void InventoryWidget::drawInventoryItem(Graphics::ManagedSurface &surface, const Common::String &item, int pos) {
+ Gui::InventoryMap::iterator it = _inventoryMap.find(item);
+ if (it == _inventoryMap.end()) {
+ return;
+ }
+
+ const int index = it->_value;
+ const int surfaceNo = index / (INVENTORY_ITEMS_LINES * INVENTORY_ITEMS_PER_LINE);
+ const int indexInSurface = index % (INVENTORY_ITEMS_LINES * INVENTORY_ITEMS_PER_LINE);
+ const int itemX = indexInSurface % INVENTORY_ITEMS_PER_LINE;
+ const int itemY = indexInSurface / INVENTORY_ITEMS_PER_LINE;
+
+ Common::Point destStartPos(INVENTORY_START_X + pos * INVENTORY_ITEM_WIDTH, INVENTORY_START_Y);
+ Common::Rect sourceRect(itemX * INVENTORY_ITEM_WIDTH, itemY * INVENTORY_ITEM_HEIGHT, (itemX + 1) * INVENTORY_ITEM_WIDTH, (itemY + 1) * INVENTORY_ITEM_HEIGHT);
+ surface.blitFrom(_surfaces[surfaceNo], sourceRect, destStartPos);
+}
+
+void InventoryWidget::_draw(Graphics::ManagedSurface &surface) {
+ Inventory &inventory = _gui.getGame().getGameData().getInventory();
+ const Inventory::Items &items = inventory.getItems();
+ surface.fillRect(_area, 0x00);
+ for (int i = 0; i < MIN((int) items.size(), (int) Inventory::VISIBLE_ITEMS); ++i) {
+ drawInventoryItem(surface, items[i], i);
+ }
+}
+
+}
diff --git a/engines/mutationofjb/widgets/inventorywidget.h b/engines/mutationofjb/widgets/inventorywidget.h
new file mode 100644
index 0000000..f0bc4ba
--- /dev/null
+++ b/engines/mutationofjb/widgets/inventorywidget.h
@@ -0,0 +1,48 @@
+/* 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_INVENTORYWIDGET_H
+#define MUTATIONOFJB_INVENTORYWIDGET_H
+
+#include "mutationofjb/widgets/widget.h"
+#include "mutationofjb/gui.h"
+
+namespace Common {
+class String;
+}
+
+namespace MutationOfJB {
+
+class InventoryWidget : public Widget {
+public:
+ InventoryWidget(Gui &gui, Gui::InventoryMap &inventoryMap, const Common::Array<Graphics::Surface>& inventorySurfaces);
+ virtual void _draw(Graphics::ManagedSurface &) override;
+
+private:
+ void drawInventoryItem(Graphics::ManagedSurface &surface, const Common::String &item, int pos);
+ Gui::InventoryMap &_inventoryMap;
+ const Common::Array<Graphics::Surface>& _surfaces;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/widgets/widget.cpp b/engines/mutationofjb/widgets/widget.cpp
new file mode 100644
index 0000000..fea7f6f
--- /dev/null
+++ b/engines/mutationofjb/widgets/widget.cpp
@@ -0,0 +1,50 @@
+/* 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/widgets/widget.h"
+
+namespace MutationOfJB {
+
+int Widget::getId() const {
+ return _id;
+}
+
+void Widget::setId(int id) {
+ _id = id;
+}
+
+void Widget::markDirty() {
+ _dirty = true;
+}
+
+bool Widget::isDirty() const {
+ return _dirty;
+}
+
+void Widget::update(Graphics::ManagedSurface &surface) {
+ if (_dirty) {
+ _draw(surface);
+ _dirty = false;
+ }
+}
+
+}
diff --git a/engines/mutationofjb/widgets/widget.h b/engines/mutationofjb/widgets/widget.h
new file mode 100644
index 0000000..f81d466
--- /dev/null
+++ b/engines/mutationofjb/widgets/widget.h
@@ -0,0 +1,66 @@
+/* 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_WIDGET_H
+#define MUTATIONOFJB_WIDGET_H
+
+#include <common/scummsys.h>
+#include <common/rect.h>
+
+namespace Common {
+class Event;
+}
+
+namespace Graphics {
+class ManagedSurface;
+}
+
+namespace MutationOfJB {
+
+class Gui;
+
+class Widget {
+public:
+ Widget(Gui &gui, const Common::Rect &area) : _gui(gui), _area(area), _id(0), _dirty(true) {}
+ virtual ~Widget() {}
+
+ int getId() const;
+ void setId(int id);
+
+ bool isDirty() const;
+ void markDirty();
+ void update(Graphics::ManagedSurface &);
+
+ virtual void handleEvent(const Common::Event &) {}
+protected:
+ virtual void _draw(Graphics::ManagedSurface &) = 0;
+
+ Gui &_gui;
+ Common::Rect _area;
+ int _id;
+ bool _dirty;
+};
+
+}
+
+#endif
+
Commit: 29a809d691c77b549bea615421d9e840f3773142
https://github.com/scummvm/scummvm/commit/29a809d691c77b549bea615421d9e840f3773142
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add rename command.
Changed paths:
A engines/mutationofjb/commands/renamecommand.cpp
A engines/mutationofjb/commands/renamecommand.h
engines/mutationofjb/commands/changecommand.cpp
engines/mutationofjb/commands/changecommand.h
engines/mutationofjb/commands/gotocommand.h
engines/mutationofjb/commands/saycommand.h
engines/mutationofjb/gamedata.cpp
engines/mutationofjb/gamedata.h
engines/mutationofjb/inventory.cpp
engines/mutationofjb/inventory.h
engines/mutationofjb/module.mk
engines/mutationofjb/script.cpp
diff --git a/engines/mutationofjb/commands/changecommand.cpp b/engines/mutationofjb/commands/changecommand.cpp
index f2639b6..a2d4526 100644
--- a/engines/mutationofjb/commands/changecommand.cpp
+++ b/engines/mutationofjb/commands/changecommand.cpp
@@ -66,7 +66,7 @@ bool ChangeCommandParser::parseValueString(const Common::String &valueString, bo
if (valueString.hasPrefix("NM")) {
reg = ChangeCommand::NM;
op = ChangeCommand::SetValue;
- strncpy(ccv._strVal, val, MAX_STR_LENGTH);
+ strncpy(ccv._strVal, val, MAX_ENTITY_NAME_LENGTH);
} else if (valueString.hasPrefix("LT")) {
reg = ChangeCommand::LT;
ccv._byteVal = parseInteger(val, op);
@@ -324,7 +324,7 @@ Command::ExecuteResult ChangeDoorCommand::execute(ScriptExecutionContext &script
switch (_register) {
case NM:
- strncpy(door->_name, _value._strVal, MAX_STR_LENGTH);
+ strncpy(door->_name, _value._strVal, MAX_ENTITY_NAME_LENGTH);
break;
case LT:
door->_destSceneId = _value._byteVal;
@@ -447,7 +447,7 @@ Command::ExecuteResult ChangeStaticCommand::execute(ScriptExecutionContext &scri
stat->_active = _value._byteVal;
break;
case NM:
- strncpy(stat->_name, _value._strVal, MAX_STR_LENGTH);
+ strncpy(stat->_name, _value._strVal, MAX_ENTITY_NAME_LENGTH);
break;
case XX:
stat->_x = _value._wordVal;
diff --git a/engines/mutationofjb/commands/changecommand.h b/engines/mutationofjb/commands/changecommand.h
index f5d7cf5..6fa090e 100644
--- a/engines/mutationofjb/commands/changecommand.h
+++ b/engines/mutationofjb/commands/changecommand.h
@@ -28,7 +28,7 @@ namespace MutationOfJB {
union ChangeCommandValue {
uint8 _byteVal;
uint16 _wordVal;
- char _strVal[MAX_STR_LENGTH + 1];
+ char _strVal[MAX_ENTITY_NAME_LENGTH + 1];
};
class ChangeCommand : public SeqCommand {
diff --git a/engines/mutationofjb/commands/gotocommand.h b/engines/mutationofjb/commands/gotocommand.h
index 09d426f..b56e642 100644
--- a/engines/mutationofjb/commands/gotocommand.h
+++ b/engines/mutationofjb/commands/gotocommand.h
@@ -34,7 +34,7 @@ class GotoCommandParser : public CommandParser {
public:
GotoCommandParser() {}
- virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
};
class GotoCommand : public Command {
diff --git a/engines/mutationofjb/commands/renamecommand.cpp b/engines/mutationofjb/commands/renamecommand.cpp
new file mode 100644
index 0000000..03a8832
--- /dev/null
+++ b/engines/mutationofjb/commands/renamecommand.cpp
@@ -0,0 +1,78 @@
+/* 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/renamecommand.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
+#include "common/algorithm.h"
+
+/*
+ "REN " <oldName> " " <newName>
+ Renames every door, static (in the current scene) and inventory item
+ with the name oldName to newName.
+*/
+
+namespace MutationOfJB {
+
+bool RenameCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
+ if (line.size() < 7 || !line.hasPrefix("REN")) {
+ return false;
+ }
+
+ Common::String::const_iterator sep = Common::find(line.begin() + 4, line.end(), ' ');
+ if (sep == line.end() || sep + 1 == line.end()) {
+ return false;
+ }
+
+ const Common::String oldName(line.begin() + 4, sep);
+ const Common::String newName(sep + 1, line.end());
+ command = new RenameCommand(oldName, newName);
+
+ return true;
+}
+
+
+Command::ExecuteResult RenameCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ Scene *const scene = scriptExecCtx.getGameData().getCurrentScene();
+
+ for (int i = 1; i <= scene->getNoDoors(); ++i) {
+ Door *const door = scene->getDoor(i);
+ if (strcmp(door->_name, _oldName.c_str()) == 0) {
+ strncpy(door->_name, _newName.c_str(), MAX_ENTITY_NAME_LENGTH);
+ }
+ }
+ for (int i = 1; i <= scene->getNoStatics(); ++i) {
+ Static *const stat = scene->getStatic(i);
+ if (strcmp(stat->_name, _oldName.c_str()) == 0) {
+ strncpy(stat->_name, _newName.c_str(), MAX_ENTITY_NAME_LENGTH);
+ }
+ }
+
+ scriptExecCtx.getGameData().getInventory().renameItem(_oldName, _newName);
+ return Finished;
+}
+
+Common::String RenameCommand::debugString() const {
+ return Common::String::format("RENAME '%s' '%s'", _oldName.c_str(), _newName.c_str());
+}
+
+}
diff --git a/engines/mutationofjb/commands/renamecommand.h b/engines/mutationofjb/commands/renamecommand.h
new file mode 100644
index 0000000..566d46e
--- /dev/null
+++ b/engines/mutationofjb/commands/renamecommand.h
@@ -0,0 +1,50 @@
+/* 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_RENAMECOMMAND_H
+#define MUTATIONOFJB_RENAMECOMMAND_H
+
+#include "mutationofjb/commands/seqcommand.h"
+#include "common/str.h"
+
+namespace MutationOfJB {
+
+class RenameCommandParser : public SeqCommandParser {
+public:
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
+};
+
+class RenameCommand : public SeqCommand {
+public:
+ RenameCommand(const Common::String &oldName, const Common::String &newName) : _oldName(oldName), _newName(newName) {}
+
+ virtual Command::ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
+ virtual Common::String debugString() const override;
+
+private:
+ Common::String _oldName;
+ Common::String _newName;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/commands/saycommand.h b/engines/mutationofjb/commands/saycommand.h
index e41d10f..60c7cc8 100644
--- a/engines/mutationofjb/commands/saycommand.h
+++ b/engines/mutationofjb/commands/saycommand.h
@@ -32,7 +32,7 @@ class SayCommandParser : public SeqCommandParser {
public:
SayCommandParser() {}
- virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
};
class SayCommand : public SeqCommand {
diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp
index 099cea7..1ece44c 100644
--- a/engines/mutationofjb/gamedata.cpp
+++ b/engines/mutationofjb/gamedata.cpp
@@ -28,13 +28,13 @@
namespace MutationOfJB {
static bool readString(Common::ReadStream &stream, char *str) {
- char buf[MAX_STR_LENGTH];
- memset(str, 0, MAX_STR_LENGTH + 1);
+ char buf[MAX_ENTITY_NAME_LENGTH];
+ memset(str, 0, MAX_ENTITY_NAME_LENGTH + 1);
uint8 len = stream.readByte();
- stream.read(buf, MAX_STR_LENGTH);
+ stream.read(buf, MAX_ENTITY_NAME_LENGTH);
- len = MIN(len, MAX_STR_LENGTH);
+ len = MIN(len, (uint8) MAX_ENTITY_NAME_LENGTH);
memcpy(str, buf, len);
return true;
diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h
index 64de01e..321a688 100644
--- a/engines/mutationofjb/gamedata.h
+++ b/engines/mutationofjb/gamedata.h
@@ -32,7 +32,9 @@ class ReadStream;
namespace MutationOfJB {
-static const uint8 MAX_STR_LENGTH = 0x14;
+enum {
+ MAX_ENTITY_NAME_LENGTH = 0x14
+};
/*
There are 4 types of entities present in the game data:
@@ -47,7 +49,7 @@ struct Door {
Door name.
Can be empty - deactivates door completely.
*/
- char _name[MAX_STR_LENGTH + 1];
+ char _name[MAX_ENTITY_NAME_LENGTH + 1];
/*
Scene ID where the door leads.
Can be 0 - you can hover your mouse over it, but clicking it doesn't do anything (unless scripted).
@@ -96,7 +98,7 @@ struct Object {
struct Static {
uint8 _active;
- char _name[MAX_STR_LENGTH + 1];
+ char _name[MAX_ENTITY_NAME_LENGTH + 1];
uint16 _x;
uint8 _y;
uint16 _width;
diff --git a/engines/mutationofjb/inventory.cpp b/engines/mutationofjb/inventory.cpp
index b6561b2..2fa7f2c 100644
--- a/engines/mutationofjb/inventory.cpp
+++ b/engines/mutationofjb/inventory.cpp
@@ -33,7 +33,7 @@ const Inventory::Items &Inventory::getItems() const {
}
bool Inventory::hasItem(const Common::String &item) const {
- Items::const_iterator it = find(_items.begin(), _items.end(), item);
+ Items::const_iterator it = Common::find(_items.begin(), _items.end(), item);
return (it != _items.end());
}
@@ -49,7 +49,7 @@ void Inventory::addItem(const Common::String &item) {
}
void Inventory::removeItem(const Common::String &item) {
- Items::iterator it = find(_items.begin(), _items.end(), item);
+ Items::iterator it = Common::find(_items.begin(), _items.end(), item);
if (it == _items.end()) {
debug("Item '%s' not in inventory.", item.c_str());
return;
@@ -68,6 +68,19 @@ void Inventory::removeAllItems() {
}
}
+void Inventory::renameItem(const Common::String &oldName, const Common::String &newName) {
+ bool renamed = false;
+ for (Items::iterator it = _items.begin(); it != _items.end(); ++it) {
+ if (*it == oldName) {
+ *it = newName;
+ renamed = true;
+ }
+ }
+ if (renamed && _observer) {
+ _observer->onInventoryChanged();
+ }
+}
+
void Inventory::rotateItemsRight(uint n) {
if (_items.size() < 2) {
return;
diff --git a/engines/mutationofjb/inventory.h b/engines/mutationofjb/inventory.h
index 91c2932..c22422d 100644
--- a/engines/mutationofjb/inventory.h
+++ b/engines/mutationofjb/inventory.h
@@ -50,6 +50,7 @@ public:
void addItem(const Common::String &item);
void removeItem(const Common::String &item);
void removeAllItems();
+ void renameItem(const Common::String &oldName, const Common::String &newName);
void rotateItemsRight(uint n);
void rotateItemsLeft(uint n);
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 2352ae9..f66b671 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -16,6 +16,7 @@ MODULE_OBJS := \
commands/newroomcommand.o \
commands/removeallitemscommand.o \
commands/removeitemcommand.o \
+ commands/renamecommand.o \
commands/saycommand.o \
commands/seqcommand.o \
widgets/buttonwidget.o \
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index f213de9..1f5571f 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -42,6 +42,7 @@
#include "mutationofjb/commands/camefromcommand.h"
#include "mutationofjb/commands/callmacrocommand.h"
#include "mutationofjb/commands/newroomcommand.h"
+#include "mutationofjb/commands/renamecommand.h"
#include "mutationofjb/game.h"
namespace MutationOfJB {
@@ -62,6 +63,7 @@ static CommandParser **getParsers() {
new AddItemCommandParser,
new RemoveItemCommandParser,
new RemoveAllItemsCommandParser,
+ new RenameCommandParser,
new NewRoomCommandParser,
new GotoCommandParser,
new LabelCommandParser,
Commit: 5290d9a74b2f704675cf5ae69bcf892b5afd274f
https://github.com/scummvm/scummvm/commit/5290d9a74b2f704675cf5ae69bcf892b5afd274f
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Draw HUD background.
Changed paths:
A engines/mutationofjb/widgets/imagewidget.cpp
A engines/mutationofjb/widgets/imagewidget.h
engines/mutationofjb/gui.cpp
engines/mutationofjb/module.mk
engines/mutationofjb/mutationofjb.h
diff --git a/engines/mutationofjb/gui.cpp b/engines/mutationofjb/gui.cpp
index 76e9305..c7be355 100644
--- a/engines/mutationofjb/gui.cpp
+++ b/engines/mutationofjb/gui.cpp
@@ -29,6 +29,7 @@
#include "mutationofjb/util.h"
#include "mutationofjb/widgets/widget.h"
#include "mutationofjb/widgets/inventorywidget.h"
+#include "mutationofjb/widgets/imagewidget.h"
#include "common/rect.h"
#include "graphics/screen.h"
@@ -52,7 +53,11 @@ enum {
INVENTORY_ITEM_WIDTH = 34,
INVENTORY_ITEM_HEIGHT = 33,
INVENTORY_ITEMS_PER_LINE = 8,
- INVENTORY_ITEMS_LINES = 5
+ INVENTORY_ITEMS_LINES = 5,
+ CONVERSATION_X = 0,
+ CONVERSATION_Y = 139,
+ CONVERSATION_WIDTH = 320,
+ CONVERSATION_HEIGHT = 61
};
@@ -86,6 +91,12 @@ bool Gui::init() {
_game.getGameData().getInventory().setObserver(this);
// Init widgets.
+
+ const Common::Rect backgroundRect(CONVERSATION_X, CONVERSATION_Y, CONVERSATION_X + CONVERSATION_WIDTH, CONVERSATION_Y + CONVERSATION_HEIGHT);
+ const Graphics::Surface backgroundSurface = _hudSurfaces[0].getSubArea(backgroundRect);
+ ImageWidget *image = new ImageWidget(*this, backgroundRect, backgroundSurface);
+ _widgets.push_back(image);
+
_inventoryWidget = new InventoryWidget(*this, _inventoryItems, _inventorySurfaces);
_widgets.push_back(_inventoryWidget);
@@ -170,7 +181,7 @@ void HudAnimationDecoderCallback::onPaletteUpdated(byte [PALETTE_SIZE]) {
}
void HudAnimationDecoderCallback::onFrame(int frameNo, Graphics::Surface &surface) {
- if (frameNo == 0 || frameNo == 1 || frameNo == 3) {
+ if (frameNo == 0 || frameNo == 1 || frameNo == 4) {
Graphics::Surface outSurface;
outSurface.copyFrom(surface);
_gui._hudSurfaces.push_back(outSurface);
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index f66b671..8604d40 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -20,6 +20,7 @@ MODULE_OBJS := \
commands/saycommand.o \
commands/seqcommand.o \
widgets/buttonwidget.o \
+ widgets/imagewidget.o \
widgets/inventorywidget.o \
widgets/widget.o \
animationdecoder.o \
diff --git a/engines/mutationofjb/mutationofjb.h b/engines/mutationofjb/mutationofjb.h
index ef0c973..348165f 100644
--- a/engines/mutationofjb/mutationofjb.h
+++ b/engines/mutationofjb/mutationofjb.h
@@ -57,7 +57,6 @@ private:
Console *_console;
Graphics::Screen *_screen;
Game *_game;
- ActionInfo::Action _currentAction;
uint8 _mapObjectId;
};
diff --git a/engines/mutationofjb/widgets/imagewidget.cpp b/engines/mutationofjb/widgets/imagewidget.cpp
new file mode 100644
index 0000000..3395da8
--- /dev/null
+++ b/engines/mutationofjb/widgets/imagewidget.cpp
@@ -0,0 +1,37 @@
+/* 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/widgets/imagewidget.h"
+#include "graphics/managed_surface.h"
+
+namespace MutationOfJB {
+
+ImageWidget::ImageWidget(Gui &gui, const Common::Rect &area, const Graphics::Surface &image) :
+ Widget(gui, area),
+ _image(image) {}
+
+
+void ImageWidget::_draw(Graphics::ManagedSurface &surface) {
+ surface.blitFrom(_image, Common::Point(_area.left, _area.top));
+}
+
+}
diff --git a/engines/mutationofjb/widgets/imagewidget.h b/engines/mutationofjb/widgets/imagewidget.h
new file mode 100644
index 0000000..4585a72
--- /dev/null
+++ b/engines/mutationofjb/widgets/imagewidget.h
@@ -0,0 +1,44 @@
+/* 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_IMAGEWIDGET_H
+#define MUTATIONOFJB_IMAGEWIDGET_H
+
+#include "mutationofjb/widgets/widget.h"
+#include "graphics/surface.h"
+
+namespace MutationOfJB {
+
+class ImageWidget : public Widget {
+public:
+ ImageWidget(Gui &gui, const Common::Rect &area, const Graphics::Surface &image);
+
+protected:
+ virtual void _draw(Graphics::ManagedSurface &surface) override;
+
+private:
+ Graphics::Surface _image;
+};
+
+}
+
+#endif
Commit: 61c106b3307ee2f8aaa579dbc5d7c8f8e62ae41a
https://github.com/scummvm/scummvm/commit/61c106b3307ee2f8aaa579dbc5d7c8f8e62ae41a
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add font support and conversation widget.
Changed paths:
A engines/mutationofjb/font.cpp
A engines/mutationofjb/font.h
A engines/mutationofjb/widgets/conversationwidget.cpp
A engines/mutationofjb/widgets/conversationwidget.h
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/gui.cpp
engines/mutationofjb/gui.h
engines/mutationofjb/module.mk
engines/mutationofjb/widgets/widget.cpp
engines/mutationofjb/widgets/widget.h
diff --git a/engines/mutationofjb/font.cpp b/engines/mutationofjb/font.cpp
new file mode 100644
index 0000000..235c60a
--- /dev/null
+++ b/engines/mutationofjb/font.cpp
@@ -0,0 +1,125 @@
+/* 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/font.h"
+#include "mutationofjb/encryptedfile.h"
+#include "mutationofjb/util.h"
+#include "common/debug.h"
+
+namespace MutationOfJB {
+
+Font::Font(const Common::String &fileName, int horizSpacing, int vertSpacing) :
+ _horizSpacing(horizSpacing),
+ _vertSpacing(vertSpacing) {
+
+ load(fileName);
+}
+
+bool Font::load(const Common::String &fileName) {
+ EncryptedFile file;
+ file.open(fileName);
+ if (!file.isOpen()) {
+ reportFileMissingError(fileName.c_str());
+ return false;
+ }
+
+ file.seek(0x02D6, SEEK_SET); // Skip header + unknown data (unused palette?).
+
+ uint16 noGlyphs = 0;
+ noGlyphs = file.readUint16LE();
+
+ file.seek(7, SEEK_CUR); // Skip unknown data (0s).
+
+ uint8 maxHeight = 0;
+
+ while (noGlyphs--) {
+ const uint8 character = file.readByte();
+ const uint8 width = file.readByte();
+ const uint8 height = file.readByte();
+
+ Graphics::ManagedSurface &surf = _glyphs[character];
+ surf.create(width, height);
+ for (int h = 0; h < height; ++h) {
+ file.read(surf.getBasePtr(0, h), width);
+ }
+
+ if (height > maxHeight) {
+ maxHeight = height;
+ }
+ }
+
+ if (_vertSpacing == -1) {
+ _vertSpacing = maxHeight;
+ }
+
+ return true;
+}
+
+
+void Font::drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf) {
+ GlyphMap::iterator it = _glyphs.find(glyph);
+ if (it == _glyphs.end()) {
+ warning("Glyph %d not found", glyph);
+ return;
+ }
+
+ Graphics::ManagedSurface &glyphSurface = it->_value;
+
+ Graphics::ManagedSurface tmp(glyphSurface);
+ for (int h = 0; h < tmp.h; ++h) {
+ uint8 *ptr = reinterpret_cast<uint8 *>(tmp.getBasePtr(0, h));
+ for (int w = 0; w < tmp.w; ++w) {
+ if (*ptr != 0) {
+ *ptr = transformColor(baseColor, *ptr);
+ }
+ ptr++;
+ }
+ }
+ surf.transBlitFrom(tmp.rawSurface(), Common::Point(x, y));
+
+ x += glyphSurface.w + _horizSpacing;
+}
+
+void Font::drawString(const Common::String &str, uint8 baseColor, int16 x, int16 y, Graphics::ManagedSurface &surf) {
+ for (uint i = 0; i < str.size(); ++i) {
+ drawGlyph(str[i], baseColor, x, y, surf); // "x" is updated.
+ }
+}
+
+uint8 Font::transformColor(uint8 baseColor, uint8 glyphColor) {
+ return baseColor + glyphColor - 0x10;
+}
+
+SystemFont::SystemFont() : Font("sysfnt.aft", 1, 7) {}
+
+SpeechFont::SpeechFont() : Font("font1.aft", -1, -1) {}
+
+uint8 SpeechFont::transformColor(uint8 baseColor, uint8 glyphColor) {
+ // Hack in original game.
+ if (glyphColor == 0x11) {
+ return 0xC0;
+ }
+
+ return Font::transformColor(baseColor, glyphColor);
+}
+
+}
diff --git a/engines/mutationofjb/font.h b/engines/mutationofjb/font.h
new file mode 100644
index 0000000..5aa6a4f
--- /dev/null
+++ b/engines/mutationofjb/font.h
@@ -0,0 +1,70 @@
+/* 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_FONT_H
+#define MUTATIONOFJB_FONT_H
+
+#include "common/scummsys.h"
+#include "common/hashmap.h"
+#include "graphics/managed_surface.h"
+
+namespace Common {
+class String;
+}
+
+namespace MutationOfJB {
+
+class Font {
+public:
+ Font(const Common::String &fileName, int horizSpacing, int vertSpacing);
+ virtual ~Font() {}
+ void drawString(const Common::String &str, uint8 baseColor, int16 x, int16 y, Graphics::ManagedSurface &surf);
+
+protected:
+ virtual uint8 transformColor(uint8 baseColor, uint8 glyphColor);
+
+private:
+ void drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf);
+ bool load(const Common::String &fileName);
+
+ int _horizSpacing;
+ int _vertSpacing;
+ typedef Common::HashMap<uint8, Graphics::ManagedSurface> GlyphMap;
+ GlyphMap _glyphs;
+};
+
+class SystemFont : public Font {
+public:
+ SystemFont();
+};
+
+class SpeechFont : public Font {
+public:
+ SpeechFont();
+
+protected:
+ virtual uint8 transformColor(uint8 baseColor, uint8 glyphColor) override;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index af0b76b..d6ab622 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -192,4 +192,12 @@ void Game::setCurrentAction(ActionInfo::Action action) {
_currentAction = action;
}
+Font& Game::getSystemFont() {
+ return _systemFont;
+}
+
+Font& Game::getSpeechFont() {
+ return _speechFont;
+}
+
}
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index 19cf406..122c2a1 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "mutationofjb/script.h"
+#include "mutationofjb/font.h"
#include "mutationofjb/gui.h"
namespace Common {
@@ -64,6 +65,9 @@ public:
ActionInfo::Action getCurrentAction() const;
void setCurrentAction(ActionInfo::Action);
+ Font& getSystemFont();
+ Font& getSpeechFont();
+
private:
bool loadGameData(bool partB);
void runActiveCommand();
@@ -81,6 +85,9 @@ private:
ActionInfo::Action _currentAction;
ScriptExecutionContext _scriptExecCtx;
+
+ SystemFont _systemFont;
+ SpeechFont _speechFont;
};
}
diff --git a/engines/mutationofjb/gui.cpp b/engines/mutationofjb/gui.cpp
index c7be355..7102407 100644
--- a/engines/mutationofjb/gui.cpp
+++ b/engines/mutationofjb/gui.cpp
@@ -30,6 +30,7 @@
#include "mutationofjb/widgets/widget.h"
#include "mutationofjb/widgets/inventorywidget.h"
#include "mutationofjb/widgets/imagewidget.h"
+#include "mutationofjb/widgets/conversationwidget.h"
#include "common/rect.h"
#include "graphics/screen.h"
@@ -120,6 +121,12 @@ bool Gui::init() {
_widgets.push_back(button);
}
+ const Common::Rect conversationRect(CONVERSATION_X, CONVERSATION_Y, CONVERSATION_X + CONVERSATION_WIDTH, CONVERSATION_Y + CONVERSATION_HEIGHT);
+ const Graphics::Surface conversationSurface =_hudSurfaces[2].getSubArea(conversationRect);
+ _conversationWidget = new ConversationWidget(*this, conversationRect, conversationSurface);
+ _conversationWidget->setVisible(false);
+ _widgets.push_back(_conversationWidget);
+
return true;
}
@@ -141,6 +148,10 @@ void Gui::update() {
}
}
+ConversationWidget& Gui::getConversationWidget() {
+ return *_conversationWidget;
+}
+
class InventoryAnimationDecoderCallback : public AnimationDecoderCallback {
public:
InventoryAnimationDecoderCallback(Gui &gui) : _gui(gui) {}
diff --git a/engines/mutationofjb/gui.h b/engines/mutationofjb/gui.h
index 5d8358b..d8e1286 100644
--- a/engines/mutationofjb/gui.h
+++ b/engines/mutationofjb/gui.h
@@ -43,9 +43,21 @@ namespace MutationOfJB {
class Game;
class Widget;
class InventoryWidget;
+class ConversationWidget;
class Gui : public InventoryObserver, public ButtonWidgetCallback {
public:
+ enum Colors {
+ WHITE = 0xC6,
+ DARKGRAY = 0xC2,
+ LIGHTGRAY = 0xC4,
+ GREEN = 0xC8,
+ ORANGE = 0xCA,
+ DARKBLUE = 0xD6,
+ LIGHTBLUE = 0xDA,
+ BROWN = 0xDC
+ };
+
typedef Common::HashMap<Common::String, int> InventoryMap;
friend class InventoryAnimationDecoderCallback;
@@ -64,6 +76,8 @@ public:
virtual void onInventoryChanged() override;
virtual void onButtonClicked(ButtonWidget *) override;
+ ConversationWidget& getConversationWidget();
+
private:
bool loadInventoryGfx();
bool loadHudGfx();
@@ -78,6 +92,7 @@ private:
Common::Array<Graphics::Surface> _hudSurfaces;
InventoryWidget *_inventoryWidget;
+ ConversationWidget *_conversationWidget;
Common::Array<Widget *> _widgets;
};
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 8604d40..2fd4123 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -20,6 +20,7 @@ MODULE_OBJS := \
commands/saycommand.o \
commands/seqcommand.o \
widgets/buttonwidget.o \
+ widgets/conversationwidget.o \
widgets/imagewidget.o \
widgets/inventorywidget.o \
widgets/widget.o \
@@ -27,6 +28,7 @@ MODULE_OBJS := \
debug.o \
detection.o \
encryptedfile.o \
+ font.o \
game.o \
gamedata.o \
gui.o \
diff --git a/engines/mutationofjb/widgets/conversationwidget.cpp b/engines/mutationofjb/widgets/conversationwidget.cpp
new file mode 100644
index 0000000..6196bc6
--- /dev/null
+++ b/engines/mutationofjb/widgets/conversationwidget.cpp
@@ -0,0 +1,65 @@
+/* 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/widgets/conversationwidget.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/gui.h"
+#include "mutationofjb/font.h"
+
+namespace MutationOfJB {
+
+enum {
+ CONVERSATION_LINES_X = 5,
+ CONVERSATION_LINES_Y = 151,
+ CONVERSATION_LINE_HEIGHT = 12
+};
+
+ConversationWidget::ConversationWidget(Gui &gui, const Common::Rect &area, const Graphics::Surface &surface) :
+ Widget(gui, area),
+ _surface(surface) {}
+
+
+void ConversationWidget::setLine(int lineNo, const Common::String &str) {
+ if (lineNo >= CONVERSATION_LINES) {
+ return;
+ }
+
+ _lines[lineNo] = str;
+ markDirty();
+}
+
+void ConversationWidget::_draw(Graphics::ManagedSurface &surface) {
+ surface.blitFrom(_surface, Common::Point(_area.left, _area.top));
+
+ for (int i = 0; i < CONVERSATION_LINES; ++i) {
+ Common::String &line = _lines[i];
+ if (line.empty()) {
+ continue;
+ }
+
+ // TODO: Active line should be Gui::WHITE.
+ _gui.getGame().getSystemFont().drawString(line, Gui::LIGHTGRAY, CONVERSATION_LINES_X, CONVERSATION_LINES_Y + i * CONVERSATION_LINE_HEIGHT, surface);
+ }
+}
+
+}
+
diff --git a/engines/mutationofjb/widgets/conversationwidget.h b/engines/mutationofjb/widgets/conversationwidget.h
new file mode 100644
index 0000000..0f26a99
--- /dev/null
+++ b/engines/mutationofjb/widgets/conversationwidget.h
@@ -0,0 +1,50 @@
+/* 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_CONVERSATIONWIDGET_H
+#define MUTATIONOFJB_CONVERSATIONWIDGET_H
+
+#include "mutationofjb/widgets/widget.h"
+#include "graphics/surface.h"
+
+namespace MutationOfJB {
+
+class ConversationWidget : public Widget {
+public:
+ enum { CONVERSATION_LINES = 4 };
+
+ ConversationWidget(Gui &gui, const Common::Rect &area, const Graphics::Surface &surface);
+
+ void setLine(int lineNo, const Common::String &str);
+
+protected:
+ void _draw(Graphics::ManagedSurface &surface);
+
+private:
+
+ Graphics::Surface _surface;
+ Common::String _lines[CONVERSATION_LINES];
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/widgets/widget.cpp b/engines/mutationofjb/widgets/widget.cpp
index fea7f6f..5503f62 100644
--- a/engines/mutationofjb/widgets/widget.cpp
+++ b/engines/mutationofjb/widgets/widget.cpp
@@ -32,6 +32,17 @@ void Widget::setId(int id) {
_id = id;
}
+bool Widget::isVisible() const {
+ return _visible;
+}
+
+void Widget::setVisible(bool visible) {
+ if (!_visible && visible) {
+ markDirty();
+ }
+ _visible = visible;
+}
+
void Widget::markDirty() {
_dirty = true;
}
@@ -42,7 +53,9 @@ bool Widget::isDirty() const {
void Widget::update(Graphics::ManagedSurface &surface) {
if (_dirty) {
- _draw(surface);
+ if (_visible) {
+ _draw(surface);
+ }
_dirty = false;
}
}
diff --git a/engines/mutationofjb/widgets/widget.h b/engines/mutationofjb/widgets/widget.h
index f81d466..ed3a3ac 100644
--- a/engines/mutationofjb/widgets/widget.h
+++ b/engines/mutationofjb/widgets/widget.h
@@ -40,12 +40,15 @@ class Gui;
class Widget {
public:
- Widget(Gui &gui, const Common::Rect &area) : _gui(gui), _area(area), _id(0), _dirty(true) {}
+ Widget(Gui &gui, const Common::Rect &area) : _gui(gui), _area(area), _id(0), _visible(true), _dirty(true) {}
virtual ~Widget() {}
int getId() const;
void setId(int id);
+ bool isVisible() const;
+ void setVisible(bool visible);
+
bool isDirty() const;
void markDirty();
void update(Graphics::ManagedSurface &);
@@ -57,6 +60,7 @@ protected:
Gui &_gui;
Common::Rect _area;
int _id;
+ bool _visible;
bool _dirty;
};
Commit: 2fb867b2f56b5c337fe3c547a5f53a627e52b74e
https://github.com/scummvm/scummvm/commit/2fb867b2f56b5c337fe3c547a5f53a627e52b74e
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Fix issue with parsing #MACRO and #STARTUP right after end block command.
Changed paths:
engines/mutationofjb/commands/endblockcommand.cpp
engines/mutationofjb/commands/endblockcommand.h
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index cc6a455..3b4c25b 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -61,6 +61,7 @@ bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext
}
// This is the start or end of section/block.
+ command = new EndBlockCommand();
if (line.size() >= 4 && (line.hasPrefix("#L ") || line.hasPrefix("-L "))) {
ActionInfo ai = {ActionInfo::Look, line.c_str() + 3, "", firstChar == '#', nullptr};
@@ -112,21 +113,23 @@ bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext
_ifTag = line[5];
}
} else if (line.size() >= 8 && line.hasPrefix("#MACRO")) {
- _foundMacro = line.c_str() + 7;
+ NameAndCommand nc = {line.c_str() + 7, command};
+ _foundMacros.push_back(nc);
} else if (line.size() >= 10 && line.hasPrefix("#STARTUP")) {
- _foundStartup = line.c_str() + 9;
+ const uint8 startupId = atoi(line.c_str() + 9);
+ IdAndCommand ic = {startupId, command};
+ _foundStartups.push_back(ic);
}
if (firstChar == '#') {
_hashFound = true;
}
- command = new EndBlockCommand();
return true;
}
-void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *, Command *newCommand, CommandParser *newCommandParser) {
+void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser) {
if (_elseFound || _hashFound) {
if (newCommand) {
ScriptParseContext::ConditionalCommandInfos::iterator it = parseCtx._pendingCondCommands.begin();
@@ -146,26 +149,39 @@ void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *,
_ifTag = 0;
}
- if (!_foundMacro.empty()) {
+ if (!_foundMacros.empty()) {
if (newCommand) {
- if (!parseCtx._macros.contains(_foundMacro)) {
- parseCtx._macros[_foundMacro] = newCommand;
- } else {
- warning(_("Macro '%s' already exists."), _foundMacro.c_str());
+ for (NameAndCommandArray::iterator it = _foundMacros.begin(); it != _foundMacros.end();) {
+ if (it->_command != oldCommand) {
+ it++;
+ continue;
+ }
+
+ if (!parseCtx._macros.contains(it->_name)) {
+ parseCtx._macros[it->_name] = newCommand;
+ } else {
+ warning(_("Macro '%s' already exists"), it->_name.c_str());
+ }
+ it = _foundMacros.erase(it);
}
}
- _foundMacro.clear();
}
- if (!_foundStartup.empty()) {
+ if (!_foundStartups.empty()) {
if (newCommand) {
- const uint8 startupId = atoi(_foundStartup.c_str());
- if (!parseCtx._startups.contains(startupId)) {
- parseCtx._startups[startupId] = newCommand;
- } else {
- warning(_("Startup %u already exists."), (unsigned int) startupId);
+ for (IdAndCommandArray::iterator it = _foundStartups.begin(); it != _foundStartups.end();) {
+ if (it->_command != oldCommand) {
+ it++;
+ continue;
+ }
+
+ if (!parseCtx._startups.contains(it->_id)) {
+ parseCtx._startups[it->_id] = newCommand;
+ } else {
+ warning(_("Startup %u already exists"), (unsigned int) it->_id);
+ }
+ it = _foundStartups.erase(it);
}
}
- _foundStartup.clear();
}
if (newCommandParser != this) {
@@ -186,8 +202,15 @@ void EndBlockCommandParser::finish(ScriptParseContext &) {
if (!_pendingActionInfos.empty()) {
debug("Problem: Pending action infos from end block parser is not empty!");
}
+ if (!_foundMacros.empty()) {
+ debug("Problem: Found macros from end block parser is not empty!");
+ }
+ if (!_foundStartups.empty()) {
+ debug("Problem: Found startups from end block parser is not empty!");
+ }
_pendingActionInfos.clear();
- _foundMacro = "";
+ _foundMacros.clear();
+ _foundStartups.clear();
}
Command::ExecuteResult EndBlockCommand::execute(ScriptExecutionContext &scriptExecCtx) {
diff --git a/engines/mutationofjb/commands/endblockcommand.h b/engines/mutationofjb/commands/endblockcommand.h
index eb77f43..4ca46dd 100644
--- a/engines/mutationofjb/commands/endblockcommand.h
+++ b/engines/mutationofjb/commands/endblockcommand.h
@@ -44,8 +44,18 @@ private:
char _ifTag;
Common::Array<uint> _pendingActionInfos;
- Common::String _foundMacro;
- Common::String _foundStartup;
+ struct NameAndCommand {
+ Common::String _name;
+ Command *_command;
+ };
+ struct IdAndCommand {
+ uint8 _id;
+ Command *_command;
+ };
+ typedef Common::Array<NameAndCommand> NameAndCommandArray;
+ typedef Common::Array<IdAndCommand> IdAndCommandArray;
+ NameAndCommandArray _foundMacros;
+ IdAndCommandArray _foundStartups;
};
class EndBlockCommand : public Command {
Commit: f102667fc20d91149b685aac1bb5b05cabbc6e2b
https://github.com/scummvm/scummvm/commit/f102667fc20d91149b685aac1bb5b05cabbc6e2b
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add support for DEFINE_STRUCT script command.
Changed paths:
A engines/mutationofjb/commands/definestructcommand.cpp
A engines/mutationofjb/commands/definestructcommand.h
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/gamedata.h
engines/mutationofjb/gui.h
engines/mutationofjb/module.mk
engines/mutationofjb/script.cpp
engines/mutationofjb/widgets/conversationwidget.cpp
diff --git a/engines/mutationofjb/commands/definestructcommand.cpp b/engines/mutationofjb/commands/definestructcommand.cpp
new file mode 100644
index 0000000..ee15274
--- /dev/null
+++ b/engines/mutationofjb/commands/definestructcommand.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/definestructcommand.h"
+#include "mutationofjb/script.h"
+#include "mutationofjb/game.h"
+#include "common/debug.h"
+
+namespace MutationOfJB {
+
+bool DefineStructCommandParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) {
+ if (line.size() < 24 || !line.hasPrefix("DEFINE_STRUCT")) {
+ return false;
+ }
+
+ ConversationInfo convInfo;
+
+ const int numLines = atoi(line.c_str() + 14);
+ convInfo._context = atoi(line.c_str() + 18);
+ convInfo._objectId = atoi(line.c_str() + 20);
+ convInfo._color = Game::colorFromString(line.c_str() + 23);
+
+ for (int i = 0; i < numLines; ++i) {
+ Common::String convLineStr;
+ if (!parseCtx.readLine(convLineStr)) {
+ break;
+ }
+
+ if (convLineStr.size() != 74) {
+ debug("Conversation line in DEFINE_STRUCT with wrong length");
+ continue;
+ }
+
+ const char* linePtr = convLineStr.c_str();
+
+ ConversationInfo::Line convLine;
+
+ for (int j = 0; j < 5; ++j) {
+ ConversationInfo::Item convItem;
+ convItem._question = atoi(linePtr);
+ linePtr += 6;
+ convItem._response = atoi(linePtr);
+ linePtr += 6;
+ convItem._nextLineIndex = atoi(linePtr);
+ linePtr += 3;
+ convLine._items.push_back(convItem);
+ }
+ convInfo._lines.push_back(convLine);
+ }
+
+ command = new DefineStructCommand(convInfo);
+
+ return true;
+}
+
+Command::ExecuteResult DefineStructCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ scriptExecCtx.getGameData()._conversationInfo = _conversationInfo;
+ return Command::Finished;
+}
+
+Common::String DefineStructCommand::debugString() const {
+ return "DEFINE_STRUCT <data omitted>";
+}
+}
diff --git a/engines/mutationofjb/commands/definestructcommand.h b/engines/mutationofjb/commands/definestructcommand.h
new file mode 100644
index 0000000..13fc910
--- /dev/null
+++ b/engines/mutationofjb/commands/definestructcommand.h
@@ -0,0 +1,41 @@
+/* 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/seqcommand.h"
+#include "mutationofjb/gamedata.h"
+
+namespace MutationOfJB {
+
+class DefineStructCommandParser : public SeqCommandParser {
+public:
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
+};
+
+class DefineStructCommand : public SeqCommand {
+public:
+ DefineStructCommand(const ConversationInfo& convInfo) : _conversationInfo(convInfo) {}
+ virtual Command::ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
+ virtual Common::String debugString() const override;
+private:
+ ConversationInfo _conversationInfo;
+};
+}
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index d6ab622..a0f85b4 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -200,4 +200,29 @@ Font& Game::getSpeechFont() {
return _speechFont;
}
+uint8 Game::colorFromString(const char *colorStr) {
+ struct {
+ const char *str;
+ uint8 color;
+ } colors[] = {
+ {"white", WHITE},
+ {"dakrgray", DARKGRAY},
+ {"lightgray", LIGHTGRAY},
+ {"green", GREEN},
+ {"orange", ORANGE},
+ {"darkblue", DARKBLUE},
+ {"lightblue", LIGHTBLUE},
+ {"brown", BROWN}
+ };
+
+ for (int i = 0; i < ARRAYSIZE(colors); ++i) {
+ if (strcmp(colors[i].str, colorStr) == 0) {
+ return colors[i].color;
+ }
+ }
+
+ warning(_("Color not found"));
+ return 0x00;
+}
+
}
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index 122c2a1..4985a88 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -68,6 +68,8 @@ public:
Font& getSystemFont();
Font& getSpeechFont();
+ static uint8 colorFromString(const char *colorStr);
+
private:
bool loadGameData(bool partB);
void runActiveCommand();
diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h
index 321a688..22be9dd 100644
--- a/engines/mutationofjb/gamedata.h
+++ b/engines/mutationofjb/gamedata.h
@@ -161,6 +161,23 @@ struct Scene {
bool loadFromStream(Common::ReadStream &stream);
};
+struct ConversationInfo {
+ struct Item {
+ uint8 _question;
+ uint8 _response;
+ uint8 _nextLineIndex;
+ };
+
+ struct Line {
+ Common::Array<Item> _items;
+ };
+
+ Common::Array<Line> _lines;
+ uint8 _context;
+ uint8 _objectId;
+ uint8 _color;
+};
+
struct GameData {
public:
GameData();
@@ -175,10 +192,22 @@ public:
bool _partB;
Inventory _inventory;
Common::String _currentAPK;
+ ConversationInfo _conversationInfo;
private:
Scene _scenes[45];
};
+enum Colors {
+ WHITE = 0xC6,
+ DARKGRAY = 0xC2,
+ LIGHTGRAY = 0xC4,
+ GREEN = 0xC8,
+ ORANGE = 0xCA,
+ DARKBLUE = 0xD6,
+ LIGHTBLUE = 0xDA,
+ BROWN = 0xDC
+};
+
}
#endif
diff --git a/engines/mutationofjb/gui.h b/engines/mutationofjb/gui.h
index d8e1286..8919a9d 100644
--- a/engines/mutationofjb/gui.h
+++ b/engines/mutationofjb/gui.h
@@ -47,17 +47,6 @@ class ConversationWidget;
class Gui : public InventoryObserver, public ButtonWidgetCallback {
public:
- enum Colors {
- WHITE = 0xC6,
- DARKGRAY = 0xC2,
- LIGHTGRAY = 0xC4,
- GREEN = 0xC8,
- ORANGE = 0xCA,
- DARKBLUE = 0xD6,
- LIGHTBLUE = 0xDA,
- BROWN = 0xDC
- };
-
typedef Common::HashMap<Common::String, int> InventoryMap;
friend class InventoryAnimationDecoderCallback;
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 2fd4123..507ae39 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS := \
commands/changecommand.o \
commands/command.o \
commands/conditionalcommand.o \
+ commands/definestructcommand.o \
commands/endblockcommand.o \
commands/gotocommand.o \
commands/ifcommand.o \
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 1f5571f..321a5ba 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -43,6 +43,7 @@
#include "mutationofjb/commands/callmacrocommand.h"
#include "mutationofjb/commands/newroomcommand.h"
#include "mutationofjb/commands/renamecommand.h"
+#include "mutationofjb/commands/definestructcommand.h"
#include "mutationofjb/game.h"
namespace MutationOfJB {
@@ -59,6 +60,7 @@ static CommandParser **getParsers() {
new ChangeObjectCommandParser,
new ChangeStaticCommandParser,
new ChangeSceneCommandParser,
+ new DefineStructCommandParser,
new SayCommandParser,
new AddItemCommandParser,
new RemoveItemCommandParser,
diff --git a/engines/mutationofjb/widgets/conversationwidget.cpp b/engines/mutationofjb/widgets/conversationwidget.cpp
index 6196bc6..c609fb4 100644
--- a/engines/mutationofjb/widgets/conversationwidget.cpp
+++ b/engines/mutationofjb/widgets/conversationwidget.cpp
@@ -22,6 +22,7 @@
#include "mutationofjb/widgets/conversationwidget.h"
#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
#include "mutationofjb/gui.h"
#include "mutationofjb/font.h"
@@ -56,8 +57,8 @@ void ConversationWidget::_draw(Graphics::ManagedSurface &surface) {
continue;
}
- // TODO: Active line should be Gui::WHITE.
- _gui.getGame().getSystemFont().drawString(line, Gui::LIGHTGRAY, CONVERSATION_LINES_X, CONVERSATION_LINES_Y + i * CONVERSATION_LINE_HEIGHT, surface);
+ // TODO: Active line should be WHITE.
+ _gui.getGame().getSystemFont().drawString(line, LIGHTGRAY, CONVERSATION_LINES_X, CONVERSATION_LINES_Y + i * CONVERSATION_LINE_HEIGHT, surface);
}
}
Commit: 20d6d71ec97c1f7bc4b95ed6c98375b47dff6646
https://github.com/scummvm/scummvm/commit/20d6d71ec97c1f7bc4b95ed6c98375b47dff6646
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Basic conversation support.
Changed paths:
A engines/mutationofjb/assets.cpp
A engines/mutationofjb/assets.h
A engines/mutationofjb/commands/talkcommand.cpp
A engines/mutationofjb/commands/talkcommand.h
A engines/mutationofjb/conversationlinelist.cpp
A engines/mutationofjb/conversationlinelist.h
A engines/mutationofjb/tasks/conversationtask.cpp
A engines/mutationofjb/tasks/conversationtask.h
A engines/mutationofjb/tasks/task.h
A engines/mutationofjb/tasks/taskmanager.cpp
A engines/mutationofjb/tasks/taskmanager.h
engines/mutationofjb/commands/ifitemcommand.h
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/gamedata.h
engines/mutationofjb/gui.cpp
engines/mutationofjb/module.mk
engines/mutationofjb/script.cpp
engines/mutationofjb/util.cpp
engines/mutationofjb/util.h
engines/mutationofjb/widgets/conversationwidget.cpp
engines/mutationofjb/widgets/conversationwidget.h
diff --git a/engines/mutationofjb/assets.cpp b/engines/mutationofjb/assets.cpp
new file mode 100644
index 0000000..d532469
--- /dev/null
+++ b/engines/mutationofjb/assets.cpp
@@ -0,0 +1,45 @@
+/* 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/assets.h"
+
+namespace MutationOfJB {
+
+Assets::Assets(Game &game) : _game(game), _toSayList("tosay.ger"), _responseList("response.ger") {}
+
+Font& Assets::getSystemFont() {
+ return _systemFont;
+}
+
+Font& Assets::getSpeechFont() {
+ return _speechFont;
+}
+
+ConversationLineList &Assets::getToSayList() {
+ return _toSayList;
+}
+
+ConversationLineList &Assets::getResponseList() {
+ return _responseList;
+}
+
+}
diff --git a/engines/mutationofjb/assets.h b/engines/mutationofjb/assets.h
new file mode 100644
index 0000000..1d47641
--- /dev/null
+++ b/engines/mutationofjb/assets.h
@@ -0,0 +1,53 @@
+/* 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_ASSETS_H
+#define MUTATIONOFJB_ASSETS_H
+
+#include "mutationofjb/font.h"
+#include "mutationofjb/conversationlinelist.h"
+
+namespace MutationOfJB {
+
+class Game;
+
+class Assets {
+public:
+ Assets(Game &game);
+
+ Font& getSystemFont();
+ Font& getSpeechFont();
+
+ ConversationLineList& getToSayList();
+ ConversationLineList& getResponseList();
+
+private:
+ Game &_game;
+ SystemFont _systemFont;
+ SpeechFont _speechFont;
+ ConversationLineList _toSayList;
+ ConversationLineList _responseList;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/commands/ifitemcommand.h b/engines/mutationofjb/commands/ifitemcommand.h
index f11ba7c..df073b9 100644
--- a/engines/mutationofjb/commands/ifitemcommand.h
+++ b/engines/mutationofjb/commands/ifitemcommand.h
@@ -33,7 +33,7 @@ class ScriptParseContext;
class IfItemCommandParser : public ConditionalCommandParser {
public:
- virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
};
class IfItemCommand : public ConditionalCommand {
diff --git a/engines/mutationofjb/commands/talkcommand.cpp b/engines/mutationofjb/commands/talkcommand.cpp
new file mode 100644
index 0000000..d0775e4
--- /dev/null
+++ b/engines/mutationofjb/commands/talkcommand.cpp
@@ -0,0 +1,76 @@
+/* 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/talkcommand.h"
+#include "mutationofjb/tasks/conversationtask.h"
+#include "mutationofjb/script.h"
+#include "mutationofjb/game.h"
+#include "common/str.h"
+
+namespace MutationOfJB {
+
+bool TalkCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
+ if (line.size() < 11 || !line.hasPrefix("TALK TO HIM")) {
+ return false;
+ }
+
+ int modeInt = 0;
+
+ if (line.size() >= 13) {
+ modeInt = atoi(line.c_str() + 12);
+ }
+
+ TalkCommand::Mode mode = TalkCommand::NORMAL_MODE;
+
+ if (modeInt == 1) {
+ mode = TalkCommand::RAY_AND_BUTTLEG_MODE;
+ } else if (modeInt == 3) {
+ mode = TalkCommand::CARNIVAL_TICKET_SELLER_MODE;
+ }
+
+ command = new TalkCommand(mode);
+ return true;
+}
+
+Command::ExecuteResult TalkCommand::execute(ScriptExecutionContext &scriptExeCtx) {
+ if (!_task) {
+ _task = new ConversationTask(scriptExeCtx.getGame().getGameData()._conversationInfo);
+ scriptExeCtx.getGame().getTaskManager().addTask(_task);
+ }
+
+ if (_task->getState() == Task::FINISHED) {
+ scriptExeCtx.getGame().getTaskManager().removeTask(_task);
+ delete _task;
+ _task = nullptr;
+
+ return Command::Finished;
+ }
+
+ return Command::InProgress;
+}
+
+Common::String TalkCommand::debugString() const {
+ const char * modes[] = {"NORMAL", "RAY_AND_BUTTLEG", "CARNIVAL_TICKET_SELLER"};
+ return Common::String::format("TALK %s", modes[(int) _mode]);
+}
+
+}
diff --git a/engines/mutationofjb/commands/talkcommand.h b/engines/mutationofjb/commands/talkcommand.h
new file mode 100644
index 0000000..09424b2
--- /dev/null
+++ b/engines/mutationofjb/commands/talkcommand.h
@@ -0,0 +1,57 @@
+/* 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_TALKCOMMAND_H
+#define MUTATIONOFJB_TALKCOMMAND_H
+
+#include "mutationofjb/commands/seqcommand.h"
+#include "common/scummsys.h"
+
+namespace MutationOfJB {
+
+class ConversationTask;
+
+class TalkCommandParser : public SeqCommandParser {
+public:
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
+};
+
+class TalkCommand : public SeqCommand {
+public:
+ enum Mode {
+ NORMAL_MODE,
+ RAY_AND_BUTTLEG_MODE,
+ CARNIVAL_TICKET_SELLER_MODE
+ };
+
+ TalkCommand(Mode mode) : _mode(mode), _task(nullptr) {}
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
+ virtual Common::String debugString() const;
+
+private:
+ Mode _mode;
+ ConversationTask *_task;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/conversationlinelist.cpp b/engines/mutationofjb/conversationlinelist.cpp
new file mode 100644
index 0000000..562c2d0
--- /dev/null
+++ b/engines/mutationofjb/conversationlinelist.cpp
@@ -0,0 +1,91 @@
+/* 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/conversationlinelist.h"
+#include "mutationofjb/encryptedfile.h"
+#include "mutationofjb/util.h"
+
+namespace MutationOfJB {
+
+ConversationLineList::ConversationLineList(const Common::String &fileName) {
+ parseFile(fileName);
+}
+
+const ConversationLineList::Line *ConversationLineList::getLine(uint index) const {
+ if (index > _lines.size()) {
+ return nullptr;
+ }
+
+ return &_lines[index - 1];
+}
+
+bool ConversationLineList::parseFile(const Common::String &fileName) {
+ EncryptedFile file;
+ file.open(fileName);
+ if (!file.isOpen()) {
+ reportFileMissingError(fileName.c_str());
+ return false;
+ }
+
+ while (!file.eos()) {
+ Common::String lineStr = file.readLine();
+ if (lineStr.empty()) {
+ continue;
+ }
+
+ Line line;
+
+ Common::String::iterator endIt = Common::find(lineStr.begin(), lineStr.end(), '|');
+ if (endIt != lineStr.end()) {
+ Common::String extra = lineStr + endIt;
+ if (*endIt == 'X') {
+ line._extra = Common::String(endIt + 1, lineStr.end()); // Skip 'X' char.
+ }
+ }
+
+ Common::String::iterator startSpeechIt = lineStr.begin();
+ Common::String::iterator endSpeechIt = startSpeechIt;
+
+ while (startSpeechIt < endIt) {
+ endSpeechIt = Common::find(startSpeechIt, endIt, '\\');
+ Common::String::iterator voiceFileIt = Common::find(startSpeechIt, endSpeechIt, '<');
+ Speech speech;
+
+ if (voiceFileIt != endSpeechIt) {
+ if (*voiceFileIt == 'S') {
+ speech._voiceFile = Common::String(voiceFileIt + 1, endSpeechIt);
+ }
+ }
+
+ speech._text = Common::String(startSpeechIt, voiceFileIt);
+ line._speeches.push_back(speech);
+
+ startSpeechIt = endSpeechIt + 1;
+ }
+
+ _lines.push_back(line);
+ }
+
+ return true;
+}
+
+}
diff --git a/engines/mutationofjb/conversationlinelist.h b/engines/mutationofjb/conversationlinelist.h
new file mode 100644
index 0000000..9ec446e
--- /dev/null
+++ b/engines/mutationofjb/conversationlinelist.h
@@ -0,0 +1,58 @@
+/* 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_CONVERSATIONLINELIST_H
+#define MUTATIONOFJB_CONVERSATIONLINELIST_H
+
+#include "common/str.h"
+#include "common/array.h"
+
+namespace MutationOfJB {
+
+class ConversationLineList {
+public:
+ struct Speech {
+ Common::String _text;
+ Common::String _voiceFile;
+
+ bool isRepeating() const { return _text.firstChar() == '*'; }
+ bool isFirstSpeaker() const { return _text.firstChar() == '~'; }
+ bool isSecondSpeaker() const { return _text.firstChar() == '`'; }
+ };
+
+ struct Line {
+ Common::Array<Speech> _speeches;
+ Common::String _extra;
+ };
+
+ ConversationLineList(const Common::String &fileName);
+ const Line *getLine(uint index) const;
+
+private:
+ bool parseFile(const Common::String &fileName);
+
+ Common::Array<Line> _lines;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index a0f85b4..2415925 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -39,7 +39,9 @@ Game::Game(MutationOfJBEngine *vm)
_delayedLocalScript(nullptr),
_gui(*this, _vm->getScreen()),
_scriptExecCtx(*this),
- _currentAction(ActionInfo::Walk) {
+ _currentAction(ActionInfo::Walk),
+ _taskManager(*this),
+ _assets(*this) {
_gameData = new GameData;
loadGameData(false);
@@ -192,14 +194,6 @@ void Game::setCurrentAction(ActionInfo::Action action) {
_currentAction = action;
}
-Font& Game::getSystemFont() {
- return _systemFont;
-}
-
-Font& Game::getSpeechFont() {
- return _speechFont;
-}
-
uint8 Game::colorFromString(const char *colorStr) {
struct {
const char *str;
@@ -225,4 +219,12 @@ uint8 Game::colorFromString(const char *colorStr) {
return 0x00;
}
+TaskManager& Game::getTaskManager() {
+ return _taskManager;
+}
+
+Assets& Game::getAssets() {
+ return _assets;
+}
+
}
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index 4985a88..33527ae 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -24,9 +24,10 @@
#define MUTATIONOFJB_GAME_H
#include "common/scummsys.h"
-#include "mutationofjb/script.h"
-#include "mutationofjb/font.h"
+#include "mutationofjb/assets.h"
#include "mutationofjb/gui.h"
+#include "mutationofjb/script.h"
+#include "mutationofjb/tasks/taskmanager.h"
namespace Common {
class String;
@@ -65,11 +66,11 @@ public:
ActionInfo::Action getCurrentAction() const;
void setCurrentAction(ActionInfo::Action);
- Font& getSystemFont();
- Font& getSpeechFont();
-
static uint8 colorFromString(const char *colorStr);
+ TaskManager& getTaskManager();
+ Assets &getAssets();
+
private:
bool loadGameData(bool partB);
void runActiveCommand();
@@ -88,8 +89,8 @@ private:
ScriptExecutionContext _scriptExecCtx;
- SystemFont _systemFont;
- SpeechFont _speechFont;
+ TaskManager _taskManager;
+ Assets _assets;
};
}
diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h
index 22be9dd..d1bbc54 100644
--- a/engines/mutationofjb/gamedata.h
+++ b/engines/mutationofjb/gamedata.h
@@ -168,8 +168,9 @@ struct ConversationInfo {
uint8 _nextLineIndex;
};
+ typedef Common::Array<Item> Items;
struct Line {
- Common::Array<Item> _items;
+ Items _items;
};
Common::Array<Line> _lines;
diff --git a/engines/mutationofjb/gui.cpp b/engines/mutationofjb/gui.cpp
index 7102407..3c8cc66 100644
--- a/engines/mutationofjb/gui.cpp
+++ b/engines/mutationofjb/gui.cpp
@@ -132,19 +132,25 @@ bool Gui::init() {
void Gui::markDirty() {
for (Common::Array<Widget *>::iterator it = _widgets.begin(); it != _widgets.end(); ++it) {
- (*it)->markDirty();
+ if ((*it)->isVisible()) {
+ (*it)->markDirty();
+ }
}
}
void Gui::handleEvent(const Common::Event &event) {
for (Common::Array<Widget *>::iterator it = _widgets.begin(); it != _widgets.end(); ++it) {
- (*it)->handleEvent(event);
+ if ((*it)->isVisible()) {
+ (*it)->handleEvent(event);
+ }
}
}
void Gui::update() {
for (Common::Array<Widget *>::iterator it = _widgets.begin(); it != _widgets.end(); ++it) {
- (*it)->update(*_screen);
+ if ((*it)->isVisible()) {
+ (*it)->update(*_screen);
+ }
}
}
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 507ae39..89da245 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -20,12 +20,17 @@ MODULE_OBJS := \
commands/renamecommand.o \
commands/saycommand.o \
commands/seqcommand.o \
+ commands/talkcommand.o \
+ tasks/conversationtask.o \
+ tasks/taskmanager.o \
widgets/buttonwidget.o \
widgets/conversationwidget.o \
widgets/imagewidget.o \
widgets/inventorywidget.o \
widgets/widget.o \
animationdecoder.o \
+ assets.o \
+ conversationlinelist.o \
debug.o \
detection.o \
encryptedfile.o \
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 321a5ba..90146f6 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -44,6 +44,7 @@
#include "mutationofjb/commands/newroomcommand.h"
#include "mutationofjb/commands/renamecommand.h"
#include "mutationofjb/commands/definestructcommand.h"
+#include "mutationofjb/commands/talkcommand.h"
#include "mutationofjb/game.h"
namespace MutationOfJB {
@@ -62,6 +63,7 @@ static CommandParser **getParsers() {
new ChangeSceneCommandParser,
new DefineStructCommandParser,
new SayCommandParser,
+ new TalkCommandParser,
new AddItemCommandParser,
new RemoveItemCommandParser,
new RemoveAllItemsCommandParser,
diff --git a/engines/mutationofjb/tasks/conversationtask.cpp b/engines/mutationofjb/tasks/conversationtask.cpp
new file mode 100644
index 0000000..75d8504
--- /dev/null
+++ b/engines/mutationofjb/tasks/conversationtask.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/tasks/conversationtask.h"
+#include "mutationofjb/tasks/taskmanager.h"
+#include "mutationofjb/assets.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
+#include "mutationofjb/gui.h"
+#include "mutationofjb/util.h"
+#include "mutationofjb/widgets/conversationwidget.h"
+
+namespace MutationOfJB {
+
+void ConversationTask::start() {
+ Game &game = getTaskManager()->getGame();
+ ConversationWidget &widget = game.getGui().getConversationWidget();
+
+ widget.setCallback(this);
+ widget.setVisible(true);
+
+ updateWidget();
+}
+
+void ConversationTask::update() {
+}
+
+void ConversationTask::onResponseClicked(ConversationWidget *, int response) {
+
+ uint8 nextLineIndex = _convInfo._lines[_currentLine]._items[response]._nextLineIndex;
+ if (nextLineIndex == 0) {
+ setState(FINISHED);
+ Game &game = getTaskManager()->getGame();
+ ConversationWidget &widget = game.getGui().getConversationWidget();
+ widget.setVisible(false);
+ game.getGui().markDirty(); // TODO: Handle automatically when changing visibility.
+ return;
+ }
+
+ _currentLine = nextLineIndex - 1;
+ updateWidget();
+}
+
+void ConversationTask::updateWidget() {
+ Game &game = getTaskManager()->getGame();
+ ConversationWidget &widget = game.getGui().getConversationWidget();
+
+ const ConversationLineList& toSayList = game.getAssets().getToSayList();
+
+ const ConversationInfo::Line &convLine = _convInfo._lines[_currentLine];
+
+ for (ConversationInfo::Items::size_type i = 0; i < convLine._items.size(); ++i) {
+ Common::String widgetText;
+ const uint8 question = convLine._items[i]._question;
+ if (question != 0) {
+ const ConversationLineList::Line *line = toSayList.getLine(convLine._items[i]._question);
+ widgetText = toUpperCP895(line->_speeches[0]._text);
+ }
+
+ widget.setLine(i, widgetText);
+ }
+}
+
+}
diff --git a/engines/mutationofjb/tasks/conversationtask.h b/engines/mutationofjb/tasks/conversationtask.h
new file mode 100644
index 0000000..5cc0e5f
--- /dev/null
+++ b/engines/mutationofjb/tasks/conversationtask.h
@@ -0,0 +1,45 @@
+/* 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/tasks/task.h"
+#include "mutationofjb/gamedata.h"
+#include "mutationofjb/widgets/conversationwidget.h"
+
+namespace MutationOfJB {
+
+class ConversationTask : public Task, public ConversationWidgetCallback {
+public:
+ ConversationTask(const ConversationInfo& convInfo) : _convInfo(convInfo), _currentLine(0) {}
+ virtual ~ConversationTask() {}
+
+ virtual void start() override;
+ virtual void update() override;
+
+ virtual void onResponseClicked(ConversationWidget *, int response) override;
+private:
+ void updateWidget();
+
+ const ConversationInfo &_convInfo;
+ uint _currentLine;
+};
+
+}
diff --git a/engines/mutationofjb/tasks/task.h b/engines/mutationofjb/tasks/task.h
new file mode 100644
index 0000000..7b43868
--- /dev/null
+++ b/engines/mutationofjb/tasks/task.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.
+ *
+ */
+
+#include "common/scummsys.h"
+
+namespace MutationOfJB {
+
+class TaskManager;
+
+class Task {
+public:
+ enum State {
+ IDLE,
+ RUNNING,
+ FINISHED
+ };
+
+ Task() : _taskManager(nullptr) {}
+ virtual ~Task() {}
+
+ virtual void start() = 0;
+ virtual void update() = 0;
+
+ void setTaskManager(TaskManager *taskMan) { _taskManager = taskMan; }
+ TaskManager *getTaskManager() { return _taskManager; }
+
+ State getState() const { return _state; }
+
+protected:
+ void setState(State state) { _state = state; }
+
+private:
+ TaskManager *_taskManager;
+ State _state;
+};
+
+}
diff --git a/engines/mutationofjb/tasks/taskmanager.cpp b/engines/mutationofjb/tasks/taskmanager.cpp
new file mode 100644
index 0000000..9816549
--- /dev/null
+++ b/engines/mutationofjb/tasks/taskmanager.cpp
@@ -0,0 +1,47 @@
+/* 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/tasks/taskmanager.h"
+#include "mutationofjb/tasks/task.h"
+
+namespace MutationOfJB {
+
+void TaskManager::addTask(Task *task) {
+ _tasks.push_back(task);
+ task->setTaskManager(this);
+ task->start();
+}
+
+void TaskManager::removeTask(Task *task) {
+ Tasks::iterator it = Common::find(_tasks.begin(), _tasks.end(), task);
+ if (it != _tasks.end()) {
+ _tasks.erase(it);
+ }
+}
+
+void TaskManager::update() {
+ for (Tasks::const_iterator it = _tasks.begin(); it != _tasks.end(); ++it) {
+ (*it)->update();
+ }
+}
+
+}
diff --git a/engines/mutationofjb/tasks/taskmanager.h b/engines/mutationofjb/tasks/taskmanager.h
new file mode 100644
index 0000000..1f6be36
--- /dev/null
+++ b/engines/mutationofjb/tasks/taskmanager.h
@@ -0,0 +1,51 @@
+/* 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_TASKMANAGER_H
+#define MUTATIONOFJB_TASKMANAGER_H
+
+#include "common/array.h"
+
+namespace MutationOfJB {
+
+class Game;
+class Task;
+
+class TaskManager {
+public:
+ TaskManager(Game &game) : _game(game) {}
+
+ void addTask(Task *task);
+ void removeTask(Task *task);
+ void update();
+
+ Game &getGame() { return _game; }
+
+private:
+ typedef Common::Array<Task *> Tasks;
+ Tasks _tasks;
+ Game &_game;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/util.cpp b/engines/mutationofjb/util.cpp
index 1a56a62..6d7c02a 100644
--- a/engines/mutationofjb/util.cpp
+++ b/engines/mutationofjb/util.cpp
@@ -33,5 +33,27 @@ void reportFileMissingError(const char *fileName) {
warning("%s", errorMessage.c_str());
}
+Common::String toUpperCP895(const Common::String &str) {
+ static const byte conversionTable[] = {
+ 0x00, 0x9A, 0x90, 0x85, 0x8E, 0x00, 0x00, 0x80, 0x89, 0x00, 0x00, 0x00, 0x9C, 0x8A, 0x00, 0x00, /* 0x80-0x8F */
+ 0x00, 0x92, 0x00, 0xA7, 0x99, 0x00, 0xA6, 0x00, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, /* 0x90-0x9F */
+ 0x8F, 0x8B, 0x95, 0x97, 0xA5, 0x00, 0x00, 0x00, 0x9B, 0x9E, 0xAB, 0x00 /* 0xA0-0xAB */
+ };
+
+ Common::String ret = str;
+ for (Common::String::iterator it = ret.begin(); it != ret.end(); ++it) {
+ const byte cp895Byte = reinterpret_cast<const byte &>(*it);
+ if (cp895Byte < 0x80) {
+ *it = static_cast<char>(toupper(*it));
+ } else if (cp895Byte <= 0xAB) {
+ byte newChar = conversionTable[cp895Byte - 0x80];
+ if (newChar != 0) {
+ reinterpret_cast<byte &>(*it) = newChar;
+ }
+ }
+ }
+ return ret;
+}
+
}
diff --git a/engines/mutationofjb/util.h b/engines/mutationofjb/util.h
index 95a896d..86ee10f 100644
--- a/engines/mutationofjb/util.h
+++ b/engines/mutationofjb/util.h
@@ -23,9 +23,14 @@
#ifndef MUTATIONOFJB_UTIL_H
#define MUTATIONOFJB_UTIL_H
+namespace Common {
+class String;
+}
+
namespace MutationOfJB {
void reportFileMissingError(const char *fileName);
+Common::String toUpperCP895(const Common::String &str);
}
diff --git a/engines/mutationofjb/widgets/conversationwidget.cpp b/engines/mutationofjb/widgets/conversationwidget.cpp
index c609fb4..71a3483 100644
--- a/engines/mutationofjb/widgets/conversationwidget.cpp
+++ b/engines/mutationofjb/widgets/conversationwidget.cpp
@@ -25,6 +25,7 @@
#include "mutationofjb/gamedata.h"
#include "mutationofjb/gui.h"
#include "mutationofjb/font.h"
+#include "common/events.h"
namespace MutationOfJB {
@@ -36,7 +37,8 @@ enum {
ConversationWidget::ConversationWidget(Gui &gui, const Common::Rect &area, const Graphics::Surface &surface) :
Widget(gui, area),
- _surface(surface) {}
+ _surface(surface),
+ _callback(nullptr) {}
void ConversationWidget::setLine(int lineNo, const Common::String &str) {
@@ -58,7 +60,28 @@ void ConversationWidget::_draw(Graphics::ManagedSurface &surface) {
}
// TODO: Active line should be WHITE.
- _gui.getGame().getSystemFont().drawString(line, LIGHTGRAY, CONVERSATION_LINES_X, CONVERSATION_LINES_Y + i * CONVERSATION_LINE_HEIGHT, surface);
+ _gui.getGame().getAssets().getSystemFont().drawString(line, LIGHTGRAY, CONVERSATION_LINES_X, CONVERSATION_LINES_Y + i * CONVERSATION_LINE_HEIGHT, surface);
+ }
+}
+
+void ConversationWidget::handleEvent(const Common::Event &event) {
+ switch(event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ {
+ const int16 x = event.mouse.x;
+ const int16 y = event.mouse.y;
+ if (_area.contains(x, y)) {
+ if (_callback) {
+ int lineNum = (y - CONVERSATION_LINES_Y) / CONVERSATION_LINE_HEIGHT;
+ if (!_lines[lineNum].empty()) {
+ _callback->onResponseClicked(this, lineNum);
+ }
+ }
+ }
+ break;
+ }
+ default:
+ break;
}
}
diff --git a/engines/mutationofjb/widgets/conversationwidget.h b/engines/mutationofjb/widgets/conversationwidget.h
index 0f26a99..b404abc 100644
--- a/engines/mutationofjb/widgets/conversationwidget.h
+++ b/engines/mutationofjb/widgets/conversationwidget.h
@@ -28,21 +28,32 @@
namespace MutationOfJB {
+class ConversationWidget;
+
+class ConversationWidgetCallback {
+public:
+ virtual ~ConversationWidgetCallback() {}
+ virtual void onResponseClicked(ConversationWidget *, int response) = 0;
+};
+
class ConversationWidget : public Widget {
public:
enum { CONVERSATION_LINES = 4 };
ConversationWidget(Gui &gui, const Common::Rect &area, const Graphics::Surface &surface);
+ void setCallback(ConversationWidgetCallback *callback) { _callback = callback; }
void setLine(int lineNo, const Common::String &str);
+ virtual void handleEvent(const Common::Event &event) override;
+
protected:
- void _draw(Graphics::ManagedSurface &surface);
+ virtual void _draw(Graphics::ManagedSurface &surface) override;
private:
-
Graphics::Surface _surface;
Common::String _lines[CONVERSATION_LINES];
+ ConversationWidgetCallback *_callback;
};
}
Commit: d2e354b51f637dc2e9b251256b5a017cb41cfe59
https://github.com/scummvm/scummvm/commit/d2e354b51f637dc2e9b251256b5a017cb41cfe59
Author: Miroslav Remák (miroslavr256 at gmail.com)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Implement scroll buttons.
Changed paths:
engines/mutationofjb/gui.cpp
engines/mutationofjb/inventory.cpp
engines/mutationofjb/inventory.h
diff --git a/engines/mutationofjb/gui.cpp b/engines/mutationofjb/gui.cpp
index 3c8cc66..41ef94a 100644
--- a/engines/mutationofjb/gui.cpp
+++ b/engines/mutationofjb/gui.cpp
@@ -251,6 +251,10 @@ void Gui::onButtonClicked(ButtonWidget *button) {
if (buttonId <= BUTTON_PICKUP) {
const ActionInfo::Action actions[] = {ActionInfo::Walk, ActionInfo::Talk, ActionInfo::Look, ActionInfo::Use, ActionInfo::PickUp};
_game.setCurrentAction(actions[buttonId]);
+ } else if (buttonId == BUTTON_SCROLL_LEFT) {
+ _game.getGameData().getInventory().scrollLeft();
+ } else if (buttonId == BUTTON_SCROLL_RIGHT) {
+ _game.getGameData().getInventory().scrollRight();
}
}
diff --git a/engines/mutationofjb/inventory.cpp b/engines/mutationofjb/inventory.cpp
index 2fa7f2c..2d7ba28 100644
--- a/engines/mutationofjb/inventory.cpp
+++ b/engines/mutationofjb/inventory.cpp
@@ -81,6 +81,18 @@ void Inventory::renameItem(const Common::String &oldName, const Common::String &
}
}
+void Inventory::scrollLeft() {
+ if (_items.size() > VISIBLE_ITEMS) {
+ rotateItemsRight(1);
+ }
+}
+
+void Inventory::scrollRight() {
+ if (_items.size() > VISIBLE_ITEMS) {
+ rotateItemsLeft(1);
+ }
+}
+
void Inventory::rotateItemsRight(uint n) {
if (_items.size() < 2) {
return;
@@ -121,7 +133,7 @@ void Inventory::reverseItems(uint from, uint to) {
const uint size = to - from + 1;
for (uint i = 0; i < size / 2; ++i) {
- SWAP(_items[i], _items[size - i - 1]);
+ SWAP(_items[from + i], _items[to - i]);
}
}
diff --git a/engines/mutationofjb/inventory.h b/engines/mutationofjb/inventory.h
index c22422d..79a0d75 100644
--- a/engines/mutationofjb/inventory.h
+++ b/engines/mutationofjb/inventory.h
@@ -52,12 +52,14 @@ public:
void removeAllItems();
void renameItem(const Common::String &oldName, const Common::String &newName);
- void rotateItemsRight(uint n);
- void rotateItemsLeft(uint n);
+ void scrollLeft();
+ void scrollRight();
void setObserver(InventoryObserver *observer);
private:
+ void rotateItemsRight(uint n);
+ void rotateItemsLeft(uint n);
void reverseItems(uint from, uint to);
Items _items;
Commit: febff83a4edc89e1dbc6f4c56f5531f0eb8f3287
https://github.com/scummvm/scummvm/commit/febff83a4edc89e1dbc6f4c56f5531f0eb8f3287
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Draw objects (first frame only) and improve conversation support.
Changed paths:
A engines/mutationofjb/tasks/saytask.cpp
A engines/mutationofjb/tasks/saytask.h
A engines/mutationofjb/timer.cpp
A engines/mutationofjb/timer.h
engines/mutationofjb/commands/definestructcommand.cpp
engines/mutationofjb/commands/talkcommand.cpp
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/gamedata.cpp
engines/mutationofjb/gamedata.h
engines/mutationofjb/module.mk
engines/mutationofjb/room.cpp
engines/mutationofjb/room.h
engines/mutationofjb/tasks/conversationtask.cpp
engines/mutationofjb/tasks/conversationtask.h
engines/mutationofjb/tasks/task.h
engines/mutationofjb/tasks/taskmanager.cpp
engines/mutationofjb/widgets/conversationwidget.cpp
engines/mutationofjb/widgets/conversationwidget.h
diff --git a/engines/mutationofjb/commands/definestructcommand.cpp b/engines/mutationofjb/commands/definestructcommand.cpp
index ee15274..93dbfc8 100644
--- a/engines/mutationofjb/commands/definestructcommand.cpp
+++ b/engines/mutationofjb/commands/definestructcommand.cpp
@@ -56,7 +56,7 @@ bool DefineStructCommandParser::parse(const Common::String &line, ScriptParseCon
for (int j = 0; j < 5; ++j) {
ConversationInfo::Item convItem;
- convItem._question = atoi(linePtr);
+ convItem._choice = atoi(linePtr);
linePtr += 6;
convItem._response = atoi(linePtr);
linePtr += 6;
diff --git a/engines/mutationofjb/commands/talkcommand.cpp b/engines/mutationofjb/commands/talkcommand.cpp
index d0775e4..18ce956 100644
--- a/engines/mutationofjb/commands/talkcommand.cpp
+++ b/engines/mutationofjb/commands/talkcommand.cpp
@@ -21,9 +21,12 @@
*/
#include "mutationofjb/commands/talkcommand.h"
-#include "mutationofjb/tasks/conversationtask.h"
-#include "mutationofjb/script.h"
+
#include "mutationofjb/game.h"
+#include "mutationofjb/script.h"
+#include "mutationofjb/tasks/conversationtask.h"
+#include "mutationofjb/tasks/taskmanager.h"
+
#include "common/str.h"
namespace MutationOfJB {
@@ -53,7 +56,7 @@ bool TalkCommandParser::parse(const Common::String &line, ScriptParseContext &,
Command::ExecuteResult TalkCommand::execute(ScriptExecutionContext &scriptExeCtx) {
if (!_task) {
- _task = new ConversationTask(scriptExeCtx.getGame().getGameData()._conversationInfo);
+ _task = new ConversationTask(scriptExeCtx.getGameData()._currentScene, scriptExeCtx.getGame().getGameData()._conversationInfo);
scriptExeCtx.getGame().getTaskManager().addTask(_task);
}
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 2415925..69647f2 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -100,7 +100,9 @@ Script *Game::changeSceneLoadScript(uint8 sceneId, bool partB) {
_gameData->_lastScene = _gameData->_currentScene;
_gameData->_currentScene = sceneId;
_gameData->_partB = partB;
+
_room->load(_gameData->_currentScene, partB);
+ _room->redraw();
EncryptedFile scriptFile;
Common::String fileName = Common::String::format("scrn%d%s.atn", sceneId, partB ? "b" : "");
@@ -180,6 +182,7 @@ void Game::update() {
}
_gui.update();
+ _taskManager.update();
}
Gui &Game::getGui() {
@@ -227,4 +230,9 @@ Assets& Game::getAssets() {
return _assets;
}
+Graphics::Screen &Game::getScreen()
+{
+ return *_vm->getScreen();
+}
+
}
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index 33527ae..056cffb 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -71,6 +71,8 @@ public:
TaskManager& getTaskManager();
Assets &getAssets();
+ Graphics::Screen &getScreen();
+
private:
bool loadGameData(bool partB);
void runActiveCommand();
diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp
index 1ece44c..6a9c166 100644
--- a/engines/mutationofjb/gamedata.cpp
+++ b/engines/mutationofjb/gamedata.cpp
@@ -136,7 +136,11 @@ bool Scene::loadFromStream(Common::ReadStream &stream) {
_palRotStart = stream.readByte();
_palRotEnd = stream.readByte();
_palRotPeriod = stream.readByte();
- stream.read(_unknown38A, 80);
+ _exhaustedChoiceNext = stream.readByte();
+
+ for (i = 0; i < 79; ++i) {
+ _exhaustedChoices[i]._encodedData = stream.readByte();
+ }
return true;
}
@@ -222,6 +226,22 @@ Bitmap *Scene::findBitmap(int16 x, int16 y, int *index) {
return nullptr;
}
+void Scene::addExhaustedChoice(uint8 context, uint8 choiceIndex, uint8 choiceIndexList) {
+ _exhaustedChoices[_exhaustedChoiceNext - 1] = ExhaustedChoice(context, choiceIndex, choiceIndexList);
+ _exhaustedChoiceNext++;
+}
+
+bool Scene::isChoiceExhausted(uint8 context, uint8 choiceIndex, uint8 choiceListIndex) const {
+ for (uint i = 0; i < _exhaustedChoiceNext - 1; ++i) {
+ const ExhaustedChoice &choice = _exhaustedChoices[i];
+ if (choice.getContext() == context && choice.getChoiceIndex() == choiceIndex && choice.getChoiceListIndex() == choiceListIndex) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
GameData::GameData()
: _currentScene(0),
diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h
index d1bbc54..62c66a1 100644
--- a/engines/mutationofjb/gamedata.h
+++ b/engines/mutationofjb/gamedata.h
@@ -121,6 +121,22 @@ struct Bitmap {
bool loadFromStream(Common::ReadStream &stream);
};
+struct ExhaustedChoice {
+ /*
+ 1 bit - context
+ 3 bits - choice index
+ 4 bits - choice list index
+ */
+ uint8 _encodedData;
+
+ uint8 getContext() const { return (_encodedData >> 7) & 0x1; }
+ uint8 getChoiceIndex() const { return (_encodedData >> 4) & 0x7; }
+ uint8 getChoiceListIndex() const { return _encodedData & 0xF; }
+
+ ExhaustedChoice() : _encodedData(0) {}
+ ExhaustedChoice(uint8 context, uint8 choiceIndex, uint8 choiceListIndex) :
+ _encodedData(((context & 0x1) << 7) | ((choiceIndex & 0x7) << 4) | (choiceListIndex & 0xF)) {}
+};
struct Scene {
Door *getDoor(uint8 objectId);
@@ -135,6 +151,9 @@ struct Scene {
Static *findStatic(int16 x, int16 y, int *index = nullptr);
Bitmap *findBitmap(int16 x, int16 y, int *index = nullptr);
+ void addExhaustedChoice(uint8 context, uint8 choiceIndex, uint8 choiceIndexList);
+ bool isChoiceExhausted(uint8 context, uint8 choiceIndex, uint8 choiceIndexList) const;
+
uint8 _startup;
uint8 _unknown001;
uint8 _unknown002;
@@ -156,14 +175,17 @@ struct Scene {
uint8 _palRotStart;
uint8 _palRotEnd;
uint8 _palRotPeriod;
- uint8 _unknown38A[80];
+
+ /* Points to the first free item in exhausted choices list. */
+ uint8 _exhaustedChoiceNext;
+ ExhaustedChoice _exhaustedChoices[79];
bool loadFromStream(Common::ReadStream &stream);
};
struct ConversationInfo {
struct Item {
- uint8 _question;
+ uint8 _choice;
uint8 _response;
uint8 _nextLineIndex;
};
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 89da245..f3a1d78 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -22,6 +22,7 @@ MODULE_OBJS := \
commands/seqcommand.o \
commands/talkcommand.o \
tasks/conversationtask.o \
+ tasks/saytask.o \
tasks/taskmanager.o \
widgets/buttonwidget.o \
widgets/conversationwidget.o \
@@ -42,6 +43,7 @@ MODULE_OBJS := \
mutationofjb.o \
room.o \
script.o \
+ timer.o \
util.o
# This module can be built as a plugin
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
index 62af983..5577077 100644
--- a/engines/mutationofjb/room.cpp
+++ b/engines/mutationofjb/room.cpp
@@ -21,17 +21,25 @@
*/
#include "mutationofjb/room.h"
+
#include "mutationofjb/animationdecoder.h"
#include "mutationofjb/encryptedfile.h"
#include "mutationofjb/game.h"
#include "mutationofjb/gamedata.h"
#include "mutationofjb/util.h"
+
#include "common/str.h"
#include "common/translation.h"
+
#include "graphics/screen.h"
namespace MutationOfJB {
+enum {
+ GAME_AREA_WIDTH = 320,
+ GAME_AREA_HEIGHT = 139
+};
+
class RoomAnimationDecoderCallback : public AnimationDecoderCallback {
public:
RoomAnimationDecoderCallback(Room &room) : _room(room) {}
@@ -47,9 +55,11 @@ void RoomAnimationDecoderCallback::onPaletteUpdated(byte palette[PALETTE_SIZE])
void RoomAnimationDecoderCallback::onFrame(int frameNo, Graphics::Surface &surface) {
if (frameNo == 0) {
- Common::Rect rect(0, 0, 320, 139);
+ Common::Rect rect(0, 0, GAME_AREA_WIDTH, GAME_AREA_HEIGHT);
if (_room._game->isCurrentSceneMap()) {
rect = Common::Rect(0, 0, 320, 200);
+ } else {
+ _room._background.blitFrom(surface, rect, Common::Point(0, 0));
}
_room._screen->blitFrom(surface, rect, Common::Point(0, 0));
}
@@ -78,10 +88,11 @@ void RoomAnimationDecoderCallback::onFrame(int frameNo, Graphics::Surface &surfa
}
}
-Room::Room(Game *game, Graphics::Screen *screen) : _game(game), _screen(screen) {}
+Room::Room(Game *game, Graphics::Screen *screen) : _game(game), _screen(screen), _background(GAME_AREA_WIDTH, GAME_AREA_HEIGHT) {}
bool Room::load(uint8 roomNumber, bool roomB) {
_objectsStart.clear();
+ _surfaces.clear(); // TODO: Fix memory leak.
Scene *const scene = _game->getGameData().getCurrentScene();
if (scene) {
@@ -118,7 +129,23 @@ void Room::drawObjectAnimation(uint8 objectId, int animOffset) {
const int startFrame = _objectsStart[objectId - 1];
const int animFrame = startFrame + animOffset;
+ // TODO: Threshold.
_screen->blitFrom(_surfaces[animFrame], Common::Point(object->_x, object->_y));
}
+void Room::redraw() {
+ if (!_game->isCurrentSceneMap()) {
+ Common::Rect rect(0, 0, GAME_AREA_WIDTH, GAME_AREA_HEIGHT);
+ _screen->blitFrom(_background.rawSurface(), rect, Common::Point(0, 0));
+
+ Scene *const currentScene = _game->getGameData().getCurrentScene();
+ for (int i = 0; i < currentScene->getNoObjects(); ++i) {
+ Object *const obj = currentScene->getObject(i + 1);
+ if (obj->_AC) {
+ drawObjectAnimation(i + 1, 0);
+ }
+ }
+ }
+}
+
}
diff --git a/engines/mutationofjb/room.h b/engines/mutationofjb/room.h
index e57d2eb..083fba6 100644
--- a/engines/mutationofjb/room.h
+++ b/engines/mutationofjb/room.h
@@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "common/array.h"
#include "graphics/surface.h"
+#include "graphics/managed_surface.h"
namespace Graphics {
class Screen;
@@ -44,9 +45,11 @@ public:
Room(Game *game, Graphics::Screen *screen);
bool load(uint8 roomNumber, bool roomB);
void drawObjectAnimation(uint8 objectId, int animOffset);
+ void redraw();
private:
Game *_game;
Graphics::Screen *_screen;
+ Graphics::ManagedSurface _background;
Common::Array<Graphics::Surface> _surfaces;
Common::Array<int> _objectsStart;
};
diff --git a/engines/mutationofjb/tasks/conversationtask.cpp b/engines/mutationofjb/tasks/conversationtask.cpp
index 75d8504..512b38b 100644
--- a/engines/mutationofjb/tasks/conversationtask.cpp
+++ b/engines/mutationofjb/tasks/conversationtask.cpp
@@ -21,63 +21,186 @@
*/
#include "mutationofjb/tasks/conversationtask.h"
-#include "mutationofjb/tasks/taskmanager.h"
+
#include "mutationofjb/assets.h"
+#include "mutationofjb/conversationlinelist.h"
#include "mutationofjb/game.h"
#include "mutationofjb/gamedata.h"
#include "mutationofjb/gui.h"
+#include "mutationofjb/tasks/saytask.h"
+#include "mutationofjb/tasks/taskmanager.h"
#include "mutationofjb/util.h"
#include "mutationofjb/widgets/conversationwidget.h"
namespace MutationOfJB {
void ConversationTask::start() {
+ setState(RUNNING);
+
Game &game = getTaskManager()->getGame();
ConversationWidget &widget = game.getGui().getConversationWidget();
widget.setCallback(this);
widget.setVisible(true);
- updateWidget();
+ _currentLineIndex = 0;
+
+ showChoicesOrPick();
}
void ConversationTask::update() {
-}
+ if (_sayTask) {
+ if (_sayTask->getState() == Task::FINISHED) {
+ getTaskManager()->removeTask(_sayTask);
+ delete _sayTask;
+ _sayTask = nullptr;
-void ConversationTask::onResponseClicked(ConversationWidget *, int response) {
+ switch (_substate) {
+ case SAYING_NO_CHOICES:
+ finish();
+ break;
+ case SAYING_CHOICE: {
+ const ConversationLineList& responseList = getTaskManager()->getGame().getAssets().getResponseList();
+ const ConversationLineList::Line *const line = responseList.getLine(_currentItem->_response);
- uint8 nextLineIndex = _convInfo._lines[_currentLine]._items[response]._nextLineIndex;
- if (nextLineIndex == 0) {
- setState(FINISHED);
- Game &game = getTaskManager()->getGame();
- ConversationWidget &widget = game.getGui().getConversationWidget();
- widget.setVisible(false);
- game.getGui().markDirty(); // TODO: Handle automatically when changing visibility.
- return;
+ _sayTask = new SayTask(line->_speeches[0]._text, _convInfo._color);
+ getTaskManager()->addTask(_sayTask);
+ _substate = SAYING_RESPONSE;
+ break;
+ }
+ case SAYING_RESPONSE: {
+ if (_currentItem->_nextLineIndex == 0) {
+ finish();
+ } else {
+ _currentLineIndex = _currentItem->_nextLineIndex - 1;
+ showChoicesOrPick();
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
}
+}
- _currentLine = nextLineIndex - 1;
- updateWidget();
+void ConversationTask::onChoiceClicked(ConversationWidget *convWidget, int, uint32 data) {
+ const ConversationInfo::Item &item = getCurrentLine()->_items[data];
+ convWidget->clearChoices();
+
+ const ConversationLineList& toSayList = getTaskManager()->getGame().getAssets().getToSayList();
+ _sayTask = new SayTask(toSayList.getLine(item._choice)->_speeches[0]._text, _convInfo._color);
+ getTaskManager()->addTask(_sayTask);
+ _substate = SAYING_CHOICE;
+ _currentItem = &item;
+ getTaskManager()->getGame().getGameData().getCurrentScene()->addExhaustedChoice(_convInfo._context, data + 1, _currentLineIndex + 1);
}
-void ConversationTask::updateWidget() {
+void ConversationTask::showChoicesOrPick() {
Game &game = getTaskManager()->getGame();
- ConversationWidget &widget = game.getGui().getConversationWidget();
+ GameData &gameData = game.getGameData();
+ Scene *const scene = gameData.getScene(_sceneId);
+
+ Common::Array<uint32> itemsWithValidChoices;
+ Common::Array<uint32> itemsWithValidResponses;
+ Common::Array<uint32> itemsWithValidNext;
+
+ /*
+ Collect valid "to say" choices (not exhausted and not empty).
+ Collect valid responses (not exhausted and not empty).
+ If there are at least two visible choices, we show them.
+ If there is just one visible choice, pick it automatically.
+ If there are no visible choices, automatically pick first valid response.
+ */
+
+ const ConversationInfo::Line *const currentLine = getCurrentLine();
+ for (ConversationInfo::Items::size_type i = 0; i < currentLine->_items.size(); ++i) {
+ const ConversationInfo::Item &item = currentLine->_items[i];
+
+ if (scene->isChoiceExhausted(_convInfo._context, (uint8) i + 1, (uint8) _currentLineIndex + 1)) {
+ continue;
+ }
+ const uint8 choice = item._choice;
+ const uint8 response = item._response;
+ const uint8 next = item._nextLineIndex;
+
+ if (choice != 0) {
+ itemsWithValidChoices.push_back(i);
+ }
- const ConversationLineList& toSayList = game.getAssets().getToSayList();
+ if (response != 0) {
+ itemsWithValidResponses.push_back(i);
+ }
- const ConversationInfo::Line &convLine = _convInfo._lines[_currentLine];
+ if (next != 0) {
+ itemsWithValidNext.push_back(i);
+ }
+ }
+
+ if (itemsWithValidChoices.size() > 1) {
+ ConversationWidget &widget = game.getGui().getConversationWidget();
+ const ConversationLineList& toSayList = game.getAssets().getToSayList();
- for (ConversationInfo::Items::size_type i = 0; i < convLine._items.size(); ++i) {
- Common::String widgetText;
- const uint8 question = convLine._items[i]._question;
- if (question != 0) {
- const ConversationLineList::Line *line = toSayList.getLine(convLine._items[i]._question);
- widgetText = toUpperCP895(line->_speeches[0]._text);
+ for (Common::Array<uint32>::size_type i = 0; i < itemsWithValidChoices.size() && i < ConversationWidget::CONVERSATION_MAX_CHOICES; ++i) {
+ const ConversationInfo::Item &item = currentLine->_items[itemsWithValidChoices[i]];
+ const ConversationLineList::Line *const line = toSayList.getLine(item._choice);
+ const Common::String widgetText = toUpperCP895(line->_speeches[0]._text);
+ widget.setChoice((int) i, widgetText, itemsWithValidChoices[i]);
}
+ _substate = IDLE;
+ _currentItem = nullptr;
+
+ _haveChoices = true;
+ } else if (itemsWithValidChoices.size() == 1) {
+ const ConversationLineList& toSayList = game.getAssets().getToSayList();
+ const ConversationInfo::Item &item = currentLine->_items[itemsWithValidChoices.front()];
+ const ConversationLineList::Line *const line = toSayList.getLine(item._choice);
+
+ _sayTask = new SayTask(line->_speeches[0]._text, _convInfo._color);
+ getTaskManager()->addTask(_sayTask);
+ _substate = SAYING_CHOICE;
+ _currentItem = &item;
+
+ game.getGameData().getCurrentScene()->addExhaustedChoice(_convInfo._context, itemsWithValidChoices.front() + 1, _currentLineIndex + 1);
+
+ _haveChoices = true;
+ } else if (!itemsWithValidResponses.empty()) {
+ const ConversationLineList& responseList = game.getAssets().getResponseList();
+ const ConversationInfo::Item &item = currentLine->_items[itemsWithValidResponses.front()];
+ const ConversationLineList::Line *const line = responseList.getLine(item._response);
- widget.setLine(i, widgetText);
+ _sayTask = new SayTask(line->_speeches[0]._text, _convInfo._color);
+ getTaskManager()->addTask(_sayTask);
+ _substate = SAYING_RESPONSE;
+ _currentItem = &item;
+
+ _haveChoices = true;
+ } else if (!itemsWithValidNext.empty()) {
+ _currentLineIndex = currentLine->_items[itemsWithValidNext.front()]._nextLineIndex - 1;
+ showChoicesOrPick();
+ } else {
+ if (_haveChoices) {
+ finish();
+ } else {
+ _sayTask = new SayTask("Nothing to talk about.", _convInfo._color); // TODO: This is hardcoded in executable. Load it.
+ getTaskManager()->addTask(_sayTask);
+ _substate = SAYING_NO_CHOICES;
+ _currentItem = nullptr;
+ }
}
}
+const ConversationInfo::Line *ConversationTask::getCurrentLine() const {
+ return &_convInfo._lines[_currentLineIndex];
+}
+
+void ConversationTask::finish() {
+ setState(FINISHED);
+
+ Game &game = getTaskManager()->getGame();
+ ConversationWidget &widget = game.getGui().getConversationWidget();
+ widget.setVisible(false);
+ game.getGui().markDirty(); // TODO: Handle automatically when changing visibility.
+}
+
}
diff --git a/engines/mutationofjb/tasks/conversationtask.h b/engines/mutationofjb/tasks/conversationtask.h
index 5cc0e5f..3bcbb6f 100644
--- a/engines/mutationofjb/tasks/conversationtask.h
+++ b/engines/mutationofjb/tasks/conversationtask.h
@@ -26,20 +26,37 @@
namespace MutationOfJB {
+class SayTask;
+
class ConversationTask : public Task, public ConversationWidgetCallback {
public:
- ConversationTask(const ConversationInfo& convInfo) : _convInfo(convInfo), _currentLine(0) {}
+ ConversationTask(uint8 sceneId, const ConversationInfo& convInfo) : _sceneId(sceneId), _convInfo(convInfo), _currentLineIndex(0), _currentItem(nullptr), _sayTask(nullptr), _substate(IDLE), _haveChoices(false) {}
virtual ~ConversationTask() {}
virtual void start() override;
virtual void update() override;
- virtual void onResponseClicked(ConversationWidget *, int response) override;
+ virtual void onChoiceClicked(ConversationWidget *, int response, uint32 data) override;
private:
- void updateWidget();
+ void showChoicesOrPick();
+ const ConversationInfo::Line *getCurrentLine() const;
+ void finish();
+ uint8 _sceneId;
const ConversationInfo &_convInfo;
- uint _currentLine;
+ uint _currentLineIndex;
+ const ConversationInfo::Item *_currentItem;
+ SayTask* _sayTask;
+
+ enum Substate {
+ IDLE,
+ SAYING_CHOICE,
+ SAYING_RESPONSE,
+ SAYING_NO_CHOICES
+ };
+
+ Substate _substate;
+ bool _haveChoices;
};
}
diff --git a/engines/mutationofjb/tasks/saytask.cpp b/engines/mutationofjb/tasks/saytask.cpp
new file mode 100644
index 0000000..2ef4cdf
--- /dev/null
+++ b/engines/mutationofjb/tasks/saytask.cpp
@@ -0,0 +1,55 @@
+/* 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/tasks/saytask.h"
+
+#include "mutationofjb/tasks/taskmanager.h"
+#include "mutationofjb/assets.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
+#include "mutationofjb/room.h"
+
+#include "graphics/managed_surface.h"
+#include "graphics/screen.h"
+
+namespace MutationOfJB {
+
+SayTask::SayTask(const Common::String &toSay, uint8 color) : _toSay(toSay), _color(color), _timer(1000) {}
+
+void SayTask::start() {
+
+ getTaskManager()->getGame().getAssets().getSpeechFont().drawString(_toSay, _color, 0, 0, getTaskManager()->getGame().getScreen());
+ _timer.start();
+ setState(RUNNING);
+}
+
+void SayTask::update() {
+ _timer.update();
+
+ if (_timer.isFnished()) {
+ getTaskManager()->getGame().getRoom().redraw(); // TODO: Only redraw the area occupied by the text.
+ setState(FINISHED);
+ return;
+ }
+}
+
+}
diff --git a/engines/mutationofjb/tasks/saytask.h b/engines/mutationofjb/tasks/saytask.h
new file mode 100644
index 0000000..a7ac96d
--- /dev/null
+++ b/engines/mutationofjb/tasks/saytask.h
@@ -0,0 +1,44 @@
+/* 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/tasks/task.h"
+
+#include "mutationofjb/timer.h"
+
+#include "common/str.h"
+
+namespace MutationOfJB {
+
+class SayTask : public Task {
+public:
+ SayTask(const Common::String &toSay, uint8 color);
+
+ virtual void start() override;
+ virtual void update() override;
+
+private:
+ Common::String _toSay;
+ uint8 _color;
+ Timer _timer;
+};
+
+}
diff --git a/engines/mutationofjb/tasks/task.h b/engines/mutationofjb/tasks/task.h
index 7b43868..1b98097 100644
--- a/engines/mutationofjb/tasks/task.h
+++ b/engines/mutationofjb/tasks/task.h
@@ -20,6 +20,9 @@
*
*/
+#ifndef MUTATIONOFJB_TASK_H
+#define MUTATIONOFJB_TASK_H
+
#include "common/scummsys.h"
namespace MutationOfJB {
@@ -54,3 +57,5 @@ private:
};
}
+
+#endif
diff --git a/engines/mutationofjb/tasks/taskmanager.cpp b/engines/mutationofjb/tasks/taskmanager.cpp
index 9816549..7fbf64d 100644
--- a/engines/mutationofjb/tasks/taskmanager.cpp
+++ b/engines/mutationofjb/tasks/taskmanager.cpp
@@ -40,7 +40,9 @@ void TaskManager::removeTask(Task *task) {
void TaskManager::update() {
for (Tasks::const_iterator it = _tasks.begin(); it != _tasks.end(); ++it) {
- (*it)->update();
+ if ((*it)->getState() == Task::RUNNING) {
+ (*it)->update();
+ }
}
}
diff --git a/engines/mutationofjb/timer.cpp b/engines/mutationofjb/timer.cpp
new file mode 100644
index 0000000..8375445
--- /dev/null
+++ b/engines/mutationofjb/timer.cpp
@@ -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.
+ *
+ */
+
+#include "mutationofjb/timer.h"
+
+#include "common/system.h"
+
+namespace MutationOfJB {
+
+Timer::Timer(uint32 millis) : _millis(millis), _startTime(0), _state(IDLE) {
+}
+
+void Timer::start() {
+ _startTime = g_system->getMillis();
+ _state = RUNNING;
+}
+
+bool Timer::isFnished() const {
+ return _state == FINISHED;
+}
+
+bool Timer::isRunning() const {
+ return _state == RUNNING;
+}
+
+void Timer::update() {
+ if (_state != RUNNING) {
+ return;
+ }
+
+ uint32 currentTime = g_system->getMillis();
+ if (currentTime - _startTime >= _millis) {
+ _state = FINISHED;
+ }
+}
+
+}
diff --git a/engines/mutationofjb/timer.h b/engines/mutationofjb/timer.h
new file mode 100644
index 0000000..b12fe22
--- /dev/null
+++ b/engines/mutationofjb/timer.h
@@ -0,0 +1,50 @@
+/* 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 "common/scummsys.h"
+
+namespace MutationOfJB {
+
+class Timer {
+public:
+ Timer(uint32 millis);
+
+ void start();
+
+ bool isFnished() const;
+ bool isRunning() const;
+
+ void update();
+
+private:
+ enum State {
+ IDLE,
+ RUNNING,
+ FINISHED
+ };
+
+ uint32 _millis;
+ uint32 _startTime;
+ State _state;
+};
+
+}
diff --git a/engines/mutationofjb/widgets/conversationwidget.cpp b/engines/mutationofjb/widgets/conversationwidget.cpp
index 71a3483..a46b9c5 100644
--- a/engines/mutationofjb/widgets/conversationwidget.cpp
+++ b/engines/mutationofjb/widgets/conversationwidget.cpp
@@ -41,26 +41,35 @@ ConversationWidget::ConversationWidget(Gui &gui, const Common::Rect &area, const
_callback(nullptr) {}
-void ConversationWidget::setLine(int lineNo, const Common::String &str) {
- if (lineNo >= CONVERSATION_LINES) {
+void ConversationWidget::setChoice(int choiceNo, const Common::String &str, uint32 data) {
+ if (choiceNo >= CONVERSATION_MAX_CHOICES) {
return;
}
- _lines[lineNo] = str;
+ _choices[choiceNo]._str = str;
+ _choices[choiceNo]._data = data;
+ markDirty();
+}
+
+void ConversationWidget::clearChoices() {
+ for (int i = 0; i < CONVERSATION_MAX_CHOICES; ++i) {
+ _choices[i]._str.clear();
+ _choices[i]._data = 0;
+ }
markDirty();
}
void ConversationWidget::_draw(Graphics::ManagedSurface &surface) {
surface.blitFrom(_surface, Common::Point(_area.left, _area.top));
- for (int i = 0; i < CONVERSATION_LINES; ++i) {
- Common::String &line = _lines[i];
- if (line.empty()) {
+ for (int i = 0; i < CONVERSATION_MAX_CHOICES; ++i) {
+ Common::String &str = _choices[i]._str;
+ if (str.empty()) {
continue;
}
// TODO: Active line should be WHITE.
- _gui.getGame().getAssets().getSystemFont().drawString(line, LIGHTGRAY, CONVERSATION_LINES_X, CONVERSATION_LINES_Y + i * CONVERSATION_LINE_HEIGHT, surface);
+ _gui.getGame().getAssets().getSystemFont().drawString(str, LIGHTGRAY, CONVERSATION_LINES_X, CONVERSATION_LINES_Y + i * CONVERSATION_LINE_HEIGHT, surface);
}
}
@@ -72,9 +81,9 @@ void ConversationWidget::handleEvent(const Common::Event &event) {
const int16 y = event.mouse.y;
if (_area.contains(x, y)) {
if (_callback) {
- int lineNum = (y - CONVERSATION_LINES_Y) / CONVERSATION_LINE_HEIGHT;
- if (!_lines[lineNum].empty()) {
- _callback->onResponseClicked(this, lineNum);
+ int choiceNo = (y - CONVERSATION_LINES_Y) / CONVERSATION_LINE_HEIGHT;
+ if (!_choices[choiceNo]._str.empty()) {
+ _callback->onChoiceClicked(this, choiceNo, _choices[choiceNo]._data);
}
}
}
diff --git a/engines/mutationofjb/widgets/conversationwidget.h b/engines/mutationofjb/widgets/conversationwidget.h
index b404abc..51ea86e 100644
--- a/engines/mutationofjb/widgets/conversationwidget.h
+++ b/engines/mutationofjb/widgets/conversationwidget.h
@@ -33,17 +33,18 @@ class ConversationWidget;
class ConversationWidgetCallback {
public:
virtual ~ConversationWidgetCallback() {}
- virtual void onResponseClicked(ConversationWidget *, int response) = 0;
+ virtual void onChoiceClicked(ConversationWidget *, int choiceNo, uint32 data) = 0;
};
class ConversationWidget : public Widget {
public:
- enum { CONVERSATION_LINES = 4 };
+ enum { CONVERSATION_MAX_CHOICES = 4 };
ConversationWidget(Gui &gui, const Common::Rect &area, const Graphics::Surface &surface);
void setCallback(ConversationWidgetCallback *callback) { _callback = callback; }
- void setLine(int lineNo, const Common::String &str);
+ void setChoice(int choiceNo, const Common::String &str, uint32 data = 0);
+ void clearChoices();
virtual void handleEvent(const Common::Event &event) override;
@@ -52,7 +53,10 @@ protected:
private:
Graphics::Surface _surface;
- Common::String _lines[CONVERSATION_LINES];
+ struct ChoiceInfo {
+ Common::String _str;
+ uint32 _data;
+ } _choices[CONVERSATION_MAX_CHOICES];
ConversationWidgetCallback *_callback;
};
Commit: 3b614f08327441d5252add7c16f4955652e32d0a
https://github.com/scummvm/scummvm/commit/3b614f08327441d5252add7c16f4955652e32d0a
Author: Miroslav Remák (miroslavr256 at gmail.com)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Implement RANDOM command.
Changed paths:
A engines/mutationofjb/commands/randomcommand.cpp
A engines/mutationofjb/commands/randomcommand.h
engines/mutationofjb/commands/endblockcommand.cpp
engines/mutationofjb/debug.cpp
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/module.mk
engines/mutationofjb/script.cpp
engines/mutationofjb/script.h
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index 3b4c25b..5fcccd3 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -56,7 +56,7 @@ bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext
}
const char firstChar = line.firstChar();
- if (firstChar != '#' && firstChar != '=' && firstChar != '-') {
+ if (firstChar != '#' && firstChar != '=' && firstChar != '-' && firstChar != '\\') {
return false;
}
diff --git a/engines/mutationofjb/commands/randomcommand.cpp b/engines/mutationofjb/commands/randomcommand.cpp
new file mode 100644
index 0000000..ff03e96
--- /dev/null
+++ b/engines/mutationofjb/commands/randomcommand.cpp
@@ -0,0 +1,110 @@
+/* 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/randomcommand.h"
+
+#include "mutationofjb/game.h"
+#include "mutationofjb/script.h"
+#include "common/debug.h"
+#include "common/random.h"
+#include "common/translation.h"
+
+/*
+ "RANDOM " <numChoices>
+
+ RANDOM command randomly picks one of the command blocks that
+ follow it and jumps to its start.
+
+ These blocks start with "/" and end with "\". The end of a random
+ block also ends the current section. The number of blocks must
+ match numChoices.
+*/
+
+namespace MutationOfJB {
+
+bool RandomCommandParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) {
+ if (line.size() < 8 || !line.hasPrefix("RANDOM")) {
+ return false;
+ }
+
+ int numChoices = atoi(line.c_str() + 7);
+ if (parseCtx._pendingRandomCommand) {
+ // Nested RANDOM commands are unused and not properly supported by the original game.
+ warning(_("Ignoring nested RANDOM command."));
+ } else if (numChoices >= 1) {
+ RandomCommand *randomCommand = new RandomCommand(static_cast<uint>(numChoices));
+ parseCtx._pendingRandomCommand = randomCommand;
+ command = randomCommand;
+ } else {
+ warning(_("Ignoring malformed RANDOM command with %d choices."), numChoices);
+ }
+
+ return true;
+}
+
+bool RandomBlockStartParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&) {
+ if (line != "/") {
+ return false;
+ }
+
+ if (!parseCtx._pendingRandomCommand) {
+ warning(_("Unexpected start of RANDOM block"));
+ }
+
+ return true;
+}
+
+void RandomBlockStartParser::transition(ScriptParseContext &parseCtx, Command *, Command *newCommand, CommandParser *) {
+ if (newCommand && parseCtx._pendingRandomCommand) {
+ parseCtx._pendingRandomCommand->_choices.push_back(newCommand);
+ }
+}
+
+RandomCommand::RandomCommand(uint numChoices)
+ : _numChoices(numChoices),
+ _chosenNext(nullptr)
+{
+ _choices.reserve(numChoices);
+}
+
+Command::ExecuteResult RandomCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ assert(!_choices.empty());
+
+ Common::RandomSource &rng = scriptExecCtx.getGame().getRandomSource();
+ uint choice = rng.getRandomNumber(_choices.size() - 1);
+ _chosenNext = _choices[choice];
+ return Finished;
+}
+
+Command *RandomCommand::next() const {
+ return _chosenNext;
+}
+
+Common::String RandomCommand::debugString() const {
+ return Common::String::format("RANDOM %u", _numChoices);
+}
+
+const RandomCommand::Choices &RandomCommand::getChoices() const {
+ return _choices;
+}
+
+}
diff --git a/engines/mutationofjb/commands/randomcommand.h b/engines/mutationofjb/commands/randomcommand.h
new file mode 100644
index 0000000..ffe9fc2
--- /dev/null
+++ b/engines/mutationofjb/commands/randomcommand.h
@@ -0,0 +1,70 @@
+/* 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_RANDOMCOMMAND_H
+#define MUTATIONOFJB_RANDOMCOMMAND_H
+
+#include "mutationofjb/commands/command.h"
+#include "common/array.h"
+#include "common/scummsys.h"
+
+namespace MutationOfJB {
+
+class RandomCommandParser : public CommandParser {
+public:
+ RandomCommandParser() {}
+
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
+};
+
+class RandomBlockStartParser : public CommandParser {
+public:
+ RandomBlockStartParser() {}
+
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
+ virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser) override;
+};
+
+class RandomCommand : public Command {
+ friend class RandomBlockStartParser;
+
+public:
+ typedef Common::Array<Command *> Choices;
+
+ RandomCommand(uint numChoices);
+
+ virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
+ virtual Command *next() const override;
+
+ virtual Common::String debugString() const override;
+
+ const Choices &getChoices() const;
+
+private:
+ uint _numChoices;
+ Choices _choices;
+ Command *_chosenNext;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index 171eca5..b1c96ef 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -30,6 +30,7 @@
#include "mutationofjb/commands/seqcommand.h"
#include "mutationofjb/commands/conditionalcommand.h"
#include "mutationofjb/commands/callmacrocommand.h"
+#include "mutationofjb/commands/randomcommand.h"
#include "common/debug-channels.h"
#include "common/translation.h"
#include "common/scummsys.h"
@@ -152,6 +153,14 @@ void Console::showCommands(Command *command, int indentLevel) {
command = nullptr;
} else if (CallMacroCommand* const callMacroCmd = dynamic_cast<CallMacroCommand *>(command)) {
command = callMacroCmd->getReturnCommand();
+ } else if (RandomCommand* const randomCmd = dynamic_cast<RandomCommand *>(command)) {
+ const RandomCommand::Choices &choices = randomCmd->getChoices();
+ for (RandomCommand::Choices::size_type i = 0; i < choices.size(); ++i) {
+ showIndent(indentLevel + 1);
+ debugPrintf("CASE %u\n", i);
+ showCommands(choices[i], indentLevel + 2);
+ }
+ command = nullptr;
} else {
command = nullptr;
}
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 69647f2..190b62e 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -36,6 +36,7 @@ namespace MutationOfJB {
Game::Game(MutationOfJBEngine *vm)
: _vm(vm),
+ _randomSource("mutationofjb"),
_delayedLocalScript(nullptr),
_gui(*this, _vm->getScreen()),
_scriptExecCtx(*this),
@@ -60,6 +61,10 @@ Game::Game(MutationOfJBEngine *vm)
changeScene(13, false); // Initial scene.
}
+Common::RandomSource &Game::getRandomSource() {
+ return _randomSource;
+}
+
GameData &Game::getGameData() {
return *_gameData;
}
@@ -222,11 +227,11 @@ uint8 Game::colorFromString(const char *colorStr) {
return 0x00;
}
-TaskManager& Game::getTaskManager() {
+TaskManager &Game::getTaskManager() {
return _taskManager;
}
-Assets& Game::getAssets() {
+Assets &Game::getAssets() {
return _assets;
}
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index 056cffb..d70bd09 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -23,6 +23,7 @@
#ifndef MUTATIONOFJB_GAME_H
#define MUTATIONOFJB_GAME_H
+#include "common/random.h"
#include "common/scummsys.h"
#include "mutationofjb/assets.h"
#include "mutationofjb/gui.h"
@@ -47,6 +48,7 @@ class Bitmap;
class Game {
public:
Game(MutationOfJBEngine *vm);
+ Common::RandomSource &getRandomSource();
GameData &getGameData();
Room &getRoom();
Script *getGlobalScript() const;
@@ -68,7 +70,7 @@ public:
static uint8 colorFromString(const char *colorStr);
- TaskManager& getTaskManager();
+ TaskManager &getTaskManager();
Assets &getAssets();
Graphics::Screen &getScreen();
@@ -80,6 +82,7 @@ private:
Script *changeSceneLoadScript(uint8 sceneId, bool partB);
MutationOfJBEngine *_vm;
+ Common::RandomSource _randomSource;
GameData *_gameData;
Script *_globalScript;
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index f3a1d78..2ac4fab 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -21,6 +21,7 @@ MODULE_OBJS := \
commands/saycommand.o \
commands/seqcommand.o \
commands/talkcommand.o \
+ commands/randomcommand.o \
tasks/conversationtask.o \
tasks/saytask.o \
tasks/taskmanager.o \
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 90146f6..d90f37e 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -45,6 +45,7 @@
#include "mutationofjb/commands/renamecommand.h"
#include "mutationofjb/commands/definestructcommand.h"
#include "mutationofjb/commands/talkcommand.h"
+#include "mutationofjb/commands/randomcommand.h"
#include "mutationofjb/game.h"
namespace MutationOfJB {
@@ -71,6 +72,8 @@ static CommandParser **getParsers() {
new NewRoomCommandParser,
new GotoCommandParser,
new LabelCommandParser,
+ new RandomCommandParser,
+ new RandomBlockStartParser,
nullptr
};
@@ -81,7 +84,8 @@ static CommandParser **getParsers() {
ScriptParseContext::ScriptParseContext(Common::SeekableReadStream &stream) :
_stream(stream),
_currentCommand(nullptr),
- _lastCommand(nullptr)
+ _lastCommand(nullptr),
+ _pendingRandomCommand(nullptr)
{}
bool ScriptParseContext::readLine(Common::String &line) {
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 8a15a48..3ef25f4 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -43,6 +43,7 @@ class GameData;
class GotoCommand;
class ConditionalCommand;
class Script;
+class RandomCommand;
typedef Common::Array<Command *> Commands;
@@ -92,6 +93,8 @@ public:
typedef Common::HashMap<Common::String, GotoCommands> PendingGotoMap;
PendingGotoMap _pendingGotos;
+ RandomCommand *_pendingRandomCommand;
+
ActionInfos _actionInfos;
Macros _macros;
Startups _startups;
Commit: 296835f84ae2b0c54882b8de19506989a3cf1fc4
https://github.com/scummvm/scummvm/commit/296835f84ae2b0c54882b8de19506989a3cf1fc4
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Draw object animations on map scene.
Changed paths:
engines/mutationofjb/room.cpp
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
index 5577077..009c4be 100644
--- a/engines/mutationofjb/room.cpp
+++ b/engines/mutationofjb/room.cpp
@@ -137,13 +137,13 @@ void Room::redraw() {
if (!_game->isCurrentSceneMap()) {
Common::Rect rect(0, 0, GAME_AREA_WIDTH, GAME_AREA_HEIGHT);
_screen->blitFrom(_background.rawSurface(), rect, Common::Point(0, 0));
+ }
- Scene *const currentScene = _game->getGameData().getCurrentScene();
- for (int i = 0; i < currentScene->getNoObjects(); ++i) {
- Object *const obj = currentScene->getObject(i + 1);
- if (obj->_AC) {
- drawObjectAnimation(i + 1, 0);
- }
+ Scene *const currentScene = _game->getGameData().getCurrentScene();
+ for (int i = 0; i < currentScene->getNoObjects(); ++i) {
+ Object *const obj = currentScene->getObject(i + 1);
+ if (obj->_AC) {
+ drawObjectAnimation(i + 1, 0);
}
}
}
Commit: d22da95282fea56caef5066331dc7d921b079811
https://github.com/scummvm/scummvm/commit/d22da95282fea56caef5066331dc7d921b079811
Author: Miroslav Remák (miroslavr256 at gmail.com)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Fix multiple RANDOM commands in one script.
Changed paths:
engines/mutationofjb/commands/randomcommand.cpp
diff --git a/engines/mutationofjb/commands/randomcommand.cpp b/engines/mutationofjb/commands/randomcommand.cpp
index ff03e96..b9cc303 100644
--- a/engines/mutationofjb/commands/randomcommand.cpp
+++ b/engines/mutationofjb/commands/randomcommand.cpp
@@ -74,8 +74,13 @@ bool RandomBlockStartParser::parse(const Common::String &line, ScriptParseContex
}
void RandomBlockStartParser::transition(ScriptParseContext &parseCtx, Command *, Command *newCommand, CommandParser *) {
- if (newCommand && parseCtx._pendingRandomCommand) {
- parseCtx._pendingRandomCommand->_choices.push_back(newCommand);
+ RandomCommand *randomCommand = parseCtx._pendingRandomCommand;
+ if (newCommand && randomCommand) {
+ randomCommand->_choices.push_back(newCommand);
+
+ if (randomCommand->_choices.size() == randomCommand->_numChoices) {
+ parseCtx._pendingRandomCommand = nullptr;
+ }
}
}
Commit: d358a65bbc57ab9099620bf2309893f99dbf164c
https://github.com/scummvm/scummvm/commit/d358a65bbc57ab9099620bf2309893f99dbf164c
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Run extra sections from conversation.
Changed paths:
engines/mutationofjb/commands/endblockcommand.cpp
engines/mutationofjb/commands/endblockcommand.h
engines/mutationofjb/conversationlinelist.cpp
engines/mutationofjb/mutationofjb.cpp
engines/mutationofjb/script.cpp
engines/mutationofjb/script.h
engines/mutationofjb/tasks/conversationtask.cpp
engines/mutationofjb/tasks/conversationtask.h
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index 5fcccd3..b883bee 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -35,6 +35,7 @@
("#U " | "-U ") <object1> [<object2>]
("#ELSE" | "-ELSE") [<tag>]
"#MACRO " <name>
+ "#EXTRA" <name>
If a line starts with '#', '=', '-', it is treated as the end of a section.
However, at the same time it can also start a new section depending on what follows.
@@ -46,6 +47,8 @@
#ELSE is used by conditional commands (see comments for IfCommand and others).
#MACRO starts a new macro. Global script can call macros from local script and vice versa.
+
+ #EXTRA defines an "extra" section. This is called from dialog responses ("TALK TO HIM" command).
*/
namespace MutationOfJB {
@@ -119,6 +122,9 @@ bool EndBlockCommandParser::parse(const Common::String &line, ScriptParseContext
const uint8 startupId = atoi(line.c_str() + 9);
IdAndCommand ic = {startupId, command};
_foundStartups.push_back(ic);
+ } else if (line.size() >= 7 && line.hasPrefix("#EXTRA")) {
+ NameAndCommand nc = {line.c_str() + 6, command};
+ _foundExtras.push_back(nc);
}
if (firstChar == '#') {
@@ -183,6 +189,23 @@ void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *ol
}
}
}
+ if (!_foundExtras.empty()) {
+ if (newCommand) {
+ for (NameAndCommandArray::iterator it = _foundExtras.begin(); it != _foundExtras.end();) {
+ if (it->_command != oldCommand) {
+ it++;
+ continue;
+ }
+
+ if (!parseCtx._extras.contains(it->_name)) {
+ parseCtx._extras[it->_name] = newCommand;
+ } else {
+ warning(_("Extra '%s' already exists"), it->_name.c_str());
+ }
+ it = _foundExtras.erase(it);
+ }
+ }
+ }
if (newCommandParser != this) {
if (!_pendingActionInfos.empty()) {
@@ -208,9 +231,13 @@ void EndBlockCommandParser::finish(ScriptParseContext &) {
if (!_foundStartups.empty()) {
debug("Problem: Found startups from end block parser is not empty!");
}
+ if (!_foundExtras.empty()) {
+ debug("Problem: Found extras from end block parser is not empty!");
+ }
_pendingActionInfos.clear();
_foundMacros.clear();
_foundStartups.clear();
+ _foundExtras.clear();
}
Command::ExecuteResult EndBlockCommand::execute(ScriptExecutionContext &scriptExecCtx) {
diff --git a/engines/mutationofjb/commands/endblockcommand.h b/engines/mutationofjb/commands/endblockcommand.h
index 4ca46dd..55656aa 100644
--- a/engines/mutationofjb/commands/endblockcommand.h
+++ b/engines/mutationofjb/commands/endblockcommand.h
@@ -56,6 +56,7 @@ private:
typedef Common::Array<IdAndCommand> IdAndCommandArray;
NameAndCommandArray _foundMacros;
IdAndCommandArray _foundStartups;
+ NameAndCommandArray _foundExtras;
};
class EndBlockCommand : public Command {
diff --git a/engines/mutationofjb/conversationlinelist.cpp b/engines/mutationofjb/conversationlinelist.cpp
index 562c2d0..3164ff5 100644
--- a/engines/mutationofjb/conversationlinelist.cpp
+++ b/engines/mutationofjb/conversationlinelist.cpp
@@ -56,8 +56,8 @@ bool ConversationLineList::parseFile(const Common::String &fileName) {
Common::String::iterator endIt = Common::find(lineStr.begin(), lineStr.end(), '|');
if (endIt != lineStr.end()) {
- Common::String extra = lineStr + endIt;
- if (*endIt == 'X') {
+ endIt++;
+ if (endIt != lineStr.end() && *endIt == 'X') {
line._extra = Common::String(endIt + 1, lineStr.end()); // Skip 'X' char.
}
}
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index e7f534e..986b00d 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -202,6 +202,7 @@ Common::Error MutationOfJBEngine::run() {
_game->setCurrentAction(ActionInfo::PickUp);
break;
}
+ break;
}
default:
break;
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index d90f37e..39c4859 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -189,6 +189,23 @@ Command *ScriptExecutionContext::getMacro(const Common::String &name) const {
return cmd;
}
+Command *ScriptExecutionContext::getExtra(const Common::String &name) const {
+ Command *cmd = nullptr;
+
+ Script *const localScript = _localScriptOverride ? _localScriptOverride : _game.getLocalScript();
+ Script *const globalScript = _game.getGlobalScript();
+
+ if (localScript) {
+ cmd = localScript->getExtra(name);
+ }
+
+ if (!cmd && globalScript) {
+ cmd = globalScript->getExtra(name);
+ }
+
+ return cmd;
+}
+
bool Script::loadFromStream(Common::SeekableReadStream &stream) {
destroy();
@@ -236,6 +253,7 @@ bool Script::loadFromStream(Common::SeekableReadStream &stream) {
_macros = parseCtx._macros;
_startups = parseCtx._startups;
+ _extras = parseCtx._extras;
return true;
}
@@ -285,4 +303,13 @@ Command *Script::getStartup(uint8 startupId) const {
return it->_value;
}
+Command *Script::getExtra(const Common::String &name) const {
+ Extras::const_iterator it = _extras.find(name);
+ if (it == _extras.end()) {
+ return nullptr;
+ }
+
+ return it->_value;
+}
+
}
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 3ef25f4..28e0e98 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -67,6 +67,7 @@ typedef Common::Array<ActionInfo> ActionInfos;
typedef Common::Array<GotoCommand *> GotoCommands;
typedef Common::HashMap<Common::String, Command *> Macros;
typedef Common::HashMap<uint8, Command *> Startups;
+typedef Common::HashMap<Common::String, Command *> Extras;
class ScriptParseContext {
public:
@@ -98,6 +99,7 @@ public:
ActionInfos _actionInfos;
Macros _macros;
Startups _startups;
+ Extras _extras;
private:
};
@@ -116,6 +118,7 @@ public:
Game &getGame();
GameData &getGameData();
Command *getMacro(const Common::String &name) const;
+ Command *getExtra(const Common::String &name) const;
private:
Game &_game;
@@ -135,6 +138,7 @@ public:
const Startups &getStartups() const;
Command *getMacro(const Common::String &name) const;
Command *getStartup(uint8 startupId) const;
+ Command *getExtra(const Common::String &name) const;
private:
void destroy();
@@ -142,6 +146,7 @@ private:
ActionInfos _actionInfos[5];
Macros _macros;
Startups _startups;
+ Extras _extras;
};
}
diff --git a/engines/mutationofjb/tasks/conversationtask.cpp b/engines/mutationofjb/tasks/conversationtask.cpp
index 512b38b..47f27df 100644
--- a/engines/mutationofjb/tasks/conversationtask.cpp
+++ b/engines/mutationofjb/tasks/conversationtask.cpp
@@ -27,11 +27,14 @@
#include "mutationofjb/game.h"
#include "mutationofjb/gamedata.h"
#include "mutationofjb/gui.h"
+#include "mutationofjb/script.h"
#include "mutationofjb/tasks/saytask.h"
#include "mutationofjb/tasks/taskmanager.h"
#include "mutationofjb/util.h"
#include "mutationofjb/widgets/conversationwidget.h"
+#include "common/translation.h"
+
namespace MutationOfJB {
void ConversationTask::start() {
@@ -69,11 +72,11 @@ void ConversationTask::update() {
break;
}
case SAYING_RESPONSE: {
- if (_currentItem->_nextLineIndex == 0) {
- finish();
- } else {
- _currentLineIndex = _currentItem->_nextLineIndex - 1;
- showChoicesOrPick();
+ startExtra();
+
+ if (_substate != RUNNING_EXTRA)
+ {
+ gotoNextLine();
}
break;
}
@@ -82,6 +85,16 @@ void ConversationTask::update() {
}
}
}
+
+ if (_innerExecCtx) {
+ Command::ExecuteResult res = _innerExecCtx->runActiveCommand();
+ if (res == Command::Finished) {
+ delete _innerExecCtx;
+ _innerExecCtx = nullptr;
+
+ gotoNextLine();
+ }
+ }
}
void ConversationTask::onChoiceClicked(ConversationWidget *convWidget, int, uint32 data) {
@@ -203,4 +216,35 @@ void ConversationTask::finish() {
game.getGui().markDirty(); // TODO: Handle automatically when changing visibility.
}
+void ConversationTask::startExtra() {
+ const ConversationLineList& responseList = getTaskManager()->getGame().getAssets().getResponseList();
+ const ConversationLineList::Line *const line = responseList.getLine(_currentItem->_response);
+ if (!line->_extra.empty()) {
+ _innerExecCtx = new ScriptExecutionContext(getTaskManager()->getGame());
+ Command *const extraCmd = _innerExecCtx->getExtra(line->_extra);
+ if (extraCmd) {
+ Command::ExecuteResult res = _innerExecCtx->startCommand(extraCmd);
+ if (res == Command::InProgress) {
+ _substate = RUNNING_EXTRA;
+ } else {
+ delete _innerExecCtx;
+ _innerExecCtx = nullptr;
+ }
+ } else {
+ warning(_("Extra '%s' not found"), line->_extra.c_str());
+ delete _innerExecCtx;
+ _innerExecCtx = nullptr;
+ }
+ }
+}
+
+void ConversationTask::gotoNextLine() {
+ if (_currentItem->_nextLineIndex == 0) {
+ finish();
+ } else {
+ _currentLineIndex = _currentItem->_nextLineIndex - 1;
+ showChoicesOrPick();
+ }
+}
+
}
diff --git a/engines/mutationofjb/tasks/conversationtask.h b/engines/mutationofjb/tasks/conversationtask.h
index 3bcbb6f..41c8284 100644
--- a/engines/mutationofjb/tasks/conversationtask.h
+++ b/engines/mutationofjb/tasks/conversationtask.h
@@ -27,10 +27,11 @@
namespace MutationOfJB {
class SayTask;
+class ScriptExecutionContext;
class ConversationTask : public Task, public ConversationWidgetCallback {
public:
- ConversationTask(uint8 sceneId, const ConversationInfo& convInfo) : _sceneId(sceneId), _convInfo(convInfo), _currentLineIndex(0), _currentItem(nullptr), _sayTask(nullptr), _substate(IDLE), _haveChoices(false) {}
+ ConversationTask(uint8 sceneId, const ConversationInfo& convInfo) : _sceneId(sceneId), _convInfo(convInfo), _currentLineIndex(0), _currentItem(nullptr), _sayTask(nullptr), _substate(IDLE), _haveChoices(false), _innerExecCtx(nullptr) {}
virtual ~ConversationTask() {}
virtual void start() override;
@@ -41,6 +42,8 @@ private:
void showChoicesOrPick();
const ConversationInfo::Line *getCurrentLine() const;
void finish();
+ void startExtra();
+ void gotoNextLine();
uint8 _sceneId;
const ConversationInfo &_convInfo;
@@ -52,11 +55,13 @@ private:
IDLE,
SAYING_CHOICE,
SAYING_RESPONSE,
- SAYING_NO_CHOICES
+ SAYING_NO_CHOICES,
+ RUNNING_EXTRA
};
Substate _substate;
bool _haveChoices;
+ ScriptExecutionContext *_innerExecCtx;
};
}
Commit: eaba12cecdb8c062093559af9d3caee6535059d2
https://github.com/scummvm/scummvm/commit/eaba12cecdb8c062093559af9d3caee6535059d2
Author: Miroslav Remák (miroslavr256 at gmail.com)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Use the vanilla cursor.
Changed paths:
engines/mutationofjb/mutationofjb.cpp
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index 986b00d..b535e19 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -54,12 +54,29 @@ MutationOfJBEngine::~MutationOfJBEngine() {
void MutationOfJBEngine::setupCursor() {
const uint8 white[] = {0xFF, 0xFF, 0xFF};
- const uint8 cursor[] = {0xFF};
+
+ const uint8 cursor[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ };
_screen->setPalette(white, 0xFF, 1);
CursorMan.disableCursorPalette(true);
- CursorMan.pushCursor(cursor, 1, 1, 0, 0, 0);
+ CursorMan.pushCursor(cursor, 15, 15, 7, 7, 0);
CursorMan.showMouse(true);
}
Commit: 2cd1728f42664643b1bb20f76b5350ef40401786
https://github.com/scummvm/scummvm/commit/2cd1728f42664643b1bb20f76b5350ef40401786
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add support for repeating choices.
Changed paths:
engines/mutationofjb/tasks/conversationtask.cpp
diff --git a/engines/mutationofjb/tasks/conversationtask.cpp b/engines/mutationofjb/tasks/conversationtask.cpp
index 47f27df..d675b2e 100644
--- a/engines/mutationofjb/tasks/conversationtask.cpp
+++ b/engines/mutationofjb/tasks/conversationtask.cpp
@@ -102,11 +102,16 @@ void ConversationTask::onChoiceClicked(ConversationWidget *convWidget, int, uint
convWidget->clearChoices();
const ConversationLineList& toSayList = getTaskManager()->getGame().getAssets().getToSayList();
- _sayTask = new SayTask(toSayList.getLine(item._choice)->_speeches[0]._text, _convInfo._color);
+ const ConversationLineList::Speech &speech = toSayList.getLine(item._choice)->_speeches[0];
+
+ _sayTask = new SayTask(speech._text, _convInfo._color);
getTaskManager()->addTask(_sayTask);
_substate = SAYING_CHOICE;
_currentItem = &item;
- getTaskManager()->getGame().getGameData().getCurrentScene()->addExhaustedChoice(_convInfo._context, data + 1, _currentLineIndex + 1);
+
+ if (!speech.isRepeating()) {
+ getTaskManager()->getGame().getGameData().getCurrentScene()->addExhaustedChoice(_convInfo._context, data + 1, _currentLineIndex + 1);
+ }
}
void ConversationTask::showChoicesOrPick() {
@@ -122,8 +127,10 @@ void ConversationTask::showChoicesOrPick() {
Collect valid "to say" choices (not exhausted and not empty).
Collect valid responses (not exhausted and not empty).
If there are at least two visible choices, we show them.
- If there is just one visible choice, pick it automatically.
+ If there is just one visible choice, pick it automatically ONLY if this is not the first choice in this conversation.
+ Otherwise we don't start the conversation.
If there are no visible choices, automatically pick first valid response.
+ If nothing above applies, don't start the conversation.
*/
const ConversationInfo::Line *const currentLine = getCurrentLine();
@@ -164,7 +171,7 @@ void ConversationTask::showChoicesOrPick() {
_currentItem = nullptr;
_haveChoices = true;
- } else if (itemsWithValidChoices.size() == 1) {
+ } else if (itemsWithValidChoices.size() == 1 && _haveChoices) {
const ConversationLineList& toSayList = game.getAssets().getToSayList();
const ConversationInfo::Item &item = currentLine->_items[itemsWithValidChoices.front()];
const ConversationLineList::Line *const line = toSayList.getLine(item._choice);
@@ -174,10 +181,12 @@ void ConversationTask::showChoicesOrPick() {
_substate = SAYING_CHOICE;
_currentItem = &item;
- game.getGameData().getCurrentScene()->addExhaustedChoice(_convInfo._context, itemsWithValidChoices.front() + 1, _currentLineIndex + 1);
+ if (!line->_speeches[0].isRepeating()) {
+ game.getGameData().getCurrentScene()->addExhaustedChoice(_convInfo._context, itemsWithValidChoices.front() + 1, _currentLineIndex + 1);
+ }
_haveChoices = true;
- } else if (!itemsWithValidResponses.empty()) {
+ } else if (!itemsWithValidResponses.empty() && _haveChoices) {
const ConversationLineList& responseList = game.getAssets().getResponseList();
const ConversationInfo::Item &item = currentLine->_items[itemsWithValidResponses.front()];
const ConversationLineList::Line *const line = responseList.getLine(item._response);
@@ -188,7 +197,7 @@ void ConversationTask::showChoicesOrPick() {
_currentItem = &item;
_haveChoices = true;
- } else if (!itemsWithValidNext.empty()) {
+ } else if (!itemsWithValidNext.empty() && _haveChoices) {
_currentLineIndex = currentLine->_items[itemsWithValidNext.front()]._nextLineIndex - 1;
showChoicesOrPick();
} else {
Commit: 2ee0a900598caa2e91b7261eb886793b74f9e25e
https://github.com/scummvm/scummvm/commit/2ee0a900598caa2e91b7261eb886793b74f9e25e
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Change cursor color when it's under entity.
Changed paths:
engines/mutationofjb/game.cpp
engines/mutationofjb/mutationofjb.cpp
engines/mutationofjb/mutationofjb.h
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 190b62e..0cb6f53 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -57,8 +57,6 @@ Game::Game(MutationOfJBEngine *vm)
_room = new Room(this, _vm->getScreen());
_gui.init();
-
- changeScene(13, false); // Initial scene.
}
Common::RandomSource &Game::getRandomSource() {
@@ -126,6 +124,8 @@ Script *Game::changeSceneLoadScript(uint8 sceneId, bool partB) {
localScript->loadFromStream(scriptFile);
scriptFile.close();
+ _vm->updateCursor();
+
return localScript;
}
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index b535e19..cdaa037 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -43,7 +43,8 @@ MutationOfJBEngine::MutationOfJBEngine(OSystem *syst)
: Engine(syst),
_console(nullptr),
_screen(nullptr),
- _mapObjectId(0) {
+ _mapObjectId(0),
+ _cursorState(CURSOR_IDLE) {
debug("MutationOfJBEngine::MutationOfJBEngine");
}
@@ -53,8 +54,6 @@ MutationOfJBEngine::~MutationOfJBEngine() {
void MutationOfJBEngine::setupCursor() {
- const uint8 white[] = {0xFF, 0xFF, 0xFF};
-
const uint8 cursor[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -73,13 +72,24 @@ void MutationOfJBEngine::setupCursor() {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
- _screen->setPalette(white, 0xFF, 1);
+ updateCursorPalette();
CursorMan.disableCursorPalette(true);
CursorMan.pushCursor(cursor, 15, 15, 7, 7, 0);
CursorMan.showMouse(true);
}
+void MutationOfJBEngine::updateCursorPalette() {
+ if (_cursorState == CURSOR_OFF) {
+ return;
+ }
+
+ const uint8 white[] = {0xFF, 0xFF, 0xFF};
+ const uint8 blue[] = {0x00, 0xFF, 0xC3};
+
+ _screen->setPalette(_cursorState == CURSOR_ACTIVE ? blue : white, 0xFF, 1);
+}
+
Graphics::Screen *MutationOfJBEngine::getScreen() const {
return _screen;
}
@@ -88,12 +98,36 @@ Game &MutationOfJBEngine::getGame() {
return *_game;
}
+void MutationOfJBEngine::setCursorState(CursorState cursorState) {
+ if (_cursorState == cursorState) {
+ return;
+ }
+
+ _cursorState = cursorState;
+ updateCursorPalette();
+}
+
+void MutationOfJBEngine::updateCursor() {
+ if (_cursorState == CURSOR_OFF) {
+ return;
+ }
+
+ if (_game->isCurrentSceneMap()) {
+ if (_cursorState != CURSOR_IDLE) {
+ _cursorState = CURSOR_IDLE;
+ updateCursorPalette();
+ }
+ } else {
+ const Common::Point point = _eventMan->getMousePos();
+ updateCursorHitTest(point.x, point.y);
+ }
+}
+
void MutationOfJBEngine::handleNormalScene(const Common::Event &event) {
Scene *const scene = _game->getGameData().getCurrentScene();
switch (event.type) {
- case Common::EVENT_LBUTTONDOWN:
- {
+ case Common::EVENT_LBUTTONDOWN: {
const int16 x = event.mouse.x;
const int16 y = event.mouse.y;
@@ -108,6 +142,15 @@ void MutationOfJBEngine::handleNormalScene(const Common::Event &event) {
}
break;
}
+ case Common::EVENT_MOUSEMOVE: {
+ const int16 x = event.mouse.x;
+ const int16 y = event.mouse.y;
+
+ if (_cursorState != CURSOR_OFF) {
+ updateCursorHitTest(x, y);
+ }
+ break;
+ }
default:
break;
}
@@ -126,8 +169,7 @@ void MutationOfJBEngine::handleMapScene(const Common::Event &event) {
Scene *const scene = _game->getGameData().getCurrentScene();
switch (event.type) {
- case Common::EVENT_LBUTTONDOWN:
- {
+ case Common::EVENT_LBUTTONDOWN: {
const int16 x = event.mouse.x;
const int16 y = event.mouse.y;
@@ -140,8 +182,7 @@ void MutationOfJBEngine::handleMapScene(const Common::Event &event) {
}
break;
}
- case Common::EVENT_MOUSEMOVE:
- {
+ case Common::EVENT_MOUSEMOVE: {
const int16 x = event.mouse.x;
const int16 y = event.mouse.y;
@@ -177,6 +218,33 @@ void MutationOfJBEngine::handleMapScene(const Common::Event &event) {
}
}
+void MutationOfJBEngine::updateCursorHitTest(int16 x, int16 y) {
+ Scene *const scene = _game->getGameData().getCurrentScene();
+ if (!scene) {
+ return;
+ }
+
+ bool entityHit = false;
+ if (Door *const door = scene->findDoor(x, y)) {
+ if (door->_destSceneId != 0) {
+ entityHit = true;
+ }
+ } else if (Static *const stat = scene->findStatic(x, y)) {
+ if (stat->_active == 1) {
+ entityHit = true;
+ }
+ }
+ bool cursorPaletteChange = false;
+ if ((_cursorState == CURSOR_ACTIVE && !entityHit) || (_cursorState == CURSOR_IDLE && entityHit)) {
+ cursorPaletteChange = true;
+ }
+ _cursorState = entityHit ? CURSOR_ACTIVE : CURSOR_IDLE;
+ if (cursorPaletteChange) {
+ updateCursorPalette();
+ }
+
+}
+
Common::Error MutationOfJBEngine::run() {
debug("MutationOfJBEngine::run");
@@ -188,20 +256,20 @@ Common::Error MutationOfJBEngine::run() {
setupCursor();
+ _game->changeScene(13, false); // Initial scene.
+
while (!shouldQuit()) {
Common::Event event;
while (_eventMan->pollEvent(event)) {
switch (event.type) {
- case Common::EVENT_KEYDOWN:
- {
+ case Common::EVENT_KEYDOWN: {
if ((event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_d) ||
event.kbd.ascii == '~' || event.kbd.ascii == '#') {
_console->attach();
}
break;
}
- case Common::EVENT_KEYUP:
- {
+ case Common::EVENT_KEYUP: {
switch (event.kbd.ascii) {
case 'g':
_game->setCurrentAction(ActionInfo::Walk);
diff --git a/engines/mutationofjb/mutationofjb.h b/engines/mutationofjb/mutationofjb.h
index 348165f..050800e 100644
--- a/engines/mutationofjb/mutationofjb.h
+++ b/engines/mutationofjb/mutationofjb.h
@@ -41,16 +41,26 @@ class Game;
class MutationOfJBEngine : public Engine {
public:
+ enum CursorState {
+ CURSOR_OFF,
+ CURSOR_IDLE,
+ CURSOR_ACTIVE
+ };
+
MutationOfJBEngine(OSystem *syst);
~MutationOfJBEngine();
virtual Common::Error run();
Graphics::Screen *getScreen() const;
Game &getGame();
+ void setCursorState(CursorState cursorState);
+ void updateCursor();
private:
bool loadGameData(bool partB);
void setupCursor();
+ void updateCursorHitTest(int16 x, int16 y);
+ void updateCursorPalette();
void handleNormalScene(const Common::Event &event);
void handleMapScene(const Common::Event &event);
@@ -58,6 +68,8 @@ private:
Graphics::Screen *_screen;
Game *_game;
uint8 _mapObjectId;
+
+ CursorState _cursorState;
};
Commit: 74ef0d9cfe2106cd0e4286ccd3e829c2edc00f98
https://github.com/scummvm/scummvm/commit/74ef0d9cfe2106cd0e4286ccd3e829c2edc00f98
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Correctly handle empty animation frames.
Changed paths:
engines/mutationofjb/animationdecoder.cpp
diff --git a/engines/mutationofjb/animationdecoder.cpp b/engines/mutationofjb/animationdecoder.cpp
index 5b20153..c88a9e0 100644
--- a/engines/mutationofjb/animationdecoder.cpp
+++ b/engines/mutationofjb/animationdecoder.cpp
@@ -61,34 +61,38 @@ bool AnimationDecoder::decode(AnimationDecoderCallback *callback) {
// Subrecords.
if (recordId == 0xF1FA) {
- for (int i = 0; i < subrecords; ++i) {
- int32 filePos = file.pos();
-
- const uint32 subLength = file.readUint32LE();
- const uint16 type = file.readUint16LE();
-
- if (type == 0x0B) {
- loadPalette(file);
- if (callback) {
- callback->onPaletteUpdated(_palette);
- }
- } else if (type == 0x0F) {
- loadFullFrame(file, subLength - 6);
- if (callback) {
- callback->onFrame(frameNo, _surface);
- }
- } else if (type == 0x0C) {
- loadDiffFrame(file, subLength - 6);
- if (callback) {
- callback->onFrame(frameNo, _surface);
+ if (subrecords == 0) {
+ callback->onFrame(frameNo, _surface); // Empty record, frame identical to the previous one.
+ } else {
+ for (int i = 0; i < subrecords; ++i) {
+ int32 filePos = file.pos();
+
+ const uint32 subLength = file.readUint32LE();
+ const uint16 type = file.readUint16LE();
+
+ if (type == 0x0B) {
+ loadPalette(file);
+ if (callback) {
+ callback->onPaletteUpdated(_palette);
+ }
+ } else if (type == 0x0F) {
+ loadFullFrame(file, subLength - 6);
+ if (callback) {
+ callback->onFrame(frameNo, _surface);
+ }
+ } else if (type == 0x0C) {
+ loadDiffFrame(file, subLength - 6);
+ if (callback) {
+ callback->onFrame(frameNo, _surface);
+ }
+ } else {
+ debug(_("Unsupported record type %02X."), type);
+ file.seek(subLength - 6, SEEK_CUR);
}
- } else {
- debug(_("Unsupported record type %02X."), type);
- file.seek(subLength - 6, SEEK_CUR);
- }
- // Makes decoding more robust, because for some reason records might have extra data at the end.
- file.seek(filePos + subLength, SEEK_SET);
+ // Makes decoding more robust, because for some reason records might have extra data at the end.
+ file.seek(filePos + subLength, SEEK_SET);
+ }
}
frameNo++;
} else {
Commit: f70eb01061d3e5dd74ed8065d0435a4273d973dc
https://github.com/scummvm/scummvm/commit/f70eb01061d3e5dd74ed8065d0435a4273d973dc
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Add null check.
Changed paths:
engines/mutationofjb/animationdecoder.cpp
diff --git a/engines/mutationofjb/animationdecoder.cpp b/engines/mutationofjb/animationdecoder.cpp
index c88a9e0..8132385 100644
--- a/engines/mutationofjb/animationdecoder.cpp
+++ b/engines/mutationofjb/animationdecoder.cpp
@@ -62,7 +62,9 @@ bool AnimationDecoder::decode(AnimationDecoderCallback *callback) {
// Subrecords.
if (recordId == 0xF1FA) {
if (subrecords == 0) {
- callback->onFrame(frameNo, _surface); // Empty record, frame identical to the previous one.
+ if (callback) {
+ callback->onFrame(frameNo, _surface); // Empty record, frame identical to the previous one.
+ }
} else {
for (int i = 0; i < subrecords; ++i) {
int32 filePos = file.pos();
Commit: f94ff7aa8ec510de8dc353c9c2e079db5e05d5da
https://github.com/scummvm/scummvm/commit/f94ff7aa8ec510de8dc353c9c2e079db5e05d5da
Author: Miroslav Remák (miroslavr256 at gmail.com)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Implement word wrapping for subtitles.
Changed paths:
engines/mutationofjb/font.cpp
engines/mutationofjb/font.h
engines/mutationofjb/tasks/saytask.cpp
engines/mutationofjb/tasks/saytask.h
diff --git a/engines/mutationofjb/font.cpp b/engines/mutationofjb/font.cpp
index 235c60a..4350b19 100644
--- a/engines/mutationofjb/font.cpp
+++ b/engines/mutationofjb/font.cpp
@@ -27,9 +27,9 @@
namespace MutationOfJB {
-Font::Font(const Common::String &fileName, int horizSpacing, int vertSpacing) :
+Font::Font(const Common::String &fileName, int horizSpacing, int lineHeight) :
_horizSpacing(horizSpacing),
- _vertSpacing(vertSpacing) {
+ _lineHeight(lineHeight) {
load(fileName);
}
@@ -67,15 +67,14 @@ bool Font::load(const Common::String &fileName) {
}
}
- if (_vertSpacing == -1) {
- _vertSpacing = maxHeight;
+ if (_lineHeight == -1) {
+ _lineHeight = maxHeight;
}
return true;
}
-
-void Font::drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf) {
+void Font::drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf) const {
GlyphMap::iterator it = _glyphs.find(glyph);
if (it == _glyphs.end()) {
warning("Glyph %d not found", glyph);
@@ -99,13 +98,54 @@ void Font::drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics:
x += glyphSurface.w + _horizSpacing;
}
-void Font::drawString(const Common::String &str, uint8 baseColor, int16 x, int16 y, Graphics::ManagedSurface &surf) {
+int16 Font::getWidth(const Common::String &str) const {
+ int16 width = 0;
+ for (uint i = 0; i < str.size(); ++i) {
+ GlyphMap::iterator it = _glyphs.find(str[i]);
+ if (it == _glyphs.end()) {
+ continue;
+ }
+
+ width += it->_value.w + _horizSpacing;
+ }
+ return width;
+}
+
+int Font::getLineHeight() const {
+ return _lineHeight;
+}
+
+void Font::drawString(const Common::String &str, uint8 baseColor, int16 x, int16 y, Graphics::ManagedSurface &surf) const {
for (uint i = 0; i < str.size(); ++i) {
drawGlyph(str[i], baseColor, x, y, surf); // "x" is updated.
}
}
-uint8 Font::transformColor(uint8 baseColor, uint8 glyphColor) {
+void Font::wordWrap(const Common::String &str, int16 maxLineWidth, Common::Array<Common::String> &lines) const {
+ lines.push_back("");
+
+ for (Common::String::const_iterator it = str.begin(); it != str.end();) {
+ Common::String::const_iterator partStart = it;
+ it = Common::find(partStart, str.end(), ' ');
+ if (it != str.end()) {
+ while (*it == ' ' && it != str.end()) {
+ ++it;
+ }
+ }
+
+ Common::String part(partStart, it); // Word + following whitespace
+ Common::String line = lines.back() + part;
+ if (getWidth(line) <= maxLineWidth) {
+ // The part fits in the current line
+ lines.back() = line;
+ } else {
+ // The part must go to the next line
+ lines.push_back(part);
+ }
+ }
+}
+
+uint8 Font::transformColor(uint8 baseColor, uint8 glyphColor) const {
return baseColor + glyphColor - 0x10;
}
@@ -113,7 +153,7 @@ SystemFont::SystemFont() : Font("sysfnt.aft", 1, 7) {}
SpeechFont::SpeechFont() : Font("font1.aft", -1, -1) {}
-uint8 SpeechFont::transformColor(uint8 baseColor, uint8 glyphColor) {
+uint8 SpeechFont::transformColor(uint8 baseColor, uint8 glyphColor) const {
// Hack in original game.
if (glyphColor == 0x11) {
return 0xC0;
diff --git a/engines/mutationofjb/font.h b/engines/mutationofjb/font.h
index 5aa6a4f..a27303e 100644
--- a/engines/mutationofjb/font.h
+++ b/engines/mutationofjb/font.h
@@ -37,17 +37,20 @@ class Font {
public:
Font(const Common::String &fileName, int horizSpacing, int vertSpacing);
virtual ~Font() {}
- void drawString(const Common::String &str, uint8 baseColor, int16 x, int16 y, Graphics::ManagedSurface &surf);
+ int getLineHeight() const;
+ int16 getWidth(const Common::String &text) const;
+ void drawString(const Common::String &str, uint8 baseColor, int16 x, int16 y, Graphics::ManagedSurface &surf) const;
+ void wordWrap(const Common::String &str, int16 maxLineWidth, Common::Array<Common::String> &lines) const;
protected:
- virtual uint8 transformColor(uint8 baseColor, uint8 glyphColor);
+ virtual uint8 transformColor(uint8 baseColor, uint8 glyphColor) const;
private:
- void drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf);
+ void drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf) const;
bool load(const Common::String &fileName);
int _horizSpacing;
- int _vertSpacing;
+ int _lineHeight;
typedef Common::HashMap<uint8, Graphics::ManagedSurface> GlyphMap;
GlyphMap _glyphs;
};
@@ -62,7 +65,7 @@ public:
SpeechFont();
protected:
- virtual uint8 transformColor(uint8 baseColor, uint8 glyphColor) override;
+ virtual uint8 transformColor(uint8 baseColor, uint8 glyphColor) const override;
};
}
diff --git a/engines/mutationofjb/tasks/saytask.cpp b/engines/mutationofjb/tasks/saytask.cpp
index 2ef4cdf..fcef6c3 100644
--- a/engines/mutationofjb/tasks/saytask.cpp
+++ b/engines/mutationofjb/tasks/saytask.cpp
@@ -27,6 +27,7 @@
#include "mutationofjb/game.h"
#include "mutationofjb/gamedata.h"
#include "mutationofjb/room.h"
+#include "mutationofjb/util.h"
#include "graphics/managed_surface.h"
#include "graphics/screen.h"
@@ -36,8 +37,7 @@ namespace MutationOfJB {
SayTask::SayTask(const Common::String &toSay, uint8 color) : _toSay(toSay), _color(color), _timer(1000) {}
void SayTask::start() {
-
- getTaskManager()->getGame().getAssets().getSpeechFont().drawString(_toSay, _color, 0, 0, getTaskManager()->getGame().getScreen());
+ drawSubtitle(_toSay, 160, 0, _color); // TODO: Respect PTALK and LTALK commands.
_timer.start();
setState(RUNNING);
}
@@ -52,4 +52,39 @@ void SayTask::update() {
}
}
+void SayTask::drawSubtitle(const Common::String &text, int16 talkX, int16 talkY, uint8 color) {
+ const int MAX_LINE_WIDTH = 250;
+
+ const Font &font = getTaskManager()->getGame().getAssets().getSpeechFont();
+
+ Common::Array<Common::String> lines;
+ font.wordWrap(text, MAX_LINE_WIDTH, lines);
+
+ int16 x = talkX;
+ int16 y = talkY - (lines.size() - 1) * font.getLineHeight() - 15; // Get the top y
+
+ // Clamp to screen edges
+ y = MAX<int16>(y, 3);
+ int16 maxWidth = 0;
+ for (uint i = 0; i < lines.size(); i++) {
+ int16 lineWidth = font.getWidth(lines[i]);
+ if (lineWidth > maxWidth) {
+ maxWidth = lineWidth;
+ }
+ x = MAX<int16>(x, 3 + lineWidth / 2);
+ x = MIN<int16>(x, 317 - lineWidth / 2);
+ }
+
+ // Draw lines
+ for (uint i = 0; i < lines.size(); i++) {
+ font.drawString(lines[i], color, x - font.getWidth(lines[i]) / 2, y + i * font.getLineHeight(), getTaskManager()->getGame().getScreen());
+ }
+
+ // Remember the area occupied by the text
+ _boundingBox.top = x - maxWidth / 2;
+ _boundingBox.left = y;
+ _boundingBox.setWidth(maxWidth);
+ _boundingBox.setHeight(lines.size() * font.getLineHeight());
+}
+
}
diff --git a/engines/mutationofjb/tasks/saytask.h b/engines/mutationofjb/tasks/saytask.h
index a7ac96d..ef66f5b 100644
--- a/engines/mutationofjb/tasks/saytask.h
+++ b/engines/mutationofjb/tasks/saytask.h
@@ -24,6 +24,7 @@
#include "mutationofjb/timer.h"
+#include "common/rect.h"
#include "common/str.h"
namespace MutationOfJB {
@@ -36,9 +37,12 @@ public:
virtual void update() override;
private:
+ void drawSubtitle(const Common::String &text, int16 talkX, int16 talkY, uint8 color);
+
Common::String _toSay;
uint8 _color;
Timer _timer;
+ Common::Rect _boundingBox;
};
}
Commit: cda1f0dd3a553dbd4480b87a054d388c98740585
https://github.com/scummvm/scummvm/commit/cda1f0dd3a553dbd4480b87a054d388c98740585
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Animate objects.
Changed paths:
A engines/mutationofjb/tasks/objectanimationtask.cpp
A engines/mutationofjb/tasks/objectanimationtask.h
engines/mutationofjb/game.cpp
engines/mutationofjb/module.mk
engines/mutationofjb/tasks/saytask.cpp
engines/mutationofjb/tasks/saytask.h
engines/mutationofjb/timer.cpp
engines/mutationofjb/timer.h
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 0cb6f53..652336f 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -21,16 +21,19 @@
*/
#include "mutationofjb/game.h"
-#include "mutationofjb/gamedata.h"
+
+#include "mutationofjb/commands/command.h"
#include "mutationofjb/encryptedfile.h"
+#include "mutationofjb/gamedata.h"
#include "mutationofjb/mutationofjb.h"
#include "mutationofjb/room.h"
#include "mutationofjb/script.h"
+#include "mutationofjb/tasks/objectanimationtask.h"
#include "mutationofjb/util.h"
-#include "mutationofjb/commands/command.h"
-#include "common/util.h"
+
#include "common/str.h"
#include "common/translation.h"
+#include "common/util.h"
namespace MutationOfJB {
@@ -57,6 +60,8 @@ Game::Game(MutationOfJBEngine *vm)
_room = new Room(this, _vm->getScreen());
_gui.init();
+
+ _taskManager.addTask(new ObjectAnimationTask);
}
Common::RandomSource &Game::getRandomSource() {
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 2ac4fab..1913fc6 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -23,6 +23,7 @@ MODULE_OBJS := \
commands/talkcommand.o \
commands/randomcommand.o \
tasks/conversationtask.o \
+ tasks/objectanimationtask.o \
tasks/saytask.o \
tasks/taskmanager.o \
widgets/buttonwidget.o \
diff --git a/engines/mutationofjb/tasks/objectanimationtask.cpp b/engines/mutationofjb/tasks/objectanimationtask.cpp
new file mode 100644
index 0000000..75c15bf
--- /dev/null
+++ b/engines/mutationofjb/tasks/objectanimationtask.cpp
@@ -0,0 +1,91 @@
+/* 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/tasks/objectanimationtask.h"
+
+#include "mutationofjb/tasks/taskmanager.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
+#include "mutationofjb/room.h"
+
+namespace MutationOfJB {
+
+static const int TICK_MILLIS = 100;
+
+ObjectAnimationTask::ObjectAnimationTask() : _timer(TICK_MILLIS) {
+}
+
+void ObjectAnimationTask::start() {
+ setState(RUNNING);
+ _timer.start();
+}
+
+void ObjectAnimationTask::update() {
+ _timer.update();
+ if (_timer.isFinished()) {
+ _timer.start();
+ updateObjects();
+ }
+}
+
+void ObjectAnimationTask::updateObjects() {
+ Scene *const scene = getTaskManager()->getGame().getGameData().getCurrentScene();
+ if (!scene) {
+ return;
+ }
+
+ for (uint8 i = 1; i <= scene->getNoObjects(); ++i) {
+ Object *const object = scene->getObject(i);
+ // Skip if object animation not active.
+ if (!object->_AC)
+ continue;
+
+ // Number of framers must be higher than 1.
+ if (object->_NA <= 1)
+ continue;
+
+ const uint8 currentAnimOffset = object->_CA - object->_FA;
+
+ const bool randomized = object->_FR != 0;
+ const bool belowRandomFrame = currentAnimOffset < (object->_FR - 1);
+
+ uint8 maxAnimOffset = object->_NA - 1;
+ if (randomized && belowRandomFrame) {
+ maxAnimOffset = object->_FR - 2;
+ }
+
+ uint8 nextAnimationOffset = currentAnimOffset + 1;
+ if (currentAnimOffset == maxAnimOffset) {
+ if (randomized && object->_unknown != 0 && getTaskManager()->getGame().getRandomSource().getRandomNumber(object->_unknown) == 0)
+ nextAnimationOffset = object->_FR - 1;
+ else
+ nextAnimationOffset = 0;
+ }
+
+ // TODO: Hardcoded animations.
+
+ object->_CA = nextAnimationOffset + object->_FA;
+ getTaskManager()->getGame().getRoom().drawObjectAnimation(i, nextAnimationOffset);
+ }
+}
+
+}
diff --git a/engines/mutationofjb/tasks/objectanimationtask.h b/engines/mutationofjb/tasks/objectanimationtask.h
new file mode 100644
index 0000000..39f80a3
--- /dev/null
+++ b/engines/mutationofjb/tasks/objectanimationtask.h
@@ -0,0 +1,47 @@
+/* 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_OBJECTANIMATIONTASK_H
+#define MUTATIONOFJB_OBJECTANIMATIONTASK_H
+
+#include "mutationofjb/tasks/task.h"
+
+#include "mutationofjb/timer.h"
+
+namespace MutationOfJB {
+
+class ObjectAnimationTask : public Task {
+public:
+ ObjectAnimationTask();
+
+ virtual void start() override;
+ virtual void update() override;
+
+ void updateObjects();
+
+private:
+ Timer _timer;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/tasks/saytask.cpp b/engines/mutationofjb/tasks/saytask.cpp
index fcef6c3..c9c2a95 100644
--- a/engines/mutationofjb/tasks/saytask.cpp
+++ b/engines/mutationofjb/tasks/saytask.cpp
@@ -45,7 +45,7 @@ void SayTask::start() {
void SayTask::update() {
_timer.update();
- if (_timer.isFnished()) {
+ if (_timer.isFinished()) {
getTaskManager()->getGame().getRoom().redraw(); // TODO: Only redraw the area occupied by the text.
setState(FINISHED);
return;
diff --git a/engines/mutationofjb/tasks/saytask.h b/engines/mutationofjb/tasks/saytask.h
index ef66f5b..17e773d 100644
--- a/engines/mutationofjb/tasks/saytask.h
+++ b/engines/mutationofjb/tasks/saytask.h
@@ -20,6 +20,9 @@
*
*/
+#ifndef MUTATIONOFJB_SAYTASK_H
+#define MUTATIONOFJB_SAYTASK_H
+
#include "mutationofjb/tasks/task.h"
#include "mutationofjb/timer.h"
@@ -46,3 +49,5 @@ private:
};
}
+
+#endif
diff --git a/engines/mutationofjb/timer.cpp b/engines/mutationofjb/timer.cpp
index 8375445..d5a306a 100644
--- a/engines/mutationofjb/timer.cpp
+++ b/engines/mutationofjb/timer.cpp
@@ -34,7 +34,7 @@ void Timer::start() {
_state = RUNNING;
}
-bool Timer::isFnished() const {
+bool Timer::isFinished() const {
return _state == FINISHED;
}
diff --git a/engines/mutationofjb/timer.h b/engines/mutationofjb/timer.h
index b12fe22..313823a 100644
--- a/engines/mutationofjb/timer.h
+++ b/engines/mutationofjb/timer.h
@@ -30,7 +30,7 @@ public:
void start();
- bool isFnished() const;
+ bool isFinished() const;
bool isRunning() const;
void update();
Commit: 578a6794de9ba7679966fee9aec02c6b2bdbce94
https://github.com/scummvm/scummvm/commit/578a6794de9ba7679966fee9aec02c6b2bdbce94
Author: Miroslav Remák (miroslavr256 at gmail.com)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Improve documentation, rename cryptic variables.
Changed paths:
engines/mutationofjb/commands/changecommand.cpp
engines/mutationofjb/debug.cpp
engines/mutationofjb/gamedata.cpp
engines/mutationofjb/gamedata.h
engines/mutationofjb/room.cpp
engines/mutationofjb/tasks/objectanimationtask.cpp
engines/mutationofjb/tasks/saytask.cpp
diff --git a/engines/mutationofjb/commands/changecommand.cpp b/engines/mutationofjb/commands/changecommand.cpp
index a2d4526..d7a8f9c 100644
--- a/engines/mutationofjb/commands/changecommand.cpp
+++ b/engines/mutationofjb/commands/changecommand.cpp
@@ -381,22 +381,22 @@ Command::ExecuteResult ChangeObjectCommand::execute(ScriptExecutionContext &scri
switch (_register) {
case AC:
- object->_AC = _value._byteVal;
+ object->_active = _value._byteVal;
break;
case FA:
- object->_FA = _value._byteVal;
+ object->_firstFrame = _value._byteVal;
break;
case FR:
- object->_FR = _value._byteVal;
+ object->_randomFrame = _value._byteVal;
break;
case NA:
- object->_NA = _value._byteVal;
+ object->_numFrames = _value._byteVal;
break;
case FS:
- object->_FS = _value._byteVal;
+ object->_roomFrameLSB = _value._byteVal;
break;
case CA:
- object->_CA = _value._byteVal;
+ object->_currentFrame = _value._byteVal;
break;
case XX:
object->_x = _value._wordVal;
@@ -405,16 +405,16 @@ Command::ExecuteResult ChangeObjectCommand::execute(ScriptExecutionContext &scri
object->_y = _value._byteVal;
break;
case XL:
- object->_XL = _value._wordVal;
+ object->_width = _value._wordVal;
break;
case YL:
- object->_YL = _value._byteVal;
+ object->_height = _value._byteVal;
break;
case WX:
object->_WX = _value._wordVal;
break;
case WY:
- object->_WY = _value._byteVal;
+ object->_roomFrameMSB = _value._byteVal;
break;
case SP:
object->_SP = _value._byteVal;
@@ -468,7 +468,7 @@ Command::ExecuteResult ChangeStaticCommand::execute(ScriptExecutionContext &scri
stat->_walkToY = _value._byteVal;
break;
case SP:
- stat->_SP = _value._byteVal;
+ stat->_walkToFrame = _value._byteVal;
break;
default:
warning("Object does not support changing this register.");
@@ -493,7 +493,7 @@ Command::ExecuteResult ChangeSceneCommand::execute(ScriptExecutionContext &scrip
scene->_startup = _value._byteVal;
break;
case DL:
- scene->_DL = _value._byteVal;
+ scene->_delay = _value._byteVal;
break;
case ND:
scene->_noDoors = _value._byteVal;
@@ -505,13 +505,13 @@ Command::ExecuteResult ChangeSceneCommand::execute(ScriptExecutionContext &scrip
scene->_noStatics = _value._byteVal;
break;
case PF:
- scene->_palRotStart = _value._byteVal;
+ scene->_palRotFirst = _value._byteVal;
break;
case PL:
- scene->_palRotEnd = _value._byteVal;
+ scene->_palRotLast = _value._byteVal;
break;
case PD:
- scene->_palRotPeriod = _value._byteVal;
+ scene->_palRotDelay = _value._byteVal;
break;
default:
warning("Scene does not support changing this register.");
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index b1c96ef..b4f00c9 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -318,14 +318,14 @@ bool Console::cmd_dumpsceneinfo(int argc, const char **argv) {
Scene *scene = _vm->getGame().getGameData().getScene(sceneId);
if (scene) {
debugPrintf("Startup: %u\n", (unsigned int) scene->_startup);
- debugPrintf("Delay: %u\n", (unsigned int) scene->_DL);
+ debugPrintf("Delay: %u\n", (unsigned int) scene->_delay);
debugPrintf("Doors: %u\n", (unsigned int) scene->_noDoors);
debugPrintf("Objects: %u\n", (unsigned int) scene->_noObjects);
debugPrintf("Statics: %u\n", (unsigned int) scene->_noStatics);
debugPrintf("ObstacleY1: %u\n", (unsigned int) scene->_obstacleY1);
- debugPrintf("PalRotStart: %u\n", (unsigned int) scene->_palRotStart);
- debugPrintf("PalRotEnd: %u\n", (unsigned int) scene->_palRotEnd);
- debugPrintf("PalRotPeriod: %u\n", (unsigned int) scene->_palRotPeriod);
+ debugPrintf("PalRotFirst: %u\n", (unsigned int) scene->_palRotFirst);
+ debugPrintf("PalRotLast: %u\n", (unsigned int) scene->_palRotLast);
+ debugPrintf("PalRotDelay: %u\n", (unsigned int) scene->_palRotDelay);
} else {
debugPrintf(_("Scene %u not found.\n"), (unsigned int) sceneId);
}
@@ -377,19 +377,19 @@ bool Console::cmd_dumpobjectinfo(int argc, const char **argv) {
if (scene) {
Object *const object = scene->getObject(objectId);
if (object) {
- debugPrintf("AC: %u\n", (unsigned int) object->_AC);
- debugPrintf("FA: %u\n", (unsigned int) object->_FA);
- debugPrintf("FR: %u\n", (unsigned int) object->_FR);
- debugPrintf("NA: %u\n", (unsigned int) object->_NA);
- debugPrintf("FS: %u\n", (unsigned int) object->_FS);
- debugPrintf("Unknown: %u\n", (unsigned int) object->_unknown);
- debugPrintf("CA: %u\n", (unsigned int) object->_CA);
+ debugPrintf("AC: %u\n", (unsigned int) object->_active);
+ debugPrintf("FA: %u\n", (unsigned int) object->_firstFrame);
+ debugPrintf("FR: %u\n", (unsigned int) object->_randomFrame);
+ debugPrintf("NA: %u\n", (unsigned int) object->_numFrames);
+ debugPrintf("FS: %u\n", (unsigned int) object->_roomFrameLSB);
+ debugPrintf("Jump chance: %u\n", (unsigned int) object->_jumpChance);
+ debugPrintf("CA: %u\n", (unsigned int) object->_currentFrame);
debugPrintf("X: %u\n", (unsigned int) object->_x);
debugPrintf("Y: %u\n", (unsigned int) object->_y);
- debugPrintf("XL: %u\n", (unsigned int) object->_XL);
- debugPrintf("YL: %u\n", (unsigned int) object->_YL);
+ debugPrintf("XL: %u\n", (unsigned int) object->_width);
+ debugPrintf("YL: %u\n", (unsigned int) object->_height);
debugPrintf("WX: %u\n", (unsigned int) object->_WX);
- debugPrintf("WY: %u\n", (unsigned int) object->_WY);
+ debugPrintf("WY: %u\n", (unsigned int) object->_roomFrameMSB);
debugPrintf("SP: %u\n", (unsigned int) object->_SP);
} else {
debugPrintf(_("Object %u not found.\n"), (unsigned int) objectId);
@@ -421,7 +421,7 @@ bool Console::cmd_dumpstaticinfo(int argc, const char **argv) {
debugPrintf("Height: %u\n", (unsigned int) stat->_height);
debugPrintf("WalkToX: %u\n", (unsigned int) stat->_walkToY);
debugPrintf("WalkToY: %u\n", (unsigned int) stat->_walkToX);
- debugPrintf("WalkToFrame: %u\n", (unsigned int) stat->_SP);
+ debugPrintf("WalkToFrame: %u\n", (unsigned int) stat->_walkToFrame);
} else {
debugPrintf(_("Static %u not found.\n"), (unsigned int) staticId);
}
diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp
index 6a9c166..b6295a7 100644
--- a/engines/mutationofjb/gamedata.cpp
+++ b/engines/mutationofjb/gamedata.cpp
@@ -58,19 +58,19 @@ bool Door::loadFromStream(Common::ReadStream &stream) {
}
bool Object::loadFromStream(Common::ReadStream &stream) {
- _AC = stream.readByte();
- _FA = stream.readByte();
- _FR = stream.readByte();
- _NA = stream.readByte();
- _FS = stream.readByte();
- _unknown = stream.readByte();
- _CA = stream.readByte();
+ _active = stream.readByte();
+ _firstFrame = stream.readByte();
+ _randomFrame = stream.readByte();
+ _numFrames = stream.readByte();
+ _roomFrameLSB = stream.readByte();
+ _jumpChance = stream.readByte();
+ _currentFrame = stream.readByte();
_x = stream.readUint16LE();
_y = stream.readByte();
- _XL = stream.readUint16LE();
- _YL = stream.readByte();
+ _width = stream.readUint16LE();
+ _height = stream.readByte();
_WX = stream.readUint16LE();
- _WY = stream.readByte();
+ _roomFrameMSB = stream.readByte();
_SP = stream.readByte();
return true;
@@ -85,13 +85,13 @@ bool Static::loadFromStream(Common::ReadStream &stream) {
_height = stream.readByte();
_walkToX = stream.readUint16LE();
_walkToY = stream.readByte();
- _SP = stream.readByte();
+ _walkToFrame = stream.readByte();
return true;
}
bool Bitmap::loadFromStream(Common::ReadStream &stream) {
- _frame = stream.readByte();
+ _roomFrame = stream.readByte();
_isVisible = stream.readByte();
_x1 = stream.readUint16LE();
_y1 = stream.readByte();
@@ -108,7 +108,7 @@ bool Scene::loadFromStream(Common::ReadStream &stream) {
_unknown001 = stream.readByte();
_unknown002 = stream.readByte();
_unknown003 = stream.readByte();
- _DL = stream.readByte();
+ _delay = stream.readByte();
_noDoors = stream.readByte();
_noDoors = MIN(_noDoors, (uint8) ARRAYSIZE(_doors));
@@ -133,9 +133,9 @@ bool Scene::loadFromStream(Common::ReadStream &stream) {
}
_obstacleY1 = stream.readUint16LE();
- _palRotStart = stream.readByte();
- _palRotEnd = stream.readByte();
- _palRotPeriod = stream.readByte();
+ _palRotFirst = stream.readByte();
+ _palRotLast = stream.readByte();
+ _palRotDelay = stream.readByte();
_exhaustedChoiceNext = stream.readByte();
for (i = 0; i < 79; ++i) {
diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h
index 62c66a1..99174ee 100644
--- a/engines/mutationofjb/gamedata.h
+++ b/engines/mutationofjb/gamedata.h
@@ -36,40 +36,49 @@ enum {
MAX_ENTITY_NAME_LENGTH = 0x14
};
-/*
- There are 4 types of entities present in the game data:
- - Door
- - Object
- - Static
- - Bitmap
-*/
+/** @file gamedata.h
+ * There are 4 types of entities present in the game data:
+ * - Door
+ * - Object
+ * - Static
+ * - Bitmap
+ */
+/**
+ * An interactable scene changer with no visual representation.
+ */
struct Door {
- /*
- Door name.
- Can be empty - deactivates door completely.
- */
+ /**
+ * Door name (NM register).
+ *
+ * Can be empty - deactivates door completely (you can't mouse over or interact with it at all).
+ *
+ * If it ends with '+', using the "go" verb on the door will not implicitly change the scene,
+ * but the player will still walk towards the door.
+ *
+ * TODO: Implement the '+' restriction.
+ */
char _name[MAX_ENTITY_NAME_LENGTH + 1];
- /*
- Scene ID where the door leads.
- Can be 0 - you can hover your mouse over it, but clicking it doesn't do anything (unless scripted).
- */
+ /**
+ * Scene ID where the door leads (LT register).
+ * Can be 0 - you can hover your mouse over it, but clicking it doesn't do anything (unless scripted).
+ */
uint8 _destSceneId;
- /* X coordinate for player's position after going through the door. */
+ /** X coordinate for player's position after going through the door (SX register). */
uint16 _destX;
- /* Y coordinate for player's position after going through the door. */
+ /** Y coordinate for player's position after going through the door (SY register). */
uint16 _destY;
- /* X coordinate of the door rectangle. */
+ /** X coordinate of the door rectangle (XX register). */
uint16 _x;
- /* Y coordinate of the door rectangle. */
+ /** Y coordinate of the door rectangle (YY register). */
uint8 _y;
- /* Width of the door rectangle. */
+ /** Width of the door rectangle (XL register). */
uint16 _width;
- /* Height of the door rectangle. */
+ /** Height of the door rectangle (YL register). */
uint8 _height;
- /* X coordinate for position towards player will walk after clicking the door. */
+ /** X coordinate for position player will walk towards after clicking the door (WX register). */
uint16 _walkToX;
- /* Y coordinate for position towards player will walk after clicking the door. */
+ /** Y coordinate for position player will walk towards after clicking the door (WY register). */
uint8 _walkToY;
/* Unknown for now - likely not even used. */
uint8 _SP;
@@ -77,56 +86,148 @@ struct Door {
bool loadFromStream(Common::ReadStream &stream);
};
+/**
+ * An animated image in the scene.
+ *
+ * Object frames consist of surfaces carved out of room frames (starting from _roomFrame
+ * up until _roomFrame + _numFrames - 1) based on the object's rectangle. They are stored
+ * in the shared object frame space that each object occupies a continous part of from
+ * the beginning.
+ *
+ * By using the term "frame" alone we will be referring to an object frame, not a room
+ * frame.
+ *
+ * For details regarding animation playback, see objectanimationtask.cpp.
+ */
struct Object {
- uint8 _AC;
- uint8 _FA;
- uint8 _FR;
- uint8 _NA;
- uint8 _FS;
- uint8 _unknown;
- uint8 _CA;
+ /** Controls whether the animation is playing. */
+ uint8 _active;
+ /**
+ * Number of the first frame this object has in the shared object frame space (FA register).
+ *
+ * For the first object, it is equal to 1.
+ * For any subsequent object, it is equal to (_firstFrame + _numFrames) of the previous object.
+ *
+ * @note The numbering starts from 1.
+ * @note Technically this field is useless because it can be calculated.
+ */
+ uint8 _firstFrame;
+ /**
+ * The frame that is jumped to randomly based on _jumpChance (FR register).
+ *
+ * @note Numbered from 1 and relative to _firstFrame.
+ * @note A value of 0 disables randomness completely.
+ * @see objectanimationtask.cpp
+ * @see _jumpChance
+ */
+ uint8 _randomFrame;
+ /** Number of animation frames (NA register). */
+ uint8 _numFrames;
+ /**
+ * Low 8 bits of the 16-bit starting room frame (FS register).
+ *
+ * @see _roomFrameMSB
+ */
+ uint8 _roomFrameLSB;
+ /**
+ * Chance (1 in x) of the animation jumping to _randomFrame.
+ *
+ * @see objectanimationtask.cpp
+ */
+ uint8 _jumpChance;
+ /**
+ * Current animation frame (CA register).
+ *
+ * @note Absolute index to the frame space. Numbered from 1.
+ */
+ uint8 _currentFrame;
+ /** X coordinate of the object rectangle (XX register). */
uint16 _x;
+ /** Y coordinate of the object rectangle (YY register). */
uint8 _y;
- uint16 _XL;
- uint8 _YL;
+ /** Width of the object rectangle (XL register). */
+ uint16 _width;
+ /** Height of the object rectangle (YL register). */
+ uint8 _height;
+ /** A general-purpose register for use in scripts. Nothing to do with animation. */
uint16 _WX;
- uint8 _WY;
+ /**
+ * High 8 bits of the 16-bit starting room frame (WY register).
+ *
+ * @see _roomFrameLSB
+ */
+ uint8 _roomFrameMSB;
+ /* Unknown. TODO: Figure out what this does. */
uint8 _SP;
bool loadFromStream(Common::ReadStream &stream);
};
+/**
+ * An interactable area without a visual representation.
+ */
struct Static {
+ /** Whether you can mouse over and interact with the static (AC register). */
uint8 _active;
+ /**
+ * Static name (NM register).
+ *
+ * If it starts with '~', the static has an implicit "pickup" action that adds
+ * an item with the same name (except '`' replaces '~') to your inventory and
+ * disables the static. If there is a matching scripted "pickup" action, it
+ * overrides the implicit action.
+ *
+ * TODO: Support '~' statics.
+ */
char _name[MAX_ENTITY_NAME_LENGTH + 1];
+ /** X coordinate of the static rectangle (XX register). */
uint16 _x;
+ /** Y coordinate of the static rectangle (YY register). */
uint8 _y;
+ /** Width of the static rectangle (XL register). */
uint16 _width;
+ /** Height of the static rectangle (YL register). */
uint8 _height;
+ /** X coordinate of the position the player will walk towards after clicking the static (WX register). */
uint16 _walkToX;
+ /** Y coordinate of the position the player will walk towards after clicking the static (WY register). */
uint8 _walkToY;
- uint8 _SP;
+ /** Player frame (rotation) set after the player finishes walking towards the walk to position (SP register). */
+ uint8 _walkToFrame;
bool loadFromStream(Common::ReadStream &stream);
};
+/**
+ * A static image that is carved out of a room frame based on its rectangle.
+ * The bitmap rectangle also specifies where to blit it on the screen.
+ */
struct Bitmap {
- uint8 _frame;
+ /** Room frame that this bitmap carves out of. */
+ uint8 _roomFrame;
+ /** Whether to draw the bitmap. */
uint8 _isVisible;
+ /** X coordinate of the top left corner of the bitmap rectangle. */
uint16 _x1;
+ /** Y coordinate of the top left corner of the bitmap rectangle. */
uint8 _y1;
+ /** X coordinate of the bottom right corner of the bitmap rectangle. */
uint16 _x2;
+ /** Y coordinate of the bottom right corner of the bitmap rectangle. */
uint8 _y2;
bool loadFromStream(Common::ReadStream &stream);
};
+/**
+ * Encoded exhausted choice.
+ */
struct ExhaustedChoice {
- /*
- 1 bit - context
- 3 bits - choice index
- 4 bits - choice list index
- */
+ /**
+ * 1 bit - context
+ * 3 bits - choice index
+ * 4 bits - choice list index
+ */
uint8 _encodedData;
uint8 getContext() const { return (_encodedData >> 7) & 0x1; }
@@ -154,29 +255,41 @@ struct Scene {
void addExhaustedChoice(uint8 context, uint8 choiceIndex, uint8 choiceIndexList);
bool isChoiceExhausted(uint8 context, uint8 choiceIndex, uint8 choiceIndexList) const;
+ /** Refers to the script block that will be executed when you enter this scene (DS register). */
uint8 _startup;
+ /**
+ * These three variables control downscaling of the player character depending on his Y.
+ * TODO: Find out more.
+ */
uint8 _unknown001;
uint8 _unknown002;
uint8 _unknown003;
- uint8 _DL;
+ uint8 _delay; /**< Delay between object animation advancements (DL register). */
+
+ uint8 _noDoors; /**< Number of doors in the scene (ND register). */
+ Door _doors[5]; /**< Door definitions. */
- uint8 _noDoors;
- Door _doors[5];
+ uint8 _noObjects; /**< Number of animated objects in the scene (NO register). */
+ Object _objects[9]; /**< Object definitions. */
- uint8 _noObjects;
- Object _objects[9];
+ uint8 _noStatics; /**< Number of statics in the scene (NS register). */
+ Static _statics[15]; /**< Static definitions. */
- uint8 _noStatics;
- Static _statics[15];
+ Bitmap _bitmaps[10]; /**< Bitmap definitions. There is no corresponding _noBitmaps field. */
- Bitmap _bitmaps[10];
+ uint16 _obstacleY1; /**< Fixed Y coordinate for all static obstacles in the scene. Always 0 in data files. */
- uint16 _obstacleY1;
- uint8 _palRotStart;
- uint8 _palRotEnd;
- uint8 _palRotPeriod;
+ /** First index (inclusive and 0-indexed) of the rotating portion of the palette (PF register). */
+ uint8 _palRotFirst;
+ /** Last index (inclusive and 0-indexed) of the rotating portion of the palette (PL register). */
+ uint8 _palRotLast;
+ /** Delay between each right rotation of the palette portion (PD register). */
+ uint8 _palRotDelay;
- /* Points to the first free item in exhausted choices list. */
+ /**
+ * Points to the first free item in exhausted choices list.
+ * @note Indexed from 1.
+ */
uint8 _exhaustedChoiceNext;
ExhaustedChoice _exhaustedChoices[79];
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
index 009c4be..414a367 100644
--- a/engines/mutationofjb/room.cpp
+++ b/engines/mutationofjb/room.cpp
@@ -71,12 +71,12 @@ void RoomAnimationDecoderCallback::onFrame(int frameNo, Graphics::Surface &surfa
const uint8 noObjects = scene->getNoObjects();
for (int i = 0; i < noObjects; ++i) {
Object &object = scene->_objects[i];
- const uint16 startFrame = (object._WY << 8) + object._FS;
- if (frameNo1 >= startFrame && frameNo1 < startFrame + object._NA) {
+ const uint16 startFrame = (object._roomFrameMSB << 8) + object._roomFrameLSB;
+ if (frameNo1 >= startFrame && frameNo1 < startFrame + object._numFrames) {
const int x = object._x;
const int y = object._y;
- const int w = (object._XL + 3) / 4 * 4; // Original code uses this to round up width to a multiple of 4.
- const int h = object._YL;
+ const int w = (object._width + 3) / 4 * 4; // Original code uses this to round up width to a multiple of 4.
+ const int h = object._height;
Common::Rect rect(x, y, x + w, y + h);
const Graphics::Surface sharedSurface = surface.getSubArea(rect);
@@ -100,11 +100,11 @@ bool Room::load(uint8 roomNumber, bool roomB) {
for (int i = 0; i < noObjects; ++i) {
uint8 firstIndex = 0;
if (i != 0) {
- firstIndex = _objectsStart[i - 1] + scene->_objects[i - 1]._NA;
+ firstIndex = _objectsStart[i - 1] + scene->_objects[i - 1]._numFrames;
}
_objectsStart.push_back(firstIndex);
- uint8 numAnims = scene->_objects[i]._NA;
+ uint8 numAnims = scene->_objects[i]._numFrames;
while (numAnims--) {
_surfaces.push_back(Graphics::Surface());
}
@@ -142,7 +142,7 @@ void Room::redraw() {
Scene *const currentScene = _game->getGameData().getCurrentScene();
for (int i = 0; i < currentScene->getNoObjects(); ++i) {
Object *const obj = currentScene->getObject(i + 1);
- if (obj->_AC) {
+ if (obj->_active) {
drawObjectAnimation(i + 1, 0);
}
}
diff --git a/engines/mutationofjb/tasks/objectanimationtask.cpp b/engines/mutationofjb/tasks/objectanimationtask.cpp
index 75c15bf..90438f8 100644
--- a/engines/mutationofjb/tasks/objectanimationtask.cpp
+++ b/engines/mutationofjb/tasks/objectanimationtask.cpp
@@ -31,6 +31,7 @@ namespace MutationOfJB {
static const int TICK_MILLIS = 100;
+// TODO: Respect currentScene._delay.
ObjectAnimationTask::ObjectAnimationTask() : _timer(TICK_MILLIS) {
}
@@ -47,6 +48,17 @@ void ObjectAnimationTask::update() {
}
}
+/**
+ * Advances every object animation in the current scene to the next frame.
+ *
+ * Normally the animation restarts after the last object frame. However, some animations have random
+ * elements to them. If _randomFrame is set, the animation restarts when _randomFrame is reached.
+ * Additionally, there is a chance with each frame until _randomFrame that the animation may jump
+ * straight to _randomFrame and continue until the last frame, then wrap around to the first frame.
+ *
+ * Randomness is used to introduce variety - e.g. in the starting scene a perched bird occassionally
+ * spreads its wings.
+ */
void ObjectAnimationTask::updateObjects() {
Scene *const scene = getTaskManager()->getGame().getGameData().getCurrentScene();
if (!scene) {
@@ -56,34 +68,34 @@ void ObjectAnimationTask::updateObjects() {
for (uint8 i = 1; i <= scene->getNoObjects(); ++i) {
Object *const object = scene->getObject(i);
// Skip if object animation not active.
- if (!object->_AC)
+ if (!object->_active)
continue;
- // Number of framers must be higher than 1.
- if (object->_NA <= 1)
+ // Number of frames must be higher than 1.
+ if (object->_numFrames <= 1)
continue;
- const uint8 currentAnimOffset = object->_CA - object->_FA;
+ const uint8 currentAnimOffset = object->_currentFrame - object->_firstFrame;
- const bool randomized = object->_FR != 0;
- const bool belowRandomFrame = currentAnimOffset < (object->_FR - 1);
+ const bool randomized = object->_randomFrame != 0;
+ const bool belowRandomFrame = currentAnimOffset < (object->_randomFrame - 1);
- uint8 maxAnimOffset = object->_NA - 1;
+ uint8 maxAnimOffset = object->_numFrames - 1;
if (randomized && belowRandomFrame) {
- maxAnimOffset = object->_FR - 2;
+ maxAnimOffset = object->_randomFrame - 2;
}
uint8 nextAnimationOffset = currentAnimOffset + 1;
if (currentAnimOffset == maxAnimOffset) {
- if (randomized && object->_unknown != 0 && getTaskManager()->getGame().getRandomSource().getRandomNumber(object->_unknown) == 0)
- nextAnimationOffset = object->_FR - 1;
+ if (randomized && object->_jumpChance != 0 && getTaskManager()->getGame().getRandomSource().getRandomNumber(object->_jumpChance) == 0)
+ nextAnimationOffset = object->_randomFrame - 1;
else
nextAnimationOffset = 0;
}
// TODO: Hardcoded animations.
- object->_CA = nextAnimationOffset + object->_FA;
+ object->_currentFrame = nextAnimationOffset + object->_firstFrame;
getTaskManager()->getGame().getRoom().drawObjectAnimation(i, nextAnimationOffset);
}
}
diff --git a/engines/mutationofjb/tasks/saytask.cpp b/engines/mutationofjb/tasks/saytask.cpp
index c9c2a95..bd89805 100644
--- a/engines/mutationofjb/tasks/saytask.cpp
+++ b/engines/mutationofjb/tasks/saytask.cpp
@@ -60,10 +60,12 @@ void SayTask::drawSubtitle(const Common::String &text, int16 talkX, int16 talkY,
Common::Array<Common::String> lines;
font.wordWrap(text, MAX_LINE_WIDTH, lines);
+ // Get the x, y coordinates of the top center point of the text's bounding box
+ // from the (rather strange) talk coordinates coming from scripts.
int16 x = talkX;
- int16 y = talkY - (lines.size() - 1) * font.getLineHeight() - 15; // Get the top y
+ int16 y = talkY - (lines.size() - 1) * font.getLineHeight() - 15;
- // Clamp to screen edges
+ // Clamp to screen edges.
y = MAX<int16>(y, 3);
int16 maxWidth = 0;
for (uint i = 0; i < lines.size(); i++) {
@@ -75,12 +77,12 @@ void SayTask::drawSubtitle(const Common::String &text, int16 talkX, int16 talkY,
x = MIN<int16>(x, 317 - lineWidth / 2);
}
- // Draw lines
+ // Draw lines.
for (uint i = 0; i < lines.size(); i++) {
font.drawString(lines[i], color, x - font.getWidth(lines[i]) / 2, y + i * font.getLineHeight(), getTaskManager()->getGame().getScreen());
}
- // Remember the area occupied by the text
+ // Remember the area occupied by the text.
_boundingBox.top = x - maxWidth / 2;
_boundingBox.left = y;
_boundingBox.setWidth(maxWidth);
Commit: 9aa911314fb54e71b9b37b8787626d25afbcd289
https://github.com/scummvm/scummvm/commit/9aa911314fb54e71b9b37b8787626d25afbcd289
Author: Miroslav Remák (miroslavr256 at gmail.com)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Handle hardcoded animations.
Changed paths:
engines/mutationofjb/tasks/objectanimationtask.cpp
engines/mutationofjb/tasks/objectanimationtask.h
diff --git a/engines/mutationofjb/tasks/objectanimationtask.cpp b/engines/mutationofjb/tasks/objectanimationtask.cpp
index 90438f8..e93602c 100644
--- a/engines/mutationofjb/tasks/objectanimationtask.cpp
+++ b/engines/mutationofjb/tasks/objectanimationtask.cpp
@@ -93,11 +93,81 @@ void ObjectAnimationTask::updateObjects() {
nextAnimationOffset = 0;
}
- // TODO: Hardcoded animations.
-
object->_currentFrame = nextAnimationOffset + object->_firstFrame;
- getTaskManager()->getGame().getRoom().drawObjectAnimation(i, nextAnimationOffset);
+
+ const bool drawObject = handleHardcodedAnimation(object);
+ if (drawObject) {
+ getTaskManager()->getGame().getRoom().drawObjectAnimation(i, nextAnimationOffset);
+ }
+ }
+}
+
+/**
+ * Nasty, hacky stuff the original game does to make some complex animations
+ * in the Carnival and Tavern Earthquake scenes possible.
+ *
+ * @param object Object to process.
+ * @return Whether to draw the object. It's important to respect this, otherwise
+ * some of the hardcoded animations would suffer from graphical glitches.
+ */
+bool ObjectAnimationTask::handleHardcodedAnimation(Object *const object) {
+ GameData &gameData = getTaskManager()->getGame().getGameData();
+ Scene *const scene = gameData.getCurrentScene();
+
+ const bool carnivalScene = gameData._currentScene == 30 && !gameData._partB;
+ const bool tavernScene = gameData._currentScene == 8 && gameData._partB;
+
+ if (carnivalScene) {
+ // This alternates between the two burglars' talking animations.
+ // Each burglar gets to talk for a varying amount of time since
+ // the switch occurs when his random frame is reached.
+ if (object->_WX == 1 && object->_currentFrame == 79) {
+ object->_currentFrame = 68;
+ object->_active = 0;
+ scene->getObject(6)->_active = 1;
+ scene->getObject(7)->_active = 0;
+ scene->getObject(8)->_active = 1;
+ return false;
+ } else if (object->_WX == 2 && object->_currentFrame == 91) {
+ object->_currentFrame = 80;
+ object->_active = 0;
+ scene->getObject(5)->_active = 1;
+ scene->getObject(7)->_active = 1;
+ scene->getObject(8)->_active = 0;
+ return false;
+ }
+
+ // The following makes sure you can't interact with the glass
+ // while the scientist is drinking from it.
+ if (scene->getObject(4)->_currentFrame > 52 && scene->getObject(4)->_active) {
+ scene->getStatic(9)->_active = 0; // disable scientist's glass
+ } else {
+ scene->getStatic(9)->_active = 1; // enable scientist's glass
+ }
+
+ if (!scene->getObject(4)->_active) {
+ scene->getStatic(9)->_active = 0; // disable scientist's glass
+ }
+ } else if (tavernScene) {
+ // Similarly to the carnival burglars, this alternates between
+ // the talking animations of the two soldiers in the tavern.
+ //
+ // At some point the script disables their conversation
+ // by nulling their _WX registers.
+ if (object->_WX == 3 && object->_currentFrame == 46) {
+ object->_currentFrame = 30;
+ object->_active = 0;
+ scene->getObject(3)->_active = 1;
+ return false;
+ } else if (object->_WX == 4 && object->_currentFrame == 63) {
+ object->_currentFrame = 47;
+ object->_active = 0;
+ scene->getObject(2)->_active = 1;
+ return false;
+ }
}
+
+ return true;
}
}
diff --git a/engines/mutationofjb/tasks/objectanimationtask.h b/engines/mutationofjb/tasks/objectanimationtask.h
index 39f80a3..320868f 100644
--- a/engines/mutationofjb/tasks/objectanimationtask.h
+++ b/engines/mutationofjb/tasks/objectanimationtask.h
@@ -29,6 +29,8 @@
namespace MutationOfJB {
+class Object;
+
class ObjectAnimationTask : public Task {
public:
ObjectAnimationTask();
@@ -37,6 +39,7 @@ public:
virtual void update() override;
void updateObjects();
+ bool handleHardcodedAnimation(Object *const object);
private:
Timer _timer;
Commit: 96fbe2f8817303e25e0436641e23b0f7b4275658
https://github.com/scummvm/scummvm/commit/96fbe2f8817303e25e0436641e23b0f7b4275658
Author: Miroslav Remák (miroslavr256 at gmail.com)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Fix crash when static/door name is set to empty string.
Changed paths:
engines/mutationofjb/commands/changecommand.cpp
diff --git a/engines/mutationofjb/commands/changecommand.cpp b/engines/mutationofjb/commands/changecommand.cpp
index d7a8f9c..4eac41e 100644
--- a/engines/mutationofjb/commands/changecommand.cpp
+++ b/engines/mutationofjb/commands/changecommand.cpp
@@ -52,7 +52,7 @@ bool ChangeCommandParser::parseValueString(const Common::String &valueString, bo
if (changeEntity) {
entityId = atoi(valueString.c_str() + 6);
}
- const char *val = nullptr;
+ const char *val = "";
if (changeEntity) {
if (valueString.size() >= 9) {
val = valueString.c_str() + 9;
Commit: 215b87ccca4c4888cd70c990271fe62177d054f0
https://github.com/scummvm/scummvm/commit/215b87ccca4c4888cd70c990271fe62177d054f0
Author: Miroslav Remák (miroslavr256 at gmail.com)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: When redrawing room, draw object animations at their current frame instead of their first frame.
Changed paths:
engines/mutationofjb/room.cpp
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
index 414a367..1da2730 100644
--- a/engines/mutationofjb/room.cpp
+++ b/engines/mutationofjb/room.cpp
@@ -143,7 +143,7 @@ void Room::redraw() {
for (int i = 0; i < currentScene->getNoObjects(); ++i) {
Object *const obj = currentScene->getObject(i + 1);
if (obj->_active) {
- drawObjectAnimation(i + 1, 0);
+ drawObjectAnimation(i + 1, obj->_currentFrame - _objectsStart[i] - 1);
}
}
}
Commit: 6c4ae7f19883dd7fa6de4fc3234351f1e33ba7a3
https://github.com/scummvm/scummvm/commit/6c4ae7f19883dd7fa6de4fc3234351f1e33ba7a3
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Implement multiple speeches in one response line.
Changed paths:
A engines/mutationofjb/tasks/sequentialtask.cpp
A engines/mutationofjb/tasks/sequentialtask.h
engines/mutationofjb/commands/talkcommand.cpp
engines/mutationofjb/commands/talkcommand.h
engines/mutationofjb/conversationlinelist.h
engines/mutationofjb/game.cpp
engines/mutationofjb/module.mk
engines/mutationofjb/tasks/conversationtask.cpp
engines/mutationofjb/tasks/conversationtask.h
engines/mutationofjb/tasks/task.h
engines/mutationofjb/tasks/taskmanager.cpp
engines/mutationofjb/tasks/taskmanager.h
diff --git a/engines/mutationofjb/commands/talkcommand.cpp b/engines/mutationofjb/commands/talkcommand.cpp
index 18ce956..8411e90 100644
--- a/engines/mutationofjb/commands/talkcommand.cpp
+++ b/engines/mutationofjb/commands/talkcommand.cpp
@@ -56,14 +56,13 @@ bool TalkCommandParser::parse(const Common::String &line, ScriptParseContext &,
Command::ExecuteResult TalkCommand::execute(ScriptExecutionContext &scriptExeCtx) {
if (!_task) {
- _task = new ConversationTask(scriptExeCtx.getGameData()._currentScene, scriptExeCtx.getGame().getGameData()._conversationInfo);
+ _task = TaskPtr(new ConversationTask(scriptExeCtx.getGameData()._currentScene, scriptExeCtx.getGame().getGameData()._conversationInfo, _mode));
scriptExeCtx.getGame().getTaskManager().addTask(_task);
}
if (_task->getState() == Task::FINISHED) {
scriptExeCtx.getGame().getTaskManager().removeTask(_task);
- delete _task;
- _task = nullptr;
+ _task.reset();
return Command::Finished;
}
diff --git a/engines/mutationofjb/commands/talkcommand.h b/engines/mutationofjb/commands/talkcommand.h
index 09424b2..15b185c 100644
--- a/engines/mutationofjb/commands/talkcommand.h
+++ b/engines/mutationofjb/commands/talkcommand.h
@@ -25,6 +25,7 @@
#include "mutationofjb/commands/seqcommand.h"
#include "common/scummsys.h"
+#include "mutationofjb/tasks/task.h"
namespace MutationOfJB {
@@ -43,13 +44,13 @@ public:
CARNIVAL_TICKET_SELLER_MODE
};
- TalkCommand(Mode mode) : _mode(mode), _task(nullptr) {}
+ TalkCommand(Mode mode) : _mode(mode) {}
virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const;
private:
Mode _mode;
- ConversationTask *_task;
+ TaskPtr _task;
};
}
diff --git a/engines/mutationofjb/conversationlinelist.h b/engines/mutationofjb/conversationlinelist.h
index 9ec446e..0f8346f 100644
--- a/engines/mutationofjb/conversationlinelist.h
+++ b/engines/mutationofjb/conversationlinelist.h
@@ -39,8 +39,9 @@ public:
bool isSecondSpeaker() const { return _text.firstChar() == '`'; }
};
+ typedef Common::Array<Speech> Speeches;
struct Line {
- Common::Array<Speech> _speeches;
+ Speeches _speeches;
Common::String _extra;
};
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 652336f..9f5f469 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -61,7 +61,7 @@ Game::Game(MutationOfJBEngine *vm)
_gui.init();
- _taskManager.addTask(new ObjectAnimationTask);
+ _taskManager.addTask(TaskPtr(new ObjectAnimationTask));
}
Common::RandomSource &Game::getRandomSource() {
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 1913fc6..60d450e 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -25,6 +25,7 @@ MODULE_OBJS := \
tasks/conversationtask.o \
tasks/objectanimationtask.o \
tasks/saytask.o \
+ tasks/sequentialtask.o \
tasks/taskmanager.o \
widgets/buttonwidget.o \
widgets/conversationwidget.o \
diff --git a/engines/mutationofjb/tasks/conversationtask.cpp b/engines/mutationofjb/tasks/conversationtask.cpp
index d675b2e..a2a0a73 100644
--- a/engines/mutationofjb/tasks/conversationtask.cpp
+++ b/engines/mutationofjb/tasks/conversationtask.cpp
@@ -23,12 +23,12 @@
#include "mutationofjb/tasks/conversationtask.h"
#include "mutationofjb/assets.h"
-#include "mutationofjb/conversationlinelist.h"
#include "mutationofjb/game.h"
#include "mutationofjb/gamedata.h"
#include "mutationofjb/gui.h"
#include "mutationofjb/script.h"
#include "mutationofjb/tasks/saytask.h"
+#include "mutationofjb/tasks/sequentialtask.h"
#include "mutationofjb/tasks/taskmanager.h"
#include "mutationofjb/util.h"
#include "mutationofjb/widgets/conversationwidget.h"
@@ -55,8 +55,7 @@ void ConversationTask::update() {
if (_sayTask) {
if (_sayTask->getState() == Task::FINISHED) {
getTaskManager()->removeTask(_sayTask);
- delete _sayTask;
- _sayTask = nullptr;
+ _sayTask.reset();
switch (_substate) {
case SAYING_NO_CHOICES:
@@ -66,9 +65,9 @@ void ConversationTask::update() {
const ConversationLineList& responseList = getTaskManager()->getGame().getAssets().getResponseList();
const ConversationLineList::Line *const line = responseList.getLine(_currentItem->_response);
- _sayTask = new SayTask(line->_speeches[0]._text, _convInfo._color);
- getTaskManager()->addTask(_sayTask);
_substate = SAYING_RESPONSE;
+ createSayTasks(line);
+ getTaskManager()->addTask(_sayTask);
break;
}
case SAYING_RESPONSE: {
@@ -102,14 +101,14 @@ void ConversationTask::onChoiceClicked(ConversationWidget *convWidget, int, uint
convWidget->clearChoices();
const ConversationLineList& toSayList = getTaskManager()->getGame().getAssets().getToSayList();
- const ConversationLineList::Speech &speech = toSayList.getLine(item._choice)->_speeches[0];
+ const ConversationLineList::Line *line = toSayList.getLine(item._choice);
- _sayTask = new SayTask(speech._text, _convInfo._color);
- getTaskManager()->addTask(_sayTask);
_substate = SAYING_CHOICE;
+ createSayTasks(line);
+ getTaskManager()->addTask(_sayTask);
_currentItem = &item;
- if (!speech.isRepeating()) {
+ if (!line->_speeches[0].isRepeating()) {
getTaskManager()->getGame().getGameData().getCurrentScene()->addExhaustedChoice(_convInfo._context, data + 1, _currentLineIndex + 1);
}
}
@@ -176,9 +175,9 @@ void ConversationTask::showChoicesOrPick() {
const ConversationInfo::Item &item = currentLine->_items[itemsWithValidChoices.front()];
const ConversationLineList::Line *const line = toSayList.getLine(item._choice);
- _sayTask = new SayTask(line->_speeches[0]._text, _convInfo._color);
- getTaskManager()->addTask(_sayTask);
_substate = SAYING_CHOICE;
+ createSayTasks(line);
+ getTaskManager()->addTask(_sayTask);
_currentItem = &item;
if (!line->_speeches[0].isRepeating()) {
@@ -191,9 +190,9 @@ void ConversationTask::showChoicesOrPick() {
const ConversationInfo::Item &item = currentLine->_items[itemsWithValidResponses.front()];
const ConversationLineList::Line *const line = responseList.getLine(item._response);
- _sayTask = new SayTask(line->_speeches[0]._text, _convInfo._color);
- getTaskManager()->addTask(_sayTask);
_substate = SAYING_RESPONSE;
+ createSayTasks(line);
+ getTaskManager()->addTask(_sayTask);
_currentItem = &item;
_haveChoices = true;
@@ -204,7 +203,7 @@ void ConversationTask::showChoicesOrPick() {
if (_haveChoices) {
finish();
} else {
- _sayTask = new SayTask("Nothing to talk about.", _convInfo._color); // TODO: This is hardcoded in executable. Load it.
+ _sayTask = TaskPtr(new SayTask("Nothing to talk about.", _convInfo._color)); // TODO: This is hardcoded in executable. Load it.
getTaskManager()->addTask(_sayTask);
_substate = SAYING_NO_CHOICES;
_currentItem = nullptr;
@@ -256,4 +255,32 @@ void ConversationTask::gotoNextLine() {
}
}
+void ConversationTask::createSayTasks(const ConversationLineList::Line *line) {
+ if (line->_speeches.size() == 1) {
+ const ConversationLineList::Speech &speech = line->_speeches[0];
+ _sayTask = TaskPtr(new SayTask(speech._text, getSpeechColor(speech)));
+ } else {
+ TaskPtrs tasks;
+ for (ConversationLineList::Speeches::const_iterator it = line->_speeches.begin(); it != line->_speeches.end(); ++it) {
+ tasks.push_back(TaskPtr(new SayTask(it->_text, getSpeechColor(*it))));
+ }
+ _sayTask = TaskPtr(new SequentialTask(tasks));
+ }
+}
+
+uint8 ConversationTask::getSpeechColor(const ConversationLineList::Speech &speech) {
+ uint8 color = WHITE;
+ if (_substate == SAYING_RESPONSE) {
+ color = _convInfo._color;
+ if (_mode == TalkCommand::RAY_AND_BUTTLEG_MODE) {
+ if (speech.isFirstSpeaker()) {
+ color = GREEN;
+ } else if (speech.isSecondSpeaker()) {
+ color = LIGHTBLUE;
+ }
+ }
+ }
+ return color;
+}
+
}
diff --git a/engines/mutationofjb/tasks/conversationtask.h b/engines/mutationofjb/tasks/conversationtask.h
index 41c8284..e4bbdc3 100644
--- a/engines/mutationofjb/tasks/conversationtask.h
+++ b/engines/mutationofjb/tasks/conversationtask.h
@@ -20,8 +20,10 @@
*
*/
-#include "mutationofjb/tasks/task.h"
+#include "mutationofjb/commands/talkcommand.h"
+#include "mutationofjb/conversationlinelist.h"
#include "mutationofjb/gamedata.h"
+#include "mutationofjb/tasks/task.h"
#include "mutationofjb/widgets/conversationwidget.h"
namespace MutationOfJB {
@@ -31,7 +33,7 @@ class ScriptExecutionContext;
class ConversationTask : public Task, public ConversationWidgetCallback {
public:
- ConversationTask(uint8 sceneId, const ConversationInfo& convInfo) : _sceneId(sceneId), _convInfo(convInfo), _currentLineIndex(0), _currentItem(nullptr), _sayTask(nullptr), _substate(IDLE), _haveChoices(false), _innerExecCtx(nullptr) {}
+ ConversationTask(uint8 sceneId, const ConversationInfo& convInfo, TalkCommand::Mode mode) : _sceneId(sceneId), _convInfo(convInfo), _mode(mode), _currentLineIndex(0), _currentItem(nullptr), _substate(IDLE), _haveChoices(false), _innerExecCtx(nullptr) {}
virtual ~ConversationTask() {}
virtual void start() override;
@@ -44,12 +46,15 @@ private:
void finish();
void startExtra();
void gotoNextLine();
+ void createSayTasks(const ConversationLineList::Line *line);
+ uint8 getSpeechColor(const ConversationLineList::Speech &speech);
uint8 _sceneId;
const ConversationInfo &_convInfo;
+ TalkCommand::Mode _mode;
uint _currentLineIndex;
const ConversationInfo::Item *_currentItem;
- SayTask* _sayTask;
+ TaskPtr _sayTask;
enum Substate {
IDLE,
diff --git a/engines/mutationofjb/tasks/sequentialtask.cpp b/engines/mutationofjb/tasks/sequentialtask.cpp
new file mode 100644
index 0000000..57efbb5
--- /dev/null
+++ b/engines/mutationofjb/tasks/sequentialtask.cpp
@@ -0,0 +1,62 @@
+/* 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/tasks/sequentialtask.h"
+
+#include "mutationofjb/tasks/taskmanager.h"
+
+namespace MutationOfJB {
+
+SequentialTask::SequentialTask(const TaskPtrs &tasks) : _tasks(tasks) {
+}
+
+void SequentialTask::start() {
+ setState(RUNNING);
+ runTasks();
+}
+
+void SequentialTask::update() {
+ runTasks();
+}
+
+void SequentialTask::runTasks() {
+ while (true) {
+ if (_tasks.empty()) {
+ setState(FINISHED);
+ return;
+ }
+
+ const TaskPtr &task = _tasks.front();
+ switch (task->getState()) {
+ case IDLE:
+ getTaskManager()->addTask(task);
+ break;
+ case RUNNING:
+ return;
+ case FINISHED:
+ _tasks.remove_at(0);
+ break;
+ }
+ }
+}
+
+}
diff --git a/engines/mutationofjb/tasks/sequentialtask.h b/engines/mutationofjb/tasks/sequentialtask.h
new file mode 100644
index 0000000..078fd8a
--- /dev/null
+++ b/engines/mutationofjb/tasks/sequentialtask.h
@@ -0,0 +1,45 @@
+/* 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_SEQUENTIALTASK_H
+#define MUTATIONOFJB_SEQUENTIALTASK_H
+
+#include "mutationofjb/tasks/task.h"
+
+namespace MutationOfJB {
+
+class SequentialTask : public Task {
+public:
+ SequentialTask(const TaskPtrs &tasks);
+
+ virtual void start() override;
+ virtual void update() override;
+
+private:
+ void runTasks();
+
+ TaskPtrs _tasks;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/tasks/task.h b/engines/mutationofjb/tasks/task.h
index 1b98097..9f2acb3 100644
--- a/engines/mutationofjb/tasks/task.h
+++ b/engines/mutationofjb/tasks/task.h
@@ -24,6 +24,8 @@
#define MUTATIONOFJB_TASK_H
#include "common/scummsys.h"
+#include "common/ptr.h"
+#include "common/array.h"
namespace MutationOfJB {
@@ -37,7 +39,7 @@ public:
FINISHED
};
- Task() : _taskManager(nullptr) {}
+ Task() : _taskManager(nullptr), _state(IDLE) {}
virtual ~Task() {}
virtual void start() = 0;
@@ -56,6 +58,9 @@ private:
State _state;
};
+typedef Common::SharedPtr<Task> TaskPtr;
+typedef Common::Array<Common::SharedPtr<Task> > TaskPtrs;
+
}
#endif
diff --git a/engines/mutationofjb/tasks/taskmanager.cpp b/engines/mutationofjb/tasks/taskmanager.cpp
index 7fbf64d..1167500 100644
--- a/engines/mutationofjb/tasks/taskmanager.cpp
+++ b/engines/mutationofjb/tasks/taskmanager.cpp
@@ -25,24 +25,31 @@
namespace MutationOfJB {
-void TaskManager::addTask(Task *task) {
+void TaskManager::addTask(const TaskPtr &task) {
_tasks.push_back(task);
task->setTaskManager(this);
task->start();
}
-void TaskManager::removeTask(Task *task) {
- Tasks::iterator it = Common::find(_tasks.begin(), _tasks.end(), task);
+void TaskManager::removeTask(const TaskPtr &task) {
+ TaskPtrs::iterator it = Common::find(_tasks.begin(), _tasks.end(), task);
if (it != _tasks.end()) {
_tasks.erase(it);
}
}
void TaskManager::update() {
- for (Tasks::const_iterator it = _tasks.begin(); it != _tasks.end(); ++it) {
- if ((*it)->getState() == Task::RUNNING) {
+ for (TaskPtrs::iterator it = _tasks.begin(); it != _tasks.end();) {
+ const Task::State state = (*it)->getState();
+ if (state == Task::RUNNING) {
(*it)->update();
}
+
+ if (state == Task::FINISHED) {
+ it = _tasks.erase(it);
+ } else {
+ ++it;
+ }
}
}
diff --git a/engines/mutationofjb/tasks/taskmanager.h b/engines/mutationofjb/tasks/taskmanager.h
index 1f6be36..299a271 100644
--- a/engines/mutationofjb/tasks/taskmanager.h
+++ b/engines/mutationofjb/tasks/taskmanager.h
@@ -24,6 +24,7 @@
#define MUTATIONOFJB_TASKMANAGER_H
#include "common/array.h"
+#include "task.h"
namespace MutationOfJB {
@@ -34,15 +35,14 @@ class TaskManager {
public:
TaskManager(Game &game) : _game(game) {}
- void addTask(Task *task);
- void removeTask(Task *task);
+ void addTask(const TaskPtr &task);
+ void removeTask(const TaskPtr &task);
void update();
Game &getGame() { return _game; }
private:
- typedef Common::Array<Task *> Tasks;
- Tasks _tasks;
+ TaskPtrs _tasks;
Game &_game;
};
Commit: 2e656e69b3b9416f5164f0963951df203f4978e5
https://github.com/scummvm/scummvm/commit/2e656e69b3b9416f5164f0963951df203f4978e5
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Blit with threshold.
Changed paths:
engines/mutationofjb/room.cpp
engines/mutationofjb/util.cpp
engines/mutationofjb/util.h
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
index 1da2730..dd9a6db 100644
--- a/engines/mutationofjb/room.cpp
+++ b/engines/mutationofjb/room.cpp
@@ -28,6 +28,7 @@
#include "mutationofjb/gamedata.h"
#include "mutationofjb/util.h"
+#include "common/rect.h"
#include "common/str.h"
#include "common/translation.h"
@@ -117,6 +118,13 @@ bool Room::load(uint8 roomNumber, bool roomB) {
return decoder.decode(&callback);
}
+// TODO: Take the threshold value from ATN data.
+struct ThresholdBlitOperation {
+ bool operator()(const byte /*srcColor*/, const byte destColor) {
+ return destColor <= 0xBF;
+ }
+};
+
void Room::drawObjectAnimation(uint8 objectId, int animOffset) {
Scene *const scene = _game->getGameData().getCurrentScene();
if (!scene) {
@@ -129,8 +137,8 @@ void Room::drawObjectAnimation(uint8 objectId, int animOffset) {
const int startFrame = _objectsStart[objectId - 1];
const int animFrame = startFrame + animOffset;
- // TODO: Threshold.
- _screen->blitFrom(_surfaces[animFrame], Common::Point(object->_x, object->_y));
+
+ blit_if(_surfaces[animFrame], *_screen, Common::Point(object->_x, object->_y), ThresholdBlitOperation());
}
void Room::redraw() {
@@ -140,7 +148,7 @@ void Room::redraw() {
}
Scene *const currentScene = _game->getGameData().getCurrentScene();
- for (int i = 0; i < currentScene->getNoObjects(); ++i) {
+ for (uint8 i = 0; i < currentScene->getNoObjects(); ++i) {
Object *const obj = currentScene->getObject(i + 1);
if (obj->_active) {
drawObjectAnimation(i + 1, obj->_currentFrame - _objectsStart[i] - 1);
diff --git a/engines/mutationofjb/util.cpp b/engines/mutationofjb/util.cpp
index 6d7c02a..72d2d0f 100644
--- a/engines/mutationofjb/util.cpp
+++ b/engines/mutationofjb/util.cpp
@@ -21,8 +21,10 @@
*/
#include "mutationofjb/util.h"
+
#include "common/str.h"
#include "common/translation.h"
+
#include "engines/engine.h"
namespace MutationOfJB {
diff --git a/engines/mutationofjb/util.h b/engines/mutationofjb/util.h
index 86ee10f..06d1a0b 100644
--- a/engines/mutationofjb/util.h
+++ b/engines/mutationofjb/util.h
@@ -23,15 +23,51 @@
#ifndef MUTATIONOFJB_UTIL_H
#define MUTATIONOFJB_UTIL_H
+#include "common/rect.h"
+
+#include "graphics/managed_surface.h"
+#include "graphics/surface.h"
+
namespace Common {
class String;
}
+
namespace MutationOfJB {
void reportFileMissingError(const char *fileName);
Common::String toUpperCP895(const Common::String &str);
+template <typename BlitOp>
+void blit_if(const Graphics::Surface &src, const Common::Rect &srcRect, Graphics::ManagedSurface &dest, const Common::Point &destPos, BlitOp blitOp) {
+ const Common::Rect srcBounds = srcRect;
+ const Common::Rect destBounds(destPos.x, destPos.y, destPos.x + srcRect.width(), destPos.y + srcRect.height());
+
+ assert(srcRect.isValidRect());
+ assert(dest.format == src.format);
+
+ for (int y = 0; y < srcBounds.height(); ++y) {
+ const byte *srcP = reinterpret_cast<const byte *>(src.getBasePtr(srcBounds.left, srcBounds.top + y));
+ const byte *srcEndP = srcP + srcBounds.width();
+ byte *destP = reinterpret_cast<byte *>(dest.getBasePtr(destBounds.left, destBounds.top + y));
+
+ while (srcP != srcEndP) {
+ if (blitOp(*srcP, *destP)) {
+ *destP = *srcP;
+ }
+ ++srcP;
+ ++destP;
+ }
+ }
+
+ dest.getSubArea(destBounds); // This is a hack to invalidate the destination rectangle.
+}
+
+template <typename BlitOp>
+void blit_if(const Graphics::Surface &src, Graphics::ManagedSurface &dest, const Common::Point &destPos, BlitOp blitOp) {
+ blit_if(src, Common::Rect(0, 0, src.w, src.h), dest, destPos, blitOp);
+}
+
}
#endif
Commit: 3306cbfeaa2f1c6fd471daaee054290df7e44280
https://github.com/scummvm/scummvm/commit/3306cbfeaa2f1c6fd471daaee054290df7e44280
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Implement SayCommand::execute.
Changed paths:
engines/mutationofjb/commands/saycommand.cpp
engines/mutationofjb/commands/talkcommand.cpp
engines/mutationofjb/font.cpp
engines/mutationofjb/game.cpp
engines/mutationofjb/game.h
engines/mutationofjb/gamedata.cpp
engines/mutationofjb/gamedata.h
engines/mutationofjb/script.cpp
engines/mutationofjb/tasks/conversationtask.cpp
engines/mutationofjb/tasks/saytask.cpp
engines/mutationofjb/tasks/saytask.h
engines/mutationofjb/tasks/sequentialtask.cpp
engines/mutationofjb/tasks/task.h
engines/mutationofjb/tasks/taskmanager.cpp
engines/mutationofjb/tasks/taskmanager.h
diff --git a/engines/mutationofjb/commands/saycommand.cpp b/engines/mutationofjb/commands/saycommand.cpp
index 854c957..0474a3e 100644
--- a/engines/mutationofjb/commands/saycommand.cpp
+++ b/engines/mutationofjb/commands/saycommand.cpp
@@ -21,7 +21,13 @@
*/
#include "mutationofjb/commands/saycommand.h"
+
+#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
#include "mutationofjb/script.h"
+#include "mutationofjb/tasks/saytask.h"
+#include "mutationofjb/tasks/taskmanager.h"
+
#include "common/str.h"
#include "common/debug.h"
#include "common/debug-channels.h"
@@ -140,9 +146,18 @@ bool SayCommandParser::parse(const Common::String &line, ScriptParseContext &par
}
-Command::ExecuteResult SayCommand::execute(ScriptExecutionContext &) {
- // TODO: Actual implementation.
- debug("%s [%s]", _lineToSay.c_str(), _voiceFile.c_str());
+Command::ExecuteResult SayCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ Game &game = scriptExecCtx.getGame();
+
+ if (_waitForPrevious) {
+ if (game.getActiveSayTask()) {
+ return InProgress;
+ }
+ }
+
+ TaskPtr task(new SayTask(_lineToSay, game.getGameData()._color));
+ game.getTaskManager().startTask(task);
+
return Finished;
}
diff --git a/engines/mutationofjb/commands/talkcommand.cpp b/engines/mutationofjb/commands/talkcommand.cpp
index 8411e90..6a3b204 100644
--- a/engines/mutationofjb/commands/talkcommand.cpp
+++ b/engines/mutationofjb/commands/talkcommand.cpp
@@ -57,11 +57,10 @@ bool TalkCommandParser::parse(const Common::String &line, ScriptParseContext &,
Command::ExecuteResult TalkCommand::execute(ScriptExecutionContext &scriptExeCtx) {
if (!_task) {
_task = TaskPtr(new ConversationTask(scriptExeCtx.getGameData()._currentScene, scriptExeCtx.getGame().getGameData()._conversationInfo, _mode));
- scriptExeCtx.getGame().getTaskManager().addTask(_task);
+ scriptExeCtx.getGame().getTaskManager().startTask(_task);
}
if (_task->getState() == Task::FINISHED) {
- scriptExeCtx.getGame().getTaskManager().removeTask(_task);
_task.reset();
return Command::Finished;
diff --git a/engines/mutationofjb/font.cpp b/engines/mutationofjb/font.cpp
index 4350b19..4f4a0ee 100644
--- a/engines/mutationofjb/font.cpp
+++ b/engines/mutationofjb/font.cpp
@@ -77,7 +77,7 @@ bool Font::load(const Common::String &fileName) {
void Font::drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf) const {
GlyphMap::iterator it = _glyphs.find(glyph);
if (it == _glyphs.end()) {
- warning("Glyph %d not found", glyph);
+ // Missing glyph is a common situation in the game and it's okay to ignore it.
return;
}
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 9f5f469..787bb7b 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -42,8 +42,8 @@ Game::Game(MutationOfJBEngine *vm)
_randomSource("mutationofjb"),
_delayedLocalScript(nullptr),
_gui(*this, _vm->getScreen()),
- _scriptExecCtx(*this),
_currentAction(ActionInfo::Walk),
+ _scriptExecCtx(*this),
_taskManager(*this),
_assets(*this) {
@@ -61,7 +61,7 @@ Game::Game(MutationOfJBEngine *vm)
_gui.init();
- _taskManager.addTask(TaskPtr(new ObjectAnimationTask));
+ _taskManager.startTask(TaskPtr(new ObjectAnimationTask));
}
Common::RandomSource &Game::getRandomSource() {
@@ -240,9 +240,16 @@ Assets &Game::getAssets() {
return _assets;
}
-Graphics::Screen &Game::getScreen()
-{
+Graphics::Screen &Game::getScreen() {
return *_vm->getScreen();
}
+TaskPtr Game::getActiveSayTask() const {
+ return _activeSayTask;
+}
+
+void Game::setActiveSayTask(const TaskPtr &sayTask) {
+ _activeSayTask = sayTask;
+}
+
}
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index d70bd09..316dc75 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -23,13 +23,15 @@
#ifndef MUTATIONOFJB_GAME_H
#define MUTATIONOFJB_GAME_H
-#include "common/random.h"
-#include "common/scummsys.h"
#include "mutationofjb/assets.h"
#include "mutationofjb/gui.h"
#include "mutationofjb/script.h"
#include "mutationofjb/tasks/taskmanager.h"
+#include "common/ptr.h"
+#include "common/random.h"
+#include "common/scummsys.h"
+
namespace Common {
class String;
}
@@ -44,6 +46,7 @@ class Room;
class Door;
class Static;
class Bitmap;
+class SayTask;
class Game {
public:
@@ -75,6 +78,9 @@ public:
Graphics::Screen &getScreen();
+ TaskPtr getActiveSayTask() const;
+ void setActiveSayTask(const TaskPtr &sayTask);
+
private:
bool loadGameData(bool partB);
void runActiveCommand();
@@ -96,6 +102,7 @@ private:
TaskManager _taskManager;
Assets _assets;
+ TaskPtr _activeSayTask;
};
}
diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp
index b6295a7..54335d1 100644
--- a/engines/mutationofjb/gamedata.cpp
+++ b/engines/mutationofjb/gamedata.cpp
@@ -247,7 +247,8 @@ GameData::GameData()
: _currentScene(0),
_lastScene(0),
_partB(false),
- _inventory()
+ _inventory(),
+ _color(WHITE)
{}
Scene *GameData::getScene(uint8 sceneId) {
diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h
index 99174ee..47272c6 100644
--- a/engines/mutationofjb/gamedata.h
+++ b/engines/mutationofjb/gamedata.h
@@ -323,14 +323,16 @@ public:
bool loadFromStream(Common::ReadStream &stream);
- uint8 _currentScene;
+ uint8 _currentScene; // Persistent.
uint8 _lastScene;
- bool _partB;
- Inventory _inventory;
- Common::String _currentAPK;
+ bool _partB; // Persistent.
+ Inventory _inventory; // Persistent.
+ Common::String _currentAPK; // Persistent.
ConversationInfo _conversationInfo;
+ /** Current SayCommand color. */
+ uint8 _color;
private:
- Scene _scenes[45];
+ Scene _scenes[45]; // Persistent.
};
enum Colors {
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 39c4859..069545c 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -154,6 +154,7 @@ Command::ExecuteResult ScriptExecutionContext::startCommand(Command *cmd) {
warning(_("Trying to start command while another one is running."));
return Command::Finished;
}
+ getGameData()._color = WHITE; // The original game resets the color to WHITE beforing running script sections.
clear();
_activeCommand = cmd;
return runActiveCommand();
diff --git a/engines/mutationofjb/tasks/conversationtask.cpp b/engines/mutationofjb/tasks/conversationtask.cpp
index a2a0a73..d4fab56 100644
--- a/engines/mutationofjb/tasks/conversationtask.cpp
+++ b/engines/mutationofjb/tasks/conversationtask.cpp
@@ -54,7 +54,6 @@ void ConversationTask::start() {
void ConversationTask::update() {
if (_sayTask) {
if (_sayTask->getState() == Task::FINISHED) {
- getTaskManager()->removeTask(_sayTask);
_sayTask.reset();
switch (_substate) {
@@ -67,7 +66,7 @@ void ConversationTask::update() {
_substate = SAYING_RESPONSE;
createSayTasks(line);
- getTaskManager()->addTask(_sayTask);
+ getTaskManager()->startTask(_sayTask);
break;
}
case SAYING_RESPONSE: {
@@ -105,7 +104,7 @@ void ConversationTask::onChoiceClicked(ConversationWidget *convWidget, int, uint
_substate = SAYING_CHOICE;
createSayTasks(line);
- getTaskManager()->addTask(_sayTask);
+ getTaskManager()->startTask(_sayTask);
_currentItem = &item;
if (!line->_speeches[0].isRepeating()) {
@@ -177,7 +176,7 @@ void ConversationTask::showChoicesOrPick() {
_substate = SAYING_CHOICE;
createSayTasks(line);
- getTaskManager()->addTask(_sayTask);
+ getTaskManager()->startTask(_sayTask);
_currentItem = &item;
if (!line->_speeches[0].isRepeating()) {
@@ -192,7 +191,7 @@ void ConversationTask::showChoicesOrPick() {
_substate = SAYING_RESPONSE;
createSayTasks(line);
- getTaskManager()->addTask(_sayTask);
+ getTaskManager()->startTask(_sayTask);
_currentItem = &item;
_haveChoices = true;
@@ -204,7 +203,7 @@ void ConversationTask::showChoicesOrPick() {
finish();
} else {
_sayTask = TaskPtr(new SayTask("Nothing to talk about.", _convInfo._color)); // TODO: This is hardcoded in executable. Load it.
- getTaskManager()->addTask(_sayTask);
+ getTaskManager()->startTask(_sayTask);
_substate = SAYING_NO_CHOICES;
_currentItem = nullptr;
}
diff --git a/engines/mutationofjb/tasks/saytask.cpp b/engines/mutationofjb/tasks/saytask.cpp
index bd89805..cfa412b 100644
--- a/engines/mutationofjb/tasks/saytask.cpp
+++ b/engines/mutationofjb/tasks/saytask.cpp
@@ -34,21 +34,31 @@
namespace MutationOfJB {
-SayTask::SayTask(const Common::String &toSay, uint8 color) : _toSay(toSay), _color(color), _timer(1000) {}
+SayTask::SayTask(const Common::String &toSay, uint8 color) : _toSay(toSay), _color(color), _timer(50 * toSay.size()) {}
void SayTask::start() {
+ Game &game = getTaskManager()->getGame();
+ if (game.getActiveSayTask()) {
+ getTaskManager()->stopTask(game.getActiveSayTask());
+ }
+ game.setActiveSayTask(getTaskManager()->getTask(this));
+
+ setState(RUNNING);
drawSubtitle(_toSay, 160, 0, _color); // TODO: Respect PTALK and LTALK commands.
_timer.start();
- setState(RUNNING);
}
void SayTask::update() {
_timer.update();
if (_timer.isFinished()) {
- getTaskManager()->getGame().getRoom().redraw(); // TODO: Only redraw the area occupied by the text.
- setState(FINISHED);
- return;
+ finish();
+ }
+}
+
+void SayTask::stop() {
+ if (getState() == RUNNING) {
+ finish();
}
}
@@ -89,4 +99,14 @@ void SayTask::drawSubtitle(const Common::String &text, int16 talkX, int16 talkY,
_boundingBox.setHeight(lines.size() * font.getLineHeight());
}
+void SayTask::finish() {
+ getTaskManager()->getGame().getRoom().redraw(); // TODO: Only redraw the area occupied by the text.
+ setState(FINISHED);
+
+ Game &game = getTaskManager()->getGame();
+ if (game.getActiveSayTask().get() == this) {
+ game.setActiveSayTask(Common::SharedPtr<SayTask>());
+ }
+}
+
}
diff --git a/engines/mutationofjb/tasks/saytask.h b/engines/mutationofjb/tasks/saytask.h
index 17e773d..2200436 100644
--- a/engines/mutationofjb/tasks/saytask.h
+++ b/engines/mutationofjb/tasks/saytask.h
@@ -38,9 +38,11 @@ public:
virtual void start() override;
virtual void update() override;
+ virtual void stop() override;
private:
void drawSubtitle(const Common::String &text, int16 talkX, int16 talkY, uint8 color);
+ void finish();
Common::String _toSay;
uint8 _color;
diff --git a/engines/mutationofjb/tasks/sequentialtask.cpp b/engines/mutationofjb/tasks/sequentialtask.cpp
index 57efbb5..20b5290 100644
--- a/engines/mutationofjb/tasks/sequentialtask.cpp
+++ b/engines/mutationofjb/tasks/sequentialtask.cpp
@@ -48,7 +48,7 @@ void SequentialTask::runTasks() {
const TaskPtr &task = _tasks.front();
switch (task->getState()) {
case IDLE:
- getTaskManager()->addTask(task);
+ getTaskManager()->startTask(task);
break;
case RUNNING:
return;
diff --git a/engines/mutationofjb/tasks/task.h b/engines/mutationofjb/tasks/task.h
index 9f2acb3..8c9c0e8 100644
--- a/engines/mutationofjb/tasks/task.h
+++ b/engines/mutationofjb/tasks/task.h
@@ -44,6 +44,7 @@ public:
virtual void start() = 0;
virtual void update() = 0;
+ virtual void stop() { assert(false); } // Assert by default - stopping might not be safe for all tasks.
void setTaskManager(TaskManager *taskMan) { _taskManager = taskMan; }
TaskManager *getTaskManager() { return _taskManager; }
diff --git a/engines/mutationofjb/tasks/taskmanager.cpp b/engines/mutationofjb/tasks/taskmanager.cpp
index 1167500..a6d4dc1 100644
--- a/engines/mutationofjb/tasks/taskmanager.cpp
+++ b/engines/mutationofjb/tasks/taskmanager.cpp
@@ -21,21 +21,39 @@
*/
#include "mutationofjb/tasks/taskmanager.h"
+
#include "mutationofjb/tasks/task.h"
+#include "common/translation.h"
+
namespace MutationOfJB {
-void TaskManager::addTask(const TaskPtr &task) {
+void TaskManager::startTask(const TaskPtr &task) {
_tasks.push_back(task);
task->setTaskManager(this);
task->start();
}
-void TaskManager::removeTask(const TaskPtr &task) {
+void TaskManager::stopTask(const TaskPtr &task) {
TaskPtrs::iterator it = Common::find(_tasks.begin(), _tasks.end(), task);
- if (it != _tasks.end()) {
- _tasks.erase(it);
+ if (it == _tasks.end()) {
+ warning(_("Task is not registered in TaskManager."));
+ return;
+ }
+
+ task->stop();
+ assert(task->getState() != Task::RUNNING);
+ _tasks.erase(it);
+}
+
+TaskPtr TaskManager::getTask(Task *const task) {
+ for (TaskPtrs::iterator it = _tasks.begin(); it != _tasks.end(); ++it) {
+ if (it->get() == task) {
+ return *it;
+ }
}
+
+ return TaskPtr();
}
void TaskManager::update() {
diff --git a/engines/mutationofjb/tasks/taskmanager.h b/engines/mutationofjb/tasks/taskmanager.h
index 299a271..29e854a 100644
--- a/engines/mutationofjb/tasks/taskmanager.h
+++ b/engines/mutationofjb/tasks/taskmanager.h
@@ -35,8 +35,30 @@ class TaskManager {
public:
TaskManager(Game &game) : _game(game) {}
- void addTask(const TaskPtr &task);
- void removeTask(const TaskPtr &task);
+ /**
+ * Adds the task to the internal list and starts it.
+ *
+ * When the task is finished, it is automatically removed from the list.
+ * stopTask does not need to be called for that.
+ */
+ void startTask(const TaskPtr &task);
+
+ /**
+ * Stops the task and removes it from the internal list.
+ *
+ * Call this only if you need to explicitly stop the task (usually before it's finished).
+ */
+ void stopTask(const TaskPtr &task);
+
+ /**
+ * Gets task shared pointer from raw pointer.
+ *
+ * Since task lifetime is under control of SharedPtr, raw pointers shouldn't be used.
+ * However, if only a raw pointer is available (e.g. this),
+ * the method can be used to obtain a SharedPtr.
+ */
+ TaskPtr getTask(Task* task);
+
void update();
Game &getGame() { return _game; }
Commit: 32df911b4d29342552556bc22dda7f2e13968d0d
https://github.com/scummvm/scummvm/commit/32df911b4d29342552556bc22dda7f2e13968d0d
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Implement SETCOL command.
Changed paths:
A engines/mutationofjb/commands/setcolorcommand.cpp
A engines/mutationofjb/commands/setcolorcommand.h
engines/mutationofjb/game.cpp
engines/mutationofjb/module.mk
engines/mutationofjb/script.cpp
diff --git a/engines/mutationofjb/commands/setcolorcommand.cpp b/engines/mutationofjb/commands/setcolorcommand.cpp
new file mode 100644
index 0000000..dbcb2a8
--- /dev/null
+++ b/engines/mutationofjb/commands/setcolorcommand.cpp
@@ -0,0 +1,60 @@
+/* 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/setcolorcommand.h"
+
+#include "mutationofjb/game.h"
+#include "mutationofjb/gamedata.h"
+#include "mutationofjb/script.h"
+
+#include "common/str.h"
+
+/** @file
+ * "SETCOL " <colorString>
+ *
+ * Sets subtitle color used by SayCommand.
+ */
+
+namespace MutationOfJB {
+
+bool SetColorCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
+ if (line.size() < 8 || !line.hasPrefix("SETCOL")) {
+ return false;
+ }
+
+ const char *const colorStr = line.c_str() + 7;
+ const uint8 color = Game::colorFromString(colorStr);
+
+ command = new SetColorCommand(color);
+ return true;
+}
+
+Command::ExecuteResult SetColorCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+ scriptExecCtx.getGameData()._color = _color;
+ return Finished;
+}
+
+Common::String SetColorCommand::debugString() const {
+ return Common::String::format("SETCOL %u", _color);
+}
+
+}
diff --git a/engines/mutationofjb/commands/setcolorcommand.h b/engines/mutationofjb/commands/setcolorcommand.h
new file mode 100644
index 0000000..ace36ff
--- /dev/null
+++ b/engines/mutationofjb/commands/setcolorcommand.h
@@ -0,0 +1,51 @@
+/* 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_SETCOLORCOMMAND_H
+#define MUTATIONOFJB_SETCOLORCOMMAND_H
+
+#include "mutationofjb/commands/seqcommand.h"
+
+#include "common/scummsys.h"
+
+namespace MutationOfJB {
+
+class SetColorCommandParser : public SeqCommandParser {
+public:
+ virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) override;
+};
+
+
+class SetColorCommand : public SeqCommand {
+public:
+ SetColorCommand(uint8 color) : _color(color) {}
+
+ virtual Command::ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
+ virtual Common::String debugString() const override;
+
+private:
+ uint8 _color;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 787bb7b..7b500d3 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -228,6 +228,10 @@ uint8 Game::colorFromString(const char *colorStr) {
}
}
+ if (*colorStr == 'n') {
+ return static_cast<uint8>(atoi(colorStr + 1));
+ }
+
warning(_("Color not found"));
return 0x00;
}
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 60d450e..465f228 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -20,6 +20,7 @@ MODULE_OBJS := \
commands/renamecommand.o \
commands/saycommand.o \
commands/seqcommand.o \
+ commands/setcolorcommand.o \
commands/talkcommand.o \
commands/randomcommand.o \
tasks/conversationtask.o \
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 069545c..3e93c47 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -46,6 +46,7 @@
#include "mutationofjb/commands/definestructcommand.h"
#include "mutationofjb/commands/talkcommand.h"
#include "mutationofjb/commands/randomcommand.h"
+#include "mutationofjb/commands/setcolorcommand.h"
#include "mutationofjb/game.h"
namespace MutationOfJB {
@@ -74,6 +75,7 @@ static CommandParser **getParsers() {
new LabelCommandParser,
new RandomCommandParser,
new RandomBlockStartParser,
+ new SetColorCommandParser,
nullptr
};
Commit: 4fbbaf944a392d67047dac64835f37cfcf518ecf
https://github.com/scummvm/scummvm/commit/4fbbaf944a392d67047dac64835f37cfcf518ecf
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Extend blit_if to support both ManagedSurface and Surface.
Changed paths:
engines/mutationofjb/room.cpp
engines/mutationofjb/util.h
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
index dd9a6db..a396a64 100644
--- a/engines/mutationofjb/room.cpp
+++ b/engines/mutationofjb/room.cpp
@@ -120,8 +120,14 @@ bool Room::load(uint8 roomNumber, bool roomB) {
// TODO: Take the threshold value from ATN data.
struct ThresholdBlitOperation {
- bool operator()(const byte /*srcColor*/, const byte destColor) {
- return destColor <= 0xBF;
+ byte operator()(const byte srcColor, const byte destColor) {
+ if (destColor <= 0xBF) {
+ // Within threshold - replace destination with source color.
+ return srcColor;
+ }
+
+ // Outside of threshold - keep destination color.
+ return destColor;
}
};
diff --git a/engines/mutationofjb/util.h b/engines/mutationofjb/util.h
index 06d1a0b..51c532b 100644
--- a/engines/mutationofjb/util.h
+++ b/engines/mutationofjb/util.h
@@ -38,29 +38,73 @@ namespace MutationOfJB {
void reportFileMissingError(const char *fileName);
Common::String toUpperCP895(const Common::String &str);
+template <typename SurfaceType>
+void clipBounds(Common::Rect &srcBounds, Common::Rect &destBounds, SurfaceType &destSurf) {
+ // Clip the bounds if source is too big to fit into destination.
+ if (destBounds.right > destSurf.w) {
+ srcBounds.right -= destBounds.right - destSurf.w;
+ destBounds.right = destSurf.w;
+ }
+
+ if (destBounds.bottom > destSurf.h) {
+ srcBounds.bottom -= destBounds.bottom - destSurf.h;
+ destBounds.bottom = destSurf.h;
+ }
+
+ if (destBounds.top < 0) {
+ srcBounds.top += -destBounds.top;
+ destBounds.top = 0;
+ }
+
+ if (destBounds.left < 0) {
+ srcBounds.left += -destBounds.left;
+ destBounds.left = 0;
+ }
+}
+
template <typename BlitOp>
-void blit_if(const Graphics::Surface &src, const Common::Rect &srcRect, Graphics::ManagedSurface &dest, const Common::Point &destPos, BlitOp blitOp) {
- const Common::Rect srcBounds = srcRect;
- const Common::Rect destBounds(destPos.x, destPos.y, destPos.x + srcRect.width(), destPos.y + srcRect.height());
+void blit_if(const Graphics::Surface &src, const Common::Rect &srcRect, Graphics::Surface &dest, const Common::Point &destPos, BlitOp blitOp) {
+ Common::Rect srcBounds = srcRect;
+ Common::Rect destBounds(destPos.x, destPos.y, destPos.x + srcRect.width(), destPos.y + srcRect.height());
assert(srcRect.isValidRect());
assert(dest.format == src.format);
+ clipBounds(srcBounds, destBounds, dest);
+
for (int y = 0; y < srcBounds.height(); ++y) {
const byte *srcP = reinterpret_cast<const byte *>(src.getBasePtr(srcBounds.left, srcBounds.top + y));
const byte *srcEndP = srcP + srcBounds.width();
byte *destP = reinterpret_cast<byte *>(dest.getBasePtr(destBounds.left, destBounds.top + y));
while (srcP != srcEndP) {
- if (blitOp(*srcP, *destP)) {
- *destP = *srcP;
+ const byte newColor = blitOp(*srcP, *destP);
+ if (*destP != newColor) {
+ *destP = newColor;
}
++srcP;
++destP;
}
}
+}
- dest.getSubArea(destBounds); // This is a hack to invalidate the destination rectangle.
+template <typename BlitOp>
+void blit_if(const Graphics::Surface &src, const Common::Rect &srcRect, Graphics::ManagedSurface &dest, const Common::Point &destPos, BlitOp blitOp) {
+ Common::Rect srcBounds = srcRect;
+ Common::Rect destBounds(destPos.x, destPos.y, destPos.x + srcRect.width(), destPos.y + srcRect.height());
+
+ assert(srcRect.isValidRect());
+ assert(dest.format == src.format);
+
+ clipBounds(srcBounds, destBounds, dest);
+
+ Graphics::Surface destSurf = dest.getSubArea(destBounds); // This will invalidate the rectangle.
+ blit_if(src, srcRect, destSurf, Common::Point(0, 0), blitOp);
+}
+
+template <typename BlitOp>
+void blit_if(const Graphics::Surface &src, Graphics::Surface &dest, const Common::Point &destPos, BlitOp blitOp) {
+ blit_if(src, Common::Rect(0, 0, src.w, src.h), dest, destPos, blitOp);
}
template <typename BlitOp>
Commit: cd15dd82a252c3bca1f96a96c4d2c5a2bf4387d9
https://github.com/scummvm/scummvm/commit/cd15dd82a252c3bca1f96a96c4d2c5a2bf4387d9
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Check for out of bounds destination in blit_if.
Changed paths:
engines/mutationofjb/util.h
diff --git a/engines/mutationofjb/util.h b/engines/mutationofjb/util.h
index 51c532b..ac1239d 100644
--- a/engines/mutationofjb/util.h
+++ b/engines/mutationofjb/util.h
@@ -38,8 +38,13 @@ namespace MutationOfJB {
void reportFileMissingError(const char *fileName);
Common::String toUpperCP895(const Common::String &str);
+// Taken from ManagedSurface::clip.
template <typename SurfaceType>
-void clipBounds(Common::Rect &srcBounds, Common::Rect &destBounds, SurfaceType &destSurf) {
+bool clipBounds(Common::Rect &srcBounds, Common::Rect &destBounds, SurfaceType &destSurf) {
+ if (destBounds.left >= destSurf.w || destBounds.top >= destSurf.h ||
+ destBounds.right <= 0 || destBounds.bottom <= 0)
+ return false;
+
// Clip the bounds if source is too big to fit into destination.
if (destBounds.right > destSurf.w) {
srcBounds.right -= destBounds.right - destSurf.w;
@@ -60,6 +65,8 @@ void clipBounds(Common::Rect &srcBounds, Common::Rect &destBounds, SurfaceType &
srcBounds.left += -destBounds.left;
destBounds.left = 0;
}
+
+ return true;
}
template <typename BlitOp>
@@ -70,7 +77,8 @@ void blit_if(const Graphics::Surface &src, const Common::Rect &srcRect, Graphics
assert(srcRect.isValidRect());
assert(dest.format == src.format);
- clipBounds(srcBounds, destBounds, dest);
+ if (!clipBounds(srcBounds, destBounds, dest))
+ return;
for (int y = 0; y < srcBounds.height(); ++y) {
const byte *srcP = reinterpret_cast<const byte *>(src.getBasePtr(srcBounds.left, srcBounds.top + y));
@@ -96,7 +104,8 @@ void blit_if(const Graphics::Surface &src, const Common::Rect &srcRect, Graphics
assert(srcRect.isValidRect());
assert(dest.format == src.format);
- clipBounds(srcBounds, destBounds, dest);
+ if (!clipBounds(srcBounds, destBounds, dest))
+ return;
Graphics::Surface destSurf = dest.getSubArea(destBounds); // This will invalidate the rectangle.
blit_if(src, srcRect, destSurf, Common::Point(0, 0), blitOp);
Commit: 298bfc3d109110b8f4332083b4f9aca850f43eea
https://github.com/scummvm/scummvm/commit/298bfc3d109110b8f4332083b4f9aca850f43eea
Author: Miroslav Remák (miroslavr256 at gmail.com)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Subclass Graphics::Font to reuse existing code.
Changed paths:
engines/mutationofjb/font.cpp
engines/mutationofjb/font.h
engines/mutationofjb/tasks/saytask.cpp
engines/mutationofjb/widgets/conversationwidget.cpp
diff --git a/engines/mutationofjb/font.cpp b/engines/mutationofjb/font.cpp
index 4f4a0ee..f87f25b 100644
--- a/engines/mutationofjb/font.cpp
+++ b/engines/mutationofjb/font.cpp
@@ -29,7 +29,8 @@ namespace MutationOfJB {
Font::Font(const Common::String &fileName, int horizSpacing, int lineHeight) :
_horizSpacing(horizSpacing),
- _lineHeight(lineHeight) {
+ _lineHeight(lineHeight),
+ _maxCharWidth(0) {
load(fileName);
}
@@ -62,6 +63,10 @@ bool Font::load(const Common::String &fileName) {
file.read(surf.getBasePtr(0, h), width);
}
+ if (width > _maxCharWidth) {
+ _maxCharWidth = width;
+ }
+
if (height > maxHeight) {
maxHeight = height;
}
@@ -74,75 +79,69 @@ bool Font::load(const Common::String &fileName) {
return true;
}
-void Font::drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf) const {
- GlyphMap::iterator it = _glyphs.find(glyph);
+int Font::getFontHeight() const {
+ return _lineHeight;
+}
+
+int Font::getMaxCharWidth() const {
+ return _maxCharWidth;
+}
+
+int Font::getCharWidth(uint32 chr) const {
+ GlyphMap::iterator it = _glyphs.find(chr);
if (it == _glyphs.end()) {
- // Missing glyph is a common situation in the game and it's okay to ignore it.
- return;
+ return 0;
}
+ return it->_value.w;
+}
- Graphics::ManagedSurface &glyphSurface = it->_value;
+int Font::getKerningOffset(uint32 left, uint32 right) const {
+ if (left == 0) {
+ // Do not displace the first character.
+ return 0;
+ }
- Graphics::ManagedSurface tmp(glyphSurface);
- for (int h = 0; h < tmp.h; ++h) {
- uint8 *ptr = reinterpret_cast<uint8 *>(tmp.getBasePtr(0, h));
- for (int w = 0; w < tmp.w; ++w) {
- if (*ptr != 0) {
- *ptr = transformColor(baseColor, *ptr);
- }
- ptr++;
- }
+ if (_glyphs.find(left) == _glyphs.end()) {
+ // Missing glyphs must not create extra displacement.
+ // FIXME: This way is not completely correct, as if the last character is
+ // missing a glyph, it will still create extra displacement. This should
+ // not affect the visuals but it might affect getStringWidth() / getBoundingBox().
+ return 0;
}
- surf.transBlitFrom(tmp.rawSurface(), Common::Point(x, y));
- x += glyphSurface.w + _horizSpacing;
+ return _horizSpacing;
}
-int16 Font::getWidth(const Common::String &str) const {
- int16 width = 0;
- for (uint i = 0; i < str.size(); ++i) {
- GlyphMap::iterator it = _glyphs.find(str[i]);
- if (it == _glyphs.end()) {
- continue;
+class FontBlitOperation {
+public:
+ FontBlitOperation(const Font &font, const byte baseColor)
+ : _font(font),
+ _baseColor(baseColor) {}
+
+ byte operator()(const byte srcColor, const byte destColor) {
+ if (srcColor == 0) {
+ // Transparency - keep destination color.
+ return destColor;
}
- width += it->_value.w + _horizSpacing;
+ // Replace destination with transformed source color.
+ return _font.transformColor(_baseColor, srcColor);
}
- return width;
-}
-int Font::getLineHeight() const {
- return _lineHeight;
-}
+private:
+ const Font &_font;
+ const byte _baseColor;
+};
-void Font::drawString(const Common::String &str, uint8 baseColor, int16 x, int16 y, Graphics::ManagedSurface &surf) const {
- for (uint i = 0; i < str.size(); ++i) {
- drawGlyph(str[i], baseColor, x, y, surf); // "x" is updated.
+void Font::drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const {
+ GlyphMap::iterator it = _glyphs.find(chr);
+ if (it == _glyphs.end()) {
+ // Missing glyph is a common situation in the game and it's okay to ignore it.
+ return;
}
-}
-void Font::wordWrap(const Common::String &str, int16 maxLineWidth, Common::Array<Common::String> &lines) const {
- lines.push_back("");
-
- for (Common::String::const_iterator it = str.begin(); it != str.end();) {
- Common::String::const_iterator partStart = it;
- it = Common::find(partStart, str.end(), ' ');
- if (it != str.end()) {
- while (*it == ' ' && it != str.end()) {
- ++it;
- }
- }
-
- Common::String part(partStart, it); // Word + following whitespace
- Common::String line = lines.back() + part;
- if (getWidth(line) <= maxLineWidth) {
- // The part fits in the current line
- lines.back() = line;
- } else {
- // The part must go to the next line
- lines.push_back(part);
- }
- }
+ Graphics::ManagedSurface &glyphSurface = it->_value;
+ blit_if(glyphSurface, *dst, Common::Point(x, y), FontBlitOperation(*this, color));
}
uint8 Font::transformColor(uint8 baseColor, uint8 glyphColor) const {
diff --git a/engines/mutationofjb/font.h b/engines/mutationofjb/font.h
index a27303e..51825db 100644
--- a/engines/mutationofjb/font.h
+++ b/engines/mutationofjb/font.h
@@ -25,7 +25,9 @@
#include "common/scummsys.h"
#include "common/hashmap.h"
+#include "graphics/font.h"
#include "graphics/managed_surface.h"
+#include "graphics/surface.h"
namespace Common {
class String;
@@ -33,24 +35,26 @@ class String;
namespace MutationOfJB {
-class Font {
+class Font : public Graphics::Font {
+ friend class FontBlitOperation;
public:
- Font(const Common::String &fileName, int horizSpacing, int vertSpacing);
- virtual ~Font() {}
- int getLineHeight() const;
- int16 getWidth(const Common::String &text) const;
- void drawString(const Common::String &str, uint8 baseColor, int16 x, int16 y, Graphics::ManagedSurface &surf) const;
- void wordWrap(const Common::String &str, int16 maxLineWidth, Common::Array<Common::String> &lines) const;
+ Font(const Common::String &fileName, int horizSpacing, int lineHeight);
+
+ virtual int getFontHeight() const override;
+ virtual int getMaxCharWidth() const override;
+ virtual int getCharWidth(uint32 chr) const override;
+ virtual int getKerningOffset(uint32 left, uint32 right) const override;
+ virtual void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const override;
protected:
virtual uint8 transformColor(uint8 baseColor, uint8 glyphColor) const;
private:
- void drawGlyph(uint8 glyph, uint8 baseColor, int16 &x, int16 &y, Graphics::ManagedSurface &surf) const;
bool load(const Common::String &fileName);
int _horizSpacing;
int _lineHeight;
+ int _maxCharWidth;
typedef Common::HashMap<uint8, Graphics::ManagedSurface> GlyphMap;
GlyphMap _glyphs;
};
diff --git a/engines/mutationofjb/tasks/saytask.cpp b/engines/mutationofjb/tasks/saytask.cpp
index cfa412b..21a7dea 100644
--- a/engines/mutationofjb/tasks/saytask.cpp
+++ b/engines/mutationofjb/tasks/saytask.cpp
@@ -68,35 +68,27 @@ void SayTask::drawSubtitle(const Common::String &text, int16 talkX, int16 talkY,
const Font &font = getTaskManager()->getGame().getAssets().getSpeechFont();
Common::Array<Common::String> lines;
- font.wordWrap(text, MAX_LINE_WIDTH, lines);
+ const int16 actualMaxWidth = font.wordWrapText(text, MAX_LINE_WIDTH, lines);
// Get the x, y coordinates of the top center point of the text's bounding box
// from the (rather strange) talk coordinates coming from scripts.
int16 x = talkX;
- int16 y = talkY - (lines.size() - 1) * font.getLineHeight() - 15;
+ int16 y = talkY - (lines.size() - 1) * font.getFontHeight() - 15;
// Clamp to screen edges.
+ x = CLIP<int16>(x, 3 + actualMaxWidth / 2, 317 - actualMaxWidth / 2);
y = MAX<int16>(y, 3);
- int16 maxWidth = 0;
- for (uint i = 0; i < lines.size(); i++) {
- int16 lineWidth = font.getWidth(lines[i]);
- if (lineWidth > maxWidth) {
- maxWidth = lineWidth;
- }
- x = MAX<int16>(x, 3 + lineWidth / 2);
- x = MIN<int16>(x, 317 - lineWidth / 2);
- }
+
+ // Remember the area occupied by the text.
+ _boundingBox.left = x - actualMaxWidth / 2;
+ _boundingBox.top = y;
+ _boundingBox.setWidth(actualMaxWidth);
+ _boundingBox.setHeight(lines.size() * font.getFontHeight());
// Draw lines.
for (uint i = 0; i < lines.size(); i++) {
- font.drawString(lines[i], color, x - font.getWidth(lines[i]) / 2, y + i * font.getLineHeight(), getTaskManager()->getGame().getScreen());
+ font.drawString(&getTaskManager()->getGame().getScreen(), lines[i], _boundingBox.left, _boundingBox.top + i * font.getFontHeight(), _boundingBox.width(), color, Graphics::kTextAlignCenter);
}
-
- // Remember the area occupied by the text.
- _boundingBox.top = x - maxWidth / 2;
- _boundingBox.left = y;
- _boundingBox.setWidth(maxWidth);
- _boundingBox.setHeight(lines.size() * font.getLineHeight());
}
void SayTask::finish() {
diff --git a/engines/mutationofjb/widgets/conversationwidget.cpp b/engines/mutationofjb/widgets/conversationwidget.cpp
index a46b9c5..24bb5e1 100644
--- a/engines/mutationofjb/widgets/conversationwidget.cpp
+++ b/engines/mutationofjb/widgets/conversationwidget.cpp
@@ -69,7 +69,7 @@ void ConversationWidget::_draw(Graphics::ManagedSurface &surface) {
}
// TODO: Active line should be WHITE.
- _gui.getGame().getAssets().getSystemFont().drawString(str, LIGHTGRAY, CONVERSATION_LINES_X, CONVERSATION_LINES_Y + i * CONVERSATION_LINE_HEIGHT, surface);
+ _gui.getGame().getAssets().getSystemFont().drawString(&surface, str, CONVERSATION_LINES_X, CONVERSATION_LINES_Y + i * CONVERSATION_LINE_HEIGHT, _area.width(), LIGHTGRAY);
}
}
Commit: 6ff609c51478c07a00018e57d8149f09d97677e7
https://github.com/scummvm/scummvm/commit/6ff609c51478c07a00018e57d8149f09d97677e7
Author: Miroslav Remák (miroslavr256 at gmail.com)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Improve documentation for statics.
Changed paths:
engines/mutationofjb/gamedata.h
diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h
index 47272c6..fc755f7 100644
--- a/engines/mutationofjb/gamedata.h
+++ b/engines/mutationofjb/gamedata.h
@@ -164,7 +164,7 @@ struct Object {
};
/**
- * An interactable area without a visual representation.
+ * An interactable area, usually without a visual representation.
*/
struct Static {
/** Whether you can mouse over and interact with the static (AC register). */
@@ -175,9 +175,14 @@ struct Static {
* If it starts with '~', the static has an implicit "pickup" action that adds
* an item with the same name (except '`' replaces '~') to your inventory and
* disables the static. If there is a matching scripted "pickup" action, it
- * overrides the implicit action.
+ * overrides the implicit action. This kind of static also has graphics in the
+ * form of its rectangle extracted from room frame 2 (and 3 after pickup).
+ *
+ * If it ends with '[', the "use" action allows combining the static with another
+ * entity.
*
* TODO: Support '~' statics.
+ * TODO: Support combinable statics.
*/
char _name[MAX_ENTITY_NAME_LENGTH + 1];
/** X coordinate of the static rectangle (XX register). */
Commit: a25715a29b0587ae6795eef63a575172e2cb971d
https://github.com/scummvm/scummvm/commit/a25715a29b0587ae6795eef63a575172e2cb971d
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Fix code formatting issues (with astyle).
Changed paths:
engines/mutationofjb/animationdecoder.cpp
engines/mutationofjb/assets.cpp
engines/mutationofjb/assets.h
engines/mutationofjb/commands/additemcommand.cpp
engines/mutationofjb/commands/callmacrocommand.cpp
engines/mutationofjb/commands/camefromcommand.cpp
engines/mutationofjb/commands/changecommand.cpp
engines/mutationofjb/commands/changecommand.h
engines/mutationofjb/commands/definestructcommand.cpp
engines/mutationofjb/commands/endblockcommand.cpp
engines/mutationofjb/commands/gotocommand.cpp
engines/mutationofjb/commands/ifcommand.cpp
engines/mutationofjb/commands/ifcommand.h
engines/mutationofjb/commands/ifitemcommand.cpp
engines/mutationofjb/commands/ifitemcommand.h
engines/mutationofjb/commands/ifpiggycommand.cpp
engines/mutationofjb/commands/labelcommand.cpp
engines/mutationofjb/commands/newroomcommand.cpp
engines/mutationofjb/commands/randomcommand.cpp
engines/mutationofjb/commands/removeallitemscommand.cpp
engines/mutationofjb/commands/removeitemcommand.cpp
engines/mutationofjb/commands/renamecommand.cpp
engines/mutationofjb/commands/saycommand.cpp
engines/mutationofjb/commands/seqcommand.cpp
engines/mutationofjb/commands/seqcommand.h
engines/mutationofjb/commands/talkcommand.cpp
engines/mutationofjb/conversationlinelist.h
engines/mutationofjb/debug.cpp
engines/mutationofjb/encryptedfile.cpp
engines/mutationofjb/game.cpp
engines/mutationofjb/gamedata.cpp
engines/mutationofjb/gamedata.h
engines/mutationofjb/gui.cpp
engines/mutationofjb/gui.h
engines/mutationofjb/mutationofjb.cpp
engines/mutationofjb/script.cpp
engines/mutationofjb/script.h
engines/mutationofjb/tasks/conversationtask.cpp
engines/mutationofjb/tasks/conversationtask.h
engines/mutationofjb/tasks/task.h
engines/mutationofjb/tasks/taskmanager.h
engines/mutationofjb/util.cpp
engines/mutationofjb/util.h
engines/mutationofjb/widgets/buttonwidget.cpp
engines/mutationofjb/widgets/conversationwidget.cpp
engines/mutationofjb/widgets/conversationwidget.h
engines/mutationofjb/widgets/inventorywidget.cpp
engines/mutationofjb/widgets/inventorywidget.h
diff --git a/engines/mutationofjb/animationdecoder.cpp b/engines/mutationofjb/animationdecoder.cpp
index 8132385..712cb42 100644
--- a/engines/mutationofjb/animationdecoder.cpp
+++ b/engines/mutationofjb/animationdecoder.cpp
@@ -114,7 +114,7 @@ void AnimationDecoder::loadPalette(Common::SeekableReadStream &file) {
copyCount = PALETTE_COLORS;
}
- while(packets--) {
+ while (packets--) {
file.read(_palette + skipCount * 3, copyCount * 3);
for (int j = skipCount * 3; j < (skipCount + copyCount) * 3; ++j) {
@@ -145,7 +145,7 @@ void AnimationDecoder::loadFullFrame(EncryptedFile &file, uint32 size) {
// RLE - Copy color n times.
uint8 color = file.readByte();
readBytes++;
- while(n--) {
+ while (n--) {
*ptr++ = color;
}
} else {
diff --git a/engines/mutationofjb/assets.cpp b/engines/mutationofjb/assets.cpp
index d532469..2adda51 100644
--- a/engines/mutationofjb/assets.cpp
+++ b/engines/mutationofjb/assets.cpp
@@ -26,11 +26,11 @@ namespace MutationOfJB {
Assets::Assets(Game &game) : _game(game), _toSayList("tosay.ger"), _responseList("response.ger") {}
-Font& Assets::getSystemFont() {
+Font &Assets::getSystemFont() {
return _systemFont;
}
-Font& Assets::getSpeechFont() {
+Font &Assets::getSpeechFont() {
return _speechFont;
}
diff --git a/engines/mutationofjb/assets.h b/engines/mutationofjb/assets.h
index 1d47641..2cd0612 100644
--- a/engines/mutationofjb/assets.h
+++ b/engines/mutationofjb/assets.h
@@ -34,11 +34,11 @@ class Assets {
public:
Assets(Game &game);
- Font& getSystemFont();
- Font& getSpeechFont();
+ Font &getSystemFont();
+ Font &getSpeechFont();
- ConversationLineList& getToSayList();
- ConversationLineList& getResponseList();
+ ConversationLineList &getToSayList();
+ ConversationLineList &getResponseList();
private:
Game &_game;
diff --git a/engines/mutationofjb/commands/additemcommand.cpp b/engines/mutationofjb/commands/additemcommand.cpp
index 1a670f7..67d3e13 100644
--- a/engines/mutationofjb/commands/additemcommand.cpp
+++ b/engines/mutationofjb/commands/additemcommand.cpp
@@ -24,11 +24,11 @@
#include "mutationofjb/gamedata.h"
#include "mutationofjb/script.h"
-/*
- "ADDITEM" " " <item>
-
- Adds item to inventory.
-*/
+/** @file
+ * "ADDITEM " <item>
+ *
+ * Adds item to inventory.
+ */
namespace MutationOfJB {
diff --git a/engines/mutationofjb/commands/callmacrocommand.cpp b/engines/mutationofjb/commands/callmacrocommand.cpp
index 49b948c..01470f2 100644
--- a/engines/mutationofjb/commands/callmacrocommand.cpp
+++ b/engines/mutationofjb/commands/callmacrocommand.cpp
@@ -25,11 +25,11 @@
#include "mutationofjb/game.h"
#include "common/translation.h"
-/*
- "_" <name>
-
- Calls macro with the specified name.
-*/
+/** @file
+ * "_" <name>
+ *
+ * Calls macro with the specified name.
+ */
namespace MutationOfJB {
diff --git a/engines/mutationofjb/commands/camefromcommand.cpp b/engines/mutationofjb/commands/camefromcommand.cpp
index 0583187..485e0c5 100644
--- a/engines/mutationofjb/commands/camefromcommand.cpp
+++ b/engines/mutationofjb/commands/camefromcommand.cpp
@@ -25,13 +25,13 @@
#include "mutationofjb/script.h"
#include "common/str.h"
-/*
- "CAMEFROM" <sceneId>
-
- This command tests whether last scene (the scene player came from) is sceneId.
- If true, the execution continues after this command.
- Otherwise the execution continues after first '#' found.
-*/
+/** @file
+ * "CAMEFROM" <sceneId>
+ *
+ * This command tests whether last scene (the scene player came from) is sceneId.
+ * If true, the execution continues after this command.
+ * Otherwise the execution continues after first '#' found.
+ */
namespace MutationOfJB {
diff --git a/engines/mutationofjb/commands/changecommand.cpp b/engines/mutationofjb/commands/changecommand.cpp
index 4eac41e..5d6833b 100644
--- a/engines/mutationofjb/commands/changecommand.cpp
+++ b/engines/mutationofjb/commands/changecommand.cpp
@@ -27,15 +27,21 @@
namespace MutationOfJB {
-// CHANGEe rr ss ii val
-// <e> 1B Entity to change register for.
-// D door
-// O object
-// S static
-// <rr> 2B Register name.
-// <ss> 2B Scene ID.
-// <ii> 2B Entity ID.
-// <val> VL Value.
+/** @file
+ * "CHANGE" <entity> " " <register> " " <sceneId> " " <entityId> " " <value>
+ *
+ * Changes entity register value for specified scene.
+ * <entity> 1B Entity to change register for.
+ * Possible values:
+ * 'D' - door
+ * 'O' - object
+ * 'S' - static
+ * '' - scene
+ * <register> 2B Register name.
+ * <sceneId> 2B Scene ID.
+ * <entityid> 2B Entity ID.
+ * <value> *B Value (variable length).
+ */
bool ChangeCommandParser::parseValueString(const Common::String &valueString, bool changeEntity, uint8 &sceneId, uint8 &entityId, ChangeCommand::ChangeRegister ®, ChangeCommand::ChangeOperation &op, ChangeCommandValue &ccv) {
if (changeEntity) {
@@ -102,7 +108,7 @@ bool ChangeCommandParser::parseValueString(const Common::String &valueString, bo
ccv._byteVal = parseInteger(val, op);
} else if (valueString.hasPrefix("FR")) {
reg = ChangeCommand::FR;
- ccv._byteVal = parseInteger(val, op);
+ ccv._byteVal = parseInteger(val, op);
} else if (valueString.hasPrefix("NA")) {
reg = ChangeCommand::NA;
ccv._byteVal = parseInteger(val, op);
@@ -234,32 +240,58 @@ int ChangeCommandParser::parseInteger(const char *val, ChangeCommand::ChangeOper
const char *ChangeCommand::getRegisterAsString() const {
switch (_register) {
- case NM: return "NM";
- case LT: return "LT";
- case SX: return "SX";
- case SY: return "SY";
- case XX: return "XX";
- case YY: return "YY";
- case XL: return "XL";
- case YL: return "YL";
- case WX: return "WX";
- case WY: return "WY";
- case SP: return "SP";
- case AC: return "AC";
- case FA: return "FA";
- case FR: return "FR";
- case NA: return "NA";
- case FS: return "FS";
- case CA: return "CA";
- case DS: return "DS";
- case DL: return "DL";
- case ND: return "ND";
- case NO: return "NO";
- case NS: return "NS";
- case PF: return "PF";
- case PL: return "PL";
- case PD: return "PD";
- default: return "(unknown)";
+ case NM:
+ return "NM";
+ case LT:
+ return "LT";
+ case SX:
+ return "SX";
+ case SY:
+ return "SY";
+ case XX:
+ return "XX";
+ case YY:
+ return "YY";
+ case XL:
+ return "XL";
+ case YL:
+ return "YL";
+ case WX:
+ return "WX";
+ case WY:
+ return "WY";
+ case SP:
+ return "SP";
+ case AC:
+ return "AC";
+ case FA:
+ return "FA";
+ case FR:
+ return "FR";
+ case NA:
+ return "NA";
+ case FS:
+ return "FS";
+ case CA:
+ return "CA";
+ case DS:
+ return "DS";
+ case DL:
+ return "DL";
+ case ND:
+ return "ND";
+ case NO:
+ return "NO";
+ case NS:
+ return "NS";
+ case PF:
+ return "PF";
+ case PL:
+ return "PL";
+ case PD:
+ return "PD";
+ default:
+ return "(unknown)";
}
}
diff --git a/engines/mutationofjb/commands/changecommand.h b/engines/mutationofjb/commands/changecommand.h
index 6fa090e..a88cdc1 100644
--- a/engines/mutationofjb/commands/changecommand.h
+++ b/engines/mutationofjb/commands/changecommand.h
@@ -44,7 +44,7 @@ public:
YL, // Height
WX, // Walk to X
WY, // Walk to Y
- SP, //
+ SP, //
AC, // Active
FA, // First animation
FR,
@@ -67,7 +67,7 @@ public:
SubtractValue
};
- ChangeCommand(uint8 sceneId, uint8 entityId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue& val) :
+ ChangeCommand(uint8 sceneId, uint8 entityId, ChangeRegister reg, ChangeOperation op, const ChangeCommandValue &val) :
_sceneId(sceneId), _entityId(entityId), _register(reg), _operation(op), _value(val)
{}
protected:
diff --git a/engines/mutationofjb/commands/definestructcommand.cpp b/engines/mutationofjb/commands/definestructcommand.cpp
index 93dbfc8..4ccf2e8 100644
--- a/engines/mutationofjb/commands/definestructcommand.cpp
+++ b/engines/mutationofjb/commands/definestructcommand.cpp
@@ -50,7 +50,7 @@ bool DefineStructCommandParser::parse(const Common::String &line, ScriptParseCon
continue;
}
- const char* linePtr = convLineStr.c_str();
+ const char *linePtr = convLineStr.c_str();
ConversationInfo::Line convLine;
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index b883bee..c7fbd41 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -27,29 +27,29 @@
#include "common/debug.h"
#include "common/translation.h"
-/*
- ("#L " | "-L ") <object>
- ("#W " | "-W ") <object>
- ("#T " | "-T ") <object>
- ("#P " | "-P ") <object1>
- ("#U " | "-U ") <object1> [<object2>]
- ("#ELSE" | "-ELSE") [<tag>]
- "#MACRO " <name>
- "#EXTRA" <name>
-
- If a line starts with '#', '=', '-', it is treated as the end of a section.
- However, at the same time it can also start a new section depending on what follows.
-
- #L (look), #W (walk), #T (talk), #U (use) sections are executed
- when the user starts corresponding action on the object or in case of "use" up to two objects.
- The difference between '#' and '-' version is whether the player walks towards the object ('#') or not ('-').
-
- #ELSE is used by conditional commands (see comments for IfCommand and others).
-
- #MACRO starts a new macro. Global script can call macros from local script and vice versa.
-
- #EXTRA defines an "extra" section. This is called from dialog responses ("TALK TO HIM" command).
-*/
+/** @file
+ * ("#L " | "-L ") <object>
+ * ("#W " | "-W ") <object>
+ * ("#T " | "-T ") <object>
+ * ("#P " | "-P ") <object1>
+ * ("#U " | "-U ") <object1> [<object2>]
+ * ("#ELSE" | "-ELSE") [<tag>]
+ * "#MACRO " <name>
+ * "#EXTRA" <name>
+ *
+ * If a line starts with '#', '=', '-', it is treated as the end of a section.
+ * However, at the same time it can also start a new section depending on what follows.
+ *
+ * #L (look), #W (walk), #T (talk), #U (use) sections are executed
+ * when the user starts corresponding action on the object or in case of "use" up to two objects.
+ * The difference between '#' and '-' version is whether the player walks towards the object ('#') or not ('-').
+ *
+ * #ELSE is used by conditional commands (see comments for IfCommand and others).
+ *
+ * #MACRO starts a new macro. Global script can call macros from local script and vice versa.
+ *
+ * #EXTRA defines an "extra" section. This is called from dialog responses ("TALK TO HIM" command).
+ */
namespace MutationOfJB {
diff --git a/engines/mutationofjb/commands/gotocommand.cpp b/engines/mutationofjb/commands/gotocommand.cpp
index bc24e2c..b8d15a7 100644
--- a/engines/mutationofjb/commands/gotocommand.cpp
+++ b/engines/mutationofjb/commands/gotocommand.cpp
@@ -25,11 +25,11 @@
#include "mutationofjb/gamedata.h"
#include "mutationofjb/script.h"
-/*
- "GOTO " <label>
-
- Jumps to a label.
-*/
+/** @file
+ * "GOTO " <label>
+ *
+ * Jumps to a label.
+ */
namespace MutationOfJB {
diff --git a/engines/mutationofjb/commands/ifcommand.cpp b/engines/mutationofjb/commands/ifcommand.cpp
index b5f03fc..06fb5ca 100644
--- a/engines/mutationofjb/commands/ifcommand.cpp
+++ b/engines/mutationofjb/commands/ifcommand.cpp
@@ -26,24 +26,24 @@
#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" or "=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 like 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.
-*/
+/** @file
+ * "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" or "=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 like 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 {
@@ -58,7 +58,7 @@ bool IfCommandParser::parse(const Common::String &line, ScriptParseContext &, Co
if (line.size() < 10) {
return false;
}
-
+
if (!line.hasPrefix("IF")) {
return false;
}
diff --git a/engines/mutationofjb/commands/ifcommand.h b/engines/mutationofjb/commands/ifcommand.h
index b04d8a3..04174d9 100644
--- a/engines/mutationofjb/commands/ifcommand.h
+++ b/engines/mutationofjb/commands/ifcommand.h
@@ -39,7 +39,7 @@ private:
class IfCommand : public ConditionalCommand {
public:
IfCommand(uint8 sceneId, uint8 objectId, uint16 value, bool negative);
-
+
virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const;
diff --git a/engines/mutationofjb/commands/ifitemcommand.cpp b/engines/mutationofjb/commands/ifitemcommand.cpp
index 7a58cee..d70add9 100644
--- a/engines/mutationofjb/commands/ifitemcommand.cpp
+++ b/engines/mutationofjb/commands/ifitemcommand.cpp
@@ -27,22 +27,22 @@
#include "common/str.h"
#include "common/translation.h"
-/*
- "IFITEM" <item> ["!"]
-
- IFITEM command tests whether an item is in the inventory.
- If it is, execution continues to the next line.
- Otherwise execution continues after first "#ELSE" or "=ELSE".
- The logic can be reversed with exclamation mark at the end.
-
- Please note that this does not work like you are used to from saner languages.
- IFITEM does not have any blocks. It only searches for first #ELSE, so you can have stuff like:
- IFITEM item1
- IFITEM item2
- #ELSE
- ...
- This is effectively logical AND.
-*/
+/** @file
+ * "IFITEM" <item> ["!"]
+ *
+ * IFITEM command tests whether an item is in the inventory.
+ * If it is, execution continues to the next line.
+ * Otherwise execution continues after first "#ELSE" or "=ELSE".
+ * The logic can be reversed with exclamation mark at the end.
+ *
+ * Please note that this does not work like you are used to from saner languages.
+ * IFITEM does not have any blocks. It only searches for first #ELSE, so you can have stuff like:
+ * IFITEM item1
+ * IFITEM item2
+ * #ELSE
+ * ...
+ * This is effectively logical AND.
+ */
namespace MutationOfJB {
@@ -50,7 +50,7 @@ bool IfItemCommandParser::parse(const Common::String &line, ScriptParseContext &
if (line.size() < 8) {
return false;
}
-
+
if (!line.hasPrefix("IFITEM")) {
return false;
}
diff --git a/engines/mutationofjb/commands/ifitemcommand.h b/engines/mutationofjb/commands/ifitemcommand.h
index df073b9..86a5ad2 100644
--- a/engines/mutationofjb/commands/ifitemcommand.h
+++ b/engines/mutationofjb/commands/ifitemcommand.h
@@ -39,7 +39,7 @@ public:
class IfItemCommand : public ConditionalCommand {
public:
IfItemCommand(const Common::String &item, bool negative);
-
+
virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
virtual Common::String debugString() const;
diff --git a/engines/mutationofjb/commands/ifpiggycommand.cpp b/engines/mutationofjb/commands/ifpiggycommand.cpp
index e30213a..e3107806 100644
--- a/engines/mutationofjb/commands/ifpiggycommand.cpp
+++ b/engines/mutationofjb/commands/ifpiggycommand.cpp
@@ -27,21 +27,21 @@
#include "common/str.h"
#include "common/translation.h"
-/*
- "IFPIGGY"
-
- IFPIGGY command tests whether current loaded APK file (character animation) is "piggy.apk".
- If it is, execution continues to the next line.
- Otherwise execution continues after first "#ELSE" or "=ELSE".
-
- Please note that this does not work like you are used to from saner languages.
- IFPIGGY does not have any blocks. It only searches for first #ELSE, so you can have stuff like:
- IFPIGGY
- IFITEM someitem
- #ELSE
- ...
- This is effectively logical AND.
-*/
+/** @file
+ * "IFPIGGY"
+ *
+ * IFPIGGY command tests whether current loaded APK file (character animation) is "piggy.apk".
+ * If it is, execution continues to the next line.
+ * Otherwise execution continues after first "#ELSE" or "=ELSE".
+ *
+ * Please note that this does not work like you are used to from saner languages.
+ * IFPIGGY does not have any blocks. It only searches for first #ELSE, so you can have stuff like:
+ * IFPIGGY
+ * IFITEM someitem
+ * #ELSE
+ * ...
+ * This is effectively logical AND.
+ */
namespace MutationOfJB {
diff --git a/engines/mutationofjb/commands/labelcommand.cpp b/engines/mutationofjb/commands/labelcommand.cpp
index de6de02..7593e52 100644
--- a/engines/mutationofjb/commands/labelcommand.cpp
+++ b/engines/mutationofjb/commands/labelcommand.cpp
@@ -24,11 +24,11 @@
#include "mutationofjb/commands/gotocommand.h"
#include "mutationofjb/script.h"
-/*
- <label> ":"
-
- Creates a label.
-*/
+/** @file
+ * <label> ":"
+ *
+ * Creates a label.
+ */
namespace MutationOfJB {
@@ -59,8 +59,7 @@ bool LabelCommandParser::parse(const Common::String &line, ScriptParseContext &p
return true;
}
-const Common::String &LabelCommand::getName() const
-{
+const Common::String &LabelCommand::getName() const {
return _name;
}
diff --git a/engines/mutationofjb/commands/newroomcommand.cpp b/engines/mutationofjb/commands/newroomcommand.cpp
index 818ef7d..5aabc67 100644
--- a/engines/mutationofjb/commands/newroomcommand.cpp
+++ b/engines/mutationofjb/commands/newroomcommand.cpp
@@ -26,15 +26,15 @@
#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).
-*/
+/** @file
+ * "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 {
@@ -62,7 +62,7 @@ Command::ExecuteResult NewRoomCommand::execute(ScriptExecutionContext &scriptExe
if (!_innerExecCtx) {
Script *newScript = game.changeSceneDelayScript(_sceneId, game.getGameData()._partB);
_innerExecCtx = new ScriptExecutionContext(scriptExecCtx.getGame(), newScript);
- res =_innerExecCtx->startStartupSection();
+ res = _innerExecCtx->startStartupSection();
} else {
res = _innerExecCtx->runActiveCommand();
}
diff --git a/engines/mutationofjb/commands/randomcommand.cpp b/engines/mutationofjb/commands/randomcommand.cpp
index b9cc303..467f788 100644
--- a/engines/mutationofjb/commands/randomcommand.cpp
+++ b/engines/mutationofjb/commands/randomcommand.cpp
@@ -28,16 +28,16 @@
#include "common/random.h"
#include "common/translation.h"
-/*
- "RANDOM " <numChoices>
-
- RANDOM command randomly picks one of the command blocks that
- follow it and jumps to its start.
-
- These blocks start with "/" and end with "\". The end of a random
- block also ends the current section. The number of blocks must
- match numChoices.
-*/
+/** @file
+ * "RANDOM " <numChoices>
+ *
+ * RANDOM command randomly picks one of the command blocks that
+ * follow it and jumps to its start.
+ *
+ * These blocks start with "/" and end with "\". The end of a random
+ * block also ends the current section. The number of blocks must
+ * match numChoices.
+ */
namespace MutationOfJB {
@@ -86,8 +86,7 @@ void RandomBlockStartParser::transition(ScriptParseContext &parseCtx, Command *,
RandomCommand::RandomCommand(uint numChoices)
: _numChoices(numChoices),
- _chosenNext(nullptr)
-{
+ _chosenNext(nullptr) {
_choices.reserve(numChoices);
}
diff --git a/engines/mutationofjb/commands/removeallitemscommand.cpp b/engines/mutationofjb/commands/removeallitemscommand.cpp
index d9ebe45..38e30de 100644
--- a/engines/mutationofjb/commands/removeallitemscommand.cpp
+++ b/engines/mutationofjb/commands/removeallitemscommand.cpp
@@ -24,11 +24,11 @@
#include "mutationofjb/script.h"
#include "mutationofjb/gamedata.h"
-/*
- "DELALLITEMS"
-
- Removes all items from inventory.
-*/
+/** @file
+ * "DELALLITEMS"
+ *
+ * Removes all items from inventory.
+ */
namespace MutationOfJB {
diff --git a/engines/mutationofjb/commands/removeitemcommand.cpp b/engines/mutationofjb/commands/removeitemcommand.cpp
index 48dbda9..21d1123 100644
--- a/engines/mutationofjb/commands/removeitemcommand.cpp
+++ b/engines/mutationofjb/commands/removeitemcommand.cpp
@@ -24,11 +24,11 @@
#include "mutationofjb/script.h"
#include "mutationofjb/gamedata.h"
-/*
- "DELITEM" " " <item>
-
- Removes item from inventory.
-*/
+/** @file
+ * "DELITEM" " " <item>
+ *
+ * Removes item from inventory.
+ */
namespace MutationOfJB {
diff --git a/engines/mutationofjb/commands/renamecommand.cpp b/engines/mutationofjb/commands/renamecommand.cpp
index 03a8832..7bd5269 100644
--- a/engines/mutationofjb/commands/renamecommand.cpp
+++ b/engines/mutationofjb/commands/renamecommand.cpp
@@ -25,11 +25,12 @@
#include "mutationofjb/gamedata.h"
#include "common/algorithm.h"
-/*
- "REN " <oldName> " " <newName>
- Renames every door, static (in the current scene) and inventory item
- with the name oldName to newName.
-*/
+/** @file
+ * "REN " <oldName> " " <newName>
+ *
+ * Renames every door, static (in the current scene) and inventory item
+ * with the name oldName to newName.
+ */
namespace MutationOfJB {
diff --git a/engines/mutationofjb/commands/saycommand.cpp b/engines/mutationofjb/commands/saycommand.cpp
index 0474a3e..e63ceb1 100644
--- a/engines/mutationofjb/commands/saycommand.cpp
+++ b/engines/mutationofjb/commands/saycommand.cpp
@@ -32,27 +32,27 @@
#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.
-*/
+/** @file
+ * ("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 {
@@ -113,7 +113,7 @@ bool SayCommandParser::parse(const Common::String &line, ScriptParseContext &par
Common::String talkStr(currentLine.c_str() + startPos, endPos - startPos);
if (endPos != currentLine.size()) {
- const char * end = currentLine.c_str() + endPos + 1;
+ const char *end = currentLine.c_str() + endPos + 1;
if (end[0] == '!') {
cont = true;
} else {
diff --git a/engines/mutationofjb/commands/seqcommand.cpp b/engines/mutationofjb/commands/seqcommand.cpp
index 02164dc..4836d03 100644
--- a/engines/mutationofjb/commands/seqcommand.cpp
+++ b/engines/mutationofjb/commands/seqcommand.cpp
@@ -34,8 +34,7 @@ void SeqCommandParser::transition(ScriptParseContext &, Command *oldCommand, Com
static_cast<SeqCommand *>(oldCommand)->setNextCommand(newCommand);
}
-void SeqCommand::setNextCommand(Command *nextCommand)
-{
+void SeqCommand::setNextCommand(Command *nextCommand) {
_nextCommand = nextCommand;
}
diff --git a/engines/mutationofjb/commands/seqcommand.h b/engines/mutationofjb/commands/seqcommand.h
index 04731c2..6c969e9 100644
--- a/engines/mutationofjb/commands/seqcommand.h
+++ b/engines/mutationofjb/commands/seqcommand.h
@@ -21,7 +21,7 @@
*/
#ifndef MUTATIONOFJB_SEQCOMMAND_H
-#define MUTATIONOFJB_SEQCOMMAND_H
+#define MUTATIONOFJB_SEQCOMMAND_H
#include "mutationofjb/commands/command.h"
#include "common/scummsys.h"
diff --git a/engines/mutationofjb/commands/talkcommand.cpp b/engines/mutationofjb/commands/talkcommand.cpp
index 6a3b204..5c7eb8e 100644
--- a/engines/mutationofjb/commands/talkcommand.cpp
+++ b/engines/mutationofjb/commands/talkcommand.cpp
@@ -70,7 +70,7 @@ Command::ExecuteResult TalkCommand::execute(ScriptExecutionContext &scriptExeCtx
}
Common::String TalkCommand::debugString() const {
- const char * modes[] = {"NORMAL", "RAY_AND_BUTTLEG", "CARNIVAL_TICKET_SELLER"};
+ const char *modes[] = {"NORMAL", "RAY_AND_BUTTLEG", "CARNIVAL_TICKET_SELLER"};
return Common::String::format("TALK %s", modes[(int) _mode]);
}
diff --git a/engines/mutationofjb/conversationlinelist.h b/engines/mutationofjb/conversationlinelist.h
index 0f8346f..4f208ad 100644
--- a/engines/mutationofjb/conversationlinelist.h
+++ b/engines/mutationofjb/conversationlinelist.h
@@ -34,9 +34,15 @@ public:
Common::String _text;
Common::String _voiceFile;
- bool isRepeating() const { return _text.firstChar() == '*'; }
- bool isFirstSpeaker() const { return _text.firstChar() == '~'; }
- bool isSecondSpeaker() const { return _text.firstChar() == '`'; }
+ bool isRepeating() const {
+ return _text.firstChar() == '*';
+ }
+ bool isFirstSpeaker() const {
+ return _text.firstChar() == '~';
+ }
+ bool isSecondSpeaker() const {
+ return _text.firstChar() == '`';
+ }
};
typedef Common::Array<Speech> Speeches;
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index b4f00c9..f7b074a 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -42,7 +42,7 @@ static Common::String convertToASCII(const Common::String &str) {
static const char conversionTable[] = {
'C', 'u', 'e', 'd', 'a', 'D', 'T', 'c', 'e', 'E', 'L', 'I', 'l', 'l', 'A', 'A', /* 0x80-0x8F */
'E', 'z', 'Z', 'o', 'o', 'O', 'u', 'U', 'y', 'O', 'U', 'S', 'L', 'Y', 'R', 't', /* 0x90-0x9F */
- 'a', 'i', 'o', 'u', 'n', 'N', 'U', 'O', 's', 'r', 'r', 'R' /* 0xA0-0xAB */
+ 'a', 'i', 'o', 'u', 'n', 'N', 'U', 'O', 's', 'r', 'r', 'R' /* 0xA0-0xAB */
};
Common::String ret = str;
@@ -151,9 +151,9 @@ void Console::showCommands(Command *command, int indentLevel) {
debugPrintf("ELSE\n");
showCommands(condCmd->getFalseCommand(), indentLevel + 1);
command = nullptr;
- } else if (CallMacroCommand* const callMacroCmd = dynamic_cast<CallMacroCommand *>(command)) {
+ } else if (CallMacroCommand *const callMacroCmd = dynamic_cast<CallMacroCommand *>(command)) {
command = callMacroCmd->getReturnCommand();
- } else if (RandomCommand* const randomCmd = dynamic_cast<RandomCommand *>(command)) {
+ } else if (RandomCommand *const randomCmd = dynamic_cast<RandomCommand *>(command)) {
const RandomCommand::Choices &choices = randomCmd->getChoices();
for (RandomCommand::Choices::size_type i = 0; i < choices.size(); ++i) {
showIndent(indentLevel + 1);
@@ -450,7 +450,7 @@ Script *Console::getScriptFromArg(const char *arg) {
}
bool Console::cmd_listinventory(int, const char **) {
- Inventory &inventory =_vm->getGame().getGameData().getInventory();
+ Inventory &inventory = _vm->getGame().getGameData().getInventory();
const Inventory::Items &items = inventory.getItems();
for (Inventory::Items::const_iterator it = items.begin(); it != items.end(); ++it) {
debugPrintf("%s\n", convertToASCII(*it).c_str());
diff --git a/engines/mutationofjb/encryptedfile.cpp b/engines/mutationofjb/encryptedfile.cpp
index 0796811..c02bcc7 100644
--- a/engines/mutationofjb/encryptedfile.cpp
+++ b/engines/mutationofjb/encryptedfile.cpp
@@ -23,34 +23,34 @@
#include "encryptedfile.h"
static const uint8 XOR_TABLE[] = {
- 0x41, 0x2b, 0x7a, 0x0c, 0xc8, 0xe5, 0x0c, 0xde, 0x45, 0xa8, 0x00, 0xad,
- 0x70, 0xac, 0x23, 0xe0, 0x0c, 0xde, 0xac, 0x16, 0xa1, 0x1a, 0x70, 0x17,
- 0x1b, 0x90, 0x34, 0x6e, 0x53, 0xfe, 0xdd, 0x3c, 0xef, 0x74, 0x75, 0x3e,
- 0x2e, 0xb0, 0x3d, 0x2b, 0x74, 0x6d, 0x59, 0xde, 0xc6, 0x20, 0xb8, 0xf3,
- 0x7d, 0xfa, 0x4d, 0xbd, 0xdb, 0x3c, 0xc5, 0xcb, 0x57, 0x13, 0x40, 0x6b,
- 0xb8, 0xad, 0xb9, 0xc1, 0x6a, 0x37, 0x39, 0x80, 0x94, 0xd3, 0xdf, 0x4b,
- 0xe4, 0xe4, 0x7a, 0x4c, 0x0f, 0x21, 0x27, 0x9a, 0x7e, 0x52, 0x35, 0x58,
- 0xb4, 0xbc, 0x5a, 0xc9, 0x48, 0x7f, 0xcc, 0xb6, 0x97, 0x7b, 0xf1, 0xd5,
- 0x88, 0x8c, 0xa9, 0x27, 0xf7, 0x20, 0x68, 0x65, 0xad, 0x6f, 0x9e, 0x07,
- 0xf8, 0xf6, 0x2c, 0x65, 0x4a, 0xe9, 0xd8, 0x13, 0x6a, 0xb5, 0x14, 0x6f,
- 0x29, 0xdc, 0x68, 0xf8, 0xa0, 0xb6, 0x73, 0x03, 0x69, 0xe3, 0x4f, 0xb6,
- 0x59, 0x79, 0xae, 0x93, 0xad, 0x40, 0x27, 0xd0, 0xb5, 0x7a, 0x68, 0x5d,
- 0x5e, 0x19, 0x53, 0x4f, 0x40, 0x56, 0x3d, 0x10, 0xf8, 0x0a, 0xc6, 0x90,
- 0x06, 0x45, 0x13, 0x4a, 0x6a, 0xfe, 0x56, 0xeb, 0xbc, 0xd9, 0xee, 0xe0,
- 0x85, 0x5e, 0x98, 0x23, 0xf9, 0x19, 0x60, 0xf9, 0x7e, 0x8d, 0x61, 0xa0,
- 0x7c, 0xe1, 0x84, 0xf2, 0x7a, 0xb8, 0xbe, 0x8e, 0x81, 0x9e, 0x87, 0x20,
- 0x32, 0xf3, 0x8c, 0xb4, 0x2c, 0x4d, 0xc8, 0x50, 0x9b, 0xa5, 0x9c, 0x27,
- 0x02, 0xd6, 0x7f, 0x2a, 0xaf, 0x46, 0x65, 0xd0, 0x6a, 0xae, 0xfa, 0x53,
- 0x37, 0x6c, 0x49, 0xb9, 0x4d, 0xcd, 0x6c, 0x6b, 0xa7, 0x2d, 0x66, 0x32,
- 0xb4, 0xf5, 0x41, 0xd5, 0x18, 0xc4, 0xfd, 0xbe, 0x8a, 0x47, 0x11, 0x50,
- 0x3d, 0x97, 0x64, 0xda, 0x5a, 0x27, 0x18, 0x60, 0x78, 0x80, 0x86, 0x8a,
- 0x2a, 0x72, 0x40, 0x89
+ 0x41, 0x2b, 0x7a, 0x0c, 0xc8, 0xe5, 0x0c, 0xde, 0x45, 0xa8, 0x00, 0xad,
+ 0x70, 0xac, 0x23, 0xe0, 0x0c, 0xde, 0xac, 0x16, 0xa1, 0x1a, 0x70, 0x17,
+ 0x1b, 0x90, 0x34, 0x6e, 0x53, 0xfe, 0xdd, 0x3c, 0xef, 0x74, 0x75, 0x3e,
+ 0x2e, 0xb0, 0x3d, 0x2b, 0x74, 0x6d, 0x59, 0xde, 0xc6, 0x20, 0xb8, 0xf3,
+ 0x7d, 0xfa, 0x4d, 0xbd, 0xdb, 0x3c, 0xc5, 0xcb, 0x57, 0x13, 0x40, 0x6b,
+ 0xb8, 0xad, 0xb9, 0xc1, 0x6a, 0x37, 0x39, 0x80, 0x94, 0xd3, 0xdf, 0x4b,
+ 0xe4, 0xe4, 0x7a, 0x4c, 0x0f, 0x21, 0x27, 0x9a, 0x7e, 0x52, 0x35, 0x58,
+ 0xb4, 0xbc, 0x5a, 0xc9, 0x48, 0x7f, 0xcc, 0xb6, 0x97, 0x7b, 0xf1, 0xd5,
+ 0x88, 0x8c, 0xa9, 0x27, 0xf7, 0x20, 0x68, 0x65, 0xad, 0x6f, 0x9e, 0x07,
+ 0xf8, 0xf6, 0x2c, 0x65, 0x4a, 0xe9, 0xd8, 0x13, 0x6a, 0xb5, 0x14, 0x6f,
+ 0x29, 0xdc, 0x68, 0xf8, 0xa0, 0xb6, 0x73, 0x03, 0x69, 0xe3, 0x4f, 0xb6,
+ 0x59, 0x79, 0xae, 0x93, 0xad, 0x40, 0x27, 0xd0, 0xb5, 0x7a, 0x68, 0x5d,
+ 0x5e, 0x19, 0x53, 0x4f, 0x40, 0x56, 0x3d, 0x10, 0xf8, 0x0a, 0xc6, 0x90,
+ 0x06, 0x45, 0x13, 0x4a, 0x6a, 0xfe, 0x56, 0xeb, 0xbc, 0xd9, 0xee, 0xe0,
+ 0x85, 0x5e, 0x98, 0x23, 0xf9, 0x19, 0x60, 0xf9, 0x7e, 0x8d, 0x61, 0xa0,
+ 0x7c, 0xe1, 0x84, 0xf2, 0x7a, 0xb8, 0xbe, 0x8e, 0x81, 0x9e, 0x87, 0x20,
+ 0x32, 0xf3, 0x8c, 0xb4, 0x2c, 0x4d, 0xc8, 0x50, 0x9b, 0xa5, 0x9c, 0x27,
+ 0x02, 0xd6, 0x7f, 0x2a, 0xaf, 0x46, 0x65, 0xd0, 0x6a, 0xae, 0xfa, 0x53,
+ 0x37, 0x6c, 0x49, 0xb9, 0x4d, 0xcd, 0x6c, 0x6b, 0xa7, 0x2d, 0x66, 0x32,
+ 0xb4, 0xf5, 0x41, 0xd5, 0x18, 0xc4, 0xfd, 0xbe, 0x8a, 0x47, 0x11, 0x50,
+ 0x3d, 0x97, 0x64, 0xda, 0x5a, 0x27, 0x18, 0x60, 0x78, 0x80, 0x86, 0x8a,
+ 0x2a, 0x72, 0x40, 0x89
};
namespace MutationOfJB {
uint32 EncryptedFile::read(void *dataPtr, uint32 dataSize) {
- uint8 xorPos = pos() % 256;
+ uint8 xorPos = static_cast<uint8>(pos() % ARRAYSIZE(XOR_TABLE));
const uint32 readBytes = Common::File::read(dataPtr, dataSize);
for (uint32 i = 0; i < readBytes; ++i) {
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 7b500d3..2843ad9 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -39,13 +39,13 @@ namespace MutationOfJB {
Game::Game(MutationOfJBEngine *vm)
: _vm(vm),
- _randomSource("mutationofjb"),
- _delayedLocalScript(nullptr),
- _gui(*this, _vm->getScreen()),
- _currentAction(ActionInfo::Walk),
- _scriptExecCtx(*this),
- _taskManager(*this),
- _assets(*this) {
+ _randomSource("mutationofjb"),
+ _delayedLocalScript(nullptr),
+ _gui(*this, _vm->getScreen()),
+ _currentAction(ActionInfo::Walk),
+ _scriptExecCtx(*this),
+ _taskManager(*this),
+ _assets(*this) {
_gameData = new GameData;
loadGameData(false);
diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp
index 54335d1..f25eff6 100644
--- a/engines/mutationofjb/gamedata.cpp
+++ b/engines/mutationofjb/gamedata.cpp
@@ -245,11 +245,10 @@ bool Scene::isChoiceExhausted(uint8 context, uint8 choiceIndex, uint8 choiceList
GameData::GameData()
: _currentScene(0),
- _lastScene(0),
- _partB(false),
- _inventory(),
- _color(WHITE)
- {}
+ _lastScene(0),
+ _partB(false),
+ _inventory(),
+ _color(WHITE) {}
Scene *GameData::getScene(uint8 sceneId) {
if (sceneId == 0 || sceneId > ARRAYSIZE(_scenes)) {
diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h
index fc755f7..8783555 100644
--- a/engines/mutationofjb/gamedata.h
+++ b/engines/mutationofjb/gamedata.h
@@ -235,9 +235,15 @@ struct ExhaustedChoice {
*/
uint8 _encodedData;
- uint8 getContext() const { return (_encodedData >> 7) & 0x1; }
- uint8 getChoiceIndex() const { return (_encodedData >> 4) & 0x7; }
- uint8 getChoiceListIndex() const { return _encodedData & 0xF; }
+ uint8 getContext() const {
+ return (_encodedData >> 7) & 0x1;
+ }
+ uint8 getChoiceIndex() const {
+ return (_encodedData >> 4) & 0x7;
+ }
+ uint8 getChoiceListIndex() const {
+ return _encodedData & 0xF;
+ }
ExhaustedChoice() : _encodedData(0) {}
ExhaustedChoice(uint8 context, uint8 choiceIndex, uint8 choiceListIndex) :
diff --git a/engines/mutationofjb/gui.cpp b/engines/mutationofjb/gui.cpp
index 41ef94a..6266ff0 100644
--- a/engines/mutationofjb/gui.cpp
+++ b/engines/mutationofjb/gui.cpp
@@ -64,7 +64,7 @@ enum {
Gui::Gui(Game &game, Graphics::Screen *screen)
: _game(game),
- _screen(screen) {}
+ _screen(screen) {}
Gui::~Gui() {
for (Common::Array<Widget *>::iterator it = _widgets.begin(); it != _widgets.end(); ++it) {
@@ -122,7 +122,7 @@ bool Gui::init() {
}
const Common::Rect conversationRect(CONVERSATION_X, CONVERSATION_Y, CONVERSATION_X + CONVERSATION_WIDTH, CONVERSATION_Y + CONVERSATION_HEIGHT);
- const Graphics::Surface conversationSurface =_hudSurfaces[2].getSubArea(conversationRect);
+ const Graphics::Surface conversationSurface = _hudSurfaces[2].getSubArea(conversationRect);
_conversationWidget = new ConversationWidget(*this, conversationRect, conversationSurface);
_conversationWidget->setVisible(false);
_widgets.push_back(_conversationWidget);
@@ -154,7 +154,7 @@ void Gui::update() {
}
}
-ConversationWidget& Gui::getConversationWidget() {
+ConversationWidget &Gui::getConversationWidget() {
return *_conversationWidget;
}
diff --git a/engines/mutationofjb/gui.h b/engines/mutationofjb/gui.h
index 8919a9d..f644517 100644
--- a/engines/mutationofjb/gui.h
+++ b/engines/mutationofjb/gui.h
@@ -65,7 +65,7 @@ public:
virtual void onInventoryChanged() override;
virtual void onButtonClicked(ButtonWidget *) override;
- ConversationWidget& getConversationWidget();
+ ConversationWidget &getConversationWidget();
private:
bool loadInventoryGfx();
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index cdaa037..2320255 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -40,11 +40,11 @@
namespace MutationOfJB {
MutationOfJBEngine::MutationOfJBEngine(OSystem *syst)
-: Engine(syst),
- _console(nullptr),
- _screen(nullptr),
- _mapObjectId(0),
- _cursorState(CURSOR_IDLE) {
+ : Engine(syst),
+ _console(nullptr),
+ _screen(nullptr),
+ _mapObjectId(0),
+ _cursorState(CURSOR_IDLE) {
debug("MutationOfJBEngine::MutationOfJBEngine");
}
@@ -174,7 +174,7 @@ void MutationOfJBEngine::handleMapScene(const Common::Event &event) {
const int16 y = event.mouse.y;
int index = 0;
- if (Bitmap *const bitmap = scene->findBitmap(x, y, &index)) {
+ if (Bitmap *const bitmap = scene->findBitmap(x, y, &index)) {
Static *const stat = scene->getStatic(index);
if (stat && stat->_active == 1) {
_game->startActionSection(ActionInfo::Walk, stat->_name);
@@ -188,7 +188,7 @@ void MutationOfJBEngine::handleMapScene(const Common::Event &event) {
int index = 0;
bool found = false;
- if (Bitmap *const bitmap = scene->findBitmap(x, y, &index)) {
+ if (Bitmap *const bitmap = scene->findBitmap(x, y, &index)) {
Static *const stat = scene->getStatic(index);
if (stat && stat->_active == 1) {
Object *const object = scene->getObject(index);
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 3e93c47..fb148c1 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -103,7 +103,7 @@ bool ScriptParseContext::readLine(Common::String &line) {
}
return true;
}
- } while(!_stream.eos());
+ } while (!_stream.eos());
return false;
}
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 28e0e98..17e1810 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -21,7 +21,7 @@
*/
#ifndef MUTATIONOFJB_SCRIPT_H
-#define MUTATIONOFJB_SCRIPT_H
+#define MUTATIONOFJB_SCRIPT_H
#include "mutationofjb/commands/command.h"
#include "common/array.h"
diff --git a/engines/mutationofjb/tasks/conversationtask.cpp b/engines/mutationofjb/tasks/conversationtask.cpp
index d4fab56..8c07b32 100644
--- a/engines/mutationofjb/tasks/conversationtask.cpp
+++ b/engines/mutationofjb/tasks/conversationtask.cpp
@@ -61,7 +61,7 @@ void ConversationTask::update() {
finish();
break;
case SAYING_CHOICE: {
- const ConversationLineList& responseList = getTaskManager()->getGame().getAssets().getResponseList();
+ const ConversationLineList &responseList = getTaskManager()->getGame().getAssets().getResponseList();
const ConversationLineList::Line *const line = responseList.getLine(_currentItem->_response);
_substate = SAYING_RESPONSE;
@@ -72,8 +72,7 @@ void ConversationTask::update() {
case SAYING_RESPONSE: {
startExtra();
- if (_substate != RUNNING_EXTRA)
- {
+ if (_substate != RUNNING_EXTRA) {
gotoNextLine();
}
break;
@@ -99,7 +98,7 @@ void ConversationTask::onChoiceClicked(ConversationWidget *convWidget, int, uint
const ConversationInfo::Item &item = getCurrentLine()->_items[data];
convWidget->clearChoices();
- const ConversationLineList& toSayList = getTaskManager()->getGame().getAssets().getToSayList();
+ const ConversationLineList &toSayList = getTaskManager()->getGame().getAssets().getToSayList();
const ConversationLineList::Line *line = toSayList.getLine(item._choice);
_substate = SAYING_CHOICE;
@@ -157,7 +156,7 @@ void ConversationTask::showChoicesOrPick() {
if (itemsWithValidChoices.size() > 1) {
ConversationWidget &widget = game.getGui().getConversationWidget();
- const ConversationLineList& toSayList = game.getAssets().getToSayList();
+ const ConversationLineList &toSayList = game.getAssets().getToSayList();
for (Common::Array<uint32>::size_type i = 0; i < itemsWithValidChoices.size() && i < ConversationWidget::CONVERSATION_MAX_CHOICES; ++i) {
const ConversationInfo::Item &item = currentLine->_items[itemsWithValidChoices[i]];
@@ -170,7 +169,7 @@ void ConversationTask::showChoicesOrPick() {
_haveChoices = true;
} else if (itemsWithValidChoices.size() == 1 && _haveChoices) {
- const ConversationLineList& toSayList = game.getAssets().getToSayList();
+ const ConversationLineList &toSayList = game.getAssets().getToSayList();
const ConversationInfo::Item &item = currentLine->_items[itemsWithValidChoices.front()];
const ConversationLineList::Line *const line = toSayList.getLine(item._choice);
@@ -185,7 +184,7 @@ void ConversationTask::showChoicesOrPick() {
_haveChoices = true;
} else if (!itemsWithValidResponses.empty() && _haveChoices) {
- const ConversationLineList& responseList = game.getAssets().getResponseList();
+ const ConversationLineList &responseList = game.getAssets().getResponseList();
const ConversationInfo::Item &item = currentLine->_items[itemsWithValidResponses.front()];
const ConversationLineList::Line *const line = responseList.getLine(item._response);
@@ -224,7 +223,7 @@ void ConversationTask::finish() {
}
void ConversationTask::startExtra() {
- const ConversationLineList& responseList = getTaskManager()->getGame().getAssets().getResponseList();
+ const ConversationLineList &responseList = getTaskManager()->getGame().getAssets().getResponseList();
const ConversationLineList::Line *const line = responseList.getLine(_currentItem->_response);
if (!line->_extra.empty()) {
_innerExecCtx = new ScriptExecutionContext(getTaskManager()->getGame());
diff --git a/engines/mutationofjb/tasks/conversationtask.h b/engines/mutationofjb/tasks/conversationtask.h
index e4bbdc3..bdfa875 100644
--- a/engines/mutationofjb/tasks/conversationtask.h
+++ b/engines/mutationofjb/tasks/conversationtask.h
@@ -33,7 +33,7 @@ class ScriptExecutionContext;
class ConversationTask : public Task, public ConversationWidgetCallback {
public:
- ConversationTask(uint8 sceneId, const ConversationInfo& convInfo, TalkCommand::Mode mode) : _sceneId(sceneId), _convInfo(convInfo), _mode(mode), _currentLineIndex(0), _currentItem(nullptr), _substate(IDLE), _haveChoices(false), _innerExecCtx(nullptr) {}
+ ConversationTask(uint8 sceneId, const ConversationInfo &convInfo, TalkCommand::Mode mode) : _sceneId(sceneId), _convInfo(convInfo), _mode(mode), _currentLineIndex(0), _currentItem(nullptr), _substate(IDLE), _haveChoices(false), _innerExecCtx(nullptr) {}
virtual ~ConversationTask() {}
virtual void start() override;
diff --git a/engines/mutationofjb/tasks/task.h b/engines/mutationofjb/tasks/task.h
index 8c9c0e8..b14fc97 100644
--- a/engines/mutationofjb/tasks/task.h
+++ b/engines/mutationofjb/tasks/task.h
@@ -44,15 +44,26 @@ public:
virtual void start() = 0;
virtual void update() = 0;
- virtual void stop() { assert(false); } // Assert by default - stopping might not be safe for all tasks.
+ virtual void stop() {
+ assert(false); // Assert by default - stopping might not be safe for all tasks.
+ }
- void setTaskManager(TaskManager *taskMan) { _taskManager = taskMan; }
- TaskManager *getTaskManager() { return _taskManager; }
+ void setTaskManager(TaskManager *taskMan) {
+ _taskManager = taskMan;
+ }
- State getState() const { return _state; }
+ TaskManager *getTaskManager() {
+ return _taskManager;
+ }
+
+ State getState() const {
+ return _state;
+ }
protected:
- void setState(State state) { _state = state; }
+ void setState(State state) {
+ _state = state;
+ }
private:
TaskManager *_taskManager;
diff --git a/engines/mutationofjb/tasks/taskmanager.h b/engines/mutationofjb/tasks/taskmanager.h
index 29e854a..2f351c0 100644
--- a/engines/mutationofjb/tasks/taskmanager.h
+++ b/engines/mutationofjb/tasks/taskmanager.h
@@ -57,11 +57,13 @@ public:
* However, if only a raw pointer is available (e.g. this),
* the method can be used to obtain a SharedPtr.
*/
- TaskPtr getTask(Task* task);
+ TaskPtr getTask(Task *task);
void update();
- Game &getGame() { return _game; }
+ Game &getGame() {
+ return _game;
+ }
private:
TaskPtrs _tasks;
diff --git a/engines/mutationofjb/util.cpp b/engines/mutationofjb/util.cpp
index 72d2d0f..2e3b0b3 100644
--- a/engines/mutationofjb/util.cpp
+++ b/engines/mutationofjb/util.cpp
@@ -37,9 +37,9 @@ void reportFileMissingError(const char *fileName) {
Common::String toUpperCP895(const Common::String &str) {
static const byte conversionTable[] = {
- 0x00, 0x9A, 0x90, 0x85, 0x8E, 0x00, 0x00, 0x80, 0x89, 0x00, 0x00, 0x00, 0x9C, 0x8A, 0x00, 0x00, /* 0x80-0x8F */
- 0x00, 0x92, 0x00, 0xA7, 0x99, 0x00, 0xA6, 0x00, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, /* 0x90-0x9F */
- 0x8F, 0x8B, 0x95, 0x97, 0xA5, 0x00, 0x00, 0x00, 0x9B, 0x9E, 0xAB, 0x00 /* 0xA0-0xAB */
+ 0x00, 0x9A, 0x90, 0x85, 0x8E, 0x00, 0x00, 0x80, 0x89, 0x00, 0x00, 0x00, 0x9C, 0x8A, 0x00, 0x00, /* 0x80-0x8F */
+ 0x00, 0x92, 0x00, 0xA7, 0x99, 0x00, 0xA6, 0x00, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, /* 0x90-0x9F */
+ 0x8F, 0x8B, 0x95, 0x97, 0xA5, 0x00, 0x00, 0x00, 0x9B, 0x9E, 0xAB, 0x00 /* 0xA0-0xAB */
};
Common::String ret = str;
diff --git a/engines/mutationofjb/util.h b/engines/mutationofjb/util.h
index ac1239d..fe72794 100644
--- a/engines/mutationofjb/util.h
+++ b/engines/mutationofjb/util.h
@@ -39,7 +39,7 @@ void reportFileMissingError(const char *fileName);
Common::String toUpperCP895(const Common::String &str);
// Taken from ManagedSurface::clip.
-template <typename SurfaceType>
+template<typename SurfaceType>
bool clipBounds(Common::Rect &srcBounds, Common::Rect &destBounds, SurfaceType &destSurf) {
if (destBounds.left >= destSurf.w || destBounds.top >= destSurf.h ||
destBounds.right <= 0 || destBounds.bottom <= 0)
@@ -69,7 +69,7 @@ bool clipBounds(Common::Rect &srcBounds, Common::Rect &destBounds, SurfaceType &
return true;
}
-template <typename BlitOp>
+template<typename BlitOp>
void blit_if(const Graphics::Surface &src, const Common::Rect &srcRect, Graphics::Surface &dest, const Common::Point &destPos, BlitOp blitOp) {
Common::Rect srcBounds = srcRect;
Common::Rect destBounds(destPos.x, destPos.y, destPos.x + srcRect.width(), destPos.y + srcRect.height());
@@ -96,7 +96,7 @@ void blit_if(const Graphics::Surface &src, const Common::Rect &srcRect, Graphics
}
}
-template <typename BlitOp>
+template<typename BlitOp>
void blit_if(const Graphics::Surface &src, const Common::Rect &srcRect, Graphics::ManagedSurface &dest, const Common::Point &destPos, BlitOp blitOp) {
Common::Rect srcBounds = srcRect;
Common::Rect destBounds(destPos.x, destPos.y, destPos.x + srcRect.width(), destPos.y + srcRect.height());
@@ -111,12 +111,12 @@ void blit_if(const Graphics::Surface &src, const Common::Rect &srcRect, Graphics
blit_if(src, srcRect, destSurf, Common::Point(0, 0), blitOp);
}
-template <typename BlitOp>
+template<typename BlitOp>
void blit_if(const Graphics::Surface &src, Graphics::Surface &dest, const Common::Point &destPos, BlitOp blitOp) {
blit_if(src, Common::Rect(0, 0, src.w, src.h), dest, destPos, blitOp);
}
-template <typename BlitOp>
+template<typename BlitOp>
void blit_if(const Graphics::Surface &src, Graphics::ManagedSurface &dest, const Common::Point &destPos, BlitOp blitOp) {
blit_if(src, Common::Rect(0, 0, src.w, src.h), dest, destPos, blitOp);
}
diff --git a/engines/mutationofjb/widgets/buttonwidget.cpp b/engines/mutationofjb/widgets/buttonwidget.cpp
index 9f9a401..911cb7d 100644
--- a/engines/mutationofjb/widgets/buttonwidget.cpp
+++ b/engines/mutationofjb/widgets/buttonwidget.cpp
@@ -38,9 +38,8 @@ void ButtonWidget::setCallback(ButtonWidgetCallback *callback) {
}
void ButtonWidget::handleEvent(const Common::Event &event) {
- switch(event.type) {
- case Common::EVENT_LBUTTONDOWN:
- {
+ switch (event.type) {
+ case Common::EVENT_LBUTTONDOWN: {
const int16 x = event.mouse.x;
const int16 y = event.mouse.y;
if (_area.contains(x, y)) {
@@ -49,8 +48,7 @@ void ButtonWidget::handleEvent(const Common::Event &event) {
}
break;
}
- case Common::EVENT_LBUTTONUP:
- {
+ case Common::EVENT_LBUTTONUP: {
if (_pressed) {
_pressed = false;
markDirty();
diff --git a/engines/mutationofjb/widgets/conversationwidget.cpp b/engines/mutationofjb/widgets/conversationwidget.cpp
index 24bb5e1..e0bbf66 100644
--- a/engines/mutationofjb/widgets/conversationwidget.cpp
+++ b/engines/mutationofjb/widgets/conversationwidget.cpp
@@ -74,9 +74,8 @@ void ConversationWidget::_draw(Graphics::ManagedSurface &surface) {
}
void ConversationWidget::handleEvent(const Common::Event &event) {
- switch(event.type) {
- case Common::EVENT_LBUTTONDOWN:
- {
+ switch (event.type) {
+ case Common::EVENT_LBUTTONDOWN: {
const int16 x = event.mouse.x;
const int16 y = event.mouse.y;
if (_area.contains(x, y)) {
diff --git a/engines/mutationofjb/widgets/conversationwidget.h b/engines/mutationofjb/widgets/conversationwidget.h
index 51ea86e..abde702 100644
--- a/engines/mutationofjb/widgets/conversationwidget.h
+++ b/engines/mutationofjb/widgets/conversationwidget.h
@@ -41,7 +41,9 @@ public:
enum { CONVERSATION_MAX_CHOICES = 4 };
ConversationWidget(Gui &gui, const Common::Rect &area, const Graphics::Surface &surface);
- void setCallback(ConversationWidgetCallback *callback) { _callback = callback; }
+ void setCallback(ConversationWidgetCallback *callback) {
+ _callback = callback;
+ }
void setChoice(int choiceNo, const Common::String &str, uint32 data = 0);
void clearChoices();
diff --git a/engines/mutationofjb/widgets/inventorywidget.cpp b/engines/mutationofjb/widgets/inventorywidget.cpp
index d78ef10..96f35e4 100644
--- a/engines/mutationofjb/widgets/inventorywidget.cpp
+++ b/engines/mutationofjb/widgets/inventorywidget.cpp
@@ -41,7 +41,7 @@ enum {
INVENTORY_ITEMS_LINES = 5
};
-InventoryWidget::InventoryWidget(Gui &gui, Gui::InventoryMap &inventoryMap, const Common::Array<Graphics::Surface>& inventorySurfaces) :
+InventoryWidget::InventoryWidget(Gui &gui, Gui::InventoryMap &inventoryMap, const Common::Array<Graphics::Surface> &inventorySurfaces) :
Widget(gui, Common::Rect(INVENTORY_START_X, INVENTORY_START_Y, INVENTORY_START_X + Inventory::VISIBLE_ITEMS * INVENTORY_ITEM_WIDTH, INVENTORY_START_Y + INVENTORY_ITEM_HEIGHT)),
_inventoryMap(inventoryMap),
_surfaces(inventorySurfaces) {}
diff --git a/engines/mutationofjb/widgets/inventorywidget.h b/engines/mutationofjb/widgets/inventorywidget.h
index f0bc4ba..8d6205e 100644
--- a/engines/mutationofjb/widgets/inventorywidget.h
+++ b/engines/mutationofjb/widgets/inventorywidget.h
@@ -34,13 +34,13 @@ namespace MutationOfJB {
class InventoryWidget : public Widget {
public:
- InventoryWidget(Gui &gui, Gui::InventoryMap &inventoryMap, const Common::Array<Graphics::Surface>& inventorySurfaces);
+ InventoryWidget(Gui &gui, Gui::InventoryMap &inventoryMap, const Common::Array<Graphics::Surface> &inventorySurfaces);
virtual void _draw(Graphics::ManagedSurface &) override;
private:
void drawInventoryItem(Graphics::ManagedSurface &surface, const Common::String &item, int pos);
Gui::InventoryMap &_inventoryMap;
- const Common::Array<Graphics::Surface>& _surfaces;
+ const Common::Array<Graphics::Surface> &_surfaces;
};
}
Commit: 4633b8398642f3005827780313c25479689a72dc
https://github.com/scummvm/scummvm/commit/4633b8398642f3005827780313c25479689a72dc
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Improve documentation and naming.
Changed paths:
engines/mutationofjb/commands/camefromcommand.cpp
engines/mutationofjb/commands/changecommand.cpp
engines/mutationofjb/commands/command.h
engines/mutationofjb/commands/definestructcommand.cpp
engines/mutationofjb/commands/endblockcommand.cpp
engines/mutationofjb/commands/ifitemcommand.cpp
engines/mutationofjb/commands/removeitemcommand.cpp
engines/mutationofjb/commands/saycommand.cpp
engines/mutationofjb/commands/seqcommand.h
engines/mutationofjb/commands/talkcommand.cpp
engines/mutationofjb/gamedata.cpp
engines/mutationofjb/gamedata.h
engines/mutationofjb/tasks/conversationtask.cpp
engines/mutationofjb/tasks/conversationtask.h
engines/mutationofjb/tasks/objectanimationtask.cpp
engines/mutationofjb/tasks/sequentialtask.h
engines/mutationofjb/tasks/task.h
engines/mutationofjb/tasks/taskmanager.h
diff --git a/engines/mutationofjb/commands/camefromcommand.cpp b/engines/mutationofjb/commands/camefromcommand.cpp
index 485e0c5..67033b8 100644
--- a/engines/mutationofjb/commands/camefromcommand.cpp
+++ b/engines/mutationofjb/commands/camefromcommand.cpp
@@ -26,7 +26,7 @@
#include "common/str.h"
/** @file
- * "CAMEFROM" <sceneId>
+ * "CAMEFROM " <sceneId>
*
* This command tests whether last scene (the scene player came from) is sceneId.
* If true, the execution continues after this command.
diff --git a/engines/mutationofjb/commands/changecommand.cpp b/engines/mutationofjb/commands/changecommand.cpp
index 5d6833b..7d2e7e6 100644
--- a/engines/mutationofjb/commands/changecommand.cpp
+++ b/engines/mutationofjb/commands/changecommand.cpp
@@ -25,8 +25,6 @@
#include "mutationofjb/gamedata.h"
#include "common/translation.h"
-namespace MutationOfJB {
-
/** @file
* "CHANGE" <entity> " " <register> " " <sceneId> " " <entityId> " " <value>
*
@@ -43,6 +41,8 @@ namespace MutationOfJB {
* <value> *B Value (variable length).
*/
+namespace MutationOfJB {
+
bool ChangeCommandParser::parseValueString(const Common::String &valueString, bool changeEntity, uint8 &sceneId, uint8 &entityId, ChangeCommand::ChangeRegister ®, ChangeCommand::ChangeOperation &op, ChangeCommandValue &ccv) {
if (changeEntity) {
if (valueString.size() < 8) {
diff --git a/engines/mutationofjb/commands/command.h b/engines/mutationofjb/commands/command.h
index 0133d52..b407aa1 100644
--- a/engines/mutationofjb/commands/command.h
+++ b/engines/mutationofjb/commands/command.h
@@ -33,18 +33,56 @@ class Command;
class ScriptExecutionContext;
class ScriptParseContext;
+/**
+ * Base class for command parsers.
+ *
+ * The parser's main job is to create a Command instance from input line.
+ */
class CommandParser {
public:
virtual ~CommandParser();
+
+ /**
+ * Parses the specified line and possibly returns a Command instance.
+ *
+ * @param line Line to parse.
+ * @param parseCtx Parse context.
+ * @param command Output parameter for newly created command.
+ * @return True if the line has been successfully parsed by this parser, false otherwise.
+ * @note You may return true and set command to nullptr.
+ * That means the line has been successfully parsed, but no command is needed.
+ */
virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) = 0;
- /* Old command - created by this parser. */
+ /**
+ * Called when transitioning parsing between two commands.
+ *
+ * For example, cmdParserA->transition(parseCtx, cmdA, cmdB, cmdParserB) is called after command B is done parsing
+ * to notify command A parser about the transition from command A to command B.
+ * This is useful for sequential commands, because at the time command A is being parsed,
+ * we don't have any information about command B, so we cannot set the next pointer.
+ * Transition method can be used to set the next pointer after command B is available.
+ *
+ * @param parseCtx Parse context.
+ * @param oldCommand Old command (created by this parser).
+ * @param newCommand New command (created by newCommandParser).
+ * @param newCommandParser Command parser which created the new command.
+ */
virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser);
- /* Called after parsing. */
+ /**
+ * Called after the whole script is parsed.
+ *
+ * Can be used for cleanup.
+ *
+ * @param parseCtx Parse context.
+ */
virtual void finish(ScriptParseContext &parseCtx);
};
+/**
+ * Base class for script commands.
+ */
class Command {
public:
enum ExecuteResult {
@@ -60,6 +98,7 @@ public:
virtual Common::String debugString() const = 0;
};
+
}
#endif
diff --git a/engines/mutationofjb/commands/definestructcommand.cpp b/engines/mutationofjb/commands/definestructcommand.cpp
index 4ccf2e8..bea3497 100644
--- a/engines/mutationofjb/commands/definestructcommand.cpp
+++ b/engines/mutationofjb/commands/definestructcommand.cpp
@@ -25,6 +25,22 @@
#include "mutationofjb/game.h"
#include "common/debug.h"
+/** @file
+ * "DEFINE_STRUCT " <numItemGroups> " " <context> " " <objectId> " " <colorString> <CRLF>
+ * <itemGroup> { <CRLF> <itemGroup> }
+ *
+ * item ::= <questionIndex> " " <responseIndex> " " <nextGroup>
+ * itemGroup ::= <item> " " <item> " " <item> " " <item> " " <item>
+ *
+ * Defines the flow of an interactive conversation.
+ *
+ * Every item group consists of 5 conversation items.
+ * "questionIndex" and "responseIndex" specify what the player and the responder say when the conversation item is selected.
+ * They refer to the line numbers of TOSAY.GER and RESPONSE.GER, respectively.
+ * "nextGroup" refers to the group that follows when the conversation item is selected. A value of 0 indicates end of
+ * conversation.
+ */
+
namespace MutationOfJB {
bool DefineStructCommandParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) {
@@ -52,19 +68,19 @@ bool DefineStructCommandParser::parse(const Common::String &line, ScriptParseCon
const char *linePtr = convLineStr.c_str();
- ConversationInfo::Line convLine;
+ ConversationInfo::ItemGroup convGroup;
for (int j = 0; j < 5; ++j) {
ConversationInfo::Item convItem;
- convItem._choice = atoi(linePtr);
+ convItem._question = atoi(linePtr);
linePtr += 6;
convItem._response = atoi(linePtr);
linePtr += 6;
- convItem._nextLineIndex = atoi(linePtr);
+ convItem._nextGroupIndex = atoi(linePtr);
linePtr += 3;
- convLine._items.push_back(convItem);
+ convGroup.push_back(convItem);
}
- convInfo._lines.push_back(convLine);
+ convInfo._itemGroups.push_back(convGroup);
}
command = new DefineStructCommand(convInfo);
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index c7fbd41..8ad11f8 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -28,16 +28,19 @@
#include "common/translation.h"
/** @file
- * ("#L " | "-L ") <object>
- * ("#W " | "-W ") <object>
- * ("#T " | "-T ") <object>
- * ("#P " | "-P ") <object1>
- * ("#U " | "-U ") <object1> [<object2>]
- * ("#ELSE" | "-ELSE") [<tag>]
- * "#MACRO " <name>
- * "#EXTRA" <name>
+ * <look> | <walk> | <talk> | <pickup> | <use> | <else> | <macro> | <extra> | <endRandom>
*
- * If a line starts with '#', '=', '-', it is treated as the end of a section.
+ * look ::= ("#L " | "-L ") <object>
+ * walk ::= ("#W " | "-W ") <object>
+ * talk ::= ("#T " | "-T ") <object>
+ * pickup ::= ("#P " | "-P ") <object1>
+ * use ::= ("#U " | "-U ") <object1> [<object2>]
+ * else ::= ("#ELSE" | "-ELSE") [<tag>]
+ * macro ::= "#MACRO " <name>
+ * extra ::= "#EXTRA" <name>
+ * endRandom ::= "\"
+ *
+ * If a line starts with '#', '=', '-', '\' it is treated as the end of a section.
* However, at the same time it can also start a new section depending on what follows.
*
* #L (look), #W (walk), #T (talk), #U (use) sections are executed
@@ -49,6 +52,8 @@
* #MACRO starts a new macro. Global script can call macros from local script and vice versa.
*
* #EXTRA defines an "extra" section. This is called from dialog responses ("TALK TO HIM" command).
+ *
+ * TODO: TIMERPROC.
*/
namespace MutationOfJB {
diff --git a/engines/mutationofjb/commands/ifitemcommand.cpp b/engines/mutationofjb/commands/ifitemcommand.cpp
index d70add9..eec4621 100644
--- a/engines/mutationofjb/commands/ifitemcommand.cpp
+++ b/engines/mutationofjb/commands/ifitemcommand.cpp
@@ -28,7 +28,7 @@
#include "common/translation.h"
/** @file
- * "IFITEM" <item> ["!"]
+ * "IFITEM " <item> [ "!" ]
*
* IFITEM command tests whether an item is in the inventory.
* If it is, execution continues to the next line.
diff --git a/engines/mutationofjb/commands/removeitemcommand.cpp b/engines/mutationofjb/commands/removeitemcommand.cpp
index 21d1123..be8ea23 100644
--- a/engines/mutationofjb/commands/removeitemcommand.cpp
+++ b/engines/mutationofjb/commands/removeitemcommand.cpp
@@ -25,7 +25,7 @@
#include "mutationofjb/gamedata.h"
/** @file
- * "DELITEM" " " <item>
+ * "DELITEM " <item>
*
* Removes item from inventory.
*/
diff --git a/engines/mutationofjb/commands/saycommand.cpp b/engines/mutationofjb/commands/saycommand.cpp
index e63ceb1..e99b4f2 100644
--- a/engines/mutationofjb/commands/saycommand.cpp
+++ b/engines/mutationofjb/commands/saycommand.cpp
@@ -33,8 +33,10 @@
#include "common/debug-channels.h"
/** @file
- * ("SM" | "SLM" | "NM" | "NLM") " " <lineToSay> ["<" <voiceFile> | "<!"]
- * <skipped> " " <lineToSay> ("<" <voiceFile> | "<!")
+ * <firstLine> { <CRLF> <additionalLine> }
+ *
+ * firstLine ::= ("SM" | "SLM" | "NM" | "NLM") " " <lineToSay> [ "<" <voiceFile> | "<!" ]
+ * additionalLine ::= <skipped> " " <lineToSay> ( "<" <voiceFile> | "<!" )
*
* Say command comes in four variants: SM, SLM, NM and NLM.
* Note: In script files, they are usually written as *SM.
diff --git a/engines/mutationofjb/commands/seqcommand.h b/engines/mutationofjb/commands/seqcommand.h
index 6c969e9..e37f77f 100644
--- a/engines/mutationofjb/commands/seqcommand.h
+++ b/engines/mutationofjb/commands/seqcommand.h
@@ -33,6 +33,9 @@ public:
virtual void transition(ScriptParseContext &parseCtx, Command *oldCommand, Command *newCommand, CommandParser *newCommandParser) override;
};
+/**
+ * Base class for sequential commands.
+ */
class SeqCommand : public Command {
public:
SeqCommand() : _nextCommand(nullptr) {}
diff --git a/engines/mutationofjb/commands/talkcommand.cpp b/engines/mutationofjb/commands/talkcommand.cpp
index 5c7eb8e..9857f38 100644
--- a/engines/mutationofjb/commands/talkcommand.cpp
+++ b/engines/mutationofjb/commands/talkcommand.cpp
@@ -29,6 +29,17 @@
#include "common/str.h"
+/** @file
+ * "TALK TO HIM" [ " " <mode> ]
+ *
+ * Begins interactive conversation defined by DefineStructCommand.
+ * The command supports multiple modes:
+ * 0 - normal mode,
+ * 1 - Ray and Buttleg mode (two responders),
+ * 2 - unknown (unused) mode,
+ * 3 - carnival ticket seller mode (special animation).
+ */
+
namespace MutationOfJB {
bool TalkCommandParser::parse(const Common::String &line, ScriptParseContext &, Command *&command) {
diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp
index f25eff6..d91c0fb 100644
--- a/engines/mutationofjb/gamedata.cpp
+++ b/engines/mutationofjb/gamedata.cpp
@@ -136,10 +136,10 @@ bool Scene::loadFromStream(Common::ReadStream &stream) {
_palRotFirst = stream.readByte();
_palRotLast = stream.readByte();
_palRotDelay = stream.readByte();
- _exhaustedChoiceNext = stream.readByte();
+ _exhaustedConvItemNext = stream.readByte();
for (i = 0; i < 79; ++i) {
- _exhaustedChoices[i]._encodedData = stream.readByte();
+ _exhaustedConvItems[i]._encodedData = stream.readByte();
}
return true;
@@ -226,15 +226,15 @@ Bitmap *Scene::findBitmap(int16 x, int16 y, int *index) {
return nullptr;
}
-void Scene::addExhaustedChoice(uint8 context, uint8 choiceIndex, uint8 choiceIndexList) {
- _exhaustedChoices[_exhaustedChoiceNext - 1] = ExhaustedChoice(context, choiceIndex, choiceIndexList);
- _exhaustedChoiceNext++;
+void Scene::addExhaustedConvItem(uint8 context, uint8 convItemIndex, uint8 convGroupIndex) {
+ _exhaustedConvItems[_exhaustedConvItemNext - 1] = ExhaustedConvItem(context, convItemIndex, convGroupIndex);
+ _exhaustedConvItemNext++;
}
-bool Scene::isChoiceExhausted(uint8 context, uint8 choiceIndex, uint8 choiceListIndex) const {
- for (uint i = 0; i < _exhaustedChoiceNext - 1; ++i) {
- const ExhaustedChoice &choice = _exhaustedChoices[i];
- if (choice.getContext() == context && choice.getChoiceIndex() == choiceIndex && choice.getChoiceListIndex() == choiceListIndex) {
+bool Scene::isConvItemExhausted(uint8 context, uint8 convItemIndex, uint8 convGroupIndex) const {
+ for (uint8 i = 0; i < _exhaustedConvItemNext - 1; ++i) {
+ const ExhaustedConvItem &convItem = _exhaustedConvItems[i];
+ if (convItem.getContext() == context && convItem.getConvItemIndex() == convItemIndex && convItem.getConvGroupIndex() == convGroupIndex) {
return true;
}
}
diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h
index 8783555..8088969 100644
--- a/engines/mutationofjb/gamedata.h
+++ b/engines/mutationofjb/gamedata.h
@@ -225,29 +225,29 @@ struct Bitmap {
};
/**
- * Encoded exhausted choice.
+ * Encoded exhausted convesation item.
*/
-struct ExhaustedChoice {
+struct ExhaustedConvItem {
/**
- * 1 bit - context
- * 3 bits - choice index
- * 4 bits - choice list index
+ * 1 bit - context.
+ * 3 bits - conversation item index.
+ * 4 bits - conversation group index.
*/
uint8 _encodedData;
uint8 getContext() const {
return (_encodedData >> 7) & 0x1;
}
- uint8 getChoiceIndex() const {
+ uint8 getConvItemIndex() const {
return (_encodedData >> 4) & 0x7;
}
- uint8 getChoiceListIndex() const {
+ uint8 getConvGroupIndex() const {
return _encodedData & 0xF;
}
- ExhaustedChoice() : _encodedData(0) {}
- ExhaustedChoice(uint8 context, uint8 choiceIndex, uint8 choiceListIndex) :
- _encodedData(((context & 0x1) << 7) | ((choiceIndex & 0x7) << 4) | (choiceListIndex & 0xF)) {}
+ ExhaustedConvItem() : _encodedData(0) {}
+ ExhaustedConvItem(uint8 context, uint8 convItemIndex, uint8 convGroupIndex) :
+ _encodedData(((context & 0x1) << 7) | ((convItemIndex & 0x7) << 4) | (convGroupIndex & 0xF)) {}
};
struct Scene {
@@ -263,8 +263,8 @@ struct Scene {
Static *findStatic(int16 x, int16 y, int *index = nullptr);
Bitmap *findBitmap(int16 x, int16 y, int *index = nullptr);
- void addExhaustedChoice(uint8 context, uint8 choiceIndex, uint8 choiceIndexList);
- bool isChoiceExhausted(uint8 context, uint8 choiceIndex, uint8 choiceIndexList) const;
+ void addExhaustedConvItem(uint8 context, uint8 convItemIndex, uint8 convGroupIndex);
+ bool isConvItemExhausted(uint8 context, uint8 convItemIndex, uint8 convGroupIndex) const;
/** Refers to the script block that will be executed when you enter this scene (DS register). */
uint8 _startup;
@@ -298,28 +298,25 @@ struct Scene {
uint8 _palRotDelay;
/**
- * Points to the first free item in exhausted choices list.
+ * Points to the first free item in exhausted conversation item array.
* @note Indexed from 1.
*/
- uint8 _exhaustedChoiceNext;
- ExhaustedChoice _exhaustedChoices[79];
+ uint8 _exhaustedConvItemNext;
+ ExhaustedConvItem _exhaustedConvItems[79];
bool loadFromStream(Common::ReadStream &stream);
};
struct ConversationInfo {
struct Item {
- uint8 _choice;
+ uint8 _question;
uint8 _response;
- uint8 _nextLineIndex;
+ uint8 _nextGroupIndex;
};
- typedef Common::Array<Item> Items;
- struct Line {
- Items _items;
- };
+ typedef Common::Array<Item> ItemGroup;
- Common::Array<Line> _lines;
+ Common::Array<ItemGroup> _itemGroups;
uint8 _context;
uint8 _objectId;
uint8 _color;
diff --git a/engines/mutationofjb/tasks/conversationtask.cpp b/engines/mutationofjb/tasks/conversationtask.cpp
index 8c07b32..3b1dcc5 100644
--- a/engines/mutationofjb/tasks/conversationtask.cpp
+++ b/engines/mutationofjb/tasks/conversationtask.cpp
@@ -46,7 +46,7 @@ void ConversationTask::start() {
widget.setCallback(this);
widget.setVisible(true);
- _currentLineIndex = 0;
+ _currentGroupIndex = 0;
showChoicesOrPick();
}
@@ -57,10 +57,10 @@ void ConversationTask::update() {
_sayTask.reset();
switch (_substate) {
- case SAYING_NO_CHOICES:
+ case SAYING_NO_QUESTIONS:
finish();
break;
- case SAYING_CHOICE: {
+ case SAYING_QUESTION: {
const ConversationLineList &responseList = getTaskManager()->getGame().getAssets().getResponseList();
const ConversationLineList::Line *const line = responseList.getLine(_currentItem->_response);
@@ -73,7 +73,7 @@ void ConversationTask::update() {
startExtra();
if (_substate != RUNNING_EXTRA) {
- gotoNextLine();
+ gotoNextGroup();
}
break;
}
@@ -89,25 +89,25 @@ void ConversationTask::update() {
delete _innerExecCtx;
_innerExecCtx = nullptr;
- gotoNextLine();
+ gotoNextGroup();
}
}
}
void ConversationTask::onChoiceClicked(ConversationWidget *convWidget, int, uint32 data) {
- const ConversationInfo::Item &item = getCurrentLine()->_items[data];
+ const ConversationInfo::Item &item = getCurrentGroup()[data];
convWidget->clearChoices();
const ConversationLineList &toSayList = getTaskManager()->getGame().getAssets().getToSayList();
- const ConversationLineList::Line *line = toSayList.getLine(item._choice);
+ const ConversationLineList::Line *line = toSayList.getLine(item._question);
- _substate = SAYING_CHOICE;
+ _substate = SAYING_QUESTION;
createSayTasks(line);
getTaskManager()->startTask(_sayTask);
_currentItem = &item;
if (!line->_speeches[0].isRepeating()) {
- getTaskManager()->getGame().getGameData().getCurrentScene()->addExhaustedChoice(_convInfo._context, data + 1, _currentLineIndex + 1);
+ getTaskManager()->getGame().getGameData().getCurrentScene()->addExhaustedConvItem(_convInfo._context, data + 1, _currentGroupIndex + 1);
}
}
@@ -116,33 +116,33 @@ void ConversationTask::showChoicesOrPick() {
GameData &gameData = game.getGameData();
Scene *const scene = gameData.getScene(_sceneId);
- Common::Array<uint32> itemsWithValidChoices;
+ Common::Array<uint32> itemsWithValidQuestions;
Common::Array<uint32> itemsWithValidResponses;
Common::Array<uint32> itemsWithValidNext;
/*
- Collect valid "to say" choices (not exhausted and not empty).
+ Collect valid questions (not exhausted and not empty).
Collect valid responses (not exhausted and not empty).
- If there are at least two visible choices, we show them.
- If there is just one visible choice, pick it automatically ONLY if this is not the first choice in this conversation.
+ If there are at least two visible questions, we show them.
+ If there is just one visible question, pick it automatically ONLY if this is not the first question in this conversation.
Otherwise we don't start the conversation.
- If there are no visible choices, automatically pick first valid response.
+ If there are no visible questions, automatically pick the first valid response.
If nothing above applies, don't start the conversation.
*/
- const ConversationInfo::Line *const currentLine = getCurrentLine();
- for (ConversationInfo::Items::size_type i = 0; i < currentLine->_items.size(); ++i) {
- const ConversationInfo::Item &item = currentLine->_items[i];
+ const ConversationInfo::ItemGroup ¤tGroup = getCurrentGroup();
+ for (ConversationInfo::ItemGroup::size_type i = 0; i < currentGroup.size(); ++i) {
+ const ConversationInfo::Item &item = currentGroup[i];
- if (scene->isChoiceExhausted(_convInfo._context, (uint8) i + 1, (uint8) _currentLineIndex + 1)) {
+ if (scene->isConvItemExhausted(_convInfo._context, (uint8) i + 1, (uint8) _currentGroupIndex + 1)) {
continue;
}
- const uint8 choice = item._choice;
+ const uint8 toSay = item._question;
const uint8 response = item._response;
- const uint8 next = item._nextLineIndex;
+ const uint8 next = item._nextGroupIndex;
- if (choice != 0) {
- itemsWithValidChoices.push_back(i);
+ if (toSay != 0) {
+ itemsWithValidQuestions.push_back(i);
}
if (response != 0) {
@@ -154,38 +154,38 @@ void ConversationTask::showChoicesOrPick() {
}
}
- if (itemsWithValidChoices.size() > 1) {
+ if (itemsWithValidQuestions.size() > 1) {
ConversationWidget &widget = game.getGui().getConversationWidget();
const ConversationLineList &toSayList = game.getAssets().getToSayList();
- for (Common::Array<uint32>::size_type i = 0; i < itemsWithValidChoices.size() && i < ConversationWidget::CONVERSATION_MAX_CHOICES; ++i) {
- const ConversationInfo::Item &item = currentLine->_items[itemsWithValidChoices[i]];
- const ConversationLineList::Line *const line = toSayList.getLine(item._choice);
+ for (Common::Array<uint32>::size_type i = 0; i < itemsWithValidQuestions.size() && i < ConversationWidget::CONVERSATION_MAX_CHOICES; ++i) {
+ const ConversationInfo::Item &item = currentGroup[itemsWithValidQuestions[i]];
+ const ConversationLineList::Line *const line = toSayList.getLine(item._question);
const Common::String widgetText = toUpperCP895(line->_speeches[0]._text);
- widget.setChoice((int) i, widgetText, itemsWithValidChoices[i]);
+ widget.setChoice((int) i, widgetText, itemsWithValidQuestions[i]);
}
_substate = IDLE;
_currentItem = nullptr;
_haveChoices = true;
- } else if (itemsWithValidChoices.size() == 1 && _haveChoices) {
+ } else if (itemsWithValidQuestions.size() == 1 && _haveChoices) {
const ConversationLineList &toSayList = game.getAssets().getToSayList();
- const ConversationInfo::Item &item = currentLine->_items[itemsWithValidChoices.front()];
- const ConversationLineList::Line *const line = toSayList.getLine(item._choice);
+ const ConversationInfo::Item &item = currentGroup[itemsWithValidQuestions.front()];
+ const ConversationLineList::Line *const line = toSayList.getLine(item._question);
- _substate = SAYING_CHOICE;
+ _substate = SAYING_QUESTION;
createSayTasks(line);
getTaskManager()->startTask(_sayTask);
_currentItem = &item;
if (!line->_speeches[0].isRepeating()) {
- game.getGameData().getCurrentScene()->addExhaustedChoice(_convInfo._context, itemsWithValidChoices.front() + 1, _currentLineIndex + 1);
+ game.getGameData().getCurrentScene()->addExhaustedConvItem(_convInfo._context, itemsWithValidQuestions.front() + 1, _currentGroupIndex + 1);
}
_haveChoices = true;
} else if (!itemsWithValidResponses.empty() && _haveChoices) {
const ConversationLineList &responseList = game.getAssets().getResponseList();
- const ConversationInfo::Item &item = currentLine->_items[itemsWithValidResponses.front()];
+ const ConversationInfo::Item &item = currentGroup[itemsWithValidResponses.front()];
const ConversationLineList::Line *const line = responseList.getLine(item._response);
_substate = SAYING_RESPONSE;
@@ -195,7 +195,7 @@ void ConversationTask::showChoicesOrPick() {
_haveChoices = true;
} else if (!itemsWithValidNext.empty() && _haveChoices) {
- _currentLineIndex = currentLine->_items[itemsWithValidNext.front()]._nextLineIndex - 1;
+ _currentGroupIndex = currentGroup[itemsWithValidNext.front()]._nextGroupIndex - 1;
showChoicesOrPick();
} else {
if (_haveChoices) {
@@ -203,14 +203,15 @@ void ConversationTask::showChoicesOrPick() {
} else {
_sayTask = TaskPtr(new SayTask("Nothing to talk about.", _convInfo._color)); // TODO: This is hardcoded in executable. Load it.
getTaskManager()->startTask(_sayTask);
- _substate = SAYING_NO_CHOICES;
+ _substate = SAYING_NO_QUESTIONS;
_currentItem = nullptr;
}
}
}
-const ConversationInfo::Line *ConversationTask::getCurrentLine() const {
- return &_convInfo._lines[_currentLineIndex];
+const ConversationInfo::ItemGroup &ConversationTask::getCurrentGroup() const {
+ assert(_currentGroupIndex < _convInfo._itemGroups.size());
+ return _convInfo._itemGroups[_currentGroupIndex];
}
void ConversationTask::finish() {
@@ -244,11 +245,11 @@ void ConversationTask::startExtra() {
}
}
-void ConversationTask::gotoNextLine() {
- if (_currentItem->_nextLineIndex == 0) {
+void ConversationTask::gotoNextGroup() {
+ if (_currentItem->_nextGroupIndex == 0) {
finish();
} else {
- _currentLineIndex = _currentItem->_nextLineIndex - 1;
+ _currentGroupIndex = _currentItem->_nextGroupIndex - 1;
showChoicesOrPick();
}
}
diff --git a/engines/mutationofjb/tasks/conversationtask.h b/engines/mutationofjb/tasks/conversationtask.h
index bdfa875..9522876 100644
--- a/engines/mutationofjb/tasks/conversationtask.h
+++ b/engines/mutationofjb/tasks/conversationtask.h
@@ -33,7 +33,7 @@ class ScriptExecutionContext;
class ConversationTask : public Task, public ConversationWidgetCallback {
public:
- ConversationTask(uint8 sceneId, const ConversationInfo &convInfo, TalkCommand::Mode mode) : _sceneId(sceneId), _convInfo(convInfo), _mode(mode), _currentLineIndex(0), _currentItem(nullptr), _substate(IDLE), _haveChoices(false), _innerExecCtx(nullptr) {}
+ ConversationTask(uint8 sceneId, const ConversationInfo &convInfo, TalkCommand::Mode mode) : _sceneId(sceneId), _convInfo(convInfo), _mode(mode), _currentGroupIndex(0), _currentItem(nullptr), _substate(IDLE), _haveChoices(false), _innerExecCtx(nullptr) {}
virtual ~ConversationTask() {}
virtual void start() override;
@@ -42,25 +42,25 @@ public:
virtual void onChoiceClicked(ConversationWidget *, int response, uint32 data) override;
private:
void showChoicesOrPick();
- const ConversationInfo::Line *getCurrentLine() const;
+ const ConversationInfo::ItemGroup &getCurrentGroup() const;
void finish();
void startExtra();
- void gotoNextLine();
+ void gotoNextGroup();
void createSayTasks(const ConversationLineList::Line *line);
uint8 getSpeechColor(const ConversationLineList::Speech &speech);
uint8 _sceneId;
const ConversationInfo &_convInfo;
TalkCommand::Mode _mode;
- uint _currentLineIndex;
+ uint _currentGroupIndex;
const ConversationInfo::Item *_currentItem;
TaskPtr _sayTask;
enum Substate {
IDLE,
- SAYING_CHOICE,
+ SAYING_QUESTION,
SAYING_RESPONSE,
- SAYING_NO_CHOICES,
+ SAYING_NO_QUESTIONS,
RUNNING_EXTRA
};
diff --git a/engines/mutationofjb/tasks/objectanimationtask.cpp b/engines/mutationofjb/tasks/objectanimationtask.cpp
index e93602c..2b4bf80 100644
--- a/engines/mutationofjb/tasks/objectanimationtask.cpp
+++ b/engines/mutationofjb/tasks/objectanimationtask.cpp
@@ -56,7 +56,7 @@ void ObjectAnimationTask::update() {
* Additionally, there is a chance with each frame until _randomFrame that the animation may jump
* straight to _randomFrame and continue until the last frame, then wrap around to the first frame.
*
- * Randomness is used to introduce variety - e.g. in the starting scene a perched bird occassionally
+ * Randomness is used to introduce variety - e.g. in the starting scene a perched bird occasionally
* spreads its wings.
*/
void ObjectAnimationTask::updateObjects() {
diff --git a/engines/mutationofjb/tasks/sequentialtask.h b/engines/mutationofjb/tasks/sequentialtask.h
index 078fd8a..1c00751 100644
--- a/engines/mutationofjb/tasks/sequentialtask.h
+++ b/engines/mutationofjb/tasks/sequentialtask.h
@@ -27,6 +27,9 @@
namespace MutationOfJB {
+/**
+ * Queues multiple tasks.
+ */
class SequentialTask : public Task {
public:
SequentialTask(const TaskPtrs &tasks);
diff --git a/engines/mutationofjb/tasks/task.h b/engines/mutationofjb/tasks/task.h
index b14fc97..115668a 100644
--- a/engines/mutationofjb/tasks/task.h
+++ b/engines/mutationofjb/tasks/task.h
@@ -31,6 +31,9 @@ namespace MutationOfJB {
class TaskManager;
+/**
+ * Base class for tasks.
+ */
class Task {
public:
enum State {
diff --git a/engines/mutationofjb/tasks/taskmanager.h b/engines/mutationofjb/tasks/taskmanager.h
index 2f351c0..c88da59 100644
--- a/engines/mutationofjb/tasks/taskmanager.h
+++ b/engines/mutationofjb/tasks/taskmanager.h
@@ -31,6 +31,11 @@ namespace MutationOfJB {
class Game;
class Task;
+/**
+ * Handles task management.
+ *
+ * Tasks are a way run game logic asynchronously.
+ */
class TaskManager {
public:
TaskManager(Game &game) : _game(game) {}
Commit: 9f1c628d4bfbd6600ceb67b5b872cf08825dc1e4
https://github.com/scummvm/scummvm/commit/9f1c628d4bfbd6600ceb67b5b872cf08825dc1e4
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Fix forward declarations of structs.
Changed paths:
engines/mutationofjb/commands/endblockcommand.h
engines/mutationofjb/game.h
engines/mutationofjb/gui.h
engines/mutationofjb/mutationofjb.h
engines/mutationofjb/script.h
engines/mutationofjb/widgets/widget.h
diff --git a/engines/mutationofjb/commands/endblockcommand.h b/engines/mutationofjb/commands/endblockcommand.h
index 55656aa..bda50fb 100644
--- a/engines/mutationofjb/commands/endblockcommand.h
+++ b/engines/mutationofjb/commands/endblockcommand.h
@@ -29,7 +29,7 @@
namespace MutationOfJB {
-class ActionInfo;
+struct ActionInfo;
class EndBlockCommandParser : public CommandParser {
public:
diff --git a/engines/mutationofjb/game.h b/engines/mutationofjb/game.h
index 316dc75..9ab52ef 100644
--- a/engines/mutationofjb/game.h
+++ b/engines/mutationofjb/game.h
@@ -40,13 +40,13 @@ namespace MutationOfJB {
class Command;
class MutationOfJBEngine;
-class GameData;
class Script;
class Room;
-class Door;
-class Static;
-class Bitmap;
class SayTask;
+struct GameData;
+struct Door;
+struct Static;
+struct Bitmap;
class Game {
public:
diff --git a/engines/mutationofjb/gui.h b/engines/mutationofjb/gui.h
index f644517..354d04f 100644
--- a/engines/mutationofjb/gui.h
+++ b/engines/mutationofjb/gui.h
@@ -31,7 +31,7 @@
#include "mutationofjb/widgets/buttonwidget.h"
namespace Common {
-class Event;
+struct Event;
}
namespace Graphics {
diff --git a/engines/mutationofjb/mutationofjb.h b/engines/mutationofjb/mutationofjb.h
index 050800e..91a3138 100644
--- a/engines/mutationofjb/mutationofjb.h
+++ b/engines/mutationofjb/mutationofjb.h
@@ -27,7 +27,7 @@
#include "mutationofjb/script.h"
namespace Common {
-class Event;
+struct Event;
}
namespace Graphics {
diff --git a/engines/mutationofjb/script.h b/engines/mutationofjb/script.h
index 17e1810..86f2450 100644
--- a/engines/mutationofjb/script.h
+++ b/engines/mutationofjb/script.h
@@ -39,13 +39,13 @@ namespace MutationOfJB {
class Command;
class LabelCommand;
class Game;
-class GameData;
class GotoCommand;
class ConditionalCommand;
class Script;
class RandomCommand;
-typedef Common::Array<Command *> Commands;
+struct GameData;
+typedef Common::Array<Command *> Commands;
struct ActionInfo {
enum Action {
diff --git a/engines/mutationofjb/widgets/widget.h b/engines/mutationofjb/widgets/widget.h
index ed3a3ac..a88f628 100644
--- a/engines/mutationofjb/widgets/widget.h
+++ b/engines/mutationofjb/widgets/widget.h
@@ -27,7 +27,7 @@
#include <common/rect.h>
namespace Common {
-class Event;
+struct Event;
}
namespace Graphics {
Commit: 561309eaa2fb2d5298567366068ac9daafc7c2f7
https://github.com/scummvm/scummvm/commit/561309eaa2fb2d5298567366068ac9daafc7c2f7
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Fix missing lines between block ends.
Changed paths:
engines/mutationofjb/commands/changecommand.cpp
engines/mutationofjb/commands/conditionalcommand.cpp
engines/mutationofjb/commands/definestructcommand.cpp
engines/mutationofjb/commands/definestructcommand.h
engines/mutationofjb/commands/ifcommand.cpp
engines/mutationofjb/commands/ifitemcommand.cpp
engines/mutationofjb/commands/ifpiggycommand.cpp
engines/mutationofjb/commands/labelcommand.cpp
engines/mutationofjb/commands/newroomcommand.cpp
engines/mutationofjb/commands/randomcommand.cpp
engines/mutationofjb/commands/seqcommand.h
engines/mutationofjb/debug.h
engines/mutationofjb/detection.cpp
engines/mutationofjb/mutationofjb.cpp
engines/mutationofjb/mutationofjb.h
engines/mutationofjb/script.cpp
engines/mutationofjb/util.cpp
engines/mutationofjb/util.h
engines/mutationofjb/widgets/buttonwidget.cpp
engines/mutationofjb/widgets/buttonwidget.h
engines/mutationofjb/widgets/conversationwidget.cpp
engines/mutationofjb/widgets/conversationwidget.h
engines/mutationofjb/widgets/imagewidget.cpp
engines/mutationofjb/widgets/imagewidget.h
engines/mutationofjb/widgets/inventorywidget.cpp
engines/mutationofjb/widgets/inventorywidget.h
engines/mutationofjb/widgets/widget.cpp
engines/mutationofjb/widgets/widget.h
diff --git a/engines/mutationofjb/commands/changecommand.cpp b/engines/mutationofjb/commands/changecommand.cpp
index 7d2e7e6..e3c8a99 100644
--- a/engines/mutationofjb/commands/changecommand.cpp
+++ b/engines/mutationofjb/commands/changecommand.cpp
@@ -556,4 +556,5 @@ Command::ExecuteResult ChangeSceneCommand::execute(ScriptExecutionContext &scrip
Common::String ChangeSceneCommand::debugString() const {
return Common::String::format("SCENE%d.%s %s %s", _sceneId, getRegisterAsString(), getOperationAsString(), getValueAsString().c_str());
}
+
}
diff --git a/engines/mutationofjb/commands/conditionalcommand.cpp b/engines/mutationofjb/commands/conditionalcommand.cpp
index 27b2714..2a6b36a 100644
--- a/engines/mutationofjb/commands/conditionalcommand.cpp
+++ b/engines/mutationofjb/commands/conditionalcommand.cpp
@@ -46,9 +46,7 @@ void ConditionalCommandParser::finish(ScriptParseContext &) {
ConditionalCommand::ConditionalCommand() :
_trueCommand(nullptr),
_falseCommand(nullptr),
- _cachedResult(false)
-{}
-
+ _cachedResult(false) {}
Command *ConditionalCommand::getTrueCommand() const {
return _trueCommand;
@@ -73,4 +71,5 @@ Command *ConditionalCommand::next() const {
return _falseCommand;
}
}
+
}
diff --git a/engines/mutationofjb/commands/definestructcommand.cpp b/engines/mutationofjb/commands/definestructcommand.cpp
index bea3497..455e243 100644
--- a/engines/mutationofjb/commands/definestructcommand.cpp
+++ b/engines/mutationofjb/commands/definestructcommand.cpp
@@ -96,4 +96,5 @@ Command::ExecuteResult DefineStructCommand::execute(ScriptExecutionContext &scri
Common::String DefineStructCommand::debugString() const {
return "DEFINE_STRUCT <data omitted>";
}
+
}
diff --git a/engines/mutationofjb/commands/definestructcommand.h b/engines/mutationofjb/commands/definestructcommand.h
index 13fc910..651f943 100644
--- a/engines/mutationofjb/commands/definestructcommand.h
+++ b/engines/mutationofjb/commands/definestructcommand.h
@@ -38,4 +38,5 @@ public:
private:
ConversationInfo _conversationInfo;
};
+
}
diff --git a/engines/mutationofjb/commands/ifcommand.cpp b/engines/mutationofjb/commands/ifcommand.cpp
index 06fb5ca..9c43588 100644
--- a/engines/mutationofjb/commands/ifcommand.cpp
+++ b/engines/mutationofjb/commands/ifcommand.cpp
@@ -77,12 +77,12 @@ bool IfCommandParser::parse(const Common::String &line, ScriptParseContext &, Co
return true;
}
+
IfCommand::IfCommand(uint8 sceneId, uint8 objectId, uint16 value, bool negative) :
_sceneId(sceneId),
_objectId(objectId),
_value(value),
- _negative(negative)
-{}
+ _negative(negative) {}
Command::ExecuteResult IfCommand::execute(ScriptExecutionContext &scriptExecCtx) {
Scene *const scene = scriptExecCtx.getGameData().getScene(_sceneId);
@@ -108,4 +108,3 @@ Common::String IfCommand::debugString() const {
}
}
-
diff --git a/engines/mutationofjb/commands/ifitemcommand.cpp b/engines/mutationofjb/commands/ifitemcommand.cpp
index eec4621..ccbf09e 100644
--- a/engines/mutationofjb/commands/ifitemcommand.cpp
+++ b/engines/mutationofjb/commands/ifitemcommand.cpp
@@ -70,8 +70,7 @@ bool IfItemCommandParser::parse(const Common::String &line, ScriptParseContext &
IfItemCommand::IfItemCommand(const Common::String &item, bool negative) :
_item(item),
- _negative(negative)
-{}
+ _negative(negative) {}
Command::ExecuteResult IfItemCommand::execute(ScriptExecutionContext &scriptExecCtx) {
_cachedResult = scriptExecCtx.getGameData()._inventory.hasItem(_item);
@@ -87,4 +86,3 @@ Common::String IfItemCommand::debugString() const {
}
}
-
diff --git a/engines/mutationofjb/commands/ifpiggycommand.cpp b/engines/mutationofjb/commands/ifpiggycommand.cpp
index e3107806..d500b4a 100644
--- a/engines/mutationofjb/commands/ifpiggycommand.cpp
+++ b/engines/mutationofjb/commands/ifpiggycommand.cpp
@@ -68,4 +68,3 @@ Common::String IfPiggyCommand::debugString() const {
}
}
-
diff --git a/engines/mutationofjb/commands/labelcommand.cpp b/engines/mutationofjb/commands/labelcommand.cpp
index 7593e52..ef2410a 100644
--- a/engines/mutationofjb/commands/labelcommand.cpp
+++ b/engines/mutationofjb/commands/labelcommand.cpp
@@ -59,6 +59,7 @@ bool LabelCommandParser::parse(const Common::String &line, ScriptParseContext &p
return true;
}
+
const Common::String &LabelCommand::getName() const {
return _name;
}
diff --git a/engines/mutationofjb/commands/newroomcommand.cpp b/engines/mutationofjb/commands/newroomcommand.cpp
index 5aabc67..0f4d214 100644
--- a/engines/mutationofjb/commands/newroomcommand.cpp
+++ b/engines/mutationofjb/commands/newroomcommand.cpp
@@ -80,4 +80,3 @@ Common::String NewRoomCommand::debugString() const {
}
}
-
diff --git a/engines/mutationofjb/commands/randomcommand.cpp b/engines/mutationofjb/commands/randomcommand.cpp
index 467f788..260fd3a 100644
--- a/engines/mutationofjb/commands/randomcommand.cpp
+++ b/engines/mutationofjb/commands/randomcommand.cpp
@@ -61,6 +61,7 @@ bool RandomCommandParser::parse(const Common::String &line, ScriptParseContext &
return true;
}
+
bool RandomBlockStartParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&) {
if (line != "/") {
return false;
@@ -84,6 +85,7 @@ void RandomBlockStartParser::transition(ScriptParseContext &parseCtx, Command *,
}
}
+
RandomCommand::RandomCommand(uint numChoices)
: _numChoices(numChoices),
_chosenNext(nullptr) {
diff --git a/engines/mutationofjb/commands/seqcommand.h b/engines/mutationofjb/commands/seqcommand.h
index e37f77f..f61f33b 100644
--- a/engines/mutationofjb/commands/seqcommand.h
+++ b/engines/mutationofjb/commands/seqcommand.h
@@ -49,4 +49,3 @@ private:
}
#endif
-
diff --git a/engines/mutationofjb/debug.h b/engines/mutationofjb/debug.h
index 24b1e95..b5c40c0 100644
--- a/engines/mutationofjb/debug.h
+++ b/engines/mutationofjb/debug.h
@@ -60,4 +60,3 @@ private:
}
#endif
-
diff --git a/engines/mutationofjb/detection.cpp b/engines/mutationofjb/detection.cpp
index f95f696..5e80760 100644
--- a/engines/mutationofjb/detection.cpp
+++ b/engines/mutationofjb/detection.cpp
@@ -110,4 +110,3 @@ public:
#else
REGISTER_PLUGIN_STATIC(MUTATIONOFJB, PLUGIN_TYPE_ENGINE, MutationOfJBMetaEngine);
#endif
-
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index 2320255..1d88269 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -52,7 +52,6 @@ MutationOfJBEngine::~MutationOfJBEngine() {
debug("MutationOfJBEngine::~MutationOfJBEngine");
}
-
void MutationOfJBEngine::setupCursor() {
const uint8 cursor[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
diff --git a/engines/mutationofjb/mutationofjb.h b/engines/mutationofjb/mutationofjb.h
index 91a3138..21f8094 100644
--- a/engines/mutationofjb/mutationofjb.h
+++ b/engines/mutationofjb/mutationofjb.h
@@ -72,7 +72,6 @@ private:
CursorState _cursorState;
};
-
}
#endif
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index fb148c1..01aef2c 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -87,8 +87,7 @@ ScriptParseContext::ScriptParseContext(Common::SeekableReadStream &stream) :
_stream(stream),
_currentCommand(nullptr),
_lastCommand(nullptr),
- _pendingRandomCommand(nullptr)
-{}
+ _pendingRandomCommand(nullptr) {}
bool ScriptParseContext::readLine(Common::String &line) {
do {
diff --git a/engines/mutationofjb/util.cpp b/engines/mutationofjb/util.cpp
index 2e3b0b3..1483fb2 100644
--- a/engines/mutationofjb/util.cpp
+++ b/engines/mutationofjb/util.cpp
@@ -58,4 +58,3 @@ Common::String toUpperCP895(const Common::String &str) {
}
}
-
diff --git a/engines/mutationofjb/util.h b/engines/mutationofjb/util.h
index fe72794..a98f6ff 100644
--- a/engines/mutationofjb/util.h
+++ b/engines/mutationofjb/util.h
@@ -32,7 +32,6 @@ namespace Common {
class String;
}
-
namespace MutationOfJB {
void reportFileMissingError(const char *fileName);
diff --git a/engines/mutationofjb/widgets/buttonwidget.cpp b/engines/mutationofjb/widgets/buttonwidget.cpp
index 911cb7d..e2a9dd3 100644
--- a/engines/mutationofjb/widgets/buttonwidget.cpp
+++ b/engines/mutationofjb/widgets/buttonwidget.cpp
@@ -62,7 +62,9 @@ void ButtonWidget::handleEvent(const Common::Event &event) {
break;
}
}
-void ButtonWidget::_draw(Graphics::ManagedSurface &surface) {
+
+void ButtonWidget::draw(Graphics::ManagedSurface &surface) {
surface.blitFrom(_pressed ? _pressedSurface : _normalSurface, Common::Point(_area.left, _area.top));
}
+
}
diff --git a/engines/mutationofjb/widgets/buttonwidget.h b/engines/mutationofjb/widgets/buttonwidget.h
index de8cb63..d148fa8 100644
--- a/engines/mutationofjb/widgets/buttonwidget.h
+++ b/engines/mutationofjb/widgets/buttonwidget.h
@@ -44,7 +44,7 @@ public:
virtual void handleEvent(const Common::Event &event) override;
protected:
- virtual void _draw(Graphics::ManagedSurface &) override;
+ virtual void draw(Graphics::ManagedSurface &) override;
private:
Graphics::Surface _normalSurface;
diff --git a/engines/mutationofjb/widgets/conversationwidget.cpp b/engines/mutationofjb/widgets/conversationwidget.cpp
index e0bbf66..56e0057 100644
--- a/engines/mutationofjb/widgets/conversationwidget.cpp
+++ b/engines/mutationofjb/widgets/conversationwidget.cpp
@@ -59,7 +59,7 @@ void ConversationWidget::clearChoices() {
markDirty();
}
-void ConversationWidget::_draw(Graphics::ManagedSurface &surface) {
+void ConversationWidget::draw(Graphics::ManagedSurface &surface) {
surface.blitFrom(_surface, Common::Point(_area.left, _area.top));
for (int i = 0; i < CONVERSATION_MAX_CHOICES; ++i) {
@@ -94,4 +94,3 @@ void ConversationWidget::handleEvent(const Common::Event &event) {
}
}
-
diff --git a/engines/mutationofjb/widgets/conversationwidget.h b/engines/mutationofjb/widgets/conversationwidget.h
index abde702..34ea215 100644
--- a/engines/mutationofjb/widgets/conversationwidget.h
+++ b/engines/mutationofjb/widgets/conversationwidget.h
@@ -51,7 +51,7 @@ public:
virtual void handleEvent(const Common::Event &event) override;
protected:
- virtual void _draw(Graphics::ManagedSurface &surface) override;
+ virtual void draw(Graphics::ManagedSurface &surface) override;
private:
Graphics::Surface _surface;
diff --git a/engines/mutationofjb/widgets/imagewidget.cpp b/engines/mutationofjb/widgets/imagewidget.cpp
index 3395da8..8eeb7ed 100644
--- a/engines/mutationofjb/widgets/imagewidget.cpp
+++ b/engines/mutationofjb/widgets/imagewidget.cpp
@@ -30,7 +30,7 @@ ImageWidget::ImageWidget(Gui &gui, const Common::Rect &area, const Graphics::Sur
_image(image) {}
-void ImageWidget::_draw(Graphics::ManagedSurface &surface) {
+void ImageWidget::draw(Graphics::ManagedSurface &surface) {
surface.blitFrom(_image, Common::Point(_area.left, _area.top));
}
diff --git a/engines/mutationofjb/widgets/imagewidget.h b/engines/mutationofjb/widgets/imagewidget.h
index 4585a72..da3dd36 100644
--- a/engines/mutationofjb/widgets/imagewidget.h
+++ b/engines/mutationofjb/widgets/imagewidget.h
@@ -33,7 +33,7 @@ public:
ImageWidget(Gui &gui, const Common::Rect &area, const Graphics::Surface &image);
protected:
- virtual void _draw(Graphics::ManagedSurface &surface) override;
+ virtual void draw(Graphics::ManagedSurface &surface) override;
private:
Graphics::Surface _image;
diff --git a/engines/mutationofjb/widgets/inventorywidget.cpp b/engines/mutationofjb/widgets/inventorywidget.cpp
index 96f35e4..a26bab6 100644
--- a/engines/mutationofjb/widgets/inventorywidget.cpp
+++ b/engines/mutationofjb/widgets/inventorywidget.cpp
@@ -63,7 +63,7 @@ void InventoryWidget::drawInventoryItem(Graphics::ManagedSurface &surface, const
surface.blitFrom(_surfaces[surfaceNo], sourceRect, destStartPos);
}
-void InventoryWidget::_draw(Graphics::ManagedSurface &surface) {
+void InventoryWidget::draw(Graphics::ManagedSurface &surface) {
Inventory &inventory = _gui.getGame().getGameData().getInventory();
const Inventory::Items &items = inventory.getItems();
surface.fillRect(_area, 0x00);
diff --git a/engines/mutationofjb/widgets/inventorywidget.h b/engines/mutationofjb/widgets/inventorywidget.h
index 8d6205e..f1841e8 100644
--- a/engines/mutationofjb/widgets/inventorywidget.h
+++ b/engines/mutationofjb/widgets/inventorywidget.h
@@ -35,7 +35,7 @@ namespace MutationOfJB {
class InventoryWidget : public Widget {
public:
InventoryWidget(Gui &gui, Gui::InventoryMap &inventoryMap, const Common::Array<Graphics::Surface> &inventorySurfaces);
- virtual void _draw(Graphics::ManagedSurface &) override;
+ virtual void draw(Graphics::ManagedSurface &) override;
private:
void drawInventoryItem(Graphics::ManagedSurface &surface, const Common::String &item, int pos);
diff --git a/engines/mutationofjb/widgets/widget.cpp b/engines/mutationofjb/widgets/widget.cpp
index 5503f62..b030211 100644
--- a/engines/mutationofjb/widgets/widget.cpp
+++ b/engines/mutationofjb/widgets/widget.cpp
@@ -54,7 +54,7 @@ bool Widget::isDirty() const {
void Widget::update(Graphics::ManagedSurface &surface) {
if (_dirty) {
if (_visible) {
- _draw(surface);
+ draw(surface);
}
_dirty = false;
}
diff --git a/engines/mutationofjb/widgets/widget.h b/engines/mutationofjb/widgets/widget.h
index a88f628..e16b1e4 100644
--- a/engines/mutationofjb/widgets/widget.h
+++ b/engines/mutationofjb/widgets/widget.h
@@ -55,7 +55,7 @@ public:
virtual void handleEvent(const Common::Event &) {}
protected:
- virtual void _draw(Graphics::ManagedSurface &) = 0;
+ virtual void draw(Graphics::ManagedSurface &) = 0;
Gui &_gui;
Common::Rect _area;
@@ -67,4 +67,3 @@ protected:
}
#endif
-
Commit: 959f37dfe4f0d46a28217f85832af07b73e190c0
https://github.com/scummvm/scummvm/commit/959f37dfe4f0d46a28217f85832af07b73e190c0
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Don't mark internal strings as translatable.
Changed paths:
engines/mutationofjb/animationdecoder.cpp
engines/mutationofjb/commands/callmacrocommand.cpp
engines/mutationofjb/commands/changecommand.cpp
engines/mutationofjb/commands/conditionalcommand.cpp
engines/mutationofjb/commands/endblockcommand.cpp
engines/mutationofjb/commands/ifcommand.cpp
engines/mutationofjb/commands/ifitemcommand.cpp
engines/mutationofjb/commands/ifpiggycommand.cpp
engines/mutationofjb/commands/randomcommand.cpp
engines/mutationofjb/commands/seqcommand.cpp
engines/mutationofjb/debug.cpp
engines/mutationofjb/game.cpp
engines/mutationofjb/gamedata.cpp
engines/mutationofjb/room.cpp
engines/mutationofjb/script.cpp
engines/mutationofjb/tasks/conversationtask.cpp
engines/mutationofjb/tasks/taskmanager.cpp
diff --git a/engines/mutationofjb/animationdecoder.cpp b/engines/mutationofjb/animationdecoder.cpp
index 712cb42..43590a9 100644
--- a/engines/mutationofjb/animationdecoder.cpp
+++ b/engines/mutationofjb/animationdecoder.cpp
@@ -24,7 +24,6 @@
#include "mutationofjb/encryptedfile.h"
#include "mutationofjb/util.h"
#include "common/debug.h"
-#include "common/translation.h"
namespace MutationOfJB {
@@ -88,7 +87,7 @@ bool AnimationDecoder::decode(AnimationDecoderCallback *callback) {
callback->onFrame(frameNo, _surface);
}
} else {
- debug(_("Unsupported record type %02X."), type);
+ debug("Unsupported record type %02X.", type);
file.seek(subLength - 6, SEEK_CUR);
}
diff --git a/engines/mutationofjb/commands/callmacrocommand.cpp b/engines/mutationofjb/commands/callmacrocommand.cpp
index 01470f2..c2ed50f 100644
--- a/engines/mutationofjb/commands/callmacrocommand.cpp
+++ b/engines/mutationofjb/commands/callmacrocommand.cpp
@@ -23,7 +23,6 @@
#include "mutationofjb/commands/callmacrocommand.h"
#include "mutationofjb/script.h"
#include "mutationofjb/game.h"
-#include "common/translation.h"
/** @file
* "_" <name>
@@ -45,7 +44,7 @@ bool CallMacroCommandParser::parse(const Common::String &line, ScriptParseContex
void CallMacroCommandParser::transition(ScriptParseContext &, Command *oldCommand, Command *newCommand, CommandParser *) {
if (!oldCommand || !newCommand) {
- warning(_("Unexpected empty command in transition"));
+ warning("Unexpected empty command in transition");
return;
}
diff --git a/engines/mutationofjb/commands/changecommand.cpp b/engines/mutationofjb/commands/changecommand.cpp
index e3c8a99..73c5357 100644
--- a/engines/mutationofjb/commands/changecommand.cpp
+++ b/engines/mutationofjb/commands/changecommand.cpp
@@ -23,7 +23,6 @@
#include "mutationofjb/commands/changecommand.h"
#include "mutationofjb/script.h"
#include "mutationofjb/gamedata.h"
-#include "common/translation.h"
/** @file
* "CHANGE" <entity> " " <register> " " <sceneId> " " <entityId> " " <value>
diff --git a/engines/mutationofjb/commands/conditionalcommand.cpp b/engines/mutationofjb/commands/conditionalcommand.cpp
index 2a6b36a..56cc2bf 100644
--- a/engines/mutationofjb/commands/conditionalcommand.cpp
+++ b/engines/mutationofjb/commands/conditionalcommand.cpp
@@ -23,13 +23,12 @@
#include "mutationofjb/commands/conditionalcommand.h"
#include "mutationofjb/script.h"
#include "common/scummsys.h"
-#include "common/translation.h"
namespace MutationOfJB {
void ConditionalCommandParser::transition(ScriptParseContext &parseContext, Command *oldCommand, Command *newCommand, CommandParser *) {
if (!oldCommand || !newCommand) {
- warning(_("Unexpected empty command in transition"));
+ warning("Unexpected empty command in transition");
return;
}
diff --git a/engines/mutationofjb/commands/endblockcommand.cpp b/engines/mutationofjb/commands/endblockcommand.cpp
index 8ad11f8..ae8ad91 100644
--- a/engines/mutationofjb/commands/endblockcommand.cpp
+++ b/engines/mutationofjb/commands/endblockcommand.cpp
@@ -25,7 +25,6 @@
#include "mutationofjb/commands/conditionalcommand.h"
#include "common/str.h"
#include "common/debug.h"
-#include "common/translation.h"
/** @file
* <look> | <walk> | <talk> | <pickup> | <use> | <else> | <macro> | <extra> | <endRandom>
@@ -171,7 +170,7 @@ void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *ol
if (!parseCtx._macros.contains(it->_name)) {
parseCtx._macros[it->_name] = newCommand;
} else {
- warning(_("Macro '%s' already exists"), it->_name.c_str());
+ warning("Macro '%s' already exists", it->_name.c_str());
}
it = _foundMacros.erase(it);
}
@@ -188,7 +187,7 @@ void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *ol
if (!parseCtx._startups.contains(it->_id)) {
parseCtx._startups[it->_id] = newCommand;
} else {
- warning(_("Startup %u already exists"), (unsigned int) it->_id);
+ warning("Startup %u already exists", (unsigned int) it->_id);
}
it = _foundStartups.erase(it);
}
@@ -205,7 +204,7 @@ void EndBlockCommandParser::transition(ScriptParseContext &parseCtx, Command *ol
if (!parseCtx._extras.contains(it->_name)) {
parseCtx._extras[it->_name] = newCommand;
} else {
- warning(_("Extra '%s' already exists"), it->_name.c_str());
+ warning("Extra '%s' already exists", it->_name.c_str());
}
it = _foundExtras.erase(it);
}
diff --git a/engines/mutationofjb/commands/ifcommand.cpp b/engines/mutationofjb/commands/ifcommand.cpp
index 9c43588..47e06f3 100644
--- a/engines/mutationofjb/commands/ifcommand.cpp
+++ b/engines/mutationofjb/commands/ifcommand.cpp
@@ -24,7 +24,6 @@
#include "mutationofjb/gamedata.h"
#include "mutationofjb/script.h"
#include "common/str.h"
-#include "common/translation.h"
/** @file
* "IF" <tag> <sceneId> <objectId> <value> ["!"]
diff --git a/engines/mutationofjb/commands/ifitemcommand.cpp b/engines/mutationofjb/commands/ifitemcommand.cpp
index ccbf09e..9695172 100644
--- a/engines/mutationofjb/commands/ifitemcommand.cpp
+++ b/engines/mutationofjb/commands/ifitemcommand.cpp
@@ -25,7 +25,6 @@
#include "mutationofjb/script.h"
#include "mutationofjb/util.h"
#include "common/str.h"
-#include "common/translation.h"
/** @file
* "IFITEM " <item> [ "!" ]
diff --git a/engines/mutationofjb/commands/ifpiggycommand.cpp b/engines/mutationofjb/commands/ifpiggycommand.cpp
index d500b4a..4df1deb 100644
--- a/engines/mutationofjb/commands/ifpiggycommand.cpp
+++ b/engines/mutationofjb/commands/ifpiggycommand.cpp
@@ -25,7 +25,6 @@
#include "mutationofjb/script.h"
#include "mutationofjb/util.h"
#include "common/str.h"
-#include "common/translation.h"
/** @file
* "IFPIGGY"
diff --git a/engines/mutationofjb/commands/randomcommand.cpp b/engines/mutationofjb/commands/randomcommand.cpp
index 260fd3a..ab0f304 100644
--- a/engines/mutationofjb/commands/randomcommand.cpp
+++ b/engines/mutationofjb/commands/randomcommand.cpp
@@ -26,7 +26,6 @@
#include "mutationofjb/script.h"
#include "common/debug.h"
#include "common/random.h"
-#include "common/translation.h"
/** @file
* "RANDOM " <numChoices>
@@ -49,13 +48,13 @@ bool RandomCommandParser::parse(const Common::String &line, ScriptParseContext &
int numChoices = atoi(line.c_str() + 7);
if (parseCtx._pendingRandomCommand) {
// Nested RANDOM commands are unused and not properly supported by the original game.
- warning(_("Ignoring nested RANDOM command."));
+ warning("Ignoring nested RANDOM command.");
} else if (numChoices >= 1) {
RandomCommand *randomCommand = new RandomCommand(static_cast<uint>(numChoices));
parseCtx._pendingRandomCommand = randomCommand;
command = randomCommand;
} else {
- warning(_("Ignoring malformed RANDOM command with %d choices."), numChoices);
+ warning("Ignoring malformed RANDOM command with %d choices.", numChoices);
}
return true;
@@ -68,7 +67,7 @@ bool RandomBlockStartParser::parse(const Common::String &line, ScriptParseContex
}
if (!parseCtx._pendingRandomCommand) {
- warning(_("Unexpected start of RANDOM block"));
+ warning("Unexpected start of RANDOM block");
}
return true;
diff --git a/engines/mutationofjb/commands/seqcommand.cpp b/engines/mutationofjb/commands/seqcommand.cpp
index 4836d03..6356986 100644
--- a/engines/mutationofjb/commands/seqcommand.cpp
+++ b/engines/mutationofjb/commands/seqcommand.cpp
@@ -21,13 +21,14 @@
*/
#include "mutationofjb/commands/seqcommand.h"
-#include "common/translation.h"
+
+#include "common/textconsole.h"
namespace MutationOfJB {
void SeqCommandParser::transition(ScriptParseContext &, Command *oldCommand, Command *newCommand, CommandParser *) {
if (!oldCommand || !newCommand) {
- warning(_("Unexpected empty command in transition"));
+ warning("Unexpected empty command in transition");
return;
}
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index f7b074a..b5b49cd 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -32,7 +32,6 @@
#include "mutationofjb/commands/callmacrocommand.h"
#include "mutationofjb/commands/randomcommand.h"
#include "common/debug-channels.h"
-#include "common/translation.h"
#include "common/scummsys.h"
namespace MutationOfJB {
@@ -84,7 +83,7 @@ bool Console::cmd_showallcommands(int argc, const char **argv) {
}
}
} else {
- debugPrintf(_("showallcommands <G|L>\n"));
+ debugPrintf("showallcommands <G|L>\n");
}
return true;
@@ -98,21 +97,21 @@ bool Console::cmd_listsections(int argc, const char **argv) {
const char *word = nullptr;
if (strcmp(argv[2], "L") == 0) {
action = ActionInfo::Look;
- word = _("Look");
+ word = "Look";
} else if (strcmp(argv[2], "W") == 0) {
action = ActionInfo::Walk;
- word = _("Walk");
+ word = "Walk";
} else if (strcmp(argv[2], "T") == 0) {
action = ActionInfo::Talk;
- word = _("Talk");
+ word = "Talk";
} else if (strcmp(argv[2], "U") == 0) {
action = ActionInfo::Use;
- word = _("Use");
+ word = "Use";
} else if (strcmp(argv[2], "P") == 0) {
action = ActionInfo::PickUp;
- word = _("Pick up");
+ word = "Pick up";
} else {
- debugPrintf(_("Choose 'L' (look), 'W' (walk), 'T' (talk), 'U' (use) or 'P' (pick up).\n"));
+ debugPrintf("Choose 'L' (look), 'W' (walk), 'T' (talk), 'U' (use) or 'P' (pick up).\n");
}
if (word) {
const ActionInfos &actionInfos = script->getActionInfos(action);
@@ -127,7 +126,7 @@ bool Console::cmd_listsections(int argc, const char **argv) {
}
}
} else {
- debugPrintf(_("listsections <G|L> <L|W|T|U|P>\n"));
+ debugPrintf("listsections <G|L> <L|W|T|U|P>\n");
}
return true;
}
@@ -187,7 +186,7 @@ bool Console::cmd_showsection(int argc, const char **argv) {
} else if (strcmp(argv[2], "P") == 0) {
action = ActionInfo::PickUp;
} else {
- debugPrintf(_("Choose 'L' (look), 'W' (walk), 'T' (talk), 'U' (use) or 'P' (pick up).\n"));
+ debugPrintf("Choose 'L' (look), 'W' (walk), 'T' (talk), 'U' (use) or 'P' (pick up).\n");
correctAction = false;
}
@@ -212,7 +211,7 @@ bool Console::cmd_showsection(int argc, const char **argv) {
}
}
} else {
- debugPrintf(_("showsection <G|L> <L|W|T|U|P> <sectionname>\n"));
+ debugPrintf("showsection <G|L> <L|W|T|U|P> <sectionname>\n");
}
return true;
@@ -228,7 +227,7 @@ bool Console::cmd_listmacros(int argc, const char **argv) {
}
}
} else {
- debugPrintf(_("listmacros <G|L>\n"));
+ debugPrintf("listmacros <G|L>\n");
}
return true;
@@ -243,7 +242,7 @@ bool Console::cmd_showmacro(int argc, const char **argv) {
script = _vm->getGame().getLocalScript();
}
if (!script) {
- debugPrintf(_("Choose 'G' (global) or 'L' (local) script.\n"));
+ debugPrintf("Choose 'G' (global) or 'L' (local) script.\n");
} else {
const Macros ¯os = script->getMacros();
Macros::const_iterator itMacro = macros.find(argv[2]);
@@ -256,7 +255,7 @@ bool Console::cmd_showmacro(int argc, const char **argv) {
}
}
} else {
- debugPrintf(_("showmacro <G|L> <macroname>\n"));
+ debugPrintf("showmacro <G|L> <macroname>\n");
}
return true;
@@ -272,7 +271,7 @@ bool Console::cmd_liststartups(int argc, const char **argv) {
}
}
} else {
- debugPrintf(_("liststartups <G|L>\n"));
+ debugPrintf("liststartups <G|L>\n");
}
return true;
@@ -293,7 +292,7 @@ bool Console::cmd_showstartup(int argc, const char **argv) {
}
}
} else {
- debugPrintf(_("showstartup <G|L> <startupid>\n"));
+ debugPrintf("showstartup <G|L> <startupid>\n");
}
return true;
@@ -306,7 +305,7 @@ bool Console::cmd_changescene(int argc, const char **argv) {
_vm->getGame().changeScene(sceneId, partB);
} else {
- debugPrintf(_("changescene <scenename>\n"));
+ debugPrintf("changescene <scenename>\n");
}
return true;
@@ -327,10 +326,10 @@ bool Console::cmd_dumpsceneinfo(int argc, const char **argv) {
debugPrintf("PalRotLast: %u\n", (unsigned int) scene->_palRotLast);
debugPrintf("PalRotDelay: %u\n", (unsigned int) scene->_palRotDelay);
} else {
- debugPrintf(_("Scene %u not found.\n"), (unsigned int) sceneId);
+ debugPrintf("Scene %u not found.\n", (unsigned int) sceneId);
}
} else {
- debugPrintf(_("dumpsceneinfo <sceneid>\n"));
+ debugPrintf("dumpsceneinfo <sceneid>\n");
}
return true;
@@ -357,13 +356,13 @@ bool Console::cmd_dumpdoorinfo(int argc, const char **argv) {
debugPrintf("WalkToY: %u\n", (unsigned int) door->_walkToY);
debugPrintf("SP: %u\n", (unsigned int) door->_SP);
} else {
- debugPrintf(_("Door %u not found.\n"), (unsigned int) doorId);
+ debugPrintf("Door %u not found.\n", (unsigned int) doorId);
}
} else {
- debugPrintf(_("Scene %u not found.\n"), (unsigned int) sceneId);
+ debugPrintf("Scene %u not found.\n", (unsigned int) sceneId);
}
} else {
- debugPrintf(_("dumpdoorinfo <sceneid> <doorid>\n"));
+ debugPrintf("dumpdoorinfo <sceneid> <doorid>\n");
}
return true;
@@ -392,13 +391,13 @@ bool Console::cmd_dumpobjectinfo(int argc, const char **argv) {
debugPrintf("WY: %u\n", (unsigned int) object->_roomFrameMSB);
debugPrintf("SP: %u\n", (unsigned int) object->_SP);
} else {
- debugPrintf(_("Object %u not found.\n"), (unsigned int) objectId);
+ debugPrintf("Object %u not found.\n", (unsigned int) objectId);
}
} else {
- debugPrintf(_("Scene %u not found.\n"), (unsigned int) sceneId);
+ debugPrintf("Scene %u not found.\n", (unsigned int) sceneId);
}
} else {
- debugPrintf(_("dumpobjectinfo <sceneid> <objectid>\n"));
+ debugPrintf("dumpobjectinfo <sceneid> <objectid>\n");
}
return true;
@@ -423,13 +422,13 @@ bool Console::cmd_dumpstaticinfo(int argc, const char **argv) {
debugPrintf("WalkToY: %u\n", (unsigned int) stat->_walkToX);
debugPrintf("WalkToFrame: %u\n", (unsigned int) stat->_walkToFrame);
} else {
- debugPrintf(_("Static %u not found.\n"), (unsigned int) staticId);
+ debugPrintf("Static %u not found.\n", (unsigned int) staticId);
}
} else {
- debugPrintf(_("Scene %u not found.\n"), (unsigned int) sceneId);
+ debugPrintf("Scene %u not found.\n", (unsigned int) sceneId);
}
} else {
- debugPrintf(_("dumpstaticinfo <sceneid> <staticid>\n"));
+ debugPrintf("dumpstaticinfo <sceneid> <staticid>\n");
}
return true;
@@ -443,7 +442,7 @@ Script *Console::getScriptFromArg(const char *arg) {
script = _vm->getGame().getLocalScript();
}
if (!script) {
- debugPrintf(_("Choose 'G' (global) or 'L' (local) script.\n"));
+ debugPrintf("Choose 'G' (global) or 'L' (local) script.\n");
}
return script;
diff --git a/engines/mutationofjb/game.cpp b/engines/mutationofjb/game.cpp
index 2843ad9..27def7d 100644
--- a/engines/mutationofjb/game.cpp
+++ b/engines/mutationofjb/game.cpp
@@ -32,7 +32,6 @@
#include "mutationofjb/util.h"
#include "common/str.h"
-#include "common/translation.h"
#include "common/util.h"
namespace MutationOfJB {
@@ -232,7 +231,7 @@ uint8 Game::colorFromString(const char *colorStr) {
return static_cast<uint8>(atoi(colorStr + 1));
}
- warning(_("Color not found"));
+ warning("Color not found");
return 0x00;
}
diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp
index d91c0fb..fc006dc 100644
--- a/engines/mutationofjb/gamedata.cpp
+++ b/engines/mutationofjb/gamedata.cpp
@@ -23,7 +23,6 @@
#include "mutationofjb/gamedata.h"
#include "common/stream.h"
#include "common/util.h"
-#include "common/translation.h"
namespace MutationOfJB {
@@ -147,7 +146,7 @@ bool Scene::loadFromStream(Common::ReadStream &stream) {
Door *Scene::getDoor(uint8 doorId) {
if (doorId == 0 || doorId > _noDoors) {
- warning(_("Door %d does not exist"), doorId);
+ warning("Door %d does not exist", doorId);
return nullptr;
}
@@ -156,7 +155,7 @@ Door *Scene::getDoor(uint8 doorId) {
Object *Scene::getObject(uint8 objectId, bool ignoreNo) {
if (objectId == 0 || objectId > getNoObjects(ignoreNo)) {
- warning(_("Object %d does not exist"), objectId);
+ warning("Object %d does not exist", objectId);
return nullptr;
}
@@ -165,7 +164,7 @@ Object *Scene::getObject(uint8 objectId, bool ignoreNo) {
Static *Scene::getStatic(uint8 staticId, bool ignoreNo) {
if (staticId == 0 || staticId > (!ignoreNo ? MIN(_noStatics, (uint8) ARRAYSIZE(_statics)) : ARRAYSIZE(_statics))) {
- warning(_("Static %d does not exist"), staticId);
+ warning("Static %d does not exist", staticId);
return nullptr;
}
@@ -252,7 +251,7 @@ GameData::GameData()
Scene *GameData::getScene(uint8 sceneId) {
if (sceneId == 0 || sceneId > ARRAYSIZE(_scenes)) {
- warning(_("Scene %d does not exist"), sceneId);
+ warning("Scene %d does not exist", sceneId);
return nullptr;
}
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
index a396a64..783edae 100644
--- a/engines/mutationofjb/room.cpp
+++ b/engines/mutationofjb/room.cpp
@@ -30,7 +30,6 @@
#include "common/rect.h"
#include "common/str.h"
-#include "common/translation.h"
#include "graphics/screen.h"
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index 01aef2c..7538017 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -26,7 +26,6 @@
#include "common/hash-str.h"
#include "common/stream.h"
#include "common/debug.h"
-#include "common/translation.h"
#include "mutationofjb/commands/command.h"
#include "mutationofjb/commands/ifcommand.h"
#include "mutationofjb/commands/ifitemcommand.h"
@@ -152,7 +151,7 @@ Command::ExecuteResult ScriptExecutionContext::runActiveCommand() {
Command::ExecuteResult ScriptExecutionContext::startCommand(Command *cmd) {
if (_activeCommand) {
- warning(_("Trying to start command while another one is running."));
+ warning("Trying to start command while another one is running.");
return Command::Finished;
}
getGameData()._color = WHITE; // The original game resets the color to WHITE beforing running script sections.
diff --git a/engines/mutationofjb/tasks/conversationtask.cpp b/engines/mutationofjb/tasks/conversationtask.cpp
index 3b1dcc5..6e5d020 100644
--- a/engines/mutationofjb/tasks/conversationtask.cpp
+++ b/engines/mutationofjb/tasks/conversationtask.cpp
@@ -33,8 +33,6 @@
#include "mutationofjb/util.h"
#include "mutationofjb/widgets/conversationwidget.h"
-#include "common/translation.h"
-
namespace MutationOfJB {
void ConversationTask::start() {
@@ -238,7 +236,7 @@ void ConversationTask::startExtra() {
_innerExecCtx = nullptr;
}
} else {
- warning(_("Extra '%s' not found"), line->_extra.c_str());
+ warning("Extra '%s' not found", line->_extra.c_str());
delete _innerExecCtx;
_innerExecCtx = nullptr;
}
diff --git a/engines/mutationofjb/tasks/taskmanager.cpp b/engines/mutationofjb/tasks/taskmanager.cpp
index a6d4dc1..6d860d4 100644
--- a/engines/mutationofjb/tasks/taskmanager.cpp
+++ b/engines/mutationofjb/tasks/taskmanager.cpp
@@ -24,8 +24,6 @@
#include "mutationofjb/tasks/task.h"
-#include "common/translation.h"
-
namespace MutationOfJB {
void TaskManager::startTask(const TaskPtr &task) {
@@ -37,7 +35,7 @@ void TaskManager::startTask(const TaskPtr &task) {
void TaskManager::stopTask(const TaskPtr &task) {
TaskPtrs::iterator it = Common::find(_tasks.begin(), _tasks.end(), task);
if (it == _tasks.end()) {
- warning(_("Task is not registered in TaskManager."));
+ warning("Task is not registered in TaskManager");
return;
}
Commit: cf878d87776f779f2a13669689361903fbe438cb
https://github.com/scummvm/scummvm/commit/cf878d87776f779f2a13669689361903fbe438cb
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Change old-style C casts to static_cast.
Changed paths:
engines/mutationofjb/commands/changecommand.cpp
engines/mutationofjb/commands/talkcommand.cpp
engines/mutationofjb/debug.cpp
engines/mutationofjb/gamedata.cpp
engines/mutationofjb/tasks/conversationtask.cpp
engines/mutationofjb/widgets/inventorywidget.cpp
diff --git a/engines/mutationofjb/commands/changecommand.cpp b/engines/mutationofjb/commands/changecommand.cpp
index 73c5357..9051e8e 100644
--- a/engines/mutationofjb/commands/changecommand.cpp
+++ b/engines/mutationofjb/commands/changecommand.cpp
@@ -317,13 +317,13 @@ Common::String ChangeCommand::getValueAsString() const {
case PF:
case PL:
case PD:
- return Common::String::format("%d", (int)_value._byteVal);
+ return Common::String::format("%d", static_cast<int>(_value._byteVal));
case SX:
case SY:
case XX:
case XL:
case WX:
- return Common::String::format("%d", (int)_value._wordVal);
+ return Common::String::format("%d", static_cast<int>(_value._wordVal));
default:
return "(unknown)";
}
diff --git a/engines/mutationofjb/commands/talkcommand.cpp b/engines/mutationofjb/commands/talkcommand.cpp
index 9857f38..aa10e38 100644
--- a/engines/mutationofjb/commands/talkcommand.cpp
+++ b/engines/mutationofjb/commands/talkcommand.cpp
@@ -82,7 +82,7 @@ Command::ExecuteResult TalkCommand::execute(ScriptExecutionContext &scriptExeCtx
Common::String TalkCommand::debugString() const {
const char *modes[] = {"NORMAL", "RAY_AND_BUTTLEG", "CARNIVAL_TICKET_SELLER"};
- return Common::String::format("TALK %s", modes[(int) _mode]);
+ return Common::String::format("TALK %s", modes[static_cast<int>(_mode)]);
}
}
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index b5b49cd..69804fd 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -282,7 +282,7 @@ bool Console::cmd_showstartup(int argc, const char **argv) {
Script *const script = getScriptFromArg(argv[1]);
if (script) {
const Startups &startups = script->getStartups();
- Startups::const_iterator itMacro = startups.find((uint8) atoi(argv[2]));
+ Startups::const_iterator itMacro = startups.find(static_cast<uint8>(atoi(argv[2])));
if (itMacro != startups.end()) {
if (itMacro->_value) {
showCommands(itMacro->_value);
diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp
index fc006dc..2026c3e 100644
--- a/engines/mutationofjb/gamedata.cpp
+++ b/engines/mutationofjb/gamedata.cpp
@@ -33,7 +33,7 @@ static bool readString(Common::ReadStream &stream, char *str) {
uint8 len = stream.readByte();
stream.read(buf, MAX_ENTITY_NAME_LENGTH);
- len = MIN(len, (uint8) MAX_ENTITY_NAME_LENGTH);
+ len = MIN(len, static_cast<uint8>(MAX_ENTITY_NAME_LENGTH));
memcpy(str, buf, len);
return true;
@@ -110,19 +110,19 @@ bool Scene::loadFromStream(Common::ReadStream &stream) {
_delay = stream.readByte();
_noDoors = stream.readByte();
- _noDoors = MIN(_noDoors, (uint8) ARRAYSIZE(_doors));
+ _noDoors = MIN(_noDoors, static_cast<uint8>(ARRAYSIZE(_doors)));
for (i = 0; i < ARRAYSIZE(_doors); ++i) {
_doors[i].loadFromStream(stream);
}
_noObjects = stream.readByte();
- _noObjects = MIN(_noObjects, (uint8) ARRAYSIZE(_objects));
+ _noObjects = MIN(_noObjects, static_cast<uint8>(ARRAYSIZE(_objects)));
for (i = 0; i < ARRAYSIZE(_objects); ++i) {
_objects[i].loadFromStream(stream);
}
_noStatics = stream.readByte();
- _noStatics = MIN(_noStatics, (uint8) ARRAYSIZE(_statics));
+ _noStatics = MIN(_noStatics, static_cast<uint8>(ARRAYSIZE(_statics)));
for (i = 0; i < ARRAYSIZE(_statics); ++i) {
_statics[i].loadFromStream(stream);
}
@@ -163,7 +163,7 @@ Object *Scene::getObject(uint8 objectId, bool ignoreNo) {
}
Static *Scene::getStatic(uint8 staticId, bool ignoreNo) {
- if (staticId == 0 || staticId > (!ignoreNo ? MIN(_noStatics, (uint8) ARRAYSIZE(_statics)) : ARRAYSIZE(_statics))) {
+ if (staticId == 0 || staticId > (!ignoreNo ? MIN(_noStatics, static_cast<uint8>(ARRAYSIZE(_statics))) : ARRAYSIZE(_statics))) {
warning("Static %d does not exist", staticId);
return nullptr;
}
@@ -172,15 +172,15 @@ Static *Scene::getStatic(uint8 staticId, bool ignoreNo) {
}
uint8 Scene::getNoDoors(bool ignoreNo) const {
- return (!ignoreNo ? MIN(_noDoors, (uint8) ARRAYSIZE(_doors)) : ARRAYSIZE(_doors));
+ return (!ignoreNo ? MIN(_noDoors, static_cast<uint8>(ARRAYSIZE(_doors))) : ARRAYSIZE(_doors));
}
uint8 Scene::getNoObjects(bool ignoreNo) const {
- return (!ignoreNo ? MIN(_noObjects, (uint8) ARRAYSIZE(_objects)) : ARRAYSIZE(_objects));
+ return (!ignoreNo ? MIN(_noObjects, static_cast<uint8>(ARRAYSIZE(_objects))) : ARRAYSIZE(_objects));
}
uint8 Scene::getNoStatics(bool ignoreNo) const {
- return (!ignoreNo ? MIN(_noStatics, (uint8) ARRAYSIZE(_statics)) : ARRAYSIZE(_statics));
+ return (!ignoreNo ? MIN(_noStatics, static_cast<uint8>(ARRAYSIZE(_statics))) : ARRAYSIZE(_statics));
}
Door *Scene::findDoor(int16 x, int16 y, int *index) {
diff --git a/engines/mutationofjb/tasks/conversationtask.cpp b/engines/mutationofjb/tasks/conversationtask.cpp
index 6e5d020..5b0f0f4 100644
--- a/engines/mutationofjb/tasks/conversationtask.cpp
+++ b/engines/mutationofjb/tasks/conversationtask.cpp
@@ -132,7 +132,7 @@ void ConversationTask::showChoicesOrPick() {
for (ConversationInfo::ItemGroup::size_type i = 0; i < currentGroup.size(); ++i) {
const ConversationInfo::Item &item = currentGroup[i];
- if (scene->isConvItemExhausted(_convInfo._context, (uint8) i + 1, (uint8) _currentGroupIndex + 1)) {
+ if (scene->isConvItemExhausted(_convInfo._context, static_cast<uint8>(i + 1), static_cast<uint8>(_currentGroupIndex + 1))) {
continue;
}
const uint8 toSay = item._question;
@@ -160,7 +160,7 @@ void ConversationTask::showChoicesOrPick() {
const ConversationInfo::Item &item = currentGroup[itemsWithValidQuestions[i]];
const ConversationLineList::Line *const line = toSayList.getLine(item._question);
const Common::String widgetText = toUpperCP895(line->_speeches[0]._text);
- widget.setChoice((int) i, widgetText, itemsWithValidQuestions[i]);
+ widget.setChoice(static_cast<int>(i), widgetText, itemsWithValidQuestions[i]);
}
_substate = IDLE;
_currentItem = nullptr;
diff --git a/engines/mutationofjb/widgets/inventorywidget.cpp b/engines/mutationofjb/widgets/inventorywidget.cpp
index a26bab6..46bfab9 100644
--- a/engines/mutationofjb/widgets/inventorywidget.cpp
+++ b/engines/mutationofjb/widgets/inventorywidget.cpp
@@ -67,7 +67,7 @@ void InventoryWidget::draw(Graphics::ManagedSurface &surface) {
Inventory &inventory = _gui.getGame().getGameData().getInventory();
const Inventory::Items &items = inventory.getItems();
surface.fillRect(_area, 0x00);
- for (int i = 0; i < MIN((int) items.size(), (int) Inventory::VISIBLE_ITEMS); ++i) {
+ for (Inventory::Items::size_type i = 0; i < MIN<Inventory::Items::size_type>(items.size(), Inventory::VISIBLE_ITEMS); ++i) {
drawInventoryItem(surface, items[i], i);
}
}
Commit: 696b61c14626495fd01ffbacc309a2f8f5db4069
https://github.com/scummvm/scummvm/commit/696b61c14626495fd01ffbacc309a2f8f5db4069
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Move method comments to headers.
Changed paths:
engines/mutationofjb/mutationofjb.cpp
engines/mutationofjb/mutationofjb.h
engines/mutationofjb/tasks/objectanimationtask.cpp
engines/mutationofjb/tasks/objectanimationtask.h
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index 1d88269..8841a30 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -156,14 +156,6 @@ void MutationOfJBEngine::handleNormalScene(const Common::Event &event) {
_game->getGui().handleEvent(event);
}
-/*
- Special handling for map scenes.
-
- Bitmaps define mouse clickable areas.
- Statics are used to start actions.
- Objects are used for showing labels.
-
-*/
void MutationOfJBEngine::handleMapScene(const Common::Event &event) {
Scene *const scene = _game->getGameData().getCurrentScene();
diff --git a/engines/mutationofjb/mutationofjb.h b/engines/mutationofjb/mutationofjb.h
index 21f8094..3803254 100644
--- a/engines/mutationofjb/mutationofjb.h
+++ b/engines/mutationofjb/mutationofjb.h
@@ -61,7 +61,27 @@ private:
void setupCursor();
void updateCursorHitTest(int16 x, int16 y);
void updateCursorPalette();
+
+ /**
+ * Handling for normal (non-map) scenes.
+ *
+ * Statics and doors define mouse clickable areas.
+ * Statics are used to start actions.
+ * Doors are used to transition between scenes.
+ *
+ * @param event ScummVM event.
+ */
void handleNormalScene(const Common::Event &event);
+
+ /**
+ * Special handling for map scenes.
+ *
+ * Bitmaps define mouse clickable areas.
+ * Statics are used to start actions.
+ * Objects are used for showing labels.
+ *
+ * @param event ScummVM event.
+ */
void handleMapScene(const Common::Event &event);
Console *_console;
diff --git a/engines/mutationofjb/tasks/objectanimationtask.cpp b/engines/mutationofjb/tasks/objectanimationtask.cpp
index 2b4bf80..eab3d75 100644
--- a/engines/mutationofjb/tasks/objectanimationtask.cpp
+++ b/engines/mutationofjb/tasks/objectanimationtask.cpp
@@ -48,17 +48,6 @@ void ObjectAnimationTask::update() {
}
}
-/**
- * Advances every object animation in the current scene to the next frame.
- *
- * Normally the animation restarts after the last object frame. However, some animations have random
- * elements to them. If _randomFrame is set, the animation restarts when _randomFrame is reached.
- * Additionally, there is a chance with each frame until _randomFrame that the animation may jump
- * straight to _randomFrame and continue until the last frame, then wrap around to the first frame.
- *
- * Randomness is used to introduce variety - e.g. in the starting scene a perched bird occasionally
- * spreads its wings.
- */
void ObjectAnimationTask::updateObjects() {
Scene *const scene = getTaskManager()->getGame().getGameData().getCurrentScene();
if (!scene) {
@@ -102,14 +91,6 @@ void ObjectAnimationTask::updateObjects() {
}
}
-/**
- * Nasty, hacky stuff the original game does to make some complex animations
- * in the Carnival and Tavern Earthquake scenes possible.
- *
- * @param object Object to process.
- * @return Whether to draw the object. It's important to respect this, otherwise
- * some of the hardcoded animations would suffer from graphical glitches.
- */
bool ObjectAnimationTask::handleHardcodedAnimation(Object *const object) {
GameData &gameData = getTaskManager()->getGame().getGameData();
Scene *const scene = gameData.getCurrentScene();
diff --git a/engines/mutationofjb/tasks/objectanimationtask.h b/engines/mutationofjb/tasks/objectanimationtask.h
index 320868f..9e09139 100644
--- a/engines/mutationofjb/tasks/objectanimationtask.h
+++ b/engines/mutationofjb/tasks/objectanimationtask.h
@@ -38,7 +38,27 @@ public:
virtual void start() override;
virtual void update() override;
+ /**
+ * Advances every object animation in the current scene to the next frame.
+ *
+ * Normally the animation restarts after the last object frame. However, some animations have random
+ * elements to them. If _randomFrame is set, the animation restarts when _randomFrame is reached.
+ * Additionally, there is a chance with each frame until _randomFrame that the animation may jump
+ * straight to _randomFrame and continue until the last frame, then wrap around to the first frame.
+ *
+ * Randomness is used to introduce variety - e.g. in the starting scene a perched bird occasionally
+ * spreads its wings.
+ */
void updateObjects();
+
+ /**
+ * Nasty, hacky stuff the original game does to make some complex animations
+ * in the Carnival and Tavern Earthquake scenes possible.
+ *
+ * @param object Object to process.
+ * @return Whether to draw the object. It's important to respect this, otherwise
+ * some of the hardcoded animations would suffer from graphical glitches.
+ */
bool handleHardcodedAnimation(Object *const object);
private:
Commit: 0e90d6eae39363687a447e39d3ba0a4994f1800f
https://github.com/scummvm/scummvm/commit/0e90d6eae39363687a447e39d3ba0a4994f1800f
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Use advanced detector.
Changed paths:
common/language.cpp
common/language.h
engines/mutationofjb/detection.cpp
engines/mutationofjb/mutationofjb.cpp
diff --git a/common/language.cpp b/common/language.cpp
index 2112182..0d4fbee 100644
--- a/common/language.cpp
+++ b/common/language.cpp
@@ -51,6 +51,7 @@ const LanguageDescription g_languages[] = {
{ "pl", "pl_PL", "Polish", PL_POL },
{ "br", "pt_BR", "Portuguese", PT_BRA },
{ "ru", "ru_RU", "Russian", RU_RUS },
+ { "sk", "sk_SK", "Slovak", SK_SVK },
{ "es", "es_ES", "Spanish", ES_ESP },
{ "se", "sv_SE", "Swedish", SE_SWE },
{ "uk", "uk_UA", "Ukrainian", UA_UKR },
diff --git a/common/language.h b/common/language.h
index 752914b..3d4ba3a 100644
--- a/common/language.h
+++ b/common/language.h
@@ -56,6 +56,7 @@ enum Language {
PL_POL,
PT_BRA,
RU_RUS,
+ SK_SVK,
ES_ESP,
SE_SWE,
UA_UKR,
diff --git a/engines/mutationofjb/detection.cpp b/engines/mutationofjb/detection.cpp
index 5e80760..33664c1 100644
--- a/engines/mutationofjb/detection.cpp
+++ b/engines/mutationofjb/detection.cpp
@@ -24,15 +24,71 @@
#include "common/config-manager.h"
-#include "engines/metaengine.h"
+#include "engines/advancedDetector.h"
-static const PlainGameDescriptor mutationofjb_setting[] = {
+static const PlainGameDescriptor mutationofjbGames[] = {
{"mutationofjb", "Mutation of J.B."},
- {0, 0}
+ {nullptr, nullptr}
};
-class MutationOfJBMetaEngine : public MetaEngine {
+static const ADGameDescription mutationofjbDescriptions[] = {
+ {
+ "mutationofjb",
+ "",
+ {
+ {"jb.ex_", 0, "934164b09c72fa7167811f448ee0a426", 150048},
+ {"startup.dat", 0, nullptr, -1},
+ {"startupb.dat", 0, nullptr, -1},
+ {"global.atn", 0, nullptr, -1},
+ {"piggy.apk", 0, nullptr, -1},
+ {"foogl.apk", 0, nullptr, -1},
+ {"tosay.ger", 0, nullptr, -1},
+ {"response.ger", 0, nullptr, -1},
+ {"font1.aft", 0, nullptr, -1},
+ {"sysfnt.aft", 0, nullptr, -1},
+ {nullptr, 0, nullptr, 0}
+ },
+ Common::SK_SVK,
+ Common::kPlatformDOS,
+ ADGF_CD,
+ GUIO0()
+ },
+ {
+ "mutationofjb",
+ "",
+ {
+ {"jb.ex_", 0, "8833f22f1763d05eeb909e8626cdec7b", 150800},
+ {"startup.dat", 0, nullptr, -1},
+ {"startupb.dat", 0, nullptr, -1},
+ {"global.atn", 0, nullptr, -1},
+ {"piggy.apk", 0, nullptr, -1},
+ {"foogl.apk", 0, nullptr, -1},
+ {"tosay.ger", 0, nullptr, -1},
+ {"response.ger", 0, nullptr, -1},
+ {"font1.aft", 0, nullptr, -1},
+ {"sysfnt.aft", 0, nullptr, -1},
+ {nullptr, 0, nullptr, 0}
+ },
+ Common::DE_DEU,
+ Common::kPlatformDOS,
+ ADGF_CD,
+ GUIO0()
+ },
+ AD_TABLE_END_MARKER
+};
+
+static const char *const mutationofjbDirectoryGlobs[] = {
+ "data",
+ nullptr
+};
+
+class MutationOfJBMetaEngine : public AdvancedMetaEngine {
public:
+ MutationOfJBMetaEngine() : AdvancedMetaEngine(mutationofjbDescriptions, sizeof(ADGameDescription), mutationofjbGames) {
+ _maxScanDepth = 2;
+ _directoryGlobs = mutationofjbDirectoryGlobs;
+ }
+
virtual const char *getName() const {
return "Mutation of J.B.";
}
@@ -41,67 +97,11 @@ public:
return "Mutation of J.B. (C) 1996 RIKI Computer Games";
}
- virtual PlainGameList getSupportedGames() const {
- PlainGameList games;
- const PlainGameDescriptor *g = mutationofjb_setting;
- while (g->gameId) {
- games.push_back(*g);
- g++;
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ if (desc) {
+ *engine = new MutationOfJB::MutationOfJBEngine(syst);
}
-
- return games;
- }
-
- virtual PlainGameDescriptor findGame(const char *gameid) const {
- const PlainGameDescriptor *g = mutationofjb_setting;
- while (g->gameId) {
- if (0 == scumm_stricmp(gameid, g->gameId))
- return *g;
- g++;
- }
- return PlainGameDescriptor::empty();
- }
-
- virtual DetectedGames detectGames(const Common::FSList &fslist) const {
- DetectedGames detectedGames;
-
- for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
- if (!file->isDirectory()) {
- const char *gameName = file->getName().c_str();
-
- if (0 == scumm_stricmp("startup.dat", gameName)) {
- detectedGames.push_back(DetectedGame(mutationofjb_setting[0]));
- break;
- }
- }
- }
- return detectedGames;
- }
-
- virtual Common::Error createInstance(OSystem *syst, Engine **engine) const {
- assert(syst);
- assert(engine);
-
- Common::FSList fslist;
- Common::FSNode dir(ConfMan.get("path"));
- if (!dir.getChildren(fslist, Common::FSNode::kListAll)) {
- return Common::kNoGameDataFoundError;
- }
-
- // Invoke the detector
- Common::String gameid = ConfMan.get("gameid");
- DetectedGames detectedGames = detectGames(fslist);
-
- for (uint i = 0; i < detectedGames.size(); i++) {
- if (detectedGames[i].gameId == gameid) {
- // At this point you may want to perform additional sanity checks.
- *engine = new MutationOfJB::MutationOfJBEngine(syst);
- return Common::kNoError;
- }
- }
-
- // Failed to find any game data
- return Common::kNoGameDataFoundError;
+ return desc != nullptr;
}
};
diff --git a/engines/mutationofjb/mutationofjb.cpp b/engines/mutationofjb/mutationofjb.cpp
index 8841a30..376c024 100644
--- a/engines/mutationofjb/mutationofjb.cpp
+++ b/engines/mutationofjb/mutationofjb.cpp
@@ -22,10 +22,12 @@
#include "common/scummsys.h"
+#include "common/config-manager.h"
#include "common/debug.h"
#include "common/error.h"
#include "common/system.h"
#include "common/events.h"
+#include "common/fs.h"
#include "graphics/screen.h"
#include "graphics/cursorman.h"
@@ -45,13 +47,13 @@ MutationOfJBEngine::MutationOfJBEngine(OSystem *syst)
_screen(nullptr),
_mapObjectId(0),
_cursorState(CURSOR_IDLE) {
- debug("MutationOfJBEngine::MutationOfJBEngine");
-}
-MutationOfJBEngine::~MutationOfJBEngine() {
- debug("MutationOfJBEngine::~MutationOfJBEngine");
+ const Common::FSNode gameDataDir(ConfMan.get("path"));
+ SearchMan.addSubDirectoryMatching(gameDataDir, "data");
}
+MutationOfJBEngine::~MutationOfJBEngine() {}
+
void MutationOfJBEngine::setupCursor() {
const uint8 cursor[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -237,8 +239,6 @@ void MutationOfJBEngine::updateCursorHitTest(int16 x, int16 y) {
}
Common::Error MutationOfJBEngine::run() {
- debug("MutationOfJBEngine::run");
-
initGraphics(320, 200);
_console = new Console(this);
Commit: b00395b0b976b869cb83c1181481f1ad7ba16b1e
https://github.com/scummvm/scummvm/commit/b00395b0b976b869cb83c1181481f1ad7ba16b1e
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-08-25T23:12:01+02:00
Commit Message:
MUTATIONOFJB: Fix MSVC warnings.
Changed paths:
engines/mutationofjb/debug.cpp
engines/mutationofjb/tasks/objectanimationtask.h
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index 69804fd..2a06cce 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -93,7 +93,7 @@ bool Console::cmd_listsections(int argc, const char **argv) {
if (argc == 3) {
Script *const script = getScriptFromArg(argv[1]);
if (script) {
- ActionInfo::Action action;
+ ActionInfo::Action action = ActionInfo::Look;
const char *word = nullptr;
if (strcmp(argv[2], "L") == 0) {
action = ActionInfo::Look;
@@ -171,7 +171,7 @@ bool Console::cmd_showsection(int argc, const char **argv) {
Script *const script = getScriptFromArg(argv[1]);
if (script) {
Command *command = nullptr;
- ActionInfo::Action action;
+ ActionInfo::Action action = ActionInfo::Look;
bool correctAction = true;
bool found = false;
diff --git a/engines/mutationofjb/tasks/objectanimationtask.h b/engines/mutationofjb/tasks/objectanimationtask.h
index 9e09139..45e83b3 100644
--- a/engines/mutationofjb/tasks/objectanimationtask.h
+++ b/engines/mutationofjb/tasks/objectanimationtask.h
@@ -29,7 +29,7 @@
namespace MutationOfJB {
-class Object;
+struct Object;
class ObjectAnimationTask : public Task {
public:
More information about the Scummvm-git-logs
mailing list