使用F1C200S从零制作掌机之debian文件系统完善NES
一、模拟器源码
源码: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
#/bin/bash
cd rootfs
sudo mount --bind /dev dev/
sudo mount --bind /sys sys/
sudo mount --bind /proc proc/
sudo mount --bind /dev/pts dev/pts/
sudo cp /usr/bin/qemu-arm-static usr/bin/
cd ..
sudo LC_ALL=C LANGUAGE=C LANG=C chroot rootfs
编译:
cd /home/arm-NES-linux/linux && make
退出debian模拟器
unmount_debian.sh
sudo rm rootfs/usr/bin/qemu-arm-static #删除之前拷贝的文件
cd rootfs
sudo umount dev/pts/ # 一定要在/dev前面umount
sudo umount dev/
sudo umount sys/
sudo umount proc/
四、适配遥控
builtroot制作的文件系统下调试驱动。
在debian系统下使用:evtest命令
这里使用无线手柄:
在命令行执行:evtest,操作无线手柄可发现有按键事件上报。
修改NES模拟器源码linux目录下的joypad_input.cpp,使其适配自己的无线手柄。
修改一
int InitJoypadInput(void)
{int iErr = 0;//iErr = RegisterJoypadInput(&joypadInput);iErr = RegisterJoypadInput(&usbJoypadInput); // 只注册这个输入return iErr;
}
修改二
static int USBjoypadGet(void)
{/*** FC手柄 bit 键位对应关系 真实手柄中有一个定时器,处理 连A 连B * 0 1 2 3 4 5 6 7* A B Select Start Up Down Left Right*///因为 USB 手柄每次只能读到一位键值 所以要有静态变量保存上一次的值static unsigned char joypad = 0;struct input_event e;if(0 < read (USBjoypad_fd, &e, sizeof(e))){if(0x3 == e.type){/*上:value:0x8001 type:0x2 number:0x5value:0x0 type:0x2 number:0x5*/if(17 == e.code && -1 == e.value){joypad |= 1<<4;}/*下:value:0x7fff type:0x2 number:0x5value:0x0 type:0x2 number:0x5*/if(17 == e.code && 1 == e.value){joypad |= 1<<5;}//松开if(17 == e.code && 0 == e.value){joypad &= ~(1<<4 | 1<<5);}/*左:value:0x8001 type:0x2 number:0x4value:0x0 type:0x2 number:0x4*/if(16 == e.code && -1 == e.value){joypad |= 1<<6;}/*右:value:0x7fff type:0x2 number:0x4value:0x0 type:0x2 number:0x4*/if(16 == e.code && 1 == e.value){joypad |= 1<<7;}//松开if(16 == e.code && 0 == e.value){joypad &= ~(1<<6 | 1<<7);}}if(0x1 == e.type){/*选择:value:0x1 type:0x1 number:0xavalue:0x0 type:0x1 number:0xa*/if(314 == e.code && 1 == e.value){joypad |= 1<<2;}if(314 == e.code && 0 == e.value){joypad &= ~(1<<2);}/*开始value:0x1 type:0x1 number:0xbvalue:0x0 type:0x1 number:0xb*/if(315 == e.code && 1 == e.value){joypad |= 1<<3;}if(315 == e.code && 0 == e.value){joypad &= ~(1<<3);}/*Avalue:0x1 type:0x1 number:0x0value:0x0 type:0x1 number:0x0*/if(304 == e.code && 1 == e.value){joypad |= 1<<0;}if(304 == e.code && 0 == e.value){joypad &= ~(1<<0);}/*Bvalue:0x1 type:0x1 number:0x1value:0x0 type:0x1 number:0x1*/if(305 == e.code && 1 == e.value){joypad |= 1<<1;}if(305 == e.code && 0 == e.value){joypad &= ~(1<<1);}/*Xvalue:0x1 type:0x1 number:0x3value:0x0 type:0x1 number:0x3*/if(307 == e.code && 1 == e.value){joypad |= 1<<0;}if(307 == e.code && 0 == e.value){joypad &= ~(1<<0);}/*Yvalue:0x1 type:0x1 number:0x4value:0x0 type:0x1 number:0x4*/if(308 == e.code && 1 == e.value){joypad |= 1<<1;}if(308 == e.code && 0 == e.value){joypad &= ~(1<<1);}}return joypad;}return -1;
}
修改三
static void *InputEventTreadFunction(void *pVoid)
{/* 定义函数指针 */int (*GetJoypad)(void);GetJoypad = (int (*)(void))pVoid;while (1){//因为有阻塞所以没有输入时是休眠//g_InputEvent = GetJoypad();int data = GetJoypad();if (data == -1){continue;}else{g_InputEvent = data;}//有数据时唤醒pthread_mutex_lock(&g_tMutex);//因为有阻塞所以没有输入时是休眠pthread_cond_signal(&g_tConVar);pthread_mutex_unlock(&g_tMutex);}
}
五、测试游戏是否可以正常玩耍
可以无声音畅玩了。
六、先解决debian系统下的语音播放
检查声卡
cat /proc/asound/cards
默认声卡配置
vi /etc/asound.conf
defaults.ctl.card 0
defaults.pcm.card 0
defaults.timer.card 0
amixer controls 用于查看音频系统提供的操作接口
amixer contents 用于查看接口配置参数
amixer cget + 接口函数
amixer cset + 接口函数 + 设置值amixer cget numid=14,iface=MIXER,name='ADC Mixer Mic Capture Switch'
amixer cset numid=14,iface=MIXER,name='ADC Mixer Mic Capture Switch' on
打开之后才可以录音
arecord out.wav
root@wang-virtual-machine:~# arecord out.wav
Recording WAVE 'out.wav' : Unsigned 8 bit, Rate 8000 Hz, Mono
^CAborted by signal Interrupt...
root@wang-virtual-machine:~#
root@wang-virtual-machine:~#
root@wang-virtual-machine:~# aplay out.wav
Playing WAVE 'out.wav' : Unsigned 8 bit, Rate 8000 Hz, Mono
^CAborted by signal Interrupt...
七、解决NES模拟器的声音
启动游戏会出现乱七八糟的声音,也不知道对不对。在NES中是通过一些PCM的API操作音频的,具体的看代码吧。
八、mplayer播放音频
mplayer -ao alsa out.wav 特别慢有声音
mplayer -ao alsa test.wav
mplayer -ao alsa test.mp3
root@wang-virtual-machine:/home# mplayer -ao alsa test.mp3
MPlayer 1.4 (Debian), built with gcc-10 (C) 2000-2019 MPlayer Team
do_connect: could not connect to socket
connect: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.Playing test.mp3.
libavformat version 58.45.100 (external)
Audio only file format detected.
Load subtitles in ./
==========================================================================
Opening audio decoder: [mpg123] MPEG 1.0/2.0/2.5 layers I, II, III
AUDIO: 16000 Hz, 2 ch, s16le, 16.0 kbit/3.12% (ratio: 2000->64000)
Selected audio codec: [mpg123] afm: mpg123 (MPEG 1.0/2.0/2.5 layers I, II, III)
==========================================================================
AO: [alsa] 16000Hz 2ch s16le (2 bytes per sample)
Video: no video
Starting playback...
A: 3.1 (03.0) of 3.0 (03.0) 12.7%Exiting... (End of file)
有办法去掉connect to socket吗?
是遥控器,通过配置去掉。
vi /etc/mplayer/mplayer.conf
lirc=no
但依然还是很慢。能正常使用。
九、参考
https://zhuanlan.zhihu.com/p/670785159
相关文章:

使用F1C200S从零制作掌机之debian文件系统完善NES
一、模拟器源码 源码:https://files.cnblogs.com/files/twzy/arm-NES-linux-master.zip 二、文件系统 文件系统:debian bullseye 使用builtroot2018构建的文件系统,使用InfoNES模拟器存在bug,搞不定,所以放弃&…...

Vue 3 与 TypeScript:最佳实践详解
大家好,我是CodeQi! 很多人问我为什么要用TypeScript? 因为 Vue3 喜欢它! 开个玩笑... 在我们开始探索 Vue 3 和 TypeScript 最佳实践之前,让我们先打个比方。 如果你曾经尝试过在没有 GPS 的情况下开车到一个陌生的地方,你可能会知道那种迷失方向的感觉。 而 Typ…...
PyMysql error : Packet Sequence Number Wrong - got 1 expected 0
文章目录 错误一错误原因解决方案 错误二原因解决方案 我自己知道的,这类问题有两类原因,两种解决方案。 错误一 错误原因 pymysql的主进程启动的connect无法给子进程中使用,所以读取大批量数据时最后容易出现了此类问题。 解决方案 换成…...
MVC 生成验证码
在mvc 出现之前 生成验证码思路 在一个html页面上,生成一个验证码,在把这个页面嵌入到需要验证码的页面中。 JS生成验证码 <script type"text/javascript">jQuery(function ($) {/**生成一个随机数**/function randomNum(min, max) {…...

OSPF.综合实验
1、首先将各个网段基于172.16.0.0 16 进行划分 1.1、划分为4个大区域 172.16.0.0 18 172.16.64.0 18 172.16.128.0 18 172.16.192.0 18 四个网段 划分R4 划分area2 划分area3 划分area1 2、进行IP配置 如图使用配置指令进行配置 ip address x.x.x.x /x 并且将缺省路由…...

云计算【第一阶段(29)】远程访问及控制
一、ssh远程管理 1.1、ssh (secureshell)协议 是一种安全通道协议对通信数据进行了加密处理,用于远程管理功能SSH 协议对通信双方的数据传输进行了加密处理,其中包括用户登录时输入的用户口令,建立在应用层和传输层基础上的安全协议。SSH客…...
2024前端面试真题【CSS篇】
盒子模型 盒子模型:box-sizing,描述了文档中的元素如何生成矩形盒子,并通过这些盒子的布局来组织和设计网页。包含content、padding、margin、border四个部分。 分类 W3C盒子模型(content-box):标准盒子模…...
python中设置代码格式,函数编写指南,类的编程风格
4.6 设置代码格式 随着你编写的程序越来越长,确保代码格式一致变得尤为重要。花时间让代码尽可能易于阅读,这不仅有助于你理解程序的功能,也能帮助他人理解你的代码。 为了保证所有人的代码结构大致一致,Python程序员遵循一系列…...

CentOS 8升级gcc版本
1、查看gcc版本 gcc -v发现gcc版本为8.x.x,而跑某个项目的finetune需要gcc-9,之前搜索过很多更新gcc版本的方式,例如https://blog.csdn.net/xunye_dream/article/details/108918316?spm1001.2014.3001.5506,但执行指令 sudo yu…...

Kafka基础入门篇(深度好文)
Kafka简介 Kafka 是一个高吞吐量的分布式的基于发布/订阅模式的消息队列(Message Queue),主要应用与大数据实时处理领域。 1. 以时间复杂度为O(1)的方式提供消息持久化能力。 2. 高吞吐率。(Kafka 的吞吐量是MySQL 吞吐量的30…...
C++之复合资料型态KU网址第二部V蒐NAY3989
结构 结构可存放不同资料型态的数值,例如 #include <iostream>struct Demo {int member1;char *member2;float member3; };int main() {Demo d;d.member1 19823;d.member2 "203";d.member3 3.011;std::cout << "member1: " &l…...
乡镇集装箱生活污水处理设备处理效率高
乡镇集装箱生活污水处理设备处理效率高 乡镇集装箱生活污水处理设备优势 结构紧凑:集装箱式设计减少了占地面积,便于在土地资源紧张的乡镇地区部署。 安装方便:设备出厂前已完成组装和调试,现场只需进行简单的连接和调试即可投入使…...
计算机网络高频面试题
从输入URL到展现页面的全过程: 用户在浏览器中输入URL。浏览器解析URL,确定协议、主机名和路径。浏览器查找本地DNS缓存,如果没有找到,向DNS服务器发起查询请求。DNS服务器解析主机名,返回IP地址。浏览器使用IP地址建立…...

进程通信(1):无名管道(pipe)
无名管道(pipe)用来具有亲缘关系的进程之间进行单向通信。半双工的通信方式,数据只能单向流动。 管道以字节流的方式通信,数据格式由用户自行定义。 无名管道多用于父子进程间通信,也可用于其他亲缘关系进程间通信。 因为父进程调用fork函…...

YOLOv10改进 | 损失函数篇 | SlideLoss、FocalLoss、VFLoss分类损失函数助力细节涨点(全网最全)
一、本文介绍 本文给大家带来的是分类损失 SlideLoss、VFLoss、FocalLoss损失函数,我们之前看那的那些IoU都是边界框回归损失,和本文的修改内容并不冲突,所以大家可以知道损失函数分为两种一种是分类损失另一种是边界框回归损失,…...

【数组、特殊矩阵的压缩存储】
目录 一、数组1.1、一维数组1.1.1 、一维数组的定义方式1.1.2、一维数组的数组名 1.2、二维数组1.2.1、二维数组的定义方式1.2.2、二维数组的数组名 二、对称矩阵的压缩存储三、三角矩阵的压缩存储四、三对角矩阵的压缩存储五、稀疏矩阵的压缩存储 一、数组 概述:数…...

Flat Ads:金融APP海外广告投放素材的优化指南
在当今全球化的数字营销环境中,金融APP的海外营销推广已成为众多金融机构与开发者最为关注的环节之一。面对不同地域、文化及用户习惯的挑战,如何优化广告素材,以吸引目标受众的注意并促成有效转化,成为了广告主们亟待解决的问题。 作为领先的全球化营销推广平台,Flat Ads凭借…...

DBA 数据库管理 表管理 数据批量处理。表头约束
表管理 建库 库名命名规则:仅可以使用数字、字母、下划线、不能纯数字 不可使用MySQL命令或特殊字符 库名区分字母大小写 加if not exists 命令避免重名报错 create database if not exists gamedb; 建表 drop database if exists gamedb ; 删表…...

C# 上位机开发之旅-委托事件的那些事[2]
上位机项目开发过程,应该不少遇见界面同步实时刷新的情况,设备的运行情况以及设备数据的实时更新,应用场景非常之多。 那么这个时候,我们就可以用到C#语言中的一些关键功能来实现,比如事件,委托,…...

浏览器出现 502 Bad Gateway的原理分析以及解决方法
目录 前言1. 问题所示2. 原理分析3. 解决方法 前言 此类问题主要作为疑难杂症 1. 问题所示 2. 原理分析 502 Bad Gateway 错误表示服务器作为网关或代理时,从上游服务器收到了无效的响应 通常出现在充当代理或网关的网络服务器上,例如 Nginx、Apache…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
TCP/IP 网络编程 | 服务端 客户端的封装
设计模式 文章目录 设计模式一、socket.h 接口(interface)二、socket.cpp 实现(implementation)三、server.cpp 使用封装(main 函数)四、client.cpp 使用封装(main 函数)五、退出方法…...

GAN模式奔溃的探讨论文综述(一)
简介 简介:今天带来一篇关于GAN的,对于模式奔溃的一个探讨的一个问题,帮助大家更好的解决训练中遇到的一个难题。 论文题目:An in-depth review and analysis of mode collapse in GAN 期刊:Machine Learning 链接:...

使用ch340继电器完成随机断电测试
前言 如图所示是市面上常见的OTA压测继电器,通过ch340串口模块完成对继电器的分路控制,这里我编写了一个脚本方便对4路继电器的控制,可以设置开启时间,关闭时间,复位等功能 软件界面 在设备管理器查看串口号后&…...
ubuntu清理垃圾
windows和ubuntu 双系统,ubuntu 150GB,开发用,基本不装太多软件。但是磁盘基本用完。 1、查看home目录 sudo du -h -d 1 $HOME | grep -v K 上面的命令查看$HOME一级目录大小,发现 .cache 有26GB,.local 有几个GB&am…...