Compare commits

...

37 commits

Author SHA1 Message Date
Goodfeat
205240cfc5 Merge branch 'Master_PR' into 'master'
Improvements and fixes to issues in the controller input menu

See merge request ryubing/ryujinx!2
2025-04-13 19:18:17 -05:00
Rondo
2c8afa7e6e Update Ukrainian translation
See merge request ryubing/ryujinx!10
2025-04-13 17:05:57 -05:00
GreemDev
d98ed30450 fix "regular builds" linking to canary builds 2025-04-13 13:25:23 -05:00
Goodfeat
9d6e8ada6e Merge branch ryujinx:master into Master_PR 2025-04-07 21:03:06 -05:00
Vova
aa9c4192de Merge branch 'Master_PR' of https://git.ryujinx.app/Goodfeat/ryujinx into Master_PR 2025-04-06 10:28:48 +10:00
Vova
5364360fee (Fix) Removing TurboMode hotkey didn't work 2025-03-27 16:51:19 +10:00
Vova
a67657e3ec Merge branch 'Master_PR' of https://git.ryujinx.app/Goodfeat/ryujinx into Master_PR 2025-03-27 15:07:04 +10:00
Vova
66acfcbed7 (Fix) Returned the ability to delete assigned hotkeys with the right mouse button 2025-03-27 15:06:43 +10:00
Goodfeat
53d1cfad32 Merge branch ryujinx:master into Master_PR 2025-03-25 09:03:09 +00:00
Goodfeat
d8086c605c Merge branch ryujinx:master into Master_PR 2025-03-20 22:11:09 +00:00
Goodfeat
40f759ae66 Merge branch ryujinx:master into Master_PR 2025-03-19 12:28:01 +00:00
Goodfeat
a1e2d24d84 Merge branch ryujinx:master into Master_PR 2025-03-16 12:57:11 +00:00
Goodfeat
ad3f6c2eac Merge branch ryujinx:master into Master_PR 2025-03-16 02:18:56 +00:00
Goodfeat
5f4ef9f9c8 Merge branch 'master' into 'Master_PR'
# Conflicts:
#   src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs
2025-03-15 10:13:00 +00:00
Goodfeat
7266f1812f Merge branch ryujinx:master into Master_PR 2025-03-14 13:24:26 +00:00
Goodfeat
fc9d42b8c3 Merge branch ryujinx:master into Master_PR 2025-03-13 23:27:54 +00:00
Vova
db08498a89 Addition: Device Name and ID are displayed when the controller is turned off, but the controller is configured.
Added the "Name" property for controllers.
Changed the controller setup message to be more informative.
2025-03-06 17:13:11 +10:00
Vova
7a43dcb513 Merge branch 'Master_PR' of https://github.com/Goodfeat/Ryujinx_alt into Master_PR 2025-03-06 14:52:48 +10:00
Vova
f2329d0e8a Fixed bug with turning off active gamepad (independent profiles)
When switching profiles, if the profile does not belong to the gamepad itself, the gamepad began to be displayed as turned off.
Fixed a bug where the return button did not return the initially selected gamepad
2025-03-06 14:52:30 +10:00
Vladimir Sokolov
3aa7ed661d
Merge branch 'master' into Master_PR 2025-03-06 11:44:18 +10:00
Vladimir Sokolov
6e824e44b8
Merge branch 'master' into Master_PR 2025-03-06 08:38:55 +10:00
Vladimir Sokolov
a964bf8f68
Merge branch 'master' into Master_PR 2025-03-05 19:12:19 +10:00
Vladimir Sokolov
89e4d287d6
Merge branch 'master' into Master_PR 2025-03-05 09:18:36 +10:00
Vladimir Sokolov
f34745a66c
Merge branch 'master' into Master_PR 2025-03-04 21:31:56 +10:00
Vladimir Sokolov
d5b7851c9b
Merge branch 'master' into Master_PR 2025-03-03 21:22:24 +10:00
Vova
1b7032b589 smal fix 2025-03-03 00:07:05 +10:00
Vova
e097ea71ff Fix: exclude device id when loading preset (independent presets)
fixed bug when selected gamepad disappears if another gamepad was disconnected
2025-03-02 23:49:40 +10:00
Vova
299f2144c8 Bug fixes, functionality improvements:
Now the profile changes immediately upon selection.
The icon for restoring settings has been changed.
A bug has been fixed where restoring settings did not restore the previously selected gamepad.
2025-03-02 19:07:49 +10:00
Vova
33e3ba9ff2 Fixed profiles on the input page:
- profiles are unlinked from controllers
- sometimes a new profile after saving changed to the previous one, had to select it again (fixed)
- when deleting, the profile now resets the name to "default"
2025-03-01 23:44:05 +10:00
Vladimir Sokolov
9dc36646c1
Merge branch 'master' into Master_PR 2025-02-28 20:54:11 +10:00
Vova
8eea75a6e8 Small fix 2025-02-23 16:44:10 +10:00
Vladimir Sokolov
57fbcc7aed
Merge branch 'master' into Master_PR 2025-02-23 16:18:11 +10:00
Vova
d1c15f3562 Fixed a bug with the (undo last changes) button in the gamepad settings 2025-02-23 16:16:43 +10:00
Vova
0423fad7ff Merge branch 'Master_PR' of https://github.com/Goodfeat/Ryujinx_alt into Master_PR 2025-02-23 16:04:12 +10:00
Vova
1951fe0077 Added the ability to delete assigned buttons with the right mouse button in the settings.
- for keyboard
- for hotkeys
2025-02-23 15:59:03 +10:00
Vladimir Sokolov
7fd5a63a5d
Merge branch 'master' into Master_PR 2025-02-23 14:18:24 +10:00
Vova
a0594e8169 Improved interaction with "Input" settings.
- paired devices have notifications that they are configured and require connection
- paired devices load the configuration when connected
- A notification appears when changing control configuration settings.
- Now control settings will be saved only when they are changed
- Added a button to roll back changes to the previously saved state
- Fixed a bug: when switching the "player", if the "input device" and "controller type" settings were changed, the save dialog box did not appear.
- "Motion", "Rumble" and "Led" also have events notifying about changes
2025-02-23 10:20:42 +10:00
14 changed files with 541 additions and 104 deletions

View file

@ -59,7 +59,7 @@ jobs:
body: | body: |
# Canary builds: # Canary builds:
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/latest) instead if that sounds like something you don't want to deal with. These builds are experimental and may sometimes not work, use [regular builds](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/Stable-Releases/releases/latest) instead if that sounds like something you don't want to deal with.
| Platform | Artifact | | Platform | Artifact |
|--|--| |--|--|

View file

