aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorĽubomír Remák2018-04-02 14:03:40 +0200
committerEugene Sandulenko2018-08-25 23:12:01 +0200
commit99d9055e201b0518baad741f4f46cb86c2f7e172 (patch)
treecf981af171d578d9064c09ab5e0ff60fb1c853c3 /engines
parent2b94873694619272f79f6b358d4a18c8bce13cd8 (diff)
downloadscummvm-rg350-99d9055e201b0518baad741f4f46cb86c2f7e172.tar.gz
scummvm-rg350-99d9055e201b0518baad741f4f46cb86c2f7e172.tar.bz2
scummvm-rg350-99d9055e201b0518baad741f4f46cb86c2f7e172.zip
MUTATIONOFJB: Load object frames and implement special handling for map scenes.
Diffstat (limited to 'engines')
-rw-r--r--engines/mutationofjb/animationdecoder.cpp2
-rw-r--r--engines/mutationofjb/debug.cpp33
-rw-r--r--engines/mutationofjb/debug.h1
-rw-r--r--engines/mutationofjb/game.cpp40
-rw-r--r--engines/mutationofjb/game.h7
-rw-r--r--engines/mutationofjb/gamedata.cpp56
-rw-r--r--engines/mutationofjb/gamedata.h9
-rw-r--r--engines/mutationofjb/mutationofjb.cpp125
-rw-r--r--engines/mutationofjb/mutationofjb.h11
-rw-r--r--engines/mutationofjb/room.cpp65
-rw-r--r--engines/mutationofjb/room.h11
11 files changed, 296 insertions, 64 deletions
diff --git a/engines/mutationofjb/animationdecoder.cpp b/engines/mutationofjb/animationdecoder.cpp
index 585ad91aa8..5b201535c8 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 f533a94ffb..4ce2418d1b 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 e57b787a6d..0cd7257203 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 156c0205d5..a46ca63965 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 503cde98e4..c71b5f16e7 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 acca555bbc..fb9e642355 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 473575328d..b0c64c5ac8 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 622be67a8c..df8ad113a6 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 893cca9772..ef0c97346d 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 547cda43f4..66da3acfb2 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 e8f444007e..a2be2fc3be 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;
};
}