小白自制Linux开发板 十. NES游戏玩起来

1. 开发环境搭建
gcc -v
如果显示如下信息
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabi/8/lto-wrapper
Target: arm-linux-gnueabi
Configured with: ../src/configure -v --with-pkgversion='Debian 8.3.0-6' --with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-8 --program-prefix=arm-linux-gnueabi- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-sjlj-exceptions --with-arch=armv5te --with-float=soft --disable-werror --enable-checking=release --build=arm-linux-gnueabi --host=arm-linux-gnueabi --target=arm-linux-gnueabi
Thread model: posix
gcc version 8.3.0 (Debian 8.3.0-6)
就表示我们的小板已经安装了编译器了。
接下来我们就开始移植NES游戏机模拟器程序,这里使用InfoNes,代码下载:
https://files.cnblogs.com/files/twzy/arm-NES-linux-master.zip
InfoNES 音频部分需要alsa相关的组件,大概有两个alsa-utils和 alsa-lib,这个组件我们在音频部分有过了解。
对于alsa-utils可以直接通过 apt-get install alsa-utils 进行安装,此处不做过多细说,但是对于alsa-lib作者并没有在找到可以直接安装的包,所以我们手动编译。
1.1 安装alsa-lib
首先下载alsa-lib库
https://files.cnblogs.com/files/twzy/alsa-lib-1.2.5.1.zip
然后把zip文件上传到到我们的开发板上面,解压进入alsa-lib-1.2.5.1目录中,接下来就是Linux三板斧安装方法:
- 执行 ./configure 进行项目配置
- 执行 make 进行编译
- 执行 make install 进行安装
因为alsa-lib项目较大,我们的小电脑很弱,所以你会等很长时间。
安装完成以后,在目录/usr/include中,就会有个alsa文件夹,里面就有项目使用的头文件。
1.2 安装SDL(可选)
本节为可选项,因为在墨云编译其他版本的nes模拟器的时候,有要求需要用到这个库,所以这个开发板已经安装了,根据作者经验应该大概率不用安装,读者可以自行决定。
SDL是Simple DirectMedia Layer(简易直控媒体层)的缩写。它是一个跨平台的多媒体库,以用于直接控制底层的多媒体硬件的接口。主要用在开发游戏上!
apt-get install libsdl1.2-dev
sudo apt-get install libsdl-image1.2-dev
sudo apt-get install libsdl-mixer1.2-dev
sudo apt-get install libsdl-ttf2.0-dev
sudo apt-get install libsdl-gfx1.2-dev
2. NES项目配置
2.1 修改Makefile
vi Makefile
这里我们只需要修改最开始的cc=gcc 就行
终于不用配置交叉编译工具了,毕竟是小电脑啊 ^_^
2.2 增加键盘输入
InfoNes默认只支持具有专有驱动的游戏手柄和一种USB通用手柄,但是作者手头只有键盘,所以我们需要添加键盘相关的驱动代码。事实上你下载的代码已经添加了键盘功能,如果想要看看我修改了啥,可以看下面。
#include <linux/input.h> //此处需要用到 input_event结构
#define KEYBOARD_DEV "/dev/input/event0" //键盘所在的文件、请根据实际情况进行调整
……
static int joypad_fd;
static int USBjoypad_fd;
static int keyboard_fd; //新增加的用于存储键盘的句柄
static PT_JoypadInput g_ptJoypadInputHead;
……
接下来是添加键盘结构体,以及相关初始化、释放、获取值相关的代码。
这里我们重点看一下KeyBoardGet() ,在nes游戏中我们只需要配置8个键就可以了,对应如下表所示:
代码如下:
//****************************keyBoard**************************************** static int KeyBoardGet(void)
{
/**
* FC手柄 bit 键位对应关系 真实手柄中有一个定时器,处理 连A 连B
* 0 1 2 3 4 5 6 7
* A B Select Start Up Down Left Right
*
* o p <space> <Enter> w s a d
* 24 25 57 28 17 31 30 32
*
* 来自 /usr/include/linux/input-event-codes.h
*/
//因为 USB 手柄每次只能读到一位键值 所以要有静态变量保存上一次的值
static unsigned char joypad = 0;
struct input_event e; //这里使用标准的input_event结构体
int result = -1;
result = read(keyboard_fd, &e, sizeof(struct input_event));
if (result != sizeof(struct input_event))
{
printf("key error %d \n", result);
return -1;
} //printf("value:%u type:%u code:%u ", e.value, e.type, e.code); if (0x01 == e.type) //EV_KEY 0x01
{
/*上 W */
if (1 == e.value && 17 == e.code)
{
joypad |= 1 << 4;
}
if (0 == e.value && 17 == e.code)
{
joypad &= ~(1 << 4);
} /*下 S*/
if (1 == e.value && 31 == e.code)
{
joypad |= 1 << 5;
}
if (0 == e.value && 31 == e.code)
{
joypad &= ~(1 << 5);
} /*左 A*/
if (1 == e.value && 30 == e.code)
{
joypad |= 1 << 6;
}
if (0 == e.value && 30 == e.code)
{
joypad &= ~(1 << 6);
} /*右 D*/
if (1 == e.value && 32 == e.code)
{
joypad |= 1 << 7;
}
if (0 == e.value && 32 == e.code)
{
joypad &= ~(1 << 7);
} /*选择 space*/
if (1 == e.value && 57 == e.code)
{
joypad |= 1 << 2;
}
if (0 == e.value && 57 == e.code)
{
joypad &= ~(1 << 2);
} /*开始 enter*/
if (1 == e.value && 28 == e.code)
{
joypad |= 1 << 3;
}
if (0 == e.value && 28 == e.code)
{
joypad &= ~(1 << 3);
} /*A O*/
if (1 == e.value && 24 == e.code)
{
joypad |= 1 << 0;
}
if (0 == e.value && 24 == e.code)
{
joypad &= ~(1 << 0);
} /*B P*/
if (1 == e.value && 25 == e.code)
{
joypad |= 1 << 1;
}
if (0 == e.value && 25 == e.code)
{
joypad &= ~(1 << 1);
}
}
return joypad;
} static int KeyBoardDevInit(void)
{
keyboard_fd = open(KEYBOARD_DEV, O_RDONLY);
if (-1 == keyboard_fd)
{
printf("%s dev not found \r\n", KEYBOARD_DEV);
return -1;
}
return 0;
} static int KeyBoardDevExit(void)
{
close(keyboard_fd);
return 0;
} static T_JoypadInput KeyBoardInput = {
KeyBoardDevInit,
KeyBoardDevExit,
KeyBoardGet,
}; //********************************************************************
最后我们来注册一下键盘,修改int InitJoypadInput(void) 函数
int InitJoypadInput(void)
{
int iErr = 0;
//iErr = RegisterJoypadInput(&joypadInput);
//iErr = RegisterJoypadInput(&usbJoypadInput);
iErr = RegisterJoypadInput(&KeyBoardInput); //这里我们只注册键盘
return iErr;
}
2.3 修改偏色问题
键盘修改完毕,接下来就改一下屏幕偏色的问题,这里只需要修改 linux/InfoNES_System_Linux.cpp文件中的static int lcd_fb_display_px函数(调整spi屏幕的颜色):
static int lcd_fb_display_px(WORD color, int x, int y)
{
// unsigned char *pen8;
// unsigned short *pen16;
// pen8 = (unsigned char *)(fb_mem + y*line_width + x*px_width);
// pen16 = (unsigned short *)pen8;
// *pen16 = color; // return 0; //修改InfoNES_System_Linux.cpp文件中的static int lcd_fb_display_px函数(调整spi屏幕的颜色):
WORD *pen16;
unsigned char r, g, b;
r = ((color >> 10) & 0x1f);
g = ((color >> 5) & 0x3f);
b = (color & 0x1f); color = r<<11|g<<6|b;
pen16 = (WORD *)(fb_mem + y*line_width + x*px_width);
*pen16 = color;
return 0;
}
接下来就在linux目录下执行
make
命令,等待编译结束就可以在当前目录下看到一个叫InfoNES的软件,这就是编译好的模拟器,接下来执行命令(我的游戏存放在/root/game/目录下)
./InfoNES /root/game/h.nes
不出意外就可以看到如下的画面
所以还不玩起来……
4. 遗留问题
- 画面 ~ 在操作游戏的时候、因为FrameBuffer的关系,可以明显看到光标导致的画面异常;
- 声音 ~ 只能算是听个响,真的;
所以后续随缘解决吧。
随着本篇的结束,本项目也算是正式结束,所以本系列也就到此为止、后续墨云会根据实际情况将这个系列中的各种问题集中汇总处理一下。最后感谢关注过墨云的你,最主要的是感谢哇酷开发者社区(https://whycan.com/)提供的大料资料支持,以及期间帮助过墨云的所有人。
小白自制Linux开发板 十. NES游戏玩起来的更多相关文章
- 小白自制Linux开发板 二. u-boot移植
上一篇:小白自制Linux开发板 一. 瞎抄原理图与乱画PCB 中我们做了一个小型而没用的开发板,用的是Licheepi Nano的镜像,那从本篇开始我们开始自己构建它的灵魂吧. 我们都知道,PC在 ...
- 小白自制Linux开发板 三. Linux内核与文件系统移植
上一篇完成了uboot的移植,但是想要愉快的在开发板上玩耍还需要移植Linux内核和文件系统. 1.Linux内核 事实上对于F1C100S/F1C200S,Linux官方源码已经对licheepi ...
- 小白自制Linux开发板 八. Linux音频驱动配置
不知不觉小白自制开发板系列已经到第八篇了,本篇要配置的是音频驱动,也算是硬件部分的最后一片了,积攒的文章也差不多全放完了,后续更新可能会放缓,还请见谅. 对于F1C200s是自带了多媒体处理功能的,所 ...
- 小白自制Linux开发板 一. 瞎抄原理图与乱画PCB
因为墨云是基于高中物理水平的电路知识来学习.而且此前也就玩过树莓派.Esp8266之类的开发板,水平基础趋近于零,所以在写这个系列的时候抱着记录的心态.还望不足之处还望大佬们指正. <论语> ...
- 小白自制Linux开发板 四. 通过SPI使用ESP8266做无线网卡
本文章基于 WhyCan Forum(哇酷开发者社区) https://whycan.com/t_4149.htmlhttps://whycan.com/t_5870.html整理而成. 为了尊重原作 ...
- 小白自制Linux开发板 九. 修改开机Logo
许久不见啊,今天我们继续来修改我们的系统. 通过前面的几篇文章我们已经能轻松驾驭我们的开发板了,但是现在都是追求个性化的时代,我们在开发板上打上了自己的Logo,那我们是否可以改变开机启动的Logo呢 ...
- 小白自制Linux开发板(第二季 V3s篇) 一. 换个核心再来一次
1.前言 大家心心念念(个人认为)的小白自制开发板全新系列正式来了,之前我们使用全志的F1C200s芯片制作了一个小电脑,众所周知,调试很艰难,坑也很多,以至于墨云到现在还是没找到对应的补救方案,为了 ...
- 小白自制Linux开发板 番外篇 一 modprobe加载驱动问题(转载整理)
使用modprobe加载驱动 转载地址:https://blog.csdn.net/qq_39101111/article/details/78773362 前面我们提到,modprobe并不需要指定 ...
- 小白自制Linux开发板 六. SPI TFT屏幕修改与移植
本文章参考:https://www.bilibili.com/read/cv9947785?spm_id_from=333.999.0.0 本篇通过SPI接口,使用ST7789V TFT焊接屏(13p ...
随机推荐
- 缩减Centos7xfs磁盘空间
问题描述:df -h查看 root目录仅有20G空间,其余300G空间全在home目录下.xfs不可以直接缩减,所以只能删除xfs盘然后重新添加. 解决办法: 1. 注释想要删除的磁盘,此处以cent ...
- PHP中的MySQLi扩展学习(五)MySQLI_STMT对象操作
就像 PDO 中的 PDO_Statment 对象一样,MySQLI_STMT 对象也是一个预处理语句所形成的对象,专门用来操作 MySQLi 所生成的预处理语句的.其实操作方式之类也都比较相似,不外 ...
- linux中如何查看文件上下文
grep -C 10 keyword catalina.out filename https://blog.csdn.net/weixin_34791683/article/details/11660 ...
- Charles抓包工具断点修改返回内容
在测试过程中,往往需要让服务器返回指定的内容,测试一些特殊情况.例如列表内容为空.数据异常的情况等.如果通过操作服务器配合构造相应的数据会比较麻烦,甚至不好构造数据.此时,可以使用Charles的断点 ...
- 通过JMETER后置处理器JSON Path Extractor插件来获取响应结果
学生金币充值接口:该接口有权限验证,需要admin用户才可以做操作,需要添加cookie.cookie中key为登录的用户名,value从登录接口中获取,登陆成功之后会返回sign. 通常做法是在HT ...
- P3235-[HNOI2014]江南乐【整除分块,SG函数】
正题 题目链接:https://www.luogu.com.cn/problem/P3235 题目大意 \(T\)组游戏,固定给出\(F\).每组游戏有\(n\)个石头,每次操作的人可以选择一个数量不 ...
- P6378-[PA2010]Riddle【2-SAT】
正题 题目链接:https://www.luogu.com.cn/problem/P6378 题目大意 给出\(n\)个点\(m\)条边的一张无向图,图中有\(k\)种颜色的点. 要求每种颜色选择一个 ...
- Hive语法及其进阶(一)
1.Hive完整建表 1 CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name( 2 [(col_name data_type [COMMENT col ...
- PC Register简介
PC Regiter介绍: JVM中的程序计数寄存器(Program Counter Register)中,Register的命名源于CPU的寄存器,寄存器存储指令相关的现场信息,CPU只有把数据装载 ...
- Java运行时异常与非运行时异常
Java运行时异常与非运行时异常 Exception(异常)是程序本身可以处理的异常.主要包含RuntimeException等运行时异常和IOException,SQLException等非运行时异 ...