Browse Source

Add buttons for using potions from belt

pull/2949/head
staphen 5 years ago committed by Anders Jenbo
parent
commit
b8950877c5
  1. 10
      Source/controls/game_controls.cpp
  2. 6
      Source/controls/touch/event_handlers.cpp
  3. 6
      Source/controls/touch/event_handlers.h
  4. 10
      Source/controls/touch/gamepad.cpp
  5. 4
      Source/controls/touch/gamepad.h
  6. 154
      Source/controls/touch/renderers.cpp
  7. 36
      Source/controls/touch/renderers.h

10
Source/controls/game_controls.cpp

@ -126,6 +126,16 @@ bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrlEvent, Game
*action = GameActionSendKey { DVL_VK_SPACE, false };
return true;
}
if (VirtualGamepadState.healthButton.isHeld && VirtualGamepadState.healthButton.didStateChange) {
if (!QuestLogIsOpen && !sbookflag && stextflag == STORE_NONE)
*action = GameAction(GameActionType_USE_HEALTH_POTION);
return true;
}
if (VirtualGamepadState.manaButton.isHeld && VirtualGamepadState.manaButton.didStateChange) {
if (!QuestLogIsOpen && !sbookflag && stextflag == STORE_NONE)
*action = GameAction(GameActionType_USE_MANA_POTION);
return true;
}
}
#endif

6
Source/controls/touch/event_handlers.cpp

@ -125,6 +125,12 @@ bool VirtualGamepadEventHandler::Handle(const SDL_Event &event)
if (cancelButtonEventHandler.Handle(event))
return true;
if (healthButtonEventHandler.Handle(event))
return true;
if (manaButtonEventHandler.Handle(event))
return true;
return false;
}

6
Source/controls/touch/event_handlers.h

@ -58,6 +58,8 @@ public:
, secondaryActionButtonEventHandler(&virtualGamepad->secondaryActionButton)
, spellActionButtonEventHandler(&virtualGamepad->spellActionButton)
, cancelButtonEventHandler(&virtualGamepad->cancelButton)
, healthButtonEventHandler(&virtualGamepad->healthButton)
, manaButtonEventHandler(&virtualGamepad->manaButton)
{
}
@ -65,10 +67,14 @@ public:
private:
VirtualDirectionPadEventHandler directionPadEventHandler;
VirtualPadButtonEventHandler primaryActionButtonEventHandler;
VirtualPadButtonEventHandler secondaryActionButtonEventHandler;
VirtualPadButtonEventHandler spellActionButtonEventHandler;
VirtualPadButtonEventHandler cancelButtonEventHandler;
VirtualPadButtonEventHandler healthButtonEventHandler;
VirtualPadButtonEventHandler manaButtonEventHandler;
};
void HandleTouchEvent(const SDL_Event &event);

10
Source/controls/touch/gamepad.cpp

@ -102,6 +102,16 @@ void InitializeVirtualGamepad()
cancelButton.area.position.x = (padButtonLeft + padButtonRight) / 2;
cancelButton.area.position.y = padButtonBottom;
cancelButton.area.radius = padButtonSize / 2;
VirtualPadButton &healthButton = VirtualGamepadState.healthButton;
healthButton.area.position.x = padButtonRight - padButtonSize - padButtonSpacing;
healthButton.area.position.y = padButtonTop - padButtonSize - padButtonSpacing;
healthButton.area.radius = padButtonSize / 2;
VirtualPadButton &manaButton = VirtualGamepadState.manaButton;
manaButton.area.position.x = padButtonRight;
manaButton.area.position.y = padButtonTop - padButtonSize - padButtonSpacing;
manaButton.area.radius = padButtonSize / 2;
}
void VirtualDirectionPad::UpdatePosition(Point touchCoordinates)

4
Source/controls/touch/gamepad.h

