利用F1C200S从零制作掌机之debian文件体系完善NES

打印 上一主题 下一主题

主题 1788|帖子 1788|积分 5364

一、模仿器源码

源码:https://files.cnblogs.com/files/twzy/arm-NES-linux-master.zip
二、文件体系

文件体系:debian bullseye
利用builtroot2018构建的文件体系,利用InfoNES模仿器存在bug,搞不定,以是放弃,改用debian。
三、编译

在debian文件体系下编译,在f1c200s开发板实验
解压源码进入Linux目录,不用做修改实验make编译。
编译后在f1c200s开发板实验,屏幕可见画面。
启动debian模仿器
mount_debian.sh
  1. #/bin/bash
  2. cd rootfs
  3. sudo mount --bind /dev dev/
  4. sudo mount --bind /sys sys/
  5. sudo mount --bind /proc proc/
  6. sudo mount --bind /dev/pts dev/pts/
  7. sudo cp /usr/bin/qemu-arm-static  usr/bin/
  8. cd ..
  9. sudo LC_ALL=C LANGUAGE=C LANG=C chroot rootfs
复制代码
编译:
  1. cd /home/arm-NES-linux/linux && make
复制代码
退出debian模仿器
unmount_debian.sh
  1. sudo rm rootfs/usr/bin/qemu-arm-static #删除之前拷贝的文件
  2. cd rootfs
  3. sudo umount   dev/pts/ # 一定要在/dev前面umount
  4. sudo umount   dev/
  5. sudo umount   sys/
  6. sudo umount   proc/
复制代码
四、适配遥控

builtroot制作的文件体系下调试驱动。
在debian体系下利用:evtest下令
这里利用无线手柄:
在下令行实验:evtest,利用无线手柄可发现有按键变乱上报。

修改NES模仿器源码linux目录下的joypad_input.cpp,使其适配自己的无线手柄。
修改一
  1. int InitJoypadInput(void)
  2. {
  3.         int iErr = 0;
  4.         //iErr = RegisterJoypadInput(&joypadInput);
  5.         iErr = RegisterJoypadInput(&usbJoypadInput);    // 只注册这个输入
  6.         return iErr;
  7. }
复制代码
修改二
  1. static int USBjoypadGet(void)
  2. {
  3.         /**
  4.          * FC手柄 bit 键位对应关系 真实手柄中有一个定时器,处理 连A  连B
  5.          * 0  1   2       3       4    5      6     7
  6.          * A  B   Select  Start  Up   Down   Left  Right
  7.          */
  8.         //因为 USB 手柄每次只能读到一位键值 所以要有静态变量保存上一次的值
  9.         static unsigned char joypad = 0;
  10.         struct input_event e;
  11.         if(0 < read (USBjoypad_fd, &e, sizeof(e)))
  12.         {
  13.                 if(0x3 == e.type)
  14.                 {
  15.                         /*
  16.                         上:
  17.                         value:0x8001 type:0x2 number:0x5
  18.                         value:0x0 type:0x2 number:0x5
  19.                         */
  20.                         if(17 == e.code && -1 == e.value)
  21.                         {
  22.                                 joypad |= 1<<4;
  23.                         }
  24.                         /*下:
  25.                         value:0x7fff type:0x2 number:0x5
  26.                         value:0x0 type:0x2 number:0x5
  27.                         */
  28.                         if(17 == e.code && 1 == e.value)
  29.                         {
  30.                                 joypad |= 1<<5;
  31.                         }
  32.                         //松开
  33.                         if(17 == e.code && 0 == e.value)
  34.                         {
  35.                                 joypad &= ~(1<<4 | 1<<5);
  36.                         }
  37.                        
  38.                         /*左:
  39.                         value:0x8001 type:0x2 number:0x4
  40.                         value:0x0 type:0x2 number:0x4
  41.                         */
  42.                         if(16 == e.code && -1 == e.value)
  43.                         {
  44.                                 joypad |= 1<<6;
  45.                         }
  46.                        
  47.                         /*右:
  48.                         value:0x7fff type:0x2 number:0x4
  49.                         value:0x0 type:0x2 number:0x4
  50.                         */
  51.                         if(16 == e.code && 1 == e.value)
  52.                         {
  53.                                 joypad |= 1<<7;
  54.                         }
  55.                         //松开
  56.                         if(16 == e.code && 0 == e.value)
  57.                         {
  58.                                 joypad &= ~(1<<6 | 1<<7);
  59.                         }
  60.                 }
  61.                 if(0x1 == e.type)
  62.                 {
  63.                         /*选择:
  64.                         value:0x1 type:0x1 number:0xa
  65.                         value:0x0 type:0x1 number:0xa
  66.                         */
  67.                         if(314 == e.code && 1 == e.value)
  68.                         {
  69.                                 joypad |= 1<<2;
  70.                         }
  71.                         if(314 == e.code && 0 == e.value)
  72.                         {
  73.                                 joypad &= ~(1<<2);
  74.                         }
  75.                        
  76.                         /*开始
  77.                         value:0x1 type:0x1 number:0xb
  78.                         value:0x0 type:0x1 number:0xb
  79.                         */
  80.                         if(315 == e.code && 1 == e.value)
  81.                         {
  82.                                 joypad |= 1<<3;
  83.                         }
  84.                         if(315 == e.code && 0 == e.value)
  85.                         {
  86.                                 joypad &= ~(1<<3);
  87.                         }
  88.                         /*A
  89.                         value:0x1 type:0x1 number:0x0
  90.                         value:0x0 type:0x1 number:0x0
  91.                         */
  92.                         if(304 == e.code && 1 == e.value)
  93.                         {
  94.                                 joypad |= 1<<0;
  95.                         }
  96.                         if(304 == e.code && 0 == e.value)
  97.                         {
  98.                                 joypad &= ~(1<<0);
  99.                         }
  100.                         /*B
  101.                         value:0x1 type:0x1 number:0x1
  102.                         value:0x0 type:0x1 number:0x1
  103.                         */
  104.                         if(305 == e.code && 1 == e.value)
  105.                         {
  106.                                 joypad |= 1<<1;
  107.                         }
  108.                         if(305 == e.code && 0 == e.value)
  109.                         {
  110.                                 joypad &= ~(1<<1);
  111.                         }
  112.                         /*X
  113.                         value:0x1 type:0x1 number:0x3
  114.                         value:0x0 type:0x1 number:0x3
  115.                         */
  116.                         if(307 == e.code && 1 == e.value)
  117.                         {
  118.                                 joypad |= 1<<0;
  119.                         }
  120.                         if(307 == e.code && 0 == e.value)
  121.                         {
  122.                                 joypad &= ~(1<<0);
  123.                         }
  124.                         /*Y
  125.                         value:0x1 type:0x1 number:0x4
  126.                         value:0x0 type:0x1 number:0x4
  127.                          */
  128.                          if(308 == e.code && 1 == e.value)
  129.                         {
  130.                                 joypad |= 1<<1;
  131.                         }
  132.                         if(308 == e.code && 0 == e.value)
  133.                         {
  134.                                 joypad &= ~(1<<1);
  135.                         }
  136.                 }
  137.                 return joypad;
  138.         }
  139.         return -1;
  140. }
