|
|
|
|
#include "control.h"
|
|
|
|
|
#include "controls/plrctrls.h"
|
|
|
|
|
#include "controls/touch/renderers.h"
|
|
|
|
|
#include "cursor.h"
|
|
|
|
|
#include "doom.h"
|
|
|
|
|
#include "engine.h"
|
|
|
|
|
#include "gendung.h"
|
|
|
|
|
#include "inv.h"
|
|
|
|
|
#include "minitext.h"
|
|
|
|
|
#include "stores.h"
|
|
|
|
|
#include "towners.h"
|
|
|
|
|
|
|
|
|
|
namespace devilution {
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
VirtualGamepadRenderer Renderer(&VirtualGamepadState);
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
void DrawVirtualGamepad(const Surface &out)
|
|
|
|
|
{
|
|
|
|
|
Renderer.Render(out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VirtualGamepadRenderer::Render(const Surface &out)
|
|
|
|
|
{
|
|
|
|
|
directionPadRenderer.Render(out);
|
|
|
|
|
primaryActionButtonRenderer.Render(out);
|
|
|
|
|
secondaryActionButtonRenderer.Render(out);
|
|
|
|
|
spellActionButtonRenderer.Render(out);
|
|
|
|
|
cancelButtonRenderer.Render(out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VirtualDirectionPadRenderer::Render(const Surface &out)
|
|
|
|
|
{
|
|
|
|
|
RenderPad(out);
|
|
|
|
|
RenderKnob(out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VirtualDirectionPadRenderer::RenderPad(const Surface &out)
|
|
|
|
|
{
|
|
|
|
|
if (padSurface == nullptr)
|
|
|
|
|
padSurface.reset(LoadPNG("ui_art\\directions.png"));
|
|
|
|
|
|
|
|
|
|
auto center = virtualDirectionPad->area.position;
|
|
|
|
|
auto radius = virtualDirectionPad->area.radius;
|
|
|
|
|
int diameter = 2 * radius;
|
|
|
|
|
|
|
|
|
|
int x = center.x - radius;
|
|
|
|
|
int y = center.y - radius;
|
|
|
|
|
int width = diameter;
|
|
|
|
|
int height = diameter;
|
|
|
|
|
SDL_Rect rect { x, y, width, height };
|
|
|
|
|
SDL_BlitScaled(padSurface.get(), nullptr, out.surface, &rect);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VirtualDirectionPadRenderer::RenderKnob(const Surface &out)
|
|
|
|
|
{
|
|
|
|
|
if (knobSurface == nullptr)
|
|
|
|
|
knobSurface.reset(LoadPNG("ui_art\\directions2.png"));
|
|
|
|
|
|
|
|
|
|
auto center = virtualDirectionPad->position;
|
|
|
|
|
auto radius = virtualDirectionPad->area.radius / 3;
|
|
|
|
|
int diameter = 2 * radius;
|
|
|
|
|
|
|
|
|
|
int x = center.x - radius;
|
|
|
|
|
int y = center.y - radius;
|
|
|
|
|
int width = diameter;
|
|
|
|
|
int height = diameter;
|
|
|
|
|
SDL_Rect rect { x, y, width, height };
|
|
|
|
|
SDL_BlitScaled(knobSurface.get(), nullptr, out.surface, &rect);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VirtualPadButtonRenderer::Render(const Surface &out)
|
|
|
|
|
{
|
|
|
|
|
auto center = virtualPadButton->area.position;
|
|
|
|
|
auto radius = virtualPadButton->area.radius;
|
|
|
|
|
int diameter = 2 * radius;
|
|
|
|
|
|
|
|
|
|
int x = center.x - radius;
|
|
|
|
|
int y = center.y - radius;
|
|
|
|
|
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_Surface *PrimaryActionButtonRenderer::GetButtonSurface()
|
|
|
|
|
{
|
|
|
|
|
// NEED: Confirm surface
|
|
|
|
|
if (qtextflag)
|
|
|
|
|
return GetTalkSurface();
|
|
|
|
|
if (invflag)
|
|
|
|
|
return GetInventoryButtonSurface();
|
|
|
|
|
if (leveltype == DTYPE_TOWN)
|
|
|
|
|
return GetTownButtonSurface();
|
|
|
|
|
return GetDungeonButtonSurface();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SDL_Surface *PrimaryActionButtonRenderer::GetTownButtonSurface()
|
|
|
|
|
{
|
|
|
|
|
if (stextflag != STORE_NONE || pcursmonst != -1)
|
|
|
|
|
return GetTalkSurface();
|
|
|
|
|
return GetBlankSurface();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SDL_Surface *PrimaryActionButtonRenderer::GetDungeonButtonSurface()
|
|
|
|
|
{
|
|
|
|
|
if (pcursmonst != -1) {
|
|
|
|
|
const auto &monster = Monsters[pcursmonst];
|
|
|
|
|
if (M_Talker(monster) || monster.mtalkmsg != TEXT_NONE)
|
|
|
|
|
return GetTalkSurface();
|
|
|
|
|
}
|
|
|
|
|
return GetAttackSurface();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SDL_Surface *PrimaryActionButtonRenderer::GetInventoryButtonSurface()
|
|
|
|
|
{
|
|
|
|
|
if (pcursinvitem != -1 || pcurs > CURSOR_HAND)
|
|
|
|
|
return GetItemSurface();
|
|
|
|
|
return GetBlankSurface();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SDL_Surface *SecondaryActionButtonRenderer::GetButtonSurface()
|
|
|
|
|
{
|
|
|
|
|
// NEED: Stairs surface
|
|
|
|
|
if (InGameMenu() || QuestLogIsOpen || sbookflag)
|
|
|
|
|
return GetBlankSurface();
|
|
|
|
|
if (pcursobj != -1)
|
|
|
|
|
return GetObjectSurface();
|
|
|
|
|
if (pcursitem != -1)
|
|
|
|
|
return GetItemSurface();
|
|
|
|
|
return GetBlankSurface();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SDL_Surface *SpellActionButtonRenderer::GetButtonSurface()
|
|
|
|
|
{
|
|
|
|
|
if (!InGameMenu() && !QuestLogIsOpen && !sbookflag)
|
|
|
|
|
return GetCastSurface();
|
|
|
|
|
return GetBlankSurface();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SDL_Surface *CancelButtonRenderer::GetButtonSurface()
|
|
|
|
|
{
|
|
|
|
|
if (InGameMenu())
|
|
|
|
|
return GetCancelSurface();
|
|
|
|
|
if (DoomFlag || invflag || sbookflag || QuestLogIsOpen || chrflag)
|
|
|
|
|
return GetCancelSurface();
|
|
|
|
|
return GetBlankSurface();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace devilution
|