@ -44,11 +44,15 @@ struct VirtualPadButton {
struct VirtualGamepad {
VirtualDirectionPad directionPad;
VirtualPadButton primaryActionButton;
VirtualPadButton secondaryActionButton;
VirtualPadButton spellActionButton;
VirtualPadButton cancelButton;
VirtualPadButton healthButton;
VirtualPadButton manaButton;
VirtualGamepad()
{
}

154
Source/controls/touch/renderers.cpp

@ -1,15 +1,17 @@
#include "control.h"
#include "controls/plrctrls.h"
#include "controls/touch/renderers.h"
#include "cursor.h"
#include "doom.h"
#include "engine.h"
#include "engine/render/cel_render.hpp"
#include "gendung.h"
#include "init.h"
#include "inv.h"
#include "minitext.h"
#include "stores.h"
#include "towners.h"
#include "utils/sdl_compat.h"
#include "utils/sdl_wrap.h"
namespace devilution {
@ -52,6 +54,75 @@ VirtualGamepadButtonType GetBlankButtonType(bool isPressed)
return isPressed ? GAMEPAD_BLANKDOWN : GAMEPAD_BLANK;
}
void LoadButtonArt(Art *buttonArt, SDL_Renderer *renderer)
{
const int Frames = 14;
buttonArt->surface.reset(LoadPNG("ui_art\\button.png"));
if (buttonArt->surface == nullptr)
return;
buttonArt->logical_width = buttonArt->surface->w;
buttonArt->frame_height = buttonArt->surface->h / Frames;
buttonArt->frames = Frames;
if (renderer != nullptr) {
buttonArt->texture.reset(SDL_CreateTextureFromSurface(renderer, buttonArt->surface.get()));
buttonArt->surface = nullptr;
}
}
void LoadPotionArt(Art *potionArt, SDL_Renderer *renderer)
{
item_cursor_graphic potionGraphics[] {
ICURS_POTION_OF_HEALING,
ICURS_POTION_OF_MANA,
ICURS_POTION_OF_REJUVENATION,
ICURS_POTION_OF_FULL_HEALING,
ICURS_POTION_OF_FULL_MANA,
ICURS_POTION_OF_FULL_REJUVENATION,
ICURS_SCROLL_OF
};
int potionFrame = CURSOR_FIRSTITEM + ICURS_POTION_OF_HEALING;
Size potionSize = GetInvItemSize(potionFrame);
auto surface = SDLWrap::CreateRGBSurfaceWithFormat(
/*flags=*/0,
/*width=*/potionSize.width,
/*height=*/potionSize.height * sizeof(potionGraphics),
/*depth=*/8,
SDL_PIXELFORMAT_INDEX8);
auto palette = SDLWrap::AllocPalette();
if (SDLC_SetSurfaceAndPaletteColors(surface.get(), palette.get(), orig_palette, 0, 256) < 0)
ErrSdl();
Uint32 bgColor = SDL_MapRGB(surface->format, orig_palette[1].r, orig_palette[1].g, orig_palette[1].b);
if (SDL_FillRect(surface.get(), nullptr, bgColor) < 0)
ErrSdl();
if (SDL_SetColorKey(surface.get(), SDL_TRUE, bgColor) < 0)
ErrSdl();
Point position { 0, 0 };
for (item_cursor_graphic graphic : potionGraphics) {
const int frame = CURSOR_FIRSTITEM + graphic;
const CelSprite &potionSprite = GetInvItemSprite(frame);
position.y += potionSize.height;
CelClippedDrawTo(Surface(surface.get()), position, potionSprite, frame);
}
potionArt->logical_width = potionSize.width;
potionArt->frame_height = potionSize.height;
potionArt->frames = sizeof(potionGraphics);
if (renderer == nullptr) {
potionArt->surface.reset(SDL_ConvertSurfaceFormat(surface.get(), SDL_PIXELFORMAT_ARGB8888, 0));
} else {
potionArt->texture.reset(SDL_CreateTextureFromSurface(renderer, surface.get()));
potionArt->surface = nullptr;
}
}
} // namespace
void RenderVirtualGamepad(SDL_Renderer *renderer)
@ -83,20 +154,8 @@ void RenderVirtualGamepad(SDL_Surface *surface)
void VirtualGamepadRenderer::LoadArt(SDL_Renderer *renderer)
{
directionPadRenderer.LoadArt(renderer);
const int Frames = 14;
buttonArt.surface.reset(LoadPNG("ui_art\\button.png"));
if (buttonArt.surface == nullptr)
return;
buttonArt.logical_width = buttonArt.surface->w;
buttonArt.frame_height = buttonArt.surface->h / Frames;
buttonArt.frames = Frames;
if (renderer != nullptr) {
buttonArt.texture.reset(SDL_CreateTextureFromSurface(renderer, buttonArt.surface.get()));
buttonArt.surface = nullptr;
}
LoadButtonArt(&buttonArt, renderer);
LoadPotionArt(&potionArt, renderer);
}
void VirtualDirectionPadRenderer::LoadArt(SDL_Renderer *renderer)
@ -119,10 +178,16 @@ void VirtualGamepadRenderer::Render(RenderFunction renderFunction)
return;
directionPadRenderer.Render(renderFunction);
primaryActionButtonRenderer.Render(renderFunction, buttonArt);
secondaryActionButtonRenderer.Render(renderFunction, buttonArt);
spellActionButtonRenderer.Render(renderFunction, buttonArt);
cancelButtonRenderer.Render(renderFunction, buttonArt);
healthButtonRenderer.Render(renderFunction, buttonArt);
manaButtonRenderer.Render(renderFunction, buttonArt);
healthButtonRenderer.RenderPotion(renderFunction, potionArt);
manaButtonRenderer.RenderPotion(renderFunction, potionArt);
}
void VirtualDirectionPadRenderer::Render(RenderFunction renderFunction)
@ -179,6 +244,59 @@ void VirtualPadButtonRenderer::Render(RenderFunction renderFunction, Art &button
renderFunction(buttonArt, &src, &dst);
}
void PotionButtonRenderer::RenderPotion(RenderFunction renderFunction, Art &potionArt)
{
VirtualGamepadPotionType potionType = GetPotionType();
int frame = potionType;
int offset = potionArt.h() * frame;
auto center = virtualPadButton->area.position;
auto radius = virtualPadButton->area.radius * 8 / 10;
int diameter = 2 * radius;
int x = center.x - radius;
int y = center.y - radius;
int width = diameter;
int height = diameter;
SDL_Rect src { 0, offset, potionArt.w(), potionArt.h() };
SDL_Rect dst { x, y, width, height };
renderFunction(potionArt, &src, &dst);
}
VirtualGamepadPotionType PotionButtonRenderer::GetPotionType()
{
for (int i = 0; i < MAXBELTITEMS; i++) {
auto &myPlayer = Players[MyPlayerId];
const int id = AllItemsList[myPlayer.SpdList[i].IDidx].iMiscId;
const int spellId = AllItemsList[myPlayer.SpdList[i].IDidx].iSpell;
if (myPlayer.SpdList[i].isEmpty())
continue;
if (potionType == BLT_HEALING) {
if (id == IMISC_HEAL)
return GAMEPAD_HEALING;
if (id == IMISC_FULLHEAL)
return GAMEPAD_FULL_HEALING;
if (id == IMISC_SCROLL && spellId == SPL_HEAL)
return GAMEPAD_SCROLL_OF_HEALING;
}
if (potionType == BLT_MANA) {
if (id == IMISC_MANA)
return GAMEPAD_MANA;
if (id == IMISC_FULLMANA)
return GAMEPAD_FULL_MANA;
}
if (id == IMISC_REJUV)
return GAMEPAD_REJUVENATION;
if (id == IMISC_FULLREJUV)
return GAMEPAD_FULL_REJUVENATION;
}
}
VirtualGamepadButtonType PrimaryActionButtonRenderer::GetButtonType()
{
// NEED: Confirm surface
@ -243,10 +361,16 @@ VirtualGamepadButtonType CancelButtonRenderer::GetButtonType()
return GetBlankButtonType(virtualPadButton->isHeld);
}
VirtualGamepadButtonType PotionButtonRenderer::GetButtonType()
{
return GetBlankButtonType(virtualPadButton->isHeld);
}
void VirtualGamepadRenderer::UnloadArt()
{
directionPadRenderer.UnloadArt();
buttonArt.Unload();
potionArt.Unload();
}
void VirtualDirectionPadRenderer::UnloadArt()

