Как подключить геймпад к psp

Обновлено: 01.07.2024

… или сказ про то, как пингвин Америку с Японией подружил.


Итак, в стародавние времена люди играли в Sony Playstation и их все устраивало. Но прогресс не стоял на месте. Увеличивалась степень интеграции микросхем. Инженерная мысль постоянно искала новые формфакторы, а мысль маркетинговая — новые рынки сбыта. Так в 2005 году появилась в продаже за пределами Японии портативная игровая система Sony Playstation Portable. Ее игровая линейка (как и у любой другой приставки) представляла собою специально скомпилированные под железо PSP игры. Но также она обладала и достаточными вычислительными мощностями для запуска игр от оригинальной PlayStation через встроенный эмулятор. Хотя, быть может, тут ключевую роль сыграло то, что и у PlayStation, и у PSP стоял процессор одной и той же архитектуры — а именно MIPS. Но самое примечательное в этой системе то, что сразу же, в год запуска, в сеть утекли библиотеки PSP SDK. В результате, через почти 10 лет с момента запуска, мы имеем огромную библиотеку игр и отлаженного homebrew. Также, сейчас, в не самом крупном городе России полностью рабочую PSP (самой функциональной модификации) можно купить с рук за 3000 рублей. Все это делает ее к настоящему моменту очень привлекательной бюджетной игровой системой с просто огромной инсталлбазой. Самая функциональная модификация имеет компонентный выход для подключения к ТВ. Но разъем подключения к ТВ располагается неудачно с точки зрения долгого использования PSP в качестве геймпада. К тому же, при длительном использовании возникает необходимость подключения второго провода — от зарядного устройства. И удобство использования такой химеры стремится к нулю. Как относительно бюджетно и при этом гиково решить эту проблемку — про это и пойдет речь в этой статье. Также вкратце будут затронуты темы программирования драйвера USB-клиента под PSP, методика установки хук-функций в PSP, работа под линуксом с устройствами USB и с джойстиками через API. Мы начинаем.

Идея подключения портативной консоли к ТВ не нова


Но прежде чем начнем, расскажу об одном интересном факте. Поскольку PSP вышла почти 10 лет назад, то на данный момент актуальным является следующее поколение портативных консолей от Sony, а именно Sony Playstation Vita. И дело в том, что в Японии вышла стационарная версия портативной консоли. Sony PlayStation Vita TV.



В качестве геймпадов она использует обычные Dualshock 3 от Playstation 3. Поддеживается USB или Bluetooth подключение. Vita TV, как и Vita, может воспроизводить игры от Vita, PSP и от оригинальной Playstation. Таким образом, идея «стационарной портативной» консоли достаточно состоятельна и интересна.

С помощью чего подружить геймпад и PSP?


Далее возник вопрос, как подключить внешний геймпад к PSP. Казалось бы, PSP имеет разъем USB, через который энтузиасты научили PSP запускать игры из папки подключенного компьютера или передавать всю картинку с игрой в окно этого самого подключенного по USB компьютера. Но, как оказалось, USB в PSP может быть только клиентом. И даже официальные аксессуары (например камера) работают в режиме хоста (кстати гугл при работе с периферией в андроид рекомендует переводить смартфон также в режим клиента). Т.е. подключать геймпад к PSP напрямую бесполезно. Поэтому нужно какое-то промежуточное устройство. В местном радиоэлектронном магазине отладочные платы разной степени крутизны стоили от 1 до 10 тысяч рублей. При том что это микроконтроллеры, и о USB-хосте нужно думать отдельно. Тут на глаза попался Raspberry Pi.



В этой машинке есть все, что нужно — 2 USB порта, а также полноценный Linux. В не самом крупном городе России старшая модель (с 512 Мб памяти и Ethernet) стоит 1500 рублей через доски бесплатных частных объявлений. Цена соизмерима с самыми дешевыми контролерными отладочными платами, а функциональность не в пример больше. Причем еще и «Made in the UK».

Начало исследования

