Add Discord Rich Presence (#888)

* add rich presence

* more

* more

* more

* more

* more

* more

* more

* more

* more

* update translations

* more
This commit is contained in:
Logan McNaughton
2026-05-14 16:30:36 +02:00
committed by GitHub
parent 40a29d927f
commit 8341ef5731
23 changed files with 1014 additions and 747 deletions
Generated
+26 -1
View File
@@ -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",
+1
View File
@@ -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"
+3 -1
View File
@@ -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
+90 -86
View File
@@ -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"
+93 -89
View File
@@ -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"
+91 -86
View File
@@ -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 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"
+84 -79
View File
@@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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 ""
+93 -89
View File
@@ -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 "プロファイル作成ウィザードを開始"
+90 -86
View File
@@ -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"
+96 -87
View File
@@ -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 <eduardotcarvalho@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\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"
+90 -86
View File
@@ -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 "Запустить мастер создания профиля"
+25
View File
@@ -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) {
+3
View File
@@ -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
+3 -1
View File
@@ -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());
+4 -2
View File
@@ -122,8 +122,10 @@ pub fn dma_write(
}
pub fn init(device: &mut device::Device, rom_file: &[u8]) {
let now: chrono::DateTime<chrono::Local> = 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);
+15 -5
View File
@@ -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;
}
}
+108 -2
View File
@@ -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<tokio::sync::watch::Sender<()>>,
Option<tokio::task::JoinHandle<()>>,
) {
let (tx, rx) = tokio::sync::oneshot::channel::<bool>();
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<String> {
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<tokio::sync::watch::Sender<()>>,
discord_handle: Option<tokio::task::JoinHandle<()>>,
) {
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}");
}
}
}
}
})
}
+7
View File
@@ -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<AppWindow>) {
@@ -75,6 +76,7 @@ fn run_with_path(weak: slint::Weak<AppWindow>, 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,
);
+4 -3
View File
@@ -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();
+18 -5
View File
@@ -9,6 +9,7 @@ export global RAData {
in-out property <bool> hardcore;
in-out property <bool> challenge;
in-out property <bool> leaderboard;
in-out property <bool> rich_presence;
in-out property <bool> ra_logging_in;
in-out property <bool> ra_show_profile;
in-out property <bool> 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);
}
}
}
+17 -3
View File
@@ -507,7 +507,11 @@ fn update_sessions(weak: slint::Weak<NetplayJoin>) {
{
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<NetplayCreate>,
) {
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<NetplayJoin>,
) {
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,
);
+39 -33
View File
@@ -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::<retroachievements::RAConfig>(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::<retroachievements::RAConfig>(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) =
+14 -3
View File
@@ -127,7 +127,11 @@ async fn handle_connection(
}
}
pub fn init() -> (Option<tokio::sync::watch::Sender<()>>, ui::Usb) {
pub fn init() -> (
Option<tokio::sync::watch::Sender<()>>,
Option<tokio::task::JoinHandle<()>>,
ui::Usb,
) {
let (shutdown_tx, mut shutdown_rx) = tokio::sync::watch::channel(());
let (usb_tx, usb_rx): (
tokio::sync::broadcast::Sender<UsbData>,
@@ -140,7 +144,7 @@ pub fn init() -> (Option<tokio::sync::watch::Sender<()>>, 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<tokio::sync::watch::Sender<()>>, 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<tokio::sync::watch::Sender<()>>, ui::Usb) {
)
}
pub fn close(shutdown_tx: &tokio::sync::watch::Sender<()>) {
pub async fn close(
shutdown_tx: &tokio::sync::watch::Sender<()>,
usb_handle: Option<tokio::task::JoinHandle<()>>,
) {
let _ = shutdown_tx.send(());
if let Some(handle) = usb_handle {
handle.await.unwrap();
}
}
pub fn send_to_usb(usb_tx: &tokio::sync::broadcast::Sender<UsbData>, buffer: UsbData) {