36
Source/controls/touch/renderers.h

@ -2,6 +2,7 @@
#if defined(VIRTUAL_GAMEPAD) && !defined(USE_SDL1)
#include "controls/plrctrls.h"
#include "controls/touch/gamepad.h"
#include "engine/surface.hpp"
#include "utils/png.h"
@ -26,6 +27,16 @@ enum VirtualGamepadButtonType {
GAMEPAD_BLANKDOWN,
};
enum VirtualGamepadPotionType {
GAMEPAD_HEALING,
GAMEPAD_MANA,
GAMEPAD_REJUVENATION,
GAMEPAD_FULL_HEALING,
GAMEPAD_FULL_MANA,
GAMEPAD_FULL_REJUVENATION,
GAMEPAD_SCROLL_OF_HEALING,
};
typedef std::function<void(Art &art, SDL_Rect *src, SDL_Rect *dst)> RenderFunction;
class VirtualDirectionPadRenderer {
@ -110,6 +121,23 @@ private:
VirtualGamepadButtonType GetButtonType();
};
class PotionButtonRenderer : public VirtualPadButtonRenderer {
public:
PotionButtonRenderer(VirtualPadButton *potionButton, belt_item_type potionType)
: VirtualPadButtonRenderer(potionButton)
, potionType(potionType)
{
}
void RenderPotion(RenderFunction renderFunction, Art &potionArt);
private:
belt_item_type potionType;
VirtualGamepadButtonType GetButtonType();
VirtualGamepadPotionType GetPotionType();
};
class VirtualGamepadRenderer {
public:
VirtualGamepadRenderer(VirtualGamepad *virtualGamepad)
@ -118,6 +146,8 @@ public:
, secondaryActionButtonRenderer(&virtualGamepad->secondaryActionButton)
, spellActionButtonRenderer(&virtualGamepad->spellActionButton)
, cancelButtonRenderer(&virtualGamepad->cancelButton)
, healthButtonRenderer(&virtualGamepad->healthButton, BLT_HEALING)
, manaButtonRenderer(&virtualGamepad->manaButton, BLT_MANA)
{
}
@ -127,11 +157,17 @@ public:
private:
VirtualDirectionPadRenderer directionPadRenderer;
PrimaryActionButtonRenderer primaryActionButtonRenderer;
SecondaryActionButtonRenderer secondaryActionButtonRenderer;
SpellActionButtonRenderer spellActionButtonRenderer;
CancelButtonRenderer cancelButtonRenderer;
PotionButtonRenderer healthButtonRenderer;
PotionButtonRenderer manaButtonRenderer;
Art buttonArt;
Art potionArt;
};
void InitVirtualGamepadGFX(SDL_Renderer *renderer);

Loading…
Cancel
Save