Если просто подключить USB-кабель в PSP, то она станет видна как флешка. Нам же нужно, чтобы она принимала команды о внешнем управлении. Т.е. в PSP должен крутиться какой-то код, который будет принимать информацию по USB, и имитировать нажатие органов управления на самом PSP. Сама возможность запуска какого-то кода помимо лицензионных игр возможна только на пиратских прошивках. Технически пиратская прошивка — это программа, прикидывающаяся официальной программой, располагающейся на карте памяти, и которая при запуске подменяет в оперативной памяти рабочий код прошивки на модифицированный, позволяющий запускать игры из .iso-файлов с карты памяти PSP. Таким образом, прошивка работает ровно до следующей перезагрузки PSP. Но нам важно не это, а то, что она поддерживает плагины. Плагины — это объектные файлы, слинкованные в определенном формате, которые стартуют в отдельных потоках параллельно запуску главного меню, игр PSP или игр оригинальной Playstation. Последней версией оригинальной прошивки PSP является аж 6.60. Плагины, заточенные под более ранние версии прошивки могут не работать под последней прошивкой. Так произошло и в данном случае. Плагин, который умеет пересылать по USB от PSP к ПК под управлением Windows видео всего, что происходит на PSP и принимать данные от геймпада, подключенного к ПК в PSP, по USB, на прошивке 6.60 работал только наполовину, т.е. данные от геймпада до PSP доходили, но имитация управления органами управления PSP не работала. Я начал искать плагины, которые так или иначе работают с управлением именно на прошивке 6.60. И нашел. Другой плагин служит для работы с аналоговым стиком PSP, и он работает на последней прошивке. Все исходники для PSP компилируются вот этим homebrew SDK.

Модификация исходников плагинов PSP. Хуки.

За основу проекта плагина, который я буду модифицировать, я выбрал тот, что уже содержал работащий код USB-клиента. Но для привычной отладки и вообще уютной атмосферы мне понадобился printf(). На PSP. В выбранном плагине его не было. Зато в плагине, из которого я хотел вытащить рабочий код перехвата событий органов управления PSP он был, выполненный через перехват функции отрисовки очередного кадра в кадровый буфер и дорисовки к кадру нужных мне отладочных строк. Сам перехват функции (хук) отрисовки реализован следующим образом:


После вызова hook_function() операционная система PSP при вызове своей внутренней функции ядра sceDisplaySetFrameBuf() будет фактически вызывать setframebuf_hook_func(). А для вызова оригинальной sceDisplaySetFrameBuf() нужно теперь вызывать g_setframebuf(). Кому интересна тема хуков, более подробно можно почитать например здесь.

Модификация исходников плагинов PSP. Управление.

Далее я добавил в модифицируемый проект рабочие хуки на функции управления sceCtrlReadBufferPositive(), sceCtrlPeekBufferPositive(), sceCtrlReadBufferNegative() и sceCtrlPeekBufferNegative(), взяв их из того же JoySens. Только сделал так, чтобы входными данными внутри них были последние присланные в PSP данные о состоянии геймпада, подключенного к ПК-хосту. Вот архив со всеми нужными бинарниками и исходниками. Перед запуском ПК-части программы нужно установить драйвера USB. Сначала нужно запустить плагин на PSP (как запустить плагин можно узнать, погуглив в яндексе). Потом перезагрузить PSP и подключить ее к ПК. Должно обнаружиться устройство PSP Type B. Далее скачиваем драйвера. Устанавливаем драйвера через мастер (bin\inf-wizard.exe), указывая наше устройство PSP Type B и говоря в конце установить драйвер.

Подготовка минимальной версии PSP-части

Все бы хорошо, но в сети есть исходники только на версию 0.19 RemoteJoyLite. А она некорректно работает на некоторых играх (например K-On! дико тормозит, а в Dungeon Siege появляются графические артефакты). В версии 0.20 это, как говорят, исправили, но исходников этой версии в открытом доступе нет. Поэтому было решено модифицировать протокол данных, передающихся по USB, чтобы передавать только минимум информации о состоянии геймпада, а также минимизировать размер исходника PSP-части. Из протокола были удалены все данные, передающиеся от PSP в ПК, и оставлена только одна структура, передающаяся от ПК в PSP, в результате чего тормоза и артефакты канули в небытие:


