diff options
author | Paul Gilbert | 2015-06-02 21:26:42 -0400 |
---|---|---|
committer | Paul Gilbert | 2015-06-02 21:26:42 -0400 |
commit | 1f9d1e9c16da9fa6484b49dc4e4b05a89387116d (patch) | |
tree | fc3b29cd8a20af386814e2cc9ab539a2f96b33fc /engines/sherlock/tattoo | |
parent | fdd220e9f77658d765ecf2c9d2e5fb4f022663ea (diff) | |
download | scummvm-rg350-1f9d1e9c16da9fa6484b49dc4e4b05a89387116d.tar.gz scummvm-rg350-1f9d1e9c16da9fa6484b49dc4e4b05a89387116d.tar.bz2 scummvm-rg350-1f9d1e9c16da9fa6484b49dc4e4b05a89387116d.zip |
SHERLOCK: Implement RT drawAllShapes and support methods
Diffstat (limited to 'engines/sherlock/tattoo')
-rw-r--r-- | engines/sherlock/tattoo/tattoo_scene.cpp | 171 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo_scene.h | 11 |
2 files changed, 182 insertions, 0 deletions
diff --git a/engines/sherlock/tattoo/tattoo_scene.cpp b/engines/sherlock/tattoo/tattoo_scene.cpp index 8a3c5864b7..6c7af3274b 100644 --- a/engines/sherlock/tattoo/tattoo_scene.cpp +++ b/engines/sherlock/tattoo/tattoo_scene.cpp @@ -36,6 +36,172 @@ TattooScene::TattooScene(SherlockEngine *vm) : Scene(vm) { _maskCounter = 0; } +struct ShapeEntry { + Object *_shape; + Person *_person; + bool _isAnimation; + int _yp; + + ShapeEntry(Person *person, int yp) : _shape(nullptr), _person(person), _yp(yp), _isAnimation(false) {} + ShapeEntry(Object *shape, int yp) : _shape(shape), _person(nullptr), _yp(yp), _isAnimation(false) {} + ShapeEntry(int yp) : _shape(nullptr), _person(nullptr), _yp(yp), _isAnimation(true) {} + int personNum; +}; +typedef Common::List<ShapeEntry> ShapeList; + +static bool sortImagesY(const ShapeEntry &s1, const ShapeEntry &s2) { + return s1._yp <= s2._yp; +} + +void TattooScene::drawAllShapes() { + People &people = *_vm->_people; + Screen &screen = *_vm->_screen; + TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui; + ShapeList shapeList; + + // Draw all objects and animations that are set to behind + screen.setDisplayBounds(Common::Rect(ui._currentScroll.x, 0, ui._currentScroll.x + SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + + // Draw all active shapes which are behind the person + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + Object &obj = _bgShapes[idx]; + + if (obj._type == ACTIVE_BG_SHAPE && obj._misc == BEHIND) { + if (obj._quickDraw && obj._scaleVal == 256) + screen._backBuffer1.blitFrom(*obj._imageFrame, obj._position); + else + screen._backBuffer1.transBlitFrom(*obj._imageFrame, obj._position, obj._flags & OBJ_FLIPPED, 0, obj._scaleVal); + } + } + + // Draw the animation if it is behind the person + if (_activeCAnim._imageFrame != nullptr && _activeCAnim._zPlacement == BEHIND) + screen._backBuffer1.transBlitFrom(*_activeCAnim._imageFrame, _activeCAnim._position, + (_activeCAnim._flags & 4) >> 1, 0, _activeCAnim._scaleVal); + + screen.setDisplayBounds(Common::Rect(0, 0, screen._backBuffer1.w(), screen._backBuffer1.h())); + + // Queue drawing of all objects that are set to NORMAL. + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + Object &obj = _bgShapes[idx]; + + if (obj._type == ACTIVE_BG_SHAPE && (obj._misc == NORMAL_BEHIND || obj._misc == NORMAL_FORWARD)) { + if (obj._scaleVal == 256) + shapeList.push_back(ShapeEntry(&obj, obj._position.y + obj._imageFrame->_offset.y + + obj._imageFrame->_height)); + else + shapeList.push_back(ShapeEntry(&obj, obj._position.y + obj._imageFrame->sDrawYOffset(obj._scaleVal) + + obj._imageFrame->sDrawYSize(obj._scaleVal))); + } + } + + // Queue drawing the animation if it is NORMAL and can fall in front of, or behind the people + if (_activeCAnim._imageFrame != nullptr && (_activeCAnim._zPlacement == NORMAL_BEHIND) || _activeCAnim._zPlacement == NORMAL_FORWARD) { + if (_activeCAnim._scaleVal == 256) + if (_activeCAnim._scaleVal == 256) + shapeList.push_back(ShapeEntry(_activeCAnim._position.y + _activeCAnim._imageFrame->_offset.y + + _activeCAnim._imageFrame->_height)); + else + shapeList.push_back(ShapeEntry(_activeCAnim._position.y + _activeCAnim._imageFrame->sDrawYOffset(_activeCAnim._scaleVal) + + _activeCAnim._imageFrame->sDrawYSize(_activeCAnim._scaleVal))); + } + + // Queue all active characters for drawing + for (uint idx = 0; idx < MAX_CHARACTERS; ++idx) { + if (people[idx]._type == CHARACTER && people[idx]._walkLoaded) + shapeList.push_back(ShapeEntry(&people[idx], people[idx]._position.y / FIXED_INT_MULTIPLIER)); + } + + // Sort the list + Common::sort(shapeList.begin(), shapeList.end(), sortImagesY); + + // Draw the list of shapes in order + for (ShapeList::iterator i = shapeList.begin(); i != shapeList.end(); ++i) { + ShapeEntry &se = *i; + + if (se._shape) { + // it's a bg shape + if (se._shape->_quickDraw && se._shape->_scaleVal == 256) + screen._backBuffer1.blitFrom(*se._shape->_imageFrame, se._shape->_position); + else + screen._backBuffer1.transBlitFrom(*se._shape->_imageFrame, se._shape->_position, + se._shape->_flags & OBJ_FLIPPED, 0, se._shape->_scaleVal); + } else if (se._isAnimation) { + // It's an active animation + screen._backBuffer1.transBlitFrom(*_activeCAnim._imageFrame, _activeCAnim._position, + (_activeCAnim._flags & 4) >> 1, 0, _activeCAnim._scaleVal); + } else { + // Drawing person + Person &p = *se._person; + + p._tempX = p._position.x / FIXED_INT_MULTIPLIER; + p._tempScaleVal = getScaleVal(p._position); + Common::Point adjust = p._adjust; + + if (p._tempScaleVal == 256) { + p._tempX += adjust.x; + screen._backBuffer1.transBlitFrom(*p._imageFrame, Common::Point(p._tempX, p._position.y / FIXED_INT_MULTIPLIER + - p.frameHeight() - adjust.y), p._walkSequences[p._sequenceNumber]._horizFlip, 0, p._tempScaleVal); + } else { + if (adjust.x) { + if (!p._tempScaleVal) + ++p._tempScaleVal; + + if (p._tempScaleVal >= 256 && adjust.x) + --adjust.x; + + adjust.x = adjust.x * 256 / p._tempScaleVal; + + if (p._tempScaleVal >= 256) + ++adjust.x; + p._tempX += adjust.x; + } + + if (adjust.y) + { + if (!p._tempScaleVal) + p._tempScaleVal++; + + if (p._tempScaleVal >= 256 && adjust.y) + --adjust.y; + + adjust.y = adjust.y * 256 / p._tempScaleVal; + + if (p._tempScaleVal >= 256) + ++adjust.y; + } + + screen._backBuffer1.transBlitFrom(*p._imageFrame, Common::Point(p._tempX, p._position.y / FIXED_INT_MULTIPLIER + - p._imageFrame->sDrawYSize(p._tempScaleVal) - adjust.y), p._walkSequences[p._sequenceNumber]._horizFlip, 0, p._tempScaleVal); + } + } + } + + // Draw all objects & canimations that are set to FORWARD. + // Draw all static and active shapes that are FORWARD + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + Object &obj = _bgShapes[idx]; + + if (obj._type == ACTIVE_BG_SHAPE && obj._misc == FORWARD) { + if (obj._quickDraw && obj._scaleVal == 256) + screen._backBuffer1.blitFrom(*obj._imageFrame, obj._position); + else + screen._backBuffer1.transBlitFrom(*obj._imageFrame, obj._position, obj._flags & OBJ_FLIPPED, 0, obj._scaleVal); + } + } + + // Draw the canimation if it is set as FORWARD + if (_activeCAnim._imageFrame != nullptr && _activeCAnim._zPlacement == FORWARD) + screen._backBuffer1.transBlitFrom(*_activeCAnim._imageFrame, _activeCAnim._position, (_activeCAnim._flags & 4) >> 1, 0, _activeCAnim._scaleVal); + + // Draw all NO_SHAPE shapes which have their flag bits clear + for (uint idx = 0; idx < _bgShapes.size(); ++idx) { + Object &obj = _bgShapes[idx]; + if (obj._type == NO_SHAPE && (obj._flags & 1) == 0) + screen._backBuffer1.fillRect(obj.getNoShapeBounds(), 15); + } +} + void TattooScene::checkBgShapes() { People &people = *_vm->_people; Person &holmes = people._player; @@ -491,6 +657,11 @@ void TattooScene::doBgAnimDrawSprites() { } } +int TattooScene::getScaleVal(const Common::Point &pt) { + error("TODO: getScaleVal"); +} + + } // End of namespace Tattoo } // End of namespace Sherlock diff --git a/engines/sherlock/tattoo/tattoo_scene.h b/engines/sherlock/tattoo/tattoo_scene.h index 91e7ad4665..35f5957c34 100644 --- a/engines/sherlock/tattoo/tattoo_scene.h +++ b/engines/sherlock/tattoo/tattoo_scene.h @@ -46,6 +46,12 @@ private: void doBgAnimUpdateBgObjectsAndAnim(); void doBgAnimDrawSprites(); + + /** + * Returns the scale value for the passed co-ordinates. This is taken from the scene's + * scale zones, interpolating inbetween the top and bottom values of the zones as needed + */ + int getScaleVal(const Common::Point &pt); protected: /** * Checks all the background shapes. If a background shape is animating, @@ -53,6 +59,11 @@ protected: * colliding with another shape, it will also flag it as needing drawing */ virtual void checkBgShapes(); + + /** + * Draw all the shapes, people and NPCs in the correct order + */ + virtual void drawAllShapes(); public: ImageFile *_mask, *_mask1; CAnimStream _activeCAnim; |