Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1675685
  • 博文数量: 311
  • 博客积分: 7778
  • 博客等级: 少将
  • 技术积分: 4186
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-09 19:59
个人简介

蓝点工坊(http://www.bluedrum.cn) 创始人,App和嵌入式产品开发。同时也做相应培训和外包工作。 详细介绍 http://pan.baidu.com/s/1y2g88

文章存档

2012年(3)

2011年(115)

2010年(170)

2009年(23)

分类: 嵌入式

2011-09-24 11:57:21

Andrew Huang 转载请注明作者及出处

在解决硬件缩放问题后,我先移植了Dosbox ,这样很多经典的DOS游戏可以直接在板上运行.

随后我开始的对于红白机模拟器的的移植.这是任天堂出的经典游戏机,小时候隔壁小孩子有一台,多数时间只能眼巴巴看着打,不过现在有得打,倒没有时间和心情玩这个了.

 首先网上有70多MB的500合一的ROM下载.先到这里下载.压缩包里自带WINDOWS的下简单模拟器.
 可以从这里下载
  
  


我手头有三个红白机模拟器, fceux,dgen,Nestopia ,测试一下fceux和Nestopia的WINDOWS版,可以运行ROM,而Dgen在LINUX很容易移植,但是无法运行ROM,因此放弃了.因为先下到是fceux的源码,因此先移植这个版本
  

 

一.安装scons 
    
   fecux 新版的构造工具使用scons,而不是传统的make.一般的Linux没有安装这个工具,需要从网上下载源码安装.
  scons是用python语言编写的,因此确保你的机器安装Python的解释器.
  下载:
     
    它是从 
  
  安装
     它从其它的基于python的工具安装方法一样,也是用一个Pythone脚本来安装的
    解压后在源码目录运行如下命令即可安装
         python setup.py install

  使用
     scons的使用类似于make,但是他的构造脚本名字不是Makefile,名字是SConstruct.
    因此如果当前目录下有SConstruct 文件,直接运行 scons 即可

 二 fceux X86版的移植
  
  1.解压源码
    从官网下载 
   最新源码是 2.1.5
      %20Code/2.1.5%20src/fceux-2.1.5.src.tar.bz2/download
 2.修改编译选项
  
  缺省的fceux是需要GTK库的,主要是显示菜单,但是在嵌入式里移植GTK还是比较麻烦,而且命令行也能达到同样效果,因此要修改构造文件SConstruct,关闭GTK支持.
  将SConstruct 中如下句子修改
   BoolVariable('GTK', 'Enable GTK2 GUI (SDL only)', 1),
  修改成
   BoolVariable('GTK', 'Enable GTK2 GUI (SDL only)', 0),
   
 3.编译
   直接在源码目录运行
     scons 

  清除编译结果
    scons -c  #类似于make clean

   如果提示如下,说明没有安装GTK库,可以按第2步关掉GTK的支持
   
  1. src/drivers/sdl/../../utils/xstring.h:131:45: warning: no newline at end of file
  2. src/drivers/sdl/input.cpp: In function 'std::string GetUserText(const char*)':
  3. src/drivers/sdl/input.cpp:284: error: 'gtk_dialog_get_content_area' was not declared in this scope
  4. src/drivers/sdl/input.cpp: In function 'int ButtonConfigBegin()':
  5. src/drivers/sdl/input.cpp:802: error: 'gtk_widget_get_window' was not declared in this scope
  6. src/drivers/sdl/input.cpp: In function 'void ButtonConfigEnd()':
  7. src/drivers/sdl/input.cpp:833: warning: unused variable 'GameInfo'
  8. src/drivers/sdl/sdl-video.h: At global scope:
  9. src/drivers/sdl/sdl-video.h:6: warning: 's_screen' defined but not used
  10. src/drivers/sdl/sdl.h:9: warning: 'void DoFun(int)' declared 'static' but never defined

4.安装.
  运行源码的目录的安装脚本
    install.sh 

5.运行
  因为没有图形界面,直接用命令行参数指明ROM文件路径
  可以是nes或zip格式

   fceux yourrom.nes
  这是实际运行效果
   
 
三 fceux ARM版的移植

fceux提供一个脚本来演示怎么移植,debian-crossbuild.sh.主要是设环境变量。
  1. #!/bin/sh
  2. if [ -f /usr/bin/i586-mingw32msvc-windres ]; then HOST=i586-mingw32msvc
  3. else HOST=i586-mingw32
  4. fi
  5. PLATFORM=win32 CC=${HOST}-gcc CXX=${HOST}-g++ WRC=${HOST}-windres WINDRES=${HOST}-windres scons $@
  后来经过几次编译尝试后,最终我使用的脚本arm-linux.sh内容如下

  1. PLATFORM=posix CC=/usr/local/arm/4.4.1/bin/arm-linux-gcc CXX=/usr/local/arm/4.4.1/bin/arm-linux-g++ LDFLAGS="-L/home/huisen/workspace/output/arm-linux/lib -lSDL -lz -liconv -lts" scons $@
这里注意要使用绝对路径,好象Shell的PWD,PATH环境变量没有生效,因此这里使绝对路径。

这里scons的构造文件也要大量修改。我编译成功的文件内容如下,红字是改动过的
  1. import os
  2. import sys
  3. import platform
  4. opts = Variables()
  5. opts.AddVariables(
  6. BoolVariable('FRAMESKIP', 'Enable frameskipping', 1),
  7. BoolVariable('OPENGL', 'Enable OpenGL support', 1),
  8. BoolVariable('LSB_FIRST', 'Least signficant byte first (non-PPC)', 1),
  9. BoolVariable('DEBUG', 'Build with debugging symbols', 0),
  10. BoolVariable('LUA', 'Enable Lua support', 1),
  11. BoolVariable('NEWPPU', 'Enable new PPU core', 1),
  12. BoolVariable('CREATE_AVI', 'Enable avi creation support (SDL only)', 1),
  13. BoolVariable('LOGO', 'Enable a logoscreen when creating avis (SDL only)', '1'),
  14. BoolVariable('GTK', 'Enable GTK2 GUI (SDL only)', 0),
  15. BoolVariable('GTK3', 'Enable GTK3 GUI (BROKEN/EXPERIMENTAL)', 0),
  16. )
  17. env = Environment(options = opts)
  18. env.Append(CPPDEFINES=["PUBLIC_RELEASE"])
  19. # LSB_FIRST must be off for PPC to compile
  20. if platform.system == "ppc":
  21. env['LSB_FIRST'] = 0
  22. # Default compiler flags:
  23. env.Append(CCFLAGS = ['-I/home/huisen/workspace/output/arm-linux/include/SDL','-Wall', '-Wno-write-strings', '-Wno-sign-compare', '-O2', '-Isrc/lua/src','-DHAVE_ASPRINTF'])
  24. if os.environ.has_key('PLATFORM'):
  25. env.Replace(PLATFORM = os.environ['PLATFORM'])
  26. if os.environ.has_key('CC'):
  27. env.Replace(CC = os.environ['CC'])
  28. if os.environ.has_key('CXX'):
  29. env.Replace(CXX = os.environ['CXX'])
  30. if os.environ.has_key('WINDRES'):
  31. env.Replace(WINDRES = os.environ['WINDRES'])
  32. if os.environ.has_key('CFLAGS'):
  33. env.Append(CCFLAGS = os.environ['CFLAGS'].split())
  34. if os.environ.has_key('LDFLAGS'):
  35. env.Append(LINKFLAGS = os.environ['LDFLAGS'].split())
  36. print "platform: ", env['PLATFORM']
  37. # special flags for cygwin
  38. # we have to do this here so that the function and lib checks will go through mingw
  39. if env['PLATFORM'] == 'cygwin':
  40. env.Append(CCFLAGS = " -mno-cygwin")
  41. env.Append(LINKFLAGS = " -mno-cygwin")
  42. env['LIBS'] = ['wsock32'];
  43. if env['PLATFORM'] == 'win32':
  44. env.Append(CPPPATH = [".", "drivers/win/", "drivers/common/", "drivers/", "drivers/win/zlib", "drivers/win/directx", "drivers/win/lua/include"])
  45. env.Append(CPPDEFINES = ["PSS_STYLE=2", "WIN32", "_USE_SHARED_MEMORY_", "NETWORK", "FCEUDEF_DEBUGGER", "NOMINMAX", "NEED_MINGW_HACKS", "_WIN32_IE=0x0600"])
  46. env.Append(LIBS = ["rpcrt4", "comctl32", "vfw32", "winmm", "ws2_32", "comdlg32", "ole32", "gdi32", "htmlhelp"])
  47. else:
  48. conf = Configure(env)
  49. #assert conf.CheckLibWithHeader('z', 'zlib.h', 'C', 'inflate;', 1), "please install: zlib"
  50. if not conf.CheckLib('SDL'):
  51. print 'Did not find libSDL or SDL.lib, exiting!'
  52. #Exit(1)
  53. if env['GTK']:
  54. # Add compiler and linker flags from pkg-config
  55. env.ParseConfig('pkg-config --cflags --libs gtk+-2.0')
  56. env.Append(CPPDEFINES=["_GTK2"])
  57. env.Append(CCFLAGS = ["-D_GTK"])
  58. if env['GTK3']:
  59. # Add compiler and linker flags from pkg-config
  60. env.ParseConfig('pkg-config --cflags --libs gtk+-3.0')
  61. env.Append(CPPDEFINES=["_GTK3"])
  62. env.Append(CCFLAGS = ["-D_GTK"])
  63. ### Lua platform defines
  64. ### Applies to all files even though only lua needs it, but should be ok
  65. if env['LUA']:
  66. env.Append(CPPDEFINES=["_S9XLUA_H"])
  67. if env['PLATFORM'] == 'darwin':
  68. # Define LUA_USE_MACOSX otherwise we can't bind external libs from lua
  69. env.Append(CCFLAGS = ["-DLUA_USE_MACOSX"])
  70. if env['PLATFORM'] == 'posix':
  71. # If we're POSIX, we use LUA_USE_LINUX since that combines usual lua posix defines with dlfcn calls for dynamic library loading.
  72. # Should work on any *nix
  73. env.Append(CCFLAGS = ["-DLUA_USE_LINUX"])
  74. ### Search for gd if we're not in Windows
  75. if env['PLATFORM'] != 'win32' and env['PLATFORM'] != 'cygwin' and env['CREATE_AVI'] and env['LOGO']:
  76. gd = conf.CheckLib('gd', autoadd=1)
  77. if gd == 0:
  78. env['LOGO'] = 0
  79. print 'Did not find libgd, you won\'t be able to create a logo screen for your avis.'
  80. if conf.CheckFunc('asprintf'):
  81. conf.env.Append(CCFLAGS = "-DHAVE_ASPRINTF")
  82. if env['OPENGL'] and conf.CheckLibWithHeader('GL', 'GL/gl.h', 'c++', autoadd=1):
  83. conf.env.Append(CCFLAGS = "-DOPENGL")
  84. conf.env.Append(CPPDEFINES = ['PSS_STYLE=1'])
  85. # parse SDL cflags/libs
  86. #env.ParseConfig('sdl-config --cflags --libs')
  87. env = conf.Finish()
  88. if sys.byteorder == 'little' or env['PLATFORM'] == 'win32':
  89. env.Append(CPPDEFINES = ['LSB_FIRST'])
  90. if env['FRAMESKIP']:
  91. env.Append(CPPDEFINES = ['FRAMESKIP'])
  92. print "base CPPDEFINES:",env['CPPDEFINES']
  93. print "base CCFLAGS:",env['CCFLAGS']
  94. if env['DEBUG']:
  95. env.Append(CPPDEFINES=["_DEBUG"], CCFLAGS = ['-g'])
  96. if env['PLATFORM'] != 'win32' and env['PLATFORM'] != 'cygwin' and env['CREATE_AVI']:
  97. env.Append(CPPDEFINES=["CREATE_AVI"])
  98. else:
  99. env['CREATE_AVI']=0;
  100. Export('env')
  101. SConscript('src/SConscript')
  102. # Install rules
  103. exe_suffix = ''
  104. if env['PLATFORM'] == 'win32':
  105. exe_suffix = '.exe'
  106. fceux_src = 'src/fceux' + exe_suffix
  107. fceux_dst = 'bin/fceux' + exe_suffix
  108. auxlib_src = 'src/auxlib.lua'
  109. auxlib_dst = 'bin/auxlib.lua'
  110. fceux_h_src = 'src/drivers/win/help/fceux.chm'
  111. fceux_h_dst = 'bin/fceux.chm'
  112. env.Command(fceux_h_dst, fceux_h_src, [Copy(fceux_h_dst, fceux_h_src)])
  113. env.Command(fceux_dst, fceux_src, [Copy(fceux_dst, fceux_src)])
  114. env.Command(auxlib_dst, auxlib_src, [Copy(auxlib_dst, auxlib_src)])
  115. # TODO: Fix this build script to gracefully install auxlib and the man page
  116. #env.Alias(target="install", source=env.Install(dir="/usr/local/bin/", source=("bin/fceux", "bin/auxlib.lua")))
  117. env.Alias(target="install", source=env.Install(dir="/usr/local/bin/", source="bin/fceux"))

 其中使用 -DHAVE_ASPRINTF 主要为解决如下问题
  1. src/file.cpp: In function 'int asprintf(char**, const char*, ...)':
  2. src/file.cpp:464: error: 'int asprintf(char**, const char*, ...)' was declared 'extern'
  3. and later 'static'
  4. /usr/local/arm/4.4.1/bin/../arm-none-linux-gnueabi/libc/usr/include/stdio.h:382:
  5. error: previous declaration of 'int asprintf(char**, const char*, ...)'
注释掉zlib和SDL库的检测主要不知道如何让scons找到嵌入式的库,没办法直接注释掉
否则总会提示
 
  1. scons: Reading SConscript files ...
  2. platform: posix
  3. Checking for inflate in C library z... no
  4. AssertionError: please install: zlib:
  5. File "/home/huisen/workspace/apps/fceu2.1.5/SConstruct", line 58:
  6. assert conf.CheckLibWithHeader('z', 'zlib.h', 'C', 'inflate;', 1), "please install:
  7. zlib"

注释掉env.ParseConfig('sdl-config --cflags --libs') 是防止其引用桌面版的版本。

 修改完毕后,运行./arm-linux.sh 即可成功编译出arm-linux版本的 fceux来.

四 fceux ARM版的运行

在fceux 运行后,会使用 ~/.fceux/fceux.cfg作为配置文件

ARM需要写一个脚本。在最开始的音频运行卡死。因此我成功的运行参数是
  
./fceux --bpp 16 --sound 1 --fullscreen 1 CONTRA.NES

  这里运行效果实拍
  

阅读(8168) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~