Хотел перенести сейвы со Switch на Steam Machine, а получилось приложение

В августе я писал в X про две недели со Steam Machine и между делом упомянул, что настроил синхронизацию сохранений между своим Switch и Deck, «руками, правда, но работает». Потом я захотел просто вспомнить, как я эти сохранения переносил, и перетащить свой сетап с Deck на машину. Закончилось это приложением с установщиком, которое лежит на GitHub, и двумя пулл-реквестами в EmuDeck и MangoHud.

Кода я не написал ни строчки. Я надиктовывал агенту, чего хочу, и проверял на живых устройствах, а он разбирался в настройке, писал код и установщик. В играх сейчас, по-моему, вообще много такого делают с ИИ, от модов до допиливания чего-нибудь под себя, и это мой кусок в ту же копилку.

Что получилось

Проект называется Switch Deck Sync. Он умеет две вещи.

Первая, синхронизация сохранений между Switch и Ryujinx по Wi-Fi. Поиграл в Зельду на консоли в дороге, дома нажал кнопку в библиотеке Steam и продолжил на Deck или на машине с того же места. Обратно так же.

Вторая, microSD как картридж. На карте лежит вся библиотека Switch целиком, вместе с профилем и сохранениями. Вставляешь её в Deck и играешь, переставляешь в машину и продолжаешь. Между двумя SteamOS-устройствами по сети при этом ничего синхронизировать не надо, они по очереди работают с одними и теми же данными.

Игры, ключи и прошивку проект не раздаёт, всё это берётся со своей консоли и своих картриджей.

Синхронизация со Switch

Начальная идея была простая, сравнить сохранения и перенести более свежее. Выбирать победителя по времени изменения файлов оказалось ненадёжно, поэтому приложение сравнивает содержимое по хешам с тем, что было при прошлой синхронизации. Изменилась одна сторона, сохранение целиком едет на другую. Изменились обе, спрашивает меня, какой прогресс оставить. Файлы двух разных прохождений оно не смешивает.

Перед заменой сохраняются обе версии, после записи файл перечитывается и проверяется. Если передача оборвалась, надо оставить сервер на Switch открытым и запустить синхронизацию ещё раз до того, как открывать игру.

На стороне Switch нужен FTP-сервер. Сначала пробовали FTP из DBI, на моей конфигурации он на чтении сохранений отдавал «Read out of file range», и причину мы так и не доказали. Взяли открытый ftpsrv, и в нём агент нашёл конкретную ошибку в проверке типа сохранения при открытии на запись. Исправленная сборка лежит в релизе вместе с патчем и исходниками.

Поставить себе это можно так. Нужен Switch с homebrew и Ryujinx на Linux, EmuDeck и отдельная карта необязательны.

  1. Скачать из релиза ZIP, распаковать и в Desktop Mode открыть Install.desktop, выбрать синхронизацию со Switch.

  2. На Switch положить ftpsrv-save-sync.nro в папку /switch/ и запустить.

  3. В приложении ввести адрес, который показывает ftpsrv, выбрать профиль Switch, профиль Ryujinx и игры.

  4. Закрыть игры на обоих устройствах и нажать синхронизацию.

У каждой игры в Ryujinx перед первым импортом уже должно быть своё сохранение, то есть её надо один раз запустить. Работает всё по кнопке, фонового обмена нет. FTP обычный, без шифрования, поэтому сервер стоит держать открытым только на время передачи и только в домашней сети.

microSD как картридж

У меня была карта на 512 ГБ с обычными играми Deck и пустая на 64 ГБ. Вторую захотелось целиком отдать под Switch.

На карте лежат игры с обновлениями и купленными дополнениями, профиль и данные Ryujinx, сохранения и история синхронизации. На каждом устройстве остаются само приложение, эмулятор, настройки графики и контроллеров, гироскоп и кэши шейдеров. Раскладка Deck не должна приезжать на машину вместе с картой, у них разные контроллеры.

На новом устройстве это три шага. Поставить EmuDeck и выбрать в нём Ryujinx, поставить Switch Deck Sync в режиме переносимой библиотеки, вставить карту. Нужна карта в ext4 и нативный Ryujinx из EmuDeck. Steam Machine была первым чужим для установщика устройством, и я специально прошёл это сам, без агента и без SSH. Все три игры (Mario Odyssey, Breath of the Wild и Mario Kart 8) запустились со своими сохранениями.

