完美编译街机模拟器MAME(Android版)基于MAME4all

重新编译MAME4droid源码

github上开源项目MAME4all可将MAME模拟器运行在iOS和Android上,还有一个比较有名的叫MAME4droid(MAME for android),MAME4all支持iOS,因此我选择了它。但由于年代比较久远(7-8年前的项目),代码clone下来基本无法编译。

原项目虽然在github上开源,但从目录结构上可看出原项目是svn做的版本控制,这也很正常,毕竟那时github还没流行起来。首先把代码clone下来,为了方便记录升级过程,并且方便读者clone,笔者将源项目分割。基于最后一个tag “MAME4droid 1.9.2 (0.139u1)”来修改,代码已上到我的github MAME4Mobile。本文将基于此来修改编译

环境:

  1. Mac OS X 10.14.4
  2. Android Studio 3.5.2
  3. NDK 17.2.4988734

一、导入Android Studio

  原android项目应该是基于Eclipse。用Android Studio菜单的File -> New -> Import project ... 导入为AS的工程,最终工程笔者已经上到github

二、编译libMAME4droid

  此步骤比较麻烦,主要工作都集中于此步。

  1. 配置makefile

  此处历经周折, mrpostiga/imame4all 的makefile配置需要依赖本地NDK环境,因此需要配置各种路径,include, ldflag。尝试了gcc、clang等编译失败,文件中的好多写法不被clang接受,而且makefile中的编译选项是gnu的 (0_0)。最终由于源码是混合了c与c++而如果编译器根据文件后缀来确定语言类型将导致编译出错。我选择使用g++,既可以编译C又可以编译C++。

  NDK 笔者使用NDK 17.2.4988734,原因是 安卓自NDK-r18起移除了gcc, 并完全删除了gnustl、gabi++ 和 stlport。而模拟器源码使用了stl。

  具体配置详见github makefile 文件

  2. 编译

编译报错  opensl_snd.c:51:30: error: 'memcpy' was not declared in this scope, 找不到memcpy。解决办法 在opensl_snd.c中添加#include <string.h>

aarch64-linux-android/bin/ld: cannot find crtbegin_so.o: No such file or directory和aarch64-linux-android/bin/ld: cannot find crtend_so.o: No such file or directory 不知道为什么ld始终找不到这2个.o 配置了-L选项也不行,最后没办法把crtbegin_so.o,crtend_so.o拷到makefile同级目录Linking通过。(后来改为ln -s 软连接的方式,已配置到makefile实现自动ln armv7a和armv8a。

libMAME4droid.so: dlopen failed: cannot locate symbol "_ZNSs4_Rep20_S_empty_rep_storageE" 找不到_ZNSs4_Rep20_S_empty_rep_storageE这个符号,经查是c++ string类型的默认值,感觉是手机上没有找到这个,试了把libgnustl_shared.so打到apk包里,运行解决。(我用旧版本的AS-3.4.1 在Application.mk中配置了APP_STL := gnustl_shared后,nkd-build 会自动将libgnustl_shared.so拷贝到libs/armeabi-xxx目录下,升级3.5之后就没有这个行为了,不知道是不是AS改了这方面功能)

 

编译的最终结果将得到一个名为mame或mame64的二进制文件,即我们的 libMAME4droid.so 库。

当然工程里面还需要配置一下编译jni文件,你可以选择使用ndk-build或是cmake。两种我都写了一下,改下app的build.gradle可以切换两种编译方式。

 

 

3. 适配

Run起来后,手机在横屏状态下,会发现摇杆和A、B、X、Y 都挡住游戏画面了,而且两边还有很多空白区。如图:

横屏截图

 

这里笔者简单适配一下最终效果,看图

适配后

 

 这个顺眼多了。界面布局配置写在配置文件里面,位于res下的raw目录。数字的第一列表示控件类型,第二列代表控件ID,第三列x轴坐标... 感兴趣的同学看下MainHelper -> inputHandler.readControllerValues

  原作者由于基于当时的Android设备来配置屏幕空间。在当下Android手机上显然是不适配的,小弟就简单的将raw-large中的16_9内容复制到raw中,在我的荣耀V10上效果如上图。

  4. 运行  

  最后 投币、start就可以愉快的玩耍了。

  效果图

 

三、总结

  MAME是一个跨平台的街机模拟器引擎,但最新版貌似没有考虑兼容移动设备。本文使用的核心源码是比较老的0.139u1版本,在网上找ROM的时候也要留意下版本兼容性。

  还有一个iOS版我还没编译,留到下次吧~~(项目好忙)

 

  最近半年多一直在弄Android,好久没搞iOS了,不知道swift啊、xcode啊又加了什么新特性。自从苹果出了刘海屏,越来越不待见苹果了~

 

posted @ 2019-12-21 19:40  Coding&Life  阅读(7110)  评论(4编辑  收藏  举报