From 0c340485e01e0c18634a496d145841afb2ac2536 Mon Sep 17 00:00:00 2001 From: Ľubomír Remák Date: Fri, 2 Nov 2018 23:26:58 +0100 Subject: MUTATIONOFJB: Draw bitmaps. Implement RB (bitmap visibility) command. Implement stub for FLX and FLB (play animation) commands. --- engines/mutationofjb/animationdecoder.cpp | 113 ++++++++++++++------- engines/mutationofjb/animationdecoder.h | 18 ++++ .../commands/bitmapvisibilitycommand.cpp | 58 +++++++++++ .../commands/bitmapvisibilitycommand.h | 53 ++++++++++ engines/mutationofjb/commands/camefromcommand.cpp | 1 + .../mutationofjb/commands/playanimationcommand.cpp | 61 +++++++++++ .../mutationofjb/commands/playanimationcommand.h | 52 ++++++++++ engines/mutationofjb/debug.cpp | 29 ++++++ engines/mutationofjb/debug.h | 1 + engines/mutationofjb/gamedata.cpp | 13 +++ engines/mutationofjb/gamedata.h | 2 + engines/mutationofjb/module.mk | 2 + engines/mutationofjb/room.cpp | 42 ++++++++ engines/mutationofjb/room.h | 2 + engines/mutationofjb/script.cpp | 4 + 15 files changed, 417 insertions(+), 34 deletions(-) create mode 100644 engines/mutationofjb/commands/bitmapvisibilitycommand.cpp create mode 100644 engines/mutationofjb/commands/bitmapvisibilitycommand.h create mode 100644 engines/mutationofjb/commands/playanimationcommand.cpp create mode 100644 engines/mutationofjb/commands/playanimationcommand.h (limited to 'engines') diff --git a/engines/mutationofjb/animationdecoder.cpp b/engines/mutationofjb/animationdecoder.cpp index 43590a92c3..84325a95ef 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(_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 050aa3b9dd..f213440d9d 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 0000000000..f1238907a7 --- /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 " " " " " + * + * 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 0000000000..366abd3148 --- /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 67033b8a53..b4bbcc75cb 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 0000000000..60c6f1c3cf --- /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" ) " " + * + * 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 0000000000..da7ff25324 --- /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 7068b6643f..112b810048 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 \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 b5c40c032f..679cafc8ec 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 4905bbb3e2..33f9ba2411 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(ARRAYSIZE(_doors))) : ARRAYSIZE(_doors)); } @@ -310,6 +319,10 @@ uint8 Scene::getNoStatics(bool ignoreNo) const { return (!ignoreNo ? MIN(_noStatics, static_cast(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 fb81518890..c2ddfd644a 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 20272d05dc..736e9429eb 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 783edae268..6b868e75c7 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 083fba6335..0c29510a8d 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 a4bbb8f1ef..a931785404 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 }; -- cgit v1.2.3