Геймпад от Sega Mega Drive и Raspberry Pi Часть 1 (подготовительная и трёхкнопочная)

Если Вы играли на эмуляторе в игры от SMD, то наверно заметили, что самым удобным гейм-падом для этих игр является родной геймпад от SMD. Для большинства остальных приставок, при игре на эмуляторе, вполне можно обойтись тем же геймпадом от Xbox или Logitech, стандарт сформировался примерно в конце 90-х. А вот до конца 90-х, каждый изголялся как мог. Приобрести геймпад от SMD не сложно, и как правило купить его можно там где продают сами клоны приставок, по достаточно демократичной цене, примерно в пределах 300 рублей.
Подключение к Raspberry pi я, как и раньше, организовал при помощи usb шлейфа из списанного корпуса и разъёма DB-9 папа. А выводы GPIO расписал в программе. Геймпад прекрасно работает от 3,3 Вольт.

Как всегда встал вопрос о выборе эмулятора, и наиболее лучшим вариантом стал эмулятор — Picodrive, он оптимизирован для ARM, хорошо структурирован и насколько я понял, он входит в состав сборки RetroPi. Но со сборкой пришлось немного повозиться. Располагается исходный код на сервисе Github, по этому адресу.
Для сборки нам понадобятся 3 составляющие успеха из репозитория автора эмулятора:
1 Сам эмулятор Picodrive;
2 Эмулятор центрального процессора — cyclone68000;
3 И FrontEnd — Libpicofe.
Теперь это всё надо правильно скомпоновать. Распаковываем или не распаковываем Picodrive, в зависимости от того, как скачивали. Теперь открываем директорию с cyclone68000, её содержимое надо скопировать в директорию:
/ваша директория/picodrive-master/cpu/cyclone
Так же надо поступить с содержимым директории Libpicofe, его содержимое копируется в директорию:
/ваша директория/picodrive-master/platform/libpicofe
Теперь необходимо выполнить подготовку к сборке:
производим конфигурацию
sudo ./configure
После того, как конфигурация будет закончена, будет создан файл — config.mak, в нём надо будет найти и изменить некоторые строки. Ниже приведён готовый результат:
AS = arm-linux-as LDLIBS += -L/usr/lib/arm-linux-gnueabihf -lSDL -lasound -lpng -lm -lz -lwiringPi ARCH = arm PLATFORM = rpi1
Далее необходимо отредактировать файл — config.h. Он находится в директории:
/ваша директория/picodrive-master/cpu/cyclone
В нём надо проставить единички в переменных:
#define HAVE_ARMv6 1 #define CYCLONE_FOR_GENESIS 1
А теперь программная часть
Как всегда надо было найти место, где обрабатывается информация о нажатых кнопках, понять и простить код и подменить его.
Не нагоняя саспенса сразу скажу, что искомые файлы располагаются в директории:
/ваша директория/picodrive-master/pico/
Здесь нас интересуют 3 файла — pico.c, memory.c, memory.h. Наверно можно обойтись меньшим числом, и всё запихать в один, но мне так показалось проще.
И так, в файле pico.c я произвожу инициализацию библиотеки и начальную настройку пинов GPIO.
Сразу приведу часть заголовока файла:
#include "pico_int.h" #include "sound/ym2612.h" #include #define Data0 3 #define Data1 4 #define Data2 5 #define Data3 12 #define Data4 13 #define Data5 10 #define Select 6 struct Pico Pico; struct PicoMem PicoMem; PicoInterface PicoIn;
Как видно, задан заголовочник библиотеки WiringPi, и объявлены дефайны, которые пондобятся чуть ниже. Ну например сейчас в функции void PicoInit(void):
void PicoInit(void) { ... ... PicoDraw2Init(); wiringPiSetup (); pinMode (Select, OUTPUT); pinMode (Data0, INPUT); pinMode (Data1, INPUT); pinMode (Data2, INPUT); pinMode (Data3, INPUT); pinMode (Data4, INPUT); pinMode (Data5, INPUT); digitalWrite (Select, HIGH); }
Это функция инициализации памяти эмулятора (вроде). И вот именно сюда я вставил все настройки выводов GPIO.Вот тут дана распиновка разъёма DB-9
Тут надо сказать, что у геймпада имеется 6 информационных контактов (Data0…Data5), один управляющий (Seleсt), и питание.
Далее, нам эти же определения — define, нужно повторить ещё раз. Это можно сделать как и в memory.h, так и в memory.c. Я выбрал первый вариант. Нет смысла приводить листинг этого.
Вот мы и подбираемся к самому интересному — файлу memory.c. В нём имеются 2 функции с красноречивыми названиями:
static u32 read_pad_3btn(int i, u32 out_bits) static u32 read_pad_6btn(int i, u32 out_bits)
Названия как бы ненавязчиво намекают на чтение состояния 3-х кнопочных и 6-и кнопочных геймпадов.
Тут надо пояснить, что любой 6-и кнопочный геймпад может работать как 3-х кнопочный. И львиная часть игр работает именно с таким режимом геймпада. В этом режиме, один раз в 16 миллисекунд меняется состояние выхода Select. Когда Select = 0, читаются значения кнопок — UP, DOWN, A, Start. Когда Select = 1 читается состояние кнопок — UP, DOWN, LEFT, RIGHT, B, C. Ниже пример работы этого режима.
Сразу приведу листинг этой функции с изменениями:
static u32 read_pad_3btn(int i, u32 out_bits) { u32 pad = ~PicoIn.padInt[i]; // Get inverse of pad MXYZ SACB RLDU u32 value = 0; if (i == 0 && (out_bits & 0x40)) // TH { digitalWrite (Select, HIGH); delayMicroseconds (20); value ^= digitalRead(Data0) << 0; //read UP button value ^= digitalRead(Data1) << 1; //read DOWN button value ^= digitalRead(Data2) << 2; //read LEFT button value ^= digitalRead(Data3) << 3; //read RIGHT button value ^= digitalRead(Data4) << 4; //read B button value ^= digitalRead(Data5) << 5; //read C button } if (i == 0 && !(out_bits & 0x40)) { digitalWrite (Select, LOW); delayMicroseconds (20); value ^= digitalRead(Data0) << 0; //read UP button value ^= digitalRead(Data1) << 1; //read DOWN button value ^= digitalRead(Data4) << 4; //read A button value ^= digitalRead(Data5) << 5; //read Start button } if (i == 1 && (out_bits & 0x40))// TH { value = pad & 0x3f; // ?1CB RLDU } if (i == 1 && !(out_bits & 0x40)) { value = ((pad & 0xc0) >> 2) | (pad & 3); // ?0SA 00DU } return value; }
Здесь i — это номер геймпада, а выражение if (out_bits & 0x40) // TH — как раз отвечает за состояние выхода Select. Стоит обратить внимание, что в эмуляторе состояние кнопок отдаётся в таком же виде, как и в приставке. Нажатая кнопка = 0.
Вот результат работы:
Продолжение в следующей серии, Пип-Пип-Пип.
Источник
Хакер взламывает актуальную прошивку PS5, которая нужна для запуска GTA VI, а в системе нашли новую уязвимость
Новых героев Gears of War: E-Day раскритиковали, а бывший продюсер объяснила, в чем проблема
Games Workshop показала семь новых батлфорсов для настольной игры Warhammer 40,000
Бомбора» представила новую обложку книги «Heroes of Might and Magic. Пошаговая история бессмертной серии
От «Метро» до «Детства»: как видеоигры торгуют нашим прошлым
Capcom чуть не лишилась Resident Evil: разработка седьмой части шла не по плану
Сотрудник магазина видеоигр во Франции преградил путь мародёрам, а видео с этим распространилось в сети
Косплеерша показала образ Анны-Генриетты из «Ведьмака 3», справедливой, но скорой на расправу княгини Туссента