Аналоговые данные со стика в самой PSP представлены в виде однобайтового беззнакового целого для каждой оси (127 — центр), а 4 байта в протоколе выделено из-за желания даже не думать про проблемы упаковывания и выравнивания структур, т.к. в самом RemoteJoyLite данные упаковываются следующим образом:


Где module_start() — функция, вызываемая в отдельном потоке при запуске плагина пиратской прошивкой. Также при запуске драйвера происходит создание флаговой переменной типа int (т.е. 32 флага) с доступом через уникальный идентификатор объекта в операционной системе PSP и запуск вспомогательного потока:


Так вот, а вызываемый UsbAttach() устанавливает флаг USB_EVENT_ATTACH во флаговой переменной объекта UsbMainEventFlag:


При этом в предварительно созданном при вызове UsbStartFunc() потоке UsbMainThread() написано:


А это значит, что поток в бесконечном цикле ждет установки флага USB_EVENT_ATTACH или флага USB_EVENT_ASYNC во флаговой переменной объекта UsbMainEventFlag. Успешная установка связи с USB-хостом вызвала установку флага USB_EVENT_ATTACH, по которому этот поток выполняет асинхронный запрос на прием пакета данных по USB, при этом сбрасывая флаг USB_EVENT_ASYNC:


В этом запросе callback-ом устанавливается вызов функции UsbAsyncReqDone():


Эта функция, как мы видим, по завершению приема пакета данных от USB-хоста (обрабатываемого ядром операционной системы PSP по прерыванию от USB-контроллера PSP) выставляет флаг USB_EVENT_ASYNC во флаговой переменной объекта UsbMainEventFlag. По нему наш бесконечный цикл выставляет новый асинхронный запрос данных. Такой механизм событий позволяет не тратить процессорное время впустую на бесконечный опрос флага готовности данных, поскольку при вызове sceKernelWaitEventFlag() потоку не выделяются кванты времени до тех пор, пока не наступит необходимое событие — это обеспечивает планировщик потоков внутри операционной системы PSP, да и вообще этот базовый принцип работает в любой многозадачной операционной системе.

Написание сервиса для работы с USB для Linux под Raspberry Pi

Итак, PSP-часть завершена. Теперь время для разработки приложения, а точнее сервиса, который будет запускаться автоматически при включении Raspberry Pi под Linux. Вообще, для Raspberry Pi существует несколько адаптированных дистрибутивов Linux. Но я остановился на Fedora, т.к. он черпает свои корни от Red Hat, с которым я банально имел дело по работе и привык к его RPM дистрибуции пакетов. Сразу после установки Fedora Remix 18 и, в случае необходимости, настройки сети (в моем случае нужно было руками прописать сетевой адрес и шлюз, т.к. DHCP-сервер в домашней сети работает некорректно), которая делается интуитивно — подключив мышь и кликнув на значок сетевого соединения в правом верхнем углу, прямо из коробки работает SSH-сервер. А вот SMB-сервер оперативно настроить не удалось (проблемы с smbpasswd), поэтому исходник создавался и редактировался удаленно по SSH через midnight commander. Первое, с чего я начал, это подключение к PSP. Для этого нужно было узнать, как в Linux взаимодействовать с USB. В связи с этим произошла небольшая неприятная история, из-за которой, в очередной раз, у меня перед глазами рушится весь шарм линукса. Дело в том, что при попытке установить библиотеку и заголовочник для компиляции через


менеджер пакетов поругался и сказал что он устарел, используй libusbx. Хорошо, команда


скачала необходимые файлы. Но дело то в том, что libusbx по api-вызовам несовместим с libusb1, который одинаков с windows-версией libusb, которая, в свою очередь, использовалась в оригинальных исходниках RemoteJoyLite, да и вообще отлично работает под Windows. Но, ладно. С usb разобрались, теперь перейдем к доступу к геймпаду из под линукс. У меня в распоряжении есть проводной геймпад от Xbox 360, который отлично чувствует себя в Windows, и, на удивление, заработал из коробки в Fedora Remix 18 на Raspberry Pi, создав устройство /dev/input/js0. Это отработал штатный драйвер xpad. Существует альтернативный драйвер xboxdrv — он более гибок в конфигурировании. Но нам хватит и штатного.

