|
|
|
|
@ -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() |
|
|
|
|
|