Compare commits

...

29 Commits

Author SHA1 Message Date
Vladimir Sokolov
53c44b2e1d Merge branch 'master' into Master_PR 2025-03-09 21:49:39 +10:00
Evan Husted
d5527f87cb UI: [ci skip] fix changelog urls on new release channel 2025-03-08 21:07:03 -06:00
Evan Husted
fc75dbc8b8 Update release.yml 2025-03-08 20:49:21 -06:00
Evan Husted
04361b864a stable release channel repo 2025-03-08 20:45:47 -06:00
Vladimir Sokolov
ef5177f050 Merge branch 'master' into Master_PR 2025-03-09 10:58:21 +10:00
rrondo
7271e7050d Ukrainian localization update (#755) 2025-03-07 23:28:25 -06:00
Vladimir Sokolov
28bcb85c31 Merge branch 'master' into Master_PR 2025-03-06 22:13:17 +10:00
Vladimir Sokolov
da0d2e1b70 Merge branch 'master' into Master_PR 2025-03-06 17:32:24 +10: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
15 changed files with 541 additions and 115 deletions

View File

@@ -12,7 +12,8 @@ env:
RYUJINX_BASE_VERSION: "1.2"
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing"
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx"
RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx"
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Stable-Releases"
RELEASE: 1
jobs:
@@ -33,7 +34,7 @@ jobs:
script: |
github.rest.git.createRef({
owner: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}",
repo: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}",
repo: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}",
ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}',
sha: context.sha
})
@@ -52,7 +53,7 @@ jobs:
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}
omitBodyDuringUpdate: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
@@ -92,7 +93,7 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
@@ -173,7 +174,7 @@ jobs:
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}
omitBodyDuringUpdate: true
allowUpdates: true
replacesArtifacts: true
@@ -222,7 +223,7 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash

View File

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

View File

@@ -37,7 +37,7 @@ namespace Ryujinx.Common
public static string GetChangelogUrl(Version currentVersion, Version newVersion) =>
IsCanaryBuild
? $"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelSourceRepo}/compare/Canary-{currentVersion}...Canary-{newVersion}"
: $"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelSourceRepo}/releases/tag/{newVersion}";
: $"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelRepo}/releases/{newVersion}";
public static string GetChangelogForVersion(Version version) =>
$"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelRepo}/releases/tag/{version}";

View File

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

View File