@ -4942,7 +4942,7 @@
"sv_SE": "Multiplikator för turboläge:", "sv_SE": "Multiplikator för turboläge:",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "Множник Турборежиму:",
"zh_CN": "涡轮模式倍数:", "zh_CN": "涡轮模式倍数:",
"zh_TW": "" "zh_TW": ""
} }
@ -4967,7 +4967,7 @@
"sv_SE": "Målvärdet för multiplikatorn i turboläget. \n\nLämna den på 200 om du är osäker.", "sv_SE": "Målvärdet för multiplikatorn i turboläget. \n\nLämna den på 200 om du är osäker.",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "Цільове значення коефіцієнта Турборежиму.\n\nЗалиште 200, якщо не впевнені",
"zh_CN": "涡轮模式倍数的目标值。\n\n如果不确定请保留为 200。", "zh_CN": "涡轮模式倍数的目标值。\n\n如果不确定请保留为 200。",
"zh_TW": "" "zh_TW": ""
} }
@ -4992,7 +4992,7 @@
"sv_SE": "Turboläget är en emulatorfunktion som effektivt ökar eller sänker hastigheten när ett spel inte är känsligt för bildfrekvens.\nDu kan växla denna funktion i spelet med en snabbtangent, konfigurerbar i Ryujinx inställningar för snabbtangenter.\n\nLämna den på 200 om du är osäker.", "sv_SE": "Turboläget är en emulatorfunktion som effektivt ökar eller sänker hastigheten när ett spel inte är känsligt för bildfrekvens.\nDu kan växla denna funktion i spelet med en snabbtangent, konfigurerbar i Ryujinx inställningar för snabbtangenter.\n\nLämna den på 200 om du är osäker.",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "Турборежим це функція емулятора, яка ефективно прискорює або сповільнює гру, якщо та не чутлива до частоти кадрів. Цю функцію можна ввімкнути/вимкнути безпосередньо під час гри за допомогою гарячої клавіші, яку можна налаштувати в меню Гарячі клавіші в налаштуваннях.",
"zh_CN": "涡轮模式是一种模拟器功能当游戏对帧率不敏感时它可以有效地导致加速或降速。\n您可以在游戏中使用热键切换此功能,它可以在 Ryujinx 的键盘热键设置进行设置。\n\n如果不确定则保留为 200。", "zh_CN": "涡轮模式是一种模拟器功能当游戏对帧率不敏感时它可以有效地导致加速或降速。\n您可以在游戏中使用热键切换此功能,它可以在 Ryujinx 的键盘热键设置进行设置。\n\n如果不确定则保留为 200。",
"zh_TW": "" "zh_TW": ""
} }
@ -7022,6 +7022,31 @@
"zh_TW": "輸入裝置" "zh_TW": "輸入裝置"
} }
}, },
{
"ID": "ControllerSettingsWaitingConnectDevice",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Configuration found:\n\nName:\t{0}\nGUID:\t{1}\n\n Waiting for controller connection...",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{ {
"ID": "ControllerSettingsRefresh", "ID": "ControllerSettingsRefresh",
"Translations": { "Translations": {
@ -7322,6 +7347,81 @@
"zh_TW": "新增" "zh_TW": "新增"
} }
}, },
{
"ID": "ControllerSettingsModifiedNotification",
"Translations": {
"ar_SA": "(تم التعديل!)",
"de_DE": "(modifiziert!)",
"el_GR": "(τροποποιημένο!)",
"en_US": "(Modified!)",
"es_ES": "(modificado!)",
"fr_FR": "(modifié!)",
"he_IL": "(שונה!)",
"it_IT": "(modificato!)",
"ja_JP": "(変更済み!)",
"ko_KR": "(수정됨!)",
"no_NO": "(modifisert!)",
"pl_PL": "(zmodyfikowane!)",
"pt_BR": "(modificado!)",
"ru_RU": "(изменено!)",
"sv_SE": "(ändrad!)",
"th_TH": "(แก้ไขแล้ว!)",
"tr_TR": "(değiştirildi!)",
"uk_UA": "(модифіковано!)",
"zh_CN": "(已修改!)",
"zh_TW": "(已修改!)"
}
},
{
"ID": "ControllerSettingsDisableDeviceForSaving",
"Translations": {
"ar_SA": "تم إعداد التحكم.\n\nفي انتظار اتصال وحدة التحكم...",
"de_DE": "Steuerung konfiguriert.\n\nWarten auf die Verbindung des Controllers...",
"el_GR": "Η διαχείριση έχει ρυθμιστεί.\n\nΑναμένεται σύνδεση του χειριστηρίου...",
"en_US": "Control configured.\n\nWaiting for controller connection...",
"es_ES": "Control configurado.\n\nEsperando la conexión del controlador...",
"fr_FR": "Contrôle configuré.\n\nEn attente de la connexion du contrôleur...",
"he_IL": "השליטה הוגדרה.\n\nממתין לחיבור הבקר...",
"it_IT": "Controllo configurato.\n\nIn attesa della connessione del controller...",
"ja_JP": "コントロールが設定されました。\n\nコントローラーの接続を待っています...",
"ko_KR": "제어가 설정되었습니다.\n\n컨트롤러 연결 대기 중...",
"no_NO": "Kontroll konfigurert.\n\nVenter på tilkobling av kontroller...",
"pl_PL": "Sterowanie skonfigurowane.\n\nOczekiwanie na połączenie kontrolera...",
"pt_BR": "Controle configurado.\n\nAguardando conexão do controle...",
"ru_RU": "Управление настроено.\n\nОжидается подключение контроллера...",
"sv_SE": "Kontroll konfigurerad.\n\nVäntar på anslutning av kontrollen...",
"th_TH": "การควบคุมได้รับการตั้งค่าแล้ว\n\nกำลังรอการเชื่อมต่อคอนโทรลเลอร์...",
"tr_TR": "Kontrol yapılandırıldı.\n\nKontrolcü bağlantısı bekleniyor...",
"uk_UA": "Керування налаштовано.\n\nОчікується підключення контролера...",
"zh_CN": "控制已配置。\n\n等待控制器连接...",
"zh_TW": "控制已設定。\n\n等待控制器連接..."
}
},
{
"ID": "ControllerSettingsUnlink",
"Translations": {
"ar_SA": "إلغاء الربط",
"de_DE": "Entkoppeln",
"el_GR": "Αποσύνδεση",
"en_US": "Unlink",
"es_ES": "Desvincular",
"fr_FR": "Dissocier",
"he_IL": "ניתוק קישור",
"it_IT": "Scollega",
"ja_JP": "リンク解除",
"ko_KR": "연결 해제",
"no_NO": "Frakoble",
"pl_PL": "Odłącz",
"pt_BR": "Desvincular",
"ru_RU": "Отвязать",
"sv_SE": "Koppla från",
"th_TH": "ยกเลิกการเชื่อมโยง",
"tr_TR": "Bağlantıyı Kes",
"uk_UA": "Відв'язати",
"zh_CN": "解除绑定",
"zh_TW": "解除綁定"
}
},
{ {
"ID": "ControllerSettingsRemove", "ID": "ControllerSettingsRemove",
"Translations": { "Translations": {
@ -8667,7 +8767,7 @@
"sv_SE": "Färg", "sv_SE": "Färg",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "Колір",
"zh_CN": "颜色", "zh_CN": "颜色",
"zh_TW": "顏色" "zh_TW": "顏色"
} }
@ -8742,7 +8842,7 @@
"sv_SE": "Okänd", "sv_SE": "Okänd",
"th_TH": "ไม่รู้จัก", "th_TH": "ไม่รู้จัก",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Невідома", "uk_UA": "Назначити",
"zh_CN": "未知", "zh_CN": "未知",
"zh_TW": "未知" "zh_TW": "未知"
} }
@ -11972,6 +12072,31 @@
"zh_TW": "儲存設定檔" "zh_TW": "儲存設定檔"
} }
}, },
{
"ID": "ControllerSettingsCancelCurrentChangesToolTip",
"Translations": {
"ar_SA": "إلغاء التغييرات الحالية",
"de_DE": "Aktuelle Änderungen abbrechen",
"el_GR": "Ακύρωση τρεχουσών αλλαγών",
"en_US": "Cancel current changes",
"es_ES": "Cancelar los cambios actuales",
"fr_FR": "Annuler les modifications en cours",
"he_IL": "ביטול השינויים הנוכחיים",
"it_IT": "Annulla le modifiche correnti",
"ja_JP": "現在の変更をキャンセル",
"ko_KR": "현재 변경 취소",
"no_NO": "Avbryt gjeldende endringer",
"pl_PL": "Anuluj bieżące zmiany",
"pt_BR": "Cancelar alterações atuais",
"ru_RU": "Отменить текущие изменения",
"sv_SE": "Avbryt aktuella ändringar",
"th_TH": "ยกเลิกการเปลี่ยนแปลงปัจจุบัน",
"tr_TR": "Geçerli değişiklikleri iptal et",
"uk_UA": "Скасувати поточні зміни",
"zh_CN": "取消当前更改",
"zh_TW": "取消當前變更"
}
},
{ {
"ID": "MenuBarFileToolsTakeScreenshot", "ID": "MenuBarFileToolsTakeScreenshot",
"Translations": { "Translations": {
@ -18067,7 +18192,7 @@
"sv_SE": "Processor", "sv_SE": "Processor",
"th_TH": "ซีพียู", "th_TH": "ซีพียู",
"tr_TR": "İşlemci", "tr_TR": "İşlemci",
"uk_UA": "ЦП", "uk_UA": "Процесор",
"zh_CN": "", "zh_CN": "",
"zh_TW": "" "zh_TW": ""
} }
@ -18167,7 +18292,7 @@
"sv_SE": "CPU-cache", "sv_SE": "CPU-cache",
"th_TH": "แคชซีพียู", "th_TH": "แคชซีพียู",
"tr_TR": "İşlemci Belleği", "tr_TR": "İşlemci Belleği",
"uk_UA": "Кеш CPU", "uk_UA": "Кеш процесора (CPU Cache)",
"zh_CN": "CPU 缓存", "zh_CN": "CPU 缓存",
"zh_TW": "CPU 快取" "zh_TW": "CPU 快取"
} }
@ -18192,7 +18317,7 @@
"sv_SE": "CPU-läge", "sv_SE": "CPU-läge",
"th_TH": "โหมดซีพียู", "th_TH": "โหมดซีพียู",
"tr_TR": "CPU Hafızası", "tr_TR": "CPU Hafızası",
"uk_UA": "Режим CPU", "uk_UA": "Режим процесора (CPU Mode)",
"zh_CN": "CPU 模式", "zh_CN": "CPU 模式",
"zh_TW": "CPU 模式" "zh_TW": "CPU 模式"
} }
@ -18217,7 +18342,7 @@
"sv_SE": "Uppdateringar inaktiverade!", "sv_SE": "Uppdateringar inaktiverade!",
"th_TH": "ปิดใช้งานการอัปเดตแล้ว!", "th_TH": "ปิดใช้งานการอัปเดตแล้ว!",
"tr_TR": "Güncelleyici Devre Dışı!", "tr_TR": "Güncelleyici Devre Dışı!",
"uk_UA": "Програму оновлення вимкнено!", "uk_UA": "Оновлення вимкнено!",
"zh_CN": "已禁用更新!", "zh_CN": "已禁用更新!",
"zh_TW": "更新已停用!" "zh_TW": "更新已停用!"
} }
@ -18267,7 +18392,7 @@
"sv_SE": "{0} bilder/s ({1}ms), Turbo ({2}%)", "sv_SE": "{0} bilder/s ({1}ms), Turbo ({2}%)",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "{0} FPS ({1}ms), Турбо ({2}%)",
"zh_CN": "{0} FPS ({1}ms), 涡轮 ({2}%)", "zh_CN": "{0} FPS ({1}ms), 涡轮 ({2}%)",
"zh_TW": "" "zh_TW": ""
} }
@ -19914,7 +20039,7 @@
"pl_PL": "Skróty Klawiszowe Klawiatury", "pl_PL": "Skróty Klawiszowe Klawiatury",
"pt_BR": "Atalhos do Teclado", "pt_BR": "Atalhos do Teclado",
"ru_RU": "Горячие клавиши", "ru_RU": "Горячие клавиши",
"sv_SE": "Snabbtangenter", "sv_SE": "Snabbtangenter för tangentbord",
"th_TH": "ปุ่มลัดของคีย์บอร์ด", "th_TH": "ปุ่มลัดของคีย์บอร์ด",
"tr_TR": "Klavye Kısayolları", "tr_TR": "Klavye Kısayolları",
"uk_UA": "Гарячі клавіші", "uk_UA": "Гарячі клавіші",
@ -21867,7 +21992,7 @@
"sv_SE": "Grafikbakände", "sv_SE": "Grafikbakände",
"th_TH": "กราฟิกเบื้องหลัง", "th_TH": "กราฟิกเบื้องหลัง",
"tr_TR": "Grafik Arka Ucu", "tr_TR": "Grafik Arka Ucu",
"uk_UA": "Графічний сервер", "uk_UA": "Графічний рушій",
"zh_CN": "图形渲染引擎:", "zh_CN": "图形渲染引擎:",
"zh_TW": "圖形後端" "zh_TW": "圖形後端"
} }
@ -22042,7 +22167,7 @@
"sv_SE": "Välj grafikkortet som ska användas med Vulkan-grafikbakänden.\n\nPåverkar inte GPU:n som OpenGL använder.\n\nStäll in till den GPU som flaggats som \"dGPU\" om osäker. Om det inte finns någon, lämna orörd.", "sv_SE": "Välj grafikkortet som ska användas med Vulkan-grafikbakänden.\n\nPåverkar inte GPU:n som OpenGL använder.\n\nStäll in till den GPU som flaggats som \"dGPU\" om osäker. Om det inte finns någon, lämna orörd.",
"th_TH": "เลือกการ์ดจอที่จะใช้กับแบ็กเอนด์กราฟิก Vulkan\n\nไม่ส่งผลต่อ GPU ที่ OpenGL จะใช้\n\nตั้งค่าเป็น GPU ที่ถูกตั้งค่าสถานะเป็น \"dGPU\" ถ้าหากคุณไม่แน่ใจ ,หากไม่มีก็ปล่อยทิ้งไว้โดยไม่ต้องแตะต้องมัน", "th_TH": "เลือกการ์ดจอที่จะใช้กับแบ็กเอนด์กราฟิก Vulkan\n\nไม่ส่งผลต่อ GPU ที่ OpenGL จะใช้\n\nตั้งค่าเป็น GPU ที่ถูกตั้งค่าสถานะเป็น \"dGPU\" ถ้าหากคุณไม่แน่ใจ ,หากไม่มีก็ปล่อยทิ้งไว้โดยไม่ต้องแตะต้องมัน",
"tr_TR": "Vulkan Grafik Arka Ucu ile kullanılacak Ekran Kartını Seçin.\n\nOpenGL'nin kullanacağı GPU'yu etkilemez.\n\n Emin değilseniz \"dGPU\" olarak işaretlenmiş GPU'ya ayarlayın. Eğer yoksa, dokunmadan bırakın.\n", "tr_TR": "Vulkan Grafik Arka Ucu ile kullanılacak Ekran Kartını Seçin.\n\nOpenGL'nin kullanacağı GPU'yu etkilemez.\n\n Emin değilseniz \"dGPU\" olarak işaretlenmiş GPU'ya ayarlayın. Eğer yoksa, dokunmadan bırakın.\n",
"uk_UA": "Виберіть відеокарту, яка використовуватиметься з графічним сервером Vulkan.\n\nНе впливає на графічний процесор, який використовуватиме OpenGL.\n\nВстановіть графічний процесор, позначений як «dGPU», якщо не впевнені. Якщо такого немає, не чіпайте.", "uk_UA": "Виберіть відеокарту, яка використовуватиметься з графічним рушієм Vulkan.\n\nНалаштування не впливає на відеоадаптер (GPU), що використовуватиме рушій OpenGL.\n\nВстановіть графічний рушій, позначений як «dGPU», якщо не впевнені. Якщо такого пункту немає, то залиште як є.",
"zh_CN": "选择 Vulkan 图形引擎使用的 GPU。\n\n此选项不会影响 OpenGL 使用的 GPU。\n\n如果不确定建议选择\"独立显卡(dGPU)\"。如果没有独立显卡,则无需改动此选项。", "zh_CN": "选择 Vulkan 图形引擎使用的 GPU。\n\n此选项不会影响 OpenGL 使用的 GPU。\n\n如果不确定建议选择\"独立显卡(dGPU)\"。如果没有独立显卡,则无需改动此选项。",
"zh_TW": "選擇將與 Vulkan 圖形後端一起使用的顯示卡。\n\n不會影響 OpenGL 將使用的 GPU。\n\n如果不確定請設定為標記為「dGPU」的 GPU。如果沒有則保持原狀。" "zh_TW": "選擇將與 Vulkan 圖形後端一起使用的顯示卡。\n\n不會影響 OpenGL 將使用的 GPU。\n\n如果不確定請設定為標記為「dGPU」的 GPU。如果沒有則保持原狀。"
} }
@ -22642,7 +22767,7 @@
"sv_SE": "Tillämpar anti-aliasing på spelrenderaren.\n\nFXAA kommer att sudda det mesta av bilden, medan SMAA kommer att försöka hitta taggiga kanter och släta ut dem.\n\nRekommenderas inte att använda tillsammans med skalfiltret FSR.\n\nDet här alternativet kan ändras medan ett spel körs genom att klicka på \"Tillämpa\" nedan. Du kan helt enkelt flytta inställningsfönstret åt sidan och experimentera tills du hittar ditt föredragna utseende för ett spel.\n\nLämna som INGEN om du är osäker.", "sv_SE": "Tillämpar anti-aliasing på spelrenderaren.\n\nFXAA kommer att sudda det mesta av bilden, medan SMAA kommer att försöka hitta taggiga kanter och släta ut dem.\n\nRekommenderas inte att använda tillsammans med skalfiltret FSR.\n\nDet här alternativet kan ändras medan ett spel körs genom att klicka på \"Tillämpa\" nedan. Du kan helt enkelt flytta inställningsfönstret åt sidan och experimentera tills du hittar ditt föredragna utseende för ett spel.\n\nLämna som INGEN om du är osäker.",
"th_TH": "ใช้การลดรอยหยักกับการเรนเดอร์เกม\n\nFXAA จะเบลอภาพส่วนใหญ่ ในขณะที่ SMAA จะพยายามค้นหารอยหยักและปรับให้เรียบ\n\nไม่แนะนำให้ใช้ร่วมกับตัวกรองสเกล FSR\n\nตัวเลือกนี้สามารถเปลี่ยนแปลงได้ในขณะที่เกมกำลังทำงานอยู่โดยคลิก \"นำไปใช้\" ด้านล่าง คุณสามารถย้ายหน้าต่างการตั้งค่าไปด้านข้างและทดลองจนกว่าคุณจะพบรูปลักษณ์ที่คุณต้องการสำหรับเกม\n\nปล่อยไว้ที่ NONE หากไม่แน่ใจ", "th_TH": "ใช้การลดรอยหยักกับการเรนเดอร์เกม\n\nFXAA จะเบลอภาพส่วนใหญ่ ในขณะที่ SMAA จะพยายามค้นหารอยหยักและปรับให้เรียบ\n\nไม่แนะนำให้ใช้ร่วมกับตัวกรองสเกล FSR\n\nตัวเลือกนี้สามารถเปลี่ยนแปลงได้ในขณะที่เกมกำลังทำงานอยู่โดยคลิก \"นำไปใช้\" ด้านล่าง คุณสามารถย้ายหน้าต่างการตั้งค่าไปด้านข้างและทดลองจนกว่าคุณจะพบรูปลักษณ์ที่คุณต้องการสำหรับเกม\n\nปล่อยไว้ที่ NONE หากไม่แน่ใจ",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Застосовує згладження до рендера гри.\n\nFXAA розмиє більшість зображення, а SMAA спробує знайти нерівні краї та згладити їх.\n\nНе рекомендується використовувати разом з фільтром масштабування FSR.\n\nЦю опцію можна міняти коли гра запущена кліком на \"Застосувати; ви можете відсунути вікно налаштувань і поекспериментувати з видом гри.\n\nЗалиште \"Немає\", якщо не впевнені.", "uk_UA": "Вмикає згладжування.\n\nFXAA розмиє краї зображення, тоді як SMAA спробує згладити їх. FXAA (продуктивність) вимагає менше обчислювальних ресурсів, ніж SMAA (якість).\n\nНе рекомендується використовувати разом з фільтром масштабування FSR.\n\nЦю опцію можна міняти під час гри натисканням \"Застосувати\" в цьому вікні; щоб знайти найкращий варіант, просто відсуньте вікно налаштувань і поекспериментуйте.\n\nЗалиште \"Немає\", якщо не впевнені.",
"zh_CN": "抗锯齿是一种图形处理技术,用于减少图像边缘的锯齿状现象,使图像更加平滑。\n\nFXAA快速近似抗锯齿是一种性能开销相对较小的抗锯齿方法但可能会使得整体图像看起来有些模糊。\n\nSMAA增强型子像素抗锯齿则更加精细它会尝试找到锯齿边缘并平滑它们相比 FXAA 有更好的图像质量,但性能开销可能会稍大一些。\n\n如果开启了 FSRFidelityFX Super Resolution超级分辨率锐画技术来提高性能或图像质量不建议再启用抗锯齿因为它们会产生不必要的图形处理开销或者相互之间效果不协调。\n\n在游戏运行时通过点击下面的“应用”按钮可以使设置生效你可以将设置窗口移开并试验找到您喜欢的游戏画面效果。\n\n如果不确定请保持为“无”。", "zh_CN": "抗锯齿是一种图形处理技术,用于减少图像边缘的锯齿状现象,使图像更加平滑。\n\nFXAA快速近似抗锯齿是一种性能开销相对较小的抗锯齿方法但可能会使得整体图像看起来有些模糊。\n\nSMAA增强型子像素抗锯齿则更加精细它会尝试找到锯齿边缘并平滑它们相比 FXAA 有更好的图像质量,但性能开销可能会稍大一些。\n\n如果开启了 FSRFidelityFX Super Resolution超级分辨率锐画技术来提高性能或图像质量不建议再启用抗锯齿因为它们会产生不必要的图形处理开销或者相互之间效果不协调。\n\n在游戏运行时通过点击下面的“应用”按钮可以使设置生效你可以将设置窗口移开并试验找到您喜欢的游戏画面效果。\n\n如果不确定请保持为“无”。",
"zh_TW": "對遊戲繪製進行反鋸齒處理。\n\nFXAA 會模糊大部分圖像,而 SMAA 則會嘗試找出鋸齒邊緣並將其平滑化。\n\n不建議與 FSR 縮放濾鏡一起使用。\n\n此選項可在遊戲執行時透過點選下方的「套用」進行變更您只需將設定視窗移到一旁然後進行試驗直到找到您喜歡的遊戲效果。\n\n如果不確定請選擇無狀態。" "zh_TW": "對遊戲繪製進行反鋸齒處理。\n\nFXAA 會模糊大部分圖像,而 SMAA 則會嘗試找出鋸齒邊緣並將其平滑化。\n\n不建議與 FSR 縮放濾鏡一起使用。\n\n此選項可在遊戲執行時透過點選下方的「套用」進行變更您只需將設定視窗移到一旁然後進行試驗直到找到您喜歡的遊戲效果。\n\n如果不確定請選擇無狀態。"
} }
@ -22717,7 +22842,7 @@
"sv_SE": "Välj det skalfilter som ska tillämpas vid användning av upplösningsskala.\n\nBilinjär fungerar bra för 3D-spel och är ett säkert standardalternativ.\n\nNärmast rekommenderas för pixel art-spel.\n\nFSR 1.0 är bara ett skarpningsfilter, rekommenderas inte för FXAA eller SMAA.\n\nOmrådesskalning rekommenderas vid nedskalning av upplösning som är större än utdatafönstret. Det kan användas för att uppnå en supersamplad anti-alias-effekt vid nedskalning med mer än 2x.\n\nDetta alternativ kan ändras medan ett spel körs genom att klicka på \"Tillämpa\" nedan. du kan helt enkelt flytta inställningsfönstret åt sidan och experimentera tills du hittar ditt föredragna utseende för ett spel.\n\nLämna som BILINJÄR om du är osäker.", "sv_SE": "Välj det skalfilter som ska tillämpas vid användning av upplösningsskala.\n\nBilinjär fungerar bra för 3D-spel och är ett säkert standardalternativ.\n\nNärmast rekommenderas för pixel art-spel.\n\nFSR 1.0 är bara ett skarpningsfilter, rekommenderas inte för FXAA eller SMAA.\n\nOmrådesskalning rekommenderas vid nedskalning av upplösning som är större än utdatafönstret. Det kan användas för att uppnå en supersamplad anti-alias-effekt vid nedskalning med mer än 2x.\n\nDetta alternativ kan ändras medan ett spel körs genom att klicka på \"Tillämpa\" nedan. du kan helt enkelt flytta inställningsfönstret åt sidan och experimentera tills du hittar ditt föredragna utseende för ett spel.\n\nLämna som BILINJÄR om du är osäker.",
"th_TH": "เลือกตัวกรองสเกลที่จะใช้เมื่อใช้สเกลความละเอียด\n\nBilinear ทำงานได้ดีกับเกม 3D และเป็นตัวเลือกเริ่มต้นที่ปลอดภัย\n\nแนะนำให้ใช้เกมภาพพิกเซลที่ใกล้เคียงที่สุด\n\nFSR 1.0 เป็นเพียงตัวกรองความคมชัด ไม่แนะนำให้ใช้กับ FXAA หรือ SMAA\n\nตัวเลือกนี้สามารถเปลี่ยนแปลงได้ในขณะที่เกมกำลังทำงานอยู่โดยคลิก \"นำไปใช้\" ด้านล่าง คุณสามารถย้ายหน้าต่างการตั้งค่าไปด้านข้างและทดลองจนกว่าคุณจะพบรูปลักษณ์ที่คุณต้องการสำหรับเกม", "th_TH": "เลือกตัวกรองสเกลที่จะใช้เมื่อใช้สเกลความละเอียด\n\nBilinear ทำงานได้ดีกับเกม 3D และเป็นตัวเลือกเริ่มต้นที่ปลอดภัย\n\nแนะนำให้ใช้เกมภาพพิกเซลที่ใกล้เคียงที่สุด\n\nFSR 1.0 เป็นเพียงตัวกรองความคมชัด ไม่แนะนำให้ใช้กับ FXAA หรือ SMAA\n\nตัวเลือกนี้สามารถเปลี่ยนแปลงได้ในขณะที่เกมกำลังทำงานอยู่โดยคลิก \"นำไปใช้\" ด้านล่าง คุณสามารถย้ายหน้าต่างการตั้งค่าไปด้านข้างและทดลองจนกว่าคุณจะพบรูปลักษณ์ที่คุณต้องการสำหรับเกม",
"tr_TR": "Choose the scaling filter that will be applied when using resolution scale.\n\nBilinear works well for 3D games and is a safe default option.\n\nNearest is recommended for pixel art games.\n\nFSR 1.0 is merely a sharpening filter, not recommended for use with FXAA or SMAA.\n\nThis option can be changed while a game is running by clicking \"Apply\" below; you can simply move the settings window aside and experiment until you find your preferred look for a game.\n\nLeave on BILINEAR if unsure.", "tr_TR": "Choose the scaling filter that will be applied when using resolution scale.\n\nBilinear works well for 3D games and is a safe default option.\n\nNearest is recommended for pixel art games.\n\nFSR 1.0 is merely a sharpening filter, not recommended for use with FXAA or SMAA.\n\nThis option can be changed while a game is running by clicking \"Apply\" below; you can simply move the settings window aside and experiment until you find your preferred look for a game.\n\nLeave on BILINEAR if unsure.",
"uk_UA": "Виберіть фільтр масштабування, що використається при збільшенні роздільної здатності.\n\n\"Білінійний\" добре виглядає в 3D іграх, і хороше налаштування за умовчуванням.\n\n\"Найближчий\" рекомендується для ігор з піксель-артом.\n\n\"FSR 1.0\" - фільтр різкості. Не варто використовувати разом з FXAA або SMAA.\n\nЦю опцію можна змінювати під час гри кліком на \"Застосувати\" нижче; ви можете відсунути вікно налаштувань і поекспериментувати з тим, як відображатиметься гра.\n\nЗалиште \"Білінійний\", якщо не впевнені.", "uk_UA": "Оберіть фільтр масштабування, який буде використовуватися при збільшенні роздільної здатності.\n\n\"Білінійний\" добре виглядає в 3D іграх, і хороше налаштування за умовчуванням.\n\n\"Найближчий\" рекомендується для ігор з піксель-артом.\n\n\"FSR 1.0\" - фільтр різкості. Не варто використовувати разом з FXAA або SMAA.\n\nЦю опцію можна міняти під час гри натисканням \"Застосувати\" в цьому вікні; щоб знайти найкращий варіант, просто відсуньте вікно налаштувань і поекспериментуйте.\n\nЗалиште \"Білінійний\", якщо не впевнені.",
"zh_CN": "选择在分辨率缩放时将使用的缩放过滤器。\n\nBilinear双线性过滤对于3D游戏效果较好是一个安全的默认选项。\n\nNearest最近邻过滤推荐用于像素艺术游戏。\n\nFSR超级分辨率锐画只是一个锐化过滤器不推荐与 FXAA 或 SMAA 抗锯齿一起使用。\n\nArea局部过滤当渲染分辨率大于窗口实际分辨率推荐该选项。该选项在渲染比例大于2.0的情况下,可以实现超采样的效果。\n\n在游戏运行时通过点击下面的“应用”按钮可以使设置生效你可以将设置窗口移开并试验找到您喜欢的游戏画面效果。\n\n如果不确定请保持为“Bilinear双线性过滤”。", "zh_CN": "选择在分辨率缩放时将使用的缩放过滤器。\n\nBilinear双线性过滤对于3D游戏效果较好是一个安全的默认选项。\n\nNearest最近邻过滤推荐用于像素艺术游戏。\n\nFSR超级分辨率锐画只是一个锐化过滤器不推荐与 FXAA 或 SMAA 抗锯齿一起使用。\n\nArea局部过滤当渲染分辨率大于窗口实际分辨率推荐该选项。该选项在渲染比例大于2.0的情况下,可以实现超采样的效果。\n\n在游戏运行时通过点击下面的“应用”按钮可以使设置生效你可以将设置窗口移开并试验找到您喜欢的游戏画面效果。\n\n如果不确定请保持为“Bilinear双线性过滤”。",
"zh_TW": "選擇使用解析度縮放時套用的縮放過濾器。\n\n雙線性 (Bilinear) 濾鏡適用於 3D 遊戲,是一個安全的預設選項。\n\n建議像素美術遊戲使用近鄰性 (Nearest) 濾鏡。\n\nFSR 1.0 只是一個銳化濾鏡,不建議與 FXAA 或 SMAA 一起使用。\n\n此選項可在遊戲執行時透過點選下方的「套用」進行變更您只需將設定視窗移到一旁然後進行試驗直到找到您喜歡的遊戲效果。\n\n如果不確定請保持雙線性 (Bilinear) 狀態。" "zh_TW": "選擇使用解析度縮放時套用的縮放過濾器。\n\n雙線性 (Bilinear) 濾鏡適用於 3D 遊戲,是一個安全的預設選項。\n\n建議像素美術遊戲使用近鄰性 (Nearest) 濾鏡。\n\nFSR 1.0 只是一個銳化濾鏡,不建議與 FXAA 或 SMAA 一起使用。\n\n此選項可在遊戲執行時透過點選下方的「套用」進行變更您只需將設定視窗移到一旁然後進行試驗直到找到您喜歡的遊戲效果。\n\n如果不確定請保持雙線性 (Bilinear) 狀態。"
} }
@ -22817,7 +22942,7 @@
"sv_SE": "Yta", "sv_SE": "Yta",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "Зональна",
"zh_CN": "Area区域过滤", "zh_CN": "Area区域过滤",
"zh_TW": "區域" "zh_TW": "區域"
} }
@ -23767,7 +23892,7 @@
"sv_SE": "Emulerad vertikal synk. 'Switch' emulerar Switchens uppdateringsfrekvens på 60Hz. 'Obunden' är en obegränsad uppdateringsfrekvens. 'Anpassad uppdateringsfrekvens' emulerar den angivna anpassade uppdateringsfrekvensen.", "sv_SE": "Emulerad vertikal synk. 'Switch' emulerar Switchens uppdateringsfrekvens på 60Hz. 'Obunden' är en obegränsad uppdateringsfrekvens. 'Anpassad uppdateringsfrekvens' emulerar den angivna anpassade uppdateringsfrekvensen.",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Емульована вертикальна синхронізація кадрів. 'Switch' емулює частоту оновлення консолі Nintendo Switch (60 Гц). 'Необмежена' — частота оновлення не матиме обмежень. 'Користувацька' емулює вказану користувацьку частоту оновлення.", "uk_UA": "Емульована вертикальна синхронізація кадрів. 'Switch' емулює частоту оновлення консолі Nintendo Switch (60 Гц). 'Необмежена' — частота оновлення не матиме обмежень. 'Користувацька' емулює вказану користувачем частоту оновлення.",
"zh_CN": "模拟垂直同步。“Switch”模拟了 Switch 的 60Hz 刷新率。“无限制”没有刷新率限制。“自定义刷新率”模拟指定的自定义刷新率。", "zh_CN": "模拟垂直同步。“Switch”模拟了 Switch 的 60Hz 刷新率。“无限制”没有刷新率限制。“自定义刷新率”模拟指定的自定义刷新率。",
"zh_TW": "模擬垂直同步。「Switch」 模擬 Nintendo Switch 的 60Hz 重新整理頻率。「沒有限制」是沒有限制的重新整理頻率。「自訂的重新整理頻率」模擬所自訂的重新整理頻率。" "zh_TW": "模擬垂直同步。「Switch」 模擬 Nintendo Switch 的 60Hz 重新整理頻率。「沒有限制」是沒有限制的重新整理頻率。「自訂的重新整理頻率」模擬所自訂的重新整理頻率。"
} }
@ -24017,7 +24142,7 @@
"sv_SE": "Turboläge:", "sv_SE": "Turboläge:",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "Турбомод:",
"zh_CN": "涡轮模式: ", "zh_CN": "涡轮模式: ",
"zh_TW": "" "zh_TW": ""
} }
@ -24042,7 +24167,7 @@
"sv_SE": "Snabbtangenten för turboläge.\nKonfigurera beteendet för turboläge i Ryujinx CPU-inställningar.\n\nLämna Obunden om du är osäker.", "sv_SE": "Snabbtangenten för turboläge.\nKonfigurera beteendet för turboläge i Ryujinx CPU-inställningar.\n\nLämna Obunden om du är osäker.",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "Гаряча клавіша Турборежиму.\nКонфігурація поведінки турборежиму в налаштуваннях Процесору Ryujinx.\n\nНе прив'язуйте, якщо не впевнені.",
"zh_CN": "涡轮模式热键。\n可以在 Ryujinx CPU 设置中配置涡轮模式的行为。\n\n如果不确定请保留为未绑定。", "zh_CN": "涡轮模式热键。\n可以在 Ryujinx CPU 设置中配置涡轮模式的行为。\n\n如果不确定请保留为未绑定。",
"zh_TW": "" "zh_TW": ""
} }
@ -24067,7 +24192,7 @@
"sv_SE": "Endast när du trycker ner", "sv_SE": "Endast när du trycker ner",
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "Тільки під час натискання",
"zh_CN": "仅在按下时", "zh_CN": "仅在按下时",
"zh_TW": "" "zh_TW": ""
} }

