diff --git a/Cargo.lock b/Cargo.lock index 0eb23351..4c8c6bae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1389,6 +1389,21 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "discord-rich-presence" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90c55d69cab17c19677ce3a5f8face993a9e6eaf847fecac3547f3a3ff4a2494" +dependencies = [ + "log", + "serde", + "serde_derive", + "serde_json", + "serde_repr", + "thiserror 2.0.18", + "uuid 0.8.2", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -2121,6 +2136,7 @@ dependencies = [ "chrono", "clap", "dirs", + "discord-rich-presence", "encoding_rs", "fatfs", "futures", @@ -6323,6 +6339,15 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom 0.2.17", +] + [[package]] name = "uuid" version = "1.23.1" @@ -7505,7 +7530,7 @@ dependencies = [ "serde_repr", "tracing", "uds_windows", - "uuid", + "uuid 1.23.1", "windows-sys 0.61.2", "winnow 1.0.2", "zbus_macros", diff --git a/Cargo.toml b/Cargo.toml index 9bb2e2a8..cd799b0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,7 @@ semver = "1.0" postcard = { version = "1.1", features = ["use-std"] } clap = { version = "4.5", features = ["derive"] } reqwest = { version = "0.13", features = ["json", "query"] } +discord-rich-presence = "1.1" [build-dependencies] winresource = "0.1" diff --git a/build.rs b/build.rs index 34ed1b6b..5f53053e 100644 --- a/build.rs +++ b/build.rs @@ -179,7 +179,9 @@ fn main() { .allowlist_function("ra_login_token_user") .allowlist_function("ra_state_size") .allowlist_function("ra_save_state") - .allowlist_function("ra_load_state"); + .allowlist_function("ra_load_state") + .allowlist_function("ra_get_game_info") + .allowlist_function("ra_get_rich_presence"); if cfg!(feature = "gui") { retroachievements_builder = retroachievements_builder diff --git a/data/translations/de/LC_MESSAGES/gopher64.po b/data/translations/de/LC_MESSAGES/gopher64.po index b8a712ca..9330d32a 100644 --- a/data/translations/de/LC_MESSAGES/gopher64.po +++ b/data/translations/de/LC_MESSAGES/gopher64.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: gopher64\n" -"POT-Creation-Date: 2026-05-10 18:36+0000\n" +"POT-Creation-Date: 2026-05-14 13:42+0000\n" "PO-Revision-Date: 2026-05-11 12:00+0000\n" "Last-Translator: \n" "Language-Team: German\n" @@ -107,31 +107,6 @@ msgctxt "ControllerConfig" msgid "Controller" msgstr "Controller" -#: src/ui/gui/input_profile.slint:10 -msgctxt "InputProfileDialog" -msgid "Create/Modify Input Profile" -msgstr "Eingabeprofil erstellen/bearbeiten" - -#: src/ui/gui/input_profile.slint:18 -msgctxt "InputProfileDialog" -msgid "Enter profile name to create or modify" -msgstr "Profilname zum Erstellen oder Bearbeiten eingeben" - -#: src/ui/gui/input_profile.slint:29 -msgctxt "InputProfileDialog" -msgid "Deadzone Percentage" -msgstr "Deadzone Größe in Prozent" - -#: src/ui/gui/input_profile.slint:51 -msgctxt "InputProfileDialog" -msgid "Use DirectInput" -msgstr "DirectInput verwenden" - -#: src/ui/gui/input_profile.slint:61 -msgctxt "InputProfileDialog" -msgid "Start Profile Creation Wizard" -msgstr "Assistent zur Profilerstellung starten" - #: src/ui/gui/localgame_page.slint:18 msgctxt "LocalGame" msgid "Local Game" @@ -242,42 +217,42 @@ msgctxt "VruDialog" msgid "What Would You Like To Say?" msgstr "Was möchten Sie sagen?" -#: src/ui/gui/appwindow.slint:94 +#: src/ui/gui/appwindow.slint:95 msgctxt "Menu" msgid "Local Game" msgstr "Lokales Spiel" -#: src/ui/gui/appwindow.slint:95 +#: src/ui/gui/appwindow.slint:96 msgctxt "Menu" msgid "Controller Config" msgstr "Controller-Konfiguration" -#: src/ui/gui/appwindow.slint:96 +#: src/ui/gui/appwindow.slint:97 msgctxt "Menu" msgid "Netplay" msgstr "Netplay" -#: src/ui/gui/appwindow.slint:97 +#: src/ui/gui/appwindow.slint:98 msgctxt "Menu" msgid "Cheats" msgstr "Cheats" -#: src/ui/gui/appwindow.slint:98 +#: src/ui/gui/appwindow.slint:99 msgctxt "Menu" msgid "RetroAchievements" msgstr "RetroAchievements" -#: src/ui/gui/appwindow.slint:99 +#: src/ui/gui/appwindow.slint:100 msgctxt "Menu" msgid "Settings" msgstr "Einstellungen" -#: src/ui/gui/appwindow.slint:100 +#: src/ui/gui/appwindow.slint:101 msgctxt "Menu" msgid "About" msgstr "Über" -#: src/ui/gui/appwindow.slint:194 +#: src/ui/gui/appwindow.slint:195 msgctxt "ErrorDialog" msgid "Error" msgstr "Fehler" @@ -384,8 +359,7 @@ msgstr "Auf eine Sitzung klicken um diese auszuwählen" #: src/ui/gui/netplay_join.slint:67 msgctxt "NetplayJoin" msgid "No sessions available. Please refresh to check again." -msgstr "" -"Keine Sitzungen verfügbar. Bitte aktualisieren, um erneut zu prüfen." +msgstr "Keine Sitzungen verfügbar. Bitte aktualisieren, um erneut zu prüfen." #: src/ui/gui/netplay_join.slint:73 msgctxt "NetplayJoin" @@ -432,6 +406,66 @@ msgctxt "NetplayJoin" msgid "Join Session" msgstr "Sitzung beitreten" +#: src/ui/gui/retroachievements_page.slint:19 +msgctxt "RAData" +msgid "Not currently logged in" +msgstr "Derzeit nicht angemeldet" + +#: src/ui/gui/retroachievements_page.slint:27 +msgctxt "RetroAchievements" +msgid "RetroAchievements" +msgstr "RetroAchievements" + +#: src/ui/gui/retroachievements_page.slint:34 +msgctxt "RetroAchievements" +msgid "Enabled" +msgstr "Aktiviert" + +#: src/ui/gui/retroachievements_page.slint:52 +msgctxt "RetroAchievements" +msgid "Hardcore mode" +msgstr "Hardcore-Modus" + +#: src/ui/gui/retroachievements_page.slint:64 +msgctxt "RetroAchievements" +msgid "Challenge Indicators" +msgstr "Challenge Tipps" + +#: src/ui/gui/retroachievements_page.slint:76 +msgctxt "RetroAchievements" +msgid "Leaderboard Trackers" +msgstr "Bestenlisten-Tracker" + +#: src/ui/gui/retroachievements_page.slint:88 +msgctxt "RetroAchievements" +msgid "Discord Rich Presence" +msgstr "Rich Presence für Discord" + +#: src/ui/gui/retroachievements_page.slint:105 +msgctxt "RetroAchievements" +msgid "View Profile" +msgstr "Profil anzeigen" + +#: src/ui/gui/retroachievements_page.slint:115 +msgctxt "RetroAchievements" +msgid "Username" +msgstr "Benutzername" + +#: src/ui/gui/retroachievements_page.slint:125 +msgctxt "RetroAchievements" +msgid "Password" +msgstr "Passwort" + +#: src/ui/gui/retroachievements_page.slint:134 +msgctxt "RetroAchievements" +msgid "Login" +msgstr "Anmelden" + +#: src/ui/gui/retroachievements_page.slint:150 +msgctxt "RetroAchievements" +msgid "View Supported Games" +msgstr "Unterstützte Spiele anzeigen" + #: src/ui/gui/netplay_wait.slint:14 msgctxt "NetplayWait" msgid "Netplay: Waiting Room" @@ -487,57 +521,27 @@ msgctxt "NetplayWait" msgid "Start Game" msgstr "Spiel starten" -#: src/ui/gui/retroachievements_page.slint:18 -msgctxt "RAData" -msgid "Not currently logged in" -msgstr "Derzeit nicht angemeldet" +#: src/ui/gui/input_profile.slint:10 +msgctxt "InputProfileDialog" +msgid "Create/Modify Input Profile" +msgstr "Eingabeprofil erstellen/bearbeiten" -#: src/ui/gui/retroachievements_page.slint:26 -msgctxt "RetroAchievements" -msgid "RetroAchievements" -msgstr "RetroAchievements" +#: src/ui/gui/input_profile.slint:18 +msgctxt "InputProfileDialog" +msgid "Enter profile name to create or modify" +msgstr "Profilname zum Erstellen oder Bearbeiten eingeben" -#: src/ui/gui/retroachievements_page.slint:33 -msgctxt "RetroAchievements" -msgid "Enabled" -msgstr "Aktiviert" +#: src/ui/gui/input_profile.slint:29 +msgctxt "InputProfileDialog" +msgid "Deadzone Percentage" +msgstr "Deadzone Größe in Prozent" -#: src/ui/gui/retroachievements_page.slint:51 -msgctxt "RetroAchievements" -msgid "Hardcore mode" -msgstr "Hardcore-Modus" +#: src/ui/gui/input_profile.slint:51 +msgctxt "InputProfileDialog" +msgid "Use DirectInput" +msgstr "DirectInput verwenden" -#: src/ui/gui/retroachievements_page.slint:63 -msgctxt "RetroAchievements" -msgid "Challenge Indicators" -msgstr "Challenge Tipps" - -#: src/ui/gui/retroachievements_page.slint:75 -msgctxt "RetroAchievements" -msgid "Leaderboard Trackers" -msgstr "Bestenlisten-Tracker" - -#: src/ui/gui/retroachievements_page.slint:92 -msgctxt "RetroAchievements" -msgid "View Profile" -msgstr "Profil anzeigen" - -#: src/ui/gui/retroachievements_page.slint:102 -msgctxt "RetroAchievements" -msgid "Username" -msgstr "Benutzername" - -#: src/ui/gui/retroachievements_page.slint:112 -msgctxt "RetroAchievements" -msgid "Password" -msgstr "Passwort" - -#: src/ui/gui/retroachievements_page.slint:121 -msgctxt "RetroAchievements" -msgid "Login" -msgstr "Anmelden" - -#: src/ui/gui/retroachievements_page.slint:137 -msgctxt "RetroAchievements" -msgid "View Supported Games" -msgstr "Unterstützte Spiele anzeigen" +#: src/ui/gui/input_profile.slint:61 +msgctxt "InputProfileDialog" +msgid "Start Profile Creation Wizard" +msgstr "Assistent zur Profilerstellung starten" diff --git a/data/translations/es/LC_MESSAGES/gopher64.po b/data/translations/es/LC_MESSAGES/gopher64.po index f8bb63f1..5ded8244 100644 --- a/data/translations/es/LC_MESSAGES/gopher64.po +++ b/data/translations/es/LC_MESSAGES/gopher64.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: gopher64\n" -"POT-Creation-Date: 2026-05-10 13:12+0000\n" +"POT-Creation-Date: 2026-05-14 13:42+0000\n" "PO-Revision-Date: 2026-05-11 12:00+0000\n" "Last-Translator: Gemini\n" "Language-Team: Spanish (Spain)\n" @@ -107,31 +107,6 @@ msgctxt "ControllerConfig" msgid "Controller" msgstr "Mando" -#: src/ui/gui/input_profile.slint:10 -msgctxt "InputProfileDialog" -msgid "Create/Modify Input Profile" -msgstr "Crear/Modificar perfil de entrada" - -#: src/ui/gui/input_profile.slint:18 -msgctxt "InputProfileDialog" -msgid "Enter profile name to create or modify" -msgstr "Introduce el nombre del perfil para crear o modificar" - -#: src/ui/gui/input_profile.slint:29 -msgctxt "InputProfileDialog" -msgid "Deadzone Percentage" -msgstr "Porcentaje de zona muerta" - -#: src/ui/gui/input_profile.slint:51 -msgctxt "InputProfileDialog" -msgid "Use DirectInput" -msgstr "Usar DirectInput" - -#: src/ui/gui/input_profile.slint:61 -msgctxt "InputProfileDialog" -msgid "Start Profile Creation Wizard" -msgstr "Iniciar asistente de creación de perfil" - #: src/ui/gui/localgame_page.slint:18 msgctxt "LocalGame" msgid "Local Game" @@ -242,42 +217,42 @@ msgctxt "VruDialog" msgid "What Would You Like To Say?" msgstr "¿Qué te gustaría decir?" -#: src/ui/gui/appwindow.slint:94 +#: src/ui/gui/appwindow.slint:95 msgctxt "Menu" msgid "Local Game" msgstr "Juego local" -#: src/ui/gui/appwindow.slint:95 +#: src/ui/gui/appwindow.slint:96 msgctxt "Menu" msgid "Controller Config" msgstr "Config. del mando" -#: src/ui/gui/appwindow.slint:96 +#: src/ui/gui/appwindow.slint:97 msgctxt "Menu" msgid "Netplay" msgstr "Netplay" -#: src/ui/gui/appwindow.slint:97 +#: src/ui/gui/appwindow.slint:98 msgctxt "Menu" msgid "Cheats" msgstr "Trucos" -#: src/ui/gui/appwindow.slint:98 +#: src/ui/gui/appwindow.slint:99 msgctxt "Menu" msgid "RetroAchievements" msgstr "RetroAchievements" -#: src/ui/gui/appwindow.slint:99 +#: src/ui/gui/appwindow.slint:100 msgctxt "Menu" msgid "Settings" msgstr "Ajustes" -#: src/ui/gui/appwindow.slint:100 +#: src/ui/gui/appwindow.slint:101 msgctxt "Menu" msgid "About" msgstr "Acerca de" -#: src/ui/gui/appwindow.slint:194 +#: src/ui/gui/appwindow.slint:195 msgctxt "ErrorDialog" msgid "Error" msgstr "Error" @@ -332,7 +307,8 @@ msgctxt "NetplayCreate" msgid "" "This game has cheats enabled. Cheats will be synchronized with other players." msgstr "" -"Este juego tiene trucos activados. Los trucos se sincronizarán con los otros jugadores." +"Este juego tiene trucos activados. Los trucos se sincronizarán con los otros " +"jugadores." #: src/ui/gui/netplay_create.slint:103 msgctxt "NetplayCreate" @@ -381,10 +357,8 @@ msgstr "Pulsa una sesión para seleccionarla" #: src/ui/gui/netplay_join.slint:67 msgctxt "NetplayJoin" -msgid "" -"No sessions available. Please refresh to check again." -msgstr "" -"No hay sesiones disponibles. Actualiza para comprobar de nuevo." +msgid "No sessions available. Please refresh to check again." +msgstr "No hay sesiones disponibles. Actualiza para comprobar de nuevo." #: src/ui/gui/netplay_join.slint:73 msgctxt "NetplayJoin" @@ -431,6 +405,66 @@ msgctxt "NetplayJoin" msgid "Join Session" msgstr "Unirse a la sesión" +#: src/ui/gui/retroachievements_page.slint:19 +msgctxt "RAData" +msgid "Not currently logged in" +msgstr "Sesión no iniciada" + +#: src/ui/gui/retroachievements_page.slint:27 +msgctxt "RetroAchievements" +msgid "RetroAchievements" +msgstr "RetroAchievements" + +#: src/ui/gui/retroachievements_page.slint:34 +msgctxt "RetroAchievements" +msgid "Enabled" +msgstr "Activado" + +#: src/ui/gui/retroachievements_page.slint:52 +msgctxt "RetroAchievements" +msgid "Hardcore mode" +msgstr "Modo Hardcore" + +#: src/ui/gui/retroachievements_page.slint:64 +msgctxt "RetroAchievements" +msgid "Challenge Indicators" +msgstr "Indicadores de desafío" + +#: src/ui/gui/retroachievements_page.slint:76 +msgctxt "RetroAchievements" +msgid "Leaderboard Trackers" +msgstr "Indicadores de tabla de clasificación" + +#: src/ui/gui/retroachievements_page.slint:88 +msgctxt "RetroAchievements" +msgid "Discord Rich Presence" +msgstr "Rich Presence en Discord" + +#: src/ui/gui/retroachievements_page.slint:105 +msgctxt "RetroAchievements" +msgid "View Profile" +msgstr "Ver perfil" + +#: src/ui/gui/retroachievements_page.slint:115 +msgctxt "RetroAchievements" +msgid "Username" +msgstr "Usuario" + +#: src/ui/gui/retroachievements_page.slint:125 +msgctxt "RetroAchievements" +msgid "Password" +msgstr "Contraseña" + +#: src/ui/gui/retroachievements_page.slint:134 +msgctxt "RetroAchievements" +msgid "Login" +msgstr "Entrar" + +#: src/ui/gui/retroachievements_page.slint:150 +msgctxt "RetroAchievements" +msgid "View Supported Games" +msgstr "Ver juegos compatibles" + #: src/ui/gui/netplay_wait.slint:14 msgctxt "NetplayWait" msgid "Netplay: Waiting Room" @@ -486,57 +520,27 @@ msgctxt "NetplayWait" msgid "Start Game" msgstr "Iniciar juego" -#: src/ui/gui/retroachievements_page.slint:18 -msgctxt "RAData" -msgid "Not currently logged in" -msgstr "Sesión no iniciada" +#: src/ui/gui/input_profile.slint:10 +msgctxt "InputProfileDialog" +msgid "Create/Modify Input Profile" +msgstr "Crear/Modificar perfil de entrada" -#: src/ui/gui/retroachievements_page.slint:26 -msgctxt "RetroAchievements" -msgid "RetroAchievements" -msgstr "RetroAchievements" +#: src/ui/gui/input_profile.slint:18 +msgctxt "InputProfileDialog" +msgid "Enter profile name to create or modify" +msgstr "Introduce el nombre del perfil para crear o modificar" -#: src/ui/gui/retroachievements_page.slint:33 -msgctxt "RetroAchievements" -msgid "Enabled" -msgstr "Activado" +#: src/ui/gui/input_profile.slint:29 +msgctxt "InputProfileDialog" +msgid "Deadzone Percentage" +msgstr "Porcentaje de zona muerta" -#: src/ui/gui/retroachievements_page.slint:51 -msgctxt "RetroAchievements" -msgid "Hardcore mode" -msgstr "Modo Hardcore" +#: src/ui/gui/input_profile.slint:51 +msgctxt "InputProfileDialog" +msgid "Use DirectInput" +msgstr "Usar DirectInput" -#: src/ui/gui/retroachievements_page.slint:63 -msgctxt "RetroAchievements" -msgid "Challenge Indicators" -msgstr "Indicadores de desafío" - -#: src/ui/gui/retroachievements_page.slint:75 -msgctxt "RetroAchievements" -msgid "Leaderboard Trackers" -msgstr "Indicadores de tabla de clasificación" - -#: src/ui/gui/retroachievements_page.slint:92 -msgctxt "RetroAchievements" -msgid "View Profile" -msgstr "Ver perfil" - -#: src/ui/gui/retroachievements_page.slint:102 -msgctxt "RetroAchievements" -msgid "Username" -msgstr "Usuario" - -#: src/ui/gui/retroachievements_page.slint:112 -msgctxt "RetroAchievements" -msgid "Password" -msgstr "Contraseña" - -#: src/ui/gui/retroachievements_page.slint:121 -msgctxt "RetroAchievements" -msgid "Login" -msgstr "Entrar" - -#: src/ui/gui/retroachievements_page.slint:137 -msgctxt "RetroAchievements" -msgid "View Supported Games" -msgstr "Ver juegos compatibles" +#: src/ui/gui/input_profile.slint:61 +msgctxt "InputProfileDialog" +msgid "Start Profile Creation Wizard" +msgstr "Iniciar asistente de creación de perfil" diff --git a/data/translations/fr/LC_MESSAGES/gopher64.po b/data/translations/fr/LC_MESSAGES/gopher64.po index fd9f3102..7714cbef 100644 --- a/data/translations/fr/LC_MESSAGES/gopher64.po +++ b/data/translations/fr/LC_MESSAGES/gopher64.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: gopher64\n" -"POT-Creation-Date: 2026-05-10 18:36+0000\n" +"POT-Creation-Date: 2026-05-14 13:42+0000\n" "PO-Revision-Date: 2026-05-11 12:00+0000\n" "Last-Translator: \n" "Language-Team: French (France)\n" @@ -107,31 +107,6 @@ msgctxt "ControllerConfig" msgid "Controller" msgstr "Manette" -#: src/ui/gui/input_profile.slint:10 -msgctxt "InputProfileDialog" -msgid "Create/Modify Input Profile" -msgstr "Créer / modifier le profil d'entrée" - -#: src/ui/gui/input_profile.slint:18 -msgctxt "InputProfileDialog" -msgid "Enter profile name to create or modify" -msgstr "Saisir le nom du profil à créer ou à modifier" - -#: src/ui/gui/input_profile.slint:29 -msgctxt "InputProfileDialog" -msgid "Deadzone Percentage" -msgstr "Pourcentage de zone morte" - -#: src/ui/gui/input_profile.slint:51 -msgctxt "InputProfileDialog" -msgid "Use DirectInput" -msgstr "Utiliser DirectInput" - -#: src/ui/gui/input_profile.slint:61 -msgctxt "InputProfileDialog" -msgid "Start Profile Creation Wizard" -msgstr "Lancer l'assistant de création de profil" - #: src/ui/gui/localgame_page.slint:18 msgctxt "LocalGame" msgid "Local Game" @@ -242,42 +217,42 @@ msgctxt "VruDialog" msgid "What Would You Like To Say?" msgstr "Que souhaitez-vous dire ?" -#: src/ui/gui/appwindow.slint:94 +#: src/ui/gui/appwindow.slint:95 msgctxt "Menu" msgid "Local Game" msgstr "Jeu local" -#: src/ui/gui/appwindow.slint:95 +#: src/ui/gui/appwindow.slint:96 msgctxt "Menu" msgid "Controller Config" msgstr "Configuration manette" -#: src/ui/gui/appwindow.slint:96 +#: src/ui/gui/appwindow.slint:97 msgctxt "Menu" msgid "Netplay" msgstr "Netplay" -#: src/ui/gui/appwindow.slint:97 +#: src/ui/gui/appwindow.slint:98 msgctxt "Menu" msgid "Cheats" msgstr "Triche" -#: src/ui/gui/appwindow.slint:98 +#: src/ui/gui/appwindow.slint:99 msgctxt "Menu" msgid "RetroAchievements" msgstr "RetroAchievements" -#: src/ui/gui/appwindow.slint:99 +#: src/ui/gui/appwindow.slint:100 msgctxt "Menu" msgid "Settings" msgstr "Paramètres" -#: src/ui/gui/appwindow.slint:100 +#: src/ui/gui/appwindow.slint:101 msgctxt "Menu" msgid "About" msgstr "À propos" -#: src/ui/gui/appwindow.slint:194 +#: src/ui/gui/appwindow.slint:195 msgctxt "ErrorDialog" msgid "Error" msgstr "Erreur" @@ -349,8 +324,8 @@ msgstr "Création du serveur" msgctxt "DispatcherDialog" msgid "Creating server, please wait...This may take about 30 seconds." msgstr "" -"Création du serveur, veuillez patienter… Cela peut prendre environ " -"30 secondes." +"Création du serveur, veuillez patienter… Cela peut prendre environ 30 " +"secondes." #: src/ui/gui/netplay_join.slint:5 msgctxt "NetplayJoin" @@ -433,6 +408,66 @@ msgctxt "NetplayJoin" msgid "Join Session" msgstr "Rejoindre la session" +#: src/ui/gui/retroachievements_page.slint:19 +msgctxt "RAData" +msgid "Not currently logged in" +msgstr "Non connecté" + +#: src/ui/gui/retroachievements_page.slint:27 +msgctxt "RetroAchievements" +msgid "RetroAchievements" +msgstr "RetroAchievements" + +#: src/ui/gui/retroachievements_page.slint:34 +msgctxt "RetroAchievements" +msgid "Enabled" +msgstr "Activé" + +#: src/ui/gui/retroachievements_page.slint:52 +msgctxt "RetroAchievements" +msgid "Hardcore mode" +msgstr "Mode hardcore" + +#: src/ui/gui/retroachievements_page.slint:64 +msgctxt "RetroAchievements" +msgid "Challenge Indicators" +msgstr "Indicateurs de défi" + +#: src/ui/gui/retroachievements_page.slint:76 +msgctxt "RetroAchievements" +msgid "Leaderboard Trackers" +msgstr "Suivi des classements" + +#: src/ui/gui/retroachievements_page.slint:88 +msgctxt "RetroAchievements" +msgid "Discord Rich Presence" +msgstr "Rich Presence Discord" + +#: src/ui/gui/retroachievements_page.slint:105 +msgctxt "RetroAchievements" +msgid "View Profile" +msgstr "Voir le profil" + +#: src/ui/gui/retroachievements_page.slint:115 +msgctxt "RetroAchievements" +msgid "Username" +msgstr "Nom d'utilisateur" + +#: src/ui/gui/retroachievements_page.slint:125 +msgctxt "RetroAchievements" +msgid "Password" +msgstr "Mot de passe" + +#: src/ui/gui/retroachievements_page.slint:134 +msgctxt "RetroAchievements" +msgid "Login" +msgstr "Connexion" + +#: src/ui/gui/retroachievements_page.slint:150 +msgctxt "RetroAchievements" +msgid "View Supported Games" +msgstr "Voir les jeux pris en charge" + #: src/ui/gui/netplay_wait.slint:14 msgctxt "NetplayWait" msgid "Netplay: Waiting Room" @@ -488,57 +523,27 @@ msgctxt "NetplayWait" msgid "Start Game" msgstr "Lancer la partie" -#: src/ui/gui/retroachievements_page.slint:18 -msgctxt "RAData" -msgid "Not currently logged in" -msgstr "Non connecté" +#: src/ui/gui/input_profile.slint:10 +msgctxt "InputProfileDialog" +msgid "Create/Modify Input Profile" +msgstr "Créer / modifier le profil d'entrée" -#: src/ui/gui/retroachievements_page.slint:26 -msgctxt "RetroAchievements" -msgid "RetroAchievements" -msgstr "RetroAchievements" +#: src/ui/gui/input_profile.slint:18 +msgctxt "InputProfileDialog" +msgid "Enter profile name to create or modify" +msgstr "Saisir le nom du profil à créer ou à modifier" -#: src/ui/gui/retroachievements_page.slint:33 -msgctxt "RetroAchievements" -msgid "Enabled" -msgstr "Activé" +#: src/ui/gui/input_profile.slint:29 +msgctxt "InputProfileDialog" +msgid "Deadzone Percentage" +msgstr "Pourcentage de zone morte" -#: src/ui/gui/retroachievements_page.slint:51 -msgctxt "RetroAchievements" -msgid "Hardcore mode" -msgstr "Mode hardcore" +#: src/ui/gui/input_profile.slint:51 +msgctxt "InputProfileDialog" +msgid "Use DirectInput" +msgstr "Utiliser DirectInput" -#: src/ui/gui/retroachievements_page.slint:63 -msgctxt "RetroAchievements" -msgid "Challenge Indicators" -msgstr "Indicateurs de défi" - -#: src/ui/gui/retroachievements_page.slint:75 -msgctxt "RetroAchievements" -msgid "Leaderboard Trackers" -msgstr "Suivi des classements" - -#: src/ui/gui/retroachievements_page.slint:92 -msgctxt "RetroAchievements" -msgid "View Profile" -msgstr "Voir le profil" - -#: src/ui/gui/retroachievements_page.slint:102 -msgctxt "RetroAchievements" -msgid "Username" -msgstr "Nom d'utilisateur" - -#: src/ui/gui/retroachievements_page.slint:112 -msgctxt "RetroAchievements" -msgid "Password" -msgstr "Mot de passe" - -#: src/ui/gui/retroachievements_page.slint:121 -msgctxt "RetroAchievements" -msgid "Login" -msgstr "Connexion" - -#: src/ui/gui/retroachievements_page.slint:137 -msgctxt "RetroAchievements" -msgid "View Supported Games" -msgstr "Voir les jeux pris en charge" +#: src/ui/gui/input_profile.slint:61 +msgctxt "InputProfileDialog" +msgid "Start Profile Creation Wizard" +msgstr "Lancer l'assistant de création de profil" diff --git a/data/translations/gopher64.pot b/data/translations/gopher64.pot index fb724151..ffb85203 100644 --- a/data/translations/gopher64.pot +++ b/data/translations/gopher64.pot @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2026-05-10 18:36+0000\n" +"POT-Creation-Date: 2026-05-14 13:42+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -107,31 +107,6 @@ msgctxt "ControllerConfig" msgid "Controller" msgstr "" -#: src/ui/gui/input_profile.slint:10 -msgctxt "InputProfileDialog" -msgid "Create/Modify Input Profile" -msgstr "" - -#: src/ui/gui/input_profile.slint:18 -msgctxt "InputProfileDialog" -msgid "Enter profile name to create or modify" -msgstr "" - -#: src/ui/gui/input_profile.slint:29 -msgctxt "InputProfileDialog" -msgid "Deadzone Percentage" -msgstr "" - -#: src/ui/gui/input_profile.slint:51 -msgctxt "InputProfileDialog" -msgid "Use DirectInput" -msgstr "" - -#: src/ui/gui/input_profile.slint:61 -msgctxt "InputProfileDialog" -msgid "Start Profile Creation Wizard" -msgstr "" - #: src/ui/gui/localgame_page.slint:18 msgctxt "LocalGame" msgid "Local Game" @@ -242,42 +217,42 @@ msgctxt "VruDialog" msgid "What Would You Like To Say?" msgstr "" -#: src/ui/gui/appwindow.slint:94 +#: src/ui/gui/appwindow.slint:95 msgctxt "Menu" msgid "Local Game" msgstr "" -#: src/ui/gui/appwindow.slint:95 +#: src/ui/gui/appwindow.slint:96 msgctxt "Menu" msgid "Controller Config" msgstr "" -#: src/ui/gui/appwindow.slint:96 +#: src/ui/gui/appwindow.slint:97 msgctxt "Menu" msgid "Netplay" msgstr "" -#: src/ui/gui/appwindow.slint:97 +#: src/ui/gui/appwindow.slint:98 msgctxt "Menu" msgid "Cheats" msgstr "" -#: src/ui/gui/appwindow.slint:98 +#: src/ui/gui/appwindow.slint:99 msgctxt "Menu" msgid "RetroAchievements" msgstr "" -#: src/ui/gui/appwindow.slint:99 +#: src/ui/gui/appwindow.slint:100 msgctxt "Menu" msgid "Settings" msgstr "" -#: src/ui/gui/appwindow.slint:100 +#: src/ui/gui/appwindow.slint:101 msgctxt "Menu" msgid "About" msgstr "" -#: src/ui/gui/appwindow.slint:194 +#: src/ui/gui/appwindow.slint:195 msgctxt "ErrorDialog" msgid "Error" msgstr "" @@ -428,6 +403,66 @@ msgctxt "NetplayJoin" msgid "Join Session" msgstr "" +#: src/ui/gui/retroachievements_page.slint:19 +msgctxt "RAData" +msgid "Not currently logged in" +msgstr "" + +#: src/ui/gui/retroachievements_page.slint:27 +msgctxt "RetroAchievements" +msgid "RetroAchievements" +msgstr "" + +#: src/ui/gui/retroachievements_page.slint:34 +msgctxt "RetroAchievements" +msgid "Enabled" +msgstr "" + +#: src/ui/gui/retroachievements_page.slint:52 +msgctxt "RetroAchievements" +msgid "Hardcore mode" +msgstr "" + +#: src/ui/gui/retroachievements_page.slint:64 +msgctxt "RetroAchievements" +msgid "Challenge Indicators" +msgstr "" + +#: src/ui/gui/retroachievements_page.slint:76 +msgctxt "RetroAchievements" +msgid "Leaderboard Trackers" +msgstr "" + +#: src/ui/gui/retroachievements_page.slint:88 +msgctxt "RetroAchievements" +msgid "Discord Rich Presence" +msgstr "" + +#: src/ui/gui/retroachievements_page.slint:105 +msgctxt "RetroAchievements" +msgid "View Profile" +msgstr "" + +#: src/ui/gui/retroachievements_page.slint:115 +msgctxt "RetroAchievements" +msgid "Username" +msgstr "" + +#: src/ui/gui/retroachievements_page.slint:125 +msgctxt "RetroAchievements" +msgid "Password" +msgstr "" + +#: src/ui/gui/retroachievements_page.slint:134 +msgctxt "RetroAchievements" +msgid "Login" +msgstr "" + +#: src/ui/gui/retroachievements_page.slint:150 +msgctxt "RetroAchievements" +msgid "View Supported Games" +msgstr "" + #: src/ui/gui/netplay_wait.slint:14 msgctxt "NetplayWait" msgid "Netplay: Waiting Room" @@ -483,57 +518,27 @@ msgctxt "NetplayWait" msgid "Start Game" msgstr "" -#: src/ui/gui/retroachievements_page.slint:18 -msgctxt "RAData" -msgid "Not currently logged in" +#: src/ui/gui/input_profile.slint:10 +msgctxt "InputProfileDialog" +msgid "Create/Modify Input Profile" msgstr "" -#: src/ui/gui/retroachievements_page.slint:26 -msgctxt "RetroAchievements" -msgid "RetroAchievements" +#: src/ui/gui/input_profile.slint:18 +msgctxt "InputProfileDialog" +msgid "Enter profile name to create or modify" msgstr "" -#: src/ui/gui/retroachievements_page.slint:33 -msgctxt "RetroAchievements" -msgid "Enabled" +#: src/ui/gui/input_profile.slint:29 +msgctxt "InputProfileDialog" +msgid "Deadzone Percentage" msgstr "" -#: src/ui/gui/retroachievements_page.slint:51 -msgctxt "RetroAchievements" -msgid "Hardcore mode" +#: src/ui/gui/input_profile.slint:51 +msgctxt "InputProfileDialog" +msgid "Use DirectInput" msgstr "" -#: src/ui/gui/retroachievements_page.slint:63 -msgctxt "RetroAchievements" -msgid "Challenge Indicators" -msgstr "" - -#: src/ui/gui/retroachievements_page.slint:75 -msgctxt "RetroAchievements" -msgid "Leaderboard Trackers" -msgstr "" - -#: src/ui/gui/retroachievements_page.slint:92 -msgctxt "RetroAchievements" -msgid "View Profile" -msgstr "" - -#: src/ui/gui/retroachievements_page.slint:102 -msgctxt "RetroAchievements" -msgid "Username" -msgstr "" - -#: src/ui/gui/retroachievements_page.slint:112 -msgctxt "RetroAchievements" -msgid "Password" -msgstr "" - -#: src/ui/gui/retroachievements_page.slint:121 -msgctxt "RetroAchievements" -msgid "Login" -msgstr "" - -#: src/ui/gui/retroachievements_page.slint:137 -msgctxt "RetroAchievements" -msgid "View Supported Games" +#: src/ui/gui/input_profile.slint:61 +msgctxt "InputProfileDialog" +msgid "Start Profile Creation Wizard" msgstr "" diff --git a/data/translations/ja/LC_MESSAGES/gopher64.po b/data/translations/ja/LC_MESSAGES/gopher64.po index 08e2744f..a86a1b2e 100644 --- a/data/translations/ja/LC_MESSAGES/gopher64.po +++ b/data/translations/ja/LC_MESSAGES/gopher64.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: gopher64\n" -"POT-Creation-Date: 2026-05-10 18:36+0000\n" +"POT-Creation-Date: 2026-05-14 13:42+0000\n" "PO-Revision-Date: 2026-05-11 12:00+0000\n" "Last-Translator: \n" "Language-Team: Japanese\n" @@ -107,31 +107,6 @@ msgctxt "ControllerConfig" msgid "Controller" msgstr "コントローラー" -#: src/ui/gui/input_profile.slint:10 -msgctxt "InputProfileDialog" -msgid "Create/Modify Input Profile" -msgstr "入力プロファイルの作成/変更" - -#: src/ui/gui/input_profile.slint:18 -msgctxt "InputProfileDialog" -msgid "Enter profile name to create or modify" -msgstr "作成または変更するプロファイル名を入力" - -#: src/ui/gui/input_profile.slint:29 -msgctxt "InputProfileDialog" -msgid "Deadzone Percentage" -msgstr "デッドゾーン(%)" - -#: src/ui/gui/input_profile.slint:51 -msgctxt "InputProfileDialog" -msgid "Use DirectInput" -msgstr "DirectInputを使用" - -#: src/ui/gui/input_profile.slint:61 -msgctxt "InputProfileDialog" -msgid "Start Profile Creation Wizard" -msgstr "プロファイル作成ウィザードを開始" - #: src/ui/gui/localgame_page.slint:18 msgctxt "LocalGame" msgid "Local Game" @@ -242,42 +217,42 @@ msgctxt "VruDialog" msgid "What Would You Like To Say?" msgstr "何と言いますか?" -#: src/ui/gui/appwindow.slint:94 +#: src/ui/gui/appwindow.slint:95 msgctxt "Menu" msgid "Local Game" msgstr "ローカルゲーム" -#: src/ui/gui/appwindow.slint:95 +#: src/ui/gui/appwindow.slint:96 msgctxt "Menu" msgid "Controller Config" msgstr "コントローラー設定" -#: src/ui/gui/appwindow.slint:96 +#: src/ui/gui/appwindow.slint:97 msgctxt "Menu" msgid "Netplay" msgstr "ネットプレイ" -#: src/ui/gui/appwindow.slint:97 +#: src/ui/gui/appwindow.slint:98 msgctxt "Menu" msgid "Cheats" msgstr "チート" -#: src/ui/gui/appwindow.slint:98 +#: src/ui/gui/appwindow.slint:99 msgctxt "Menu" msgid "RetroAchievements" msgstr "RetroAchievements" -#: src/ui/gui/appwindow.slint:99 +#: src/ui/gui/appwindow.slint:100 msgctxt "Menu" msgid "Settings" msgstr "設定" -#: src/ui/gui/appwindow.slint:100 +#: src/ui/gui/appwindow.slint:101 msgctxt "Menu" msgid "About" msgstr "バージョン情報" -#: src/ui/gui/appwindow.slint:194 +#: src/ui/gui/appwindow.slint:195 msgctxt "ErrorDialog" msgid "Error" msgstr "エラー" @@ -331,8 +306,7 @@ msgstr "ROMを選択" msgctxt "NetplayCreate" msgid "" "This game has cheats enabled. Cheats will be synchronized with other players." -msgstr "" -"このゲームではチートが有効です。チートは他のプレイヤーと同期されます。" +msgstr "このゲームではチートが有効です。チートは他のプレイヤーと同期されます。" #: src/ui/gui/netplay_create.slint:103 msgctxt "NetplayCreate" @@ -348,7 +322,8 @@ msgstr "サーバーを作成中" msgctxt "DispatcherDialog" msgid "Creating server, please wait...This may take about 30 seconds." msgstr "" -"サーバーを作成しています。しばらくお待ちください… 最大約30秒かかることがあります。" +"サーバーを作成しています。しばらくお待ちください… 最大約30秒かかることがあり" +"ます。" #: src/ui/gui/netplay_join.slint:5 msgctxt "NetplayJoin" @@ -383,8 +358,7 @@ msgstr "下の一覧からセッションをクリックして選択" #: src/ui/gui/netplay_join.slint:67 msgctxt "NetplayJoin" msgid "No sessions available. Please refresh to check again." -msgstr "" -"利用できるセッションがありません。更新して再度確認してください。" +msgstr "利用できるセッションがありません。更新して再度確認してください。" #: src/ui/gui/netplay_join.slint:73 msgctxt "NetplayJoin" @@ -431,6 +405,66 @@ msgctxt "NetplayJoin" msgid "Join Session" msgstr "セッションに参加" +#: src/ui/gui/retroachievements_page.slint:19 +msgctxt "RAData" +msgid "Not currently logged in" +msgstr "ログインしていません" + +#: src/ui/gui/retroachievements_page.slint:27 +msgctxt "RetroAchievements" +msgid "RetroAchievements" +msgstr "RetroAchievements" + +#: src/ui/gui/retroachievements_page.slint:34 +msgctxt "RetroAchievements" +msgid "Enabled" +msgstr "有効" + +#: src/ui/gui/retroachievements_page.slint:52 +msgctxt "RetroAchievements" +msgid "Hardcore mode" +msgstr "ハードコアモード" + +#: src/ui/gui/retroachievements_page.slint:64 +msgctxt "RetroAchievements" +msgid "Challenge Indicators" +msgstr "チャレンジ表示" + +#: src/ui/gui/retroachievements_page.slint:76 +msgctxt "RetroAchievements" +msgid "Leaderboard Trackers" +msgstr "リーダーボード追跡" + +#: src/ui/gui/retroachievements_page.slint:88 +msgctxt "RetroAchievements" +msgid "Discord Rich Presence" +msgstr "Discord のリッチプレゼンス" + +#: src/ui/gui/retroachievements_page.slint:105 +msgctxt "RetroAchievements" +msgid "View Profile" +msgstr "プロフィールを表示" + +#: src/ui/gui/retroachievements_page.slint:115 +msgctxt "RetroAchievements" +msgid "Username" +msgstr "ユーザー名" + +#: src/ui/gui/retroachievements_page.slint:125 +msgctxt "RetroAchievements" +msgid "Password" +msgstr "パスワード" + +#: src/ui/gui/retroachievements_page.slint:134 +msgctxt "RetroAchievements" +msgid "Login" +msgstr "ログイン" + +#: src/ui/gui/retroachievements_page.slint:150 +msgctxt "RetroAchievements" +msgid "View Supported Games" +msgstr "対応ゲームを表示" + #: src/ui/gui/netplay_wait.slint:14 msgctxt "NetplayWait" msgid "Netplay: Waiting Room" @@ -486,57 +520,27 @@ msgctxt "NetplayWait" msgid "Start Game" msgstr "ゲーム開始" -#: src/ui/gui/retroachievements_page.slint:18 -msgctxt "RAData" -msgid "Not currently logged in" -msgstr "ログインしていません" +#: src/ui/gui/input_profile.slint:10 +msgctxt "InputProfileDialog" +msgid "Create/Modify Input Profile" +msgstr "入力プロファイルの作成/変更" -#: src/ui/gui/retroachievements_page.slint:26 -msgctxt "RetroAchievements" -msgid "RetroAchievements" -msgstr "RetroAchievements" +#: src/ui/gui/input_profile.slint:18 +msgctxt "InputProfileDialog" +msgid "Enter profile name to create or modify" +msgstr "作成または変更するプロファイル名を入力" -#: src/ui/gui/retroachievements_page.slint:33 -msgctxt "RetroAchievements" -msgid "Enabled" -msgstr "有効" +#: src/ui/gui/input_profile.slint:29 +msgctxt "InputProfileDialog" +msgid "Deadzone Percentage" +msgstr "デッドゾーン(%)" -#: src/ui/gui/retroachievements_page.slint:51 -msgctxt "RetroAchievements" -msgid "Hardcore mode" -msgstr "ハードコアモード" +#: src/ui/gui/input_profile.slint:51 +msgctxt "InputProfileDialog" +msgid "Use DirectInput" +msgstr "DirectInputを使用" -#: src/ui/gui/retroachievements_page.slint:63 -msgctxt "RetroAchievements" -msgid "Challenge Indicators" -msgstr "チャレンジ表示" - -#: src/ui/gui/retroachievements_page.slint:75 -msgctxt "RetroAchievements" -msgid "Leaderboard Trackers" -msgstr "リーダーボード追跡" - -#: src/ui/gui/retroachievements_page.slint:92 -msgctxt "RetroAchievements" -msgid "View Profile" -msgstr "プロフィールを表示" - -#: src/ui/gui/retroachievements_page.slint:102 -msgctxt "RetroAchievements" -msgid "Username" -msgstr "ユーザー名" - -#: src/ui/gui/retroachievements_page.slint:112 -msgctxt "RetroAchievements" -msgid "Password" -msgstr "パスワード" - -#: src/ui/gui/retroachievements_page.slint:121 -msgctxt "RetroAchievements" -msgid "Login" -msgstr "ログイン" - -#: src/ui/gui/retroachievements_page.slint:137 -msgctxt "RetroAchievements" -msgid "View Supported Games" -msgstr "対応ゲームを表示" +#: src/ui/gui/input_profile.slint:61 +msgctxt "InputProfileDialog" +msgid "Start Profile Creation Wizard" +msgstr "プロファイル作成ウィザードを開始" diff --git a/data/translations/nl/LC_MESSAGES/gopher64.po b/data/translations/nl/LC_MESSAGES/gopher64.po index 4f7c707a..d0d654bf 100644 --- a/data/translations/nl/LC_MESSAGES/gopher64.po +++ b/data/translations/nl/LC_MESSAGES/gopher64.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: gopher64\n" -"POT-Creation-Date: 2026-05-10 18:36+0000\n" +"POT-Creation-Date: 2026-05-14 13:42+0000\n" "PO-Revision-Date: 2026-05-11 12:00+0000\n" "Last-Translator: \n" "Language-Team: Dutch (Netherlands)\n" @@ -107,31 +107,6 @@ msgctxt "ControllerConfig" msgid "Controller" msgstr "Controller" -#: src/ui/gui/input_profile.slint:10 -msgctxt "InputProfileDialog" -msgid "Create/Modify Input Profile" -msgstr "Invoerprofiel maken/wijzigen" - -#: src/ui/gui/input_profile.slint:18 -msgctxt "InputProfileDialog" -msgid "Enter profile name to create or modify" -msgstr "Profielnaam invoeren om aan te maken of te wijzigen" - -#: src/ui/gui/input_profile.slint:29 -msgctxt "InputProfileDialog" -msgid "Deadzone Percentage" -msgstr "Dode-zonepercentage" - -#: src/ui/gui/input_profile.slint:51 -msgctxt "InputProfileDialog" -msgid "Use DirectInput" -msgstr "DirectInput gebruiken" - -#: src/ui/gui/input_profile.slint:61 -msgctxt "InputProfileDialog" -msgid "Start Profile Creation Wizard" -msgstr "Wizard voor profiel maken starten" - #: src/ui/gui/localgame_page.slint:18 msgctxt "LocalGame" msgid "Local Game" @@ -242,42 +217,42 @@ msgctxt "VruDialog" msgid "What Would You Like To Say?" msgstr "Wat wil je zeggen?" -#: src/ui/gui/appwindow.slint:94 +#: src/ui/gui/appwindow.slint:95 msgctxt "Menu" msgid "Local Game" msgstr "Lokaal spel" -#: src/ui/gui/appwindow.slint:95 +#: src/ui/gui/appwindow.slint:96 msgctxt "Menu" msgid "Controller Config" msgstr "Controllerconfiguratie" -#: src/ui/gui/appwindow.slint:96 +#: src/ui/gui/appwindow.slint:97 msgctxt "Menu" msgid "Netplay" msgstr "Netplay" -#: src/ui/gui/appwindow.slint:97 +#: src/ui/gui/appwindow.slint:98 msgctxt "Menu" msgid "Cheats" msgstr "Cheats" -#: src/ui/gui/appwindow.slint:98 +#: src/ui/gui/appwindow.slint:99 msgctxt "Menu" msgid "RetroAchievements" msgstr "RetroAchievements" -#: src/ui/gui/appwindow.slint:99 +#: src/ui/gui/appwindow.slint:100 msgctxt "Menu" msgid "Settings" msgstr "Instellingen" -#: src/ui/gui/appwindow.slint:100 +#: src/ui/gui/appwindow.slint:101 msgctxt "Menu" msgid "About" msgstr "Over" -#: src/ui/gui/appwindow.slint:194 +#: src/ui/gui/appwindow.slint:195 msgctxt "ErrorDialog" msgid "Error" msgstr "Fout" @@ -384,8 +359,7 @@ msgstr "Klik hieronder op een sessie om die te selecteren" #: src/ui/gui/netplay_join.slint:67 msgctxt "NetplayJoin" msgid "No sessions available. Please refresh to check again." -msgstr "" -"Geen sessies beschikbaar. Vernieuw om opnieuw te controleren." +msgstr "Geen sessies beschikbaar. Vernieuw om opnieuw te controleren." #: src/ui/gui/netplay_join.slint:73 msgctxt "NetplayJoin" @@ -432,6 +406,66 @@ msgctxt "NetplayJoin" msgid "Join Session" msgstr "Deelnemen aan sessie" +#: src/ui/gui/retroachievements_page.slint:19 +msgctxt "RAData" +msgid "Not currently logged in" +msgstr "Momenteel niet ingelogd" + +#: src/ui/gui/retroachievements_page.slint:27 +msgctxt "RetroAchievements" +msgid "RetroAchievements" +msgstr "RetroAchievements" + +#: src/ui/gui/retroachievements_page.slint:34 +msgctxt "RetroAchievements" +msgid "Enabled" +msgstr "Ingeschakeld" + +#: src/ui/gui/retroachievements_page.slint:52 +msgctxt "RetroAchievements" +msgid "Hardcore mode" +msgstr "Hardcore-modus" + +#: src/ui/gui/retroachievements_page.slint:64 +msgctxt "RetroAchievements" +msgid "Challenge Indicators" +msgstr "Challenge-indicatoren" + +#: src/ui/gui/retroachievements_page.slint:76 +msgctxt "RetroAchievements" +msgid "Leaderboard Trackers" +msgstr "Leaderboard-trackers" + +#: src/ui/gui/retroachievements_page.slint:88 +msgctxt "RetroAchievements" +msgid "Discord Rich Presence" +msgstr "Discord Rich Presence" + +#: src/ui/gui/retroachievements_page.slint:105 +msgctxt "RetroAchievements" +msgid "View Profile" +msgstr "Profiel bekijken" + +#: src/ui/gui/retroachievements_page.slint:115 +msgctxt "RetroAchievements" +msgid "Username" +msgstr "Gebruikersnaam" + +#: src/ui/gui/retroachievements_page.slint:125 +msgctxt "RetroAchievements" +msgid "Password" +msgstr "Wachtwoord" + +#: src/ui/gui/retroachievements_page.slint:134 +msgctxt "RetroAchievements" +msgid "Login" +msgstr "Inloggen" + +#: src/ui/gui/retroachievements_page.slint:150 +msgctxt "RetroAchievements" +msgid "View Supported Games" +msgstr "Ondersteunde spellen bekijken" + #: src/ui/gui/netplay_wait.slint:14 msgctxt "NetplayWait" msgid "Netplay: Waiting Room" @@ -487,57 +521,27 @@ msgctxt "NetplayWait" msgid "Start Game" msgstr "Spel starten" -#: src/ui/gui/retroachievements_page.slint:18 -msgctxt "RAData" -msgid "Not currently logged in" -msgstr "Momenteel niet ingelogd" +#: src/ui/gui/input_profile.slint:10 +msgctxt "InputProfileDialog" +msgid "Create/Modify Input Profile" +msgstr "Invoerprofiel maken/wijzigen" -#: src/ui/gui/retroachievements_page.slint:26 -msgctxt "RetroAchievements" -msgid "RetroAchievements" -msgstr "RetroAchievements" +#: src/ui/gui/input_profile.slint:18 +msgctxt "InputProfileDialog" +msgid "Enter profile name to create or modify" +msgstr "Profielnaam invoeren om aan te maken of te wijzigen" -#: src/ui/gui/retroachievements_page.slint:33 -msgctxt "RetroAchievements" -msgid "Enabled" -msgstr "Ingeschakeld" +#: src/ui/gui/input_profile.slint:29 +msgctxt "InputProfileDialog" +msgid "Deadzone Percentage" +msgstr "Dode-zonepercentage" -#: src/ui/gui/retroachievements_page.slint:51 -msgctxt "RetroAchievements" -msgid "Hardcore mode" -msgstr "Hardcore-modus" +#: src/ui/gui/input_profile.slint:51 +msgctxt "InputProfileDialog" +msgid "Use DirectInput" +msgstr "DirectInput gebruiken" -#: src/ui/gui/retroachievements_page.slint:63 -msgctxt "RetroAchievements" -msgid "Challenge Indicators" -msgstr "Challenge-indicatoren" - -#: src/ui/gui/retroachievements_page.slint:75 -msgctxt "RetroAchievements" -msgid "Leaderboard Trackers" -msgstr "Leaderboard-trackers" - -#: src/ui/gui/retroachievements_page.slint:92 -msgctxt "RetroAchievements" -msgid "View Profile" -msgstr "Profiel bekijken" - -#: src/ui/gui/retroachievements_page.slint:102 -msgctxt "RetroAchievements" -msgid "Username" -msgstr "Gebruikersnaam" - -#: src/ui/gui/retroachievements_page.slint:112 -msgctxt "RetroAchievements" -msgid "Password" -msgstr "Wachtwoord" - -#: src/ui/gui/retroachievements_page.slint:121 -msgctxt "RetroAchievements" -msgid "Login" -msgstr "Inloggen" - -#: src/ui/gui/retroachievements_page.slint:137 -msgctxt "RetroAchievements" -msgid "View Supported Games" -msgstr "Ondersteunde spellen bekijken" +#: src/ui/gui/input_profile.slint:61 +msgctxt "InputProfileDialog" +msgid "Start Profile Creation Wizard" +msgstr "Wizard voor profiel maken starten" diff --git a/data/translations/pt_BR/LC_MESSAGES/gopher64.po b/data/translations/pt_BR/LC_MESSAGES/gopher64.po index 94ecfc54..e1bbb715 100644 --- a/data/translations/pt_BR/LC_MESSAGES/gopher64.po +++ b/data/translations/pt_BR/LC_MESSAGES/gopher64.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2026-05-11 18:10-3000\n" +"POT-Creation-Date: 2026-05-14 13:42+0000\n" "PO-Revision-Date: 2026-05-11 18:11-3000\n" "Last-Translator: EDUARDO CARVALHO \n" "Language-Team: LANGUAGE \n" @@ -107,31 +107,6 @@ msgctxt "ControllerConfig" msgid "Controller" msgstr "Controle" -#: src/ui/gui/input_profile.slint:10 -msgctxt "InputProfileDialog" -msgid "Create/Modify Input Profile" -msgstr "Criar/Modificar Perfil de Comandos" - -#: src/ui/gui/input_profile.slint:18 -msgctxt "InputProfileDialog" -msgid "Enter profile name to create or modify" -msgstr "Insira o nome de perfil para criar ou modificar" - -#: src/ui/gui/input_profile.slint:29 -msgctxt "InputProfileDialog" -msgid "Deadzone Percentage" -msgstr "Porcentagem de Zona-morta" - -#: src/ui/gui/input_profile.slint:51 -msgctxt "InputProfileDialog" -msgid "Use DirectInput" -msgstr "Usar DirectInput" - -#: src/ui/gui/input_profile.slint:61 -msgctxt "InputProfileDialog" -msgid "Start Profile Creation Wizard" -msgstr "Iniciar Assistente de Criação de Perfil" - #: src/ui/gui/localgame_page.slint:18 msgctxt "LocalGame" msgid "Local Game" @@ -242,42 +217,42 @@ msgctxt "VruDialog" msgid "What Would You Like To Say?" msgstr "O que você quer falar?" -#: src/ui/gui/appwindow.slint:94 +#: src/ui/gui/appwindow.slint:95 msgctxt "Menu" msgid "Local Game" msgstr "Jogo Local" -#: src/ui/gui/appwindow.slint:95 +#: src/ui/gui/appwindow.slint:96 msgctxt "Menu" msgid "Controller Config" msgstr "Configurar Controle" -#: src/ui/gui/appwindow.slint:96 +#: src/ui/gui/appwindow.slint:97 msgctxt "Menu" msgid "Netplay" msgstr "Netplay" -#: src/ui/gui/appwindow.slint:97 +#: src/ui/gui/appwindow.slint:98 msgctxt "Menu" msgid "Cheats" msgstr "Trapaças" -#: src/ui/gui/appwindow.slint:98 +#: src/ui/gui/appwindow.slint:99 msgctxt "Menu" msgid "RetroAchievements" msgstr "RetroAchievements" -#: src/ui/gui/appwindow.slint:99 +#: src/ui/gui/appwindow.slint:100 msgctxt "Menu" msgid "Settings" msgstr "Configurações" -#: src/ui/gui/appwindow.slint:100 +#: src/ui/gui/appwindow.slint:101 msgctxt "Menu" msgid "About" msgstr "Sobre" -#: src/ui/gui/appwindow.slint:194 +#: src/ui/gui/appwindow.slint:195 msgctxt "ErrorDialog" msgid "Error" msgstr "Erro" @@ -331,7 +306,9 @@ msgstr "Selecionar ROM" msgctxt "NetplayCreate" msgid "" "This game has cheats enabled. Cheats will be synchronized with other players." -msgstr "Este jogo tem trapaças habilitadas. As trapaças serão sincronizadas com outros jogadores." +msgstr "" +"Este jogo tem trapaças habilitadas. As trapaças serão sincronizadas com " +"outros jogadores." #: src/ui/gui/netplay_create.slint:103 msgctxt "NetplayCreate" @@ -346,7 +323,8 @@ msgstr "Criando Servidor" #: src/ui/gui/netplay_create.slint:128 msgctxt "DispatcherDialog" msgid "Creating server, please wait...This may take about 30 seconds." -msgstr "Criando servidor, por favor aguarde...Isto poderá levar até 30 segundos." +msgstr "" +"Criando servidor, por favor aguarde...Isto poderá levar até 30 segundos." #: src/ui/gui/netplay_join.slint:5 msgctxt "NetplayJoin" @@ -381,7 +359,8 @@ msgstr "Clique em uma sessão abaixo para selecionar" #: src/ui/gui/netplay_join.slint:67 msgctxt "NetplayJoin" msgid "No sessions available. Please refresh to check again." -msgstr "Sem sessões disponíveis. Por favor recarregue para verificar novamente." +msgstr "" +"Sem sessões disponíveis. Por favor recarregue para verificar novamente." #: src/ui/gui/netplay_join.slint:73 msgctxt "NetplayJoin" @@ -428,6 +407,66 @@ msgctxt "NetplayJoin" msgid "Join Session" msgstr "Entrar na Sessão" +#: src/ui/gui/retroachievements_page.slint:19 +msgctxt "RAData" +msgid "Not currently logged in" +msgstr "Não está logado." + +#: src/ui/gui/retroachievements_page.slint:27 +msgctxt "RetroAchievements" +msgid "RetroAchievements" +msgstr "RetroAchievements" + +#: src/ui/gui/retroachievements_page.slint:34 +msgctxt "RetroAchievements" +msgid "Enabled" +msgstr "Habilitado" + +#: src/ui/gui/retroachievements_page.slint:52 +msgctxt "RetroAchievements" +msgid "Hardcore mode" +msgstr "Modo Hardcore" + +#: src/ui/gui/retroachievements_page.slint:64 +msgctxt "RetroAchievements" +msgid "Challenge Indicators" +msgstr "Indicadores de Desafio" + +#: src/ui/gui/retroachievements_page.slint:76 +msgctxt "RetroAchievements" +msgid "Leaderboard Trackers" +msgstr "Rastreadores de Tabela" + +#: src/ui/gui/retroachievements_page.slint:88 +msgctxt "RetroAchievements" +msgid "Discord Rich Presence" +msgstr "Rich Presence no Discord" + +#: src/ui/gui/retroachievements_page.slint:105 +msgctxt "RetroAchievements" +msgid "View Profile" +msgstr "Ver Perfil" + +#: src/ui/gui/retroachievements_page.slint:115 +msgctxt "RetroAchievements" +msgid "Username" +msgstr "Usuário" + +#: src/ui/gui/retroachievements_page.slint:125 +msgctxt "RetroAchievements" +msgid "Password" +msgstr "Senha" + +#: src/ui/gui/retroachievements_page.slint:134 +msgctxt "RetroAchievements" +msgid "Login" +msgstr "Login" + +#: src/ui/gui/retroachievements_page.slint:150 +msgctxt "RetroAchievements" +msgid "View Supported Games" +msgstr "Ver Jogos com Suporte" + #: src/ui/gui/netplay_wait.slint:14 msgctxt "NetplayWait" msgid "Netplay: Waiting Room" @@ -483,57 +522,27 @@ msgctxt "NetplayWait" msgid "Start Game" msgstr "Iniciar jogo" -#: src/ui/gui/retroachievements_page.slint:18 -msgctxt "RAData" -msgid "Not currently logged in" -msgstr "Não está logado." +#: src/ui/gui/input_profile.slint:10 +msgctxt "InputProfileDialog" +msgid "Create/Modify Input Profile" +msgstr "Criar/Modificar Perfil de Comandos" -#: src/ui/gui/retroachievements_page.slint:26 -msgctxt "RetroAchievements" -msgid "RetroAchievements" -msgstr "RetroAchievements" +#: src/ui/gui/input_profile.slint:18 +msgctxt "InputProfileDialog" +msgid "Enter profile name to create or modify" +msgstr "Insira o nome de perfil para criar ou modificar" -#: src/ui/gui/retroachievements_page.slint:33 -msgctxt "RetroAchievements" -msgid "Enabled" -msgstr "Habilitado" +#: src/ui/gui/input_profile.slint:29 +msgctxt "InputProfileDialog" +msgid "Deadzone Percentage" +msgstr "Porcentagem de Zona-morta" -#: src/ui/gui/retroachievements_page.slint:51 -msgctxt "RetroAchievements" -msgid "Hardcore mode" -msgstr "Modo Hardcore" +#: src/ui/gui/input_profile.slint:51 +msgctxt "InputProfileDialog" +msgid "Use DirectInput" +msgstr "Usar DirectInput" -#: src/ui/gui/retroachievements_page.slint:63 -msgctxt "RetroAchievements" -msgid "Challenge Indicators" -msgstr "Indicadores de Desafio" - -#: src/ui/gui/retroachievements_page.slint:75 -msgctxt "RetroAchievements" -msgid "Leaderboard Trackers" -msgstr "Rastreadores de Tabela" - -#: src/ui/gui/retroachievements_page.slint:92 -msgctxt "RetroAchievements" -msgid "View Profile" -msgstr "Ver Perfil" - -#: src/ui/gui/retroachievements_page.slint:102 -msgctxt "RetroAchievements" -msgid "Username" -msgstr "Usuário" - -#: src/ui/gui/retroachievements_page.slint:112 -msgctxt "RetroAchievements" -msgid "Password" -msgstr "Senha" - -#: src/ui/gui/retroachievements_page.slint:121 -msgctxt "RetroAchievements" -msgid "Login" -msgstr "Login" - -#: src/ui/gui/retroachievements_page.slint:137 -msgctxt "RetroAchievements" -msgid "View Supported Games" -msgstr "Ver Jogos com Suporte" +#: src/ui/gui/input_profile.slint:61 +msgctxt "InputProfileDialog" +msgid "Start Profile Creation Wizard" +msgstr "Iniciar Assistente de Criação de Perfil" diff --git a/data/translations/ru/LC_MESSAGES/gopher64.po b/data/translations/ru/LC_MESSAGES/gopher64.po index 80c4a6bf..424495e4 100644 --- a/data/translations/ru/LC_MESSAGES/gopher64.po +++ b/data/translations/ru/LC_MESSAGES/gopher64.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: gopher64\n" -"POT-Creation-Date: 2026-05-10 18:36+0000\n" +"POT-Creation-Date: 2026-05-14 13:42+0000\n" "PO-Revision-Date: 2026-05-11 12:00+0000\n" "Last-Translator: \n" "Language-Team: Russian\n" @@ -107,31 +107,6 @@ msgctxt "ControllerConfig" msgid "Controller" msgstr "Контроллер" -#: src/ui/gui/input_profile.slint:10 -msgctxt "InputProfileDialog" -msgid "Create/Modify Input Profile" -msgstr "Создать/изменить профиль ввода" - -#: src/ui/gui/input_profile.slint:18 -msgctxt "InputProfileDialog" -msgid "Enter profile name to create or modify" -msgstr "Введите имя профиля для создания или изменения" - -#: src/ui/gui/input_profile.slint:29 -msgctxt "InputProfileDialog" -msgid "Deadzone Percentage" -msgstr "Процент мёртвой зоны" - -#: src/ui/gui/input_profile.slint:51 -msgctxt "InputProfileDialog" -msgid "Use DirectInput" -msgstr "Использовать DirectInput" - -#: src/ui/gui/input_profile.slint:61 -msgctxt "InputProfileDialog" -msgid "Start Profile Creation Wizard" -msgstr "Запустить мастер создания профиля" - #: src/ui/gui/localgame_page.slint:18 msgctxt "LocalGame" msgid "Local Game" @@ -242,42 +217,42 @@ msgctxt "VruDialog" msgid "What Would You Like To Say?" msgstr "Что вы хотите сказать?" -#: src/ui/gui/appwindow.slint:94 +#: src/ui/gui/appwindow.slint:95 msgctxt "Menu" msgid "Local Game" msgstr "Локальная игра" -#: src/ui/gui/appwindow.slint:95 +#: src/ui/gui/appwindow.slint:96 msgctxt "Menu" msgid "Controller Config" msgstr "Настройка контроллера" -#: src/ui/gui/appwindow.slint:96 +#: src/ui/gui/appwindow.slint:97 msgctxt "Menu" msgid "Netplay" msgstr "Сетевая игра" -#: src/ui/gui/appwindow.slint:97 +#: src/ui/gui/appwindow.slint:98 msgctxt "Menu" msgid "Cheats" msgstr "Читы" -#: src/ui/gui/appwindow.slint:98 +#: src/ui/gui/appwindow.slint:99 msgctxt "Menu" msgid "RetroAchievements" msgstr "RetroAchievements" -#: src/ui/gui/appwindow.slint:99 +#: src/ui/gui/appwindow.slint:100 msgctxt "Menu" msgid "Settings" msgstr "Настройки" -#: src/ui/gui/appwindow.slint:100 +#: src/ui/gui/appwindow.slint:101 msgctxt "Menu" msgid "About" msgstr "О программе" -#: src/ui/gui/appwindow.slint:194 +#: src/ui/gui/appwindow.slint:195 msgctxt "ErrorDialog" msgid "Error" msgstr "Ошибка" @@ -383,8 +358,7 @@ msgstr "Нажмите на сессию ниже, чтобы выбрать е #: src/ui/gui/netplay_join.slint:67 msgctxt "NetplayJoin" msgid "No sessions available. Please refresh to check again." -msgstr "" -"Нет доступных сессий. Пожалуйста, обновите, чтобы проверить снова." +msgstr "Нет доступных сессий. Пожалуйста, обновите, чтобы проверить снова." #: src/ui/gui/netplay_join.slint:73 msgctxt "NetplayJoin" @@ -431,6 +405,66 @@ msgctxt "NetplayJoin" msgid "Join Session" msgstr "Присоединиться к сессии" +#: src/ui/gui/retroachievements_page.slint:19 +msgctxt "RAData" +msgid "Not currently logged in" +msgstr "В данный момент не выполнен вход" + +#: src/ui/gui/retroachievements_page.slint:27 +msgctxt "RetroAchievements" +msgid "RetroAchievements" +msgstr "RetroAchievements" + +#: src/ui/gui/retroachievements_page.slint:34 +msgctxt "RetroAchievements" +msgid "Enabled" +msgstr "Включено" + +#: src/ui/gui/retroachievements_page.slint:52 +msgctxt "RetroAchievements" +msgid "Hardcore mode" +msgstr "Хардкорный режим" + +#: src/ui/gui/retroachievements_page.slint:64 +msgctxt "RetroAchievements" +msgid "Challenge Indicators" +msgstr "Индикаторы испытаний" + +#: src/ui/gui/retroachievements_page.slint:76 +msgctxt "RetroAchievements" +msgid "Leaderboard Trackers" +msgstr "Трекеры таблицы лидеров" + +#: src/ui/gui/retroachievements_page.slint:88 +msgctxt "RetroAchievements" +msgid "Discord Rich Presence" +msgstr "Расширенный статус Discord" + +#: src/ui/gui/retroachievements_page.slint:105 +msgctxt "RetroAchievements" +msgid "View Profile" +msgstr "Просмотреть профиль" + +#: src/ui/gui/retroachievements_page.slint:115 +msgctxt "RetroAchievements" +msgid "Username" +msgstr "Имя пользователя" + +#: src/ui/gui/retroachievements_page.slint:125 +msgctxt "RetroAchievements" +msgid "Password" +msgstr "Пароль" + +#: src/ui/gui/retroachievements_page.slint:134 +msgctxt "RetroAchievements" +msgid "Login" +msgstr "Войти" + +#: src/ui/gui/retroachievements_page.slint:150 +msgctxt "RetroAchievements" +msgid "View Supported Games" +msgstr "Просмотреть поддерживаемые игры" + #: src/ui/gui/netplay_wait.slint:14 msgctxt "NetplayWait" msgid "Netplay: Waiting Room" @@ -486,57 +520,27 @@ msgctxt "NetplayWait" msgid "Start Game" msgstr "Начать игру" -#: src/ui/gui/retroachievements_page.slint:18 -msgctxt "RAData" -msgid "Not currently logged in" -msgstr "В данный момент не выполнен вход" +#: src/ui/gui/input_profile.slint:10 +msgctxt "InputProfileDialog" +msgid "Create/Modify Input Profile" +msgstr "Создать/изменить профиль ввода" -#: src/ui/gui/retroachievements_page.slint:26 -msgctxt "RetroAchievements" -msgid "RetroAchievements" -msgstr "RetroAchievements" +#: src/ui/gui/input_profile.slint:18 +msgctxt "InputProfileDialog" +msgid "Enter profile name to create or modify" +msgstr "Введите имя профиля для создания или изменения" -#: src/ui/gui/retroachievements_page.slint:33 -msgctxt "RetroAchievements" -msgid "Enabled" -msgstr "Включено" +#: src/ui/gui/input_profile.slint:29 +msgctxt "InputProfileDialog" +msgid "Deadzone Percentage" +msgstr "Процент мёртвой зоны" -#: src/ui/gui/retroachievements_page.slint:51 -msgctxt "RetroAchievements" -msgid "Hardcore mode" -msgstr "Хардкорный режим" +#: src/ui/gui/input_profile.slint:51 +msgctxt "InputProfileDialog" +msgid "Use DirectInput" +msgstr "Использовать DirectInput" -#: src/ui/gui/retroachievements_page.slint:63 -msgctxt "RetroAchievements" -msgid "Challenge Indicators" -msgstr "Индикаторы испытаний" - -#: src/ui/gui/retroachievements_page.slint:75 -msgctxt "RetroAchievements" -msgid "Leaderboard Trackers" -msgstr "Трекеры таблицы лидеров" - -#: src/ui/gui/retroachievements_page.slint:92 -msgctxt "RetroAchievements" -msgid "View Profile" -msgstr "Просмотреть профиль" - -#: src/ui/gui/retroachievements_page.slint:102 -msgctxt "RetroAchievements" -msgid "Username" -msgstr "Имя пользователя" - -#: src/ui/gui/retroachievements_page.slint:112 -msgctxt "RetroAchievements" -msgid "Password" -msgstr "Пароль" - -#: src/ui/gui/retroachievements_page.slint:121 -msgctxt "RetroAchievements" -msgid "Login" -msgstr "Войти" - -#: src/ui/gui/retroachievements_page.slint:137 -msgctxt "RetroAchievements" -msgid "View Supported Games" -msgstr "Просмотреть поддерживаемые игры" +#: src/ui/gui/input_profile.slint:61 +msgctxt "InputProfileDialog" +msgid "Start Profile Creation Wizard" +msgstr "Запустить мастер создания профиля" diff --git a/retroachievements/retroachievements.c b/retroachievements/retroachievements.c index 7f9b0176..b06d81b5 100644 --- a/retroachievements/retroachievements.c +++ b/retroachievements/retroachievements.c @@ -22,6 +22,8 @@ static bool g_challenge = false; static bool g_leaderboard = false; static rc_client_leaderboard_list_t *g_leaderboard_list = NULL; +static char g_rich_presence_buffer[512]; + static uint32_t read_memory(uint32_t address, uint8_t *buffer, uint32_t num_bytes, rc_client_t *client) { if (address + num_bytes > g_rdram_size) @@ -144,6 +146,9 @@ void ra_welcome() { } const rc_client_game_t *game = rc_client_get_game_info(g_client); + if (!game) { + return; + } rc_client_user_game_summary_t summary; rc_client_get_user_game_summary(g_client, &summary); @@ -163,6 +168,17 @@ void ra_welcome() { rdp_onscreen_message(buffer, MESSAGE_LONG); } +void ra_get_game_info(const char **game_title, const char **game_image_url) { + const rc_client_game_t *game = rc_client_get_game_info(g_client); + if (!game) { + *game_title = NULL; + *game_image_url = NULL; + return; + } + *game_title = game->title; + *game_image_url = game->badge_url; +} + void ra_load_game(const uint8_t *rom, size_t rom_size, void *userdata) { rc_client_begin_identify_and_load_game(g_client, RC_CONSOLE_NINTENDO_64, NULL, rom, rom_size, load_game_callback, @@ -344,6 +360,15 @@ void ra_do_frame() { rc_client_do_frame(g_client); } void ra_do_idle() { rc_client_idle(g_client); } +const char *ra_get_rich_presence() { + size_t size = rc_client_get_rich_presence_message( + g_client, g_rich_presence_buffer, sizeof(g_rich_presence_buffer)); + if (size == 0) { + return NULL; + } + return g_rich_presence_buffer; +} + size_t ra_state_size() { return rc_client_progress_size(g_client); } void ra_save_state(uint8_t *state, size_t state_size) { diff --git a/retroachievements/retroachievements.h b/retroachievements/retroachievements.h index cee9ca04..4fb06902 100644 --- a/retroachievements/retroachievements.h +++ b/retroachievements/retroachievements.h @@ -23,6 +23,9 @@ size_t ra_state_size(); void ra_save_state(uint8_t *state, size_t state_size); void ra_load_state(const uint8_t *state, size_t state_size); +const char *ra_get_rich_presence(); +void ra_get_game_info(const char **game_title, const char **game_image_url); + #ifdef __cplusplus extern "C" { #endif diff --git a/src/device/cart.rs b/src/device/cart.rs index 1e405b19..c8db89f7 100644 --- a/src/device/cart.rs +++ b/src/device/cart.rs @@ -148,7 +148,9 @@ fn eeprom_write_block(device: &mut device::Device, block: usize, offset: usize, fn time2data(device: &mut device::Device, offset: usize) { let timestamp = device.cart.rtc_timestamp + device.vi.elapsed_time as i64; - let now = chrono::DateTime::from_timestamp(timestamp, 0).unwrap(); + let now = chrono::DateTime::from_timestamp(timestamp, 0) + .unwrap() + .with_timezone(&chrono::Local); device.pif.ram[offset] = byte2bcd(now.second()); device.pif.ram[offset + 1] = byte2bcd(now.minute()); diff --git a/src/device/cart/rom.rs b/src/device/cart/rom.rs index bded4f64..94f2c1e4 100644 --- a/src/device/cart/rom.rs +++ b/src/device/cart/rom.rs @@ -122,8 +122,10 @@ pub fn dma_write( } pub fn init(device: &mut device::Device, rom_file: &[u8]) { - let now: chrono::DateTime = chrono::Local::now(); - device.cart.rtc_timestamp = now.naive_local().and_utc().timestamp(); + device.cart.rtc_timestamp = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_secs() as i64; if let Some(netplay) = &mut device.netplay { if netplay.player_number == 0 { netplay::send_rtc(netplay, device.cart.rtc_timestamp); diff --git a/src/main.rs b/src/main.rs index 7c7153c3..9c7ca5bb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -111,6 +111,8 @@ struct Args { help = "Enable Leaderboard Trackers for RetroAchievements" )] ra_leaderboard: bool, + #[arg(long = "discord-rich-presence", help = "Enable Discord Rich Presence")] + discord_rich_presence: bool, } #[tokio::main(worker_threads = 4)] @@ -172,6 +174,7 @@ async fn main() -> std::io::Result<()> { }; let mut shutdown_tx = None; + let mut usb_handle = None; if let Some(peer_addr) = args.netplay_peer_addr && let Some(player_number) = args.netplay_player_number @@ -190,7 +193,7 @@ async fn main() -> std::io::Result<()> { } if device.ui.config.emulation.usb { - (shutdown_tx, device.ui.usb) = ui::usb::init(); + (shutdown_tx, usb_handle, device.ui.usb) = ui::usb::init(); } if let Some(username) = args.ra_username { @@ -217,7 +220,13 @@ async fn main() -> std::io::Result<()> { } } - retroachievements::load_game(&rom_contents, rom_contents.len()).await; + let (discord_watch_tx, discord_handle) = retroachievements::load_game( + &rom_contents, + rom_contents.len(), + args.discord_rich_presence, + ) + .await; + device::run_game( &mut device, &rom_contents, @@ -228,7 +237,8 @@ async fn main() -> std::io::Result<()> { load_savestate_slot: args.load_state, }, ); - retroachievements::shutdown_client(); + + retroachievements::shutdown_client(discord_watch_tx, discord_handle).await; if device.netplay.is_some() { netplay::close(&mut device); @@ -247,7 +257,7 @@ async fn main() -> std::io::Result<()> { } } if let Some(shutdown_tx) = &shutdown_tx { - ui::usb::close(shutdown_tx); + ui::usb::close(shutdown_tx, usb_handle).await; } } else if std::env::args().count() > 1 { let mut config = ui::config::Config::new(); @@ -302,7 +312,7 @@ async fn main() -> std::io::Result<()> { { retroachievements::init_client(false, false, false); ui::gui::app_window(); - retroachievements::shutdown_client(); + retroachievements::shutdown_client(None, None).await; } } diff --git a/src/retroachievements.rs b/src/retroachievements.rs index f46ab51a..6bd58483 100644 --- a/src/retroachievements.rs +++ b/src/retroachievements.rs @@ -2,6 +2,8 @@ include!(concat!(env!("OUT_DIR"), "/retroachievements_bindings.rs")); use crate::ui; +use discord_rich_presence::DiscordIpc; + #[derive(serde::Serialize, serde::Deserialize)] pub struct RAConfig { pub username: String, @@ -10,6 +12,7 @@ pub struct RAConfig { pub hardcore: bool, pub challenge: bool, pub leaderboard: bool, + pub rich_presence: bool, } #[unsafe(no_mangle)] @@ -42,6 +45,7 @@ pub extern "C" fn store_retroachievements_credentials( hardcore: result.hardcore, challenge: result.challenge, leaderboard: result.leaderboard, + rich_presence: result.rich_presence, } } else { RAConfig { @@ -51,6 +55,7 @@ pub extern "C" fn store_retroachievements_credentials( hardcore: false, challenge: false, leaderboard: false, + rich_presence: false, } }; let f = std::fs::File::create(&file_path).unwrap(); @@ -132,13 +137,42 @@ pub extern "C" fn rust_server_call( }); } -pub async fn load_game(rom: &[u8], rom_size: usize) { +pub async fn load_game( + rom: &[u8], + rom_size: usize, + discord_rich_presence: bool, +) -> ( + Option>, + Option>, +) { let (tx, rx) = tokio::sync::oneshot::channel::(); unsafe { let tx_ptr = Box::into_raw(Box::new(tx)) as *mut std::ffi::c_void; ra_load_game(rom.as_ptr(), rom_size, tx_ptr); }; rx.await.unwrap(); + let mut c_title = std::ptr::null(); + let mut c_image_url = std::ptr::null(); + unsafe { ra_get_game_info(&mut c_title, &mut c_image_url) }; + if !discord_rich_presence || c_title.is_null() || c_image_url.is_null() { + (None, None) + } else { + let (discord_watch_tx, discord_watch_rx) = tokio::sync::watch::channel(()); + ( + Some(discord_watch_tx), + Some(init_rich_presence( + discord_watch_rx, + unsafe { std::ffi::CStr::from_ptr(c_title) } + .to_str() + .unwrap() + .to_string(), + unsafe { std::ffi::CStr::from_ptr(c_image_url) } + .to_str() + .unwrap() + .to_string(), + )), + ) + } } pub fn unload_game() { @@ -149,6 +183,20 @@ pub fn welcome() { unsafe { ra_welcome() }; } +pub fn get_rich_presence() -> Option { + let c_rich_presence = unsafe { ra_get_rich_presence() }; + if c_rich_presence.is_null() { + None + } else { + Some( + unsafe { std::ffi::CStr::from_ptr(c_rich_presence) } + .to_str() + .unwrap() + .to_string(), + ) + } +} + pub fn set_rdram(rdram: *const u8, rdram_size: usize) { unsafe { ra_set_rdram(rdram, rdram_size) }; } @@ -165,7 +213,16 @@ pub fn init_client(hardcore: bool, challenge: bool, leaderboard: bool) { unsafe { ra_init_client(hardcore, challenge, leaderboard) }; } -pub fn shutdown_client() { +pub async fn shutdown_client( + discord_watch_tx: Option>, + discord_handle: Option>, +) { + if let Some(discord_handle) = discord_handle + && let Some(discord_watch_tx) = discord_watch_tx + { + let _ = discord_watch_tx.send(()); + discord_handle.await.unwrap(); + } unsafe { ra_shutdown_client() }; } @@ -237,3 +294,52 @@ pub fn save_state(state: *mut u8, state_size: usize) { pub fn load_state(state: *const u8, state_size: usize) { unsafe { ra_load_state(state, state_size) }; } + +pub fn init_rich_presence( + mut discord_watch_rx: tokio::sync::watch::Receiver<()>, + game_title: String, + game_image_url: String, +) -> tokio::task::JoinHandle<()> { + tokio::spawn(async move { + let mut client = discord_rich_presence::DiscordIpcClient::new("1395482226463870986"); + let timestamps = discord_rich_presence::activity::Timestamps::new().start( + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_secs() as i64, + ); + + if let Err(e) = client.connect() { + eprintln!("Failed to connect to Discord: {e}"); + return; + } + loop { + tokio::select! { + _ = discord_watch_rx.changed() => { + if let Err(e) = client.clear_activity() { + eprintln!("Failed to clear Discord activity: {e}"); + } + if let Err(e) = client.close() { + eprintln!("Failed to close Discord: {e}"); + } + return; + } + _ = tokio::time::sleep(std::time::Duration::from_secs(10)) => { + if let Some(rich_presence) = get_rich_presence() + && let Err(e) = client.set_activity( + discord_rich_presence::activity::Activity::new() + .details(game_title.clone()) + .state(rich_presence) + .assets( + discord_rich_presence::activity::Assets::new() + .small_image(game_image_url.clone()), + ).timestamps(timestamps.clone()), + ) + { + eprintln!("Failed to set Discord activity: {e}"); + } + } + } + } + }) +} diff --git a/src/ui/gui.rs b/src/ui/gui.rs index ab8bfda1..b4e08cfd 100644 --- a/src/ui/gui.rs +++ b/src/ui/gui.rs @@ -25,6 +25,7 @@ pub struct RASettings { pub hardcore: bool, pub challenge: bool, pub leaderboard: bool, + pub rich_presence: bool, } fn check_latest_version(weak: slint::Weak) { @@ -75,6 +76,7 @@ fn run_with_path(weak: slint::Weak, path: std::path::PathBuf) { hardcore: handle.get_ra_hardcore(), challenge: handle.get_ra_challenge(), leaderboard: handle.get_ra_leaderboard(), + rich_presence: handle.get_ra_rich_presence(), }, weak2, ); @@ -586,6 +588,9 @@ pub fn run_rom( if ra_settings.leaderboard { command.args(["--ra-leaderboard"]); } + if ra_settings.rich_presence { + command.args(["--discord-rich-presence"]); + } } let success = command @@ -645,6 +650,7 @@ fn open_rom(app: &AppWindow) { let ra_hardcore = app.get_ra_hardcore(); let ra_challenge = app.get_ra_challenge(); let ra_leaderboard = app.get_ra_leaderboard(); + let ra_rich_presence = app.get_ra_rich_presence(); let weak = app.as_weak(); tokio::spawn(async move { @@ -663,6 +669,7 @@ fn open_rom(app: &AppWindow) { hardcore: ra_hardcore, challenge: ra_challenge, leaderboard: ra_leaderboard, + rich_presence: ra_rich_presence, }, weak, ); diff --git a/src/ui/gui/appwindow.slint b/src/ui/gui/appwindow.slint index e3af4506..b8f28d5a 100644 --- a/src/ui/gui/appwindow.slint +++ b/src/ui/gui/appwindow.slint @@ -40,7 +40,7 @@ export component AppWindow inherits Window { callback ra_button_clicked(string); callback ra_games_clicked; callback ra_show_profile_clicked; - callback ra_toggled(bool,bool,bool,bool); + callback ra_toggled(bool,bool,bool,bool,bool); callback controller_window_created; in property version <=> AboutData.version; in property has_update <=> AboutData.has_update; @@ -53,6 +53,7 @@ export component AppWindow inherits Window { in-out property ra_hardcore <=> RAData.hardcore; in-out property ra_challenge <=> RAData.challenge; in-out property ra_leaderboard <=> RAData.leaderboard; + in-out property ra_rich_presence <=> RAData.rich_presence; in-out property ra_softcore_only <=> RAData.ra_softcore_only; out property ra_not_logged_in <=> RAData.not_logged_in; in-out property integer_scaling <=> SettingsData.integer_scaling; @@ -155,8 +156,8 @@ export component AppWindow inherits Window { ra_button_clicked(password) => { ra_button_clicked(password); } - ra_toggled(enabled,hardcore,challenge,leaderboard) => { - ra_toggled(enabled,hardcore,challenge,leaderboard); + ra_toggled(enabled,hardcore,challenge,leaderboard,rich_presence) => { + ra_toggled(enabled,hardcore,challenge,leaderboard,rich_presence); } ra_games_clicked => { ra_games_clicked(); diff --git a/src/ui/gui/retroachievements_page.slint b/src/ui/gui/retroachievements_page.slint index 0bb47632..4f98e13a 100644 --- a/src/ui/gui/retroachievements_page.slint +++ b/src/ui/gui/retroachievements_page.slint @@ -9,6 +9,7 @@ export global RAData { in-out property hardcore; in-out property challenge; in-out property leaderboard; + in-out property rich_presence; in-out property ra_logging_in; in-out property ra_show_profile; in-out property ra_softcore_only; @@ -20,7 +21,7 @@ export global RAData { export component RetroAchievements inherits Page { callback ra_button_clicked(string); - callback ra_toggled(bool,bool,bool,bool); + callback ra_toggled(bool,bool,bool,bool,bool); callback ra_games_clicked; callback ra_show_profile_clicked; title: @tr("RetroAchievements"); @@ -41,7 +42,7 @@ export component RetroAchievements inherits Page { RAData.current_user_message = RAData.not_logged_in; RAData.ra_show_profile = false; } - ra_toggled(RAData.enabled,RAData.hardcore,RAData.challenge,RAData.leaderboard); + ra_toggled(RAData.enabled,RAData.hardcore,RAData.challenge,RAData.leaderboard,RAData.rich_presence); } } } @@ -53,7 +54,7 @@ export component RetroAchievements inherits Page { enabled: RAData.enabled; toggled => { RAData.hardcore = self.checked; - ra_toggled(RAData.enabled,RAData.hardcore,RAData.challenge,RAData.leaderboard); + ra_toggled(RAData.enabled,RAData.hardcore,RAData.challenge,RAData.leaderboard,RAData.rich_presence); } } } @@ -65,7 +66,7 @@ export component RetroAchievements inherits Page { enabled: RAData.enabled; toggled => { RAData.challenge = self.checked; - ra_toggled(RAData.enabled,RAData.hardcore,RAData.challenge,RAData.leaderboard); + ra_toggled(RAData.enabled,RAData.hardcore,RAData.challenge,RAData.leaderboard,RAData.rich_presence); } } } @@ -77,7 +78,19 @@ export component RetroAchievements inherits Page { enabled: RAData.enabled; toggled => { RAData.leaderboard = self.checked; - ra_toggled(RAData.enabled,RAData.hardcore,RAData.challenge,RAData.leaderboard); + ra_toggled(RAData.enabled,RAData.hardcore,RAData.challenge,RAData.leaderboard,RAData.rich_presence); + } + } + } + HorizontalBox { + alignment: start; + Switch { + text: @tr("Discord Rich Presence"); + checked: RAData.rich_presence; + enabled: RAData.enabled; + toggled => { + RAData.rich_presence = self.checked; + ra_toggled(RAData.enabled,RAData.hardcore,RAData.challenge,RAData.leaderboard,RAData.rich_presence); } } } diff --git a/src/ui/netplay.rs b/src/ui/netplay.rs index 15f5b66a..4707aaba 100644 --- a/src/ui/netplay.rs +++ b/src/ui/netplay.rs @@ -507,7 +507,11 @@ fn update_sessions(weak: slint::Weak) { { let (mut write, mut read) = socket.split(); - let now_utc = chrono::Utc::now().timestamp_millis().to_string(); + let now_utc = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_millis() + .to_string(); let hasher = Sha256::new().chain_update(&now_utc).chain_update(EMU_NAME); let request_rooms = NetplayMessage { message_type: "request_get_rooms".to_string(), @@ -623,7 +627,11 @@ fn create_session( weak: slint::Weak, ) { tokio::spawn(async move { - let now_utc = chrono::Utc::now().timestamp_millis().to_string(); + let now_utc = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_millis() + .to_string(); let hasher = Sha256::new().chain_update(&now_utc).chain_update(EMU_NAME); let mut features = std::collections::HashMap::new(); @@ -757,7 +765,11 @@ fn join_session( weak: slint::Weak, ) { tokio::spawn(async move { - let now_utc = chrono::Utc::now().timestamp_millis().to_string(); + let now_utc = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_millis() + .to_string(); let hasher = Sha256::new().chain_update(&now_utc).chain_update(EMU_NAME); let join_room = NetplayMessage { @@ -1227,6 +1239,7 @@ pub fn netplay_window(app: &AppWindow) { hardcore: handle.get_ra_hardcore(), challenge: handle.get_ra_challenge(), leaderboard: handle.get_ra_leaderboard(), + rich_presence: handle.get_ra_rich_presence(), }, handle.get_rom_dir(), weak_app, @@ -1251,6 +1264,7 @@ pub fn netplay_window(app: &AppWindow) { hardcore: handle.get_ra_hardcore(), challenge: handle.get_ra_challenge(), leaderboard: handle.get_ra_leaderboard(), + rich_presence: handle.get_ra_rich_presence(), }, weak_app, ); diff --git a/src/ui/retroachievements.rs b/src/ui/retroachievements.rs index 82aacf43..81dc5c5b 100644 --- a/src/ui/retroachievements.rs +++ b/src/ui/retroachievements.rs @@ -13,6 +13,7 @@ pub fn ra_window(app: &ui::gui::AppWindow) { app.set_ra_hardcore(result.hardcore); app.set_ra_challenge(result.challenge); app.set_ra_leaderboard(result.leaderboard); + app.set_ra_rich_presence(result.rich_presence); token = result.token; } else { app.set_ra_hardcore(true); @@ -46,14 +47,36 @@ pub fn ra_window(app: &ui::gui::AppWindow) { .unwrap(); }); - app.on_ra_toggled(move |enabled, hardcore, challenge, leaderboard| { - let file_path = ui::get_dirs().config_dir.join("retroachievements.json"); - let raconfig = if let Ok(ra_config) = std::fs::read(&file_path) - && let Ok(result) = - serde_json::from_slice::(ra_config.as_ref()) - { - if !enabled { - retroachievements::logout_user(); + app.on_ra_toggled( + move |enabled, hardcore, challenge, leaderboard, rich_presence| { + let file_path = ui::get_dirs().config_dir.join("retroachievements.json"); + let raconfig = if let Ok(ra_config) = std::fs::read(&file_path) + && let Ok(result) = + serde_json::from_slice::(ra_config.as_ref()) + { + if !enabled { + retroachievements::logout_user(); + retroachievements::RAConfig { + username: String::new(), + token: String::new(), + enabled, + hardcore, + challenge, + leaderboard, + rich_presence, + } + } else { + retroachievements::RAConfig { + username: result.username, + token: result.token, + enabled, + hardcore, + challenge, + leaderboard, + rich_presence, + } + } + } else { retroachievements::RAConfig { username: String::new(), token: String::new(), @@ -61,33 +84,16 @@ pub fn ra_window(app: &ui::gui::AppWindow) { hardcore, challenge, leaderboard, + rich_presence, } - } else { - retroachievements::RAConfig { - username: result.username, - token: result.token, - enabled, - hardcore, - challenge, - leaderboard, - } + }; + if let Ok(f) = std::fs::File::create(&file_path) + && let Err(e) = serde_json::to_writer_pretty(f, &raconfig) + { + eprintln!("Error writing RA config: {}", e); } - } else { - retroachievements::RAConfig { - username: String::new(), - token: String::new(), - enabled, - hardcore, - challenge, - leaderboard, - } - }; - if let Ok(f) = std::fs::File::create(&file_path) - && let Err(e) = serde_json::to_writer_pretty(f, &raconfig) - { - eprintln!("Error writing RA config: {}", e); - } - }); + }, + ); app.on_ra_games_clicked(move || { if let Err(e) = diff --git a/src/ui/usb.rs b/src/ui/usb.rs index 97d71e60..11c09862 100644 --- a/src/ui/usb.rs +++ b/src/ui/usb.rs @@ -127,7 +127,11 @@ async fn handle_connection( } } -pub fn init() -> (Option>, ui::Usb) { +pub fn init() -> ( + Option>, + Option>, + ui::Usb, +) { let (shutdown_tx, mut shutdown_rx) = tokio::sync::watch::channel(()); let (usb_tx, usb_rx): ( tokio::sync::broadcast::Sender, @@ -140,7 +144,7 @@ pub fn init() -> (Option>, ui::Usb) { let usb_tx_clone = usb_tx.clone(); let cart_rx_clone = cart_rx.resubscribe(); - tokio::spawn(async move { + let handle = tokio::spawn(async move { let listener = tokio::net::TcpListener::bind("localhost:64000") .await .unwrap(); @@ -162,6 +166,7 @@ pub fn init() -> (Option>, ui::Usb) { }); ( Some(shutdown_tx), + Some(handle), ui::Usb { usb_tx: Some(usb_tx_clone), cart_rx: Some(cart_rx_clone), @@ -169,8 +174,14 @@ pub fn init() -> (Option>, ui::Usb) { ) } -pub fn close(shutdown_tx: &tokio::sync::watch::Sender<()>) { +pub async fn close( + shutdown_tx: &tokio::sync::watch::Sender<()>, + usb_handle: Option>, +) { let _ = shutdown_tx.send(()); + if let Some(handle) = usb_handle { + handle.await.unwrap(); + } } pub fn send_to_usb(usb_tx: &tokio::sync::broadcast::Sender, buffer: UsbData) {