|
@@ -80,10 +80,7 @@ struct TerrainTileObject
|
|
|
|
|
|
|
|
struct TerrainTile2
|
|
struct TerrainTile2
|
|
|
{
|
|
{
|
|
|
- SDL_Surface * terbitmap; //bitmap of terrain
|
|
|
|
|
-
|
|
|
|
|
std::vector<TerrainTileObject> objects; //pointers to objects being on this tile with rects to be easier to blit this tile on screen
|
|
std::vector<TerrainTileObject> objects; //pointers to objects being on this tile with rects to be easier to blit this tile on screen
|
|
|
- TerrainTile2();
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
struct MapDrawingInfo
|
|
struct MapDrawingInfo
|
|
@@ -133,16 +130,6 @@ template <typename T> class PseudoV
|
|
|
{
|
|
{
|
|
|
public:
|
|
public:
|
|
|
PseudoV() : offset(0) { }
|
|
PseudoV() : offset(0) { }
|
|
|
- PseudoV(std::vector<T> &src, int rest, int before, int after, const T& fill) : offset(before)
|
|
|
|
|
- {
|
|
|
|
|
- inver.resize(before + rest + after);
|
|
|
|
|
- for(int i=0; i<before;i++)
|
|
|
|
|
- inver[i] = fill;
|
|
|
|
|
- for(int i=0;i<src.size();i++)
|
|
|
|
|
- inver[offset+i] = src[i];
|
|
|
|
|
- for(int i=src.size(); i<src.size()+after;i++)
|
|
|
|
|
- inver[offset+i] = fill;
|
|
|
|
|
- }
|
|
|
|
|
inline T & operator[](const int & n)
|
|
inline T & operator[](const int & n)
|
|
|
{
|
|
{
|
|
|
return inver[n+offset];
|
|
return inver[n+offset];
|
|
@@ -167,26 +154,26 @@ private:
|
|
|
};
|
|
};
|
|
|
class CMapHandler
|
|
class CMapHandler
|
|
|
{
|
|
{
|
|
|
- enum class EMapCacheType
|
|
|
|
|
|
|
+ enum class EMapCacheType : ui8
|
|
|
{
|
|
{
|
|
|
- TERRAIN, TERRAIN_CUSTOM, OBJECTS, ROADS, RIVERS, FOW, HEROES, HERO_FLAGS, FRAME
|
|
|
|
|
|
|
+ TERRAIN, OBJECTS, ROADS, RIVERS, FOW, HEROES, HERO_FLAGS, FRAME, AFTER_LAST
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/// temporarily caches rescaled sdl surfaces for map world view redrawing
|
|
/// temporarily caches rescaled sdl surfaces for map world view redrawing
|
|
|
class CMapCache
|
|
class CMapCache
|
|
|
{
|
|
{
|
|
|
- std::map<EMapCacheType, std::map<intptr_t, SDL_Surface *>> data;
|
|
|
|
|
|
|
+ std::array< std::map<intptr_t, SDL_Surface *>, (ui8)EMapCacheType::AFTER_LAST> data;
|
|
|
float worldViewCachedScale;
|
|
float worldViewCachedScale;
|
|
|
public:
|
|
public:
|
|
|
/// destroys all cached data (frees surfaces)
|
|
/// destroys all cached data (frees surfaces)
|
|
|
void discardWorldViewCache();
|
|
void discardWorldViewCache();
|
|
|
/// updates scale and determines if currently cached data is still valid
|
|
/// updates scale and determines if currently cached data is still valid
|
|
|
void updateWorldViewScale(float scale);
|
|
void updateWorldViewScale(float scale);
|
|
|
- void removeFromWorldViewCache(EMapCacheType type, intptr_t key);
|
|
|
|
|
/// asks for cached data; @returns cached surface or nullptr if data is not in cache
|
|
/// asks for cached data; @returns cached surface or nullptr if data is not in cache
|
|
|
SDL_Surface * requestWorldViewCache(EMapCacheType type, intptr_t key);
|
|
SDL_Surface * requestWorldViewCache(EMapCacheType type, intptr_t key);
|
|
|
/// asks for cached data; @returns cached data if found, new scaled surface otherwise
|
|
/// asks for cached data; @returns cached data if found, new scaled surface otherwise
|
|
|
SDL_Surface * requestWorldViewCacheOrCreate(EMapCacheType type, intptr_t key, SDL_Surface * fullSurface, float scale);
|
|
SDL_Surface * requestWorldViewCacheOrCreate(EMapCacheType type, intptr_t key, SDL_Surface * fullSurface, float scale);
|
|
|
|
|
+ SDL_Surface * requestWorldViewCacheOrCreate(EMapCacheType type, intptr_t key, const IImage * fullSurface, float scale);
|
|
|
SDL_Surface * cacheWorldViewEntry(EMapCacheType type, intptr_t key, SDL_Surface * entry);
|
|
SDL_Surface * cacheWorldViewEntry(EMapCacheType type, intptr_t key, SDL_Surface * entry);
|
|
|
intptr_t genKey(intptr_t realPtr, ui8 mod);
|
|
intptr_t genKey(intptr_t realPtr, ui8 mod);
|
|
|
};
|
|
};
|
|
@@ -194,11 +181,11 @@ class CMapHandler
|
|
|
/// helper struct to pass around resolved bitmaps of an object; surfaces can be nullptr if object doesn't have bitmap of that type
|
|
/// helper struct to pass around resolved bitmaps of an object; surfaces can be nullptr if object doesn't have bitmap of that type
|
|
|
struct AnimBitmapHolder
|
|
struct AnimBitmapHolder
|
|
|
{
|
|
{
|
|
|
- SDL_Surface * objBitmap; // main object bitmap
|
|
|
|
|
- SDL_Surface * flagBitmap; // flag bitmap for the object (probably only for heroes and boats with heroes)
|
|
|
|
|
|
|
+ IImage * objBitmap; // main object bitmap
|
|
|
|
|
+ IImage * flagBitmap; // flag bitmap for the object (probably only for heroes and boats with heroes)
|
|
|
bool isMoving; // indicates if the object is moving (again, heroes/boats only)
|
|
bool isMoving; // indicates if the object is moving (again, heroes/boats only)
|
|
|
|
|
|
|
|
- AnimBitmapHolder(SDL_Surface * objBitmap_ = nullptr, SDL_Surface * flagBitmap_ = nullptr, bool moving = false)
|
|
|
|
|
|
|
+ AnimBitmapHolder(IImage * objBitmap_ = nullptr, IImage * flagBitmap_ = nullptr, bool moving = false)
|
|
|
: objBitmap(objBitmap_),
|
|
: objBitmap(objBitmap_),
|
|
|
flagBitmap(flagBitmap_),
|
|
flagBitmap(flagBitmap_),
|
|
|
isMoving(moving)
|
|
isMoving(moving)
|
|
@@ -223,8 +210,7 @@ class CMapHandler
|
|
|
const MapDrawingInfo * info; // data for drawing passed from outside
|
|
const MapDrawingInfo * info; // data for drawing passed from outside
|
|
|
|
|
|
|
|
/// general drawing method, called internally by more specialized ones
|
|
/// general drawing method, called internally by more specialized ones
|
|
|
- virtual void drawElement(EMapCacheType cacheType, SDL_Surface * sourceSurf, SDL_Rect * sourceRect,
|
|
|
|
|
- SDL_Surface * targetSurf, SDL_Rect * destRect, bool alphaBlit = false, ui8 rotationInfo = 0u) const = 0;
|
|
|
|
|
|
|
+ virtual void drawElement(EMapCacheType cacheType, const IImage * source, SDL_Rect * sourceRect, SDL_Surface * targetSurf, SDL_Rect * destRect) const = 0;
|
|
|
|
|
|
|
|
// first drawing pass
|
|
// first drawing pass
|
|
|
|
|
|
|
@@ -236,8 +222,8 @@ class CMapHandler
|
|
|
virtual void drawRoad(SDL_Surface * targetSurf, const TerrainTile & tinfo, const TerrainTile * tinfoUpper) const;
|
|
virtual void drawRoad(SDL_Surface * targetSurf, const TerrainTile & tinfo, const TerrainTile * tinfoUpper) const;
|
|
|
/// draws all objects on current tile (higher-level logic, unlike other draw*** methods)
|
|
/// draws all objects on current tile (higher-level logic, unlike other draw*** methods)
|
|
|
virtual void drawObjects(SDL_Surface * targetSurf, const TerrainTile2 & tile) const;
|
|
virtual void drawObjects(SDL_Surface * targetSurf, const TerrainTile2 & tile) const;
|
|
|
- virtual void drawObject(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, bool moving) const;
|
|
|
|
|
- virtual void drawHeroFlag(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const;
|
|
|
|
|
|
|
+ virtual void drawObject(SDL_Surface * targetSurf, const IImage * source, SDL_Rect * sourceRect, bool moving) const;
|
|
|
|
|
+ virtual void drawHeroFlag(SDL_Surface * targetSurf, const IImage * source, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const;
|
|
|
|
|
|
|
|
// second drawing pass
|
|
// second drawing pass
|
|
|
|
|
|
|
@@ -262,9 +248,7 @@ class CMapHandler
|
|
|
/// calculates clip region for map viewport
|
|
/// calculates clip region for map viewport
|
|
|
virtual SDL_Rect clip(SDL_Surface * targetSurf) const = 0;
|
|
virtual SDL_Rect clip(SDL_Surface * targetSurf) const = 0;
|
|
|
|
|
|
|
|
- virtual ui8 getHeroFrameNum(ui8 dir, bool isMoving) const;
|
|
|
|
|
- ///returns appropriate bitmap and info if alpha blitting is necessary
|
|
|
|
|
- virtual std::pair<SDL_Surface *, bool> getVisBitmap() const;
|
|
|
|
|
|
|
+ virtual ui8 getHeroFrameGroup(ui8 dir, bool isMoving) const;
|
|
|
virtual ui8 getPhaseShift(const CGObjectInstance *object) const;
|
|
virtual ui8 getPhaseShift(const CGObjectInstance *object) const;
|
|
|
|
|
|
|
|
virtual bool canDrawObject(const CGObjectInstance * obj) const;
|
|
virtual bool canDrawObject(const CGObjectInstance * obj) const;
|
|
@@ -273,11 +257,10 @@ class CMapHandler
|
|
|
// internal helper methods to choose correct bitmap(s) for object; called internally by findObjectBitmap
|
|
// internal helper methods to choose correct bitmap(s) for object; called internally by findObjectBitmap
|
|
|
AnimBitmapHolder findHeroBitmap(const CGHeroInstance * hero, int anim) const;
|
|
AnimBitmapHolder findHeroBitmap(const CGHeroInstance * hero, int anim) const;
|
|
|
AnimBitmapHolder findBoatBitmap(const CGBoat * hero, int anim) const;
|
|
AnimBitmapHolder findBoatBitmap(const CGBoat * hero, int anim) const;
|
|
|
- SDL_Surface * findFlagBitmap(const CGHeroInstance * obj, int anim, const PlayerColor * color, int indexOffset) const;
|
|
|
|
|
- SDL_Surface * findHeroFlagBitmap(const CGHeroInstance * obj, int anim, const PlayerColor * color, int indexOffset) const;
|
|
|
|
|
- SDL_Surface * findBoatFlagBitmap(const CGBoat * obj, int anim, const PlayerColor * color, int indexOffset, ui8 dir) const;
|
|
|
|
|
- SDL_Surface * findFlagBitmapInternal(const CDefEssential * def, int anim, int indexOffset, ui8 dir, bool moving) const;
|
|
|
|
|
- int findAnimIndexByGroup(const CDefEssential * def, int groupNum) const;
|
|
|
|
|
|
|
+ IImage * findFlagBitmap(const CGHeroInstance * obj, int anim, const PlayerColor * color, int group) const;
|
|
|
|
|
+ IImage * findHeroFlagBitmap(const CGHeroInstance * obj, int anim, const PlayerColor * color, int group) const;
|
|
|
|
|
+ IImage * findBoatFlagBitmap(const CGBoat * obj, int anim, const PlayerColor * color, int group, ui8 dir) const;
|
|
|
|
|
+ IImage * findFlagBitmapInternal(std::shared_ptr<CAnimation> animation, int anim, int group, ui8 dir, bool moving) const;
|
|
|
|
|
|
|
|
public:
|
|
public:
|
|
|
CMapBlitter(CMapHandler * p) : parent(p) {}
|
|
CMapBlitter(CMapHandler * p) : parent(p) {}
|
|
@@ -285,15 +268,12 @@ class CMapHandler
|
|
|
void blit(SDL_Surface * targetSurf, const MapDrawingInfo * info);
|
|
void blit(SDL_Surface * targetSurf, const MapDrawingInfo * info);
|
|
|
/// helper method that chooses correct bitmap(s) for given object
|
|
/// helper method that chooses correct bitmap(s) for given object
|
|
|
AnimBitmapHolder findObjectBitmap(const CGObjectInstance * obj, int anim) const;
|
|
AnimBitmapHolder findObjectBitmap(const CGObjectInstance * obj, int anim) const;
|
|
|
-
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
class CMapNormalBlitter : public CMapBlitter
|
|
class CMapNormalBlitter : public CMapBlitter
|
|
|
{
|
|
{
|
|
|
protected:
|
|
protected:
|
|
|
- void drawElement(EMapCacheType cacheType, SDL_Surface * sourceSurf, SDL_Rect * sourceRect,
|
|
|
|
|
- SDL_Surface * targetSurf, SDL_Rect * destRect, bool alphaBlit = false, ui8 rotationInfo = 0u) const override;
|
|
|
|
|
-
|
|
|
|
|
|
|
+ void drawElement(EMapCacheType cacheType, const IImage * source, SDL_Rect * sourceRect, SDL_Surface * targetSurf, SDL_Rect * destRect) const override;
|
|
|
void drawTileOverlay(SDL_Surface * targetSurf,const TerrainTile2 & tile) const override {}
|
|
void drawTileOverlay(SDL_Surface * targetSurf,const TerrainTile2 & tile) const override {}
|
|
|
void init(const MapDrawingInfo * info) override;
|
|
void init(const MapDrawingInfo * info) override;
|
|
|
SDL_Rect clip(SDL_Surface * targetSurf) const override;
|
|
SDL_Rect clip(SDL_Surface * targetSurf) const override;
|
|
@@ -307,22 +287,15 @@ class CMapHandler
|
|
|
private:
|
|
private:
|
|
|
IImage * objectToIcon(Obj id, si32 subId, PlayerColor owner) const;
|
|
IImage * objectToIcon(Obj id, si32 subId, PlayerColor owner) const;
|
|
|
protected:
|
|
protected:
|
|
|
- void drawElement(EMapCacheType cacheType, SDL_Surface * sourceSurf, SDL_Rect * sourceRect,
|
|
|
|
|
- SDL_Surface * targetSurf, SDL_Rect * destRect, bool alphaBlit = false, ui8 rotationInfo = 0u) const override;
|
|
|
|
|
-
|
|
|
|
|
|
|
+ void drawElement(EMapCacheType cacheType, const IImage * source, SDL_Rect * sourceRect, SDL_Surface * targetSurf, SDL_Rect * destRect) const override;
|
|
|
void drawTileOverlay(SDL_Surface * targetSurf, const TerrainTile2 & tile) const override;
|
|
void drawTileOverlay(SDL_Surface * targetSurf, const TerrainTile2 & tile) const override;
|
|
|
- void drawHeroFlag(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const override;
|
|
|
|
|
- void drawObject(SDL_Surface * targetSurf, SDL_Surface * sourceSurf, SDL_Rect * sourceRect, bool moving) const override;
|
|
|
|
|
|
|
+ void drawHeroFlag(SDL_Surface * targetSurf, const IImage * source, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const override;
|
|
|
|
|
+ void drawObject(SDL_Surface * targetSurf, const IImage * source, SDL_Rect * sourceRect, bool moving) const override;
|
|
|
void drawFrame(SDL_Surface * targetSurf) const override {}
|
|
void drawFrame(SDL_Surface * targetSurf) const override {}
|
|
|
void drawOverlayEx(SDL_Surface * targetSurf) override;
|
|
void drawOverlayEx(SDL_Surface * targetSurf) override;
|
|
|
void init(const MapDrawingInfo * info) override;
|
|
void init(const MapDrawingInfo * info) override;
|
|
|
SDL_Rect clip(SDL_Surface * targetSurf) const override;
|
|
SDL_Rect clip(SDL_Surface * targetSurf) const override;
|
|
|
-
|
|
|
|
|
-// ui8 getHeroFrameNum(ui8 dir, bool isMoving) const override { return 0u; }
|
|
|
|
|
ui8 getPhaseShift(const CGObjectInstance *object) const override { return 0u; }
|
|
ui8 getPhaseShift(const CGObjectInstance *object) const override { return 0u; }
|
|
|
-
|
|
|
|
|
- void drawScaledRotatedElement(EMapCacheType type, SDL_Surface * baseSurf, SDL_Surface * targetSurf, ui8 rotation,
|
|
|
|
|
- float scale, SDL_Rect * dstRect, SDL_Rect * srcRect = nullptr) const;
|
|
|
|
|
void calculateWorldViewCameraPos();
|
|
void calculateWorldViewCameraPos();
|
|
|
public:
|
|
public:
|
|
|
CMapWorldViewBlitter(CMapHandler * parent);
|
|
CMapWorldViewBlitter(CMapHandler * parent);
|
|
@@ -353,6 +326,11 @@ class CMapHandler
|
|
|
CMapBlitter * resolveBlitter(const MapDrawingInfo * info) const;
|
|
CMapBlitter * resolveBlitter(const MapDrawingInfo * info) const;
|
|
|
bool updateObjectsFade();
|
|
bool updateObjectsFade();
|
|
|
bool startObjectFade(TerrainTileObject & obj, bool in, int3 pos);
|
|
bool startObjectFade(TerrainTileObject & obj, bool in, int3 pos);
|
|
|
|
|
+
|
|
|
|
|
+ void initObjectRects();
|
|
|
|
|
+ void initBorderGraphics();
|
|
|
|
|
+ void initTerrainGraphics();
|
|
|
|
|
+ void prepareFOWDefs();
|
|
|
public:
|
|
public:
|
|
|
PseudoV< PseudoV< PseudoV<TerrainTile2> > > ttiles; //informations about map tiles
|
|
PseudoV< PseudoV< PseudoV<TerrainTile2> > > ttiles; //informations about map tiles
|
|
|
int3 sizes; //map size (x = width, y = height, z = number of levels)
|
|
int3 sizes; //map size (x = width, y = height, z = number of levels)
|
|
@@ -373,13 +351,30 @@ public:
|
|
|
int offsetX;
|
|
int offsetX;
|
|
|
int offsetY;
|
|
int offsetY;
|
|
|
|
|
|
|
|
- //std::set<int> usedHeroes;
|
|
|
|
|
|
|
+ //terrain graphics
|
|
|
|
|
+
|
|
|
|
|
+ typedef std::vector<std::array<std::unique_ptr<CAnimation>, 4>> TFlippedAnimations; //[type, rotation]
|
|
|
|
|
+ typedef std::vector<std::vector<std::array<IImage *, 4>>> TFlippedCache;//[type, view type, rotation]
|
|
|
|
|
+
|
|
|
|
|
+ TFlippedAnimations terrainAnimations;//[terrain type, rotation]
|
|
|
|
|
+ TFlippedCache terrainImages;//[terrain type, view type, rotation]
|
|
|
|
|
+
|
|
|
|
|
+ TFlippedAnimations roadAnimations;//[road type, rotation]
|
|
|
|
|
+ TFlippedCache roadImages;//[road type, view type, rotation]
|
|
|
|
|
|
|
|
- std::vector<std::vector<SDL_Surface *> > terrainGraphics; // [terrain id] [view type] [rotation type]
|
|
|
|
|
- std::vector<CDefEssential *> roadDefs;
|
|
|
|
|
- std::vector<CDefEssential *> staticRiverDefs;
|
|
|
|
|
|
|
+ TFlippedAnimations riverAnimations;//[river type, rotation]
|
|
|
|
|
+ TFlippedCache riverImages;//[river type, view type, rotation]
|
|
|
|
|
|
|
|
- std::vector<std::vector<std::vector<ui8> > > hideBitmap; //specifies number of graphic that should be used to fully hide a tile
|
|
|
|
|
|
|
+ //Fog of War cache (not owned)
|
|
|
|
|
+ std::vector<const IImage *> FoWfullHide;
|
|
|
|
|
+ std::vector<std::vector<std::vector<ui8> > > hideBitmap; //frame indexes (in FoWfullHide) of graphic that should be used to fully hide a tile
|
|
|
|
|
+
|
|
|
|
|
+ std::vector<const IImage *> FoWpartialHide;
|
|
|
|
|
+
|
|
|
|
|
+ //edge graphics
|
|
|
|
|
+ std::unique_ptr<CAnimation> egdeAnimation;
|
|
|
|
|
+ std::vector<const IImage *> egdeImages;//cache of links to egdeAnimation (for faster access)
|
|
|
|
|
+ PseudoV< PseudoV< PseudoV <ui8> > > edgeFrames; //frame indexes (in egdeImages) of tile outside of map
|
|
|
|
|
|
|
|
mutable std::map<const CGObjectInstance*, ui8> animationPhase;
|
|
mutable std::map<const CGObjectInstance*, ui8> animationPhase;
|
|
|
|
|
|
|
@@ -387,21 +382,12 @@ public:
|
|
|
~CMapHandler(); //d-tor
|
|
~CMapHandler(); //d-tor
|
|
|
|
|
|
|
|
void getTerrainDescr(const int3 &pos, std::string & out, bool terName); //if tername == false => empty string when tile is clear
|
|
void getTerrainDescr(const int3 &pos, std::string & out, bool terName); //if tername == false => empty string when tile is clear
|
|
|
- CGObjectInstance * createObject(int id, int subid, int3 pos, int owner=254); //creates a new object with a certain id and subid
|
|
|
|
|
bool printObject(const CGObjectInstance * obj, bool fadein = false); //puts appropriate things to tiles, so obj will be visible on map
|
|
bool printObject(const CGObjectInstance * obj, bool fadein = false); //puts appropriate things to tiles, so obj will be visible on map
|
|
|
bool hideObject(const CGObjectInstance * obj, bool fadeout = false); //removes appropriate things from ttiles, so obj will be no longer visible on map (but still will exist)
|
|
bool hideObject(const CGObjectInstance * obj, bool fadeout = false); //removes appropriate things from ttiles, so obj will be no longer visible on map (but still will exist)
|
|
|
- bool removeObject(CGObjectInstance * obj, bool fadeout = false); //removes object from each place in VCMI (I hope)
|
|
|
|
|
void init();
|
|
void init();
|
|
|
- void calculateBlockedPos();
|
|
|
|
|
- void initObjectRects();
|
|
|
|
|
- void borderAndTerrainBitmapInit();
|
|
|
|
|
- void roadsRiverTerrainInit();
|
|
|
|
|
- void prepareFOWDefs();
|
|
|
|
|
|
|
|
|
|
EMapAnimRedrawStatus drawTerrainRectNew(SDL_Surface * targetSurface, const MapDrawingInfo * info, bool redrawOnlyAnim = false);
|
|
EMapAnimRedrawStatus drawTerrainRectNew(SDL_Surface * targetSurface, const MapDrawingInfo * info, bool redrawOnlyAnim = false);
|
|
|
void updateWater();
|
|
void updateWater();
|
|
|
- void validateRectTerr(SDL_Rect * val, const SDL_Rect * ext); //terrainRect helper
|
|
|
|
|
- static ui8 getDir(const int3 & a, const int3 & b); //returns direction number in range 0 - 7 (0 is left top, clockwise) [direction: form a to b]
|
|
|
|
|
/// determines if the map is ready to handle new hero movement (not available during fading animations)
|
|
/// determines if the map is ready to handle new hero movement (not available during fading animations)
|
|
|
bool canStartHeroMovement();
|
|
bool canStartHeroMovement();
|
|
|
|
|
|