1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef NEVERHOOD_SPRITE_H 24 #define NEVERHOOD_SPRITE_H 25 26 #include "neverhood/neverhood.h" 27 #include "neverhood/entity.h" 28 #include "neverhood/graphics.h" 29 #include "neverhood/resource.h" 30 31 namespace Neverhood { 32 33 #define SetSpriteUpdate(callback) \ 34 do { \ 35 _spriteUpdateCb = static_cast <void (Sprite::*)(void)> (callback); \ 36 debug(2, "SetSpriteUpdate(" #callback ")"); \ 37 _spriteUpdateCbName = #callback; \ 38 } while (0) 39 40 #define SetFilterX(callback) \ 41 do { \ 42 _filterXCb = static_cast <int16 (Sprite::*)(int16)> (callback); \ 43 debug(2, "SetFilterX(" #callback ")"); \ 44 } while (0) 45 46 #define SetFilterY(callback) \ 47 do { \ 48 _filterYCb = static_cast <int16 (Sprite::*)(int16)> (callback); \ 49 debug(2, "SetFilterY(" #callback ")"); \ 50 } while (0) 51 52 const int16 kDefPosition = -32768; 53 54 class Sprite : public Entity { 55 public: 56 Sprite(NeverhoodEngine *vm, int objectPriority); 57 ~Sprite() override; init()58 void init() {} getSurface()59 BaseSurface *getSurface() { return _surface; } 60 void updateBounds(); 61 void setDoDeltaX(int type); 62 void setDoDeltaY(int type); 63 bool isPointInside(int16 x, int16 y); 64 bool checkCollision(NRect &rect); getX()65 int16 getX() const { return _x; } getY()66 int16 getY() const { return _y; } setX(int16 value)67 void setX(int16 value) { _x = value; } setY(int16 value)68 void setY(int16 value) { _y = value; } getFlags()69 uint16 getFlags() const { return _flags; } isDoDeltaX()70 bool isDoDeltaX() const { return _doDeltaX; } isDoDeltaY()71 bool isDoDeltaY() const { return _doDeltaY; } getCollisionBounds()72 NRect& getCollisionBounds() { return _collisionBounds; } 73 uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); 74 void loadDataResource(uint32 fileHash); 75 int16 defFilterY(int16 y); getVisible()76 bool getVisible() const { return _surface->getVisible(); } setVisible(bool value)77 void setVisible(bool value) { _surface->setVisible(value); } getDrawRect()78 NDrawRect& getDrawRect() { return _surface->getDrawRect(); } 79 // Some shortcuts to set the clipRect getClipRect()80 NRect& getClipRect() { return _surface->getClipRect(); } 81 void setClipRect(int16 x1, int16 y1, int16 x2, int16 y2); 82 void setClipRect(NRect& clipRect); 83 void setClipRect(NDrawRect& drawRect); 84 protected: 85 void (Sprite::*_spriteUpdateCb)(); 86 Common::String _spriteUpdateCbName; // For debugging purposes 87 int16 (Sprite::*_filterXCb)(int16); 88 int16 (Sprite::*_filterYCb)(int16); 89 BaseSurface *_surface; 90 int16 _x, _y; 91 bool _doDeltaX, _doDeltaY; 92 bool _needRefresh; 93 NDrawRect _drawOffset; 94 NRect _collisionBounds; 95 NDrawRect _collisionBoundsOffset; 96 uint16 _flags; 97 DataResource _dataResource; 98 void createSurface(int surfacePriority, int16 width, int16 height); handleSpriteUpdate()99 void handleSpriteUpdate() { 100 if (_spriteUpdateCb) 101 (this->*_spriteUpdateCb)(); 102 } filterX(int16 x)103 int16 filterX(int16 x) { 104 return _filterXCb ? (this->*_filterXCb)(x) : x; 105 } filterY(int16 y)106 int16 filterY(int16 y) { 107 return _filterYCb ? (this->*_filterYCb)(y) : y; 108 } 109 }; 110 111 enum { 112 kSLFDefDrawOffset = 1 << 0, 113 kSLFCenteredDrawOffset = 1 << 1, 114 kSLFDefPosition = 1 << 2, 115 kSLFSetPosition = 1 << 3, 116 kSLFDefCollisionBoundsOffset = 1 << 4 117 }; 118 119 class StaticSprite : public Sprite { 120 public: 121 StaticSprite(NeverhoodEngine *vm, int objectPriority); 122 StaticSprite(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority, int16 x = kDefPosition, int16 y = kDefPosition); 123 void loadSprite(uint32 fileHash, uint flags = 0, int surfacePriority = 0, int16 x = kDefPosition, int16 y = kDefPosition); 124 void updatePosition(); 125 protected: 126 SpriteResource _spriteResource; 127 }; 128 129 #define AnimationCallback(callback) static_cast <void (AnimatedSprite::*)()> (callback) 130 #define GotoState(callback) gotoState(static_cast <void (AnimatedSprite::*)()> (callback)) 131 #define NextState(callback) \ 132 do { \ 133 _nextStateCb = static_cast <void (AnimatedSprite::*)(void)> (callback); \ 134 debug(2, "NextState(" #callback ")"); _nextStateCbName = #callback; \ 135 } while (0) 136 #define FinalizeState(callback) setFinalizeState(static_cast <void (AnimatedSprite::*)()> (callback)); 137 138 const int STICK_LAST_FRAME = -2; 139 140 class AnimatedSprite : public Sprite { 141 public: 142 AnimatedSprite(NeverhoodEngine *vm, int objectPriority); 143 AnimatedSprite(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority, int16 x, int16 y); 144 void update(); 145 void updateDeltaXY(); 146 void setRepl(byte oldColor, byte newColor); 147 void clearRepl(); getCurrAnimFileHash()148 uint32 getCurrAnimFileHash() const { return _currAnimFileHash; } getFrameIndex()149 int16 getFrameIndex() const { return _currFrameIndex; } getFrameIndex(uint32 frameHash)150 int16 getFrameIndex(uint32 frameHash) { return _animResource.getFrameIndex(frameHash); } setNewHashListIndex(int value)151 void setNewHashListIndex(int value) { _newStickFrameIndex = value; } 152 void startAnimation(uint32 fileHash, int16 plFirstFrameIndex, int16 plLastFrameIndex); 153 protected: 154 typedef void (AnimatedSprite::*AnimationCb)(); 155 AnimResource _animResource; 156 uint32 _currAnimFileHash, _newAnimFileHash, _nextAnimFileHash; 157 int16 _currFrameIndex, _lastFrameIndex; 158 int16 _plFirstFrameIndex, _plLastFrameIndex; 159 uint32 _plFirstFrameHash, _plLastFrameHash; 160 int16 _animStatus; 161 int16 _currFrameTicks; 162 int _currStickFrameIndex, _newStickFrameIndex; 163 uint32 _newStickFrameHash; 164 int16 _deltaX, _deltaY; 165 byte _replOldColor, _replNewColor; 166 bool _playBackwards, _frameChanged; 167 AnimationCb _finalizeStateCb; 168 AnimationCb _currStateCb; 169 AnimationCb _nextStateCb; 170 // For debugging purposes 171 Common::String _finalizeStateCbName; 172 Common::String _currStateCbName; 173 Common::String _nextStateCbName; 174 void init(); 175 void updateAnim(); 176 void updatePosition(); 177 void updateFrameIndex(); 178 void updateFrameInfo(); 179 void createSurface1(uint32 fileHash, int surfacePriority); 180 void createShadowSurface1(BaseSurface *shadowSurface, uint32 fileHash, int surfacePriority); 181 void createShadowSurface(BaseSurface *shadowSurface, int16 width, int16 height, int surfacePriority); 182 void stopAnimation(); 183 void startAnimationByHash(uint32 fileHash, uint32 plFirstFrameHash, uint32 plLastFrameHash); 184 void nextAnimationByHash(uint32 fileHash2, uint32 plFirstFrameHash, uint32 plLastFrameHash); 185 void setFinalizeState(AnimationCb finalizeStateCb); 186 void gotoState(AnimationCb currStateCb); 187 void gotoNextState(); 188 }; 189 190 } // End of namespace Neverhood 191 192 #endif /* NEVERHOOD_SPRITE_H */ 193