Compare commits

..

3 Commits

29 changed files with 397 additions and 612 deletions

View File

@@ -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, Joy-Con input support, and nearly all controllers.
We currently have support for keyboard, mouse, touch input, JoyCon 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.

View File

@@ -20,4 +20,42 @@ if command -v gamemoderun > /dev/null 2>&1; then
COMMAND="$COMMAND gamemoderun"
fi
exec $COMMAND "$SCRIPT_DIR/$RYUJINX_BIN" "$@"
# Check if user already has a manual Avalonia scaling override or session type is x11.
if [[ -n "${AVALONIA_GLOBAL_SCALE_FACTOR-}" || "$(echo "$XDG_SESSION_TYPE")" == "x11" ]]; then
echo "Scaling: Performed by environment, skipping." >&2
else
# Query monitor config directly (GNOME), default display only.
if [[ "$(echo "$XDG_CURRENT_DESKTOP")" == "GNOME" && -f ~/.config/monitors.xml ]] then
echo -n 'Scaling: Monitor config located, querying scale...' >&2
SCALING="$(grep '<scale' ~/.config/monitors.xml -m 1 | cut -f2 -d">"|cut -f1 -d"<")"
SCALING="${SCALING##* }"
echo "found! Factor: ${SCALING}" >&2
# Fallback to X DPI query for others.
# Plasma handles this fine, GNOME will always round up e.g. 1.25 -> 2.00.
elif command -v xrdb >/dev/null; then
echo -n 'Scaling: Attempting to get scaling from X DPI value...' >&2
dpi="$(xrdb -get Xft.dpi)"
if [[ -n "${dpi}" ]]; then
SCALING=$(echo "scale=2; ${dpi}/96" | bc)
fi
echo "found! Factor: ${SCALING}"
# Query kscreen-doctor for Plasma as a fallback.
elif [[ "$(echo "$XDG_CURRENT_DESKTOP")" == "KDE" ]] && command -v kscreen-doctor >/dev/null; then
echo -n 'Scaling: Attempting to get Plasma desktop scaling factor...' >&2
SCALING="$(kscreen-doctor --outputs | grep "Scale" -m 1)"
SCALING="${SCALING##* }"
SCALING=$(echo $SCALING | sed 's/\x1B\[[0-9;]*m//g') # Trim ANSI chars from ksd output.
echo "found! Factor: ${SCALING}"
fi
if [[ -z "${SCALING-}" || "${SCALING-}" == "0" ]]; then
echo 'Unset invalid scaling value' >&2
SCALING="1"
fi
COMMAND="$COMMAND AVALONIA_GLOBAL_SCALE_FACTOR=$SCALING"
fi
exec $COMMAND "$SCRIPT_DIR/$RYUJINX_BIN" "$@"

View File

@@ -71,24 +71,16 @@ namespace Ryujinx.HLE.Loaders.Mods
int patchOffset = (int)offset;
int patchSize = patch.Length;
if (patchOffset < protectedOffset)
if (patchOffset < protectedOffset || patchOffset > memory.Length)
{
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;
continue; // Add warning?
}
patchOffset -= protectedOffset;
if (patchOffset + patchSize > memory.Length)
{
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;
patchSize = memory.Length - patchOffset; // Add warning?
}
Logger.Info?.Print(LogClass.ModLoader, $"Patching address offset {patchOffset:x} <= {BitConverter.ToString(patch).Replace('-', ' ')} len={patchSize}");

View File

