1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-15 01:24:45 +02:00

Animated cursor for spell selection, removed hardcoded cursor ID's

This commit is contained in:
Ivan Savenko
2022-12-18 22:32:07 +02:00
parent 53f6b7bd32
commit 16c4851d3b
12 changed files with 309 additions and 224 deletions

View File

@ -38,13 +38,18 @@ void CCursorHandler::replaceBuffer(CIntObject * payload)
updateBuffer(payload);
}
void CCursorHandler::initCursor()
CCursorHandler::CCursorHandler()
: needUpdate(true)
, buffer(nullptr)
, cursorLayer(nullptr)
, frameTime(0.f)
, showing(false)
{
cursorLayer = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 40, 40);
SDL_SetTextureBlendMode(cursorLayer, SDL_BLENDMODE_BLEND);
xpos = ypos = 0;
type = ECursor::DEFAULT;
type = Cursor::Type::DEFAULT;
dndObject = nullptr;
cursors =
@ -55,23 +60,28 @@ void CCursorHandler::initCursor()
make_unique<CAnimImage>("CRSPELL", 0)
};
currentCursor = cursors.at(int(ECursor::DEFAULT)).get();
currentCursor = cursors.at(static_cast<size_t>(Cursor::Type::DEFAULT)).get();
buffer = CSDL_Ext::newSurface(40,40);
SDL_SetSurfaceBlendMode(buffer, SDL_BLENDMODE_NONE);
SDL_ShowCursor(SDL_DISABLE);
changeGraphic(ECursor::ADVENTURE, 0);
set(Cursor::Map::POINTER);
}
void CCursorHandler::changeGraphic(ECursor::ECursorTypes type, int index)
Point CCursorHandler::position() const
{
return Point(xpos, ypos);
}
void CCursorHandler::changeGraphic(Cursor::Type type, size_t index)
{
if(type != this->type)
{
this->type = type;
this->frame = index;
currentCursor = cursors.at(int(type)).get();
currentCursor = cursors.at(static_cast<size_t>(type)).get();
currentCursor->setFrame(index);
}
else if(index != this->frame)
@ -83,6 +93,27 @@ void CCursorHandler::changeGraphic(ECursor::ECursorTypes type, int index)
replaceBuffer(currentCursor);
}
void CCursorHandler::set(Cursor::Default index)
{
changeGraphic(Cursor::Type::DEFAULT, static_cast<size_t>(index));
}
void CCursorHandler::set(Cursor::Map index)
{
changeGraphic(Cursor::Type::ADVENTURE, static_cast<size_t>(index));
}
void CCursorHandler::set(Cursor::Combat index)
{
changeGraphic(Cursor::Type::COMBAT, static_cast<size_t>(index));
}
void CCursorHandler::set(Cursor::Spellcast index)
{
//Note: this is animated cursor, ignore specified frame and only change type
changeGraphic(Cursor::Type::SPELLBOOK, frame);
}
void CCursorHandler::dragAndDropCursor(std::unique_ptr<CAnimImage> object)
{
dndObject = std::move(object);
@ -100,54 +131,57 @@ void CCursorHandler::cursorMove(const int & x, const int & y)
void CCursorHandler::shiftPos( int &x, int &y )
{
if(( type == ECursor::COMBAT && frame != ECursor::COMBAT_POINTER) || type == ECursor::SPELLBOOK)
if(( type == Cursor::Type::COMBAT && frame != static_cast<size_t>(Cursor::Combat::POINTER)) || type == Cursor::Type::SPELLBOOK)
{
x-=16;
y-=16;
// Properly align the melee attack cursors.
if (type == ECursor::COMBAT)
if (type == Cursor::Type::COMBAT)
{
switch (frame)
switch (static_cast<Cursor::Combat>(frame))
{
case 7: // Bottom left
case Cursor::Combat::HIT_NORTHEAST:
x -= 6;
y += 16;
break;
case 8: // Left
case Cursor::Combat::HIT_EAST:
x -= 16;
y += 10;
break;
case 9: // Top left
case Cursor::Combat::HIT_SOUTHEAST:
x -= 6;
y -= 6;
break;
case 10: // Top right
case Cursor::Combat::HIT_SOUTHWEST:
x += 16;
y -= 6;
break;
case 11: // Right
case Cursor::Combat::HIT_WEST:
x += 16;
y += 11;
break;
case 12: // Bottom right
case Cursor::Combat::HIT_NORTHWEST:
x += 16;
y += 16;
break;
case 13: // Below
case Cursor::Combat::HIT_NORTH:
x += 9;
y += 16;
break;
case 14: // Above
case Cursor::Combat::HIT_SOUTH:
x += 9;
y -= 15;
break;
}
}
}
else if(type == ECursor::ADVENTURE)
else if(type == Cursor::Type::ADVENTURE)
{
if (frame == 0); //to exclude
if (frame == 0)
{
//no-op
}
else if(frame == 2)
{
x -= 12;
@ -219,6 +253,27 @@ void CCursorHandler::render()
if(!showing)
return;
if (type == Cursor::Type::SPELLBOOK)
{
static const float frameDisplayDuration = 0.1f;
frameTime += GH.mainFPSmng->getElapsedMilliseconds() / 1000.f;
size_t newFrame = frame;
while (frameTime > frameDisplayDuration)
{
frameTime -= frameDisplayDuration;
newFrame++;
}
auto & animation = cursors.at(static_cast<size_t>(type));
while (newFrame > animation->size())
newFrame -= animation->size();
changeGraphic(Cursor::Type::SPELLBOOK, newFrame);
}
//the must update texture in the main (renderer) thread, but changes to cursor type may come from other threads
updateTexture();
@ -250,15 +305,6 @@ void CCursorHandler::updateTexture()
}
}
CCursorHandler::CCursorHandler()
: needUpdate(true),
buffer(nullptr),
cursorLayer(nullptr),
showing(false)
{
}
CCursorHandler::~CCursorHandler()
{
if(buffer)