diff --git a/Packaging/resources/ui_art/attack.png b/Packaging/resources/ui_art/attack.png deleted file mode 100644 index 0b07b8b41..000000000 Binary files a/Packaging/resources/ui_art/attack.png and /dev/null differ diff --git a/Packaging/resources/ui_art/attackp.png b/Packaging/resources/ui_art/attackp.png deleted file mode 100644 index c48d108c6..000000000 Binary files a/Packaging/resources/ui_art/attackp.png and /dev/null differ diff --git a/Packaging/resources/ui_art/back.png b/Packaging/resources/ui_art/back.png deleted file mode 100644 index 0fbcea880..000000000 Binary files a/Packaging/resources/ui_art/back.png and /dev/null differ diff --git a/Packaging/resources/ui_art/backp.png b/Packaging/resources/ui_art/backp.png deleted file mode 100644 index a3b670335..000000000 Binary files a/Packaging/resources/ui_art/backp.png and /dev/null differ diff --git a/Packaging/resources/ui_art/button.png b/Packaging/resources/ui_art/button.png new file mode 100644 index 000000000..bb8a07544 Binary files /dev/null and b/Packaging/resources/ui_art/button.png differ diff --git a/Packaging/resources/ui_art/castspell.png b/Packaging/resources/ui_art/castspell.png deleted file mode 100644 index 91159b52c..000000000 Binary files a/Packaging/resources/ui_art/castspell.png and /dev/null differ diff --git a/Packaging/resources/ui_art/castspellp.png b/Packaging/resources/ui_art/castspellp.png deleted file mode 100644 index da6c71410..000000000 Binary files a/Packaging/resources/ui_art/castspellp.png and /dev/null differ diff --git a/Packaging/resources/ui_art/noaction.png b/Packaging/resources/ui_art/noaction.png deleted file mode 100644 index 6787d5825..000000000 Binary files a/Packaging/resources/ui_art/noaction.png and /dev/null differ diff --git a/Packaging/resources/ui_art/noactionp.png b/Packaging/resources/ui_art/noactionp.png deleted file mode 100644 index f72f065d3..000000000 Binary files a/Packaging/resources/ui_art/noactionp.png and /dev/null differ diff --git a/Packaging/resources/ui_art/object.png b/Packaging/resources/ui_art/object.png deleted file mode 100644 index 2284373a6..000000000 Binary files a/Packaging/resources/ui_art/object.png and /dev/null differ diff --git a/Packaging/resources/ui_art/objectp.png b/Packaging/resources/ui_art/objectp.png deleted file mode 100644 index eabad35e7..000000000 Binary files a/Packaging/resources/ui_art/objectp.png and /dev/null differ diff --git a/Packaging/resources/ui_art/pickitem.png b/Packaging/resources/ui_art/pickitem.png deleted file mode 100644 index 5c66019a1..000000000 Binary files a/Packaging/resources/ui_art/pickitem.png and /dev/null differ diff --git a/Packaging/resources/ui_art/pickitemp.png b/Packaging/resources/ui_art/pickitemp.png deleted file mode 100644 index aadcf4f51..000000000 Binary files a/Packaging/resources/ui_art/pickitemp.png and /dev/null differ diff --git a/Packaging/resources/ui_art/talk.png b/Packaging/resources/ui_art/talk.png deleted file mode 100644 index c7de225db..000000000 Binary files a/Packaging/resources/ui_art/talk.png and /dev/null differ diff --git a/Packaging/resources/ui_art/talkp.png b/Packaging/resources/ui_art/talkp.png deleted file mode 100644 index 20fc1624d..000000000 Binary files a/Packaging/resources/ui_art/talkp.png and /dev/null differ diff --git a/Source/controls/touch/renderers.cpp b/Source/controls/touch/renderers.cpp index 959f7277b..b6fae5a66 100644 --- a/Source/controls/touch/renderers.cpp +++ b/Source/controls/touch/renderers.cpp @@ -16,6 +16,41 @@ namespace { VirtualGamepadRenderer Renderer(&VirtualGamepadState); +VirtualGamepadButtonType GetAttackButtonType(bool isPressed) +{ + return isPressed ? GAMEPAD_ATTACKDOWN : GAMEPAD_ATTACK; +} + +VirtualGamepadButtonType GetTalkButtonType(bool isPressed) +{ + return isPressed ? GAMEPAD_TALKDOWN : GAMEPAD_TALK; +} + +VirtualGamepadButtonType GetItemButtonType(bool isPressed) +{ + return isPressed ? GAMEPAD_ITEMDOWN : GAMEPAD_ITEM; +} + +VirtualGamepadButtonType GetObjectButtonType(bool isPressed) +{ + return isPressed ? GAMEPAD_OBJECTDOWN : GAMEPAD_OBJECT; +} + +VirtualGamepadButtonType GetCastButtonType(bool isPressed) +{ + return isPressed ? GAMEPAD_CASTSPELLDOWN : GAMEPAD_CASTSPELL; +} + +VirtualGamepadButtonType GetCancelButtonType(bool isPressed) +{ + return isPressed ? GAMEPAD_BACKDOWN : GAMEPAD_BACK; +} + +VirtualGamepadButtonType GetBlankButtonType(bool isPressed) +{ + return isPressed ? GAMEPAD_BLANKDOWN : GAMEPAD_BLANK; +} + } // namespace void DrawVirtualGamepad(const Surface &out) @@ -23,6 +58,23 @@ void DrawVirtualGamepad(const Surface &out) Renderer.Render(out); } +void VirtualGamepadRenderer::LoadArt() +{ + directionPadRenderer.LoadArt(); + + const int Frames = 14; + buttonArt.surface.reset(LoadPNG("ui_art\\button.png")); + buttonArt.logical_width = buttonArt.surface->w; + buttonArt.frame_height = buttonArt.surface->h / Frames; + buttonArt.frames = Frames; +} + +void VirtualDirectionPadRenderer::LoadArt() +{ + padSurface.reset(LoadPNG("ui_art\\directions.png")); + knobSurface.reset(LoadPNG("ui_art\\directions2.png")); +} + void VirtualGamepadRenderer::Render(const Surface &out) { directionPadRenderer.Render(out); @@ -41,7 +93,7 @@ void VirtualDirectionPadRenderer::Render(const Surface &out) void VirtualDirectionPadRenderer::RenderPad(const Surface &out) { if (padSurface == nullptr) - padSurface.reset(LoadPNG("ui_art\\directions.png")); + return; auto center = virtualDirectionPad->area.position; auto radius = virtualDirectionPad->area.radius; @@ -58,7 +110,7 @@ void VirtualDirectionPadRenderer::RenderPad(const Surface &out) void VirtualDirectionPadRenderer::RenderKnob(const Surface &out) { if (knobSurface == nullptr) - knobSurface.reset(LoadPNG("ui_art\\directions2.png")); + return; auto center = virtualDirectionPad->position; auto radius = virtualDirectionPad->area.radius / 3; @@ -74,6 +126,13 @@ void VirtualDirectionPadRenderer::RenderKnob(const Surface &out) void VirtualPadButtonRenderer::Render(const Surface &out) { + if (buttonArt->surface == nullptr) + return; + + VirtualGamepadButtonType buttonType = GetButtonType(); + int frame = buttonType; + int offset = buttonArt->h() * frame; + auto center = virtualPadButton->area.position; auto radius = virtualPadButton->area.radius; int diameter = 2 * radius; @@ -83,136 +142,95 @@ void VirtualPadButtonRenderer::Render(const Surface &out) int width = diameter; int height = diameter; - SDL_Surface *surface = GetButtonSurface(); - SDL_Rect rect { x, y, width, height }; - SDL_BlitScaled(surface, nullptr, out.surface, &rect); -} - -SDL_Surface *VirtualPadButtonRenderer::GetAttackSurface() -{ - if (attackSurface == nullptr) - attackSurface.reset(LoadPNG("ui_art\\attack.png")); - if (pressedAttackSurface == nullptr) - pressedAttackSurface.reset(LoadPNG("ui_art\\attackp.png")); - return virtualPadButton->isHeld ? pressedAttackSurface.get() : attackSurface.get(); -} - -SDL_Surface *VirtualPadButtonRenderer::GetTalkSurface() -{ - if (talkSurface == nullptr) - talkSurface.reset(LoadPNG("ui_art\\talk.png")); - if (pressedTalkSurface == nullptr) - pressedTalkSurface.reset(LoadPNG("ui_art\\talkp.png")); - return virtualPadButton->isHeld ? pressedTalkSurface.get() : talkSurface.get(); -} - -SDL_Surface *VirtualPadButtonRenderer::GetItemSurface() -{ - if (itemSurface == nullptr) - itemSurface.reset(LoadPNG("ui_art\\pickitem.png")); - if (pressedItemSurface == nullptr) - pressedItemSurface.reset(LoadPNG("ui_art\\pickitemp.png")); - return virtualPadButton->isHeld ? pressedItemSurface.get() : itemSurface.get(); -} - -SDL_Surface *VirtualPadButtonRenderer::GetObjectSurface() -{ - if (objectSurface == nullptr) - objectSurface.reset(LoadPNG("ui_art\\object.png")); - if (pressedObjectSurface == nullptr) - pressedObjectSurface.reset(LoadPNG("ui_art\\objectp.png")); - return virtualPadButton->isHeld ? pressedObjectSurface.get() : objectSurface.get(); -} - -SDL_Surface *VirtualPadButtonRenderer::GetCastSurface() -{ - if (castSurface == nullptr) - castSurface.reset(LoadPNG("ui_art\\castspell.png")); - if (pressedCastSurface == nullptr) - pressedCastSurface.reset(LoadPNG("ui_art\\castspellp.png")); - return virtualPadButton->isHeld ? pressedCastSurface.get() : castSurface.get(); -} - -SDL_Surface *VirtualPadButtonRenderer::GetCancelSurface() -{ - if (cancelSurface == nullptr) - cancelSurface.reset(LoadPNG("ui_art\\back.png")); - if (pressedCancelSurface == nullptr) - pressedCancelSurface.reset(LoadPNG("ui_art\\backp.png")); - return virtualPadButton->isHeld ? pressedCancelSurface.get() : cancelSurface.get(); -} - -SDL_Surface *VirtualPadButtonRenderer::GetBlankSurface() -{ - if (blankSurface == nullptr) - blankSurface.reset(LoadPNG("ui_art\\noaction.png")); - if (pressedBlankSurface == nullptr) - pressedBlankSurface.reset(LoadPNG("ui_art\\noactionp.png")); - return virtualPadButton->isHeld ? pressedBlankSurface.get() : blankSurface.get(); + SDL_Rect src { 0, offset, buttonArt->w(), buttonArt->h() }; + SDL_Rect dst { x, y, width, height }; + SDL_BlitScaled(buttonArt->surface.get(), &src, out.surface, &dst); } -SDL_Surface *PrimaryActionButtonRenderer::GetButtonSurface() +VirtualGamepadButtonType PrimaryActionButtonRenderer::GetButtonType() { // NEED: Confirm surface if (qtextflag) - return GetTalkSurface(); + return GetTalkButtonType(virtualPadButton->isHeld); if (invflag) - return GetInventoryButtonSurface(); + return GetInventoryButtonType(); if (leveltype == DTYPE_TOWN) - return GetTownButtonSurface(); - return GetDungeonButtonSurface(); + return GetTownButtonType(); + return GetDungeonButtonType(); } -SDL_Surface *PrimaryActionButtonRenderer::GetTownButtonSurface() +VirtualGamepadButtonType PrimaryActionButtonRenderer::GetTownButtonType() { if (stextflag != STORE_NONE || pcursmonst != -1) - return GetTalkSurface(); - return GetBlankSurface(); + return GetTalkButtonType(virtualPadButton->isHeld); + return GetBlankButtonType(virtualPadButton->isHeld); } -SDL_Surface *PrimaryActionButtonRenderer::GetDungeonButtonSurface() +VirtualGamepadButtonType PrimaryActionButtonRenderer::GetDungeonButtonType() { if (pcursmonst != -1) { const auto &monster = Monsters[pcursmonst]; if (M_Talker(monster) || monster.mtalkmsg != TEXT_NONE) - return GetTalkSurface(); + return GetTalkButtonType(virtualPadButton->isHeld); } - return GetAttackSurface(); + return GetAttackButtonType(virtualPadButton->isHeld); } -SDL_Surface *PrimaryActionButtonRenderer::GetInventoryButtonSurface() +VirtualGamepadButtonType PrimaryActionButtonRenderer::GetInventoryButtonType() { if (pcursinvitem != -1 || pcurs > CURSOR_HAND) - return GetItemSurface(); - return GetBlankSurface(); + return GetItemButtonType(virtualPadButton->isHeld); + return GetBlankButtonType(virtualPadButton->isHeld); } -SDL_Surface *SecondaryActionButtonRenderer::GetButtonSurface() +VirtualGamepadButtonType SecondaryActionButtonRenderer::GetButtonType() { // NEED: Stairs surface if (InGameMenu() || QuestLogIsOpen || sbookflag) - return GetBlankSurface(); + return GetBlankButtonType(virtualPadButton->isHeld); if (pcursobj != -1) - return GetObjectSurface(); + return GetObjectButtonType(virtualPadButton->isHeld); if (pcursitem != -1) - return GetItemSurface(); - return GetBlankSurface(); + return GetItemButtonType(virtualPadButton->isHeld); + return GetBlankButtonType(virtualPadButton->isHeld); } -SDL_Surface *SpellActionButtonRenderer::GetButtonSurface() +VirtualGamepadButtonType SpellActionButtonRenderer::GetButtonType() { if (!InGameMenu() && !QuestLogIsOpen && !sbookflag) - return GetCastSurface(); - return GetBlankSurface(); + return GetCastButtonType(virtualPadButton->isHeld); + return GetBlankButtonType(virtualPadButton->isHeld); } -SDL_Surface *CancelButtonRenderer::GetButtonSurface() +VirtualGamepadButtonType CancelButtonRenderer::GetButtonType() { if (InGameMenu()) - return GetCancelSurface(); + return GetCancelButtonType(virtualPadButton->isHeld); if (DoomFlag || invflag || sbookflag || QuestLogIsOpen || chrflag) - return GetCancelSurface(); - return GetBlankSurface(); + return GetCancelButtonType(virtualPadButton->isHeld); + return GetBlankButtonType(virtualPadButton->isHeld); +} + +void VirtualGamepadRenderer::UnloadArt() +{ + directionPadRenderer.UnloadArt(); + buttonArt.surface = nullptr; +} + +void VirtualDirectionPadRenderer::UnloadArt() +{ + padSurface = nullptr; + knobSurface = nullptr; +} + +void InitVirtualGamepadGFX() +{ + Renderer.LoadArt(); +} + +void FreeVirtualGamepadGFX() +{ + Renderer.UnloadArt(); } } // namespace devilution diff --git a/Source/controls/touch/renderers.h b/Source/controls/touch/renderers.h index 75b9732d4..c246d274d 100644 --- a/Source/controls/touch/renderers.h +++ b/Source/controls/touch/renderers.h @@ -9,6 +9,23 @@ namespace devilution { +enum VirtualGamepadButtonType { + GAMEPAD_ATTACK, + GAMEPAD_ATTACKDOWN, + GAMEPAD_TALK, + GAMEPAD_TALKDOWN, + GAMEPAD_ITEM, + GAMEPAD_ITEMDOWN, + GAMEPAD_OBJECT, + GAMEPAD_OBJECTDOWN, + GAMEPAD_CASTSPELL, + GAMEPAD_CASTSPELLDOWN, + GAMEPAD_BACK, + GAMEPAD_BACKDOWN, + GAMEPAD_BLANK, + GAMEPAD_BLANKDOWN, +}; + class VirtualDirectionPadRenderer { public: VirtualDirectionPadRenderer(VirtualDirectionPad *virtualDirectionPad) @@ -16,7 +33,9 @@ public: { } + void LoadArt(); void Render(const Surface &out); + void UnloadArt(); private: VirtualDirectionPad *virtualDirectionPad; @@ -29,8 +48,9 @@ private: class VirtualPadButtonRenderer { public: - VirtualPadButtonRenderer(VirtualPadButton *virtualPadButton) + VirtualPadButtonRenderer(VirtualPadButton *virtualPadButton, Art *buttonArt) : virtualPadButton(virtualPadButton) + , buttonArt(buttonArt) { } @@ -39,91 +59,73 @@ public: protected: VirtualPadButton *virtualPadButton; - virtual SDL_Surface *GetButtonSurface() = 0; - SDL_Surface *GetAttackSurface(); - SDL_Surface *GetTalkSurface(); - SDL_Surface *GetItemSurface(); - SDL_Surface *GetObjectSurface(); - SDL_Surface *GetCastSurface(); - SDL_Surface *GetCancelSurface(); - SDL_Surface *GetBlankSurface(); + virtual VirtualGamepadButtonType GetButtonType() = 0; private: - SDLSurfaceUniquePtr attackSurface; - SDLSurfaceUniquePtr pressedAttackSurface; - SDLSurfaceUniquePtr talkSurface; - SDLSurfaceUniquePtr pressedTalkSurface; - SDLSurfaceUniquePtr itemSurface; - SDLSurfaceUniquePtr pressedItemSurface; - SDLSurfaceUniquePtr objectSurface; - SDLSurfaceUniquePtr pressedObjectSurface; - SDLSurfaceUniquePtr castSurface; - SDLSurfaceUniquePtr pressedCastSurface; - SDLSurfaceUniquePtr cancelSurface; - SDLSurfaceUniquePtr pressedCancelSurface; - SDLSurfaceUniquePtr blankSurface; - SDLSurfaceUniquePtr pressedBlankSurface; + Art *buttonArt; }; class PrimaryActionButtonRenderer : public VirtualPadButtonRenderer { public: - PrimaryActionButtonRenderer(VirtualPadButton *primaryActionButton) - : VirtualPadButtonRenderer(primaryActionButton) + PrimaryActionButtonRenderer(VirtualPadButton *primaryActionButton, Art *buttonArt) + : VirtualPadButtonRenderer(primaryActionButton, buttonArt) { } private: - SDL_Surface *GetButtonSurface(); - SDL_Surface *GetTownButtonSurface(); - SDL_Surface *GetDungeonButtonSurface(); - SDL_Surface *GetInventoryButtonSurface(); + VirtualGamepadButtonType GetButtonType(); + VirtualGamepadButtonType GetTownButtonType(); + VirtualGamepadButtonType GetDungeonButtonType(); + VirtualGamepadButtonType GetInventoryButtonType(); }; class SecondaryActionButtonRenderer : public VirtualPadButtonRenderer { public: - SecondaryActionButtonRenderer(VirtualPadButton *secondaryActionButton) - : VirtualPadButtonRenderer(secondaryActionButton) + SecondaryActionButtonRenderer(VirtualPadButton *secondaryActionButton, Art *buttonArt) + : VirtualPadButtonRenderer(secondaryActionButton, buttonArt) { } private: - SDL_Surface *GetButtonSurface(); + VirtualGamepadButtonType GetButtonType(); }; class SpellActionButtonRenderer : public VirtualPadButtonRenderer { public: - SpellActionButtonRenderer(VirtualPadButton *spellActionButton) - : VirtualPadButtonRenderer(spellActionButton) + SpellActionButtonRenderer(VirtualPadButton *spellActionButton, Art *buttonArt) + : VirtualPadButtonRenderer(spellActionButton, buttonArt) { } private: - SDL_Surface *GetButtonSurface(); + VirtualGamepadButtonType GetButtonType(); }; class CancelButtonRenderer : public VirtualPadButtonRenderer { public: - CancelButtonRenderer(VirtualPadButton *cancelButton) - : VirtualPadButtonRenderer(cancelButton) + CancelButtonRenderer(VirtualPadButton *cancelButton, Art *buttonArt) + : VirtualPadButtonRenderer(cancelButton, buttonArt) { } private: - SDL_Surface *GetButtonSurface(); + VirtualGamepadButtonType GetButtonType(); }; class VirtualGamepadRenderer { public: VirtualGamepadRenderer(VirtualGamepad *virtualGamepad) : directionPadRenderer(&virtualGamepad->directionPad) - , primaryActionButtonRenderer(&virtualGamepad->primaryActionButton) - , secondaryActionButtonRenderer(&virtualGamepad->secondaryActionButton) - , spellActionButtonRenderer(&virtualGamepad->spellActionButton) - , cancelButtonRenderer(&virtualGamepad->cancelButton) + , primaryActionButtonRenderer(&virtualGamepad->primaryActionButton, &buttonArt) + , secondaryActionButtonRenderer(&virtualGamepad->secondaryActionButton, &buttonArt) + , spellActionButtonRenderer(&virtualGamepad->spellActionButton, &buttonArt) + , cancelButtonRenderer(&virtualGamepad->cancelButton, &buttonArt) { } + void LoadArt(); void Render(const Surface &out); + void UnloadArt(); private: VirtualDirectionPadRenderer directionPadRenderer; @@ -131,10 +133,14 @@ private: SecondaryActionButtonRenderer secondaryActionButtonRenderer; SpellActionButtonRenderer spellActionButtonRenderer; CancelButtonRenderer cancelButtonRenderer; + Art buttonArt; }; void DrawVirtualGamepad(const Surface &out); +void InitVirtualGamepadGFX(); +void FreeVirtualGamepadGFX(); + } // namespace devilution #endif diff --git a/Source/diablo.cpp b/Source/diablo.cpp index 7a5f04a6f..0b36d703a 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -20,6 +20,7 @@ #include "DiabloUI/diabloui.h" #include "controls/keymapper.hpp" #include "controls/touch/gamepad.h" +#include "controls/touch/renderers.h" #include "diablo.h" #include "doom.h" #include "drlg_l1.h" @@ -1055,6 +1056,9 @@ void LoadLvlGFX() void LoadAllGFX() { IncProgress(); +#if defined(VIRTUAL_GAMEPAD) && !defined(USE_SDL1) + InitVirtualGamepadGFX(); +#endif IncProgress(); InitObjectGFX(); IncProgress(); @@ -1519,6 +1523,9 @@ void FreeGameMem() FreeObjectGFX(); FreeMonsterSnd(); FreeTownerGFX(); +#if defined(VIRTUAL_GAMEPAD) && !defined(USE_SDL1) + FreeVirtualGamepadGFX(); +#endif } bool StartGame(bool bNewGame, bool bSinglePlayer) @@ -1853,6 +1860,9 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir) LoadAllGFX(); } else { IncProgress(); +#if defined(VIRTUAL_GAMEPAD) && !defined(USE_SDL1) + InitVirtualGamepadGFX(); +#endif IncProgress(); InitMissileGFX(gbIsHellfire); IncProgress();