diff --git a/Core/RetroAchievements.cpp b/Core/RetroAchievements.cpp index 0675f64ea0..dc2ddff3f7 100644 --- a/Core/RetroAchievements.cpp +++ b/Core/RetroAchievements.cpp @@ -156,6 +156,7 @@ static void SubmitLeaderboard(u32 leaderboard_id, int value); static void DisplayAchievementSummary(); static void DisplayMasteredNotification(); static void SetChallengeMode(bool enabled); +static u32 GetGameID(); static Achievements::Statistics g_stats; @@ -185,6 +186,10 @@ bool ChallengeModeActive() { return g_challengeMode; } +bool IsActive() { + return GetGameID() != 0; +} + u32 GetGameID() { if (!g_rcClient) { return 0; diff --git a/Core/RetroAchievements.h b/Core/RetroAchievements.h index 5a27286748..3c495313e7 100644 --- a/Core/RetroAchievements.h +++ b/Core/RetroAchievements.h @@ -45,8 +45,12 @@ static inline bool IsUsingRAIntegration() #endif +// Returns true if the user is logged in properly, and everything is set up for playing games with achievements. bool IsLoggedIn(); +// Returns true if in a game, and achievements are active in the current game. +bool IsActive(); + /// Returns true if features such as save states should be disabled. bool ChallengeModeActive(); @@ -54,8 +58,6 @@ bool ChallengeModeActive(); // Will of course return nullptr if not active. rc_client_t *GetClient(); -u32 GetGameID(); - void Initialize(); void UpdateSettings(); diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index 0138c7b6a2..f92242b133 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -265,27 +265,13 @@ GamePauseScreen::~GamePauseScreen() { __DisplaySetWasPaused(); } -void GamePauseScreen::CreateViews() { +void GamePauseScreen::CreateSavestateControls(UI::LinearLayout *leftColumnItems, bool vertical) { + auto pa = GetI18NCategory(I18NCat::PAUSE); + static const int NUM_SAVESLOTS = 5; using namespace UI; - bool vertical = UseVerticalLayout(); - - Margins scrollMargins(0, 20, 0, 0); - Margins actionMenuMargins(0, 20, 15, 0); - auto gr = GetI18NCategory(I18NCat::GRAPHICS); - auto pa = GetI18NCategory(I18NCat::PAUSE); - - root_ = new LinearLayout(ORIENT_HORIZONTAL); - - ViewGroup *leftColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0, scrollMargins)); - root_->Add(leftColumn); - - LinearLayout *leftColumnItems = new LinearLayoutList(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT)); - leftColumn->Add(leftColumnItems); - - leftColumnItems->Add(new Spacer(0.0)); leftColumnItems->SetSpacing(10.0); for (int i = 0; i < NUM_SAVESLOTS; i++) { SaveSlotView *slot = leftColumnItems->Add(new SaveSlotView(gamePath_, i, vertical, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); @@ -311,6 +297,36 @@ void GamePauseScreen::CreateViews() { rewindButton->SetEnabled(SaveState::CanRewind()); rewindButton->OnClick.Handle(this, &GamePauseScreen::OnRewind); } +} + +void GamePauseScreen::CreateViews() { + using namespace UI; + + bool vertical = UseVerticalLayout(); + + Margins scrollMargins(0, 10, 0, 0); + Margins actionMenuMargins(0, 10, 15, 0); + auto gr = GetI18NCategory(I18NCat::GRAPHICS); + auto pa = GetI18NCategory(I18NCat::PAUSE); + auto ac = GetI18NCategory(I18NCat::ACHIEVEMENTS); + + root_ = new LinearLayout(ORIENT_HORIZONTAL); + + ViewGroup *leftColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0, scrollMargins)); + root_->Add(leftColumn); + + LinearLayout *leftColumnItems = new LinearLayoutList(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT)); + leftColumn->Add(leftColumnItems); + + leftColumnItems->Add(new Spacer(0.0)); + if (Achievements::IsActive()) { + leftColumnItems->Add(new GameAchievementSummaryView()); + leftColumnItems->Add(new Spacer(5.0)); + } + + if (!Achievements::ChallengeModeActive()) { + CreateSavestateControls(leftColumnItems, vertical); + } ViewGroup *rightColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(vertical ? 200 : 300, FILL_PARENT, actionMenuMargins)); root_->Add(rightColumn); diff --git a/UI/PauseScreen.h b/UI/PauseScreen.h index ed0dfced8d..830e7d0581 100644 --- a/UI/PauseScreen.h +++ b/UI/PauseScreen.h @@ -45,6 +45,8 @@ protected: void CallbackDeleteConfig(bool yes); private: + void CreateSavestateControls(UI::LinearLayout *viewGroup, bool vertical); + UI::EventReturn OnGameSettings(UI::EventParams &e); UI::EventReturn OnExitToMenu(UI::EventParams &e); UI::EventReturn OnReportFeedback(UI::EventParams &e); diff --git a/UI/RetroAchievementScreens.cpp b/UI/RetroAchievementScreens.cpp index 3a576ffe66..8df4fa2399 100644 --- a/UI/RetroAchievementScreens.cpp +++ b/UI/RetroAchievementScreens.cpp @@ -58,7 +58,7 @@ void RetroAchievementsListScreen::CreateAchievementsTab(UI::ViewGroup *achieveme achievements->Add(new ItemHeader(ac->T("Achievements"))); - achievements->Add(new GameAchievementSummaryView(Achievements::GetGameID())); + achievements->Add(new GameAchievementSummaryView()); achievements->Add(new ItemHeader(ac->T("Unlocked achievements"))); for (auto &achievement : unlockedAchievements) { @@ -80,7 +80,7 @@ void RetroAchievementsListScreen::CreateLeaderboardsTab(UI::ViewGroup *viewGroup using namespace UI; - viewGroup->Add(new GameAchievementSummaryView(Achievements::GetGameID())); + viewGroup->Add(new GameAchievementSummaryView()); viewGroup->Add(new ItemHeader(ac->T("Leaderboards"))); @@ -175,6 +175,8 @@ void RetroAchievementsLeaderboardScreen::update() { Poll(); } +RetroAchievementsSettingsScreen::~RetroAchievementsSettingsScreen() {} + void RetroAchievementsSettingsScreen::CreateTabs() { auto ac = GetI18NCategory(I18NCat::ACHIEVEMENTS); auto di = GetI18NCategory(I18NCat::DIALOG); @@ -265,13 +267,11 @@ void RetroAchievementsSettingsScreen::CreateSettingsTab(UI::ViewGroup *viewGroup RecreateViews(); return UI::EVENT_DONE; }); + viewGroup->Add(new CheckBox(&g_Config.bAchievementsChallengeMode, ac->T("Challenge Mode (no savestates)"))); viewGroup->Add(new CheckBox(&g_Config.bAchievementsRichPresence, ac->T("Rich Presence")))->SetEnabledPtr(&g_Config.bAchievementsEnable); viewGroup->Add(new CheckBox(&g_Config.bAchievementsSoundEffects, ac->T("Sound Effects")))->SetEnabledPtr(&g_Config.bAchievementsEnable); // not yet implemented viewGroup->Add(new CheckBox(&g_Config.bAchievementsLogBadMemReads, ac->T("Log bad memory accesses")))->SetEnabledPtr(&g_Config.bAchievementsEnable); - // Not yet fully implemented - // viewGroup->Add(new CheckBox(&g_Config.bAchievementsChallengeMode, ac->T("Challenge Mode (no savestates)"))); - // TODO: What are these for? // viewGroup->Add(new CheckBox(&g_Config.bAchievementsTestMode, ac->T("Test Mode"))); // viewGroup->Add(new CheckBox(&g_Config.bAchievementsUnofficialTestMode, ac->T("Unofficial Test Mode"))); @@ -289,9 +289,12 @@ void MeasureAchievement(const UIContext &dc, const rc_client_achievement_t *achi } } -void MeasureGameAchievementSummary(const UIContext &dc, int gameID, float *w, float *h) { +void MeasureGameAchievementSummary(const UIContext &dc, float *w, float *h) { *w = 0.0f; *h = 72.0f; + if (Achievements::ChallengeModeActive()) { + *h += 20.0f; + } } void MeasureLeaderboardSummary(const UIContext &dc, const rc_client_leaderboard_t *leaderboard, float *w, float *h) { @@ -358,11 +361,11 @@ void RenderAchievement(UIContext &dc, const rc_client_achievement_t *achievement dc.RebindTexture(); } -void RenderGameAchievementSummary(UIContext &dc, int gameID, const Bounds &bounds, float alpha) { +void RenderGameAchievementSummary(UIContext &dc, const Bounds &bounds, float alpha) { using namespace UI; UI::Drawable background = dc.theme->itemStyle.background; - background.color = colorAlpha(background.color, alpha); + background.color = alphaMul(background.color, alpha); uint32_t fgColor = colorAlpha(dc.theme->itemStyle.fgColor, alpha); float iconSpace = 64.0f; @@ -499,11 +502,11 @@ void AchievementView::Click() { } void GameAchievementSummaryView::Draw(UIContext &dc) { - RenderGameAchievementSummary(dc, gameID_, bounds_, 1.0f); + RenderGameAchievementSummary(dc, bounds_, 1.0f); } void GameAchievementSummaryView::GetContentDimensions(const UIContext &dc, float &w, float &h) const { - MeasureGameAchievementSummary(dc, gameID_, &w, &h); + MeasureGameAchievementSummary(dc, &w, &h); } void LeaderboardSummaryView::Draw(UIContext &dc) { diff --git a/UI/RetroAchievementScreens.h b/UI/RetroAchievementScreens.h index 7f45931ecd..63309afd80 100644 --- a/UI/RetroAchievementScreens.h +++ b/UI/RetroAchievementScreens.h @@ -31,6 +31,7 @@ private: class RetroAchievementsSettingsScreen : public TabbedUIDialogScreenWithGameBackground { public: RetroAchievementsSettingsScreen(const Path &gamePath) : TabbedUIDialogScreenWithGameBackground(gamePath) {} + ~RetroAchievementsSettingsScreen(); const char *tag() const override { return "RetroAchievementsSettingsScreen"; } void CreateTabs() override; @@ -85,15 +86,17 @@ enum class AchievementRenderStyle { void MeasureAchievement(const UIContext &dc, const rc_client_achievement_t *achievement, AchievementRenderStyle style, float *w, float *h); void RenderAchievement(UIContext &dc, const rc_client_achievement_t *achievement, AchievementRenderStyle style, const Bounds &bounds, float alpha, float startTime, float time_s); -void MeasureGameAchievementSummary(const UIContext &dc, int gameID, float *w, float *h); -void RenderGameAchievementSummary(UIContext &dc, int gameID, const Bounds &bounds, float alpha); +void MeasureGameAchievementSummary(const UIContext &dc, float *w, float *h); +void RenderGameAchievementSummary(UIContext &dc, const Bounds &bounds, float alpha); void MeasureLeaderboardEntry(const UIContext &dc, const rc_client_leaderboard_entry_t *entry, float *w, float *h); void RenderLeaderboardEntry(UIContext &dc, const rc_client_leaderboard_entry_t *entry, const Bounds &bounds, float alpha); class AchievementView : public UI::ClickableItem { public: - AchievementView(const rc_client_achievement_t *achievement, UI::LayoutParams *layoutParams = nullptr) : UI::ClickableItem(layoutParams), achievement_(achievement) {} + AchievementView(const rc_client_achievement_t *achievement, UI::LayoutParams *layoutParams = nullptr) : UI::ClickableItem(layoutParams), achievement_(achievement) { + layoutParams_->height = UI::WRAP_CONTENT; // Override the standard Item fixed height. + } void Click() override; void Draw(UIContext &dc) override; @@ -104,17 +107,19 @@ private: class GameAchievementSummaryView : public UI::Item { public: - GameAchievementSummaryView(int gameID, UI::LayoutParams *layoutParams = nullptr) : UI::Item(layoutParams), gameID_(gameID) {} + GameAchievementSummaryView(UI::LayoutParams *layoutParams = nullptr) : UI::Item(layoutParams) { + layoutParams_->height = UI::WRAP_CONTENT; // Override the standard Item fixed height. + } void Draw(UIContext &dc) override; void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; -private: - int gameID_; }; class LeaderboardSummaryView : public UI::ClickableItem { public: - LeaderboardSummaryView(const rc_client_leaderboard_t *leaderboard, UI::LayoutParams *layoutParams = nullptr) : UI::ClickableItem(layoutParams), leaderboard_(leaderboard) {} + LeaderboardSummaryView(const rc_client_leaderboard_t *leaderboard, UI::LayoutParams *layoutParams = nullptr) : UI::ClickableItem(layoutParams), leaderboard_(leaderboard) { + layoutParams_->height = UI::WRAP_CONTENT; // Override the standard Item fixed height. + } void Draw(UIContext &dc) override; void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; @@ -125,7 +130,10 @@ private: class LeaderboardEntryView : public UI::Item { public: - LeaderboardEntryView(const rc_client_leaderboard_entry_t *entry, bool isCurrentUser, UI::LayoutParams *layoutParams = nullptr) : UI::Item(layoutParams), entry_(entry), isCurrentUser_(isCurrentUser) {} + LeaderboardEntryView(const rc_client_leaderboard_entry_t *entry, bool isCurrentUser, UI::LayoutParams *layoutParams = nullptr) + : UI::Item(layoutParams), entry_(entry), isCurrentUser_(isCurrentUser) { + layoutParams_->height = UI::WRAP_CONTENT; // Override the standard Item fixed height. + } void Draw(UIContext &dc) override; void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; diff --git a/assets/lang/en_US.ini b/assets/lang/en_US.ini index 93180ad81c..b073a196d2 100644 --- a/assets/lang/en_US.ini +++ b/assets/lang/en_US.ini @@ -37,6 +37,8 @@ Links = Links Locked achievements = Locked achievements Log bad memory accesses = Log bad memory accesses Mastered %1 = Mastered %1 +Not available in Challenge Mode = Not available in Challenge Mode +Save states not available in Challenge Mode = Save states not available in Challenge Mode Register on www.retroachievements.org = Register on www.retroachievements.org RetroAchievements are not available for this game = RetroAchievements are not available for this game RetroAchievements website = RetroAchievements website