diff --git a/Common/Render/DrawBuffer.cpp b/Common/Render/DrawBuffer.cpp index 427a81dacc..7b6345ba29 100644 --- a/Common/Render/DrawBuffer.cpp +++ b/Common/Render/DrawBuffer.cpp @@ -348,15 +348,19 @@ void DrawBuffer::DrawImageRotatedStretch(ImageID atlas_image, const Bounds &boun } } -void DrawBuffer::Circle(float xc, float yc, float radius, float thickness, int segments, float startAngle, uint32_t color, float u_mul) { - float angleDelta = PI * 2 / segments; +void DrawBuffer::CircleSegment(float xc, float yc, float radius, float thickness, int segments, float startAngle, float endAngle, uint32_t color, float u_mul) { + if (endAngle < startAngle) { + std::swap(endAngle, startAngle); + } + + float angleDelta = (endAngle - startAngle) / segments; float uDelta = 1.0f / segments; float t2 = thickness / 2.0f; float r1 = radius + t2; float r2 = radius - t2; for (int i = 0; i < segments + 1; i++) { - float angle1 = i * angleDelta; - float angle2 = (i + 1) * angleDelta; + float angle1 = startAngle + i * angleDelta; + float angle2 = startAngle + (i + 1) * angleDelta; float u1 = u_mul * i * uDelta; float u2 = u_mul * (i + 1) * uDelta; // TODO: get rid of one pair of cos/sin per loop, can reuse from last iteration @@ -372,6 +376,10 @@ void DrawBuffer::Circle(float xc, float yc, float radius, float thickness, int s } } +void DrawBuffer::Circle(float x, float y, float radius, float thickness, int segments, float startAngle, uint32_t color, float u_mul) { + CircleSegment(x, y, radius, thickness, segments, startAngle, startAngle + PI * 2.0, color, u_mul); +} + void DrawBuffer::FillCircle(float xc, float yc, float radius, int segments, uint32_t color) { float angleDelta = PI * 2 / segments; float uDelta = 1.0f / segments; diff --git a/Common/Render/DrawBuffer.h b/Common/Render/DrawBuffer.h index 378a43f7fe..45e39443c0 100644 --- a/Common/Render/DrawBuffer.h +++ b/Common/Render/DrawBuffer.h @@ -91,6 +91,7 @@ public: V(x, y, curZ_, color, u, v); } + void CircleSegment(float x, float y, float radius, float thickness, int segments, float startAngle, float endAngle, uint32_t color, float u_mul); void Circle(float x, float y, float radius, float thickness, int segments, float startAngle, uint32_t color, float u_mul); void FillCircle(float x, float y, float radius, int segments, uint32_t color); diff --git a/Common/UI/View.cpp b/Common/UI/View.cpp index 218198d36b..8e2736fc50 100644 --- a/Common/UI/View.cpp +++ b/Common/UI/View.cpp @@ -1013,10 +1013,13 @@ void RadioButton::Draw(UIContext &dc) { void ImageView::GetContentDimensions(const UIContext &dc, float &w, float &h) const { dc.Draw()->GetAtlas()->measureImage(atlasImage_, &w, &h); + w *= scale_; + h *= scale_; // TODO: involve sizemode } void ImageView::Draw(UIContext &dc) { + dc.Begin(); const AtlasImage *img = dc.Draw()->GetAtlas()->getImage(atlasImage_); if (img) { // TODO: involve sizemode diff --git a/Common/UI/View.h b/Common/UI/View.h index 09f5762ed4..b32ae57978 100644 --- a/Common/UI/View.h +++ b/Common/UI/View.h @@ -1096,11 +1096,13 @@ public: void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; void Draw(UIContext &dc) override; std::string DescribeText() const override { return text_; } + void SetScale(float s) { scale_ = s; } // Only used for measuring. private: std::string text_; ImageID atlasImage_; ImageSizeMode sizeMode_; + float scale_ = 1.0f; }; class ProgressBar : public InertView { diff --git a/UI/IAPScreen.cpp b/UI/IAPScreen.cpp index 46c115a0f6..f960a5a7dc 100644 --- a/UI/IAPScreen.cpp +++ b/UI/IAPScreen.cpp @@ -2,6 +2,7 @@ #include "UI/IAPScreen.h" #include "UI/OnScreenDisplay.h" +#include "UI/MiscScreens.h" #include "Common/System/System.h" #include "Common/Data/Text/I18n.h" #include "Common/System/OSD.h" @@ -22,7 +23,7 @@ void IAPScreen::CreateViews() { root_->Add(leftColumnItems); ViewGroup *appTitle = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); - appTitle->Add(new ImageView(ImageID("I_ICONGOLD"), "", IS_DEFAULT, new LinearLayoutParams(64, 64))); + appTitle->Add(new ShinyIcon(ImageID("I_ICONGOLD"), new LinearLayoutParams(64, 64))); appTitle->Add(new TextView("PPSSPP Gold", new LinearLayoutParams(1.0f, G_VCENTER))); leftColumnItems->Add(appTitle); diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 0bc8c58b7e..611db9ddb1 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -916,6 +916,8 @@ void CreditsScreen::CreateViews() { back->OnClick.Handle(this, &UIScreen::OnOK); root_->SetDefaultFocusView(back); + const bool gold = System_GetPropertyBool(SYSPROP_APP_GOLD); + // Really need to redo this whole layout with some linear layouts... int rightYOffset = 0; @@ -936,10 +938,11 @@ void CreditsScreen::CreateViews() { #if PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(IOS) root_->Add(new Button(cr->T("Share PPSSPP"), new AnchorLayoutParams(260, 64, NONE, NONE, 10, rightYOffset + 158, false)))->OnClick.Handle(this, &CreditsScreen::OnShare); #endif - if (System_GetPropertyBool(SYSPROP_APP_GOLD)) { - root_->Add(new ImageView(ImageID("I_ICONGOLD"), "", IS_DEFAULT, new AnchorLayoutParams(100, 64, 10, 10, NONE, NONE, false))); + + if (true || System_GetPropertyBool(SYSPROP_APP_GOLD)) { + root_->Add(new ShinyIcon(ImageID("I_ICONGOLD"), new AnchorLayoutParams(WRAP_CONTENT, WRAP_CONTENT, 10, 10, NONE, NONE, false)))->SetScale(1.5f); } else { - root_->Add(new ImageView(ImageID("I_ICON"), "", IS_DEFAULT, new AnchorLayoutParams(100, 64, 10, 10, NONE, NONE, false))); + root_->Add(new ImageView(ImageID("I_ICON"), "", IS_DEFAULT, new AnchorLayoutParams(WRAP_CONTENT, WRAP_CONTENT, 10, 10, NONE, NONE, false)))->SetScale(1.5f); } } @@ -1223,3 +1226,33 @@ void SettingInfoMessage::Draw(UIContext &dc) { std::string SettingInfoMessage::GetText() const { return (showing_ && text_) ? text_->GetText() : ""; } + +void ShinyIcon::Draw(UIContext &dc) { + static const float radius[6] = { 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f }; + static const float startAngle[6] = { 0.3f, 0.5f, 0.1f, 0.9f, 0.7f, 0.4f }; + static const float arcLength[6] = { 0.45f, 0.2f, 0.6f, 0.7f, 0.3f, 0.5f }; + static const float speed[6] = { 0.4f, -0.9f, 0.2f, -0.6f, 0.7f, -0.1f }; + + dc.BeginNoTex(); + + const double t = time_now_d(); + const int x = bounds_.centerX(); + const int y = bounds_.centerY(); + for (int i = 0; i < 6; i++) { + float radius = (i * 0.1f + 0.4f) * 1.3f; + float alpha = (5 - i) * (1.0f / 9.0f); + + float angle = fmod(startAngle[i] + t * speed[i] * 0.7f, 1.0) * 2 * PI; + dc.Draw()->CircleSegment(x, y, radius * bounds_.w, 4.0f, 64.0f, angle, angle + arcLength[i] * 2 * PI, colorAlpha(0xFF3EC5FF, alpha), 0.0f); + } + + dc.Flush(); + dc.Begin(); + + const AtlasImage *img = dc.Draw()->GetAtlas()->getImage(ImageID("I_DROP_SHADOW")); + float scale = bounds_.w / img->w; + dc.Draw()->DrawImage(ImageID("I_DROP_SHADOW"), bounds_.centerX(), bounds_.centerY(), scale * 1.7f, 0xFF3EC5FF, ALIGN_CENTER); + dc.Flush(); + + UI::ImageView::Draw(dc); +} diff --git a/UI/MiscScreens.h b/UI/MiscScreens.h index 6199580ee9..1f443c84f7 100644 --- a/UI/MiscScreens.h +++ b/UI/MiscScreens.h @@ -193,4 +193,10 @@ private: bool showing_ = false; }; +class ShinyIcon : public UI::ImageView { +public: + ShinyIcon(ImageID atlasImage, UI::LayoutParams *layoutParams = 0) : UI::ImageView(atlasImage, "", UI::IS_DEFAULT, layoutParams) {} + void Draw(UIContext &dc) override; +}; + uint32_t GetBackgroundColorWithAlpha(const UIContext &dc);