|
|
|
|
#include "controls/touch/event_handlers.h"
|
|
|
|
|
|
|
|
|
|
#include "control.h"
|
|
|
|
|
#include "controls/plrctrls.h"
|
|
|
|
|
#include "cursor.h"
|
|
|
|
|
#include "diablo.h"
|
|
|
|
|
#include "engine.h"
|
|
|
|
|
#include "gmenu.h"
|
|
|
|
|
#include "inv.h"
|
|
|
|
|
#include "panels/spell_book.hpp"
|
|
|
|
|
#include "qol/stash.h"
|
|
|
|
|
#include "scrollrt.h"
|
|
|
|
|
#include "stores.h"
|
|
|
|
|
#include "utils/ui_fwd.h"
|
|
|
|
|
|
|
|
|
|
namespace devilution {
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
VirtualGamepadEventHandler Handler(&VirtualGamepadState);
|
|
|
|
|
|
|
|
|
|
Point ScaleToScreenCoordinates(float x, float y)
|
|
|
|
|
{
|
|
|
|
|
return Point {
|
|
|
|
|
(int)round(x * gnScreenWidth),
|
|
|
|
|
(int)round(y * gnScreenHeight)
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SimulateMouseMovement(const SDL_Event &event)
|
|
|
|
|
{
|
|
|
|
|
Point position = ScaleToScreenCoordinates(event.tfinger.x, event.tfinger.y);
|
|
|
|
|
|
|
|
|
|
bool isInMainPanel = GetMainPanel().Contains(position);
|
|
|
|
|
bool isInLeftPanel = GetLeftPanel().Contains(position);
|
|
|
|
|
bool isInRightPanel = GetRightPanel().Contains(position);
|
|
|
|
|
if (IsStashOpen) {
|
|
|
|
|
if (!spselflag && !isInMainPanel && !isInLeftPanel && !isInRightPanel)
|
|
|
|
|
return;
|
|
|
|
|
} else if (invflag) {
|
|
|
|
|
if (!spselflag && !isInMainPanel && !isInRightPanel)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MousePosition = position;
|
|
|
|
|
|
|
|
|
|
SetPointAndClick(true);
|
|
|
|
|
|
|
|
|
|
InvalidateInventorySlot();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool HandleGameMenuInteraction(const SDL_Event &event)
|
|
|
|
|
{
|
|
|
|
|
if (!gmenu_is_active())
|
|
|
|
|
return false;
|
|
|
|
|
if (event.type == SDL_FINGERDOWN && gmenu_left_mouse(true))
|
|
|
|
|
return true;
|
|
|
|
|
if (event.type == SDL_FINGERMOTION && gmenu_on_mouse_move())
|
|
|
|
|
return true;
|
|
|
|
|
return event.type == SDL_FINGERUP && gmenu_left_mouse(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool HandleStoreInteraction(const SDL_Event &event)
|
|
|
|
|
{
|
|
|
|
|
if (stextflag == STORE_NONE)
|
|
|
|
|
return false;
|
|
|
|
|
if (event.type == SDL_FINGERDOWN)
|
|
|
|
|
CheckStoreBtn();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HandleSpellBookInteraction(const SDL_Event &event)
|
|
|
|
|
{
|
|
|
|
|
if (!sbookflag)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (event.type == SDL_FINGERUP)
|
|
|
|
|
CheckSBook();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool HandleSpeedBookInteraction(const SDL_Event &event)
|
|
|
|
|
{
|
|
|
|
|
if (!spselflag)
|
|
|
|
|
return false;
|
|
|
|
|
if (event.type == SDL_FINGERUP)
|
|
|
|
|
SetSpell();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HandleBottomPanelInteraction(const SDL_Event &event)
|
|
|
|
|
{
|
|
|
|
|
if (!MyPlayer->HoldItem.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ClearPanBtn();
|
|
|
|
|
|
|
|
|
|
if (event.type != SDL_FINGERUP) {
|
|
|
|
|
spselflag = true;
|
|
|
|
|
DoPanBtn();
|
|
|
|
|
spselflag = false;
|
|
|
|
|
} else {
|
|
|
|
|
DoPanBtn();
|
|
|
|
|
if (panbtndown)
|
|
|
|
|
CheckBtnUp();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HandleCharacterPanelInteraction(const SDL_Event &event)
|
|
|
|
|
{
|
|
|
|
|
if (!chrflag)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (event.type == SDL_FINGERDOWN)
|
|
|
|
|
CheckChrBtns();
|
|
|
|
|
else if (event.type == SDL_FINGERUP && chrbtnactive)
|
|
|
|
|
ReleaseChrBtns(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HandleStashPanelInteraction(const SDL_Event &event)
|
|
|
|
|
{
|
|
|
|
|
if (!MyPlayer->HoldItem.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (event.type != SDL_FINGERUP) {
|
|
|
|
|
CheckStashButtonPress(MousePosition);
|
|
|
|
|
} else {
|
|
|
|
|
CheckStashButtonRelease(MousePosition);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
void HandleTouchEvent(const SDL_Event &event)
|
|
|
|
|
{
|
|
|
|
|
SetPointAndClick(false);
|
|
|
|
|
|
|
|
|
|
if (Handler.Handle(event)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!IsAnyOf(event.type, SDL_FINGERDOWN, SDL_FINGERUP, SDL_FINGERMOTION)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SimulateMouseMovement(event);
|
|
|
|
|
|
|
|
|
|
if (HandleGameMenuInteraction(event))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (HandleStoreInteraction(event))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (HandleSpeedBookInteraction(event))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
HandleSpellBookInteraction(event);
|
|
|
|
|
HandleBottomPanelInteraction(event);
|
|
|
|
|
HandleCharacterPanelInteraction(event);
|
|
|
|
|
HandleStashPanelInteraction(event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VirtualGamepadEventHandler::Handle(const SDL_Event &event)
|
|
|
|
|
{
|
|
|
|
|
if (!VirtualGamepadState.isActive || !IsAnyOf(event.type, SDL_FINGERDOWN, SDL_FINGERUP, SDL_FINGERMOTION)) {
|
|
|
|
|
VirtualGamepadState.primaryActionButton.didStateChange = false;
|
|
|
|
|
VirtualGamepadState.secondaryActionButton.didStateChange = false;
|
|
|
|
|
VirtualGamepadState.spellActionButton.didStateChange = false;
|
|
|
|
|
VirtualGamepadState.cancelButton.didStateChange = false;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (charMenuButtonEventHandler.Handle(event))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (questsMenuButtonEventHandler.Handle(event))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (inventoryMenuButtonEventHandler.Handle(event))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (mapMenuButtonEventHandler.Handle(event))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (directionPadEventHandler.Handle(event))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (leveltype != DTYPE_TOWN && standButtonEventHandler.Handle(event))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (primaryActionButtonEventHandler.Handle(event))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (secondaryActionButtonEventHandler.Handle(event))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (spellActionButtonEventHandler.Handle(event))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (cancelButtonEventHandler.Handle(event))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (healthButtonEventHandler.Handle(event))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (manaButtonEventHandler.Handle(event))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VirtualDirectionPadEventHandler::Handle(const SDL_Event &event)
|
|
|
|
|
{
|
|
|
|
|
switch (event.type) {
|
|
|
|
|
case SDL_FINGERDOWN:
|
|
|
|
|
return HandleFingerDown(event.tfinger);
|
|
|
|
|
|
|
|
|
|
case SDL_FINGERUP:
|
|
|
|
|
return HandleFingerUp(event.tfinger);
|
|
|
|
|
|
|
|
|
|
case SDL_FINGERMOTION:
|
|
|
|
|
return HandleFingerMotion(event.tfinger);
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VirtualDirectionPadEventHandler::HandleFingerDown(const SDL_TouchFingerEvent &event)
|
|
|
|
|
{
|
|
|
|
|
if (isActive)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
float x = event.x;
|
|
|
|
|
float y = event.y;
|
|
|
|
|
|
|
|
|
|
Point touchCoordinates = ScaleToScreenCoordinates(x, y);
|
|
|
|
|
if (!virtualDirectionPad->area.Contains(touchCoordinates))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
virtualDirectionPad->UpdatePosition(touchCoordinates);
|
|
|
|
|
activeFinger = event.fingerId;
|
|
|
|
|
isActive = true;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VirtualDirectionPadEventHandler::HandleFingerUp(const SDL_TouchFingerEvent &event)
|
|
|
|
|
{
|
|
|
|
|
if (!isActive || event.fingerId != activeFinger)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
Point position = virtualDirectionPad->area.position;
|
|
|
|
|
virtualDirectionPad->UpdatePosition(position);
|
|
|
|
|
isActive = false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VirtualDirectionPadEventHandler::HandleFingerMotion(const SDL_TouchFingerEvent &event)
|
|
|
|
|
{
|
|
|
|
|
if (!isActive || event.fingerId != activeFinger)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
float x = event.x;
|
|
|
|
|
float y = event.y;
|
|
|
|
|
|
|
|
|
|
Point touchCoordinates = ScaleToScreenCoordinates(x, y);
|
|
|
|
|
virtualDirectionPad->UpdatePosition(touchCoordinates);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VirtualButtonEventHandler::Handle(const SDL_Event &event)
|
|
|
|
|
{
|
|
|
|
|
if (!virtualButton->isUsable()) {
|
|
|
|
|
virtualButton->didStateChange = virtualButton->isHeld;
|
|
|
|
|
virtualButton->isHeld = false;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtualButton->didStateChange = false;
|
|
|
|
|
|
|
|
|
|
switch (event.type) {
|
|
|
|
|
case SDL_FINGERDOWN:
|
|
|
|
|
return HandleFingerDown(event.tfinger);
|
|
|
|
|
|
|
|
|
|
case SDL_FINGERUP:
|
|
|
|
|
return HandleFingerUp(event.tfinger);
|
|
|
|
|
|
|
|
|
|
case SDL_FINGERMOTION:
|
|
|
|
|
return HandleFingerMotion(event.tfinger);
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VirtualButtonEventHandler::HandleFingerDown(const SDL_TouchFingerEvent &event)
|
|
|
|
|
{
|
|
|
|
|
if (isActive)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
float x = event.x;
|
|
|
|
|
float y = event.y;
|
|
|
|
|
|
|
|
|
|
Point touchCoordinates = ScaleToScreenCoordinates(x, y);
|
|
|
|
|
if (!virtualButton->Contains(touchCoordinates))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (toggles)
|
|
|
|
|
virtualButton->isHeld = !virtualButton->isHeld;
|
|
|
|
|
else
|
|
|
|
|
virtualButton->isHeld = true;
|
|
|
|
|
|
|
|
|
|
virtualButton->didStateChange = true;
|
|
|
|
|
activeFinger = event.fingerId;
|
|
|
|
|
isActive = true;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VirtualButtonEventHandler::HandleFingerUp(const SDL_TouchFingerEvent &event)
|
|
|
|
|
{
|
|
|
|
|
if (!isActive || event.fingerId != activeFinger)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!toggles) {
|
|
|
|
|
if (virtualButton->isHeld)
|
|
|
|
|
virtualButton->didStateChange = true;
|
|
|
|
|
virtualButton->isHeld = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isActive = false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VirtualButtonEventHandler::HandleFingerMotion(const SDL_TouchFingerEvent &event)
|
|
|
|
|
{
|
|
|
|
|
if (!isActive || event.fingerId != activeFinger)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (toggles)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
float x = event.x;
|
|
|
|
|
float y = event.y;
|
|
|
|
|
Point touchCoordinates = ScaleToScreenCoordinates(x, y);
|
|
|
|
|
|
|
|
|
|
bool wasHeld = virtualButton->isHeld;
|
|
|
|
|
virtualButton->isHeld = virtualButton->Contains(touchCoordinates);
|
|
|
|
|
virtualButton->didStateChange = virtualButton->isHeld != wasHeld;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace devilution
|