diff options
25 files changed, 273 insertions, 44 deletions
diff --git a/engines/pink/archive.h b/engines/pink/archive.h index 45554b8553..b74b0f52da 100644 --- a/engines/pink/archive.h +++ b/engines/pink/archive.h @@ -108,8 +108,12 @@ inline Archive &operator>>(Archive &archive, Common::StringArray &array){ } inline Archive &operator>>(Archive &archive, Common::StringMap &map){ - archive.readCount(); - map.setVal(archive.readString(), archive.readString()); + uint size = archive.readCount(); + for (int i = 0; i < size; ++i) { + Common::String key = archive.readString(); + Common::String val = archive.readString(); + map.setVal(key, val); + } return archive; } @@ -142,7 +146,6 @@ inline Archive &operator<<(Archive &archive, Common::StringMap &map){ archive.writeString(pair._key); archive.writeString(pair._value); } - map.setVal(archive.readString(), archive.readString()); return archive; } diff --git a/engines/pink/director.cpp b/engines/pink/director.cpp index 25ffa5af94..4003ca5073 100644 --- a/engines/pink/director.cpp +++ b/engines/pink/director.cpp @@ -32,7 +32,7 @@ Director::Director(OSystem *system) : _system(system), showBounds(0) {} void Director::draw() { - //dd_system->fillScreen(0); + _system->fillScreen(0); for (int i = 0; i < _sprites.size(); ++i) { drawSprite(_sprites[i]); } diff --git a/engines/pink/objects/actions/action.h b/engines/pink/objects/actions/action.h index 72e9b8f989..ae3b0838d4 100644 --- a/engines/pink/objects/actions/action.h +++ b/engines/pink/objects/actions/action.h @@ -42,6 +42,9 @@ public: Actor *getActor() { return _actor;} + virtual void pause() {}; + virtual void unpause() {}; + protected: Actor *_actor; }; diff --git a/engines/pink/objects/actions/action_cel.cpp b/engines/pink/objects/actions/action_cel.cpp index e9e524726c..33e8823429 100644 --- a/engines/pink/objects/actions/action_cel.cpp +++ b/engines/pink/objects/actions/action_cel.cpp @@ -80,7 +80,15 @@ void ActionCEL::update() { } ActionCEL::~ActionCEL() { - delete _decoder; + end(); +} + +void ActionCEL::pause() { + _decoder->pauseVideo(1); +} + +void ActionCEL::unpause() { + _decoder->pauseVideo(0); } } // End of namespace Pink
\ No newline at end of file diff --git a/engines/pink/objects/actions/action_cel.h b/engines/pink/objects/actions/action_cel.h index 2ae5308d0e..a86eadcd70 100644 --- a/engines/pink/objects/actions/action_cel.h +++ b/engines/pink/objects/actions/action_cel.h @@ -45,6 +45,10 @@ public: virtual bool initPalette(Director *director); + void pause() override; + + void unpause() override; + protected: virtual void onStart() {} ; CelDecoder *_decoder; diff --git a/engines/pink/objects/actions/action_play_with_sfx.cpp b/engines/pink/objects/actions/action_play_with_sfx.cpp index fc4d48c40a..9ead26bfc4 100644 --- a/engines/pink/objects/actions/action_play_with_sfx.cpp +++ b/engines/pink/objects/actions/action_play_with_sfx.cpp @@ -48,6 +48,7 @@ void ActionPlayWithSfx::update() { _decoder->stop(); _actor->endAction(); } + updateSound(); } @@ -60,6 +61,9 @@ void ActionPlayWithSfx::onStart() { } void ActionPlayWithSfx::updateSound() { + if (!_actor->isPlaying() && !_isLoop) + return; + for (int i = 0; i < _sfxArray.size(); ++i) { if (_sfxArray[i]->getFrame() == _decoder->getCurFrame()) { _sfxArray[i]->play(_actor->getPage()); @@ -68,6 +72,7 @@ void ActionPlayWithSfx::updateSound() { } ActionPlayWithSfx::~ActionPlayWithSfx() { + ActionPlay::end(); for (int i = 0; i < _sfxArray.size(); ++i) { delete _sfxArray[i]; } diff --git a/engines/pink/objects/actions/action_sound.cpp b/engines/pink/objects/actions/action_sound.cpp index f1829a1f19..f4acb50b1f 100644 --- a/engines/pink/objects/actions/action_sound.cpp +++ b/engines/pink/objects/actions/action_sound.cpp @@ -88,4 +88,14 @@ void ActionSound::update() { _actor->endAction(); } +void ActionSound::pause() { + if (_sound) + _sound->pause(); +} + +void ActionSound::unpause() { + if (_sound) + _sound->resume(); +} + } // End of namespace Pink
\ No newline at end of file diff --git a/engines/pink/objects/actions/action_sound.h b/engines/pink/objects/actions/action_sound.h index b13481cb65..e96c41d22c 100644 --- a/engines/pink/objects/actions/action_sound.h +++ b/engines/pink/objects/actions/action_sound.h @@ -42,6 +42,9 @@ public: virtual void end(); virtual void update(); + void pause() override; + void unpause() override; + private: Sound *_sound; Common::String _fileName; diff --git a/engines/pink/objects/actions/action_talk.cpp b/engines/pink/objects/actions/action_talk.cpp index b9743005c4..30412ee0e8 100644 --- a/engines/pink/objects/actions/action_talk.cpp +++ b/engines/pink/objects/actions/action_talk.cpp @@ -54,6 +54,19 @@ void ActionTalk::update() { void ActionTalk::end() { ActionPlay::end(); delete _sound; + _sound = nullptr; +} + +void ActionTalk::pause() { + ActionCEL::pause(); + if (_sound) + _sound->pause(); +} + +void ActionTalk::unpause() { + ActionCEL::unpause(); + if (_sound) + _sound->resume(); } } // End of namespace Pink
\ No newline at end of file diff --git a/engines/pink/objects/actions/action_talk.h b/engines/pink/objects/actions/action_talk.h index 9b6d26fe32..bbe16eb496 100644 --- a/engines/pink/objects/actions/action_talk.h +++ b/engines/pink/objects/actions/action_talk.h @@ -37,6 +37,9 @@ public: virtual void end(); + void pause() override; + void unpause() override; + protected: virtual void onStart(); diff --git a/engines/pink/objects/actors/actor.cpp b/engines/pink/objects/actors/actor.cpp index 6a20a46f41..a7717d3b70 100644 --- a/engines/pink/objects/actors/actor.cpp +++ b/engines/pink/objects/actors/actor.cpp @@ -130,9 +130,7 @@ void Actor::onMouseOver(Common::Point point, CursorMgr *mgr) { Actor::~Actor() { for (int i = 0; i < _actions.size(); ++i) { - _actions[i]->toConsole(); delete _actions[i]; - _actions[i] = nullptr; } } @@ -143,8 +141,22 @@ void Actor::loadState(Archive &archive) { } void Actor::saveState(Archive &archive) { - assert(_action); - archive.writeString(_action->getName()); + Common::String actionName; + + if (_action) + actionName = _action->getName(); + + archive.writeString(actionName); +} + +void Actor::pause() { + if (_action) + _action->pause(); +} + +void Actor::unpause() { + if (_action) + _action->unpause(); } } // End of namespace Pink diff --git a/engines/pink/objects/actors/actor.h b/engines/pink/objects/actors/actor.h index 69cf37b920..0761b8ff6f 100644 --- a/engines/pink/objects/actors/actor.h +++ b/engines/pink/objects/actors/actor.h @@ -70,6 +70,10 @@ public: virtual void onMouseOver(Common::Point point, CursorMgr *mgr); virtual bool isClickable() { return 0;} + + virtual void pause(); + virtual void unpause(); + protected: GamePage *_page; Action *_action; diff --git a/engines/pink/objects/actors/inventory_actor.h b/engines/pink/objects/actors/inventory_actor.h index 4b2b424c9d..55dd83b902 100644 --- a/engines/pink/objects/actors/inventory_actor.h +++ b/engines/pink/objects/actors/inventory_actor.h @@ -37,6 +37,8 @@ public: _actions[i]->toConsole(); } } + + void pause() {} }; } // End of namespace Pink diff --git a/engines/pink/objects/actors/lead_actor.cpp b/engines/pink/objects/actors/lead_actor.cpp index d89ecb4f87..2a0f84dbcd 100644 --- a/engines/pink/objects/actors/lead_actor.cpp +++ b/engines/pink/objects/actors/lead_actor.cpp @@ -88,6 +88,8 @@ void LeadActor::update() { break; case kInventory: + getPage()->getModule()->getInventoryMgr()->update(); + break; case kPDA: break; @@ -184,25 +186,34 @@ void LeadActor::onLeftButtonClick(Common::Point point) { case kMoving: { Actor *actor = _page->getGame()->getDirector()->getActorByPoint(point); - if (this == actor){ - // inventory is not implemented + if (this == actor) { + onClick(); return; } _recipient = (SupportingActor*) actor; if (actor->isClickable() && - _recipient->isLeftClickHandlers()){ - _state = kMoving; - _nextState = kInDialog1; - _walkMgr->start(_walkMgr->findLocation(_recipient->getLocation())); + _recipient->isLeftClickHandlers()) { + WalkLocation *location = _walkMgr->findLocation(_recipient->getLocation()); + if (location) { + _state = kMoving; + _nextState = kInDialog1; + _walkMgr->start(location); + } + else if (_state == kReady){ + if (_isHaveItem) + sendUseClickMessage(_recipient); + else sendLeftClickMessage(_recipient); + } } - break; + + break; } case kPDA: break; case kInventory: - + _page->getModule()->getInventoryMgr()->onClick(point); break; default: break; @@ -220,8 +231,9 @@ void LeadActor::onWalkEnd() { _state = kReady; _nextState = kUnk_Loading; if (_recipient && oldNextState == kInDialog1){ - // if use click not impl - sendLeftClickMessage(_recipient); + if (_isHaveItem) + sendUseClickMessage(_recipient); + else sendLeftClickMessage(_recipient); } } @@ -238,7 +250,7 @@ bool LeadActor::sendLeftClickMessage(SupportingActor *actor) { void LeadActor::onClick() { if (_isHaveItem) { _isHaveItem = false; - _nextState = _state != kMoving ? + _nextState = (_state != kMoving) ? kUnk_Loading : kReady; } else { @@ -246,10 +258,28 @@ void LeadActor::onClick() { _recipient = nullptr; _nextState = kReady; } - + if (_page->getModule()->getInventoryMgr()->start(1)){ + _stateCopy = _state; + _state = kInventory; + _page->pause(); + } } } +LeadActor::LeadActor() + : _state(kReady), _nextState(kReady), + _isHaveItem(false), _recipient(nullptr), + _cursorMgr(nullptr), _walkMgr(nullptr), + _sequencer(nullptr) +{} + +void LeadActor::onInventoryClosed(bool isItemClicked) { + _isHaveItem = isItemClicked; + _state = _stateCopy; + _stateCopy = kUnk_Loading; + _page->unpause(); +} + void ParlSqPink::toConsole() { debug("ParlSqPink: _name = %s", _name.c_str()); for (int i = 0; i < _actions.size(); ++i) { diff --git a/engines/pink/objects/actors/lead_actor.h b/engines/pink/objects/actors/lead_actor.h index a2c2ededab..45e27f9233 100644 --- a/engines/pink/objects/actors/lead_actor.h +++ b/engines/pink/objects/actors/lead_actor.h @@ -35,9 +35,11 @@ class WalkMgr; class Sequencer; class SupportingActor; +class InventoryItem; class LeadActor : public Actor { public: + LeadActor(); enum State { kReady = 0, kMoving = 1, @@ -67,6 +69,7 @@ public: void onMouseMove(Common::Point point); void onWalkEnd(); void onClick(); + void onInventoryClosed(bool isItemClicked); virtual void onMouseOver(Common::Point point, CursorMgr *mgr); @@ -78,6 +81,7 @@ private: State _state; State _nextState; + State _stateCopy; bool _isHaveItem; diff --git a/engines/pink/objects/inventory.cpp b/engines/pink/objects/inventory.cpp index 9bbc279740..2c4aa5966f 100644 --- a/engines/pink/objects/inventory.cpp +++ b/engines/pink/objects/inventory.cpp @@ -25,11 +25,15 @@ #include "inventory.h" #include "engines/pink/archive.h" #include "pink/objects/actors/lead_actor.h" +#include "pink/objects/actions/action.h" +#include "pink/objects/pages/game_page.h" +#include "pink/director.h" +#include "pink/pink.h" namespace Pink { InventoryMgr::InventoryMgr() - : _lead(nullptr), _item(nullptr) + : _lead(nullptr), _item(nullptr), _isClickedOnItem(false) { } @@ -57,11 +61,12 @@ void InventoryMgr::deserialize(Archive &archive) { archive >> _items; } -InventoryItem *InventoryMgr::findInventoryItem(Common::String &name) { - return *Common::find_if(_items.begin(), _items.end(), [&name] +InventoryItem *InventoryMgr::findInventoryItem(const Common::String &name) { + auto it = Common::find_if(_items.begin(), _items.end(), [&name] (InventoryItem *item) { return name == item->getName(); });; + return it != _items.end() ? *it : nullptr; } void InventoryMgr::setLeadActor(LeadActor *lead) { @@ -101,6 +106,86 @@ void InventoryMgr::setItemOwner(const Common::String &owner, InventoryItem *item item->_currentOwner = owner; } +bool InventoryMgr::start(bool playOpening) { + if (!_item) { + _item = findInventoryItem(_lead->getName()); + if (!_item) + return false; + } + + _window = _lead->getPage()->findActor("InventoryWindow"); + _itemActor = _lead->getPage()->findActor("InventoryItem"); + _rightArrow = _lead->getPage()->findActor("InventoryRightArrow"); + _leftArrow = _lead->getPage()->findActor("InventoryLeftArrow"); + + if (playOpening){ + _window->setAction("Open"); + _state = kOpening; + } + + return true; +} + +void InventoryMgr::update() { + if (_state == kOpening && !_window->isPlaying()){ + _state = kReady; + _itemActor->setAction(_item->getName()); + _window->setAction("Show"); + _leftArrow->setAction("Show"); + _rightArrow->setAction("Show"); + } + else if (_state == kClosing && !_window->isPlaying()){ + _window->setAction("Idle"); + + _lead->onInventoryClosed(_isClickedOnItem); + + _state = kIdle; + _window = nullptr; + _itemActor = nullptr; + _isClickedOnItem = false; + } +} + +void InventoryMgr::onClick(Common::Point point) { + Actor *actor = _lead->getPage()->getGame()->getDirector()->getActorByPoint(point); + if (actor == _itemActor || actor == _window) { + _isClickedOnItem = true; + close(); + } + else if (actor == _leftArrow) { + showNextItem(kLeft); + } + else if (actor == _rightArrow) { + showNextItem(kRight); + } + else close(); +} + +void InventoryMgr::close() { + _state = kClosing; + + _window->setAction("Close"); + _itemActor->setAction("Idle"); + _leftArrow->setAction("Idle"); + _rightArrow->setAction("Idle"); +} + +void InventoryMgr::showNextItem(bool direction) { + int index = 0; + for (int i = 0; i < _items.size(); ++i) { + if (_item == _items[i]) { + index = i + _items.size(); + break; + } + } + index = (direction == kLeft) ? --index : ++index; + index %= _items.size(); + + //add check for item owner + _itemActor->setAction(_items[index]->getName()); + _item = _items[index]; +} + } // End of namespace Pink diff --git a/engines/pink/objects/inventory.h b/engines/pink/objects/inventory.h index 908f2a8d2f..db67f4e2e3 100644 --- a/engines/pink/objects/inventory.h +++ b/engines/pink/objects/inventory.h @@ -25,6 +25,7 @@ #include <common/array.h> +#include <common/rect.h> #include "engines/pink/objects/object.h" namespace Pink { @@ -45,26 +46,51 @@ private: }; class LeadActor; +class Actor; class InventoryMgr : public Object { public: InventoryMgr(); virtual ~InventoryMgr(); virtual void deserialize(Archive &archive); - virtual void toConsole(); + void update(); + void onClick(Common::Point point); + + bool start(bool playOpening); + void setLeadActor(LeadActor *lead); - InventoryItem* findInventoryItem(Common::String &name); + InventoryItem* findInventoryItem(const Common::String &name); bool isPinkOwnsAnyItems(); void setItemOwner(const Common::String &owner, InventoryItem *item); private: - LeadActor *_lead; + void close(); + enum Direction { + kLeft = 0, + kRight = 1, + }; + void showNextItem(bool direction); + + InventoryItem *_item; Common::Array<InventoryItem*> _items; - // other fields. haven't RE them yet + + LeadActor *_lead; + Actor *_window; + Actor *_itemActor; + Actor *_rightArrow; + Actor *_leftArrow; + + enum State { + kIdle = 0, + kOpening = 1, + kReady = 2, + kClosing = 3, + } _state; + bool _isClickedOnItem; }; } // End of namespace Pink diff --git a/engines/pink/objects/module.cpp b/engines/pink/objects/module.cpp index 621cd8c790..d35f794540 100644 --- a/engines/pink/objects/module.cpp +++ b/engines/pink/objects/module.cpp @@ -69,8 +69,7 @@ void Module::changePage(const Common::String &pageName) { page = findPage(pageName); assert(_page != page); - _page->clear(); - + _page->unload(); _page = page; _page->init(kLoadingNewGame); diff --git a/engines/pink/objects/pages/game_page.cpp b/engines/pink/objects/pages/game_page.cpp index d12c034d2a..e38bed8da8 100644 --- a/engines/pink/objects/pages/game_page.cpp +++ b/engines/pink/objects/pages/game_page.cpp @@ -32,7 +32,7 @@ namespace Pink { GamePage::GamePage() : _cursorMgr(nullptr), _walkMgr(nullptr), _sequencer(nullptr), - _perhapsIsLoaded(false), _memFile(nullptr) + _isLoaded(false), _memFile(nullptr) {} GamePage::~GamePage() { @@ -64,17 +64,14 @@ void GamePage::load(Archive &archive) { _leadActor = static_cast<LeadActor*>(archive.readObject()); _walkMgr->deserialize(archive); - _sequencer->deserialize(archive); archive >> _handlers; } void GamePage::init(bool isLoadingSave) { - if (!_perhapsIsLoaded) + if (!_isLoaded) loadManagers(); - getGame()->getDirector()->clear(); - toConsole(); for (int j = 0; j < _actors.size(); ++j) { @@ -108,7 +105,7 @@ bool GamePage::initHandler() { } void GamePage::loadManagers() { - _perhapsIsLoaded = true; + _isLoaded = true; _cursorMgr = new CursorMgr(_module->getGame(), this); _walkMgr = new WalkMgr; _sequencer = new Sequencer(this); @@ -150,6 +147,7 @@ WalkMgr *GamePage::getWalkMgr() { void GamePage::loadState() { Archive archive(static_cast<Common::SeekableReadStream*>(_memFile)); + _variables.clear(0); archive >> _variables; uint16 actorCount; @@ -165,6 +163,7 @@ void GamePage::loadState() { void GamePage::saveState() { _memFile = new Common::MemoryReadWriteStream(DisposeAfterUse::YES); Archive archive(static_cast<Common::WriteStream*>(_memFile)); + archive << _variables; archive.writeWORD(_actors.size()); @@ -172,12 +171,14 @@ void GamePage::saveState() { archive.writeString(_actors[i]->getName()); _actors[i]->saveState(archive); } + } void GamePage::unload() { _leadActor->setAction(_leadActor->findAction("Idle")); saveState(); clear(); + _isLoaded = false; } void GamePage::clear() { @@ -187,9 +188,9 @@ void GamePage::clear() { delete _handlers[i]; } _handlers.clear(); - delete _cursorMgr; - delete _sequencer; - delete _walkMgr; + delete _cursorMgr; _cursorMgr = nullptr; + delete _sequencer; _sequencer = nullptr; + delete _walkMgr; _walkMgr = nullptr; } diff --git a/engines/pink/objects/pages/game_page.h b/engines/pink/objects/pages/game_page.h index 79a4bee4db..c4f6dfba82 100644 --- a/engines/pink/objects/pages/game_page.h +++ b/engines/pink/objects/pages/game_page.h @@ -60,7 +60,7 @@ private: void loadState(); void saveState(); - bool _perhapsIsLoaded; + bool _isLoaded; Common::MemoryReadWriteStream *_memFile; Module *_module; CursorMgr *_cursorMgr; diff --git a/engines/pink/objects/pages/page.cpp b/engines/pink/objects/pages/page.cpp index e068367d07..1c0c67e85a 100644 --- a/engines/pink/objects/pages/page.cpp +++ b/engines/pink/objects/pages/page.cpp @@ -38,7 +38,7 @@ void Page::load(Archive &archive) { archive >> _actors; } -Actor *Page::findActor(Common::String &name) { +Actor *Page::findActor(const Common::String &name) { return *Common::find_if(_actors.begin(), _actors.end(), [&name] (Actor *actor) { return name == actor->getName(); @@ -82,6 +82,17 @@ void Page::clear() { _resMgr.clear(); } +void Page::pause() { + for (int i = 0; i < _actors.size(); ++i) { + _actors[i]->pause(); + } +} + +void Page::unpause() { + for (int i = 0; i < _actors.size(); ++i) { + _actors[i]->unpause(); + } +} } // End of namespace Pink diff --git a/engines/pink/objects/pages/page.h b/engines/pink/objects/pages/page.h index b9820fea75..23b060c143 100644 --- a/engines/pink/objects/pages/page.h +++ b/engines/pink/objects/pages/page.h @@ -40,13 +40,15 @@ public: virtual void toConsole(); void load(Archive &archive); - Actor *findActor(Common::String &name); + Actor *findActor(const Common::String &name); LeadActor *getLeadActor(); Sound *loadSound(Common::String &fileName); CelDecoder *loadCel(Common::String &fileName); virtual void clear(); + void pause(); + void unpause(); protected: void init(); diff --git a/engines/pink/objects/sequences/sequencer.h b/engines/pink/objects/sequences/sequencer.h index 1ae4689114..6ae5550a1a 100644 --- a/engines/pink/objects/sequences/sequencer.h +++ b/engines/pink/objects/sequences/sequencer.h @@ -56,6 +56,7 @@ public: void restartSequence(); void skipToLastSubSequence(); + public: void updateTimers(); diff --git a/engines/pink/objects/side_effect.cpp b/engines/pink/objects/side_effect.cpp index 1790917dd2..548a29f12f 100644 --- a/engines/pink/objects/side_effect.cpp +++ b/engines/pink/objects/side_effect.cpp @@ -66,7 +66,7 @@ void SideEffectInventoryItemOwner::deserialize(Archive &archive) { void SideEffectInventoryItemOwner::execute(Actor *actor) { InventoryMgr *mgr = actor->getPage()->getModule()->getInventoryMgr(); InventoryItem *item = mgr->findInventoryItem(_item); - mgr->setItemOwner(_item, item); + mgr->setItemOwner(_owner, item); } void SideEffectInventoryItemOwner::toConsole() { diff --git a/engines/pink/objects/walk/walk_location.h b/engines/pink/objects/walk/walk_location.h index b9515cdc10..19674a1592 100644 --- a/engines/pink/objects/walk/walk_location.h +++ b/engines/pink/objects/walk/walk_location.h @@ -32,9 +32,9 @@ namespace Pink { class WalkLocation : public NamedObject { public: virtual void deserialize(Archive &archive); - void toConsole() override; Common::StringArray &getNeigbors() { return _neighbors;} + private: Common::StringArray _neighbors; }; |