1
0
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:
beegee1 2012-04-24 18:47:05 +00:00
parent b1c99f447e
commit 7f2e2b10f8
6 changed files with 101 additions and 132 deletions

View File

@ -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);

View File

@ -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);
};

View File

@ -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)

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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
*/