Hardware Cursor: Use item hotpoint
For a hardware item cursor, set the hotpoint to the center instead of manually setting the cursor position.
This commit is contained in:
parent
4e6870a92f
commit
523d838bd4
2 changed files with 34 additions and 10 deletions
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "DiabloUI/diabloui.h"
|
||||
|
||||
#include "appfat.h"
|
||||
#include "cursor.h"
|
||||
#include "engine.h"
|
||||
#include "utils/display.h"
|
||||
|
|
@ -23,7 +24,23 @@ CursorInfo CurrentCursorInfo;
|
|||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
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 scaleY;
|
||||
|
|
@ -33,7 +50,8 @@ void SetHardwareCursor(SDL_Surface *surface)
|
|||
|
||||
SDLCursorUniquePtr newCursor;
|
||||
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 {
|
||||
// SDL does not support BlitScaled from 8-bit to RGBA.
|
||||
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)
|
||||
SDLSurfaceUniquePtr scaledSurface { SDL_CreateRGBSurfaceWithFormat(0, scaledW, scaledH, 32, SDL_PIXELFORMAT_ARGB8888) };
|
||||
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());
|
||||
CurrentCursor = std::move(newCursor);
|
||||
|
|
@ -50,7 +69,8 @@ void SetHardwareCursor(SDL_Surface *surface)
|
|||
|
||||
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 height;
|
||||
|
|
@ -68,7 +88,7 @@ void SetHardwareCursorFromSprite(int pcurs)
|
|||
SDL_SetColorKey(out.surface, 1, TransparentColor);
|
||||
CelDrawCursor(out, { outlineWidth, height - outlineWidth }, pcurs);
|
||||
|
||||
SetHardwareCursor(out.surface);
|
||||
SetHardwareCursor(out.surface, isItem ? HotpointPosition::Center : HotpointPosition::TopLeft);
|
||||
out.Free();
|
||||
}
|
||||
#endif
|
||||
|
|
@ -92,7 +112,7 @@ void SetHardwareCursor(CursorInfo cursorInfo)
|
|||
// ArtCursor is null while loading the game on the progress screen,
|
||||
// called via palette fade from ShowProgress.
|
||||
if (ArtCursor.surface != nullptr)
|
||||
SetHardwareCursor(ArtCursor.surface.get());
|
||||
SetHardwareCursor(ArtCursor.surface.get(), HotpointPosition::TopLeft);
|
||||
break;
|
||||
case CursorType::Unknown:
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue