先上工程源码链接
https://github.com/VeiLiang/BoloRTT
-------
关于InfoNES
InfoNES是一个比较早的nes模拟器了,优点是支持的mapper比较多,代码十分方便移植,虽然原版代码是cpp,但是完全没有用到任何的c++的特性,直接把后缀名字改成c就可以正常编译了。缺点就是声音效果比较差,几乎就是听个响,然后很多音效都没有了,例如热血格斗的打斗声,跳起来的声音也非常怪;还有个缺点就是虽然支持的mapper多,但是有些游戏还是会出现不能运行或者画面错乱的情况。不过瑕不掩瑜,因为移植起来真的非常简单,所以在各个平台都会有InfoNES的移植教程,致敬
移植
直接把infoNES的相关文件改成.c后缀就好。然后实现几个接口函数
显示画面函数 void InfoNES_LoadFrame()
读取按键键值 void InfoNES_PadState( DWORD *pdwPad1, DWORD *pdwPad2, DWORD *pdwSystem )
memcpy void *InfoNES_MemoryCopy( void *dest, const void *src, int count )
memset void *InfoNES_MemorySet( void *dest, int c, int count )
调试打印错误信息 void InfoNES_DebugPrint( char *pszMsg )
声音初始化 int InfoNES_SoundOpen( int samples_per_sync, int sample_rate )
声音播放 5个声道 void InfoNES_SoundOutput(int samples, BYTE *wave1, BYTE *wave2, BYTE *wave3, BYTE *wave4, BYTE *wave5)
下面是BoloRTT下实现的代码,因为板子没有游戏按键,所以就没写按键代码
/* Transfer the contents of work frame on the screen */
void InfoNES_LoadFrame()
{
unsigned int x,y;
#ifdef DISP_USE_ARGB_32
unsigned int *src,*dst;
src = (unsigned int *)WorkFrame;
#else
unsigned short *src,*dst;
src = (unsigned short *)WorkFrame;
#endif
for(x=0;x<NES_DISP_HEIGHT;x++)
{
for(y=0;y<NES_DISP_WIDTH;y++)
{
FrameBuffer[x*480+y+160] = *src;
src++;
}
}
// for(x=0;x<NES_DISP_HEIGHT;x++)
// {
// dst = FrameBuffer + (NES_DISP_HEIGHT-1-x);
// for(y=0;y<NES_DISP_WIDTH;y++)
// {
// *dst = *src;
// dst += 480;
// src++;
// }
// }
}
/* Get a joypad state */
void InfoNES_PadState( DWORD *pdwPad1, DWORD *pdwPad2, DWORD *pdwSystem )
{
//add key ctrl in here...
}
/* memcpy */
void *InfoNES_MemoryCopy( void *dest, const void *src, int count )
{
return memcpy(dest,src,count);
}
/* memset */
void *InfoNES_MemorySet( void *dest, int c, int count )
{
return memset(dest,c,count);
}
/* Print debug message */
void InfoNES_DebugPrint( char *pszMsg )
{
}
/* Wait */
void InfoNES_Wait()
{
}
/* Sound Initialize */
void InfoNES_SoundInit( void )
{
}
/* Sound Open */
int InfoNES_SoundOpen( int samples_per_sync, int sample_rate )
{
f1c100s_audio_config(1,16,sample_rate);
f1c100s_audio_open(samples_per_sync*2);
return 0;
}
/* Sound Close */
void InfoNES_SoundClose( void )
{
}
WORD final_wave[367*5];
/* Sound Output 5 Waves - 2 Pulse, 1 Triangle, 1 Noise, 1 DPCM */
void InfoNES_SoundOutput(int samples, BYTE *wave1, BYTE *wave2, BYTE *wave3, BYTE *wave4, BYTE *wave5)
{
int i;
for (i = 0; i < samples; i++)
{
final_wave[i] = (wave1[i]*32 + wave2[i]*32 + wave3[i]*32 + wave4[i]*32 + wave5[i]*32);
}
audio_pcm_play(final_wave,samples*2);
}
总结
总体下来,InfoNES还是不错的,可以跑热血系列游戏,然后就是声音真的比较差,聊胜于无吧。
后面我会继续发布正点原子开发板上跑的NES模拟器,(基于大佬ye781205 编写)cpu实现是汇编语言的,我移植到了BoloRTT上,核心也是改过的可以跑在ARM9下的汇编,速度那叫一个溜,声音效果也非常完美。敬请期待
不要脸打个广告
BoloRT工程,完美跑这bolopi上 https://github.com/VeiLiang/BoloRTT
欢迎start,fork
用爱发电
离线
还有就是说一下显示相关的,一般模拟器计算出来显示的是调色板的索引。一共常规来说就是64色的调色板
然后我们跑的时候通常会有的屏幕是RGB565,有的屏幕RGB888.我们就可以自己修改调色板的内容进行适配。
在InfoNES中,调试板的数组是NesPalette。目前BoloRTT里用的是RGB888的
离线
凉哥又出精品了!
离线
厉害,感谢大神分享,有时间研究一下,f1c的rtt看来挺完善了
离线
热血系列小时候很爱玩啊,游戏机制很不错(打的好小BOSS会投降认输),打到最后是两只老虎。
离线
热血系列小时候很爱玩啊,游戏机制很不错(打的好小BOSS会投降认输),打到最后是两只老虎。
是的,还有冒险岛,洛克人,嘿嘿
离线
你好,我想请教个问题,我移植了infones到v3s,出现声音滞后画面大约5s的问题,请问该如何解决呢?这个问题困扰了我很久。。
离线
你好,我想请教个问题,我移植了infones到v3s,出现声音滞后画面大约5s的问题,请问该如何解决呢?这个问题困扰了我很久。。
V3s声音是不是linux驱动的问题,延迟应该和infones没有关系吧。不过infones的声音效果不好
离线
有没有兴趣帮在我们新芯片上移植个NES,我们会提供开发板和资料
离线
有没有兴趣帮在我们新芯片上移植个NES,我们会提供开发板和资料
什么板子?
离线
有没有兴趣帮在我们新芯片上移植个NES,我们会提供开发板和资料
应该没有问题,什么芯片呢
离线
Kirin 说:有没有兴趣帮在我们新芯片上移植个NES,我们会提供开发板和资料
应该没有问题,什么芯片呢
全志未发布的全新芯片,私聊QQ:402041446
离线
@微凉VeiLiang
老哥我想问一下 这个调色板的值 有什么标准的吗
离线
@微凉VeiLiang
老哥我想问一下 这个调色板的值 有什么标准的吗
就是用网上写好的模拟器颜色就好了。我们无非就是拿来改成RGB888 或者RGB 565.亦或是调换下B和R位置而已
离线
像网上有一些stm32或ESP32移植NES的原理是什么?nes游戏是怎么在此类单片机上进行运行的?那些模拟6502的指令是依据哪些资料写出来的?
离线
大佬,请教一下,我的nes运行起来非常慢是咋回事呢,我是F1C200S
离线
大佬,请教一下,我的nes运行起来非常慢是咋回事呢,我是F1C200S
离线