mirror of
https://github.com/PCSX2/pcsx2.git
synced 2025-12-16 04:08:48 +00:00
FSUI: Add custom RetroAchievements login dialog
FSUI: Add custom RetroAchievements login dialog Signed-off-by: SternXD <stern@sidestore.io>
This commit is contained in:
parent
b87b8eb7bb
commit
b27846ce39
106
bin/resources/icons/ra-icon.svg
Normal file
106
bin/resources/icons/ra-icon.svg
Normal file
@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
height="275"
|
||||
width="570"
|
||||
version="1.1"
|
||||
viewBox="0 0 150.81249 72.760419"
|
||||
id="svg4"
|
||||
sodipodi:docname="RetroAchievements_logo_square.svg"
|
||||
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
|
||||
inkscape:export-filename="RetroAchievements_logo_square.png"
|
||||
inkscape:export-xdpi="960"
|
||||
inkscape:export-ydpi="960"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
id="linearGradient6"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#ca9800;stop-opacity:1;"
|
||||
offset="0.5"
|
||||
id="stop6" />
|
||||
<stop
|
||||
style="stop-color:#ffe080;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop7" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#87b6f8;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4" />
|
||||
<stop
|
||||
style="stop-color:#0f65dd;stop-opacity:1;"
|
||||
offset="0.50065017"
|
||||
id="stop5" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4"
|
||||
id="linearGradient5"
|
||||
x1="229.8"
|
||||
y1="-556.42499"
|
||||
x2="229.8"
|
||||
y2="-531.58502"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient6"
|
||||
id="linearGradient7"
|
||||
x1="257.58826"
|
||||
y1="-529.96503"
|
||||
x2="257.58826"
|
||||
y2="-558.04498"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-0.66412404)" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="namedview4"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:document-units="mm"
|
||||
showguides="true"
|
||||
inkscape:zoom="0.54074219"
|
||||
inkscape:cx="213.59532"
|
||||
inkscape:cy="218.21859"
|
||||
inkscape:window-width="1536"
|
||||
inkscape:window-height="898"
|
||||
inkscape:window-x="-6"
|
||||
inkscape:window-y="-6"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4" />
|
||||
<g
|
||||
transform="matrix(5.6312119,0,0,5.6312119,-392.00615,-696.01846)"
|
||||
id="g4">
|
||||
<g
|
||||
transform="matrix(0.35278,0,0,-0.35278,-4.3083,326.78)"
|
||||
id="g3">
|
||||
<g
|
||||
aria-label="RA"
|
||||
style="font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal"
|
||||
transform="matrix(1.1293,0,0,-1.1092,-28.246,-45.784)"
|
||||
id="g2">
|
||||
<path
|
||||
style="font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;fill:url(#linearGradient5)"
|
||||
d="m 217.38,-553.59 h 11.73 q 1.89,0 3.12,1.14 1.26,1.14 1.26,3.45 0,0.99 -0.33,1.86 -0.33,0.84 -0.93,1.47 -0.57,0.63 -1.38,0.99 -0.81,0.36 -1.74,0.36 h -0.99 l 8.55,15.03 h -4.29 l -5.94,-10.29 v 10.29 h -3.99 v -19.17 h 6.51 q 0.24,0 0.36,-0.18 0.15,-0.18 0.15,-0.39 0,-0.21 -0.15,-0.36 -0.12,-0.18 -0.36,-0.18 h -7.59 v 20.28 h -3.99 z m 12.66,10.26 q 0.87,-0.06 1.68,-0.51 0.84,-0.45 1.47,-1.2 0.63,-0.75 1.02,-1.74 0.39,-1.02 0.39,-2.22 0,-1.23 -0.39,-2.28 -0.39,-1.05 -1.11,-1.8 -0.72,-0.75 -1.74,-1.17 -0.99,-0.42 -2.25,-0.42 h -11.73 v -4.05 h 11.73 q 1.98,0 3.72,0.75 1.74,0.75 3.03,2.07 1.29,1.32 2.01,3.09 0.75,1.77 0.75,3.81 0,2.58 -0.87,4.47 -0.87,1.86 -2.37,3 l 6.84,12.24 h -4.08 z"
|
||||
id="path1" />
|
||||
<path
|
||||
style="font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;fill:url(#linearGradient7)"
|
||||
d="m 253.50413,-532.8 h 12.45 l -7.62,-21.15 q -0.09,-0.3 -0.54,-0.54 -0.45,-0.24 -0.87,-0.24 -0.48,0 -0.9,0.24 -0.39,0.24 -0.48,0.54 l -8.67,24.66 h -3.99 l 9.27,-26.16 q 0.21,-0.63 0.6,-1.2 0.39,-0.6 0.96,-1.05 0.6,-0.48 1.38,-0.75 0.81,-0.27 1.83,-0.27 1.02,0 1.8,0.27 0.78,0.27 1.35,0.75 0.6,0.45 0.99,1.05 0.39,0.57 0.63,1.2 l 9.27,26.16 h -17.46 z m 0,-1.08 v -1.14 l -1.92,5.73 h -3.63 l 8.25,-23.91 q 0.06,-0.18 0.27,-0.3 0.24,-0.15 0.45,-0.15 0.21,0 0.45,0.15 0.24,0.12 0.3,0.3 l 6.84,19.32 z m 3.42,-11.13 -2.4,7.56 h 4.89 z"
|
||||
id="path2" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
@ -255,6 +255,13 @@ namespace FullscreenUI
|
||||
static bool s_was_paused_on_quick_menu_open = false;
|
||||
static bool s_about_window_open = false;
|
||||
|
||||
// achievements login dialog state
|
||||
static bool s_achievements_login_open = false;
|
||||
static bool s_achievements_login_logging_in = false;
|
||||
static char s_achievements_login_username[256] = {};
|
||||
static char s_achievements_login_password[256] = {};
|
||||
static Achievements::LoginRequestReason s_achievements_login_reason = Achievements::LoginRequestReason::UserInitiated;
|
||||
|
||||
// local copies of the currently-running game
|
||||
static std::string s_current_game_title;
|
||||
static std::string s_current_game_subtitle;
|
||||
@ -493,6 +500,7 @@ namespace FullscreenUI
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
static void SwitchToAchievementsWindow();
|
||||
static void SwitchToLeaderboardsWindow();
|
||||
static void DrawAchievementsLoginWindow();
|
||||
} // namespace FullscreenUI
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -1034,6 +1042,9 @@ void FullscreenUI::Render()
|
||||
if (s_about_window_open)
|
||||
DrawAboutWindow();
|
||||
|
||||
if (s_achievements_login_open)
|
||||
DrawAchievementsLoginWindow();
|
||||
|
||||
if (s_input_binding_type != InputBindingInfo::Type::Unknown)
|
||||
DrawInputBindingWindow();
|
||||
|
||||
@ -7207,6 +7218,229 @@ bool FullscreenUI::OpenAchievementsWindow()
|
||||
return true;
|
||||
}
|
||||
|
||||
void FullscreenUI::DrawAchievementsLoginWindow()
|
||||
{
|
||||
ImGui::SetNextWindowSize(LayoutScale(400.0f, 330.0f));
|
||||
ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, LayoutScale(12.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(24.0f, 24.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImVec4(0.13f, 0.13f, 0.13f, 0.95f));
|
||||
|
||||
if (ImGui::BeginPopupModal("RetroAchievements", &s_achievements_login_open, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar))
|
||||
{
|
||||
const float content_width = ImGui::GetContentRegionAvail().x;
|
||||
|
||||
ImGui::PushFont(g_large_font);
|
||||
|
||||
const float icon_height = LayoutScale(24.0f);
|
||||
const float icon_width = icon_height * (500.0f / 275.0f);
|
||||
GSTexture* ra_icon = GetCachedSvgTextureAsync("icons/ra-icon.svg", ImVec2(icon_width, icon_height));
|
||||
const float title_width = ImGui::CalcTextSize("RetroAchievements").x;
|
||||
const float header_width = (ra_icon ? icon_width + LayoutScale(10.0f) : 0.0f) + title_width;
|
||||
const float header_start = (content_width - header_width) * 0.5f;
|
||||
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + header_start);
|
||||
|
||||
if (ra_icon)
|
||||
{
|
||||
ImGui::Image(reinterpret_cast<ImTextureID>(ra_icon->GetNativeHandle()),
|
||||
ImVec2(icon_width, icon_height));
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + LayoutScale(1.0f));
|
||||
ImGui::TextUnformatted(FSUI_CSTR("RetroAchievements"));
|
||||
ImGui::PopFont();
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Spacing();
|
||||
|
||||
ImGui::PushTextWrapPos(content_width);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.8f, 0.8f, 0.8f, 1.0f));
|
||||
ImGui::TextWrapped(FSUI_CSTR("Please enter your user name and password for retroachievements.org below. Your password will not be saved in PCSX2, an access token will be generated and used instead."));
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopTextWrapPos();
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Spacing();
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, LayoutScale(6.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, LayoutScale(12.0f, 10.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.2f, 0.2f, 0.2f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(0.25f, 0.25f, 0.25f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(0.3f, 0.3f, 0.3f, 1.0f));
|
||||
|
||||
if (s_achievements_login_logging_in)
|
||||
ImGui::BeginDisabled();
|
||||
|
||||
ImGui::SetNextItemWidth(content_width);
|
||||
ImGui::InputTextWithHint("##username", FSUI_CSTR("Username"), s_achievements_login_username, sizeof(s_achievements_login_username));
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
ImGui::SetNextItemWidth(content_width);
|
||||
ImGui::InputTextWithHint("##password", FSUI_CSTR("Password"), s_achievements_login_password, sizeof(s_achievements_login_password), ImGuiInputTextFlags_Password);
|
||||
|
||||
ImGui::PopStyleColor(3);
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
if (s_achievements_login_logging_in)
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Spacing();
|
||||
|
||||
if (s_achievements_login_logging_in)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.7f, 0.7f, 0.7f, 1.0f));
|
||||
const float status_width = ImGui::CalcTextSize("Logging in...").x;
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (content_width - status_width) * 0.5f);
|
||||
ImGui::TextUnformatted(FSUI_CSTR("Logging in..."));
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::Spacing();
|
||||
}
|
||||
|
||||
const float button_height = LayoutScale(36.0f);
|
||||
const float button_width = LayoutScale(100.0f);
|
||||
const float button_spacing = LayoutScale(12.0f);
|
||||
const float total_width = (button_width * 2) + button_spacing;
|
||||
const float start_x = (content_width - total_width) * 0.5f;
|
||||
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + start_x);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, LayoutScale(6.0f));
|
||||
|
||||
const bool can_login = !s_achievements_login_logging_in &&
|
||||
strlen(s_achievements_login_username) > 0 &&
|
||||
strlen(s_achievements_login_password) > 0;
|
||||
|
||||
if (can_login)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.5f, 0.9f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.3f, 0.6f, 1.0f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.1f, 0.4f, 0.8f, 1.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.3f, 0.3f, 0.3f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.3f, 0.3f, 0.3f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.3f, 0.3f, 0.3f, 1.0f));
|
||||
}
|
||||
|
||||
if (ImGui::Button(FSUI_CSTR("Login"), ImVec2(button_width, button_height)) && can_login)
|
||||
{
|
||||
s_achievements_login_logging_in = true;
|
||||
|
||||
Host::RunOnCPUThread([username = std::string(s_achievements_login_username),
|
||||
password = std::string(s_achievements_login_password)]() {
|
||||
Error error;
|
||||
const bool result = Achievements::Login(username.c_str(), password.c_str(), &error);
|
||||
|
||||
s_achievements_login_logging_in = false;
|
||||
|
||||
if (!result)
|
||||
{
|
||||
ShowToast(std::string(), fmt::format(FSUI_FSTR("Login failed.\nError: {}\n\nPlease check your username and password, and try again."),
|
||||
error.GetDescription()));
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::CloseCurrentPopup();
|
||||
s_achievements_login_open = false;
|
||||
|
||||
s_achievements_login_username[0] = '\0';
|
||||
s_achievements_login_password[0] = '\0';
|
||||
|
||||
if (s_achievements_login_reason == Achievements::LoginRequestReason::UserInitiated)
|
||||
{
|
||||
if (!Host::GetBaseBoolSettingValue("Achievements", "Enabled", false))
|
||||
{
|
||||
OpenConfirmMessageDialog(FSUI_STR("Enable Achievements"),
|
||||
FSUI_STR("Achievement tracking is not currently enabled. Your login will have no effect until "
|
||||
"after tracking is enabled.\n\nDo you want to enable tracking now?"),
|
||||
[](bool result) {
|
||||
if (result)
|
||||
{
|
||||
Host::SetBaseBoolSettingValue("Achievements", "Enabled", true);
|
||||
Host::CommitBaseSettingChanges();
|
||||
VMManager::ApplySettings();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!Host::GetBaseBoolSettingValue("Achievements", "ChallengeMode", false))
|
||||
{
|
||||
OpenConfirmMessageDialog(FSUI_STR("Enable Hardcore Mode"),
|
||||
FSUI_STR("Hardcore mode is not currently enabled. Enabling hardcore mode allows you to set times, scores, and "
|
||||
"participate in game-specific leaderboards.\n\nHowever, hardcore mode also prevents the usage of save "
|
||||
"states, cheats and slowdown functionality.\n\nDo you want to enable hardcore mode?"),
|
||||
[](bool result) {
|
||||
if (result)
|
||||
{
|
||||
Host::SetBaseBoolSettingValue("Achievements", "ChallengeMode", true);
|
||||
Host::CommitBaseSettingChanges();
|
||||
VMManager::ApplySettings();
|
||||
|
||||
bool has_active_game;
|
||||
{
|
||||
auto lock = Achievements::GetLock();
|
||||
has_active_game = Achievements::HasActiveGame();
|
||||
}
|
||||
|
||||
if (has_active_game)
|
||||
{
|
||||
OpenConfirmMessageDialog(FSUI_STR("Reset System"),
|
||||
FSUI_STR("Hardcore mode will not be enabled until the system is reset. Do you want to reset the system now?"),
|
||||
[](bool reset) {
|
||||
if (reset && VMManager::HasValidVM())
|
||||
RequestReset();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor(3);
|
||||
|
||||
ImGui::SameLine(0, button_spacing);
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.4f, 0.4f, 0.4f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.5f, 0.5f, 0.5f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.3f, 0.3f, 0.3f, 1.0f));
|
||||
|
||||
if (ImGui::Button(FSUI_CSTR("Cancel"), ImVec2(button_width, button_height)) && !s_achievements_login_logging_in)
|
||||
{
|
||||
if (s_achievements_login_reason == Achievements::LoginRequestReason::TokenInvalid)
|
||||
{
|
||||
if (VMManager::HasValidVM() && !Achievements::HasActiveGame())
|
||||
Achievements::DisableHardcoreMode();
|
||||
}
|
||||
|
||||
ImGui::CloseCurrentPopup();
|
||||
s_achievements_login_open = false;
|
||||
s_achievements_login_logging_in = false;
|
||||
|
||||
s_achievements_login_username[0] = '\0';
|
||||
s_achievements_login_password[0] = '\0';
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor(3);
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
if (!ImGui::IsPopupOpen("RetroAchievements"))
|
||||
ImGui::OpenPopup("RetroAchievements");
|
||||
}
|
||||
|
||||
bool FullscreenUI::IsAchievementsWindowOpen()
|
||||
{
|
||||
return (s_current_main_window == MainWindowType::Achievements);
|
||||
@ -7414,7 +7648,10 @@ void FullscreenUI::DrawAchievementsSettingsPage(std::unique_lock<std::mutex>& se
|
||||
ActiveButton(FSUI_ICONSTR(ICON_FA_USER, "Not Logged In"), false, false, ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY);
|
||||
|
||||
if (MenuButton(FSUI_ICONSTR(ICON_FA_KEY, "Login"), FSUI_CSTR("Logs in to RetroAchievements.")))
|
||||
Host::OnAchievementsLoginRequested(Achievements::LoginRequestReason::UserInitiated);
|
||||
{
|
||||
s_achievements_login_reason = Achievements::LoginRequestReason::UserInitiated;
|
||||
s_achievements_login_open = true;
|
||||
}
|
||||
}
|
||||
|
||||
MenuHeading(FSUI_CSTR("Current Game"));
|
||||
@ -8363,5 +8600,13 @@ TRANSLATE_NOOP("FullscreenUI", "Game not loaded or no RetroAchievements availabl
|
||||
TRANSLATE_NOOP("FullscreenUI", "Card Enabled");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Card Name");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Eject Card");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Username");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Password");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Please enter your user name and password for retroachievements.org below. Your password will not be saved in PCSX2, an access token will be generated and used instead.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Login failed.\nError: {}\n\nPlease check your username and password, and try again.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Achievement tracking is not currently enabled. Your login will have no effect until after tracking is enabled.\n\nDo you want to enable tracking now?");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Hardcore mode is not currently enabled. Enabling hardcore mode allows you to set times, scores, and participate in game-specific leaderboards.\n\nHowever, hardcore mode also prevents the usage of save states, cheats and slowdown functionality.\n\nDo you want to enable hardcore mode?");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Logging in...");
|
||||
// TRANSLATION-STRING-AREA-END
|
||||
#endif
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user