@@ -464,7 +464,7 @@
"pl_PL": "",
"pt_BR": "Abrir Pasta de Capturas de Tela",
"ru_RU": "Открыть папку со скриншотами",
"sv_SE": "Öppna skärmbildsmappen",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Відкрити теку скріншотів",
@@ -1564,7 +1564,7 @@
"pl_PL": "",
"pt_BR": "Desenvolvido por {0}",
"ru_RU": "Разработана {0}",
"sv_SE": "Utvecklat av {0}",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Розроблено: {0}",
@@ -1864,7 +1864,7 @@
"pl_PL": "",
"pt_BR": "Compatibilidade:",
"ru_RU": "Совместимость:",
"sv_SE": "Kompatibilitet:",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Сумісність:",
@@ -1889,7 +1889,7 @@
"pl_PL": "",
"pt_BR": "ID do Título:",
"ru_RU": "ID приложения",
"sv_SE": "Titel-id:",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "ID гри:",
@@ -1914,7 +1914,7 @@
"pl_PL": "",
"pt_BR": "Jogos Hospedados: {0}",
"ru_RU": "Запущенно игр: {0}",
"sv_SE": "Värdskap för spel: {0}",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Розміщені ігри: {0}",
@@ -1939,7 +1939,7 @@
"pl_PL": "",
"pt_BR": "Jogadores Online: {0}",
"ru_RU": "Игроков онлайн: {0}",
"sv_SE": "Online-spelare: {0}",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Гравців онлайн: {0}",
@@ -2289,7 +2289,7 @@
"pl_PL": "",
"pt_BR": "Limpar Cache PPTC",
"ru_RU": "Очистить кэш PPTC",
"sv_SE": "Rensa PPTC-cache",
"sv_SE": "",
"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": "Tar bort alla PPTC-cachefiler för applikationen",
"sv_SE": "",
"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": "Visa kompatibilitetspost",
"sv_SE": "",
"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": "Visa valt spel i kompatibilitetslistan som du normalt sett kan komma åt via hjälpmenyn.",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Показати цю гру в Списку Сумісності. Список сумісності також можна зайти в меню Довідки.",
@@ -2939,7 +2939,7 @@
"pl_PL": "",
"pt_BR": "Mostrar Informações do Jogo",
"ru_RU": "Показать информацию об игре",
"sv_SE": "Visa spelinformation",
"sv_SE": "",
"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": "Visa statistik och detaljer om det aktuella spelet.",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Показати статистику та деталі обраної гри.",
@@ -3514,7 +3514,7 @@
"pl_PL": "",
"pt_BR": "Verificar Atualizações:",
"ru_RU": "Проверка наличия обновлений",
"sv_SE": "Leta efter uppdateringar:",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Перевірка оновлень:",
@@ -3539,7 +3539,7 @@
"pl_PL": "",
"pt_BR": "Desligado",
"ru_RU": "Отключить",
"sv_SE": "Av",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Вимкнути",
@@ -3564,7 +3564,7 @@
"pl_PL": "",
"pt_BR": "Ao Abrir",
"ru_RU": "При запуске",
"sv_SE": "Fråga",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Запитувати щоразу",
@@ -3589,7 +3589,7 @@
"pl_PL": "",
"pt_BR": "2° Plano",
"ru_RU": "В фоне",
"sv_SE": "Bakgrund",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Оновлювати в фоні",
@@ -3614,7 +3614,7 @@
"pl_PL": "",
"pt_BR": "Ao Perder o Foco:",
"ru_RU": "При выходе эмулятора из фокуса",
"sv_SE": "När emulatorn tappar fokus:",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "При втраті фокуса емулятором:",
@@ -3639,7 +3639,7 @@
"pl_PL": "",
"pt_BR": "Não Fazer Nada",
"ru_RU": "Ничего не делать",
"sv_SE": "Gör ingenting",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Нічого не робити",
@@ -3664,7 +3664,7 @@
"pl_PL": "",
"pt_BR": "Bloquear Controles",
"ru_RU": "Блокировать управление",
"sv_SE": "Blockera inmatning",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Блокувати введення",
@@ -3689,7 +3689,7 @@
"pl_PL": "",
"pt_BR": "Ficar Mudo",
"ru_RU": "Отключить звук",
"sv_SE": "Stäng av ljudet",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Вимкнути звук",
@@ -3714,7 +3714,7 @@
"pl_PL": "",
"pt_BR": "Bloquear Controles & Ficar Mudo",
"ru_RU": "Блокировать управление и отключить звук",
"sv_SE": "Blockera inmatningar och stäng av ljudet",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Блокувати введення та Вимкнути звук",
@@ -3739,7 +3739,7 @@
"pl_PL": "",
"pt_BR": "Pausar a Emulação",
"ru_RU": "Поставить паузу",
"sv_SE": "Pausa emuleringen",
"sv_SE": "",
"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": "Inaktivera inmatning när fokus tappas",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
@@ -4839,7 +4839,7 @@
"pl_PL": "",
"pt_BR": "Sincronizar com o Sistema PC",
"ru_RU": "Соответствовать времени в системе",
"sv_SE": "Matcha systemtid",
"sv_SE": "",
"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": "Ignorera kontroller-applet",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Ігнорувати Аплет Контролера",
@@ -6114,7 +6114,7 @@
"pl_PL": "",
"pt_BR": "Habilitar Logs da IU",
"ru_RU": "Включить журнал интерфейса",
"sv_SE": "Aktivera gränssnittsloggar",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Увімкнути журнали інтерфейсу",
@@ -6514,7 +6514,7 @@
"pl_PL": "",
"pt_BR": "Redefinir Configurações",
"ru_RU": "Сбросить настройки",
"sv_SE": "Nollställ inställningar",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Скинути налаштування",
@@ -6539,7 +6539,7 @@
"pl_PL": "",
"pt_BR": "Quero redefinir minhas configurações.",
"ru_RU": "Я хочу сбросить свои настройки.",
"sv_SE": "Jag vill nollställa mina inställningar.",
"sv_SE": "",
"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": "Pro контроллер",
"ru_RU": "",
"sv_SE": "",
"th_TH": "โปรคอนโทรลเลอร์",
"tr_TR": "Profesyonel Kumanda",
@@ -8514,7 +8514,7 @@
"pl_PL": "",
"pt_BR": "Velocidade do Arco-íris",
"ru_RU": "Скорость переливания",
"sv_SE": "Regnbågshastighet",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
@@ -13814,7 +13814,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": "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?",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Ви збираєтесь видалити всі дані PPTC з:\n\n{0}\n\nБажаєте продовжити цю операцію?",
@@ -16664,7 +16664,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": "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.",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Діалогове вікно Аплету Контролера не з'явиться, якщо геймпад було відключено під час роботи програми.\n\nЗалиште вимкненим якщо не впевнені.",
@@ -17139,7 +17139,7 @@
"pl_PL": "",
"pt_BR": "Imprime mensagens de log do Avalonia (UI) no console.",
"ru_RU": "Выводит сообщения журнала Avalonia (интерфейс) в консоли.",
"sv_SE": "Skriver ut loggmeddelanden från Avalonia (användargränssnittet) i konsollen.",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Виводити повідомлення журналу Avalonia (UI) в консоль",
@@ -17339,7 +17339,7 @@
"pl_PL": "",
"pt_BR": "Abre a pasta de capturas de tela do Ryujinx",
"ru_RU": "Открывает папку скриншотов Ryujinx",
"sv_SE": "Öppna Ryujinx skärmbildsmapp",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Відкрити теку куди зберігаються скріншоти Ryujinx",
@@ -18089,7 +18089,7 @@
"pl_PL": "",
"pt_BR": "Atualização Disponível!",
"ru_RU": "Доступно обновление!",
"sv_SE": "Uppdatering finns tillgänglig!",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Доступне оновлення!",
@@ -20013,7 +20013,7 @@
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "Амибо",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
@@ -24064,7 +24064,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": "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.",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Запускається та оптимально працює (без збоїв або графічних багів) на середньостатистичному комп'ютері.",
@@ -24089,7 +24089,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": "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.",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Запускається, але в грі на вас чекатимуть одна або декілька наступних проблем: збої, зависання, графічні баги, спотворений звук або ж гра загалом працюватиме надто повільно. Можливо, її все ще можна пройти, але досвід буде не найкращим.",
@@ -24114,7 +24114,7 @@
"pl_PL": "",
"pt_BR": "Inicializa e passa da tela de título, mas não entra no jogo principal.",
"ru_RU": "Загружается титульный экран и можно перейти дальше, но сама игра не работает.",
"sv_SE": "Startar upp och går förbi titelskärmen men tar sig inte in i huvudspelet.",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Запускається та проходить початковий екран, але пограти не вийде.",
@@ -24139,7 +24139,7 @@
"pl_PL": "",
"pt_BR": "Inizializa, mas não passa da tela de título.",
"ru_RU": "Загружается, но не проходит дальше титульного экрана.",
"sv_SE": "Startar upp men tar sig inte förbi titelskärmen.",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Запускається, але не відображає навіть початкового екрану.",
@@ -24164,7 +24164,7 @@
"pl_PL": "",
"pt_BR": "Não inicializa ou não mostra sinais de atividade.",
"ru_RU": "Не запускается или не подаёт признаков жизни.",
"sv_SE": "Startar inte upp eller visar någon form av aktivitet.",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Взагалі не запускається.",
@@ -24264,7 +24264,7 @@
"pl_PL": "",
"pt_BR": "Imagem da Presença do Discord",
"ru_RU": "Изображение для статуса активности",
"sv_SE": "Bild för Rich Presence",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Зображення картки активності Discord",
@@ -24289,7 +24289,7 @@
"pl_PL": "",
"pt_BR": "Presença Dinâmica do Discord",
"ru_RU": "Динамический статус активности",
"sv_SE": "Dynamisk Rich Presence",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "Динамічна картка активності Discord",