Заодно перенёс Super Smash Bros. со своего картриджа. В DBI раздел картриджа по MTP по умолчанию выключен (Настройки, Хранилища MTP, пункт «9: Gamecard»), а я точно помнил, что раньше он был на месте. Ещё и картридж сначала перепутал, в Switch стоял Mario Kart)

Что по дороге выкинули

Первая версия была сложнее, и несколько раз я возвращал агента к простому сценарию.

Сначала приложение привязывалось к конкретной карте по UUID. Это ломало саму идею, потому что человек может купить карту побольше или держать несколько библиотек. Теперь оно смотрит на выбранный кардридер.

Был свой посредник для запуска игр, который лез в AutoMap. Убрали, эмулятор запускается средствами EmuDeck, а игры и обложки добавляет Steam ROM Manager.

И синхронизация слишком тесно срослась с картой, хотя многим нужна только она, с играми во внутренней памяти. Теперь основная установка это синхронизация со Switch, а карта идёт дополнительной опцией.

Отдельно помучились с Game Mode. Приложение запускалось, а я видел чёрный экран, и только после нескольких вариантов интерфейс на SDL2 заработал. Сейчас в нём английский и русский, и своя обложка в библиотеке Steam.

Версия пока preview. Проверено на трёх моих играх, поддержку всех остальных я не обещаю.

Дальше агенту понадобилась сама машина

Игры на машине запустились, и вылезли две проблемы уже не в моём коде. Чтобы их разобрать, агенту нужен терминал на устройстве. На Steam Machine это значит выйти в Desktop Mode, открыть Konsole и что-то туда ввести, геймпадом, на телевизоре. Включать ради этого SSH и набирать с контроллера команду с ключом для authorized_keys я не хотел, поэтому агент заходил через floo. На машине вводится одна строка:

curl -sL floo.run/sh | bash

На экране появляется код, я диктую его агенту, он у себя запускает:

bash <(curl -sL floo.run/powder) connect КОД

Дальше у него shell от пользователя deck, пока открыта Konsole. Закрыл окно, и доступа нет, ключей на машине не остаётся. В репозитории floo лежит AGENTS.md, агенту хватает ссылки на него и кода.

Что надо знать заранее. sudo спросит пароль как обычно, на SteamOS его сначала задают через passwd, и вводить его придётся самому на машине. Быстрая сессия на публичном relay живёт до 30 минут, для долгой работы поднимается свой. И машине надо запретить засыпать, у меня агент дважды терял связь посреди проверки, потому что устройства уснули)

Гироскоп или раскладка, выбери одно

Mario Kart на четырёх геймпадах заработал сразу. А Zelda сказала «неверное количество контроллеров», и когда я зашёл в настройки ввода Ryujinx отключить лишних игроков, выяснилось странное. После захода в настройки гироскоп работает, целиться наклоном Steam Controller очень удобно, но слетает раскладка AutoMap и A становится B. Не заходишь в настройки, раскладка правильная, прицел мёртвый.

Заставить это работать на одной моей машине агент мог быстро, и я сразу сказал, что меня такое не устроит. У меня ещё Deck, и вообще хочется минимум отклонений от дефолта, чтобы на следующей новой машине всё завелось само. Если это баг дефолтов, значит оформляем фикс туда, где дефолты живут.

Был и плохой момент. Агент решил, что проще всего поправить сам эмулятор, и молча пошёл пересобирать Ryujinx из исходников. Сборка упала, я высказал всё, что думаю (цитировать не буду)), и попросил найти нормальные узкие баги. Их оказалось три, все в EmuDeck AutoMap.

Когда подключён один контроллер с гироскопом, AutoMap выбирал виртуальный геймпад Steam, а у того датчиков нет вообще. В новых версиях конфига Ryujinx он обновлял раскладку, но не трогал привязку игроков к устройствам, и там оставались старые маршруты. И профиль не был привязан к игроку, поэтому открытие настроек ввода подгружало нинтендовские дефолты вместо сгенерированной раскладки. Отсюда и мой выбор между прицелом и кнопками.

