mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-21 17:17:06 +02:00
[animRewrite] * Implemented CCompAnimation glue effect * std::copy instead of memcpy * Usage of boost::optional for the optional group loading args * Removed unused selector structs
This commit is contained in:
parent
b1c99f447e
commit
7f2e2b10f8
@ -10,7 +10,7 @@
|
||||
IImage * CResourceHandler::getImage(const std::string & name, size_t frame, size_t group)
|
||||
{
|
||||
ResourceLocator loc = CGI->filesystemh->getResourceLocator(ResourceIdentifier(name, EResType::ANIMATION));
|
||||
return loadImage(loc, frame, group);
|
||||
return loadImage(loc, boost::make_optional(frame), boost::make_optional(group));
|
||||
}
|
||||
|
||||
IImage * CResourceHandler::getImage(const std::string & name)
|
||||
@ -22,16 +22,16 @@ IImage * CResourceHandler::getImage(const std::string & name)
|
||||
CSDLImage * CResourceHandler::getSurface(const std::string & name)
|
||||
{
|
||||
ResourceLocator loc = CGI->filesystemh->getResourceLocator(ResourceIdentifier(name, EResType::GRAPHICS));
|
||||
return dynamic_cast<CSDLImage *>(loadImage(loc, -1, -1, true));
|
||||
return dynamic_cast<CSDLImage *>(loadImage(loc, boost::none, boost::none, true));
|
||||
}
|
||||
|
||||
CSDLImage * CResourceHandler::getSurface(const std::string & name, size_t frame, size_t group)
|
||||
{
|
||||
ResourceLocator loc = CGI->filesystemh->getResourceLocator(ResourceIdentifier(name, EResType::ANIMATION));
|
||||
return dynamic_cast<CSDLImage *>(loadImage(loc, frame, group, true));
|
||||
return dynamic_cast<CSDLImage *>(loadImage(loc, boost::make_optional(frame), boost::make_optional(group), true));
|
||||
}
|
||||
|
||||
IImage * CResourceHandler::loadImage(const ResourceLocator & loc, size_t frame /*= -1*/, size_t group /*= -1*/, bool useSDL /*= false*/)
|
||||
IImage * CResourceHandler::loadImage(const ResourceLocator & loc, boost::optional<size_t> frame /*= boost::none*/, boost::optional<size_t> group /*= boost::none*/, bool useSDL /*= false*/)
|
||||
{
|
||||
// Load data stream
|
||||
CMemoryStream * data = CGI->filesystemh->getResource(loc);
|
||||
@ -53,15 +53,17 @@ IImage * CResourceHandler::loadImage(const ResourceLocator & loc, size_t frame /
|
||||
// Construct the .DEF animation format
|
||||
CDefFile defFile(data);
|
||||
|
||||
assert(frame && group);
|
||||
|
||||
// always use CCompImage when loading from DEF file
|
||||
// we keep the possibility to load via SDL image
|
||||
static const bool useComp = true;
|
||||
|
||||
if (useComp)
|
||||
return new CCompImage(&defFile, frame, group);
|
||||
return new CCompImage(&defFile, *frame, *group);
|
||||
|
||||
else
|
||||
return new CSDLImage(&defFile, frame, group);
|
||||
return new CSDLImage(&defFile, *frame, *group);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -69,19 +71,13 @@ IImage * CResourceHandler::loadImage(const ResourceLocator & loc, size_t frame /
|
||||
}
|
||||
}
|
||||
|
||||
CAnimationHolder * CResourceHandler::getAnimation(const std::string & name)
|
||||
{
|
||||
ResourceLocator loc = CGI->filesystemh->getResourceLocator(ResourceIdentifier(name, EResType::ANIMATION));
|
||||
return new CAnimationHolder(loadAnimation(loc));
|
||||
}
|
||||
|
||||
CAnimationHolder * CResourceHandler::getAnimation(const std::string & name, size_t group)
|
||||
CAnimationHolder * CResourceHandler::getAnimation(const std::string & name, boost::optional<size_t> group /*= boost::none*/)
|
||||
{
|
||||
ResourceLocator loc = CGI->filesystemh->getResourceLocator(ResourceIdentifier(name, EResType::ANIMATION));
|
||||
return new CAnimationHolder(loadAnimation(loc, group));
|
||||
}
|
||||
|
||||
IAnimation * CResourceHandler::loadAnimation(const ResourceLocator & loc, size_t group /*= -1*/)
|
||||
IAnimation * CResourceHandler::loadAnimation(const ResourceLocator & loc, boost::optional<size_t> group /*= boost::none*/)
|
||||
{
|
||||
CMemoryStream * data = CGI->filesystemh->getResource(loc);
|
||||
|
||||
|
@ -20,8 +20,8 @@ class CSDLImage;
|
||||
|
||||
class CResourceHandler
|
||||
{
|
||||
IImage * loadImage(const ResourceLocator & loc, size_t frame = -1, size_t group = -1, bool useSDL = false);
|
||||
IAnimation * loadAnimation(const ResourceLocator & loc, size_t group = -1);
|
||||
IImage * loadImage(const ResourceLocator & loc, boost::optional<size_t> frame = boost::none, boost::optional<size_t> group = boost::none, bool useSDL = false);
|
||||
IAnimation * loadAnimation(const ResourceLocator & loc, boost::optional<size_t> group = boost::none);
|
||||
|
||||
public:
|
||||
|
||||
@ -35,9 +35,12 @@ public:
|
||||
|
||||
CSDLImage * getSurface(const std::string & name, size_t frame, size_t group);
|
||||
|
||||
// Loads complete animation(all groups).
|
||||
CAnimationHolder * getAnimation(const std::string & name);
|
||||
|
||||
// Loads a group of an animation.
|
||||
CAnimationHolder * getAnimation(const std::string & name, size_t group);
|
||||
/**
|
||||
* Gets and loads an animation.
|
||||
*
|
||||
* @param name The resource name of the animation(no path or file extensions, only name)
|
||||
* @param group If you wan't to load one animation group only then pass the number. Leave empty to load all groups.
|
||||
* @return An object of type CAnimationHolder which provides functionality to show a time-based animation.
|
||||
*/
|
||||
CAnimationHolder * getAnimation(const std::string & name, boost::optional<size_t> group = boost::none);
|
||||
};
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "../CGameInfo.h"
|
||||
#include "../../lib/CFileSystemHandler.h"
|
||||
|
||||
IAnimation::IAnimation() : loadedGroup(0)
|
||||
IAnimation::IAnimation() : loadedGroup(boost::none)
|
||||
{
|
||||
|
||||
}
|
||||
@ -16,7 +16,7 @@ std::map<size_t, size_t> IAnimation::getEntries() const
|
||||
return entries;
|
||||
}
|
||||
|
||||
si8 IAnimation::getLoadedGroup() const
|
||||
boost::optional<size_t> IAnimation::getLoadedGroup() const
|
||||
{
|
||||
return loadedGroup;
|
||||
}
|
||||
@ -61,23 +61,25 @@ CImageBasedAnimation::~CImageBasedAnimation()
|
||||
}
|
||||
|
||||
template<typename anim>
|
||||
void CImageBasedAnimation::constructImageBasedAnimation(const CDefFile * defFile, size_t group /*= -1*/)
|
||||
void CImageBasedAnimation::constructImageBasedAnimation(const CDefFile * defFile, boost::optional<size_t> group /*= boost::none*/)
|
||||
{
|
||||
entries = defFile->getEntries();
|
||||
loadedGroup = group;
|
||||
|
||||
if (group == -1)
|
||||
// If no group was specified, then load all groups
|
||||
if(!group)
|
||||
{
|
||||
for(std::map<size_t, size_t>::iterator group = entries.begin(); group != entries.end(); ++group)
|
||||
for(size_t frame = 0; frame < group->second; frame++)
|
||||
images[group->first][frame] = new anim(defFile, frame, group->first);
|
||||
}
|
||||
// Load the specified group
|
||||
else
|
||||
{
|
||||
if(vstd::contains(entries, group))
|
||||
if(vstd::contains(entries, *group))
|
||||
{
|
||||
for(size_t frame = 0; frame < entries[group]; frame++)
|
||||
images[group][frame] = new anim(defFile, frame, group);
|
||||
for(size_t frame = 0; frame < entries[*group]; frame++)
|
||||
images[*group][frame] = new anim(defFile, frame, *group);
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,7 +89,7 @@ void CImageBasedAnimation::constructImageBasedAnimation(const CDefFile * defFile
|
||||
void CImageBasedAnimation::forEach(std::function<void(IImage *)> func)
|
||||
{
|
||||
// recolor all groups
|
||||
if(loadedGroup == -1)
|
||||
if(loadedGroup == boost::none)
|
||||
{
|
||||
for(group_it it = images.begin(); it != images.end(); ++it)
|
||||
{
|
||||
@ -101,7 +103,7 @@ void CImageBasedAnimation::forEach(std::function<void(IImage *)> func)
|
||||
else
|
||||
{
|
||||
// recolor loaded group
|
||||
group_it it = images.find(loadedGroup);
|
||||
group_it it = images.find(*loadedGroup);
|
||||
assert(it != images.end());
|
||||
|
||||
for(frame_it it2 = it->second.begin(); it2 != it->second.end(); ++it2)
|
||||
@ -136,7 +138,7 @@ void CImageBasedAnimation::recolorToPlayer(int player)
|
||||
});
|
||||
}
|
||||
|
||||
CCompAnimation::CCompAnimation(const CDefFile * defFile, size_t group /*= -1*/) : glowType(EGlowAnimationType::NONE),
|
||||
CCompAnimation::CCompAnimation(const CDefFile * defFile, boost::optional<size_t> group /*= boost::none*/) : glowType(EGlowAnimationType::NONE),
|
||||
glowIntensity(0), alpha(255), rotateFlipType(ERotateFlipType::NONE)
|
||||
{
|
||||
constructImageBasedAnimation<CCompImage>(defFile, group);
|
||||
@ -170,7 +172,7 @@ void CCompAnimation::rotateFlip(ERotateFlipType::ERotateFlipType type)
|
||||
this->rotateFlipType = type;
|
||||
}
|
||||
|
||||
CSDLAnimation::CSDLAnimation(const CDefFile * defFile, size_t group /*= -1*/)
|
||||
CSDLAnimation::CSDLAnimation(const CDefFile * defFile, boost::optional<size_t> group /*= boost::none*/)
|
||||
{
|
||||
constructImageBasedAnimation<CSDLImage>(defFile, group);
|
||||
}
|
||||
@ -365,8 +367,28 @@ CAnimationHolder::CAnimationHolder(IAnimation * animation)
|
||||
: anim(animation), currentGroup(0), currentFrame(0), glowType(EGlowAnimationType::NONE),
|
||||
glowIntensity(MIN_GLOW_INTENSITY)
|
||||
{
|
||||
size_t loadedGroup = animation->getLoadedGroup();
|
||||
setGroup(loadedGroup == -1 ? 0 : loadedGroup);
|
||||
boost::optional<size_t> loadedGroup = animation->getLoadedGroup();
|
||||
setGroup(loadedGroup == boost::none ? 0 : *loadedGroup);
|
||||
}
|
||||
|
||||
CAnimationHolder::CAnimationHolder(const CAnimationHolder & cpy)
|
||||
{
|
||||
*this = cpy;
|
||||
}
|
||||
|
||||
CAnimationHolder & CAnimationHolder::operator=(const CAnimationHolder & cpy)
|
||||
{
|
||||
anim = cpy.anim->clone();
|
||||
currentGroup = cpy.currentGroup;
|
||||
currentFrame = cpy.currentFrame;
|
||||
frameCount = cpy.frameCount;
|
||||
currentTime = cpy.currentTime;
|
||||
glowTime = cpy.glowTime;
|
||||
repeat = cpy.repeat;
|
||||
glowType = cpy.glowType;
|
||||
glowIntensity = cpy.glowIntensity;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CAnimationHolder::~CAnimationHolder()
|
||||
@ -389,16 +411,16 @@ void CAnimationHolder::setGroup(size_t group, bool repeat /*= false*/)
|
||||
this->repeat = repeat;
|
||||
std::map<size_t, size_t> entries = anim->getEntries();
|
||||
|
||||
// check if the group is loaded
|
||||
if(anim->getLoadedGroup() != group && anim->getLoadedGroup() != -1)
|
||||
{
|
||||
tlog2 << "Group Nr. " << group << " couldn't be loaded." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the group nr is defined in the animation format
|
||||
// Validate whether the group is defined in the animation format
|
||||
if(vstd::contains(entries, group))
|
||||
{
|
||||
// Validate whether the group is loaded
|
||||
if(anim->getLoadedGroup() != boost::none && *anim->getLoadedGroup() != group)
|
||||
{
|
||||
tlog2 << "Group Nr. " << group << " isn't loaded." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
frameCount = entries[group];
|
||||
currentTime = 0.0;
|
||||
currentGroup = group;
|
||||
@ -472,6 +494,7 @@ void CAnimationHolder::setGlowAnimation(EGlowAnimationType::EGlowAnimationType g
|
||||
{
|
||||
glowTime = 0.0;
|
||||
this->glowType = glowType;
|
||||
anim->setGlowAnimation(glowType, 0);
|
||||
}
|
||||
|
||||
void CAnimationHolder::setAlpha(ui8 alpha)
|
||||
|
@ -25,8 +25,8 @@ protected:
|
||||
std::map<size_t, size_t> entries;
|
||||
Point pos;
|
||||
|
||||
// Positive value for the loaded group. -1 if all groups are loaded.
|
||||
size_t loadedGroup;
|
||||
/** Contains the number of the loaded group. */
|
||||
boost::optional<size_t> loadedGroup;
|
||||
|
||||
public:
|
||||
IAnimation();
|
||||
@ -37,7 +37,7 @@ public:
|
||||
std::map<size_t, size_t> getEntries() const;
|
||||
|
||||
// Gets the index of the loaded group. -1 if all groups are loaded.
|
||||
si8 getLoadedGroup() const;
|
||||
boost::optional<size_t> getLoadedGroup() const;
|
||||
|
||||
virtual void draw(size_t frame, size_t group) const =0;
|
||||
|
||||
@ -62,7 +62,7 @@ protected:
|
||||
~CImageBasedAnimation();
|
||||
|
||||
template<typename anim>
|
||||
void constructImageBasedAnimation(const CDefFile * defFile, size_t group /*= -1*/);
|
||||
void constructImageBasedAnimation(const CDefFile * defFile, boost::optional<size_t> group = boost::none);
|
||||
|
||||
public:
|
||||
void forEach(std::function<void(IImage *)> func);
|
||||
@ -81,7 +81,7 @@ class CCompAnimation : public CImageBasedAnimation
|
||||
ERotateFlipType::ERotateFlipType rotateFlipType;
|
||||
|
||||
public:
|
||||
CCompAnimation(const CDefFile * defFile, size_t group = -1);
|
||||
CCompAnimation(const CDefFile * defFile, boost::optional<size_t> group = boost::none);
|
||||
IAnimation * clone() const;
|
||||
|
||||
void applyTransformations(IImage * img) const;
|
||||
@ -93,7 +93,7 @@ public:
|
||||
class CSDLAnimation : public CImageBasedAnimation
|
||||
{
|
||||
public:
|
||||
CSDLAnimation(const CDefFile * defFile, size_t group = -1);
|
||||
CSDLAnimation(const CDefFile * defFile, boost::optional<size_t> group = boost::none);
|
||||
IAnimation * clone() const;
|
||||
|
||||
void rotateFlip(ERotateFlipType::ERotateFlipType type);
|
||||
@ -141,6 +141,8 @@ class CAnimationHolder
|
||||
|
||||
public:
|
||||
explicit CAnimationHolder(IAnimation * animation);
|
||||
CAnimationHolder(const CAnimationHolder & cpy);
|
||||
CAnimationHolder & operator=(const CAnimationHolder & cpy);
|
||||
~CAnimationHolder();
|
||||
|
||||
void setGroup(size_t group, bool repeat = false);
|
||||
|
@ -603,6 +603,9 @@ CCompImage::CCompImage(const CDefFile * defFile, size_t frame, size_t group)
|
||||
{
|
||||
CCompImageLoader loader(this);
|
||||
defFile->loadFrame(frame, group, loader);
|
||||
|
||||
glowPalette = new SDL_Color[3];
|
||||
std::copy(palette + 5, palette + 8, glowPalette);
|
||||
}
|
||||
|
||||
CCompImage::CCompImage(const CCompImage & cpy)
|
||||
@ -617,20 +620,16 @@ CCompImage & CCompImage::operator=(const CCompImage & cpy)
|
||||
sprite = cpy.sprite;
|
||||
|
||||
palette = new SDL_Color[256];
|
||||
memcpy(reinterpret_cast<void *>(palette),
|
||||
reinterpret_cast<void *>(cpy.palette), 256 * sizeof(SDL_Color));
|
||||
std::copy(cpy.palette, cpy.palette + 256, palette);
|
||||
|
||||
glowPalette = new SDL_Color[3];
|
||||
memcpy(reinterpret_cast<void *>(glowPalette),
|
||||
reinterpret_cast<void *>(cpy.glowPalette + 5 * sizeof(SDL_Color)), 3 * sizeof(SDL_Color));
|
||||
std::copy(cpy.glowPalette, cpy.glowPalette + 3, glowPalette);
|
||||
|
||||
surf = reinterpret_cast<ui8 *>(malloc(length));
|
||||
memcpy(reinterpret_cast<void *>(surf),
|
||||
reinterpret_cast<void *>(cpy.surf), length);
|
||||
std::copy(cpy.surf, cpy.surf + length, surf);
|
||||
|
||||
line = new ui32[sprite.h + 1];
|
||||
memcpy(reinterpret_cast<void *>(line),
|
||||
reinterpret_cast<void *>(cpy.line), (sprite.h + 1) * sizeof(ui32));
|
||||
std::copy(cpy.line, cpy.line + sprite.h + 1, line);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -643,7 +642,6 @@ IImage * CCompImage::clone() const
|
||||
CCompImage::~CCompImage()
|
||||
{
|
||||
free(surf);
|
||||
delete [] glowPalette;
|
||||
delete [] line;
|
||||
delete [] palette;
|
||||
}
|
||||
@ -829,51 +827,44 @@ void CCompImage::recolorToPlayer(int player)
|
||||
else
|
||||
assert(0);
|
||||
|
||||
for(size_t i = 0; i < 32; ++i)
|
||||
{
|
||||
palette[224 + i].r = pal[i].r;
|
||||
palette[224 + i].g = pal[i].g;
|
||||
palette[224 + i].b = pal[i].b;
|
||||
palette[224 + i].unused = pal[i].unused;
|
||||
}
|
||||
std::copy(pal, pal + 32, palette + 224);
|
||||
}
|
||||
|
||||
void CCompImage::setGlowAnimation(EGlowAnimationType::EGlowAnimationType glowType, ui8 intensity)
|
||||
{
|
||||
// Init the glow palette for the first time
|
||||
if (glowPalette == NULL)
|
||||
{
|
||||
glowPalette = new SDL_Color[3];
|
||||
memcpy(reinterpret_cast<void *>(glowPalette),
|
||||
reinterpret_cast<void *>(palette + 5 * sizeof(SDL_Color)), 3 * sizeof(SDL_Color));
|
||||
}
|
||||
|
||||
if (glowType == EGlowAnimationType::BLUE)
|
||||
{
|
||||
for (size_t i = 5; i < 8; ++i)
|
||||
palette[5].r = glowPalette[0].b;
|
||||
palette[5].g = intensity - glowPalette[0].g;
|
||||
palette[5].b = intensity - glowPalette[0].r;
|
||||
palette[5].unused = 255;
|
||||
|
||||
for (size_t i = 6; i <= 7; ++i)
|
||||
{
|
||||
palette[i].r = (i == 5) ? glowPalette[i].b : 0;
|
||||
palette[i].g = (i == 5) ? (intensity - glowPalette[i].g) : intensity;
|
||||
palette[i].b = (i == 5) ? (intensity - glowPalette[i].r) : intensity;
|
||||
palette[i].r = 0;
|
||||
palette[i].g = intensity;
|
||||
palette[i].b = intensity;
|
||||
palette[i].unused = 255;
|
||||
}
|
||||
}
|
||||
else if (glowType == EGlowAnimationType::YELLOW)
|
||||
{
|
||||
for (size_t i = 5; i < 8; ++i)
|
||||
palette[5].r = intensity - glowPalette[0].r;
|
||||
palette[5].g = intensity - glowPalette[0].g;
|
||||
palette[5].b = glowPalette[0].b;
|
||||
palette[5].unused = 255;
|
||||
|
||||
for (size_t i = 6; i <= 7; ++i)
|
||||
{
|
||||
palette[i].r = (i == 5) ? (intensity - glowPalette[i].r) : intensity;
|
||||
palette[i].g = (i == 5) ? (intensity - glowPalette[i].g) : intensity;
|
||||
palette[i].b = (i == 5) ? glowPalette[i].b : 0;
|
||||
palette[i].r = intensity;
|
||||
palette[i].g = intensity;
|
||||
palette[i].b = 0;
|
||||
palette[i].unused = 255;
|
||||
}
|
||||
}
|
||||
else if (glowType == EGlowAnimationType::NONE)
|
||||
{
|
||||
for (size_t i = 5; i < 8; ++i)
|
||||
{
|
||||
palette[i].r = glowPalette[i].r;
|
||||
palette[i].g = glowPalette[i].g;
|
||||
palette[i].b = glowPalette[i].b;
|
||||
}
|
||||
std::copy(glowPalette, glowPalette + 3, palette + 5);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,52 +45,6 @@ namespace ERotateFlipType
|
||||
};
|
||||
}
|
||||
|
||||
struct GraphicsSelector
|
||||
{
|
||||
si8 frame, group;
|
||||
|
||||
GraphicsSelector(si8 Group = -1, si8 Frame = 0) : frame(Frame), group(Group) { };
|
||||
|
||||
inline bool operator==(GraphicsSelector const & other) const
|
||||
{
|
||||
return frame == other.frame && group == other.group;
|
||||
}
|
||||
|
||||
inline friend std::size_t hash_value(GraphicsSelector const & p)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
boost::hash_combine(seed, p.frame);
|
||||
boost::hash_combine(seed, p.group);
|
||||
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
struct GraphicsLocator : public ResourceLocator
|
||||
{
|
||||
GraphicsSelector sel;
|
||||
|
||||
GraphicsLocator() : ResourceLocator() { };
|
||||
GraphicsLocator(IResourceLoader * Loader, const std::string & ResourceName, const GraphicsSelector & Sel)
|
||||
: ResourceLocator(Loader, ResourceName), sel(Sel) { };
|
||||
|
||||
inline bool operator==(GraphicsLocator const & other) const
|
||||
{
|
||||
return loader == other.loader && resourceName == other.resourceName
|
||||
&& sel == other.sel;
|
||||
}
|
||||
|
||||
inline friend std::size_t hash_value(GraphicsLocator const & p)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
boost::hash_combine(seed, p.loader);
|
||||
boost::hash_combine(seed, p.resourceName);
|
||||
boost::hash_combine(seed, p.sel);
|
||||
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Interface for VCMI related graphics tasks like player coloring
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user