[Scummvm-git-logs] scummvm master -> 0c340485e01e0c18634a496d145841afb2ac2536

LubomirR lubomirr at lubomirr.eu
Fri Nov 2 23:28:28 CET 2018


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
0c340485e0 MUTATIONOFJB: Draw bitmaps.


Commit: 0c340485e01e0c18634a496d145841afb2ac2536
    https://github.com/scummvm/scummvm/commit/0c340485e01e0c18634a496d145841afb2ac2536
Author: Ľubomír Remák (lubomirr at lubomirr.eu)
Date: 2018-11-02T23:26:58+01:00

Commit Message:
MUTATIONOFJB: Draw bitmaps.

Implement RB (bitmap visibility) command.
Implement stub for FLX and FLB (play animation) commands.

Changed paths:
  A engines/mutationofjb/commands/bitmapvisibilitycommand.cpp
  A engines/mutationofjb/commands/bitmapvisibilitycommand.h
  A engines/mutationofjb/commands/playanimationcommand.cpp
  A engines/mutationofjb/commands/playanimationcommand.h
    engines/mutationofjb/animationdecoder.cpp
    engines/mutationofjb/animationdecoder.h
    engines/mutationofjb/commands/camefromcommand.cpp
    engines/mutationofjb/debug.cpp
    engines/mutationofjb/debug.h
    engines/mutationofjb/gamedata.cpp
    engines/mutationofjb/gamedata.h
    engines/mutationofjb/module.mk
    engines/mutationofjb/room.cpp
    engines/mutationofjb/room.h
    engines/mutationofjb/script.cpp


