diff --git a/assets/locales.json b/assets/locales.json
index 0d84ad4c3..327c3994e 100644
--- a/assets/locales.json
+++ b/assets/locales.json
@@ -177,7 +177,7 @@
"es_ES": null,
"fr_FR": "Logiciel",
"he_IL": "תוכנה",
- "it_IT": "",
+ "it_IT": "Programma",
"ja_JP": "ソフトウェア",
"ko_KR": "소프트웨어",
"no_NO": "Programvare",
@@ -227,7 +227,7 @@
"es_ES": "Host Sin Verificación (Más rápido, Inseguro)",
"fr_FR": "Hôte Non Vérifié (plus rapide, non sécurisé)",
"he_IL": "מארח לא מבוקר (המהיר ביותר, לא בטוח)",
- "it_IT": "Host Unchecked (più veloce, non sicura)",
+ "it_IT": "Host senza verifica (più veloce, non sicura)",
"ja_JP": "ホスト, チェックなし (最高速, 安全でない)",
"ko_KR": "호스트 확인 안함(가장 빠르나 위험)",
"no_NO": "Vert Ukontrollert (raskets, utrygt)",
@@ -277,7 +277,7 @@
"es_ES": "_Archivo",
"fr_FR": "_Fichier",
"he_IL": "_קובץ",
- "it_IT": "",
+ "it_IT": "_Archivio",
"ja_JP": "ファイル(_F)",
"ko_KR": "파일(_F)",
"no_NO": "_Fil",
@@ -352,7 +352,7 @@
"es_ES": "Cargar Juego _Desempaquetado...",
"fr_FR": "Charger un Jeu Décompressé...",
"he_IL": "טען משחק _שאינו ארוז...",
- "it_IT": "Carica _gioco estratto...",
+ "it_IT": "Carica gioco _estratto...",
"ja_JP": "_展開されたゲームをロード...",
"ko_KR": "압축 푼 게임 불러오기(_U)...",
"no_NO": "Last inn _upakket spill...",
@@ -427,7 +427,7 @@
"es_ES": "Abrir Carpeta de Ryujinx",
"fr_FR": "Ouvrir le Dossier Ryujinx",
"he_IL": "פתח את תיקיית ריוג'ינקס",
- "it_IT": "Apri cartella di Ryujinx",
+ "it_IT": "Apri la cartella di Ryujinx",
"ja_JP": "Ryujinx フォルダを開く",
"ko_KR": "Ryujinx 폴더 열기",
"no_NO": "Åpne Ryujinx mappe",
@@ -452,7 +452,7 @@
"es_ES": "Abrir Carpeta de Capturas de Pantalla",
"fr_FR": "Ouvrir le Dossier des Captures d’Écran",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Apri la cartella degli screenshots",
"ja_JP": "",
"ko_KR": "스크린샷 폴더 열기",
"no_NO": "Åpne Skjermbilde Mappen",
@@ -477,7 +477,7 @@
"es_ES": "Abrir Carpeta de Registros",
"fr_FR": "Ouvrir le Dossier des Journaux",
"he_IL": "פתח את תיקיית קבצי הלוג",
- "it_IT": "Apri cartella dei log",
+ "it_IT": "Apri la cartella dei log",
"ja_JP": "ログフォルダを開く",
"ko_KR": "로그 폴더 열기",
"no_NO": "Åpne Logg mappen",
@@ -602,7 +602,7 @@
"es_ES": "Iniziar Juegos con la Interfaz Oculta",
"fr_FR": "Démarrer les Jeux avec l’Interface Cachée",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Avvia i giochi con l'interfaccia nascosta",
"ja_JP": "",
"ko_KR": "UI를 숨긴 상태에서 게임 시작",
"no_NO": "Start Spillet med UI Gjemt",
@@ -627,7 +627,7 @@
"es_ES": "Detener Emulación",
"fr_FR": "Arrêter l'Émulation",
"he_IL": "עצור אמולציה",
- "it_IT": "Ferma emulazione",
+ "it_IT": "Arresta l'emulazione",
"ja_JP": "エミュレーションを中止",
"ko_KR": "에뮬레이션 중지",
"no_NO": "Stopp Emulering",
@@ -727,7 +727,7 @@
"es_ES": "Simular Mensaje de Reactivación",
"fr_FR": "Simuler un Message de Réveil",
"he_IL": "דמה הודעת השכמה",
- "it_IT": "Simula messaggio Wake-up",
+ "it_IT": "Simula messaggio di risveglio",
"ja_JP": "スリープ復帰メッセージをシミュレート",
"ko_KR": "절전 모드 해제 메시지 시뮬레이션",
"no_NO": "Simuler oppvåknings-melding",
@@ -745,10 +745,10 @@
{
"ID": "MenuBarActionsScanAmiibo",
"Translations": {
- "ar_SA": "فحص Amiibo",
+ "ar_SA": "مسح Amiibo",
"de_DE": "Amiibo scannen",
"el_GR": "Σάρωση Amiibo",
- "en_US": "Scan An Amiibo",
+ "en_US": "Scan Amiibo",
"es_ES": "Escanear Amiibo",
"fr_FR": "Scanner un Amiibo",
"he_IL": "סרוק אמיבו",
@@ -770,26 +770,26 @@
{
"ID": "MenuBarActionsScanAmiiboBin",
"Translations": {
- "ar_SA": "",
- "de_DE": "Amiibo scannen (aus Bin-Datei)",
- "el_GR": "",
- "en_US": "Scan An Amiibo (from .bin)",
- "es_ES": "Escanear un Amiibo (desde un .bin)",
- "fr_FR": "Scanner un Amiibo (à partir d'un .bin)",
- "he_IL": "",
- "it_IT": "Scansiona un Amiibo (da file .bin)",
- "ja_JP": "",
- "ko_KR": "Amiibo 스캔(.bin에서)",
- "no_NO": "Skann en Amiibo (fra bin fil)",
- "pl_PL": "",
- "pt_BR": "Escaneie um Amiibo (de um .bin)",
- "ru_RU": "Сканировать Amiibo (из .bin)",
- "sv_SE": "Skanna en Amiibo (från bin-fil)",
- "th_TH": "สแกนอามีโบ (จากไฟล์ Bin)",
- "tr_TR": "",
- "uk_UA": "Сканувати Amiibo (з теки Bin)",
- "zh_CN": "扫描 Amiibo (从 bin 文件)",
- "zh_TW": "掃瞄 Amiibo (從 Bin 檔案)"
+ "ar_SA": "مسح Amiibo (.BIN)",
+ "de_DE": "Amiibo scannen (.BIN)",
+ "el_GR": "Σάρωση Amiibo (.BIN)",
+ "en_US": "Scan Amiibo (.BIN)",
+ "es_ES": "Escanear un Amiibo (.BIN)",
+ "fr_FR": "Scanner un Amiibo (.BIN)",
+ "he_IL": "סרוק Amiibo (.BIN)",
+ "it_IT": "Scansiona un Amiibo (.BIN)",
+ "ja_JP": "Amiibo をスキャン (.BIN)",
+ "ko_KR": "Amiibo 스캔 (.BIN)",
+ "no_NO": "Skann en Amiibo (.BIN)",
+ "pl_PL": "Skanuj Amiibo (.BIN)",
+ "pt_BR": "Escaneie um Amiibo (.BIN)",
+ "ru_RU": "Сканировать Amiibo (.BIN)",
+ "sv_SE": "Skanna en Amiibo (.BIN)",
+ "th_TH": "สแกนอามีโบ (.BIN)",
+ "tr_TR": "Amiibo Tara (.BIN)",
+ "uk_UA": "Сканувати Amiibo (.BIN)",
+ "zh_CN": "扫描 Amiibo (.BIN)",
+ "zh_TW": "掃瞄 Amiibo (.BIN)"
}
},
{
@@ -929,13 +929,13 @@
"he_IL": "",
"it_IT": "Installa chiavi (cartella)",
"ja_JP": "",
- "ko_KR": "키(폴더) 설치",
+ "ko_KR": "키(폴더) 설치",
"no_NO": "Installer nøkler (mappe)",
"pl_PL": "",
"pt_BR": "Instalar chaves (diretório)",
"ru_RU": "Установить ключи (папка)",
"sv_SE": "Installera nycklar (katalog)",
- "th_TH": "ติดตั้งคีย์ (ไดเรกทอรี)",
+ "th_TH": "ติดตั้งคีย์ (ไดเรกทอรี)",
"tr_TR": "",
"uk_UA": "Встановити ключі (тека)",
"zh_CN": "安装密匙(文件夹",
@@ -1052,7 +1052,7 @@
"es_ES": "Herramientas",
"fr_FR": "Outils",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Strumenti",
"ja_JP": "",
"ko_KR": "도구",
"no_NO": "",
@@ -1077,7 +1077,7 @@
"es_ES": "_Vista",
"fr_FR": "_Fenêtre",
"he_IL": "",
- "it_IT": "_Vista",
+ "it_IT": "_Visualizza",
"ja_JP": "",
"ko_KR": "보기(_V)",
"no_NO": "_Vis",
@@ -1277,7 +1277,7 @@
"es_ES": "FAQ & Guías",
"fr_FR": null,
"he_IL": "שאלות נפוצות & מדריכים",
- "it_IT": "FAQ & Guides",
+ "it_IT": "FAQ & Guide",
"ja_JP": "よくある質問 & ガイド",
"ko_KR": "자주 묻는 질문(FAQ) & 안내",
"no_NO": "FAQ & Veiledninger",
@@ -1317,129 +1317,54 @@
"zh_TW": ""
}
},
- {
- "ID": "MenuBarHelpFaqTooltip",
- "Translations": {
- "ar_SA": "",
- "de_DE": "Öffnet die FAQ- und Fehlerbehebungsseite im offiziellen Ryujinx-Wiki",
- "el_GR": "",
- "en_US": "Opens the FAQ and Troubleshooting page on the official Ryujinx wiki",
- "es_ES": "Abre la FAQ y la página de Resolución de Problemas en la wiki oficial de Ryujinx",
- "fr_FR": "Ouvre la page FAQ et Dépannage sur le wiki officiel de Ryujinx",
- "he_IL": "",
- "it_IT": "Apre la pagina della wiki ufficiale di Ryujinx relativa alle domande frequenti e alla risoluzione dei problemi",
- "ja_JP": "",
- "ko_KR": "공식 Ryujinx 위키에서 자주 묻는 질문(FAQ) 및 문제 해결 페이지 열기",
- "no_NO": "Åpner FAQ- og feilsøkingssiden på den offisielle Ryujinx-wikien",
- "pl_PL": "",
- "pt_BR": "Abre a página de FAQ e solução de problemas no wiki oficial do Ryujinx",
- "ru_RU": "Открывает страницу FAQ и устранения неполадок на официальной вики Ryujinx",
- "sv_SE": "Öppnar Frågor, svar och felsökningssidan på den officiella Ryujinx-wikin",
- "th_TH": "เปิดหน้ารวมคำถามที่พบบ่อยและวิธีแก้ไขปัญหาบนเว็บไซต์วิกิของ Ryujinx",
- "tr_TR": "",
- "uk_UA": "Відкриває сторінку з Посібником по усуненню помилок та несправностей на офіційній вікі-сторінці Ryujinx (англійською)",
- "zh_CN": "打开 Ryujinx 官方 Wiki 的常见问题和问题排除页面",
- "zh_TW": "開啟官方 Ryujinx Wiki 常見問題 (FAQ) 和疑難排解頁面"
- }
- },
{
"ID": "MenuBarHelpSetup",
"Translations": {
- "ar_SA": "",
- "de_DE": "Setup- und Konfigurationsanleitung",
- "el_GR": "",
- "en_US": "Setup & Configuration Guide",
- "es_ES": "Guía de Instalación y Configuración",
- "fr_FR": "Guide d'Installation et de Configuration",
- "he_IL": "",
- "it_IT": "Guida all'installazione e alla configurazione",
- "ja_JP": "",
- "ko_KR": "설치 및 구성 안내",
- "no_NO": "Oppsett- og konfigurasjonsveiledning",
- "pl_PL": "",
- "pt_BR": "Guia de Instalação e Configuração",
- "ru_RU": "Руководство по установке и настройке",
- "sv_SE": "Konfigurationsguide",
- "th_TH": "คู่มือการติดตั้งและปรับแต่งระบบ",
- "tr_TR": "",
- "uk_UA": "Посібник зі встановлення та налаштування (eng)",
- "zh_CN": "安装与配置指南",
- "zh_TW": "設定和配置指南"
- }
- },
- {
- "ID": "MenuBarHelpSetupTooltip",
- "Translations": {
- "ar_SA": "",
- "de_DE": "Öffnet die Setup- und Konfigurationsanleitung im offiziellen Ryujinx-Wiki",
- "el_GR": "",
- "en_US": "Opens the Setup & Configuration guide on the official Ryujinx wiki",
- "es_ES": "Abre el guía de Instalación y Configuración en la wiki oficial de Ryujinx",
- "fr_FR": "Ouvre le guide d'Installation et de Configuration sur le wiki officiel de Ryujinx",
- "he_IL": "",
- "it_IT": "Apre la guida all'installazione e alla configurazione presente nella wiki ufficiale di Ryujinx",
- "ja_JP": "",
- "ko_KR": "공식 Ryujinx 위키에서 설정 및 구성 안내 열기",
- "no_NO": "Åpner oppsett- og konfigurasjonsveiledningen på den offisielle Ryujinx-wikien",
- "pl_PL": "",
- "pt_BR": "Abre o guia de instalação e configuração no wiki oficial do Ryujinx",
- "ru_RU": "Открывает руководство по установке и настройке на официальной вики Ryujinx",
- "sv_SE": "Öppnar konfigurationsguiden på den officiella Ryujinx-wikin",
- "th_TH": "เปิดคู่มือการติดตั้งและตั้งค่าบนวิกิอย่างเป็นทางการของ Ryujinx",
- "tr_TR": "",
- "uk_UA": "Відкриває посібник з Налаштування та конфігурації на офіційній вікі-сторінці Ryujinx (англійською)",
- "zh_CN": "打开 Ryujinx 官方 Wiki 的安装与配置指南",
- "zh_TW": "開啟官方 Ryujinx Wiki 設定和配置指南"
+ "ar_SA": "الإعداد والتكوين",
+ "de_DE": "Setup und Konfiguration",
+ "el_GR": "Ρύθμιση και Διαμόρφωση",
+ "en_US": "Setup & Configuration",
+ "es_ES": "Instalación y Configuración",
+ "fr_FR": "Installation et Configuration",
+ "he_IL": "הגדרה וקונפיגורציה",
+ "it_IT": "Installazione e Configurazione",
+ "ja_JP": "セットアップと構成",
+ "ko_KR": "설치 및 구성",
+ "no_NO": "Oppsett og konfigurasjon",
+ "pl_PL": "Instalacja i Konfiguracja",
+ "pt_BR": "Instalação e Configuração",
+ "ru_RU": "Установка и Настройка",
+ "sv_SE": "Installation och konfiguration",
+ "th_TH": "การติดตั้งและการกำหนดค่า",
+ "tr_TR": "Kurulum ve Yapılandırma",
+ "uk_UA": "Встановлення та Налаштування",
+ "zh_CN": "安装与配置",
+ "zh_TW": "安裝與設定"
}
},
{
"ID": "MenuBarHelpMultiplayer",
"Translations": {
- "ar_SA": "",
- "de_DE": "Multiplayer (LDN/LAN) Anleitung",
- "el_GR": "",
- "en_US": "Multiplayer (LDN/LAN) Guide",
- "es_ES": "Guía Multijugador (LDN/LAN)",
- "fr_FR": "Guide Multijoueur (LDN/LAN)",
- "he_IL": "",
- "it_IT": "Guida alla modalità multigiocatore (LDN/LAN)",
- "ja_JP": "",
- "ko_KR": "멀티플레이어(LDN/LAN) 안내",
- "no_NO": "Flerspillerveiledning (LDN/LAN)",
- "pl_PL": "",
- "pt_BR": "Guia Multijogador (LDN/LAN)",
- "ru_RU": "Руководство по мультиплееру (LDN/LAN)",
- "sv_SE": "Flerspelarguide (LDN/LAN)",
- "th_TH": "คู่มือการเล่นหลายคนผ่านระบบ LDN หรือ LAN",
- "tr_TR": "",
- "uk_UA": "Посібник з мультиплеєру (LDN/LAN) (eng)",
- "zh_CN": "多人游戏(LDN/LAN)指南",
- "zh_TW": "多人遊戲 (LDN/LAN) 指南"
- }
- },
- {
- "ID": "MenuBarHelpMultiplayerTooltip",
- "Translations": {
- "ar_SA": "",
- "de_DE": "Öffnet die Multiplayer-Anleitung im offiziellen Ryujinx-Wiki",
- "el_GR": "",
- "en_US": "Opens the Multiplayer guide on the official Ryujinx wiki",
- "es_ES": "Abre el guía Multijugadores en la wiki oficial de Ryujinx",
- "fr_FR": "Ouvre le guide de Multijoueur sur le wiki officiel de Ryujinx",
- "he_IL": "",
- "it_IT": "Apre la guida alla modalità multigiocatore presente nella wiki ufficiale di Ryujinx",
- "ja_JP": "",
- "ko_KR": "공식 Ryujinx 위키에서 멀티플레이어 안내 열기",
- "no_NO": "Åpner flerspillerveiledningen på den offisielle Ryujinx-wikien",
- "pl_PL": "",
- "pt_BR": "Abre o guia multijogador no wiki oficial do Ryujinx",
- "ru_RU": "Открывает руководство по мультиплееру на официальной вики Ryujinx",
- "sv_SE": "Öppnar flerspelarguiden på den officiella Ryujinx-wikin",
- "th_TH": "เปิดคู่มือการเล่นหลายคนบนวิกิอย่างเป็นทางการของ Ryujinx",
- "tr_TR": "",
- "uk_UA": "Відкриває посібник з налаштування Мультиплеєру на офіційній вікі-сторінці Ryujinx (англійською)",
- "zh_CN": "打开 Ryujinx 官方 Wiki 的多人游戏指南",
- "zh_TW": "開啟官方 Ryujinx Wiki 多人遊戲 (LDN/LAN) 指南"
+ "ar_SA": "متعدد اللاعبين (LDN/LAN)",
+ "de_DE": "Multiplayer (LDN/LAN)",
+ "el_GR": "Πολλαπλοί Παίκτες (LDN/LAN)",
+ "en_US": "Multiplayer (LDN/LAN)",
+ "es_ES": "Multijugador (LDN/LAN)",
+ "fr_FR": "Multijoueur (LDN/LAN)",
+ "he_IL": "ריבוי משתתפים (LDN/LAN)",
+ "it_IT": "Multigiocatore (LDN/LAN)",
+ "ja_JP": "マルチプレイヤー(LDN/LAN)",
+ "ko_KR": "멀티플레이어 (LDN/LAN)",
+ "no_NO": "Flerspiller (LDN/LAN)",
+ "pl_PL": "Tryb wieloosobowy (LDN/LAN)",
+ "pt_BR": "Multijogador (LDN/LAN)",
+ "ru_RU": "Мультиплеер (LDN/LAN)",
+ "sv_SE": "Flerspelare (LDN/LAN)",
+ "th_TH": "ผู้เล่นหลายคน (LDN/LAN)",
+ "tr_TR": "Çok Oyunculu (LDN/LAN)",
+ "uk_UA": "Мультиплеєр (LDN/LAN)",
+ "zh_CN": "多人游戏(LDN/LAN)",
+ "zh_TW": "多人遊戲(LDN/LAN)"
}
},
{
@@ -1577,7 +1502,7 @@
"es_ES": "Desarrollado por {0}",
"fr_FR": "Développé par {0}",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Sviluppato da {0}",
"ja_JP": "",
"ko_KR": "{0}에서 개발",
"no_NO": "Utviklet av {0}",
@@ -1652,7 +1577,7 @@
"es_ES": "Jugado por Última Vez:",
"fr_FR": "Dernière Partie Jouée:",
"he_IL": "",
- "it_IT": "Ultima partita:",
+ "it_IT": "Giocato l'ultima volta:",
"ja_JP": "最終プレイ日時:",
"ko_KR": "마지막 플레이 :",
"no_NO": "Sist Spilt:",
@@ -1777,7 +1702,7 @@
"es_ES": "Jugado por Última Vez",
"fr_FR": "Dernière Partie Jouée",
"he_IL": "שוחק לאחרונה",
- "it_IT": "Ultima partita",
+ "it_IT": "Giocato l'ultima volta",
"ja_JP": "最終プレイ日時",
"ko_KR": "마지막 플레이",
"no_NO": "Sist Spilt",
@@ -2002,7 +1927,7 @@
"es_ES": "Compatibilidad:",
"fr_FR": "Compatibilité :",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Compatibilità:",
"ja_JP": "",
"ko_KR": "호환성 :",
"no_NO": "Kompatibilitet",
@@ -2027,7 +1952,7 @@
"es_ES": "ID del Titulo:",
"fr_FR": "ID du Titre :",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "ID del titolo:",
"ja_JP": "",
"ko_KR": "타이틀 ID :",
"no_NO": "Tittel ID:",
@@ -2052,7 +1977,7 @@
"es_ES": "Juegos Alojados: {0}",
"fr_FR": "Jeux Hébergés : {0}",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Giochi Hostati: {0}",
"ja_JP": "",
"ko_KR": "호스트 게임 : {0}",
"no_NO": "Spill som Arrangeres: {0}",
@@ -2077,7 +2002,7 @@
"es_ES": "Jugadores en Linea: {0}",
"fr_FR": "Joueurs en Ligne : {0}",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Giocatori Online: {0}",
"ja_JP": "",
"ko_KR": "온라인 플레이어 : {0}",
"no_NO": "Online-spillere: {0}",
@@ -2295,26 +2220,26 @@
{
"ID": "GameListContextMenuCacheManagementPurgePptcToolTip",
"Translations": {
- "ar_SA": "تنشيط PPTC لإعادة البناء في وقت الإقلاع عند بدء تشغيل اللعبة التالي",
- "de_DE": "Markiert den PPTC als ungültig, sodass dieser beim nächsten Spielstart neu erstellt wird",
- "el_GR": "Διαγράφει την προσωρινή μνήμη PPTC της εφαρμογής",
- "en_US": "Trigger PPTC to rebuild at boot time on the next game launch",
- "es_ES": "Elimina la Caché de PPTC de esta Aplicación",
- "fr_FR": "Déclenche la reconstruction du cache PPTC au prochain démarrage du jeu",
- "he_IL": "גרום ל-PPTC להבנות מחדש בפתיחה הבאה של המשחק",
- "it_IT": "Esegue la rigenerazione della cache PPTC al prossimo avvio del gioco",
- "ja_JP": "次回のゲーム起動時に PPTC を再構築します",
- "ko_KR": "다음 게임 실행 부팅 시, PPTC를 트리거하여 다시 구성",
- "no_NO": "Utløs PPTC for å gjenoppbygge ved oppstart av neste spill-start",
- "pl_PL": "Zainicjuj Rekompilację PPTC przy następnym uruchomieniu gry",
- "pt_BR": "Aciona o PPTC para reconstruir o cache no momento da próxima inicialização do jogo",
+ "ar_SA": "تنشيط PPTC لإعادة البناء في وقت الإقلاع عند بدء تشغيل اللعبة التالي.",
+ "de_DE": "Markiert den PPTC als ungültig, sodass dieser beim nächsten Spielstart neu erstellt wird.",
+ "el_GR": "Διαγράφει την προσωρινή μνήμη PPTC της εφαρμογής.",
+ "en_US": "Trigger PPTC to rebuild at boot time on the next game launch.",
+ "es_ES": "Elimina la caché de PPTC de esta aplicación.",
+ "fr_FR": "Déclenche la reconstruction du cache PPTC au prochain démarrage du jeu.",
+ "he_IL": "גרום ל-PPTC להבנות מחדש בפתיחה הבאה של המשחק.",
+ "it_IT": "Esegue la rigenerazione della cache PPTC al prossimo avvio del gioco.",
+ "ja_JP": "次回のゲーム起動時に PPTC を再構築します.",
+ "ko_KR": "다음 게임 실행 부팅 시, PPTC를 트리거하여 다시 구성.",
+ "no_NO": "Utløs PPTC for å gjenoppbygge ved oppstart av neste spill-start.",
+ "pl_PL": "Zainicjuj Rekompilację PPTC przy następnym uruchomieniu gry.",
+ "pt_BR": "Aciona o PPTC para reconstruir o cache no momento da próxima inicialização do jogo.",
"ru_RU": "Запускает перестройку PPTC во время следующего запуска игры.",
- "sv_SE": "Gör så att PPTC bygger om vid uppstart när nästa spel startas",
+ "sv_SE": "Gör så att PPTC bygger om vid uppstart när nästa spel startas.",
"th_TH": "ให้ PPTC สร้างใหม่ในเวลาบูตเมื่อเปิดเกมครั้งถัดไป",
- "tr_TR": "Oyunun bir sonraki açılışında PPTC'yi yeniden yapılandır",
- "uk_UA": "Видаляє кеш PPTC застосунку (гри)",
- "zh_CN": "删除游戏的 PPTC 缓存文件,下次启动游戏时重新编译生成 PPTC 缓存文件",
- "zh_TW": "下一次啟動遊戲時,觸發 PPTC 進行重建"
+ "tr_TR": "Oyunun bir sonraki açılışında PPTC'yi yeniden yapılandır.",
+ "uk_UA": "Видаляє кеш PPTC застосунку (гри).",
+ "zh_CN": "删除游戏的 PPTC 缓存文件,下次启动游戏时重新编译生成 PPTC 缓存文件。",
+ "zh_TW": "下一次啟動遊戲時,觸發 PPTC 進行重建。"
}
},
{
@@ -2327,7 +2252,7 @@
"es_ES": "Purgar Caché PPTC",
"fr_FR": "Purger le Cache PPTC",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Elimina la cache PPTC",
"ja_JP": "",
"ko_KR": "PPTC 캐시 제거",
"no_NO": "Tøm PPTC-bufferen",
@@ -2470,26 +2395,26 @@
{
"ID": "GameListContextMenuExtractDataExeFSToolTip",
"Translations": {
- "ar_SA": " استخراج قسم نظام الملفات القابل للتنفيذ (ExeFS) من الإعدادات الحالية للتطبيقات (يتضمن التحديثات)",
- "de_DE": "Extrahiert das ExeFS aus der aktuellen Anwendungskonfiguration (einschließlich Updates)",
- "el_GR": "Εξαγωγή της ενότητας ExeFS από την τρέχουσα διαμόρφωση της εφαρμογής (συμπεριλαμβανομένου ενημερώσεων)",
- "en_US": "Extract the ExeFS section from Application's current config (including updates)",
- "es_ES": "Extraer la sección ExeFS de la configuración actual de la aplicación (incluyendo actualizaciones)",
- "fr_FR": "Extrait la section ExeFS de la configuration actuelle de l’Application (mises à jour incluses)",
- "he_IL": "חלץ את קטע ה-ExeFS מתצורת היישום הנוכחית (כולל עדכונים)",
- "it_IT": "Estrae la sezione ExeFS dall'attuale configurazione dell'applicazione (inclusi gli aggiornamenti)",
- "ja_JP": "現在のアプリケーション設定(アップデート含む)から ExeFS セクションを展開します",
- "ko_KR": "앱의 현재 구성에서 ExeFS 추출(업데이트 포함)",
- "no_NO": "Pakk ut ExeFS seksjonen fra Programmets gjeldende konfigurasjon (inkludert oppdateringer)",
- "pl_PL": "Wyodrębnij sekcję ExeFS z bieżącej konfiguracji aplikacji (w tym aktualizacje)",
- "pt_BR": "Extrai a seção ExeFS do jogo (incluindo atualizações)",
- "ru_RU": "Извлекает раздел ExeFS из текущей конфигурации приложения (включая обновления)",
- "sv_SE": "Extrahera ExeFS-sektionen från applikationens aktuella konfiguration (inkl uppdateringar)",
+ "ar_SA": "استخراج قسم نظام الملفات القابل للتنفيذ (ExeFS) من الإعدادات الحالية للتطبيقات (يتضمن التحديثات).",
+ "de_DE": "Extrahiert das ExeFS aus der aktuellen Anwendungskonfiguration (einschließlich Updates).",
+ "el_GR": "Εξαγωγή της ενότητας ExeFS από την τρέχουσα διαμόρφωση της εφαρμογής (συμπεριλαμβανομένου ενημερώσεων).",
+ "en_US": "Extract the ExeFS section from Application's current config (including updates).",
+ "es_ES": "Extraer la sección ExeFS de la configuración actual de la aplicación (incluyendo actualizaciones).",
+ "fr_FR": "Extrait la section ExeFS de la configuration actuelle de l’Application (mises à jour incluses).",
+ "he_IL": "חלץ את קטע ה-ExeFS מתצורת היישום הנוכחית (כולל עדכונים).",
+ "it_IT": "Estrae la sezione ExeFS dall'attuale configurazione dell'applicazione (inclusi gli aggiornamenti).",
+ "ja_JP": "現在のアプリケーション設定(アップデート含む)から ExeFS セクションを展開します。",
+ "ko_KR": "앱의 현재 구성에서 ExeFS 추출(업데이트 포함).",
+ "no_NO": "Pakk ut ExeFS seksjonen fra Programmets gjeldende konfigurasjon (inkludert oppdateringer).",
+ "pl_PL": "Wyodrębnij sekcję ExeFS z bieżącej konfiguracji aplikacji (w tym aktualizacje).",
+ "pt_BR": "Extrai a seção ExeFS do jogo (incluindo atualizações).",
+ "ru_RU": "Извлекает раздел ExeFS из текущей конфигурации приложения (включая обновления).",
+ "sv_SE": "Extrahera ExeFS-sektionen från applikationens aktuella konfiguration (inkl uppdateringar).",
"th_TH": "แยกข้อมูลส่วน ExeFS จากคอนฟิกปัจจุบันของแอป (รวมถึงอัปเดต)",
- "tr_TR": "Uygulamanın geçerli yapılandırmasından ExeFS kısmını ayıkla (Güncellemeler dahil)",
- "uk_UA": "Видобуває розділ ExeFS із поточної конфігурації програми (включаючи оновлення)",
- "zh_CN": "从游戏的当前状态中提取 ExeFS 分区 (包括更新)",
- "zh_TW": "從應用程式的目前配置中提取 ExeFS 分區 (包含更新)"
+ "tr_TR": "Uygulamanın geçerli yapılandırmasından ExeFS kısmını ayıkla (Güncellemeler dahil).",
+ "uk_UA": "Видобуває розділ ExeFS із поточної конфігурації програми (включаючи оновлення).",
+ "zh_CN": "从游戏的当前状态中提取 ExeFS 分区 (包括更新)。",
+ "zh_TW": "從應用程式的目前配置中提取 ExeFS 分區 (包含更新)。"
}
},
{
@@ -2520,26 +2445,26 @@
{
"ID": "GameListContextMenuExtractDataRomFSToolTip",
"Translations": {
- "ar_SA": "استخراج قسم RomFS من الإعدادات الحالية للتطبيقات (يتضمن التحديثات)",
- "de_DE": "Extrahiert das RomFS aus der aktuellen Anwendungskonfiguration (einschließlich Updates)",
- "el_GR": "Εξαγωγή της ενότητας RomFS από την τρέχουσα διαμόρφωση της εφαρμογής (συμπεριλαμβανομένου ενημερώσεων)",
- "en_US": "Extract the RomFS section from Application's current config (including updates)",
- "es_ES": "Extraer la sección RomFS de la configuración actual de la aplicación (incluyendo actualizaciones)",
- "fr_FR": "Extrait la section RomFS de la configuration actuelle de l’Application (mises à jour incluses)",
- "he_IL": "חלץ את קטע ה-RomFS מתצורת היישום הנוכחית (כולל עדכונים)",
- "it_IT": "Estrae la sezione RomFS dall'attuale configurazione dell'applicazione (inclusi gli aggiornamenti)",
- "ja_JP": "現在のアプリケーション設定(アップデート含む)から RomFS セクションを展開します",
- "ko_KR": "앱의 현재 구성에서 RomFS 추출(업데이트 포함)",
- "no_NO": "Pakk ut RomFS seksjonen fra applikasjonens gjeldende konfigurasjon (inkludert oppdateringer)",
- "pl_PL": "Wyodrębnij sekcję RomFS z bieżącej konfiguracji aplikacji (w tym aktualizacje)",
- "pt_BR": "Extrai a seção RomFS do jogo (incluindo atualizações)",
- "ru_RU": "Извлекает раздела RomFS из текущих настроек приложения (включая обновления)",
- "sv_SE": "Extrahera RomFS-sektionen från applikationens aktuella konfiguration (inkl uppdateringar)",
+ "ar_SA": "استخراج قسم RomFS من الإعدادات الحالية للتطبيقات (يتضمن التحديثات).",
+ "de_DE": "Extrahiert das RomFS aus der aktuellen Anwendungskonfiguration (einschließlich Updates).",
+ "el_GR": "Εξαγωγή της ενότητας RomFS από την τρέχουσα διαμόρφωση της εφαρμογής (συμπεριλαμβανομένου ενημερώσεων).",
+ "en_US": "Extract the RomFS section from Application's current config (including updates).",
+ "es_ES": "Extraer la sección RomFS de la configuración actual de la aplicación (incluyendo actualizaciones).",
+ "fr_FR": "Extrait la section RomFS de la configuration actuelle de l’Application (mises à jour incluses).",
+ "he_IL": "חלץ את קטע ה-RomFS מתצורת היישום הנוכחית (כולל עדכונים).",
+ "it_IT": "Estrae la sezione RomFS dall'attuale configurazione dell'applicazione (inclusi gli aggiornamenti).",
+ "ja_JP": "現在のアプリケーション設定(アップデート含む)から RomFS セクションを展開します.",
+ "ko_KR": "앱의 현재 구성에서 RomFS 추출(업데이트 포함).",
+ "no_NO": "Pakk ut RomFS seksjonen fra applikasjonens gjeldende konfigurasjon (inkludert oppdateringer).",
+ "pl_PL": "Wyodrębnij sekcję RomFS z bieżącej konfiguracji aplikacji (w tym aktualizacje).",
+ "pt_BR": "Extrai a seção RomFS do jogo (incluindo atualizações).",
+ "ru_RU": "Извлекает раздела RomFS из текущих настроек приложения (включая обновления).",
+ "sv_SE": "Extrahera RomFS-sektionen från applikationens aktuella konfiguration (inkl uppdateringar).",
"th_TH": "แยกข้อมูลส่วน RomFS จากคอนฟิกปัจจุบันของแอป (รวมถึงอัปเดต)",
- "tr_TR": "Uygulamanın geçerli yapılandırmasından RomFS kısmını ayıkla (Güncellemeler dahil)",
- "uk_UA": "Видобуває розділ RomFS із поточної конфігурації застосунку (включно з оновленнями)",
- "zh_CN": "从游戏的当前状态中提取 RomFS 分区 (包括更新)",
- "zh_TW": "從應用程式的目前配置中提取 RomFS 分區 (包含更新)"
+ "tr_TR": "Uygulamanın geçerli yapılandırmasından RomFS kısmını ayıkla (Güncellemeler dahil).",
+ "uk_UA": "Видобуває розділ RomFS із поточної конфігурації застосунку (включно з оновленнями).",
+ "zh_CN": "从游戏的当前状态中提取 RomFS 分区 (包括更新)。",
+ "zh_TW": "從應用程式的目前配置中提取 RomFS 分區 (包含更新)。"
}
},
{
@@ -2552,7 +2477,7 @@
"es_ES": null,
"fr_FR": "RomFS du DLC",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "RomFS del DLC",
"ja_JP": "",
"ko_KR": null,
"no_NO": "",
@@ -2573,23 +2498,23 @@
"ar_SA": "",
"de_DE": "",
"el_GR": "",
- "en_US": "Extract the RomFS from a selected DLC file",
- "es_ES": "Extraer el RomFS desde un archivo DLC",
- "fr_FR": "Extrait la RomFS du fichier DLC sélectionné",
+ "en_US": "Extract the RomFS from a selected DLC file.",
+ "es_ES": "Extraer el RomFS desde un archivo DLC.",
+ "fr_FR": "Extrait la RomFS du fichier DLC sélectionné.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Estrai la RomFS da un file DLC",
"ja_JP": "",
- "ko_KR": "선택한 DLC 파일에서 RomFS 추출",
- "no_NO": "Pakk ut RomFS filene fra valgt DLC fil",
+ "ko_KR": "선택한 DLC 파일에서 RomFS 추출.",
+ "no_NO": "Pakk ut RomFS filene fra valgt DLC fil.",
"pl_PL": "",
- "pt_BR": "Extraia o RomFS de um arquivo DLC selecionado",
- "ru_RU": "Извлекает файлы RomFS из выбранного файла DLC",
- "sv_SE": "Extrahera RomFS från en vald DLC-fil",
+ "pt_BR": "Extraia o RomFS de um arquivo DLC selecionado.",
+ "ru_RU": "Извлекает файлы RomFS из выбранного файла DLC.",
+ "sv_SE": "Extrahera RomFS från en vald DLC-fil.",
"th_TH": "แยกข้อมูล RomFS จากไฟล์ DLC ที่เลือก",
"tr_TR": "",
- "uk_UA": "Витягти RomFS з обраного файлу DLC",
- "zh_CN": "从选定的 DLC 文件中解压 RomFS",
- "zh_TW": "從已選擇的 DLC 檔案中提取 RomFS"
+ "uk_UA": "Витягти RomFS з обраного файлу DLC.",
+ "zh_CN": "从选定的 DLC 文件中解压 RomFS。",
+ "zh_TW": "從已選擇的 DLC 檔案中提取 RomFS。"
}
},
{
@@ -2602,7 +2527,7 @@
"es_ES": "Logotipo",
"fr_FR": null,
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Logo",
"ja_JP": "ロゴ",
"ko_KR": "로고",
"no_NO": "",
@@ -2620,76 +2545,76 @@
{
"ID": "GameListContextMenuExtractDataLogoToolTip",
"Translations": {
- "ar_SA": "استخراج قسم الشعار من الإعدادات الحالية للتطبيقات (يتضمن التحديثات)",
- "de_DE": "Extrahiert das Logo aus der aktuellen Anwendungskonfiguration (einschließlich Updates)",
- "el_GR": "Εξαγωγή της ενότητας Logo από την τρέχουσα διαμόρφωση της εφαρμογής (συμπεριλαμβανομένου ενημερώσεων)",
- "en_US": "Extract the Logo section from Application's current config (including updates)",
- "es_ES": "Extraer la sección Logo de la configuración actual de la aplicación (incluyendo actualizaciones)",
- "fr_FR": "Extrait la section Logo de la configuration actuelle de l’application (mises à jour incluses)",
- "he_IL": "חלץ את קטע ה-Logo מתצורת היישום הנוכחית (כולל עדכונים)",
- "it_IT": "Estrae la sezione Logo dall'attuale configurazione dell'applicazione (inclusi gli aggiornamenti)",
- "ja_JP": "現在のアプリケーション設定(アップデート含む)からロゴセクションを展開します",
- "ko_KR": "앱의 현재 구성에서 로고 섹션 추출 (업데이트 포함)",
- "no_NO": "Pakk ut Logo-seksjonen fra applikasjonens gjeldende konfigurasjon (inkludert oppdateringer)",
- "pl_PL": "Wyodrębnij sekcję z logiem z bieżącej konfiguracji aplikacji (w tym aktualizacje)",
- "pt_BR": "Extrai a seção Logo do jogo (incluindo atualizações)",
- "ru_RU": "Извлекает раздел с логотипом из текущих настроек приложения (включая обновления)",
- "sv_SE": "Extrahera Logo-sektionen från applikationens aktuella konfiguration (inkl uppdateringar)",
+ "ar_SA": "استخراج قسم الشعار من الإعدادات الحالية للتطبيقات (يتضمن التحديثات).",
+ "de_DE": "Extrahiert das Logo aus der aktuellen Anwendungskonfiguration (einschließlich Updates).",
+ "el_GR": "Εξαγωγή της ενότητας Logo από την τρέχουσα διαμόρφωση της εφαρμογής (συμπεριλαμβανομένου ενημερώσεων).",
+ "en_US": "Extract the Logo section from Application's current config (including updates).",
+ "es_ES": "Extraer la sección Logo de la configuración actual de la aplicación (incluyendo actualizaciones).",
+ "fr_FR": "Extrait la section Logo de la configuration actuelle de l’application (mises à jour incluses).",
+ "he_IL": "חלץ את קטע ה-Logo מתצורת היישום הנוכחית (כולל עדכונים).",
+ "it_IT": "Estrae la sezione Logo dall'attuale configurazione dell'applicazione (inclusi gli aggiornamenti).",
+ "ja_JP": "現在のアプリケーション設定(アップデート含む)からロゴセクションを展開します.",
+ "ko_KR": "앱의 현재 구성에서 로고 섹션 추출 (업데이트 포함).",
+ "no_NO": "Pakk ut Logo-seksjonen fra applikasjonens gjeldende konfigurasjon (inkludert oppdateringer).",
+ "pl_PL": "Wyodrębnij sekcję z logiem z bieżącej konfiguracji aplikacji (w tym aktualizacje).",
+ "pt_BR": "Extrai a seção Logo do jogo (incluindo atualizações).",
+ "ru_RU": "Извлекает раздел с логотипом из текущих настроек приложения (включая обновления).",
+ "sv_SE": "Extrahera Logo-sektionen från applikationens aktuella konfiguration (inkl uppdateringar).",
"th_TH": "แยกข้อมูลส่วนโลโก้จากคอนฟิกปัจจุบันของแอป (รวมถึงอัปเดต)",
- "tr_TR": "Uygulamanın geçerli yapılandırmasından Logo kısmını ayıkla (Güncellemeler dahil)",
- "uk_UA": "Видобуває розділ логотипу з поточної конфігурації програми (включаючи оновлення)",
- "zh_CN": "从游戏的当前状态中提取图标 (包括更新)",
- "zh_TW": "從應用程式的目前配置中提取 Logo 分區 (包含更新)"
+ "tr_TR": "Uygulamanın geçerli yapılandırmasından Logo kısmını ayıkla (Güncellemeler dahil).",
+ "uk_UA": "Видобуває розділ логотипу з поточної конфігурації програми (включаючи оновлення).",
+ "zh_CN": "从游戏的当前状态中提取图标 (包括更新)。",
+ "zh_TW": "從應用程式的目前配置中提取 Logo 分區 (包含更新)。"
}
},
{
"ID": "GameListContextMenuCreateShortcut",
"Translations": {
- "ar_SA": "إنشاء اختصار للتطبيق",
- "de_DE": "Erstelle Anwendungsverknüpfung",
- "el_GR": "Δημιουργία Συντόμευσης Εφαρμογής",
- "en_US": "Create Application Shortcut",
- "es_ES": "Crear Acceso Directo de Aplicación",
- "fr_FR": "Créer un Raccourci de l’Application",
- "he_IL": "ליצור קיצור דרך לאפליקציה",
+ "ar_SA": "إنشاء اختصار",
+ "de_DE": "Verknüpfung erstellen",
+ "el_GR": "Δημιουργία συντόμευσης",
+ "en_US": "Create Shortcut",
+ "es_ES": "Crear Acceso Directo",
+ "fr_FR": "Créer un Raccourci",
+ "he_IL": "ליצור קיצור דרך",
"it_IT": "Crea collegamento",
- "ja_JP": "アプリケーションのショートカットを作成",
+ "ja_JP": "ショートカットを作成",
"ko_KR": "바로 가기 만들기",
- "no_NO": "Lag programsnarvei",
- "pl_PL": "Utwórz skrót aplikacji",
- "pt_BR": "Criar Atalho da Aplicação",
+ "no_NO": "Lag snarvei",
+ "pl_PL": "Utwórz skrót",
+ "pt_BR": "Criar atalho",
"ru_RU": "Создать ярлык",
- "sv_SE": "Skapa genväg till applikation",
- "th_TH": "สร้างทางลัดของแอปพลิเคชัน",
- "tr_TR": "Uygulama Kısayolu Oluştur",
- "uk_UA": "Створити ярлик застосунку",
- "zh_CN": "创建游戏快捷方式",
- "zh_TW": "建立應用程式捷徑"
+ "sv_SE": "Skapa genväg",
+ "th_TH": "สร้างทางลัด",
+ "tr_TR": "Kısayol Oluştur",
+ "uk_UA": "Створити ярлик",
+ "zh_CN": "创建快捷方式",
+ "zh_TW": "建立捷徑"
}
},
{
"ID": "GameListContextMenuCreateShortcutToolTip",
"Translations": {
- "ar_SA": "أنشئ اختصار سطح مكتب لتشغيل التطبيق المحدد",
- "de_DE": "Erstelle eine Desktop-Verknüpfung die die gewählte Anwendung startet",
- "el_GR": "Δημιουργία συντόμευσης επιφάνειας εργασίας που ανοίγει την επιλεγμένη εφαρμογή",
- "en_US": "Create a Desktop Shortcut that launches the selected Application",
- "es_ES": "Crear un acceso directo en el escritorio que lance la aplicación seleccionada",
- "fr_FR": "Crée un Raccourci sur le Bureau qui lance l’Application sélectionnée",
- "he_IL": "ליצור קיצור דרך בשולחן העבודה שיפתח את אפליקציה זו",
- "it_IT": "Crea un collegamento sul desktop che avvia l'applicazione selezionata",
- "ja_JP": "選択したアプリケーションを起動するデスクトップショートカットを作成します",
- "ko_KR": "선택한 앱을 실행하는 바탕 화면에 바로 가기를 생성",
- "no_NO": "Lag en snarvei på skrivebordet som starter den valgte Applikasjonen",
- "pl_PL": "Utwórz skrót na pulpicie, który uruchamia wybraną aplikację",
- "pt_BR": "Criar um atalho na área de trabalho que inicia o aplicativo selecionado",
- "ru_RU": "Создаёт ярлык на рабочем столе для запуска выбранного приложения",
- "sv_SE": "Skapa en skrivbordsgenväg som startar vald applikation",
+ "ar_SA": "أنشئ اختصار سطح مكتب لتشغيل التطبيق المحدد.",
+ "de_DE": "Erstelle eine Desktop-Verknüpfung die die gewählte Anwendung startet.",
+ "el_GR": "Δημιουργία συντόμευσης επιφάνειας εργασίας που ανοίγει την επιλεγμένη εφαρμογή.",
+ "en_US": "Create a Desktop Shortcut that launches the selected Application.",
+ "es_ES": "Crear un acceso directo en el escritorio que lance la aplicación seleccionada.",
+ "fr_FR": "Crée un Raccourci sur le Bureau qui lance l’Application sélectionnée.",
+ "he_IL": "ליצור קיצור דרך בשולחן העבודה שיפתח את אפליקציה זו.",
+ "it_IT": "Crea un collegamento sul desktop che avvia l'applicazione selezionata.",
+ "ja_JP": "選択したアプリケーションを起動するデスクトップショートカットを作成します.",
+ "ko_KR": "선택한 앱을 실행하는 바탕 화면에 바로 가기를 생성.",
+ "no_NO": "Lag en snarvei på skrivebordet som starter den valgte Applikasjonen.",
+ "pl_PL": "Utwórz skrót na pulpicie, który uruchamia wybraną aplikację.",
+ "pt_BR": "Criar um atalho na área de trabalho que inicia o aplicativo selecionado.",
+ "ru_RU": "Создаёт ярлык на рабочем столе для запуска выбранного приложения.",
+ "sv_SE": "Skapa en skrivbordsgenväg som startar vald applikation.",
"th_TH": "สร้างทางลัดบนเดสก์ท็อปเพื่อเปิดแอปพลิเคชันที่เลือก",
- "tr_TR": "Seçilmiş uygulamayı çalıştıracak bir masaüstü kısayolu oluştur",
- "uk_UA": "Створити ярлик на робочому столі, який запускатиме вибраний застосунок (гру)",
- "zh_CN": "创建一个直接启动此游戏的桌面快捷方式",
- "zh_TW": "建立桌面捷徑,啟動選取的應用程式"
+ "tr_TR": "Seçilmiş uygulamayı çalıştıracak bir masaüstü kısayolu oluştur.",
+ "uk_UA": "Створити ярлик на робочому столі, який запускатиме вибраний застосунок (гру).",
+ "zh_CN": "创建一个直接启动此游戏的桌面快捷方式。",
+ "zh_TW": "建立桌面捷徑,啟動選取的應用程式。"
}
},
{
@@ -2702,7 +2627,7 @@
"es_ES": "Crear Configuración Personalizada",
"fr_FR": "Créer une Configuration Personnalisée",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Crea una Configurazione Personalizzata",
"ja_JP": "",
"ko_KR": "사용자 정의 구성 만들기",
"no_NO": "Opprett egendefinert konfigurasjon",
@@ -2727,7 +2652,7 @@
"es_ES": "Editar Configuración Personalizada",
"fr_FR": "Modifier la Configuration Personnalisée",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Modifica Configurazione Personalizzata",
"ja_JP": "",
"ko_KR": "사용자 정의 구성 편집",
"no_NO": "Rediger egendefinert konfigurasjon",
@@ -2745,26 +2670,26 @@
{
"ID": "GameListContextMenuCreateShortcutToolTipMacOS",
"Translations": {
- "ar_SA": "أنشئ اختصار يُشغل التطبيق المحدد في مجلد تطبيقات macOS",
- "de_DE": "Erstellen Sie eine Verknüpfung im MacOS-Programme-Ordner, die die ausgewählte Anwendung startet",
+ "ar_SA": "أنشئ اختصار يُشغل التطبيق المحدد في مجلد تطبيقات macOS.",
+ "de_DE": "Erstellen Sie eine Verknüpfung im MacOS-Programme-Ordner, die die ausgewählte Anwendung startet.",
"el_GR": "",
- "en_US": "Create a shortcut in macOS's Applications folder that launches the selected Application",
- "es_ES": "Crea un acceso directo en la carpeta de Aplicaciones de macOS que inicie la Aplicación seleccionada",
- "fr_FR": "Crée un raccourci dans le dossier Applications de macOS qui lance l’Application sélectionnée",
- "he_IL": "ליצור קיצור דרך בתיקיית האפליקציות של macOS שיפתח את אפליקציה זו",
- "it_IT": "Crea un collegamento nella cartella Applicazioni di macOS che avvia l'applicazione selezionata",
- "ja_JP": "選択したアプリケーションを起動する ショートカットを macOS の Applications フォルダに作成します",
- "ko_KR": "선택한 앱을 실행하는 macOS 앱 폴더에 바로 가기 만들기",
- "no_NO": "Lag snarvei i macOSs Program-mappen som starter det valgte programmet",
- "pl_PL": "Utwórz skrót w folderze 'Aplikacje' w systemie macOS, który uruchamia wybraną aplikację",
- "pt_BR": "Crie um atalho na pasta Aplicativos do macOS que abre o Aplicativo selecionado",
- "ru_RU": "Создаёт ярлык в папке Программы macOS, который запускает выбранное приложение",
- "sv_SE": "Skapa en genväg i macOS-programmapp som startar vald applikation",
+ "en_US": "Create a shortcut in macOS's Applications folder that launches the selected Application.",
+ "es_ES": "Crea un acceso directo en la carpeta de Aplicaciones de macOS que inicie la Aplicación seleccionada.",
+ "fr_FR": "Crée un raccourci dans le dossier Applications de macOS qui lance l’Application sélectionnée.",
+ "he_IL": "ליצור קיצור דרך בתיקיית האפליקציות של macOS שיפתח את אפליקציה זו.",
+ "it_IT": "Crea un collegamento nella cartella Applicazioni di macOS che avvia l'applicazione selezionata.",
+ "ja_JP": "選択したアプリケーションを起動する ショートカットを macOS の Applications フォルダに作成します.",
+ "ko_KR": "선택한 앱을 실행하는 macOS 앱 폴더에 바로 가기 만들기.",
+ "no_NO": "Lag snarvei i macOSs Program-mappen som starter det valgte programmet.",
+ "pl_PL": "Utwórz skrót w folderze 'Aplikacje' w systemie macOS, który uruchamia wybraną aplikację.",
+ "pt_BR": "Crie um atalho na pasta Aplicativos do macOS que abre o Aplicativo selecionado.",
+ "ru_RU": "Создаёт ярлык в папке Программы macOS, который запускает выбранное приложение.",
+ "sv_SE": "Skapa en genväg i macOS-programmapp som startar vald applikation.",
"th_TH": "สร้างทางลัดในโฟลเดอร์ Applications ของ macOS เพื่อเปิดแอปพลิเคชันที่เลือก",
"tr_TR": "",
- "uk_UA": "Створити ярлик у каталозі програм macOS, що запускатиме обраний застосунок (гру)",
- "zh_CN": "在 macOS 的应用程序目录中创建一个直接启动此游戏的快捷方式",
- "zh_TW": "在 macOS 的應用程式資料夾中建立捷徑,啟動選取的應用程式"
+ "uk_UA": "Створити ярлик у каталозі програм macOS, що запускатиме обраний застосунок (гру).",
+ "zh_CN": "在 macOS 的应用程序目录中创建一个直接启动此游戏的快捷方式。",
+ "zh_TW": "在 macOS 的應用程式資料夾中建立捷徑,啟動選取的應用程式。"
}
},
{
@@ -2777,7 +2702,7 @@
"es_ES": "Entrada de Compatibilidad",
"fr_FR": "Entrée de Compatibilité",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Record di Compatibilità",
"ja_JP": "",
"ko_KR": "호환성 항목",
"no_NO": "Kompatibilitetsoppføring",
@@ -2802,7 +2727,7 @@
"es_ES": "Mostra el juego seleccionado en la lista de compatibilidad, a la que normalmente se accede desde el menú Ayuda.",
"fr_FR": "Affiche le jeu sélectionné dans la liste de compatibilité accessible normalement via le menu Aide.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Mostra il gicoo selezionato nella lista di Compatibilità, accessibile normalmente attraverso il menu Aiuto",
"ja_JP": "",
"ko_KR": "일반적으로 도움말 메뉴를 통해 접근할 수 있는 호환성 목록에 선택한 게임을 표시합니다.",
"no_NO": "Vis det valgte spillet i kompatibilitetslisten, som du vanligvis får tilgang til via Hjelp-menyen.",
@@ -2852,7 +2777,7 @@
"es_ES": "Editar su configuración independiente existente para el juego seleccionado",
"fr_FR": "Modifie votre configuration indépendante existante pour le jeu sélectionné",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Modifica la tua configurazione indipendente esistente per il gioco selezionato",
"ja_JP": "",
"ko_KR": "선택한 게임에 대한 기존 독립 구성 편집",
"no_NO": "Rediger din eksisterende uavhengige konfigurasjon for det valgte spillet",
@@ -2877,7 +2802,7 @@
"es_ES": "Información del Juego",
"fr_FR": "Informations sur le Jeu",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Informazioni sul Gioco",
"ja_JP": "",
"ko_KR": "게임 정보",
"no_NO": "Spillinfo",
@@ -2963,7 +2888,7 @@
"th_TH": "เปิดโฟลเดอร์ Atmosphère บนการ์ด SD ทางเลือกที่เก็บม็อดของแอปพลิเคชัน ใช้สำหรับม็อดที่จัดเตรียมมาเพื่อฮาร์ดแวร์จริง",
"tr_TR": "",
"uk_UA": "Відкриває альтернативну теку SD-карти Atmosphère, що містить модифікації до застосунків або ігор. Корисно для модифікацій, зроблених для реального обладнання.",
- "zh_CN": "打开存放适用于大气层系统的游戏 MOD 的目录,对于为真实硬件打包的 MOD 非常有用",
+ "zh_CN": "打开存放适用于大气层系统的游戏 MOD 的目录,对于为真实硬件打包的 MOD 非常有用。",
"zh_TW": "開啟此應用程式模組的另一個 SD 卡 Atmosphère 資料夾。適用於為真實硬體封裝的模組。"
}
},
@@ -2977,7 +2902,7 @@
"es_ES": "Verificar & Recortar Archivo XCI",
"fr_FR": "Vérifier & Réduire le Fichier XCI",
"he_IL": "",
- "it_IT": "Controlla & riduci il file XCI",
+ "it_IT": "Controlla & Riduci il File XCI",
"ja_JP": "",
"ko_KR": "XCI 파일 확인 & 트림",
"no_NO": "Kontroller & trim XCI-filen",
@@ -3320,26 +3245,26 @@
{
"ID": "SettingsTabGeneral",
"Translations": {
- "ar_SA": "واجهة المستخدم",
+ "ar_SA": "واجهة",
"de_DE": "Oberfläche",
- "el_GR": "Εμφάνιση",
- "en_US": "User Interface",
- "es_ES": "Interfaz de Usuario",
- "fr_FR": "Interface Utilisateur",
- "he_IL": "ממשק משתמש",
- "it_IT": "Interfaccia utente",
- "ja_JP": "ユーザインタフェース",
- "ko_KR": "사용자 인터페이스",
- "no_NO": "Brukergrensesnitt",
- "pl_PL": "Interfejs użytkownika",
- "pt_BR": "Interface do Usuário",
+ "el_GR": "Διεπαφή",
+ "en_US": "Interface",
+ "es_ES": "Interfaz",
+ "fr_FR": "Interface",
+ "he_IL": "ממשק",
+ "it_IT": "Interfaccia",
+ "ja_JP": "インターフェース",
+ "ko_KR": "인터페이스",
+ "no_NO": "Grensesnitt",
+ "pl_PL": "Interfejs",
+ "pt_BR": "Interface",
"ru_RU": "Интерфейс",
- "sv_SE": "Användargränssnitt",
- "th_TH": "อินเทอร์เฟซผู้ใช้",
- "tr_TR": "Kullancı Arayüzü",
+ "sv_SE": "Gränssnitt",
+ "th_TH": "อินเทอร์เฟซ",
+ "tr_TR": "Arayüz",
"uk_UA": "Інтерфейс",
- "zh_CN": "用户界面",
- "zh_TW": "使用者介面"
+ "zh_CN": "界面",
+ "zh_TW": "介面"
}
},
{
@@ -3371,98 +3296,73 @@
"ID": "SettingsTabGeneralEnableDiscordRichPresence",
"Translations": {
"ar_SA": "تمكين وجود ديسكورد الغني",
- "de_DE": "Aktiviere die Statusanzeige für Discord",
- "el_GR": "Ενεργοποίηση Εμπλουτισμένης Παρουσίας Discord",
+ "de_DE": "Aktiviere Discord Rich Presence",
+ "el_GR": "Ενεργοποίηση Discord Rich Presence",
"en_US": "Enable Discord Rich Presence",
- "es_ES": "Habilitar Rich Presence Discord",
+ "es_ES": "Habilitar Discord Rich Presence",
"fr_FR": "Activer Discord Rich Presence",
"he_IL": "הפעלת תצוגה עשירה בדיסקורד",
"it_IT": "Attiva Discord Rich Presence",
"ja_JP": "Discord リッチプレゼンスを有効にする",
- "ko_KR": "디스코드 활동 상태 활성화",
- "no_NO": "Aktiver Discord Rik Tilstedeværelse",
- "pl_PL": "Włącz Bogatą Obecność Discord",
- "pt_BR": "Habilitar Presença no Discord",
- "ru_RU": "Включить cтатус активности в Discord",
+ "ko_KR": "디스코드 리치 프레즌스 활성화",
+ "no_NO": "Aktiver Discord Rich Presence",
+ "pl_PL": "Włącz Discord Rich Presence",
+ "pt_BR": "Habilitar Discord Rich Presence",
+ "ru_RU": "Включить Discord Rich Presence",
"sv_SE": "Aktivera Discord Rich Presence",
"th_TH": "เปิดใช้งาน Discord Rich Presence",
- "tr_TR": "Discord Zengin İçerik'i Etkinleştir",
- "uk_UA": "Увімкнути розширену присутність Discord",
- "zh_CN": "启用 Discord 在线状态展示",
- "zh_TW": "啟用 Discord 動態狀態展示"
+ "tr_TR": "Discord Rich Presence'i Etkinleştir",
+ "uk_UA": "Увімкнути Discord Rich Presence",
+ "zh_CN": "启用 Discord Rich Presence",
+ "zh_TW": "啟用 Discord Rich Presence"
}
},
{
"ID": "SettingsTabGeneralCheckUpdatesOnLaunch",
"Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
+ "ar_SA": "تحقق من التحديثات:",
+ "de_DE": "Nach Updates suchen:",
+ "el_GR": "Έλεγχος για ενημερώσεις:",
"en_US": "Check for Updates:",
"es_ES": "Buscar Actualizaciones:",
"fr_FR": "Vérifier les Mises à Jour :",
- "he_IL": "",
- "it_IT": "",
- "ja_JP": "",
+ "he_IL": "בדוק אם יש עדכונים:",
+ "it_IT": "Verifica aggiornamenti:",
+ "ja_JP": "アップデート確認:",
"ko_KR": "업데이트 확인 :",
"no_NO": "Se etter Oppdateringer:",
- "pl_PL": "",
+ "pl_PL": "Sprawdź dostępność aktualizacji:",
"pt_BR": "Verificar Atualizações:",
"ru_RU": "Проверка обновлений:",
"sv_SE": "Leta efter uppdateringar:",
"th_TH": "ตรวจสอบการอัปเดต:",
- "tr_TR": "",
+ "tr_TR": "Güncellemeleri Kontrol Et:",
"uk_UA": "Перевірка оновлень:",
- "zh_CN": "检查更新",
+ "zh_CN": "检查更新:",
"zh_TW": "檢查更新:"
}
},
- {
- "ID": "SettingsTabGeneralCheckUpdatesOnLaunchOff",
- "Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
- "en_US": "Off",
- "es_ES": "Desactivado",
- "fr_FR": "Désactivé",
- "he_IL": "",
- "it_IT": "",
- "ja_JP": "",
- "ko_KR": "끔",
- "no_NO": "Av",
- "pl_PL": "",
- "pt_BR": "Desligado",
- "ru_RU": "Отключить",
- "sv_SE": "Av",
- "th_TH": "ปิด",
- "tr_TR": "",
- "uk_UA": "Вимкнути",
- "zh_CN": "关闭",
- "zh_TW": "關閉"
- }
- },
{
"ID": "SettingsTabGeneralCheckUpdatesOnLaunchPromptAtStartup",
"Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
+ "ar_SA": "طلب",
+ "de_DE": "Abfrage",
+ "el_GR": "Ερώτημα",
"en_US": "Prompt",
"es_ES": "Al Inicio",
"fr_FR": "Demande",
- "he_IL": "",
- "it_IT": "",
- "ja_JP": "",
+ "he_IL": "הודעה",
+ "it_IT": "Domanda",
+ "ja_JP": "プロンプト",
"ko_KR": "프롬프트",
"no_NO": "Spør",
- "pl_PL": "",
+ "pl_PL": "Zapytanie",
"pt_BR": "Ao Abrir",
"ru_RU": "При запуске",
"sv_SE": "Fråga",
"th_TH": "คำสั่ง",
- "tr_TR": "",
- "uk_UA": "Запитувати щоразу",
+ "tr_TR": "İstem",
+ "uk_UA": "Запит",
"zh_CN": "提示",
"zh_TW": "提示"
}
@@ -3470,24 +3370,24 @@
{
"ID": "SettingsTabGeneralCheckUpdatesOnLaunchBackground",
"Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
+ "ar_SA": "في الخلفية",
+ "de_DE": "Im Hintergrund",
+ "el_GR": "Στο παρασκήνιο",
"en_US": "Background",
"es_ES": "Cambiar Fondo",
- "fr_FR": "En Arrière-plan",
- "he_IL": "",
- "it_IT": "",
- "ja_JP": "",
+ "fr_FR": "En Arrière-Plan",
+ "he_IL": "ברקע",
+ "it_IT": "In secondo piano",
+ "ja_JP": "バックグラウンドで",
"ko_KR": "백그라운드",
"no_NO": "Bakgrunn",
- "pl_PL": "",
+ "pl_PL": "W tle",
"pt_BR": "2° Plano",
"ru_RU": "В фоне",
"sv_SE": "Bakgrund",
"th_TH": "พื้นหลัง",
- "tr_TR": "",
- "uk_UA": "Оновлювати в фоні",
+ "tr_TR": "Arka planda",
+ "uk_UA": "В фоні",
"zh_CN": "背景",
"zh_TW": "背景"
}
@@ -3495,98 +3395,98 @@
{
"ID": "SettingsTabGeneralFocusLossType",
"Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
- "en_US": "On Emulator Focus Lost:",
+ "ar_SA": "عند فقدان تركيز المحاكي:",
+ "de_DE": "Beim Emulator-Fokusverlust:",
+ "el_GR": "Απώλεια εστίασης του εξομοιωτή:",
+ "en_US": "On Emulator Focus Loss:",
"es_ES": "Al Perder el Foco el Emulador:",
- "fr_FR": "Lorsque l’Émulateur Perd le Focus :",
- "he_IL": "",
- "it_IT": "",
- "ja_JP": "",
- "ko_KR": "에뮬레이터 초점 손실 :",
- "no_NO": "På Emulator Fokus Tapt:",
- "pl_PL": "",
- "pt_BR": "Ao Perder o Foco:",
- "ru_RU": "Потеря фокуса эмулятора:",
- "sv_SE": "När emulatorn tappar fokus:",
- "th_TH": "เมื่อโปรแกรมจำลองไม่ถูกเลือก (สูญเสียโฟกัส):",
- "tr_TR": "",
+ "fr_FR": "Perte du Focus de l’Émulateur:",
+ "he_IL": "כאשר האמולטור מאבד את הפוקוס:",
+ "it_IT": "Quando l’emulatore perde focus:",
+ "ja_JP": "エミュレーターのフォーカス喪失時:",
+ "ko_KR": "에뮬레이터 포커스 상실 시:",
+ "no_NO": "Når emulatoren mister fokus:",
+ "pl_PL": "Gdy emulator traci fokus:",
+ "pt_BR": "Ao Perder o Foco do Emulador:",
+ "ru_RU": "При потере фокуса эмулятором:",
+ "sv_SE": "Emulatorn tappar fokus:",
+ "th_TH": "เมื่อโปรแกรมจำลองสูญเสียโฟกัส:",
+ "tr_TR": "Emülatör odak kaybı:",
"uk_UA": "При втраті фокуса емулятором:",
- "zh_CN": "当模拟器在后台时:",
- "zh_TW": "當模擬器「失去焦點」(如切換工作)時:"
+ "zh_CN": "当模拟器失去焦点时:",
+ "zh_TW": "當模擬器失去焦點時:"
}
},
{
"ID": "SettingsTabGeneralFocusLossTypeDoNothing",
"Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
+ "ar_SA": "لا تفعل شيئًا",
+ "de_DE": "Nichts tun",
+ "el_GR": "Μη κάνεις τίποτα",
"en_US": "Do Nothing",
"es_ES": "No Hacer Nada",
"fr_FR": "Ne Rien Faire",
- "he_IL": "",
- "it_IT": "",
- "ja_JP": "",
+ "he_IL": "לא לעשות כלום",
+ "it_IT": "Non fare nulla",
+ "ja_JP": "何もしない",
"ko_KR": "아무것도 하지 않음",
- "no_NO": "Gjør Ingenting",
- "pl_PL": "",
+ "no_NO": "Ikke gjør noe",
+ "pl_PL": "Nie rób nic",
"pt_BR": "Não Fazer Nada",
"ru_RU": "Ничего не делать",
"sv_SE": "Gör ingenting",
- "th_TH": "ไม่ตอบสนอง",
- "tr_TR": "",
+ "th_TH": "ไม่ทำอะไร",
+ "tr_TR": "Hiçbir şey yapma",
"uk_UA": "Нічого не робити",
- "zh_CN": "什么事情也不做",
- "zh_TW": "沒有動作"
+ "zh_CN": "什么也不做",
+ "zh_TW": "什麼都不做"
}
},
{
"ID": "SettingsTabGeneralFocusLossTypeBlockInput",
"Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
+ "ar_SA": "حظر الإدخال",
+ "de_DE": "Eingabe blockieren",
+ "el_GR": "Αποκλεισμός εισόδου",
"en_US": "Block Input",
"es_ES": "Bloquear Entrada",
"fr_FR": "Bloquer la Saisie",
- "he_IL": "",
- "it_IT": "",
- "ja_JP": "",
+ "he_IL": "חסום קלט",
+ "it_IT": "Blocca input",
+ "ja_JP": "入力をブロック",
"ko_KR": "입력 차단",
- "no_NO": "Blokkinngang",
- "pl_PL": "",
- "pt_BR": "Bloquear Controles",
- "ru_RU": "Блокировать управление",
+ "no_NO": "Blokker inndata",
+ "pl_PL": "Zablokuj wejście",
+ "pt_BR": "Bloquear controles",
+ "ru_RU": "Блокировать ввод",
"sv_SE": "Blockera inmatning",
- "th_TH": "ป้องกันการป้อนข้อมูล",
- "tr_TR": "",
- "uk_UA": "Блокувати введення",
- "zh_CN": "禁用输入",
- "zh_TW": "停用輸入"
+ "th_TH": "บล็อกการป้อนข้อมูล",
+ "tr_TR": "Girişi Engelle",
+ "uk_UA": "Заблокувати введення",
+ "zh_CN": "阻止输入",
+ "zh_TW": "阻止輸入"
}
},
{
"ID": "SettingsTabGeneralFocusLossTypeMuteAudio",
"Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
+ "ar_SA": "كتم الصوت",
+ "de_DE": "Lautstärke stumm",
+ "el_GR": "Σίγαση έντασης",
"en_US": "Mute Volume",
- "es_ES": "Silenciar el Volumen",
+ "es_ES": "Silenciar Volumen",
"fr_FR": "Couper le Son",
- "he_IL": "",
- "it_IT": "",
- "ja_JP": "",
+ "he_IL": "כבה את הווליום",
+ "it_IT": "Disattiva volume",
+ "ja_JP": "音量をミュート",
"ko_KR": "음소거",
- "no_NO": "Demp Lyd",
- "pl_PL": "",
- "pt_BR": "Ficar Mudo",
+ "no_NO": "Dempe volumet",
+ "pl_PL": "Wycisz głośność",
+ "pt_BR": "Ficar mudo",
"ru_RU": "Отключить звук",
"sv_SE": "Stäng av ljudet",
"th_TH": "ปิดเสียง",
- "tr_TR": "",
+ "tr_TR": "Sesi Kapat",
"uk_UA": "Вимкнути звук",
"zh_CN": "静音",
"zh_TW": "靜音"
@@ -3595,49 +3495,49 @@
{
"ID": "SettingsTabGeneralFocusLossTypeBlockInputAndMuteAudio",
"Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
+ "ar_SA": "حظر الإدخال وكتم الصوت",
+ "de_DE": "Eingabe blockieren & Ton stumm",
+ "el_GR": "Αποκλεισμός εισόδου & σίγαση ήχου",
"en_US": "Block Input & Mute Volume",
"es_ES": "Bloquear Entrada y Silenciar el Volumen",
"fr_FR": "Bloquer la Saisie & Couper le Son",
- "he_IL": "",
- "it_IT": "",
- "ja_JP": "",
- "ko_KR": "입력 차단 및 음소거",
- "no_NO": "Blokker Inputs og demp Volumet",
- "pl_PL": "",
- "pt_BR": "Bloquear Controles & Ficar Mudo",
- "ru_RU": "Блокировать управление и отключить звук",
- "sv_SE": "Blockera inmatningar och stäng av ljudet",
- "th_TH": "ป้องกันการป้อนข้อมูลและปิดเสียง",
- "tr_TR": "",
- "uk_UA": "Блокувати введення та Вимкнути звук",
- "zh_CN": "阻止输入并静音",
- "zh_TW": "停用輸入且靜音"
+ "he_IL": "חסום קלט וכבה קול",
+ "it_IT": "Blocca input & silenzia volume",
+ "ja_JP": "入力をブロック&音量を消音",
+ "ko_KR": "입력 차단 & 음소거",
+ "no_NO": "Blokker innmating & demp lyd",
+ "pl_PL": "Blokuj wejście & wycisz dźwięk",
+ "pt_BR": "Bloquear controles & silenciar",
+ "ru_RU": "Блокировать ввод & отключить звук",
+ "sv_SE": "Blockera input & stäng av ljud",
+ "th_TH": "บล็อกข้อมูล & ปิดเสียง",
+ "tr_TR": "Girişi engelle & sesi kapat",
+ "uk_UA": "Блокувати введення & вимкнути звук",
+ "zh_CN": "阻止输入 & 静音",
+ "zh_TW": "停用輸入 & 靜音"
}
},
{
"ID": "SettingsTabGeneralFocusLossTypePauseEmulation",
"Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
+ "ar_SA": "إيقاف التشغيل مؤقتًا",
+ "de_DE": "Emulation pausieren",
+ "el_GR": "Παύση προσομοίωσης",
"en_US": "Pause Emulation",
"es_ES": "Pausar Emulación",
"fr_FR": "Pauser l'Émulation",
- "he_IL": "",
- "it_IT": "",
- "ja_JP": "",
- "ko_KR": "에뮬레이션 일시 중지",
+ "he_IL": "השהיית האמולציה",
+ "it_IT": "Pausa emulazione",
+ "ja_JP": "エミュレーション一時停止",
+ "ko_KR": "에뮬레이션 일시중지",
"no_NO": "Pause Emulatoren",
- "pl_PL": "",
- "pt_BR": "Pausar a Emulação",
- "ru_RU": "Поставить паузу",
+ "pl_PL": "Wstrzymaj emulację",
+ "pt_BR": "Pausar emulação",
+ "ru_RU": "Пауза эмуляции",
"sv_SE": "Pausa emuleringen",
"th_TH": "พักการจำลอง",
- "tr_TR": "",
- "uk_UA": "Поставити на паузу",
+ "tr_TR": "Emülasyonu Duraklat",
+ "uk_UA": "Пауза емуляції",
"zh_CN": "暂停模拟",
"zh_TW": "暫停模擬"
}
@@ -3645,26 +3545,26 @@
{
"ID": "SettingsTabGeneralShowConfirmExitDialog",
"Translations": {
- "ar_SA": "إظهار مربع حوار \"تأكيد الخروج\"",
- "de_DE": "Zeige den \"Beenden bestätigen\"-Dialog",
- "el_GR": "Εμφάνιση διαλόγου \"Επιβεβαίωση Εξόδου\".",
- "en_US": "Show \"Confirm Exit\" Dialog",
- "es_ES": "Mostrar Diálogo de Confirmación al Cerrar",
- "fr_FR": "Afficher le Message de \"Confirmation de sortie\"",
- "he_IL": "הראה דיאלוג \"אשר יציאה\"",
- "it_IT": "Mostra dialogo \"Conferma Uscita\"",
- "ja_JP": "\"終了を確認\" ダイアログを表示する",
- "ko_KR": "\"종료 확인\" 대화 상자 표시",
- "no_NO": "Vis \"Bekreft Avslutt\" vinduet",
- "pl_PL": "Pokazuj okno dialogowe \"Potwierdź wyjście\"",
- "pt_BR": "Exibir \"Diálogo de confirmação\" ao Sair",
- "ru_RU": "Подтверждать выход из игры",
- "sv_SE": "Visa \"Bekräfta avslut\"-dialog",
- "th_TH": "แสดง \"ปุ่มยืนยันการออก\" เมื่อออกเกม",
- "tr_TR": "\"Çıkışı Onayla\" Diyaloğunu Göster",
- "uk_UA": "Показати діалогове вікно «Підтвердити вихід».",
- "zh_CN": "退出游戏时需要确认",
- "zh_TW": "顯示「確認結束」對話方塊"
+ "ar_SA": "تأكيد إيقاف اللعبة",
+ "de_DE": "Bestätige Spiel Shutdown",
+ "el_GR": "Επιβεβαίωση τερματισμού παιχνιδιού",
+ "en_US": "Confirm Game Shutdown",
+ "es_ES": "Confirmar Cierre del Juego",
+ "fr_FR": "Confirmer l'Arrêt du Jeu",
+ "he_IL": "אשר סיום המשחק",
+ "it_IT": "Conferma Chiusura Gioco",
+ "ja_JP": "ゲーム終了確認",
+ "ko_KR": "게임 종료 확인",
+ "no_NO": "Bekreft Spill Avslutning",
+ "pl_PL": "Potwierdź zamknięcie gry",
+ "pt_BR": "Confirmar fechamento do jogo",
+ "ru_RU": "Подтверждать завершение игры",
+ "sv_SE": "Bekräfta Spelavslut",
+ "th_TH": "ยืนยันการปิดเกม",
+ "tr_TR": "Oyun Kapanışını Onayla",
+ "uk_UA": "Підтвердження закриття гри",
+ "zh_CN": "确认关闭游戏",
+ "zh_TW": "確認關閉遊戲"
}
},
{
@@ -3672,23 +3572,23 @@
"Translations": {
"ar_SA": "تذكر حجم/موضع النافذة",
"de_DE": "Fenstergröße/-position merken",
- "el_GR": "",
+ "el_GR": "Απομνημόνευση μεγέθους/θέσης παραθύρου",
"en_US": "Remember Window Size/Position",
"es_ES": "Recordar Tamaño/Posición de la Ventana",
"fr_FR": "Mémoriser la Taille/Position de la Fenêtre",
- "he_IL": "",
- "it_IT": "Ricorda la dimensione e la posizione della finestra",
- "ja_JP": "",
+ "he_IL": "זכור גודל/מיקום חלון",
+ "it_IT": "Ricorda dimensione/posizione finestra",
+ "ja_JP": "ウィンドウのサイズと位置を記憶",
"ko_KR": "창 크기/위치 기억",
- "no_NO": "Husk vinduets størrelse/posisjon",
- "pl_PL": "",
- "pt_BR": "Lembrar Tamanho e Posição da Janela",
+ "no_NO": "Husk vindusstørrelse/posisjon",
+ "pl_PL": "Zapamiętaj rozmiar/pozycję okna",
+ "pt_BR": "Lembrar tamanho/posição da janela",
"ru_RU": "Запомнить размер/положение окна",
"sv_SE": "Kom ihåg fönstrets storlek/position",
- "th_TH": "จดจำ ขนาดหน้าต่างแอพพลิเคชั่น/คำแหน่ง",
- "tr_TR": "",
- "uk_UA": "Запам'ятати Розмір/Позицію вікна",
- "zh_CN": "记住窗口大小和位置",
+ "th_TH": "จดจำขนาดและตำแหน่งหน้าต่าง",
+ "tr_TR": "Pencere Boyutu/Konumu Hatırla",
+ "uk_UA": "Запам’ятати розмір/позицію вікна",
+ "zh_CN": "记住窗口大小/位置",
"zh_TW": "記住視窗大小/位置"
}
},
@@ -3702,7 +3602,7 @@
"es_ES": "Desactivar la Entrada al Perder el Foco",
"fr_FR": "Désactiver la Saisie en cas de Perte de Focus",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Disabilità Input quando fuori dal focus",
"ja_JP": "",
"ko_KR": "초점이 맞지 않으면 입력 비활성화",
"no_NO": "Deaktiver inndata når vinduet er ute av fokus",
@@ -3720,114 +3620,89 @@
{
"ID": "SettingsTabGeneralShowOldUI",
"Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
- "en_US": "Show Original UI Style (Requires Restart)",
- "es_ES": "Mostrar la Interfaz Original (requiere un reincio)",
- "fr_FR": "Afficher le Style d’Interface Utilisateur Original (Redémarrage requis)",
- "he_IL": "",
- "it_IT": "",
- "ja_JP": "",
- "ko_KR": "원래 UI 스타일 표시(다시 시작 필요)",
- "no_NO": "Vis original UI-stil (krever omstart)",
- "pl_PL": "",
- "pt_BR": "Mostrar Estilo Original da Interface (Requer Reinicialização)",
- "ru_RU": "Оригинальный интерфейс (требуется перезагрузка)",
- "sv_SE": "Visa ursprunglig gränssnittsstil (kräver omstart)",
- "th_TH": "แสดงรูปแบบอินเทอร์เฟซเดิม (ต้องเริ่มโปรแกรมใหม่)",
- "tr_TR": "",
- "uk_UA": "Показати оригінальний UI (Потрібен перезапуск)",
- "zh_CN": "显示原始 UI 样式 (需要重启)",
- "zh_TW": "顯示原始 UI 樣式 (需要重新啟動 Ryujinx)"
+ "ar_SA": "الواجهة الكلاسيكية (مطلوب إعادة تشغيل)",
+ "de_DE": "Klassische Oberfläche (Neustart nötig)",
+ "el_GR": "Κλασική διεπαφή (Απαιτείται επανεκκίνηση)",
+ "en_US": "Classic Interface (Requires Restart)",
+ "es_ES": "Interfaz Clásica (Requiere Reiniciar)",
+ "fr_FR": "Interface Classique (Redémarrage Requis)",
+ "he_IL": "ממשק קלאסי (הפעלה מחדש דרושה)",
+ "it_IT": "Interfaccia classica (Riavvio necessario)",
+ "ja_JP": "クラシックインターフェース(再起動必要)",
+ "ko_KR": "클래식 인터페이스 (재시작 필요)",
+ "no_NO": "Klassisk grensesnitt (Krever omstart)",
+ "pl_PL": "Klasyczny interfejs (Wymaga restartu)",
+ "pt_BR": "Interface Clássica (Reinício necessário)",
+ "ru_RU": "Классический интерфейс (Треб. перезапуск)",
+ "sv_SE": "Klassiskt gränssnitt (Omstart krävs)",
+ "th_TH": "อินเทอร์เฟซคลาสสิก (รีสตาร์ทจำเป็น)",
+ "tr_TR": "Klasik arayüz (Yeniden başlatma gerekli)",
+ "uk_UA": "Класичний інтерфейс (Потрібен перезапуск)",
+ "zh_CN": "经典界面(需重启)",
+ "zh_TW": "經典介面(需重啟)"
}
},
{
"ID": "SettingsTabGeneralShowOldUIToolTip",
"Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
- "en_US": "Show the older Avalonia Ryujinx UI reminiscent of Ryujinx 1.1.1403. This is enabled by default on platforms that are not Windows.\n\nThe classic-style title bar is back and major window layout reworkings are reversed; such as the settings navigation placement above this tooltip.",
- "es_ES": "Mostrar la antigua interfaz Avalonia de Ryujinx, similar a la versión 1.1.1403. Esto está activado por defecto en plataformas que no son Windows.\n\nLa barra de título de estilo clásico ha vuelto y se revierten los principales cambios en el diseño de las ventanas; por ejemplo, la navegación de configuración ahora aparece sobre esta sugerencia",
- "fr_FR": "Afficher l’ancienne interface Avalonia Ryujinx, rappelant Ryujinx 1.1.1403. Cette option est activée par défaut sur les plateformes autres que Windows.\n\nLa barre de titre au style classique est de retour et les modifications majeures de la disposition des fenêtres sont annulées, comme le placement de la navigation des paramètres au-dessus de cette infobulle.",
- "he_IL": "",
- "it_IT": "",
- "ja_JP": "",
- "ko_KR": "Ryujinx 1.1.1403을 연상시키는 이전 Avalonia Ryujinx UI를 표시합니다. 이 기능은 윈도가 아닌 플랫폼에서는 기본적으로 활성화됩니다.\n\n 클래식 스타일의 타이틀 바가 돌아왔고 주요 창 레이아웃 변경 사항이 원래대로 적용됩니다. 이 툴팁 위의 설정 탐색 배치와 같은 경우입니다.",
- "no_NO": "Vis det eldre Avalonia Ryujinx-grensesnittet som minner om Ryujinx 1.1.1403. Dette er aktivert som standard på plattformer som ikke er Windows.\n\nTittellinjen i klassisk stil er tilbake, og store omarbeidinger av vindusoppsettet er reversert, for eksempel plasseringen av innstillingsnavigasjonen over dette verktøytipset.",
- "pl_PL": "",
- "pt_BR": "Mostrar a Interface Avalonia antiga do Ryujinx 1.1.1403. Esta versão é ativada por padrão nas plataformas que não sejam Windows.\n\nO estilo clássico da Barra de Título retorna e grande parte das mudanças do Layout de janela são revertidas; assim como as configurações de posicionamento da navegação acima dessa descrição.",
- "ru_RU": "Показать старый пользовательский интерфейс Avalonia Ryujinx, напоминающий Ryujinx 1.1.1403. Включено по умолчанию на платформах, отличных от Windows.\n\nКлассическая панель заголовка возвращается, а основные изменения в расположении окон отменяются — например, навигация по настройкам — снова расположена выше этой подсказки.",
- "sv_SE": "Visa det gamla Ryuijinx-gränssnittet baserat på Avalonia som påminner om version 1.1.1403. Detta är aktiverat som standard på plattformat som inte är Windows.\n\nDen klassiska titelfältet är tillbaka och de stora omarbetningarna av fönsterlayouten är omvända, till exempel placeringen av inställningsnavigeringen ovanför detta verktygstips.",
- "th_TH": "แสดง UI แบบเก่าของ Avalonia Ryujinx ที่คล้ายกับเวอร์ชัน 1.1.1403 (เปิดใช้งานโดยอัตโนมัติในระบบที่ไม่ใช่ Windows)\n\nแถบชื่อหน้าต่างแบบดั้งเดิมกลับมาแล้ว และการจัดวางหน้าต่างที่เคยเปลี่ยนไปก็ถูกปรับกลับ เช่น ตำแหน่งของเมนูการตั้งค่าเหนือข้อความนี้",
- "tr_TR": "",
- "uk_UA": "Показати старий інтерфейс Avalonia Ryujinx, який був у Ryujinx 1.1.1403. Ця опція активна за замовчуванням на всіх інших, окрім Windows платформах.\n\nПовернеться класична панель заголовка, а всі суттєві зміни інтерфейсу будуть скасовані, зокрема горизонтальне розміщення навігації в налаштуваннях.",
- "zh_CN": "显示旧的类似 Ryujinx 1.1.1403 的 Avalonia Ryujinx UI。在非 Windows 平台上默认启用此选项。\n\n经典样式的标题栏已回归并且恢复了对窗口布局的重大重构;例如在工具提示上方放置设置导航。",
- "zh_TW": "顯示舊版 Ryujinx 1.1.1403 的 Avalonia UI 樣式。在非 Windows 平台預設啟用。\n\n經典樣式的標題欄已回歸,並且還原了對設定視窗佈局的大型重構:例如在工具提示上方設置導覽列。"
+ "ar_SA": "يعرض واجهة Ryujinx القديمة التي تذكر بإصدار Ryujinx 1.1.1403. هذا الخيار مفعل بشكل افتراضي على الأنظمة غير ويندوز.\n\nشريط العنوان الكلاسيكي عاد وتمت إعادة العروض الكبرى للتخطيط، مثل موضع التنقل في الإعدادات.",
+ "de_DE": "Zeigt die ältere Ryujinx-Benutzeroberfläche, die an Ryujinx 1.1.1403 erinnert. Diese Option ist standardmäßig auf Plattformen aktiviert, die nicht Windows sind.\n\nDie klassische Titelleiste ist zurück und wesentliche Layoutänderungen werden rückgängig gemacht, wie zum Beispiel die Platzierung der Einstellungen-Navigation.",
+ "el_GR": "Εμφανίζει την παλαιότερη διεπαφή χρήστη Ryujinx που θυμίζει το Ryujinx 1.1.1403. Αυτή η επιλογή είναι ενεργοποιημένη από προεπιλογή σε πλατφόρμες που δεν είναι Windows.\n\nΗ κλασική γραμμή τίτλου επιστρέφει και βασικές επεξεργασίες στη διάταξη αντιστρέφονται, όπως η θέση της πλοήγησης ρυθμίσεων.",
+ "en_US": "Shows the older Ryujinx UI reminiscent of Ryujinx 1.1.1403. This option enabled by default on platforms that are not Windows.\n\nThe classic title bar is back and major layout reworkings are reversed, such as the settings navigation placement.",
+ "es_ES": "Muestra la antigua interfaz Ryujinx que recuerda a Ryujinx 1.1.1403. Esta opción está activada por defecto en plataformas que no son Windows.\n\nLa barra de título clásica ha vuelto y los grandes cambios en el diseño se revierten, como la colocación de la navegación de ajustes.",
+ "fr_FR": "Affiche l’ancienne interface Ryujinx rappelant Ryujinx 1.1.1403. Cette option est activée par défaut sur les plateformes autres que Windows.\n\nLa barre de titre classique est de retour et les grandes modifications de disposition sont annulées, comme le placement de la navigation des paramètres.",
+ "he_IL": "מציג את ממשק המשתמש הישן של Ryujinx המזכיר את Ryujinx 1.1.1403. אפשרות זו מופעלת כברירת מחדל בפלטפורמות שאינן Windows.\n\nסרגל הכותרת הקלאסי חזר ועיצוב הממשק העיקרי התהפך, כמו מיקום הניווט בהגדרות.",
+ "it_IT": "Mostra l’interfaccia Ryujinx più vecchia che ricorda Ryujinx 1.1.1403. Questa opzione è abilitata di default sulle piattaforme non Windows.\n\nLa barra del titolo classica è tornata e le principali modifiche al layout sono state annullate, come la posizione della navigazione delle impostazioni.",
+ "ja_JP": "Ryujinx 1.1.1403を思い起こさせる古いRyujinx UIを表示します。このオプションはWindows以外のプラットフォームでデフォルトで有効になっています。\n\nクラシックなタイトルバーが復活し、設定ナビゲーションの配置など大幅なレイアウト変更が元に戻されました。",
+ "ko_KR": "Ryujinx 1.1.1403을 연상시키는 이전 Ryujinx UI를 표시합니다. 이 옵션은 Windows가 아닌 플랫폼에서 기본적으로 활성화되어 있습니다.\n\n클래식 타이틀 바가 돌아왔고 주요 레이아웃 변경 사항이 원래대로 되돌려졌습니다. 예를 들어 설정 탐색 위치 등입니다.",
+ "no_NO": "Vis det eldre Ryujinx-grensesnittet som minner om Ryujinx 1.1.1403. Dette er aktivert som standard på plattformer som ikke er Windows.\n\nDen klassiske tittellinjen er tilbake, og store omarbeidinger av layouten er reversert, som plasseringen av innstillingsnavigasjonen.",
+ "pl_PL": "Wyświetla starszy interfejs Ryujinx przypominający Ryujinx 1.1.1403. Ta opcja jest domyślnie włączona na platformach innych niż Windows.\n\nKlasyczny pasek tytułu powraca, a główne zmiany w układzie są cofane, takie jak umiejscowienie nawigacji ustawień.",
+ "pt_BR": "Mostra a interface antiga do Ryujinx que lembra a versão 1.1.1403. Esta opção está ativada por padrão em plataformas que não sejam Windows.\n\nA barra de título clássica está de volta e as principais alterações no layout foram revertidas, como a posição da navegação das configurações.",
+ "ru_RU": "Показывает старый интерфейс Ryujinx, напоминающий Ryujinx 1.1.1403. Эта опция включена по умолчанию на платформах, отличных от Windows.\n\nКлассическая строка заголовка возвращается, а основные изменения в расположении элементов отменяются, например, положение навигации настроек.",
+ "sv_SE": "Visar det äldre Ryujinx-gränssnittet som påminner om Ryujinx 1.1.1403. Detta är aktiverat som standard på plattformar som inte är Windows.\n\nDen klassiska titelraden är tillbaka och stora layoutförändringar återställs, till exempel placeringen av inställningsnavigeringen.",
+ "th_TH": "แสดง UI แบบเก่าของ Ryujinx ที่คล้ายกับ Ryujinx 1.1.1403 ตัวเลือกนี้เปิดใช้งานโดยค่าเริ่มต้นในแพลตฟอร์มที่ไม่ใช่ Windows\n\nแถบชื่อเรื่องคลาสสิกกลับมาแล้ว และการปรับเปลี่ยนเลย์เอาต์หลักได้รับการย้อนกลับ เช่น ตำแหน่งการนำทางการตั้งค่า",
+ "tr_TR": "Ryujinx 1.1.1403'ü anımsatan eski Ryujinx kullanıcı arayüzünü gösterir. Bu seçenek Windows dışındaki platformlarda varsayılan olarak etkinleştirilmiştir.\n\nKlasik başlık çubuğu geri geldi ve ayarları gezinme konumu gibi büyük düzenlemeler geri alındı。",
+ "uk_UA": "Показує старий інтерфейс Ryujinx, який нагадує Ryujinx 1.1.1403. Ця опція ввімкнена за замовчуванням на платформах, окрім Windows.\n\nПовертається класична рядок заголовка, а великі зміни в макеті відміняються, як-от розташування навігації налаштувань.",
+ "zh_CN": "显示旧版 Ryujinx 用户界面,类似于 Ryujinx 1.1.1403。在非 Windows 平台上默认启用该选项。\n\n经典标题栏回归,主要布局变更被撤销,例如设置导航的位置。",
+ "zh_TW": "顯示類似 Ryujinx 1.1.1403 的舊版 Ryujinx 使用者介面。此選項在非 Windows 平台預設啟用。\n\n經典標題列回歸,主要的佈局變更被還原,例如設定導覽的位置。"
}
},
{
"ID": "SettingsTabGeneralHideCursor",
"Translations": {
"ar_SA": "إخفاء المؤشر:",
- "de_DE": "Mauszeiger ausblenden",
- "el_GR": "Απόκρυψη Κέρσορα:",
+ "de_DE": "Mauszeiger ausblenden:",
+ "el_GR": "Απόκρυψη δείκτη:",
"en_US": "Hide Cursor:",
- "es_ES": "Esconder el Cursor:",
+ "es_ES": "Esconder Cursor:",
"fr_FR": "Masquer le Curseur :",
- "he_IL": "הסתר את הסמן",
+ "he_IL": "הסתר את הסמן:",
"it_IT": "Nascondi il cursore:",
- "ja_JP": "マウスカーソルを非表示",
+ "ja_JP": "マウスカーソルを非表示:",
"ko_KR": "커서 숨기기 :",
"no_NO": "Skjul musepeker:",
"pl_PL": "Ukryj kursor:",
- "pt_BR": "Esconder Cursor do Mouse:",
+ "pt_BR": "Esconder cursor:",
"ru_RU": "Скрывать курсор:",
- "sv_SE": "Dölj markör:",
+ "sv_SE": "Dölj pekare:",
"th_TH": "ซ่อน เคอร์เซอร์:",
"tr_TR": "İşaretçiyi Gizle:",
"uk_UA": "Сховати курсор:",
"zh_CN": "隐藏鼠标指针:",
- "zh_TW": "隱藏滑鼠游標:"
- }
- },
- {
- "ID": "SettingsTabGeneralHideCursorNever",
- "Translations": {
- "ar_SA": "مطلقا",
- "de_DE": "Niemals",
- "el_GR": "Ποτέ",
- "en_US": "Never",
- "es_ES": "Nunca",
- "fr_FR": "Jamais",
- "he_IL": "אף פעם",
- "it_IT": "Mai",
- "ja_JP": "決して",
- "ko_KR": "절대 안 함",
- "no_NO": "Aldri",
- "pl_PL": "Nigdy",
- "pt_BR": "Nunca",
- "ru_RU": "Никогда",
- "sv_SE": "Aldrig",
- "th_TH": "ไม่ต้อง",
- "tr_TR": "Hiçbir Zaman",
- "uk_UA": "Ніколи",
- "zh_CN": "从不隐藏",
- "zh_TW": "從不"
+ "zh_TW": "隱藏滑鼠指標:"
}
},
{
"ID": "SettingsTabGeneralHideCursorOnIdle",
"Translations": {
"ar_SA": "عند الخمول",
- "de_DE": "Mauszeiger bei Inaktivität ausblenden",
- "el_GR": "Απόκρυψη Δρομέα στην Αδράνεια",
+ "de_DE": "Bei Inaktivität",
+ "el_GR": "Εάν ανενεργός",
"en_US": "On Idle",
- "es_ES": "Mientras Inactivo",
+ "es_ES": "Si Inactivo",
"fr_FR": "Si Inactif",
"he_IL": "במצב סרק",
- "it_IT": "Quando è inattivo",
+ "it_IT": "Se inattivo",
"ja_JP": "アイドル時",
"ko_KR": "유휴 상태",
"no_NO": "Når inaktiv",
@@ -3837,7 +3712,7 @@
"sv_SE": "Vid overksam",
"th_TH": "เมื่อไม่ได้ใช้งาน",
"tr_TR": "Hareketsiz Durumda",
- "uk_UA": "Сховати у режимі очікування",
+ "uk_UA": "Якщо неактивний",
"zh_CN": "自动隐藏",
"zh_TW": "閒置時"
}
@@ -3895,51 +3770,51 @@
{
"ID": "SettingsTabGeneralAutoloadDirectories",
"Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
+ "ar_SA": "تحميل تلقائي للمجلدات DLC/التحديثات",
+ "de_DE": "Automatisches Laden DLC/Update-Ordner",
+ "el_GR": "Αυτόματο φόρτωμα φακέλων DLC/Ενημερώσεων",
"en_US": "Autoload DLC/Updates Directories",
- "es_ES": "Carpetas de DLC/Actualizaciones para Carga Automática",
- "fr_FR": "Dossiers des DLC/Mises à Jour",
- "he_IL": "",
- "it_IT": "Cartelle di caricamento automatico di DLC/aggiornamenti",
- "ja_JP": "",
+ "es_ES": "Carga automática Carpetas DLC/Actualizaciones",
+ "fr_FR": "Chargement automatique Dossiers DLC/Mises à Jour",
+ "he_IL": "טעינה אוטומטית של תיקיות DLC/עדכונים",
+ "it_IT": "Caricamento automatico Cartelle DLC/Aggiornamenti",
+ "ja_JP": "DLC/アップデートフォルダ自動読み込み",
"ko_KR": "DLC/업데이트 디렉터리 자동 불러오기",
- "no_NO": "Autoload DLC/Updates-mapper",
- "pl_PL": "",
- "pt_BR": "Carregar Automaticamente Pasta de DLC e Atualizações",
- "ru_RU": "Автозагрузка папок с DLC/Обновлениями",
- "sv_SE": "Läs automatiskt in DLC/speluppdateringar",
- "th_TH": "โหลดไดเรกทอรี DLC/ไฟล์อัปเดต อัตโนมัติ",
- "tr_TR": "",
- "uk_UA": "Автозавантаження теки DLC/Оновлень",
- "zh_CN": "自动加载 DLC 及 游戏更新 的目录",
- "zh_TW": "自動載入 DLC/遊戲更新資料夾"
+ "no_NO": "Automatisk lasting DLC/Updates-mapper",
+ "pl_PL": "Automatyczne ładowanie folderów DLC/aktualizacji",
+ "pt_BR": "Carregamento automático Pastas DLC/Atualizações",
+ "ru_RU": "Автоматическая загрузка папок DLC/Обновлений",
+ "sv_SE": "Automatiskt laddande DLC/Uppdateringsmappar",
+ "th_TH": "โหลดอัตโนมัติ DLC/อัปเดตไดเรกทอรี",
+ "tr_TR": "DLC/Güncelleme Klasörlerini Otomatik Yükle",
+ "uk_UA": "Автоматичне завантаження теки DLC/Оновлень",
+ "zh_CN": "自动加载 DLC/更新目录",
+ "zh_TW": "自動載入 DLC/更新資料夾"
}
},
{
"ID": "SettingsTabGeneralAutoloadNote",
"Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
- "en_US": "DLC and Updates which refer to missing files will be unloaded automatically",
- "es_ES": "DLC y Actualizaciones que hacen referencia a archivos ausentes serán desactivado automáticamente",
- "fr_FR": "Les DLC et les Mises à Jour faisant référence aux fichiers manquants seront automatiquement déchargés.",
- "he_IL": "",
- "it_IT": "Aggiornamenti e DLC che fanno riferimento a file mancanti verranno disabilitati automaticamente",
- "ja_JP": "",
- "ko_KR": "누락된 파일을 참조하는 DLC 및 업데이트가 자동으로 불러오기 취소",
- "no_NO": "DLC og oppdateringer som henviser til manglende filer, vil bli lastet ned automatisk",
- "pl_PL": "",
- "pt_BR": "DLCs e Atualizações que se referem a arquivos ausentes serão desabilitados automaticamente",
- "ru_RU": "DLC и обновления, ссылающиеся на отсутствующие файлы, будут автоматически выгружены",
- "sv_SE": "DLC och speluppdateringar som refererar till saknade filer kommer inte att läsas in automatiskt",
- "th_TH": "DLC และอัปเดตที่มีการอ้างอิงถึงไฟล์ที่ไม่มีอยู่ จะถูกปิดการใช้งานโดยอัตโนมัติ",
- "tr_TR": "",
- "uk_UA": "DLC та Оновлення, які посилаються на відсутні файли, будуть автоматично вимкнуті.",
- "zh_CN": "DLC 及 游戏更新 可自动加载和卸载",
- "zh_TW": "遺失的 DLC 及遊戲更新檔案將會在自動載入中移除"
+ "ar_SA": "DLC/التحديثات المتعلقة بالملفات/الألعاب المفقودة ستُزال تلقائيًا",
+ "de_DE": "DLC/Updates, die auf fehlende Dateien/Spiele verweisen, werden automatisch entladen",
+ "el_GR": "DLC/Ενημερώσεις για αρχεία/παιχνίδια που λείπουν θα αποφορτωθούν αυτόματα",
+ "en_US": "DLC/Updates Referring To Missing Files/Games Will Unload Automatically",
+ "es_ES": "DLC/Actualizaciones que hacen referencia a archivos/juegos ausentes se descargarán automáticamente",
+ "fr_FR": "DLC/Mises à jour concernant des fichiers/jeux manquants seront déchargées automatiquement",
+ "he_IL": "DLC/עדכונים המתייחסים לקבצים/משחקים חסרים יוסרו אוטומטית",
+ "it_IT": "DLC/Aggiornamenti relativi a file/gioco mancanti verranno disabilitati automaticamente",
+ "ja_JP": "DLC/欠損ファイル/ゲームを参照するアップデートは自動的にアンロードされます",
+ "ko_KR": "DLC/누락된 파일/게임을 참조하는 업데이트는 자동으로 언로드됩니다",
+ "no_NO": "DLC/Oppdateringer som refererer til manglende filer/spill vil automatisk lastes ut",
+ "pl_PL": "DLC/Aktualizacje odnoszące się do brakujących plików/gier będą automatycznie usuwane",
+ "pt_BR": "DLC/Atualizações que fazem referência a arquivos/jogos ausentes serão desabilitadas automaticamente",
+ "ru_RU": "DLC/Обновления, ссылающиеся на отсутствующие файлы/игры, будут автоматически выгружены",
+ "sv_SE": "DLC/Uppdateringar som hänvisar till saknade filer/spel kommer att avlastas automatiskt",
+ "th_TH": "DLC/การอัปเดตที่อ้างถึงไฟล์/เกมที่หายไปจะถูกยกเลิกการโหลดโดยอัตโนมัติ",
+ "tr_TR": "DLC/Eksik dosya/oyunları referans alan güncellemeler otomatik olarak kaldırılacak",
+ "uk_UA": "DLC/Оновлення, що посилаються на відсутні файли/ігри, будуть автоматично вимкнені",
+ "zh_CN": "DLC/引用缺失文件/游戏的更新将自动卸载",
+ "zh_TW": "DLC/引用缺少檔案/遊戲的更新將自動卸載"
}
},
{
@@ -4152,7 +4027,7 @@
"es_ES": null,
"fr_FR": "Australie",
"he_IL": "אוסטרליה",
- "it_IT": "",
+ "it_IT": "Australia",
"ja_JP": "オーストラリア",
"ko_KR": "호주",
"no_NO": "",
@@ -4227,7 +4102,7 @@
"es_ES": "Taiwán",
"fr_FR": "Taïwan",
"he_IL": "טייוואן",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "台湾",
"ko_KR": "대만",
"no_NO": "",
@@ -4552,7 +4427,7 @@
"es_ES": "Taiwanés",
"fr_FR": "Taïwanais",
"he_IL": "טייוואנית",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "台湾語",
"ko_KR": "대만어",
"no_NO": "Taiwansk",
@@ -4752,7 +4627,7 @@
"es_ES": "Usar Hora del Sistema",
"fr_FR": "Synchroniser avec l’heure du système",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Sincronizza con l'orario del sistema",
"ja_JP": "",
"ko_KR": "매치 시스템 시간",
"no_NO": "Match systemtid",
@@ -4827,7 +4702,7 @@
"es_ES": "Multiplicator del Modo Turbo:",
"fr_FR": "Multiplicateur du Mode Turbo :",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Moltiplicatore di Modalità Turbo ",
"ja_JP": "",
"ko_KR": "터보 모드 배수 :",
"no_NO": "Multiplikator i turbomodus:",
@@ -4852,7 +4727,7 @@
"es_ES": "Valor objetivo del multiplicador del modo turbo.\n\nDéjar en 200 si no está seguro.",
"fr_FR": "La valeur souhaitée du multiplicateur du mode Turbo.\n\nLaissez à 200 si vous n'êtes pas sûr.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Il valore target del moltiplicatore della modalità Turbo.\n\nLascia a 200 se non sei sicuro.",
"ja_JP": "",
"ko_KR": "터보 모드 배수 목표 값입니다.\n\n모르면 200으로 두세요.",
"no_NO": "Målverdien for multiplikatoren i turbomodus. \n\nLa syå på 200 hvis du er usikker.",
@@ -4862,7 +4737,7 @@
"sv_SE": "Målvärdet för multiplikatorn i turboläget. \n\nLämna den på 200 om du är osäker.",
"th_TH": "กำหนดค่าตัวคูณสำหรับโหมดเทอร์โบ\n\n(หากไม่แน่ใจ ให้ปล่อยไว้ที่ค่าเริ่มต้น 200)",
"tr_TR": "",
- "uk_UA": "Цільове значення коефіцієнта Турборежиму.\n\nЗалиште 200, якщо не впевнені",
+ "uk_UA": "Цільове значення коефіцієнта Турборежиму.\n\nЗалиште 200, якщо не впевнені.",
"zh_CN": "涡轮模式倍数的目标值。\n\n如果不确定请保留为 200。",
"zh_TW": "加速模式倍數的數值。\n\n如果不確定,請保持數值為 200。"
}
@@ -4874,10 +4749,10 @@
"de_DE": "",
"el_GR": "",
"en_US": "Turbo Mode is an emulator feature which effectively causes speed up or slow down when a game is not frame-rate sensitive.\nYou can toggle this feature in-game with a hotkey, configurable in Ryujinx Keyboard Hotkeys settings.\n\nLeave at 200 if unsure.",
- "es_ES": "El modo turbo es una función del emulador que permite acelerar o ralentizar el juego cuando no depende de la tasa de frames.\nPuedes activar o desactivar esta función durante el juego usando una tecla rápida, configurable en los ajustes de Teclas rápidas de Ryujinx.\n\nDéjar en 200 si no está seguro",
+ "es_ES": "El modo turbo es una función del emulador que permite acelerar o ralentizar el juego cuando no depende de la tasa de frames.\nPuedes activar o desactivar esta función durante el juego usando una tecla rápida, configurable en los ajustes de Teclas rápidas de Ryujinx.\n\nDéjar en 200 si no está seguro.",
"fr_FR": "Le Mode Turbo est une fonctionnalité de l’émulateur qui permet d’accélérer ou de ralentir le jeu lorsque celui-ci n’est pas sensible au taux de rafraîchissement.\nVous pouvez activer ou désactiver cette fonction en jeu via un raccourci clavier, configurable dans les paramètres des raccourcis clavier de Ryujinx.\n\nLaissez à 200 si vous n’êtes pas sûr.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "La Modalità Turbo è una funzione dell'emulatore che permette di accelerare o rallentare il gioco quando non è sensibile al frame rate.\nPuoi attivare o disattivare questa funzione durante il gioco tramite un tasto rapido, configurabile nelle impostazioni dei Tasti Rapidi di Ryujinx.\n\nLascia a 200 se non sei sicuro.",
"ja_JP": "",
"ko_KR": "터보 모드는 게임이 프레임 속도에 민감하지 않을 때 효과적으로 속도를 높이거나 낮추는 에뮬레이터 기능입니다.\n이 기능은 Ryujinx 키보드 단축키 설정에서 구성할 수 있는 단축키를 사용하여 게임 내에서 전환할 수 있습니다.\n\n모르면 200으로 두세요.",
"no_NO": "Turbo-modus er en emulatorfunksjon som effektivt øker eller senker hastigheten når et spill ikke er følsom for bildefrekvens.\nDu kan slå på denne funksjonen i spillet med en hurtigtast, som kan konfigureres i Ryujinx Keyboard Hotkeys-innstillingene.\n\nLa den stå på 200 hvis du er usikker.",
@@ -4952,7 +4827,7 @@
"es_ES": "Vacío",
"fr_FR": "Désactivée",
"he_IL": "גולם",
- "it_IT": "",
+ "it_IT": "Non funzionante",
"ja_JP": "ダミー",
"ko_KR": "더미",
"no_NO": "",
@@ -5101,20 +4976,20 @@
"en_US": "DRAM Size:",
"es_ES": "Tamaño DRAM:",
"fr_FR": "Taille de la DRAM :",
- "he_IL": "השתמש בפריסת זיכרון חלופית (נועד למפתחים)",
+ "he_IL": "השתמש בפריסת זיכרון חלופית (נועד למפתחים):",
"it_IT": "Dimensione memoria DRAM:",
"ja_JP": "DRAMサイズ:",
"ko_KR": "DRAM 크기 :",
"no_NO": "DRAM Mengde",
- "pl_PL": "Użyj alternatywnego układu pamięci (Deweloperzy)",
+ "pl_PL": "Użyj alternatywnego układu pamięci (Deweloperzy):",
"pt_BR": "Tamanho da DRAM:",
"ru_RU": "Размер DRAM:",
"sv_SE": "DRAM-storlek:",
- "th_TH": "ใช้หน่วยความจำสำรอง (โหมดนักพัฒนา)",
- "tr_TR": "Alternatif bellek düzeni kullan (Geliştirici)",
- "uk_UA": "Використовувати альтернативне розташування пам'яті (для розробників)",
- "zh_CN": "使用开发机的内存布局(开发人员使用)",
- "zh_TW": "使用替代的記憶體配置 (開發者專用)"
+ "th_TH": "ใช้หน่วยความจำสำรอง (โหมดนักพัฒนา):",
+ "tr_TR": "Alternatif bellek düzeni kullan (Geliştirici):",
+ "uk_UA": "Використовувати альтернативне розташування пам'яті (для розробників):",
+ "zh_CN": "使用开发机的内存布局(开发人员使用):",
+ "zh_TW": "使用替代的記憶體配置 (開發者專用):"
}
},
{
@@ -5127,7 +5002,7 @@
"es_ES": null,
"fr_FR": "4GiO",
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "4GB",
"no_NO": "4GB",
@@ -5152,7 +5027,7 @@
"es_ES": null,
"fr_FR": "6GiO",
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "6GB",
"no_NO": "6GB",
@@ -5177,7 +5052,7 @@
"es_ES": null,
"fr_FR": "8GiO",
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "8GB",
"no_NO": "8GB",
@@ -5202,7 +5077,7 @@
"es_ES": null,
"fr_FR": "12GiO",
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "12GB",
"no_NO": "12GB",
@@ -5252,7 +5127,7 @@
"es_ES": "Ignorar el Applet del Controlador",
"fr_FR": "Ignorer l’Applet de Manette",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Ignora Applet del Controller",
"ja_JP": "",
"ko_KR": "컨트롤러 애플릿 무시",
"no_NO": "Ignorer Kontroller-applet",
@@ -5427,7 +5302,7 @@
"es_ES": "x2",
"fr_FR": "x2",
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "2배",
"no_NO": "",
@@ -5452,7 +5327,7 @@
"es_ES": "x4",
"fr_FR": "x4",
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "4배",
"no_NO": "",
@@ -5477,7 +5352,7 @@
"es_ES": "x8",
"fr_FR": "x8",
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "8배",
"no_NO": "",
@@ -5502,7 +5377,7 @@
"es_ES": "x16",
"fr_FR": "x16",
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "16배",
"no_NO": "",
@@ -5602,7 +5477,7 @@
"es_ES": "x2 (1440p/2160p)",
"fr_FR": "x2 (1440p/2160p)",
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "2배(1440p/2160p)",
"no_NO": "",
@@ -5627,7 +5502,7 @@
"es_ES": "x3 (2160p/3240p)",
"fr_FR": "x3 (2160p/3240p)",
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "3배(2160p/3240p)",
"no_NO": "",
@@ -5652,7 +5527,7 @@
"es_ES": "4x (2880p/4320p) (No Recomendado)",
"fr_FR": "x4 (2880p/4320p) (Non Recommandé)",
"he_IL": "4x (2880p/4320p) (לא מומלץ)",
- "it_IT": "4x (2880p/4320p) (Non consigliato)",
+ "it_IT": "x4 (2880p/4320p) (Non consigliato)",
"ja_JP": "4x (2880p/4320p) (非推奨)",
"ko_KR": "4배(2880p/4320p) (권장하지 않음)",
"no_NO": "4x (2880p/4320p) (anbefales ikke)",
@@ -5677,10 +5552,10 @@
"es_ES": "Relación de Aspecto:",
"fr_FR": "Format d'Affichage :",
"he_IL": "יחס גובה-רוחב:",
- "it_IT": "Rapporto d'aspetto:",
+ "it_IT": "Rapporto di visualizzazione:",
"ja_JP": "アスペクト比:",
"ko_KR": "종횡비 :",
- "no_NO": "Bildeformat",
+ "no_NO": "Bildeformat:",
"pl_PL": "Format obrazu:",
"pt_BR": "Proporção da Tela:",
"ru_RU": "Соотношение сторон:",
@@ -6127,7 +6002,7 @@
"es_ES": "Habilitar Registros UI",
"fr_FR": "Activer les Journaux de l'Interface Utilisateur",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Abilita i log UI",
"ja_JP": "",
"ko_KR": "UI 로그 활성화",
"no_NO": "Aktivere UI-logger",
@@ -6175,8 +6050,8 @@
"el_GR": "Λειτουργία Καταγραφής Καθολικής Πρόσβασης FS:",
"en_US": "Fs Global Access Log Mode:",
"es_ES": "Modo de Registros Fs Global Access:",
- "fr_FR": "Mode Global des Journaux d’Accès FS",
- "he_IL": "מצב רישום גלובלי של גישת קבצי מערכת",
+ "fr_FR": "Mode Global des Journaux d’Accès FS:",
+ "he_IL": "מצב רישום גלובלי של גישת קבצי מערכת:",
"it_IT": "Modalità log di accesso globale FS:",
"ja_JP": "Fs グローバルアクセスログモード:",
"ko_KR": "파일 시스템 전역 접속 로그 모드 :",
@@ -6227,7 +6102,7 @@
"es_ES": "ADVERTENCIA: Reducirá el Rendimiento",
"fr_FR": "ATTENTION : Réduira la Performance",
"he_IL": "אזהרה: יפחית ביצועים",
- "it_IT": "ATTENZIONE: ridurranno le prestazioni",
+ "it_IT": "ATTENZIONE: ridurrà le prestazioni",
"ja_JP": "警告: パフォーマンスを低下させます",
"ko_KR": "경고 : 성능이 감소합니다.",
"no_NO": "Advarsel: Vil redusere ytelsen",
@@ -6545,23 +6420,23 @@
{
"ID": "SettingsButtonReset",
"Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
+ "ar_SA": "إعادة تعيين الإعدادات",
+ "de_DE": "Einstellungen zurücksetzen",
+ "el_GR": "Επαναφορά ρυθμίσεων",
"en_US": "Reset Settings",
"es_ES": "Restablecer la Configuración",
"fr_FR": "Réinitialiser les Paramètres",
- "he_IL": "",
- "it_IT": "",
- "ja_JP": "",
+ "he_IL": "איפוס הגדרות",
+ "it_IT": "Reimposta impostazioni",
+ "ja_JP": "設定をリセット",
"ko_KR": "설정 초기화",
"no_NO": "Tilbakestill innstillinger",
- "pl_PL": "",
+ "pl_PL": "Resetuj ustawienia",
"pt_BR": "Redefinir Configurações",
"ru_RU": "Сбросить настройки",
"sv_SE": "Nollställ inställningar",
- "th_TH": "",
- "tr_TR": "",
+ "th_TH": "รีเซ็ตการตั้งค่า",
+ "tr_TR": "Ayarları Sıfırla",
"uk_UA": "Скинути налаштування",
"zh_CN": "重置设置",
"zh_TW": "重設設定"
@@ -6570,49 +6445,49 @@
{
"ID": "SettingsButtonResetConfirm",
"Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
- "en_US": "I want to reset my settings.",
+ "ar_SA": "أريد إعادة تعيين إعداداتي",
+ "de_DE": "Ich möchte meine Einstellungen zurücksetzen",
+ "el_GR": "Θέλω να επαναφέρω τις ρυθμίσεις μου",
+ "en_US": "I Want To Reset My Settings",
"es_ES": "Quiero Restablecer Mi Configuración",
- "fr_FR": "Je veux réinitialiser mes paramètres.",
- "he_IL": "",
- "it_IT": "",
- "ja_JP": "",
- "ko_KR": "설정을 초기화하고 싶습니다.",
- "no_NO": "Jeg vil tilbakestille innstillingene mine.",
- "pl_PL": "",
- "pt_BR": "Quero redefinir minhas configurações.",
- "ru_RU": "Я хочу сбросить свои настройки.",
- "sv_SE": "Jag vill nollställa mina inställningar.",
- "th_TH": "",
- "tr_TR": "",
- "uk_UA": "Я хочу скинути налаштування.",
- "zh_CN": "我要重置我的设置。",
- "zh_TW": "我想重設我的設定。"
+ "fr_FR": "Je Veux Réinitialiser Mes Paramètres",
+ "he_IL": "אני רוצה לאפס את ההגדרות שלי",
+ "it_IT": "Voglio reimpostare le mie impostazioni",
+ "ja_JP": "設定をリセットしたいです",
+ "ko_KR": "설정을 초기화하고 싶습니다",
+ "no_NO": "Jeg vil tilbakestille innstillingene mine",
+ "pl_PL": "Chcę zresetować moje ustawienia",
+ "pt_BR": "Quero redefinir minhas configurações",
+ "ru_RU": "Я хочу сбросить свои настройки",
+ "sv_SE": "Jag vill nollställa mina inställningar",
+ "th_TH": "ฉันต้องการรีเซ็ตการตั้งค่าของฉัน",
+ "tr_TR": "Ayarlarımı sıfırlamak istiyorum",
+ "uk_UA": "Я хочу скинути налаштування",
+ "zh_CN": "我要重置我的设置",
+ "zh_TW": "我想重設我的設定"
}
},
{
"ID": "SettingsButtonOk",
"Translations": {
"ar_SA": "موافق",
- "de_DE": "",
- "el_GR": "",
+ "de_DE": null,
+ "el_GR": "Εντάξει",
"en_US": "OK",
"es_ES": "Aceptar",
"fr_FR": null,
"he_IL": "אישור",
- "it_IT": "",
- "ja_JP": "",
+ "it_IT": null,
+ "ja_JP": "確認",
"ko_KR": "확인",
- "no_NO": "",
- "pl_PL": "",
- "pt_BR": "",
+ "no_NO": null,
+ "pl_PL": null,
+ "pt_BR": null,
"ru_RU": null,
- "sv_SE": "Ok",
+ "sv_SE": null,
"th_TH": "ตกลง",
"tr_TR": "Tamam",
- "uk_UA": "",
+ "uk_UA": "Добре",
"zh_CN": "确定",
"zh_TW": "確定"
}
@@ -6952,7 +6827,7 @@
"es_ES": "Configuración encontrada:\n\nNombre:\t{0}\nGUID:\t{1}\n\nEsperando la conexión del controlador...",
"fr_FR": "Configuration trouvée:\n\nNom:\t{0}\nGUID:\t{1}\n\n En attente de connexion de la manette...",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Configurazione trovata:\n\nNome:\t{0}\nGUID:\t{1}\n\nIn attesa della connessione del controller...",
"ja_JP": "",
"ko_KR": "발견된 구성 :\n\n이름 : \t{0}\n가이드 : \t{1}\n\n 컨트롤러 연결 대기 중...",
"no_NO": "",
@@ -7077,7 +6952,7 @@
"es_ES": "Mando Pro",
"fr_FR": "Manette Switch Pro",
"he_IL": "שלט פרו ",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "Pro コントローラ",
"ko_KR": "프로 컨트롤러",
"no_NO": "",
@@ -7870,26 +7745,26 @@
{
"ID": "ControllerSettingsStickDeadzone",
"Translations": {
- "ar_SA": "المنطقة الميتة:",
+ "ar_SA": "المنطقة الميتة",
"de_DE": "",
- "el_GR": "Νεκρή Ζώνη:",
- "en_US": "Deadzone:",
- "es_ES": "Zona Muerta:",
- "fr_FR": "Zone Morte :",
- "he_IL": "שטח מת:",
- "it_IT": "Zona morta:",
- "ja_JP": "遊び:",
- "ko_KR": "데드존 :",
- "no_NO": "Død sone:",
- "pl_PL": "Martwa strefa:",
- "pt_BR": "Zona Morta:",
- "ru_RU": "Мёртвая зона:",
- "sv_SE": "Dödläge:",
- "th_TH": "โซนที่ไม่ทำงานของ จอยสติ๊ก:",
+ "el_GR": "Νεκρή Ζώνη",
+ "en_US": "Deadzone",
+ "es_ES": "Zona muerta",
+ "fr_FR": "Zone Morte",
+ "he_IL": "שטח מת",
+ "it_IT": "Zona morta",
+ "ja_JP": "遊び",
+ "ko_KR": "데드존",
+ "no_NO": "Død sone",
+ "pl_PL": "Martwa strefa",
+ "pt_BR": "Zona Morta",
+ "ru_RU": "Мёртвая зона",
+ "sv_SE": "Dödläge",
+ "th_TH": "โซนที่ไม่ทำงานของ จอยสติ๊ก",
"tr_TR": "Ölü Bölge",
- "uk_UA": "Мертва зона:",
- "zh_CN": "死区:",
- "zh_TW": "無感帶:"
+ "uk_UA": "Мертва зона",
+ "zh_CN": "死区",
+ "zh_TW": "無感帶"
}
},
{
@@ -8345,26 +8220,26 @@
{
"ID": "ControllerSettingsTriggerThreshold",
"Translations": {
- "ar_SA": "قوة التحفيز:",
- "de_DE": "Empfindlichkeit:",
- "el_GR": "Κατώφλι Σκανδάλης:",
- "en_US": "Trigger Threshold:",
- "es_ES": "Límite de Gatillos:",
- "fr_FR": "Seuil de Gachettes :",
- "he_IL": "סף הדק:",
- "it_IT": "Sensibilità dei grilletti:",
- "ja_JP": "トリガーしきい値:",
- "ko_KR": "트리거 임계값 :",
- "no_NO": "Utløser terskel:",
- "pl_PL": "Próg Triggerów:",
- "pt_BR": "Sensibilidade do Gatilho:",
- "ru_RU": "Порог срабатывания:",
- "sv_SE": "Tröskelvärde avtryckare:",
- "th_TH": "ตั้งค่าขีดจำกัดการกด:",
- "tr_TR": "Tetik Eşiği:",
- "uk_UA": "Поріг спрацьовування:",
- "zh_CN": "扳机阈值:",
- "zh_TW": "扳機閾值:"
+ "ar_SA": "قوة التحفيز",
+ "de_DE": "Empfindlichkeit",
+ "el_GR": "Κατώφλι Σκανδάλης",
+ "en_US": "Trigger Threshold",
+ "es_ES": "Límite de gatillos",
+ "fr_FR": "Seuil de Gachettes",
+ "he_IL": "סף הדק",
+ "it_IT": "Sensibilità dei grilletti",
+ "ja_JP": "トリガーしきい値",
+ "ko_KR": "트리거 임계값",
+ "no_NO": "Utløser terskel",
+ "pl_PL": "Próg Triggerów",
+ "pt_BR": "Sensibilidade do Gatilho",
+ "ru_RU": "Порог срабатывания",
+ "sv_SE": "Tröskelvärde avtryckare",
+ "th_TH": "ตั้งค่าขีดจำกัดการกด",
+ "tr_TR": "Tetik Eşiği",
+ "uk_UA": "Поріг спрацьовування",
+ "zh_CN": "扳机阈值",
+ "zh_TW": "扳機閾值"
}
},
{
@@ -8426,7 +8301,7 @@
"en_US": "Controller Slot:",
"es_ES": "Puerto del Mando:",
"fr_FR": "Manette ID :",
- "he_IL": "מיקום שלט",
+ "he_IL": "מיקום שלט:",
"it_IT": "Slot del controller:",
"ja_JP": "コントローラ スロット:",
"ko_KR": "컨트롤러 슬롯 :",
@@ -8476,7 +8351,7 @@
"en_US": "Right JoyCon Slot:",
"es_ES": "Puerto del Joy-Con Derecho:",
"fr_FR": "JoyCon Droit ID :",
- "he_IL": "מיקום ג'ויקון ימני",
+ "he_IL": "מיקום ג'ויקון ימני:",
"it_IT": "Slot JoyCon destro:",
"ja_JP": "JoyCon 右 スロット:",
"ko_KR": "우측 조이콘 슬롯:",
@@ -8577,7 +8452,7 @@
"es_ES": null,
"fr_FR": null,
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": null,
"no_NO": "",
@@ -8602,7 +8477,7 @@
"es_ES": "Desactivar",
"fr_FR": "Désactiver",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Disattiva",
"ja_JP": "",
"ko_KR": "비활성화",
"no_NO": "Deaktiver",
@@ -8627,7 +8502,7 @@
"es_ES": "Arcoíris",
"fr_FR": "Arc-en-ciel",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Arcobaleno",
"ja_JP": "",
"ko_KR": "레인보우",
"no_NO": "Regnbue",
@@ -8648,23 +8523,23 @@
"ar_SA": "",
"de_DE": "",
"el_GR": "",
- "en_US": "Rainbow Speed",
- "es_ES": "Velocidad del Arcoíris",
- "fr_FR": "Vitesse de l'Arc-en-ciel",
+ "en_US": "Rainbow Speed:",
+ "es_ES": "Velocidad del arcoíris:",
+ "fr_FR": "Vitesse de l'Arc-en-ciel:",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Velocità Arcobaleno",
"ja_JP": "",
- "ko_KR": "레인보우 속도",
- "no_NO": "Regnbue Hastighet",
+ "ko_KR": "레인보우 속도:",
+ "no_NO": "Regnbue Hastighet:",
"pl_PL": "",
- "pt_BR": "Velocidade do Arco-íris",
- "ru_RU": "Скорость переливания",
- "sv_SE": "Regnbågshastighet",
- "th_TH": "ความเร็วของสีรุ้ง",
+ "pt_BR": "Velocidade do Arco-íris:",
+ "ru_RU": "Скорость переливания:",
+ "sv_SE": "Regnbågshastighet:",
+ "th_TH": "ความเร็วของสีรุ้ง:",
"tr_TR": "",
- "uk_UA": "Швидкість зміни кольорів",
- "zh_CN": "彩虹滚动速度",
- "zh_TW": "彩虹滾動速度"
+ "uk_UA": "Швидкість зміни кольорів:",
+ "zh_CN": "彩虹滚动速度:",
+ "zh_TW": "彩虹滾動速度:"
}
},
{
@@ -8677,7 +8552,7 @@
"es_ES": null,
"fr_FR": "Couleur",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Colore",
"ja_JP": "",
"ko_KR": "색상",
"no_NO": "Farge",
@@ -9327,7 +9202,7 @@
"es_ES": null,
"fr_FR": null,
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "탭",
"no_NO": "",
@@ -9352,7 +9227,7 @@
"es_ES": "Retroceso",
"fr_FR": "Retour arrière",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Canc",
"ja_JP": "",
"ko_KR": "백스페이스",
"no_NO": "Tilbaketast",
@@ -9652,7 +9527,7 @@
"es_ES": "Borrar",
"fr_FR": "Effacer",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Cancella",
"ja_JP": "",
"ko_KR": null,
"no_NO": "Tøm",
@@ -11102,7 +10977,7 @@
"es_ES": "Panel táctil",
"fr_FR": "Pavé tactile",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Pannello tattile",
"ja_JP": "",
"ko_KR": "터치패드",
"no_NO": "Berøringsplate",
@@ -11627,7 +11502,7 @@
"es_ES": "Aceptar",
"fr_FR": null,
"he_IL": "בסדר",
- "it_IT": "",
+ "it_IT": "Accetta",
"ja_JP": "",
"ko_KR": "확인",
"no_NO": "",
@@ -12122,7 +11997,7 @@
"Translations": {
"ar_SA": "السمة:",
"de_DE": "Design:",
- "el_GR": "",
+ "el_GR": "Θέμα:",
"en_US": "Theme:",
"es_ES": "Tema:",
"fr_FR": "Thème :",
@@ -12142,37 +12017,12 @@
"zh_TW": "佈景主題:"
}
},
- {
- "ID": "SettingsTabGeneralThemeAuto",
- "Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
- "en_US": "Auto",
- "es_ES": null,
- "fr_FR": null,
- "he_IL": "",
- "it_IT": "Automatico",
- "ja_JP": "",
- "ko_KR": "자동",
- "no_NO": "Automatisk",
- "pl_PL": "",
- "pt_BR": "Automático",
- "ru_RU": "Авто",
- "sv_SE": "Automatiskt",
- "th_TH": "อัตโนมัติ",
- "tr_TR": "",
- "uk_UA": "Авто.",
- "zh_CN": "自动",
- "zh_TW": "自動"
- }
- },
{
"ID": "SettingsTabGeneralThemeDark",
"Translations": {
"ar_SA": "داكن",
"de_DE": "Dunkel",
- "el_GR": "",
+ "el_GR": "Σκούρο",
"en_US": "Dark",
"es_ES": "Oscuro",
"fr_FR": "Sombre",
@@ -12197,7 +12047,7 @@
"Translations": {
"ar_SA": "فاتح",
"de_DE": "Hell",
- "el_GR": "",
+ "el_GR": "Φωτεινό",
"en_US": "Light",
"es_ES": "Claro",
"fr_FR": "Clair",
@@ -12270,51 +12120,51 @@
{
"ID": "ControllerSettingsRumbleStrongMultiplier",
"Translations": {
- "ar_SA": "مضاعف اهتزاز قوي",
- "de_DE": "Starker Vibrations-Multiplikator",
- "el_GR": "Ισχυρός Πολλαπλασιαστής Δόνησης",
- "en_US": "Strong Rumble Multiplier",
- "es_ES": "Multiplicador de Vibraciones Fuertes",
- "fr_FR": "Multiplicateur de Vibrations Fortes",
- "he_IL": "העצמת רטט חזק",
- "it_IT": "Moltiplicatore vibrazione forte",
- "ja_JP": "強振動の補正値",
- "ko_KR": "강진동 보정폭",
- "no_NO": "Sterk Vibrasjon multiplikator",
- "pl_PL": "Mnożnik mocnych wibracji",
- "pt_BR": "Multiplicador de Vibração Forte",
- "ru_RU": "Множитель сильной вибрации",
- "sv_SE": "Försvaga stark vibration",
- "th_TH": "เพิ่มความแรงการสั่น",
- "tr_TR": "Güçlü Titreşim Çoklayıcı",
- "uk_UA": "Множник сильної вібрації",
- "zh_CN": "强震动幅度",
- "zh_TW": "強震動調節"
+ "ar_SA": "مضاعف اهتزاز قوي:",
+ "de_DE": "Starker Vibrations-Multiplikator:",
+ "el_GR": "Ισχυρός Πολλαπλασιαστής Δόνησης:",
+ "en_US": "Strong Rumble Multiplier:",
+ "es_ES": "Multiplicador de vibraciones fuertes:",
+ "fr_FR": "Multiplicateur de Vibrations Fortes:",
+ "he_IL": "העצמת רטט חזק:",
+ "it_IT": "Moltiplicatore vibrazione forte:",
+ "ja_JP": "強振動の補正値:",
+ "ko_KR": "강진동 보정폭:",
+ "no_NO": "Sterk Vibrasjon multiplikator:",
+ "pl_PL": "Mnożnik mocnych wibracji:",
+ "pt_BR": "Multiplicador de Vibração Forte:",
+ "ru_RU": "Множитель сильной вибрации:",
+ "sv_SE": "Försvaga stark vibration:",
+ "th_TH": "เพิ่มความแรงการสั่น:",
+ "tr_TR": "Güçlü Titreşim Çoklayıcı:",
+ "uk_UA": "Множник сильної вібрації:",
+ "zh_CN": "强震动幅度:",
+ "zh_TW": "強震動調節:"
}
},
{
"ID": "ControllerSettingsRumbleWeakMultiplier",
"Translations": {
- "ar_SA": "مضاعف اهتزاز ضعيف",
- "de_DE": "Schwacher Vibrations-Multiplikator",
- "el_GR": "Αδύναμος Πολλαπλασιαστής Δόνησης",
- "en_US": "Weak Rumble Multiplier",
- "es_ES": "Multiplicador de Vibraciones Débiles",
- "fr_FR": "Multiplicateur de Vibrations Faibles",
- "he_IL": "מכפיל רטט חלש",
- "it_IT": "Moltiplicatore vibrazione debole",
- "ja_JP": "弱振動の補正値",
- "ko_KR": "약진동 보정폭",
- "no_NO": "Svak Vibrasjon multiplikator",
- "pl_PL": "Mnożnik słabych wibracji",
- "pt_BR": "Multiplicador de Vibração Fraca",
- "ru_RU": "Множитель слабой вибрации",
- "sv_SE": "Förstärk svag vibration",
- "th_TH": "ลดความแรงการสั่น",
- "tr_TR": "Zayıf Titreşim Seviyesi",
- "uk_UA": "Множник слабкої вібрації",
- "zh_CN": "弱震动幅度",
- "zh_TW": "弱震動調節"
+ "ar_SA": "مضاعف اهتزاز ضعيف:",
+ "de_DE": "Schwacher Vibrations-Multiplikator:",
+ "el_GR": "Αδύναμος Πολλαπλασιαστής Δόνησης:",
+ "en_US": "Weak Rumble Multiplier:",
+ "es_ES": "Multiplicador de vibraciones débiles:",
+ "fr_FR": "Multiplicateur de Vibrations Faibles:",
+ "he_IL": "מכפיל רטט חלש:",
+ "it_IT": "Moltiplicatore vibrazione debole:",
+ "ja_JP": "弱振動の補正値:",
+ "ko_KR": "약진동 보정폭:",
+ "no_NO": "Svak Vibrasjon multiplikator:",
+ "pl_PL": "Mnożnik słabych wibracji:",
+ "pt_BR": "Multiplicador de Vibração Fraca:",
+ "ru_RU": "Множитель слабой вибрации:",
+ "sv_SE": "Förstärk svag vibration:",
+ "th_TH": "ลดความแรงการสั่น:",
+ "tr_TR": "Zayıf Titreşim Seviyesi:",
+ "uk_UA": "Множник слабкої вібрації:",
+ "zh_CN": "弱震动幅度:",
+ "zh_TW": "弱震動調節:"
}
},
{
@@ -12852,7 +12702,7 @@
"es_ES": "Error al convertir la versión de Ryujinx recibida del servidor de actualizaciones.",
"fr_FR": "Échec de la conversion de la version de Ryujinx reçue du serveur de Mise à Jour.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Impossibile convertire la versione di Ryujinx ricevuta dal server di aggiornamento.",
"ja_JP": "",
"ko_KR": "업데이트 서버에서 받은 Ryujinx 버전을 변환하는 데 실패했습니다.",
"no_NO": "Kunne ikke konvertere Ryujinx-versjonen som ble mottatt fra oppdateringsserveren.",
@@ -13602,7 +13452,7 @@
"es_ES": null,
"fr_FR": "{0} : {1}",
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "{0} : {1}",
"no_NO": "",
@@ -13927,7 +13777,7 @@
"es_ES": "Está a punto de eliminar todos los datos PPTC de:\n\n{0}\n\n¿Está seguro de que desea continuar?",
"fr_FR": "Vous êtes sur le point de supprimer toutes les données PPTC de :\n\n{0}\n\nÊtes-vous sûr de vouloir continuer ?",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Stai per eliminare tutti i dati PPTC da:\n\n{0}\n\nSei sicuro di voler procedere?",
"ja_JP": "",
"ko_KR": "다음에서 모든 PPTC 데이터를 제거하려고 합니다:\n\n{0}\n\n계속하시겠습니까?",
"no_NO": "Du er i ferd med å slette alle PPTC-data fra:\n\n{0}\n\n\nEr du sikker på at du vil fortsette?",
@@ -15021,24 +14871,24 @@
"ID": "CommonAuto",
"Translations": {
"ar_SA": "تلقائي",
- "de_DE": "",
+ "de_DE": "Automatisch",
"el_GR": "Αυτόματο",
"en_US": "Auto",
- "es_ES": "Automático",
+ "es_ES": null,
"fr_FR": null,
"he_IL": "אוטומטי",
- "it_IT": "Automatico",
+ "it_IT": null,
"ja_JP": "自動",
"ko_KR": "자동",
- "no_NO": "Automatisk",
- "pl_PL": "",
- "pt_BR": "Automático",
- "ru_RU": "Автоматически",
- "sv_SE": "Automatiskt",
+ "no_NO": null,
+ "pl_PL": null,
+ "pt_BR": null,
+ "ru_RU": "Авто",
+ "sv_SE": null,
"th_TH": "อัตโนมัติ",
"tr_TR": "Otomatik",
"uk_UA": "Авто",
- "zh_CN": "自动(推荐)",
+ "zh_CN": "自动",
"zh_TW": "自動"
}
},
@@ -15127,7 +14977,7 @@
"es_ES": null,
"fr_FR": "Non",
"he_IL": "לא",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "いいえ",
"ko_KR": "아니오",
"no_NO": "Nei",
@@ -15552,7 +15402,7 @@
"es_ES": "Mostrar Amiibo incompatibles con este juego",
"fr_FR": "Montrer les Amiibo incompatibles avec ce jeu",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Mostra Amiibo compatibili per questo gioco",
"ja_JP": "",
"ko_KR": "이 게임에 호환되지 않는 Amiibo 표시",
"no_NO": "",
@@ -16020,176 +15870,51 @@
{
"ID": "ToggleDiscordTooltip",
"Translations": {
- "ar_SA": "اختر ما إذا كنت تريد عرض ريوجينكس في نشاط ديسكورد \"يتم تشغيله حاليا\" أم لا",
- "de_DE": "Zeige momentanes Spiel auf Discord",
- "el_GR": "Ενεργοποιεί ή απενεργοποιεί την Εμπλουτισμένη Παρουσία σας στο Discord",
- "en_US": "Choose whether or not to display Ryujinx on your \"currently playing\" Discord activity",
- "es_ES": "Elige si muestras Ryujinx o no en tu actividad de Discord cuando lo estés usando",
- "fr_FR": "Choisissez d’afficher ou non Ryujinx dans votre activité Discord « en cours de jeu »",
- "he_IL": "בחרו להציג את ריוג'ינקס או לא בפעילות הדיסקורד שלכם \"משוחק כרגע\".",
- "it_IT": "Scegli se mostrare o meno Ryujinx nella tua attività su Discord",
- "ja_JP": "Discord の \"現在プレイ中\" アクティビティに Ryujinx を表示するかどうかを選択します",
- "ko_KR": "\"현재 진행 중인\" 디스코드 활동에 Ryujinx를 표시할지 여부를 선택",
- "no_NO": "Velg om Ryujinx skal vises på din \"spillende\" Discord aktivitet eller ikke",
- "pl_PL": "Wybierz, czy chcesz wyświetlać Ryujinx w swojej \"aktualnie grane\" aktywności Discord",
- "pt_BR": "Escolha se deseja mostrar Ryujinx ou não na sua atividade do Discord quando estiver usando-o",
- "ru_RU": "Включает или отключает отображение Ryujinx в статусе \"Сейчас Играет\" в Discord.",
- "sv_SE": "Välj huruvida Ryujinx ska visas på din \"spelar för tillfället\" Discord-aktivitet",
- "th_TH": "เลือกว่าจะแสดง Ryujinx ในกิจกรรม Discord \"ที่กำลังเล่นอยู่\" ของคุณหรือไม่?",
- "tr_TR": "Ryujinx'i \"şimdi oynanıyor\" Discord aktivitesinde göstermeyi veya göstermemeyi seçin",
- "uk_UA": "Виберіть, чи відображати Ryujinx у вашій «поточній грі» в Discord",
- "zh_CN": "选择是否在 Discord 中显示您的游玩状态",
- "zh_TW": "啟用或關閉 Discord 動態狀態展示"
+ "ar_SA": "يعرض Ryujinx في نشاط \"اللعب\" الخاص بك في Discord.",
+ "de_DE": "Zeigt Ryujinx in deiner Discord-\"Spielen\"-Aktivität an.",
+ "el_GR": "Εμφανίζει το Ryujinx στη δραστηριότητα \"Παίζοντας\" στο Discord σου.",
+ "en_US": "Displays Ryujinx in your Discord's \"Playing\" activity.",
+ "es_ES": "Muestra Ryujinx en tu actividad \"Jugando\" en Discord.",
+ "fr_FR": "Affiche Ryujinx dans votre activité Discord « En Cours de Jeu ».",
+ "he_IL": "מציג את Ryujinx בפעילות \"משחק\" ב-Discord שלך.",
+ "it_IT": "Mostra Ryujinx nella tua attività \"In Gioco\" su Discord.",
+ "ja_JP": "Discordの「プレイ中」アクティビティにRyujinxを表示します。",
+ "ko_KR": "Discord의 \"플레이 중\" 활동에 Ryujinx를 표시합니다.",
+ "no_NO": "Viser Ryujinx i din Discords \"Spiller\"-aktivitet.",
+ "pl_PL": "Wyświetla Ryujinx w Twojej aktywności „Aktualnie grane” na Discordzie.",
+ "pt_BR": "Exibe Ryujinx na atividade \"Jogando\" do seu Discord.",
+ "ru_RU": "Отображает Ryujinx в статусе \"Играет\" в Discord.",
+ "sv_SE": "Visar Ryujinx i din Discords \"Spelar\"-aktivitet.",
+ "th_TH": "แสดง Ryujinx ในกิจกรรม \"กำลังเล่น\" ของ Discord ของคุณ",
+ "tr_TR": "Discord'daki \"Oynuyor\" etkinliğinizde Ryujinx'i gösterir.",
+ "uk_UA": "Відображає Ryujinx у вашій активності Discord «Грає».",
+ "zh_CN": "在 Discord 的“正在游玩”状态中显示 Ryujinx。",
+ "zh_TW": "在 Discord 的「正在遊玩」狀態中顯示 Ryujinx。"
}
},
{
"ID": "AddGameDirBoxTooltip",
"Translations": {
- "ar_SA": "أدخل مجلد اللعبة لإضافته إلى القائمة",
- "de_DE": "Gibt das Spielverzeichnis an, das der Liste hinzuzufügt wird",
- "el_GR": "Εισαγάγετε μία τοποθεσία παιχνιδιών για προσθήκη στη λίστα",
- "en_US": "Enter a game directory to add to the list",
- "es_ES": "Elige un directorio de juegos para mostrar en la ventana principal",
- "fr_FR": "Entrez un répertoire de jeux à ajouter à la liste",
- "he_IL": "הזן תקיית משחקים כדי להוסיף לרשימה",
- "it_IT": "Inserisci una cartella dei giochi per aggiungerla alla lista",
- "ja_JP": "リストに追加するゲームディレクトリを入力します",
- "ko_KR": "목록에 추가할 게임 디렉터리를 입력",
- "no_NO": "Angi en spillmappe for å legge til i listen",
- "pl_PL": "Wprowadź katalog gier aby dodać go do listy",
- "pt_BR": "Escreva um diretório de jogo para adicionar à lista",
- "ru_RU": "Введите путь к папке с играми чтобы добавить ее в список выше",
- "sv_SE": "Ange en spelkatalog att lägga till i listan",
- "th_TH": "ป้อนไดเรกทอรี่เกมที่จะทำการเพิ่มลงในรายการ",
- "tr_TR": "Listeye eklemek için oyun dizini seçin",
- "uk_UA": "Додайте теку з іграми, щоб додати їх до списку",
- "zh_CN": "输入要添加的游戏目录",
- "zh_TW": "輸入要新增到清單中的遊戲資料夾"
- }
- },
- {
- "ID": "AddGameDirTooltip",
- "Translations": {
- "ar_SA": "إضافة مجلد اللعبة إلى القائمة",
- "de_DE": "Fügt ein neues Spielverzeichnis hinzu",
- "el_GR": "Προσθέστε μία τοποθεσία παιχνιδιών στη λίστα",
- "en_US": "Add a game directory to the list",
- "es_ES": "Agrega un directorio de juegos a la lista",
- "fr_FR": "Ajoute un répertoire de jeux à la liste",
- "he_IL": "הוסף תקיית משחקים לרשימה",
- "it_IT": "Aggiungi una cartella dei giochi alla lista",
- "ja_JP": "リストにゲームディレクトリを追加します",
- "ko_KR": "목록에 게임 디렉터리 추가",
- "no_NO": "Legg til en spillmappe i listen",
- "pl_PL": "Dodaj katalog gier do listy",
- "pt_BR": "Adicionar um diretório de jogo à lista",
- "ru_RU": "Добавить папку с играми в список",
- "sv_SE": "Lägg till en spelkatalog till listan",
- "th_TH": "เพิ่มไดเรกทอรี่เกมลงในรายการ",
- "tr_TR": "Listeye oyun dizini ekle",
- "uk_UA": "Додати теку з іграми до списку",
- "zh_CN": "添加游戏目录到列表中",
- "zh_TW": "新增遊戲資料夾到清單中"
- }
- },
- {
- "ID": "RemoveGameDirTooltip",
- "Translations": {
- "ar_SA": "إزالة مجلد اللعبة المحدد",
- "de_DE": "Entfernt das ausgewähltes Spielverzeichnis",
- "el_GR": "Αφαιρέστε την επιλεγμένη τοποθεσία παιχνιδιών",
- "en_US": "Remove selected game directory",
- "es_ES": "Quita el directorio seleccionado de la lista",
- "fr_FR": "Supprime le répertoire de jeu sélectionné",
- "he_IL": "הסר את תקיית המשחקים שנבחרה",
- "it_IT": "Rimuovi la cartella dei giochi selezionata",
- "ja_JP": "選択したゲームディレクトリを削除します",
- "ko_KR": "선택한 게임 디렉터리 제거",
- "no_NO": "Fjern valgt spillmappe",
- "pl_PL": "Usuń wybrany katalog gier",
- "pt_BR": "Remover diretório de jogo selecionado",
- "ru_RU": "Убрать выбранную папку игры из списка",
- "sv_SE": "Ta bort vald spelkatalog",
- "th_TH": "ลบไดเรกทอรี่เกมที่เลือก",
- "tr_TR": "Seçili oyun dizinini kaldır",
- "uk_UA": "Видалити вибрану теку гри",
- "zh_CN": "移除选中的目录",
- "zh_TW": "移除選取的遊戲資料夾"
- }
- },
- {
- "ID": "AddAutoloadDirBoxTooltip",
- "Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
- "en_US": "Enter an autoload directory to add to the list",
- "es_ES": "Elige un directorio de carga automática para agregar a la lista",
- "fr_FR": "Saisissez un répertoire d’autochargement à ajouter à la liste",
- "he_IL": "",
- "it_IT": "Inserisci una cartella di caricamento automatico da aggiungere alla lista",
- "ja_JP": "",
- "ko_KR": "목록에 추가할 자동 불러오기 디렉터리를 입력",
- "no_NO": "Angi en autoload-mappe som skal legges til i listen",
- "pl_PL": "",
- "pt_BR": "Insira um diretório de carregamento automático para adicionar à lista",
- "ru_RU": "Введите папку автозагрузки для добавления в список выше",
- "sv_SE": "Ange en katalog att automatiskt läsa in till listan",
- "th_TH": "ป้อนไดเร็กทอรีสำหรับโหลดอัตโนมัติเพื่อเพิ่มลงในรายการ",
- "tr_TR": "",
- "uk_UA": "Введіть шлях автозавантаження для додавання до списку",
- "zh_CN": "输入需要添加到列表中的自动加载目录",
- "zh_TW": "輸入要新增到清單中的「自動載入 DLC/遊戲更新資料夾」"
- }
- },
- {
- "ID": "AddAutoloadDirTooltip",
- "Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
- "en_US": "Add an autoload directory to the list",
- "es_ES": "Agregar un directorio de carga automática a la lista",
- "fr_FR": "Ajouter un répertoire d’autochargement à la liste",
- "he_IL": "",
- "it_IT": "Aggiungi una cartella di caricamento automatico alla lista",
- "ja_JP": "",
- "ko_KR": "목록에 자동 불러오기 디렉터리 추가",
- "no_NO": "Legg til en autoload-mappe i listen",
- "pl_PL": "",
- "pt_BR": "Adicionar um diretório de carregamento automático à lista",
- "ru_RU": "Добавить папку автозагрузки в список",
- "sv_SE": "Lägg till en katalog att automatiskt läsa in till listan",
- "th_TH": "ป้อนไดเร็กทอรีสำหรับโหลดอัตโนมัติเพื่อเพิ่มลงในรายการ",
- "tr_TR": "",
- "uk_UA": "Додайте шлях автозавантаження для додавання до списку",
- "zh_CN": "添加一个自动加载目录到列表中",
- "zh_TW": "新增「自動載入 DLC/遊戲更新資料夾」到清單中"
- }
- },
- {
- "ID": "RemoveAutoloadDirTooltip",
- "Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
- "en_US": "Remove selected autoload directory",
- "es_ES": "Eliminar el directorio de carga automática seleccionado",
- "fr_FR": "Supprimer le répertoire d’autochargement sélectionné",
- "he_IL": "",
- "it_IT": "Rimuovi la cartella di caricamento automatico selezionata",
- "ja_JP": "",
- "ko_KR": "선택한 자동 불러오기 디렉터리 제거",
- "no_NO": "Fjern valgt autoload-mappe",
- "pl_PL": "",
- "pt_BR": "Remover o diretório de carregamento automático selecionado",
- "ru_RU": "Убрать папку автозагрузки из списка",
- "sv_SE": "Ta bort markerad katalog för automatisk inläsning",
- "th_TH": "ลบไดเรกทอรีสำหรับโหลดอัตโนมัติที่เลือก",
- "tr_TR": "",
- "uk_UA": "Видалити вибрану теку автозавантаження",
- "zh_CN": "移除被选中的自动加载目录",
- "zh_TW": "移除選取的「自動載入 DLC/遊戲更新資料夾」"
+ "ar_SA": "أدخل مسار الدليل أو استخدم زر \"إضافة\"...",
+ "de_DE": "Geben Sie einen Pfad ein oder nutzen Sie \"Hinzufügen\"...",
+ "el_GR": "Εισαγάγετε διαδρομή ή χρησιμοποιήστε το \"Προσθήκη\"...",
+ "en_US": "Enter a directory path or use the \"Add\" button...",
+ "es_ES": "Escriba una ruta o use el botón \"Agregar\"...",
+ "fr_FR": "Entrez un chemin ou utilisez le bouton « Ajouter »...",
+ "he_IL": "הזן נתיב או השתמש בכפתור \"הוסף\"...",
+ "it_IT": "Inserisci un percorso o usa il pulsante \"Aggiungi\"...",
+ "ja_JP": "パスを入力するか、「追加」ボタンを使ってください…",
+ "ko_KR": "경로를 입력하거나 \"추가\" 버튼을 사용하세요...",
+ "no_NO": "Skriv inn en bane eller bruk knappen \"Legg til\"...",
+ "pl_PL": "Wprowadź ścieżkę lub użyj przycisku \"Dodaj\"...",
+ "pt_BR": "Digite o caminho ou use o botão \"Adicionar\"...",
+ "ru_RU": "Введите путь или используйте кнопку \"Добавить\"...",
+ "sv_SE": "Ange en väg eller använd knappen \"Lägg till\"...",
+ "th_TH": "ใส่เส้นทางหรือใช้ปุ่ม \"เพิ่ม\"...",
+ "tr_TR": "Bir yol girin veya \"Ekle\" düğmesini kullanın...",
+ "uk_UA": "Введіть шлях або використовуйте кнопку \"Додати\"...",
+ "zh_CN": "输入路径或使用“添加”按钮...",
+ "zh_TW": "輸入路徑或使用「新增」按鈕..."
}
},
{
@@ -16277,7 +16002,7 @@
"es_ES": "Si esta opción está activada en los ajustes personalizados, se utilizará la configuración de entrada global.\n\nEn los ajustes globales: puedes activarla o desactivarla según sea necesario; esta configuración se aplicará a cualquier nueva configuración personalizada que se cree.",
"fr_FR": "Si cette option est activée dans les paramètres personnalisés, la configuration d’entrée globale sera utilisée.\n\nDans les paramètres globaux, vous pouvez l’activer ou la désactiver selon vos besoins ; ce réglage sera alors hérité par toutes les nouvelles configurations personnalisées créées",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Se questa opzione è abilitata nelle impostazioni personalizzate, verrà utilizzata la configurazione di input globale.\n\nNelle impostazioni globali: puoi abilitarla o disabilitarla secondo necessità; questa impostazione verrà ereditata da tutte le nuove configurazioni personalizzate create.",
"ja_JP": "",
"ko_KR": "사용자 지정 설정에서 이 옵션을 활성화하면 전역 입력 구성이 사용됩니다.\n\n전역 설정에서 필요에 따라 활성화하거나 비활성화할 수 있습니다. 이 설정은 새로 생성된 모든 사용자 지정 구성에 상속됩니다.",
"no_NO": "",
@@ -16382,7 +16107,7 @@
"ko_KR": "시스템 시간을 PC의 현재 날짜 및 시간과 일치하도록 다시 동기화합니다.",
"no_NO": "Resynkroniser systemtiden slik at den samsvarer med PC-ens gjeldende dato og klokkeslett.",
"pl_PL": "",
- "pt_BR": "Sincroniza a data e hora do emulador com seu sistema PC",
+ "pt_BR": "Sincroniza a data e hora do emulador com seu sistema PC.",
"ru_RU": "Синхронизировать время системы с текущей датой и временем на вашем компьютере.",
"sv_SE": "Återsynkronisera systemtiden för att matcha din dators aktuella datum och tid.",
"th_TH": "ปรับเวลาในระบบให้ตรงกับวันที่และเวลาปัจจุบันของเครื่องคอมพิวเตอร์ของคุณ",
@@ -16446,7 +16171,7 @@
"ID": "LowPowerPptcToggleTooltip",
"Translations": {
"ar_SA": "",
- "de_DE": "Lädt den PPTC mit einem Drittel der verfügbaren Prozessorkernen",
+ "de_DE": "Lädt den PPTC mit einem Drittel der verfügbaren Prozessorkernen.",
"el_GR": "",
"en_US": "Load the PPTC using a third of the amount of cores.",
"es_ES": "Cargue el PPTC utilizando un tercio de la cantidad de núcleos.",
@@ -16463,7 +16188,7 @@
"th_TH": "โหลด PPTC โดยใช้หนึ่งในสามของจำนวนคอร์",
"tr_TR": "",
"uk_UA": "Завантажувати PPTC використовуючи третину від кількості ядер.",
- "zh_CN": "使用三分之一的核心数加载 PPTC.",
+ "zh_CN": "使用三分之一的核心数加载 PPTC。",
"zh_TW": "使用 CPU 核心數量的三分之一載入 PPTC。"
}
},
@@ -16631,7 +16356,7 @@
"ja_JP": "JIT の代わりにハイパーバイザーを使用します. 利用可能な場合, パフォーマンスが大幅に向上しますが, 現在の状態では不安定になる可能性があります.",
"ko_KR": "JIT 대신 Hypervisor를 사용하세요. 사용 가능한 경우 성능이 크게 향상되지만 현재 상태에서는 불안정할 수 있습니다.",
"no_NO": "Bruk Hypervisor i stedet for JIT. Det øker ytelsen mye hvis det er tilgjengelig, men det kan være ustabilt i den nåværende tilstanden.",
- "pl_PL": "Użyj Hiperwizora zamiast JIT. Znacznie poprawia wydajność, gdy jest dostępny, ale może być niestabilny w swoim obecnym stanie ",
+ "pl_PL": "Użyj Hiperwizora zamiast JIT. Znacznie poprawia wydajność, gdy jest dostępny, ale może być niestabilny w swoim obecnym stanie.",
"pt_BR": "Usa o Hypervisor em vez de JIT (recompilador dinâmico). Melhora significativamente o desempenho quando disponível, mas pode ser instável no seu estado atual.",
"ru_RU": "Использует Hypervisor вместо JIT. Когда доступен, значительно улучшает производительность, но может быть нестабильным в текущем состоянии.",
"sv_SE": "Använd hypervisor istället för JIT. Förbättrar prestandan avsevärt när den finns tillgänglig men kan ge ostabilitet i dess aktuella tillstånd.",
@@ -16702,7 +16427,7 @@
"es_ES": "El cuadro de diálogo del Applet de controladores no aparecerá si el gamepad se desconecta mientras una aplicación está en ejecución.\n\nDéjar DESACTIVADO si no está seguro.",
"fr_FR": "La fenêtre de l’Applet Manette ne s’affichera pas si la manette est déconnectée pendant l’exécution d’une application\n\nLaissez DÉSACTIVÉ si vous n’êtes pas sûr.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "La finestra del Controller Applet non apparirà se il gamepad viene disconnesso mentre un'applicazione è in esecuzione.\n\nLascia DISATTIVATO se non sei sicuro.",
"ja_JP": "",
"ko_KR": "앱이 실행 중일 때, 게임패드의 연결이 끊어지면 컨트롤러 애플릿 대화 상자가 나타나지 않습니다.\n\n모르시면 체크 해제 상태로 두십시오.",
"no_NO": "Håndkontroller-appleten vises ikke hvis gamepaden kobles fra mens et program kjører.",
@@ -16762,7 +16487,7 @@
"sv_SE": "Kör kommandon för grafikbakände i en andra tråd.\n\nSnabbar upp shader compilation, minskar stuttering och förbättrar prestandan på GPU-drivrutiner utan stöd för egen multithreading. Något bättre prestanda på drivrutiner med multithreading.\n\nStäll in till AUTO om du är osäker.",
"th_TH": "ดำเนินการคำสั่งแบ็กเอนด์กราฟิกบนเธรดที่สอง\n\nเร่งความเร็วการคอมไพล์ ลดการกระตุก และปรับปรุงประสิทธิภาพการทำงานของไดรเวอร์ GPU โดยไม่ต้องรองรับมัลติเธรดในตัว ประสิทธิภาพที่ดีขึ้นเล็กน้อยสำหรับไดรเวอร์ที่มีมัลติเธรด\n\nตั้งเป็น อัตโนมัติ หากคุณไม่แน่ใจ",
"tr_TR": "Grafik arka uç komutlarını ikinci bir iş parçacığında işletir.\n\nKendi multithreading desteği olmayan sürücülerde shader derlemeyi hızlandırıp performansı artırır. Multithreading desteği olan sürücülerde çok az daha iyi performans sağlar.\n\nEmin değilseniz Otomatik seçeneğine ayarlayın.",
- "uk_UA": "Виконує команди графічного сервера в другому потоці.\n\nПрискорює компіляцію шейдерів, зменшує затримки та покращує продуктивність драйверів GPU без власної підтримки багатопоточності. Трохи краща продуктивність на драйверах з багатопотоковістю.\nВстановіть значення «Авто» якщо не впевнені",
+ "uk_UA": "Виконує команди графічного сервера в другому потоці.\n\nПрискорює компіляцію шейдерів, зменшує затримки та покращує продуктивність драйверів GPU без власної підтримки багатопоточності. Трохи краща продуктивність на драйверах з багатопотоковістю.\nВстановіть значення «Авто» якщо не впевнені.",
"zh_CN": "在第二个线程上执行图形引擎指令。\n\n可以加速着色器编译,减少卡顿,提高 GPU 的性能。\n\n如果不确定,请设置为“自动”。",
"zh_TW": "在第二個執行緒上執行圖形後端指令。\n\n在本身不支援多執行緒的 GPU 驅動程式上,可加快著色器編譯、減少卡頓並提高效能。在支援多執行緒的驅動程式上效能略有提升。\n\n如果不確定,請設定為自動。"
}
@@ -17120,26 +16845,26 @@
{
"ID": "FSAccessLogModeTooltip",
"Translations": {
- "ar_SA": "تمكين إخراج سجل الوصول إلى نظام الملفات إلى وحدة التحكم. الأوضاع الممكنة هي 0-3",
- "de_DE": "Aktiviert die Ausgabe des FS-Zugriff-Logs in der Konsole. Mögliche Modi sind 0-3",
- "el_GR": "Ενεργοποιεί την έξοδο καταγραφής πρόσβασης FS στην κονσόλα. Οι πιθανοί τρόποι λειτουργίας είναι 0-3",
- "en_US": "Enables FS access log output to the console. Possible modes are 0-3",
- "es_ES": "Activa registros FS Access en la consola. Los modos posibles son entre 0 y 3",
+ "ar_SA": "تمكين إخراج سجل الوصول إلى نظام الملفات إلى وحدة التحكم. الأوضاع الممكنة هي 0-3.",
+ "de_DE": "Aktiviert die Ausgabe des FS-Zugriff-Logs in der Konsole. Mögliche Modi sind 0-3.",
+ "el_GR": "Ενεργοποιεί την έξοδο καταγραφής πρόσβασης FS στην κονσόλα. Οι πιθανοί τρόποι λειτουργίας είναι 0-3.",
+ "en_US": "Enables FS access log output to the console. Possible modes are 0-3.",
+ "es_ES": "Activa registros FS Access en la consola. Los modos posibles son entre 0 y 3.",
"fr_FR": "Active l’affichage des journaux d’accès FS dans la console. Les modes possibles sont de 0 à 3.",
"he_IL": "מאפשר גישה לרישומי FS ליציאת שורת הפקודות. האפשרויות הינן 0-3.",
- "it_IT": "Attiva l'output dei log di accesso FS nella console. Le modalità possibili vanno da 0 a 3",
- "ja_JP": "コンソールへのファイルシステムアクセスログ出力を有効にします.0-3 のモードが有効です",
- "ko_KR": "콘솔에 파일 시스템 접속 기록 출력을 활성화합니다. 가능한 모드는 0-3",
- "no_NO": "Aktiverer FS tilgang loggutgang til konsollen. Mulige moduser er 0-3",
- "pl_PL": "Włącza wyjście dziennika dostępu FS do konsoli. Możliwe tryby to 0-3",
- "pt_BR": "Habilita a saída do log de acesso FS para o console. Os modos possíveis são 0-3",
- "ru_RU": "Включает вывод журнала доступа к файловой системе. Возможные режимы: 0-3",
- "sv_SE": "Aktiverar loggutdata för filsystemsåtkomst i konsollen. Möjliga lägen är 0-3",
- "th_TH": "เปิดใช้งาน เอาต์พุตประวัติการเข้าถึง FS ไปยังคอนโซล โหมดที่เป็นไปได้คือ 0-3",
- "tr_TR": "Konsola FS erişim loglarının yazılmasını etkinleştirir. Kullanılabilir modlar 0-3'tür",
- "uk_UA": "Увімкнути виведення журналу доступу (access log) до файлової системи в консоль. Можливі режими: 0-3",
+ "it_IT": "Attiva l'output dei log di accesso FS nella console. Le modalità possibili vanno da 0 a 3.",
+ "ja_JP": "コンソールへのファイルシステムアクセスログ出力を有効にします.0-3 のモードが有効です.",
+ "ko_KR": "콘솔에 파일 시스템 접속 기록 출력을 활성화합니다. 가능한 모드는 0-3.",
+ "no_NO": "Aktiverer FS tilgang loggutgang til konsollen. Mulige moduser er 0-3.",
+ "pl_PL": "Włącza wyjście dziennika dostępu FS do konsoli. Możliwe tryby to 0-3.",
+ "pt_BR": "Habilita a saída do log de acesso FS para o console. Os modos possíveis são 0-3.",
+ "ru_RU": "Включает вывод журнала доступа к файловой системе. Возможные режимы: 0-3.",
+ "sv_SE": "Aktiverar loggutdata för filsystemsåtkomst i konsollen. Möjliga lägen är 0-3.",
+ "th_TH": "เปิดใช้งาน เอาต์พุตประวัติการเข้าถึง FS ไปยังคอนโซล โหมดที่เป็นไปได้คือ 0-3.",
+ "tr_TR": "Konsola FS erişim loglarının yazılmasını etkinleştirir. Kullanılabilir modlar 0-3'tür.",
+ "uk_UA": "Увімкнути виведення журналу доступу (access log) до файлової системи в консоль. Можливі режими: 0-3.",
"zh_CN": "在控制台中显示文件系统访问日志,可选模式为 0-3。",
- "zh_TW": "啟用檔案系統存取日誌輸出到控制台中。可能的模式為 0 到 3"
+ "zh_TW": "啟用檔案系統存取日誌輸出到控制台中。可能的模式為 0 到 3。"
}
},
{
@@ -17177,7 +16902,7 @@
"es_ES": "Muestra los mensajes del registro de Avalonia (UI) en la consola.",
"fr_FR": "Affiche les journaux Avalonia (Interface Utilisateur) dans la console.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Stampa i messaggi di log di Avalonia (UI) nella console.",
"ja_JP": "",
"ko_KR": "콘솔에 Avalonia(UI) 로그 메시지를 출력합니다.",
"no_NO": "Skriver ut Avalonia (UI)-loggmeldinger i konsollen.",
@@ -17195,26 +16920,26 @@
{
"ID": "OpenGlLogLevel",
"Translations": {
- "ar_SA": "يتطلب تمكين مستويات السجل المناسبة",
- "de_DE": "Erfordert die Aktivierung der entsprechenden Log-Level",
- "el_GR": "Απαιτεί τα κατάλληλα επίπεδα καταγραφής ενεργοποιημένα",
- "en_US": "Requires appropriate log levels enabled",
- "es_ES": "Requiere activar los niveles de registro apropiados",
- "fr_FR": "Nécessite l'activation des niveaux de journalisation appropriés",
- "he_IL": "דורש הפעלת רמות רישום מתאימות",
- "it_IT": "Richiede che i livelli di log appropriati siano abilitati",
- "ja_JP": "適切なログレベルを有効にする必要があります",
- "ko_KR": "적절한 기록 수준이 활성화되어 있어야 함",
- "no_NO": "Krever riktige loggnivåer aktivert",
- "pl_PL": "Wymaga włączonych odpowiednich poziomów logów",
- "pt_BR": "Requer níveis de log apropriados habilitados",
- "ru_RU": "Требует включения соответствующих уровней ведения журнала",
- "sv_SE": "Kräver att lämpliga loggnivåer aktiveras",
+ "ar_SA": "يتطلب تمكين مستويات السجل المناسبة.",
+ "de_DE": "Erfordert die Aktivierung der entsprechenden Log-Level.",
+ "el_GR": "Απαιτεί τα κατάλληλα επίπεδα καταγραφής ενεργοποιημένα.",
+ "en_US": "Requires appropriate log levels enabled.",
+ "es_ES": "Requiere activar los niveles de registro apropiados.",
+ "fr_FR": "Nécessite l'activation des niveaux de journalisation appropriés.",
+ "he_IL": "דורש הפעלת רמות רישום מתאימות.",
+ "it_IT": "Richiede che i livelli di log appropriati siano abilitati.",
+ "ja_JP": "適切なログレベルを有効にする必要があります.",
+ "ko_KR": "적절한 기록 수준이 활성화되어 있어야 함.",
+ "no_NO": "Krever riktige loggnivåer aktivert.",
+ "pl_PL": "Wymaga włączonych odpowiednich poziomów logów.",
+ "pt_BR": "Requer níveis de log apropriados habilitados.",
+ "ru_RU": "Требует включения соответствующих уровней ведения журнала.",
+ "sv_SE": "Kräver att lämpliga loggnivåer aktiveras.",
"th_TH": "จำเป็นต้องเปิดใช้งานระดับบันทึกที่เหมาะสม",
- "tr_TR": "Uygun log seviyesinin aktif olmasını gerektirir",
- "uk_UA": "Потрібно увімкнути відповідні рівні журналу (log)",
- "zh_CN": "需要启用适当的日志级别",
- "zh_TW": "需要啟用適當的日誌等級"
+ "tr_TR": "Uygun log seviyesinin aktif olmasını gerektirir.",
+ "uk_UA": "Потрібно увімкнути відповідні рівні журналу (log).",
+ "zh_CN": "需要启用适当的日志级别。",
+ "zh_TW": "需要啟用適當的日誌等級。"
}
},
{
@@ -17327,7 +17052,7 @@
"es_ES": "Volumen: ",
"fr_FR": "Volume :",
"he_IL": "עוצמת קול: ",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "音量: ",
"ko_KR": "음량 : ",
"no_NO": "Lydnivå: ",
@@ -17371,8 +17096,8 @@
"ID": "EnableInternetAccessTooltip",
"Translations": {
"ar_SA": "للسماح للتطبيق الذي تمت محاكاته بالاتصال بالإنترنت.\n\nيمكن للألعاب التي تحتوي على وضع LAN الاتصال ببعضها البعض عند تمكين ذلك وتوصيل الأنظمة بنفس نقطة الوصول. وهذا يشمل الأجهزة الحقيقية أيضا.\n\nلا يسمح بالاتصال بخوادم نينتندو. قد يتسبب في حدوث عطل في بعض الألعاب التي تحاول الاتصال بالإنترنت.\n\nاتركه معطلا إذا لم تكن متأكدا.",
- "de_DE": "Erlaubt es der emulierten Anwendung sich mit dem Internet zu verbinden.\n\nSpiele die den LAN-Modus unterstützen, ermöglichen es Ryujinx sich sowohl mit anderen Ryujinx-Systemen, als auch mit offiziellen Nintendo Switch Konsolen zu verbinden. Allerdings nur, wenn diese Option aktiviert ist und die Systeme mit demselben lokalen Netzwerk verbunden sind.\n\nDies erlaubt KEINE Verbindung zu Nintendo-Servern. Kann bei bestimmten Spielen die versuchen sich mit dem Internet zu verbinden zum Absturz führen.\n\nIm Zweifelsfall AUS lassen",
- "el_GR": "Επιτρέπει την πρόσβαση επισκέπτη στο Διαδίκτυο. Εάν ενεργοποιηθεί, η εξομοιωμένη κονσόλα Switch θα συμπεριφέρεται σαν να είναι συνδεδεμένη στο Διαδίκτυο. Λάβετε υπόψη ότι σε ορισμένες περιπτώσεις, οι εφαρμογές ενδέχεται να εξακολουθούν να έχουν πρόσβαση στο Διαδίκτυο, ακόμη και όταν αυτή η επιλογή είναι απενεργοποιημένη",
+ "de_DE": "Erlaubt es der emulierten Anwendung sich mit dem Internet zu verbinden.\n\nSpiele die den LAN-Modus unterstützen, ermöglichen es Ryujinx sich sowohl mit anderen Ryujinx-Systemen, als auch mit offiziellen Nintendo Switch Konsolen zu verbinden. Allerdings nur, wenn diese Option aktiviert ist und die Systeme mit demselben lokalen Netzwerk verbunden sind.\n\nDies erlaubt KEINE Verbindung zu Nintendo-Servern. Kann bei bestimmten Spielen die versuchen sich mit dem Internet zu verbinden zum Absturz führen.\n\nIm Zweifelsfall AUS lassen.",
+ "el_GR": "Επιτρέπει την πρόσβαση επισκέπτη στο Διαδίκτυο. Εάν ενεργοποιηθεί, η εξομοιωμένη κονσόλα Switch θα συμπεριφέρεται σαν να είναι συνδεδεμένη στο Διαδίκτυο. Λάβετε υπόψη ότι σε ορισμένες περιπτώσεις, οι εφαρμογές ενδέχεται να εξακολουθούν να έχουν πρόσβαση στο Διαδίκτυο, ακόμη και όταν αυτή η επιλογή είναι απενεργοποιημένη.",
"en_US": "Allows the emulated application to connect to the Internet.\n\nGames with a LAN mode can connect to each other when this is enabled and the systems are connected to the same access point. This includes real consoles as well.\n\nDoes NOT allow connecting to Nintendo servers. May cause crashing in certain games that try to connect to the Internet.\n\nLeave OFF if unsure.",
"es_ES": "Permite a la aplicación emulada conectarse a Internet.\n\nLos juegos que tengan modo LAN podrán conectarse entre sí habilitando esta opción y estando conectados al mismo módem. Asimismo, esto permite conexiones con consolas reales.\n\nNO permite conectar con los servidores de Nintendo Online. Puede causar que ciertos juegos crasheen al intentar conectarse a sus servidores.\n\nDesactívalo si no estás seguro.",
"fr_FR": "Permet à l'application émulée de se connecter à Internet.\n\nLes jeux avec un mode LAN peuvent se connecter les uns aux autres lorsque cette option est cochée et que les systèmes sont connectés au même point d'accès. Cela inclut également les vrais consoles.\n\nCette option n'autorise PAS la connexion aux serveurs Nintendo. Elle peut faire planter certains jeux qui essaient de se connecter à l'Internet.\n\nLaissez DÉSACTIVÉ si vous n'êtes pas sûr.",
@@ -17445,26 +17170,26 @@
{
"ID": "ControllerSettingsStickRange",
"Translations": {
- "ar_SA": "نطاق:",
- "de_DE": "Bereich:",
- "el_GR": "Εύρος:",
- "en_US": "Range:",
- "es_ES": "Alcance:",
- "fr_FR": "Intervalle :",
- "he_IL": "טווח:",
- "it_IT": "Raggio:",
- "ja_JP": "範囲:",
- "ko_KR": "범위 :",
- "no_NO": "Omfang:",
- "pl_PL": "Zasięg:",
- "pt_BR": "Intervalo:",
- "ru_RU": "Диапазон:",
- "sv_SE": "Omfång:",
- "th_TH": "ขอบเขต:",
- "tr_TR": "Menzil:",
- "uk_UA": "Діапазон:",
- "zh_CN": "范围:",
- "zh_TW": "範圍:"
+ "ar_SA": "نطاق",
+ "de_DE": "Bereich",
+ "el_GR": "Εύρος",
+ "en_US": "Range",
+ "es_ES": "Alcance",
+ "fr_FR": "Intervalle",
+ "he_IL": "טווח",
+ "it_IT": "Raggio",
+ "ja_JP": "範囲",
+ "ko_KR": "범위",
+ "no_NO": "Omfang",
+ "pl_PL": "Zasięg",
+ "pt_BR": "Intervalo",
+ "ru_RU": "Диапазон",
+ "sv_SE": "Omfång",
+ "th_TH": "ขอบเขต",
+ "tr_TR": "Menzil",
+ "uk_UA": "Діапазон",
+ "zh_CN": "范围",
+ "zh_TW": "範圍"
}
},
{
@@ -17527,7 +17252,7 @@
"es_ES": "Procesador",
"fr_FR": "Processeur",
"he_IL": "מעבד",
- "it_IT": "",
+ "it_IT": "Processore",
"ja_JP": "",
"ko_KR": "중앙처리장치",
"no_NO": "Prosessor",
@@ -17552,7 +17277,7 @@
"es_ES": "Sonido",
"fr_FR": null,
"he_IL": "שמע",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "音声",
"ko_KR": "음향",
"no_NO": "Lyd",
@@ -17702,7 +17427,7 @@
"es_ES": null,
"fr_FR": null,
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "{0}FPS({1}밀리초)",
"no_NO": "",
@@ -17727,7 +17452,7 @@
"es_ES": null,
"fr_FR": null,
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "{0}FPS({1}밀리초), ({2}%) 터보",
"no_NO": "",
@@ -17752,7 +17477,7 @@
"es_ES": "Actualizacion Disponible!",
"fr_FR": "Mise à jour Disponible !",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Aggiornamento disponibile!",
"ja_JP": "",
"ko_KR": "업데이트 가능!",
"no_NO": "Oppdatering tilgjengelig!",
@@ -17792,31 +17517,6 @@
"zh_TW": "順時針旋轉 90°"
}
},
- {
- "ID": "IconSize",
- "Translations": {
- "ar_SA": "حجم الأيقونة",
- "de_DE": "Cover Größe",
- "el_GR": "Μέγεθος Εικονιδίου",
- "en_US": "Icon Size",
- "es_ES": "Tamaño de Iconos",
- "fr_FR": "Taille d'Icône",
- "he_IL": "גודל הסמל",
- "it_IT": "Dimensioni icone",
- "ja_JP": "アイコンサイズ",
- "ko_KR": "아이콘 크기",
- "no_NO": "Ikon størrelse",
- "pl_PL": "Rozmiar ikon",
- "pt_BR": "Tamanho do Ícone",
- "ru_RU": "Размер обложек",
- "sv_SE": "Ikonstorlek",
- "th_TH": "ขนาดไอคอน",
- "tr_TR": "Ikon Boyutu",
- "uk_UA": "Розмір обкладинки",
- "zh_CN": "图标尺寸",
- "zh_TW": "圖示大小"
- }
- },
{
"ID": "MenuBarOptionsShowConsole",
"Translations": {
@@ -18602,7 +18302,7 @@
"es_ES": "Diálogo Gabinete",
"fr_FR": "Dialogue de Cabinet",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Modale del Cabinet",
"ja_JP": "",
"ko_KR": "캐비닛 대화 상자",
"no_NO": "Dialogboks for kabinett",
@@ -19420,26 +19120,26 @@
{
"ID": "SettingsTabHotkeys",
"Translations": {
- "ar_SA": "مفاتيح الاختصار في لوحة المفاتيح",
- "de_DE": "Tastatur-Hotkeys",
- "el_GR": "Συντομεύσεις Πληκτρολογίου",
- "en_US": "Keyboard Hotkeys",
- "es_ES": "Atajos de Teclado",
- "fr_FR": "Raccourcis Clavier",
- "he_IL": "מקשי קיצור במקלדת",
- "it_IT": "Tasti di scelta rapida",
- "ja_JP": "キーボード ホットキー",
- "ko_KR": "키보드 단축키",
- "no_NO": "Hurtigtaster for tastatur",
- "pl_PL": "Skróty Klawiszowe Klawiatury",
- "pt_BR": "Atalhos do Teclado",
+ "ar_SA": "اختصارات",
+ "de_DE": "Hotkeys",
+ "el_GR": "Συντομεύσεις",
+ "en_US": "Hotkeys",
+ "es_ES": "Atajos",
+ "fr_FR": "Raccourcis",
+ "he_IL": "מקשי קיצור",
+ "it_IT": "Tasti rapidi",
+ "ja_JP": "ホットキー",
+ "ko_KR": "단축키",
+ "no_NO": "Hurtigtaster",
+ "pl_PL": "Skróty klawiszowe",
+ "pt_BR": "Atalhos",
"ru_RU": "Горячие клавиши",
"sv_SE": "Snabbtangenter",
- "th_TH": "ปุ่มลัดของคีย์บอร์ด",
- "tr_TR": "Klavye Kısayolları",
+ "th_TH": "ปุ่มลัด",
+ "tr_TR": "Kısayollar",
"uk_UA": "Гарячі клавіші",
"zh_CN": "快捷键",
- "zh_TW": "鍵盤快速鍵"
+ "zh_TW": "快速鍵"
}
},
{
@@ -19627,7 +19327,7 @@
"es_ES": "Configuración LED",
"fr_FR": "Paramètres LED",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Impostazioni LED",
"ja_JP": "",
"ko_KR": "LED 설정",
"no_NO": "LED-innstillinger",
@@ -19727,7 +19427,7 @@
"es_ES": null,
"fr_FR": null,
"he_IL": "אמיבו",
- "it_IT": "",
+ "it_IT": "Amiibo",
"ja_JP": "",
"ko_KR": null,
"no_NO": "",
@@ -19892,31 +19592,6 @@
"zh_TW": "選取模組資料夾"
}
},
- {
- "ID": "TrimXCIFileDialogTitle",
- "Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
- "en_US": "Check and Trim XCI File",
- "es_ES": "Verificar y Recortar Archivo XCI",
- "fr_FR": "Vérifier et Réduire le Fichier XCI",
- "he_IL": "",
- "it_IT": "Controlla e riduci la dimensione del file XCI",
- "ja_JP": "",
- "ko_KR": "XCI 파일 확인 및 정리",
- "no_NO": "Kontroller og trim XCI-filen",
- "pl_PL": "",
- "pt_BR": "Verifique e Reduza o Arquivo XCI",
- "ru_RU": "Проверить и обрезать XCI файл",
- "sv_SE": "Kontrollera och optimera XCI-filer",
- "th_TH": "ตรวจสอบและตัดแต่งไฟล์ XCI",
- "tr_TR": "",
- "uk_UA": "Перевірити та Обрізати XCI файл",
- "zh_CN": "检查并瘦身 XCI 文件",
- "zh_TW": "檢查及修剪 XCI 檔案"
- }
- },
{
"ID": "TrimXCIFileDialogPrimaryText",
"Translations": {
@@ -20848,7 +20523,7 @@
"ar_SA": "",
"de_DE": "",
"el_GR": "",
- "en_US": "{0} DLC(s) available",
+ "en_US": "{0} DLC(s) Available",
"es_ES": "{0} DLC(s) disponible(s)",
"fr_FR": "{0} DLC(s) disponible(s)",
"he_IL": "{0} הרחבות משחק",
@@ -20873,7 +20548,7 @@
"ar_SA": "",
"de_DE": "",
"el_GR": "",
- "en_US": "{0} new downloadable content(s) added",
+ "en_US": "{0} New Downloadable Content(s) Added",
"es_ES": "Se agregó/aron {0} nuevo(s) contenido(s) descargable(s)",
"fr_FR": "{0} nouveau(x) contenu(s) téléchargeable(s) ajouté(s)",
"he_IL": "",
@@ -20898,7 +20573,7 @@
"ar_SA": "",
"de_DE": "",
"el_GR": "",
- "en_US": "{0} new downloadable content(s) added",
+ "en_US": "{0} New Downloadable Content(s) Added",
"es_ES": "Se agregó/aron {0} nuevo(s) contenido(s) descargable(s)",
"fr_FR": "{0} nouveau(x) contenu(s) téléchargeable(s) ajouté(s)",
"he_IL": "",
@@ -20923,7 +20598,7 @@
"ar_SA": "",
"de_DE": "",
"el_GR": "",
- "en_US": "{0} missing downloadable content(s) removed",
+ "en_US": "{0} Missing Downloadable Content(s) Removed",
"es_ES": "Se eliminó/aron {0} contenido(s) descargable(s) faltante(s)",
"fr_FR": "{0} contenu(s) téléchargeable(s) manquant(s) supprimé(s)",
"he_IL": "",
@@ -20948,7 +20623,7 @@
"ar_SA": "",
"de_DE": "",
"el_GR": "",
- "en_US": "{0} new update(s) added",
+ "en_US": "{0} New Update(s) Added",
"es_ES": "Se agregó/aron {0} nueva(s) actualización(es)",
"fr_FR": "{0} nouvelle(s) mise(s) à jour ajoutée(s)",
"he_IL": "",
@@ -20973,7 +20648,7 @@
"ar_SA": "",
"de_DE": "",
"el_GR": "",
- "en_US": "{0} missing update(s) removed",
+ "en_US": "{0} Missing Update(s) Removed",
"es_ES": "Se eliminó/aron {0} actualización(es) faltante(s)",
"fr_FR": "{0} mise(s) à jour manquante(s) supprimée(s)",
"he_IL": "",
@@ -21370,26 +21045,26 @@
{
"ID": "SettingsTabGraphicsBackend",
"Translations": {
- "ar_SA": "خلفية الرسومات",
+ "ar_SA": "خلفية الرسومات:",
"de_DE": "Grafik-Backend:",
- "el_GR": "Σύστημα Υποστήριξης Γραφικών",
- "en_US": "Graphics Backend",
- "es_ES": "Fondo de Gráficos",
- "fr_FR": "API de Rendu",
- "he_IL": "אחראי גראפיקה",
- "it_IT": "Backend grafico",
- "ja_JP": "グラフィックスバックエンド",
- "ko_KR": "그래픽 후단부",
- "no_NO": "Grafikk Backend",
- "pl_PL": "Backend Graficzny",
- "pt_BR": "Renderizador Gráfico",
+ "el_GR": "Σύστημα Υποστήριξης Γραφικών:",
+ "en_US": "Graphics Backend:",
+ "es_ES": "Fondo de gráficos:",
+ "fr_FR": "API de Rendu :",
+ "he_IL": "אחראי גראפיקה:",
+ "it_IT": "Backend grafico:",
+ "ja_JP": "グラフィックスバックエンド:",
+ "ko_KR": "그래픽 후단부 :",
+ "no_NO": "Grafikk Backend:",
+ "pl_PL": "Backend Graficzny:",
+ "pt_BR": "Renderizador Gráfico:",
"ru_RU": "Графический бэкенд:",
- "sv_SE": "Grafikbakände",
- "th_TH": "กราฟิกเบื้องหลัง",
- "tr_TR": "Grafik Arka Ucu",
- "uk_UA": "Графічний API",
+ "sv_SE": "Grafikbakände:",
+ "th_TH": "กราฟิกเบื้องหลัง:",
+ "tr_TR": "Grafik Arka Ucu:",
+ "uk_UA": "Графічний API:",
"zh_CN": "图形渲染引擎:",
- "zh_TW": "圖形後端"
+ "zh_TW": "圖形後端:"
}
},
{
@@ -21404,7 +21079,7 @@
"he_IL": "",
"it_IT": "Seleziona il backend grafico che verrà utilizzato nell'emulatore.\n\nVulkan è nel complesso migliore per tutte le schede grafiche moderne, a condizione che i relativi driver siano aggiornati. Vulkan dispone anche di una compilazione degli shader più veloce (con minore stuttering) su tutte le marche di GPU.\n\nOpenGL può ottenere risultati migliori su vecchie GPU Nvidia, su vecchie GPU AMD su Linux, o su GPU con poca VRAM, anche se lo stuttering dovuto alla compilazione degli shader sarà maggiore.\n\nNel dubbio, scegli Vulkan. Seleziona OpenGL se la GPU non supporta Vulkan nemmeno con i driver grafici più recenti.",
"ja_JP": "エミュレーションに使用するグラフィックスバックエンドを選択します.\n\nVulkanは, 最近のグラフィックカードでドライバが最新であれば, 全体的に優れています. すべてのGPUベンダーで, シェーダーコンパイルがより高速で, スタッタリングが少ないのが特徴です.\n\n古いNvidia GPU, Linuxでの古いAMD GPU, VRAMの少ないGPUなどでは, OpenGLの方が良い結果が得られるかもしれません. ですが, シェーダーコンパイルのスタッターは大きくなります.\n\n不明な場合はVulkanに設定してください。最新のグラフィックドライバでもVulkanをサポートしていないGPUの場合は, OpenGLに設定してください.",
- "ko_KR": "에뮬레이터에서 사용할 그래픽 후단부를 선택합니다.\n\nVulkan은 드라이버가 최신 상태인 한 모든 최신 그래픽 카드에 전반적으로 더 좋습니다. Vulkan은 또한 모든 GPU 공급업체에서 더 빠른 셰이더 컴파일(덜 끊김)을 제공합니다.\n\nOpenGL은 오래된 Nvidia GPU, Linux의 오래된 AMD GPU 또는 VRAM이 낮은 GPU에서 더 나은 결과를 얻을 수 있지만 셰이더 컴파일 끊김이 더 큽니다.\n\n모르면 Vulkan으로 설정합니다. 최신 그래픽 드라이버를 사용해도 GPU가 Vulkan을 지원하지 않는 경우 OpenGL로 설정하세요..",
+ "ko_KR": "에뮬레이터에서 사용할 그래픽 후단부를 선택합니다.\n\nVulkan은 드라이버가 최신 상태인 한 모든 최신 그래픽 카드에 전반적으로 더 좋습니다. Vulkan은 또한 모든 GPU 공급업체에서 더 빠른 셰이더 컴파일(덜 끊김)을 제공합니다.\n\nOpenGL은 오래된 Nvidia GPU, Linux의 오래된 AMD GPU 또는 VRAM이 낮은 GPU에서 더 나은 결과를 얻을 수 있지만 셰이더 컴파일 끊김이 더 큽니다.\n\n모르면 Vulkan으로 설정합니다. 최신 그래픽 드라이버를 사용해도 GPU가 Vulkan을 지원하지 않는 경우 OpenGL로 설정하세요.",
"no_NO": "Velg grafikkbackend som skal brukes i emulatoren.\n\nVulkan er generelt bedre for alle moderne grafikkort, så lenge driverne er oppdatert. Vulkan har også en raskere sammenstilling av Shader (mindre hakkete) på alle GPU-leverandører.\n\nOpenGL kan oppnå bedre resultater for eldre Nvidia GPU-er, på eldre AMD GPU-er på Linux, eller på GPU-er med lavere VRAM, selv om skyggekompileringsutløser vil være større.\n\nSett til Vulkan hvis du er usikker. Sett til OpenGL hvis ikke GPU-en støtter Vulkan selv med de nyeste grafikkdriverne.",
"pl_PL": "",
"pt_BR": "Selecione o renderizador gráfico que será usado no emulador.\n\nO Vulkan é melhor no geral para todas as placas de vídeo modernas, desde que seus drivers estejam atualizados. O Vulkan também apresenta compilação de shader mais rápida (menos travamentos) em todos os fornecedores de GPU.\n\nO OpenGL pode obter melhores resultados em GPUs Nvidia antigas, em GPUs AMD antigas no Linux ou em GPUs com VRAM menor, embora os travamentos de compilação de shader sejam maiores.\n\nDefina como Vulkan se não tiver certeza. Defina como OpenGL se sua GPU não suportar Vulkan, mesmo com os drivers gráficos mais recentes.",
@@ -21470,26 +21145,26 @@
{
"ID": "SettingsTabGraphicsPreferredGpu",
"Translations": {
- "ar_SA": "وحدة معالجة الرسوميات المفضلة",
- "de_DE": "Bevorzugte GPU",
- "el_GR": "Προτιμώμενη GPU",
- "en_US": "Preferred GPU",
- "es_ES": "GPU Preferida",
- "fr_FR": "GPU Préféré",
- "he_IL": "כרטיס גראפי מועדף",
- "it_IT": "GPU preferita",
- "ja_JP": "優先使用するGPU",
- "ko_KR": "기본 GPU",
- "no_NO": "Foretrukket GPU",
- "pl_PL": "Preferowane GPU",
- "pt_BR": "GPU Preferida",
- "ru_RU": "Предпочтительный видеоадаптер",
- "sv_SE": "Föredragen GPU",
- "th_TH": "GPU ที่ต้องการ",
- "tr_TR": "Kullanılan GPU",
- "uk_UA": "Бажаний GPU",
+ "ar_SA": "وحدة معالجة الرسوميات المفضلة:",
+ "de_DE": "Bevorzugte GPU:",
+ "el_GR": "Προτιμώμενη GPU:",
+ "en_US": "Preferred GPU:",
+ "es_ES": "GPU preferida:",
+ "fr_FR": "GPU Préféré :",
+ "he_IL": "כרטיס גראפי מועדף:",
+ "it_IT": "GPU preferita:",
+ "ja_JP": "優先使用するGPU:",
+ "ko_KR": "기본 GPU :",
+ "no_NO": "Foretrukket GPU:",
+ "pl_PL": "Preferowane GPU:",
+ "pt_BR": "GPU Preferida:",
+ "ru_RU": "Предпочтительный видеоадаптер:",
+ "sv_SE": "Föredragen GPU:",
+ "th_TH": "GPU ที่ต้องการ:",
+ "tr_TR": "Kullanılan GPU:",
+ "uk_UA": "Бажаний GPU:",
"zh_CN": "首选 GPU:",
- "zh_TW": "優先選取的 GPU"
+ "zh_TW": "優先選取的 GPU:"
}
},
{
@@ -21777,7 +21452,7 @@
"es_ES": "Volumen",
"fr_FR": null,
"he_IL": "שמע",
- "it_IT": "",
+ "it_IT": "Volume",
"ja_JP": "音量",
"ko_KR": "음량",
"no_NO": "",
@@ -22227,7 +21902,7 @@
"es_ES": "Cercano",
"fr_FR": "Plus Proche",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Il più vicino",
"ja_JP": "",
"ko_KR": "근린",
"no_NO": "Nærmeste",
@@ -22277,7 +21952,7 @@
"es_ES": "Área",
"fr_FR": "Zone",
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "영역",
"no_NO": "Område",
@@ -22427,7 +22102,7 @@
"es_ES": null,
"fr_FR": null,
"he_IL": "SMAA אולטרה",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "SMAA 울트라",
"no_NO": "",
@@ -22499,13 +22174,13 @@
"de_DE": "Netzwerkschnittstelle:",
"el_GR": "Διεπαφή Δικτύου",
"en_US": "Network Interface:",
- "es_ES": "Interfaz de Red",
+ "es_ES": "Interfaz de Red:",
"fr_FR": "Interface Réseau :",
- "he_IL": "ממשק רשת",
+ "he_IL": "ממשק רשת:",
"it_IT": "Interfaccia di rete:",
"ja_JP": "ネットワークインタフェース:",
"ko_KR": "네트워크 인터페이스 :",
- "no_NO": "Nettverksgrensesnitt",
+ "no_NO": "Nettverksgrensesnitt:",
"pl_PL": "Interfejs sieci:",
"pt_BR": "Interface de Rede:",
"ru_RU": "Сетевой интерфейс:",
@@ -22602,7 +22277,7 @@
"es_ES": "Ver el Changelog",
"fr_FR": "Afficher les Changements",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Vedi Changelog",
"ja_JP": "",
"ko_KR": "변경 로그 보기",
"no_NO": "",
@@ -22712,7 +22387,7 @@
"sv_SE": "Ändra LDN-flerspelarläge\n\nLdnMitm kommer att ändra lokal funktionalitet för trådlös/lokalt spel att fungera som om det vore ett LAN, vilket ger stöd för anslutningar med local och same-network med andra Ryujinx-instanser och hackade Nintendo Switch-konsoller som har modulen ldn_mitm installerad.\n\nFlerspelare kräver att alla spelare har samma spelversion (t.ex. Super Smash Bros. Ultimate v13.0.1 kan inte ansluta till v13.0.0).\n\nLämna INAKTIVERAD om du är osäker.",
"th_TH": "เปลี่ยนโหมดผู้เล่นหลายคนของ LDN\n\nLdnMitm จะปรับเปลี่ยนฟังก์ชันการเล่นแบบไร้สาย/ภายใน จะให้เกมทำงานเหมือนกับว่าเป็น LAN ช่วยให้สามารถเชื่อมต่อภายในเครือข่ายเดียวกันกับอินสแตนซ์ Ryujinx อื่น ๆ และคอนโซล Nintendo Switch ที่ถูกแฮ็กซึ่งมีโมดูล ldn_mitm ติดตั้งอยู่\n\nผู้เล่นหลายคนต้องการให้ผู้เล่นทุกคนอยู่ในเกมเวอร์ชันเดียวกัน (เช่น Super Smash Bros. Ultimate v13.0.1 ไม่สามารถเชื่อมต่อกับ v13.0.0)\n\nปล่อยให้ปิดการใช้งานหากไม่แน่ใจ",
"tr_TR": "",
- "uk_UA": "Змінити LDN мультиплеєру.\n\nLdnMitm змінить функціонал бездротової/локальної гри в іграх, щоб вони працювали так, ніби це LAN, що дозволяє локальні підключення в тій самій мережі з іншими екземплярами Ryujinx та хакнутими консолями Nintendo Switch, які мають встановлений модуль ldn_mitm.\n\nМультиплеєр вимагає, щоб усі гравці були на одній і тій же версії гри (наприклад Super Smash Bros. Ultimate v13.0.1 не зможе під'єднатися до v13.0.0).\n\nЗалиште на \"Вимкнено\", якщо не впевнені, ",
+ "uk_UA": "Змінити LDN мультиплеєру.\n\nLdnMitm змінить функціонал бездротової/локальної гри в іграх, щоб вони працювали так, ніби це LAN, що дозволяє локальні підключення в тій самій мережі з іншими екземплярами Ryujinx та хакнутими консолями Nintendo Switch, які мають встановлений модуль ldn_mitm.\n\nМультиплеєр вимагає, щоб усі гравці були на одній і тій же версії гри (наприклад Super Smash Bros. Ultimate v13.0.1 не зможе під'єднатися до v13.0.0).\n\nЗалиште на \"Вимкнено\", якщо не впевнені.",
"zh_CN": "修改 LDN 多人联机游玩模式。\n\nldn_mitm 联机插件将修改游戏中的本地无线和本地游玩功能,使其表现得像局域网一样,允许和其他安装了 ldn_mitm 插件的 Ryujinx 模拟器和破解的任天堂 Switch 主机在同一网络下进行本地连接,实现多人联机游玩。\n\n多人联机游玩要求所有玩家必须运行相同的游戏版本(例如,游戏版本 v13.0.1 无法与 v13.0.0 联机)。\n\n如果不确定,请保持为“禁用”。",
"zh_TW": "變更 LDN 多人遊戲模式。\n\nLdnMitm 將修改遊戲中的本機無線/本機遊戲功能,使其如同區域網路一樣執行,允許與其他安裝了 ldn_mitm 模組的 Ryujinx 實例和已破解的 Nintendo Switch 遊戲機進行本機同網路連線。\n\n多人遊戲要求所有玩家使用相同的遊戲版本 (例如,Super Smash Bros. Ultimate v13.0.1 無法連接 v13.0.0)。\n\n如果不確定,請保持 Disabled (停用) 狀態。"
}
@@ -22802,7 +22477,7 @@
"es_ES": "Desactivar el Hosteo de Red P2P (puede aumentar latencia)",
"fr_FR": "Désactiver PàP Hébergement de Réseau (pourrait augmenter la latence)",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Disabilita l'hosting di rete P2P (potrebbe aumentare la latenza)",
"ja_JP": "",
"ko_KR": "P2P 네트워크 호스팅 비활성화(대기 시간이 늘어날 수 있음)",
"no_NO": "Deaktiver P2P-nettverkshosting (kan øke ventetiden)",
@@ -22827,7 +22502,7 @@
"es_ES": "Desactivar el hosteo de red P2P, pares se conectarán a través del servidor maestro en lugar de conectarse directamente contigo.",
"fr_FR": "Désactive PàP hébergement de réseau, les postes vont proxy avec le serveur principal au lieu de se connecter directement à vous.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Disabilita l'hosting di rete P2P, i peer passeranno attraverso il server principale invece di connettersi direttamente a te.",
"ja_JP": "",
"ko_KR": "P2P 네트워크 호스팅을 비활성화하면 피어가 직접 연결하지 않고 마스터 서버를 통해 프록시합니다.",
"no_NO": "Deaktiver P2P-nettverkshosting, så vil andre brukere gå via hovedserveren i stedet for å koble seg direkte til deg.",
@@ -22852,7 +22527,7 @@
"es_ES": "Frase de Contraseña de la Red:",
"fr_FR": "Mot de passe Réseau :",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Passphrase di rete:",
"ja_JP": "",
"ko_KR": "네트워크 암호 문구 :",
"no_NO": "Nettverkspassord:",
@@ -22877,7 +22552,7 @@
"es_ES": "Solo podrás ver los juegos hosteados con la misma frase de contraseña que tú.",
"fr_FR": "Vous pourez seulement voir les jeux hébergé avec le même mot de passe que vous.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Potrai vedere solo i giochi ospitati con la stessa passphrase che stai usando.",
"ja_JP": "",
"ko_KR": "귀하는 귀하와 동일한 암호를 사용하는 호스팅 게임만 볼 수 있습니다.",
"no_NO": "Du vil bare kunne se spill som er arrangert med samme passordfrase som deg.",
@@ -22902,7 +22577,7 @@
"es_ES": "Ingresar una frase de contraseña en formato Ryujinx-<8 caracteres hexadecimales>. Solamente podrás ver juegos hosteados con la misma frase de contraseña que tú.",
"fr_FR": "Entrer un mot de passe dans le format Ryujinx-<8 hex chars>. Vous pourez seulement voir les jeux hébergé avec le même mot de passe que vous.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Inserisci una passphrase nel formato Ryujinx-<8 caratteri esadecimali>. Potrai vedere solo i giochi ospitati con la stessa passphrase che stai usando.",
"ja_JP": "",
"ko_KR": "Ryujinx-<8 hex chars> 형식으로 암호를 입력하세요. 귀하는 귀하와 동일한 암호를 사용하는 호스팅 게임만 볼 수 있습니다.",
"no_NO": "Skriv inn en passordfrase i formatet Ryujinx-<8 heks tegn>. Du vil bare kunne se spill som er arrangert med samme passordfrase som deg.",
@@ -22927,7 +22602,7 @@
"es_ES": "(público)",
"fr_FR": "(publique)",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "(pubblico)",
"ja_JP": "",
"ko_KR": "(일반)",
"no_NO": "(offentlig)",
@@ -22952,7 +22627,7 @@
"es_ES": "Generar Aleatorio",
"fr_FR": "Générer Aléatoire",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Generatore Casuale",
"ja_JP": "",
"ko_KR": "무작위 생성",
"no_NO": "Generer tilfeldig",
@@ -22977,7 +22652,7 @@
"es_ES": "Genera una nueva frase de contraseña, que puede ser compartida con otros jugadores.",
"fr_FR": "Génére un nouveau mot de passe, qui peut être partagé avec les autres.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Genera una nuova passphrase, che può essere condivisa con altri giocatori.",
"ja_JP": "",
"ko_KR": "다른 플레이어와 공유할 수 있는 새로운 암호 문구를 생성합니다.",
"no_NO": "Genererer en ny passordfrase, som kan deles med andre spillere.",
@@ -23002,7 +22677,7 @@
"es_ES": "Borrar",
"fr_FR": "Supprimer",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Cancella",
"ja_JP": "",
"ko_KR": "지우기",
"no_NO": "Slett",
@@ -23027,7 +22702,7 @@
"es_ES": "Borra la frase de contraseña actual, regresando a la red pública.",
"fr_FR": "Supprime le mot de passe actuel, ce qui vous remet sur le réseau public.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Cancella la passphrase corrente, tornando alla rete pubblica.",
"ja_JP": "",
"ko_KR": "현재 암호를 지우고 공용 네트워크로 돌아갑니다.",
"no_NO": "Sletter den gjeldende passordfrasen og går tilbake til det offentlige nettverket.",
@@ -23052,7 +22727,7 @@
"es_ES": "Frase de Contraseña Inválida! Debe ser en formato \"Ryujinx-<8 caracteres hexadecimales>\"",
"fr_FR": "Mot de passe invalide ! Il doit être dans le format \"Ryujinx-<8 hex chars>\"",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Passphrase non valida! Deve essere nel formato \"Ryujinx-<8 caratteri esadecimali>\"",
"ja_JP": "",
"ko_KR": "유효하지 않은 암호입니다! \"Ryujinx-<8 hex chars>\" 형식이어야 합니다.",
"no_NO": "Ugyldig passordfrase! Må være i formatet \"Ryujinx-<8 hex tegn>\"",
@@ -23077,7 +22752,7 @@
"es_ES": null,
"fr_FR": "VSync :",
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "수직 동기화 :",
"no_NO": "",
@@ -23088,7 +22763,7 @@
"th_TH": "วีซิงค์:",
"tr_TR": "",
"uk_UA": "Вертикальна синхронізація (VSync):",
- "zh_CN": "垂直同步(VSync)",
+ "zh_CN": "垂直同步(VSync):",
"zh_TW": "垂直同步:"
}
},
@@ -23399,7 +23074,7 @@
"de_DE": "VSync-Modus umschalten:",
"el_GR": "",
"en_US": "Toggle VSync Mode:",
- "es_ES": "Alternar Modo VSync",
+ "es_ES": "Alternar modo VSync:",
"fr_FR": "Basculer le Mode VSync :",
"he_IL": "",
"it_IT": "Cambia modalità VSync:",
@@ -23423,23 +23098,23 @@
"ar_SA": "",
"de_DE": "Benutzerdefinierte Bildwiederholfrequenz erhöhen:",
"el_GR": "",
- "en_US": "Raise Custom Refresh Rate",
+ "en_US": "Raise Custom Refresh Rate:",
"es_ES": "Aumentar la Frecuencia de Actualización Personalizada",
"fr_FR": "Augmenter le Taux de Rafraîchissement Customisé :",
"he_IL": "",
"it_IT": "Aumenta la frequenza di aggiornamento personalizzata:",
"ja_JP": "",
- "ko_KR": "사용자 정의 주사율 증가",
- "no_NO": "Øk den egendefinerte oppdateringsfrekvensen",
+ "ko_KR": "사용자 정의 주사율 증가 :",
+ "no_NO": "Øk den egendefinerte oppdateringsfrekvensen:",
"pl_PL": "",
"pt_BR": "Aumentar Taxa de Atualização:",
"ru_RU": "Увеличить пользовательскую частоту кадров:",
"sv_SE": "Höj anpassad uppdateringsfrekvens",
"th_TH": "เพิ่มอัตรารีเฟรชแบบกำหนดเอง",
"tr_TR": "",
- "uk_UA": "Підвищити користувацьку частоту оновлення",
+ "uk_UA": "Підвищити користувацьку частоту оновлення:",
"zh_CN": "提高自定义刷新率:",
- "zh_TW": "提高自訂的重新整理頻率"
+ "zh_TW": "提高自訂的重新整理頻率:"
}
},
{
@@ -23454,17 +23129,17 @@
"he_IL": "",
"it_IT": "Riduci la frequenza di aggiornamento personalizzata:",
"ja_JP": "",
- "ko_KR": "사용자 정의 주사율 감소",
- "no_NO": "Lavere tilpasset oppdateringsfrekvens",
+ "ko_KR": "사용자 정의 주사율 감소 :",
+ "no_NO": "Lavere tilpasset oppdateringsfrekvens:",
"pl_PL": "",
"pt_BR": "Reduzir Taxa de Atualização:",
"ru_RU": "Уменьшить пользовательскую частоту кадров:",
"sv_SE": "Sänk anpassad uppdateringsfrekvens",
"th_TH": "ลดอัตรารีเฟรชแบบกำหนดเอง:",
"tr_TR": "",
- "uk_UA": "Понизити користувацьку частоту оновлення",
+ "uk_UA": "Понизити користувацьку частоту оновлення:",
"zh_CN": "降低自定义刷新率:",
- "zh_TW": "降低自訂的重新整理頻率"
+ "zh_TW": "降低自訂的重新整理頻率:"
}
},
{
@@ -23477,7 +23152,7 @@
"es_ES": "Modo Turbo:",
"fr_FR": "Mode Turbo :",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Modalità Turbo:",
"ja_JP": "",
"ko_KR": "터보 모드 :",
"no_NO": "",
@@ -23502,7 +23177,7 @@
"es_ES": "La tecla de acceso rápido del modo Turbo.\nConfigura el comportamiento del modo Turbo en los ajustes de CPU de Ryujinx.\n\nDejar sin asignar si no está seguro.",
"fr_FR": "Le raccourci clavier Mode Turbo.\nConfigurez le comportement du Mode Turbo dans les paramètres de CPU de Ryujinx.\n\nLaisser Non Attribué si incertain.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Il tasto rapido della Modalità Turbo.\nConfigura il comportamento della Modalità Turbo nelle impostazioni CPU di Ryujinx.\n\nLascia Non assegnato se non sei sicuro.",
"ja_JP": "",
"ko_KR": "터보 모드 단축키입니다.\nRyujinx CPU 설정에서 터보 모드의 동작을 구성합니다.\n\n모르면 바인딩 해제 상태로 두세요.",
"no_NO": "Hurtigtasten for turbo-modus.\nKonfigurer oppførselen til turbo-modus i Ryujinx CPU-innstillinger.\n\nLa være ubundet hvis du er usikker.",
@@ -23527,7 +23202,7 @@
"es_ES": "Solo Mientras se Mantiene Pulsado",
"fr_FR": "Seulement Quand le Raccourci est Maintenu",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Solo mentre è premuto",
"ja_JP": "",
"ko_KR": "누르고 있는 동안만",
"no_NO": "Bare mens du trykker på",
@@ -23552,7 +23227,7 @@
"es_ES": "Última Actualización: {0}",
"fr_FR": "Dernière Mise à Jour : {0}",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Ultimo aggiornamento: {0}",
"ja_JP": "",
"ko_KR": "최종 업데이트 : {0}",
"no_NO": "Sist oppdatert: {0}",
@@ -23577,7 +23252,7 @@
"es_ES": "Lista de Compatibilidad - {0} entradas",
"fr_FR": "Liste de Compatibilité – {0} entrées",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Lista di compatibilità - {0} voci",
"ja_JP": "",
"ko_KR": "호환성 목록 - {0}개 항목",
"no_NO": "Kompatibilitetsliste - {0} oppføringer",
@@ -23602,7 +23277,7 @@
"es_ES": "Esta lista de compatibilidad podría contener entradas desactualizadas.\nNo dudes en probar los juegos en estado \"En el juego\".",
"fr_FR": "Cette liste de compatibilité peut contenir des entrées obsolètes.N’hésitez pas à tester les jeux dont le statut est « En cours ».",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Questa lista di compatibilità potrebbe contenere voci obsolete.\nNon esitare a testare i giochi con lo stato \"Ingame\".",
"ja_JP": "",
"ko_KR": "이 호환성 목록에는 오래된 항목이 포함되어 있을 수 있습니다.\n\"게임 내\" 상태에서 게임을 테스트하는 것을 반대하지 마십시오.",
"no_NO": "Denne kompatibilitetslisten kan inneholde oppføringer som er tomme for data.\nVær ikke imot å teste spill i statusen «Ingame».",
@@ -23627,7 +23302,7 @@
"es_ES": "Buscar entradas de compatibilidad…",
"fr_FR": "Rechercher les entrées de compatibilité...",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Cerca voci di compatibilità...",
"ja_JP": "",
"ko_KR": "호환성 항목 검색...",
"no_NO": "Søk i kompatibilitetsoppføringer...",
@@ -23652,7 +23327,7 @@
"es_ES": "Buscar {0} entradas de compatibilidad…",
"fr_FR": "Rechercher {0} entrées de compatibilité...",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Cerca {0} voci di compatibilità...",
"ja_JP": "",
"ko_KR": "어카이브 {0} 호환성 항목...",
"no_NO": "Søk i {0} kompatibilitetsoppføringer...",
@@ -23777,7 +23452,7 @@
"es_ES": null,
"fr_FR": null,
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Statistiche",
"ja_JP": "",
"ko_KR": "상태",
"no_NO": "",
@@ -23802,7 +23477,7 @@
"es_ES": "Solo mostrar juegos que posees",
"fr_FR": "Afficher uniquement les jeux possédés",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Mostra solo i giochi posseduti",
"ja_JP": "",
"ko_KR": "보유 게임만 표시",
"no_NO": "Vis bare eide spill",
@@ -23827,7 +23502,7 @@
"es_ES": "Jugable",
"fr_FR": "Jouable",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Giocabile",
"ja_JP": "",
"ko_KR": "원활",
"no_NO": "Spillbar",
@@ -23852,7 +23527,7 @@
"es_ES": "En el Juego",
"fr_FR": "En Jeu",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "In gioco",
"ja_JP": "",
"ko_KR": "가능",
"no_NO": "",
@@ -23877,7 +23552,7 @@
"es_ES": "Menu",
"fr_FR": "Menu",
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": "메뉴",
"no_NO": "Menyer",
@@ -23902,7 +23577,7 @@
"es_ES": "Inicia",
"fr_FR": "Démarre",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Avvia",
"ja_JP": "",
"ko_KR": "부팅",
"no_NO": "Starter",
@@ -23927,7 +23602,7 @@
"es_ES": "Nada",
"fr_FR": "Rien",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Niente",
"ja_JP": "",
"ko_KR": "불가",
"no_NO": "Ingenting",
@@ -23952,7 +23627,7 @@
"es_ES": "Se inicia y funciona sin ningún fallo ni error de GPU, y a una velocidad lo suficientemente rápida como para disfrutarlo razonablemente en un PC promedio",
"fr_FR": "Démarre et fonctionne aucun crash ou bugs graphiques, et à une vitesse raisonable pour pouvoir en profiter sur un PC ordinaire.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Si avvia e funziona senza crash o bug della GPU di alcun tipo, e a una velocità sufficientemente alta da poter essere goduto su un PC medio.",
"ja_JP": "",
"ko_KR": "어떠한 충돌이나 GPU 버그 없이 부팅 및 플레이가 가능하며, 일반 PC에서 충분히 즐길 수 있을 만큼 쾌적한 속도입니다.",
"no_NO": "Starter opp og spiller uten krasj eller GPU-feil av noe slag, og med en hastighet som er rask nok til å ha rimelig glede av på en gjennomsnittlig PC.",
@@ -23977,7 +23652,7 @@
"es_ES": "Se inicia y llega al juego, pero presenta uno o más de los siguientes problemas: cierres inesperados, bloqueos, errores de GPU, audio molesto o deficiente, o simplemente es demasiado lento. El juego aún podría jugarse hasta el final, pero no como fue pensado originalmente.",
"fr_FR": "Démarre et va en jeux mais souffre d'un ou plusieurs des éléments suivants: crashs, bloacages, bugs graphiques, problèmes audios, ou est trop lent. Le jeu peut toujours être joué jusqu'au bout, mais pas dans des conditions prévues.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Si avvia e entra nel gioco, ma presenta uno o più dei seguenti problemi: crash, blocchi, bug della GPU, audio fastidiosamente scadente, oppure è semplicemente troppo lento. Il gioco potrebbe comunque essere completabile, ma non come previsto.",
"ja_JP": "",
"ko_KR": "부팅하고 게임에 진입하지만 충돌, 교착, GPU 버그, 오디오에 문제가 있거나 버벅임 중 하나 이상으로 인해 문제가 발생합니다. 게임은 어쨌든 진행할 수 있습니다.",
"no_NO": "Starter og går i gang i spillet, men lider av ett eller flere av følgende: krasjer, fastlåser, GPU-feil, distraherende dårlig lyd eller er rett og slett for tregt. Spillet kan fortsatt spilles helt til ende, men ikke slik det er ment å spilles.",
@@ -24002,7 +23677,7 @@
"es_ES": "Se inicia y pasa de la pantalla de título, pero no llega al juego principal.",
"fr_FR": "Démarre et dépasse l'écran titre, mais n'arrive pas au gameplay principal.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Si avvia e supera la schermata del titolo, ma non entra nel gameplay principale.",
"ja_JP": "",
"ko_KR": "부팅하고 타이틀 화면이 나오지만 메인 게임 플레이로 진입할 수 없습니다.",
"no_NO": "Starter opp og går forbi tittelskjermen, men kommer ikke inn i hovedspillet.",
@@ -24027,7 +23702,7 @@
"es_ES": "Se inicia, pero no pasa de la pantalla de título.",
"fr_FR": "Démarre mais ne dépasse pas l'écran titre.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Si avvia ma non supera la schermata del titolo.",
"ja_JP": "",
"ko_KR": "부팅되지만 타이틀 화면을 통과하지 못합니다.",
"no_NO": "Starter, men kommer ikke lenger enn til tittelskjermen.",
@@ -24052,7 +23727,7 @@
"es_ES": "No se inicia o no muestra ningún signo de actividad.",
"fr_FR": "Ne démarre pas ou ne montre aucun signe d'activité.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Non si avvia o non mostra alcun segno di attività.",
"ja_JP": "",
"ko_KR": "부팅되지 않거나 동작하지 않습니다.",
"no_NO": "Starter ikke opp eller viser ingen tegn til aktivitet.",
@@ -24070,26 +23745,26 @@
{
"ID": "GameSpecificConfigurationHeader",
"Translations": {
- "ar_SA": "",
- "de_DE": "",
- "el_GR": "",
+ "ar_SA": "التكوين المخصص",
+ "de_DE": "Benutzerdefinierte Konfiguration",
+ "el_GR": "Προσαρμοσμένη ρύθμιση",
"en_US": "Custom Config",
"es_ES": "Configuración Personalizada",
"fr_FR": "Configuration Personnalisée",
- "he_IL": "",
- "it_IT": "",
- "ja_JP": "",
+ "he_IL": "הגדרה מותאמת",
+ "it_IT": "Configurazione personalizzata",
+ "ja_JP": "カスタム設定",
"ko_KR": "사용자 정의 설정",
"no_NO": "Tilpasset konfigurasjon",
- "pl_PL": "",
+ "pl_PL": "Konfiguracja niestandardowa",
"pt_BR": "Configurações Customizadas",
"ru_RU": "Индивидуальная конфигурация",
"sv_SE": "Anpassad konfiguration",
"th_TH": "การตั้งค่าแบบกำหนดเอง",
- "tr_TR": "",
+ "tr_TR": "Özel Konfigürasyon",
"uk_UA": "Власна конфігурація",
"zh_CN": "自定义配置",
- "zh_TW": "遊戲獨立自訂 (game-specific) 設定"
+ "zh_TW": "自訂配置"
}
},
{
@@ -24102,7 +23777,7 @@
"es_ES": null,
"fr_FR": null,
"he_IL": "",
- "it_IT": "",
+ "it_IT": "(Globale)",
"ja_JP": "",
"ko_KR": "(글로벌)",
"no_NO": "",
@@ -24127,7 +23802,7 @@
"es_ES": "Selecciona un DLC para extraer",
"fr_FR": "Choisissez un DLC à Extraire",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Seleziona un DLC da estrarre",
"ja_JP": "",
"ko_KR": "추출할 DLC 선택",
"no_NO": "Velg en DLC og hente ut",
@@ -24152,7 +23827,7 @@
"es_ES": "Imagen Rich Presence",
"fr_FR": "Image Rich Presence",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Immagine Rich Presence",
"ja_JP": "",
"ko_KR": "리치 프레즌스 이미지",
"no_NO": "Rikt nærværsbilde",
@@ -24177,7 +23852,7 @@
"es_ES": "Rich Presence Dinámico",
"fr_FR": "Rich Presence Dynamique",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Rich Presence dinamico",
"ja_JP": "",
"ko_KR": "다이내믹 리치 프레즌스",
"no_NO": "Dynamisk og rik tilstedeværelse",
@@ -24252,7 +23927,7 @@
"es_ES": "ADVERTENCIA: Solo para uso de desarrolladores, reducirá el rendimiento",
"fr_FR": "ATTENTION: Uniquement pour les développeurs, réduit la performance",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "ATTENZIONE: Solo per uso degli sviluppatori, ridurrà le prestazioni",
"ja_JP": "",
"ko_KR": "경고 : 개발자 전용으로, 성능이 저하될 수 있습니다.",
"no_NO": "",
@@ -24277,7 +23952,7 @@
"es_ES": "Activar Stub GDB",
"fr_FR": "Activer GDB Stub",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Abilita GDB Stub",
"ja_JP": "",
"ko_KR": "GDB Stub 활성화",
"no_NO": "",
@@ -24302,7 +23977,7 @@
"es_ES": "Activa el stub GDB, lo que permite depurar la aplicación en ejecución. ¡Solo para uso de desarrollo!",
"fr_FR": "Active le GDB stub, ce qui rend le débogage de l'application possible. Pour les développeurs uniquement !",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Abilita il GDB stub, rendendo possibile il debug dell'applicazione in esecuzione. Solo per uso di sviluppo!",
"ja_JP": "",
"ko_KR": "GDB Stub을 활성화하여 실행 중인 응용 프로그램을 디버그할 수 있도록 합니다. 개발 용도로만 사용하십시오!",
"no_NO": "",
@@ -24327,7 +24002,7 @@
"es_ES": "Puerto del Stub GDB:",
"fr_FR": "Port du GDB Stub :",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Porta GDB Stub:",
"ja_JP": "",
"ko_KR": "GDB Stub 포트 :",
"no_NO": "",
@@ -24352,7 +24027,7 @@
"es_ES": "Suspender la Aplicación al Iniciar",
"fr_FR": "Mettre en Pause l'Application au Démarrage",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Sospendi l'applicazione all'avvio",
"ja_JP": "",
"ko_KR": "시작 시, 앱 일시 중지",
"no_NO": "",
@@ -24377,7 +24052,7 @@
"es_ES": "Suspende la aplicación antes de ejecutar la primera instrucción, permitiendo depurar desde el punto más temprano.",
"fr_FR": "Met en pause l'application avant d'éxécuter la première instruction, permet de déboger au plus tôt que possible.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Sospende l'applicazione prima di eseguire la prima istruzione, permettendo il debug dal punto più iniziale.",
"ja_JP": "",
"ko_KR": "1번째 명령어를 실행하기 전에 앱앱을 일시 중지하여 가장 초기의 단계에서 디버깅을 가능하게 합니다.",
"no_NO": "",
@@ -24398,23 +24073,23 @@
"ar_SA": "",
"de_DE": "",
"el_GR": "",
- "en_US": "Open LDN Game List",
- "es_ES": "Abrir la Lista de Juegos LDN",
- "fr_FR": "Ouvrir la Liste de Jeux LDN",
+ "en_US": "LDN Game List",
+ "es_ES": "Lista de Juegos LDN",
+ "fr_FR": "Liste des Jeux LDN",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Apri lista giochi LDN",
"ja_JP": "",
"ko_KR": "LDN 게임 목록 열기",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
- "ru_RU": "Открыть список игр LDN",
+ "ru_RU": "Cписок LDN игр",
"sv_SE": "",
"th_TH": "เปิดรายชื่อเกม LDN",
"tr_TR": "",
- "uk_UA": "",
- "zh_CN": "打开 LDN 游戏列表",
- "zh_TW": "開啟 LDN 遊戲瀏覽器"
+ "uk_UA": "Список LDN ігор",
+ "zh_CN": "LDN 游戏列表",
+ "zh_TW": "LDN 遊戲列表"
}
},
{
@@ -24427,7 +24102,7 @@
"es_ES": "Navegador de Juegos LDN - {0} juegos",
"fr_FR": "Navigateur de Jeux LDN - {0} Parties",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Browser giochi LDN - {0} giochi",
"ja_JP": "",
"ko_KR": "LDN 게임 브라우저 - {0}게임",
"no_NO": "",
@@ -24452,7 +24127,7 @@
"es_ES": "Buscar {0} Juegos LDN...",
"fr_FR": "Rechercher {0} Jeux LDN...",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Cerca {0} giochi LDN...",
"ja_JP": "",
"ko_KR": "{0} LDN 게임 검색...",
"no_NO": "",
@@ -24477,7 +24152,7 @@
"es_ES": "¿Qué es LDN?",
"fr_FR": "Qu'est-ce que LDN ?",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Cos'è LDN?",
"ja_JP": "",
"ko_KR": "LDN이 뭔가요?",
"no_NO": "",
@@ -24498,23 +24173,23 @@
"ar_SA": "",
"de_DE": "",
"el_GR": "",
- "en_US": "Refresh available games from the server at {0}",
- "es_ES": "Actualizar los juegos disponibles del servidor a las {0}",
- "fr_FR": "Rafraîchir les parties disponibles depuis le serveur à {0}",
+ "en_US": "Refresh available games from the server at {0}.",
+ "es_ES": "Actualizar los juegos disponibles del servidor a las {0}.",
+ "fr_FR": "Rafraîchir les parties disponibles depuis le serveur à {0}.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Aggiorna i giochi disponibili dal server su {0}",
"ja_JP": "",
- "ko_KR": "{0} 서버에서 사용 가능한 게임을 새로 고침",
+ "ko_KR": "{0} 서버에서 사용 가능한 게임을 새로 고침.",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
- "ru_RU": "Обновить доступные игры с сервера по адресу {0}",
+ "ru_RU": "Обновить доступные игры с сервера по адресу {0}.",
"sv_SE": "",
"th_TH": "รีเฟรชเกมที่มีอยู่จากเซิร์ฟเวอร์ที่ {0}",
"tr_TR": "",
"uk_UA": "",
- "zh_CN": "在 {0} 时从服务器刷新可用游戏",
- "zh_TW": "從 {0} 伺服器重新整理有效的遊戲"
+ "zh_CN": "在 {0} 时从服务器刷新可用游戏。",
+ "zh_TW": "從 {0} 伺服器重新整理有效的遊戲。"
}
},
{
@@ -24527,7 +24202,7 @@
"es_ES": "Contador de jugadores - Desactivar",
"fr_FR": "Nombre de joueurs - Désactiver",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Conteggio giocatori - Disabilita",
"ja_JP": "",
"ko_KR": "플레이어 수 - 비활성화",
"no_NO": "",
@@ -24552,7 +24227,7 @@
"es_ES": "Contador de jugadores - Ascendente",
"fr_FR": "Nombre de joueurs - Croissant",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Conteggio giocatori - Ascendente",
"ja_JP": "",
"ko_KR": "플레이어 수 - 오름차순",
"no_NO": "",
@@ -24577,7 +24252,7 @@
"es_ES": "Contador de jugadores - Descendente",
"fr_FR": "Nombre de joueurs - Décroissant",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Conteggio giocatori - Discendente",
"ja_JP": "",
"ko_KR": "플레이어 수 - 내림차순",
"no_NO": "",
@@ -24602,7 +24277,7 @@
"es_ES": "Filtros",
"fr_FR": "Filtres",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Filtri",
"ja_JP": "",
"ko_KR": "필터",
"no_NO": "",
@@ -24627,7 +24302,7 @@
"es_ES": "Solo mostrar juegos públicos",
"fr_FR": "Afficher uniquement les parties publiques",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Mostra solo i giochi pubblici",
"ja_JP": "",
"ko_KR": "공개 게임만 표시",
"no_NO": "",
@@ -24652,7 +24327,7 @@
"es_ES": "Solo mostrar juegos a los que se puede unir",
"fr_FR": "Afficher uniquement les parties auxquelles on peut se joindre",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Mostra solo i giochi a cui è possibile partecipare",
"ja_JP": "",
"ko_KR": "참여 가능한 게임만 표시",
"no_NO": "",
@@ -24677,7 +24352,7 @@
"es_ES": "Proxy del Servidor Maestro",
"fr_FR": "Proxy du Serveur Maître",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Proxy del server principale",
"ja_JP": "",
"ko_KR": "마스터 서버 프록시",
"no_NO": "",
@@ -24702,7 +24377,7 @@
"es_ES": null,
"fr_FR": null,
"he_IL": "",
- "it_IT": "",
+ "it_IT": null,
"ja_JP": "",
"ko_KR": null,
"no_NO": "",
@@ -24727,7 +24402,7 @@
"es_ES": "Conexión a través del servidor RyuLDN (más lento).",
"fr_FR": "Connection via le serveur RyuLDN (plus lent).",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Si connette tramite il server RyuLDN (più lento).",
"ja_JP": "",
"ko_KR": "RyuLDN 서버를 통해 연결합니다.(느림)",
"no_NO": "",
@@ -24752,7 +24427,7 @@
"es_ES": "Conexión Peer-to-Peer a través de UPnP (más rápido).",
"fr_FR": "Se connecte en Peer-to-Peer via UPnP (plus rapide).",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Si connette tramite Peer-to-Peer via UPnP (più veloce).",
"ja_JP": "",
"ko_KR": "UPnP를 통한 P2P 방식으로 연결합니다.(빠름)",
"no_NO": "",
@@ -24777,7 +24452,7 @@
"es_ES": "Creado: {0}",
"fr_FR": "Créé : {0}",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Creati: {0}",
"ja_JP": "",
"ko_KR": "생성일 : {0}",
"no_NO": "",
@@ -24802,7 +24477,7 @@
"es_ES": "Jugadores ({0} de {1}):",
"fr_FR": "Joueurs ({0} sur {1}) :",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Giocatori ({0} su {1}):",
"ja_JP": "",
"ko_KR": "플레이어({1}명 중 {0}명) :",
"no_NO": "",
@@ -24827,7 +24502,7 @@
"es_ES": "Unible",
"fr_FR": "Rejoignable",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Partecipabile",
"ja_JP": "",
"ko_KR": "참여 가능",
"no_NO": "",
@@ -24852,7 +24527,7 @@
"es_ES": "El juego es unible si es público o si conoces la frase de contraseña.",
"fr_FR": "La partie est joignable si elle est publique ou si vous connaissez le mot de passe.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Un gioco è partecipabile se è pubblico o se conosci la passphrase.",
"ja_JP": "",
"ko_KR": "게임이 공개되어 있거나 비밀번호를 알고 있는 경우 게임에 참여할 수 있습니다.",
"no_NO": "",
@@ -24877,7 +24552,7 @@
"es_ES": "No se puede unir",
"fr_FR": "Non Rejoignable",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Non partecipabile",
"ja_JP": "",
"ko_KR": "가입 불가",
"no_NO": "",
@@ -24902,7 +24577,7 @@
"es_ES": "El juego está en curso.",
"fr_FR": "En cours de partie.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Il gioco è attualmente in corso.",
"ja_JP": "",
"ko_KR": "현재 게임이 진행 중입니다.",
"no_NO": "",
@@ -24927,7 +24602,7 @@
"es_ES": "Público",
"fr_FR": "Publique",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Pubblico",
"ja_JP": "",
"ko_KR": "공개",
"no_NO": "",
@@ -24952,7 +24627,7 @@
"es_ES": "Cualquiera puede unirse a este juego.",
"fr_FR": "N'importe qui peut rejoindre cette partie.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Chiunque può partecipare a questo gioco.",
"ja_JP": "",
"ko_KR": "누구나 이 게임에 참여할 수 있습니다.",
"no_NO": "",
@@ -24977,7 +24652,7 @@
"es_ES": "Privado",
"fr_FR": "Privé",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Privato",
"ja_JP": "",
"ko_KR": "비공개",
"no_NO": "",
@@ -25002,7 +24677,7 @@
"es_ES": "Solo puedes unirte a este juego si también tienes la misma frase de contraseña LDN en tus ajustes.",
"fr_FR": "Vous pouvez seulement rejoindre cette partie si vous avez le même mot de passe LDN dans vos paramètres.",
"he_IL": "",
- "it_IT": "",
+ "it_IT": "Puoi partecipare a questo gioco solo se hai la stessa passphrase LDN nelle tue impostazioni.",
"ja_JP": "",
"ko_KR": "설정에 동일한 LDN 암호가 있는 경우에만 이 게임에 참여할 수 있습니다.",
"no_NO": "",
diff --git a/docs/compatibility.csv b/docs/compatibility.csv
index 21baad773..a75a50f42 100644
--- a/docs/compatibility.csv
+++ b/docs/compatibility.csv
@@ -1175,6 +1175,7 @@
0100EB100AB42000,"FINAL FANTASY XII THE ZODIAC AGE",opengl;vulkan-backend-bug,playable,2024-08-11 07:01:54
010068F00AA78000,"FINAL FANTASY XV POCKET EDITION HD",,playable,2021-01-05 17:52:08
0100CE4010AAC000,"FINAL FANTASY® CRYSTAL CHRONICLES™ Remastered Edition",,playable,2023-04-02 23:39:12
+010038B015560000,FINAL FANTASY TACTICS - The Ivalice Chronicles,gpu,boots,2024-09-30 02:59:00
01001BA00AE4E000,"Final Light, The Prison",,playable,2020-07-31 21:48:44
0100FF100FB68000,"Finding Teddy 2 : Definitive Edition",gpu,ingame,2024-04-19 16:51:33
0100F4E013AAE000,"Fire & Water",,playable,2020-12-15 15:43:20
@@ -2271,6 +2272,7 @@
0100ABF008968000,"Pokémon Sword + Pokémon Sword Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-26 15:40:37
01009AD008C4C000,"Pokémon: Let's Go, Pikachu! demo",slow;demo,playable,2023-11-26 11:23:20
0100000011D90000,"Pokémon™ Brilliant Diamond",gpu;ldn-works,ingame,2024-08-28 13:26:35
+010018E011D92000,"Pokémon™ Shining Pearl",gpu;ldn-works,ingame,2024-08-28 13:26:35
010015F008C54000,"Pokémon™ HOME",Needs Update;crash;services,menus,2020-12-06 06:01:51
01001F5010DFA000,"Pokémon™ Legends: Arceus",gpu;Needs Update;ldn-works,ingame,2024-09-19 10:02:02
01005D100807A000,"Pokémon™ Quest",,playable,2022-02-22 16:12:32
@@ -2707,6 +2709,8 @@
01008F701C074000,"SONIC SUPERSTARS",gpu;nvdec,ingame,2023-10-28 17:48:07
010088801C150000,"Sonic Superstars Digital Art Book with Mini Digital Soundtrack",,playable,2024-08-20 13:26:56
01005EA01C0FC000,"SONIC X SHADOW GENERATIONS",crash,ingame,2025-01-07 04:20:45
+010064B0242BE000,"Sonic Racing: CrossWorlds - Demo",gpu;vulkan-backend-bug;demo,ingame,2024-09-25 11:27:53
+01006E001823C000,"Sonic Racing: CrossWorlds",gpu;vulkan-backend-bug;ldn-broken,ingame,2024-09-30 17:23:00
010064F00C212000,"Soul Axiom Rebooted",nvdec;slow,ingame,2020-09-04 12:41:01
0100F2100F0B2000,"Soul Searching",,playable,2020-07-09 18:39:07
01008F2005154000,"South Park™: The Fractured but Whole™ - Standard Edition",slow;online-broken;vulkan-backend-bug;gpu,ingame,2025-01-21 17:35:10
@@ -2864,11 +2868,13 @@
0100BC0018138000,"Super Mario RPG™",gpu;audio;nvdec,ingame,2024-06-19 17:43:42
,"Super Mario World",homebrew,boots,2024-06-13 01:40:31
010049900F546000,"Super Mario™ 3D All-Stars",services-horizon;slow;vulkan;amd-vendor-bug,ingame,2024-05-07 02:38:16
+010099C022B96000,"Super Mario Galaxy",slow;vulkan;amd-vendor-bug;vulkan-vendor-bug,ingame,2025-10-01 15:30:00
+0100FD8022DAA000,"Super Mario Galaxy 2",slow;vulkan;amd-vendor-bug;vulkan-vendor-bug;deadlock,ingame,2025-10-04 18:50:00
010028600EBDA000,"Super Mario™ 3D World + Bowser’s Fury",ldn-works,playable,2024-07-31 10:45:37
01004F8006A78000,"Super Meat Boy",services,playable,2020-04-02 23:10:07
01009C200D60E000,"Super Meat Boy Forever",gpu,boots,2021-04-26 14:25:39
0100BDD00EC5C000,"Super Mega Space Blaster Special Turbo",online,playable,2020-08-06 12:13:25
-010031F019294000,"Super Monkey Ball Banana Rumble",,playable,2024-06-28 10:39:18
+010031F019294000,"Super Monkey Ball Banana Rumble",ldn-broken,playable,2025-10-01 18:03:00
0100B2A00E1E0000,"Super Monkey Ball: Banana Blitz HD",online-broken,playable,2022-09-16 13:16:25
01006D000D2A0000,"Super Mutant Alien Assault",,playable,2020-06-07 23:32:45
01004D600AC14000,"Super Neptunia RPG",nvdec,playable,2022-08-17 16:38:52
@@ -2934,6 +2940,7 @@
0100B76011DAA000,"Taxi Chaos",slow;online-broken;UE4,playable,2022-10-25 19:13:00
0100F43011E5A000,"Tcheco in the Castle of Lucio",,playable,2020-06-27 13:35:43
010092B0091D0000,"Team Sonic Racing",online-broken;ldn-works,playable,2024-02-05 15:05:27
+010084B00B36E000,"Team Sonic Racing",online-broken;ldn-works,playable,2024-02-05 15:05:27
0100FE701475A000,"Teenage Mutant Ninja Turtles: Shredder's Revenge",deadlock;crash,boots,2024-09-28 09:31:39
01005CF01E784000,"Teenage Mutant Ninja Turtles: Splintered Fate",,playable,2024-08-03 13:50:42
0100FDB0154E4000,"Teenage Mutant Ninja Turtles: The Cowabunga Collection",,playable,2024-01-22 19:39:04
@@ -3220,6 +3227,7 @@
010038400C2FE000,"TY the Tasmanian Tiger™ HD",32-bit;crash;nvdec,menus,2020-12-17 21:15:00
010073A00C4B2000,"Tyd wag vir Niemand",,playable,2021-03-02 13:39:53
0100D5B00D6DA000,"Type:Rider",,playable,2021-01-06 13:12:55
+01008AF01AD22000,"The Patrick Star Game",,playable,2025-10-01 17:55:30
010040D01222C000,"UBERMOSH: SANTICIDE",,playable,2020-11-27 15:05:01
0100992010BF8000,"Ubongo",,playable,2021-02-04 21:15:01
010079000B56C000,"UglyDolls: An Imperfect Adventure",nvdec;UE4,playable,2022-08-25 14:42:16
@@ -3466,3 +3474,6 @@
0100F4401940A000,"超探偵事件簿 レインコード (Master Detective Archives: Rain Code)",crash,ingame,2024-02-12 20:58:31
010064801A01C000,"超次元ゲイム ネプテューヌ GameMaker R:Evolution",crash,nothing,2023-10-30 22:37:40
0100F3400332C000,"ゼノブレイド2",deadlock;amd-vendor-bug,ingame,2024-03-28 14:31:41
+010075000ECBE000,"超级马力欧 奥德赛",nvdec;intel-vendor-bug;mac-bug,playable,2024-08-25 01:32:34
+010075100E8EC000,"马力欧卡丁车8 豪华版",32-bit;ldn-works;LAN;amd-vendor-bug,playable,2024-09-19 11:55:17
+0100E8C00F506000,"新 超级马力欧兄弟U 豪华版",32-bit,playable,2023-10-08 02:06:37
diff --git a/src/Ryujinx.Audio/Renderer/Common/BehaviourParameter.cs b/src/Ryujinx.Audio/Renderer/Common/BehaviourParameter.cs
index 3b8d15dc5..5b4f39e23 100644
--- a/src/Ryujinx.Audio/Renderer/Common/BehaviourParameter.cs
+++ b/src/Ryujinx.Audio/Renderer/Common/BehaviourParameter.cs
@@ -1,9 +1,11 @@
+using Ryujinx.Audio.Renderer.Server;
+using Ryujinx.Audio.Renderer.Server.MemoryPool;
using System.Runtime.InteropServices;
namespace Ryujinx.Audio.Renderer.Common
{
///
- /// Represents the input parameter for .
+ /// Represents the input parameter for .
///
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BehaviourParameter
@@ -21,7 +23,7 @@ namespace Ryujinx.Audio.Renderer.Common
///
/// The flags given controlling behaviour of the audio renderer
///
- /// See and .
+ /// See and .
public ulong Flags;
///
@@ -43,7 +45,7 @@ namespace Ryujinx.Audio.Renderer.Common
///
/// Extra information given with the
///
- /// This is usually used to report a faulting cpu address when a mapping fail.
+ /// This is usually used to report a faulting cpu address when a mapping fail.
public ulong ExtraErrorInfo;
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Common/VoiceUpdateState.cs b/src/Ryujinx.Audio/Renderer/Common/VoiceState.cs
similarity index 95%
rename from src/Ryujinx.Audio/Renderer/Common/VoiceUpdateState.cs
rename to src/Ryujinx.Audio/Renderer/Common/VoiceState.cs
index 7f881373f..508daa6e2 100644
--- a/src/Ryujinx.Audio/Renderer/Common/VoiceUpdateState.cs
+++ b/src/Ryujinx.Audio/Renderer/Common/VoiceState.cs
@@ -1,4 +1,5 @@
using Ryujinx.Audio.Renderer.Dsp.State;
+using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Common.Memory;
using Ryujinx.Common.Utilities;
using System;
@@ -11,7 +12,7 @@ namespace Ryujinx.Audio.Renderer.Common
///
/// This is shared between the server and audio processor.
[StructLayout(LayoutKind.Sequential, Pack = Align)]
- public struct VoiceUpdateState
+ public struct VoiceState
{
public const int Align = 0x10;
public const int BiquadStateOffset = 0x0;
@@ -25,7 +26,7 @@ namespace Ryujinx.Audio.Renderer.Common
/// The total amount of samples that was played.
///
/// This is reset to 0 when a finishes playing and is set.
- /// This is reset to 0 when looping while is set.
+ /// This is reset to 0 when looping while is set.
public ulong PlayedSampleCount;
///
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/BiquadFilterHelper.cs b/src/Ryujinx.Audio/Renderer/Dsp/BiquadFilterHelper.cs
index 2122f2b44..4f98a8fb5 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/BiquadFilterHelper.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/BiquadFilterHelper.cs
@@ -1,5 +1,7 @@
using Ryujinx.Audio.Renderer.Dsp.State;
using Ryujinx.Audio.Renderer.Parameter;
+using Ryujinx.Audio.Renderer.Parameter.Effect;
+using Ryujinx.Common.Memory;
using System;
using System.Runtime.CompilerServices;
@@ -9,6 +11,112 @@ namespace Ryujinx.Audio.Renderer.Dsp
{
private const int FixedPointPrecisionForParameter = 14;
+ public static BiquadFilterParameter1 ToBiquadFilterParameter1(BiquadFilterParameter2 parameter)
+ {
+ BiquadFilterParameter1 result = new()
+ {
+ Enable = parameter.Enable, Numerator = new Array3(), Denominator = new Array2()
+ };
+
+ Span resultNumeratorSpan = result.Numerator.AsSpan();
+ Span resultDenominatorSpan = result.Denominator.AsSpan();
+
+ Span parameterNumeratorSpan = parameter.Numerator.AsSpan();
+ Span parameterDenominatorSpan = parameter.Denominator.AsSpan();
+
+
+ resultNumeratorSpan[0] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[0], FixedPointPrecisionForParameter);
+ resultNumeratorSpan[1] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[1], FixedPointPrecisionForParameter);
+ resultNumeratorSpan[2] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[2], FixedPointPrecisionForParameter);
+
+ resultDenominatorSpan[0] = (short)FixedPointHelper.ToFixed(parameterDenominatorSpan[0], FixedPointPrecisionForParameter);
+ resultDenominatorSpan[1] = (short)FixedPointHelper.ToFixed(parameterDenominatorSpan[1], FixedPointPrecisionForParameter);
+
+ return result;
+ }
+
+ public static BiquadFilterParameter2 ToBiquadFilterParameter2(BiquadFilterParameter1 parameter)
+ {
+ BiquadFilterParameter2 result = new()
+ {
+ Enable = parameter.Enable, Numerator = new Array3(), Denominator = new Array2()
+ };
+
+ Span resultNumeratorSpan = result.Numerator.AsSpan();
+ Span resultDenominatorSpan = result.Denominator.AsSpan();
+
+ Span parameterNumeratorSpan = parameter.Numerator.AsSpan();
+ Span parameterDenominatorSpan = parameter.Denominator.AsSpan();
+
+
+ resultNumeratorSpan[0] = FixedPointHelper.ToFloat(parameterNumeratorSpan[0], FixedPointPrecisionForParameter);
+ resultNumeratorSpan[1] = FixedPointHelper.ToFloat(parameterNumeratorSpan[1], FixedPointPrecisionForParameter);
+ resultNumeratorSpan[2] = FixedPointHelper.ToFloat(parameterNumeratorSpan[2], FixedPointPrecisionForParameter);
+
+ resultDenominatorSpan[0] = FixedPointHelper.ToFloat(parameterDenominatorSpan[0], FixedPointPrecisionForParameter);
+ resultDenominatorSpan[1] = FixedPointHelper.ToFloat(parameterDenominatorSpan[1], FixedPointPrecisionForParameter);
+
+ return result;
+ }
+
+ public static BiquadFilterEffectParameter1 ToBiquadFilterEffectParameter1(BiquadFilterEffectParameter2 parameter)
+ {
+ BiquadFilterEffectParameter1 result = new()
+ {
+ Input = parameter.Input,
+ Output = parameter.Output,
+ Numerator = new Array3(),
+ Denominator = new Array2(),
+ ChannelCount = parameter.ChannelCount,
+ Status = parameter.Status,
+ };
+
+ Span resultNumeratorSpan = result.Numerator.AsSpan();
+ Span resultDenominatorSpan = result.Denominator.AsSpan();
+
+ Span parameterNumeratorSpan = parameter.Numerator.AsSpan();
+ Span parameterDenominatorSpan = parameter.Denominator.AsSpan();
+
+
+ resultNumeratorSpan[0] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[0], FixedPointPrecisionForParameter);
+ resultNumeratorSpan[1] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[1], FixedPointPrecisionForParameter);
+ resultNumeratorSpan[2] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[2], FixedPointPrecisionForParameter);
+
+ resultDenominatorSpan[0] = (short)FixedPointHelper.ToFixed(parameterDenominatorSpan[0], FixedPointPrecisionForParameter);
+ resultDenominatorSpan[1] = (short)FixedPointHelper.ToFixed(parameterDenominatorSpan[1], FixedPointPrecisionForParameter);
+
+ return result;
+ }
+
+ public static BiquadFilterEffectParameter2 ToBiquadFilterEffectParameter2(BiquadFilterEffectParameter1 parameter)
+ {
+ BiquadFilterEffectParameter2 result = new()
+ {
+ Input = parameter.Input,
+ Output = parameter.Output,
+ Numerator = new Array3(),
+ Denominator = new Array2(),
+ ChannelCount = parameter.ChannelCount,
+ Status = parameter.Status,
+ };
+
+ Span resultNumeratorSpan = result.Numerator.AsSpan();
+ Span resultDenominatorSpan = result.Denominator.AsSpan();
+
+ Span parameterNumeratorSpan = parameter.Numerator.AsSpan();
+ Span parameterDenominatorSpan = parameter.Denominator.AsSpan();
+
+
+ resultNumeratorSpan[0] = FixedPointHelper.ToFloat(parameterNumeratorSpan[0], FixedPointPrecisionForParameter);
+ resultNumeratorSpan[1] = FixedPointHelper.ToFloat(parameterNumeratorSpan[1], FixedPointPrecisionForParameter);
+ resultNumeratorSpan[2] = FixedPointHelper.ToFloat(parameterNumeratorSpan[2], FixedPointPrecisionForParameter);
+
+ resultDenominatorSpan[0] = FixedPointHelper.ToFloat(parameterDenominatorSpan[0], FixedPointPrecisionForParameter);
+ resultDenominatorSpan[1] = FixedPointHelper.ToFloat(parameterDenominatorSpan[1], FixedPointPrecisionForParameter);
+
+ return result;
+ }
+
///
/// Apply a single biquad filter.
///
@@ -20,21 +128,21 @@ namespace Ryujinx.Audio.Renderer.Dsp
/// The count of samples to process
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ProcessBiquadFilter(
- ref BiquadFilterParameter parameter,
+ ref BiquadFilterParameter2 parameter,
ref BiquadFilterState state,
Span outputBuffer,
ReadOnlySpan inputBuffer,
uint sampleCount)
{
- Span numeratorSpan = parameter.Numerator.AsSpan();
- Span denominatorSpan = parameter.Denominator.AsSpan();
+ Span numeratorSpan = parameter.Numerator.AsSpan();
+ Span denominatorSpan = parameter.Denominator.AsSpan();
- float a0 = FixedPointHelper.ToFloat(numeratorSpan[0], FixedPointPrecisionForParameter);
- float a1 = FixedPointHelper.ToFloat(numeratorSpan[1], FixedPointPrecisionForParameter);
- float a2 = FixedPointHelper.ToFloat(numeratorSpan[2], FixedPointPrecisionForParameter);
+ float a0 = numeratorSpan[0];
+ float a1 = numeratorSpan[1];
+ float a2 = numeratorSpan[2];
- float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
- float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
+ float b1 = denominatorSpan[0];
+ float b2 = denominatorSpan[1];
for (int i = 0; i < sampleCount; i++)
{
@@ -60,22 +168,22 @@ namespace Ryujinx.Audio.Renderer.Dsp
/// Mix volume
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ProcessBiquadFilterAndMix(
- ref BiquadFilterParameter parameter,
+ ref BiquadFilterParameter2 parameter,
ref BiquadFilterState state,
Span outputBuffer,
ReadOnlySpan inputBuffer,
uint sampleCount,
float volume)
{
- Span numeratorSpan = parameter.Numerator.AsSpan();
- Span denominatorSpan = parameter.Denominator.AsSpan();
+ Span numeratorSpan = parameter.Numerator.AsSpan();
+ Span denominatorSpan = parameter.Denominator.AsSpan();
- float a0 = FixedPointHelper.ToFloat(numeratorSpan[0], FixedPointPrecisionForParameter);
- float a1 = FixedPointHelper.ToFloat(numeratorSpan[1], FixedPointPrecisionForParameter);
- float a2 = FixedPointHelper.ToFloat(numeratorSpan[2], FixedPointPrecisionForParameter);
+ float a0 = numeratorSpan[0];
+ float a1 = numeratorSpan[1];
+ float a2 = numeratorSpan[2];
- float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
- float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
+ float b1 = denominatorSpan[0];
+ float b2 = denominatorSpan[1];
for (int i = 0; i < sampleCount; i++)
{
@@ -105,7 +213,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
/// Last filtered sample value
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float ProcessBiquadFilterAndMixRamp(
- ref BiquadFilterParameter parameter,
+ ref BiquadFilterParameter2 parameter,
ref BiquadFilterState state,
Span outputBuffer,
ReadOnlySpan inputBuffer,
@@ -113,15 +221,15 @@ namespace Ryujinx.Audio.Renderer.Dsp
float volume,
float ramp)
{
- Span numeratorSpan = parameter.Numerator.AsSpan();
- Span denominatorSpan = parameter.Denominator.AsSpan();
+ Span numeratorSpan = parameter.Numerator.AsSpan();
+ Span denominatorSpan = parameter.Denominator.AsSpan();
- float a0 = FixedPointHelper.ToFloat(numeratorSpan[0], FixedPointPrecisionForParameter);
- float a1 = FixedPointHelper.ToFloat(numeratorSpan[1], FixedPointPrecisionForParameter);
- float a2 = FixedPointHelper.ToFloat(numeratorSpan[2], FixedPointPrecisionForParameter);
+ float a0 = numeratorSpan[0];
+ float a1 = numeratorSpan[1];
+ float a2 = numeratorSpan[2];
- float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
- float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
+ float b1 = denominatorSpan[0];
+ float b2 = denominatorSpan[1];
float mixState = 0f;
@@ -155,7 +263,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
/// The count of samples to process
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ProcessBiquadFilter(
- ReadOnlySpan parameters,
+ ReadOnlySpan parameters,
Span states,
Span outputBuffer,
ReadOnlySpan inputBuffer,
@@ -163,19 +271,19 @@ namespace Ryujinx.Audio.Renderer.Dsp
{
for (int stageIndex = 0; stageIndex < parameters.Length; stageIndex++)
{
- BiquadFilterParameter parameter = parameters[stageIndex];
+ BiquadFilterParameter2 parameter = parameters[stageIndex];
ref BiquadFilterState state = ref states[stageIndex];
- Span numeratorSpan = parameter.Numerator.AsSpan();
- Span denominatorSpan = parameter.Denominator.AsSpan();
+ Span numeratorSpan = parameter.Numerator.AsSpan();
+ Span denominatorSpan = parameter.Denominator.AsSpan();
- float a0 = FixedPointHelper.ToFloat(numeratorSpan[0], FixedPointPrecisionForParameter);
- float a1 = FixedPointHelper.ToFloat(numeratorSpan[1], FixedPointPrecisionForParameter);
- float a2 = FixedPointHelper.ToFloat(numeratorSpan[2], FixedPointPrecisionForParameter);
+ float a0 = numeratorSpan[0];
+ float a1 = numeratorSpan[1];
+ float a2 = numeratorSpan[2];
- float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
- float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
+ float b1 = denominatorSpan[0];
+ float b2 = denominatorSpan[1];
for (int i = 0; i < sampleCount; i++)
{
@@ -204,8 +312,8 @@ namespace Ryujinx.Audio.Renderer.Dsp
/// Mix volume
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ProcessDoubleBiquadFilterAndMix(
- ref BiquadFilterParameter parameter0,
- ref BiquadFilterParameter parameter1,
+ ref BiquadFilterParameter2 parameter0,
+ ref BiquadFilterParameter2 parameter1,
ref BiquadFilterState state0,
ref BiquadFilterState state1,
Span outputBuffer,
@@ -213,25 +321,25 @@ namespace Ryujinx.Audio.Renderer.Dsp
uint sampleCount,
float volume)
{
- Span numerator0Span = parameter0.Numerator.AsSpan();
- Span numerator1Span = parameter1.Numerator.AsSpan();
- Span denominator0Span = parameter0.Denominator.AsSpan();
- Span denominator1Span = parameter1.Denominator.AsSpan();
+ Span numerator0Span = parameter0.Numerator.AsSpan();
+ Span numerator1Span = parameter1.Numerator.AsSpan();
+ Span denominator0Span = parameter0.Denominator.AsSpan();
+ Span denominator1Span = parameter1.Denominator.AsSpan();
- float a00 = FixedPointHelper.ToFloat(numerator0Span[0], FixedPointPrecisionForParameter);
- float a10 = FixedPointHelper.ToFloat(numerator0Span[1], FixedPointPrecisionForParameter);
- float a20 = FixedPointHelper.ToFloat(numerator0Span[2], FixedPointPrecisionForParameter);
+ float a00 = numerator0Span[0];
+ float a10 = numerator0Span[1];
+ float a20 = numerator0Span[2];
- float b10 = FixedPointHelper.ToFloat(denominator0Span[0], FixedPointPrecisionForParameter);
- float b20 = FixedPointHelper.ToFloat(denominator0Span[1], FixedPointPrecisionForParameter);
+ float b10 = denominator0Span[0];
+ float b20 = denominator0Span[1];
- float a01 = FixedPointHelper.ToFloat(numerator1Span[0], FixedPointPrecisionForParameter);
- float a11 = FixedPointHelper.ToFloat(numerator1Span[1], FixedPointPrecisionForParameter);
- float a21 = FixedPointHelper.ToFloat(numerator1Span[2], FixedPointPrecisionForParameter);
+ float a01 = numerator1Span[0];
+ float a11 = numerator1Span[1];
+ float a21 = numerator1Span[2];
- float b11 = FixedPointHelper.ToFloat(denominator1Span[0], FixedPointPrecisionForParameter);
- float b21 = FixedPointHelper.ToFloat(denominator1Span[1], FixedPointPrecisionForParameter);
+ float b11 = denominator1Span[0];
+ float b21 = denominator1Span[1];
for (int i = 0; i < sampleCount; i++)
{
@@ -269,8 +377,8 @@ namespace Ryujinx.Audio.Renderer.Dsp
/// Last filtered sample value
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float ProcessDoubleBiquadFilterAndMixRamp(
- ref BiquadFilterParameter parameter0,
- ref BiquadFilterParameter parameter1,
+ ref BiquadFilterParameter2 parameter0,
+ ref BiquadFilterParameter2 parameter1,
ref BiquadFilterState state0,
ref BiquadFilterState state1,
Span outputBuffer,
@@ -279,24 +387,24 @@ namespace Ryujinx.Audio.Renderer.Dsp
float volume,
float ramp)
{
- Span numerator0Span = parameter0.Numerator.AsSpan();
- Span numerator1Span = parameter1.Numerator.AsSpan();
- Span denominator0Span = parameter0.Denominator.AsSpan();
- Span denominator1Span = parameter1.Denominator.AsSpan();
+ Span numerator0Span = parameter0.Numerator.AsSpan();
+ Span numerator1Span = parameter1.Numerator.AsSpan();
+ Span denominator0Span = parameter0.Denominator.AsSpan();
+ Span denominator1Span = parameter1.Denominator.AsSpan();
- float a00 = FixedPointHelper.ToFloat(numerator0Span[0], FixedPointPrecisionForParameter);
- float a10 = FixedPointHelper.ToFloat(numerator0Span[1], FixedPointPrecisionForParameter);
- float a20 = FixedPointHelper.ToFloat(numerator0Span[2], FixedPointPrecisionForParameter);
+ float a00 = numerator0Span[0];
+ float a10 = numerator0Span[1];
+ float a20 = numerator0Span[2];
- float b10 = FixedPointHelper.ToFloat(denominator0Span[0], FixedPointPrecisionForParameter);
- float b20 = FixedPointHelper.ToFloat(denominator0Span[1], FixedPointPrecisionForParameter);
+ float b10 = denominator0Span[0];
+ float b20 = denominator0Span[1];
- float a01 = FixedPointHelper.ToFloat(numerator1Span[0], FixedPointPrecisionForParameter);
- float a11 = FixedPointHelper.ToFloat(numerator1Span[1], FixedPointPrecisionForParameter);
- float a21 = FixedPointHelper.ToFloat(numerator1Span[2], FixedPointPrecisionForParameter);
+ float a01 = numerator1Span[0];
+ float a11 = numerator1Span[1];
+ float a21 = numerator1Span[2];
- float b11 = FixedPointHelper.ToFloat(denominator1Span[0], FixedPointPrecisionForParameter);
- float b21 = FixedPointHelper.ToFloat(denominator1Span[1], FixedPointPrecisionForParameter);
+ float b11 = denominator1Span[0];
+ float b21 = denominator1Span[1];
float mixState = 0f;
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/AdpcmDataSourceCommandVersion1.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/AdpcmDataSourceCommandVersion1.cs
index 59786c059..60161ee7a 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/AdpcmDataSourceCommandVersion1.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/AdpcmDataSourceCommandVersion1.cs
@@ -2,7 +2,7 @@ using Ryujinx.Audio.Common;
using Ryujinx.Audio.Renderer.Common;
using Ryujinx.Audio.Renderer.Server.Voice;
using System;
-using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
+using Ryujinx.Audio.Renderer.Parameter;
using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer;
namespace Ryujinx.Audio.Renderer.Dsp.Command
@@ -24,23 +24,23 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public WaveBuffer[] WaveBuffers { get; }
- public Memory State { get; }
+ public Memory State { get; }
public ulong AdpcmParameter { get; }
public ulong AdpcmParameterSize { get; }
public DecodingBehaviour DecodingBehaviour { get; }
- public AdpcmDataSourceCommandVersion1(ref VoiceState serverState, Memory state, ushort outputBufferIndex, int nodeId)
+ public AdpcmDataSourceCommandVersion1(ref VoiceInfo serverInfo, Memory state, ushort outputBufferIndex, int nodeId)
{
Enabled = true;
NodeId = nodeId;
OutputBufferIndex = outputBufferIndex;
- SampleRate = serverState.SampleRate;
- Pitch = serverState.Pitch;
+ SampleRate = serverInfo.SampleRate;
+ Pitch = serverInfo.Pitch;
- Span waveBufferSpan = serverState.WaveBuffers.AsSpan();
+ Span waveBufferSpan = serverInfo.WaveBuffers.AsSpan();
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
@@ -51,10 +51,10 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
WaveBuffers[i] = voiceWaveBuffer.ToCommon(1);
}
- AdpcmParameter = serverState.DataSourceStateAddressInfo.GetReference(true);
- AdpcmParameterSize = serverState.DataSourceStateAddressInfo.Size;
+ AdpcmParameter = serverInfo.DataSourceStateAddressInfo.GetReference(true);
+ AdpcmParameterSize = serverInfo.DataSourceStateAddressInfo.Size;
State = state;
- DecodingBehaviour = serverState.DecodingBehaviour;
+ DecodingBehaviour = serverInfo.DecodingBehaviour;
}
public void Process(CommandList context)
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterAndMixCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterAndMixCommand.cs
index 106fc0357..624c0d55b 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterAndMixCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterAndMixCommand.cs
@@ -18,12 +18,12 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public ushort InputBufferIndex { get; }
public ushort OutputBufferIndex { get; }
- private BiquadFilterParameter _parameter;
+ private BiquadFilterParameter2 _parameter;
public Memory BiquadFilterState { get; }
public Memory PreviousBiquadFilterState { get; }
- public Memory State { get; }
+ public Memory State { get; }
public int LastSampleIndex { get; }
@@ -40,8 +40,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
uint inputBufferIndex,
uint outputBufferIndex,
int lastSampleIndex,
- Memory state,
- ref BiquadFilterParameter filter,
+ Memory state,
+ ref BiquadFilterParameter2 filter,
Memory biquadFilterState,
Memory previousBiquadFilterState,
bool needInitialization,
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterCommand.cs
index ac1e581f6..a8c996428 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterCommand.cs
@@ -19,11 +19,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public int OutputBufferIndex { get; }
public bool NeedInitialization { get; }
- private BiquadFilterParameter _parameter;
+ private BiquadFilterParameter2 _parameter;
public BiquadFilterCommand(
int baseIndex,
- ref BiquadFilterParameter filter,
+ ref BiquadFilterParameter2 filter,
Memory biquadFilterStateMemory,
int inputBufferOffset,
int outputBufferOffset,
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandList.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandList.cs
index 185d169f0..9abd6a18a 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandList.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandList.cs
@@ -129,7 +129,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
{
startTime = PerformanceCounter.ElapsedNanoseconds;
}
-
+
command.Process(this);
if (shouldMeter)
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandType.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandType.cs
index de5c0ea2c..377eb6e57 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandType.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandType.cs
@@ -12,6 +12,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
Volume,
VolumeRamp,
BiquadFilter,
+ BiquadFilterFloatCoeff, // new
Mix,
MixRamp,
MixRampGrouped,
@@ -31,9 +32,17 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
LimiterVersion1,
LimiterVersion2,
MultiTapBiquadFilter,
+ MultiTapBiquadFilterFloatCoeff, // new
CaptureBuffer,
Compressor,
BiquadFilterAndMix,
+ BiquadFilterAndMixFloatCoeff, // new
MultiTapBiquadFilterAndMix,
+ MultiTapBiquadFilterAndMixFloatCoef, // new
+ AuxiliaryBufferGrouped, // new
+ FillMixBuffer, // new
+ BiquadFilterCrossFade, // new
+ MultiTapBiquadFilterCrossFade, // new
+ FillBuffer, // new
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DataSourceVersion2Command.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DataSourceVersion2Command.cs
index d3d3d2418..1fbd95c32 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DataSourceVersion2Command.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DataSourceVersion2Command.cs
@@ -2,7 +2,7 @@ using Ryujinx.Audio.Common;
using Ryujinx.Audio.Renderer.Common;
using Ryujinx.Audio.Renderer.Server.Voice;
using System;
-using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
+using Ryujinx.Audio.Renderer.Parameter;
using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer;
namespace Ryujinx.Audio.Renderer.Dsp.Command
@@ -24,7 +24,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public WaveBuffer[] WaveBuffers { get; }
- public Memory State { get; }
+ public Memory State { get; }
public ulong ExtraParameter { get; }
public ulong ExtraParameterSize { get; }
@@ -39,21 +39,21 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public SampleRateConversionQuality SrcQuality { get; }
- public DataSourceVersion2Command(ref VoiceState serverState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
+ public DataSourceVersion2Command(ref VoiceInfo serverInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
{
Enabled = true;
NodeId = nodeId;
ChannelIndex = channelIndex;
- ChannelCount = serverState.ChannelsCount;
- SampleFormat = serverState.SampleFormat;
- SrcQuality = serverState.SrcQuality;
+ ChannelCount = serverInfo.ChannelsCount;
+ SampleFormat = serverInfo.SampleFormat;
+ SrcQuality = serverInfo.SrcQuality;
CommandType = GetCommandTypeBySampleFormat(SampleFormat);
OutputBufferIndex = (ushort)(channelIndex + outputBufferIndex);
- SampleRate = serverState.SampleRate;
- Pitch = serverState.Pitch;
+ SampleRate = serverInfo.SampleRate;
+ Pitch = serverInfo.Pitch;
- Span waveBufferSpan = serverState.WaveBuffers.AsSpan();
+ Span waveBufferSpan = serverInfo.WaveBuffers.AsSpan();
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
@@ -66,12 +66,12 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
if (SampleFormat == SampleFormat.Adpcm)
{
- ExtraParameter = serverState.DataSourceStateAddressInfo.GetReference(true);
- ExtraParameterSize = serverState.DataSourceStateAddressInfo.Size;
+ ExtraParameter = serverInfo.DataSourceStateAddressInfo.GetReference(true);
+ ExtraParameterSize = serverInfo.DataSourceStateAddressInfo.Size;
}
State = state;
- DecodingBehaviour = serverState.DecodingBehaviour;
+ DecodingBehaviour = serverInfo.DecodingBehaviour;
}
private static CommandType GetCommandTypeBySampleFormat(SampleFormat sampleFormat)
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopPrepareCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopPrepareCommand.cs
index a76f690e4..18ae11eb4 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopPrepareCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopPrepareCommand.cs
@@ -17,10 +17,10 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public ushort[] OutputBufferIndices { get; }
- public Memory State { get; }
+ public Memory State { get; }
public Memory DepopBuffer { get; }
- public DepopPrepareCommand(Memory state, Memory depopBuffer, uint mixBufferCount, uint bufferOffset, int nodeId, bool enabled)
+ public DepopPrepareCommand(Memory state, Memory depopBuffer, uint mixBufferCount, uint bufferOffset, int nodeId, bool enabled)
{
Enabled = enabled;
NodeId = nodeId;
@@ -39,7 +39,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public void Process(CommandList context)
{
- ref VoiceUpdateState state = ref State.Span[0];
+ ref VoiceState state = ref State.Span[0];
Span depopBuffer = DepopBuffer.Span;
Span lastSamplesSpan = state.LastSamples.AsSpan();
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DeviceSinkCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DeviceSinkCommand.cs
index 322c5d386..b0e4b3c99 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DeviceSinkCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DeviceSinkCommand.cs
@@ -42,9 +42,9 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
}
- if (sink.UpsamplerState != null)
+ if (sink.UpsamplerInfo != null)
{
- Buffers = sink.UpsamplerState.OutputBuffer;
+ Buffers = sink.UpsamplerInfo.OutputBuffer;
}
else
{
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/FillBufferCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/FillBufferCommand.cs
new file mode 100644
index 000000000..ca5428c56
--- /dev/null
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/FillBufferCommand.cs
@@ -0,0 +1,69 @@
+using Ryujinx.Audio.Renderer.Server.Splitter;
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Ryujinx.Audio.Renderer.Dsp.Command
+{
+ public class FillBufferCommand : ICommand
+ {
+ public bool Enabled { get; set; }
+
+ public int NodeId { get; }
+
+ public CommandType CommandType => CommandType.FillBuffer;
+
+ public uint EstimatedProcessingTime { get; set; }
+
+ public SplitterDestinationVersion1 Destination1 { get; }
+ public SplitterDestinationVersion2 Destination2 { get; }
+ public bool IsV2 { get; }
+ public int Length { get; }
+ public float Value { get; }
+
+ public FillBufferCommand(SplitterDestinationVersion1 destination, int length, float value, int nodeId)
+ {
+ Enabled = true;
+ NodeId = nodeId;
+
+ Destination1 = destination;
+ IsV2 = false;
+ Length = length;
+ Value = value;
+ }
+
+ public FillBufferCommand(SplitterDestinationVersion2 destination, int length, float value, int nodeId)
+ {
+ Enabled = true;
+ NodeId = nodeId;
+
+ Destination2 = destination;
+ IsV2 = true;
+ Length = length;
+ Value = value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void ProcessFillBuffer()
+ {
+ if (IsV2)
+ {
+ for (int i = 0; i < Length; i++)
+ {
+ Destination2.PreviousMixBufferVolume[i] = Value;
+ }
+ }
+ else
+ {
+ for (int i = 0; i < Length; i++)
+ {
+ Destination1.PreviousMixBufferVolume[i] = Value;
+ }
+ }
+ }
+
+ public void Process(CommandList context)
+ {
+ ProcessFillBuffer();
+ }
+ }
+}
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampCommand.cs
index f77a233e1..6c5f7628c 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampCommand.cs
@@ -20,11 +20,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public float Volume0 { get; }
public float Volume1 { get; }
- public Memory State { get; }
+ public Memory State { get; }
public int LastSampleIndex { get; }
- public MixRampCommand(float volume0, float volume1, uint inputBufferIndex, uint outputBufferIndex, int lastSampleIndex, Memory state, int nodeId)
+ public MixRampCommand(float volume0, float volume1, uint inputBufferIndex, uint outputBufferIndex, int lastSampleIndex, Memory state, int nodeId)
{
Enabled = true;
NodeId = nodeId;
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampGroupedCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampGroupedCommand.cs
index bc1f277ac..0d732c3fa 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampGroupedCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampGroupedCommand.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public float[] Volume0 { get; }
public float[] Volume1 { get; }
- public Memory State { get; }
+ public Memory State { get; }
public MixRampGroupedCommand(
uint mixBufferCount,
@@ -30,7 +30,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
uint outputBufferIndex,
ReadOnlySpan volume0,
ReadOnlySpan volume1,
- Memory state,
+ Memory state,
int nodeId)
{
Enabled = true;
@@ -79,7 +79,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public void Process(CommandList context)
{
- ref VoiceUpdateState state = ref State.Span[0];
+ ref VoiceState state = ref State.Span[0];
Span lastSamplesSpan = state.LastSamples.AsSpan();
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterAndMixCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterAndMixCommand.cs
index e359371b4..ee28ce2fb 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterAndMixCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterAndMixCommand.cs
@@ -18,15 +18,15 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public ushort InputBufferIndex { get; }
public ushort OutputBufferIndex { get; }
- private BiquadFilterParameter _parameter0;
- private BiquadFilterParameter _parameter1;
+ private BiquadFilterParameter2 _parameter0;
+ private BiquadFilterParameter2 _parameter1;
public Memory BiquadFilterState0 { get; }
public Memory BiquadFilterState1 { get; }
public Memory PreviousBiquadFilterState0 { get; }
public Memory PreviousBiquadFilterState1 { get; }
- public Memory State { get; }
+ public Memory State { get; }
public int LastSampleIndex { get; }
@@ -44,9 +44,9 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
uint inputBufferIndex,
uint outputBufferIndex,
int lastSampleIndex,
- Memory state,
- ref BiquadFilterParameter filter0,
- ref BiquadFilterParameter filter1,
+ Memory state,
+ ref BiquadFilterParameter2 filter0,
+ ref BiquadFilterParameter2 filter1,
Memory biquadFilterState0,
Memory biquadFilterState1,
Memory previousBiquadFilterState0,
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterCommand.cs
index e159f8ef7..84998056f 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterCommand.cs
@@ -14,13 +14,13 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public uint EstimatedProcessingTime { get; set; }
- private readonly BiquadFilterParameter[] _parameters;
+ private readonly BiquadFilterParameter2[] _parameters;
private readonly Memory _biquadFilterStates;
private readonly int _inputBufferIndex;
private readonly int _outputBufferIndex;
private readonly bool[] _isInitialized;
- public MultiTapBiquadFilterCommand(int baseIndex, ReadOnlySpan filters, Memory biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, ReadOnlySpan isInitialized, int nodeId)
+ public MultiTapBiquadFilterCommand(int baseIndex, ReadOnlySpan filters, Memory biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, ReadOnlySpan isInitialized, int nodeId)
{
_parameters = filters.ToArray();
_biquadFilterStates = biquadFilterStateMemory;
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmFloatDataSourceCommandVersion1.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmFloatDataSourceCommandVersion1.cs
index 2b5f0de72..d54158541 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmFloatDataSourceCommandVersion1.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmFloatDataSourceCommandVersion1.cs
@@ -2,7 +2,7 @@ using Ryujinx.Audio.Common;
using Ryujinx.Audio.Renderer.Common;
using Ryujinx.Audio.Renderer.Server.Voice;
using System;
-using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
+using Ryujinx.Audio.Renderer.Parameter;
using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer;
namespace Ryujinx.Audio.Renderer.Dsp.Command
@@ -27,23 +27,23 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public WaveBuffer[] WaveBuffers { get; }
- public Memory State { get; }
+ public Memory State { get; }
public DecodingBehaviour DecodingBehaviour { get; }
- public PcmFloatDataSourceCommandVersion1(ref VoiceState serverState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
+ public PcmFloatDataSourceCommandVersion1(ref VoiceInfo serverInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
{
Enabled = true;
NodeId = nodeId;
OutputBufferIndex = (ushort)(channelIndex + outputBufferIndex);
- SampleRate = serverState.SampleRate;
+ SampleRate = serverInfo.SampleRate;
ChannelIndex = channelIndex;
- ChannelCount = serverState.ChannelsCount;
- Pitch = serverState.Pitch;
+ ChannelCount = serverInfo.ChannelsCount;
+ Pitch = serverInfo.Pitch;
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
- Span waveBufferSpan = serverState.WaveBuffers.AsSpan();
+ Span waveBufferSpan = serverInfo.WaveBuffers.AsSpan();
for (int i = 0; i < WaveBuffers.Length; i++)
{
@@ -53,7 +53,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
}
State = state;
- DecodingBehaviour = serverState.DecodingBehaviour;
+ DecodingBehaviour = serverInfo.DecodingBehaviour;
}
public void Process(CommandList context)
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmInt16DataSourceCommandVersion1.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmInt16DataSourceCommandVersion1.cs
index 9c30de41d..91619d80f 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmInt16DataSourceCommandVersion1.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmInt16DataSourceCommandVersion1.cs
@@ -2,7 +2,7 @@ using Ryujinx.Audio.Common;
using Ryujinx.Audio.Renderer.Common;
using Ryujinx.Audio.Renderer.Server.Voice;
using System;
-using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
+using Ryujinx.Audio.Renderer.Parameter;
using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer;
namespace Ryujinx.Audio.Renderer.Dsp.Command
@@ -27,23 +27,23 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public WaveBuffer[] WaveBuffers { get; }
- public Memory State { get; }
+ public Memory State { get; }
public DecodingBehaviour DecodingBehaviour { get; }
- public PcmInt16DataSourceCommandVersion1(ref VoiceState serverState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
+ public PcmInt16DataSourceCommandVersion1(ref VoiceInfo serverInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
{
Enabled = true;
NodeId = nodeId;
OutputBufferIndex = (ushort)(channelIndex + outputBufferIndex);
- SampleRate = serverState.SampleRate;
+ SampleRate = serverInfo.SampleRate;
ChannelIndex = channelIndex;
- ChannelCount = serverState.ChannelsCount;
- Pitch = serverState.Pitch;
+ ChannelCount = serverInfo.ChannelsCount;
+ Pitch = serverInfo.Pitch;
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
- Span waveBufferSpan = serverState.WaveBuffers.AsSpan();
+ Span waveBufferSpan = serverInfo.WaveBuffers.AsSpan();
for (int i = 0; i < WaveBuffers.Length; i++)
{
@@ -53,7 +53,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
}
State = state;
- DecodingBehaviour = serverState.DecodingBehaviour;
+ DecodingBehaviour = serverInfo.DecodingBehaviour;
}
public void Process(CommandList context)
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/UpsampleCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/UpsampleCommand.cs
index 8882500cd..5d23addae 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/UpsampleCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/UpsampleCommand.cs
@@ -18,11 +18,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public uint InputSampleCount { get; }
public uint InputSampleRate { get; }
- public UpsamplerState UpsamplerInfo { get; }
+ public UpsamplerInfo UpsamplerInfo { get; }
public Memory OutBuffer { get; }
- public UpsampleCommand(uint bufferOffset, UpsamplerState info, uint inputCount, Span inputBufferOffset, uint bufferCount, uint sampleCount, uint sampleRate, int nodeId)
+ public UpsampleCommand(uint bufferOffset, UpsamplerInfo info, uint inputCount, Span inputBufferOffset, uint bufferCount, uint sampleCount, uint sampleRate, int nodeId)
{
Enabled = true;
NodeId = nodeId;
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/DataSourceHelper.cs b/src/Ryujinx.Audio/Renderer/Dsp/DataSourceHelper.cs
index 130836c6b..9e4e04890 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/DataSourceHelper.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/DataSourceHelper.cs
@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;
using System.Runtime.Intrinsics.X86;
-using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
+using Ryujinx.Audio.Renderer.Parameter;
namespace Ryujinx.Audio.Renderer.Dsp
{
@@ -42,7 +42,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
};
}
- public static void ProcessWaveBuffers(IVirtualMemoryManager memoryManager, Span outputBuffer, ref WaveBufferInformation info, Span wavebuffers, ref VoiceUpdateState voiceState, uint targetSampleRate, int sampleCount)
+ public static void ProcessWaveBuffers(IVirtualMemoryManager memoryManager, Span outputBuffer, ref WaveBufferInformation info, Span wavebuffers, ref VoiceState voiceState, uint targetSampleRate, int sampleCount)
{
const int TempBufferSize = 0x3F00;
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs b/src/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs
index 16048d7ff..0de34101e 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs
@@ -3,7 +3,7 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
-using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
+using Ryujinx.Audio.Renderer.Parameter;
namespace Ryujinx.Audio.Renderer.Dsp
{
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/AudioRendererConfiguration.cs b/src/Ryujinx.Audio/Renderer/Parameter/AudioRendererConfiguration.cs
index 491a05c86..c70e16544 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/AudioRendererConfiguration.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/AudioRendererConfiguration.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Audio.Renderer.Server;
using Ryujinx.Audio.Renderer.Server.Types;
using System.Runtime.InteropServices;
@@ -93,7 +94,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
///
/// The user audio revision
///
- ///
+ ///
public int Revision;
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter1.cs
similarity index 95%
rename from src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter.cs
rename to src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter1.cs
index f1492b0b1..5a3091f62 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter1.cs
@@ -7,7 +7,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
/// Biquad filter parameters.
///
[StructLayout(LayoutKind.Sequential, Size = 0xC, Pack = 1)]
- public struct BiquadFilterParameter
+ public struct BiquadFilterParameter1
{
///
/// Set to true if the biquad filter is active.
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter2.cs b/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter2.cs
new file mode 100644
index 000000000..8e47b22e0
--- /dev/null
+++ b/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter2.cs
@@ -0,0 +1,36 @@
+using Ryujinx.Common.Memory;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Audio.Renderer.Parameter
+{
+ ///
+ /// Biquad filter parameters.
+ ///
+ [StructLayout(LayoutKind.Sequential, Size = 0x18, Pack = 1)]
+ public struct BiquadFilterParameter2
+ {
+ ///
+ /// Set to true if the biquad filter is active.
+ ///
+ [MarshalAs(UnmanagedType.I1)]
+ public bool Enable;
+
+ ///
+ /// Reserved/padding.
+ ///
+ private readonly byte _reserved1;
+ private readonly byte _reserved2;
+ private readonly byte _reserved3;
+
+ ///
+ /// Biquad filter numerator (b0, b1, b2).
+ ///
+ public Array3 Numerator;
+
+ ///
+ /// Biquad filter denominator (a1, a2).
+ ///
+ /// a0 = 1
+ public Array2 Denominator;
+ }
+}
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter1.cs
similarity index 96%
rename from src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter.cs
rename to src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter1.cs
index b12a941a5..443b257be 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter1.cs
@@ -8,7 +8,7 @@ namespace Ryujinx.Audio.Renderer.Parameter.Effect
/// for .
///
[StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct BiquadFilterEffectParameter
+ public struct BiquadFilterEffectParameter1
{
///
/// The input channel indices that will be used by the .
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter2.cs b/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter2.cs
new file mode 100644
index 000000000..0c74f1e7b
--- /dev/null
+++ b/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter2.cs
@@ -0,0 +1,49 @@
+using Ryujinx.Audio.Renderer.Server.Effect;
+using Ryujinx.Common.Memory;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Audio.Renderer.Parameter.Effect
+{
+ ///
+ /// for .
+ ///
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct BiquadFilterEffectParameter2
+ {
+ ///
+ /// The input channel indices that will be used by the .
+ ///
+ public Array6 Input;
+
+ ///
+ /// The output channel indices that will be used by the .
+ ///
+ public Array6 Output;
+
+ ///
+ /// Biquad filter numerator (b0, b1, b2).
+ ///
+ public Array3 Numerator;
+
+ ///
+ /// Biquad filter denominator (a1, a2).
+ ///
+ /// a0 = 1
+ public Array2 Denominator;
+
+ ///
+ /// The total channel count used.
+ ///
+ public byte ChannelCount;
+
+ ///
+ /// The current usage status of the effect on the client side.
+ ///
+ public UsageState Status;
+
+ ///
+ /// Reserved/unused.
+ ///
+ private readonly ushort _reserved;
+ }
+}
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion3.cs b/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion3.cs
new file mode 100644
index 000000000..2cf4911a6
--- /dev/null
+++ b/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion3.cs
@@ -0,0 +1,97 @@
+using Ryujinx.Audio.Renderer.Common;
+using Ryujinx.Common.Utilities;
+using System;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Audio.Renderer.Parameter
+{
+ ///
+ /// Input information for an effect version 2. (added with REV9)
+ ///
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct EffectInParameterVersion3 : IEffectInParameter
+ {
+ ///
+ /// Type of the effect.
+ ///
+ public EffectType Type;
+
+ ///
+ /// Set to true if the effect is new.
+ ///
+ [MarshalAs(UnmanagedType.I1)]
+ public bool IsNew;
+
+ ///
+ /// Set to true if the effect must be active.
+ ///
+ [MarshalAs(UnmanagedType.I1)]
+ public bool IsEnabled;
+
+ ///
+ /// Reserved/padding.
+ ///
+ private readonly byte _reserved1;
+
+ ///
+ /// The target mix id of the effect.
+ ///
+ public int MixId;
+
+ ///
+ /// Address of the processing workbuffer.
+ ///
+ /// This is additional data that could be required by the effect processing.
+ public ulong BufferBase;
+
+ ///
+ /// Size of the processing workbuffer.
+ ///
+ /// This is additional data that could be required by the effect processing.
+ public ulong BufferSize;
+
+ ///
+ /// Position of the effect while processing effects.
+ ///
+ public uint ProcessingOrder;
+
+ ///
+ /// Reserved/padding.
+ ///
+ private readonly uint _reserved2;
+
+ ///
+ /// Specific data storage.
+ ///
+ private SpecificDataStruct _specificDataStart;
+
+ [StructLayout(LayoutKind.Sequential, Size = 0xA0, Pack = 1)]
+ private struct SpecificDataStruct { }
+
+ public Span SpecificData => SpanHelpers.AsSpan(ref _specificDataStart);
+
+ readonly EffectType IEffectInParameter.Type => Type;
+
+ readonly bool IEffectInParameter.IsNew => IsNew;
+
+ readonly bool IEffectInParameter.IsEnabled => IsEnabled;
+
+ readonly int IEffectInParameter.MixId => MixId;
+
+ readonly ulong IEffectInParameter.BufferBase => BufferBase;
+
+ readonly ulong IEffectInParameter.BufferSize => BufferSize;
+
+ readonly uint IEffectInParameter.ProcessingOrder => ProcessingOrder;
+
+ ///
+ /// Check if the given channel count is valid.
+ ///
+ /// The channel count to check
+ /// Returns true if the channel count is valid.
+ public static bool IsChannelCountValid(int channelCount)
+ {
+ return channelCount is 1 or 2 or 4 or 6;
+ }
+ }
+}
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/ISplitterDestinationInParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/ISplitterDestinationInParameter.cs
index 7ee49f11a..c3224c57d 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/ISplitterDestinationInParameter.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/ISplitterDestinationInParameter.cs
@@ -17,11 +17,11 @@ namespace Ryujinx.Audio.Renderer.Parameter
/// The mix to output the result of the splitter.
///
int DestinationId { get; }
-
+
///
/// Biquad filter parameters.
///
- Array2 BiquadFilters { get; }
+ Array2 BiquadFilters2 { get; }
///
/// Set to true if in use.
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/SinkInParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/SinkInParameter.cs
index 3c1ac09c0..86ceea30a 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/SinkInParameter.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/SinkInParameter.cs
@@ -25,7 +25,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
///
/// Reserved/padding.
///
- private readonly ushort _reserved1;
+ private readonly ushort _magic; // 0xCAFE
///
/// The node id of the sink.
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion1.cs b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion1.cs
index f346efcb0..fbc036806 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion1.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion1.cs
@@ -60,8 +60,8 @@ namespace Ryujinx.Audio.Renderer.Parameter
readonly int ISplitterDestinationInParameter.Id => Id;
readonly int ISplitterDestinationInParameter.DestinationId => DestinationId;
-
- readonly Array2 ISplitterDestinationInParameter.BiquadFilters => default;
+
+ readonly Array2 ISplitterDestinationInParameter.BiquadFilters2 => default;
readonly bool ISplitterDestinationInParameter.IsUsed => IsUsed;
readonly bool ISplitterDestinationInParameter.ResetPrevVolume => ResetPrevVolume;
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2a.cs b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2a.cs
new file mode 100644
index 000000000..4270b5e20
--- /dev/null
+++ b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2a.cs
@@ -0,0 +1,100 @@
+using Ryujinx.Audio.Renderer.Dsp;
+using Ryujinx.Common.Memory;
+using Ryujinx.Common.Utilities;
+using System;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Audio.Renderer.Parameter
+{
+ ///
+ /// Input header for a splitter destination version 2 update.
+ ///
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct SplitterDestinationInParameterVersion2a : ISplitterDestinationInParameter
+ {
+ ///
+ /// Magic of the input header.
+ ///
+ public uint Magic;
+
+ ///
+ /// Target splitter destination data id.
+ ///
+ public int Id;
+
+ ///
+ /// Mix buffer volumes storage.
+ ///
+ private MixArray _mixBufferVolume;
+
+ ///
+ /// The mix to output the result of the splitter.
+ ///
+ public int DestinationId;
+
+ ///
+ /// Biquad filter parameters.
+ ///
+ public Array2 BiquadFilters;
+
+ ///
+ /// Set to true if in use.
+ ///
+ [MarshalAs(UnmanagedType.I1)]
+ public bool IsUsed;
+
+ ///
+ /// Set to true to force resetting the previous mix volumes.
+ ///
+ [MarshalAs(UnmanagedType.I1)]
+ public bool ResetPrevVolume;
+
+ ///
+ /// Reserved/padding.
+ ///
+ private unsafe fixed byte _reserved[10];
+
+ [StructLayout(LayoutKind.Sequential, Size = sizeof(float) * Constants.MixBufferCountMax, Pack = 1)]
+ private struct MixArray { }
+
+ ///
+ /// Mix buffer volumes.
+ ///
+ /// Used when a splitter id is specified in the mix.
+ public Span MixBufferVolume => SpanHelpers.AsSpan(ref _mixBufferVolume);
+
+ readonly int ISplitterDestinationInParameter.Id => Id;
+
+ readonly int ISplitterDestinationInParameter.DestinationId => DestinationId;
+
+ readonly Array2 ISplitterDestinationInParameter.BiquadFilters2
+ {
+ get
+ {
+ Array2 newFilters = new();
+ Span newFiltersSpan = newFilters.AsSpan();
+ newFiltersSpan[0] = BiquadFilterHelper.ToBiquadFilterParameter2(BiquadFilters[0]);
+ newFiltersSpan[1] = BiquadFilterHelper.ToBiquadFilterParameter2(BiquadFilters[1]);
+
+ return newFilters;
+ }
+ }
+
+ readonly bool ISplitterDestinationInParameter.IsUsed => IsUsed;
+ readonly bool ISplitterDestinationInParameter.ResetPrevVolume => ResetPrevVolume;
+
+ ///
+ /// The expected constant of any input header.
+ ///
+ private const uint ValidMagic = 0x44444E53;
+
+ ///
+ /// Check if the magic is valid.
+ ///
+ /// Returns true if the magic is valid.
+ public readonly bool IsMagicValid()
+ {
+ return Magic == ValidMagic;
+ }
+ }
+}
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2.cs b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2b.cs
similarity index 90%
rename from src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2.cs
rename to src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2b.cs
index 1d867919d..81e9d823b 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2b.cs
@@ -9,7 +9,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
/// Input header for a splitter destination version 2 update.
///
[StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct SplitterDestinationInParameterVersion2 : ISplitterDestinationInParameter
+ public struct SplitterDestinationInParameterVersion2b : ISplitterDestinationInParameter
{
///
/// Magic of the input header.
@@ -34,7 +34,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
///
/// Biquad filter parameters.
///
- public Array2 BiquadFilters;
+ public Array2 BiquadFilters;
///
/// Set to true if in use.
@@ -66,7 +66,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
readonly int ISplitterDestinationInParameter.DestinationId => DestinationId;
- readonly Array2 ISplitterDestinationInParameter.BiquadFilters => BiquadFilters;
+ readonly Array2 ISplitterDestinationInParameter.BiquadFilters2 => BiquadFilters;
readonly bool ISplitterDestinationInParameter.IsUsed => IsUsed;
readonly bool ISplitterDestinationInParameter.ResetPrevVolume => ResetPrevVolume;
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter1.cs
similarity index 98%
rename from src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter.cs
rename to src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter1.cs
index f33d82aa0..a3633edbd 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter1.cs
@@ -12,7 +12,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
/// Input information for a voice.
///
[StructLayout(LayoutKind.Sequential, Size = 0x170, Pack = 1)]
- public struct VoiceInParameter
+ public struct VoiceInParameter1
{
///
/// Id of the voice.
@@ -79,7 +79,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
///
/// Biquad filters to apply to the output of the voice.
///
- public Array2 BiquadFilters;
+ public Array2 BiquadFilters;
///
/// Total count of of the voice.
@@ -171,8 +171,9 @@ namespace Ryujinx.Audio.Renderer.Parameter
/// Reserved/unused.
///
private unsafe fixed uint _reserved3[2];
-
- ///
+ }
+
+ ///
/// Input information for a voice wavebuffer.
///
[StructLayout(LayoutKind.Sequential, Size = 0x38, Pack = 1)]
@@ -328,5 +329,4 @@ namespace Ryujinx.Audio.Renderer.Parameter
///
Low,
}
- }
}
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter2.cs b/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter2.cs
new file mode 100644
index 000000000..78e47b69a
--- /dev/null
+++ b/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter2.cs
@@ -0,0 +1,176 @@
+using Ryujinx.Audio.Common;
+using Ryujinx.Audio.Renderer.Common;
+using Ryujinx.Audio.Renderer.Dsp;
+using Ryujinx.Common.Memory;
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Audio.Renderer.Parameter
+{
+ ///
+ /// Input information for a voice.
+ ///
+ [StructLayout(LayoutKind.Sequential, Size = 0x188, Pack = 1)]
+ public struct VoiceInParameter2
+ {
+ ///
+ /// Id of the voice.
+ ///
+ public int Id;
+
+ ///
+ /// Node id of the voice.
+ ///
+ public int NodeId;
+
+ ///
+ /// Set to true if the voice is new.
+ ///
+ [MarshalAs(UnmanagedType.I1)]
+ public bool IsNew;
+
+ ///
+ /// Set to true if the voice is used.
+ ///
+ [MarshalAs(UnmanagedType.I1)]
+ public bool InUse;
+
+ ///
+ /// The voice wanted by the user.
+ ///
+ public PlayState PlayState;
+
+ ///
+ /// The of the voice.
+ ///
+ public SampleFormat SampleFormat;
+
+ ///
+ /// The sample rate of the voice.
+ ///
+ public uint SampleRate;
+
+ ///
+ /// The priority of the voice.
+ ///
+ public uint Priority;
+
+ ///
+ /// Target sorting position of the voice. (Used to sort voices with the same )
+ ///
+ public uint SortingOrder;
+
+ ///
+ /// The total channel count used.
+ ///
+ public uint ChannelCount;
+
+ ///
+ /// The pitch used on the voice.
+ ///
+ public float Pitch;
+
+ ///
+ /// The output volume of the voice.
+ ///
+ public float Volume;
+
+ ///
+ /// Biquad filters to apply to the output of the voice.
+ ///
+ public Array2 BiquadFilters;
+
+ ///
+ /// Total count of of the voice.
+ ///
+ public uint WaveBuffersCount;
+
+ ///
+ /// Current playing of the voice.
+ ///
+ public uint WaveBuffersIndex;
+
+ ///
+ /// Reserved/unused.
+ ///
+ private readonly uint
+ _reserved1;
+
+ ///
+ /// User state address required by the data source.
+ ///
+ /// Only used for as the address of the GC-ADPCM coefficients.
+ public ulong DataSourceStateAddress;
+
+ ///
+ /// User state size required by the data source.
+ ///
+ /// Only used for as the size of the GC-ADPCM coefficients.
+ public ulong DataSourceStateSize;
+
+ ///
+ /// The target mix id of the voice.
+ ///
+ public int MixId;
+
+ ///
+ /// The target splitter id of the voice.
+ ///
+ public uint SplitterId;
+
+ ///
+ /// The wavebuffer parameters of this voice.
+ ///
+ public Array4 WaveBuffers;
+
+ ///
+ /// The channel resource ids associated to the voice.
+ ///
+ public Array6 ChannelResourceIds;
+
+ ///
+ /// Reset the voice drop flag during voice server update.
+ ///
+ [MarshalAs(UnmanagedType.I1)]
+ public bool ResetVoiceDropFlag;
+
+ ///
+ /// Flush the amount of wavebuffer specified. This will result in the wavebuffer being skipped and marked played.
+ ///
+ /// This was added on REV5.
+ public byte FlushWaveBufferCount;
+
+ ///
+ /// Reserved/unused.
+ ///
+ private readonly ushort _reserved2;
+
+ ///
+ /// Change the behaviour of the voice.
+ ///
+ /// This was added on REV5.
+ public DecodingBehaviour DecodingBehaviourFlags;
+
+ ///
+ /// Change the Sample Rate Conversion (SRC) quality of the voice.
+ ///
+ /// This was added on REV8.
+ public SampleRateConversionQuality SrcQuality;
+
+ ///
+ /// This was previously used for opus codec support on the Audio Renderer and was removed on REV3.
+ ///
+ public uint ExternalContext;
+
+ ///
+ /// This was previously used for opus codec support on the Audio Renderer and was removed on REV3.
+ ///
+ public uint ExternalContextSize;
+
+ ///
+ /// Reserved/unused.
+ ///
+ private unsafe fixed uint _reserved3[2];
+ }
+}
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/VoiceOutStatus.cs b/src/Ryujinx.Audio/Renderer/Parameter/VoiceOutStatus.cs
index a7c749835..0ec864cdc 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/VoiceOutStatus.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/VoiceOutStatus.cs
@@ -1,3 +1,5 @@
+using Ryujinx.Audio.Renderer.Common;
+using Ryujinx.Audio.Renderer.Server;
using System.Runtime.InteropServices;
namespace Ryujinx.Audio.Renderer.Parameter
@@ -5,7 +7,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
///
/// Output information about a voice.
///
- /// See
+ /// See
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct VoiceOutStatus
{
@@ -13,7 +15,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
/// The total amount of samples that was played.
///
/// This is reset to 0 when a finishes playing and is set.
- /// This is reset to 0 when looping while is set.
+ /// This is reset to 0 when looping while is set.
public ulong PlayedSampleCount;
///
diff --git a/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs b/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs
index ee2f23479..188af8640 100644
--- a/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs
@@ -31,7 +31,7 @@ namespace Ryujinx.Audio.Renderer.Server
private AudioRendererRenderingDevice _renderingDevice;
private AudioRendererExecutionMode _executionMode;
private readonly IWritableEvent _systemEvent;
- private MemoryPoolState _dspMemoryPoolState;
+ private MemoryPoolInfo _dspMemoryPoolInfo;
private readonly VoiceContext _voiceContext;
private readonly MixContext _mixContext;
private readonly SinkContext _sinkContext;
@@ -40,13 +40,13 @@ namespace Ryujinx.Audio.Renderer.Server
private PerformanceManager _performanceManager;
private UpsamplerManager _upsamplerManager;
private bool _isActive;
- private BehaviourContext _behaviourContext;
+ private BehaviourInfo _behaviourInfo;
#pragma warning disable IDE0052 // Remove unread private member
private ulong _totalElapsedTicksUpdating;
private ulong _totalElapsedTicks;
#pragma warning restore IDE0052
private int _sessionId;
- private Memory _memoryPools;
+ private Memory _memoryPools;
private uint _sampleRate;
private uint _sampleCount;
@@ -84,7 +84,7 @@ namespace Ryujinx.Audio.Renderer.Server
public AudioRenderSystem(AudioRendererManager manager, IWritableEvent systemEvent)
{
_manager = manager;
- _dspMemoryPoolState = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp);
+ _dspMemoryPoolInfo = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Dsp);
_voiceContext = new VoiceContext();
_mixContext = new MixContext();
_sinkContext = new SinkContext();
@@ -93,7 +93,7 @@ namespace Ryujinx.Audio.Renderer.Server
_commandProcessingTimeEstimator = null;
_systemEvent = systemEvent;
- _behaviourContext = new BehaviourContext();
+ _behaviourInfo = new BehaviourInfo();
_totalElapsedTicksUpdating = 0;
_sessionId = 0;
@@ -110,7 +110,7 @@ namespace Ryujinx.Audio.Renderer.Server
ulong appletResourceId,
IVirtualMemoryManager memoryManager)
{
- if (!BehaviourContext.CheckValidRevision(parameter.Revision))
+ if (!BehaviourInfo.CheckValidRevision(parameter.Revision))
{
return ResultCode.OperationFailed;
}
@@ -122,9 +122,9 @@ namespace Ryujinx.Audio.Renderer.Server
Debug.Assert(parameter.RenderingDevice == AudioRendererRenderingDevice.Dsp && parameter.ExecutionMode == AudioRendererExecutionMode.Auto);
- Logger.Info?.Print(LogClass.AudioRenderer, $"Initializing with REV{BehaviourContext.GetRevisionNumber(parameter.Revision)}");
+ Logger.Info?.Print(LogClass.AudioRenderer, $"Initializing with REV{BehaviourInfo.GetRevisionNumber(parameter.Revision)}");
- _behaviourContext.SetUserRevision(parameter.Revision);
+ _behaviourInfo.SetUserRevision(parameter.Revision);
_sampleRate = parameter.SampleRate;
_sampleCount = parameter.SampleCount;
@@ -151,7 +151,7 @@ namespace Ryujinx.Audio.Renderer.Server
workBufferAllocator = new WorkBufferAllocator(workBufferMemory);
PoolMapper poolMapper = new(processHandle, false);
- poolMapper.InitializeSystemPool(ref _dspMemoryPoolState, workBuffer, workBufferSize);
+ poolMapper.InitializeSystemPool(ref _dspMemoryPoolInfo, workBuffer, workBufferSize);
_mixBuffer = workBufferAllocator.Allocate(_sampleCount * (_voiceChannelCountMax + _mixBufferCount), 0x10);
@@ -176,7 +176,7 @@ namespace Ryujinx.Audio.Renderer.Server
Memory splitterBqfStates = Memory.Empty;
- if (_behaviourContext.IsBiquadFilterParameterForSplitterEnabled() &&
+ if (_behaviourInfo.IsBiquadFilterParameterForSplitterEnabled() &&
parameter.SplitterCount > 0 &&
parameter.SplitterDestinationCount > 0)
{
@@ -191,23 +191,23 @@ namespace Ryujinx.Audio.Renderer.Server
}
// Invalidate DSP cache on what was currently allocated with workBuffer.
- AudioProcessorMemoryManager.InvalidateDspCache(_dspMemoryPoolState.Translate(workBuffer, workBufferAllocator.Offset), workBufferAllocator.Offset);
+ AudioProcessorMemoryManager.InvalidateDspCache(_dspMemoryPoolInfo.Translate(workBuffer, workBufferAllocator.Offset), workBufferAllocator.Offset);
Debug.Assert((workBufferAllocator.Offset % Constants.BufferAlignment) == 0);
- Memory voices = workBufferAllocator.Allocate(parameter.VoiceCount, VoiceState.Alignment);
+ Memory voices = workBufferAllocator.Allocate(parameter.VoiceCount, VoiceInfo.Alignment);
if (voices.IsEmpty)
{
return ResultCode.WorkBufferTooSmall;
}
- foreach (ref VoiceState voice in voices.Span)
+ foreach (ref VoiceInfo voice in voices.Span)
{
voice.Initialize();
}
- // A pain to handle as we can't have VoiceState*, use indices to be a bit more safe
+ // A pain to handle as we can't have VoiceInfo*, use indices to be a bit more safe
Memory sortedVoices = workBufferAllocator.Allocate(parameter.VoiceCount, 0x10);
if (sortedVoices.IsEmpty)
@@ -233,16 +233,16 @@ namespace Ryujinx.Audio.Renderer.Server
voiceChannelResource.IsUsed = false;
}
- Memory voiceUpdateStates = workBufferAllocator.Allocate(parameter.VoiceCount, VoiceUpdateState.Align);
+ Memory voiceStates = workBufferAllocator.Allocate(parameter.VoiceCount, VoiceState.Align);
- if (voiceUpdateStates.IsEmpty)
+ if (voiceStates.IsEmpty)
{
return ResultCode.WorkBufferTooSmall;
}
uint mixesCount = parameter.SubMixBufferCount + 1;
- Memory mixes = workBufferAllocator.Allocate(mixesCount, MixState.Alignment);
+ Memory mixes = workBufferAllocator.Allocate(mixesCount, MixInfo.Alignment);
if (mixes.IsEmpty)
{
@@ -251,18 +251,18 @@ namespace Ryujinx.Audio.Renderer.Server
if (parameter.EffectCount == 0)
{
- foreach (ref MixState mix in mixes.Span)
+ foreach (ref MixInfo mix in mixes.Span)
{
- mix = new MixState(Memory.Empty, ref _behaviourContext);
+ mix = new MixInfo(Memory.Empty, ref _behaviourInfo);
}
}
else
{
Memory effectProcessingOrderArray = workBufferAllocator.Allocate(parameter.EffectCount * mixesCount, 0x10);
- foreach (ref MixState mix in mixes.Span)
+ foreach (ref MixInfo mix in mixes.Span)
{
- mix = new MixState(effectProcessingOrderArray[..(int)parameter.EffectCount], ref _behaviourContext);
+ mix = new MixInfo(effectProcessingOrderArray[..(int)parameter.EffectCount], ref _behaviourInfo);
effectProcessingOrderArray = effectProcessingOrderArray[(int)parameter.EffectCount..];
}
@@ -271,20 +271,20 @@ namespace Ryujinx.Audio.Renderer.Server
// Initialize the final mix id
mixes.Span[0].MixId = Constants.FinalMixId;
- Memory sortedMixesState = workBufferAllocator.Allocate(mixesCount, 0x10);
+ Memory sortedMixesInfo = workBufferAllocator.Allocate(mixesCount, 0x10);
- if (sortedMixesState.IsEmpty)
+ if (sortedMixesInfo.IsEmpty)
{
return ResultCode.WorkBufferTooSmall;
}
// Clear memory (use -1 as it's an invalid index)
- sortedMixesState.Span.Fill(-1);
+ sortedMixesInfo.Span.Fill(-1);
Memory nodeStatesWorkBuffer = Memory.Empty;
Memory edgeMatrixWorkBuffer = Memory.Empty;
- if (_behaviourContext.IsSplitterSupported())
+ if (_behaviourInfo.IsSplitterSupported())
{
nodeStatesWorkBuffer = workBufferAllocator.Allocate((uint)NodeStates.GetWorkBufferSize((int)mixesCount), 1);
edgeMatrixWorkBuffer = workBufferAllocator.Allocate((uint)EdgeMatrix.GetWorkBufferSize((int)mixesCount), 1);
@@ -295,21 +295,21 @@ namespace Ryujinx.Audio.Renderer.Server
}
}
- _mixContext.Initialize(sortedMixesState, mixes, nodeStatesWorkBuffer, edgeMatrixWorkBuffer);
+ _mixContext.Initialize(sortedMixesInfo, mixes, nodeStatesWorkBuffer, edgeMatrixWorkBuffer);
- _memoryPools = workBufferAllocator.Allocate(_memoryPoolCount, MemoryPoolState.Alignment);
+ _memoryPools = workBufferAllocator.Allocate(_memoryPoolCount, MemoryPoolInfo.Alignment);
if (_memoryPools.IsEmpty)
{
return ResultCode.WorkBufferTooSmall;
}
- foreach (ref MemoryPoolState state in _memoryPools.Span)
+ foreach (ref MemoryPoolInfo info in _memoryPools.Span)
{
- state = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ info = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
}
- if (!_splitterContext.Initialize(ref _behaviourContext, ref parameter, workBufferAllocator, splitterBqfStates))
+ if (!_splitterContext.Initialize(ref _behaviourInfo, ref parameter, workBufferAllocator, splitterBqfStates))
{
return ResultCode.WorkBufferTooSmall;
}
@@ -318,21 +318,21 @@ namespace Ryujinx.Audio.Renderer.Server
_upsamplerManager = new UpsamplerManager(upSamplerWorkBuffer, _upsamplerCount);
- _effectContext.Initialize(parameter.EffectCount, _behaviourContext.IsEffectInfoVersion2Supported() ? parameter.EffectCount : 0);
+ _effectContext.Initialize(parameter.EffectCount, _behaviourInfo.IsEffectInfoVersion2Supported() ? parameter.EffectCount : 0);
_sinkContext.Initialize(parameter.SinkCount);
- Memory voiceUpdateStatesDsp = workBufferAllocator.Allocate(parameter.VoiceCount, VoiceUpdateState.Align);
+ Memory voiceStatesDsp = workBufferAllocator.Allocate(parameter.VoiceCount, VoiceState.Align);
- if (voiceUpdateStatesDsp.IsEmpty)
+ if (voiceStatesDsp.IsEmpty)
{
return ResultCode.WorkBufferTooSmall;
}
- _voiceContext.Initialize(sortedVoices, voices, voiceChannelResources, voiceUpdateStates, voiceUpdateStatesDsp, parameter.VoiceCount);
+ _voiceContext.Initialize(sortedVoices, voices, voiceChannelResources, voiceStates, voiceStatesDsp, parameter.VoiceCount);
if (parameter.PerformanceMetricFramesCount > 0)
{
- ulong performanceBufferSize = PerformanceManager.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter, ref _behaviourContext) * (parameter.PerformanceMetricFramesCount + 1) + 0xC;
+ ulong performanceBufferSize = PerformanceManager.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter, ref _behaviourInfo) * (parameter.PerformanceMetricFramesCount + 1) + 0xC;
_performanceBuffer = workBufferAllocator.Allocate(performanceBufferSize, Constants.BufferAlignment);
@@ -341,7 +341,7 @@ namespace Ryujinx.Audio.Renderer.Server
return ResultCode.WorkBufferTooSmall;
}
- _performanceManager = PerformanceManager.Create(_performanceBuffer, ref parameter, _behaviourContext);
+ _performanceManager = PerformanceManager.Create(_performanceBuffer, ref parameter, _behaviourInfo);
}
else
{
@@ -359,14 +359,14 @@ namespace Ryujinx.Audio.Renderer.Server
_elapsedFrameCount = 0;
_voiceDropParameter = 1.0f;
- _commandProcessingTimeEstimator = _behaviourContext.GetCommandProcessingTimeEstimatorVersion() switch
+ _commandProcessingTimeEstimator = _behaviourInfo.GetCommandProcessingTimeEstimatorVersion() switch
{
1 => new CommandProcessingTimeEstimatorVersion1(_sampleCount, _mixBufferCount),
2 => new CommandProcessingTimeEstimatorVersion2(_sampleCount, _mixBufferCount),
3 => new CommandProcessingTimeEstimatorVersion3(_sampleCount, _mixBufferCount),
4 => new CommandProcessingTimeEstimatorVersion4(_sampleCount, _mixBufferCount),
5 => new CommandProcessingTimeEstimatorVersion5(_sampleCount, _mixBufferCount),
- _ => throw new NotImplementedException($"Unsupported processing time estimator version {_behaviourContext.GetCommandProcessingTimeEstimatorVersion()}."),
+ _ => throw new NotImplementedException($"Unsupported processing time estimator version {_behaviourInfo.GetCommandProcessingTimeEstimatorVersion()}."),
};
return ResultCode.Success;
@@ -411,11 +411,11 @@ namespace Ryujinx.Audio.Renderer.Server
output.Span.Clear();
- StateUpdater stateUpdater = new(input, output, _processHandle, _behaviourContext);
+ StateUpdater stateUpdater = new(input, output, _processHandle, _behaviourInfo);
ResultCode result;
- result = stateUpdater.UpdateBehaviourContext();
+ result = stateUpdater.UpdateBehaviourInfo();
if (result != ResultCode.Success)
{
@@ -436,9 +436,16 @@ namespace Ryujinx.Audio.Renderer.Server
return result;
}
- PoolMapper poolMapper = new(_processHandle, _memoryPools, _behaviourContext.IsMemoryPoolForceMappingEnabled());
+ PoolMapper poolMapper = new(_processHandle, _memoryPools, _behaviourInfo.IsMemoryPoolForceMappingEnabled());
- result = stateUpdater.UpdateVoices(_voiceContext, poolMapper);
+ if (_behaviourInfo.IsBiquadFilterParameterFloatSupported())
+ {
+ result = stateUpdater.UpdateVoices2(_voiceContext, poolMapper);
+ }
+ else
+ {
+ result = stateUpdater.UpdateVoices1(_voiceContext, poolMapper);
+ }
if (result != ResultCode.Success)
{
@@ -452,7 +459,7 @@ namespace Ryujinx.Audio.Renderer.Server
return result;
}
- if (_behaviourContext.IsSplitterSupported())
+ if (_behaviourInfo.IsSplitterSupported())
{
result = stateUpdater.UpdateSplitter(_splitterContext);
@@ -490,7 +497,7 @@ namespace Ryujinx.Audio.Renderer.Server
return result;
}
- if (_behaviourContext.IsElapsedFrameCountSupported())
+ if (_behaviourInfo.IsElapsedFrameCountSupported())
{
result = stateUpdater.UpdateRendererInfo(_elapsedFrameCount);
@@ -557,7 +564,7 @@ namespace Ryujinx.Audio.Renderer.Server
break;
}
- ref VoiceState voice = ref _voiceContext.GetState(NodeIdHelper.GetBase(targetNodeId));
+ ref VoiceInfo voice = ref _voiceContext.GetState(NodeIdHelper.GetBase(targetNodeId));
if (voice.Priority == Constants.VoiceHighestPriority)
{
@@ -646,7 +653,7 @@ namespace Ryujinx.Audio.Renderer.Server
_voiceContext.UpdateForCommandGeneration();
- if (_behaviourContext.IsEffectInfoVersion2Supported())
+ if (_behaviourInfo.IsEffectInfoVersion2Supported())
{
_effectContext.UpdateResultStateForCommandGeneration();
}
@@ -661,7 +668,7 @@ namespace Ryujinx.Audio.Renderer.Server
private int GetMaxAllocatedTimeForDsp()
{
- return (int)(Constants.AudioProcessorMaxUpdateTimePerSessions * _behaviourContext.GetAudioRendererProcessingTimeLimit() * (GetRenderingTimeLimit() / 100.0f));
+ return (int)(Constants.AudioProcessorMaxUpdateTimePerSessions * _behaviourInfo.GetAudioRendererProcessingTimeLimit() * (GetRenderingTimeLimit() / 100.0f));
}
public void SendCommands()
@@ -736,7 +743,7 @@ namespace Ryujinx.Audio.Renderer.Server
return new RendererSystemContext
{
ChannelCount = _manager.Processor.OutputDevices[_sessionId].GetChannelCount(),
- BehaviourContext = _behaviourContext,
+ BehaviourInfo = _behaviourInfo,
DepopBuffer = _depopBuffer,
MixBufferCount = GetMixBufferCount(),
SessionId = _sessionId,
@@ -751,9 +758,9 @@ namespace Ryujinx.Audio.Renderer.Server
public static ulong GetWorkBufferSize(ref AudioRendererConfiguration parameter)
{
- BehaviourContext behaviourContext = new();
+ BehaviourInfo behaviourInfo = new();
- behaviourContext.SetUserRevision(parameter.Revision);
+ behaviourInfo.SetUserRevision(parameter.Revision);
uint mixesCount = parameter.SubMixBufferCount + 1;
@@ -771,28 +778,28 @@ namespace Ryujinx.Audio.Renderer.Server
size = WorkBufferAllocator.GetTargetSize(size, BitUtils.AlignUp(parameter.MixBufferCount, Constants.BufferAlignment), Constants.BufferAlignment);
// Voice
- size = WorkBufferAllocator.GetTargetSize(size, parameter.VoiceCount, VoiceState.Alignment);
+ size = WorkBufferAllocator.GetTargetSize(size, parameter.VoiceCount, VoiceInfo.Alignment);
size = WorkBufferAllocator.GetTargetSize(size, parameter.VoiceCount, 0x10);
size = WorkBufferAllocator.GetTargetSize(size, parameter.VoiceCount, VoiceChannelResource.Alignment);
- size = WorkBufferAllocator.GetTargetSize(size, parameter.VoiceCount, VoiceUpdateState.Align);
+ size = WorkBufferAllocator.GetTargetSize(size, parameter.VoiceCount, VoiceState.Align);
// Mix
- size = WorkBufferAllocator.GetTargetSize(size, mixesCount, MixState.Alignment);
+ size = WorkBufferAllocator.GetTargetSize(size, mixesCount, MixInfo.Alignment);
size = WorkBufferAllocator.GetTargetSize(size, parameter.EffectCount * mixesCount, 0x10);
size = WorkBufferAllocator.GetTargetSize(size, mixesCount, 0x10);
- if (behaviourContext.IsSplitterSupported())
+ if (behaviourInfo.IsSplitterSupported())
{
size += (ulong)BitUtils.AlignUp(NodeStates.GetWorkBufferSize((int)mixesCount) + EdgeMatrix.GetWorkBufferSize((int)mixesCount), 0x10);
}
// Memory Pool
- size = WorkBufferAllocator.GetTargetSize(size, memoryPoolCount, MemoryPoolState.Alignment);
+ size = WorkBufferAllocator.GetTargetSize(size, memoryPoolCount, MemoryPoolInfo.Alignment);
// Splitter
- size = SplitterContext.GetWorkBufferSize(size, ref behaviourContext, ref parameter);
+ size = SplitterContext.GetWorkBufferSize(size, ref behaviourInfo, ref parameter);
- if (behaviourContext.IsBiquadFilterParameterForSplitterEnabled() &&
+ if (behaviourInfo.IsBiquadFilterParameterForSplitterEnabled() &&
parameter.SplitterCount > 0 &&
parameter.SplitterDestinationCount > 0)
{
@@ -800,12 +807,12 @@ namespace Ryujinx.Audio.Renderer.Server
}
// DSP Voice
- size = WorkBufferAllocator.GetTargetSize(size, parameter.VoiceCount, VoiceUpdateState.Align);
+ size = WorkBufferAllocator.GetTargetSize(size, parameter.VoiceCount, VoiceState.Align);
// Performance
if (parameter.PerformanceMetricFramesCount > 0)
{
- ulong performanceMetricsPerFramesSize = PerformanceManager.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter, ref behaviourContext) * (parameter.PerformanceMetricFramesCount + 1) + 0xC;
+ ulong performanceMetricsPerFramesSize = PerformanceManager.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter, ref behaviourInfo) * (parameter.PerformanceMetricFramesCount + 1) + 0xC;
size += BitUtils.AlignUp(performanceMetricsPerFramesSize, Constants.PerformanceMetricsPerFramesSizeAlignment);
}
@@ -847,13 +854,13 @@ namespace Ryujinx.Audio.Renderer.Server
}
PoolMapper mapper = new(_processHandle, false);
- mapper.Unmap(ref _dspMemoryPoolState);
+ mapper.Unmap(ref _dspMemoryPoolInfo);
PoolMapper.ClearUsageState(_memoryPools);
for (int i = 0; i < _memoryPoolCount; i++)
{
- ref MemoryPoolState memoryPool = ref _memoryPools.Span[i];
+ ref MemoryPoolInfo memoryPool = ref _memoryPools.Span[i];
if (memoryPool.IsMapped())
{
@@ -875,7 +882,7 @@ namespace Ryujinx.Audio.Renderer.Server
public void SetVoiceDropParameter(float voiceDropParameter)
{
- _voiceDropParameter = Math.Clamp(voiceDropParameter, 0.0f, 2.0f);
+ _voiceDropParameter = Math.Clamp(voiceDropParameter, 0.0f, 4.0f);
}
public float GetVoiceDropParameter()
diff --git a/src/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs b/src/Ryujinx.Audio/Renderer/Server/BehaviourInfo.cs
similarity index 89%
rename from src/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs
rename to src/Ryujinx.Audio/Renderer/Server/BehaviourInfo.cs
index f725eb9f3..04463e876 100644
--- a/src/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/BehaviourInfo.cs
@@ -1,3 +1,5 @@
+using Ryujinx.Audio.Renderer.Parameter;
+using Ryujinx.Common.Memory;
using System;
using System.Buffers;
using System.Diagnostics;
@@ -9,7 +11,7 @@ namespace Ryujinx.Audio.Renderer.Server
/// Behaviour context.
///
/// This handles features based on the audio renderer revision provided by the user.
- public class BehaviourContext
+ public class BehaviourInfo
{
///
/// The base magic of the Audio Renderer revision.
@@ -40,7 +42,7 @@ namespace Ryujinx.Audio.Renderer.Server
public const int Revision4 = 4 << 24;
///
- /// REV5: , were added to voice.
+ /// REV5: , were added to voice.
/// A new performance frame format (version 2) was added with support for more information about DSP timing.
/// was added to supply the count of update done sent to the DSP.
/// A new version of the command estimator was added to address timing changes caused by the voice changes.
@@ -64,7 +66,7 @@ namespace Ryujinx.Audio.Renderer.Server
///
/// REV8:
/// Wavebuffer was changed to support more control over loop (you can now specify where to start and end a loop, and how many times to loop).
- /// was added (see for more info).
+ /// was added (see for more info).
/// Final leftovers of the codec system were removed.
/// support was added.
/// A new version of the command estimator was added to address timing changes caused by the voice and command changes.
@@ -115,16 +117,27 @@ namespace Ryujinx.Audio.Renderer.Server
///
/// This was added in system update 18.0.0
public const int Revision13 = 13 << 24;
+
+ ///
+ /// REV14:
+ /// Fixes the Depop Bug.
+ ///
+ ///
+ /// This was added in system update 19.0.0
+ public const int Revision14 = 14 << 24;
+
+ ///
+ /// REV15:
+ /// Support for float coefficients in biquad filters
+ ///
+ ///
+ /// This was added in system update 19.0.0
+ public const int Revision15 = 15 << 24;
///
/// Last revision supported by the implementation.
///
- public const int LastRevision = Revision13;
-
- ///
- /// Target revision magic supported by the implementation.
- ///
- public const int ProcessRevision = BaseRevisionMagic + LastRevision;
+ public const int LastRevision = Revision15;
///
/// Get the revision number from the revision magic.
@@ -133,15 +146,25 @@ namespace Ryujinx.Audio.Renderer.Server
/// The revision number.
public static int GetRevisionNumber(int revision) => (revision - BaseRevisionMagic) >> 24;
+ ///
+ /// Target revision magic supported by the implementation.
+ ///
+ public const int ProcessRevision = BaseRevisionMagic + LastRevision;
+
///
/// Current active revision.
///
public int UserRevision { get; private set; }
+
+ ///
+ /// Current flags of the .
+ ///
+ private ulong _flags;
///
/// Error storage.
///
- private readonly ErrorInfo[] _errorInfos;
+ private readonly Array10 _errorInfos;
///
/// Current position in the array.
@@ -149,17 +172,12 @@ namespace Ryujinx.Audio.Renderer.Server
private uint _errorIndex;
///
- /// Current flags of the .
+ /// Create a new instance of .
///
- private ulong _flags;
-
- ///
- /// Create a new instance of .
- ///
- public BehaviourContext()
+ public BehaviourInfo()
{
UserRevision = 0;
- _errorInfos = new ErrorInfo[Constants.MaxErrorInfos];
+ _errorInfos = new Array10();
_errorIndex = 0;
}
@@ -173,7 +191,7 @@ namespace Ryujinx.Audio.Renderer.Server
}
///
- /// Update flags of the .
+ /// Update flags of the .
///
/// The new flags.
public void UpdateFlags(ulong flags)
@@ -321,9 +339,9 @@ namespace Ryujinx.Audio.Renderer.Server
}
///
- /// Check if the audio renderer should support .
+ /// Check if the audio renderer should support .
///
- /// True if the audio renderer should support .
+ /// True if the audio renderer should support .
public bool IsDecodingBehaviourFlagSupported()
{
return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision5);
@@ -400,6 +418,24 @@ namespace Ryujinx.Audio.Renderer.Server
{
return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision13);
}
+
+ ///
+ /// Check if the audio renderer should support the depop bug fix.
+ ///
+ /// True if the audio renderer supports the depop bug fix
+ public bool IsSplitterDepopBugFixEnabled()
+ {
+ return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision14);
+ }
+
+ ///
+ /// Check if the audio renderer should support biquad filter with float coefficients.
+ ///
+ /// True if the audio renderer support biquad filter with float coefficients
+ public bool IsBiquadFilterParameterFloatSupported()
+ {
+ return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision15);
+ }
///
/// Get the version of the .
@@ -440,7 +476,7 @@ namespace Ryujinx.Audio.Renderer.Server
if (_errorIndex <= Constants.MaxErrorInfos - 1)
{
- _errorInfos[_errorIndex++] = errorInfo;
+ _errorInfos[(int)_errorIndex++] = errorInfo;
}
}
@@ -457,22 +493,8 @@ namespace Ryujinx.Audio.Renderer.Server
}
errorCount = Math.Min(_errorIndex, Constants.MaxErrorInfos);
-
- for (int i = 0; i < Constants.MaxErrorInfos; i++)
- {
- if (i < errorCount)
- {
- errorInfos[i] = _errorInfos[i];
- }
- else
- {
- errorInfos[i] = new ErrorInfo
- {
- ErrorCode = 0,
- ExtraErrorInfo = 0,
- };
- }
- }
+
+ _errorInfos.AsSpan().CopyTo(errorInfos);
}
///
diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs b/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs
index d65897e45..62380f926 100644
--- a/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs
@@ -5,9 +5,11 @@ using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Audio.Renderer.Parameter.Effect;
using Ryujinx.Audio.Renderer.Server.Performance;
using Ryujinx.Audio.Renderer.Server.Sink;
+using Ryujinx.Audio.Renderer.Server.Splitter;
using Ryujinx.Audio.Renderer.Server.Upsampler;
using Ryujinx.Audio.Renderer.Server.Voice;
using System;
+using System.Runtime.CompilerServices;
using CpuAddress = System.UInt64;
namespace Ryujinx.Audio.Renderer.Server
@@ -77,7 +79,7 @@ namespace Ryujinx.Audio.Renderer.Server
/// The target buffer offset.
/// The node id associated to this command.
/// Set to true if the voice was playing previously.
- public void GenerateDepopPrepare(Memory state, Memory depopBuffer, uint bufferCount, uint bufferOffset, int nodeId, bool wasPlaying)
+ public void GenerateDepopPrepare(Memory state, Memory depopBuffer, uint bufferCount, uint bufferOffset, int nodeId, bool wasPlaying)
{
DepopPrepareCommand command = new(state, depopBuffer, bufferCount, bufferOffset, nodeId, wasPlaying);
@@ -120,14 +122,14 @@ namespace Ryujinx.Audio.Renderer.Server
///
/// Create a new .
///
- /// The to generate the command from.
- /// The to generate the command from.
+ /// The to generate the command from.
+ /// The to generate the command from.
/// The output buffer index to use.
/// The target channel index.
/// The node id associated to this command.
- public void GenerateDataSourceVersion2(ref VoiceState voiceState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
+ public void GenerateDataSourceVersion2(ref VoiceInfo voiceInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
{
- DataSourceVersion2Command command = new(ref voiceState, state, outputBufferIndex, channelIndex, nodeId);
+ DataSourceVersion2Command command = new(ref voiceInfo, state, outputBufferIndex, channelIndex, nodeId);
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
@@ -137,14 +139,14 @@ namespace Ryujinx.Audio.Renderer.Server
///
/// Create a new .
///
- /// The to generate the command from.
- /// The to generate the command from.
+ /// The to generate the command from.
+ /// The to generate the command from.
/// The output buffer index to use.
/// The target channel index.
/// The node id associated to this command.
- public void GeneratePcmInt16DataSourceVersion1(ref VoiceState voiceState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
+ public void GeneratePcmInt16DataSourceVersion1(ref VoiceInfo voiceInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
{
- PcmInt16DataSourceCommandVersion1 command = new(ref voiceState, state, outputBufferIndex, channelIndex, nodeId);
+ PcmInt16DataSourceCommandVersion1 command = new(ref voiceInfo, state, outputBufferIndex, channelIndex, nodeId);
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
@@ -154,14 +156,14 @@ namespace Ryujinx.Audio.Renderer.Server
///
/// Create a new .
///
- /// The to generate the command from.
- /// The to generate the command from.
+ /// The to generate the command from.
+ /// The to generate the command from.
/// The output buffer index to use.
/// The target channel index.
/// The node id associated to this command.
- public void GeneratePcmFloatDataSourceVersion1(ref VoiceState voiceState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
+ public void GeneratePcmFloatDataSourceVersion1(ref VoiceInfo voiceInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
{
- PcmFloatDataSourceCommandVersion1 command = new(ref voiceState, state, outputBufferIndex, channelIndex, nodeId);
+ PcmFloatDataSourceCommandVersion1 command = new(ref voiceInfo, state, outputBufferIndex, channelIndex, nodeId);
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
@@ -171,13 +173,13 @@ namespace Ryujinx.Audio.Renderer.Server
///
/// Create a new .
///
- /// The to generate the command from.
- /// The to generate the command from.
+ /// The to generate the command from.
+ /// The to generate the command from.
/// The output buffer index to use.
/// The node id associated to this command.
- public void GenerateAdpcmDataSourceVersion1(ref VoiceState voiceState, Memory state, ushort outputBufferIndex, int nodeId)
+ public void GenerateAdpcmDataSourceVersion1(ref VoiceInfo voiceInfo, Memory state, ushort outputBufferIndex, int nodeId)
{
- AdpcmDataSourceCommandVersion1 command = new(ref voiceState, state, outputBufferIndex, nodeId);
+ AdpcmDataSourceCommandVersion1 command = new(ref voiceInfo, state, outputBufferIndex, nodeId);
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
@@ -194,7 +196,7 @@ namespace Ryujinx.Audio.Renderer.Server
/// The output buffer offset.
/// Set to true if the biquad filter state needs to be initialized.
/// The node id associated to this command.
- public void GenerateBiquadFilter(int baseIndex, ref BiquadFilterParameter filter, Memory biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, bool needInitialization, int nodeId)
+ public void GenerateBiquadFilter(int baseIndex, ref BiquadFilterParameter2 filter, Memory biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, bool needInitialization, int nodeId)
{
BiquadFilterCommand command = new(baseIndex, ref filter, biquadFilterStateMemory, inputBufferOffset, outputBufferOffset, needInitialization, nodeId);
@@ -213,7 +215,7 @@ namespace Ryujinx.Audio.Renderer.Server
/// The output buffer offset.
/// Set to true if the biquad filter state is initialized.
/// The node id associated to this command.
- public void GenerateMultiTapBiquadFilter(int baseIndex, ReadOnlySpan filters, Memory biquadFilterStatesMemory, int inputBufferOffset, int outputBufferOffset, ReadOnlySpan isInitialized, int nodeId)
+ public void GenerateMultiTapBiquadFilter(int baseIndex, ReadOnlySpan filters, Memory biquadFilterStatesMemory, int inputBufferOffset, int outputBufferOffset, ReadOnlySpan isInitialized, int nodeId)
{
MultiTapBiquadFilterCommand command = new(baseIndex, filters, biquadFilterStatesMemory, inputBufferOffset, outputBufferOffset, isInitialized, nodeId);
@@ -230,9 +232,9 @@ namespace Ryujinx.Audio.Renderer.Server
/// The base output index.
/// The previous volume.
/// The new volume.
- /// The to generate the command from.
+ /// The to generate the command from.
/// The node id associated to this command.
- public void GenerateMixRampGrouped(uint mixBufferCount, uint inputBufferIndex, uint outputBufferIndex, ReadOnlySpan previousVolume, ReadOnlySpan volume, Memory state, int nodeId)
+ public void GenerateMixRampGrouped(uint mixBufferCount, uint inputBufferIndex, uint outputBufferIndex, ReadOnlySpan previousVolume, ReadOnlySpan volume, Memory state, int nodeId)
{
MixRampGroupedCommand command = new(mixBufferCount, inputBufferIndex, outputBufferIndex, previousVolume, volume, state, nodeId);
@@ -248,10 +250,10 @@ namespace Ryujinx.Audio.Renderer.Server
/// The new volume.
/// The input buffer index.
/// The output buffer index.
- /// The index in the array to store the ramped sample.
- /// The to generate the command from.
+ /// The index in the array to store the ramped sample.
+ /// The to generate the command from.
/// The node id associated to this command.
- public void GenerateMixRamp(float previousVolume, float volume, uint inputBufferIndex, uint outputBufferIndex, int lastSampleIndex, Memory state, int nodeId)
+ public void GenerateMixRamp(float previousVolume, float volume, uint inputBufferIndex, uint outputBufferIndex, int lastSampleIndex, Memory state, int nodeId)
{
MixRampCommand command = new(previousVolume, volume, inputBufferIndex, outputBufferIndex, lastSampleIndex, state, nodeId);
@@ -267,8 +269,8 @@ namespace Ryujinx.Audio.Renderer.Server
/// The new volume.
/// The input buffer index.
/// The output buffer index.
- /// The index in the array to store the ramped sample.
- /// The to generate the command from.
+ /// The index in the array to store the ramped sample.
+ /// The to generate the command from.
/// The biquad filter parameter.
/// The biquad state.
/// The previous biquad state.
@@ -282,8 +284,8 @@ namespace Ryujinx.Audio.Renderer.Server
uint inputBufferIndex,
uint outputBufferIndex,
int lastSampleIndex,
- Memory state,
- ref BiquadFilterParameter filter,
+ Memory state,
+ ref BiquadFilterParameter2 filter,
Memory biquadFilterState,
Memory previousBiquadFilterState,
bool needInitialization,
@@ -318,8 +320,8 @@ namespace Ryujinx.Audio.Renderer.Server
/// The new volume.
/// The input buffer index.
/// The output buffer index.
- /// The index in the array to store the ramped sample.
- /// The to generate the command from.
+ /// The index in the array to store the ramped sample.
+ /// The to generate the command from.
/// First biquad filter parameter.
/// Second biquad filter parameter.
/// First biquad state.
@@ -337,9 +339,9 @@ namespace Ryujinx.Audio.Renderer.Server
uint inputBufferIndex,
uint outputBufferIndex,
int lastSampleIndex,
- Memory state,
- ref BiquadFilterParameter filter0,
- ref BiquadFilterParameter filter1,
+ Memory state,
+ ref BiquadFilterParameter2 filter0,
+ ref BiquadFilterParameter2 filter1,
Memory biquadFilterState0,
Memory biquadFilterState1,
Memory previousBiquadFilterState0,
@@ -654,14 +656,14 @@ namespace Ryujinx.Audio.Renderer.Server
/// Create a new .
///
/// The offset of the mix buffer.
- /// The associated.
+ /// The associated.
/// The total input count.
/// The input buffer mix offset.
/// The buffer count per sample.
/// The source sample count.
/// The source sample rate.
/// The node id associated to this command.
- public void GenerateUpsample(uint bufferOffset, UpsamplerState upsampler, uint inputCount, Span inputBufferOffset, uint bufferCountPerSample, uint sampleCount, uint sampleRate, int nodeId)
+ public void GenerateUpsample(uint bufferOffset, UpsamplerInfo upsampler, uint inputCount, Span inputBufferOffset, uint bufferCountPerSample, uint sampleCount, uint sampleRate, int nodeId)
{
UpsampleCommand command = new(bufferOffset, upsampler, inputCount, inputBufferOffset, bufferCountPerSample, sampleCount, sampleRate, nodeId);
@@ -686,5 +688,23 @@ namespace Ryujinx.Audio.Renderer.Server
AddCommand(command);
}
+
+ public void GenerateFillBuffer(SplitterDestination destination, float value, int length, int nodeId)
+ {
+ FillBufferCommand command;
+
+ if (Unsafe.IsNullRef(ref destination.GetV2RefOrNull()))
+ {
+ command = new(destination.GetV1RefOrNull(), length, value, nodeId);
+ }
+ else
+ {
+ command = new(destination.GetV2RefOrNull(), length, value, nodeId);
+ }
+
+ command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
+
+ AddCommand(command);
+ }
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs b/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs
index 519de9b65..c88aa51f2 100644
--- a/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs
@@ -1,5 +1,6 @@
using Ryujinx.Audio.Common;
using Ryujinx.Audio.Renderer.Common;
+using Ryujinx.Audio.Renderer.Dsp;
using Ryujinx.Audio.Renderer.Dsp.Command;
using Ryujinx.Audio.Renderer.Dsp.State;
using Ryujinx.Audio.Renderer.Parameter;
@@ -41,27 +42,27 @@ namespace Ryujinx.Audio.Renderer.Server
_commandBuffer.GenerateClearMixBuffer(Constants.InvalidNodeId);
}
- private void GenerateDataSource(ref VoiceState voiceState, Memory dspState, int channelIndex)
+ private void GenerateDataSource(ref VoiceInfo voiceInfo, Memory dspState, int channelIndex)
{
- if (voiceState.MixId != Constants.UnusedMixId)
+ if (voiceInfo.MixId != Constants.UnusedMixId)
{
- ref MixState mix = ref _mixContext.GetState(voiceState.MixId);
+ ref MixInfo mix = ref _mixContext.GetState(voiceInfo.MixId);
_commandBuffer.GenerateDepopPrepare(
dspState,
_rendererContext.DepopBuffer,
mix.BufferCount,
mix.BufferOffset,
- voiceState.NodeId,
- voiceState.WasPlaying);
+ voiceInfo.NodeId,
+ voiceInfo.WasPlaying);
}
- else if (voiceState.SplitterId != Constants.UnusedSplitterId)
+ else if (voiceInfo.SplitterId != Constants.UnusedSplitterId)
{
int destinationId = 0;
while (true)
{
- SplitterDestination destination = _splitterContext.GetDestination((int)voiceState.SplitterId, destinationId++);
+ SplitterDestination destination = _splitterContext.GetDestination((int)voiceInfo.SplitterId, destinationId++);
if (destination.IsNull)
{
@@ -74,15 +75,17 @@ namespace Ryujinx.Audio.Renderer.Server
if (mixId < _mixContext.GetCount() && mixId != Constants.UnusedSplitterIdInt)
{
- ref MixState mix = ref _mixContext.GetState(mixId);
+ ref MixInfo mix = ref _mixContext.GetState(mixId);
+
+ // _commandBuffer.GenerateFillBuffer();
_commandBuffer.GenerateDepopPrepare(
dspState,
_rendererContext.DepopBuffer,
mix.BufferCount,
mix.BufferOffset,
- voiceState.NodeId,
- voiceState.WasPlaying);
+ voiceInfo.NodeId,
+ voiceInfo.WasPlaying);
destination.MarkAsNeedToUpdateInternalState();
}
@@ -90,71 +93,71 @@ namespace Ryujinx.Audio.Renderer.Server
}
}
- if (!voiceState.WasPlaying)
+ if (!voiceInfo.WasPlaying)
{
- Debug.Assert(voiceState.SampleFormat != SampleFormat.Adpcm || channelIndex == 0);
+ Debug.Assert(voiceInfo.SampleFormat != SampleFormat.Adpcm || channelIndex == 0);
- if (_rendererContext.BehaviourContext.IsWaveBufferVersion2Supported())
+ if (_rendererContext.BehaviourInfo.IsWaveBufferVersion2Supported())
{
_commandBuffer.GenerateDataSourceVersion2(
- ref voiceState,
+ ref voiceInfo,
dspState,
(ushort)_rendererContext.MixBufferCount,
(ushort)channelIndex,
- voiceState.NodeId);
+ voiceInfo.NodeId);
}
else
{
- switch (voiceState.SampleFormat)
+ switch (voiceInfo.SampleFormat)
{
case SampleFormat.PcmInt16:
_commandBuffer.GeneratePcmInt16DataSourceVersion1(
- ref voiceState,
+ ref voiceInfo,
dspState,
(ushort)_rendererContext.MixBufferCount,
(ushort)channelIndex,
- voiceState.NodeId);
+ voiceInfo.NodeId);
break;
case SampleFormat.PcmFloat:
_commandBuffer.GeneratePcmFloatDataSourceVersion1(
- ref voiceState,
+ ref voiceInfo,
dspState,
(ushort)_rendererContext.MixBufferCount,
(ushort)channelIndex,
- voiceState.NodeId);
+ voiceInfo.NodeId);
break;
case SampleFormat.Adpcm:
_commandBuffer.GenerateAdpcmDataSourceVersion1(
- ref voiceState,
+ ref voiceInfo,
dspState,
(ushort)_rendererContext.MixBufferCount,
- voiceState.NodeId);
+ voiceInfo.NodeId);
break;
default:
- throw new NotImplementedException($"Unsupported data source {voiceState.SampleFormat}");
+ throw new NotImplementedException($"Unsupported data source {voiceInfo.SampleFormat}");
}
}
}
}
- private void GenerateBiquadFilterForVoice(ref VoiceState voiceState, Memory state, int baseIndex, int bufferOffset, int nodeId)
+ private void GenerateBiquadFilterForVoice(ref VoiceInfo voiceInfo, Memory state, int baseIndex, int bufferOffset, int nodeId)
{
- bool supportsOptimizedPath = _rendererContext.BehaviourContext.UseMultiTapBiquadFilterProcessing();
+ bool supportsOptimizedPath = _rendererContext.BehaviourInfo.UseMultiTapBiquadFilterProcessing();
- Span biquadFiltersSpan = voiceState.BiquadFilters.AsSpan();
+ Span biquadFiltersSpan = voiceInfo.BiquadFilters.AsSpan();
if (supportsOptimizedPath && biquadFiltersSpan[0].Enable && biquadFiltersSpan[1].Enable)
{
Memory biquadStateRawMemory = SpanMemoryManager.Cast(state)[..(Unsafe.SizeOf() * Constants.VoiceBiquadFilterCount)];
Memory stateMemory = SpanMemoryManager.Cast(biquadStateRawMemory);
- _commandBuffer.GenerateMultiTapBiquadFilter(baseIndex, biquadFiltersSpan, stateMemory, bufferOffset, bufferOffset, voiceState.BiquadFilterNeedInitialization, nodeId);
+ _commandBuffer.GenerateMultiTapBiquadFilter(baseIndex, biquadFiltersSpan, stateMemory, bufferOffset, bufferOffset, voiceInfo.BiquadFilterNeedInitialization, nodeId);
}
else
{
for (int i = 0; i < biquadFiltersSpan.Length; i++)
{
- ref BiquadFilterParameter filter = ref biquadFiltersSpan[i];
+ ref BiquadFilterParameter2 filter = ref biquadFiltersSpan[i];
if (filter.Enable)
{
@@ -167,7 +170,7 @@ namespace Ryujinx.Audio.Renderer.Server
stateMemory.Slice(i, 1),
bufferOffset,
bufferOffset,
- !voiceState.BiquadFilterNeedInitialization[i],
+ !voiceInfo.BiquadFilterNeedInitialization[i],
nodeId);
}
}
@@ -176,7 +179,7 @@ namespace Ryujinx.Audio.Renderer.Server
private void GenerateVoiceMixWithSplitter(
SplitterDestination destination,
- Memory state,
+ Memory state,
uint bufferOffset,
uint bufferCount,
uint bufferIndex,
@@ -185,8 +188,8 @@ namespace Ryujinx.Audio.Renderer.Server
ReadOnlySpan mixVolumes = destination.MixBufferVolume;
ReadOnlySpan previousMixVolumes = destination.PreviousMixBufferVolume;
- ref BiquadFilterParameter bqf0 = ref destination.GetBiquadFilterParameter(0);
- ref BiquadFilterParameter bqf1 = ref destination.GetBiquadFilterParameter(1);
+ ref BiquadFilterParameter2 bqf0 = ref destination.GetBiquadFilterParameter(0);
+ ref BiquadFilterParameter2 bqf1 = ref destination.GetBiquadFilterParameter(1);
Memory bqfState = _splitterContext.GetBiquadFilterState(destination);
@@ -270,7 +273,7 @@ namespace Ryujinx.Audio.Renderer.Server
private void GenerateVoiceMix(
ReadOnlySpan mixVolumes,
ReadOnlySpan previousMixVolumes,
- Memory state,
+ Memory state,
uint bufferOffset,
uint bufferCount,
uint bufferIndex,
@@ -309,27 +312,27 @@ namespace Ryujinx.Audio.Renderer.Server
}
}
- private void GenerateVoice(ref VoiceState voiceState)
+ private void GenerateVoice(ref VoiceInfo voiceInfo)
{
- int nodeId = voiceState.NodeId;
- uint channelsCount = voiceState.ChannelsCount;
+ int nodeId = voiceInfo.NodeId;
+ uint channelsCount = voiceInfo.ChannelsCount;
- Span channelResourceIdsSpan = voiceState.ChannelResourceIds.AsSpan();
- Span biquadFiltersSpan = voiceState.BiquadFilters.AsSpan();
+ Span channelResourceIdsSpan = voiceInfo.ChannelResourceIds.AsSpan();
+ Span biquadFiltersSpan = voiceInfo.BiquadFilters.AsSpan();
for (int channelIndex = 0; channelIndex < channelsCount; channelIndex++)
{
- Memory dspStateMemory = _voiceContext.GetUpdateStateForDsp(channelResourceIdsSpan[channelIndex]);
+ Memory dspStateMemory = _voiceContext.GetUpdateStateForDsp(channelResourceIdsSpan[channelIndex]);
ref VoiceChannelResource channelResource = ref _voiceContext.GetChannelResource(channelResourceIdsSpan[channelIndex]);
PerformanceDetailType dataSourceDetailType = PerformanceDetailType.Adpcm;
- if (voiceState.SampleFormat == SampleFormat.PcmInt16)
+ if (voiceInfo.SampleFormat == SampleFormat.PcmInt16)
{
dataSourceDetailType = PerformanceDetailType.PcmInt16;
}
- else if (voiceState.SampleFormat == SampleFormat.PcmFloat)
+ else if (voiceInfo.SampleFormat == SampleFormat.PcmFloat)
{
dataSourceDetailType = PerformanceDetailType.PcmFloat;
}
@@ -345,18 +348,18 @@ namespace Ryujinx.Audio.Renderer.Server
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
}
- GenerateDataSource(ref voiceState, dspStateMemory, channelIndex);
+ GenerateDataSource(ref voiceInfo, dspStateMemory, channelIndex);
if (performanceInitialized)
{
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.End, nodeId);
}
- if (voiceState.WasPlaying)
+ if (voiceInfo.WasPlaying)
{
- voiceState.PreviousVolume = 0.0f;
+ voiceInfo.PreviousVolume = 0.0f;
}
- else if (voiceState.HasAnyDestination())
+ else if (voiceInfo.HasAnyDestination())
{
performanceInitialized = false;
@@ -367,7 +370,7 @@ namespace Ryujinx.Audio.Renderer.Server
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
}
- GenerateBiquadFilterForVoice(ref voiceState, dspStateMemory, (int)_rendererContext.MixBufferCount, channelIndex, nodeId);
+ GenerateBiquadFilterForVoice(ref voiceInfo, dspStateMemory, (int)_rendererContext.MixBufferCount, channelIndex, nodeId);
if (performanceInitialized)
{
@@ -384,8 +387,8 @@ namespace Ryujinx.Audio.Renderer.Server
}
_commandBuffer.GenerateVolumeRamp(
- voiceState.PreviousVolume,
- voiceState.Volume,
+ voiceInfo.PreviousVolume,
+ voiceInfo.Volume,
_rendererContext.MixBufferCount + (uint)channelIndex,
nodeId);
@@ -394,17 +397,17 @@ namespace Ryujinx.Audio.Renderer.Server
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.End, nodeId);
}
- voiceState.PreviousVolume = voiceState.Volume;
+ voiceInfo.PreviousVolume = voiceInfo.Volume;
- if (voiceState.MixId == Constants.UnusedMixId)
+ if (voiceInfo.MixId == Constants.UnusedMixId)
{
- if (voiceState.SplitterId != Constants.UnusedSplitterId)
+ if (voiceInfo.SplitterId != Constants.UnusedSplitterId)
{
int destinationId = channelIndex;
while (true)
{
- SplitterDestination destination = _splitterContext.GetDestination((int)voiceState.SplitterId, destinationId);
+ SplitterDestination destination = _splitterContext.GetDestination((int)voiceInfo.SplitterId, destinationId);
if (destination.IsNull)
{
@@ -419,7 +422,7 @@ namespace Ryujinx.Audio.Renderer.Server
if (mixId < _mixContext.GetCount() && mixId != Constants.UnusedSplitterIdInt)
{
- ref MixState mix = ref _mixContext.GetState(mixId);
+ ref MixInfo mix = ref _mixContext.GetState(mixId);
if (destination.IsBiquadFilterEnabled())
{
@@ -451,7 +454,7 @@ namespace Ryujinx.Audio.Renderer.Server
}
else
{
- ref MixState mix = ref _mixContext.GetState(voiceState.MixId);
+ ref MixInfo mix = ref _mixContext.GetState(voiceInfo.MixId);
performanceInitialized = false;
@@ -479,9 +482,9 @@ namespace Ryujinx.Audio.Renderer.Server
channelResource.UpdateState();
}
- for (int i = 0; i < voiceState.BiquadFilterNeedInitialization.Length; i++)
+ for (int i = 0; i < voiceInfo.BiquadFilterNeedInitialization.Length; i++)
{
- voiceState.BiquadFilterNeedInitialization[i] = biquadFiltersSpan[i].Enable;
+ voiceInfo.BiquadFilterNeedInitialization[i] = biquadFiltersSpan[i].Enable;
}
}
}
@@ -491,11 +494,11 @@ namespace Ryujinx.Audio.Renderer.Server
{
for (int i = 0; i < _voiceContext.GetCount(); i++)
{
- ref VoiceState sortedState = ref _voiceContext.GetSortedState(i);
+ ref VoiceInfo sortedInfo = ref _voiceContext.GetSortedState(i);
- if (!sortedState.ShouldSkip() && sortedState.UpdateForCommandGeneration(_voiceContext))
+ if (!sortedInfo.ShouldSkip() && sortedInfo.UpdateForCommandGeneration(_voiceContext))
{
- int nodeId = sortedState.NodeId;
+ int nodeId = sortedInfo.NodeId;
PerformanceEntryAddresses performanceEntry = new();
@@ -508,7 +511,7 @@ namespace Ryujinx.Audio.Renderer.Server
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
}
- GenerateVoice(ref sortedState);
+ GenerateVoice(ref sortedInfo);
if (performanceInitialized)
{
@@ -639,9 +642,9 @@ namespace Ryujinx.Audio.Renderer.Server
if (effect.IsEnabled)
{
bool needInitialization = effect.Parameter.Status == UsageState.Invalid ||
- (effect.Parameter.Status == UsageState.New && !_rendererContext.BehaviourContext.IsBiquadFilterEffectStateClearBugFixed());
+ (effect.Parameter.Status == UsageState.New && !_rendererContext.BehaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
- BiquadFilterParameter parameter = new()
+ BiquadFilterParameter2 parameter = new()
{
Enable = true,
};
@@ -683,7 +686,7 @@ namespace Ryujinx.Audio.Renderer.Server
ulong workBuffer = effect.GetWorkBuffer(-1);
- if (_rendererContext.BehaviourContext.IsEffectInfoVersion2Supported())
+ if (_rendererContext.BehaviourInfo.IsEffectInfoVersion2Supported())
{
Memory dspResultState;
@@ -777,7 +780,7 @@ namespace Ryujinx.Audio.Renderer.Server
nodeId);
}
- private void GenerateEffect(ref MixState mix, int effectId, BaseEffect effect)
+ private void GenerateEffect(ref MixInfo mix, int effectId, BaseEffect effect)
{
int nodeId = mix.NodeId;
@@ -807,13 +810,13 @@ namespace Ryujinx.Audio.Renderer.Server
GenerateAuxEffect(mix.BufferOffset, (AuxiliaryBufferEffect)effect, nodeId);
break;
case EffectType.Delay:
- GenerateDelayEffect(mix.BufferOffset, (DelayEffect)effect, nodeId, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
+ GenerateDelayEffect(mix.BufferOffset, (DelayEffect)effect, nodeId, _rendererContext.BehaviourInfo.IsNewEffectChannelMappingSupported());
break;
case EffectType.Reverb:
- GenerateReverbEffect(mix.BufferOffset, (ReverbEffect)effect, nodeId, mix.IsLongSizePreDelaySupported, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
+ GenerateReverbEffect(mix.BufferOffset, (ReverbEffect)effect, nodeId, mix.IsLongSizePreDelaySupported, _rendererContext.BehaviourInfo.IsNewEffectChannelMappingSupported());
break;
case EffectType.Reverb3d:
- GenerateReverb3dEffect(mix.BufferOffset, (Reverb3dEffect)effect, nodeId, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
+ GenerateReverb3dEffect(mix.BufferOffset, (Reverb3dEffect)effect, nodeId, _rendererContext.BehaviourInfo.IsNewEffectChannelMappingSupported());
break;
case EffectType.BiquadFilter:
GenerateBiquadFilterEffect(mix.BufferOffset, (BiquadFilterEffect)effect, nodeId);
@@ -839,7 +842,7 @@ namespace Ryujinx.Audio.Renderer.Server
effect.UpdateForCommandGeneration();
}
- private void GenerateEffects(ref MixState mix)
+ private void GenerateEffects(ref MixInfo mix)
{
ReadOnlySpan effectProcessingOrderArray = mix.EffectProcessingOrderArray;
@@ -875,8 +878,8 @@ namespace Ryujinx.Audio.Renderer.Server
ref bool isFirstMixBuffer,
int nodeId)
{
- ref BiquadFilterParameter bqf0 = ref destination.GetBiquadFilterParameter(0);
- ref BiquadFilterParameter bqf1 = ref destination.GetBiquadFilterParameter(1);
+ ref BiquadFilterParameter2 bqf0 = ref destination.GetBiquadFilterParameter(0);
+ ref BiquadFilterParameter2 bqf1 = ref destination.GetBiquadFilterParameter(1);
Memory bqfState = _splitterContext.GetBiquadFilterState(destination);
@@ -888,7 +891,7 @@ namespace Ryujinx.Audio.Renderer.Server
inputBufferIndex,
outputBufferIndex,
0,
- Memory.Empty,
+ Memory.Empty,
ref bqf0,
ref bqf1,
bqfState[..1],
@@ -912,7 +915,7 @@ namespace Ryujinx.Audio.Renderer.Server
inputBufferIndex,
outputBufferIndex,
0,
- Memory.Empty,
+ Memory.Empty,
ref bqf0,
bqfState[..1],
bqfState.Slice(1, 1),
@@ -931,7 +934,7 @@ namespace Ryujinx.Audio.Renderer.Server
inputBufferIndex,
outputBufferIndex,
0,
- Memory.Empty,
+ Memory.Empty,
ref bqf1,
bqfState[..1],
bqfState.Slice(1, 1),
@@ -946,7 +949,7 @@ namespace Ryujinx.Audio.Renderer.Server
isFirstMixBuffer = false;
}
- private void GenerateMix(ref MixState mix)
+ private void GenerateMix(ref MixInfo mix)
{
if (mix.HasAnyDestination())
{
@@ -975,7 +978,7 @@ namespace Ryujinx.Audio.Renderer.Server
if (mixId < _mixContext.GetCount() && mixId != Constants.UnusedSplitterIdInt)
{
- ref MixState destinationMix = ref _mixContext.GetState(mixId);
+ ref MixInfo destinationMix = ref _mixContext.GetState(mixId);
uint inputBufferIndex = mix.BufferOffset + ((uint)destinationIndex % mix.BufferCount);
@@ -1014,7 +1017,7 @@ namespace Ryujinx.Audio.Renderer.Server
}
else
{
- ref MixState destinationMix = ref _mixContext.GetState(mix.DestinationMixId);
+ ref MixInfo destinationMix = ref _mixContext.GetState(mix.DestinationMixId);
for (uint bufferIndex = 0; bufferIndex < mix.BufferCount; bufferIndex++)
{
@@ -1036,7 +1039,7 @@ namespace Ryujinx.Audio.Renderer.Server
}
}
- private void GenerateSubMix(ref MixState subMix)
+ private void GenerateSubMix(ref MixInfo subMix)
{
_commandBuffer.GenerateDepopForMixBuffers(
_rendererContext.DepopBuffer,
@@ -1072,11 +1075,11 @@ namespace Ryujinx.Audio.Renderer.Server
{
for (int id = 0; id < _mixContext.GetCount(); id++)
{
- ref MixState sortedState = ref _mixContext.GetSortedState(id);
+ ref MixInfo sortedInfo = ref _mixContext.GetSortedState(id);
- if (sortedState.IsUsed && sortedState.MixId != Constants.FinalMixId)
+ if (sortedInfo.IsUsed && sortedInfo.MixId != Constants.FinalMixId)
{
- int nodeId = sortedState.NodeId;
+ int nodeId = sortedInfo.NodeId;
PerformanceEntryAddresses performanceEntry = new();
@@ -1089,7 +1092,7 @@ namespace Ryujinx.Audio.Renderer.Server
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
}
- GenerateSubMix(ref sortedState);
+ GenerateSubMix(ref sortedInfo);
if (performanceInitialized)
{
@@ -1101,7 +1104,7 @@ namespace Ryujinx.Audio.Renderer.Server
private void GenerateFinalMix()
{
- ref MixState finalMix = ref _mixContext.GetFinalState();
+ ref MixInfo finalMix = ref _mixContext.GetFinalState();
_commandBuffer.GenerateDepopForMixBuffers(
_rendererContext.DepopBuffer,
@@ -1180,16 +1183,16 @@ namespace Ryujinx.Audio.Renderer.Server
}
}
- private void GenerateCircularBuffer(CircularBufferSink sink, ref MixState finalMix)
+ private void GenerateCircularBuffer(CircularBufferSink sink, ref MixInfo finalMix)
{
_commandBuffer.GenerateCircularBuffer(finalMix.BufferOffset, sink, Constants.InvalidNodeId);
}
- private void GenerateDevice(DeviceSink sink, ref MixState finalMix)
+ private void GenerateDevice(DeviceSink sink, ref MixInfo finalMix)
{
- if (_commandBuffer.CommandList.SampleRate != 48000 && sink.UpsamplerState == null)
+ if (_commandBuffer.CommandList.SampleRate != 48000 && sink.UpsamplerInfo == null)
{
- sink.UpsamplerState = _rendererContext.UpsamplerManager.Allocate();
+ sink.UpsamplerInfo = _rendererContext.UpsamplerManager.Allocate();
}
bool useCustomDownMixingCommand = _rendererContext.ChannelCount == 2 && sink.Parameter.DownMixParameterEnabled;
@@ -1216,11 +1219,11 @@ namespace Ryujinx.Audio.Renderer.Server
CommandList commandList = _commandBuffer.CommandList;
- if (sink.UpsamplerState != null)
+ if (sink.UpsamplerInfo != null)
{
_commandBuffer.GenerateUpsample(
finalMix.BufferOffset,
- sink.UpsamplerState,
+ sink.UpsamplerInfo,
sink.Parameter.InputCount,
sink.Parameter.Input.AsSpan(),
commandList.BufferCount,
@@ -1237,7 +1240,7 @@ namespace Ryujinx.Audio.Renderer.Server
Constants.InvalidNodeId);
}
- private void GenerateSink(BaseSink sink, ref MixState finalMix)
+ private void GenerateSink(BaseSink sink, ref MixInfo finalMix)
{
bool performanceInitialized = false;
@@ -1275,7 +1278,7 @@ namespace Ryujinx.Audio.Renderer.Server
public void GenerateSinks()
{
- ref MixState finalMix = ref _mixContext.GetFinalState();
+ ref MixInfo finalMix = ref _mixContext.GetFinalState();
for (int i = 0; i < _sinkContext.GetCount(); i++)
{
diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs
index cff754b82..8abe81e1f 100644
--- a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs
@@ -194,5 +194,10 @@ namespace Ryujinx.Audio.Renderer.Server
{
return 0;
}
+
+ public uint Estimate(FillBufferCommand command)
+ {
+ return 0;
+ }
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs
index 1e9b6c53e..85e340393 100644
--- a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs
@@ -486,5 +486,10 @@ namespace Ryujinx.Audio.Renderer.Server
{
return 0;
}
+
+ public uint Estimate(FillBufferCommand command)
+ {
+ return 0;
+ }
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs
index 85e016019..4b0eec4f3 100644
--- a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs
@@ -3,7 +3,7 @@ using Ryujinx.Audio.Renderer.Dsp.Command;
using Ryujinx.Audio.Renderer.Parameter.Effect;
using System;
using System.Diagnostics;
-using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
+using Ryujinx.Audio.Renderer.Parameter;
namespace Ryujinx.Audio.Renderer.Server
{
@@ -656,5 +656,10 @@ namespace Ryujinx.Audio.Renderer.Server
{
return 0;
}
+
+ public virtual uint Estimate(FillBufferCommand command)
+ {
+ return 0;
+ }
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs
index fe6103f2b..906065792 100644
--- a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs
@@ -286,5 +286,10 @@ namespace Ryujinx.Audio.Renderer.Server
return 8683;
}
}
+
+ public override uint Estimate(FillBufferCommand command)
+ {
+ return 0;
+ }
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs
index 77d9b5c29..6324689e4 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs
@@ -174,6 +174,19 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
updateErrorInfo = new ErrorInfo();
}
+
+ ///
+ /// Update the internal state from a user version 3 parameter.
+ ///
+ /// The possible that was generated.
+ /// The user parameter.
+ /// The mapper to use.
+ public virtual void Update(out ErrorInfo updateErrorInfo, in EffectInParameterVersion3 parameter, PoolMapper mapper)
+ {
+ Debug.Assert(IsTypeValid(in parameter));
+
+ updateErrorInfo = new ErrorInfo();
+ }
///
/// Get the work buffer DSP address at the given index.
diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs
index 3b3e1021c..f920c6873 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs
@@ -1,4 +1,5 @@
using Ryujinx.Audio.Renderer.Common;
+using Ryujinx.Audio.Renderer.Dsp;
using Ryujinx.Audio.Renderer.Dsp.State;
using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Audio.Renderer.Parameter.Effect;
@@ -17,7 +18,7 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
///
/// The biquad filter parameter.
///
- public BiquadFilterEffectParameter Parameter;
+ public BiquadFilterEffectParameter2 Parameter;
///
/// The biquad filter state.
@@ -29,7 +30,7 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
///
public BiquadFilterEffect()
{
- Parameter = new BiquadFilterEffectParameter();
+ Parameter = new BiquadFilterEffectParameter2();
State = new BiquadFilterState[Constants.ChannelCountMax];
}
@@ -44,6 +45,11 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
{
Update(out updateErrorInfo, in parameter, mapper);
}
+
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, in EffectInParameterVersion3 parameter, PoolMapper mapper)
+ {
+ Update(out updateErrorInfo, in parameter, mapper);
+ }
public void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, in T parameter, PoolMapper mapper) where T : unmanaged, IEffectInParameter
{
@@ -51,7 +57,17 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
UpdateParameterBase(in parameter);
- Parameter = MemoryMarshal.Cast(parameter.SpecificData)[0];
+ if (typeof(T) == typeof(EffectInParameterVersion3))
+ {
+ Parameter = MemoryMarshal.Cast(parameter.SpecificData)[0];
+ }
+ else
+ {
+ BiquadFilterEffectParameter1 oldParameter =
+ MemoryMarshal.Cast(parameter.SpecificData)[0];
+ Parameter = BiquadFilterHelper.ToBiquadFilterEffectParameter2(oldParameter);
+ }
+
IsEnabled = parameter.IsEnabled;
updateErrorInfo = new BehaviourParameter.ErrorInfo();
diff --git a/src/Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs b/src/Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs
index 9c4312ad6..360241278 100644
--- a/src/Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs
@@ -38,5 +38,6 @@ namespace Ryujinx.Audio.Renderer.Server
uint Estimate(CompressorCommand command);
uint Estimate(BiquadFilterAndMixCommand command);
uint Estimate(MultiTapBiquadFilterAndMixCommand command);
+ uint Estimate(FillBufferCommand command);
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/AddressInfo.cs b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/AddressInfo.cs
index 3337e44b0..0ae6d518d 100644
--- a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/AddressInfo.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/AddressInfo.cs
@@ -20,14 +20,14 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
///
public ulong Size;
- private unsafe MemoryPoolState* _memoryPools;
+ private unsafe MemoryPoolInfo* _memoryPools;
///
/// The forced DSP address of the region.
///
public DspAddress ForceMappedDspAddress;
- private readonly unsafe ref MemoryPoolState MemoryPoolState => ref *_memoryPools;
+ private readonly unsafe ref MemoryPoolInfo MemoryPoolInfo => ref *_memoryPools;
public readonly unsafe bool HasMemoryPoolState => (nint)_memoryPools != nint.Zero;
@@ -53,7 +53,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
return new AddressInfo
{
CpuAddress = cpuAddress,
- _memoryPools = MemoryPoolState.Null,
+ _memoryPools = MemoryPoolInfo.Null,
Size = size,
ForceMappedDspAddress = 0,
};
@@ -73,19 +73,19 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
unsafe
{
- _memoryPools = MemoryPoolState.Null;
+ _memoryPools = MemoryPoolInfo.Null;
}
}
///
- /// Set the associated.
+ /// Set the associated.
///
- /// The associated.
- public void SetupMemoryPool(Span memoryPoolState)
+ /// The associated.
+ public void SetupMemoryPool(Span memoryPoolState)
{
unsafe
{
- fixed (MemoryPoolState* ptr = &MemoryMarshal.GetReference(memoryPoolState))
+ fixed (MemoryPoolInfo* ptr = &MemoryMarshal.GetReference(memoryPoolState))
{
SetupMemoryPool(ptr);
}
@@ -93,27 +93,27 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Set the associated.
+ /// Set the associated.
///
- /// The associated.
- public unsafe void SetupMemoryPool(MemoryPoolState* memoryPoolState)
+ /// The associated.
+ public unsafe void SetupMemoryPool(MemoryPoolInfo* memoryPoolState)
{
_memoryPools = memoryPoolState;
}
///
- /// Check if the is mapped.
+ /// Check if the is mapped.
///
- /// Returns true if the is mapped.
+ /// Returns true if the is mapped.
public readonly bool HasMappedMemoryPool()
{
- return HasMemoryPoolState && MemoryPoolState.IsMapped();
+ return HasMemoryPoolState && MemoryPoolInfo.IsMapped();
}
///
/// Get the DSP address associated to the .
///
- /// If true, mark the as used.
+ /// If true, mark the as used.
/// Returns the DSP address associated to the .
public readonly DspAddress GetReference(bool markUsed)
{
@@ -124,10 +124,10 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
if (markUsed)
{
- MemoryPoolState.IsUsed = true;
+ MemoryPoolInfo.IsUsed = true;
}
- return MemoryPoolState.Translate(CpuAddress, Size);
+ return MemoryPoolInfo.Translate(CpuAddress, Size);
}
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolState.cs b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolInfo.cs
similarity index 73%
rename from src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolState.cs
rename to src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolInfo.cs
index 50153af37..eb0117f50 100644
--- a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolState.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolInfo.cs
@@ -8,62 +8,62 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
/// Server state for a memory pool.
///
[StructLayout(LayoutKind.Sequential, Size = 0x20, Pack = Alignment)]
- public struct MemoryPoolState
+ public struct MemoryPoolInfo
{
public const int Alignment = 0x10;
///
- /// The location of the .
+ /// The location of the .
///
public enum LocationType : uint
{
///
- /// located on the CPU side for user use.
+ /// located on the CPU side for user use.
///
Cpu,
///
- /// located on the DSP side for system use.
+ /// located on the DSP side for system use.
///
Dsp,
}
///
- /// The CPU address associated to the .
+ /// The CPU address associated to the .
///
public CpuAddress CpuAddress;
///
- /// The DSP address associated to the .
+ /// The DSP address associated to the .
///
public DspAddress DspAddress;
///
- /// The size associated to the .
+ /// The size associated to the .
///
public ulong Size;
///
- /// The associated to the .
+ /// The associated to the .
///
public LocationType Location;
///
- /// Set to true if the is used.
+ /// Set to true if the is used.
///
[MarshalAs(UnmanagedType.I1)]
public bool IsUsed;
- public static unsafe MemoryPoolState* Null => (MemoryPoolState*)nint.Zero.ToPointer();
+ public static unsafe MemoryPoolInfo* Null => (MemoryPoolInfo*)nint.Zero.ToPointer();
///
- /// Create a new with the given .
+ /// Create a new with the given .
///
/// The location type to use.
- /// A new with the given .
- public static MemoryPoolState Create(LocationType location)
+ /// A new with the given .
+ public static MemoryPoolInfo Create(LocationType location)
{
- return new MemoryPoolState
+ return new MemoryPoolInfo
{
CpuAddress = 0,
DspAddress = 0,
@@ -73,7 +73,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Set the and size of the .
+ /// Set the and size of the .
///
/// The .
/// The size.
@@ -84,11 +84,11 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Check if the given and size is contains in the .
+ /// Check if the given and size is contains in the .
///
/// The .
/// The size.
- /// True if the is contained inside the .
+ /// True if the is contained inside the .
public readonly bool Contains(CpuAddress targetCpuAddress, ulong size)
{
if (CpuAddress <= targetCpuAddress && size + targetCpuAddress <= Size + CpuAddress)
@@ -118,9 +118,9 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Is the mapped on the DSP?
+ /// Is the mapped on the DSP?
///
- /// Returns true if the is mapped on the DSP.
+ /// Returns true if the is mapped on the DSP.
public readonly bool IsMapped()
{
return DspAddress != 0;
diff --git a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/PoolMapper.cs b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/PoolMapper.cs
index 535e2fd79..2b7153b54 100644
--- a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/PoolMapper.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/PoolMapper.cs
@@ -18,7 +18,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
const uint CurrentProcessPseudoHandle = 0xFFFF8001;
///
- /// The result of .
+ /// The result of .
///
public enum UpdateResult : uint
{
@@ -49,9 +49,9 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
private readonly uint _processHandle;
///
- /// The that will be manipulated.
+ /// The that will be manipulated.
///
- private readonly Memory _memoryPools;
+ private readonly Memory _memoryPools;
///
/// If set to true, this will try to force map memory pool even if their state are considered invalid.
@@ -67,7 +67,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
{
_processHandle = processHandle;
_isForceMapEnabled = isForceMapEnabled;
- _memoryPools = Memory.Empty;
+ _memoryPools = Memory.Empty;
}
///
@@ -76,7 +76,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
/// The handle of the process owning the CPU memory manipulated.
/// The user memory pools.
/// If set to true, this will try to force map memory pool even if their state are considered invalid.
- public PoolMapper(uint processHandle, Memory memoryPool, bool isForceMapEnabled)
+ public PoolMapper(uint processHandle, Memory memoryPool, bool isForceMapEnabled)
{
_processHandle = processHandle;
_memoryPools = memoryPool;
@@ -84,15 +84,15 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Initialize the for system use.
+ /// Initialize the for system use.
///
- /// The for system use.
+ /// The for system use.
/// The to assign.
/// The size to assign.
/// Returns true if mapping on the succeeded.
- public bool InitializeSystemPool(ref MemoryPoolState memoryPool, CpuAddress cpuAddress, ulong size)
+ public bool InitializeSystemPool(ref MemoryPoolInfo memoryPool, CpuAddress cpuAddress, ulong size)
{
- if (memoryPool.Location != MemoryPoolState.LocationType.Dsp)
+ if (memoryPool.Location != MemoryPoolInfo.LocationType.Dsp)
{
return false;
}
@@ -101,13 +101,13 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Initialize the .
+ /// Initialize the .
///
- /// The .
+ /// The .
/// The to assign.
/// The size to assign.
/// Returns true if mapping on the succeeded.
- public bool InitializePool(ref MemoryPoolState memoryPool, CpuAddress cpuAddress, ulong size)
+ public bool InitializePool(ref MemoryPoolInfo memoryPool, CpuAddress cpuAddress, ulong size)
{
memoryPool.SetCpuAddress(cpuAddress, size);
@@ -115,18 +115,18 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Get the process handle associated to the .
+ /// Get the process handle associated to the .
///
- /// The .
- /// Returns the process handle associated to the .
- public uint GetProcessHandle(ref MemoryPoolState memoryPool)
+ /// The .
+ /// Returns the process handle associated to the .
+ public uint GetProcessHandle(ref MemoryPoolInfo memoryPool)
{
- if (memoryPool.Location == MemoryPoolState.LocationType.Cpu)
+ if (memoryPool.Location == MemoryPoolInfo.LocationType.Cpu)
{
return CurrentProcessPseudoHandle;
}
- if (memoryPool.Location == MemoryPoolState.LocationType.Dsp)
+ if (memoryPool.Location == MemoryPoolInfo.LocationType.Dsp)
{
return _processHandle;
}
@@ -135,11 +135,11 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Map the on the .
+ /// Map the on the .
///
- /// The to map.
+ /// The to map.
/// Returns the DSP address mapped.
- public DspAddress Map(ref MemoryPoolState memoryPool)
+ public DspAddress Map(ref MemoryPoolInfo memoryPool)
{
DspAddress result = AudioProcessorMemoryManager.Map(GetProcessHandle(ref memoryPool), memoryPool.CpuAddress, memoryPool.Size);
@@ -152,11 +152,11 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Unmap the from the .
+ /// Unmap the from the .
///
- /// The to unmap.
+ /// The to unmap.
/// Returns true if unmapped.
- public bool Unmap(ref MemoryPoolState memoryPool)
+ public bool Unmap(ref MemoryPoolInfo memoryPool)
{
if (memoryPool.IsUsed)
{
@@ -172,12 +172,12 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Find a associated to the region given.
+ /// Find a associated to the region given.
///
/// The region .
/// The region size.
- /// Returns the found or if not found.
- private Span FindMemoryPool(CpuAddress cpuAddress, ulong size)
+ /// Returns the found or if not found.
+ private Span FindMemoryPool(CpuAddress cpuAddress, ulong size)
{
if (!_memoryPools.IsEmpty && _memoryPools.Length > 0)
{
@@ -190,7 +190,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
}
- return Span.Empty;
+ return Span.Empty;
}
///
@@ -201,7 +201,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
{
if (_isForceMapEnabled)
{
- Span memoryPool = FindMemoryPool(addressInfo.CpuAddress, addressInfo.Size);
+ Span memoryPool = FindMemoryPool(addressInfo.CpuAddress, addressInfo.Size);
if (!memoryPool.IsEmpty)
{
@@ -243,13 +243,13 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Update a using user parameters.
+ /// Update a using user parameters.
///
- /// The to update.
+ /// The to update.
/// Input user parameter.
/// Output user parameter.
/// Returns the of the operations performed.
- public UpdateResult Update(ref MemoryPoolState memoryPool, in MemoryPoolInParameter inParameter, ref MemoryPoolOutStatus outStatus)
+ public UpdateResult Update(ref MemoryPoolInfo memoryPool, in MemoryPoolInParameter inParameter, ref MemoryPoolOutStatus outStatus)
{
MemoryPoolUserState inputState = inParameter.State;
@@ -321,7 +321,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
if (_memoryPools.Length > 0)
{
- Span memoryPool = FindMemoryPool(addressInfo.CpuAddress, addressInfo.Size);
+ Span memoryPool = FindMemoryPool(addressInfo.CpuAddress, addressInfo.Size);
if (!memoryPool.IsEmpty)
{
@@ -343,7 +343,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
{
unsafe
{
- addressInfo.SetupMemoryPool(MemoryPoolState.Null);
+ addressInfo.SetupMemoryPool(MemoryPoolInfo.Null);
}
}
@@ -351,12 +351,12 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Remove the usage flag from all the .
+ /// Remove the usage flag from all the .
///
- /// The to reset.
- public static void ClearUsageState(Memory memoryPool)
+ /// The to reset.
+ public static void ClearUsageState(Memory memoryPool)
{
- foreach (ref MemoryPoolState info in memoryPool.Span)
+ foreach (ref MemoryPoolInfo info in memoryPool.Span)
{
info.IsUsed = false;
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/Mix/MixContext.cs b/src/Ryujinx.Audio/Renderer/Server/Mix/MixContext.cs
index 8991ceaf9..cdb6511cb 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Mix/MixContext.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Mix/MixContext.cs
@@ -17,12 +17,12 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
private uint _mixesCount;
///
- /// Storage for .
+ /// Storage for .
///
- private Memory _mixes;
+ private Memory _mixes;
///
- /// Storage of the sorted indices to .
+ /// Storage of the sorted indices to .
///
private Memory _sortedMixes;
@@ -49,10 +49,10 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
/// Initialize the .
///
/// The storage for sorted indices.
- /// The storage of .
+ /// The storage of .
/// The storage used for the .
/// The storage used for the .
- public void Initialize(Memory sortedMixes, Memory mixes, Memory nodeStatesWorkBuffer, Memory edgeMatrixWorkBuffer)
+ public void Initialize(Memory sortedMixes, Memory mixes, Memory nodeStatesWorkBuffer, Memory edgeMatrixWorkBuffer)
{
_mixesCount = (uint)mixes.Length;
_mixes = mixes;
@@ -82,30 +82,30 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
}
///
- /// Get a reference to the final .
+ /// Get a reference to the final .
///
- /// A reference to the final .
- public ref MixState GetFinalState()
+ /// A reference to the final .
+ public ref MixInfo GetFinalState()
{
return ref GetState(Constants.FinalMixId);
}
///
- /// Get a reference to a at the given .
+ /// Get a reference to a at the given .
///
/// The index to use.
- /// A reference to a at the given .
- public ref MixState GetState(int id)
+ /// A reference to a at the given .
+ public ref MixInfo GetState(int id)
{
return ref SpanIOHelper.GetFromMemory(_mixes, id, _mixesCount);
}
///
- /// Get a reference to a at the given of the sorted mix info.
+ /// Get a reference to a at the given of the sorted mix info.
///
/// The index to use.
- /// A reference to a at the given .
- public ref MixState GetSortedState(int id)
+ /// A reference to a at the given .
+ public ref MixInfo GetSortedState(int id)
{
Debug.Assert(id >= 0 && id < _mixesCount);
@@ -122,18 +122,18 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
}
///
- /// Update the internal distance from the final mix value of every .
+ /// Update the internal distance from the final mix value of every .
///
private void UpdateDistancesFromFinalMix()
{
- foreach (ref MixState mix in _mixes.Span)
+ foreach (ref MixInfo mix in _mixes.Span)
{
mix.ClearDistanceFromFinalMix();
}
for (int i = 0; i < GetCount(); i++)
{
- ref MixState mix = ref GetState(i);
+ ref MixInfo mix = ref GetState(i);
SetSortedState(i, i);
@@ -149,13 +149,13 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
{
if (mixId == Constants.UnusedMixId)
{
- distance = MixState.InvalidDistanceFromFinalMix;
+ distance = MixInfo.InvalidDistanceFromFinalMix;
break;
}
- ref MixState distanceMix = ref GetState(mixId);
+ ref MixInfo distanceMix = ref GetState(mixId);
- if (distanceMix.DistanceFromFinalMix != MixState.InvalidDistanceFromFinalMix)
+ if (distanceMix.DistanceFromFinalMix != MixInfo.InvalidDistanceFromFinalMix)
{
distance = distanceMix.DistanceFromFinalMix + 1;
break;
@@ -171,12 +171,12 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
if (distance > GetCount())
{
- distance = MixState.InvalidDistanceFromFinalMix;
+ distance = MixInfo.InvalidDistanceFromFinalMix;
}
}
else
{
- distance = MixState.InvalidDistanceFromFinalMix;
+ distance = MixInfo.InvalidDistanceFromFinalMix;
}
mix.DistanceFromFinalMix = distance;
@@ -185,13 +185,13 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
}
///
- /// Update the internal mix buffer offset of all .
+ /// Update the internal mix buffer offset of all .
///
private void UpdateMixBufferOffset()
{
uint offset = 0;
- foreach (ref MixState mix in _mixes.Span)
+ foreach (ref MixInfo mix in _mixes.Span)
{
mix.BufferOffset = offset;
@@ -210,10 +210,10 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
Array.Sort(sortedMixesTemp, (a, b) =>
{
- ref MixState stateA = ref GetState(a);
- ref MixState stateB = ref GetState(b);
+ ref MixInfo infoA = ref GetState(a);
+ ref MixInfo infoB = ref GetState(b);
- return stateB.DistanceFromFinalMix.CompareTo(stateA.DistanceFromFinalMix);
+ return infoB.DistanceFromFinalMix.CompareTo(infoA.DistanceFromFinalMix);
});
sortedMixesTemp.AsSpan().CopyTo(_sortedMixes.Span);
diff --git a/src/Ryujinx.Audio/Renderer/Server/Mix/MixState.cs b/src/Ryujinx.Audio/Renderer/Server/Mix/MixInfo.cs
similarity index 93%
rename from src/Ryujinx.Audio/Renderer/Server/Mix/MixState.cs
rename to src/Ryujinx.Audio/Renderer/Server/Mix/MixInfo.cs
index 34b3ed4bd..eae141a66 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Mix/MixState.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Mix/MixInfo.cs
@@ -15,7 +15,7 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
/// Server state for a mix.
///
[StructLayout(LayoutKind.Sequential, Size = 0x940, Pack = Alignment)]
- public struct MixState
+ public struct MixInfo
{
public const uint InvalidDistanceFromFinalMix = 0x80000000;
@@ -136,11 +136,11 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
}
///
- /// Create a new
+ /// Create a new
///
///
- ///
- public MixState(Memory effectProcessingOrderArray, ref BehaviourContext behaviourContext) : this()
+ ///
+ public MixInfo(Memory effectProcessingOrderArray, ref BehaviourInfo behaviourInfo) : this()
{
MixId = UnusedMixId;
@@ -158,7 +158,7 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
EffectProcessingOrderArrayMaxCount = (uint)effectProcessingOrderArray.Length;
- IsLongSizePreDelaySupported = behaviourContext.IsLongSizePreDelaySupported();
+ IsLongSizePreDelaySupported = behaviourInfo.IsLongSizePreDelaySupported();
ClearEffectProcessingOrder();
}
@@ -257,9 +257,9 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
/// The input parameter of the mix.
/// The effect context.
/// The splitter context.
- /// The behaviour context.
+ /// The behaviour context.
/// Return true if the mix was changed.
- public bool Update(EdgeMatrix edgeMatrix, in MixParameter parameter, EffectContext effectContext, SplitterContext splitterContext, BehaviourContext behaviourContext)
+ public bool Update(EdgeMatrix edgeMatrix, in MixParameter parameter, EffectContext effectContext, SplitterContext splitterContext, BehaviourInfo behaviourInfo)
{
bool isDirty;
@@ -271,7 +271,7 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
NodeId = parameter.NodeId;
parameter.MixBufferVolume.CopyTo(MixBufferVolume);
- if (behaviourContext.IsSplitterSupported())
+ if (behaviourInfo.IsSplitterSupported())
{
isDirty = UpdateConnection(edgeMatrix, in parameter, ref splitterContext);
}
@@ -279,10 +279,7 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
{
isDirty = DestinationMixId != parameter.DestinationMixId;
- if (DestinationMixId != parameter.DestinationMixId)
- {
- DestinationMixId = parameter.DestinationMixId;
- }
+ DestinationMixId = parameter.DestinationMixId;
DestinationSplitterId = UnusedSplitterId;
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManager.cs b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManager.cs
index da5a0ad45..e430d99c3 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManager.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManager.cs
@@ -10,11 +10,11 @@ namespace Ryujinx.Audio.Renderer.Server.Performance
/// Get the required size for a single performance frame.
///
/// The audio renderer configuration.
- /// The behaviour context.
+ /// The behaviour context.
/// The required size for a single performance frame.
- public static ulong GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref AudioRendererConfiguration parameter, ref BehaviourContext behaviourContext)
+ public static ulong GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref AudioRendererConfiguration parameter, ref BehaviourInfo behaviourInfo)
{
- uint version = behaviourContext.GetPerformanceMetricsDataFormat();
+ uint version = behaviourInfo.GetPerformanceMetricsDataFormat();
if (version == 2)
{
@@ -81,11 +81,11 @@ namespace Ryujinx.Audio.Renderer.Server.Performance
///
/// The backing memory available for use by the manager.
/// The audio renderer configuration.
- /// The behaviour context;
+ /// The behaviour context;
/// A new .
- public static PerformanceManager Create(Memory performanceBuffer, ref AudioRendererConfiguration parameter, BehaviourContext behaviourContext)
+ public static PerformanceManager Create(Memory performanceBuffer, ref AudioRendererConfiguration parameter, BehaviourInfo behaviourInfo)
{
- uint version = behaviourContext.GetPerformanceMetricsDataFormat();
+ uint version = behaviourInfo.GetPerformanceMetricsDataFormat();
return version switch
{
diff --git a/src/Ryujinx.Audio/Renderer/Server/RendererSystemContext.cs b/src/Ryujinx.Audio/Renderer/Server/RendererSystemContext.cs
index 090850018..fa7a24d09 100644
--- a/src/Ryujinx.Audio/Renderer/Server/RendererSystemContext.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/RendererSystemContext.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Audio.Renderer.Server.Mix;
using Ryujinx.Audio.Renderer.Server.Upsampler;
using System;
@@ -19,7 +20,7 @@ namespace Ryujinx.Audio.Renderer.Server
///
/// The target channel count for sink.
///
- /// See for usage.
+ /// See for usage.
public uint ChannelCount;
///
@@ -28,12 +29,12 @@ namespace Ryujinx.Audio.Renderer.Server
public uint MixBufferCount;
///
- /// Instance of the used to derive bug fixes and features of the current audio renderer revision.
+ /// Instance of the used to derive bug fixes and features of the current audio renderer revision.
///
- public BehaviourContext BehaviourContext;
+ public BehaviourInfo BehaviourInfo;
///
- /// Instance of the used for upsampling (see )
+ /// Instance of the used for upsampling (see )
///
public UpsamplerManager UpsamplerManager;
diff --git a/src/Ryujinx.Audio/Renderer/Server/Sink/DeviceSink.cs b/src/Ryujinx.Audio/Renderer/Server/Sink/DeviceSink.cs
index afe2d4b1b..c590b69d9 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Sink/DeviceSink.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Sink/DeviceSink.cs
@@ -28,7 +28,7 @@ namespace Ryujinx.Audio.Renderer.Server.Sink
/// The upsampler instance used by this sink.
///
/// Null if no upsampling is needed.
- public UpsamplerState UpsamplerState;
+ public UpsamplerInfo UpsamplerInfo;
///
/// Create a new .
@@ -40,9 +40,9 @@ namespace Ryujinx.Audio.Renderer.Server.Sink
public override void CleanUp()
{
- UpsamplerState?.Release();
+ UpsamplerInfo?.Release();
- UpsamplerState = null;
+ UpsamplerInfo = null;
base.CleanUp();
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterContext.cs b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterContext.cs
index 6dddb4315..7d914e137 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterContext.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterContext.cs
@@ -55,22 +55,27 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// If set to true, the previous mix volume is explicitly resetted using the input parameter, instead of implicitly on first use.
///
public bool IsSplitterPrevVolumeResetSupported { get; private set; }
+
+ ///
+ /// If set to true, the previous mix volume is explicitly resetted using the input parameter, instead of implicitly on first use.
+ ///
+ public bool IsBiquadFilterParameterFloatSupported { get; private set; }
///
/// Initialize .
///
- /// The behaviour context.
+ /// The behaviour context.
/// The audio renderer configuration.
/// The .
/// Memory to store the biquad filtering state for splitters during processing.
/// Return true if the initialization was successful.
public bool Initialize(
- ref BehaviourContext behaviourContext,
+ ref BehaviourInfo behaviourInfo,
ref AudioRendererConfiguration parameter,
WorkBufferAllocator workBufferAllocator,
Memory splitterBqfStates)
{
- if (!behaviourContext.IsSplitterSupported() || parameter.SplitterCount <= 0 || parameter.SplitterDestinationCount <= 0)
+ if (!behaviourInfo.IsSplitterSupported() || parameter.SplitterCount <= 0 || parameter.SplitterDestinationCount <= 0)
{
Setup(Memory.Empty, Memory.Empty, Memory.Empty, false);
@@ -94,7 +99,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
Memory splitterDestinationsV1 = Memory.Empty;
Memory splitterDestinationsV2 = Memory.Empty;
- if (!behaviourContext.IsBiquadFilterParameterForSplitterEnabled())
+ if (!behaviourInfo.IsBiquadFilterParameterForSplitterEnabled())
{
Version = 1;
@@ -144,11 +149,12 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
}
}
- IsSplitterPrevVolumeResetSupported = behaviourContext.IsSplitterPrevVolumeResetSupported();
+ IsSplitterPrevVolumeResetSupported = behaviourInfo.IsSplitterPrevVolumeResetSupported();
+ IsBiquadFilterParameterFloatSupported = behaviourInfo.IsBiquadFilterParameterFloatSupported();
SplitterState.InitializeSplitters(splitters.Span);
- Setup(splitters, splitterDestinationsV1, splitterDestinationsV2, behaviourContext.IsSplitterBugFixed());
+ Setup(splitters, splitterDestinationsV1, splitterDestinationsV2, behaviourInfo.IsSplitterBugFixed());
return true;
}
@@ -157,16 +163,16 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// Get the work buffer size while adding the size needed for splitter to operate.
///
/// The current size.
- /// The behaviour context.
+ /// The behaviour context.
/// The renderer configuration.
/// Return the new size taking splitter into account.
- public static ulong GetWorkBufferSize(ulong size, ref BehaviourContext behaviourContext, ref AudioRendererConfiguration parameter)
+ public static ulong GetWorkBufferSize(ulong size, ref BehaviourInfo behaviourInfo, ref AudioRendererConfiguration parameter)
{
- if (behaviourContext.IsSplitterSupported())
+ if (behaviourInfo.IsSplitterSupported())
{
size = WorkBufferAllocator.GetTargetSize(size, parameter.SplitterCount, SplitterState.Alignment);
- if (behaviourContext.IsBiquadFilterParameterForSplitterEnabled())
+ if (behaviourInfo.IsBiquadFilterParameterForSplitterEnabled())
{
size = WorkBufferAllocator.GetTargetSize(size, parameter.SplitterDestinationCount, SplitterDestinationVersion2.Alignment);
}
@@ -175,12 +181,10 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
size = WorkBufferAllocator.GetTargetSize(size, parameter.SplitterDestinationCount, SplitterDestinationVersion1.Alignment);
}
- if (behaviourContext.IsSplitterBugFixed())
+ if (behaviourInfo.IsSplitterBugFixed())
{
size = WorkBufferAllocator.GetTargetSize(size, parameter.SplitterDestinationCount, 0x10);
}
-
- return size;
}
return size;
@@ -227,7 +231,16 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
return 0;
}
- int length = _splitterDestinationsV2.IsEmpty ? _splitterDestinationsV1.Length : _splitterDestinationsV2.Length;
+ int length;
+
+ if (_splitterDestinationsV2.IsEmpty)
+ {
+ length = _splitterDestinationsV1.Length;
+ }
+ else
+ {
+ length = _splitterDestinationsV2.Length;
+ }
return length / _splitters.Length;
}
@@ -278,8 +291,17 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
if (parameter.IsMagicValid())
{
- int length = _splitterDestinationsV2.IsEmpty ? _splitterDestinationsV1.Length : _splitterDestinationsV2.Length;
+ int length;
+ if (_splitterDestinationsV2.IsEmpty)
+ {
+ length = _splitterDestinationsV1.Length;
+ }
+ else
+ {
+ length = _splitterDestinationsV2.Length;
+ }
+
if (parameter.Id >= 0 && parameter.Id < length)
{
SplitterDestination destination = GetDestination(parameter.Id);
@@ -315,9 +337,19 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
}
else if (Version == 2)
{
- if (!UpdateData(ref input))
+ if (IsBiquadFilterParameterFloatSupported)
{
- break;
+ if (!UpdateData(ref input))
+ {
+ break;
+ }
+ }
+ else
+ {
+ if (!UpdateData(ref input))
+ {
+ break;
+ }
}
}
else
@@ -381,10 +413,8 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return new SplitterDestination(ref SpanIOHelper.GetFromMemory(_splitterDestinationsV1, id, (uint)_splitterDestinationsV1.Length));
}
- else
- {
- return new SplitterDestination(ref SpanIOHelper.GetFromMemory(_splitterDestinationsV2, id, (uint)_splitterDestinationsV2.Length));
- }
+
+ return new SplitterDestination(ref SpanIOHelper.GetFromMemory(_splitterDestinationsV2, id, (uint)_splitterDestinationsV2.Length));
}
///
diff --git a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestination.cs b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestination.cs
index 1a46d41fd..1253e5d2c 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestination.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestination.cs
@@ -31,15 +31,11 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return 0;
}
- else
- {
- return _v1.Id;
- }
- }
- else
- {
- return _v2.Id;
+
+ return _v1.Id;
}
+
+ return _v2.Id;
}
}
@@ -56,15 +52,11 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return 0;
}
- else
- {
- return _v1.DestinationId;
- }
- }
- else
- {
- return _v2.DestinationId;
+
+ return _v1.DestinationId;
}
+
+ return _v2.DestinationId;
}
}
@@ -82,15 +74,11 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return Span.Empty;
}
- else
- {
- return _v1.MixBufferVolume;
- }
- }
- else
- {
- return _v2.MixBufferVolume;
+
+ return _v1.MixBufferVolume;
}
+
+ return _v2.MixBufferVolume;
}
}
@@ -108,15 +96,11 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return Span.Empty;
}
- else
- {
- return _v1.PreviousMixBufferVolume;
- }
- }
- else
- {
- return _v2.PreviousMixBufferVolume;
+
+ return _v1.PreviousMixBufferVolume;
}
+
+ return _v2.PreviousMixBufferVolume;
}
}
@@ -135,15 +119,11 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return new SplitterDestination();
}
- else
- {
- return new SplitterDestination(ref _v1.Next);
- }
- }
- else
- {
- return new SplitterDestination(ref _v2.Next);
+
+ return new SplitterDestination(ref _v1.Next);
}
+
+ return new SplitterDestination(ref _v2.Next);
}
}
}
@@ -169,6 +149,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
_v2 = ref v2;
}
+
///
/// Creates a new splitter destination wrapper for the splitter destination data.
///
@@ -233,7 +214,12 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// True if the splitter destination is used and has a destination.
public readonly bool IsConfigured()
{
- return Unsafe.IsNullRef(ref _v2) ? _v1.IsConfigured() : _v2.IsConfigured();
+ if (Unsafe.IsNullRef(ref _v2))
+ {
+ return _v1.IsConfigured();
+ }
+
+ return _v2.IsConfigured();
}
///
@@ -243,7 +229,12 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// The volume for the given destination.
public float GetMixVolume(int destinationIndex)
{
- return Unsafe.IsNullRef(ref _v2) ? _v1.GetMixVolume(destinationIndex) : _v2.GetMixVolume(destinationIndex);
+ if (Unsafe.IsNullRef(ref _v2))
+ {
+ return _v1.GetMixVolume(destinationIndex);
+ }
+
+ return _v2.GetMixVolume(destinationIndex);
}
///
@@ -253,7 +244,12 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// The volume for the given destination.
public float GetMixVolumePrev(int destinationIndex)
{
- return Unsafe.IsNullRef(ref _v2) ? _v1.GetMixVolumePrev(destinationIndex) : _v2.GetMixVolumePrev(destinationIndex);
+ if (Unsafe.IsNullRef(ref _v2))
+ {
+ return _v1.GetMixVolumePrev(destinationIndex);
+ }
+
+ return _v2.GetMixVolumePrev(destinationIndex);
}
///
@@ -280,13 +276,13 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
if (Unsafe.IsNullRef(ref _v2))
{
Debug.Assert(!Unsafe.IsNullRef(ref next._v1));
-
+
_v1.Link(ref next._v1);
}
else
{
Debug.Assert(!Unsafe.IsNullRef(ref next._v2));
-
+
_v2.Link(ref next._v2);
}
}
@@ -308,6 +304,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
///
/// Checks if any biquad filter is enabled.
+ /// Virtual function at function table + 0x8.
///
/// True if any biquad filter is enabled.
public bool IsBiquadFilterEnabled()
@@ -326,13 +323,14 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
///
/// Gets the biquad filter parameters.
+ /// /// Virtual function at function table + 0x10.
///
/// Biquad filter index (0 or 1).
/// Biquad filter parameters.
- public ref BiquadFilterParameter GetBiquadFilterParameter(int index)
+ public ref BiquadFilterParameter2 GetBiquadFilterParameter(int index)
{
Debug.Assert(!Unsafe.IsNullRef(ref _v2));
-
+
return ref _v2.GetBiquadFilterParameter(index);
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestinationVersion2.cs b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestinationVersion2.cs
index 3102ccdf0..7fb455241 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestinationVersion2.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestinationVersion2.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Audio.Renderer.Dsp;
using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Common.Memory;
using Ryujinx.Common.Utilities;
@@ -11,7 +12,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
///
/// Server state for a splitter destination (version 2).
///
- [StructLayout(LayoutKind.Sequential, Size = 0x110, Pack = Alignment)]
+ [StructLayout(LayoutKind.Sequential, Size = 0x128, Pack = Alignment)]
public struct SplitterDestinationVersion2
{
public const int Alignment = 0x10;
@@ -78,7 +79,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
}
}
- private Array2 _biquadFilters;
+ private Array2 _biquadFilters;
private Array2 _isPreviousBiquadFilterEnabled;
@@ -109,7 +110,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
parameter.MixBufferVolume.CopyTo(MixBufferVolume);
- _biquadFilters = parameter.BiquadFilters;
+ _biquadFilters = parameter.BiquadFilters2;
bool resetPrevVolume = isPrevVolumeResetSupported ? parameter.ResetPrevVolume : !IsUsed && parameter.IsUsed;
if (resetPrevVolume)
@@ -218,7 +219,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// True if any biquad filter is enabled.
public bool IsBiquadFilterEnabled()
{
- Span biquadFiltersSpan = _biquadFilters.AsSpan();
+ Span biquadFiltersSpan = _biquadFilters.AsSpan();
return biquadFiltersSpan[0].Enable || biquadFiltersSpan[1].Enable;
}
@@ -236,7 +237,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
///
/// Biquad filter index (0 or 1).
/// Biquad filter parameters.
- public ref BiquadFilterParameter GetBiquadFilterParameter(int index)
+ public ref BiquadFilterParameter2 GetBiquadFilterParameter(int index)
{
return ref _biquadFilters[index];
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/StateUpdater.cs b/src/Ryujinx.Audio/Renderer/Server/StateUpdater.cs
index 27207a90d..a02d70240 100644
--- a/src/Ryujinx.Audio/Renderer/Server/StateUpdater.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/StateUpdater.cs
@@ -27,39 +27,39 @@ namespace Ryujinx.Audio.Renderer.Server
private Memory _output;
private readonly uint _processHandle;
- private BehaviourContext _behaviourContext;
+ private BehaviourInfo _behaviourInfo;
private readonly ref readonly UpdateDataHeader _inputHeader;
private readonly Memory _outputHeader;
private readonly ref UpdateDataHeader OutputHeader => ref _outputHeader.Span[0];
- public StateUpdater(ReadOnlySequence input, Memory output, uint processHandle, BehaviourContext behaviourContext)
+ public StateUpdater(ReadOnlySequence input, Memory output, uint processHandle, BehaviourInfo behaviourInfo)
{
_inputReader = new SequenceReader(input);
_output = output;
_outputOrigin = _output;
_processHandle = processHandle;
- _behaviourContext = behaviourContext;
+ _behaviourInfo = behaviourInfo;
_inputHeader = ref _inputReader.GetRefOrRefToCopy(out _);
_outputHeader = SpanMemoryManager.Cast(_output[..Unsafe.SizeOf()]);
- OutputHeader.Initialize(_behaviourContext.UserRevision);
+ OutputHeader.Initialize(_behaviourInfo.UserRevision);
_output = _output[Unsafe.SizeOf()..];
}
- public ResultCode UpdateBehaviourContext()
+ public ResultCode UpdateBehaviourInfo()
{
ref readonly BehaviourParameter parameter = ref _inputReader.GetRefOrRefToCopy(out _);
- if (!BehaviourContext.CheckValidRevision(parameter.UserRevision) || parameter.UserRevision != _behaviourContext.UserRevision)
+ if (!BehaviourInfo.CheckValidRevision(parameter.UserRevision) || parameter.UserRevision != _behaviourInfo.UserRevision)
{
return ResultCode.InvalidUpdateInfo;
}
- _behaviourContext.ClearError();
- _behaviourContext.UpdateFlags(parameter.Flags);
+ _behaviourInfo.ClearError();
+ _behaviourInfo.UpdateFlags(parameter.Flags);
if (_inputHeader.BehaviourSize != Unsafe.SizeOf())
{
@@ -69,16 +69,16 @@ namespace Ryujinx.Audio.Renderer.Server
return ResultCode.Success;
}
- public ResultCode UpdateMemoryPools(Span memoryPools)
+ public ResultCode UpdateMemoryPools(Span memoryPools)
{
- PoolMapper mapper = new(_processHandle, _behaviourContext.IsMemoryPoolForceMappingEnabled());
+ PoolMapper mapper = new(_processHandle, _behaviourInfo.IsMemoryPoolForceMappingEnabled());
if (memoryPools.Length * Unsafe.SizeOf() != _inputHeader.MemoryPoolsSize)
{
return ResultCode.InvalidUpdateInfo;
}
- foreach (ref MemoryPoolState memoryPool in memoryPools)
+ foreach (ref MemoryPoolInfo memoryPool in memoryPools)
{
ref readonly MemoryPoolInParameter parameter = ref _inputReader.GetRefOrRefToCopy(out _);
@@ -125,10 +125,10 @@ namespace Ryujinx.Audio.Renderer.Server
return ResultCode.Success;
}
-
- public ResultCode UpdateVoices(VoiceContext context, PoolMapper mapper)
+
+ public ResultCode UpdateVoices2(VoiceContext context, PoolMapper mapper)
{
- if (context.GetCount() * Unsafe.SizeOf() != _inputHeader.VoicesSize)
+ if (context.GetCount() * Unsafe.SizeOf() != _inputHeader.VoicesSize)
{
return ResultCode.InvalidUpdateInfo;
}
@@ -140,27 +140,27 @@ namespace Ryujinx.Audio.Renderer.Server
// First make everything not in use.
for (int i = 0; i < context.GetCount(); i++)
{
- ref VoiceState state = ref context.GetState(i);
+ ref VoiceInfo info = ref context.GetState(i);
- state.InUse = false;
+ info.InUse = false;
}
- Memory[] voiceUpdateStatesArray = ArrayPool>.Shared.Rent(Constants.VoiceChannelCountMax);
+ Memory[] voiceStatesArray = ArrayPool>.Shared.Rent(Constants.VoiceChannelCountMax);
- Span> voiceUpdateStates = voiceUpdateStatesArray.AsSpan(0, Constants.VoiceChannelCountMax);
+ Span> voiceStates = voiceStatesArray.AsSpan(0, Constants.VoiceChannelCountMax);
// Start processing
for (int i = 0; i < context.GetCount(); i++)
{
- ref readonly VoiceInParameter parameter = ref _inputReader.GetRefOrRefToCopy(out _);
+ ref readonly VoiceInParameter2 parameter = ref _inputReader.GetRefOrRefToCopy(out _);
- voiceUpdateStates.Fill(Memory.Empty);
+ voiceStates.Fill(Memory.Empty);
ref VoiceOutStatus outStatus = ref SpanIOHelper.GetWriteRef(ref _output)[0];
if (parameter.InUse)
{
- ref VoiceState currentVoiceState = ref context.GetState(i);
+ ref VoiceInfo currentVoiceInfo = ref context.GetState(i);
Span channelResourceIdsSpan = parameter.ChannelResourceIds.AsSpan();
@@ -170,36 +170,123 @@ namespace Ryujinx.Audio.Renderer.Server
Debug.Assert(channelId >= 0 && channelId < context.GetCount());
- voiceUpdateStates[channelResourceIndex] = context.GetUpdateStateForCpu(channelId);
+ voiceStates[channelResourceIndex] = context.GetUpdateStateForCpu(channelId);
}
if (parameter.IsNew)
{
- currentVoiceState.Initialize();
+ currentVoiceInfo.Initialize();
}
- currentVoiceState.UpdateParameters(out ErrorInfo updateParameterError, in parameter, mapper, ref _behaviourContext);
+ currentVoiceInfo.UpdateParameters2(out ErrorInfo updateParameterError, in parameter, mapper, ref _behaviourInfo);
if (updateParameterError.ErrorCode != ResultCode.Success)
{
- _behaviourContext.AppendError(ref updateParameterError);
+ _behaviourInfo.AppendError(ref updateParameterError);
}
- currentVoiceState.UpdateWaveBuffers(out ErrorInfo[] waveBufferUpdateErrorInfos, in parameter, voiceUpdateStates, mapper, ref _behaviourContext);
+ currentVoiceInfo.UpdateWaveBuffers2(out ErrorInfo[] waveBufferUpdateErrorInfos, in parameter, voiceStates, mapper, ref _behaviourInfo);
foreach (ref ErrorInfo errorInfo in waveBufferUpdateErrorInfos.AsSpan())
{
if (errorInfo.ErrorCode != ResultCode.Success)
{
- _behaviourContext.AppendError(ref errorInfo);
+ _behaviourInfo.AppendError(ref errorInfo);
}
}
- currentVoiceState.WriteOutStatus(ref outStatus, in parameter, voiceUpdateStates);
+ currentVoiceInfo.WriteOutStatus2(ref outStatus, in parameter, voiceStates);
}
}
- ArrayPool>.Shared.Return(voiceUpdateStatesArray);
+ ArrayPool>.Shared.Return(voiceStatesArray);
+
+ int currentOutputSize = _output.Length;
+
+ OutputHeader.VoicesSize = (uint)(Unsafe.SizeOf() * context.GetCount());
+ OutputHeader.TotalSize += OutputHeader.VoicesSize;
+
+ Debug.Assert((initialOutputSize - currentOutputSize) == OutputHeader.VoicesSize);
+
+ _inputReader.SetConsumed(initialInputConsumed + _inputHeader.VoicesSize);
+
+ return ResultCode.Success;
+ }
+
+ public ResultCode UpdateVoices1(VoiceContext context, PoolMapper mapper)
+ {
+ if (context.GetCount() * Unsafe.SizeOf() != _inputHeader.VoicesSize)
+ {
+ return ResultCode.InvalidUpdateInfo;
+ }
+
+ int initialOutputSize = _output.Length;
+
+ long initialInputConsumed = _inputReader.Consumed;
+
+ // First make everything not in use.
+ for (int i = 0; i < context.GetCount(); i++)
+ {
+ ref VoiceInfo info = ref context.GetState(i);
+
+ info.InUse = false;
+ }
+
+ Memory[] voiceStatesArray = ArrayPool>.Shared.Rent(Constants.VoiceChannelCountMax);
+
+ Span> voiceStates = voiceStatesArray.AsSpan(0, Constants.VoiceChannelCountMax);
+
+ // Start processing
+ for (int i = 0; i < context.GetCount(); i++)
+ {
+ ref readonly VoiceInParameter1 parameter = ref _inputReader.GetRefOrRefToCopy(out _);
+
+ voiceStates.Fill(Memory.Empty);
+
+ ref VoiceOutStatus outStatus = ref SpanIOHelper.GetWriteRef(ref _output)[0];
+
+ if (parameter.InUse)
+ {
+ ref VoiceInfo currentVoiceInfo = ref context.GetState(i);
+
+ Span channelResourceIdsSpan = parameter.ChannelResourceIds.AsSpan();
+
+ for (int channelResourceIndex = 0; channelResourceIndex < parameter.ChannelCount; channelResourceIndex++)
+ {
+ int channelId = channelResourceIdsSpan[channelResourceIndex];
+
+ Debug.Assert(channelId >= 0 && channelId < context.GetCount());
+
+ voiceStates[channelResourceIndex] = context.GetUpdateStateForCpu(channelId);
+ }
+
+ if (parameter.IsNew)
+ {
+ currentVoiceInfo.Initialize();
+ }
+
+ currentVoiceInfo.UpdateParameters1(out ErrorInfo updateParameterError, in parameter, mapper, ref _behaviourInfo);
+
+ if (updateParameterError.ErrorCode != ResultCode.Success)
+ {
+ _behaviourInfo.AppendError(ref updateParameterError);
+ }
+
+ currentVoiceInfo.UpdateWaveBuffers1(out ErrorInfo[] waveBufferUpdateErrorInfos, in parameter, voiceStates, mapper, ref _behaviourInfo);
+
+ foreach (ref ErrorInfo errorInfo in waveBufferUpdateErrorInfos.AsSpan())
+ {
+ if (errorInfo.ErrorCode != ResultCode.Success)
+ {
+ _behaviourInfo.AppendError(ref errorInfo);
+ }
+ }
+
+ currentVoiceInfo.WriteOutStatus1(ref outStatus, in parameter, voiceStates);
+ }
+ }
+
+ ArrayPool>.Shared.Return(voiceStatesArray);
int currentOutputSize = _output.Length;
@@ -235,7 +322,12 @@ namespace Ryujinx.Audio.Renderer.Server
public ResultCode UpdateEffects(EffectContext context, bool isAudioRendererActive, PoolMapper mapper)
{
- if (_behaviourContext.IsEffectInfoVersion2Supported())
+ if (_behaviourInfo.IsBiquadFilterParameterFloatSupported())
+ {
+ return UpdateEffectsVersion3(context, isAudioRendererActive, mapper);
+ }
+
+ if (_behaviourInfo.IsEffectInfoVersion2Supported())
{
return UpdateEffectsVersion2(context, isAudioRendererActive, mapper);
}
@@ -243,6 +335,60 @@ namespace Ryujinx.Audio.Renderer.Server
return UpdateEffectsVersion1(context, isAudioRendererActive, mapper);
}
+ public ResultCode UpdateEffectsVersion3(EffectContext context, bool isAudioRendererActive, PoolMapper mapper)
+ {
+ if (context.GetCount() * Unsafe.SizeOf() != _inputHeader.EffectsSize)
+ {
+ return ResultCode.InvalidUpdateInfo;
+ }
+
+ int initialOutputSize = _output.Length;
+
+ long initialInputConsumed = _inputReader.Consumed;
+
+ for (int i = 0; i < context.GetCount(); i++)
+ {
+ ref readonly EffectInParameterVersion3 parameter = ref _inputReader.GetRefOrRefToCopy(out _);
+
+ ref EffectOutStatusVersion2 outStatus = ref SpanIOHelper.GetWriteRef(ref _output)[0];
+
+ ref BaseEffect effect = ref context.GetEffect(i);
+
+ if (!effect.IsTypeValid(in parameter))
+ {
+ ResetEffect(ref effect, in parameter, mapper);
+ }
+
+ effect.Update(out ErrorInfo updateErrorInfo, in parameter, mapper);
+
+ if (updateErrorInfo.ErrorCode != ResultCode.Success)
+ {
+ _behaviourInfo.AppendError(ref updateErrorInfo);
+ }
+
+ effect.StoreStatus(ref outStatus, isAudioRendererActive);
+
+ if (parameter.IsNew)
+ {
+ effect.InitializeResultState(ref context.GetDspState(i));
+ effect.InitializeResultState(ref context.GetState(i));
+ }
+
+ effect.UpdateResultState(ref outStatus.ResultState, ref context.GetState(i));
+ }
+
+ int currentOutputSize = _output.Length;
+
+ OutputHeader.EffectsSize = (uint)(Unsafe.SizeOf() * context.GetCount());
+ OutputHeader.TotalSize += OutputHeader.EffectsSize;
+
+ Debug.Assert((initialOutputSize - currentOutputSize) == OutputHeader.EffectsSize);
+
+ _inputReader.SetConsumed(initialInputConsumed + _inputHeader.EffectsSize);
+
+ return ResultCode.Success;
+ }
+
public ResultCode UpdateEffectsVersion2(EffectContext context, bool isAudioRendererActive, PoolMapper mapper)
{
if (context.GetCount() * Unsafe.SizeOf() != _inputHeader.EffectsSize)
@@ -271,7 +417,7 @@ namespace Ryujinx.Audio.Renderer.Server
if (updateErrorInfo.ErrorCode != ResultCode.Success)
{
- _behaviourContext.AppendError(ref updateErrorInfo);
+ _behaviourInfo.AppendError(ref updateErrorInfo);
}
effect.StoreStatus(ref outStatus, isAudioRendererActive);
@@ -325,7 +471,7 @@ namespace Ryujinx.Audio.Renderer.Server
if (updateErrorInfo.ErrorCode != ResultCode.Success)
{
- _behaviourContext.AppendError(ref updateErrorInfo);
+ _behaviourInfo.AppendError(ref updateErrorInfo);
}
effect.StoreStatus(ref outStatus, isAudioRendererActive);
@@ -384,7 +530,7 @@ namespace Ryujinx.Audio.Renderer.Server
uint inputMixSize;
uint inputSize = 0;
- if (_behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported())
+ if (_behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported())
{
ref readonly MixInParameterDirtyOnlyUpdate parameter = ref _inputReader.GetRefOrRefToCopy(out _);
@@ -423,12 +569,12 @@ namespace Ryujinx.Audio.Renderer.Server
int mixId = i;
- if (_behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported())
+ if (_behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported())
{
mixId = parameter.MixId;
}
- ref MixState mix = ref mixContext.GetState(mixId);
+ ref MixInfo mix = ref mixContext.GetState(mixId);
if (parameter.IsUsed != mix.IsUsed)
{
@@ -444,13 +590,13 @@ namespace Ryujinx.Audio.Renderer.Server
if (mix.IsUsed)
{
- isMixContextDirty |= mix.Update(mixContext.EdgeMatrix, in parameter, effectContext, splitterContext, _behaviourContext);
+ isMixContextDirty |= mix.Update(mixContext.EdgeMatrix, in parameter, effectContext, splitterContext, _behaviourInfo);
}
}
if (isMixContextDirty)
{
- if (_behaviourContext.IsSplitterSupported() && splitterContext.UsingSplitter())
+ if (_behaviourInfo.IsSplitterSupported() && splitterContext.UsingSplitter())
{
if (!mixContext.Sort(splitterContext))
{
@@ -507,7 +653,7 @@ namespace Ryujinx.Audio.Renderer.Server
if (updateErrorInfo.ErrorCode != ResultCode.Success)
{
- _behaviourContext.AppendError(ref updateErrorInfo);
+ _behaviourInfo.AppendError(ref updateErrorInfo);
}
}
@@ -555,7 +701,7 @@ namespace Ryujinx.Audio.Renderer.Server
{
ref BehaviourErrorInfoOutStatus outStatus = ref SpanIOHelper.GetWriteRef(ref _output)[0];
- _behaviourContext.CopyErrorInfo(outStatus.ErrorInfos.AsSpan(), out outStatus.ErrorInfosCount);
+ _behaviourInfo.CopyErrorInfo(outStatus.ErrorInfos.AsSpan(), out outStatus.ErrorInfosCount);
OutputHeader.BehaviourSize = (uint)Unsafe.SizeOf();
OutputHeader.TotalSize += OutputHeader.BehaviourSize;
diff --git a/src/Ryujinx.Audio/Renderer/Server/Types/PlayState.cs b/src/Ryujinx.Audio/Renderer/Server/Types/PlayState.cs
index 46aae05ab..4b72274ce 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Types/PlayState.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Types/PlayState.cs
@@ -1,7 +1,9 @@
+using Ryujinx.Audio.Renderer.Server.Voice;
+
namespace Ryujinx.Audio.Renderer.Server.Types
{
///
- /// The internal play state of a
+ /// The internal play state of a
///
public enum PlayState
{
@@ -24,7 +26,7 @@ namespace Ryujinx.Audio.Renderer.Server.Types
///
///
/// This is changed to the state after command generation.
- ///
+ ///
///
Stopping,
diff --git a/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerState.cs b/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerInfo.cs
similarity index 82%
rename from src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerState.cs
rename to src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerInfo.cs
index 39a58c91a..d84d8fa70 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerState.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerInfo.cs
@@ -5,7 +5,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
///
/// Server state for a upsampling.
///
- public class UpsamplerState
+ public class UpsamplerInfo
{
///
/// The output buffer containing the target samples.
@@ -18,7 +18,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
public uint SampleCount { get; }
///
- /// The index of the . (used to free it)
+ /// The index of the . (used to free it)
///
private readonly int _index;
@@ -43,13 +43,13 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
public UpsamplerBufferState[] BufferStates;
///
- /// Create a new .
+ /// Create a new .
///
/// The upsampler manager.
- /// The index of the . (used to free it)
+ /// The index of the . (used to free it)
/// The output buffer used to contain the target samples.
/// The target sample count.
- public UpsamplerState(UpsamplerManager manager, int index, Memory outputBuffer, uint sampleCount)
+ public UpsamplerInfo(UpsamplerManager manager, int index, Memory outputBuffer, uint sampleCount)
{
_manager = manager;
_index = index;
@@ -58,7 +58,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
}
///
- /// Release the .
+ /// Release the .
///
public void Release()
{
diff --git a/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerManager.cs b/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerManager.cs
index 8b3f39439..942345f8d 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerManager.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerManager.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
///
/// The upsamplers instances.
///
- private readonly UpsamplerState[] _upsamplers;
+ private readonly UpsamplerInfo[] _upsamplers;
///
/// The count of upsamplers.
@@ -39,14 +39,14 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
_upSamplerWorkBuffer = upSamplerWorkBuffer;
_count = count;
- _upsamplers = new UpsamplerState[_count];
+ _upsamplers = new UpsamplerInfo[_count];
}
///
- /// Allocate a new .
+ /// Allocate a new .
///
- /// A new or null if out of memory.
- public UpsamplerState Allocate()
+ /// A new or null if out of memory.
+ public UpsamplerInfo Allocate()
{
int workBufferOffset = 0;
@@ -56,7 +56,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
{
if (_upsamplers[i] == null)
{
- _upsamplers[i] = new UpsamplerState(this, i, _upSamplerWorkBuffer.Slice(workBufferOffset, Constants.UpSampleEntrySize), Constants.TargetSampleCount);
+ _upsamplers[i] = new UpsamplerInfo(this, i, _upSamplerWorkBuffer.Slice(workBufferOffset, Constants.UpSampleEntrySize), Constants.TargetSampleCount);
return _upsamplers[i];
}
@@ -69,9 +69,9 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
}
///
- /// Free a at the given index.
+ /// Free a at the given index.
///
- /// The index of the to free.
+ /// The index of the to free.
public void Free(int index)
{
lock (_lock)
diff --git a/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceContext.cs b/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceContext.cs
index 827d24fe5..5cb334ddd 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceContext.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceContext.cs
@@ -11,14 +11,14 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
public class VoiceContext
{
///
- /// Storage of the sorted indices to .
+ /// Storage of the sorted indices to .
///
private Memory _sortedVoices;
///
- /// Storage for .
+ /// Storage for .
///
- private Memory _voices;
+ private Memory _voices;
///
/// Storage for .
@@ -26,27 +26,27 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
private Memory _voiceChannelResources;
///
- /// Storage for that are used during audio renderer server updates.
+ /// Storage for that are used during audio renderer server updates.
///
- private Memory _voiceUpdateStatesCpu;
+ private Memory _voiceStatesCpu;
///
- /// Storage for for the .
+ /// Storage for for the .
///
- private Memory _voiceUpdateStatesDsp;
+ private Memory _voiceStatesDsp;
///
/// The total voice count.
///
private uint _voiceCount;
- public void Initialize(Memory sortedVoices, Memory voices, Memory voiceChannelResources, Memory voiceUpdateStatesCpu, Memory voiceUpdateStatesDsp, uint voiceCount)
+ public void Initialize(Memory sortedVoices, Memory voices, Memory voiceChannelResources, Memory voiceStatesCpu, Memory voiceStatesDsp, uint voiceCount)
{
_sortedVoices = sortedVoices;
_voices = voices;
_voiceChannelResources = voiceChannelResources;
- _voiceUpdateStatesCpu = voiceUpdateStatesCpu;
- _voiceUpdateStatesDsp = voiceUpdateStatesDsp;
+ _voiceStatesCpu = voiceStatesCpu;
+ _voiceStatesDsp = voiceStatesDsp;
_voiceCount = voiceCount;
}
@@ -70,38 +70,38 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
}
///
- /// Get a at the given .
+ /// Get a at the given .
///
/// The index to use.
- /// A at the given .
- /// The returned should only be used when updating the server state.
- public Memory GetUpdateStateForCpu(int id)
+ /// A at the given .
+ /// The returned should only be used when updating the server state.
+ public Memory GetUpdateStateForCpu(int id)
{
- return SpanIOHelper.GetMemory(_voiceUpdateStatesCpu, id, _voiceCount);
+ return SpanIOHelper.GetMemory(_voiceStatesCpu, id, _voiceCount);
}
///
- /// Get a at the given .
+ /// Get a at the given .
///
/// The index to use.
- /// A at the given .
- /// The returned should only be used in the context of processing on the .
- public Memory GetUpdateStateForDsp(int id)
+ /// A at the given .
+ /// The returned should only be used in the context of processing on the .
+ public Memory GetUpdateStateForDsp(int id)
{
- return SpanIOHelper.GetMemory(_voiceUpdateStatesDsp, id, _voiceCount);
+ return SpanIOHelper.GetMemory(_voiceStatesDsp, id, _voiceCount);
}
///
- /// Get a reference to a at the given .
+ /// Get a reference to a at the given .
///
/// The index to use.
- /// A reference to a at the given .
- public ref VoiceState GetState(int id)
+ /// A reference to a at the given .
+ public ref VoiceInfo GetState(int id)
{
return ref SpanIOHelper.GetFromMemory(_voices, id, _voiceCount);
}
- public ref VoiceState GetSortedState(int id)
+ public ref VoiceInfo GetSortedState(int id)
{
Debug.Assert(id >= 0 && id < _voiceCount);
@@ -113,7 +113,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
///
public void UpdateForCommandGeneration()
{
- _voiceUpdateStatesDsp.CopyTo(_voiceUpdateStatesCpu);
+ _voiceStatesDsp.CopyTo(_voiceStatesCpu);
}
///
@@ -130,14 +130,14 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
sortedVoicesTemp.Sort((a, b) =>
{
- ref VoiceState aState = ref GetState(a);
- ref VoiceState bState = ref GetState(b);
+ ref VoiceInfo aInfo = ref GetState(a);
+ ref VoiceInfo bInfo = ref GetState(b);
- int result = aState.Priority.CompareTo(bState.Priority);
+ int result = aInfo.Priority.CompareTo(bInfo.Priority);
if (result == 0)
{
- return aState.SortingOrder.CompareTo(bState.SortingOrder);
+ return aInfo.SortingOrder.CompareTo(bInfo.SortingOrder);
}
return result;
diff --git a/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceState.cs b/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceInfo.cs
similarity index 66%
rename from src/Ryujinx.Audio/Renderer/Server/Voice/VoiceState.cs
rename to src/Ryujinx.Audio/Renderer/Server/Voice/VoiceInfo.cs
index 9fcff199d..ba6158b71 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceState.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceInfo.cs
@@ -1,5 +1,6 @@
using Ryujinx.Audio.Common;
using Ryujinx.Audio.Renderer.Common;
+using Ryujinx.Audio.Renderer.Dsp;
using Ryujinx.Audio.Renderer.Dsp.State;
using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Audio.Renderer.Server.MemoryPool;
@@ -9,13 +10,13 @@ using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using static Ryujinx.Audio.Renderer.Common.BehaviourParameter;
-using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
+using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter1;
using PlayState = Ryujinx.Audio.Renderer.Server.Types.PlayState;
namespace Ryujinx.Audio.Renderer.Server.Voice
{
[StructLayout(LayoutKind.Sequential, Pack = Alignment)]
- public struct VoiceState
+ public struct VoiceInfo
{
public const int Alignment = 0x10;
@@ -102,7 +103,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
///
/// Biquad filters to apply to the output of the voice.
///
- public Array2 BiquadFilters;
+ public Array2 BiquadFilters;
///
/// Total count of of the voice.
@@ -185,7 +186,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
public Span BiquadFilterNeedInitialization => SpanHelpers.AsSpan(ref _biquadFilterNeedInitialization);
///
- /// Initialize the .
+ /// Initialize the .
///
public void Initialize()
{
@@ -215,7 +216,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
}
///
- /// Initialize the in this .
+ /// Initialize the in this .
///
private void InitializeWaveBuffers()
{
@@ -250,13 +251,13 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
{
return MixId != Constants.UnusedMixId || SplitterId != Constants.UnusedSplitterId;
}
-
+
///
/// Indicate if the server voice information needs to be updated.
///
/// The user parameter.
/// Return true, if the server voice information needs to be updated.
- private readonly bool ShouldUpdateParameters(in VoiceInParameter parameter)
+ private readonly bool ShouldUpdateParameters2(in VoiceInParameter2 parameter)
{
if (DataSourceStateAddressInfo.CpuAddress == parameter.DataSourceStateAddress)
{
@@ -268,14 +269,31 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
DataSourceStateUnmapped;
}
+ ///
+ /// Indicate if the server voice information needs to be updated.
+ ///
+ /// The user parameter.
+ /// Return true, if the server voice information needs to be updated.
+ private readonly bool ShouldUpdateParameters1(in VoiceInParameter1 parameter)
+ {
+ if (DataSourceStateAddressInfo.CpuAddress == parameter.DataSourceStateAddress)
+ {
+ return DataSourceStateAddressInfo.Size != parameter.DataSourceStateSize;
+ }
+
+ return DataSourceStateAddressInfo.CpuAddress != parameter.DataSourceStateAddress ||
+ DataSourceStateAddressInfo.Size != parameter.DataSourceStateSize ||
+ DataSourceStateUnmapped;
+ }
+
///
/// Update the internal state from a user parameter.
///
/// The possible that was generated.
/// The user parameter.
/// The mapper to use.
- /// The behaviour context.
- public void UpdateParameters(out ErrorInfo outErrorInfo, in VoiceInParameter parameter, PoolMapper poolMapper, ref BehaviourContext behaviourContext)
+ /// The behaviour context.
+ public void UpdateParameters2(out ErrorInfo outErrorInfo, in VoiceInParameter2 parameter, PoolMapper poolMapper, ref BehaviourInfo behaviourInfo)
{
InUse = parameter.InUse;
Id = parameter.Id;
@@ -296,14 +314,14 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
WaveBuffersCount = parameter.WaveBuffersCount;
WaveBuffersIndex = parameter.WaveBuffersIndex;
- if (behaviourContext.IsFlushVoiceWaveBuffersSupported())
+ if (behaviourInfo.IsFlushVoiceWaveBuffersSupported())
{
FlushWaveBufferCount += parameter.FlushWaveBufferCount;
}
MixId = parameter.MixId;
- if (behaviourContext.IsSplitterSupported())
+ if (behaviourInfo.IsSplitterSupported())
{
SplitterId = parameter.SplitterId;
}
@@ -316,7 +334,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
DecodingBehaviour behaviour = DecodingBehaviour.Default;
- if (behaviourContext.IsDecodingBehaviourFlagSupported())
+ if (behaviourInfo.IsDecodingBehaviourFlagSupported())
{
behaviour = parameter.DecodingBehaviourFlags;
}
@@ -328,7 +346,78 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
VoiceDropFlag = false;
}
- if (ShouldUpdateParameters(in parameter))
+ if (ShouldUpdateParameters2(in parameter))
+ {
+ DataSourceStateUnmapped = !poolMapper.TryAttachBuffer(out outErrorInfo, ref DataSourceStateAddressInfo, parameter.DataSourceStateAddress, parameter.DataSourceStateSize);
+ }
+ else
+ {
+ outErrorInfo = new ErrorInfo();
+ }
+ }
+
+ ///
+ /// Update the internal state from a user parameter.
+ ///
+ /// The possible that was generated.
+ /// The user paramter2.
+ /// The mapper to use.
+ /// The behaviour context.
+ public void UpdateParameters1(out ErrorInfo outErrorInfo, in VoiceInParameter1 parameter, PoolMapper poolMapper, ref BehaviourInfo behaviourInfo)
+ {
+ InUse = parameter.InUse;
+ Id = parameter.Id;
+ NodeId = parameter.NodeId;
+
+ UpdatePlayState(parameter.PlayState);
+
+ SrcQuality = parameter.SrcQuality;
+
+ Priority = parameter.Priority;
+ SortingOrder = parameter.SortingOrder;
+ SampleRate = parameter.SampleRate;
+ SampleFormat = parameter.SampleFormat;
+ ChannelsCount = parameter.ChannelCount;
+ Pitch = parameter.Pitch;
+ Volume = parameter.Volume;
+ BiquadFilters[0] = BiquadFilterHelper.ToBiquadFilterParameter2(parameter.BiquadFilters[0]);
+ BiquadFilters[1] = BiquadFilterHelper.ToBiquadFilterParameter2(parameter.BiquadFilters[1]);
+ WaveBuffersCount = parameter.WaveBuffersCount;
+ WaveBuffersIndex = parameter.WaveBuffersIndex;
+
+ if (behaviourInfo.IsFlushVoiceWaveBuffersSupported())
+ {
+ FlushWaveBufferCount += parameter.FlushWaveBufferCount;
+ }
+
+ MixId = parameter.MixId;
+
+ if (behaviourInfo.IsSplitterSupported())
+ {
+ SplitterId = parameter.SplitterId;
+ }
+ else
+ {
+ SplitterId = Constants.UnusedSplitterId;
+ }
+
+ parameter.ChannelResourceIds.AsSpan().CopyTo(ChannelResourceIds.AsSpan());
+
+ DecodingBehaviour behaviour = DecodingBehaviour.Default;
+
+ if (behaviourInfo.IsDecodingBehaviourFlagSupported())
+ {
+ behaviour = parameter.DecodingBehaviourFlags;
+ }
+
+ DecodingBehaviour = behaviour;
+
+ if (parameter.ResetVoiceDropFlag)
+ {
+ VoiceDropFlag = false;
+ }
+
+ if (ShouldUpdateParameters1(in parameter))
{
DataSourceStateUnmapped = !poolMapper.TryAttachBuffer(out outErrorInfo, ref DataSourceStateAddressInfo, parameter.DataSourceStateAddress, parameter.DataSourceStateSize);
}
@@ -375,14 +464,14 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
PlayState = newServerPlayState;
}
-
+
///
/// Write the status of the voice to the given user output.
///
/// The given user output.
/// The user parameter.
- /// The voice states associated to the .
- public void WriteOutStatus(ref VoiceOutStatus outStatus, in VoiceInParameter parameter, ReadOnlySpan> voiceUpdateStates)
+ /// The voice states associated to the .
+ public void WriteOutStatus2(ref VoiceOutStatus outStatus, in VoiceInParameter2 parameter, ReadOnlySpan> voiceStates)
{
#if DEBUG
// Sanity check in debug mode of the internal state
@@ -390,8 +479,8 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
{
for (int i = 1; i < ChannelsCount; i++)
{
- ref VoiceUpdateState stateA = ref voiceUpdateStates[i - 1].Span[0];
- ref VoiceUpdateState stateB = ref voiceUpdateStates[i].Span[0];
+ ref VoiceState stateA = ref voiceStates[i - 1].Span[0];
+ ref VoiceState stateB = ref voiceStates[i].Span[0];
Debug.Assert(stateA.WaveBufferConsumed == stateB.WaveBufferConsumed);
Debug.Assert(stateA.PlayedSampleCount == stateB.PlayedSampleCount);
@@ -412,7 +501,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
}
else
{
- ref VoiceUpdateState state = ref voiceUpdateStates[0].Span[0];
+ ref VoiceState state = ref voiceStates[0].Span[0];
outStatus.VoiceDropFlag = VoiceDropFlag;
outStatus.PlayedWaveBuffersCount = state.WaveBufferConsumed;
@@ -421,19 +510,63 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
}
///
- /// Update the internal state of all the of the .
+ /// Write the status of the voice to the given user output.
+ ///
+ /// The given user output.
+ /// The user parameter.
+ /// The voice states associated to the .
+ public void WriteOutStatus1(ref VoiceOutStatus outStatus, in VoiceInParameter1 parameter, ReadOnlySpan> voiceStates)
+ {
+#if DEBUG
+ // Sanity check in debug mode of the internal state
+ if (!parameter.IsNew && !IsNew)
+ {
+ for (int i = 1; i < ChannelsCount; i++)
+ {
+ ref VoiceState stateA = ref voiceStates[i - 1].Span[0];
+ ref VoiceState stateB = ref voiceStates[i].Span[0];
+
+ Debug.Assert(stateA.WaveBufferConsumed == stateB.WaveBufferConsumed);
+ Debug.Assert(stateA.PlayedSampleCount == stateB.PlayedSampleCount);
+ Debug.Assert(stateA.Offset == stateB.Offset);
+ Debug.Assert(stateA.WaveBufferIndex == stateB.WaveBufferIndex);
+ Debug.Assert(stateA.Fraction == stateB.Fraction);
+ Debug.Assert(stateA.IsWaveBufferValid.SequenceEqual(stateB.IsWaveBufferValid));
+ }
+ }
+#endif
+ if (parameter.IsNew || IsNew)
+ {
+ IsNew = true;
+
+ outStatus.VoiceDropFlag = false;
+ outStatus.PlayedWaveBuffersCount = 0;
+ outStatus.PlayedSampleCount = 0;
+ }
+ else
+ {
+ ref VoiceState state = ref voiceStates[0].Span[0];
+
+ outStatus.VoiceDropFlag = VoiceDropFlag;
+ outStatus.PlayedWaveBuffersCount = state.WaveBufferConsumed;
+ outStatus.PlayedSampleCount = state.PlayedSampleCount;
+ }
+ }
+
+ ///
+ /// Update the internal state of all the of the .
///
/// An array of used to report errors when mapping any of the .
/// The user parameter.
- /// The voice states associated to the .
+ /// The voice states associated to the .
/// The mapper to use.
- /// The behaviour context.
- public void UpdateWaveBuffers(
+ /// The behaviour context.
+ public void UpdateWaveBuffers2(
out ErrorInfo[] errorInfos,
- in VoiceInParameter parameter,
- ReadOnlySpan> voiceUpdateStates,
+ in VoiceInParameter2 parameter,
+ ReadOnlySpan> voiceStates,
PoolMapper mapper,
- ref BehaviourContext behaviourContext)
+ ref BehaviourInfo behaviourInfo)
{
errorInfos = new ErrorInfo[Constants.VoiceWaveBufferCount * 2];
@@ -443,23 +576,61 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
for (int i = 0; i < parameter.ChannelCount; i++)
{
- voiceUpdateStates[i].Span[0].IsWaveBufferValid.Clear();
+ voiceStates[i].Span[0].IsWaveBufferValid.Clear();
}
}
- ref VoiceUpdateState voiceUpdateState = ref voiceUpdateStates[0].Span[0];
+ ref VoiceState voiceState = ref voiceStates[0].Span[0];
Span waveBuffersSpan = WaveBuffers.AsSpan();
Span pWaveBuffersSpan = parameter.WaveBuffers.AsSpan();
for (int i = 0; i < Constants.VoiceWaveBufferCount; i++)
{
- UpdateWaveBuffer(errorInfos.AsSpan(i * 2, 2), ref waveBuffersSpan[i], ref pWaveBuffersSpan[i], parameter.SampleFormat, voiceUpdateState.IsWaveBufferValid[i], mapper, ref behaviourContext);
+ UpdateWaveBuffer(errorInfos.AsSpan(i * 2, 2), ref waveBuffersSpan[i], ref pWaveBuffersSpan[i], parameter.SampleFormat, voiceState.IsWaveBufferValid[i], mapper, ref behaviourInfo);
}
}
///
- /// Update the internal state of one of the of the .
+ /// Update the internal state of all the of the .
+ ///
+ /// An array of used to report errors when mapping any of the .
+ /// The user parameter.
+ /// The voice states associated to the .
+ /// The mapper to use.
+ /// The behaviour context.
+ public void UpdateWaveBuffers1(
+ out ErrorInfo[] errorInfos,
+ in VoiceInParameter1 parameter,
+ ReadOnlySpan> voiceStates,
+ PoolMapper mapper,
+ ref BehaviourInfo behaviourInfo)
+ {
+ errorInfos = new ErrorInfo[Constants.VoiceWaveBufferCount * 2];
+
+ if (parameter.IsNew)
+ {
+ InitializeWaveBuffers();
+
+ for (int i = 0; i < parameter.ChannelCount; i++)
+ {
+ voiceStates[i].Span[0].IsWaveBufferValid.Clear();
+ }
+ }
+
+ ref VoiceState voiceState = ref voiceStates[0].Span[0];
+
+ Span waveBuffersSpan = WaveBuffers.AsSpan();
+ Span pWaveBuffersSpan = parameter.WaveBuffers.AsSpan();
+
+ for (int i = 0; i < Constants.VoiceWaveBufferCount; i++)
+ {
+ UpdateWaveBuffer(errorInfos.AsSpan(i * 2, 2), ref waveBuffersSpan[i], ref pWaveBuffersSpan[i], parameter.SampleFormat, voiceState.IsWaveBufferValid[i], mapper, ref behaviourInfo);
+ }
+ }
+
+ ///
+ /// Update the internal state of one of the of the .
///
/// A used to report errors when mapping the .
/// The to update.
@@ -467,7 +638,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
/// The from the user input.
/// If set to true, the server side wavebuffer is considered valid.
/// The mapper to use.
- /// The behaviour context.
+ /// The behaviour context.
private void UpdateWaveBuffer(
Span errorInfos,
ref WaveBuffer waveBuffer,
@@ -475,7 +646,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
SampleFormat sampleFormat,
bool isValid,
PoolMapper mapper,
- ref BehaviourContext behaviourContext)
+ ref BehaviourInfo behaviourInfo)
{
if (!isValid && waveBuffer.IsSendToAudioProcessor && waveBuffer.BufferAddressInfo.CpuAddress != 0)
{
@@ -502,7 +673,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
errorInfos[0] = bufferInfoError;
- if (sampleFormat == SampleFormat.Adpcm && behaviourContext.IsAdpcmLoopContextBugFixed() && inputWaveBuffer.ContextAddress != 0)
+ if (sampleFormat == SampleFormat.Adpcm && behaviourInfo.IsAdpcmLoopContextBugFixed() && inputWaveBuffer.ContextAddress != 0)
{
bool adpcmLoopContextMapped = mapper.TryAttachBuffer(out ErrorInfo adpcmLoopContextInfoError,
ref waveBuffer.ContextAddressInfo,
@@ -511,13 +682,13 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
errorInfos[1] = adpcmLoopContextInfoError;
- if (adpcmLoopContextMapped)
+ if (!adpcmLoopContextMapped || BufferInfoUnmapped)
{
- BufferInfoUnmapped = DataSourceStateUnmapped;
+ BufferInfoUnmapped = true;
}
else
{
- BufferInfoUnmapped = true;
+ BufferInfoUnmapped = false;
}
}
else
@@ -534,7 +705,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
}
///
- /// Reset the resources associated to this .
+ /// Reset the resources associated to this .
///
/// The voice context.
private void ResetResources(VoiceContext context)
@@ -549,9 +720,9 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
Debug.Assert(voiceChannelResource.IsUsed);
- Memory dspSharedState = context.GetUpdateStateForDsp(channelResourceId);
+ Memory dspSharedState = context.GetUpdateStateForDsp(channelResourceId);
- MemoryMarshal.Cast(dspSharedState.Span).Clear();
+ MemoryMarshal.Cast(dspSharedState.Span).Clear();
voiceChannelResource.UpdateState();
}
@@ -561,9 +732,9 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
/// Flush a certain amount of .
///
/// The amount of wavebuffer to flush.
- /// The voice states associated to the .
+ /// The voice states associated to the .
/// The channel count from user input.
- private void FlushWaveBuffers(uint waveBufferCount, Memory[] voiceUpdateStates, uint channelCount)
+ private void FlushWaveBuffers(uint waveBufferCount, Memory[] voiceStates, uint channelCount)
{
uint waveBufferIndex = WaveBuffersIndex;
@@ -575,12 +746,17 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
for (int j = 0; j < channelCount; j++)
{
- ref VoiceUpdateState voiceUpdateState = ref voiceUpdateStates[j].Span[0];
-
- voiceUpdateState.WaveBufferIndex = (voiceUpdateState.WaveBufferIndex + 1) % Constants.VoiceWaveBufferCount;
- voiceUpdateState.WaveBufferConsumed++;
- voiceUpdateState.IsWaveBufferValid[(int)waveBufferIndex] = false;
+ ref VoiceState voiceState = ref voiceStates[j].Span[0];
+
+ if (!waveBuffersSpan[(int)waveBufferIndex].IsSendToAudioProcessor || voiceState.IsWaveBufferValid[(int)waveBufferIndex])
+ {
+ voiceState.WaveBufferIndex = (voiceState.WaveBufferIndex + 1) % Constants.VoiceWaveBufferCount;
+ voiceState.WaveBufferConsumed++;
+ voiceState.IsWaveBufferValid[(int)waveBufferIndex] = false;
+ }
}
+
+ waveBuffersSpan[(int)waveBufferIndex].IsSendToAudioProcessor = true;
waveBufferIndex = (waveBufferIndex + 1) % Constants.VoiceWaveBufferCount;
}
@@ -589,13 +765,13 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
///
/// Update the internal parameters for command generation.
///
- /// The voice states associated to the .
+ /// The voice states associated to the .
/// Return true if this voice should be played.
- public bool UpdateParametersForCommandGeneration(Memory[] voiceUpdateStates)
+ public bool UpdateParametersForCommandGeneration(Memory[] voiceStates)
{
if (FlushWaveBufferCount != 0)
{
- FlushWaveBuffers(FlushWaveBufferCount, voiceUpdateStates, ChannelsCount);
+ FlushWaveBuffers(FlushWaveBufferCount, voiceStates, ChannelsCount);
FlushWaveBufferCount = 0;
}
@@ -615,9 +791,9 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
{
for (int y = 0; y < ChannelsCount; y++)
{
- Debug.Assert(!voiceUpdateStates[y].Span[0].IsWaveBufferValid[i]);
+ Debug.Assert(!voiceStates[y].Span[0].IsWaveBufferValid[i]);
- voiceUpdateStates[y].Span[0].IsWaveBufferValid[i] = true;
+ voiceStates[y].Span[0].IsWaveBufferValid[i] = true;
}
waveBuffer.IsSendToAudioProcessor = true;
@@ -626,11 +802,11 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
WasPlaying = false;
- ref VoiceUpdateState primaryVoiceUpdateState = ref voiceUpdateStates[0].Span[0];
+ ref VoiceState primaryVoiceState = ref voiceStates[0].Span[0];
- for (int i = 0; i < primaryVoiceUpdateState.IsWaveBufferValid.Length; i++)
+ for (int i = 0; i < primaryVoiceState.IsWaveBufferValid.Length; i++)
{
- if (primaryVoiceUpdateState.IsWaveBufferValid[i])
+ if (primaryVoiceState.IsWaveBufferValid[i])
{
return true;
}
@@ -649,27 +825,27 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
for (int j = 0; j < ChannelsCount; j++)
{
- ref VoiceUpdateState voiceUpdateState = ref voiceUpdateStates[j].Span[0];
+ ref VoiceState voiceState = ref voiceStates[j].Span[0];
- if (voiceUpdateState.IsWaveBufferValid[i])
+ if (voiceState.IsWaveBufferValid[i])
{
- voiceUpdateState.WaveBufferIndex = (voiceUpdateState.WaveBufferIndex + 1) % Constants.VoiceWaveBufferCount;
- voiceUpdateState.WaveBufferConsumed++;
+ voiceState.WaveBufferIndex = (voiceState.WaveBufferIndex + 1) % Constants.VoiceWaveBufferCount;
+ voiceState.WaveBufferConsumed++;
}
- voiceUpdateState.IsWaveBufferValid[i] = false;
+ voiceState.IsWaveBufferValid[i] = false;
}
}
for (int i = 0; i < ChannelsCount; i++)
{
- ref VoiceUpdateState voiceUpdateState = ref voiceUpdateStates[i].Span[0];
+ ref VoiceState voiceState = ref voiceStates[i].Span[0];
- voiceUpdateState.Offset = 0;
- voiceUpdateState.PlayedSampleCount = 0;
- voiceUpdateState.Pitch.AsSpan().Clear();
- voiceUpdateState.Fraction = 0;
- voiceUpdateState.LoopContext = new AdpcmLoopContext();
+ voiceState.Offset = 0;
+ voiceState.PlayedSampleCount = 0;
+ voiceState.Pitch.AsSpan().Clear();
+ voiceState.Fraction = 0;
+ voiceState.LoopContext = new AdpcmLoopContext();
}
PlayState = PlayState.Stopped;
@@ -715,16 +891,16 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
IsNew = false;
}
- Memory[] voiceUpdateStates = new Memory[Constants.VoiceChannelCountMax];
+ Memory[] voiceStates = new Memory[Constants.VoiceChannelCountMax];
Span channelResourceIdsSpan = ChannelResourceIds.AsSpan();
for (int i = 0; i < ChannelsCount; i++)
{
- voiceUpdateStates[i] = context.GetUpdateStateForDsp(channelResourceIdsSpan[i]);
+ voiceStates[i] = context.GetUpdateStateForDsp(channelResourceIdsSpan[i]);
}
- return UpdateParametersForCommandGeneration(voiceUpdateStates);
+ return UpdateParametersForCommandGeneration(voiceStates);
}
}
}
diff --git a/src/Ryujinx.Common/Collections/BitMap.cs b/src/Ryujinx.Common/Collections/BitMap.cs
new file mode 100644
index 000000000..2c9211300
--- /dev/null
+++ b/src/Ryujinx.Common/Collections/BitMap.cs
@@ -0,0 +1,226 @@
+namespace Ryujinx.Common.Collections
+{
+ ///
+ /// Represents a collection that can store 1 bit values.
+ ///
+ public struct BitMap
+ {
+ ///
+ /// Size in bits of the integer used internally for the groups of bits.
+ ///
+ public const int IntSize = 64;
+
+ private const int IntShift = 6;
+ private const int IntMask = IntSize - 1;
+
+ private readonly long[] _masks;
+
+ ///
+ /// Gets or sets the value of a bit.
+ ///
+ /// Bit to access
+ /// Bit value
+ public bool this[int bit]
+ {
+ get => IsSet(bit);
+ set
+ {
+ if (value)
+ {
+ Set(bit);
+ }
+ else
+ {
+ Clear(bit);
+ }
+ }
+ }
+
+ ///
+ /// Creates a new bitmap.
+ ///
+ /// Total number of bits
+ public BitMap(int count)
+ {
+ _masks = new long[(count + IntMask) / IntSize];
+ }
+
+ ///
+ /// Checks if any bit is set.
+ ///
+ /// True if any bit is set, false otherwise
+ public bool AnySet()
+ {
+ for (int i = 0; i < _masks.Length; i++)
+ {
+ if (_masks[i] != 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// Checks if a specific bit is set.
+ ///
+ /// Bit to be checked
+ /// True if set, false otherwise
+ public bool IsSet(int bit)
+ {
+ int wordIndex = bit >> IntShift;
+ int wordBit = bit & IntMask;
+
+ long wordMask = 1L << wordBit;
+
+ return (_masks[wordIndex] & wordMask) != 0;
+ }
+
+ ///
+ /// Checks if any bit inside a given range of bits is set.
+ ///
+ /// Start bit of the range
+ /// End bit of the range (inclusive)
+ /// True if any bit is set, false otherwise
+ public bool IsSet(int start, int end)
+ {
+ if (start == end)
+ {
+ return IsSet(start);
+ }
+
+ int startIndex = start >> IntShift;
+ int startBit = start & IntMask;
+ long startMask = -1L << startBit;
+
+ int endIndex = end >> IntShift;
+ int endBit = end & IntMask;
+ long endMask = (long)(ulong.MaxValue >> (IntMask - endBit));
+
+ if (startIndex == endIndex)
+ {
+ return (_masks[startIndex] & startMask & endMask) != 0;
+ }
+
+ if ((_masks[startIndex] & startMask) != 0)
+ {
+ return true;
+ }
+
+ for (int i = startIndex + 1; i < endIndex; i++)
+ {
+ if (_masks[i] != 0)
+ {
+ return true;
+ }
+ }
+
+ if ((_masks[endIndex] & endMask) != 0)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Sets the value of a bit to 1.
+ ///
+ /// Bit to be set
+ /// True if the bit was 0 and then changed to 1, false if it was already 1
+ public bool Set(int bit)
+ {
+ int wordIndex = bit >> IntShift;
+ int wordBit = bit & IntMask;
+
+ long wordMask = 1L << wordBit;
+
+ if ((_masks[wordIndex] & wordMask) != 0)
+ {
+ return false;
+ }
+
+ _masks[wordIndex] |= wordMask;
+
+ return true;
+ }
+
+ ///
+ /// Sets a given range of bits to 1.
+ ///
+ /// Start bit of the range
+ /// End bit of the range (inclusive)
+ public void SetRange(int start, int end)
+ {
+ if (start == end)
+ {
+ Set(start);
+ return;
+ }
+
+ int startIndex = start >> IntShift;
+ int startBit = start & IntMask;
+ long startMask = -1L << startBit;
+
+ int endIndex = end >> IntShift;
+ int endBit = end & IntMask;
+ long endMask = (long)(ulong.MaxValue >> (IntMask - endBit));
+
+ if (startIndex == endIndex)
+ {
+ _masks[startIndex] |= startMask & endMask;
+ }
+ else
+ {
+ _masks[startIndex] |= startMask;
+
+ for (int i = startIndex + 1; i < endIndex; i++)
+ {
+ _masks[i] |= -1;
+ }
+
+ _masks[endIndex] |= endMask;
+ }
+ }
+
+ ///
+ /// Sets a given bit to 0.
+ ///
+ /// Bit to be cleared
+ public void Clear(int bit)
+ {
+ int wordIndex = bit >> IntShift;
+ int wordBit = bit & IntMask;
+
+ long wordMask = 1L << wordBit;
+
+ _masks[wordIndex] &= ~wordMask;
+ }
+
+ ///
+ /// Sets all bits to 0.
+ ///
+ public void Clear()
+ {
+ for (int i = 0; i < _masks.Length; i++)
+ {
+ _masks[i] = 0;
+ }
+ }
+
+ ///
+ /// Sets one or more groups of bits to 0.
+ /// See for how many bits are inside each group.
+ ///
+ /// Start index of the group
+ /// End index of the group (inclusive)
+ public void ClearInt(int start, int end)
+ {
+ for (int i = start; i <= end; i++)
+ {
+ _masks[i] = 0;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Ryujinx.Common/TitleIDs.cs b/src/Ryujinx.Common/TitleIDs.cs
index b541fae5a..793848d6d 100644
--- a/src/Ryujinx.Common/TitleIDs.cs
+++ b/src/Ryujinx.Common/TitleIDs.cs
@@ -83,6 +83,8 @@ namespace Ryujinx.Common
"010049900F546002", // Super Mario Sunshine
"0100a3900c3e2000", // Paper Mario: The Origami King
"0100ecd018ebe000", // Paper Mario: The Thousand-Year Door
+ "01009cC022b96000", // Super Mario Galaxy
+ "0100fd8022daa000", // Super Mario Galaxy 2
//Pikmin Franchise
"0100aa80194b0000", // Pikmin 1
@@ -158,6 +160,8 @@ namespace Ryujinx.Common
"01009aa000faa000", // Sonic Mania
"01005ea01c0fc000", // SONIC X SHADOW GENERATIONS
"01005ea01c0fc001", // ^
+ "01006e001823c000", // Sonic Racing: CrossWorlds
+ "010064b0242be000", // Sonic Racing: CrossWorlds - Demo
//Xenoblade Franchise
"0100ff500e34a000", // Xenoblade Chronicles - Definitive Edition
diff --git a/src/Ryujinx.Graphics.GAL/Format.cs b/src/Ryujinx.Graphics.GAL/Format.cs
index 17c42d2d4..25446f978 100644
--- a/src/Ryujinx.Graphics.GAL/Format.cs
+++ b/src/Ryujinx.Graphics.GAL/Format.cs
@@ -149,6 +149,7 @@ namespace Ryujinx.Graphics.GAL
B8G8R8A8Srgb,
B10G10R10A2Unorm,
X8UintD24Unorm,
+ A8B8G8R8Uint,
}
public static class FormatExtensions
diff --git a/src/Ryujinx.Graphics.Gpu/Image/FormatTable.cs b/src/Ryujinx.Graphics.Gpu/Image/FormatTable.cs
index ee217714c..8d8b00719 100644
--- a/src/Ryujinx.Graphics.Gpu/Image/FormatTable.cs
+++ b/src/Ryujinx.Graphics.Gpu/Image/FormatTable.cs
@@ -359,6 +359,7 @@ namespace Ryujinx.Graphics.Gpu.Image
A2B10G10R10Sint = (A2B10G10R10 << 21) | (Sint << 27), // 0x1e000000
A2B10G10R10Uscaled = (A2B10G10R10 << 21) | (Uscaled << 27), // 0x2e000000
A2B10G10R10Sscaled = (A2B10G10R10 << 21) | (Sscaled << 27), // 0x36000000
+ A8B8G8R8Uint = (A8B8G8R8 << 21) | (Uint << 27), // 0x25E00040
}
private static readonly Dictionary _textureFormats = new()
@@ -554,6 +555,7 @@ namespace Ryujinx.Graphics.Gpu.Image
{ VertexAttributeFormat.A2B10G10R10Sint, Format.R10G10B10A2Sint },
{ VertexAttributeFormat.A2B10G10R10Uscaled, Format.R10G10B10A2Uscaled },
{ VertexAttributeFormat.A2B10G10R10Sscaled, Format.R10G10B10A2Sscaled },
+ { VertexAttributeFormat.A8B8G8R8Uint, Format.A8B8G8R8Uint },
};
#pragma warning restore IDE0055
diff --git a/src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs b/src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs
index fd1609c23..c2a503840 100644
--- a/src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs
+++ b/src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Common.Collections;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Memory;
@@ -72,6 +73,7 @@ namespace Ryujinx.Graphics.Gpu.Image
}
private readonly GpuChannel _channel;
+ private readonly BitMap _invalidMap;
private readonly ConcurrentQueue _dereferenceQueue = new();
private TextureDescriptor _defaultDescriptor;
@@ -166,6 +168,7 @@ namespace Ryujinx.Graphics.Gpu.Image
{
_channel = channel;
_aliasLists = new Dictionary();
+ _invalidMap = new BitMap(maximumId + 1);
}
///
@@ -182,6 +185,11 @@ namespace Ryujinx.Graphics.Gpu.Image
if (texture == null)
{
+ if (_invalidMap.IsSet(id))
+ {
+ return ref descriptor;
+ }
+
texture = PhysicalMemory.TextureCache.FindShortCache(descriptor);
if (texture == null)
@@ -198,6 +206,7 @@ namespace Ryujinx.Graphics.Gpu.Image
// If this happens, then the texture address is invalid, we can't add it to the cache.
if (texture == null)
{
+ _invalidMap.Set(id);
return ref descriptor;
}
}
@@ -515,6 +524,8 @@ namespace Ryujinx.Graphics.Gpu.Image
RemoveAliasList(texture);
}
}
+
+ _invalidMap.Clear(id);
}
}
diff --git a/src/Ryujinx.Graphics.Vulkan/FormatCapabilities.cs b/src/Ryujinx.Graphics.Vulkan/FormatCapabilities.cs
index 0657638c9..aee55fef4 100644
--- a/src/Ryujinx.Graphics.Vulkan/FormatCapabilities.cs
+++ b/src/Ryujinx.Graphics.Vulkan/FormatCapabilities.cs
@@ -211,6 +211,9 @@ namespace Ryujinx.Graphics.Vulkan
case Format.R16G16B16Uint:
format = VkFormat.R16G16B16A16Uint;
break;
+ case Format.A8B8G8R8Uint:
+ format = VkFormat.A8B8G8R8UintPack32;
+ break;
default:
Logger.Error?.Print(LogClass.Gpu, $"Format {srcFormat} is not supported by the host.");
break;
diff --git a/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs b/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
index c7bb1ba59..8504c4343 100644
--- a/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
+++ b/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
@@ -160,7 +160,7 @@ namespace Ryujinx.Graphics.Vulkan
private static bool HasPushDescriptorsBug(VulkanRenderer gd)
{
// Those GPUs/drivers do not work properly with push descriptors, so we must force disable them.
- return gd.IsNvidiaPreTuring || (gd.IsIntelArc && gd.IsIntelWindows);
+ return gd.IsNvidiaPreTuring || (gd.IsIntelArc && (gd.IsIntelWindows || gd.IsIntelLinux));
}
private static bool CanUsePushDescriptors(VulkanRenderer gd, ResourceLayout layout, bool isCompute)
diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
index 32c22dd2a..5f1c50b00 100644
--- a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
+++ b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
@@ -91,6 +91,7 @@ namespace Ryujinx.Graphics.Vulkan
internal Vendor Vendor { get; private set; }
internal bool IsAmdWindows { get; private set; }
internal bool IsIntelWindows { get; private set; }
+ internal bool IsIntelLinux { get; private set; }
internal bool IsAmdGcn { get; private set; }
internal bool IsAmdRdna3 { get; private set; }
internal bool IsNvidiaPreTuring { get; private set; }
@@ -359,6 +360,7 @@ namespace Ryujinx.Graphics.Vulkan
IsAmdWindows = Vendor == Vendor.Amd && OperatingSystem.IsWindows();
IsIntelWindows = Vendor == Vendor.Intel && OperatingSystem.IsWindows();
+ IsIntelLinux = Vendor == Vendor.Intel && OperatingSystem.IsLinux();
IsTBDR =
Vendor is Vendor.Apple or
Vendor.Qualcomm or
@@ -398,7 +400,7 @@ namespace Ryujinx.Graphics.Vulkan
}
else if (Vendor == Vendor.Intel)
{
- IsIntelArc = GpuRenderer.StartsWith("Intel(R) Arc(TM)");
+ IsIntelArc = GpuRenderer.StartsWithIgnoreCase("Intel(R) Arc(TM)");
}
IsQualcommProprietary = hasDriverProperties && driverProperties.DriverID == DriverId.QualcommProprietary;
diff --git a/src/Ryujinx.HLE/Debugger/Debugger.cs b/src/Ryujinx.HLE/Debugger/Debugger.cs
index 66e42681b..2c935ca7f 100644
--- a/src/Ryujinx.HLE/Debugger/Debugger.cs
+++ b/src/Ryujinx.HLE/Debugger/Debugger.cs
@@ -859,7 +859,13 @@ namespace Ryujinx.HLE.Debugger
{
if (threadId == 0 || threadId == null)
{
- threadId = GetThreads().First().ThreadUid;
+ var threads = GetThreads();
+ if (threads.Length == 0)
+ {
+ ReplyError();
+ return;
+ }
+ threadId = threads.First().ThreadUid;
}
if (DebugProcess.GetThread(threadId.Value) == null)
@@ -1037,12 +1043,13 @@ namespace Ryujinx.HLE.Debugger
string response = command.Trim().ToLowerInvariant() switch
{
- "help" => "backtrace\nbt\nregisters\nreg\nget info\n",
+ "help" => "backtrace\nbt\nregisters\nreg\nget info\nminidump\n",
"get info" => GetProcessInfo(),
"backtrace" => GetStackTrace(),
"bt" => GetStackTrace(),
"registers" => GetRegisters(),
"reg" => GetRegisters(),
+ "minidump" => GetMinidump(),
_ => $"Unknown command: {command}\n"
};
@@ -1077,6 +1084,42 @@ namespace Ryujinx.HLE.Debugger
return Process.Debugger.GetCpuRegisterPrintout(DebugProcess.GetThread(gThread.Value));
}
+ private string GetMinidump()
+ {
+ var response = new StringBuilder();
+ response.AppendLine("=== Begin Minidump ===\n");
+ response.AppendLine(GetProcessInfo());
+
+ foreach (var thread in GetThreads())
+ {
+ response.AppendLine($"=== Thread {thread.ThreadUid} ===");
+ try
+ {
+ string stackTrace = Process.Debugger.GetGuestStackTrace(thread);
+ response.AppendLine(stackTrace);
+ }
+ catch (Exception e)
+ {
+ response.AppendLine($"[Error getting stack trace: {e.Message}]");
+ }
+
+ try
+ {
+ string registers = Process.Debugger.GetCpuRegisterPrintout(thread);
+ response.AppendLine(registers);
+ }
+ catch (Exception e)
+ {
+ response.AppendLine($"[Error getting registers: {e.Message}]");
+ }
+ }
+
+ response.AppendLine("=== End Minidump ===");
+
+ Logger.Info?.Print(LogClass.GdbStub, response.ToString());
+ return response.ToString();
+ }
+
private string GetProcessInfo()
{
try
@@ -1155,11 +1198,11 @@ namespace Ryujinx.HLE.Debugger
// If the user connects before the application is running, wait for the application to start.
int retries = 10;
- while (DebugProcess == null && retries-- > 0)
+ while ((DebugProcess == null || GetThreads().Length == 0) && retries-- > 0)
{
Thread.Sleep(200);
}
- if (DebugProcess == null)
+ if (DebugProcess == null || GetThreads().Length == 0)
{
Logger.Warning?.Print(LogClass.GdbStub, "Application is not running, cannot accept GDB client connection");
ClientSocket.Close();
diff --git a/src/Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs b/src/Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs
index 93bf7e00a..54440ab5f 100644
--- a/src/Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs
+++ b/src/Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs
@@ -293,6 +293,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
KThread currentThread = KernelStatic.GetCurrentThread();
KThread selectedThread = _state.SelectedThread;
+ if (!currentThread.IsThreadNamed && currentThread.GetThreadName() != "")
+ {
+ currentThread.HostThread.Name = $"<{currentThread.GetThreadName()}>";
+ currentThread.IsThreadNamed = true;
+ }
+
// If the thread is already scheduled and running on the core, we have nothing to do.
if (currentThread == selectedThread)
{
diff --git a/src/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs b/src/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
index 6e0dd906f..058cc3202 100644
--- a/src/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
+++ b/src/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
@@ -53,6 +53,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
public ulong AffinityMask { get; set; }
public ulong ThreadUid { get; private set; }
+
+ public bool IsThreadNamed { get; set; }
private long _totalTimeRunning;
diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledDataStruct.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledDataStruct.cs
index 312075bc4..5a6aab495 100644
--- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledDataStruct.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledDataStruct.cs
@@ -50,7 +50,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common
ulong value = BinaryPrimitives.ReadUInt64LittleEndian(byteSpan);
- return value;
+ return value << 1;
}
private static int GetSamplingNumberFieldOffset(ref T sampledDataStruct) where T : unmanaged, ISampledDataStruct
diff --git a/src/Ryujinx.Horizon/Audio/AudioUserIpcServer.cs b/src/Ryujinx.Horizon/Audio/AudioUserIpcServer.cs
index 20c824e1e..1de123f7f 100644
--- a/src/Ryujinx.Horizon/Audio/AudioUserIpcServer.cs
+++ b/src/Ryujinx.Horizon/Audio/AudioUserIpcServer.cs
@@ -33,11 +33,13 @@ namespace Ryujinx.Horizon.Audio
AudioOutManager audioOutManager = new(_managers.AudioOutputManager);
AudioInManager audioInManager = new(_managers.AudioInputManager);
FinalOutputRecorderManager finalOutputRecorderManager = new();
+ AudioSnoopManager audioSnoopManager = new();
_serverManager.RegisterObjectForServer(audioRendererManager, ServiceName.Encode("audren:u"), MaxSessionsCount);
_serverManager.RegisterObjectForServer(audioOutManager, ServiceName.Encode("audout:u"), MaxSessionsCount);
_serverManager.RegisterObjectForServer(audioInManager, ServiceName.Encode("audin:u"), MaxSessionsCount);
_serverManager.RegisterObjectForServer(finalOutputRecorderManager, ServiceName.Encode("audrec:u"), MaxSessionsCount);
+ _serverManager.RegisterObjectForServer(audioSnoopManager, ServiceName.Encode("auddev"), MaxSessionsCount);
}
public void ServiceRequests()
diff --git a/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioDevice.cs b/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioDevice.cs
index 583a04de3..4fda4bc61 100644
--- a/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioDevice.cs
+++ b/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioDevice.cs
@@ -23,10 +23,10 @@ namespace Ryujinx.Horizon.Sdk.Audio.Detail
{
_registry = registry;
- BehaviourContext behaviourContext = new();
- behaviourContext.SetUserRevision((int)revision);
+ BehaviourInfo behaviourInfo = new();
+ behaviourInfo.SetUserRevision((int)revision);
- _isUsbDeviceSupported = behaviourContext.IsAudioUsbDeviceOutputSupported();
+ _isUsbDeviceSupported = behaviourInfo.IsAudioUsbDeviceOutputSupported();
_sessions = registry.GetSessionByAppletResourceId(appletResourceId.Id);
Os.CreateSystemEvent(out _audioEvent, EventClearMode.AutoClear, interProcess: true);
diff --git a/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioRendererManager.cs b/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioRendererManager.cs
index 40cbecc40..e7eedeccd 100644
--- a/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioRendererManager.cs
+++ b/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioRendererManager.cs
@@ -61,7 +61,7 @@ namespace Ryujinx.Horizon.Sdk.Audio.Detail
[CmifCommand(1)]
public Result GetWorkBufferSize(out long workBufferSize, AudioRendererParameterInternal parameter)
{
- if (BehaviourContext.CheckValidRevision(parameter.Configuration.Revision))
+ if (BehaviourInfo.CheckValidRevision(parameter.Configuration.Revision))
{
workBufferSize = (long)Ryujinx.Audio.Renderer.Server.AudioRendererManager.GetWorkBufferSize(ref parameter.Configuration);
@@ -73,7 +73,7 @@ namespace Ryujinx.Horizon.Sdk.Audio.Detail
{
workBufferSize = 0;
- Logger.Warning?.Print(LogClass.ServiceAudio, $"Library Revision REV{BehaviourContext.GetRevisionNumber(parameter.Configuration.Revision)} is not supported!");
+ Logger.Warning?.Print(LogClass.ServiceAudio, $"Library Revision REV{BehaviourInfo.GetRevisionNumber(parameter.Configuration.Revision)} is not supported!");
return AudioResult.UnsupportedRevision;
}
diff --git a/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioSnoopManager.cs b/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioSnoopManager.cs
index cf1fe3d1d..5eb31a14b 100644
--- a/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioSnoopManager.cs
+++ b/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioSnoopManager.cs
@@ -1,30 +1,64 @@
using Ryujinx.Horizon.Common;
using Ryujinx.Horizon.Sdk.Sf;
+using Ryujinx.Horizon.Sdk.Sf.Hipc;
+using System;
namespace Ryujinx.Horizon.Sdk.Audio.Detail
{
partial class AudioSnoopManager : IAudioSnoopManager
{
+ private byte[] _dspStatisticsParameter;
+
// Note: The interface changed completely on firmware 17.0.0, this implementation is for older firmware.
- [CmifCommand(0)]
+ [CmifCommand(0)] // [6.0.0-16.1.0]
public Result EnableDspUsageMeasurement()
{
return Result.Success;
}
- [CmifCommand(1)]
+ [CmifCommand(1)] // [6.0.0-16.1.0]
public Result DisableDspUsageMeasurement()
{
return Result.Success;
}
-
- [CmifCommand(6)]
+
+ [CmifCommand(6)] // [6.0.0-16.1.0]
public Result GetDspUsage(out uint usage)
{
usage = 0;
return Result.Success;
}
+
+ [CmifCommand(0)] // 17.0.0+
+ public Result GetDspStatistics(out uint statistics) => GetDspUsage(out statistics);
+
+ [CmifCommand(1)] // 20.0.0+
+ public Result GetAppletStateSummaries([Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span summaries)
+ {
+ // Since we do not have any real applets, return empty state summaries.
+ summaries.Clear();
+
+ return Result.Success;
+ }
+
+ [CmifCommand(2)] // 20.0.0+
+ public Result SetDspStatisticsParameter([Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan parameter)
+ {
+ _dspStatisticsParameter = null;
+ _dspStatisticsParameter = new byte[0x100];
+ parameter.CopyTo(_dspStatisticsParameter);
+
+ return Result.Success;
+ }
+
+ [CmifCommand(3)] // 20.0.0+
+ public Result GetDspStatisticsParameter([Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span parameter)
+ {
+ _dspStatisticsParameter.CopyTo(parameter);
+
+ return Result.Success;
+ }
}
}
diff --git a/src/Ryujinx.Horizon/Sdk/Audio/Detail/IAudioSnoopManager.cs b/src/Ryujinx.Horizon/Sdk/Audio/Detail/IAudioSnoopManager.cs
index 72853886a..9a52beb30 100644
--- a/src/Ryujinx.Horizon/Sdk/Audio/Detail/IAudioSnoopManager.cs
+++ b/src/Ryujinx.Horizon/Sdk/Audio/Detail/IAudioSnoopManager.cs
@@ -1,5 +1,6 @@
using Ryujinx.Horizon.Common;
using Ryujinx.Horizon.Sdk.Sf;
+using System;
namespace Ryujinx.Horizon.Sdk.Audio.Detail
{
@@ -8,5 +9,10 @@ namespace Ryujinx.Horizon.Sdk.Audio.Detail
Result EnableDspUsageMeasurement();
Result DisableDspUsageMeasurement();
Result GetDspUsage(out uint usage);
+
+ Result GetDspStatistics(out uint statistics);
+ Result GetAppletStateSummaries(Span summaries);
+ Result SetDspStatisticsParameter(ReadOnlySpan parameter);
+ Result GetDspStatisticsParameter(Span parameter);
}
}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/BiquadFilterParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/BiquadFilterParameterTests.cs
index 617b52457..76e8a180a 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/BiquadFilterParameterTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/BiquadFilterParameterTests.cs
@@ -9,7 +9,8 @@ namespace Ryujinx.Tests.Audio.Renderer
[Test]
public void EnsureTypeSize()
{
- Assert.AreEqual(0xC, Unsafe.SizeOf());
+ Assert.AreEqual(0xC, Unsafe.SizeOf());
+ Assert.AreEqual(0x18, Unsafe.SizeOf());
}
}
}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Common/VoiceUpdateStateTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Common/VoiceStateTests.cs
similarity index 68%
rename from src/Ryujinx.Tests/Audio/Renderer/Common/VoiceUpdateStateTests.cs
rename to src/Ryujinx.Tests/Audio/Renderer/Common/VoiceStateTests.cs
index 7b09d18cc..eff982670 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Common/VoiceUpdateStateTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Common/VoiceStateTests.cs
@@ -4,12 +4,12 @@ using System.Runtime.CompilerServices;
namespace Ryujinx.Tests.Audio.Renderer.Common
{
- class VoiceUpdateStateTests
+ class VoiceStateTests
{
[Test]
public void EnsureTypeSize()
{
- Assert.LessOrEqual(Unsafe.SizeOf(), 0x100);
+ Assert.LessOrEqual(Unsafe.SizeOf(), 0x100);
}
}
}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Dsp/ResamplerTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Dsp/ResamplerTests.cs
index f393c971a..b774b74e1 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Dsp/ResamplerTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Dsp/ResamplerTests.cs
@@ -8,19 +8,19 @@ namespace Ryujinx.Tests.Audio.Renderer.Dsp
class ResamplerTests
{
[Test]
- [TestCase(VoiceInParameter.SampleRateConversionQuality.Low)]
- [TestCase(VoiceInParameter.SampleRateConversionQuality.Default)]
- [TestCase(VoiceInParameter.SampleRateConversionQuality.High)]
- public void TestResamplerConsistencyUpsampling(VoiceInParameter.SampleRateConversionQuality quality)
+ [TestCase(SampleRateConversionQuality.Low)]
+ [TestCase(SampleRateConversionQuality.Default)]
+ [TestCase(SampleRateConversionQuality.High)]
+ public void TestResamplerConsistencyUpsampling(SampleRateConversionQuality quality)
{
DoResamplingTest(44100, 48000, quality);
}
[Test]
- [TestCase(VoiceInParameter.SampleRateConversionQuality.Low)]
- [TestCase(VoiceInParameter.SampleRateConversionQuality.Default)]
- [TestCase(VoiceInParameter.SampleRateConversionQuality.High)]
- public void TestResamplerConsistencyDownsampling(VoiceInParameter.SampleRateConversionQuality quality)
+ [TestCase(SampleRateConversionQuality.Low)]
+ [TestCase(SampleRateConversionQuality.Default)]
+ [TestCase(SampleRateConversionQuality.High)]
+ public void TestResamplerConsistencyDownsampling(SampleRateConversionQuality quality)
{
DoResamplingTest(48000, 44100, quality);
}
@@ -32,7 +32,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Dsp
/// The input sample rate to test
/// The output sample rate to test
/// The resampler quality to use
- private static void DoResamplingTest(int inputRate, int outputRate, VoiceInParameter.SampleRateConversionQuality quality)
+ private static void DoResamplingTest(int inputRate, int outputRate, SampleRateConversionQuality quality)
{
float inputSampleRate = inputRate;
float outputSampleRate = outputRate;
@@ -61,8 +61,8 @@ namespace Ryujinx.Tests.Audio.Renderer.Dsp
float sumDifference = 0;
int delay = quality switch
{
- VoiceInParameter.SampleRateConversionQuality.High => 3,
- VoiceInParameter.SampleRateConversionQuality.Default => 1,
+ SampleRateConversionQuality.High => 3,
+ SampleRateConversionQuality.Default => 1,
_ => 0,
};
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameterTests.cs
index 73c1ea9d3..d76478ed8 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameterTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameterTests.cs
@@ -9,7 +9,8 @@ namespace Ryujinx.Tests.Audio.Renderer.Parameter.Effect
[Test]
public void EnsureTypeSize()
{
- Assert.AreEqual(0x18, Unsafe.SizeOf());
+ Assert.AreEqual(0x18, Unsafe.SizeOf());
+ Assert.AreEqual(0x24, Unsafe.SizeOf());
}
}
}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/AddressInfoTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/AddressInfoTests.cs
index 53a662584..6f855d3a4 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Server/AddressInfoTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Server/AddressInfoTests.cs
@@ -16,8 +16,8 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestGetReference()
{
- MemoryPoolState[] memoryPoolState = new MemoryPoolState[1];
- memoryPoolState[0] = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ MemoryPoolInfo[] memoryPoolState = new MemoryPoolInfo[1];
+ memoryPoolState[0] = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
memoryPoolState[0].SetCpuAddress(0x1000000, 0x10000);
memoryPoolState[0].DspAddress = 0x4000000;
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/BehaviourContextTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/BehaviourContextTests.cs
deleted file mode 100644
index 0b0ed7a54..000000000
--- a/src/Ryujinx.Tests/Audio/Renderer/Server/BehaviourContextTests.cs
+++ /dev/null
@@ -1,413 +0,0 @@
-using NUnit.Framework;
-using Ryujinx.Audio.Renderer.Server;
-
-namespace Ryujinx.Tests.Audio.Renderer.Server
-{
- public class BehaviourContextTests
- {
- [Test]
- public void TestCheckFeature()
- {
- int latestRevision = BehaviourContext.BaseRevisionMagic + BehaviourContext.LastRevision;
- int previousRevision = BehaviourContext.BaseRevisionMagic + (BehaviourContext.LastRevision - 1);
- int invalidRevision = BehaviourContext.BaseRevisionMagic + (BehaviourContext.LastRevision + 1);
-
- Assert.IsTrue(BehaviourContext.CheckFeatureSupported(latestRevision, latestRevision));
- Assert.IsFalse(BehaviourContext.CheckFeatureSupported(previousRevision, latestRevision));
- Assert.IsTrue(BehaviourContext.CheckFeatureSupported(latestRevision, previousRevision));
- // In case we get an invalid revision, this is supposed to auto default to REV1 internally.. idk what the hell Nintendo was thinking here..
- Assert.IsTrue(BehaviourContext.CheckFeatureSupported(invalidRevision, latestRevision));
- }
-
- [Test]
- public void TestsMemoryPoolForceMappingEnabled()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision1);
-
- Assert.IsFalse(behaviourContext.IsMemoryPoolForceMappingEnabled());
-
- behaviourContext.UpdateFlags(0x1);
-
- Assert.IsTrue(behaviourContext.IsMemoryPoolForceMappingEnabled());
- }
-
- [Test]
- public void TestRevision1()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision1);
-
- Assert.IsFalse(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsFalse(behaviourContext.IsSplitterSupported());
- Assert.IsFalse(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsFalse(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsFalse(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsFalse(behaviourContext.IsSplitterBugFixed());
- Assert.IsFalse(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsFalse(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsFalse(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsFalse(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsFalse(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.70f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(1, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(1, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision2()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision2);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsFalse(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsFalse(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsFalse(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsFalse(behaviourContext.IsSplitterBugFixed());
- Assert.IsFalse(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsFalse(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsFalse(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsFalse(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsFalse(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.70f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(1, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(1, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision3()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision3);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsFalse(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsFalse(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsFalse(behaviourContext.IsSplitterBugFixed());
- Assert.IsFalse(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsFalse(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsFalse(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsFalse(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsFalse(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.70f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(1, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(1, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision4()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision4);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsFalse(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsFalse(behaviourContext.IsSplitterBugFixed());
- Assert.IsFalse(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsFalse(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsFalse(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsFalse(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsFalse(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.75f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(1, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(1, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision5()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision5);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsFalse(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsFalse(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsFalse(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(2, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision6()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision6);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsFalse(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsFalse(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsFalse(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(2, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision7()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision7);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsTrue(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsFalse(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsFalse(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(2, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision8()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision8);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsTrue(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsTrue(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsFalse(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(3, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision9()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision9);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsTrue(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsTrue(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsTrue(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(3, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision10()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision10);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsTrue(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsTrue(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsTrue(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsTrue(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(4, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision11()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision11);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsTrue(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsTrue(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsTrue(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsTrue(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsTrue(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(5, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision12()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision12);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsTrue(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsTrue(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsTrue(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsTrue(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsTrue(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(5, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision13()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision13);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsTrue(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsTrue(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsTrue(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsTrue(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsTrue(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsTrue(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(5, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
- }
-}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/BehaviourInfoTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/BehaviourInfoTests.cs
new file mode 100644
index 000000000..ac85e44b4
--- /dev/null
+++ b/src/Ryujinx.Tests/Audio/Renderer/Server/BehaviourInfoTests.cs
@@ -0,0 +1,413 @@
+using NUnit.Framework;
+using Ryujinx.Audio.Renderer.Server;
+
+namespace Ryujinx.Tests.Audio.Renderer.Server
+{
+ public class BehaviourInfoTests
+ {
+ [Test]
+ public void TestCheckFeature()
+ {
+ int latestRevision = BehaviourInfo.BaseRevisionMagic + BehaviourInfo.LastRevision;
+ int previousRevision = BehaviourInfo.BaseRevisionMagic + (BehaviourInfo.LastRevision - 1);
+ int invalidRevision = BehaviourInfo.BaseRevisionMagic + (BehaviourInfo.LastRevision + 1);
+
+ Assert.IsTrue(BehaviourInfo.CheckFeatureSupported(latestRevision, latestRevision));
+ Assert.IsFalse(BehaviourInfo.CheckFeatureSupported(previousRevision, latestRevision));
+ Assert.IsTrue(BehaviourInfo.CheckFeatureSupported(latestRevision, previousRevision));
+ // In case we get an invalid revision, this is supposed to auto default to REV1 internally.. idk what the hell Nintendo was thinking here..
+ Assert.IsTrue(BehaviourInfo.CheckFeatureSupported(invalidRevision, latestRevision));
+ }
+
+ [Test]
+ public void TestsMemoryPoolForceMappingEnabled()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision1);
+
+ Assert.IsFalse(behaviourInfo.IsMemoryPoolForceMappingEnabled());
+
+ behaviourInfo.UpdateFlags(0x1);
+
+ Assert.IsTrue(behaviourInfo.IsMemoryPoolForceMappingEnabled());
+ }
+
+ [Test]
+ public void TestRevision1()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision1);
+
+ Assert.IsFalse(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsFalse(behaviourInfo.IsSplitterSupported());
+ Assert.IsFalse(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsFalse(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsFalse(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsFalse(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsFalse(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsFalse(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsFalse(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsFalse(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsFalse(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.70f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(1, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(1, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision2()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision2);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsFalse(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsFalse(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsFalse(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsFalse(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsFalse(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsFalse(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsFalse(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsFalse(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsFalse(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.70f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(1, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(1, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision3()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision3);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsFalse(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsFalse(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsFalse(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsFalse(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsFalse(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsFalse(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsFalse(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsFalse(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.70f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(1, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(1, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision4()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision4);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsFalse(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsFalse(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsFalse(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsFalse(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsFalse(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsFalse(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsFalse(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.75f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(1, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(1, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision5()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision5);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsFalse(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsFalse(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsFalse(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(2, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision6()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision6);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsFalse(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsFalse(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsFalse(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(2, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision7()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision7);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsTrue(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsFalse(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsFalse(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(2, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision8()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision8);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsTrue(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsTrue(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsFalse(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(3, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision9()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision9);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsTrue(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsTrue(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsTrue(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(3, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision10()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision10);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsTrue(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsTrue(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsTrue(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsTrue(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(4, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision11()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision11);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsTrue(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsTrue(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsTrue(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsTrue(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsTrue(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(5, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision12()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision12);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsTrue(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsTrue(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsTrue(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsTrue(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsTrue(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(5, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision13()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision13);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsTrue(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsTrue(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsTrue(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsTrue(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsTrue(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsTrue(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(5, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+ }
+}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/MemoryPoolStateTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/MemoryPoolInfoTests.cs
similarity index 80%
rename from src/Ryujinx.Tests/Audio/Renderer/Server/MemoryPoolStateTests.cs
rename to src/Ryujinx.Tests/Audio/Renderer/Server/MemoryPoolInfoTests.cs
index c6a2e473e..612df4dc1 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Server/MemoryPoolStateTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Server/MemoryPoolInfoTests.cs
@@ -4,18 +4,18 @@ using System.Runtime.CompilerServices;
namespace Ryujinx.Tests.Audio.Renderer.Server
{
- class MemoryPoolStateTests
+ class MemoryPoolInfoTests
{
[Test]
public void EnsureTypeSize()
{
- Assert.AreEqual(Unsafe.SizeOf(), 0x20);
+ Assert.AreEqual(Unsafe.SizeOf(), 0x20);
}
[Test]
public void TestContains()
{
- MemoryPoolState memoryPool = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ MemoryPoolInfo memoryPool = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
memoryPool.SetCpuAddress(0x1000000, 0x1000);
@@ -32,7 +32,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestTranslate()
{
- MemoryPoolState memoryPool = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ MemoryPoolInfo memoryPool = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
memoryPool.SetCpuAddress(0x1000000, 0x1000);
@@ -48,7 +48,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestIsMapped()
{
- MemoryPoolState memoryPool = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ MemoryPoolInfo memoryPool = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
memoryPool.SetCpuAddress(0x1000000, 0x1000);
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/MixStateTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/MixInfoTests.cs
similarity index 73%
rename from src/Ryujinx.Tests/Audio/Renderer/Server/MixStateTests.cs
rename to src/Ryujinx.Tests/Audio/Renderer/Server/MixInfoTests.cs
index 6262913b4..dbdc5c343 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Server/MixStateTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Server/MixInfoTests.cs
@@ -4,12 +4,12 @@ using System.Runtime.CompilerServices;
namespace Ryujinx.Tests.Audio.Renderer.Server
{
- class MixStateTests
+ class MixInfoTests
{
[Test]
public void EnsureTypeSize()
{
- Assert.AreEqual(0x940, Unsafe.SizeOf());
+ Assert.AreEqual(0x940, Unsafe.SizeOf());
}
}
}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/PoolMapperTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/PoolMapperTests.cs
index 941afae6f..5a1256937 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Server/PoolMapperTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Server/PoolMapperTests.cs
@@ -16,8 +16,8 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
public void TestInitializeSystemPool()
{
PoolMapper poolMapper = new(DummyProcessHandle, true);
- MemoryPoolState memoryPoolDsp = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp);
- MemoryPoolState memoryPoolCpu = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ MemoryPoolInfo memoryPoolDsp = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Dsp);
+ MemoryPoolInfo memoryPoolCpu = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
const CpuAddress CpuAddress = 0x20000;
const DspAddress DspAddress = CpuAddress; // TODO: DSP LLE
@@ -35,8 +35,8 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
public void TestGetProcessHandle()
{
PoolMapper poolMapper = new(DummyProcessHandle, true);
- MemoryPoolState memoryPoolDsp = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp);
- MemoryPoolState memoryPoolCpu = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ MemoryPoolInfo memoryPoolDsp = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Dsp);
+ MemoryPoolInfo memoryPoolCpu = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
Assert.AreEqual(0xFFFF8001, poolMapper.GetProcessHandle(ref memoryPoolCpu));
Assert.AreEqual(DummyProcessHandle, poolMapper.GetProcessHandle(ref memoryPoolDsp));
@@ -46,8 +46,8 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
public void TestMappings()
{
PoolMapper poolMapper = new(DummyProcessHandle, true);
- MemoryPoolState memoryPoolDsp = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp);
- MemoryPoolState memoryPoolCpu = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ MemoryPoolInfo memoryPoolDsp = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Dsp);
+ MemoryPoolInfo memoryPoolCpu = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
const CpuAddress CpuAddress = 0x20000;
const DspAddress DspAddress = CpuAddress; // TODO: DSP LLE
@@ -77,11 +77,11 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
const int MemoryPoolStateArraySize = 0x10;
const CpuAddress CpuAddressRegionEnding = CpuAddress * MemoryPoolStateArraySize;
- MemoryPoolState[] memoryPoolStateArray = new MemoryPoolState[MemoryPoolStateArraySize];
+ MemoryPoolInfo[] memoryPoolStateArray = new MemoryPoolInfo[MemoryPoolStateArraySize];
for (int i = 0; i < memoryPoolStateArray.Length; i++)
{
- memoryPoolStateArray[i] = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ memoryPoolStateArray[i] = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
memoryPoolStateArray[i].SetCpuAddress(CpuAddress + (ulong)i * CpuSize, CpuSize);
}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/SplitterDestinationTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/SplitterDestinationTests.cs
index 80b801336..e85111c9f 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Server/SplitterDestinationTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Server/SplitterDestinationTests.cs
@@ -10,7 +10,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
public void EnsureTypeSize()
{
Assert.AreEqual(0xE0, Unsafe.SizeOf());
- Assert.AreEqual(0x110, Unsafe.SizeOf());
+ Assert.AreEqual(0x128, Unsafe.SizeOf());
}
}
}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/VoiceStateTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/VoiceInfoTests.cs
similarity index 71%
rename from src/Ryujinx.Tests/Audio/Renderer/Server/VoiceStateTests.cs
rename to src/Ryujinx.Tests/Audio/Renderer/Server/VoiceInfoTests.cs
index dbd6eff8f..1382d693c 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Server/VoiceStateTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Server/VoiceInfoTests.cs
@@ -4,12 +4,12 @@ using System.Runtime.CompilerServices;
namespace Ryujinx.Tests.Audio.Renderer.Server
{
- class VoiceStateTests
+ class VoiceInfoTests
{
[Test]
public void EnsureTypeSize()
{
- Assert.LessOrEqual(Unsafe.SizeOf(), 0x220);
+ Assert.LessOrEqual(Unsafe.SizeOf(), 0x238);
}
}
}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/VoiceInParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/VoiceInParameterTests.cs
index 239da195a..e91675563 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/VoiceInParameterTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/VoiceInParameterTests.cs
@@ -9,7 +9,8 @@ namespace Ryujinx.Tests.Audio.Renderer
[Test]
public void EnsureTypeSize()
{
- Assert.AreEqual(0x170, Unsafe.SizeOf());
+ Assert.AreEqual(0x170, Unsafe.SizeOf());
+ Assert.AreEqual(0x188, Unsafe.SizeOf());
}
}
}
diff --git a/src/Ryujinx.Tests/Memory/PartialUnmaps.cs b/src/Ryujinx.Tests/Memory/PartialUnmaps.cs
index 92b994279..1a01a36bc 100644
--- a/src/Ryujinx.Tests/Memory/PartialUnmaps.cs
+++ b/src/Ryujinx.Tests/Memory/PartialUnmaps.cs
@@ -226,7 +226,7 @@ namespace Ryujinx.Tests.Memory
ref PartialUnmapState state = ref PartialUnmapState.GetRef();
- // Create some state to be used for managing the native writing loop.
+ // Create some info to be used for managing the native writing loop.
int stateSize = Unsafe.SizeOf();
IntPtr statePtr = Marshal.AllocHGlobal(stateSize);
Unsafe.InitBlockUnaligned((void*)statePtr, 0, (uint)stateSize);
diff --git a/src/Ryujinx/Assets/Styles/Themes.xaml b/src/Ryujinx/Assets/Styles/Themes.xaml
index de7584240..53c4dcd59 100644
--- a/src/Ryujinx/Assets/Styles/Themes.xaml
+++ b/src/Ryujinx/Assets/Styles/Themes.xaml
@@ -19,6 +19,7 @@
#FFFF4554
#6483F5
#800080
+ #00B5B8
#FFFF4554
#6483F5
#800080
+ #00B5B8
#FFFF4554
#6483F5
#FFA500
+ #00B5B8
diff --git a/src/Ryujinx/Systems/Updater/Updater.cs b/src/Ryujinx/Systems/Updater/Updater.cs
index 39bb5d9d4..add940deb 100644
--- a/src/Ryujinx/Systems/Updater/Updater.cs
+++ b/src/Ryujinx/Systems/Updater/Updater.cs
@@ -101,8 +101,8 @@ namespace Ryujinx.Ava.Systems
await Dispatcher.UIThread.InvokeAsync(async () =>
{
string newVersionString = ReleaseInformation.IsCanaryBuild
- ? $"Canary {currentVersion} -> Canary {newVersion}"
- : $"{currentVersion} -> {newVersion}";
+ ? $"Canary {currentVersion} → Canary {newVersion}"
+ : $"{currentVersion} → {newVersion}";
Logger.Info?.Print(LogClass.Application, $"Version found: {newVersionString}");
diff --git a/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml
index 8cd1f5914..909154540 100755
--- a/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml
+++ b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml
@@ -114,16 +114,20 @@
Header="{ext:Locale GameListContextMenuCacheManagementPurgePptc}"
Icon="{ext:Icon fa-solid fa-arrow-rotate-right}"
ToolTip.Tip="{ext:Locale GameListContextMenuCacheManagementPurgePptcToolTip}" />
+
+ Icon="{ext:Icon fa-solid fa-trash-can}"
+ IsEnabled="{Binding HasPtcCacheFiles}" />
+ Icon="{ext:Icon fa-solid fa-trash-can}"
+ IsEnabled="{Binding HasShaderCacheFiles}" />
+
+
+
diff --git a/src/Ryujinx/UI/Views/Main/MainViewControls.axaml b/src/Ryujinx/UI/Views/Main/MainViewControls.axaml
index fec75b38a..55d23ba41 100644
--- a/src/Ryujinx/UI/Views/Main/MainViewControls.axaml
+++ b/src/Ryujinx/UI/Views/Main/MainViewControls.axaml
@@ -46,10 +46,6 @@
FontFamily="avares://FluentAvalonia/Fonts#Symbols"
Glyph="{helpers:GlyphValueConverter Grid}" />
-
-
diff --git a/src/Ryujinx/UI/Views/Misc/ApplicationGridView.axaml b/src/Ryujinx/UI/Views/Misc/ApplicationGridView.axaml
index 4d1db1507..39db76031 100644
--- a/src/Ryujinx/UI/Views/Misc/ApplicationGridView.axaml
+++ b/src/Ryujinx/UI/Views/Misc/ApplicationGridView.axaml
@@ -35,7 +35,7 @@
@@ -46,9 +49,11 @@
Padding="10"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
- ClipToBounds="True"
- CornerRadius="5">
+ ClipToBounds="True">
+
+
+
+ Padding="1.5">
+ Foreground="{DynamicResource CustomConfig}" />
+
diff --git a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
index ad05efd06..fed868243 100644
--- a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
@@ -27,13 +27,6 @@
Spacing="10">
-
-
-
-
-
+
+
+
+
+
@@ -101,7 +101,7 @@
HorizontalContentAlignment="Left"
MinWidth="100">
-
+
-
+
@@ -146,7 +146,7 @@
HorizontalContentAlignment="Left"
MinWidth="100">
-
+
@@ -198,14 +198,13 @@
@@ -213,8 +212,7 @@
Name="RemoveGameDirButton"
Grid.Column="2"
MinWidth="90"
- Margin="10,0,0,0"
- ToolTip.Tip="{ext:Locale RemoveGameDirTooltip}"
+ Margin="5,0,0,0"
Click="RemoveGameDirButton_OnClick">
@@ -252,14 +250,13 @@
@@ -267,8 +264,7 @@
Name="RemoveAutoloadDirButton"
Grid.Column="2"
MinWidth="90"
- Margin="10,0,0,0"
- ToolTip.Tip="{ext:Locale RemoveAutoloadDirTooltip}"
+ Margin="5,0,0,0"
Click="RemoveAutoloadDirButton_OnClick">
diff --git a/src/Ryujinx/UI/Views/User/UserSaveManagerView.axaml b/src/Ryujinx/UI/Views/User/UserSaveManagerView.axaml
index f04b8a7a3..f742af9ed 100644
--- a/src/Ryujinx/UI/Views/User/UserSaveManagerView.axaml
+++ b/src/Ryujinx/UI/Views/User/UserSaveManagerView.axaml
@@ -28,7 +28,6 @@
Orientation="Horizontal"
HorizontalAlignment="Left"
VerticalAlignment="Center">
-
-
-
-
+
@@ -54,7 +54,7 @@
IsSettingsVisible="False"
Name="NavPanel"
IsBackEnabled="False"
- Margin="10,10,10,0"
+ Margin="10,0,10,0"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
OpenPaneLength="200">
@@ -62,16 +62,17 @@
+ Tag="UiPage">
+
+
+
+
-
+
+ Tag="DebugPage">
+
+
+
+