nes 红白机模拟器 第1篇

对比了很多种,开源的 NES 模拟器 VirtuaNES , nestopia , FakeNES , FCEUX , InfoNES , LiteNES
最后决定使用 LiteNES 进行移值,它是由 mynes 移值而来。LiteNES 对 mynes 代码进行整理兼容了 C99 标准,编译时无警告。
https://github.com/NJUOS/LiteNES
https://github.com/yaglo/mynes
LiteNES , mynes 基于 Allegro ,Allegro 是一种提供底层画图,输入,定时器等支持的库。
LiteNES 全部抽象提取代码到 一个 hal.c 文件里面,修改移值十分方便。下面是修改后的样子,替换这个文件。
在修改下 Makefile 中的 gcc 改为 arm-linux-gcc 编译 即可在板子上出现 Game 画面了(经过测试,发现支持的游戏不多,有的载加不出来)
NES 移值第1篇,仅能出现画面。以后会更新添加声音,多线程,输入等。现在只为能显示出画面。
hal.c :
/*
This file present all abstraction needed to port LiteNES.
(The current working implementation uses allegro library.) To port this project, replace the following functions by your own:
1) nes_hal_init()
Do essential initialization work, including starting a FPS HZ timer. 2) nes_set_bg_color(c)
Set the back ground color to be the NES internal color code c. 3) nes_flush_buf(*buf)
Flush the entire pixel buf's data to frame buffer. 4) nes_flip_display()
Fill the screen with previously set background color, and
display all contents in the frame buffer. 5) wait_for_frame()
Implement it to make the following code is executed FPS times a second:
while (1) {
wait_for_frame();
do_something();
} 6) int nes_key_state(int b)
Query button b's state (1 to be pressed, otherwise 0).
The correspondence of b and the buttons:
0 - Power
1 - A
2 - B
3 - SELECT
4 - START
5 - UP
6 - DOWN
7 - LEFT
8 - RIGHT
*/
#include "hal.h"
#include "fce.h"
#include "common.h" /**
* allegro API 不明白的看文档
* https://www.allegro.cc/manual/5/index.html
*/
/* lcd 操作相关 头文件 */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h> static int fb_fd;
static unsigned char *fb_mem;
static int px_width;
static int line_width;
static int screen_width;
static struct fb_var_screeninfo var; static int lcd_fb_display_px(int color, int x, int y)
{
unsigned char *pen8;
unsigned short *pen16; unsigned char r,g,b; pen8 = (unsigned char *)(fb_mem + y*line_width + x*px_width);
pen16 = (unsigned short *)pen8; //合并为 565 格式 16bbp
r = (color>>) & 0xff;
g = (color>>) & 0xff;
b = (color>>) & 0xff;
*pen16 = (r>>)<< | (g>>)<< | (b>>); return ;
} //调色板转16进行32位颜色
static int pal2color(pal pal)
{
int color = ;
color = pal.r << | pal.g << | pal.b;
return color;
} static int lcd_fb_init()
{
//如果使用 mmap 打开方式 必须是 读写方式
fb_fd = open("/dev/fb0", O_RDWR);
if(- == fb_fd)
{
printf("cat't open /dev/fb0 \n");
return -;
}
//获取屏幕参数
if(- == ioctl(fb_fd, FBIOGET_VSCREENINFO, &var))
{
close(fb_fd);
printf("cat't ioctl /dev/fb0 \n");
return -;
}
//计算参数
px_width = var.bits_per_pixel / ;
line_width = var.xres * px_width;
screen_width = var.yres * line_width; fb_mem = (unsigned char *)mmap(NULL, screen_width, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, );
if(fb_mem == (void *)-)
{
close(fb_fd);
printf("cat't mmap /dev/fb0 \n");
return -;
}
//清屏
memset(fb_mem, , screen_width);
return ;
} /* Wait until next allegro timer event is fired. */
void wait_for_frame()
{
//休眠 FPS = 60 * 1000 毫秒
usleep(/FPS*);
} /* Set background color. RGB value of c is defined in fce.h */
void nes_set_bg_color(int c)
{
//画背景颜色
int i,j;
for(i=; i<SCREEN_WIDTH; i++)
{
for(j=; j<SCREEN_HEIGHT; j++)
{
lcd_fb_display_px(pal2color(palette[c]), i, j);
}
}
} /* Flush the pixel buffer */
void nes_flush_buf(PixelBuf *buf)
{
Pixel *p;
int i,x,y,color;
for (i = ; i < buf->size; i++)
{
p = &buf->buf[i];
x = p->x;
y = p->y; color = pal2color(palette[p->c]);
lcd_fb_display_px(color, x, y);
lcd_fb_display_px(color, x+, y);
lcd_fb_display_px(color, x, y+);
lcd_fb_display_px(color, x+, y+);
}
} /* Initialization:
(1) start a 1/FPS Hz timer.
(2) register fce_timer handle on each timer event */
void nes_hal_init()
{
/**
* 需要完成的事情
* 1,初始化 lcd
* 2,初始化 定时器 先做简单的直接用系统延时
*/
if(- == lcd_fb_init())
{
printf("lcd fb init error \n");
return ;
}
} /* Update screen at FPS rate by allegro's drawing function.
Timer ensures this function is called FPS times a second. */
void nes_flip_display()
{
//设置64种颜色值 不必设置
} /* Query a button's state.
Returns 1 if button #b is pressed. */
int nes_key_state(int b)
{
switch (b)
{
case : // On / Off
return ;
case : // A
return ;
case : // B
return ;
case : // SELECT
return ;
case : // START
return ;
case : // UP
return ;
case : // DOWN
return ;
case : // LEFT
return ;
case : // RIGHT
return ;
default:
return ;
}
}
nes 红白机模拟器 第1篇的更多相关文章
- nes 红白机模拟器 第7篇 编译使用方法
模拟器,基于 InfoNES ,作者添加修改以下功能: 1, joypad 真实手柄驱动程序(字符型设备驱动) 2,原始图像只有256*240 ,添加 图像放大算法,这里实现了2种,a, 最近邻插值 ...
- arm 2440 linux 应用程序 nes 红白机模拟器 第1篇
对比了很多种,开源的 NES 模拟器 VirtuaNES , nestopia , FakeNES , FCEUX , InfoNES , LiteNES 最后决定使用 LiteNES 进行移值,它是 ...
- arm 2440 linux 应用程序 nes 红白机模拟器 第4篇 linux 手柄驱动支持
小霸王学习机的真实手柄,实测CPU 占用 80% 接线图: 手柄读时序: joypad.c 驱动: 普通的字符设备驱动. #include <linux/module.h> #includ ...
- arm 2440 linux 应用程序 nes 红白机模拟器 第2篇 InfoNES
InfoNES 支持 map ,声音,代码比较少,方便 移值. 在上个 LiteNES 的基础上,其实不到半小时就移值好了这个,但问题是,一直是黑屏.InfoNES_LoadFrame () Wo ...
- nes 红白机模拟器 第6篇 声音支持
InfoNES 源码中并没有包含 linux 的声音支持. 但提供 wince 和 win 的工程,文件,通过分析,win 的 DirectSound 发声,在使用 linux ALSA 实现. 先使 ...
- nes 红白机模拟器 第5篇 全屏显示
先看一下效果图 放大的原理是使用最初级的算法,直接取对应像素法. /*================================================================= ...
- nes 红白机模拟器 第4篇 linux 手柄驱动支持
小霸王学习机的真实手柄,实测CPU 占用 80% 接线图: 手柄读时序: joypad.c 驱动: 普通的字符设备驱动. #include <linux/module.h> #includ ...
- nes 红白机模拟器 第2篇 InfoNES
InfoNES 支持 map ,声音,代码比较少,方便 移值. 在上个 LiteNES 的基础上,其实不到半小时就移值好了这个,但问题是,一直是黑屏.InfoNES_LoadFrame () Wo ...
- nes 红白机模拟器 第3篇 游戏手柄测试 51 STM32
手柄使用的是 CD4021 ,datasheet 上说支持 3V - 15V . 因为手柄是 5V 供电,2440 开发板上是GPIO 3.3V 电平,STM32 GPIO 也是 3.3V (也兼容5 ...
随机推荐
- logstash output kafka ip 设置的坑
原设置 output { kafka { acks => " enable_metric => false codec => "json" topic_ ...
- SQL语句:把Excel文件中数据导入SQL数据库中的方法
1.从Excel文件中,导入数据到SQL数据库情况一.如果接受数据导入的表不存在 select * into jd$ from OPENROWSET('MICROSOFT.JET.OLEDB.4.0' ...
- MOOC(7)- case依赖、读取json配置文件进行多个接口请求-模拟接口响应数据(18)
这里是把传入的请求数据作为响应值返回 # -*- coding: utf-8 -*- # @Time : 2020/2/15 9:47 # @File : do_mock_18.py # @Autho ...
- 公式化学习requests(第二卷)
请求浏览器分为两种一种是不需要用户登录验证直接请求 另一种是需要用户登陆验证请求,现在说一下利用COOKIE实现,COOKIE在前端开发时有很多的作用,要熟练使用, 直接上代码了: 第一步:访问页面, ...
- 关于php自学
自己本人现在正在自学php有一段时间了,不知道现在的学习状态咋样,在我看来应该属于不算很糟糕,但有点糟糕的状态. 如果算学习自学php的话,现在断断续续应该是有5个月了,按理说是差不多可以做出独立项目 ...
- Nginx笔记总结二:Nginx编译参数
-prefix= 安装路径-with-http_ssl_module ...
- centos7系统盘变为只读文件的修复
一台物理机的系统盘在磁盘空间有剩余的情况下变为只读了,咨询后发现前几日修改过系统,然后就不可写了,重启也不行.见下图 解决:参考链接https://bbs.51cto.com/thread-92640 ...
- shell的循环嵌套语法
测试shell的循环嵌套语法 [root@localhost test]# vi Xunhuanqiantao.sh #!/bin/bash #程序功能描述: # 测试循环嵌套 #作者:孤舟点点 #版 ...
- springboot利用swagger构建api文档
前言 Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件.本文简单介绍了在项目中集成swagger的方法和一些常见问题.如果想深入分析项目源码,了解更多内容,见参考资料. S ...
- java反序列化-ysoserial-调试分析总结篇(2)
前言: 这篇主要分析commonCollections2,调用链如下图所示: 调用链分析: 分析环境:jdk1.8.0 反序列化的入口点为src.zip!/java/util/PriorityQueu ...