From 807eca8bee4aec188ef893f362b83d921e2c6686 Mon Sep 17 00:00:00 2001 From: beegee1 Date: Fri, 20 Apr 2012 19:10:18 +0000 Subject: [PATCH] [animRewrite] * Implemented flip operation * Code clean-up & Bug fixes --- client/CMT.cpp | 2 +- client/CResourceHandler.cpp | 94 +++++++------- client/CResourceHandler.h | 27 ++-- client/UIFramework/AnimationClasses.cpp | 163 ++++++++++++++---------- client/UIFramework/AnimationClasses.h | 61 ++++++--- client/UIFramework/ImageClasses.cpp | 85 ++++++++---- client/UIFramework/ImageClasses.h | 14 +- client/UIFramework/ImageClassesFwd.h | 33 +++-- client/UIFramework/SDL_Extensions.cpp | 8 +- client/UIFramework/SDL_Extensions.h | 4 +- configure | 2 +- configure.ac | 2 +- lib/CConsoleHandler.h | 7 +- 13 files changed, 297 insertions(+), 205 deletions(-) diff --git a/client/CMT.cpp b/client/CMT.cpp index f8c86486e..2d13b5b5e 100644 --- a/client/CMT.cpp +++ b/client/CMT.cpp @@ -596,7 +596,7 @@ static void setScreenRes(int w, int h, int bpp, bool fullscreen) if(suggestedBpp != bpp) { - tlog3 << "Warning: SDL says that the adjusted resolution of " << bpp << "bpp wasn't available. Changed bpp to " << suggestedBpp << " ." << std::endl; + tlog0 << "Warning: SDL says that the adjusted resolution of " << bpp << "bpp wasn't available. Changed bpp to " << suggestedBpp << "." << std::endl; } if(screen) //screen has been already initialized diff --git a/client/CResourceHandler.cpp b/client/CResourceHandler.cpp index cb0179deb..1afd0a1cd 100644 --- a/client/CResourceHandler.cpp +++ b/client/CResourceHandler.cpp @@ -7,80 +7,74 @@ #include "UIFramework/AnimationClasses.h" -IImage * CResourceHandler::getImage(const ResourceIdentifier & identifier, size_t frame, size_t group, bool fromBegin /*= false*/) +IImage * CResourceHandler::getImage(const ResourceIdentifier & identifier, size_t frame, size_t group) { - ResourceLocator loc = CGI->filesystemh->getResourceLocator(identifier, fromBegin); + ResourceLocator loc = CGI->filesystemh->getResourceLocator(identifier); return loadImage(loc, frame, group); } -IImage * CResourceHandler::getImage(const ResourceIdentifier & identifier, bool fromBegin /*= false*/) +IImage * CResourceHandler::getImage(const ResourceIdentifier & identifier) { - ResourceLocator loc = CGI->filesystemh->getResourceLocator(identifier, fromBegin); + ResourceLocator loc = CGI->filesystemh->getResourceLocator(identifier); return loadImage(loc); } -IImage * CResourceHandler::createImageFromFile(CMemoryStream * data, const std::string & imageType) +CSDLImage * CResourceHandler::getSurface(const ResourceIdentifier & identifier) { - // always use SDL when loading image from file - return new CSDLImage(data, imageType); + ResourceLocator loc = CGI->filesystemh->getResourceLocator(identifier); + return dynamic_cast(loadImage(loc, -1, -1, true)); } -IImage * CResourceHandler::createSpriteFromDEF(const CDefFile * defFile, size_t frame, size_t group) +CSDLImage * CResourceHandler::getSurface(const ResourceIdentifier & identifier, size_t frame, size_t 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); - - else - return new CSDLImage(defFile, frame, group); + ResourceLocator loc = CGI->filesystemh->getResourceLocator(identifier); + return dynamic_cast(loadImage(loc, frame, group, true)); } -IImage * CResourceHandler::loadImage(const ResourceLocator & loc, size_t frame /*= -1*/, size_t group /*= -1*/) +IImage * CResourceHandler::loadImage(const ResourceLocator & loc, size_t frame /*= -1*/, size_t group /*= -1*/, bool useSDL /*= false*/) { + // Load data stream CMemoryStream * data = CGI->filesystemh->getResource(loc); - // get file info of the locator + // Get file info CFileInfo locInfo(loc.resourceName); + // If the image should be used for image editing, then load it as SDL + if(useSDL) + return new CSDLImage(data, locInfo.getExtension()); + + // Requested image(sprite) resides in a .DEF file if(boost::iequals(locInfo.getExtension(), ".DEF")) { + // Construct the .DEF animation format CDefFile defFile(data); - return createSpriteFromDEF(&defFile, 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); + + else + return new CSDLImage(&defFile, frame, group); } else { - return createImageFromFile(data, locInfo.getExtension()); + return new CSDLImage(data, locInfo.getExtension()); } } -IAnimation * CResourceHandler::getAnimation(const ResourceIdentifier & identifier, bool fromBegin /*= false*/) +CAnimationHolder * CResourceHandler::getAnimation(const ResourceIdentifier & identifier) { - ResourceLocator loc = CGI->filesystemh->getResourceLocator(identifier, fromBegin); - return loadAnimation(loc); + ResourceLocator loc = CGI->filesystemh->getResourceLocator(identifier); + return new CAnimationHolder(loadAnimation(loc)); } -IAnimation * CResourceHandler::getAnimation(const ResourceIdentifier & identifier, size_t group, bool fromBegin /*= false*/) +CAnimationHolder * CResourceHandler::getAnimation(const ResourceIdentifier & identifier, size_t group) { - ResourceLocator loc = CGI->filesystemh->getResourceLocator(identifier, fromBegin); - return loadAnimation(loc, group); -} - -IAnimation * CResourceHandler::createAnimation(const CDefFile * defFile, size_t group /*= -1*/) -{ - // use always image based animations for the moment; - static const bool useImageBased = true; - - if (useImageBased) - { - return new CImageBasedAnimation(defFile, group); - } - else - { - return new CDefAnimation(defFile); - } + ResourceLocator loc = CGI->filesystemh->getResourceLocator(identifier); + return new CAnimationHolder(loadAnimation(loc, group)); } IAnimation * CResourceHandler::loadAnimation(const ResourceLocator & loc, size_t group /*= -1*/) @@ -93,7 +87,21 @@ IAnimation * CResourceHandler::loadAnimation(const ResourceLocator & loc, size_t if(boost::iequals(locInfo.getExtension(), ".DEF")) { CDefFile * defFile = new CDefFile(data); - return createAnimation(defFile, group); + + // always use image based animations as cdef animation is deprecated + static const bool useImageBased = true; + + if (useImageBased) + { + //TODO add support for VCMI anim format + + // use ccomp animation for all def based animations + return new CCompAnimation(defFile, group); + } + else + { + return new CDefAnimation(defFile); + } } return NULL; diff --git a/client/CResourceHandler.h b/client/CResourceHandler.h index a7553f042..d260e0686 100644 --- a/client/CResourceHandler.h +++ b/client/CResourceHandler.h @@ -5,6 +5,8 @@ class IAnimation; class IImage; class CDefFile; +class CAnimationHolder; +class CSDLImage; /* * CResourceHandler.h, part of VCMI engine @@ -18,29 +20,24 @@ class CDefFile; class CResourceHandler { - IImage * loadImage(const ResourceLocator & loc, size_t frame = -1, size_t group = -1); + 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 * createImageFromFile(CMemoryStream * data, const std::string & imageType); - - IImage * createSpriteFromDEF(const CDefFile * defFile, size_t frame, size_t group); - - IAnimation * createAnimation(const CDefFile * defFile, size_t group = -1); public: // Loads an image. - IImage * getImage(const ResourceIdentifier & identifier, bool fromBegin = false); + IImage * getImage(const ResourceIdentifier & identifier); // Loads a frame/sprite. - IImage * getImage(const ResourceIdentifier & identifier, size_t frame, size_t group, bool fromBegin = false); + IImage * getImage(const ResourceIdentifier & identifier, size_t frame, size_t group); + + CSDLImage * getSurface(const ResourceIdentifier & identifier); + + CSDLImage * getSurface(const ResourceIdentifier & identifier, size_t frame, size_t group); // Loads complete animation(all groups). - IAnimation * getAnimation(const ResourceIdentifier & identifier, bool fromBegin = false); + CAnimationHolder * getAnimation(const ResourceIdentifier & identifier); // Loads a group of an animation. - IAnimation * getAnimation(const ResourceIdentifier & identifier, size_t group, bool fromBegin = false); - - - // Needs access to: createSpriteFromDEF - friend class CImageBasedAnimation; -}; \ No newline at end of file + CAnimationHolder * getAnimation(const ResourceIdentifier & identifier, size_t group); +}; diff --git a/client/UIFramework/AnimationClasses.cpp b/client/UIFramework/AnimationClasses.cpp index 0d84096a7..d586a4196 100644 --- a/client/UIFramework/AnimationClasses.cpp +++ b/client/UIFramework/AnimationClasses.cpp @@ -4,9 +4,13 @@ #include "ImageClasses.h" #include "SDL_Extensions.h" #include "../CGameInfo.h" -#include "../CResourceHandler.h" #include "../../lib/CFileSystemHandler.h" +IAnimation::IAnimation() : loadedGroup(0) +{ + +} + std::map IAnimation::getEntries() const { return entries; @@ -27,30 +31,6 @@ Point IAnimation::getPosition() const return pos; } -CImageBasedAnimation::CImageBasedAnimation(const CDefFile * defFile, size_t group /*= -1*/) -{ - images.clear(); - entries = defFile->getEntries(); - loadedGroup = group; - - if (group == -1) - { - for(std::map::iterator group = entries.begin(); group != entries.end(); ++group) - for(size_t frame = 0; frame < group->second; frame++) - images[group->first][frame] = CCS->resh->createSpriteFromDEF(defFile, frame, group->first); - } - else - { - if(vstd::contains(entries, group)) - { - for(size_t frame = 0; frame < entries[group]; frame++) - images[group][frame] = CCS->resh->createSpriteFromDEF(defFile, frame, group); - } - } - - delete defFile; -} - CImageBasedAnimation::CImageBasedAnimation(const CImageBasedAnimation & other) { *this = other; @@ -69,14 +49,10 @@ CImageBasedAnimation & CImageBasedAnimation::operator=(const CImageBasedAnimatio } } + IAnimation::operator=(other); return *this; } -IAnimation * CImageBasedAnimation::clone() const -{ - return new CImageBasedAnimation(*this); -} - CImageBasedAnimation::~CImageBasedAnimation() { forEach([](IImage * img) { @@ -84,6 +60,30 @@ CImageBasedAnimation::~CImageBasedAnimation() }); } +template +void CImageBasedAnimation::constructImageBasedAnimation(const CDefFile * defFile, size_t group /*= -1*/) +{ + entries = defFile->getEntries(); + loadedGroup = group; + + if (group == -1) + { + for(std::map::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); + } + else + { + if(vstd::contains(entries, group)) + { + for(size_t frame = 0; frame < entries[group]; frame++) + images[group][frame] = new anim(defFile, frame, group); + } + } + + delete defFile; +} + void CImageBasedAnimation::forEach(std::function func) { // recolor all groups @@ -121,8 +121,10 @@ void CImageBasedAnimation::draw(size_t frame, size_t group) const if(it2 != it->second.end()) { - it2->second->setPosition(pos); - it2->second->draw(); + IImage * img = it2->second; + img->setPosition(pos); + applyTransformations(img); + img->draw(); } } } @@ -134,23 +136,58 @@ void CImageBasedAnimation::recolorToPlayer(int player) }); } -void CImageBasedAnimation::setAlpha(ui8 alpha) +CCompAnimation::CCompAnimation(const CDefFile * defFile, size_t group /*= -1*/) { - assert(0); + constructImageBasedAnimation(defFile, group); } -void CImageBasedAnimation::setGlowAnimation(EGlowAnimationType::EGlowAnimationType glowType, ui8 alpha) +IAnimation * CCompAnimation::clone() const { - assert(0); + return new CCompAnimation(*this); } -void CImageBasedAnimation::flipHorizontal(bool flipped) +void CCompAnimation::applyTransformations(IImage * img) const { - assert(0); + img->rotateFlip(rotateFlipType); + img->setGlowAnimation(glowType, glowIntensity); + img->setAlpha(alpha); +} + +void CCompAnimation::setGlowAnimation(EGlowAnimationType::EGlowAnimationType glowType, ui8 intensity) +{ + this->glowIntensity = alpha; + this->glowType = glowType; +} + +void CCompAnimation::setAlpha(float alpha) +{ + this->alpha = alpha; +} + +void CCompAnimation::rotateFlip(ERotateFlipType::ERotateFlipType type) +{ + this->rotateFlipType = type; +} + +CSDLAnimation::CSDLAnimation(const CDefFile * defFile, size_t group /*= -1*/) +{ + constructImageBasedAnimation(defFile, group); +} + +IAnimation * CSDLAnimation::clone() const +{ + return new CSDLAnimation(*this); +} + +void CSDLAnimation::rotateFlip(ERotateFlipType::ERotateFlipType type) +{ + forEach([type](IImage * img) { + img->rotateFlip(type); + }); } CDefAnimation::CDefAnimation(const CDefFile * defFile) -: def(defFile), flippedX(false), glowType(EGlowAnimationType::NONE), glowIntensity(0) +: def(defFile), playerColor(-1), glowType(EGlowAnimationType::NONE), glowIntensity(0), rotateFlipType(ERotateFlipType::NONE) { entries = defFile->getEntries(); loadedGroup = -1; @@ -173,8 +210,6 @@ void CDefAnimation::draw(size_t frame, size_t group) const case 2: drawT<2>(frame, group, screen, pos.x, pos.y); break; case 3: drawT<3>(frame, group, screen, pos.x, pos.y); break; case 4: drawT<4>(frame, group, screen, pos.x, pos.y); break; - default: - tlog1 << (int)screen->format->BitsPerPixel << " bpp is not supported!!!\n"; } } @@ -224,7 +259,8 @@ void CDefAnimation::drawT(size_t frame, size_t group, SDL_Surface * surf, int po segmentLength = framePtr[baseOffset++]; const int remainder = ftcp % sprite.fullWidth; - int xB = (flippedX ? sprite.fullWidth - remainder - 1 : remainder) + posX; + int xB = (rotateFlipType == ERotateFlipType::ROTATENONE_FLIPX + ? sprite.fullWidth - remainder - 1 : remainder) + posX; for(size_t k = 0; k <= segmentLength; k++) { @@ -239,7 +275,7 @@ void CDefAnimation::drawT(size_t frame, size_t group, SDL_Surface * surf, int po } ftcp++; - if(flippedX) + if(rotateFlipType == ERotateFlipType::ROTATENONE_FLIPX) xB--; else xB++; @@ -313,9 +349,9 @@ inline void CDefAnimation::putPixel(SDL_Surface * surf, int posX, int posY, SDL_ } -void CDefAnimation::flipHorizontal(bool flipped) +void CDefAnimation::rotateFlip(ERotateFlipType::ERotateFlipType type) { - this->flippedX = flipped; + rotateFlipType = type; } void CDefAnimation::setGlowAnimation(EGlowAnimationType::EGlowAnimationType glowType, ui8 intensity) @@ -324,35 +360,12 @@ void CDefAnimation::setGlowAnimation(EGlowAnimationType::EGlowAnimationType glow this->glowIntensity = intensity; } -void CDefAnimation::setAlpha(ui8 alpha) -{ - assert(0); -} - -void CDefAnimation::recolorToPlayer(int player) -{ - assert(0); -} - CAnimationHolder::CAnimationHolder(IAnimation * animation) : anim(animation), currentGroup(0), currentFrame(0), glowType(EGlowAnimationType::NONE), glowIntensity(MIN_GLOW_INTENSITY) { - setGroup(0); -} - -CAnimationHolder::CAnimationHolder(const ResourceIdentifier & identifier) - : currentGroup(0), currentFrame(0), glowType(EGlowAnimationType::NONE), glowIntensity(MIN_GLOW_INTENSITY) -{ - anim = CCS->resh->getAnimation(identifier); - setGroup(0); -} - -CAnimationHolder::CAnimationHolder(const ResourceIdentifier & identifier, size_t group, bool repeat /*= false*/) - : currentGroup(group), currentFrame(0), glowType(EGlowAnimationType::NONE), glowIntensity(MIN_GLOW_INTENSITY) -{ - anim = CCS->resh->getAnimation(identifier, group); - setGroup(group, repeat); + size_t loadedGroup = animation->getLoadedGroup(); + setGroup(loadedGroup == -1 ? 0 : loadedGroup); } CAnimationHolder::~CAnimationHolder() @@ -459,3 +472,13 @@ void CAnimationHolder::setGlowAnimation(EGlowAnimationType::EGlowAnimationType g glowTime = 0.0; this->glowType = glowType; } + +void CAnimationHolder::setAlpha(float alpha) +{ + anim->setAlpha(alpha); +} + +void CAnimationHolder::rotateFlip(ERotateFlipType::ERotateFlipType type) +{ + anim->rotateFlip(type); +} diff --git a/client/UIFramework/AnimationClasses.h b/client/UIFramework/AnimationClasses.h index 52de89e3b..0034106b8 100644 --- a/client/UIFramework/AnimationClasses.h +++ b/client/UIFramework/AnimationClasses.h @@ -15,6 +15,8 @@ class IAnimation; class CImageBasedAnimation; +class CCompAnimation; +class CSDLAnimation; class CAnimationHolder; class IAnimation : public ITransformational @@ -27,6 +29,7 @@ protected: size_t loadedGroup; public: + IAnimation(); virtual ~IAnimation() { }; virtual IAnimation * clone() const =0; @@ -44,6 +47,7 @@ public: class CImageBasedAnimation : public IAnimation { +protected: // images[group][frame], store objects with loaded images std::map > images; @@ -52,31 +56,56 @@ class CImageBasedAnimation : public IAnimation typedef std::map >::const_iterator group_itc; typedef std::map::const_iterator frame_itc; -public: - // Loads frames of the specified group of an animation. Assign -1 to the second parameter 'group' to load all groups. - CImageBasedAnimation(const CDefFile * defFile, size_t group = -1); - + CImageBasedAnimation() { }; CImageBasedAnimation(const CImageBasedAnimation & other); - CImageBasedAnimation & operator=(const CImageBasedAnimation & other); + CImageBasedAnimation & operator=(const CImageBasedAnimation & other); ~CImageBasedAnimation(); - IAnimation * clone() const; + template + void constructImageBasedAnimation(const CDefFile * defFile, size_t group /*= -1*/); + +public: void forEach(std::function func); + virtual void applyTransformations(IImage * img) const { }; void draw(size_t frame, size_t group) const; void recolorToPlayer(int player); +}; + +class CCompAnimation : public CImageBasedAnimation +{ + EGlowAnimationType::EGlowAnimationType glowType; + ui8 glowIntensity; + float alpha; + ERotateFlipType::ERotateFlipType rotateFlipType; + +public: + CCompAnimation(const CDefFile * defFile, size_t group = -1); + IAnimation * clone() const; + + void applyTransformations(IImage * img) const; void setGlowAnimation(EGlowAnimationType::EGlowAnimationType glowType, ui8 intensity); - void setAlpha(ui8 alpha); - void flipHorizontal(bool flipped); + void setAlpha(float alpha); + void rotateFlip(ERotateFlipType::ERotateFlipType type); +}; + +class CSDLAnimation : public CImageBasedAnimation +{ +public: + CSDLAnimation(const CDefFile * defFile, size_t group = -1); + IAnimation * clone() const; + + void rotateFlip(ERotateFlipType::ERotateFlipType type); }; class CDefAnimation : public IAnimation { const CDefFile * def; - bool flippedX; + int playerColor; EGlowAnimationType::EGlowAnimationType glowType; ui8 glowIntensity; + ERotateFlipType::ERotateFlipType rotateFlipType; template inline void putPixel(SDL_Surface * surf, int posX, int posY, SDL_Color color, ui8 colorNr) const; @@ -85,19 +114,15 @@ class CDefAnimation : public IAnimation void drawT(size_t frame, size_t group, SDL_Surface * surf, int posX, int posY) const; public: - CDefAnimation(const CDefFile * defFile); + explicit CDefAnimation(const CDefFile * defFile); ~CDefAnimation(); IAnimation * clone() const; void draw(size_t frame, size_t group) const; - void flipHorizontal(bool flipped); + void rotateFlip(ERotateFlipType::ERotateFlipType type); void setGlowAnimation(EGlowAnimationType::EGlowAnimationType glowType, ui8 intensity); - - // Not available here, do not call - void setAlpha(ui8 alpha); - void recolorToPlayer(int player); }; class CAnimationHolder @@ -115,9 +140,7 @@ class CAnimationHolder void updateGlowAnimation(double elapsedTime); public: - CAnimationHolder(IAnimation * animation); - CAnimationHolder(const ResourceIdentifier & identifier); - CAnimationHolder(const ResourceIdentifier & identifier, size_t group, bool repeat = false); + explicit CAnimationHolder(IAnimation * animation); ~CAnimationHolder(); void setGroup(size_t group, bool repeat = false); @@ -130,4 +153,6 @@ public: void recolorToPlayer(int player); void setGlowAnimation(EGlowAnimationType::EGlowAnimationType glowType); + void setAlpha(float alpha); + void rotateFlip(ERotateFlipType::ERotateFlipType type); }; diff --git a/client/UIFramework/ImageClasses.cpp b/client/UIFramework/ImageClasses.cpp index e54353aff..abde9ee03 100644 --- a/client/UIFramework/ImageClasses.cpp +++ b/client/UIFramework/ImageClasses.cpp @@ -402,21 +402,18 @@ void CSDLImage::recolorToPlayer(int player) SDL_SetColors(surf, palette, 224, 32); } + else + { + tlog1 << "The method recolorToPlayer for standard SDL images cannot be applied to non 8-bit images." << std::endl; + } } -void CSDLImage::setGlowAnimation(EGlowAnimationType::EGlowAnimationType glowType, ui8 intensity) +void CSDLImage::rotateFlip(ERotateFlipType::ERotateFlipType rotateType) { - assert(0); -} - -void CSDLImage::setAlpha(ui8 alpha) -{ - assert(0); -} - -void CSDLImage::flipHorizontal(bool flipped) -{ - assert(0); + if(rotateType == ERotateFlipType::ROTATENONE_FLIPX) + surf = CSDL_Ext::hFlip(surf, true); + else if (rotateType == ERotateFlipType::ROTATENONE_FLIPY) + surf = CSDL_Ext::rotate01(surf, true); } CCompImage::CCompImageLoader::CCompImageLoader(CCompImage * Img) : image(Img), position(NULL), entry(NULL), @@ -601,7 +598,7 @@ CCompImage::CCompImageLoader::~CCompImageLoader() } CCompImage::CCompImage(const CDefFile * defFile, size_t frame, size_t group) -: surf(NULL), length(0), line(NULL), palette(NULL), alpha(0) +: surf(NULL), length(0), line(NULL), palette(NULL), glowPalette(NULL), alpha(0), rotateFlipType(ERotateFlipType::NONE) { CCompImageLoader loader(this); defFile->loadFrame(frame, group, loader); @@ -622,6 +619,10 @@ CCompImage & CCompImage::operator=(const CCompImage & cpy) memcpy(reinterpret_cast(palette), reinterpret_cast(cpy.palette), 256 * sizeof(SDL_Color)); + glowPalette = new SDL_Color[3]; + memcpy(reinterpret_cast(glowPalette), + reinterpret_cast(cpy.glowPalette + 5 * sizeof(SDL_Color)), 3 * sizeof(SDL_Color)); + surf = reinterpret_cast(malloc(length)); memcpy(reinterpret_cast(surf), reinterpret_cast(cpy.surf), length); @@ -641,18 +642,16 @@ IImage * CCompImage::clone() const CCompImage::~CCompImage() { free(surf); + delete [] glowPalette; delete [] line; delete [] palette; } void CCompImage::draw() const { - ui8 rotation = 0; //TODO - //rotation == 1 = horizontal rotation - //rotation == 2 = vertical rotation - if(!surf) return; + Rect sourceRect(sprite); //TODO: rotation and scaling @@ -664,9 +663,9 @@ void CCompImage::draw() const //Starting point on SDL surface Point dest(pos.x + sourceRect.x, pos.y + sourceRect.y); - if(rotation == 1) + if(rotateFlipType == ERotateFlipType::ROTATENONE_FLIPX) dest.y += sourceRect.h; - if(rotation == 2) + else if(rotateFlipType == ERotateFlipType::ROTATENONE_FLIPY) dest.x += sourceRect.w; sourceRect -= sprite.topLeft(); @@ -698,7 +697,7 @@ void CCompImage::draw() const //Calculate position for blitting: pixels + Y + X ui8 * blitPos = reinterpret_cast(screen->pixels); - if(rotation == 2) + if(rotateFlipType == ERotateFlipType::ROTATENONE_FLIPY) blitPos += (static_cast(dest.y) - currY) * screen->pitch; else blitPos += (static_cast(dest.y) + currY) * screen->pitch; @@ -708,7 +707,7 @@ void CCompImage::draw() const while(currX + size < sourceRect.w) { //blit block, pointers will be modified if needed - blitBlockWithBpp(bpp, type, size, data, blitPos, alpha, rotation == 1); + blitBlockWithBpp(bpp, type, size, data, blitPos, alpha, rotateFlipType == ERotateFlipType::ROTATENONE_FLIPX); currX += size; type = *(data++); @@ -716,7 +715,7 @@ void CCompImage::draw() const } //Blit last, semi-visible block size = sourceRect.w - currX; - blitBlockWithBpp(bpp, type, size, data, blitPos, alpha, rotation == 1); + blitBlockWithBpp(bpp, type, size, data, blitPos, alpha, rotateFlipType == ERotateFlipType::ROTATENONE_FLIPX); } } @@ -840,7 +839,41 @@ void CCompImage::recolorToPlayer(int player) void CCompImage::setGlowAnimation(EGlowAnimationType::EGlowAnimationType glowType, ui8 intensity) { - assert(0); + // Init the glow palette for the first time + if (glowPalette == NULL) + { + glowPalette = new SDL_Color[3]; + memcpy(reinterpret_cast(glowPalette), + reinterpret_cast(palette + 5 * sizeof(SDL_Color)), 3 * sizeof(SDL_Color)); + } + + if (glowType == EGlowAnimationType::BLUE) + { + for (size_t i = 5; i < 8; ++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; + } + } + else if (glowType == EGlowAnimationType::YELLOW) + { + for (size_t i = 5; i < 8; ++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; + } + } + 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; + } + } } void CCompImage::setAlpha(ui8 alpha) @@ -848,7 +881,7 @@ void CCompImage::setAlpha(ui8 alpha) this->alpha = alpha; } -void CCompImage::flipHorizontal(bool flipped) +void CCompImage::rotateFlip(ERotateFlipType::ERotateFlipType rotateType) { - assert(0); -} \ No newline at end of file + this->rotateFlipType = rotateType; +} diff --git a/client/UIFramework/ImageClasses.h b/client/UIFramework/ImageClasses.h index ae0a3ca4e..abe2dd2a8 100644 --- a/client/UIFramework/ImageClasses.h +++ b/client/UIFramework/ImageClasses.h @@ -135,9 +135,7 @@ public: SDL_Surface * getRawSurface() const; void recolorToPlayer(int player); - void setGlowAnimation(EGlowAnimationType::EGlowAnimationType glowType, ui8 intensity); - void setAlpha(ui8 alpha); - void flipHorizontal(bool flipped); + void rotateFlip(ERotateFlipType::ERotateFlipType rotateType); }; /* @@ -198,8 +196,13 @@ class CCompImage : public IImage //palette SDL_Color * palette; + //glow palette, original values (3 values, nr.5-7) + SDL_Color * glowPalette; + ui8 alpha; + ERotateFlipType::ERotateFlipType rotateFlipType; + //Used internally to blit one block of data template void blitBlock(ui8 type, ui8 size, ui8 * & data, ui8 * & dest, ui8 alpha) const; @@ -208,7 +211,6 @@ class CCompImage : public IImage public: // Loads an sprite image from DEF file. CCompImage(const CDefFile * defFile, size_t frame, size_t group); - CCompImage(const CCompImage & cpy); CCompImage & operator=(const CCompImage & cpy); ~CCompImage(); @@ -220,5 +222,5 @@ public: void recolorToPlayer(int player); void setGlowAnimation(EGlowAnimationType::EGlowAnimationType glowType, ui8 intensity); void setAlpha(ui8 alpha); - void flipHorizontal(bool flipped); -}; \ No newline at end of file + void rotateFlip(ERotateFlipType::ERotateFlipType rotateType); +}; diff --git a/client/UIFramework/ImageClassesFwd.h b/client/UIFramework/ImageClassesFwd.h index ae807b3fa..a695dfc44 100644 --- a/client/UIFramework/ImageClassesFwd.h +++ b/client/UIFramework/ImageClassesFwd.h @@ -1,7 +1,9 @@ #pragma once +#include #include "../../lib/CFileSystemHandlerFwd.h" + /* * ImageClassesFwd.h, part of VCMI engine * @@ -32,12 +34,14 @@ namespace EGlowAnimationType }; } -namespace EImageRotation +/** Enumeration for the rotation/flip type. May be extended to support more rotations. */ +namespace ERotateFlipType { - enum EImageRotation + enum ERotateFlipType { - Flip180X, - Flip180Y + NONE, + ROTATENONE_FLIPX, + ROTATENONE_FLIPY }; } @@ -45,14 +49,11 @@ struct GraphicsSelector { si8 frame, group; - // TODO: add imageTask queries, transformations,... - si8 playerColor; - - GraphicsSelector(si8 Group = -1, si8 Frame = 0) : frame(Frame), group(Group), playerColor(-1) { }; + 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 && playerColor == other.playerColor; + return frame == other.frame && group == other.group; } inline friend std::size_t hash_value(GraphicsSelector const & p) @@ -60,7 +61,6 @@ struct GraphicsSelector std::size_t seed = 0; boost::hash_combine(seed, p.frame); boost::hash_combine(seed, p.group); - boost::hash_combine(seed, p.playerColor); return seed; } @@ -97,13 +97,18 @@ struct GraphicsLocator : public ResourceLocator class ITransformational { public: + inline void printNotImplMsg(const std::string & methodName) + { + tlog1 << "Method " << methodName << " in class " << typeid(*this).name() << " not implemented." << std::endl; + } + // Change palette to specific player. - virtual void recolorToPlayer(int player) =0; + virtual void recolorToPlayer(int player) { printNotImplMsg("recolorToPlayer"); } // Sets/Unsets the yellow or blue glow animation effect. - virtual void setGlowAnimation(EGlowAnimationType::EGlowAnimationType glowType, ui8 intensity) =0; + virtual void setGlowAnimation(EGlowAnimationType::EGlowAnimationType glowType, ui8 intensity) { printNotImplMsg("setGlowAnimation"); } - virtual void setAlpha(ui8 alpha) =0; + virtual void setAlpha(ui8 alpha) { printNotImplMsg("setAlpha"); } - virtual void flipHorizontal(bool flipped) =0; + virtual void rotateFlip(ERotateFlipType::ERotateFlipType type) { printNotImplMsg("rotateFlip"); } }; diff --git a/client/UIFramework/SDL_Extensions.cpp b/client/UIFramework/SDL_Extensions.cpp index 34c98bddd..d090925ad 100644 --- a/client/UIFramework/SDL_Extensions.cpp +++ b/client/UIFramework/SDL_Extensions.cpp @@ -538,7 +538,7 @@ void printToWR(const std::string & text, int x, int y, TTF_Font * font, SDL_Colo } // Vertical flip -SDL_Surface * CSDL_Ext::rotate01(SDL_Surface * toRot) +SDL_Surface * CSDL_Ext::rotate01(SDL_Surface * toRot, bool freeSurf /*= false*/) { SDL_Surface * ret = SDL_ConvertSurface(toRot, toRot->format, toRot->flags); const int bpl = ret->pitch; @@ -554,11 +554,13 @@ SDL_Surface * CSDL_Ext::rotate01(SDL_Surface * toRot) } } + if (freeSurf) + SDL_FreeSurface(toRot); return ret; } // Horizontal flip -SDL_Surface * CSDL_Ext::hFlip(SDL_Surface * toRot) +SDL_Surface * CSDL_Ext::hFlip(SDL_Surface * toRot, bool freeSurf /*= false*/) { SDL_Surface * ret = SDL_ConvertSurface(toRot, toRot->format, toRot->flags); int bpl = ret->pitch; @@ -567,6 +569,8 @@ SDL_Surface * CSDL_Ext::hFlip(SDL_Surface * toRot) memcpy((char *)ret->pixels + i*bpl, (char *)toRot->pixels + (ret->h-i-1)*bpl, bpl); } + if (freeSurf) + SDL_FreeSurface(toRot); return ret; }; diff --git a/client/UIFramework/SDL_Extensions.h b/client/UIFramework/SDL_Extensions.h index f87cd33d9..dc1e46ea8 100644 --- a/client/UIFramework/SDL_Extensions.h +++ b/client/UIFramework/SDL_Extensions.h @@ -149,8 +149,8 @@ namespace CSDL_Ext void SDL_PutPixelWithoutRefresh(SDL_Surface *ekran, const int & x, const int & y, const Uint8 & R, const Uint8 & G, const Uint8 & B, Uint8 A = 255); void SDL_PutPixelWithoutRefreshIfInSurf(SDL_Surface *ekran, const int & x, const int & y, const Uint8 & R, const Uint8 & G, const Uint8 & B, Uint8 A = 255); - SDL_Surface * rotate01(SDL_Surface * toRot); //vertical flip - SDL_Surface * hFlip(SDL_Surface * toRot); //horizontal flip + SDL_Surface * rotate01(SDL_Surface * toRot, bool freeSurf = false); //vertical flip + SDL_Surface * hFlip(SDL_Surface * toRot, bool freeSurf = false); //horizontal flip SDL_Surface * rotate02(SDL_Surface * toRot); //rotate 90 degrees left SDL_Surface * rotate03(SDL_Surface * toRot); //rotate 180 degrees SDL_Cursor * SurfaceToCursor(SDL_Surface *image, int hx, int hy); //creates cursor from bitmap diff --git a/configure b/configure index 4199344bb..d439d7071 100755 --- a/configure +++ b/configure @@ -17479,7 +17479,7 @@ fi done -CXXFLAGS="$CXXFLAGS -DM_DATA_DIR=\\\"\$(pkgdatadir)\\\" -DM_BIN_DIR=\\\"\$(bindir)\\\" -DM_LIB_DIR=\\\"\$(pkglibdir)\\\"" +CXXFLAGS="$CXXFLAGS -DM_DATA_DIR=\$(pkgdatadir) -DM_BIN_DIR=\$(bindir) -DM_LIB_DIR=\$(pkglibdir)" diff --git a/configure.ac b/configure.ac index 201deeaed..e083650eb 100644 --- a/configure.ac +++ b/configure.ac @@ -97,7 +97,7 @@ AC_CHECK_HEADERS([boost/filesystem.hpp boost/algorithm/string.hpp boost/algorith # Checks for library functions. AC_CHECK_FUNCS([atexit memset pow select sqrt]) -CXXFLAGS="$CXXFLAGS -DM_DATA_DIR=\\\"\$(pkgdatadir)\\\" -DM_BIN_DIR=\\\"\$(bindir)\\\" -DM_LIB_DIR=\\\"\$(pkglibdir)\\\"" +CXXFLAGS="$CXXFLAGS -DM_DATA_DIR=\$(pkgdatadir) -DM_BIN_DIR=\$(bindir) -DM_LIB_DIR=\$(pkglibdir)" AC_SUBST(SDL_LIBS) AC_SUBST(SDL_CXXFLAGS) diff --git a/lib/CConsoleHandler.h b/lib/CConsoleHandler.h index ac6231e26..60d22a601 100644 --- a/lib/CConsoleHandler.h +++ b/lib/CConsoleHandler.h @@ -34,12 +34,7 @@ public: template void print(const T &data, int lvl) { setColor(lvl); - - if(!coloredConsoleOutput && lvl >= 1 && lvl <= 3) - std::cerr << data << std::flush; - else - std::cout << data << std::flush; - + std::cout << data << std::flush; setColor(-1); } };