mirror of
https://github.com/vcmi/vcmi.git
synced 2025-06-08 23:36:33 +02:00
Refactoring of CursorHandler, in preparation for HW cursor routines
This commit is contained in:
parent
246281e62a
commit
d44e809369
@ -44,11 +44,11 @@ CCursorHandler::CCursorHandler()
|
|||||||
, cursorLayer(nullptr)
|
, cursorLayer(nullptr)
|
||||||
, frameTime(0.f)
|
, frameTime(0.f)
|
||||||
, showing(false)
|
, showing(false)
|
||||||
|
, pos(0,0)
|
||||||
{
|
{
|
||||||
cursorLayer = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 40, 40);
|
cursorLayer = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 40, 40);
|
||||||
SDL_SetTextureBlendMode(cursorLayer, SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(cursorLayer, SDL_BLENDMODE_BLEND);
|
||||||
|
|
||||||
xpos = ypos = 0;
|
|
||||||
type = Cursor::Type::DEFAULT;
|
type = Cursor::Type::DEFAULT;
|
||||||
dndObject = nullptr;
|
dndObject = nullptr;
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ CCursorHandler::CCursorHandler()
|
|||||||
|
|
||||||
Point CCursorHandler::position() const
|
Point CCursorHandler::position() const
|
||||||
{
|
{
|
||||||
return Point(xpos, ypos);
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCursorHandler::changeGraphic(Cursor::Type type, size_t index)
|
void CCursorHandler::changeGraphic(Cursor::Type type, size_t index)
|
||||||
@ -127,136 +127,134 @@ void CCursorHandler::dragAndDropCursor(std::unique_ptr<CAnimImage> object)
|
|||||||
|
|
||||||
void CCursorHandler::cursorMove(const int & x, const int & y)
|
void CCursorHandler::cursorMove(const int & x, const int & y)
|
||||||
{
|
{
|
||||||
xpos = x;
|
pos.x = x;
|
||||||
ypos = y;
|
pos.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCursorHandler::shiftPos( int &x, int &y )
|
Point CCursorHandler::getPivotOffsetDefault(size_t index)
|
||||||
{
|
{
|
||||||
if(( type == Cursor::Type::COMBAT && frame != static_cast<size_t>(Cursor::Combat::POINTER)) || type == Cursor::Type::SPELLBOOK)
|
return {0, 0};
|
||||||
{
|
}
|
||||||
x-=16;
|
|
||||||
y-=16;
|
|
||||||
|
|
||||||
// Properly align the melee attack cursors.
|
Point CCursorHandler::getPivotOffsetMap(size_t index)
|
||||||
if (type == Cursor::Type::COMBAT)
|
{
|
||||||
{
|
static const std::array<Point, 43> offsets = {{
|
||||||
switch (static_cast<Cursor::Combat>(frame))
|
{ 0, 0}, // POINTER = 0,
|
||||||
{
|
{ 0, 0}, // HOURGLASS = 1,
|
||||||
case Cursor::Combat::HIT_NORTHEAST:
|
{ 12, 10}, // HERO = 2,
|
||||||
x -= 6;
|
{ 12, 12}, // TOWN = 3,
|
||||||
y += 16;
|
|
||||||
break;
|
{ 15, 13}, // T1_MOVE = 4,
|
||||||
case Cursor::Combat::HIT_EAST:
|
{ 13, 13}, // T1_ATTACK = 5,
|
||||||
x -= 16;
|
{ 20, 20}, // T1_SAIL = 6,
|
||||||
y += 10;
|
{ 13, 16}, // T1_DISEMBARK = 7,
|
||||||
break;
|
{ 8, 9}, // T1_EXCHANGE = 8,
|
||||||
case Cursor::Combat::HIT_SOUTHEAST:
|
{ 14, 16}, // T1_VISIT = 9,
|
||||||
x -= 6;
|
|
||||||
y -= 6;
|
{ 15, 13}, // T2_MOVE = 10,
|
||||||
break;
|
{ 13, 13}, // T2_ATTACK = 11,
|
||||||
case Cursor::Combat::HIT_SOUTHWEST:
|
{ 20, 20}, // T2_SAIL = 12,
|
||||||
x += 16;
|
{ 13, 16}, // T2_DISEMBARK = 13,
|
||||||
y -= 6;
|
{ 8, 9}, // T2_EXCHANGE = 14,
|
||||||
break;
|
{ 14, 16}, // T2_VISIT = 15,
|
||||||
case Cursor::Combat::HIT_WEST:
|
|
||||||
x += 16;
|
{ 15, 13}, // T3_MOVE = 16,
|
||||||
y += 11;
|
{ 13, 13}, // T3_ATTACK = 17,
|
||||||
break;
|
{ 20, 20}, // T3_SAIL = 18,
|
||||||
case Cursor::Combat::HIT_NORTHWEST:
|
{ 13, 16}, // T3_DISEMBARK = 19,
|
||||||
x += 16;
|
{ 8, 9}, // T3_EXCHANGE = 20,
|
||||||
y += 16;
|
{ 14, 16}, // T3_VISIT = 21,
|
||||||
break;
|
|
||||||
case Cursor::Combat::HIT_NORTH:
|
{ 15, 13}, // T4_MOVE = 22,
|
||||||
x += 9;
|
{ 13, 13}, // T4_ATTACK = 23,
|
||||||
y += 16;
|
{ 20, 20}, // T4_SAIL = 24,
|
||||||
break;
|
{ 13, 16}, // T4_DISEMBARK = 25,
|
||||||
case Cursor::Combat::HIT_SOUTH:
|
{ 8, 9}, // T4_EXCHANGE = 26,
|
||||||
x += 9;
|
{ 14, 16}, // T4_VISIT = 27,
|
||||||
y -= 15;
|
|
||||||
break;
|
{ 20, 20}, // T1_SAIL_VISIT = 28,
|
||||||
}
|
{ 20, 20}, // T2_SAIL_VISIT = 29,
|
||||||
}
|
{ 20, 20}, // T3_SAIL_VISIT = 30,
|
||||||
}
|
{ 20, 20}, // T4_SAIL_VISIT = 31,
|
||||||
else if(type == Cursor::Type::ADVENTURE)
|
|
||||||
{
|
{ 6, 1}, // SCROLL_NORTH = 32,
|
||||||
if (frame == 0)
|
{ 16, 2}, // SCROLL_NORTHEAST = 33,
|
||||||
{
|
{ 21, 6}, // SCROLL_EAST = 34,
|
||||||
//no-op
|
{ 16, 16}, // SCROLL_SOUTHEAST = 35,
|
||||||
}
|
{ 6, 21}, // SCROLL_SOUTH = 36,
|
||||||
else if(frame == 2)
|
{ 1, 16}, // SCROLL_SOUTHWEST = 37,
|
||||||
{
|
{ 1, 5}, // SCROLL_WEST = 38,
|
||||||
x -= 12;
|
{ 2, 1}, // SCROLL_NORTHWEST = 39,
|
||||||
y -= 10;
|
|
||||||
}
|
{ 0, 0}, // POINTER_COPY = 40,
|
||||||
else if(frame == 3)
|
{ 14, 16}, // TELEPORT = 41,
|
||||||
{
|
{ 20, 20}, // SCUTTLE_BOAT = 42
|
||||||
x -= 12;
|
}};
|
||||||
y -= 12;
|
|
||||||
}
|
static_assert (offsets.size() == size_t(Cursor::Map::COUNT), "Invalid number of pivot offsets for cursor" );
|
||||||
else if(frame < 27)
|
assert(index < offsets.size());
|
||||||
{
|
return offsets[index];
|
||||||
int hlpNum = (frame - 4)%6;
|
}
|
||||||
if(hlpNum == 0)
|
|
||||||
{
|
Point CCursorHandler::getPivotOffsetCombat(size_t index)
|
||||||
x -= 15;
|
{
|
||||||
y -= 13;
|
static const std::array<Point, 20> offsets = {{
|
||||||
}
|
{ 12, 12 }, // BLOCKED = 0,
|
||||||
else if(hlpNum == 1)
|
{ 10, 14 }, // MOVE = 1,
|
||||||
{
|
{ 14, 14 }, // FLY = 2,
|
||||||
x -= 13;
|
{ 12, 12 }, // SHOOT = 3,
|
||||||
y -= 13;
|
{ 12, 12 }, // HERO = 4,
|
||||||
}
|
{ 8, 12 }, // QUERY = 5,
|
||||||
else if(hlpNum == 2)
|
{ 0, 0 }, // POINTER = 6,
|
||||||
{
|
{ 21, 0 }, // HIT_NORTHEAST = 7,
|
||||||
x -= 20;
|
{ 31, 5 }, // HIT_EAST = 8,
|
||||||
y -= 20;
|
{ 21, 21 }, // HIT_SOUTHEAST = 9,
|
||||||
}
|
{ 0, 21 }, // HIT_SOUTHWEST = 10,
|
||||||
else if(hlpNum == 3)
|
{ 0, 5 }, // HIT_WEST = 11,
|
||||||
{
|
{ 0, 0 }, // HIT_NORTHWEST = 12,
|
||||||
x -= 13;
|
{ 6, 0 }, // HIT_NORTH = 13,
|
||||||
y -= 16;
|
{ 6, 31 }, // HIT_SOUTH = 14,
|
||||||
}
|
{ 14, 0 }, // SHOOT_PENALTY = 15,
|
||||||
else if(hlpNum == 4)
|
{ 12, 12 }, // SHOOT_CATAPULT = 16,
|
||||||
{
|
{ 12, 12 }, // HEAL = 17,
|
||||||
x -= 8;
|
{ 12, 12 }, // SACRIFICE = 18,
|
||||||
y -= 9;
|
{ 14, 20 }, // TELEPORT = 19
|
||||||
}
|
}};
|
||||||
else if(hlpNum == 5)
|
|
||||||
{
|
static_assert (offsets.size() == size_t(Cursor::Combat::COUNT), "Invalid number of pivot offsets for cursor" );
|
||||||
x -= 14;
|
assert(index < offsets.size());
|
||||||
y -= 16;
|
return offsets[index];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if(frame == 41)
|
Point CCursorHandler::getPivotOffsetSpellcast()
|
||||||
{
|
{
|
||||||
x -= 14;
|
return { 18, 28};
|
||||||
y -= 16;
|
}
|
||||||
}
|
|
||||||
else if(frame < 31 || frame == 42)
|
Point CCursorHandler::getPivotOffset()
|
||||||
{
|
{
|
||||||
x -= 20;
|
switch (type) {
|
||||||
y -= 20;
|
case Cursor::Type::ADVENTURE: return getPivotOffsetMap(frame);
|
||||||
}
|
case Cursor::Type::COMBAT: return getPivotOffsetCombat(frame);
|
||||||
}
|
case Cursor::Type::DEFAULT: return getPivotOffsetDefault(frame);
|
||||||
|
case Cursor::Type::SPELLBOOK: return getPivotOffsetSpellcast();
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(0);
|
||||||
|
return {0, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCursorHandler::centerCursor()
|
void CCursorHandler::centerCursor()
|
||||||
{
|
{
|
||||||
this->xpos = static_cast<int>((screen->w / 2.) - (currentCursor->pos.w / 2.));
|
pos.x = static_cast<int>((screen->w / 2.) - (currentCursor->pos.w / 2.));
|
||||||
this->ypos = static_cast<int>((screen->h / 2.) - (currentCursor->pos.h / 2.));
|
pos.y = static_cast<int>((screen->h / 2.) - (currentCursor->pos.h / 2.));
|
||||||
SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
|
SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
|
||||||
SDL_WarpMouse(this->xpos, this->ypos);
|
SDL_WarpMouse(pos.x, pos.y);
|
||||||
SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
|
SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCursorHandler::render()
|
void CCursorHandler::updateSpellcastCursor()
|
||||||
{
|
{
|
||||||
if(!showing)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (type == Cursor::Type::SPELLBOOK)
|
|
||||||
{
|
|
||||||
static const float frameDisplayDuration = 0.1f;
|
static const float frameDisplayDuration = 0.1f;
|
||||||
|
|
||||||
frameTime += GH.mainFPSmng->getElapsedMilliseconds() / 1000.f;
|
frameTime += GH.mainFPSmng->getElapsedMilliseconds() / 1000.f;
|
||||||
@ -274,24 +272,30 @@ void CCursorHandler::render()
|
|||||||
newFrame -= animation->size();
|
newFrame -= animation->size();
|
||||||
|
|
||||||
changeGraphic(Cursor::Type::SPELLBOOK, newFrame);
|
changeGraphic(Cursor::Type::SPELLBOOK, newFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CCursorHandler::render()
|
||||||
|
{
|
||||||
|
if(!showing)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (type == Cursor::Type::SPELLBOOK)
|
||||||
|
updateSpellcastCursor();
|
||||||
|
|
||||||
|
|
||||||
//the must update texture in the main (renderer) thread, but changes to cursor type may come from other threads
|
//the must update texture in the main (renderer) thread, but changes to cursor type may come from other threads
|
||||||
updateTexture();
|
updateTexture();
|
||||||
|
|
||||||
int x = xpos;
|
Point renderPos = pos;
|
||||||
int y = ypos;
|
|
||||||
shiftPos(x, y);
|
|
||||||
|
|
||||||
if(dndObject)
|
if(dndObject)
|
||||||
{
|
renderPos -= dndObject->pos.dimensions() / 2;
|
||||||
x -= dndObject->pos.w/2;
|
else
|
||||||
y -= dndObject->pos.h/2;
|
renderPos -= getPivotOffset();
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Rect destRect;
|
SDL_Rect destRect;
|
||||||
destRect.x = x;
|
destRect.x = renderPos.x;
|
||||||
destRect.y = y;
|
destRect.y = renderPos.y;
|
||||||
destRect.w = 40;
|
destRect.w = 40;
|
||||||
destRect.h = 40;
|
destRect.h = 40;
|
||||||
|
|
||||||
|
@ -8,11 +8,13 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class CIntObject;
|
class CIntObject;
|
||||||
class CAnimImage;
|
class CAnimImage;
|
||||||
struct SDL_Surface;
|
struct SDL_Surface;
|
||||||
struct SDL_Texture;
|
struct SDL_Texture;
|
||||||
struct Point;
|
|
||||||
|
#include "Geometries.h"
|
||||||
|
|
||||||
namespace Cursor
|
namespace Cursor
|
||||||
{
|
{
|
||||||
@ -51,7 +53,9 @@ namespace Cursor
|
|||||||
SHOOT_CATAPULT = 16,
|
SHOOT_CATAPULT = 16,
|
||||||
HEAL = 17,
|
HEAL = 17,
|
||||||
SACRIFICE = 18,
|
SACRIFICE = 18,
|
||||||
TELEPORT = 19
|
TELEPORT = 19,
|
||||||
|
|
||||||
|
COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Map {
|
enum class Map {
|
||||||
@ -97,7 +101,9 @@ namespace Cursor
|
|||||||
SCROLL_NORTHWEST = 39,
|
SCROLL_NORTHWEST = 39,
|
||||||
//POINTER_COPY = 40, // probably unused
|
//POINTER_COPY = 40, // probably unused
|
||||||
TELEPORT = 41,
|
TELEPORT = 41,
|
||||||
SCUTTLE_BOAT = 42
|
SCUTTLE_BOAT = 42,
|
||||||
|
|
||||||
|
COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Spellcast {
|
enum class Spellcast {
|
||||||
@ -123,7 +129,6 @@ class CCursorHandler final
|
|||||||
void clearBuffer();
|
void clearBuffer();
|
||||||
void updateBuffer(CIntObject * payload);
|
void updateBuffer(CIntObject * payload);
|
||||||
void replaceBuffer(CIntObject * payload);
|
void replaceBuffer(CIntObject * payload);
|
||||||
void shiftPos( int &x, int &y );
|
|
||||||
|
|
||||||
void updateTexture();
|
void updateTexture();
|
||||||
|
|
||||||
@ -135,8 +140,15 @@ class CCursorHandler final
|
|||||||
void changeGraphic(Cursor::Type type, size_t index);
|
void changeGraphic(Cursor::Type type, size_t index);
|
||||||
|
|
||||||
/// position of cursor
|
/// position of cursor
|
||||||
int xpos, ypos;
|
Point pos;
|
||||||
|
|
||||||
|
Point getPivotOffsetDefault(size_t index);
|
||||||
|
Point getPivotOffsetMap(size_t index);
|
||||||
|
Point getPivotOffsetCombat(size_t index);
|
||||||
|
Point getPivotOffsetSpellcast();
|
||||||
|
Point getPivotOffset();
|
||||||
|
|
||||||
|
void updateSpellcastCursor();
|
||||||
public:
|
public:
|
||||||
CCursorHandler();
|
CCursorHandler();
|
||||||
~CCursorHandler();
|
~CCursorHandler();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user