重新编译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. 编译

(建议直接在我的git根目录下执行make,这里编译一次要很久,而且有时遇到修改,make命令不能中途自动更新obj文件,导致重新编译好多次,太花时间)

编译报错  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啊又加了什么新特性。自从苹果出了刘海屏,越来越不待见苹果了~

完美编译街机模拟器MAME(Android版)基于MAME4all的更多相关文章

  1. MAME 0.201 发布,重温童年的街机模拟器

    MAME 0.201 已发布,MAME 最初是街机模拟器,随着时间的推移,MAME 吸收了姊妹项目 MESS(多机种模拟器超级系统),所以 MAME 现在还记录了各种各样的(大多是老式的)电脑游戏.掌 ...

  2. Atitit. 常用街机系统and 模拟器总结 snk neo geo cps mame sfc smc

    Atitit. 常用街机系统and 模拟器总结 snk neo geo cps mame sfc smc 1. #-------常用 游戏类型 1 2. 街机的历史 2 3. #=========== ...

  3. AOSP ON MAKO(在NEXUS 4上刷ANDROID 4.4 源代码包-下载/配置/编译/刷机)

    AOSP ON MAKO(在NEXUS 4上刷ANDROID 4.4 源代码包-下载/配置/编译/刷机) 特别感谢google官方文档及AOSP源代码开放 參考链接: https://source.a ...

  4. 完美高仿精仿京东商城手机客户端android版源码

    完美高仿精仿京东商城手机客户端android版源码,是从安卓教程网那边转载过来的,这款应用源码非常不错的,也是一个非常优秀的应用源码的,希望能够帮到学习的朋友. _js_op> <igno ...

  5. 利用lipo编译合并iPhone模拟器和真机通用的静态类

    利用lipo编译合并iPhone模拟器和真机通用的静态类 如何编译静态类库,而且现在网上也有很多的教程,现在问题时我们编译好了的静态类库会时两个版本的.a文件,分别用于模拟器和iPhone真迹,因此M ...

  6. Android版网易云音乐唱片机唱片磁盘旋转及唱片机机械臂动画关键代码实现思路

     Android版网易云音乐唱片机唱片磁盘旋转及唱片机机械臂动画关键代码实现思路 先看一看我的代码运行结果. 代码运行起来初始化状态: 点击开始按钮,唱片机的机械臂匀速接近唱片磁盘,同时唱片磁盘也 ...

  7. 业余时间折腾了个微信小程序版本的街机游戏模拟器(吾爱街机),8090后的童年回忆,欢迎大家体验

    好多年没来博客园了,有段时间想玩街机游戏,发现都需要下载安装,现在小程序这么流行,是不是可以集成到小程序里(无需下载,在线玩),出于这想法,就业余时间折腾了下,分享给大家,偶尔可以回味畅玩下. 中间遇 ...

  8. 最牛叉的街机游戏合集 & 模拟器

    亲爱的小伙伴们,是否还记得那年我们玩的疯狂的街机游戏吗,街机中心提供400多个街机游戏,让你爽到底. 例如:拳皇96,拳皇97,恐龙新世纪.名将.快打旋风.惩罚者.魂斗罗.超级玛丽.雪山兄弟.忍者神龟 ...

  9. 开发腾讯移动游戏平台SDK Android版Ane扩展 总结

    本文记录了在开发 腾讯移动游戏平台SDK(MSDK) Android版Ane扩展 过程中所遇到的问题和相关解决方式 问题一:编译报错:Unable to resolve target 'android ...

随机推荐

  1. redis 入门之列表

    lpush 将一个或多个值 value 插入到列表 key 的表头如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表头: 比如说,对空列表 mylist 执行命令 LPU ...

  2. __attribute__((regparm(3))) from GNU C

    在 x86 上,regparm 属性会传递一个数值给编译器,这个数值会告诉编译器要用多少个寄存器来传递函数参数(EAX, EDX 或 ECX,最多 3 个寄存器),通常情况下函数是用堆栈来传递参数的. ...

  3. Java 多态基础

    多态的定义 程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在运行期间才确定. 或者是同一个行为具有多个不同表现形式或形态的能力. 多态的体现 在玩LOL时,W ...

  4. NFS(网络文件系统)

    NFS(网络文件系统) 1.关于NFS介绍 1.1NFS在企业中的应用场景 在企业集群架构的工作场景中,NFS网络文件系统一般被用来存储共享视频,图片,附件等静态资源文件,通常网站用户上传的文件都会放 ...

  5. Educational Codeforces Round 60 (Rated for Div. 2) E. Decypher the String

    题目大意:这是一道交互题.给你一个长度为n的字符串,这个字符串是经过规则变换的,题目不告诉你变换规则,但是允许你提问3次:每次提问你给出一个长度为n的字符串,程序会返回按变换规则变换后的字符串,提问3 ...

  6. 初试avalon

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. Stream(Java 8)

    Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利.高效的聚合操作(aggregate operation),或者大批量数据操作 (b ...

  8. Magento笔记/记录(1)

    1.Magento eav_attribute表中source如何指定自定义数据来源  如果你引用的类名为yebihai_usermanage_model_entity_school你必须完整的给出地 ...

  9. 半途而废的Java爬虫学习经历

    最近在面试,发现Java爬虫对于小数据量数据的爬取的应用还是比较广,抽空周末学习一手,留下学习笔记 Java网络爬虫 简单介绍 爬虫我相信大家都应该知道什么,有什么用,主要的用途就是通过程序自动的去获 ...

  10. 排序+并查集——cf1213F

    /* 有向边(pi,pi+1),形成链后进行dfs,求出dfs序 一个联通块内的元素必须是同一个字符,如果最后的联通块个数<k,说明不行 */ #include<bits/stdc++.h ...