mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Merge pull request #14347 from unknownbrackets/ui-anim
UI: Add BG animation for recent games
This commit is contained in:
@@ -38,11 +38,6 @@ enum ChatPositions {
|
||||
CENTER_RIGHT = 7,
|
||||
};
|
||||
|
||||
enum class BackgroundAnimation {
|
||||
OFF = 0,
|
||||
FLOATING_SYMBOLS = 1,
|
||||
};
|
||||
|
||||
namespace http {
|
||||
class Download;
|
||||
class Downloader;
|
||||
|
||||
@@ -116,3 +116,9 @@ enum class UnthrottleMode {
|
||||
SKIP_DRAW = 1,
|
||||
SKIP_FLIP = 2,
|
||||
};
|
||||
|
||||
enum class BackgroundAnimation {
|
||||
OFF = 0,
|
||||
FLOATING_SYMBOLS = 1,
|
||||
RECENT_GAMES = 2,
|
||||
};
|
||||
|
||||
@@ -100,6 +100,14 @@ public:
|
||||
std::string GetTitle();
|
||||
void SetTitle(const std::string &newTitle);
|
||||
|
||||
GameInfoTex *GetBGPic() {
|
||||
if (pic0.texture)
|
||||
return &pic0;
|
||||
if (pic1.texture)
|
||||
return &pic1;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Hold this when reading or writing from the GameInfo.
|
||||
// Don't need to hold it when just passing around the pointer,
|
||||
// and obviously also not when creating it and holding the only pointer
|
||||
|
||||
@@ -875,7 +875,7 @@ void GameSettingsScreen::CreateViews() {
|
||||
if (backgroundChoice_ != nullptr) {
|
||||
backgroundChoice_->OnClick.Handle(this, &GameSettingsScreen::OnChangeBackground);
|
||||
}
|
||||
static const char *backgroundAnimations[] = { "No animation", "Floating Symbols" };
|
||||
static const char *backgroundAnimations[] = { "No animation", "Floating symbols", "Recent games" };
|
||||
systemSettings->Add(new PopupMultiChoice(&g_Config.iBackgroundAnimation, sy->T("UI background animation"), backgroundAnimations, 0, ARRAY_SIZE(backgroundAnimations), sy->GetName(), screenManager()));
|
||||
|
||||
systemSettings->Add(new ItemHeader(sy->T("Help the PPSSPP team")));
|
||||
|
||||
+2
-6
@@ -1309,12 +1309,8 @@ bool MainScreen::DrawBackgroundFor(UIContext &dc, const std::string &gamePath, f
|
||||
return false;
|
||||
}
|
||||
|
||||
Draw::Texture *texture = nullptr;
|
||||
if (ginfo->pic1.texture) {
|
||||
texture = ginfo->pic1.texture->GetTexture();
|
||||
} else if (ginfo->pic0.texture) {
|
||||
texture = ginfo->pic0.texture->GetTexture();
|
||||
}
|
||||
auto pic = ginfo->GetBGPic();
|
||||
Draw::Texture *texture = pic ? pic->texture->GetTexture() : nullptr;
|
||||
|
||||
uint32_t color = whiteAlpha(ease(progress)) & 0xFFc0c0c0;
|
||||
if (texture) {
|
||||
|
||||
+108
-23
@@ -85,17 +85,11 @@ public:
|
||||
void Draw(UIContext &dc, double t, float alpha) override {
|
||||
float xres = dc.GetBounds().w;
|
||||
float yres = dc.GetBounds().h;
|
||||
if (xbase[0] == 0.0f || last_xres != xres || last_yres != yres) {
|
||||
GMRng rng;
|
||||
for (int i = 0; i < 100; i++) {
|
||||
xbase[i] = rng.F() * xres;
|
||||
ybase[i] = rng.F() * yres;
|
||||
}
|
||||
last_xres = xres;
|
||||
last_yres = yres;
|
||||
if (last_xres != xres || last_yres != yres) {
|
||||
Regenerate(xres, yres);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
for (int i = 0; i < COUNT; i++) {
|
||||
float x = xbase[i] + dc.GetBounds().x;
|
||||
float y = ybase[i] + dc.GetBounds().y + 40 * cosf(i * 7.2f + t * 1.3f);
|
||||
float angle = (float)sin(i + t);
|
||||
@@ -103,11 +97,106 @@ public:
|
||||
ui_draw2d.DrawImageRotated(symbols[n], x, y, 1.0f, angle, colorAlpha(colors[n], alpha * 0.1f));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
float xbase[100] = { 0 };
|
||||
float ybase[100] = { 0 };
|
||||
static constexpr int COUNT = 100;
|
||||
|
||||
float xbase[COUNT]{};
|
||||
float ybase[COUNT]{};
|
||||
float last_xres = 0;
|
||||
float last_yres = 0;
|
||||
|
||||
void Regenerate(int xres, int yres) {
|
||||
GMRng rng;
|
||||
for (int i = 0; i < COUNT; i++) {
|
||||
xbase[i] = rng.F() * xres;
|
||||
ybase[i] = rng.F() * yres;
|
||||
}
|
||||
|
||||
last_xres = xres;
|
||||
last_yres = yres;
|
||||
}
|
||||
};
|
||||
|
||||
class RecentGamesAnimation : public Animation {
|
||||
public:
|
||||
~RecentGamesAnimation() override {}
|
||||
void Draw(UIContext &dc, double t, float alpha) override {
|
||||
if (lastIndex_ == nextIndex_) {
|
||||
CheckNext(dc, t);
|
||||
} else if (t > nextT_) {
|
||||
lastIndex_ = nextIndex_;
|
||||
}
|
||||
|
||||
if (!g_Config.recentIsos.empty()) {
|
||||
std::shared_ptr<GameInfo> lastInfo = GetInfo(dc, lastIndex_);
|
||||
std::shared_ptr<GameInfo> nextInfo = GetInfo(dc, nextIndex_);
|
||||
dc.Flush();
|
||||
|
||||
float lastAmount = Clamp((float)(nextT_ - t) * 1.0f / TRANSITION, 0.0f, 1.0f);
|
||||
DrawTex(dc, lastInfo, lastAmount * alpha * 0.2f);
|
||||
|
||||
float nextAmount = lastAmount <= 0.0f ? 1.0f : 1.0f - lastAmount;
|
||||
DrawTex(dc, nextInfo, nextAmount * alpha * 0.2f);
|
||||
|
||||
dc.RebindTexture();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void CheckNext(UIContext &dc, double t) {
|
||||
if (g_Config.recentIsos.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int index = lastIndex_ + 1; index != lastIndex_; ++index) {
|
||||
if (index < 0 || index >= (int)g_Config.recentIsos.size()) {
|
||||
if (lastIndex_ == -1)
|
||||
break;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
std::shared_ptr<GameInfo> ginfo = GetInfo(dc, index);
|
||||
if (ginfo && ginfo->pending) {
|
||||
// Wait for it to load. It might be the next one.
|
||||
break;
|
||||
}
|
||||
if (ginfo && (ginfo->pic1.texture || ginfo->pic0.texture)) {
|
||||
nextIndex_ = index;
|
||||
nextT_ = t + INTERVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
// Otherwise, keep going. This skips games with no BG.
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<GameInfo> GetInfo(UIContext &dc, int index) {
|
||||
if (index < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return g_gameInfoCache->GetInfo(dc.GetDrawContext(), g_Config.recentIsos[index], GAMEINFO_WANTBG);
|
||||
}
|
||||
|
||||
void DrawTex(UIContext &dc, std::shared_ptr<GameInfo> &ginfo, float amount) {
|
||||
if (!ginfo || amount <= 0.0f)
|
||||
return;
|
||||
GameInfoTex *pic = ginfo->GetBGPic();
|
||||
if (!pic)
|
||||
return;
|
||||
|
||||
dc.GetDrawContext()->BindTexture(0, pic->texture->GetTexture());
|
||||
uint32_t color = whiteAlpha(amount) & 0xFFc0c0c0;
|
||||
dc.Draw()->DrawTexRect(dc.GetBounds(), 0, 0, 1, 1, color);
|
||||
dc.Flush();
|
||||
}
|
||||
|
||||
static constexpr double INTERVAL = 8.0;
|
||||
static constexpr float TRANSITION = 3.0f;
|
||||
|
||||
int lastIndex_ = -1;
|
||||
int nextIndex_ = -1;
|
||||
double nextT_ = -INTERVAL;
|
||||
};
|
||||
|
||||
// TODO: Add more styles. Remember to add to the enum in Config.cpp and the selector in GameSettings too.
|
||||
@@ -137,6 +226,9 @@ void DrawBackground(UIContext &dc, float alpha) {
|
||||
case BackgroundAnimation::FLOATING_SYMBOLS:
|
||||
g_Animation.reset(new FloatingSymbolsAnimation());
|
||||
break;
|
||||
case BackgroundAnimation::RECENT_GAMES:
|
||||
g_Animation.reset(new RecentGamesAnimation());
|
||||
break;
|
||||
default:
|
||||
g_Animation.reset(nullptr);
|
||||
}
|
||||
@@ -177,19 +269,12 @@ void DrawGameBackground(UIContext &dc, const std::string &gamePath) {
|
||||
ginfo = g_gameInfoCache->GetInfo(dc.GetDrawContext(), gamePath, GAMEINFO_WANTBG);
|
||||
dc.Flush();
|
||||
|
||||
bool hasPic = false;
|
||||
double loadTime;
|
||||
if (ginfo && ginfo->pic1.texture) {
|
||||
dc.GetDrawContext()->BindTexture(0, ginfo->pic1.texture->GetTexture());
|
||||
loadTime = ginfo->pic1.timeLoaded;
|
||||
hasPic = true;
|
||||
} else if (ginfo && ginfo->pic0.texture) {
|
||||
dc.GetDrawContext()->BindTexture(0, ginfo->pic0.texture->GetTexture());
|
||||
loadTime = ginfo->pic0.timeLoaded;
|
||||
hasPic = true;
|
||||
GameInfoTex *pic = ginfo ? ginfo->GetBGPic() : nullptr;
|
||||
if (pic) {
|
||||
dc.GetDrawContext()->BindTexture(0, pic->texture->GetTexture());
|
||||
}
|
||||
if (hasPic) {
|
||||
uint32_t color = whiteAlpha(ease((time_now_d() - loadTime) * 3)) & 0xFFc0c0c0;
|
||||
if (pic) {
|
||||
uint32_t color = whiteAlpha(ease((time_now_d() - pic->timeLoaded) * 3)) & 0xFFc0c0c0;
|
||||
dc.Draw()->DrawTexRect(dc.GetBounds(), 0,0,1,1, color);
|
||||
dc.Flush();
|
||||
dc.RebindTexture();
|
||||
|
||||
+3
-5
@@ -236,11 +236,9 @@ void GameIconView::Draw(UIContext &dc) {
|
||||
|
||||
// Fade icon with the backgrounds.
|
||||
double loadTime = info->icon.timeLoaded;
|
||||
if (info->pic1.texture) {
|
||||
loadTime = std::max(loadTime, info->pic1.timeLoaded);
|
||||
}
|
||||
if (info->pic0.texture) {
|
||||
loadTime = std::max(loadTime, info->pic0.timeLoaded);
|
||||
auto pic = info->GetBGPic();
|
||||
if (pic) {
|
||||
loadTime = std::max(loadTime, pic->timeLoaded);
|
||||
}
|
||||
uint32_t color = whiteAlpha(ease((time_now_d() - loadTime) * 3));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user