View File

@@ -17,8 +17,12 @@
<viewModels:ProfileSelectorDialogViewModel />
</Design.DataContext>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowDefinitions="*,Auto">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border
CornerRadius="5"
BorderBrush="{DynamicResource AppListHoverBackgroundColor}"

View File

@@ -14,7 +14,10 @@
mc:Ignorable="d"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
x:DataType="viewModels:MainWindowViewModel">
<Grid RowDefinitions="*">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox
Grid.Row="0"
Padding="8"
@@ -54,7 +57,11 @@
Classes.small="{Binding $parent[UserControl].((viewModels:MainWindowViewModel)DataContext).IsGridSmall}"
ClipToBounds="True"
CornerRadius="4">
<Grid RowDefinitions="Auto,Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image
Grid.Row="0"
HorizontalAlignment="Stretch"

View File

@@ -13,7 +13,10 @@
mc:Ignorable="d"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
x:DataType="viewModels:MainWindowViewModel">
<Grid RowDefinitions="*">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox
Name="GameListBox"
Grid.Row="0"

View File

@@ -13,7 +13,15 @@
<Grid
Margin="20"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto">
VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image
Grid.Row="1"
Height="70"

View File

@@ -1,260 +0,0 @@
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.ViewModels.Input;
using Ryujinx.Input;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Models.Input
{
public class StickVisualizer : BaseModel, IDisposable
{
public const int DrawStickPollRate = 50; // Milliseconds per poll.
public const int DrawStickCircumference = 5;
public const float DrawStickScaleFactor = DrawStickCanvasCenter;
public const int DrawStickCanvasSize = 100;
public const int DrawStickBorderSize = DrawStickCanvasSize + 5;
public const float DrawStickCanvasCenter = (DrawStickCanvasSize - DrawStickCircumference) / 2;
public const float MaxVectorLength = DrawStickCanvasSize / 2;
public CancellationTokenSource PollTokenSource;
public CancellationToken PollToken;
private static float _vectorLength;
private static float _vectorMultiplier;
private bool disposedValue;
private DeviceType _type;
public DeviceType Type
{
get => _type;
set
{
_type = value;
OnPropertyChanged();
}
}
private GamepadInputConfig _gamepadConfig;
public GamepadInputConfig GamepadConfig
{
get => _gamepadConfig;
set
{
_gamepadConfig = value;
OnPropertyChanged();
}
}
private KeyboardInputConfig _keyboardConfig;
public KeyboardInputConfig KeyboardConfig
{
get => _keyboardConfig;
set
{
_keyboardConfig = value;
OnPropertyChanged();
}
}
private (float, float) _uiStickLeft;
public (float, float) UiStickLeft
{
get => (_uiStickLeft.Item1 * DrawStickScaleFactor, _uiStickLeft.Item2 * DrawStickScaleFactor);
set
{
_uiStickLeft = value;
OnPropertyChanged();
OnPropertyChanged(nameof(UiStickRightX));
OnPropertyChanged(nameof(UiStickRightY));
OnPropertyChanged(nameof(UiDeadzoneRight));
}
}
private (float, float) _uiStickRight;
public (float, float) UiStickRight
{
get => (_uiStickRight.Item1 * DrawStickScaleFactor, _uiStickRight.Item2 * DrawStickScaleFactor);
set
{
_uiStickRight = value;
OnPropertyChanged();
OnPropertyChanged(nameof(UiStickLeftX));
OnPropertyChanged(nameof(UiStickLeftY));
OnPropertyChanged(nameof(UiDeadzoneLeft));
}
}
public float UiStickLeftX => ClampVector(UiStickLeft).Item1;
public float UiStickLeftY => ClampVector(UiStickLeft).Item2;
public float UiStickRightX => ClampVector(UiStickRight).Item1;
public float UiStickRightY => ClampVector(UiStickRight).Item2;
public int UiStickCircumference => DrawStickCircumference;
public int UiCanvasSize => DrawStickCanvasSize;
public int UiStickBorderSize => DrawStickBorderSize;
public float? UiDeadzoneLeft => _gamepadConfig?.DeadzoneLeft * DrawStickCanvasSize - DrawStickCircumference;
public float? UiDeadzoneRight => _gamepadConfig?.DeadzoneRight * DrawStickCanvasSize - DrawStickCircumference;
private InputViewModel Parent;
public StickVisualizer(InputViewModel parent)
{
Parent = parent;
PollTokenSource = new CancellationTokenSource();
PollToken = PollTokenSource.Token;
Task.Run(Initialize, PollToken);
}
public void UpdateConfig(object config)
{
if (config is ControllerInputViewModel padConfig)
{
GamepadConfig = padConfig.Config;
Type = DeviceType.Controller;
return;
}
else if (config is KeyboardInputViewModel keyConfig)
{
KeyboardConfig = keyConfig.Config;
Type = DeviceType.Keyboard;
return;
}
Type = DeviceType.None;
}
public async Task Initialize()
{
(float, float) leftBuffer;
(float, float) rightBuffer;
while (!PollToken.IsCancellationRequested)
{
leftBuffer = (0f, 0f);
rightBuffer = (0f, 0f);
switch (Type)
{
case DeviceType.Keyboard:
IKeyboard keyboard = (IKeyboard)Parent.AvaloniaKeyboardDriver.GetGamepad("0");
if (keyboard != null)
{
KeyboardStateSnapshot snapshot = keyboard.GetKeyboardStateSnapshot();
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickRight))
{
leftBuffer.Item1 += 1;
}
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickLeft))
{
leftBuffer.Item1 -= 1;
}
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickUp))
{
leftBuffer.Item2 += 1;
}
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickDown))
{
leftBuffer.Item2 -= 1;
}
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickRight))
{
rightBuffer.Item1 += 1;
}
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickLeft))
{
rightBuffer.Item1 -= 1;
}
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickUp))
{
rightBuffer.Item2 += 1;
}
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickDown))
{
rightBuffer.Item2 -= 1;
}
UiStickLeft = leftBuffer;
UiStickRight = rightBuffer;
}
break;
case DeviceType.Controller:
IGamepad controller = Parent.SelectedGamepad;
if (controller != null)
{
leftBuffer = controller.GetStick((StickInputId)GamepadConfig.LeftJoystick);
rightBuffer = controller.GetStick((StickInputId)GamepadConfig.RightJoystick);
}
break;
case DeviceType.None:
break;
default:
throw new ArgumentException($"Unable to poll device type \"{Type}\"");
}
UiStickLeft = leftBuffer;
UiStickRight = rightBuffer;
await Task.Delay(DrawStickPollRate, PollToken);
}
PollTokenSource.Dispose();
}
public static (float, float) ClampVector((float, float) vect)
{
_vectorMultiplier = 1;
_vectorLength = MathF.Sqrt((vect.Item1 * vect.Item1) + (vect.Item2 * vect.Item2));
if (_vectorLength > MaxVectorLength)
{
_vectorMultiplier = MaxVectorLength / _vectorLength;
}
vect.Item1 = vect.Item1 * _vectorMultiplier + DrawStickCanvasCenter;
vect.Item2 = vect.Item2 * _vectorMultiplier + DrawStickCanvasCenter;
return vect;
}
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
PollTokenSource.Cancel();
}
KeyboardConfig = null;
GamepadConfig = null;
Parent = null;
disposedValue = true;
}
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}