Драйвер xpad входит в состав ядра Linux для андроида:


И точно так же создается устройство /dev/input/js0:


Например рассмотрим, как происходит получение списка устройств ввода в андроиде. Рекомендуемое api говорит нам для этого вызвать getDeviceIds(), в котором написано:


Тут вступает в дело сервис InputManager:


getId() приводит нас уже туда, где мы были (андроид удивителен):


В нативной части андроида экземпляр InputDevice() создается здесь (спасибо оперативному ответу с тостера):


Эта функция вызывается здесь:


Вызов функции notifyInputDevicesChanged() определен колбэком опять в уже знакомом сервисе InputManager:


Вызов самого колбэка инициируется в InputReader:


Так же здесь мы видим, что события от устройства ввода принимаются классом EventHubInterface:


И, в итоге, в реализации этого класса EventHub.cpp идет открытие и работа с устройством из /dev/input, как и в обычном Linux Fedora в Raspberry Pi:


А вообще, про всю эту систему ввода в андроиде вкратце объяснено в самих исходниках здесь:

Итак, итоговый исходный код сервиса имеет следующий вид:

Вот ссылка на двоичный файл сервиса. А вот также содержимое скрипта компиляции m.sh:


По самому исходнику хотелось бы отметить два момента. Во-первых, аналоговые стики Xbox имеют точность 16 бит, в то время как стик PSP имеет точность 8 бит. В связи с этим пакет я шлю по изменению приведенного к 8 битам значения осей, а не по изменению исходных данных от контроллера Xbox. Во-вторых, в PSP значение диагоналей соответствует полной шкале (т.е. круглый стик PSP с точки зрения шкалы — это квадрат), а в Xbox, как и положено, половине шкалы:


Поэтому введен линейно увеличивающийся (чем больше отклонение от центра оси контроллера Xbox, тем больше) коэффициент с максимумом в 1.4 (хотя, как выяснилось позже, правильно было бы определять значение угла, и чем ближе угол к диагонали, тем больше делать коэффициент). С этими значениями геймпад Xbox ощущается без какого то ни было дискомфорта, хоть чисто технически чувствительность и получилась загрубленной. В Doom 0.05 управлять удобно, в Dungeon Siege все три скорости перемещения (в зависимости от силы отклонения стика) работают и ощущаются как на самой PSP. Ибо, при столкновении с проблемой, в начале был опробован простой коэффициент (и 1.5, и 1.4), без линейного увеличения в зависимости от отклонения, и в названных играх ощущался резкий дискомфорт — играть было невозможно.

Добавление собственного сервиса в автозагрузку в Fedora Remix 18 для Raspberry Pi

Поверхностное гугление по вопросу добавления программы в автозагрузку в Linux дает в основном рекомендации по модификации скрипта init rc. Но в нашем случае нужно поступить по-другому.

1. Сначала нужно скопировать наш сервис xbox2psp.o в /usr/local/bin и установить ему права запуска(все три бита).

2. Затем создать файл /lib/systemd/system/xbox2psp.service следующего содержания:

3. Перейти в папку /etc/systemd/system/ и создать ссылку командой

4. Перезагрузить конфигурацию демона автозагрузки:

5. Активировать автозапуск нового сервиса

6. При необходимости можно сразу запустить сервис командой

В итоге мы получили удобную возможность управлять PSP при помощи геймпада от Xbox 360. При желании этот проект можно модифицировать для подключения например Dualshock 3 по Bluetooth.
UDP 15.11.2020 обновлены ссылки на файлы

image

Вы — счастливый владелец консоли Sony PSP? Я расскажу Вам, как без лишних затрат всего за несколько минут обзавестись еще и пультом д\у для Вашего компьютера. А потратив еще немного времени, можно получить отличный геймпад.

Реализовать данную затею можно двумя способами: дешевым и относительно-недорогим.

В первом случае, консоль будет работать посредством mini-usb кабеля. Очевидно, что рассчитывать на «переключить музыку с дивана» не придется (хотя, конечно-же, можно и удлинитель пробросить =) ). Зато получится вполне удобный геймпад.
Для второго случая нам дополнительно понадобится Wi-Fi роутер (благо, есть у каждого третьего). Таким образом, Ваш пульт станет полноценным, а геймпад — еще более удобным.
Примечание: неважно, есть ли WiFi на самом компьютере. К роутеру можно подключиться и обычной витой парой. Главное, чтобы компьютер оказался в одной сети с PSP.