Встроенный в EmuDeck GyroDSU тут не помощник. Он читает датчики самого Deck, а у машины своих датчиков нет, они в контроллере. Я его потом с машины удалил, на Deck оставил.

После фикса с одним гироскопным контроллером Ryujinx читает его напрямую, на Deck всё по-прежнему идёт через DSU. Цена такая: для этого контроллера в эмуляторе перестают действовать переназначения Steam Input. Меня это устраивает, за настройку контроллера для эмулированных игр должны отвечать эмуляторы, а менять там что-то поверх будут очень редко.

PR лежит в EmuDeck с конца октября, ответа пока нет.

Счётчик FPS, который умирал до перезагрузки

Вторая проблема выглядела как мелочь. После любой игры Switch переставал показываться счётчик FPS в оверлее Steam, причём уже во всех играх, и лечилось это только перезагрузкой всей машины.

Оказался баг в MangoHud. Он читает /proc//fdinfo запущенного процесса и перед открытием каждого файла проверял, существует ли тот. Если доступ к процессу закрывался как раз в этот момент, проверка кидала исключение раньше, чем срабатывала уже написанная обработка ошибки открытия, и оверлей падал целиком. Проверки были лишние, весь фикс в том, чтобы их удалить.

Автор попросил убрать из PR тест и оставить только сам фикс, и влил. Мой коммит в MangoHud целиком из минусов)

4K120 с HDR есть, но без VRR

Побочная история. В Kingdom Come 2 картинка шла как-то неплавно, хотя счётчик писал 60 FPS. Я переключил вывод с 4K на 1440p 120 Гц, снял лимит кадров и включил VRR. На средне-высоких игра пошла в 80, 90, 100 FPS, и такой плавности я вообще не видел.

Телевизор у меня LG с 4K120, компьютер на него так и выводит, а машина показывала максимум 4K60. Первая причина оказалась глупой. У телевизора два входа HDMI 2.0 и два 2.1, машина стояла в первом, а 4K120 он там просто не объявляет. Переставил её в четвёртый тем же кабелем, и режим появился в списке.

С HDR картинка в нём выбеленная, это видно прямо в меню Steam. Без HDR всё нормально, 4K60 с HDR тоже нормально. Телевизор в сервисном оверлее пишет для машины «YCBCR420 8b TM HDR10», а для компьютера на том же входе «rgb 12b 4L12 HDR10». Второй кабель дал то же самое.

Дальше агент выяснил, что быстрый режим HDMI 2.1 в драйвере amdgpu на машине выключен и включается параметром ядра. Драйвер он не трогал. Сделал одноразовую загрузку с amdgpu.dcfeaturemask=0x402, после которой машина сама перезагружалась обратно в штатный режим. В этой загрузке телевизор показал те же «rgb 12b 4L12 HDR10», что и у компьютера, с нормальными цветами. Зато пропал VRR, телевизор писал FIXED.

Так что 4K120 с HDR железо умеет, а вместе с VRR на штатном драйвере пока не выходит. Есть сторонний проект с патчами для amdgpu, который это чинит, ставить его я не стал. Почему картинка выбеливается в обычном режиме, мы так и не доказали, в сети есть владельцы с такой же строкой на телевизоре и нормальными цветами.

Машину я вернул в первый вход и оставил 1440p 120 Гц, там одновременно работают и HDR, и VRR. Большой разницы с 4K я с дивана не вижу.

Ссылки

  • Switch Deck Sync: github.com/interkelstar/switch-deck-sync

  • EmuDeck, гироскоп и раскладка в AutoMap: PR #1776, ждёт ревью

  • MangoHud, падение оверлея: PR #2185, влит

  • floo: github.com/interkelstar/floo

В систему при этом ничего лишнего не ставилось, ни драйверов, ни своих сборок эмулятора. Когда оба патча довезут в SteamOS и EmuDeck, на новой машине останется поставить EmuDeck, Switch Deck Sync и вставить карту.

Если у вас Deck или Steam Machine и рядом лежит Switch, попробуйте, и расскажите, что сломалось)

Источник: habr.com

0 0 голоса
Рейтинг новости
1
0
Подписаться
Уведомить о
0 комментариев