View File

@@ -1,9 +1,5 @@
using Avalonia.Svg.Skia;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Input;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Views.Input;
using Ryujinx.Common.Utilities;
@@ -14,30 +10,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{
public partial class ControllerInputViewModel : BaseModel
{
private GamepadInputConfig _config;
public GamepadInputConfig Config
{
get => _config;
set
{
_config = value;
[ObservableProperty] private GamepadInputConfig _config;
OnPropertyChanged();
}
}
private StickVisualizer _visualizer;
public StickVisualizer Visualizer
{
get => _visualizer;
set
{
_visualizer = value;
OnPropertyChanged();
}
}
private bool _isLeft;
public bool IsLeft
{
@@ -63,15 +37,14 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
}
public bool HasSides => IsLeft ^ IsRight;
[ObservableProperty] private SvgImage _image;
public InputViewModel ParentModel { get; }
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config, StickVisualizer visualizer)
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig config)
{
ParentModel = model;
Visualizer = visualizer;
model.NotifyChangesEvent += OnParentModelChanged;
OnParentModelChanged();
config.PropertyChanged += (_, args) =>

View File

@@ -49,7 +49,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
private int _controller;
private string _controllerImage;
private int _device;
private object _configViewModel;
[ObservableProperty] private object _configViewModel;
[ObservableProperty] private string _profileName;
private bool _isLoaded;
@@ -74,7 +74,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed));
}
}
public StickVisualizer VisualStick { get; private set; }
public ObservableCollection<PlayerModel> PlayerIndexes { get; set; }
public ObservableCollection<(DeviceType Type, string Id, string Name)> Devices { get; set; }
@@ -95,19 +94,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public bool IsModified { get; set; }
public event Action NotifyChangesEvent;
public object ConfigViewModel
{
get => _configViewModel;
set
{
_configViewModel = value;
VisualStick.UpdateConfig(value);
OnPropertyChanged();
}
}
public PlayerIndex PlayerIdChoose
{
get => _playerIdChoose;
@@ -283,7 +269,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
Devices = [];
ProfilesList = [];
DeviceList = [];
VisualStick = new StickVisualizer(this);
ControllerImage = ProControllerResource;
@@ -304,12 +289,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
if (Config is StandardKeyboardInputConfig keyboardInputConfig)
{
ConfigViewModel = new KeyboardInputViewModel(this, new KeyboardInputConfig(keyboardInputConfig), VisualStick);
ConfigViewModel = new KeyboardInputViewModel(this, new KeyboardInputConfig(keyboardInputConfig));
}
if (Config is StandardControllerInputConfig controllerInputConfig)
{
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig), VisualStick);
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig));
}
}
@@ -908,8 +893,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
_mainWindow.ViewModel.AppHost?.NpadManager.UnblockInputUpdates();
VisualStick.Dispose();
SelectedGamepad?.Dispose();
AvaloniaKeyboardDriver.Dispose();

