1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Implemented terrain palette animatiions. Removed old code

This commit is contained in:
Ivan Savenko 2023-02-19 22:05:19 +02:00
parent 57d906a01c
commit ca13e7dedf
14 changed files with 85 additions and 507 deletions

View File

@ -172,73 +172,6 @@ void HeroPathStorage::verifyPath(const CGHeroInstance *h)
setPath(h, getPath(h).endPos());
}
//CGPath * CPlayerInterface::getAndVerifyPath(const CGHeroInstance * h)
//{
// if (vstd::contains(paths,h)) //hero has assigned path
// {
// CGPath &path = paths[h];
// if (!path.nodes.size())
// {
// logGlobal->warn("Warning: empty path found...");
// paths.erasePath(h);
// }
// else
// {
// assert(h->visitablePos() == path.startPos());
// //update the hero path in case of something has changed on map
// if (LOCPLINT->cb->getPathsInfo(h)->getPath(path, path.endPos()))
// return &path;
//
// paths.erase(h);
// return nullptr;
// }
// }
//
// return nullptr;
//}
//
//CGPath * CPlayerInterface::getPath(const CGHeroInstance * h)
//{
// if (vstd::contains(paths,h)) //hero has assigned path
// return &paths[h];
//
// return nullptr;
//}
//removeLastNode
//void HeroPathStorage::setPath(const CGHeroInstance *h, const CGPath & path)
//{
//
//}
//
//const CGPath & HeroPathStorage::getPath(const CGHeroInstance *h)
//{
//
//}
//
//void HeroPathStorage::verifyPath(const CGHeroInstance *h)
//{
//
//}
//void CPlayerInterface::eraseCurrentPathOf(const CGHeroInstance * ho, bool checkForExistanceOfPath)
//{
// if (checkForExistanceOfPath)
// {
// assert(vstd::contains(paths, ho));
// }
// else if (!vstd::contains(paths, ho))
// {
// return;
// }
// assert(ho == adventureInt->selection);
//
// paths.erasePath(ho);
// adventureInt->updateMoveHero(ho, false);
//}
template<typename Handler>
void HeroPathStorage::serialize(Handler & h, int version)
{
@ -398,10 +331,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
adventureInt->minimap->updateTile(hero->convertToVisitablePos(details.start));
adventureInt->minimap->updateTile(hero->convertToVisitablePos(details.end));
bool directlyAttackingCreature =
details.attackedFrom
&& paths.hasPath(hero) //in case if movement has been canceled in the meantime and path was already erased
&& paths.getPath(hero).nodes.size() == 3;//FIXME should be 2 but works nevertheless...
bool directlyAttackingCreature = details.attackedFrom && paths.hasPath(hero) && paths.getPath(hero).endPos() == *details.attackedFrom;
if(makingTurn && hero->tempOwner == playerID) //we are moving our hero - we may need to update assigned path
{
@ -429,11 +359,6 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
}
}
adventureInt->centerOn(hero, true); //actualizing screen pos
adventureInt->minimap->redraw();
adventureInt->heroList->update(hero);
return; //teleport - no fancy moving animation
//TODO: smooth disappear / appear effect
}
if(hero->pos != details.end //hero didn't change tile but visit succeeded
@ -450,7 +375,6 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
if(details.stopMovement()) //hero failed to move
{
hero->isStanding = true;
stillMoveHero.setn(STOP_MOVE);
GH.totalRedraw();
adventureInt->heroList->update(hero);
@ -462,9 +386,6 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
CGI->mh->waitForOngoingAnimations();
//finishing move
hero->isStanding = true;
//move finished
adventureInt->minimap->redraw();
adventureInt->heroList->update(hero);
@ -1687,8 +1608,6 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns
{
auto subArr = (CGI->mh->ttiles)[hp.z];
ho->isStanding = false;
int heroWidth = ho->appearance->getWidth();
int heroHeight = ho->appearance->getHeight();

View File

@ -157,6 +157,17 @@ void MapRendererTerrain::renderTile(const IMapRendererContext & context, Canvas
const auto & image = storage.find(terrainIndex, rotationIndex, imageIndex);
if(mapTile.terType->getId() == ETerrainId::LAVA)
{
image->shiftPalette(246, 9, context.terrainImageIndex(9));
}
if(mapTile.terType->getId() == ETerrainId::WATER)
{
image->shiftPalette(229, 12, context.terrainImageIndex(12));
image->shiftPalette(242, 14, context.terrainImageIndex(14));
}
target.draw(image, Point(0, 0));
}
@ -171,15 +182,34 @@ void MapRendererRiver::renderTile(const IMapRendererContext & context, Canvas &
{
const TerrainTile & mapTile = context.getMapTile(coordinates);
if(mapTile.riverType->getId() != River::NO_RIVER)
{
int32_t terrainIndex = mapTile.riverType->getIndex();
int32_t imageIndex = mapTile.riverDir;
int32_t rotationIndex = (mapTile.extTileFlags >> 2) % 4;
if(mapTile.riverType->getId() == River::NO_RIVER)
return;
const auto & image = storage.find(terrainIndex, rotationIndex, imageIndex);
target.draw(image, Point(0, 0));
int32_t terrainIndex = mapTile.riverType->getIndex();
int32_t imageIndex = mapTile.riverDir;
int32_t rotationIndex = (mapTile.extTileFlags >> 2) % 4;
const auto & image = storage.find(terrainIndex, rotationIndex, imageIndex);
if(mapTile.riverType->getId() == River::WATER_RIVER)
{
image->shiftPalette(183, 12, context.terrainImageIndex(12));
image->shiftPalette(195, 6, context.terrainImageIndex(6));
}
if(mapTile.riverType->getId() == River::MUD_RIVER)
{
image->shiftPalette(228, 12, context.terrainImageIndex(12));
image->shiftPalette(183, 6, context.terrainImageIndex(6));
image->shiftPalette(240, 6, context.terrainImageIndex(6));
}
if(mapTile.riverType->getId() == River::LAVA_RIVER)
{
image->shiftPalette(240, 9, context.terrainImageIndex(9));
}
target.draw(image, Point(0, 0));
}
MapRendererRoad::MapRendererRoad()

View File

@ -61,6 +61,9 @@ public:
/// returns animation frame for selected object
virtual size_t objectImageIndex(ObjectInstanceID objectID, size_t groupSize) const = 0;
/// returns animation frame for terrain
virtual size_t terrainImageIndex(size_t groupSize) const = 0;
/// returns size of ouput tile, in pixels. 32x32 for "standard" map, may be smaller for world view mode
virtual Point getTileSize() const = 0;

View File

@ -155,7 +155,7 @@ const CGPath * MapRendererContext::currentPath() const
size_t MapRendererContext::objectImageIndex(ObjectInstanceID objectID, size_t groupSize) const
{
assert(groupSize > 0);
if (groupSize == 0)
if(groupSize == 0)
return 0;
// H3 timing for adventure map objects animation is 180 ms
@ -164,14 +164,22 @@ size_t MapRendererContext::objectImageIndex(ObjectInstanceID objectID, size_t gr
// hero movement animation always plays at ~50ms / frame
// in-game setting only affect movement across screen
if (movementAnimation && movementAnimation->target == objectID)
baseFrameTime = 50;
if(movementAnimation && movementAnimation->target == objectID)
baseFrameTime = 50;
size_t frameCounter = animationTime / baseFrameTime;
size_t frameIndex = frameCounter % groupSize;
return frameIndex;
}
size_t MapRendererContext::terrainImageIndex(size_t groupSize) const
{
size_t baseFrameTime = 180;
size_t frameCounter = animationTime / baseFrameTime;
size_t frameIndex = frameCounter % groupSize;
return frameIndex;
}
Point MapRendererContext::getTileSize() const
{
return Point(32, 32);
@ -179,7 +187,7 @@ Point MapRendererContext::getTileSize() const
bool MapRendererContext::showGrid() const
{
return true; // settings["session"]["showGrid"].Bool();
return true; // settings["gameTweaks"]["showGrid"].Bool();
}
void MapViewController::setViewCenter(const int3 & position)

View File

@ -13,6 +13,7 @@
#include "../gui/CIntObject.h"
#include "../lib/int3.h"
class IImage;
class Canvas;
class MapRenderer;
class MapViewController;
@ -66,6 +67,7 @@ public:
Point objectImageOffset(ObjectInstanceID objectID, const int3 & coordinates) const override;
double objectTransparency(ObjectInstanceID objectID) const override;
size_t objectImageIndex(ObjectInstanceID objectID, size_t groupSize) const override;
size_t terrainImageIndex(size_t groupSize) const override;
Point getTileSize() const override;
bool showGrid() const override;
};
@ -120,6 +122,7 @@ public:
class MapViewCache
{
std::shared_ptr<MapViewModel> model;
std::shared_ptr<IImage> mapTransition; //TODO
std::unique_ptr<Canvas> terrain;
std::unique_ptr<MapRenderer> mapRenderer;

View File

@ -184,298 +184,6 @@ CMapPuzzleViewBlitter::CMapPuzzleViewBlitter(CMapHandler * parent)
}
*/
/*
void CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingInfo * info)
{
init(info);
auto prevClip = clip(targetSurf);
pos = int3(0, 0, topTile.z);
for (realPos.x = initPos.x, pos.x = topTile.x; pos.x < topTile.x + tileCount.x; pos.x++, realPos.x += tileSize)
{
if (pos.x < 0 || pos.x >= parent->sizes.x)
continue;
for (realPos.y = initPos.y, pos.y = topTile.y; pos.y < topTile.y + tileCount.y; pos.y++, realPos.y += tileSize)
{
if (pos.y < 0 || pos.y >= parent->sizes.y)
continue;
const bool isVisible = canDrawCurrentTile();
realTileRect.x = realPos.x;
realTileRect.y = realPos.y;
const TerrainTile2 & tile = parent->ttiles[pos.z][pos.x][pos.y];
const TerrainTile & tinfo = parent->map->getTile(pos);
const TerrainTile * tinfoUpper = pos.y > 0 ? &parent->map->getTile(int3(pos.x, pos.y - 1, pos.z)) : nullptr;
if(isVisible || info->showAllTerrain)
{
drawTileTerrain(targetSurf, tinfo, tile);
if(tinfo.riverType->getId() != River::NO_RIVER)
drawRiver(targetSurf, tinfo);
drawRoad(targetSurf, tinfo, tinfoUpper);
}
if(isVisible)
drawObjects(targetSurf, tile);
}
}
for (realPos.x = initPos.x, pos.x = topTile.x; pos.x < topTile.x + tileCount.x; pos.x++, realPos.x += tileSize)
{
for (realPos.y = initPos.y, pos.y = topTile.y; pos.y < topTile.y + tileCount.y; pos.y++, realPos.y += tileSize)
{
realTileRect.x = realPos.x;
realTileRect.y = realPos.y;
if (pos.x < 0 || pos.x >= parent->sizes.x ||
pos.y < 0 || pos.y >= parent->sizes.y)
{
drawFrame(targetSurf);
}
else
{
const TerrainTile2 & tile = parent->ttiles[pos.z][pos.x][pos.y];
if(!settings["session"]["spectate"].Bool() && !(*info->visibilityMap)[topTile.z][pos.x][pos.y] && !info->showAllTerrain)
drawFow(targetSurf);
// overlay needs to be drawn over fow, because of artifacts-aura-like spells
drawTileOverlay(targetSurf, tile);
// drawDebugVisitables()
if (settings["session"]["showBlock"].Bool())
{
if(parent->map->getTile(int3(pos.x, pos.y, pos.z)).blocked) //temporary hiding blocked positions
{
static std::shared_ptr<IImage> block;
if (!block)
block = IImage::createFromFile("blocked");
block->draw(targetSurf, realTileRect.x, realTileRect.y);
}
}
if (settings["session"]["showVisit"].Bool())
{
if(parent->map->getTile(int3(pos.x, pos.y, pos.z)).visitable) //temporary hiding visitable positions
{
static std::shared_ptr<IImage> visit;
if (!visit)
visit = IImage::createFromFile("visitable");
visit->draw(targetSurf, realTileRect.x, realTileRect.y);
}
}
}
}
}
drawOverlayEx(targetSurf);
// drawDebugGrid()
if (settings["gameTweaks"]["showGrid"].Bool())
{
for (realPos.x = initPos.x, pos.x = topTile.x; pos.x < topTile.x + tileCount.x; pos.x++, realPos.x += tileSize)
{
for (realPos.y = initPos.y, pos.y = topTile.y; pos.y < topTile.y + tileCount.y; pos.y++, realPos.y += tileSize)
{
constexpr ColorRGBA color(0x55, 0x55, 0x55);
if (realPos.y >= info->drawBounds.y &&
realPos.y < info->drawBounds.y + info->drawBounds.h)
for(int i = 0; i < tileSize; i++)
if (realPos.x + i >= info->drawBounds.x &&
realPos.x + i < info->drawBounds.x + info->drawBounds.w)
CSDL_Ext::putPixelWithoutRefresh(targetSurf, realPos.x + i, realPos.y, color.r, color.g, color.b);
if (realPos.x >= info->drawBounds.x &&
realPos.x < info->drawBounds.x + info->drawBounds.w)
for(int i = 0; i < tileSize; i++)
if (realPos.y + i >= info->drawBounds.y &&
realPos.y + i < info->drawBounds.y + info->drawBounds.h)
CSDL_Ext::putPixelWithoutRefresh(targetSurf, realPos.x, realPos.y + i, color.r, color.g, color.b);
}
}
}
postProcessing(targetSurf);
CSDL_Ext::setClipRect(targetSurf, prevClip);
}
*/
/*
bool CMapHandler::updateObjectsFade()
{
for (auto iter = fadeAnims.begin(); iter != fadeAnims.end(); )
{
int3 pos = (*iter).second.first;
CFadeAnimation * anim = (*iter).second.second;
anim->update();
if (anim->isFading())
++iter;
else // fade finished
{
auto &objs = ttiles[pos.z][pos.x][pos.y].objects;
for (auto objIter = objs.begin(); objIter != objs.end(); ++objIter)
{
if ((*objIter).fadeAnimKey == (*iter).first)
{
logAnim->trace("Fade anim finished for obj at %s; remaining: %d", pos.toString(), fadeAnims.size() - 1);
if (anim->fadingMode == CFadeAnimation::EMode::OUT)
objs.erase(objIter); // if this was fadeout, remove the object from the map
else
(*objIter).fadeAnimKey = -1; // for fadein, just remove its connection to the finished fade
break;
}
}
delete (*iter).second.second;
iter = fadeAnims.erase(iter);
}
}
return !fadeAnims.empty();
}
*/
/*
bool CMapHandler::startObjectFade(TerrainTileObject & obj, bool in, int3 pos)
{
SDL_Surface * fadeBitmap;
assert(obj.obj);
auto objData = normalBlitter->findObjectBitmap(obj.obj, 0);
if (objData.objBitmap)
{
if (objData.isMoving) // ignore fading of moving objects (for now?)
{
logAnim->debug("Ignoring fade of moving object");
return false;
}
fadeBitmap = CSDL_Ext::newSurface(32, 32); // TODO cache these bitmaps instead of creating new ones?
Rect objSrcRect(obj.rect.x, obj.rect.y, 32, 32);
objData.objBitmap->draw(fadeBitmap,0,0,&objSrcRect);
if (objData.flagBitmap)
{
if (obj.obj->pos.x - 1 == pos.x && obj.obj->pos.y - 1 == pos.y) // -1 to draw flag in top-center instead of right-bottom; kind of a hack
{
Rect flagSrcRect(32, 0, 32, 32);
objData.flagBitmap->draw(fadeBitmap,0,0, &flagSrcRect);
}
}
auto anim = new CFadeAnimation();
anim->init(in ? CFadeAnimation::EMode::IN : CFadeAnimation::EMode::OUT, fadeBitmap, true);
fadeAnims[++fadeAnimCounter] = std::pair<int3, CFadeAnimation*>(pos, anim);
obj.fadeAnimKey = fadeAnimCounter;
logAnim->trace("Fade anim started for obj %d at %s; anim count: %d", obj.obj->ID, pos.toString(), fadeAnims.size());
return true;
}
return false;
}
*/
/*
bool CMapHandler::printObject(const CGObjectInstance * obj, bool fadein)
{
auto animation = graphics->getAnimation(obj);
if(!animation)
return false;
auto bitmap = animation->getImage(0);
if(!bitmap)
return false;
const int tilesW = bitmap->width()/32;
const int tilesH = bitmap->height()/32;
auto ttilesWidth = ttiles.shape()[1];
auto ttilesHeight = ttiles.shape()[2];
for(int fx=0; fx<tilesW; ++fx)
{
for(int fy=0; fy<tilesH; ++fy)
{
Rect cr;
cr.w = 32;
cr.h = 32;
cr.x = fx*32;
cr.y = fy*32;
if((obj->pos.x + fx - tilesW + 1) >= 0 &&
(obj->pos.x + fx - tilesW + 1) < ttilesWidth - frameW &&
(obj->pos.y + fy - tilesH + 1) >= 0 &&
(obj->pos.y + fy - tilesH + 1) < ttilesHeight - frameH)
{
int3 pos(obj->pos.x + fx - tilesW + 1, obj->pos.y + fy - tilesH + 1, obj->pos.z);
TerrainTile2 & curt = ttiles[pos.z][pos.x][pos.y];
TerrainTileObject toAdd(obj, cr, obj->visitableAt(pos.x, pos.y));
if (fadein && ADVOPT.objectFading)
{
startObjectFade(toAdd, true, pos);
}
auto i = curt.objects.begin();
for(; i != curt.objects.end(); i++)
{
if(objectBlitOrderSorter(toAdd, *i))
{
curt.objects.insert(i, toAdd);
i = curt.objects.begin(); //to validate and avoid adding it second time
break;
}
}
if(i == curt.objects.end())
curt.objects.insert(i, toAdd);
}
}
}
return true;
}
*/
/*
bool CMapHandler::hideObject(const CGObjectInstance * obj, bool fadeout)
{
for(size_t z = 0; z < map->levels(); z++)
{
for(size_t x = 0; x < map->width; x++)
{
for(size_t y = 0; y < map->height; y++)
{
auto &objs = ttiles[(int)z][(int)x][(int)y].objects;
for(size_t i = 0; i < objs.size(); i++)
{
if (objs[i].obj && objs[i].obj->id == obj->id)
{
if (fadeout && ADVOPT.objectFading) // object should be faded == erase is delayed until the end of fadeout
{
if (startObjectFade(objs[i], false, int3((si32)x, (si32)y, (si32)z)))
objs[i].obj = nullptr;
else
objs.erase(objs.begin() + i);
}
else
objs.erase(objs.begin() + i);
break;
}
}
}
}
}
return true;
}
*/
bool CMapHandler::hasOngoingAnimations()
{
for (auto * observer : observers)
@ -494,51 +202,6 @@ void CMapHandler::waitForOngoingAnimations()
}
}
/*
void CMapHandler::updateWater() //shift colors in palettes of water tiles
{
for(auto & elem : terrainImages["lava"])
{
for(auto img : elem)
img->shiftPalette(246, 9);
}
for(auto & elem : terrainImages["water"])
{
for(auto img : elem)
{
img->shiftPalette(229, 12);
img->shiftPalette(242, 14);
}
}
for(auto & elem : riverImages["clrrvr"])
{
for(auto img : elem)
{
img->shiftPalette(183, 12);
img->shiftPalette(195, 6);
}
}
for(auto & elem : riverImages["mudrvr"])
{
for(auto img : elem)
{
img->shiftPalette(228, 12);
img->shiftPalette(183, 6);
img->shiftPalette(240, 6);
}
}
for(auto & elem : riverImages["lavrvr"])
{
for(auto img : elem)
img->shiftPalette(240, 9);
}
}
*/
bool CMapHandler::hasObjectHole(const int3 & pos) const
{
//const TerrainTile2 & tt = ttiles[pos.z][pos.x][pos.y];

View File

@ -51,7 +51,7 @@ public:
int height() const;
//only indexed bitmaps, 16 colors maximum
virtual void shiftPalette(int from, int howMany) = 0;
virtual void shiftPalette(uint32_t firstColorID, uint32_t colorsToMove, uint32_t distanceToMove) = 0;
virtual void adjustPalette(const ColorFilter & shifter, size_t colorsToSkip) = 0;
virtual void resetPalette(int colorID) = 0;
virtual void resetPalette() = 0;

View File

@ -272,20 +272,17 @@ void SDLImage::savePalette()
SDL_SetPaletteColors(originalPalette, surf->format->palette->colors, 0, DEFAULT_PALETTE_COLORS);
}
void SDLImage::shiftPalette(int from, int howMany)
void SDLImage::shiftPalette(uint32_t firstColorID, uint32_t colorsToMove, uint32_t distanceToMove)
{
//works with at most 16 colors, if needed more -> increase values
assert(howMany < 16);
if(surf->format->palette)
{
SDL_Color palette[16];
std::vector<SDL_Color> shifterColors(colorsToMove);
for(int i=0; i<howMany; ++i)
for(uint32_t i=0; i<colorsToMove; ++i)
{
palette[(i+1)%howMany] = surf->format->palette->colors[from + i];
shifterColors[(i+distanceToMove)%colorsToMove] = originalPalette->colors[firstColorID + i];
}
CSDL_Ext::setColors(surf, palette, from, howMany);
CSDL_Ext::setColors(surf, shifterColors.data(), firstColorID, colorsToMove);
}
}

View File

@ -63,7 +63,7 @@ public:
void horizontalFlip() override;
void verticalFlip() override;
void shiftPalette(int from, int howMany) override;
void shiftPalette(uint32_t firstColorID, uint32_t colorsToMove, uint32_t distanceToMove) override;
void adjustPalette(const ColorFilter & shifter, size_t colorsToSkip) override;
void resetPalette(int colorID) override;
void resetPalette() override;

View File

@ -625,80 +625,37 @@ void CSDL_Ext::putPixelWithoutRefreshIfInSurf(SDL_Surface *ekran, const int & x,
}
template<int bpp>
void CSDL_Ext::applyEffectBpp(SDL_Surface * surf, const Rect & rect, int mode )
void CSDL_Ext::convertToGrayscaleBpp(SDL_Surface * surf, const Rect & rect )
{
switch(mode)
uint8_t * pixels = static_cast<uint8_t*>(surf->pixels);
for(int yp = rect.top(); yp < rect.bottom(); ++yp)
{
case 0: //sepia
uint8_t * pixel_from = pixels + rect.top() * surf->pitch + rect.left() * surf->format->BytesPerPixel;
uint8_t * pixel_dest = pixels + rect.top() * surf->pitch + rect.right() * surf->format->BytesPerPixel;
for (uint8_t * pixel = pixel_from; pixel < pixel_dest; pixel += surf->format->BytesPerPixel)
{
const int sepiaDepth = 20;
const int sepiaIntensity = 30;
int r = Channels::px<bpp>::r.get(pixel);
int g = Channels::px<bpp>::g.get(pixel);
int b = Channels::px<bpp>::b.get(pixel);
for(int xp = rect.x; xp < rect.x + rect.w; ++xp)
{
for(int yp = rect.y; yp < rect.y + rect.h; ++yp)
{
uint8_t * pixel = (ui8*)surf->pixels + yp * surf->pitch + xp * surf->format->BytesPerPixel;
int r = Channels::px<bpp>::r.get(pixel);
int g = Channels::px<bpp>::g.get(pixel);
int b = Channels::px<bpp>::b.get(pixel);
int gray = static_cast<int>(0.299 * r + 0.587 * g + 0.114 * b);
int gray = static_cast<int>(0.299 * r + 0.587 * g + 0.114 *b);
r = g = b = gray;
r = r + (sepiaDepth * 2);
g = g + sepiaDepth;
if (r>255) r=255;
if (g>255) g=255;
if (b>255) b=255;
// Darken blue color to increase sepia effect
b -= sepiaIntensity;
// normalize if out of bounds
if (b<0) b=0;
Channels::px<bpp>::r.set(pixel, r);
Channels::px<bpp>::g.set(pixel, g);
Channels::px<bpp>::b.set(pixel, b);
}
}
Channels::px<bpp>::r.set(pixel, gray);
Channels::px<bpp>::g.set(pixel, gray);
Channels::px<bpp>::b.set(pixel, gray);
}
break;
case 1: //grayscale
{
for(int xp = rect.x; xp < rect.x + rect.w; ++xp)
{
for(int yp = rect.y; yp < rect.y + rect.h; ++yp)
{
uint8_t * pixel = (ui8*)surf->pixels + yp * surf->pitch + xp * surf->format->BytesPerPixel;
int r = Channels::px<bpp>::r.get(pixel);
int g = Channels::px<bpp>::g.get(pixel);
int b = Channels::px<bpp>::b.get(pixel);
int gray = static_cast<int>(0.299 * r + 0.587 * g + 0.114 *b);
vstd::amax(gray, 255);
Channels::px<bpp>::r.set(pixel, gray);
Channels::px<bpp>::g.set(pixel, gray);
Channels::px<bpp>::b.set(pixel, gray);
}
}
}
break;
default:
throw std::runtime_error("Unsupported effect!");
}
}
void CSDL_Ext::applyEffect( SDL_Surface * surf, const Rect & rect, int mode )
void CSDL_Ext::convertToGrayscale( SDL_Surface * surf, const Rect & rect )
{
switch(surf->format->BytesPerPixel)
{
case 2: applyEffectBpp<2>(surf, rect, mode); break;
case 3: applyEffectBpp<3>(surf, rect, mode); break;
case 4: applyEffectBpp<4>(surf, rect, mode); break;
case 2: convertToGrayscaleBpp<2>(surf, rect); break;
case 3: convertToGrayscaleBpp<3>(surf, rect); break;
case 4: convertToGrayscaleBpp<4>(surf, rect); break;
}
}

View File

@ -102,8 +102,8 @@ typedef void (*TColorPutterAlpha)(uint8_t *&ptr, const uint8_t & R, const uint8_
SDL_Surface * scaleSurface(SDL_Surface *surf, int width, int height);
template<int bpp>
void applyEffectBpp( SDL_Surface * surf, const Rect & rect, int mode );
void applyEffect(SDL_Surface * surf, const Rect & rect, int mode); //mode: 0 - sepia, 1 - grayscale
void convertToGrayscaleBpp( SDL_Surface * surf, const Rect & rect );
void convertToGrayscale(SDL_Surface * surf, const Rect & rect);
bool isResolutionSupported(const std::vector<Point> & resolutions, const Point toTest );

View File

@ -237,7 +237,6 @@ CGHeroInstance::CGHeroInstance():
IBoatGenerator(this),
tacticFormationEnabled(false),
inTownGarrison(false),
isStanding(true),
moveDir(4),
mana(UNINITIALIZED_MANA),
movement(UNINITIALIZED_MOVEMENT),

View File

@ -57,7 +57,6 @@ public:
// 8 4
// 765
ui8 moveDir;
mutable ui8 isStanding;
mutable ui8 tacticFormationEnabled;
//////////////////////////////////////////////////////////////////////////

View File

@ -282,7 +282,7 @@ std::shared_ptr<QImage> MapHandler::findFlagBitmap(const CGHeroInstance * hero,
if(!hero || hero->boat)
return std::shared_ptr<QImage>();
return findFlagBitmapInternal(graphics->heroFlagAnimations.at(color.getNum()), anim, group, hero->moveDir, !hero->isStanding);
return findFlagBitmapInternal(graphics->heroFlagAnimations.at(color.getNum()), anim, group, hero->moveDir, true);
}
std::shared_ptr<QImage> MapHandler::findFlagBitmapInternal(std::shared_ptr<Animation> animation, int anim, int group, ui8 dir, bool moving) const