diff --git a/engines/mutationofjb/animationdecoder.cpp b/engines/mutationofjb/animationdecoder.cpp
index 43590a9..84325a9 100644
--- a/engines/mutationofjb/animationdecoder.cpp
+++ b/engines/mutationofjb/animationdecoder.cpp
@@ -27,10 +27,13 @@
 
 namespace MutationOfJB {
 
-AnimationDecoder::AnimationDecoder(const Common::String &fileName) : _fileName(fileName) {
+AnimationDecoder::AnimationDecoder(const Common::String &fileName) : _fileName(fileName), _fromFrame(-1), _toFrame(-1), _threshold(0xFF) {
 	_surface.create(IMAGE_WIDTH, IMAGE_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
+	_owningSurface = true;
 }
 
+AnimationDecoder::AnimationDecoder(const Common::String &fileName, const Graphics::Surface &outSurface) : _fileName(fileName), _surface(outSurface), _owningSurface(false), _fromFrame(-1), _toFrame(-1), _threshold(0xFF) {}
+
 bool AnimationDecoder::decode(AnimationDecoderCallback *callback) {
 	EncryptedFile file;
 	file.open(_fileName);
@@ -60,39 +63,43 @@ bool AnimationDecoder::decode(AnimationDecoderCallback *callback) {
 
 		// Subrecords.
 		if (recordId == 0xF1FA) {
-			if (subrecords == 0) {
-				if (callback) {
-					callback->onFrame(frameNo, _surface); // Empty record, frame identical to the previous one.
-				}
+			if ((_fromFrame != -1 && frameNo < _fromFrame) || (_toFrame != -1 && frameNo > _toFrame)) {
+				file.seek(length - 16, SEEK_CUR);
 			} 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);
+				if (subrecords == 0) {
+					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();
+
+						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);
+						// Makes decoding more robust, because for some reason records might have extra data at the end.
+						file.seek(filePos + subLength, SEEK_SET);
+					}
 				}
 			}
 			frameNo++;
@@ -105,6 +112,13 @@ bool AnimationDecoder::decode(AnimationDecoderCallback *callback) {
 	return true;
 }
 
+void AnimationDecoder::setPartialMode(int fromFrame, int toFrame, const Common::Rect area, uint8 threshold) {
+	_fromFrame = fromFrame;
+	_toFrame = toFrame;
+	_area = area;
+	_threshold = threshold;
+}
+
 void AnimationDecoder::loadPalette(Common::SeekableReadStream &file) {
 	uint16 packets = file.readUint16LE();
 	const uint8 skipCount = file.readByte();
@@ -165,6 +179,11 @@ void AnimationDecoder::loadDiffFrame(EncryptedFile &file, uint32) {
 
 	for (uint16 line = firstLine; line < firstLine + numLines; ++line) {
 		uint8 *imageData = reinterpret_cast<uint8 *>(_surface.getBasePtr(0, line));
+		uint16 lineOffset = 0;
+
+		// Optimization for skipping the whole line if outside of confined area.
+		const bool skipLineOutput = !_area.isEmpty() && (line < _area.top || line >= _area.bottom);
+		uint8 buf[0x80];
 
 		uint8 runs = file.readByte();
 		while (runs--) {
@@ -172,17 +191,42 @@ void AnimationDecoder::loadDiffFrame(EncryptedFile &file, uint32) {
 			uint8 num = file.readByte();
 
 			imageData += localOffset;
+			lineOffset += localOffset;
 			if (num == 0) {
 				// Ignore?
 				debug("Zero RLE number found.");
 			} else if (num < 0x80) {
-				file.read(imageData, num);
+				if (!skipLineOutput) {
+					if (_area.isEmpty() && _threshold == 0xFF) {
+						file.read(imageData, num);
+					} else {
+						file.read(buf, num);
+						for (uint16 i = 0; i < num; i++) {
+							if ((_area.isEmpty() || _area.contains(lineOffset + i, line)) && imageData[i] <= _threshold)
+								imageData[i] = buf[i];
+						}
+					}
+				} else {
+					file.skip(num);
+				}
+
 				imageData += num;
+				lineOffset += num;
 			} else {
 				const uint8 color = file.readByte();
 				const int no = 0x100 - num;
-				memset(imageData, color, no);
+				if (!skipLineOutput) {
+					if (_area.isEmpty() && _threshold == 0xFF) {
+						memset(imageData, color, no);
+					} else {
+						for (int i = 0; i < no; i++) {
+							if ((_area.isEmpty() || _area.contains(lineOffset + i, line)) && imageData[i] <= _threshold)
+								imageData[i] = color;
+						}
+					}
+				}
 				imageData += no;
+				lineOffset += no;
 			}
 
 		}
@@ -190,7 +234,8 @@ void AnimationDecoder::loadDiffFrame(EncryptedFile &file, uint32) {
 }
 
 AnimationDecoder::~AnimationDecoder() {
-	_surface.free();
+	if (_owningSurface)
+		_surface.free();
 }
 
 }
diff --git a/engines/mutationofjb/animationdecoder.h b/engines/mutationofjb/animationdecoder.h
index 050aa3b..f213440 100644
--- a/engines/mutationofjb/animationdecoder.h
+++ b/engines/mutationofjb/animationdecoder.h
@@ -23,8 +23,10 @@
 #ifndef MUTATIONOFJB_ANIMATIONDECODER_H
 #define MUTATIONOFJB_ANIMATIONDECODER_H
 
+#include "common/rect.h"
 #include "common/scummsys.h"
 #include "common/str.h"
+
 #include "graphics/surface.h"
 #include "mutationofjb/encryptedfile.h"
 
@@ -51,9 +53,20 @@ public:
 class AnimationDecoder {
 public:
 	AnimationDecoder(const Common::String &fileName);
+	AnimationDecoder(const Common::String &fileName, const Graphics::Surface &outSurface);
 	~AnimationDecoder();
 	bool decode(AnimationDecoderCallback *callback);
 
+	/**
+	 * Enables partial decoding mode.
+	 *
+	 * @param fromFrame Frame to start decoding on (inclusive).
+	 * @param toFrame Frame to end decoding on (inclusive).
+	 * @param area Output surface will be confined to this area.
+	 * @param threshold Source pixels with color index above this threshold will not be replaced.
+	 */
+	void setPartialMode(int fromFrame, int toFrame, const Common::Rect area = Common::Rect(), uint8 threshold = 0xFF);
+
 private:
 	void loadPalette(Common::SeekableReadStream &stream);
 	void loadFullFrame(EncryptedFile &file, uint32 size);
@@ -61,7 +74,12 @@ private:
 
 	Common::String _fileName;
 	Graphics::Surface _surface;
+	bool _owningSurface;
 	byte _palette[PALETTE_SIZE];
+	int _fromFrame;
+	int _toFrame;
+	Common::Rect _area;
+	uint8 _threshold;
 };
 
 }
diff --git a/engines/mutationofjb/commands/bitmapvisibilitycommand.cpp b/engines/mutationofjb/commands/bitmapvisibilitycommand.cpp
new file mode 100644
index 0000000..f123890
--- /dev/null
+++ b/engines/mutationofjb/commands/bitmapvisibilitycommand.cpp
@@ -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.
+ *
+ */
+
+#include "mutationofjb/commands/bitmapvisibilitycommand.h"
+#include "mutationofjb/gamedata.h"
+#include "mutationofjb/script.h"
+
+/** @file
+ * "RB " <sceneId> " " <bitmapId> " " <visible>
+ *
+ * Changes visibility of a bitmap in the specified scene.
+ */
+
+namespace MutationOfJB {
+
+bool BitmapVisibilityCommandParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) {
+	if (line.size() < 10 || !line.hasPrefix("RB "))
+		return false;
+
+	const uint8 sceneId = (uint8) atoi(line.c_str() + 3);
+	const uint8 bitmapId = (uint8) atoi(line.c_str() + 6);
+	const bool visible = (line[9] == '1');
+
+	command = new BitmapVisibilityCommand(sceneId, bitmapId, visible);
+	return true;
+}
+
+
+Command::ExecuteResult BitmapVisibilityCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+	scriptExecCtx.getGameData().getScene(_sceneId)->getBitmap(_bitmapId)->_isVisible = _visible;
+
+	return Finished;
+}
+
+Common::String BitmapVisibilityCommand::debugString() const {
+	return Common::String::format("SETBITMAPVIS %u %u %s", (unsigned int) _sceneId, (unsigned int) _bitmapId, _visible ? "true" : "false");
+}
+
+}
diff --git a/engines/mutationofjb/commands/bitmapvisibilitycommand.h b/engines/mutationofjb/commands/bitmapvisibilitycommand.h
new file mode 100644
index 0000000..366abd3
--- /dev/null
+++ b/engines/mutationofjb/commands/bitmapvisibilitycommand.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_BITMAPVISIBILITYCOMMAND_H
+#define MUTATIONOFJB_BITMAPVISIBILITYCOMMAND_H
+
+#include "mutationofjb/commands/seqcommand.h"
+#include "common/str.h"
+
+namespace MutationOfJB {
+
+class BitmapVisibilityCommandParser : public SeqCommandParser {
+public:
+	BitmapVisibilityCommandParser() {}
+
+	virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+};
+
+class BitmapVisibilityCommand : public SeqCommand {
+public:
+	BitmapVisibilityCommand(uint8 sceneId, uint8 bitmapId, bool visible) : _sceneId(sceneId), _bitmapId(bitmapId), _visible(visible) {}
+	const Common::String &getName() const;
+
+	virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
+	virtual Common::String debugString() const override;
+private:
+	uint8 _sceneId;
+	uint8 _bitmapId;
+	bool _visible;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/commands/camefromcommand.cpp b/engines/mutationofjb/commands/camefromcommand.cpp
index 67033b8..b4bbcc7 100644
--- a/engines/mutationofjb/commands/camefromcommand.cpp
+++ b/engines/mutationofjb/commands/camefromcommand.cpp
@@ -41,6 +41,7 @@ bool CameFromCommandParser::parse(const Common::String &line, ScriptParseContext
 	}
 
 	const uint8 sceneId = atoi(line.c_str() + 9);
+	_tags.push(0);
 	command = new CameFromCommand(sceneId);
 	return true;
 }
diff --git a/engines/mutationofjb/commands/playanimationcommand.cpp b/engines/mutationofjb/commands/playanimationcommand.cpp
new file mode 100644
index 0000000..60c6f1c
--- /dev/null
+++ b/engines/mutationofjb/commands/playanimationcommand.cpp
@@ -0,0 +1,61 @@
+/* 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/playanimationcommand.h"
+#include "mutationofjb/game.h"
+#include "mutationofjb/room.h"
+#include "mutationofjb/script.h"
+
+/** @file
+ * ( "FLB " | "FLX" ) <fromFrame> " " <toFrame>
+ *
+ * Plays the specified frames from room animation.
+ *
+ * TODO: Parse all arguments of this command.
+ * TODO: Actually play the animation instead of just showing last frame.
+ */
+
+namespace MutationOfJB {
+
+bool PlayAnimationCommandParser::parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command) {
+	if (line.size() < 11 || (!line.hasPrefix("FLB ") && !line.hasPrefix("FLX ")))
+		return false;
+
+	const uint8 fromFrame = (uint8) atoi(line.c_str() + 4);
+	const uint8 toFrame = (uint8) atoi(line.c_str() + 8);
+
+	command = new PlayAnimationCommand(fromFrame, toFrame);
+	return true;
+}
+
+
+Command::ExecuteResult PlayAnimationCommand::execute(ScriptExecutionContext &scriptExecCtx) {
+	scriptExecCtx.getGame().getRoom().drawFrames(_fromFrame - 1, _toFrame - 1);
+
+	return Finished;
+}
+
+Common::String PlayAnimationCommand::debugString() const {
+	return Common::String::format("PLAYROOMANIM %u %u", (unsigned int) _fromFrame, (unsigned int) _toFrame);
+}
+
+}
diff --git a/engines/mutationofjb/commands/playanimationcommand.h b/engines/mutationofjb/commands/playanimationcommand.h
new file mode 100644
index 0000000..da7ff25
--- /dev/null
+++ b/engines/mutationofjb/commands/playanimationcommand.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_PLAYANIMATIONCOMMAND_H
+#define MUTATIONOFJB_PLAYANIMATIONCOMMAND_H
+
+#include "mutationofjb/commands/seqcommand.h"
+#include "common/str.h"
+
+namespace MutationOfJB {
+
+class PlayAnimationCommandParser : public SeqCommandParser {
+public:
+	PlayAnimationCommandParser() {}
+
+	virtual bool parse(const Common::String &line, ScriptParseContext &parseCtx, Command *&command);
+};
+
+class PlayAnimationCommand : public SeqCommand {
+public:
+	PlayAnimationCommand(uint8 fromFrame, uint8 toFrame) : _fromFrame(fromFrame), _toFrame(toFrame) {}
+	const Common::String &getName() const;
+
+	virtual ExecuteResult execute(ScriptExecutionContext &scriptExecCtx) override;
+	virtual Common::String debugString() const override;
+private:
+	uint8 _fromFrame;
+	uint8 _toFrame;
+};
+
+}
+
+#endif
diff --git a/engines/mutationofjb/debug.cpp b/engines/mutationofjb/debug.cpp
index 7068b66..112b810 100644
--- a/engines/mutationofjb/debug.cpp
+++ b/engines/mutationofjb/debug.cpp
@@ -69,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("dumpbitmapinfo", WRAP_METHOD(Console, cmd_dumpbitmapinfo));
 	registerCmd("listinventory", WRAP_METHOD(Console, cmd_listinventory));
 }
 
@@ -437,6 +438,34 @@ bool Console::cmd_dumpstaticinfo(int argc, const char **argv) {
 	return true;
 }
 
+bool Console::cmd_dumpbitmapinfo(int argc, const char **argv) {
+	if (argc == 3) {
+		const uint8 sceneId = atoi(argv[1]);
+		const uint8 bitmapId = atoi(argv[2]);
+
+		Scene *const scene = _vm->getGame().getGameData().getScene(sceneId);
+		if (scene) {
+			Bitmap *const bitmap = scene->getBitmap(bitmapId);
+			if (bitmap) {
+				debugPrintf("Room Frame: %u\n", (unsigned int) bitmap->_roomFrame);
+				debugPrintf("Visible: %u\n", (unsigned int) bitmap->_isVisible);
+				debugPrintf("X1: %u\n", (unsigned int) bitmap->_x1);
+				debugPrintf("Y1: %u\n", (unsigned int) bitmap->_y1);
+				debugPrintf("X2: %u\n", (unsigned int) bitmap->_x2);
+				debugPrintf("Y2: %u\n", (unsigned int) bitmap->_y2);
+			} else {
+				debugPrintf("Bitmap %u not found.\n", (unsigned int) bitmapId);
+			}
+		} else {
+			debugPrintf("Scene %u not found.\n", (unsigned int) sceneId);
+		}
+	} else {
+		debugPrintf("dumpbitmapinfo <sceneid> <bitmapid>\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 b5c40c0..679cafc 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_dumpbitmapinfo(int argc, const char **argv);
 	bool cmd_listinventory(int argc, const char **argv);
 
 	void showIndent(int indentLevel);
diff --git a/engines/mutationofjb/gamedata.cpp b/engines/mutationofjb/gamedata.cpp
index 4905bbb..33f9ba2 100644
--- a/engines/mutationofjb/gamedata.cpp
+++ b/engines/mutationofjb/gamedata.cpp
@@ -298,6 +298,15 @@ Static *Scene::getStatic(uint8 staticId, bool ignoreNo) {
 	return &_statics[staticId - 1];
 }
 
+Bitmap *Scene::getBitmap(uint8 bitmapId) {
+	if (bitmapId == 0 || bitmapId > ARRAYSIZE(_bitmaps)) {
+		warning("Bitmap %d does not exist", bitmapId);
+		return nullptr;
+	}
+
+	return &_bitmaps[bitmapId - 1];
+}
+
 uint8 Scene::getNoDoors(bool ignoreNo) const {
 	return (!ignoreNo ? MIN(_noDoors, static_cast<uint8>(ARRAYSIZE(_doors))) : ARRAYSIZE(_doors));
 }
@@ -310,6 +319,10 @@ uint8 Scene::getNoStatics(bool ignoreNo) const {
 	return (!ignoreNo ? MIN(_noStatics, static_cast<uint8>(ARRAYSIZE(_statics))) : ARRAYSIZE(_statics));
 }
 
+uint8 Scene::getNoBitmaps() const {
+	return ARRAYSIZE(_bitmaps);
+}
+
 Door *Scene::findDoor(int16 x, int16 y, bool activeOnly, int *index) {
 	for (int i = 0; i < getNoDoors(); ++i) {
 		Door &door = _doors[i];
diff --git a/engines/mutationofjb/gamedata.h b/engines/mutationofjb/gamedata.h
index fb81518..c2ddfd6 100644
--- a/engines/mutationofjb/gamedata.h
+++ b/engines/mutationofjb/gamedata.h
@@ -338,10 +338,12 @@ struct Scene : Common::Serializable {
 	Door *getDoor(uint8 objectId);
 	Object *getObject(uint8 objectId, bool ignoreNo = false);
 	Static *getStatic(uint8 staticId, bool ignoreNo = false);
+	Bitmap *getBitmap(uint8 bitmapId);
 
 	uint8 getNoDoors(bool ignoreNo = false) const;
 	uint8 getNoObjects(bool ignoreNo = false) const;
 	uint8 getNoStatics(bool ignoreNo = false) const;
+	uint8 getNoBitmaps() const;
 
 	/**
 	 * Finds the door at the given position. By default, only active doors are considered.
diff --git a/engines/mutationofjb/module.mk b/engines/mutationofjb/module.mk
index 20272d0..736e942 100644
--- a/engines/mutationofjb/module.mk
+++ b/engines/mutationofjb/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/mutationofjb
 
 MODULE_OBJS := \
 	commands/additemcommand.o \
+	commands/bitmapvisibilitycommand.o \
 	commands/callmacrocommand.o \
 	commands/camefromcommand.o \
 	commands/changecommand.o \
@@ -16,6 +17,7 @@ MODULE_OBJS := \
 	commands/labelcommand.o \
 	commands/loadplayercommand.o \
 	commands/newroomcommand.o \
+	commands/playanimationcommand.o \
 	commands/removeallitemscommand.o \
 	commands/removeitemcommand.o \
 	commands/renamecommand.o \
diff --git a/engines/mutationofjb/room.cpp b/engines/mutationofjb/room.cpp
index 783edae..6b868e7 100644
--- a/engines/mutationofjb/room.cpp
+++ b/engines/mutationofjb/room.cpp
@@ -146,6 +146,41 @@ void Room::drawObjectAnimation(uint8 objectId, int animOffset) {
 	blit_if(_surfaces[animFrame], *_screen, Common::Point(object->_x, object->_y), ThresholdBlitOperation());
 }
 
+void Room::drawBitmap(uint8 bitmapId) {
+	GameData &gameData = _game->getGameData();
+
+	Scene *const scene = gameData.getCurrentScene();
+	if (!scene) {
+		return;
+	}
+	Bitmap *const bitmap = scene->getBitmap(bitmapId);
+	if (!bitmap) {
+		return;
+	}
+
+	Common::Rect bitmapArea(bitmap->_x1, bitmap->_y1, bitmap->_x2 + 1, bitmap->_y2 + 1);
+	drawFrames(bitmap->_roomFrame - 1, bitmap->_roomFrame - 1, bitmapArea, 0xC0);
+}
+
+void Room::drawFrames(uint8 fromFrame, uint8 toFrame, const Common::Rect &area, uint8 threshold) {
+	GameData &gameData = _game->getGameData();
+
+	Scene *const scene = gameData.getCurrentScene();
+	if (!scene) {
+		return;
+	}
+
+	const Common::String fileName = Common::String::format("room%d%s.dat", gameData._currentScene, gameData._partB ? "b" : "");
+
+	AnimationDecoder decoder(fileName, *_screen);
+	decoder.setPartialMode(fromFrame, toFrame, area, threshold);
+	decoder.decode(nullptr);
+	if (!area.isEmpty())
+		_screen->getSubArea(area); // Add dirty rect.
+	else
+		_screen->makeAllDirty();
+}
+
 void Room::redraw() {
 	if (!_game->isCurrentSceneMap()) {
 		Common::Rect rect(0, 0, GAME_AREA_WIDTH, GAME_AREA_HEIGHT);
@@ -159,6 +194,13 @@ void Room::redraw() {
 			drawObjectAnimation(i + 1, obj->_currentFrame - _objectsStart[i] - 1);
 		}
 	}
+
+	for (uint8 i = 0; i < currentScene->getNoBitmaps(); ++i) {
+		Bitmap *const bitmap = currentScene->getBitmap(i + 1);
+		if (bitmap->_isVisible && bitmap->_roomFrame > 0) {
+			drawBitmap(i + 1);
+		}
+	}
 }
 
 }
diff --git a/engines/mutationofjb/room.h b/engines/mutationofjb/room.h
index 083fba6..0c29510 100644
--- a/engines/mutationofjb/room.h
+++ b/engines/mutationofjb/room.h
@@ -45,6 +45,8 @@ public:
 	Room(Game *game, Graphics::Screen *screen);
 	bool load(uint8 roomNumber, bool roomB);
 	void drawObjectAnimation(uint8 objectId, int animOffset);
+	void drawBitmap(uint8 bitmapId);
+	void drawFrames(uint8 fromFrame, uint8 toFrame, const Common::Rect &area = Common::Rect(), uint8 threshold = 0xFF);
 	void redraw();
 private:
 	Game *_game;
diff --git a/engines/mutationofjb/script.cpp b/engines/mutationofjb/script.cpp
index a4bbb8f..a931785 100644
--- a/engines/mutationofjb/script.cpp
+++ b/engines/mutationofjb/script.cpp
@@ -49,6 +49,8 @@
 #include "mutationofjb/commands/specialshowcommand.h"
 #include "mutationofjb/commands/switchpartcommand.h"
 #include "mutationofjb/commands/loadplayercommand.h"
+#include "mutationofjb/commands/bitmapvisibilitycommand.h"
+#include "mutationofjb/commands/playanimationcommand.h"
 #include "mutationofjb/game.h"
 
 namespace MutationOfJB {
@@ -81,6 +83,8 @@ static CommandParser **getParsers() {
 		new SpecialShowCommandParser,
 		new SwitchPartCommandParser,
 		new LoadPlayerCommandParser,
+		new BitmapVisibilityCommandParser,
+		new PlayAnimationCommandParser,
 		nullptr
 	};
 





More information about the Scummvm-git-logs mailing list