diff --git a/Source/DiabloUI/diabloui.cpp b/Source/DiabloUI/diabloui.cpp index 9ab7df1c..d2b53d6c 100644 --- a/Source/DiabloUI/diabloui.cpp +++ b/Source/DiabloUI/diabloui.cpp @@ -658,7 +658,7 @@ void LoadBackgroundArt(const char *pszFile, int frames) fadeTc = 0; fadeValue = 0; - if (IsHardwareCursorEnabled() && ArtCursor.surface != nullptr && GetCurrentCursorInfo().type() != CursorType::UserInterface) { + if (IsHardwareCursorEnabled() && ControlMode == ControlTypes::KeyboardAndMouse && ArtCursor.surface != nullptr && GetCurrentCursorInfo().type() != CursorType::UserInterface) { #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_SetSurfacePalette(ArtCursor.surface.get(), Palette.get()); SDL_SetColorKey(ArtCursor.surface.get(), 1, 0); diff --git a/Source/controls/plrctrls.cpp b/Source/controls/plrctrls.cpp index 04d1fc96..3a7d48fa 100644 --- a/Source/controls/plrctrls.cpp +++ b/Source/controls/plrctrls.cpp @@ -17,6 +17,7 @@ #include "engine/point.hpp" #include "gmenu.h" #include "help.h" +#include "hwcursor.hpp" #include "inv.h" #include "items.h" #include "minitext.h" @@ -1337,6 +1338,16 @@ void DetectInputMethod(const SDL_Event &event, const ControllerButtonEvent &game if (inputType != ControlTypes::None && inputType != ControlMode) { ControlMode = inputType; + +#ifndef USE_SDL1 + if (ControlMode != ControlTypes::KeyboardAndMouse) { + if (IsHardwareCursor()) + SetHardwareCursor(CursorInfo::UnknownCursor()); + } else { + ResetCursor(); + } +#endif + CalculatePanelAreas(); } } @@ -1378,6 +1389,8 @@ void HandleRightStickMotion() static int lastMouseSetTick = 0; const int now = SDL_GetTicks(); if (now - lastMouseSetTick > 0) { + ControlMode = ControlTypes::KeyboardAndMouse; + ResetCursor(); SetCursorPos({ x, y }); lastMouseSetTick = now; } diff --git a/Source/cursor.cpp b/Source/cursor.cpp index 6ddf4bc0..57b8f1e9 100644 --- a/Source/cursor.cpp +++ b/Source/cursor.cpp @@ -8,6 +8,7 @@ #include #include "control.h" +#include "controls/plrctrls.h" #include "doom.h" #include "engine.h" #include "engine/load_cel.hpp" @@ -165,12 +166,17 @@ void SetICursor(int cursId) icursSize28 = icursSize / 28; } +void ResetCursor() +{ + NewCursor(pcurs); +} + void NewCursor(int cursId) { pcurs = cursId; cursSize = GetInvItemSize(cursId); SetICursor(cursId); - if (IsHardwareCursorEnabled() && GetCurrentCursorInfo() != CursorInfo::GameCursor(cursId) && cursId != CURSOR_NONE) { + if (IsHardwareCursorEnabled() && ControlMode == ControlTypes::KeyboardAndMouse && GetCurrentCursorInfo() != CursorInfo::GameCursor(cursId) && cursId != CURSOR_NONE) { SetHardwareCursor(CursorInfo::GameCursor(cursId)); } } diff --git a/Source/cursor.h b/Source/cursor.h index 06510705..9e3692c8 100644 --- a/Source/cursor.h +++ b/Source/cursor.h @@ -46,6 +46,7 @@ extern DVL_API_FOR_TEST int pcurs; void InitCursor(); void FreeCursor(); void SetICursor(int cursId); +void ResetCursor(); void NewCursor(int cursId); void InitLevelCursor(); void CheckRportal(); diff --git a/Source/hwcursor.hpp b/Source/hwcursor.hpp index 56e01edb..460105d1 100644 --- a/Source/hwcursor.hpp +++ b/Source/hwcursor.hpp @@ -13,7 +13,7 @@ namespace devilution { inline bool IsHardwareCursorEnabled() { #if SDL_VERSION_ATLEAST(2, 0, 0) - return *sgOptions.Graphics.hardwareCursor; + return *sgOptions.Graphics.hardwareCursor && HardwareCursorSupported(); #else return false; #endif diff --git a/Source/miniwin/misc_msg.cpp b/Source/miniwin/misc_msg.cpp index 09d5ae3b..a1cb5539 100644 --- a/Source/miniwin/misc_msg.cpp +++ b/Source/miniwin/misc_msg.cpp @@ -52,9 +52,6 @@ namespace devilution { static std::deque message_queue; -bool mouseWarping = false; -Point mousePositionWarping; - void SetMouseButtonEvent(SDL_Event &event, uint32_t type, uint8_t button, Point position) { event.type = type; @@ -70,8 +67,11 @@ void SetMouseButtonEvent(SDL_Event &event, uint32_t type, uint8_t button, Point void SetCursorPos(Point position) { - mousePositionWarping = position; - mouseWarping = true; + if (ControlMode != ControlTypes::KeyboardAndMouse) { + MousePosition = position; + return; + } + LogicalToOutput(&position.x, &position.y); if (!demo::IsRunning()) SDL_WarpMouseInWindow(ghMainWnd, position.x, position.y); @@ -474,15 +474,6 @@ bool FetchMessage_Real(tagMSG *lpMsg) return true; } -#ifdef __vita__ - if (e.type < SDL_JOYAXISMOTION || (e.type >= SDL_FINGERDOWN && e.type < SDL_DOLLARGESTURE)) { -#else - if (e.type < SDL_JOYAXISMOTION) { -#endif - if (mouseWarping && e.type == SDL_MOUSEMOTION) - mouseWarping = false; - } - if (HandleControllerAddedOrRemovedEvent(e)) return true; @@ -606,15 +597,6 @@ bool FetchMessage_Real(tagMSG *lpMsg) case SDL_WINDOWEVENT_TAKE_FOCUS: #endif break; - case SDL_WINDOWEVENT_ENTER: - // Bug in SDL, SDL_WarpMouseInWindow doesn't emit SDL_MOUSEMOTION - // and SDL_GetMouseState gives previous location if mouse was - // outside window (observed on Ubuntu 19.04) - if (mouseWarping) { - MousePosition = mousePositionWarping; - mouseWarping = false; - } - break; case SDL_WINDOWEVENT_CLOSE: lpMsg->message = DVL_WM_QUERYENDSESSION; break; diff --git a/Source/movie.cpp b/Source/movie.cpp index dfdcdbbb..e9ec6ba6 100644 --- a/Source/movie.cpp +++ b/Source/movie.cpp @@ -4,6 +4,7 @@ * Implementation of video playback. */ +#include "controls/plrctrls.h" #include "diablo.h" #include "effects.h" #include "engine/demomode.h" @@ -30,7 +31,7 @@ void play_movie(const char *pszMovie, bool userCanClose) stream_stop(); effects_play_sound("Sfx\\Misc\\blank.wav"); - if (IsHardwareCursorEnabled()) { + if (IsHardwareCursorEnabled() && ControlMode == ControlTypes::KeyboardAndMouse) { SetHardwareCursorVisible(false); } diff --git a/Source/options.cpp b/Source/options.cpp index a0f0245b..c4e87ec6 100644 --- a/Source/options.cpp +++ b/Source/options.cpp @@ -219,12 +219,6 @@ void SaveIni() } #if SDL_VERSION_ATLEAST(2, 0, 0) -bool HardwareCursorSupported() -{ - SDL_version v; - SDL_GetVersion(&v); - return SDL_VERSIONNUM(v.major, v.minor, v.patch) >= SDL_VERSIONNUM(2, 0, 12); -} bool HardwareCursorDefault() { #if defined(__ANDROID__) || defined(TARGET_OS_IPHONE) @@ -310,6 +304,19 @@ void OptionAudioChanged() Options sgOptions; bool sbWasOptionsLoaded = false; +#if SDL_VERSION_ATLEAST(2, 0, 0) +bool HardwareCursorSupported() +{ +#if defined(TARGET_OS_IPHONE) + return false; +#else + SDL_version v; + SDL_GetVersion(&v); + return SDL_VERSIONNUM(v.major, v.minor, v.patch) >= SDL_VERSIONNUM(2, 0, 12); +#endif +} +#endif + void LoadOptions() { for (OptionCategoryBase *pCategory : sgOptions.GetCategories()) { diff --git a/Source/options.h b/Source/options.h index a4b5ac7b..8c2afae3 100644 --- a/Source/options.h +++ b/Source/options.h @@ -605,6 +605,8 @@ struct Options { extern DVL_API_FOR_TEST Options sgOptions; extern bool sbWasOptionsLoaded; +bool HardwareCursorSupported(); + /** * @brief Save game configurations to ini file */ diff --git a/Source/player.cpp b/Source/player.cpp index aeca966c..9bbc490a 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -1481,7 +1481,7 @@ bool IsPlayerAdjacentToObject(Player &player, Object &object) { int x = abs(player.position.tile.x - object.position.x); int y = abs(player.position.tile.y - object.position.y); - if (y > 1 && ObjectAtPosition(object.position + Direction::NorthEast) == &object) { + if (y > 1 && object.position.y >= 1 && ObjectAtPosition(object.position + Direction::NorthEast) == &object) { // special case for activating a large object from the north-east side y = abs(player.position.tile.y - object.position.y + 1); }