Browse Source

Hardware Cursor: Use item hotpoint

For a hardware item cursor, set the hotpoint to the center
instead of manually setting the cursor position.
pull/2196/head
Gleb Mazovetskiy 5 years ago
parent
commit
523d838bd4
  1. 32
      Source/hwcursor.cpp
  2. 12
      Source/inv.cpp

32
Source/hwcursor.cpp

@ -11,6 +11,7 @@
#include "DiabloUI/diabloui.h" #include "DiabloUI/diabloui.h"
#include "appfat.h"
#include "cursor.h" #include "cursor.h"
#include "engine.h" #include "engine.h"
#include "utils/display.h" #include "utils/display.h"
@ -23,7 +24,23 @@ CursorInfo CurrentCursorInfo;
#if SDL_VERSION_ATLEAST(2, 0, 0) #if SDL_VERSION_ATLEAST(2, 0, 0)
SDLCursorUniquePtr CurrentCursor; SDLCursorUniquePtr CurrentCursor;
void SetHardwareCursor(SDL_Surface *surface) enum class HotpointPosition {
TopLeft,
Center,
};
Point GetHotpointPosition(const SDL_Surface &surface, HotpointPosition position)
{
switch (position) {
case HotpointPosition::TopLeft:
return { 0, 0 };
case HotpointPosition::Center:
return { surface.w / 2, surface.h / 2 };
}
app_fatal("Unhandled enum value");
}
void SetHardwareCursor(SDL_Surface *surface, HotpointPosition hotpointPosition)
{ {
float scaleX; float scaleX;
float scaleY; float scaleY;
@ -33,7 +50,8 @@ void SetHardwareCursor(SDL_Surface *surface)
SDLCursorUniquePtr newCursor; SDLCursorUniquePtr newCursor;
if (renderer == nullptr || (scaleX == 1.0F && scaleY == 1.0F)) { if (renderer == nullptr || (scaleX == 1.0F && scaleY == 1.0F)) {
newCursor = SDLCursorUniquePtr { SDL_CreateColorCursor(surface, 0, 0) }; const Point hotpoint = GetHotpointPosition(*surface, hotpointPosition);
newCursor = SDLCursorUniquePtr { SDL_CreateColorCursor(surface, hotpoint.x, hotpoint.y) };
} else { } else {
// SDL does not support BlitScaled from 8-bit to RGBA. // SDL does not support BlitScaled from 8-bit to RGBA.
SDLSurfaceUniquePtr converted { SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888, 0) }; SDLSurfaceUniquePtr converted { SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888, 0) };
@ -42,7 +60,8 @@ void SetHardwareCursor(SDL_Surface *surface)
const int scaledH = surface->h * scaleY; // NOLINT(bugprone-narrowing-conversions) const int scaledH = surface->h * scaleY; // NOLINT(bugprone-narrowing-conversions)
SDLSurfaceUniquePtr scaledSurface { SDL_CreateRGBSurfaceWithFormat(0, scaledW, scaledH, 32, SDL_PIXELFORMAT_ARGB8888) }; SDLSurfaceUniquePtr scaledSurface { SDL_CreateRGBSurfaceWithFormat(0, scaledW, scaledH, 32, SDL_PIXELFORMAT_ARGB8888) };
SDL_BlitScaled(converted.get(), nullptr, scaledSurface.get(), nullptr); SDL_BlitScaled(converted.get(), nullptr, scaledSurface.get(), nullptr);
newCursor = SDLCursorUniquePtr { SDL_CreateColorCursor(scaledSurface.get(), 0, 0) }; const Point hotpoint = GetHotpointPosition(*scaledSurface, hotpointPosition);
newCursor = SDLCursorUniquePtr { SDL_CreateColorCursor(scaledSurface.get(), hotpoint.x, hotpoint.y) };
} }
SDL_SetCursor(newCursor.get()); SDL_SetCursor(newCursor.get());
CurrentCursor = std::move(newCursor); CurrentCursor = std::move(newCursor);
@ -50,7 +69,8 @@ void SetHardwareCursor(SDL_Surface *surface)
void SetHardwareCursorFromSprite(int pcurs) void SetHardwareCursorFromSprite(int pcurs)
{ {
const int outlineWidth = IsItemSprite(pcurs) ? 1 : 0; const bool isItem = IsItemSprite(pcurs);
const int outlineWidth = isItem ? 1 : 0;
int width; int width;
int height; int height;
@ -68,7 +88,7 @@ void SetHardwareCursorFromSprite(int pcurs)
SDL_SetColorKey(out.surface, 1, TransparentColor); SDL_SetColorKey(out.surface, 1, TransparentColor);
CelDrawCursor(out, { outlineWidth, height - outlineWidth }, pcurs); CelDrawCursor(out, { outlineWidth, height - outlineWidth }, pcurs);
SetHardwareCursor(out.surface); SetHardwareCursor(out.surface, isItem ? HotpointPosition::Center : HotpointPosition::TopLeft);
out.Free(); out.Free();
} }
#endif #endif
@ -92,7 +112,7 @@ void SetHardwareCursor(CursorInfo cursorInfo)
// ArtCursor is null while loading the game on the progress screen, // ArtCursor is null while loading the game on the progress screen,
// called via palette fade from ShowProgress. // called via palette fade from ShowProgress.
if (ArtCursor.surface != nullptr) if (ArtCursor.surface != nullptr)
SetHardwareCursor(ArtCursor.surface.get()); SetHardwareCursor(ArtCursor.surface.get(), HotpointPosition::TopLeft);
break; break;
case CursorType::Unknown: case CursorType::Unknown:
break; break;