@@ -2767,7 +2767,7 @@
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"uk_UA": "Створити користувацьку конфігурацію",
"zh_CN": "",
"zh_TW": ""
}
@@ -2792,7 +2792,7 @@
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"uk_UA": "Редагувати користувацьку конфігурацію",
"zh_CN": "",
"zh_TW": ""
}
@@ -2842,7 +2842,7 @@
"sv_SE": "Skapar en oberoende konfiguration för det aktuella spelet",
"th_TH": "สร้างการกำหนดค่าที่เป็นอิสระสำหรับเกมปัจจุบัน",
"tr_TR": "Mevcut oyun için bağımsız bir yapılandırma oluşturur",
"uk_UA": "Створює незалежну конфігурацію для поточної гри",
"uk_UA": "Створюйте незалежну конфігурацію для поточної гри",
"zh_CN": "为当前游戏创建独立的配置",
"zh_TW": "為當前遊戲創建獨立的配置"
}
@@ -2867,7 +2867,7 @@
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"uk_UA": "Відредагувати наявну індивідуальну конфігурацію для цієї гри.",
"zh_CN": "",
"zh_TW": ""
}
@@ -3442,7 +3442,7 @@
"sv_SE": "Användargränssnitt",
"th_TH": "หน้าจอผู้ใช้",
"tr_TR": "Kullancı Arayüzü",
"uk_UA": "Інтерфейс користувача",
"uk_UA": "Інтерфейс",
"zh_CN": "用户界面",
"zh_TW": "使用者介面"
}
@@ -3817,7 +3817,7 @@
"sv_SE": "Inaktivera inmatning när fokus tappas",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"uk_UA": "Вимкнути введення, якщо вікно неактивне",
"zh_CN": "在后台时禁用输入",
"zh_TW": ""
}
@@ -3842,7 +3842,7 @@
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"uk_UA": "Показати оригінальний UI (Потрібен перезапуск)",
"zh_CN": "",
"zh_TW": ""
}
@@ -3867,7 +3867,7 @@
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"uk_UA": "Показати старий інтерфейс Avalonia Ryujinx, який був у Ryujinx 1.1.1403. Ця опція активна за замовчуванням на всіх інших, окрім Windows платформах.\nПовернеться класична панель заголовка, а всі суттєві зміни інтерфейсу будуть скасовані, зокрема горизонтальне розміщення навігації в налаштуваннях.",
"zh_CN": "",
"zh_TW": ""
}
@@ -4867,7 +4867,7 @@
"sv_SE": "Matcha systemtid",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"uk_UA": "Синхронізувати з системним годинником",
"zh_CN": "与系统时间同步",
"zh_TW": ""
}
@@ -6922,6 +6922,31 @@
"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",
"Translations": {
@@ -7222,6 +7247,81 @@
"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",
"Translations": {
@@ -8467,7 +8567,7 @@
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"uk_UA": "LED-підсвітка",
"zh_CN": "",
"zh_TW": ""
}
@@ -8492,7 +8592,7 @@
"sv_SE": "Inaktivera",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"uk_UA": "Вимкнути",
"zh_CN": "关闭",
"zh_TW": ""
}
@@ -8517,7 +8617,7 @@
"sv_SE": "Regnbåge",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"uk_UA": "Веселка",
"zh_CN": "彩虹",
"zh_TW": ""
}
@@ -8542,7 +8642,7 @@
"sv_SE": "Regnbågshastighet",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"uk_UA": "Швидкість зміни кольорів",
"zh_CN": "彩虹滚动速度",
"zh_TW": ""
}
@@ -9167,7 +9267,7 @@
"sv_SE": "",
"th_TH": "",
"tr_TR": "Esc",
"uk_UA": "",
"uk_UA": "Esc",
"zh_CN": "Esc",
"zh_TW": "Esc 鍵"
}
@@ -10867,7 +10967,7 @@
"sv_SE": "Diverse",
"th_TH": "",
"tr_TR": "Diğer",
"uk_UA": "",
"uk_UA": "Інше",
"zh_CN": "截图键",
"zh_TW": "其他按鍵"
}
@@ -11872,6 +11972,31 @@
"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",
"Translations": {
@@ -17692,7 +17817,7 @@
"sv_SE": "Ändra ljudvolym",
"th_TH": "ปรับระดับเสียง",
"tr_TR": "Ses seviyesini değiştirir",
"uk_UA": "Змінити гучність звуку",
"uk_UA": "Регулювання гучності",
"zh_CN": "调节音量",
"zh_TW": "調節音量"
}
@@ -19592,7 +19717,7 @@
"sv_SE": "Alla tangentbord",
"th_TH": "คีย์บอร์ดทั้งหมด",
"tr_TR": "Tüm Klavyeler",
"uk_UA": "Всі клавіатури",
"uk_UA": "Усі клавіатури",
"zh_CN": "所有键盘",
"zh_TW": "所有鍵盤"
}
@@ -19742,7 +19867,7 @@
"sv_SE": "Snabbtangenter för tangentbord",
"th_TH": "ปุ่มลัดของคีย์บอร์ด",
"tr_TR": "Klavye Kısayolları",
"uk_UA": "Гарячі клавіші клавіатури",
"uk_UA": "Гарячі клавіші",
"zh_CN": "快捷键",
"zh_TW": "鍵盤快速鍵"
}
@@ -22467,7 +22592,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.",
"th_TH": "ใช้การลดรอยหยักกับการเรนเดอร์เกม\n\nFXAA จะเบลอภาพส่วนใหญ่ ในขณะที่ SMAA จะพยายามค้นหารอยหยักและปรับให้เรียบ\n\nไม่แนะนำให้ใช้ร่วมกับตัวกรองสเกล FSR\n\nตัวเลือกนี้สามารถเปลี่ยนแปลงได้ในขณะที่เกมกำลังทำงานอยู่โดยคลิก \"นำไปใช้\" ด้านล่าง คุณสามารถย้ายหน้าต่างการตั้งค่าไปด้านข้างและทดลองจนกว่าคุณจะพบรูปลักษณ์ที่คุณต้องการสำหรับเกม\n\nปล่อยไว้ที่ NONE หากไม่แน่ใจ",
"tr_TR": "",
"uk_UA": "Застосовує згладження до рендера гри.\n\nFXAA розмиє більшість зображення, а SMAA спробує знайти нерівні краї та згладити їх.\n\nНе рекомендується використовувати разом з фільтром масштабування FSR.\n\nЦю опцію можна міняти коли гра запущена кліком на \"Застосувати; ви можете відсунути вікно налаштувань і поекспериментувати з видом гри.\n\nЗалиште на \"Немає\", якщо не впевнені.",
"uk_UA": "Застосовує згладження до рендера гри.\n\nFXAA розмиє більшість зображення, а 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_TW": "對遊戲繪製進行反鋸齒處理。\n\nFXAA 會模糊大部分圖像,而 SMAA 則會嘗試找出鋸齒邊緣並將其平滑化。\n\n不建議與 FSR 縮放濾鏡一起使用。\n\n此選項可在遊戲執行時透過點選下方的「套用」進行變更您只需將設定視窗移到一旁然後進行試驗直到找到您喜歡的遊戲效果。\n\n如果不確定請選擇無狀態。"
}
@@ -22542,7 +22667,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.",
"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.",
"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_TW": "選擇使用解析度縮放時套用的縮放過濾器。\n\n雙線性 (Bilinear) 濾鏡適用於 3D 遊戲,是一個安全的預設選項。\n\n建議像素美術遊戲使用近鄰性 (Nearest) 濾鏡。\n\nFSR 1.0 只是一個銳化濾鏡,不建議與 FXAA 或 SMAA 一起使用。\n\n此選項可在遊戲執行時透過點選下方的「套用」進行變更您只需將設定視窗移到一旁然後進行試驗直到找到您喜歡的遊戲效果。\n\n如果不確定請保持雙線性 (Bilinear) 狀態。"
}
@@ -23867,7 +23992,7 @@
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"uk_UA": "Список сумісності — {0} ігор",
"zh_CN": "",
"zh_TW": ""
}
@@ -23942,7 +24067,7 @@
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"uk_UA": "Шукати серед {0} перевірених ігор...",
"zh_CN": "",
"zh_TW": ""
}
@@ -24017,7 +24142,7 @@
"sv_SE": "Spelbart",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Оптимально",
"uk_UA": "Справна",
"zh_CN": "可游玩",
"zh_TW": "可暢順遊玩"
}
@@ -24267,7 +24392,7 @@
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"uk_UA": "Власна конфігурація",
"zh_CN": "",
"zh_TW": ""
}
@@ -24292,7 +24417,7 @@
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"uk_UA": "(Глобальні)",
"zh_CN": "",
"zh_TW": ""
}
@@ -24373,4 +24498,4 @@
}
}
]
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -51,6 +51,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
private int _device;
private object _configViewModel;
[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 static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
@@ -88,13 +90,40 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public bool IsKeyboard => !IsController;
public bool IsRight { get; set; }
public bool IsLeft { get; set; }
public string RevertDeviceId { get; set; }
public bool HasLed => SelectedGamepad.Features.HasFlag(GamepadFeaturesFlag.Led);
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 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
{
get => _configViewModel;
@@ -120,14 +149,14 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
set
{
if (IsModified)
{
{
_playerIdChoose = value;
return;
}
IsModified = false;
_playerId = value;
_isChangeTrackingActive = false;
if (!Enum.IsDefined<PlayerIndex>(_playerId))
{
@@ -135,13 +164,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
}
_isLoaded = false;
LoadConfiguration();
LoadDevice();
LoadProfiles();
RevertDeviceId = Devices[Device].Id;
_isLoaded = true;
_isChangeTrackingActive = true;
OnPropertyChanged();
}
}
@@ -151,6 +180,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
get => _controller;
set
{
MarkAsChanged();
_controller = value;
if (_controller == -1)
@@ -185,11 +216,11 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
IsLeft = false;
break;
}
LoadInputDriver();
LoadProfiles();
}
OnPropertyChanged();
NotifyChanges();
}
@@ -229,6 +260,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
get => _device;
set
{
MarkAsChanged();
_device = value < 0 ? 0 : value;
if (_device >= Devices.Count)
@@ -248,11 +281,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
}
}
FindPairedDeviceInConfigFile();
OnPropertyChanged();
NotifyChanges();
}
}
public InputConfig Config { get; set; }
public InputViewModel(UserControl owner) : this()
@@ -274,6 +309,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
PlayerId = PlayerIndex.Player1;
}
_isChangeTrackingActive = true;
}
public InputViewModel()
@@ -311,8 +348,50 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{
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()
{
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()
@@ -558,12 +657,14 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
if (activeDevice.Type == DeviceType.Keyboard)
{
string id = activeDevice.Id;
string name = activeDevice.Name;
config = new StandardKeyboardInputConfig
{
Version = InputConfig.CurrentVersion,
Backend = InputBackendType.WindowKeyboard,
Id = id,
Name = name,
ControllerType = ControllerType.ProController,
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");
string id = activeDevice.Id.Split(" ")[0];
string name = activeDevice.Name;
config = new StandardControllerInputConfig
{
Version = InputConfig.CurrentVersion,
Backend = InputBackendType.GamepadSDL2,
Id = id,
Name = name,
ControllerType = ControllerType.ProController,
DeadzoneLeft = 0.1f,
DeadzoneRight = 0.1f,
@@ -688,6 +791,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
return config;
}
public void LoadProfileButton()
{
LoadProfile();
IsModified = true;
}
public async void LoadProfile()
{
if (Device == 0)
@@ -739,9 +848,11 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{
_isLoaded = false;
config.Id = Config.Id; // Set current device id instead of changing device(independent profiles)
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;
@@ -751,54 +862,58 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public async void SaveProfile()
{
if (Device == 0)
{
return;
}
if (Device == 0)
{
return;
}
if (ConfigViewModel == null)
{
return;
}
if (ProfileName == LocaleManager.Instance[LocaleKeys.ControllerSettingsProfileDefault])
{
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogProfileDefaultProfileOverwriteErrorMessage]);
if (ConfigViewModel == null)
{
return;
}
return;
}
else
{
bool validFileName = ProfileName.IndexOfAny(Path.GetInvalidFileNameChars()) == -1;
if (ProfileName == LocaleManager.Instance[LocaleKeys.ControllerSettingsProfileDefault])
{
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogProfileDefaultProfileOverwriteErrorMessage]);
if (validFileName)
{
string path = Path.Combine(GetProfileBasePath(), ProfileName + ".json");
return;
}
else
{
bool validFileName = ProfileName.IndexOfAny(Path.GetInvalidFileNameChars()) == -1;
InputConfig config = null;
if (validFileName)
{
string path = Path.Combine(GetProfileBasePath(), ProfileName + ".json");
if (IsKeyboard)
{
config = (ConfigViewModel as KeyboardInputViewModel).Config.GetConfig();
}
else if (IsController)
{
config = (ConfigViewModel as ControllerInputViewModel).Config.GetConfig();
}
InputConfig config = null;
config.ControllerType = Controllers[_controller].Type;
if (IsKeyboard)
{
config = (ConfigViewModel as KeyboardInputViewModel).Config.GetConfig();
}
else if (IsController)
{
config = (ConfigViewModel as ControllerInputViewModel).Config.GetConfig();
}
string jsonString = JsonHelper.Serialize(config, _serializerContext.InputConfig);
config.ControllerType = Controllers[_controller].Type;
await File.WriteAllTextAsync(path, jsonString);
string jsonString = JsonHelper.Serialize(config, _serializerContext.InputConfig);
LoadProfiles();
await File.WriteAllTextAsync(path, jsonString);
LoadProfiles();
}
else
{
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogProfileInvalidProfileNameErrorMessage]);
}
}
ProfileChoose = ProfileName; // Show new profile
}
else
{
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogProfileInvalidProfileNameErrorMessage]);
}
}
}
public async void RemoveProfile()
@@ -825,14 +940,33 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
}
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()
{
if (!IsModified)
{
return; //If the input settings were not touched, then do nothing
}
IsModified = false;
List<InputConfig> newConfig = [];
RevertDeviceId = Devices[Device].Id; // Remember selected device after saving
List <InputConfig> newConfig = [];
newConfig.AddRange(ConfigurationState.Instance.Hid.InputConfig.Value);
@@ -862,6 +996,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
: (ConfigViewModel as ControllerInputViewModel).Config.GetConfig();
config.ControllerType = Controllers[_controller].Type;
config.PlayerIndex = _playerId;
config.Name = device.Name;
int i = newConfig.FindIndex(x => x.PlayerIndex == PlayerId);
if (i == -1)

View File

@@ -64,8 +64,9 @@ namespace Ryujinx.Ava.UI.Views.Input
};
if (!float.IsNaN(_changeSlider) && _changeSlider != (float)check.Value)
{
(DataContext as ControllerInputViewModel)!.ParentModel.IsModified = true;
{
FlagInputConfigChanged();
_changeSlider = (float)check.Value;
}
}
@@ -75,7 +76,8 @@ namespace Ryujinx.Ava.UI.Views.Input
{
if (sender is CheckBox { IsPointerOver: true })
{
(DataContext as ControllerInputViewModel)!.ParentModel.IsModified = true;
FlagInputConfigChanged();
_currentAssigner?.Cancel();
_currentAssigner = null;
}
@@ -102,7 +104,7 @@ namespace Ryujinx.Ava.UI.Views.Input
this.Focus(NavigationMethod.Pointer);
PointerPressed += MouseClick;
ControllerInputViewModel viewModel = (DataContext as ControllerInputViewModel);
IKeyboard keyboard =
@@ -115,7 +117,7 @@ namespace Ryujinx.Ava.UI.Views.Input
if (e.ButtonValue.HasValue)
{
Button buttonValue = e.ButtonValue.Value;
viewModel.ParentModel.IsModified = true;
FlagInputConfigChanged();
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)
{
bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
@@ -232,7 +239,6 @@ namespace Ryujinx.Ava.UI.Views.Input
{
gamepad?.ClearLed();
}
_currentAssigner?.Cancel();
_currentAssigner = null;
}

View File

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

View File

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

View File

@@ -9,6 +9,8 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels.Input;
using Ryujinx.Input;
using Ryujinx.Input.Assigner;
using System.Collections.Generic;
using System;
using Button = Ryujinx.Input.Button;
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 shouldRemoveBinding = e.GetCurrentPoint(this).Properties.IsRightButtonPressed;
if (shouldRemoveBinding)
{
DeleteBind();
}
_currentAssigner?.Cancel(shouldUnbind);
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)
{
base.OnDetachedFromVisualTree(e);

View File

@@ -10,6 +10,8 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Input;
using Ryujinx.Input.Assigner;
using System.Collections.Generic;
using System;
using Button = Ryujinx.Input.Button;
using Key = Ryujinx.Common.Configuration.Hid.Key;
@@ -48,12 +50,47 @@ 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 }
};
if (buttonActions.TryGetValue(_currentAssigner.ToggledButton.Name, out Action action))
{
action();
}
}
}
private void Button_IsCheckedChanged(object sender, RoutedEventArgs e)
{
if (sender is ToggleButton button)