View File

@@ -6,29 +6,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
{
public partial class KeyboardInputViewModel : BaseModel
{
private KeyboardInputConfig _config;
public KeyboardInputConfig Config
{
get => _config;
set
{
_config = value;
OnPropertyChanged();
}
}
private StickVisualizer _visualizer;
public StickVisualizer Visualizer
{
get => _visualizer;
set
{
_visualizer = value;
OnPropertyChanged();
}
}
[ObservableProperty] private KeyboardInputConfig _config;
private bool _isLeft;
public bool IsLeft
@@ -60,10 +38,9 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public readonly InputViewModel ParentModel;
public KeyboardInputViewModel(InputViewModel model, KeyboardInputConfig config, StickVisualizer visualizer)
public KeyboardInputViewModel(InputViewModel model, KeyboardInputConfig config)
{
ParentModel = model;
Visualizer = visualizer;
model.NotifyChangesEvent += OnParentModelChanged;
OnParentModelChanged();
Config = config;

View File

@@ -34,7 +34,12 @@
<!-- Button / JoyStick Settings -->
<Grid
Name="SettingButtons"
MinHeight="450" ColumnDefinitions="Auto,*,Auto">
MinHeight="450">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Left Controls -->
<StackPanel
Orientation="Vertical"
@@ -49,7 +54,15 @@
CornerRadius="5">
<Grid
Margin="10"
HorizontalAlignment="Stretch" ColumnDefinitions="*,*" RowDefinitions="*,*">
HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel
Grid.Column="0"
Grid.Row="0"
@@ -303,99 +316,17 @@
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<!-- Controller Picture -->
<Image
Margin="0,10"
MaxHeight="300"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Source="{Binding Image}" />
<Border
BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="1"
CornerRadius="5"
Margin="0,0, 0, 5"
MinHeight="90">
<StackPanel Orientation="Vertical">
<Image
Margin="5,10"
MaxHeight="300"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Source="{Binding Image}" />
<StackPanel
Margin="10"
Orientation="Horizontal"
Spacing="20"
HorizontalAlignment="Center">
<Border
BorderBrush="Transparent"
Height="{Binding Visualizer.UiStickBorderSize}"
Width="{Binding Visualizer.UiStickBorderSize}"
IsVisible="{Binding IsLeft}">
<Canvas
Background="{DynamicResource ThemeBackgroundColor}"
Height="{Binding Visualizer.UiCanvasSize}"
Width="{Binding Visualizer.UiCanvasSize}">
<Grid
Height="{Binding Visualizer.UiCanvasSize}"
Width="{Binding Visualizer.UiCanvasSize}"
Background="{DynamicResource ThemeBackgroundColor}">
<Ellipse
HorizontalAlignment="Center"
Stroke="{DynamicResource ThemeControlBorderColor}"
StrokeThickness="1"
Width="{Binding Visualizer.UiCanvasSize}"
Height="{Binding Visualizer.UiCanvasSize}" />
<Ellipse
HorizontalAlignment="Center"
Fill="Black"
Opacity="100"
Height="{Binding Visualizer.UiDeadzoneLeft}"
Width="{Binding Visualizer.UiDeadzoneLeft}" />
</Grid>
<Ellipse
Fill="{DynamicResource Warning}"
Width="{Binding Visualizer.UiStickCircumference}"
Height="{Binding Visualizer.UiStickCircumference}"
Canvas.Bottom="{Binding Visualizer.UiStickLeftY}"
Canvas.Left="{Binding Visualizer.UiStickLeftX}" />
</Canvas>
</Border>
<Border
BorderBrush="Transparent"
Height="{Binding Visualizer.UiStickBorderSize}"
Width="{Binding Visualizer.UiStickBorderSize}"
IsVisible="{Binding IsRight}">
<Canvas
Background="{DynamicResource ThemeBackgroundColor}"
Height="{Binding Visualizer.UiCanvasSize}"
Width="{Binding Visualizer.UiCanvasSize}">
<Grid
Height="{Binding Visualizer.UiCanvasSize}"
Width="{Binding Visualizer.UiCanvasSize}"
Background="{DynamicResource ThemeBackgroundColor}">
<Ellipse
HorizontalAlignment="Center"
Stroke="{DynamicResource ThemeControlBorderColor}"
StrokeThickness="1"
Width="{Binding Visualizer.UiCanvasSize}"
Height="{Binding Visualizer.UiCanvasSize}" />
<Ellipse
HorizontalAlignment="Center"
Fill="Black"
Opacity="100"
Height="{Binding Visualizer.UiDeadzoneRight}"
Width="{Binding Visualizer.UiDeadzoneRight}" />
</Grid>
<Ellipse
Fill="{DynamicResource Warning}"
Width="{Binding Visualizer.UiStickCircumference}"
Height="{Binding Visualizer.UiStickCircumference}"
Canvas.Bottom="{Binding Visualizer.UiStickRightY}"
Canvas.Left="{Binding Visualizer.UiStickRightX}" />
</Canvas>
</Border>
</StackPanel>
</StackPanel>
</Border>
<Border
BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="1"
CornerRadius="5">
<StackPanel
Margin="8"
Orientation="Vertical">
@@ -414,8 +345,8 @@
Minimum="0"
Value="{Binding Config.TriggerThreshold, Mode=TwoWay}" />
<TextBlock
Width="25"
Text="{Binding Config.TriggerThreshold, StringFormat=\{0:0.00\}}" />
Width="25"
Text="{Binding Config.TriggerThreshold, StringFormat=\{0:0.00\}}" />
</StackPanel>
<StackPanel
Orientation="Vertical"
@@ -497,7 +428,7 @@
</Border>
<!-- Motion, Rumble, LED -->
<StackPanel
Margin="0,5,0,0"
Margin="0,10,0,0"
Spacing="5"
Orientation="Vertical"
VerticalAlignment="Bottom">
@@ -507,7 +438,11 @@
CornerRadius="5"
VerticalAlignment="Bottom"
HorizontalAlignment="Stretch">
<Grid ColumnDefinitions="*,Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox
Margin="10"
MinWidth="0"
@@ -529,7 +464,11 @@
CornerRadius="5"
HorizontalAlignment="Stretch"
Margin="0,-1,0,0">
<Grid ColumnDefinitions="*,Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox
Margin="10"
MinWidth="0"
@@ -551,7 +490,11 @@
CornerRadius="5"
HorizontalAlignment="Stretch"
Margin="0,-1,0,0">
<Grid IsVisible="{Binding ParentModel.HasLed}" ColumnDefinitions="*,Auto">
<Grid IsVisible="{Binding ParentModel.HasLed}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox
Margin="10, 10, 5, 10"
MinWidth="0"
@@ -583,7 +526,15 @@
CornerRadius="5">
<Grid
Margin="10"
HorizontalAlignment="Stretch" ColumnDefinitions="*,*" RowDefinitions="*,*">
HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel
Grid.Column="1"
Grid.Row="0"

View File

@@ -35,13 +35,22 @@
Margin="0 0 0 5"
Orientation="Vertical"
Spacing="5">
<Grid ColumnDefinitions="*,10,*">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Player Selection -->
<Grid
Grid.Column="0"
Margin="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Center" ColumnDefinitions="Auto,*">
VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
Margin="5,0,10,0"
Width="90"
@@ -68,7 +77,14 @@
Grid.Column="2"
Margin="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Center" ColumnDefinitions="Auto,*,Auto,Auto,Auto">
VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Margin="5,0,10,0"
Width="90"
@@ -123,12 +139,22 @@
</Grid>
</Grid>
<Separator />
<Grid ColumnDefinitions="*,10,*">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Input Device -->
<Grid
Grid.Column="0"
Margin="2"
HorizontalAlignment="Stretch" ColumnDefinitions="Auto,*,Auto">
HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Margin="5,0,10,0"
@@ -160,7 +186,11 @@
Grid.Column="2"
Margin="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Center" ColumnDefinitions="Auto,*">
VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
Margin="5,0,10,0"
Width="90"

View File

@@ -32,7 +32,12 @@
<!-- Button / JoyStick Settings -->
<Grid
Name="SettingButtons"
MinHeight="450" ColumnDefinitions="Auto,*,Auto">
MinHeight="450">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Left Controls -->
<StackPanel
Orientation="Vertical"
@@ -47,7 +52,15 @@
CornerRadius="5">
<Grid
Margin="10"
HorizontalAlignment="Stretch" ColumnDefinitions="*,*" RowDefinitions="*,*">
HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel
Grid.Column="0"
Grid.Row="0"
@@ -296,79 +309,12 @@
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<!-- Controller Picture -->
<Border
BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="1"
CornerRadius="5"
<Image
Margin="0,10"
MinHeight="90">
<StackPanel
Margin="10"
Orientation="Horizontal"
Spacing="20"
HorizontalAlignment="Center">
<Border
BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="1"
CornerRadius="5"
Height="{Binding Visualizer.UiStickBorderSize}"
Width="{Binding Visualizer.UiStickBorderSize}"
IsVisible="{Binding IsLeft}">
<Canvas
Background="{DynamicResource ThemeBackgroundColor}"
Height="{Binding Visualizer.UiCanvasSize}"
Width="{Binding Visualizer.UiCanvasSize}">
<Grid
Height="{Binding Visualizer.UiCanvasSize}"
Width="{Binding Visualizer.UiCanvasSize}"
Background="{DynamicResource ThemeBackgroundColor}">
<Ellipse
HorizontalAlignment="Center"
Stroke="Black"
StrokeThickness="1"
Width="{Binding Visualizer.UiCanvasSize}"
Height="{Binding Visualizer.UiCanvasSize}"/>
</Grid>
<Ellipse
Fill="Red"
Width="{Binding Visualizer.UiStickCircumference}"
Height="{Binding Visualizer.UiStickCircumference}"
Canvas.Bottom="{Binding Visualizer.UiStickLeftY}"
Canvas.Left="{Binding Visualizer.UiStickLeftX}" />
</Canvas>
</Border>
<Border
BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="1"
CornerRadius="5"
Height="{Binding Visualizer.UiStickBorderSize}"
Width="{Binding Visualizer.UiStickBorderSize}"
IsVisible="{Binding IsRight}">
<Canvas
Background="{DynamicResource ThemeBackgroundColor}"
Height="{Binding Visualizer.UiCanvasSize}"
Width="{Binding Visualizer.UiCanvasSize}">
<Grid
Height="{Binding Visualizer.UiCanvasSize}"
Width="{Binding Visualizer.UiCanvasSize}"
Background="{DynamicResource ThemeBackgroundColor}">
<Ellipse
HorizontalAlignment="Center"
Stroke="Black"
StrokeThickness="1"
Width="{Binding Visualizer.UiCanvasSize}"
Height="{Binding Visualizer.UiCanvasSize}"/>
</Grid>
<Ellipse
Fill="Red"
Width="{Binding Visualizer.UiStickCircumference}"
Height="{Binding Visualizer.UiStickCircumference}"
Canvas.Bottom="{Binding Visualizer.UiStickRightY}"
Canvas.Left="{Binding Visualizer.UiStickRightX}" />
</Canvas>
</Border>
</StackPanel>
</Border>
MaxHeight="300"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Source="{Binding Image}" />
<Border
BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="1"
@@ -467,7 +413,15 @@
CornerRadius="5">
<Grid
Margin="10"
HorizontalAlignment="Stretch" ColumnDefinitions="*,*" RowDefinitions="*,*">
HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel
Grid.Column="1"
Grid.Row="0"

View File

@@ -11,7 +11,11 @@
x:Class="Ryujinx.Ava.UI.Views.Input.MotionInputView"
x:DataType="viewModels:MotionInputViewModel"
Focusable="True">
<Grid Margin="10" RowDefinitions="Auto,*">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical">
<StackPanel
Orientation="Horizontal"
@@ -76,7 +80,11 @@
BorderThickness="1"
CornerRadius="5"
HorizontalAlignment="Stretch">
<Grid VerticalAlignment="Top" RowDefinitions="Auto,*">
<Grid VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel
Grid.Row="1"
HorizontalAlignment="Center"
@@ -110,7 +118,15 @@
Text="{Binding DsuServerPort, Mode=TwoWay}" />
</StackPanel>
<StackPanel Orientation="Vertical">
<Grid RowDefinitions="*,*" ColumnDefinitions="*,*">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock
Margin="0,10,0,0"
VerticalAlignment="Center"

View File

@@ -10,7 +10,11 @@
x:Class="Ryujinx.Ava.UI.Views.Input.RumbleInputView"
x:DataType="viewModels:RumbleInputViewModel"
Focusable="True">
<Grid Margin="10" RowDefinitions="Auto,*">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock

View File

@@ -21,7 +21,12 @@
<Border Classes="settings">
<Panel
Margin="10">
<Grid RowDefinitions="Auto,*,Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<views:InputView
Grid.Row="0"
Name="InputView" />

View File

@@ -177,7 +177,12 @@
</Style>
</ListBox.Styles>
</ListBox>
<Grid HorizontalAlignment="Stretch" ColumnDefinitions="*,Auto,Auto">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox
Name="GameDirPathBox"
Margin="0"
@@ -230,7 +235,12 @@
</Style>
</ListBox.Styles>
</ListBox>
<Grid HorizontalAlignment="Stretch" ColumnDefinitions="*,Auto,Auto">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox
Name="AutoloadDirPathBox"
Margin="0"

View File

@@ -14,7 +14,15 @@
mc:Ignorable="d"
Focusable="True"
x:DataType="models:TempProfile">
<Grid Margin="0" ColumnDefinitions="Auto,*" RowDefinitions="*,Auto">
<Grid Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel
Grid.Row="0"
Grid.Column="0"

View File

@@ -20,7 +20,13 @@
<Grid
Margin="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" RowDefinitions="Auto,*,Auto,Auto">
VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox
Grid.Row="1"
BorderThickness="0"

View File

@@ -17,7 +17,12 @@
</Design.DataContext>
<Grid
HorizontalAlignment="Stretch"
VerticalAlignment="Center" RowDefinitions="Auto,70,Auto">
VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="70" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
Grid.Row="0"
TextWrapping="Wrap"

View File

@@ -18,7 +18,11 @@
<viewModels:UserProfileViewModel />
</Design.DataContext>
<Grid HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" RowDefinitions="*,Auto">
VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border
CornerRadius="5"
BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
@@ -37,7 +41,11 @@
VerticalAlignment="Stretch"
ClipToBounds="True"
CornerRadius="5">
<Grid Margin="0" ColumnDefinitions="*,Auto">
<Grid Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding UserId}"

View File

@@ -19,10 +19,19 @@
<Design.DataContext>
<viewModels:UserSaveManagerViewModel />
</Design.DataContext>
<Grid RowDefinitions="Auto,*,Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid
Grid.Row="0"
HorizontalAlignment="Stretch" ColumnDefinitions="Auto,*">
HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel
Spacing="10"
Orientation="Horizontal"
@@ -71,7 +80,11 @@
<Grid
Grid.Column="1"
HorizontalAlignment="Stretch"
Margin="10,0, 0, 0" ColumnDefinitions="Auto,*">
Margin="10,0, 0, 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Content="{ext:Locale Search}" VerticalAlignment="Center" />
<TextBox
Margin="5,0,0,0"
@@ -105,7 +118,11 @@
</ListBox.Styles>
<ListBox.ItemTemplate>
<DataTemplate x:DataType="models:SaveModel">
<Grid HorizontalAlignment="Stretch" ColumnDefinitions="*,Auto">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel
Grid.Column="0"
Orientation="Horizontal"

View File

@@ -18,7 +18,11 @@
<Design.DataContext>
<viewModels:UserProfileViewModel />
</Design.DataContext>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowDefinitions="*,Auto">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border
CornerRadius="5"
BorderBrush="{DynamicResource AppListHoverBackgroundColor}"

View File

@@ -53,12 +53,18 @@
<!-- For image -->
<ui:NavigationView.PaneHeader>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" RowDefinitions="Auto,Auto,Auto,5">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="5"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding GameId}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0,0,0,10"
TextAlignment="Center" Grid.Row="0" />
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0,0,0,10"
TextAlignment="Center" Grid.Row="0" />
<Image Source="{Binding GameIcon}"
Width="160"
Height="160"

View File

@@ -70,7 +70,11 @@
<DataTemplate
DataType="models:ModModel">
<Panel Margin="10">
<Grid ColumnDefinitions="*,Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
HorizontalAlignment="Left"
VerticalAlignment="Center"

View File

@@ -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="927"
Height="918"
MinWidth="800"
MinHeight="480"
WindowStartupLocation="CenterOwner"

View File

@@ -13,7 +13,14 @@
x:DataType="viewModels:XCITrimmerViewModel"
Focusable="True"
mc:Ignorable="d">
<Grid Margin="20 0 20 0" RowDefinitions="Auto,Auto,*,Auto,Auto">
<Grid Margin="20 0 20 0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Panel
Margin="10 10 10 10"
Grid.Row="0">
@@ -23,7 +30,12 @@
Margin="0 0 10 10"
IsVisible="{Binding !Processing}"
Grid.Row="1">
<Grid ColumnDefinitions="Auto,*,Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel
Grid.Column="0"
Orientation="Horizontal">
@@ -133,7 +145,11 @@
<DataTemplate
DataType="models:XCITrimmerFileModel">
<Panel Margin="10">
<Grid ColumnDefinitions="65*,35*">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="65*" />
<ColumnDefinition Width="35*" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Margin="10 0 10 0"
@@ -144,7 +160,11 @@
TextTrimming="CharacterEllipsis"
Text="{Binding Name}">
</TextBlock>
<Grid Grid.Column="1" ColumnDefinitions="45*,55*">
<Grid Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="45*" />
<ColumnDefinition Width="55*" />
</Grid.ColumnDefinitions>
<ProgressBar
Height="10"
Margin="10 0 10 0"
@@ -206,7 +226,15 @@
BorderThickness="1"
CornerRadius="5"
Padding="2.5">
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
Grid.Column="0"
Grid.Row="0"
@@ -246,7 +274,11 @@
<Panel
Grid.Row="4"
HorizontalAlignment="Stretch">
<Grid ColumnDefinitions="*,Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel
Grid.Column="0"
Orientation="Horizontal"