Sega Mega Drive和Raspberry Pi第1部分的游戏手柄(预备和三键)

秋天到了白菜开花了快到了冬天,我刚把它弄乱了。 但是,您还是想玩一些古老的音乐,比如窗外的暴风雪,例如Sonic或Jim的蠕虫。 本文底部是具有初步结果的视频。



如果您在模拟器上玩过SMD游戏,您可能会注意到,这些游戏最方便的游戏手柄是SMD的本机游戏手柄。 对于大多数其他游戏机,在模拟器上玩游戏时,很有可能使用相同的Xbox或Logitech游戏手柄,该标准是在90年代末左右形成的。 但是直到90年代末,每个人都尽其所能。

从SMD购买游戏手柄并不难,通常,您可以在游戏机本身的克隆品以相当实惠的价格出售的情况下购买,大约300卢布。

和以前一样,我使用了退役机壳和爸爸DB-9连接器上的USB电缆来组织与Raspberry pi的连接。 GPIO在程序中绘制了结论。 游戏手柄从3.3伏特起即可正常工作。



与往常一样,选择仿真器引起了问题,最好的选择是仿真器-Picodrive,它针对ARM进行了优化,结构合理,据我所知,它是RetroPi组件的一部分。 但是在集会上,我不得不稍作修改。 源代码位于Github服务上的此地址

要进行构建,我们需要从模拟器作者的存储库中获得3个成功要素:

  1. Picodrive仿真器本身;
  2. CPU仿真器-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.cmemory.cmemory.h 。 可能您可以使用较小的数字,然后将所有内容都填充为一个,但是在我看来,这更容易。
因此,在pico.c文件中我初始化了库并初始配置了GPIO引脚。

我将立即给出部分文件头:

 #include "pico_int.h" #include "sound/ym2612.h" #include <wiringPi.h> #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库的标题为set ,并定义了一些定义,它们的显示位置略低一些。 好吧,例如,现在在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),一个控制器(Selest)和电源。

接下来,我们有相同的定义-定义,我们需要再次重复。 这可以在memory.hmemory.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,开始。 当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。

这是工作的结果:


在下一个系列中继续, Pip-Pip-Pip

Source: https://habr.com/ru/post/zh-CN423565/


All Articles