mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-26 22:57:00 +02:00
Abstracted fading into separate class;
Smoother fade animations; Added fading when recentering hero after switching levels;
This commit is contained in:
parent
e64c08df27
commit
5e78a3147a
@ -276,6 +276,8 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
adventureInt->centerOn(hero, true); //actualizing screen pos
|
||||||
|
adventureInt->minimap.redraw();
|
||||||
adventureInt->heroList.update(hero);
|
adventureInt->heroList.update(hero);
|
||||||
return; //teleport - no fancy moving animation
|
return; //teleport - no fancy moving animation
|
||||||
//TODO: smooth disappear / appear effect
|
//TODO: smooth disappear / appear effect
|
||||||
|
@ -1222,3 +1222,88 @@ void CAnimation::getAnimInfo()
|
|||||||
logGlobal->errorStream()<<", "<<anim->images.begin()->second.size()<<" image loaded in group "<< anim->images.begin()->first;
|
logGlobal->errorStream()<<", "<<anim->images.begin()->second.size()<<" image loaded in group "<< anim->images.begin()->first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float CFadeAnimation::initialCounter() const
|
||||||
|
{
|
||||||
|
if (fadingMode == EMode::OUT)
|
||||||
|
return 1.0f;
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFadeAnimation::update()
|
||||||
|
{
|
||||||
|
if (!fading)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fadingMode == EMode::OUT)
|
||||||
|
fadingCounter -= delta;
|
||||||
|
else
|
||||||
|
fadingCounter += delta;
|
||||||
|
|
||||||
|
if (isFinished())
|
||||||
|
{
|
||||||
|
fading = false;
|
||||||
|
if (shouldFreeSurface)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(fadingSurface);
|
||||||
|
fadingSurface = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFadeAnimation::isFinished() const
|
||||||
|
{
|
||||||
|
if (fadingMode == EMode::OUT)
|
||||||
|
return fadingCounter <= 0.0f;
|
||||||
|
return fadingCounter >= 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFadeAnimation::CFadeAnimation()
|
||||||
|
: fadingSurface(nullptr),
|
||||||
|
fading(false),
|
||||||
|
fadingMode(EMode::NONE)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CFadeAnimation::~CFadeAnimation()
|
||||||
|
{
|
||||||
|
if (fadingSurface && shouldFreeSurface)
|
||||||
|
SDL_FreeSurface(fadingSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFadeAnimation::init(EMode mode, float animDelta /* = DEFAULT_DELTA */, SDL_Surface * sourceSurface /* = nullptr */, bool freeSurfaceAtEnd /* = false */)
|
||||||
|
{
|
||||||
|
if (fading)
|
||||||
|
{
|
||||||
|
logGlobal->warnStream() << "Tried to init fading animation that is already running.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (animDelta <= 0.0f)
|
||||||
|
{
|
||||||
|
logGlobal->warnStream() << "Fade anim: delta should be positive; " << animDelta << " given.";
|
||||||
|
animDelta = DEFAULT_DELTA;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sourceSurface)
|
||||||
|
fadingSurface = sourceSurface;
|
||||||
|
|
||||||
|
delta = animDelta;
|
||||||
|
fadingMode = mode;
|
||||||
|
fadingCounter = initialCounter();
|
||||||
|
fading = true;
|
||||||
|
shouldFreeSurface = freeSurfaceAtEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFadeAnimation::draw(SDL_Surface * targetSurface, const SDL_Rect * sourceRect, SDL_Rect * destRect)
|
||||||
|
{
|
||||||
|
if (!fading || !fadingSurface || fadingMode == EMode::NONE)
|
||||||
|
{
|
||||||
|
fading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_SetSurfaceAlphaMod(fadingSurface, fadingCounter * 255);
|
||||||
|
SDL_BlitSurface(fadingSurface, sourceRect, targetSurface, destRect);
|
||||||
|
SDL_SetSurfaceAlphaMod(fadingSurface, 255);
|
||||||
|
}
|
||||||
|
@ -220,3 +220,31 @@ public:
|
|||||||
//total count of frames in group (including not loaded)
|
//total count of frames in group (including not loaded)
|
||||||
size_t size(size_t group=0) const;
|
size_t size(size_t group=0) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CFadeAnimation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class EMode
|
||||||
|
{
|
||||||
|
NONE, IN, OUT
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
static constexpr float DEFAULT_DELTA = 0.05f;
|
||||||
|
float delta;
|
||||||
|
SDL_Surface * fadingSurface;
|
||||||
|
bool fading;
|
||||||
|
float fadingCounter;
|
||||||
|
bool shouldFreeSurface;
|
||||||
|
|
||||||
|
float initialCounter() const;
|
||||||
|
bool isFinished() const;
|
||||||
|
public:
|
||||||
|
EMode fadingMode;
|
||||||
|
|
||||||
|
CFadeAnimation();
|
||||||
|
~CFadeAnimation();
|
||||||
|
void init(EMode mode, float animDelta = DEFAULT_DELTA, SDL_Surface * sourceSurface = nullptr, bool freeSurfaceAtEnd = false);
|
||||||
|
void update();
|
||||||
|
void draw(SDL_Surface * targetSurface, const SDL_Rect * sourceRect, SDL_Rect * destRect);
|
||||||
|
bool isFading() const { return fading; }
|
||||||
|
};
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "mapHandler.h"
|
#include "mapHandler.h"
|
||||||
|
|
||||||
#include "CBitmapHandler.h"
|
#include "CBitmapHandler.h"
|
||||||
|
#include "gui/CAnimation.h"
|
||||||
#include "gui/SDL_Extensions.h"
|
#include "gui/SDL_Extensions.h"
|
||||||
#include "CGameInfo.h"
|
#include "CGameInfo.h"
|
||||||
#include "../lib/mapObjects/CGHeroInstance.h"
|
#include "../lib/mapObjects/CGHeroInstance.h"
|
||||||
@ -185,11 +186,12 @@ void CMapHandler::prepareFOWDefs()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapHandler::drawTerrainRectNew(SDL_Surface * targetSurface, const MapDrawingInfo * info)
|
EMapAnimRedrawStatus CMapHandler::drawTerrainRectNew(SDL_Surface * targetSurface, const MapDrawingInfo * info, bool redrawOnlyAnim /* = false */)
|
||||||
{
|
{
|
||||||
assert(info);
|
assert(info);
|
||||||
updateObjectsFade();
|
bool hasActiveFade = updateObjectsFade();
|
||||||
resolveBlitter(info)->blit(targetSurface, info);
|
resolveBlitter(info)->blit(targetSurface, info);
|
||||||
|
return hasActiveFade ? EMapAnimRedrawStatus::REDRAW_REQUESTED : EMapAnimRedrawStatus::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapHandler::roadsRiverTerrainInit()
|
void CMapHandler::roadsRiverTerrainInit()
|
||||||
@ -810,20 +812,21 @@ void CMapHandler::CMapBlitter::drawObjects(SDL_Surface * targetSurf, const Terra
|
|||||||
auto & objects = tile.objects;
|
auto & objects = tile.objects;
|
||||||
for(auto & object : objects)
|
for(auto & object : objects)
|
||||||
{
|
{
|
||||||
if (object.fading == EMapObjectFadingType::OUT)
|
if (object.fadeAnimKey >= 0)
|
||||||
|
{
|
||||||
|
// this object is currently fading, so skip normal drawing
|
||||||
|
// TODO fading heroes/boats will not be drawn correctly this way
|
||||||
|
|
||||||
|
auto fadeIter = parent->fadeAnims.find(object.fadeAnimKey);
|
||||||
|
if (fadeIter != parent->fadeAnims.end())
|
||||||
{
|
{
|
||||||
auto &bitmap = graphics->advmapobjGraphics[object.image]->ourImages[0].bitmap;
|
|
||||||
if (!parent->fadingOffscreenBitmapSurface)
|
|
||||||
parent->fadingOffscreenBitmapSurface = CSDL_Ext::newSurface(tileSize, tileSize, targetSurf);
|
|
||||||
Rect r1(object.rect);
|
Rect r1(object.rect);
|
||||||
r1.w = tileSize;
|
r1.w = tileSize;
|
||||||
r1.h = tileSize;
|
r1.h = tileSize;
|
||||||
Rect r2(realTileRect);
|
Rect r2(realTileRect);
|
||||||
SDL_SetSurfaceAlphaMod(parent->fadingOffscreenBitmapSurface, object.fadingCounter * 255);
|
CFadeAnimation * fade = (*fadeIter).second.second;
|
||||||
SDL_BlitSurface(bitmap, &r1, parent->fadingOffscreenBitmapSurface, nullptr);
|
fade->draw(targetSurf, &r1, &r2);
|
||||||
SDL_BlitSurface(parent->fadingOffscreenBitmapSurface, nullptr, targetSurf, &r2);
|
}
|
||||||
SDL_SetSurfaceAlphaMod(parent->fadingOffscreenBitmapSurface, 255);
|
|
||||||
SDL_FillRect(parent->fadingOffscreenBitmapSurface, nullptr, 0);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1164,50 +1167,67 @@ std::pair<SDL_Surface *, bool> CMapHandler::CMapBlitter::getVisBitmap() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapHandler::updateObjectsFade()
|
bool CMapHandler::updateObjectsFade()
|
||||||
{
|
{
|
||||||
// TODO caching fading objects indices for optimization?
|
for (auto iter = fadeAnims.begin(); iter != fadeAnims.end(); )
|
||||||
for (size_t i=0; i<map->width; i++)
|
|
||||||
{
|
{
|
||||||
for (size_t j=0; j<map->height; j++)
|
int3 pos = (*iter).second.first;
|
||||||
{
|
CFadeAnimation * anim = (*iter).second.second;
|
||||||
for (size_t k=0; k<(map->twoLevel ? 2 : 1); k++)
|
|
||||||
{
|
|
||||||
for(size_t x=0; x < ttiles[i][j][k].objects.size(); )
|
|
||||||
{
|
|
||||||
auto &obj = ttiles[i][j][k].objects[x];
|
|
||||||
|
|
||||||
switch (obj.fading)
|
anim->update();
|
||||||
{
|
if (anim->isFading())
|
||||||
case EMapObjectFadingType::IN:
|
++iter;
|
||||||
obj.fadingCounter += 0.2f;
|
|
||||||
if (obj.fadingCounter >= 1.0f)
|
|
||||||
{
|
|
||||||
obj.fadingCounter = 1.0f;
|
|
||||||
obj.fading = EMapObjectFadingType::NONE;
|
|
||||||
}
|
|
||||||
++x;
|
|
||||||
break;
|
|
||||||
case EMapObjectFadingType::OUT:
|
|
||||||
obj.fadingCounter -= 0.2f;
|
|
||||||
if (obj.fadingCounter <= 0.0f)
|
|
||||||
{
|
|
||||||
obj.fadingCounter = 0.0f;
|
|
||||||
obj.fading = EMapObjectFadingType::NONE;
|
|
||||||
ttiles[i][j][k].objects.erase(ttiles[i][j][k].objects.begin() + x);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
++x;
|
{
|
||||||
break;
|
auto &objs = ttiles[pos.x][pos.y][pos.z].objects;
|
||||||
default:
|
for (auto objIter = objs.begin(); objIter != objs.end(); ++objIter)
|
||||||
// not fading
|
{
|
||||||
++x;
|
if ((*objIter).fadeAnimKey == (*iter).first)
|
||||||
|
{
|
||||||
|
objs.erase(objIter);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
iter = fadeAnims.erase(iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
// TODO caching fading objects indices for optimization?
|
||||||
|
// for (size_t i=0; i<map->width; i++)
|
||||||
|
// {
|
||||||
|
// for (size_t j=0; j<map->height; j++)
|
||||||
|
// {
|
||||||
|
// for (size_t k=0; k<(map->twoLevel ? 2 : 1); k++)
|
||||||
|
// {
|
||||||
|
// for(size_t x=0; x < ttiles[i][j][k].objects.size(); )
|
||||||
|
// {
|
||||||
|
// auto &obj = ttiles[i][j][k].objects[x];
|
||||||
|
|
||||||
|
// if (obj.fadeAnimKey >= 0)
|
||||||
|
// {
|
||||||
|
// auto fadeAnimIter = fadeAnims.find(obj.fadeAnimKey);
|
||||||
|
// if (fadeAnimIter == fadeAnims.end())
|
||||||
|
// {
|
||||||
|
// obj.fadeAnimKey = -1;
|
||||||
|
// ++x;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// obj.fadeAnim->update();
|
||||||
|
// if (obj.fadeAnim->isFading())
|
||||||
|
// {
|
||||||
|
// anyObjectsStillFading = true;
|
||||||
|
// ++x;
|
||||||
|
// }
|
||||||
|
// else if (obj.fadeAnim->fadingMode == CFadeAnimation::EMode::OUT)
|
||||||
|
// ttiles[i][j][k].objects.erase(ttiles[i][j][k].objects.begin() + x);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// ++x;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
return !fadeAnims.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMapHandler::printObject(const CGObjectInstance *obj, bool fadein /* = false */)
|
bool CMapHandler::printObject(const CGObjectInstance *obj, bool fadein /* = false */)
|
||||||
@ -1215,7 +1235,7 @@ bool CMapHandler::printObject(const CGObjectInstance *obj, bool fadein /* = fals
|
|||||||
if (!graphics->getDef(obj))
|
if (!graphics->getDef(obj))
|
||||||
processDef(obj->appearance);
|
processDef(obj->appearance);
|
||||||
|
|
||||||
const SDL_Surface *bitmap = graphics->getDef(obj)->ourImages[0].bitmap;
|
SDL_Surface *bitmap = graphics->getDef(obj)->ourImages[0].bitmap;
|
||||||
const int tilesW = bitmap->w/32;
|
const int tilesW = bitmap->w/32;
|
||||||
const int tilesH = bitmap->h/32;
|
const int tilesH = bitmap->h/32;
|
||||||
|
|
||||||
@ -1231,8 +1251,12 @@ bool CMapHandler::printObject(const CGObjectInstance *obj, bool fadein /* = fals
|
|||||||
TerrainTileObject toAdd(obj, cr);
|
TerrainTileObject toAdd(obj, cr);
|
||||||
if (fadein)
|
if (fadein)
|
||||||
{
|
{
|
||||||
toAdd.fading = EMapObjectFadingType::IN;
|
auto tmp = CSDL_Ext::newSurface(bitmap->w, bitmap->h);
|
||||||
toAdd.fadingCounter = 0.0f;
|
SDL_BlitSurface(bitmap, nullptr, tmp, nullptr); // can't be 8bpp for fading
|
||||||
|
auto anim = new CFadeAnimation();
|
||||||
|
anim->init(CFadeAnimation::EMode::IN, 0.05f, tmp, true);
|
||||||
|
fadeAnims[++fadeAnimCounter] = std::pair<int3, CFadeAnimation*>(int3(fx, fy, obj->pos.z), anim);
|
||||||
|
toAdd.fadeAnimKey = fadeAnimCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((obj->pos.x + fx - tilesW+1)>=0 && (obj->pos.x + fx - tilesW+1)<ttiles.size()-frameW && (obj->pos.y + fy - tilesH+1)>=0 && (obj->pos.y + fy - tilesH+1)<ttiles[0].size()-frameH)
|
if((obj->pos.x + fx - tilesW+1)>=0 && (obj->pos.x + fx - tilesW+1)<ttiles.size()-frameW && (obj->pos.y + fy - tilesH+1)>=0 && (obj->pos.y + fy - tilesH+1)<ttiles[0].size()-frameH)
|
||||||
@ -1273,10 +1297,14 @@ bool CMapHandler::hideObject(const CGObjectInstance *obj, bool fadeout /* = fals
|
|||||||
{
|
{
|
||||||
if (fadeout) // erase delayed until end of fadeout
|
if (fadeout) // erase delayed until end of fadeout
|
||||||
{
|
{
|
||||||
ttiles[i][j][k].objects[x].fading = EMapObjectFadingType::OUT;
|
auto bitmap = graphics->getDef(obj)->ourImages[0].bitmap;
|
||||||
ttiles[i][j][k].objects[x].fadingCounter = 1.0f;
|
auto tmp = CSDL_Ext::newSurface(bitmap->w, bitmap->h); // TODO cache these bitmaps instead of creating new ones?
|
||||||
ttiles[i][j][k].objects[x].image = ttiles[i][j][k].objects[x].obj->appearance.animationFile;
|
SDL_BlitSurface(bitmap, nullptr, tmp, nullptr); // can't be 8bpp for fading
|
||||||
// fadingObjectsCache.push_back(std::make_pair(int3(i, j, k), ttiles[i][j][k].objects[x].obj->ID));
|
|
||||||
|
auto anim = new CFadeAnimation();
|
||||||
|
anim->init(CFadeAnimation::EMode::OUT, 0.05f, tmp, true);
|
||||||
|
fadeAnims[++fadeAnimCounter] = std::pair<int3, CFadeAnimation*>(int3(i, j, k), anim);
|
||||||
|
ttiles[i][j][k].objects[x].fadeAnimKey = fadeAnimCounter;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ttiles[i][j][k].objects.erase(ttiles[i][j][k].objects.begin() + x);
|
ttiles[i][j][k].objects.erase(ttiles[i][j][k].objects.begin() + x);
|
||||||
@ -1410,8 +1438,8 @@ CMapHandler::~CMapHandler()
|
|||||||
{
|
{
|
||||||
delete graphics->FoWfullHide;
|
delete graphics->FoWfullHide;
|
||||||
delete graphics->FoWpartialHide;
|
delete graphics->FoWpartialHide;
|
||||||
if (fadingOffscreenBitmapSurface)
|
// if (fadingOffscreenBitmapSurface)
|
||||||
delete fadingOffscreenBitmapSurface;
|
// delete fadingOffscreenBitmapSurface;
|
||||||
|
|
||||||
delete normalBlitter;
|
delete normalBlitter;
|
||||||
delete worldViewBlitter;
|
delete worldViewBlitter;
|
||||||
@ -1428,6 +1456,11 @@ CMapHandler::~CMapHandler()
|
|||||||
for(int j=0; j < elem.size(); ++j)
|
for(int j=0; j < elem.size(); ++j)
|
||||||
SDL_FreeSurface(elem[j]);
|
SDL_FreeSurface(elem[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto & elem : fadeAnims)
|
||||||
|
{
|
||||||
|
delete elem.second.second;
|
||||||
|
}
|
||||||
terrainGraphics.clear();
|
terrainGraphics.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1436,10 +1469,10 @@ CMapHandler::CMapHandler()
|
|||||||
frameW = frameH = 0;
|
frameW = frameH = 0;
|
||||||
graphics->FoWfullHide = nullptr;
|
graphics->FoWfullHide = nullptr;
|
||||||
graphics->FoWpartialHide = nullptr;
|
graphics->FoWpartialHide = nullptr;
|
||||||
fadingOffscreenBitmapSurface = nullptr;
|
|
||||||
normalBlitter = new CMapNormalBlitter(this);
|
normalBlitter = new CMapNormalBlitter(this);
|
||||||
worldViewBlitter = new CMapWorldViewBlitter(this);
|
worldViewBlitter = new CMapWorldViewBlitter(this);
|
||||||
puzzleViewBlitter = new CMapPuzzleViewBlitter(this);
|
puzzleViewBlitter = new CMapPuzzleViewBlitter(this);
|
||||||
|
fadeAnimCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapHandler::getTerrainDescr( const int3 &pos, std::string & out, bool terName )
|
void CMapHandler::getTerrainDescr( const int3 &pos, std::string & out, bool terName )
|
||||||
@ -1560,3 +1593,14 @@ bool CMapHandler::compareObjectBlitOrder(const CGObjectInstance * a, const CGObj
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TerrainTileObject::TerrainTileObject(const CGObjectInstance * obj_, SDL_Rect rect_)
|
||||||
|
: obj(obj_),
|
||||||
|
rect(rect_),
|
||||||
|
fadeAnimKey(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TerrainTileObject::~TerrainTileObject()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ struct TerrainTile;
|
|||||||
struct SDL_Surface;
|
struct SDL_Surface;
|
||||||
struct SDL_Rect;
|
struct SDL_Rect;
|
||||||
class CDefEssential;
|
class CDefEssential;
|
||||||
|
class CFadeAnimation;
|
||||||
|
|
||||||
enum class EWorldViewIcon
|
enum class EWorldViewIcon
|
||||||
{
|
{
|
||||||
@ -57,20 +58,20 @@ enum class EMapObjectFadingType
|
|||||||
OUT
|
OUT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class EMapAnimRedrawStatus
|
||||||
|
{
|
||||||
|
OK,
|
||||||
|
REDRAW_REQUESTED // map blitter requests quick redraw due to current animation
|
||||||
|
};
|
||||||
|
|
||||||
struct TerrainTileObject
|
struct TerrainTileObject
|
||||||
{
|
{
|
||||||
const CGObjectInstance *obj;
|
const CGObjectInstance *obj;
|
||||||
SDL_Rect rect;
|
SDL_Rect rect;
|
||||||
EMapObjectFadingType fading;
|
int fadeAnimKey;
|
||||||
float fadingCounter;
|
|
||||||
std::string image;
|
|
||||||
|
|
||||||
TerrainTileObject(const CGObjectInstance *obj_, SDL_Rect rect_)
|
TerrainTileObject(const CGObjectInstance *obj_, SDL_Rect rect_);
|
||||||
: obj(obj_),
|
~TerrainTileObject();
|
||||||
rect(rect_),
|
|
||||||
fading(EMapObjectFadingType::NONE),
|
|
||||||
fadingCounter(0.0f)
|
|
||||||
{}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TerrainTile2
|
struct TerrainTile2
|
||||||
@ -308,11 +309,11 @@ class CMapHandler
|
|||||||
CMapBlitter * worldViewBlitter;
|
CMapBlitter * worldViewBlitter;
|
||||||
CMapBlitter * puzzleViewBlitter;
|
CMapBlitter * puzzleViewBlitter;
|
||||||
|
|
||||||
// std::vector<std::pair<int3, int>> fadingObjectsCache;
|
std::map<int, std::pair<int3, CFadeAnimation*>> fadeAnims;
|
||||||
SDL_Surface * fadingOffscreenBitmapSurface;
|
int fadeAnimCounter;
|
||||||
|
|
||||||
CMapBlitter * resolveBlitter(const MapDrawingInfo * info) const;
|
CMapBlitter * resolveBlitter(const MapDrawingInfo * info) const;
|
||||||
void updateObjectsFade();
|
bool updateObjectsFade();
|
||||||
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)
|
||||||
@ -358,7 +359,7 @@ public:
|
|||||||
void roadsRiverTerrainInit();
|
void roadsRiverTerrainInit();
|
||||||
void prepareFOWDefs();
|
void prepareFOWDefs();
|
||||||
|
|
||||||
void drawTerrainRectNew(SDL_Surface * targetSurface, const MapDrawingInfo * info);
|
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
|
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]
|
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]
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "../Graphics.h"
|
#include "../Graphics.h"
|
||||||
#include "../mapHandler.h"
|
#include "../mapHandler.h"
|
||||||
|
|
||||||
|
#include "../gui/CAnimation.h"
|
||||||
#include "../gui/CCursorHandler.h"
|
#include "../gui/CCursorHandler.h"
|
||||||
#include "../gui/CGuiHandler.h"
|
#include "../gui/CGuiHandler.h"
|
||||||
#include "../gui/SDL_Extensions.h"
|
#include "../gui/SDL_Extensions.h"
|
||||||
@ -61,7 +62,10 @@ CAdvMapInt *adventureInt;
|
|||||||
|
|
||||||
|
|
||||||
CTerrainRect::CTerrainRect()
|
CTerrainRect::CTerrainRect()
|
||||||
: curHoveredTile(-1,-1,-1), currentPath(nullptr)
|
: fadeSurface(nullptr),
|
||||||
|
fadeAnim(new CFadeAnimation()),
|
||||||
|
curHoveredTile(-1,-1,-1),
|
||||||
|
currentPath(nullptr)
|
||||||
{
|
{
|
||||||
tilesw=(ADVOPT.advmapW+31)/32;
|
tilesw=(ADVOPT.advmapW+31)/32;
|
||||||
tilesh=(ADVOPT.advmapH+31)/32;
|
tilesh=(ADVOPT.advmapH+31)/32;
|
||||||
@ -73,6 +77,13 @@ CTerrainRect::CTerrainRect()
|
|||||||
addUsedEvents(LCLICK | RCLICK | HOVER | MOVE);
|
addUsedEvents(LCLICK | RCLICK | HOVER | MOVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CTerrainRect::~CTerrainRect()
|
||||||
|
{
|
||||||
|
if (fadeSurface)
|
||||||
|
SDL_FreeSurface(fadeSurface);
|
||||||
|
delete fadeAnim;
|
||||||
|
}
|
||||||
|
|
||||||
void CTerrainRect::deactivate()
|
void CTerrainRect::deactivate()
|
||||||
{
|
{
|
||||||
CIntObject::deactivate();
|
CIntObject::deactivate();
|
||||||
@ -273,7 +284,13 @@ void CTerrainRect::show(SDL_Surface * to)
|
|||||||
if (ADVOPT.smoothMove)
|
if (ADVOPT.smoothMove)
|
||||||
info.movement = int3(moveX, moveY, 0);
|
info.movement = int3(moveX, moveY, 0);
|
||||||
|
|
||||||
CGI->mh->drawTerrainRectNew(to, &info);
|
lastRedrawStatus = CGI->mh->drawTerrainRectNew(to, &info);
|
||||||
|
if (fadeAnim->isFading())
|
||||||
|
{
|
||||||
|
Rect r(pos);
|
||||||
|
fadeAnim->update();
|
||||||
|
fadeAnim->draw(to, nullptr, &r);
|
||||||
|
}
|
||||||
|
|
||||||
if (currentPath/* && adventureInt->position.z==currentPath->startPos().z*/) //drawing path
|
if (currentPath/* && adventureInt->position.z==currentPath->startPos().z*/) //drawing path
|
||||||
{
|
{
|
||||||
@ -298,6 +315,22 @@ void CTerrainRect::showAll(SDL_Surface * to)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CTerrainRect::showAnim(SDL_Surface * to)
|
||||||
|
{
|
||||||
|
if (fadeAnim->isFading())
|
||||||
|
show(to);
|
||||||
|
else if (lastRedrawStatus == EMapAnimRedrawStatus::REDRAW_REQUESTED)
|
||||||
|
{
|
||||||
|
MapDrawingInfo info(adventureInt->position, &LOCPLINT->cb->getVisibilityMap(), &pos);
|
||||||
|
info.otherheroAnim = true;
|
||||||
|
info.anim = adventureInt->anim;
|
||||||
|
info.heroAnim = adventureInt->heroAnim;
|
||||||
|
if (ADVOPT.smoothMove)
|
||||||
|
info.movement = int3(moveX, moveY, 0);
|
||||||
|
lastRedrawStatus = CGI->mh->drawTerrainRectNew(to, &info, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int3 CTerrainRect::whichTileIsIt(const int & x, const int & y)
|
int3 CTerrainRect::whichTileIsIt(const int & x, const int & y)
|
||||||
{
|
{
|
||||||
int3 ret;
|
int3 ret;
|
||||||
@ -326,6 +359,22 @@ int3 CTerrainRect::tileCountOnScreen()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CTerrainRect::fadeFromCurrentView()
|
||||||
|
{
|
||||||
|
if (adventureInt->mode == EAdvMapMode::WORLD_VIEW)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!fadeSurface)
|
||||||
|
fadeSurface = CSDL_Ext::newSurface(pos.w, pos.h);
|
||||||
|
SDL_BlitSurface(screen, &pos, fadeSurface, nullptr);
|
||||||
|
fadeAnim->init(CFadeAnimation::EMode::OUT, 0.05f, fadeSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTerrainRect::needsAnimUpdate()
|
||||||
|
{
|
||||||
|
return fadeAnim->isFading() || lastRedrawStatus == EMapAnimRedrawStatus::REDRAW_REQUESTED;
|
||||||
|
}
|
||||||
|
|
||||||
void CResDataBar::clickRight(tribool down, bool previousState)
|
void CResDataBar::clickRight(tribool down, bool previousState)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -917,6 +966,13 @@ void CAdvMapInt::show(SDL_Surface * to)
|
|||||||
updateScreen=false;
|
updateScreen=false;
|
||||||
LOCPLINT->cingconsole->showAll(to);
|
LOCPLINT->cingconsole->showAll(to);
|
||||||
}
|
}
|
||||||
|
else if (terrain.needsAnimUpdate())
|
||||||
|
{
|
||||||
|
terrain.showAnim(to);
|
||||||
|
for(int i=0;i<4;i++)
|
||||||
|
blitAt(gems[i]->ourImages[LOCPLINT->playerID.getNum()].bitmap,ADVOPT.gemX[i],ADVOPT.gemY[i],to);
|
||||||
|
}
|
||||||
|
|
||||||
infoBar.show(to);
|
infoBar.show(to);
|
||||||
statusbar.showAll(to);
|
statusbar.showAll(to);
|
||||||
}
|
}
|
||||||
@ -928,10 +984,16 @@ void CAdvMapInt::selectionChanged()
|
|||||||
select(to);
|
select(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAdvMapInt::centerOn(int3 on)
|
void CAdvMapInt::centerOn(int3 on, bool fadeIfZChanged /* = false */)
|
||||||
{
|
{
|
||||||
bool switchedLevels = on.z != position.z;
|
bool switchedLevels = on.z != position.z;
|
||||||
|
|
||||||
|
if (switchedLevels && fadeIfZChanged)
|
||||||
|
{
|
||||||
|
logGlobal->warnStream() << "START FADING";
|
||||||
|
terrain.fadeFromCurrentView();
|
||||||
|
}
|
||||||
|
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
@ -962,9 +1024,9 @@ void CAdvMapInt::centerOn(int3 on)
|
|||||||
terrain.redraw();
|
terrain.redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAdvMapInt::centerOn(const CGObjectInstance *obj)
|
void CAdvMapInt::centerOn(const CGObjectInstance *obj, bool fadeIfZChanged /* = false */)
|
||||||
{
|
{
|
||||||
centerOn(obj->getSightCenter());
|
centerOn(obj->getSightCenter(), fadeIfZChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||||
|
@ -15,6 +15,8 @@ class CGTownInstance;
|
|||||||
class CHeroWindow;
|
class CHeroWindow;
|
||||||
class CSpell;
|
class CSpell;
|
||||||
class IShipyard;
|
class IShipyard;
|
||||||
|
enum class EMapAnimRedrawStatus;
|
||||||
|
class CFadeAnimation;
|
||||||
|
|
||||||
/*****************************/
|
/*****************************/
|
||||||
|
|
||||||
@ -48,12 +50,16 @@ public:
|
|||||||
class CTerrainRect
|
class CTerrainRect
|
||||||
: public CIntObject
|
: public CIntObject
|
||||||
{
|
{
|
||||||
|
SDL_Surface * fadeSurface;
|
||||||
|
EMapAnimRedrawStatus lastRedrawStatus;
|
||||||
|
CFadeAnimation * fadeAnim;
|
||||||
public:
|
public:
|
||||||
int tilesw, tilesh; //width and height of terrain to blit in tiles
|
int tilesw, tilesh; //width and height of terrain to blit in tiles
|
||||||
int3 curHoveredTile;
|
int3 curHoveredTile;
|
||||||
int moveX, moveY; //shift between actual position of screen and the one we wil blit; ranges from -31 to 31 (in pixels)
|
int moveX, moveY; //shift between actual position of screen and the one we wil blit; ranges from -31 to 31 (in pixels)
|
||||||
|
|
||||||
CTerrainRect();
|
CTerrainRect();
|
||||||
|
virtual ~CTerrainRect();
|
||||||
CGPath * currentPath;
|
CGPath * currentPath;
|
||||||
void deactivate();
|
void deactivate();
|
||||||
void clickLeft(tribool down, bool previousState);
|
void clickLeft(tribool down, bool previousState);
|
||||||
@ -62,11 +68,15 @@ public:
|
|||||||
void mouseMoved (const SDL_MouseMotionEvent & sEvent);
|
void mouseMoved (const SDL_MouseMotionEvent & sEvent);
|
||||||
void show(SDL_Surface * to);
|
void show(SDL_Surface * to);
|
||||||
void showAll(SDL_Surface * to);
|
void showAll(SDL_Surface * to);
|
||||||
|
void showAnim(SDL_Surface * to);
|
||||||
void showPath(const SDL_Rect * extRect, SDL_Surface * to);
|
void showPath(const SDL_Rect * extRect, SDL_Surface * to);
|
||||||
int3 whichTileIsIt(const int & x, const int & y); //x,y are cursor position
|
int3 whichTileIsIt(const int & x, const int & y); //x,y are cursor position
|
||||||
int3 whichTileIsIt(); //uses current cursor pos
|
int3 whichTileIsIt(); //uses current cursor pos
|
||||||
/// @returns number of visible tiles on screen respecting current map scaling
|
/// @returns number of visible tiles on screen respecting current map scaling
|
||||||
int3 tileCountOnScreen();
|
int3 tileCountOnScreen();
|
||||||
|
/// animates view by caching current surface and crossfading it with normal screen
|
||||||
|
void fadeFromCurrentView();
|
||||||
|
bool needsAnimUpdate();
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Resources bar which shows information about how many gold, crystals,... you have
|
/// Resources bar which shows information about how many gold, crystals,... you have
|
||||||
@ -176,8 +186,8 @@ public:
|
|||||||
|
|
||||||
void select(const CArmedInstance *sel, bool centerView = true);
|
void select(const CArmedInstance *sel, bool centerView = true);
|
||||||
void selectionChanged();
|
void selectionChanged();
|
||||||
void centerOn(int3 on);
|
void centerOn(int3 on, bool fadeIfZChanged = false);
|
||||||
void centerOn(const CGObjectInstance *obj);
|
void centerOn(const CGObjectInstance *obj, bool fadeIfZChanged = false);
|
||||||
int3 verifyPos(int3 ver);
|
int3 verifyPos(int3 ver);
|
||||||
void handleRightClick(std::string text, tribool down);
|
void handleRightClick(std::string text, tribool down);
|
||||||
void keyPressed(const SDL_KeyboardEvent & key);
|
void keyPressed(const SDL_KeyboardEvent & key);
|
||||||
|
Loading…
Reference in New Issue
Block a user