diff options
39 files changed, 621 insertions, 182 deletions
diff --git a/engines/pink/archive.cpp b/engines/pink/archive.cpp index e3fab5342d..4db6d8ed33 100644 --- a/engines/pink/archive.cpp +++ b/engines/pink/archive.cpp @@ -45,68 +45,10 @@  #include <engines/pink/objects/actors/cursor_actor.h>  #include <engines/pink/objects/handlers/handler_timer.h>  #include <engines/pink/objects/actors/inventory_actor.h> +#include "constants.h"  namespace Pink { -enum { -    kMaxClassLength = 32, -    kMaxStringLength = 64, // adjust -    kNullObject = 0 -}; - -enum { -    kActionHide, -    kActionLoop, -    kActionPlay, -    kActionPlayWithSfx, -    kActionSfx, -    kActionSound, -    kActionStill, -    kActionTalk, -    kActionText, -    kActor, -    kAudioInfoPDAButton, -    kConditionGameVariable, -    kConditionInventoryItemOwner, -    kConditionModuleVariable, -    kConditionNotInventoryItemOwner, -    kConditionNotModuleVariable, -    kConditionNotPageVariable, -    kConditionPageVariable, -    kCursorActor, -    kGamePage, -    kHandlerLeftClick, -    kHandlerStartPage, -    kHandlerTimer, -    kHandlerTimerActions, -    kHandlerTimerSequences, -    kHandlerUseClick, -    kInventoryActor, -    kInventoryItem, -    kLeadActor, -    kModuleProxy, -    kPDAButtonActor, -    kParlSqPink, -    kPubPink, -    kSeqTimer, -    kSequence, -    kSequenceAudio, -    kSequenceItem, -    kSequenceItemDefaultAction, -    kSequenceItemLeader, -    kSequenceItemLeaderAudio, -    kSideEffectExit, -    kSideEffectGameVariable, -    kSideEffectInventoryItemOwner, -    kSideEffectLocation, -    kSideEffectModuleVariable, -    kSideEffectPageVariable, -    kSideEffectRandomPageVariable, -    kSupportingActor, -    kWalkAction, -    kWalkLocation -}; -  static const struct RuntimeClass {      const char *name;      int id; diff --git a/engines/pink/cel_decoder.cpp b/engines/pink/cel_decoder.cpp index 82dca7bee3..b907f45bca 100644 --- a/engines/pink/cel_decoder.cpp +++ b/engines/pink/cel_decoder.cpp @@ -21,6 +21,7 @@   */  #include <common/stream.h> +#include <graphics/surface.h>  #include "cel_decoder.h"  namespace Pink { @@ -79,6 +80,18 @@ const Graphics::Surface *CelDecoder::getCurrentFrame() {      return track->getCurrentFrame();  } +Common::Point CelDecoder::getCenter() { +    CelVideoTrack *track = (CelVideoTrack*) getTrack(0); +    if (!track) +        return {0,0}; +    return track->getCenter(); +} + +Common::Rect &CelDecoder::getRectangle() { +    CelVideoTrack *track = (CelVideoTrack*) getTrack(0); +    return track->getRect(); +} +  CelDecoder::CelVideoTrack::CelVideoTrack(Common::SeekableReadStream *stream, uint16 frameCount, uint16 width, uint16 height, bool skipHeader)          : FlicVideoTrack(stream, frameCount, width, height, 1), _center(0,0), _transparentColourIndex(0){      readHeader(); @@ -100,33 +113,21 @@ void CelDecoder::CelVideoTrack::readPrefixChunk() {      switch (subchunkType) {          case CEL_DATA: -            debug("%u", _fileStream->readUint16LE()); +            _fileStream->readUint16LE();              _center.x = _fileStream->readUint16LE();              _center.y = _fileStream->readUint16LE(); -            debug("stretch x: %u", _fileStream->readUint16LE()); -            debug("stretch y: %u", _fileStream->readUint16LE()); -            debug("rotation x: %u", _fileStream->readUint16LE()); -            debug("rotation y: %u", _fileStream->readUint16LE()); -            debug("rotation z: %u", _fileStream->readUint16LE()); -            debug("current Frame: %u", _fileStream->readUint16LE()); -            debug("next frame offset: %u",_fileStream->readUint32LE()); -            debug("tcolor: %u", _transparentColourIndex = _fileStream->readUint16LE()); -            for (int j = 0; j < 18; ++j) { -                debug("%u", _fileStream->readUint16LE()); -            }              break;          default:              error("Unknown subchunk type");              _fileStream->skip(subchunkSize - 6);              break;      } - +    _rect = Common::Rect::center(_center.x, _center.y, _surface->w, _surface->h);  }  void CelDecoder::CelVideoTrack::readHeader() { -    _fileStream->readUint16LE();	// flags -    // Note: The normal delay is a 32-bit integer (dword), whereas the overridden delay is a 16-bit integer (word) -    // the frame delay is the FLIC "speed", in milliseconds. +    _fileStream->readUint16LE(); +      _frameDelay = _startFrameDelay = _fileStream->readUint32LE();      _fileStream->seek(80); @@ -137,7 +138,6 @@ void CelDecoder::CelVideoTrack::readHeader() {          readPrefixChunk();      } -    // Seek to the first frame      _fileStream->seek(_offsetFrame1);  } @@ -157,4 +157,42 @@ const Graphics::Surface *CelDecoder::CelVideoTrack::getCurrentFrame() {      return _surface;  } +Common::Point CelDecoder::CelVideoTrack::getCenter() { +    return _center; +} + +Common::Rect &CelDecoder::CelVideoTrack::getRect() { +    return _rect; +} + +#define FRAME_TYPE 0xF1FA + +const Graphics::Surface *CelDecoder::CelVideoTrack::decodeNextFrame() { +    // Read chunk +    /*uint32 frameSize = */ _fileStream->readUint32LE(); +    uint16 frameType = _fileStream->readUint16LE(); + +    switch (frameType) { +        case FRAME_TYPE: +            handleFrame(); +            break; +        default: +            error("FlicDecoder::decodeFrame(): unknown main chunk type (type = 0x%02X)", frameType); +            break; +    } + +    _curFrame++; +    _nextFrameStartTime += _frameDelay; + +    if (_atRingFrame) { +        // If we decoded the ring frame, seek to the second frame +        _atRingFrame = false; +        _fileStream->seek(_offsetFrame2); +    } + +    if (_curFrame == 0) +        _transparentColourIndex = *(byte*)_surface->getBasePtr(0,0); +    return _surface; +} +  } // End of namepsace Pink
\ No newline at end of file diff --git a/engines/pink/cel_decoder.h b/engines/pink/cel_decoder.h index 3ccea1a52a..f0c612d12c 100644 --- a/engines/pink/cel_decoder.h +++ b/engines/pink/cel_decoder.h @@ -32,6 +32,9 @@ class CelDecoder : public Video::FlicDecoder {  public:      uint32 getX();      uint32 getY(); +    Common::Point getCenter(); +    Common::Rect &getRectangle(); +      uint16 getTransparentColourIndex();      const Graphics::Surface *getCurrentFrame(); @@ -45,14 +48,19 @@ protected:          uint32 getX() const;          uint32 getY() const; +        Common::Point getCenter(); +        Common::Rect &getRect();          uint16 getTransparentColourIndex();          const Graphics::Surface *getCurrentFrame();      private: +        const Graphics::Surface *decodeNextFrame();          void readPrefixChunk(); -        uint16 _transparentColourIndex; +          Common::Point _center; +        Common::Rect _rect; +        byte _transparentColourIndex;      };  }; diff --git a/engines/pink/constants.h b/engines/pink/constants.h new file mode 100644 index 0000000000..db9c60abac --- /dev/null +++ b/engines/pink/constants.h @@ -0,0 +1,136 @@ +/* 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 PINK_CONSTANTS_H +#define PINK_CONSTANTS_H + +namespace Pink { + +enum { +    kMaxClassLength = 32, +    kMaxStringLength = 64, +    kNullObject = 0 +}; + +enum { +    kActionHide, +    kActionLoop, +    kActionPlay, +    kActionPlayWithSfx, +    kActionSfx, +    kActionSound, +    kActionStill, +    kActionTalk, +    kActionText, +    kActor, +    kAudioInfoPDAButton, +    kConditionGameVariable, +    kConditionInventoryItemOwner, +    kConditionModuleVariable, +    kConditionNotInventoryItemOwner, +    kConditionNotModuleVariable, +    kConditionNotPageVariable, +    kConditionPageVariable, +    kCursorActor, +    kGamePage, +    kHandlerLeftClick, +    kHandlerStartPage, +    kHandlerTimer, +    kHandlerTimerActions, +    kHandlerTimerSequences, +    kHandlerUseClick, +    kInventoryActor, +    kInventoryItem, +    kLeadActor, +    kModuleProxy, +    kPDAButtonActor, +    kParlSqPink, +    kPubPink, +    kSeqTimer, +    kSequence, +    kSequenceAudio, +    kSequenceItem, +    kSequenceItemDefaultAction, +    kSequenceItemLeader, +    kSequenceItemLeaderAudio, +    kSideEffectExit, +    kSideEffectGameVariable, +    kSideEffectInventoryItemOwner, +    kSideEffectLocation, +    kSideEffectModuleVariable, +    kSideEffectPageVariable, +    kSideEffectRandomPageVariable, +    kSupportingActor, +    kWalkAction, +    kWalkLocation +}; + +enum { +    kCursorsCount = 11 +}; + +enum { +    kLoadingCursor = 0, +    kExitForwardCursor = 1, +    kExitLeftCursor = 2, +    kExitRightCursor = 3, +    kDefaultCursor = 4, +    kClickableFirstFrameCursor = 5, +    kClickableSecondFrameCursor = 6, +    kNotClickableCursor = 7, +    kHoldingItemCursor = 8, +    kPDAFirstCursor = 9, +    kPDASecondCursor = 10 +}; + + +// values are from Hokus Pokus +enum { +    kPokusLoadingCursorID = 135, +    kPokusExitForwardCursorID = 138, +    kPokusExitLeftCursorID = 133, +    kPokusExitRightCursorID = 134, +    kPokusClickableFirstCursorID = 137, +    kPokusClickableSecondCursorID = 136, +    kPokusClickableThirdCursorID = 145, +    kPokusNotClickableCursorID = 140, +    kPokusHoldingItemCursorID = 147, +    kPokusPDAFirstCursorID = 141, +    kPokusPDASecondCursorID = 144 +}; + +// from Peril +// it contains cursors whose ids differ +enum { +    kPerilClickableThirdCursorID = 140, +    kPerilNotClickableCursorID = 139, +    kPerilPDASecondCursorID = 142 +}; + +enum { +    kLoadingSave = 1, +    kLoadingNewGame = 0 +}; + +} // End of namespace Pink + +#endif diff --git a/engines/pink/cursor_mgr.cpp b/engines/pink/cursor_mgr.cpp index b5f9d4c64b..b1a2182c41 100644 --- a/engines/pink/cursor_mgr.cpp +++ b/engines/pink/cursor_mgr.cpp @@ -21,9 +21,57 @@   */  #include "cursor_mgr.h" +#include "pink.h"  namespace Pink { -CursorMgr::CursorMgr(GamePage *page) : _page(page) {} +CursorMgr::CursorMgr(PinkEngine *game, GamePage *page) +        : _actor(nullptr), _page(page), _game(game), +          _isPlayingAnimation(0), _firstFrameIndex(0) +{} + +CursorMgr::~CursorMgr() {} + +void CursorMgr::setCursor(uint index, Common::Point point) { +    if (index == kClickableFirstFrameCursor) { +        if (!_isPlayingAnimation) { +            _isPlayingAnimation = 1; +            _time = _game->getTotalPlayTime(); +            _firstFrameIndex = index; +            _isSecondFrame = 0; +            _game->setCursor(index); +        } +    } +    else { +        _isPlayingAnimation = 0; +        _game->setCursor(index); +    } +} + +void CursorMgr::update() { +    if (!_isPlayingAnimation) +        return; + +    uint newTime = _game->getTotalPlayTime(); +    if (newTime - _time > 0xC8){ +        _time = newTime; +        _isSecondFrame = !_isSecondFrame; +        _game->setCursor(_firstFrameIndex + _isSecondFrame); +    } +} + +void CursorMgr::setCursor(Common::String &cursorName, Common::Point point) { +    uint index; +    if (cursorName == "ExitLeft") { +        index = kExitLeftCursor; +    } +    else if (cursorName == "ExitRight"){ +        index = kExitRightCursor; +    } +    else if (cursorName == "ExitForward") +        index = kExitForwardCursor; +    else assert(0); +    setCursor(index, point); +}  } // End of namespace Pink
\ No newline at end of file diff --git a/engines/pink/cursor_mgr.h b/engines/pink/cursor_mgr.h index bd5c17cf9a..2b7d37d51c 100644 --- a/engines/pink/cursor_mgr.h +++ b/engines/pink/cursor_mgr.h @@ -23,21 +23,35 @@  #ifndef PINK_CURSOR_MGR_H  #define PINK_CURSOR_MGR_H -#include "engines/pink/objects/object.h" +#include <graphics/wincursor.h> +#include <engines/pink/objects/object.h> +#include <common/rect.h>  namespace Pink { +  class Actor;  class GamePage; +class PinkEngine;  class CursorMgr : public Object {  public: -    CursorMgr(GamePage *page); +    CursorMgr(PinkEngine *game, GamePage *page); +    ~CursorMgr(); +    void update(); +    void setCursor(uint index, Common::Point point); +    void setCursor(Common::String &cursorName, Common::Point point);  private:      Actor *_actor;      GamePage *_page; +    PinkEngine *_game; + +    uint _time; +    uint _firstFrameIndex; +    bool _isPlayingAnimation; +    bool _isSecondFrame;  };  } // End of namespace Pink diff --git a/engines/pink/detection_tables.h b/engines/pink/detection_tables.h index b14803bb51..a59e4e371a 100644 --- a/engines/pink/detection_tables.h +++ b/engines/pink/detection_tables.h @@ -33,6 +33,7 @@ static const ADGameDescription gameDescriptions[] = {                  0,{                          {"PPTP.ORB", NULL, NULL, -1},                          {"PPTP.BRO", NULL, NULL, -1}, +                        {"PPTP.EXE", NULL, NULL, -1},                          AD_LISTEND},                  Common::EN_ANY,                  Common::kPlatformWindows, @@ -41,8 +42,10 @@ static const ADGameDescription gameDescriptions[] = {          },          {                  "pokus", -                0, -                AD_ENTRY1s("hpp.ORB", NULL, -1), +                0, { +                        {"HPP.orb", NULL, NULL, -1}, +                        {"hpp.exe", NULL, NULL, -1}, +                        AD_LISTEND},                  Common::EN_ANY,                  Common::kPlatformWindows,                  ADGF_UNSTABLE, diff --git a/engines/pink/director.cpp b/engines/pink/director.cpp index 3d218cb682..3fa149e535 100644 --- a/engines/pink/director.cpp +++ b/engines/pink/director.cpp @@ -32,28 +32,28 @@ Director::Director(OSystem *system)      : _system(system), showBounds(0) {}  void Director::draw() { +    _system->fillScreen(0);      for (int i = 0; i < _sprites.size(); ++i) { -        CelDecoder *decoder = _sprites[i]->getDecoder(); -        drawSprite(decoder); +        drawSprite(_sprites[i]);      }      _system->updateScreen();  } -void Director::drawSprite(CelDecoder *decoder) { +void Director::drawSprite(ActionCEL *sprite) { +    CelDecoder *decoder = sprite->getDecoder();      const Graphics::Surface *surface;      if (decoder->needsUpdate())          surface = decoder->decodeNextFrame();      else surface = decoder->getCurrentFrame(); - -    uint16 colourIndex = decoder->getTransparentColourIndex(); -    if (!showBounds && colourIndex != 0) { +    if (!showBounds) {          Graphics::Surface *screen = _system->lockScreen(); +          for (int y = 0; y < decoder->getHeight(); ++y) {              for (int x = 0; x < decoder->getWidth(); ++x) { -                byte spritePixelColourIndex = *(byte*)surface->getBasePtr(x, y); -                if (spritePixelColourIndex != colourIndex && spritePixelColourIndex != 229) { // hack because sprite have wrong colour index +                uint16 spritePixelColourIndex = *(byte*)surface->getBasePtr(x, y); +                if (spritePixelColourIndex != decoder->getTransparentColourIndex()) {                      *(byte *) screen->getBasePtr(decoder->getX() + x, decoder->getY() + y) = spritePixelColourIndex;                  }              } @@ -115,4 +115,16 @@ void Director::clear() {      _sprites.clear();  } +Actor *Director::getActorByPoint(Common::Point point) { +    for (int i = _sprites.size() - 1; i > 0; --i) { +        CelDecoder *decoder = _sprites[i]->getDecoder(); +        if (decoder->getRectangle().contains(point) && +            *(byte*)decoder->getCurrentFrame()->getBasePtr(640 - point.x, 480 - point.y) +            != decoder->getTransparentColourIndex()) +            return _sprites[i]->getActor(); +    } + +    return nullptr; +} +  }
\ No newline at end of file diff --git a/engines/pink/director.h b/engines/pink/director.h index 63c622752b..b03f22edd6 100644 --- a/engines/pink/director.h +++ b/engines/pink/director.h @@ -25,9 +25,11 @@  #include <common/array.h>  #include <common/system.h> +#include <common/rect.h>  namespace Pink { +class Actor;  class ActionCEL;  class ActionSound;  class CelDecoder; @@ -49,10 +51,11 @@ public:      void clear(); +    Actor *getActorByPoint(Common::Point point);      bool showBounds;  private: -    void drawSprite(CelDecoder *decoder); +    void drawSprite(ActionCEL *sprite);      OSystem *_system;      Common::Array<ActionCEL*> _sprites;      Common::Array<ActionSound*> _sounds; diff --git a/engines/pink/objects/actions/action.h b/engines/pink/objects/actions/action.h index f981b523d6..72e9b8f989 100644 --- a/engines/pink/objects/actions/action.h +++ b/engines/pink/objects/actions/action.h @@ -40,6 +40,8 @@ public:      virtual bool initPalette(Director *director) { return 0;} +    Actor *getActor() { return _actor;} +  protected:      Actor *_actor;  }; diff --git a/engines/pink/objects/actions/action_cel.cpp b/engines/pink/objects/actions/action_cel.cpp index 7436c859fe..938d117015 100644 --- a/engines/pink/objects/actions/action_cel.cpp +++ b/engines/pink/objects/actions/action_cel.cpp @@ -23,6 +23,7 @@  #include <common/debug.h>  #include "action_cel.h"  #include <pink/objects/actors/actor.h> +#include <graphics/surface.h>  #include "engines/pink/archive.h"  #include "engines/pink/objects/pages/game_page.h"  #include "pink/pink.h" @@ -44,6 +45,7 @@ void ActionCEL::start(bool unk) {      if (!_decoder)          _decoder = _actor->getPage()->loadCel(_fileName);      _actor->getPage()->getGame()->getDirector()->addSprite(this); +      this->onStart();  } diff --git a/engines/pink/objects/actions/action_loop.cpp b/engines/pink/objects/actions/action_loop.cpp index 81760c5125..c821fb1530 100644 --- a/engines/pink/objects/actions/action_loop.cpp +++ b/engines/pink/objects/actions/action_loop.cpp @@ -55,7 +55,7 @@ void ActionLoop::update() {      // for now it supports only forward loop animation      if (_style == kForward) {          if (_decoder->endOfVideo()){ -            debug("ACTION LOOP : NEXT ITERATION"); +            //debug("ACTION LOOP : NEXT ITERATION");              _decoder->rewind();          }      } diff --git a/engines/pink/objects/actions/action_play_with_sfx.cpp b/engines/pink/objects/actions/action_play_with_sfx.cpp index 8c8cf6fa9d..fc4d48c40a 100644 --- a/engines/pink/objects/actions/action_play_with_sfx.cpp +++ b/engines/pink/objects/actions/action_play_with_sfx.cpp @@ -93,7 +93,8 @@ void ActionSfx::play(GamePage *page) {      if (!_sound)          _sound = page->loadSound(_sfxName); -    _sound->play(Audio::Mixer::SoundType::kSFXSoundType, _volume, 0); +    if (!_sound->isPlaying()) +        _sound->play(Audio::Mixer::SoundType::kSFXSoundType, _volume, 0);  }  ActionSfx::~ActionSfx() { diff --git a/engines/pink/objects/actions/action_play_with_sfx.h b/engines/pink/objects/actions/action_play_with_sfx.h index 020b380a58..c7aab59866 100644 --- a/engines/pink/objects/actions/action_play_with_sfx.h +++ b/engines/pink/objects/actions/action_play_with_sfx.h @@ -31,12 +31,11 @@ namespace Pink {  class ActionSfx;  class ActionPlayWithSfx : public ActionPlay { +public:      virtual ~ActionPlayWithSfx();      virtual void deserialize(Archive &archive);      virtual void toConsole();      virtual void update(); - -public:      virtual void end();  protected: diff --git a/engines/pink/objects/actors/actor.cpp b/engines/pink/objects/actors/actor.cpp index c6ea1dcb1c..2bd6af4f82 100644 --- a/engines/pink/objects/actors/actor.cpp +++ b/engines/pink/objects/actors/actor.cpp @@ -20,10 +20,12 @@   *   */ +#include <engines/pink/constants.h>  #include "actor.h"  #include "engines/pink/objects/pages/game_page.h"  #include "lead_actor.h"  #include "engines/pink/objects/actions/action.h" +#include "pink/cursor_mgr.h"  namespace Pink { @@ -122,4 +124,14 @@ bool Actor::initPallete(Director *director) {      return false;  } +void Actor::onMouseOver(Common::Point point, CursorMgr *mgr) { +    mgr->setCursor(kDefaultCursor, point); +} + +Actor::~Actor() { +    for (int i = 0; i < _actions.size(); ++i) { +        delete _actions[i]; +    } +} +  } // End of namespace Pink diff --git a/engines/pink/objects/actors/actor.h b/engines/pink/objects/actors/actor.h index 1d6fdf4bd4..270ac99914 100644 --- a/engines/pink/objects/actors/actor.h +++ b/engines/pink/objects/actors/actor.h @@ -24,6 +24,7 @@  #define PINK_ACTOR_H  #include <common/array.h> +#include <common/rect.h>  #include "engines/pink/objects/object.h"  namespace Pink { @@ -32,6 +33,7 @@ class GamePage;  class Action;  class Sequencer;  class Director; +class CursorMgr;  class Actor : public NamedObject {  public: @@ -39,6 +41,7 @@ public:       : _page(nullptr), _action(nullptr),          _isActionEnded(1)      {}; +    ~Actor();      virtual void deserialize(Archive &archive);      virtual void toConsole(); @@ -61,6 +64,9 @@ public:      virtual void update() {}; +    virtual void onMouseOver(Common::Point point, CursorMgr *mgr); + +    virtual bool isClickable() { return 0;}  protected:      GamePage *_page;      Action *_action; diff --git a/engines/pink/objects/actors/lead_actor.cpp b/engines/pink/objects/actors/lead_actor.cpp index be7dfbe879..e26b50a42c 100644 --- a/engines/pink/objects/actors/lead_actor.cpp +++ b/engines/pink/objects/actors/lead_actor.cpp @@ -29,13 +29,13 @@  #include "engines/pink/archive.h"  #include "engines/pink/objects/pages/game_page.h"  #include "engines/pink/pink.h" +#include "supporting_actor.h"  namespace Pink {  void LeadActor::deserialize(Archive &archive) {      _state = kReady;      Actor::deserialize(archive); -    _state = kReady;      _cursorMgr = static_cast<CursorMgr*>(archive.readObject());      _walkMgr = static_cast<WalkMgr*>(archive.readObject());      _sequencer = static_cast<Sequencer*>(archive.readObject()); @@ -70,18 +70,36 @@ LeadActor::State LeadActor::getState() const {  void LeadActor::update() {      switch (_state) { +        case kReady: + +            _sequencer->update(); +            //fall-through intended +        case kMoving: + +            _cursorMgr->update(); +            break; +        case kInDialog1: +        case kInDialog2: +            _sequencer->update(); +            break; + +        case kInventory: +        case kPDA: +            break; +          case kPlayingVideo:              _sequencer->update();              if (!_sequencer->_context){                  _state = kUnk_Loading;                  _page->getGame()->changeScene(_page);              } -        default: +            break; +        case kUnk_Loading:              break;      }  } -void LeadActor::OnKeyboardButtonClick(Common::KeyCode code) { +void LeadActor::onKeyboardButtonClick(Common::KeyCode code) {      switch(_state) {          case kMoving:              switch (code){ @@ -116,6 +134,73 @@ void LeadActor::OnKeyboardButtonClick(Common::KeyCode code) {      }  } +void LeadActor::start(bool isHandler) { +    if (isHandler && _state != kPlayingVideo){ +        _state = kReady; +    } +    updateCursor({0,0}); +} + +void LeadActor::onMouseMove(Common::Point point) { +    if (_state != kPDA) +        updateCursor(point); +    else error("pda is not supported"); +} + +void LeadActor::updateCursor(Common::Point point) { +    switch (_state) { +        case kReady: +        case kMoving: { +            Director *director = _page->getGame()->getDirector(); +            Actor *actor = director->getActorByPoint(point); +            if (actor) +                actor->onMouseOver(point, _cursorMgr); +            else _cursorMgr->setCursor(kDefaultCursor, point); +            break; +        } +        case kInDialog1: +        case kInDialog2: +        case kPlayingVideo: +            _cursorMgr->setCursor(kNotClickableCursor, point); +            break; +        case kPDA: +        case kInventory: +            _cursorMgr->setCursor(kDefaultCursor, point); +            break; +        default: +            break; +    } +} + +void LeadActor::onLeftButtonClick(Common::Point point) { +    switch (_state) { +        case kReady: +        case kMoving: { +        Actor *actor = _page->getGame()->getDirector()->getActorByPoint(point); +        if (this == actor){ +          // inventory is not implemented +            return; +        } + +        if (actor->isClickable() && +            ((SupportingActor*) actor)->isLeftClickHandlers()) + + + + +            break; +        } +        case kPDA: + +            break; +        case kInventory: + +            break; +        default: +            break; +    } +} +  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 4e17bf285a..3a64893991 100644 --- a/engines/pink/objects/actors/lead_actor.h +++ b/engines/pink/objects/actors/lead_actor.h @@ -24,6 +24,7 @@  #define PINK_LEAD_ACTOR_H  #include <common/keyboard.h> +#include <common/rect.h>  #include "actor.h"  namespace Pink { @@ -58,8 +59,14 @@ public:      void start(bool isHandler);      void update(); -    void OnKeyboardButtonClick(Common::KeyCode code); +    void onKeyboardButtonClick(Common::KeyCode code); +    void onLeftButtonClick(Common::Point point); +    void onMouseMove(Common::Point point); +  private: +    void updateCursor(Common::Point point); + +      State _state;      CursorMgr *_cursorMgr;      WalkMgr *_walkMgr; diff --git a/engines/pink/objects/actors/supporting_actor.cpp b/engines/pink/objects/actors/supporting_actor.cpp index 2cffbf16ce..a7e1b79954 100644 --- a/engines/pink/objects/actors/supporting_actor.cpp +++ b/engines/pink/objects/actors/supporting_actor.cpp @@ -23,7 +23,8 @@  #include "supporting_actor.h"  #include <engines/pink/archive.h>  #include <engines/pink/objects/actions/action.h> -#include <common/debug.h> +#include <engines/pink/constants.h> +#include "pink/cursor_mgr.h"  namespace Pink { @@ -42,4 +43,18 @@ void SupportingActor::toConsole() {      _handlerMgr.toConsole();  } +void SupportingActor::onMouseOver(Common::Point point, CursorMgr *mgr) { +    if (isLeftClickHandlers()){ +        if (!_cursor.empty()){ +            mgr->setCursor(_cursor, point); +        } +        else mgr->setCursor(kClickableFirstFrameCursor, point); +    } +    else Actor::onMouseOver(point, mgr); +} + +bool SupportingActor::isLeftClickHandlers() { +    return _handlerMgr.isLeftClickHandler(this); +} +  } // End of namespace Pink
\ No newline at end of file diff --git a/engines/pink/objects/actors/supporting_actor.h b/engines/pink/objects/actors/supporting_actor.h index a9dd69a495..bfee083dbd 100644 --- a/engines/pink/objects/actors/supporting_actor.h +++ b/engines/pink/objects/actors/supporting_actor.h @@ -33,6 +33,11 @@ public:      virtual void deserialize(Archive &archive);      virtual void toConsole(); +    virtual void onMouseOver(Common::Point point, CursorMgr *mgr); + +    virtual bool isClickable() { return 1; } +    bool isLeftClickHandlers(); +  private:      HandlerMgr _handlerMgr;      Common::String _location; diff --git a/engines/pink/objects/condition.cpp b/engines/pink/objects/condition.cpp index 71a68d4f3a..b0e093817e 100644 --- a/engines/pink/objects/condition.cpp +++ b/engines/pink/objects/condition.cpp @@ -32,7 +32,7 @@ void Pink::ConditionVariable::deserialize(Archive &archive) {      archive >> _name >> _value;  } -bool Pink::ConditionGameVariable::evaluate(LeadActor *leadActor) { +bool Pink::ConditionGameVariable::evaluate(Actor *leadActor) {      return leadActor->getPage()->getModule()->getGame()->checkValueOfVariable(_name, _value);  } @@ -40,7 +40,7 @@ void ConditionGameVariable::toConsole() {      debug("\t\tConditionGameVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str());  } -bool Pink::ConditionModuleVariable::evaluate(LeadActor *leadActor) { +bool Pink::ConditionModuleVariable::evaluate(Actor *leadActor) {      return leadActor->getPage()->getModule()->checkValueOfVariable(_name, _value);  } @@ -48,7 +48,7 @@ void ConditionModuleVariable::toConsole() {      debug("\t\tConditionModuleVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str());  } -bool Pink::ConditionNotModuleVariable::evaluate(LeadActor *leadActor) { +bool Pink::ConditionNotModuleVariable::evaluate(Actor *leadActor) {      return !ConditionModuleVariable::evaluate(leadActor);  } @@ -56,7 +56,7 @@ void ConditionNotModuleVariable::toConsole() {      debug("\t\tConditionNotModuleVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str());  } -bool ConditionPageVariable::evaluate(LeadActor *leadActor) { +bool ConditionPageVariable::evaluate(Actor *leadActor) {      return leadActor->getPage()->checkValueOfVariable(_name, _value);  } @@ -64,7 +64,7 @@ void ConditionPageVariable::toConsole() {      debug("\t\tConditionPageVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str());  } -bool ConditionNotPageVariable::evaluate(LeadActor *leadActor) { +bool ConditionNotPageVariable::evaluate(Actor *leadActor) {      return !ConditionPageVariable::evaluate(leadActor);  } @@ -76,7 +76,7 @@ void ConditionInventoryItemOwner::deserialize(Archive &archive) {      archive >> _item >> _owner;  } -bool ConditionInventoryItemOwner::evaluate(LeadActor *leadActor) { +bool ConditionInventoryItemOwner::evaluate(Actor *leadActor) {      InventoryMgr *mgr = leadActor->getPage()->getModule()->getInventoryMgr();      InventoryItem *item = mgr->findInventoryItem(_item);      return item->getCurrentOwner() == _owner; @@ -86,7 +86,7 @@ void ConditionInventoryItemOwner::toConsole() {      debug("\t\tConditionInventoryItemOwner: _item=%s, _owner=%s", _item.c_str(), _owner.c_str());  } -bool ConditionNotInventoryItemOwner::evaluate(LeadActor *leadActor) { +bool ConditionNotInventoryItemOwner::evaluate(Actor *leadActor) {      return !ConditionInventoryItemOwner::evaluate(leadActor);  } diff --git a/engines/pink/objects/condition.h b/engines/pink/objects/condition.h index 6df1920046..3ab1ff0b50 100644 --- a/engines/pink/objects/condition.h +++ b/engines/pink/objects/condition.h @@ -32,14 +32,14 @@ class LeadActor;  class Condition : public Object {  public:      virtual void deserialize(Archive &archive) = 0; -    virtual bool evaluate(LeadActor *leadActor) = 0; +    virtual bool evaluate(Actor *leadActor) = 0;  };  class ConditionVariable : public Condition {  public:      virtual void deserialize(Archive &archive); -    virtual bool evaluate(LeadActor *leadActor) = 0; +    virtual bool evaluate(Actor *actor) = 0;  protected:      Common::String _name; @@ -49,7 +49,7 @@ protected:  class ConditionGameVariable : public ConditionVariable {  public:      virtual void toConsole(); -    virtual bool evaluate(LeadActor *leadActor); +    virtual bool evaluate(Actor *actor);  };  /* @@ -62,32 +62,32 @@ class ConditionNotGameVariable : public ConditionGameVariable {  class ConditionModuleVariable : public ConditionVariable {  public:      virtual void toConsole(); -    virtual bool evaluate(LeadActor *leadActor); +    virtual bool evaluate(Actor *actor);  };  class ConditionNotModuleVariable : public ConditionModuleVariable {  public:      virtual void toConsole(); -    virtual bool evaluate(LeadActor *leadActor); +    virtual bool evaluate(Actor *actor);  };  class ConditionPageVariable : public ConditionVariable {  public:      virtual void toConsole(); -    virtual bool evaluate(LeadActor *leadActor); +    virtual bool evaluate(Actor *actor);  };  class ConditionNotPageVariable : public ConditionPageVariable {  public:      virtual void toConsole(); -    virtual bool evaluate(LeadActor *leadActor); +    virtual bool evaluate(Actor *actor);  };  class ConditionInventoryItemOwner : public Condition {  public:      virtual void toConsole();      virtual void deserialize(Archive &archive); -    virtual bool evaluate(LeadActor *leadActor); +    virtual bool evaluate(Actor *actor);  protected:      Common::String _item; @@ -97,7 +97,7 @@ protected:  class ConditionNotInventoryItemOwner : public ConditionInventoryItemOwner {  public:      virtual void toConsole(); -    virtual bool evaluate(LeadActor *leadActor); +    virtual bool evaluate(Actor *actor);  };  } // End of namespace Pink diff --git a/engines/pink/objects/handlers/handler.cpp b/engines/pink/objects/handlers/handler.cpp index a848cfd98e..8916bc0b3b 100644 --- a/engines/pink/objects/handlers/handler.cpp +++ b/engines/pink/objects/handlers/handler.cpp @@ -37,7 +37,7 @@ void Handler::deserialize(Archive &archive) {      archive >> _sideEffects;  } -bool Handler::isSuitable(LeadActor *actor) { +bool Handler::isSuitable(Actor *actor) {      for (int i = 0; i < _conditions.size(); ++i) {          if (!_conditions[i]->evaluate(actor)){              return false; @@ -56,6 +56,15 @@ void Handler::onMessage(LeadActor *actor) {      executeSideEffects(actor);  } +Handler::~Handler() { +    for (int i = 0; i < _sideEffects.size(); ++i) { +        delete _sideEffects[i]; +    } +    for (int i = 0; i < _conditions.size(); ++i) { +        delete _conditions[i]; +    } +} +  void HandlerSequences::deserialize(Archive &archive) {      Handler::deserialize(archive);      archive >> _sequences; diff --git a/engines/pink/objects/handlers/handler.h b/engines/pink/objects/handlers/handler.h index b2e5fcf2d7..ed42ed7cde 100644 --- a/engines/pink/objects/handlers/handler.h +++ b/engines/pink/objects/handlers/handler.h @@ -33,12 +33,14 @@ namespace Pink {  class Condition;  class SideEffect;  class LeadActor; +class Actor;  class Handler : public Object {  public: +    ~Handler();      virtual void deserialize(Archive &archive);      virtual void onMessage(LeadActor *actor); -    bool isSuitable(LeadActor *actor); +    bool isSuitable(Actor *actor);  protected:      void executeSideEffects(LeadActor *actor); diff --git a/engines/pink/objects/handlers/handler_mgr.cpp b/engines/pink/objects/handlers/handler_mgr.cpp index 6e7755a804..83236de6a1 100644 --- a/engines/pink/objects/handlers/handler_mgr.cpp +++ b/engines/pink/objects/handlers/handler_mgr.cpp @@ -27,4 +27,13 @@ void HandlerMgr::toConsole() {      }  } +bool HandlerMgr::isLeftClickHandler(Actor *actor) { +    for (int i = 0; i < _leftClickHandlers.size(); ++i) { +        if (_leftClickHandlers[i]->isSuitable(actor)) +            return true; +    } + +    return false; +} +  } diff --git a/engines/pink/objects/handlers/handler_mgr.h b/engines/pink/objects/handlers/handler_mgr.h index 0de44cf004..f939d592da 100644 --- a/engines/pink/objects/handlers/handler_mgr.h +++ b/engines/pink/objects/handlers/handler_mgr.h @@ -31,6 +31,7 @@ namespace Pink {  class HandlerLeftClick;  class HandlerUseClick;  class HandlerTimer; +class Actor;  class HandlerMgr : public Object {  public: @@ -38,6 +39,8 @@ public:      virtual void toConsole(); +    bool isLeftClickHandler(Actor *actor); +  private:      Common::Array<HandlerLeftClick*> _leftClickHandlers;      Common::Array<HandlerUseClick*> _useClickHandlers; diff --git a/engines/pink/objects/module.cpp b/engines/pink/objects/module.cpp index a8166dee43..f7b6adda87 100644 --- a/engines/pink/objects/module.cpp +++ b/engines/pink/objects/module.cpp @@ -93,6 +93,12 @@ InventoryMgr *Module::getInventoryMgr() {      return &_invMgr;  } +Module::~Module() { +    for (int i = 0; i < _pages.size(); ++i) { +        delete _pages[i]; +    } +} +  } // End of namespace Pink diff --git a/engines/pink/objects/module.h b/engines/pink/objects/module.h index 959f886a83..2824191dcd 100644 --- a/engines/pink/objects/module.h +++ b/engines/pink/objects/module.h @@ -43,6 +43,7 @@ class GamePage;  class Module : public NamedObject {  public:      Module(PinkEngine *game, const Common::String &name); +    ~Module();      void load(Archive &archive);      void init(bool isLoadingSave, const Common::String &pageName); diff --git a/engines/pink/objects/pages/game_page.cpp b/engines/pink/objects/pages/game_page.cpp index 5ff7f0bdc3..6a90b4887b 100644 --- a/engines/pink/objects/pages/game_page.cpp +++ b/engines/pink/objects/pages/game_page.cpp @@ -77,7 +77,7 @@ void GamePage::init(bool isLoadingSave) {          isHandler = initHandler();      } -    //_leadActor->start(isHandler); +    _leadActor->start(isHandler);  }  bool GamePage::initHandler() { @@ -92,7 +92,7 @@ bool GamePage::initHandler() {  void GamePage::loadManagers() {      perhapsIsLoaded = true; -    _cursorMgr = new CursorMgr(this); +    _cursorMgr = new CursorMgr(_module->getGame(), this);      _walkMgr = new WalkMgr;      _sequencer = new Sequencer(this); @@ -137,4 +137,19 @@ void GamePage::toConsole() {      }  } +GamePage::~GamePage() { +    delete _cursorMgr; +    delete _walkMgr; +    delete _sequencer; +    for (int i = 0; i < _handlers.size(); ++i) { +        delete _handlers[i]; +    } +} + +GamePage::GamePage() +    : _cursorMgr(nullptr), _walkMgr(nullptr), _sequencer(nullptr) +{ + +} +  } // End of namespace Pink
\ No newline at end of file diff --git a/engines/pink/objects/pages/game_page.h b/engines/pink/objects/pages/game_page.h index 94bff54200..705fb32e22 100644 --- a/engines/pink/objects/pages/game_page.h +++ b/engines/pink/objects/pages/game_page.h @@ -34,6 +34,8 @@ class HandlerStartPage;  class GamePage : public Page {  public: +    GamePage(); +    ~GamePage();      virtual void deserialize(Archive &archive);      virtual void load(Archive &archive); diff --git a/engines/pink/objects/pages/page.cpp b/engines/pink/objects/pages/page.cpp index a57860e11d..a579d19d5f 100644 --- a/engines/pink/objects/pages/page.cpp +++ b/engines/pink/objects/pages/page.cpp @@ -65,4 +65,10 @@ void Page::init() {      }  } +Page::~Page() { +    for (int i = 0; i < _actors.size(); ++i) { +        delete _actors[i]; +    } +} +  } // End of namespace Pink diff --git a/engines/pink/objects/pages/page.h b/engines/pink/objects/pages/page.h index 282d061f1e..81a49db9f6 100644 --- a/engines/pink/objects/pages/page.h +++ b/engines/pink/objects/pages/page.h @@ -36,7 +36,7 @@ class LeadActor;  class Page : public NamedObject {  public: - +    ~Page();      void load(Archive &archive);      Actor *findActor(Common::String &name);      Sound* loadSound(Common::String &fileName); diff --git a/engines/pink/objects/sequences/sequence.cpp b/engines/pink/objects/sequences/sequence.cpp index 2071683681..098330bf03 100644 --- a/engines/pink/objects/sequences/sequence.cpp +++ b/engines/pink/objects/sequences/sequence.cpp @@ -134,6 +134,11 @@ void Sequence::skipItemsTo(int index) {      }  } +void Sequence::skipSubSequence() { +    if (_context->getNextItemIndex() < _context->getSequence()->getItems().size()) +        _context->getSequence()->start(0); +} +  void SequenceAudio::deserialize(Archive &archive) {      Sequence::deserialize(archive);      archive >> _soundName; @@ -182,4 +187,8 @@ void SequenceAudio::restart() {      Sequence::restart();  } +void SequenceAudio::skipToLastSubSequence() { +    end(); +} +  } // End of namespace Pink
\ No newline at end of file diff --git a/engines/pink/objects/sequences/sequence.h b/engines/pink/objects/sequences/sequence.h index e4695f2088..5db00b4920 100644 --- a/engines/pink/objects/sequences/sequence.h +++ b/engines/pink/objects/sequences/sequence.h @@ -49,9 +49,11 @@ public:      virtual void update();      virtual void restart(); -    void skipToLastSubSequence(); +    virtual void skipSubSequence(); +    virtual void skipToLastSubSequence();      void skipItemsTo(int index); +  public:      SequenceContext *_context;      Sequencer *_sequencer; @@ -69,9 +71,13 @@ public:      virtual void init(int unk);      virtual void start(int unk);      virtual void end(); +      virtual void update();      virtual void restart(); +    virtual void skipSubSequence() {}; +    virtual void skipToLastSubSequence(); +  private:      Common::String _soundName;      Sound *_sound; diff --git a/engines/pink/objects/sequences/sequencer.cpp b/engines/pink/objects/sequences/sequencer.cpp index 057603a790..871a2e2621 100644 --- a/engines/pink/objects/sequences/sequencer.cpp +++ b/engines/pink/objects/sequences/sequencer.cpp @@ -73,7 +73,8 @@ void Sequencer::toConsole() {  }  void Sequencer::update() { -    _context->_sequence->update(); +    if (_context) +        _context->_sequence->update();  }  void Sequencer::removeContext(SequenceContext *context) { @@ -82,8 +83,8 @@ void Sequencer::removeContext(SequenceContext *context) {  }  void Sequencer::skipSubSequence() { -    if (_context && _context->getNextItemIndex() < _context->getSequence()->getItems().size()) -        _context->getSequence()->start(0); +    if (_context) +        _context->getSequence()->skipSubSequence();  }  void Sequencer::restartSequence() { diff --git a/engines/pink/pink.cpp b/engines/pink/pink.cpp index a4b603dcef..9cc0ee5145 100644 --- a/engines/pink/pink.cpp +++ b/engines/pink/pink.cpp @@ -28,6 +28,8 @@  #include "engines/pink/objects/module.h"  #include "engines/pink/objects/actors/lead_actor.h"  #include <graphics/surface.h> +#include <graphics/cursorman.h> +#include <common/winexe_pe.h>  namespace Pink { @@ -51,6 +53,9 @@ Pink::PinkEngine::~PinkEngine() {      for (uint i = 0; i < _modules.size(); ++i) {          delete _modules[i];      } +    for (int j = 0; j < _cursors.size(); ++j) { +        delete _cursors[j]; +    }      DebugMan.clearAllDebugChannels();  } @@ -65,7 +70,7 @@ Common::Error PinkEngine::init() {      Common::String orbName{_desc.filesDescriptions[0].fileName};      Common::String broName{_desc.filesDescriptions[1].fileName}; -    if (!broName.empty()){ +    if (strcmp(_desc.gameId, "peril") == 0){          _bro = new BroFile();      }      else debug("This game doesn't need to use bro"); @@ -74,8 +79,11 @@ Common::Error PinkEngine::init() {          return Common::kNoGameDataFoundError;      } -    // TODO load cursor +    if (!loadCursors()) +        return Common::kNoGameDataFoundError; +    setCursor(kLoadingCursor); +    _system->showMouse(1);      _orb.loadGame(this);      const Common::String empty; @@ -86,10 +94,8 @@ Common::Error PinkEngine::init() {  Common::Error Pink::PinkEngine::run() {      Common::Error error = init(); -    if (error.getCode() != Common::kNoError){ +    if (error.getCode() != Common::kNoError)          return error; -    } -      while(!shouldQuit()){          Common::Event event; @@ -99,15 +105,15 @@ Common::Error Pink::PinkEngine::run() {                  case Common::EVENT_RTL:                      return Common::kNoError;                  case Common::EVENT_MOUSEMOVE: - +                    _actor->onMouseMove(event.mouse);                      break;                  case Common::EVENT_LBUTTONDOWN: - +                    _actor->onLeftButtonClick(event.mouse);                      break;                  case Common::EVENT_KEYDOWN:                      if (event.kbd.keycode == Common::KEYCODE_d)                          _director.showBounds = !_director.showBounds; -                    else _actor->OnKeyboardButtonClick(event.kbd.keycode); +                    else _actor->onKeyboardButtonClick(event.kbd.keycode);                      break;                      // don't know why it is used in original @@ -118,10 +124,11 @@ Common::Error Pink::PinkEngine::run() {              }          } +          _actor->update();             _director.update();          _director.draw(); -        _system->delayMillis(50); +        _system->delayMillis(5);      }      return Common::kNoError; @@ -135,35 +142,30 @@ void PinkEngine::load(Archive &archive) {  void PinkEngine::initModule(const Common::String &moduleName, bool isLoadingFromSave, const Common::String &pageName) {      if (_module) { +        for (uint i = 0; i < _modules.size(); ++i) { +            if (_module == _modules[i]){ +                _modules[i] = new ModuleProxy(_module->getName()); -        //call module function (smth with unloading) +                delete _module; +                _module = nullptr; -        uint i; -        for (i = 0; i < _modules.size(); ++i) { -            if (_module == _modules[i]){                  break;              }          } - -        _modules[i] = new ModuleProxy(_module->getName()); - -        delete _module; -        _module = nullptr;      } -    uint i; -    for (i = 0; i < _modules.size(); ++i) { +    for (uint i = 0; i < _modules.size(); ++i) {          if (_modules[i]->getName() == moduleName) {              loadModule(i); +            _module = static_cast<Module*>(_modules[i]); +            _module->init(isLoadingFromSave, pageName);              break;          }      } - -    _module = static_cast<Module*>(_modules[i]); -    _module->init(isLoadingFromSave, pageName);  }  void PinkEngine::changeScene(GamePage *page) { +    setCursor(kLoadingCursor);      if (!_nextModule.empty() && _nextModule.compareTo(_module->getName())) {          initModule(_nextModule, kLoadingNewGame, _nextPage);      } @@ -198,4 +200,47 @@ void PinkEngine::setVariable(Common::String &variable, Common::String &value) {      _variables[variable] = value;  } +bool PinkEngine::loadCursors() { +    Common::PEResources exeResources; +    bool isPokus = !strcmp(_desc.gameId, "pokus"); +    Common::String fileName = isPokus ? _desc.filesDescriptions[1].fileName : _desc.filesDescriptions[2].fileName; +    if (!exeResources.loadFromEXE(fileName)) +        return false; + +    _cursors.reserve(kCursorsCount); + +    _cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusLoadingCursorID)); +    _cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusExitForwardCursorID)); +    _cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusExitLeftCursorID)); +    _cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusExitRightCursorID)); +    _cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusClickableFirstCursorID)); +    _cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusClickableSecondCursorID)); + +    if (isPokus) { +        _cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusClickableThirdCursorID)); +        _cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusNotClickableCursorID)); +    } +    else { +        _cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPerilClickableThirdCursorID)); +        _cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPerilNotClickableCursorID)); +    } + +    _cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusHoldingItemCursorID)); +    _cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusPDAFirstCursorID)); + +    if (isPokus) +        _cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusPDASecondCursorID)); +    else +        _cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPerilPDASecondCursorID)); + +    return true; +} + +void PinkEngine::setCursor(uint cursorIndex) { +    Graphics::Cursor *cursor = _cursors[cursorIndex]->cursors[0].cursor; +    _system->setCursorPalette(cursor->getPalette(), cursor->getPaletteStartIndex(), cursor->getPaletteCount()); +    _system->setMouseCursor(cursor->getSurface(), cursor->getWidth(), cursor->getHeight(), +                            cursor->getHotspotX(), cursor->getHotspotY(), cursor->getKeyColor()); +} +  }
\ No newline at end of file diff --git a/engines/pink/pink.h b/engines/pink/pink.h index 63a9a21fca..32de7c9f1e 100644 --- a/engines/pink/pink.h +++ b/engines/pink/pink.h @@ -23,13 +23,14 @@  #ifndef PINK_PINK_H  #define PINK_PINK_H +#include <graphics/wincursor.h>  #include "common/random.h"  #include "engines/engine.h"  #include "gui/EventRecorder.h"  #include "gui/debugger.h"  #include "file.h"  #include "director.h" - +#include "constants.h"  /*   *  This is the namespace of the Pink engine. @@ -60,11 +61,6 @@ enum {      kPinkDebugSound = 1 << 4  }; -enum { -    kLoadingSave = 1, -    kLoadingNewGame = 0 -}; -  class PinkEngine : public Engine {  public:      PinkEngine(OSystem *system, const ADGameDescription *desc); @@ -87,14 +83,16 @@ public:      void setVariable(Common::String &variable, Common::String &value);      bool checkValueOfVariable(Common::String &variable, Common::String &value); +    inline void setCursor(uint cursorIndex);  private:      Common::Error init(); -    void loadModule(int index); - +    bool loadCursors(); +    void loadModule(int index);      Console *_console;      Common::RandomSource _rnd; +    Common::Array<Graphics::WinCursorGroup*> _cursors;      Common::String _nextModule;      Common::String _nextPage; diff --git a/engines/pink/sound.cpp b/engines/pink/sound.cpp index b02275181e..fda91e548a 100644 --- a/engines/pink/sound.cpp +++ b/engines/pink/sound.cpp @@ -23,24 +23,24 @@  #include <audio/audiostream.h>  #include <audio/decoders/wave.h>  #include <audio/decoders/adpcm.h> +#include <common/substream.h>  #include "sound.h"  namespace Pink { -Sound::Sound(Audio::Mixer *mixer, Common::SeekableReadStream *stream) -    : _mixer(mixer) +Sound::Sound(Audio::Mixer *mixer, Common::SafeSeekableSubReadStream *stream) +    : _mixer(mixer), _fileStream(stream)  { -    load(stream); +  }  Sound::~Sound() {      stop(); -    delete _stream; +    delete _fileStream;  }  bool Sound::isPlaying() {      return _mixer->isSoundHandleActive(_handle); -  }  void Sound::pause() { @@ -56,28 +56,19 @@ void Sound::stop() {  }  void Sound::play(Audio::Mixer::SoundType type, int volume, bool isLoop) { +    // Vox files in pink have wave format. +    // RIFF (little-endian) data, WAVE audio, Microsoft PCM, 8 bit, mono 22050 Hz      _mixer->stopHandle(_handle); +    _fileStream->seek(0); +    Audio::AudioStream *audioStream ; +    Audio::SeekableAudioStream *wavStream = Audio::makeWAVStream(_fileStream, DisposeAfterUse::NO);      if (isLoop) { -        //bad impl? -        Audio::SeekableAudioStream *seekableStream = dynamic_cast<Audio::SeekableAudioStream*>(_stream); -        _stream = Audio::makeLoopingAudioStream(seekableStream, 0, 0, 0); +        audioStream = Audio::makeLoopingAudioStream(wavStream, 0, 0, 0);      } +    else audioStream = wavStream; -    _mixer->playStream(type, &_handle ,_stream, -1 , Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO); -} - -bool Sound::load(Common::SeekableReadStream *stream) { -    // Vox files in pink have wave format. -    // RIFF (little-endian) data, WAVE audio, Microsoft PCM, 8 bit, mono 22050 Hz - -    _stream = Audio::makeWAVStream(stream, DisposeAfterUse::YES); - -    return isLoaded(); -} - -bool Sound::isLoaded() { -    return _stream != nullptr; +    _mixer->playStream(type, &_handle , audioStream, -1 , Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::YES);  }  void Sound::setBalance(int8 balance) { diff --git a/engines/pink/sound.h b/engines/pink/sound.h index 9e9dbdff62..0116825800 100644 --- a/engines/pink/sound.h +++ b/engines/pink/sound.h @@ -36,13 +36,11 @@ namespace Pink {  class Sound {  public: -    Sound(Audio::Mixer *mixer, Common::SeekableReadStream *stream); +    Sound(Audio::Mixer *mixer, Common::SafeSeekableSubReadStream *stream);      ~Sound(); -    bool load(Common::SeekableReadStream *stream);      void play(Audio::Mixer::SoundType type, int volume, bool isLoop); -    bool isLoaded();      bool isPlaying();      void pause(); @@ -54,8 +52,8 @@ public:  private:      Audio::Mixer *_mixer; -    Audio::AudioStream *_stream;      Audio::SoundHandle _handle; +    Common::SafeSeekableSubReadStream *_fileStream;  };  } // End of namespace Pink  | 