12
Source/inv.cpp

@ -11,6 +11,7 @@
#include "cursor.h" #include "cursor.h"
#include "engine/render/cel_render.hpp" #include "engine/render/cel_render.hpp"
#include "engine/render/text_render.hpp" #include "engine/render/text_render.hpp"
#include "hwcursor.hpp"
#include "minitext.h" #include "minitext.h"
#include "options.h" #include "options.h"
#include "plrmsg.h" #include "plrmsg.h"
@ -808,8 +809,8 @@ void CheckInvPaste(int pnum, Point cursorPosition)
auto &player = plr[pnum]; auto &player = plr[pnum];
SetICursor(player.HoldItem._iCurs + CURSOR_FIRSTITEM); SetICursor(player.HoldItem._iCurs + CURSOR_FIRSTITEM);
int i = cursorPosition.x + (icursW / 2); int i = cursorPosition.x + (IsHardwareCursorEnabled() ? 0 : (icursW / 2));
int j = cursorPosition.y + (icursH / 2); int j = cursorPosition.y + (IsHardwareCursorEnabled() ? 0 : (icursH / 2));
int sx = icursW28; int sx = icursW28;
int sy = icursH28; int sy = icursH28;
bool done = false; bool done = false;
@ -1177,7 +1178,7 @@ void CheckInvPaste(int pnum, Point cursorPosition)
} }
CalcPlrInv(pnum, true); CalcPlrInv(pnum, true);
if (pnum == myplr) { if (pnum == myplr) {
if (cn == CURSOR_HAND) if (cn == CURSOR_HAND && !IsHardwareCursorEnabled())
SetCursorPos(MouseX + (cursW / 2), MouseY + (cursH / 2)); SetCursorPos(MouseX + (cursW / 2), MouseY + (cursH / 2));
NewCursor(cn); NewCursor(cn);
} }
@ -1416,7 +1417,10 @@ void CheckInvCut(int pnum, Point cursorPosition, bool automaticMove)
holdItem._itype = ITYPE_NONE; holdItem._itype = ITYPE_NONE;
} else { } else {
NewCursor(holdItem._iCurs + CURSOR_FIRSTITEM); NewCursor(holdItem._iCurs + CURSOR_FIRSTITEM);
SetCursorPos(cursorPosition.x - (cursW / 2), MouseY - (cursH / 2)); if (!IsHardwareCursorEnabled()) {
// For a hardware cursor, we set the "hot point" to the center of the item instead.
SetCursorPos(cursorPosition.x - (cursW / 2), cursorPosition.y - (cursH / 2));
}
} }
} }
} }

Loading…
Cancel
Save