1 /* 2 * The ManaPlus Client 3 * Copyright (C) 2004-2009 The Mana World Development Team 4 * Copyright (C) 2009-2010 The Mana Developers 5 * Copyright (C) 2011-2019 The ManaPlus Developers 6 * Copyright (C) 2019-2021 Andrei Karas 7 * 8 * This file is part of The ManaPlus Client. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program. If not, see <http://www.gnu.org/licenses/>. 22 */ 23 24 #ifndef RESOURCES_MAP_MAPLAYER_H 25 #define RESOURCES_MAP_MAPLAYER_H 26 27 #include "listeners/configlistener.h" 28 29 #include "resources/memorycounter.h" 30 31 #include "being/actor.h" 32 33 #include "enums/resources/map/maptype.h" 34 35 #include "utils/vector.h" 36 37 #include "resources/map/tileinfo.h" 38 39 class Image; 40 class MapRowVertexes; 41 class SpecialLayer; 42 43 struct MetaTile; 44 45 /** 46 * A map layer. Stores a grid of tiles and their offset, and implements layer 47 * rendering. 48 */ 49 class MapLayer final : public MemoryCounter, public ConfigListener 50 { 51 public: 52 friend class Map; 53 54 /** 55 * Constructor, taking layer origin, size and whether this layer is the 56 * fringe layer. The fringe layer is the layer that draws the actors. 57 * There can be only one fringe layer per map. 58 */ 59 MapLayer(const std::string &name, 60 const int x, 61 const int y, 62 const int width, 63 const int height, 64 const bool isFringeLayer, 65 const int mask, 66 const int tileCondition); 67 68 A_DELETE_COPY(MapLayer) 69 70 /** 71 * Destructor. 72 */ 73 ~MapLayer() override final; 74 75 /** 76 * Set tile image, with x and y in layer coordinates. 77 */ setTile(const int x,const int y,Image * restrict const img)78 constexpr3 void setTile(const int x, 79 const int y, 80 Image *restrict const img) restrict 81 { 82 mTiles[x + y * mWidth].image = img; 83 } 84 85 /** 86 * Set tile image with x + y * width already known. 87 */ setTile(const int index,Image * restrict const img)88 constexpr3 void setTile(const int index, 89 Image *restrict const img) restrict 90 { mTiles[index].image = img; } 91 92 /** 93 * Draws this layer to the given graphics context. The coordinates are 94 * expected to be in map range and will be translated to local layer 95 * coordinates and clipped to the layer's dimensions. 96 * 97 * The given actors are only drawn when this layer is the fringe 98 * layer. 99 */ 100 void draw(Graphics *restrict const graphics, 101 int startX, 102 int startY, 103 int endX, 104 int endY, 105 const int scrollX, 106 const int scrollY) const restrict A_NONNULL(2); 107 108 void drawSDL(Graphics *restrict const graphics) const restrict2 109 A_NONNULL(2); 110 111 #ifdef USE_OPENGL 112 void drawOGL(Graphics *restrict const graphics) const restrict2 113 A_NONNULL(2); 114 115 void updateOGL(Graphics *restrict const graphics, 116 int startX, 117 int startY, 118 int endX, 119 int endY, 120 const int scrollX, 121 const int scrollY) restrict2 A_NONNULL(2); 122 #endif // USE_OPENGL 123 124 void updateSDL(const Graphics *restrict const graphics, 125 int startX, 126 int startY, 127 int endX, 128 int endY, 129 const int scrollX, 130 const int scrollY) restrict2 A_NONNULL(2); 131 132 void drawFringe(Graphics *restrict const graphics, 133 int startX, 134 int startY, 135 int endX, 136 int endY, 137 const int scrollX, 138 const int scrollY, 139 const Actors &actors) const restrict A_NONNULL(2); 140 isFringeLayer()141 constexpr3 bool isFringeLayer() const restrict noexcept2 A_WARN_UNUSED 142 { return mIsFringeLayer; } 143 setSpecialLayer(const SpecialLayer * restrict const val)144 void setSpecialLayer(const SpecialLayer *restrict const val) 145 restrict noexcept2 146 { mSpecialLayer = val; } 147 setTempLayer(const SpecialLayer * restrict const val)148 void setTempLayer(const SpecialLayer *restrict const val) 149 restrict noexcept2 150 { mTempLayer = val; } 151 getWidth()152 constexpr3 int getWidth() const restrict noexcept2 A_WARN_UNUSED 153 { return mWidth; } 154 getHeight()155 constexpr3 int getHeight() const restrict noexcept2 A_WARN_UNUSED 156 { return mHeight; } 157 158 void optionChanged(const std::string &restrict value) 159 restrict override final; 160 setDrawLayerFlags(const MapTypeT & restrict n)161 void setDrawLayerFlags(const MapTypeT &restrict n) 162 restrict noexcept2 163 { 164 mDrawLayerFlags = n; 165 mSpecialFlag = (mDrawLayerFlags != MapType::SPECIAL && 166 mDrawLayerFlags != MapType::SPECIAL2 && 167 mDrawLayerFlags != MapType::SPECIAL4); 168 } 169 setActorsFix(const int y)170 void setActorsFix(const int y) restrict noexcept2 171 { mActorsFix = y; } 172 173 int calcMemoryLocal() const override final; 174 175 int calcMemoryChilds(const int level) const override final; 176 getCounterName()177 std::string getCounterName() const override final 178 { return mName; } 179 180 #ifdef UNITTESTS getTiles()181 constexpr3 TileInfo *getTiles() const restrict noexcept2 182 { 183 return mTiles; 184 } 185 setTileCondition(const int c)186 void setTileCondition(const int c) restrict noexcept2 187 { 188 mTileCondition = c; 189 } 190 #endif // UNITTESTS 191 192 #ifndef UNITTESTS 193 protected: 194 #endif // UNITTESTS 195 static int getTileDrawWidth(const TileInfo *restrict img, 196 const int endX, 197 int &restrict width, 198 int &restrict nextTile) 199 A_WARN_UNUSED A_NONNULL(1); 200 201 static int getEmptyTileDrawWidth(const TileInfo *restrict img, 202 const int endX, 203 int &restrict nextTile) 204 A_WARN_UNUSED A_NONNULL(1); 205 206 void updateConditionTiles(const MetaTile *restrict const metaTiles, 207 const int width, 208 const int height) restrict A_NONNULL(2); 209 210 void updateCache(const int width, 211 const int height) restrict; 212 213 void drawSpecialLayer(Graphics *const graphics, 214 const int y, 215 const int startX, 216 const int endX, 217 const int scrollX, 218 const int scrollY) const restrict; 219 220 private: 221 const int mX; 222 const int mY; 223 const int mPixelX; 224 const int mPixelY; 225 const int mWidth; 226 const int mHeight; 227 TileInfo *restrict const mTiles; 228 MapTypeT mDrawLayerFlags; 229 const SpecialLayer *restrict mSpecialLayer; 230 const SpecialLayer *restrict mTempLayer; 231 const std::string mName; 232 typedef STD_VECTOR<MapRowVertexes*> MapRows; 233 MapRows mTempRows; 234 int mMask; 235 int mTileCondition; 236 int mActorsFix; 237 const bool mIsFringeLayer; /**< Whether the actors are drawn. */ 238 bool mHighlightAttackRange; 239 bool mSpecialFlag; 240 }; 241 242 #endif // RESOURCES_MAP_MAPLAYER_H 243