复制代码
修改三
  1. static void *InputEventTreadFunction(void *pVoid)
  2. {
  3.         /* 定义函数指针 */
  4.         int (*GetJoypad)(void);
  5.         GetJoypad = (int (*)(void))pVoid;
  6.         while (1)
  7.         {
  8.                 //因为有阻塞所以没有输入时是休眠
  9.                 //g_InputEvent = GetJoypad();
  10.                 int data = GetJoypad();
  11.                 if (data == -1)
  12.                 {
  13.                         continue;
  14.                 }
  15.                 else
  16.                 {
  17.                         g_InputEvent = data;
  18.                 }
  19.                 //有数据时唤醒
  20.                 pthread_mutex_lock(&g_tMutex);
  21.                 //因为有阻塞所以没有输入时是休眠
  22.                 pthread_cond_signal(&g_tConVar);
  23.                 pthread_mutex_unlock(&g_tMutex);
  24.         }
  25. }
复制代码
五、测试游戏是否可以正常玩耍

可以无声音畅玩了。

六、先解决debian体系下的语音播放

查抄声卡
  1. cat /proc/asound/cards
复制代码
默认声卡配置
vi /etc/asound.conf
  1. defaults.ctl.card 0
  2. defaults.pcm.card 0
  3. defaults.timer.card 0
复制代码
  1. amixer controls 用于查看音频系统提供的操作接口
  2. amixer contents 用于查看接口配置参数
  3. amixer cget + 接口函数
  4. amixer cset + 接口函数 + 设置值
  5. amixer cget numid=14,iface=MIXER,name='ADC Mixer Mic Capture Switch'
  6. amixer cset numid=14,iface=MIXER,name='ADC Mixer Mic Capture Switch' on
  7. 打开之后才可以录音
  8. arecord out.wav
复制代码
  1. root@wang-virtual-machine:~# arecord out.wav
  2. Recording WAVE 'out.wav' : Unsigned 8 bit, Rate 8000 Hz, Mono
  3. ^CAborted by signal Interrupt...
  4. root@wang-virtual-machine:~#
  5. root@wang-virtual-machine:~#
  6. root@wang-virtual-machine:~# aplay out.wav
  7. Playing WAVE 'out.wav' : Unsigned 8 bit, Rate 8000 Hz, Mono
  8. ^CAborted by signal Interrupt...
复制代码
七、解决NES模仿器的声音

启动游戏会出现七零八落的声音,也不知道对不对。在NES中是通过一些PCM的API利用音频的,具体的看代码吧。
八、mplayer播放音频

mplayer -ao alsa out.wav 特别慢有声音
mplayer -ao alsa test.wav
mplayer -ao alsa test.mp3
  1. root@wang-virtual-machine:/home# mplayer -ao alsa test.mp3
  2. MPlayer 1.4 (Debian), built with gcc-10 (C) 2000-2019 MPlayer Team
  3. do_connect: could not connect to socket
  4. connect: No such file or directory
  5. Failed to open LIRC support. You will not be able to use your remote control.
  6. Playing test.mp3.
  7. libavformat version 58.45.100 (external)
  8. Audio only file format detected.
  9. Load subtitles in ./
  10. ==========================================================================
  11. Opening audio decoder: [mpg123] MPEG 1.0/2.0/2.5 layers I, II, III
  12. AUDIO: 16000 Hz, 2 ch, s16le, 16.0 kbit/3.12% (ratio: 2000->64000)
  13. Selected audio codec: [mpg123] afm: mpg123 (MPEG 1.0/2.0/2.5 layers I, II, III)
  14. ==========================================================================
  15. AO: [alsa] 16000Hz 2ch s16le (2 bytes per sample)
  16. Video: no video
  17. Starting playback...
  18. A:   3.1 (03.0) of 3.0 (03.0) 12.7%
  19. Exiting... (End of file)
复制代码
有办法去掉connect to socket吗?
是遥控器,通过配置去掉。
  1. vi /etc/mplayer/mplayer.conf
  2. lirc=no
复制代码
但依然还是很慢。能正常利用。
九、参考

https://zhuanlan.zhihu.com/p/670785159

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

罪恶克星

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表