View file

@ -21,6 +21,11 @@ namespace Ryujinx.Common.Configuration.Hid
/// </summary> /// </summary>
public string Id { get; set; } public string Id { get; set; }
/// <summary>
/// Controller name
/// </summary>
public string Name { get; set; }
/// <summary> /// <summary>
/// Controller's Type /// Controller's Type
/// </summary> /// </summary>

View file

@ -49,7 +49,6 @@
<TextBlock <TextBlock
Classes="globalConfigMarker"/> Classes="globalConfigMarker"/>
</StackPanel> </StackPanel>
</Border> </Border>
</Design.PreviewWith> </Design.PreviewWith>
<Style Selector="DropDownButton"> <Style Selector="DropDownButton">

View file

@ -276,6 +276,7 @@ namespace Ryujinx.Ava.Systems.Configuration
Version = InputConfig.CurrentVersion, Version = InputConfig.CurrentVersion,
Backend = InputBackendType.WindowKeyboard, Backend = InputBackendType.WindowKeyboard,
Id = "0", Id = "0",
Name = "Keyboard",
PlayerIndex = PlayerIndex.Player1, PlayerIndex = PlayerIndex.Player1,
ControllerType = ControllerType.ProController, ControllerType = ControllerType.ProController,
LeftJoycon = new LeftJoyconCommonConfig<Key> LeftJoycon = new LeftJoyconCommonConfig<Key>

