You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
3.9 KiB
159 lines
3.9 KiB
#include <SDL.h> |
|
|
|
#include "DiabloUI/button.h" |
|
#include "DiabloUI/diabloui.h" |
|
#include "control.h" |
|
#include "controls/input.h" |
|
#include "controls/menu_controls.h" |
|
#include "engine/clx_sprite.hpp" |
|
#include "engine/dx.h" |
|
#include "engine/load_pcx.hpp" |
|
#include "engine/palette.h" |
|
#include "engine/render/clx_render.hpp" |
|
#include "hwcursor.hpp" |
|
#include "utils/display.h" |
|
#include "utils/is_of.hpp" |
|
#include "utils/language.h" |
|
|
|
namespace devilution { |
|
namespace { |
|
OptionalOwnedClxSpriteList ArtPopupSm; |
|
OptionalOwnedClxSpriteList ArtProgBG; |
|
OptionalOwnedClxSpriteList ProgFil; |
|
std::vector<std::unique_ptr<UiItemBase>> vecProgress; |
|
bool endMenu; |
|
|
|
void DialogActionCancel() |
|
{ |
|
endMenu = true; |
|
} |
|
|
|
void ProgressLoadBackground() |
|
{ |
|
UiLoadBlackBackground(); |
|
ArtPopupSm = LoadPcx("ui_art\\spopup"); |
|
ArtProgBG = LoadPcx("ui_art\\prog_bg"); |
|
} |
|
|
|
void ProgressLoadForeground() |
|
{ |
|
LoadDialogButtonGraphics(); |
|
ProgFil = LoadPcx("ui_art\\prog_fil"); |
|
|
|
const Point uiPosition = GetUIRectangle().position; |
|
SDL_Rect rect3 = { (Sint16)(uiPosition.x + 265), (Sint16)(uiPosition.y + 267), DialogButtonWidth, DialogButtonHeight }; |
|
vecProgress.push_back(std::make_unique<UiButton>(_("Cancel"), &DialogActionCancel, rect3)); |
|
} |
|
|
|
void ProgressFreeBackground() |
|
{ |
|
ArtBackground = std::nullopt; |
|
ArtPopupSm = std::nullopt; |
|
ArtProgBG = std::nullopt; |
|
} |
|
|
|
void ProgressFreeForeground() |
|
{ |
|
vecProgress.clear(); |
|
ProgFil = std::nullopt; |
|
FreeDialogButtonGraphics(); |
|
} |
|
|
|
Point GetPosition() |
|
{ |
|
return { GetCenterOffset(280), GetCenterOffset(144, gnScreenHeight) }; |
|
} |
|
|
|
void ProgressRenderBackground() |
|
{ |
|
SDL_FillRect(DiabloUiSurface(), nullptr, 0x000000); |
|
|
|
const Surface &out = Surface(DiabloUiSurface()); |
|
const Point position = GetPosition(); |
|
RenderClxSprite(out.subregion(position.x, position.y, 280, 140), (*ArtPopupSm)[0], { 0, 0 }); |
|
RenderClxSprite(out.subregion(GetCenterOffset(227), 0, 227, out.h()), (*ArtProgBG)[0], { 0, position.y + 52 }); |
|
} |
|
|
|
void ProgressRenderForeground(int progress) |
|
{ |
|
const Surface &out = Surface(DiabloUiSurface()); |
|
const Point position = GetPosition(); |
|
if (progress != 0) { |
|
const int x = GetCenterOffset(227); |
|
const int w = 227 * progress / 100; |
|
RenderClxSprite(out.subregion(x, 0, w, out.h()), (*ProgFil)[0], { 0, position.y + 52 }); |
|
} |
|
// Not rendering an actual button, only the top 2 rows of its graphics. |
|
RenderClxSprite( |
|
out.subregion(GetCenterOffset(110), position.y + 99, DialogButtonWidth, 2), |
|
ButtonSprite(/*pressed=*/false), { 0, 0 }); |
|
} |
|
|
|
} // namespace |
|
|
|
bool UiProgressDialog(int (*fnfunc)()) |
|
{ |
|
SetFadeLevel(256); |
|
|
|
// Blit the background once and then free it. |
|
ProgressLoadBackground(); |
|
|
|
ProgressRenderBackground(); |
|
|
|
if (RenderDirectlyToOutputSurface && PalSurface != nullptr) { |
|
// Render into all the backbuffers if there are multiple. |
|
const void *initialPixels = PalSurface->pixels; |
|
UiFadeIn(); |
|
while (PalSurface->pixels != initialPixels) { |
|
ProgressRenderBackground(); |
|
UiFadeIn(); |
|
} |
|
} |
|
|
|
ProgressFreeBackground(); |
|
|
|
ProgressLoadForeground(); |
|
|
|
endMenu = false; |
|
int progress = 0; |
|
|
|
SDL_Event event; |
|
while (!endMenu && progress < 100) { |
|
progress = fnfunc(); |
|
ProgressRenderForeground(progress); |
|
UiRenderItems(vecProgress); |
|
DrawMouse(); |
|
UiFadeIn(); |
|
|
|
while (PollEvent(&event) != 0) { |
|
switch (event.type) { |
|
case SDL_MOUSEBUTTONDOWN: |
|
case SDL_MOUSEBUTTONUP: |
|
UiItemMouseEvents(&event, vecProgress); |
|
break; |
|
#ifndef USE_SDL1 |
|
case SDLK_KP_ENTER: |
|
#endif |
|
case SDLK_ESCAPE: |
|
case SDLK_RETURN: |
|
case SDLK_SPACE: |
|
endMenu = true; |
|
break; |
|
default: |
|
for (MenuAction menuAction : GetMenuActions(event)) { |
|
if (IsNoneOf(menuAction, MenuAction_BACK, MenuAction_SELECT)) |
|
continue; |
|
endMenu = true; |
|
break; |
|
} |
|
break; |
|
} |
|
UiHandleEvents(&event); |
|
} |
|
} |
|
ProgressFreeForeground(); |
|
|
|
return progress == 100; |
|
} |
|
|
|
} // namespace devilution
|
|
|