Compare commits
15 Commits
Canary-1.2
...
2901174ef5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2901174ef5 | ||
|
|
9dc36646c1 | ||
|
|
e104ee6be3 | ||
|
|
e65d1ec6c9 | ||
|
|
534f92506b | ||
|
|
10d20c1ae3 | ||
|
|
e294a79975 | ||
|
|
ec06a86899 | ||
|
|
8eea75a6e8 | ||
|
|
57fbcc7aed | ||
|
|
d1c15f3562 | ||
|
|
0423fad7ff | ||
|
|
1951fe0077 | ||
|
|
7fd5a63a5d | ||
|
|
a0594e8169 |
@@ -97,7 +97,7 @@ If you are planning to contribute or just want to learn more about this project
|
||||
|
||||
- **Input**
|
||||
|
||||
We currently have support for keyboard, mouse, touch input, JoyCon input support, and nearly all controllers.
|
||||
We currently have support for keyboard, mouse, touch input, Joy-Con input support, and nearly all controllers.
|
||||
Motion controls are natively supported in most cases; for dual-JoyCon motion support, DS4Windows or BetterJoy are currently required.
|
||||
In all scenarios, you can set up everything inside the input configuration menu.
|
||||
|
||||
|
||||
@@ -71,16 +71,24 @@ namespace Ryujinx.HLE.Loaders.Mods
|
||||
int patchOffset = (int)offset;
|
||||
int patchSize = patch.Length;
|
||||
|
||||
if (patchOffset < protectedOffset || patchOffset > memory.Length)
|
||||
if (patchOffset < protectedOffset)
|
||||
{
|
||||
continue; // Add warning?
|
||||
Logger.Warning?.Print(LogClass.ModLoader, $"Attempted to patch protected memory ({patchOffset:x} is within protected boundary of {protectedOffset:x}).");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (patchOffset > memory.Length)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.ModLoader, $"Attempted to patch out of bounds memory (offset {patchOffset} ({patchOffset:x}) exceeds memory buffer length {memory.Length}).");
|
||||
continue;
|
||||
}
|
||||
|
||||
patchOffset -= protectedOffset;
|
||||
|
||||
if (patchOffset + patchSize > memory.Length)
|
||||
{
|
||||
patchSize = memory.Length - patchOffset; // Add warning?
|
||||
Logger.Warning?.Print(LogClass.ModLoader, $"Patch offset ({patchOffset:x}) + size ({patchSize}) is greater than the size of the memory buffer ({memory.Length}). Attempting to fix this...");
|
||||
patchSize = memory.Length - patchOffset;
|
||||
}
|
||||
|
||||
Logger.Info?.Print(LogClass.ModLoader, $"Patching address offset {patchOffset:x} <= {BitConverter.ToString(patch).Replace('-', ' ')} len={patchSize}");
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
<TextBlock
|
||||
Classes="globalConfigMarker"/>
|
||||
</StackPanel>
|
||||
|
||||
</Border>
|
||||
</Design.PreviewWith>
|
||||
<Style Selector="DropDownButton">
|
||||
|
||||
@@ -464,7 +464,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Abrir Pasta de Capturas de Tela",
|
||||
"ru_RU": "Открыть папку со скриншотами",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Öppna skärmbildsmappen",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Відкрити теку скріншотів",
|
||||
@@ -1564,7 +1564,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Desenvolvido por {0}",
|
||||
"ru_RU": "Разработана {0}",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Utvecklat av {0}",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Розроблено: {0}",
|
||||
@@ -1864,7 +1864,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Compatibilidade:",
|
||||
"ru_RU": "Совместимость:",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Kompatibilitet:",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Сумісність:",
|
||||
@@ -1889,7 +1889,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "ID do Título:",
|
||||
"ru_RU": "ID приложения",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Titel-id:",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "ID гри:",
|
||||
@@ -1914,7 +1914,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Jogos Hospedados: {0}",
|
||||
"ru_RU": "Запущенно игр: {0}",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Värdskap för spel: {0}",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Розміщені ігри: {0}",
|
||||
@@ -1939,7 +1939,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Jogadores Online: {0}",
|
||||
"ru_RU": "Игроков онлайн: {0}",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Online-spelare: {0}",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Гравців онлайн: {0}",
|
||||
@@ -2289,7 +2289,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Limpar Cache PPTC",
|
||||
"ru_RU": "Очистить кэш PPTC",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Rensa PPTC-cache",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Очистити кеш PPTC",
|
||||
@@ -2314,7 +2314,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Apaga os arquivos de cache PPTC do aplicativo",
|
||||
"ru_RU": "Удаляет все файлы кэша PPTC для приложения",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Tar bort alla PPTC-cachefiler för applikationen",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Видаляє всі файли кешу PPTC для застосунку",
|
||||
@@ -2763,7 +2763,7 @@
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"ru_RU": "Создать пользовательскую конфигурацию",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
@@ -2788,7 +2788,7 @@
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"ru_RU": "Изменить пользовательскую конфигурацию",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
@@ -2863,7 +2863,7 @@
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"ru_RU": "Отредактировать существующую независимую конфигурацию для выбранной игры.",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
@@ -2889,7 +2889,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Mostrar Dados de Compatibilidade",
|
||||
"ru_RU": "Показать записи о совместимости",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Visa kompatibilitetspost",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Iнформація про сумісність",
|
||||
@@ -2914,7 +2914,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Exibe o jogo selecionado na Lista de Compatibilidade, que normalmente pode ser acessada pelo menu Ajuda.",
|
||||
"ru_RU": "Отобразить выбранную игру в списке совместимости, доступ к которому вы обычно можете получить через меню Справки.",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Visa valt spel i kompatibilitetslistan som du normalt sett kan komma åt via hjälpmenyn.",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Показати цю гру в Списку Сумісності. Список сумісності також можна зайти в меню Довідки.",
|
||||
@@ -2939,7 +2939,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Mostrar Informações do Jogo",
|
||||
"ru_RU": "Показать информацию об игре",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Visa spelinformation",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Інформація про гру",
|
||||
@@ -2964,7 +2964,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Exibe estatísticas e detalhes sobre o jogo selecionado.",
|
||||
"ru_RU": "Показывать статистику и подробную информацию о выбранной игре.",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Visa statistik och detaljer om det aktuella spelet.",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Показати статистику та деталі обраної гри.",
|
||||
@@ -3514,7 +3514,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Verificar Atualizações:",
|
||||
"ru_RU": "Проверка наличия обновлений",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Leta efter uppdateringar:",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Перевірка оновлень:",
|
||||
@@ -3539,7 +3539,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Desligado",
|
||||
"ru_RU": "Отключить",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Av",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Вимкнути",
|
||||
@@ -3564,7 +3564,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Ao Abrir",
|
||||
"ru_RU": "При запуске",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Fråga",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Запитувати щоразу",
|
||||
@@ -3589,7 +3589,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "2° Plano",
|
||||
"ru_RU": "В фоне",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Bakgrund",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Оновлювати в фоні",
|
||||
@@ -3614,7 +3614,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Ao Perder o Foco:",
|
||||
"ru_RU": "При выходе эмулятора из фокуса",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "När emulatorn tappar fokus:",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "При втраті фокуса емулятором:",
|
||||
@@ -3639,7 +3639,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Não Fazer Nada",
|
||||
"ru_RU": "Ничего не делать",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Gör ingenting",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Нічого не робити",
|
||||
@@ -3664,7 +3664,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Bloquear Controles",
|
||||
"ru_RU": "Блокировать управление",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Blockera inmatning",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Блокувати введення",
|
||||
@@ -3689,7 +3689,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Ficar Mudo",
|
||||
"ru_RU": "Отключить звук",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Stäng av ljudet",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Вимкнути звук",
|
||||
@@ -3714,7 +3714,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Bloquear Controles & Ficar Mudo",
|
||||
"ru_RU": "Блокировать управление и отключить звук",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Blockera inmatningar och stäng av ljudet",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Блокувати введення та Вимкнути звук",
|
||||
@@ -3739,7 +3739,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Pausar a Emulação",
|
||||
"ru_RU": "Поставить паузу",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Pausa emuleringen",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Поставити на паузу",
|
||||
@@ -3814,7 +3814,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Desativar Controles Quando Estiver Fora de Foco",
|
||||
"ru_RU": "Отключает управление при выходе из фокуса",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Inaktivera inmatning när fokus tappas",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
@@ -4839,7 +4839,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Sincronizar com o Sistema PC",
|
||||
"ru_RU": "Соответствовать времени в системе",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Matcha systemtid",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
@@ -5013,7 +5013,7 @@
|
||||
"no_NO": "Lyd Inn/Ut",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"ru_RU": "Выход/Вход звука",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
@@ -5264,7 +5264,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Ignorar Applet do Controlador",
|
||||
"ru_RU": "Игнорировать апплет контроллера",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Ignorera kontroller-applet",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Ігнорувати Аплет Контролера",
|
||||
@@ -6114,7 +6114,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Habilitar Logs da IU",
|
||||
"ru_RU": "Включить журнал интерфейса",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Aktivera gränssnittsloggar",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Увімкнути журнали інтерфейсу",
|
||||
@@ -6514,7 +6514,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Redefinir Configurações",
|
||||
"ru_RU": "Сбросить настройки",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Nollställ inställningar",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Скинути налаштування",
|
||||
@@ -6539,7 +6539,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Quero redefinir minhas configurações.",
|
||||
"ru_RU": "Я хочу сбросить свои настройки.",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Jag vill nollställa mina inställningar.",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Я хочу скинути налаштування.",
|
||||
@@ -6563,7 +6563,7 @@
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"ru_RU": "Ок",
|
||||
"sv_SE": "Ok",
|
||||
"th_TH": "ตกลง",
|
||||
"tr_TR": "Tamam",
|
||||
@@ -7013,7 +7013,7 @@
|
||||
"no_NO": "",
|
||||
"pl_PL": "Pro Kontroler",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"ru_RU": "Pro контроллер",
|
||||
"sv_SE": "",
|
||||
"th_TH": "โปรคอนโทรลเลอร์",
|
||||
"tr_TR": "Profesyonel Kumanda",
|
||||
@@ -7197,6 +7197,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": {
|
||||
@@ -8514,7 +8589,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Velocidade do Arco-íris",
|
||||
"ru_RU": "Скорость переливания",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Regnbågshastighet",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
@@ -11847,6 +11922,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": {
|
||||
@@ -13814,7 +13914,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Você está prestes a limpar todos os dados PPTC de:\n\n{0}\n\nTem certeza de que deseja continuar?",
|
||||
"ru_RU": "Вы собираетесь удалить все данные PPTC из:\n\n{0}\n\nВы уверены, что хотите продолжить?",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Du är på väg att ta bort allt PPTC-data från:\n\n{0}\n\nÄr du säker på att du vill fortsätta?",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Ви збираєтесь видалити всі дані PPTC з:\n\n{0}\n\nБажаєте продовжити цю операцію?",
|
||||
@@ -16664,7 +16764,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "A caixa de diálogo do Applet do controlador não aparecerá se o controle for desconectado enquanto um aplicativo estiver em execução.\n\nDeixe a opção DESLIGADO se não tiver certeza.",
|
||||
"ru_RU": "Диалоговое окно апплета контроллера не будет отображаться, если геймпад отключен во время работы приложения.\n\nОставьте выключенным, если не уверены.",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Handkontroller-appleten kommer inte att visas om gamepaden är frånkopplad under tiden en applikation körs.\n\nLämna AV om du är osäker.",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Діалогове вікно Аплету Контролера не з'явиться, якщо геймпад було відключено під час роботи програми.\n\nЗалиште вимкненим якщо не впевнені.",
|
||||
@@ -17139,7 +17239,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Imprime mensagens de log do Avalonia (UI) no console.",
|
||||
"ru_RU": "Выводит сообщения журнала Avalonia (интерфейс) в консоли.",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Skriver ut loggmeddelanden från Avalonia (användargränssnittet) i konsollen.",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Виводити повідомлення журналу Avalonia (UI) в консоль",
|
||||
@@ -17339,7 +17439,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Abre a pasta de capturas de tela do Ryujinx",
|
||||
"ru_RU": "Открывает папку скриншотов Ryujinx",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Öppna Ryujinx skärmbildsmapp",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Відкрити теку куди зберігаються скріншоти Ryujinx",
|
||||
@@ -18089,7 +18189,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Atualização Disponível!",
|
||||
"ru_RU": "Доступно обновление!",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Uppdatering finns tillgänglig!",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Доступне оновлення!",
|
||||
@@ -20013,7 +20113,7 @@
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"ru_RU": "Амибо",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
@@ -24064,7 +24164,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Inicializa e roda sem travamentos ou bugs de GPU de qualquer tipo, e em uma velocidade rápida o suficiente para ser aproveitado em um PC comum.",
|
||||
"ru_RU": "Запускается и работает без любого рода сбоев или графисечких ошибок и на скорости, достаточной для работы на обычном ПК.",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Startar upp och spelas utan några krascher eller GPU-fel av några slag och med en hastighet som är snabb nog för bra upplevelse på en genomsnittlig PC.",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Запускається та оптимально працює (без збоїв або графічних багів) на середньостатистичному комп'ютері.",
|
||||
@@ -24089,7 +24189,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Inicializa e entra no jogo, mas sofre de um ou mais dos seguintes: travamentos, deadlocks, bugs de GPU, áudio ruim que distrai ou é simplesmente muito lento. O jogo ainda pode ser jogado até o fim, mas não da forma como foi criado para ser jogado.",
|
||||
"ru_RU": "Запускается и работает, но возникает одна или несколько из следующих проблем: сбои, взаимоблокировки, ошибки GPU, отвлекающие звуки или просто слишком медленная работа. Возможно, игру всё же удастся пройти до конца, но не так, как она задумана.",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Startar och går in i spelet men lider av ett eller flera av följande: kraschar, deadlocks, GPU-buggar, distraherande dåligt ljud eller är helt enkelt för långsamt. Spelet kan fortfarande spelas hela vägen igenom, men inte så som spelet är avsett att spelas.",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Запускається, але в грі на вас чекатимуть одна або декілька наступних проблем: збої, зависання, графічні баги, спотворений звук або ж гра загалом працюватиме надто повільно. Можливо, її все ще можна пройти, але досвід буде не найкращим.",
|
||||
@@ -24114,7 +24214,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Inicializa e passa da tela de título, mas não entra no jogo principal.",
|
||||
"ru_RU": "Загружается титульный экран и можно перейти дальше, но сама игра не работает.",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Startar upp och går förbi titelskärmen men tar sig inte in i huvudspelet.",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Запускається та проходить початковий екран, але пограти не вийде.",
|
||||
@@ -24139,7 +24239,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Inizializa, mas não passa da tela de título.",
|
||||
"ru_RU": "Загружается, но не проходит дальше титульного экрана.",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Startar upp men tar sig inte förbi titelskärmen.",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Запускається, але не відображає навіть початкового екрану.",
|
||||
@@ -24164,7 +24264,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Não inicializa ou não mostra sinais de atividade.",
|
||||
"ru_RU": "Не запускается или не подаёт признаков жизни.",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Startar inte upp eller visar någon form av aktivitet.",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Взагалі не запускається.",
|
||||
@@ -24264,7 +24364,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Imagem da Presença do Discord",
|
||||
"ru_RU": "Изображение для статуса активности",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Bild för Rich Presence",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Зображення картки активності Discord",
|
||||
@@ -24289,7 +24389,7 @@
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Presença Dinâmica do Discord",
|
||||
"ru_RU": "Динамический статус активности",
|
||||
"sv_SE": "",
|
||||
"sv_SE": "Dynamisk Rich Presence",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Динамічна картка активності Discord",
|
||||
|
||||
@@ -158,16 +158,6 @@ namespace Ryujinx.Ava
|
||||
}
|
||||
}
|
||||
|
||||
public static bool FindGameConfig(string gameDir)
|
||||
{
|
||||
if (File.Exists(gameDir))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string GetDirGameUserConfig(string gameId, bool rememberGlobalDir = false, bool changeFolderForGame = false)
|
||||
{
|
||||
if (string.IsNullOrEmpty(gameId))
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace Ryujinx.Ava.UI.Applet
|
||||
_parent.SettingsWindow =
|
||||
new SettingsWindow(_parent.VirtualFileSystem, _parent.ContentManager);
|
||||
|
||||
await _parent.SettingsWindow.ShowDialog(window);
|
||||
await StyleableAppWindow.ShowAsync(_parent.SettingsWindow, window);
|
||||
|
||||
_parent.SettingsWindow = null;
|
||||
|
||||
|
||||
@@ -91,11 +91,14 @@ namespace Ryujinx.Ava.UI.Controls
|
||||
public async void OpenCheatManager_Click(object sender, RoutedEventArgs args)
|
||||
{
|
||||
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||
await new CheatWindow(
|
||||
viewModel.VirtualFileSystem,
|
||||
viewModel.SelectedApplication.IdString,
|
||||
viewModel.SelectedApplication.Name,
|
||||
viewModel.SelectedApplication.Path).ShowDialog((Window)viewModel.TopLevel);
|
||||
await StyleableAppWindow.ShowAsync(
|
||||
new CheatWindow(
|
||||
viewModel.VirtualFileSystem,
|
||||
viewModel.SelectedApplication.IdString,
|
||||
viewModel.SelectedApplication.Name,
|
||||
viewModel.SelectedApplication.Path
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public void OpenModsDirectory_Click(object sender, RoutedEventArgs args)
|
||||
@@ -391,9 +394,9 @@ namespace Ryujinx.Ava.UI.Controls
|
||||
{
|
||||
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||
{
|
||||
await new GameSpecificSettingsWindow(viewModel).ShowDialog((Window)viewModel.TopLevel);
|
||||
await StyleableAppWindow.ShowAsync(new GameSpecificSettingsWindow(viewModel));
|
||||
|
||||
//just checking for file presence
|
||||
// just checking for file presence
|
||||
viewModel.SelectedApplication.HasIndependentConfiguration = File.Exists(Program.GetDirGameUserConfig(viewModel.SelectedApplication.IdString,false,false));
|
||||
|
||||
viewModel.RefreshView();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Threading;
|
||||
@@ -384,6 +385,10 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||
Position = parent.PointToScreen(new Point()),
|
||||
ShowInTaskbar = false,
|
||||
};
|
||||
|
||||
#if DEBUG
|
||||
_contentDialogOverlayWindow.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Control));
|
||||
#endif
|
||||
|
||||
parent.PositionChanged += OverlayOnPositionChanged;
|
||||
|
||||
|
||||
@@ -68,18 +68,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()
|
||||
|
||||
@@ -91,7 +91,19 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
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 PlayerIndex PlayerIdChoose
|
||||
@@ -106,14 +118,14 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
set
|
||||
{
|
||||
if (IsModified)
|
||||
{
|
||||
|
||||
{
|
||||
_playerIdChoose = value;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
IsModified = false;
|
||||
_playerId = value;
|
||||
_isChangeTrackingActive = false;
|
||||
|
||||
if (!Enum.IsDefined<PlayerIndex>(_playerId))
|
||||
{
|
||||
@@ -121,13 +133,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
|
||||
}
|
||||
_isLoaded = false;
|
||||
|
||||
LoadConfiguration();
|
||||
LoadDevice();
|
||||
LoadProfiles();
|
||||
|
||||
_isLoaded = true;
|
||||
|
||||
_isChangeTrackingActive = true;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
@@ -171,11 +182,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
IsLeft = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
LoadInputDriver();
|
||||
LoadProfiles();
|
||||
SetChangeTrackingActive();
|
||||
}
|
||||
|
||||
|
||||
OnPropertyChanged();
|
||||
NotifyChanges();
|
||||
}
|
||||
@@ -233,14 +245,28 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
LoadConfiguration(LoadDefaultConfiguration());
|
||||
}
|
||||
}
|
||||
|
||||
FindPairedDevice();
|
||||
SetChangeTrackingActive();
|
||||
OnPropertyChanged();
|
||||
NotifyChanges();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public InputConfig Config { get; set; }
|
||||
|
||||
public bool _notificationView;
|
||||
|
||||
public bool NotificationView
|
||||
{
|
||||
get => _notificationView;
|
||||
set
|
||||
{
|
||||
_notificationView = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public InputViewModel(UserControl owner) : this()
|
||||
{
|
||||
if (Program.PreviewerDetached)
|
||||
@@ -260,6 +286,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
|
||||
PlayerId = PlayerIndex.Player1;
|
||||
}
|
||||
|
||||
_isChangeTrackingActive = true;
|
||||
}
|
||||
|
||||
public InputViewModel()
|
||||
@@ -296,8 +324,54 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
{
|
||||
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig));
|
||||
}
|
||||
|
||||
FindPairedDevice();
|
||||
}
|
||||
|
||||
private void FindPairedDevice()
|
||||
{
|
||||
// This feature allows you to display a notification
|
||||
// if a configuration is found, but the gamepad is not connected.
|
||||
if (Config != null)
|
||||
{
|
||||
(DeviceType Type, string Id, string Name) activeDevice = Devices.FirstOrDefault(d => d.Id == Config.Id);
|
||||
|
||||
if (activeDevice.Id != Config.Id)
|
||||
{
|
||||
// display notification when input device is turned off, and
|
||||
// if device and configuration do not match (different controllers)
|
||||
NotificationView = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
NotificationView = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NotificationView = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetChangeTrackingActive()
|
||||
{
|
||||
|
||||
if (_isChangeTrackingActive)
|
||||
{
|
||||
IsModified = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void DisableDeviceForSaving()
|
||||
{
|
||||
// "Disabled" mode is available after unbinding the device
|
||||
// NOTE: the IsModified flag to be able to apply the settings.
|
||||
IsModified = true;
|
||||
NotificationView = false;
|
||||
}
|
||||
|
||||
|
||||
public void LoadDevice()
|
||||
{
|
||||
if (Config == null || Config.Backend == InputBackendType.Invalid)
|
||||
@@ -363,14 +437,35 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleOnGamepadDisconnected(string id)
|
||||
private async void HandleOnGamepadDisconnected(string id)
|
||||
{
|
||||
Dispatcher.UIThread.Post(LoadDevices);
|
||||
_isChangeTrackingActive = false;
|
||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
LoadDevices();
|
||||
FindPairedDevice();
|
||||
_isChangeTrackingActive = true;
|
||||
return System.Threading.Tasks.Task.CompletedTask;
|
||||
});
|
||||
}
|
||||
|
||||
private void HandleOnGamepadConnected(string id)
|
||||
private async void HandleOnGamepadConnected(string id)
|
||||
{
|
||||
Dispatcher.UIThread.Post(LoadDevices);
|
||||
_isChangeTrackingActive = false;
|
||||
|
||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
LoadDevices();
|
||||
|
||||
if (Config != null)
|
||||
{
|
||||
// Load configuration after connection if it is in the configuration file
|
||||
IsModified = true;
|
||||
LoadSavedConfiguration();
|
||||
}
|
||||
|
||||
_isChangeTrackingActive = true;
|
||||
});
|
||||
}
|
||||
|
||||
private string GetCurrentGamepadId()
|
||||
@@ -813,8 +908,25 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadSavedConfiguration()
|
||||
{
|
||||
if (IsModified) // Fixes random gamepad appearance in "disabled" option
|
||||
{
|
||||
LoadDevice();
|
||||
LoadConfiguration();
|
||||
IsModified = false;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
|
||||
if (!IsModified)
|
||||
{
|
||||
return; //If the input settings were not touched, then do nothing
|
||||
}
|
||||
|
||||
IsModified = false;
|
||||
|
||||
List<InputConfig> newConfig = [];
|
||||
|
||||
@@ -1747,7 +1747,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
string titleId = AppHost.Device.Processes.ActiveApplication.ProgramIdText.ToUpper();
|
||||
AmiiboWindow window = new(ShowAll, LastScannedAmiiboId, titleId);
|
||||
|
||||
await window.ShowDialog(Window);
|
||||
await StyleableAppWindow.ShowAsync(window);
|
||||
|
||||
if (window.IsScanned)
|
||||
{
|
||||
|
||||
@@ -63,8 +63,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;
|
||||
}
|
||||
}
|
||||
@@ -74,7 +75,8 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||
{
|
||||
if (sender is CheckBox { IsPointerOver: true })
|
||||
{
|
||||
(DataContext as ControllerInputViewModel)!.ParentModel.IsModified = true;
|
||||
FlagInputConfigChanged();
|
||||
|
||||
_currentAssigner?.Cancel();
|
||||
_currentAssigner = null;
|
||||
}
|
||||
@@ -101,7 +103,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||
this.Focus(NavigationMethod.Pointer);
|
||||
|
||||
PointerPressed += MouseClick;
|
||||
|
||||
|
||||
ControllerInputViewModel viewModel = (DataContext as ControllerInputViewModel);
|
||||
|
||||
IKeyboard keyboard =
|
||||
@@ -114,7 +116,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||
if (e.ButtonValue.HasValue)
|
||||
{
|
||||
Button buttonValue = e.ButtonValue.Value;
|
||||
viewModel.ParentModel.IsModified = true;
|
||||
FlagInputConfigChanged();
|
||||
|
||||
switch (button.Name)
|
||||
{
|
||||
@@ -208,6 +210,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;
|
||||
@@ -239,7 +246,6 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||
{
|
||||
gamepad?.ClearLed();
|
||||
}
|
||||
|
||||
_currentAssigner?.Cancel();
|
||||
_currentAssigner = null;
|
||||
}
|
||||
|
||||
@@ -50,13 +50,21 @@
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
<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"
|
||||
@@ -71,6 +79,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 LoadSavedConfiguration}">
|
||||
<ui:SymbolIcon
|
||||
Symbol="Cancel"
|
||||
FontSize="15"
|
||||
Height="20" />
|
||||
</Button>
|
||||
</Grid>
|
||||
<!-- Profile Selection -->
|
||||
<Grid
|
||||
@@ -174,7 +194,7 @@
|
||||
MinWidth="0"
|
||||
Margin="5,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
Command="{Binding LoadDevices}">
|
||||
Command="{Binding LoadDevice}">
|
||||
<ui:SymbolIcon
|
||||
Symbol="Refresh"
|
||||
FontSize="15"
|
||||
@@ -211,15 +231,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 NotificationView}">
|
||||
<ContentControl.Content>
|
||||
<StackPanel>
|
||||
<TextBlock
|
||||
Margin="5,20,0,0"
|
||||
Text="{ext:Locale ControllerSettingsDisableDeviceForSaving}" />
|
||||
|
||||
<Button
|
||||
MinWidth="0"
|
||||
Width="90"
|
||||
Height="27"
|
||||
Margin="5,10,0,0"
|
||||
VerticalAlignment="Center"
|
||||
Command="{Binding DisableDeviceForSaving}">
|
||||
<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>
|
||||
|
||||
@@ -62,14 +62,15 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ViewModel.PlayerId = ViewModel.PlayerIdChoose;
|
||||
|
||||
ViewModel.IsModified = false;
|
||||
ViewModel.PlayerId = ViewModel.PlayerIdChoose;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ViewModel.Dispose();
|
||||
|
||||
@@ -8,6 +8,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;
|
||||
|
||||
@@ -73,7 +75,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||
if (e.ButtonValue.HasValue)
|
||||
{
|
||||
Button buttonValue = e.ButtonValue.Value;
|
||||
viewModel.ParentModel.IsModified = true;
|
||||
FlagInputConfigChanged();
|
||||
|
||||
switch (button.Name)
|
||||
{
|
||||
@@ -184,15 +186,74 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||
}
|
||||
}
|
||||
|
||||
private void FlagInputConfigChanged()
|
||||
{
|
||||
(DataContext as KeyboardInputViewModel)!.ParentModel.IsModified = true;
|
||||
}
|
||||
|
||||
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 KeyboardInputViewModel viewModel)
|
||||
return;
|
||||
|
||||
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();
|
||||
FlagInputConfigChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnDetachedFromVisualTree(e);
|
||||
|
||||
@@ -19,6 +19,7 @@ using Ryujinx.Common.Utilities;
|
||||
using Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -133,20 +134,20 @@ namespace Ryujinx.Ava.UI.Views.Main
|
||||
|
||||
if (ViewModel.SelectedApplication is null) // Checks if game data exists
|
||||
{
|
||||
await Window.SettingsWindow.ShowDialog(Window);
|
||||
await StyleableAppWindow.ShowAsync(Window.SettingsWindow);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool userConfigExist = Program.FindGameConfig(Program.GetDirGameUserConfig(ViewModel.SelectedApplication.IdString, false, false));
|
||||
bool customConfigExists = File.Exists(Program.GetDirGameUserConfig(ViewModel.SelectedApplication.IdString));
|
||||
|
||||
if (!ViewModel.IsGameRunning || !userConfigExist)
|
||||
if (!ViewModel.IsGameRunning || !customConfigExists)
|
||||
{
|
||||
await Window.SettingsWindow.ShowDialog(Window); // The game is not running, or if the user configuration does not exist
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there is a custom configuration in the folder
|
||||
await new GameSpecificSettingsWindow(ViewModel, userConfigExist).ShowDialog((Window)ViewModel.TopLevel);
|
||||
await StyleableAppWindow.ShowAsync(new GameSpecificSettingsWindow(ViewModel, customConfigExists));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,11 +176,13 @@ namespace Ryujinx.Ava.UI.Views.Main
|
||||
|
||||
string name = ViewModel.AppHost.Device.Processes.ActiveApplication.ApplicationControlProperties.Title[(int)ViewModel.AppHost.Device.System.State.DesiredTitleLanguage].NameString.ToString();
|
||||
|
||||
await new CheatWindow(
|
||||
Window.VirtualFileSystem,
|
||||
ViewModel.AppHost.Device.Processes.ActiveApplication.ProgramIdText,
|
||||
name,
|
||||
ViewModel.SelectedApplication.Path).ShowDialog(Window);
|
||||
await StyleableAppWindow.ShowAsync(
|
||||
new CheatWindow(
|
||||
Window.VirtualFileSystem,
|
||||
ViewModel.AppHost.Device.Processes.ActiveApplication.ProgramIdText,
|
||||
name,
|
||||
ViewModel.SelectedApplication.Path)
|
||||
);
|
||||
|
||||
ViewModel.AppHost.Device.EnableCheats();
|
||||
}
|
||||
|
||||
@@ -8,6 +8,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;
|
||||
|
||||
@@ -46,12 +48,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)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||
xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common"
|
||||
Width="1100"
|
||||
Height="768"
|
||||
Height="910"
|
||||
MinWidth="800"
|
||||
MinHeight="480"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
|
||||
@@ -47,11 +47,6 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
|
||||
InitializeComponent();
|
||||
Load();
|
||||
|
||||
#if DEBUG
|
||||
this.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Alt));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
public void SaveSettings()
|
||||
@@ -65,7 +60,6 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
Pages.Children.Clear();
|
||||
NavPanel.SelectionChanged += NavPanelOnSelectionChanged;
|
||||
NavPanel.SelectedItem = NavPanel.MenuItems.ElementAt(0);
|
||||
|
||||
}
|
||||
|
||||
private void NavPanelOnSelectionChanged(object sender, NavigationViewSelectionChangedEventArgs e)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||
xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common"
|
||||
Width="1100"
|
||||
Height="768"
|
||||
Height="918"
|
||||
MinWidth="800"
|
||||
MinHeight="480"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
@@ -8,7 +6,6 @@ using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.Input;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Key = Avalonia.Input.Key;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Windows
|
||||
{
|
||||
@@ -27,10 +24,6 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
|
||||
InitializeComponent();
|
||||
Load();
|
||||
|
||||
#if DEBUG
|
||||
this.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Alt));
|
||||
#endif
|
||||
}
|
||||
|
||||
public SettingsWindow()
|
||||
|
||||
@@ -1,15 +1,26 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Platform;
|
||||
using FluentAvalonia.UI.Windowing;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Windows
|
||||
{
|
||||
public abstract class StyleableAppWindow : AppWindow
|
||||
{
|
||||
public static async Task ShowAsync(StyleableAppWindow appWindow, Window owner = null)
|
||||
{
|
||||
#if DEBUG
|
||||
appWindow.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Control));
|
||||
#endif
|
||||
await appWindow.ShowDialog(owner ?? RyujinxApp.MainWindow);
|
||||
}
|
||||
|
||||
protected StyleableAppWindow()
|
||||
{
|
||||
WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
@@ -36,6 +47,14 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
|
||||
public abstract class StyleableWindow : Window
|
||||
{
|
||||
public static async Task ShowAsync(StyleableWindow window, Window owner = null)
|
||||
{
|
||||
#if DEBUG
|
||||
window.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Control));
|
||||
#endif
|
||||
await window.ShowDialog(owner ?? RyujinxApp.MainWindow);
|
||||
}
|
||||
|
||||
protected StyleableWindow()
|
||||
{
|
||||
WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
|
||||
Reference in New Issue
Block a user