View file

@ -22,6 +22,8 @@ namespace Ryujinx.Ava.UI.Models.Input
public float StrongRumble { get; set; } public float StrongRumble { get; set; }
public string Id { get; set; } public string Id { get; set; }
public string Name { get; set; }
public ControllerType ControllerType { get; set; } public ControllerType ControllerType { get; set; }
public PlayerIndex PlayerIndex { get; set; } public PlayerIndex PlayerIndex { get; set; }
@ -111,6 +113,7 @@ namespace Ryujinx.Ava.UI.Models.Input
if (config != null) if (config != null)
{ {
Id = config.Id; Id = config.Id;
Name = config.Name;
ControllerType = config.ControllerType; ControllerType = config.ControllerType;
PlayerIndex = config.PlayerIndex; PlayerIndex = config.PlayerIndex;
@ -201,6 +204,7 @@ namespace Ryujinx.Ava.UI.Models.Input
StandardControllerInputConfig config = new() StandardControllerInputConfig config = new()
{ {
Id = Id, Id = Id,
Name = Name,
Backend = InputBackendType.GamepadSDL2, Backend = InputBackendType.GamepadSDL2,
PlayerIndex = PlayerIndex, PlayerIndex = PlayerIndex,
ControllerType = ControllerType, ControllerType = ControllerType,

View file

@ -2,12 +2,14 @@ using CommunityToolkit.Mvvm.ComponentModel;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Keyboard; using Ryujinx.Common.Configuration.Hid.Keyboard;
using System.Xml.Linq;
namespace Ryujinx.Ava.UI.Models.Input namespace Ryujinx.Ava.UI.Models.Input
{ {
public partial class KeyboardInputConfig : BaseModel public partial class KeyboardInputConfig : BaseModel
{ {
public string Id { get; set; } public string Id { get; set; }
public string Name { get; set; }
public ControllerType ControllerType { get; set; } public ControllerType ControllerType { get; set; }
public PlayerIndex PlayerIndex { get; set; } public PlayerIndex PlayerIndex { get; set; }
@ -53,6 +55,7 @@ namespace Ryujinx.Ava.UI.Models.Input
if (config != null) if (config != null)
{ {
Id = config.Id; Id = config.Id;
Name = config.Name;
ControllerType = config.ControllerType; ControllerType = config.ControllerType;
PlayerIndex = config.PlayerIndex; PlayerIndex = config.PlayerIndex;
@ -100,6 +103,7 @@ namespace Ryujinx.Ava.UI.Models.Input
StandardKeyboardInputConfig config = new() StandardKeyboardInputConfig config = new()
{ {
Id = Id, Id = Id,
Name = Name,
Backend = InputBackendType.WindowKeyboard, Backend = InputBackendType.WindowKeyboard,
PlayerIndex = PlayerIndex, PlayerIndex = PlayerIndex,
ControllerType = ControllerType, ControllerType = ControllerType,

View file

@ -93,16 +93,19 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public async void ShowMotionConfig() public async void ShowMotionConfig()
{ {
await MotionInputView.Show(this); await MotionInputView.Show(this);
ParentModel.IsModified = true;
} }
public async void ShowRumbleConfig() public async void ShowRumbleConfig()
{ {
await RumbleInputView.Show(this); await RumbleInputView.Show(this);
ParentModel.IsModified = true;
} }
public async void ShowLedConfig() public async void ShowLedConfig()
{ {
await LedInputView.Show(this); await LedInputView.Show(this);
ParentModel.IsModified = true;
} }
public void OnParentModelChanged() public void OnParentModelChanged()

View file

@ -51,6 +51,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
private int _device; private int _device;
private object _configViewModel; private object _configViewModel;
[ObservableProperty] private string _profileName; [ObservableProperty] private string _profileName;
[ObservableProperty] private bool _notificationIsVisible; // Automatically call the NotificationView property with OnPropertyChanged()
[ObservableProperty] private string _notificationText; // Automatically call the NotificationText property with OnPropertyChanged()
private bool _isLoaded; private bool _isLoaded;
private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
@ -88,13 +90,40 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public bool IsKeyboard => !IsController; public bool IsKeyboard => !IsController;
public bool IsRight { get; set; } public bool IsRight { get; set; }
public bool IsLeft { get; set; } public bool IsLeft { get; set; }
public string RevertDeviceId { get; set; }
public bool HasLed => SelectedGamepad.Features.HasFlag(GamepadFeaturesFlag.Led); public bool HasLed => SelectedGamepad.Features.HasFlag(GamepadFeaturesFlag.Led);
public bool CanClearLed => SelectedGamepad.Name.ContainsIgnoreCase("DualSense"); public bool CanClearLed => SelectedGamepad.Name.ContainsIgnoreCase("DualSense");
public bool IsModified { get; set; } public bool _isChangeTrackingActive;
public bool _isModified;
public bool IsModified
{
get => _isModified;
set
{
_isModified = value;
OnPropertyChanged();
}
}
public event Action NotifyChangesEvent; public event Action NotifyChangesEvent;
public string _profileChoose;
public string ProfileChoose
{
get => _profileChoose;
set
{
// When you select a profile, the settings from the profile will be applied.
// To save the settings, you still need to click the apply button
_profileChoose = value;
LoadProfile();
OnPropertyChanged();
}
}
public object ConfigViewModel public object ConfigViewModel
{ {
get => _configViewModel; get => _configViewModel;
@ -121,13 +150,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{ {
if (IsModified) if (IsModified)
{ {
_playerIdChoose = value; _playerIdChoose = value;
return; return;
} }
IsModified = false; IsModified = false;
_playerId = value; _playerId = value;
_isChangeTrackingActive = false;
if (!Enum.IsDefined<PlayerIndex>(_playerId)) if (!Enum.IsDefined<PlayerIndex>(_playerId))
{ {
@ -135,13 +164,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
} }
_isLoaded = false; _isLoaded = false;
LoadConfiguration(); LoadConfiguration();
LoadDevice(); LoadDevice();
LoadProfiles(); LoadProfiles();
RevertDeviceId = Devices[Device].Id;
_isLoaded = true; _isLoaded = true;
_isChangeTrackingActive = true;
OnPropertyChanged(); OnPropertyChanged();
} }
} }
@ -151,6 +180,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
get => _controller; get => _controller;
set set
{ {
MarkAsChanged();
_controller = value; _controller = value;
if (_controller == -1) if (_controller == -1)
@ -229,6 +260,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
get => _device; get => _device;
set set
{ {
MarkAsChanged();
_device = value < 0 ? 0 : value; _device = value < 0 ? 0 : value;
if (_device >= Devices.Count) if (_device >= Devices.Count)
@ -248,11 +281,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
} }
} }
FindPairedDeviceInConfigFile();
OnPropertyChanged(); OnPropertyChanged();
NotifyChanges(); NotifyChanges();
} }
} }
public InputConfig Config { get; set; } public InputConfig Config { get; set; }
public InputViewModel(UserControl owner) : this() public InputViewModel(UserControl owner) : this()
@ -274,6 +309,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
PlayerId = PlayerIndex.Player1; PlayerId = PlayerIndex.Player1;
} }
_isChangeTrackingActive = true;
} }
public InputViewModel() public InputViewModel()
@ -311,8 +348,50 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{ {
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig), VisualStick); ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig), VisualStick);
} }
FindPairedDeviceInConfigFile();
} }
private void FindPairedDeviceInConfigFile()
{
// This function allows you to output a message about the device configuration found in the file
// NOTE: if the configuration is found, we display the message "Waiting for controller connection",
// but only if the id gamepad belongs to the selected player
NotificationIsVisible = Config != null && Devices.FirstOrDefault(d => d.Id == Config.Id).Id != Config.Id && Config.PlayerIndex == PlayerId;
if (NotificationIsVisible)
{
if (string.IsNullOrEmpty(Config.Name))
{
NotificationText = $"{LocaleManager.Instance[LocaleKeys.ControllerSettingsWaitingConnectDevice].Format("No information", Config.Id)}";
}
else
{
NotificationText = $"{LocaleManager.Instance[LocaleKeys.ControllerSettingsWaitingConnectDevice].Format(Config.Name, Config.Id)}";
}
}
}
private void MarkAsChanged()
{
//If tracking is active, then allow changing the modifier
if (!IsModified && _isChangeTrackingActive)
{
RevertDeviceId = Devices[Device].Id; // Remember the device to undo changes
IsModified = true;
}
}
public void UnlinkDevice()
{
// "Disabled" mode is available after unbinding the device
// NOTE: the IsModified flag to be able to apply the settings.
NotificationIsVisible = false;
IsModified = true;
}
public void LoadDevice() public void LoadDevice()
{ {
if (Config == null || Config.Backend == InputBackendType.Invalid) if (Config == null || Config.Backend == InputBackendType.Invalid)
@ -378,14 +457,34 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
} }
} }
private void HandleOnGamepadDisconnected(string id) private async void HandleOnGamepadDisconnected(string id)
{ {
Dispatcher.UIThread.Post(LoadDevices); _isChangeTrackingActive = false; // Disable configuration change tracking
await Dispatcher.UIThread.InvokeAsync(() =>
{
LoadDevices();
IsModified = true;
RevertChanges();
FindPairedDeviceInConfigFile();
_isChangeTrackingActive = true; // Enable configuration change tracking
return System.Threading.Tasks.Task.CompletedTask;
});
} }
private void HandleOnGamepadConnected(string id) private async void HandleOnGamepadConnected(string id)
{ {
Dispatcher.UIThread.Post(LoadDevices); _isChangeTrackingActive = false; // Disable configuration change tracking
await Dispatcher.UIThread.InvokeAsync(() =>
{
LoadDevices();
IsModified = true;
RevertChanges();
_isChangeTrackingActive = true;// Enable configuration change tracking
});
} }
private string GetCurrentGamepadId() private string GetCurrentGamepadId()
@ -558,12 +657,14 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
if (activeDevice.Type == DeviceType.Keyboard) if (activeDevice.Type == DeviceType.Keyboard)
{ {
string id = activeDevice.Id; string id = activeDevice.Id;
string name = activeDevice.Name;
config = new StandardKeyboardInputConfig config = new StandardKeyboardInputConfig
{ {
Version = InputConfig.CurrentVersion, Version = InputConfig.CurrentVersion,
Backend = InputBackendType.WindowKeyboard, Backend = InputBackendType.WindowKeyboard,
Id = id, Id = id,
Name = name,
ControllerType = ControllerType.ProController, ControllerType = ControllerType.ProController,
LeftJoycon = new LeftJoyconCommonConfig<Key> LeftJoycon = new LeftJoyconCommonConfig<Key>
{ {
@ -613,12 +714,14 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
bool isNintendoStyle = Devices.ToList().FirstOrDefault(x => x.Id == activeDevice.Id).Name.Contains("Nintendo"); bool isNintendoStyle = Devices.ToList().FirstOrDefault(x => x.Id == activeDevice.Id).Name.Contains("Nintendo");
string id = activeDevice.Id.Split(" ")[0]; string id = activeDevice.Id.Split(" ")[0];
string name = activeDevice.Name;
config = new StandardControllerInputConfig config = new StandardControllerInputConfig
{ {
Version = InputConfig.CurrentVersion, Version = InputConfig.CurrentVersion,
Backend = InputBackendType.GamepadSDL2, Backend = InputBackendType.GamepadSDL2,
Id = id, Id = id,
Name = name,
ControllerType = ControllerType.ProController, ControllerType = ControllerType.ProController,
DeadzoneLeft = 0.1f, DeadzoneLeft = 0.1f,
DeadzoneRight = 0.1f, DeadzoneRight = 0.1f,
@ -688,6 +791,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
return config; return config;
} }
public void LoadProfileButton()
{
LoadProfile();
IsModified = true;
}
public async void LoadProfile() public async void LoadProfile()
{ {
if (Device == 0) if (Device == 0)
@ -739,9 +848,11 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{ {
_isLoaded = false; _isLoaded = false;
config.Id = Config.Id; // Set current device id instead of changing device(independent profiles)
LoadConfiguration(config); LoadConfiguration(config);
LoadDevice(); //LoadDevice(); This line of code hard-links profiles to controllers, the commented line allows profiles to be applied to all controllers
_isLoaded = true; _isLoaded = true;
@ -751,6 +862,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public async void SaveProfile() public async void SaveProfile()
{ {
if (Device == 0) if (Device == 0)
{ {
return; return;
@ -793,12 +905,15 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
await File.WriteAllTextAsync(path, jsonString); await File.WriteAllTextAsync(path, jsonString);
LoadProfiles(); LoadProfiles();
ProfileChoose = ProfileName; // Show new profile
} }
else else
{ {
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogProfileInvalidProfileNameErrorMessage]); await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogProfileInvalidProfileNameErrorMessage]);
} }
} }
} }
public async void RemoveProfile() public async void RemoveProfile()
@ -825,14 +940,33 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
} }
LoadProfiles(); LoadProfiles();
ProfileChoose = ProfilesList[0].ToString(); // Show default profile
} }
} }
public void RevertChanges()
{
Device = Devices.ToList().FindIndex(d => d.Id == RevertDeviceId);
LoadDevice();
LoadConfiguration();
OnPropertyChanged();
IsModified = false;
}
public void Save() public void Save()
{ {
if (!IsModified)
{
return; //If the input settings were not touched, then do nothing
}
IsModified = false; IsModified = false;
List<InputConfig> newConfig = []; RevertDeviceId = Devices[Device].Id; // Remember selected device after saving
List <InputConfig> newConfig = [];
newConfig.AddRange(ConfigurationState.Instance.Hid.InputConfig.Value); newConfig.AddRange(ConfigurationState.Instance.Hid.InputConfig.Value);
@ -862,6 +996,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
: (ConfigViewModel as ControllerInputViewModel).Config.GetConfig(); : (ConfigViewModel as ControllerInputViewModel).Config.GetConfig();
config.ControllerType = Controllers[_controller].Type; config.ControllerType = Controllers[_controller].Type;
config.PlayerIndex = _playerId; config.PlayerIndex = _playerId;
config.Name = device.Name;
int i = newConfig.FindIndex(x => x.PlayerIndex == PlayerId); int i = newConfig.FindIndex(x => x.PlayerIndex == PlayerId);
if (i == -1) if (i == -1)

View file

@ -65,7 +65,8 @@ namespace Ryujinx.Ava.UI.Views.Input
if (!float.IsNaN(_changeSlider) && _changeSlider != (float)check.Value) if (!float.IsNaN(_changeSlider) && _changeSlider != (float)check.Value)
{ {
(DataContext as ControllerInputViewModel)!.ParentModel.IsModified = true; FlagInputConfigChanged();
_changeSlider = (float)check.Value; _changeSlider = (float)check.Value;
} }
} }
@ -75,7 +76,8 @@ namespace Ryujinx.Ava.UI.Views.Input
{ {
if (sender is CheckBox { IsPointerOver: true }) if (sender is CheckBox { IsPointerOver: true })
{ {
(DataContext as ControllerInputViewModel)!.ParentModel.IsModified = true; FlagInputConfigChanged();
_currentAssigner?.Cancel(); _currentAssigner?.Cancel();
_currentAssigner = null; _currentAssigner = null;
} }
@ -115,7 +117,7 @@ namespace Ryujinx.Ava.UI.Views.Input
if (e.ButtonValue.HasValue) if (e.ButtonValue.HasValue)
{ {
Button buttonValue = e.ButtonValue.Value; Button buttonValue = e.ButtonValue.Value;
viewModel.ParentModel.IsModified = true; FlagInputConfigChanged();
switch (button.Name) switch (button.Name)
{ {
@ -209,6 +211,11 @@ namespace Ryujinx.Ava.UI.Views.Input
} }
} }
private void FlagInputConfigChanged()
{
(DataContext as ControllerInputViewModel)!.ParentModel.IsModified = true;
}
private void MouseClick(object sender, PointerPressedEventArgs e) private void MouseClick(object sender, PointerPressedEventArgs e)
{ {
bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed; bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
@ -232,7 +239,6 @@ namespace Ryujinx.Ava.UI.Views.Input
{ {
gamepad?.ClearLed(); gamepad?.ClearLed();
} }
_currentAssigner?.Cancel(); _currentAssigner?.Cancel();
_currentAssigner = null; _currentAssigner = null;
} }

View file

@ -41,13 +41,20 @@
Grid.Column="0" Grid.Column="0"
Margin="2" Margin="2"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Center" ColumnDefinitions="Auto,*"> VerticalAlignment="Center" ColumnDefinitions="Auto,*,Auto">
<TextBlock <StackPanel
Orientation="Vertical"
Margin="5,0,10,0" Margin="5,0,10,0"
Width="90"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Center" VerticalAlignment="Center"
Width="90">
<TextBlock
Text="{ext:Locale ControllerSettingsPlayer}" /> Text="{ext:Locale ControllerSettingsPlayer}" />
<TextBlock
Classes="pending"
Text ="{ext:Locale ControllerSettingsModifiedNotification}"
IsVisible="{Binding IsModified}"/>
</StackPanel>
<ComboBox <ComboBox
Grid.Column="1" Grid.Column="1"
Name="PlayerIndexBox" Name="PlayerIndexBox"
@ -62,6 +69,18 @@
</DataTemplate> </DataTemplate>
</ComboBox.ItemTemplate> </ComboBox.ItemTemplate>
</ComboBox> </ComboBox>
<Button
Grid.Column="2"
MinWidth="0"
Margin="5,0,0,0"
VerticalAlignment="Center"
ToolTip.Tip="{ext:Locale ControllerSettingsCancelCurrentChangesToolTip}"
Command="{Binding RevertChanges}">
<ui:SymbolIcon
Symbol="Undo"
FontSize="15"
Height="20" />
</Button>
</Grid> </Grid>
<!-- Profile Selection --> <!-- Profile Selection -->
<Grid <Grid
@ -81,7 +100,8 @@
Name="ProfileBox" Name="ProfileBox"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Center" VerticalAlignment="Center"
SelectedIndex="0" SelectedItem="{Binding ProfileChoose, Mode=TwoWay}"
SelectionChanged="ComboBox_SelectionChanged"
ItemsSource="{Binding ProfilesList}" ItemsSource="{Binding ProfilesList}"
Text="{Binding ProfileName, Mode=TwoWay}" /> Text="{Binding ProfileName, Mode=TwoWay}" />
<Button <Button
@ -90,7 +110,7 @@
Margin="5,0,0,0" Margin="5,0,0,0"
VerticalAlignment="Center" VerticalAlignment="Center"
ToolTip.Tip="{ext:Locale ControllerSettingsLoadProfileToolTip}" ToolTip.Tip="{ext:Locale ControllerSettingsLoadProfileToolTip}"
Command="{Binding LoadProfile}"> Command="{Binding LoadProfileButton}">
<ui:SymbolIcon <ui:SymbolIcon
Symbol="View" Symbol="View"
FontSize="15" FontSize="15"
@ -148,7 +168,7 @@
MinWidth="0" MinWidth="0"
Margin="5,0,0,0" Margin="5,0,0,0"
VerticalAlignment="Center" VerticalAlignment="Center"
Command="{Binding LoadDevices}"> Command="{Binding LoadDevice}">
<ui:SymbolIcon <ui:SymbolIcon
Symbol="Refresh" Symbol="Refresh"
FontSize="15" FontSize="15"
@ -181,6 +201,28 @@
</Grid> </Grid>
</Grid> </Grid>
</StackPanel> </StackPanel>
<ContentControl IsVisible="{Binding NotificationIsVisible}">
<ContentControl.Content>
<StackPanel>
<TextBlock
Margin="5,20,0,0"
Text="{Binding NotificationText}" />
<Button
MinWidth="0"
Width="90"
Height="27"
Margin="0,10,0,0"
VerticalAlignment="Center"
Command="{Binding UnlinkDevice}">
<TextBlock
Text="{ext:Locale ControllerSettingsUnlink}"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Button>
</StackPanel>
</ContentControl.Content>
</ContentControl>
<ContentControl Content="{Binding ConfigViewModel}" IsVisible="{Binding ShowSettings}"> <ContentControl Content="{Binding ConfigViewModel}" IsVisible="{Binding ShowSettings}">
<ContentControl.DataTemplates> <ContentControl.DataTemplates>
<DataTemplate DataType="viewModels:ControllerInputViewModel"> <DataTemplate DataType="viewModels:ControllerInputViewModel">

View file

@ -1,4 +1,5 @@
using Avalonia.Controls; using Avalonia.Controls;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
@ -63,13 +64,22 @@ namespace Ryujinx.Ava.UI.Views.Input
return; return;
} }
ViewModel.IsModified = false;
ViewModel.PlayerId = ViewModel.PlayerIdChoose; ViewModel.PlayerId = ViewModel.PlayerIdChoose;
ViewModel.IsModified = false;
} }
} }
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is FAComboBox faComboBox)
{
faComboBox.IsDropDownOpen = false;
ViewModel.IsModified = true;
}
}
public void Dispose() public void Dispose()
{ {
ViewModel.Dispose(); ViewModel.Dispose();

View file

@ -9,6 +9,8 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels.Input; using Ryujinx.Ava.UI.ViewModels.Input;
using Ryujinx.Input; using Ryujinx.Input;
using Ryujinx.Input.Assigner; using Ryujinx.Input.Assigner;
using System.Collections.Generic;
using System;
using Button = Ryujinx.Input.Button; using Button = Ryujinx.Input.Button;
using Key = Ryujinx.Common.Configuration.Hid.Key; using Key = Ryujinx.Common.Configuration.Hid.Key;
@ -186,11 +188,63 @@ namespace Ryujinx.Ava.UI.Views.Input
{ {
bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed; bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
bool shouldRemoveBinding = e.GetCurrentPoint(this).Properties.IsRightButtonPressed;
if (shouldRemoveBinding)
{
DeleteBind();
}
_currentAssigner?.Cancel(shouldUnbind); _currentAssigner?.Cancel(shouldUnbind);
PointerPressed -= MouseClick; PointerPressed -= MouseClick;
} }
private void DeleteBind()
{
if (_currentAssigner != null)
{
Dictionary<string, Action> buttonActions = new Dictionary<string, Action>
{
{ "ButtonZl", () => ViewModel.Config.ButtonZl = Key.Unbound },
{ "ButtonL", () => ViewModel.Config.ButtonL = Key.Unbound },
{ "ButtonMinus", () => ViewModel.Config.ButtonMinus = Key.Unbound },
{ "LeftStickButton", () => ViewModel.Config.LeftStickButton = Key.Unbound },
{ "LeftStickUp", () => ViewModel.Config.LeftStickUp = Key.Unbound },
{ "LeftStickDown", () => ViewModel.Config.LeftStickDown = Key.Unbound },
{ "LeftStickRight", () => ViewModel.Config.LeftStickRight = Key.Unbound },
{ "LeftStickLeft", () => ViewModel.Config.LeftStickLeft = Key.Unbound },
{ "DpadUp", () => ViewModel.Config.DpadUp = Key.Unbound },
{ "DpadDown", () => ViewModel.Config.DpadDown = Key.Unbound },
{ "DpadLeft", () => ViewModel.Config.DpadLeft = Key.Unbound },
{ "DpadRight", () => ViewModel.Config.DpadRight = Key.Unbound },
{ "LeftButtonSr", () => ViewModel.Config.LeftButtonSr = Key.Unbound },
{ "LeftButtonSl", () => ViewModel.Config.LeftButtonSl = Key.Unbound },
{ "RightButtonSr", () => ViewModel.Config.RightButtonSr = Key.Unbound },
{ "RightButtonSl", () => ViewModel.Config.RightButtonSl = Key.Unbound },
{ "ButtonZr", () => ViewModel.Config.ButtonZr = Key.Unbound },
{ "ButtonR", () => ViewModel.Config.ButtonR = Key.Unbound },
{ "ButtonPlus", () => ViewModel.Config.ButtonPlus = Key.Unbound },
{ "ButtonA", () => ViewModel.Config.ButtonA = Key.Unbound },
{ "ButtonB", () => ViewModel.Config.ButtonB = Key.Unbound },
{ "ButtonX", () => ViewModel.Config.ButtonX = Key.Unbound },
{ "ButtonY", () => ViewModel.Config.ButtonY = Key.Unbound },
{ "RightStickButton", () => ViewModel.Config.RightStickButton = Key.Unbound },
{ "RightStickUp", () => ViewModel.Config.RightStickUp = Key.Unbound },
{ "RightStickDown", () => ViewModel.Config.RightStickDown = Key.Unbound },
{ "RightStickRight", () => ViewModel.Config.RightStickRight = Key.Unbound },
{ "RightStickLeft", () => ViewModel.Config.RightStickLeft = Key.Unbound }
};
if (buttonActions.TryGetValue(_currentAssigner.ToggledButton.Name, out Action action))
{
action();
ViewModel.ParentModel.IsModified = true;
}
}
}
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{ {
base.OnDetachedFromVisualTree(e); base.OnDetachedFromVisualTree(e);

View file

@ -10,6 +10,8 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Input; using Ryujinx.Input;
using Ryujinx.Input.Assigner; using Ryujinx.Input.Assigner;
using System.Collections.Generic;
using System;
using Button = Ryujinx.Input.Button; using Button = Ryujinx.Input.Button;
using Key = Ryujinx.Common.Configuration.Hid.Key; using Key = Ryujinx.Common.Configuration.Hid.Key;
@ -45,6 +47,51 @@ namespace Ryujinx.Ava.UI.Views.Settings
} }
} }
private void MouseClick(object sender, PointerPressedEventArgs e)
{
bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
bool shouldRemoveBinding = e.GetCurrentPoint(this).Properties.IsRightButtonPressed;
if (shouldRemoveBinding)
{
DeleteBind();
}
_currentAssigner?.Cancel(shouldUnbind);
PointerPressed -= MouseClick;
}
private void DeleteBind()
{
if (DataContext is not SettingsViewModel viewModel)
return;
if (_currentAssigner != null)
{
Dictionary<string, Action> buttonActions = new Dictionary<string, Action>
{
{ "ToggleVSyncMode", () => viewModel.KeyboardHotkey.ToggleVSyncMode = Key.Unbound },
{ "Screenshot", () => viewModel.KeyboardHotkey.Screenshot = Key.Unbound },
{ "ShowUI", () => viewModel.KeyboardHotkey.ShowUI = Key.Unbound },
{ "Pause", () => viewModel.KeyboardHotkey.Pause = Key.Unbound },
{ "ToggleMute", () => viewModel.KeyboardHotkey.ToggleMute = Key.Unbound },
{ "ResScaleUp", () => viewModel.KeyboardHotkey.ResScaleUp = Key.Unbound },
{ "ResScaleDown", () => viewModel.KeyboardHotkey.ResScaleDown = Key.Unbound },
{ "VolumeUp", () => viewModel.KeyboardHotkey.VolumeUp = Key.Unbound },
{ "VolumeDown", () => viewModel.KeyboardHotkey.VolumeDown = Key.Unbound },
{ "CustomVSyncIntervalIncrement", () => viewModel.KeyboardHotkey.CustomVSyncIntervalIncrement = Key.Unbound },
{ "CustomVSyncIntervalDecrement", () => viewModel.KeyboardHotkey.CustomVSyncIntervalDecrement = Key.Unbound },
{ "TurboMode", () => viewModel.KeyboardHotkey.TurboMode = Key.Unbound }
};
if (buttonActions.TryGetValue(_currentAssigner.ToggledButton.Name, out Action action))
{
action();
}
}
}
private void Button_IsCheckedChanged(object sender, RoutedEventArgs e) private void Button_IsCheckedChanged(object sender, RoutedEventArgs e)
{ {
if (sender is ToggleButton button) if (sender is ToggleButton button)
@ -62,6 +109,8 @@ namespace Ryujinx.Ava.UI.Views.Settings
this.Focus(NavigationMethod.Pointer); this.Focus(NavigationMethod.Pointer);
PointerPressed += MouseClick;
IKeyboard keyboard = (IKeyboard)_avaloniaKeyboardDriver.GetGamepad("0"); IKeyboard keyboard = (IKeyboard)_avaloniaKeyboardDriver.GetGamepad("0");
IButtonAssigner assigner = new KeyboardKeyAssigner(keyboard); IButtonAssigner assigner = new KeyboardKeyAssigner(keyboard);