Я использую PSP Slim&lite, ноутбук с Windows 7 на борту и роутер D-Link DI-524.

Шаг 1: Установка всего необходимого

image

  • Консоль «Playstation Portable» с custom-прошивкой (например, 5.03 Gen-C).
  • Windows 7/Vista.
  • Mini-USB кабель для подключения консоли.
  • Wi-Fi роутер (для второго способа)
  • Программа «PSPdisp»
  1. Подключаем PSP с помощью кабеля mini-usb.
  2. Запускаем инсталлятор PSPdisp.
  3. Установку выполняем с параметрами по-умолчанию.
  4. Подтверждаем установку не подписанных драйверов.
  5. В процессе установки программа обнаружит консоль и запросит разрешение на копирование утилиты на карту памяти. Если этого не произошло, указываем путь к папке X:/PSP/GAME вручную.
  6. Завершаем установку PSPdisp.

Шаг 2: Настройка

image

  1. Отключаем PSP от компьютера.
  2. Включаем PSP.
  3. Заходим в «Игры — Memory Stick», запускаем PSPdisp (должна стать первой в списке).
  4. Программа должна выдать такое:
  5. Жмем треугольник. Вписываем внутренний ip-адрес вашего компьютера (например, 192.168.0.3).
  6. Выбираем способ подключения. Если выбрали USB — вставляем назад кабель в PSP и компьютер. Если WiFi — появиться стандартный диалог подключения консоли к WiFi-точке.
Для WiFi-подключения:
  1. В системном трее Windows находим значок PSPDisp, жмем правой кнопкой. В меню выбираем «Options — Use wireless LAN».
  2. В меню выбираем пункт «Enabled». Программа сообщит внутренний ip-адрес компьютера и попросит подключаться по нему.

Шаг 3: Завершающий этап. Проверка

image

  • Жмем правой кнопкой на PSPdisp в трее. Выбираем «Control — Mouse emulation».

  • Проверяем работоспособность наших махинаций: подвигайте аналогом. Курсор должен передвигаться. На экран PSP должна выводиться часть изображения возле курсора. «Крестик» эмулирует нажатие правой кнопкой мыши, «квадрат» — левой.

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

На данном этапе первая часть топика заканчивается. В следующей части я опишу подробную настройку PSPDisp, программирование кнопок под конкретные действия. В качестве примера, опишу настройку под Windows Media Center и Aimp. Также покажу, как же сделать из PSP полноценный геймпад (на примере игры «Need for speed: Underground 2»).

В портативную игровую консоль PlayStationPortable можно играть и вдвоем, используя для управления специальные джойстики. Это доступно не для каждой модели устройства.

Как играть в PSP джойстиками

  • Как играть в PSP джойстиками
  • Как на PSP включить игру
  • Как соединить две psp

Убедитесь в том, что игра, в которую вы хотите играть вдвоем с другим человеком, поддерживает режим «Мультплеер». Это делается через ее главное меню. Подключите джойстики к боковым разъемам портативной приставки PlayStationPortable, обратите внимание, что в некоторых случаях для осуществления функций управления игровым процессом в таком режиме необходима установка специального программного обеспечения, например, Dualshock или его аналогов.

Зайдите в режим игры «Мультплеер», после чего укажите количество игроков согласно количеству джойстиков. Примените изменения и запустите игру. Обратите внимание, что это далеко не самый удобный способ командной игры на приставке PlayStationPortable, поскольку от такого просмотра игры на экране зрение может значительно ухудшиться.

Если вы хотите играть в игру в режиме «Мультплеер» на вашей игровой консоли PlayStationPortable, воспользуйтесь подключением и обменом данных между владельцами данных приставок посредством беспроводной связи, к примеру, Wi-Fi или Bluetooth. В этом случае неудобство возникает с количеством игровых дисков, поскольку диск с игрой должен в обязательном порядке находиться в UMD-приводе вашей PlayStationPortable.

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

Читайте также: