首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
拉勾
V2EX  ›  分享创造

一次移植 GBA 模拟器到微信小游戏的血泪史

  •  1
     
  •   w88975 · 27 天前 · 4956 次点击

    前言

    • 近期任天堂直面会发布了要重制塞尔达梦见岛的消息,勾起了我想在 GBA 上玩通关梦见岛的兴趣。于是在手机上下载了几款 GBA 模拟器,发现都不太好用(主要是摇杆很反人类)
    • 既然 GBA 模拟器这么难用,于是就在 GitHub 上搜有没有开源的,倒是找到了一个名为 gba4ios 的项目,但一看时间已经几年没维护了,估计对 iPhoneX 的分辨率支持也不够好,遂放弃(自我猜测)。
    • 在搜的过程中,发现了一款 js 实现的 GBA 模拟器( gbajs ),遂在线试用了一下,发现电脑手机上都没有性能问题,很流畅,于是就萌生了把 GBA 模拟器移植到微信小游戏上的想法。

    开始动手

    • 由于之前有过小游戏开发经验,也做过 js 游戏引擎相关的开发,还是蛮相信自己能搞定的。下载了代码,作者也没写注释,只能硬着头皮猜,核心部分就是用 js 模拟了 GBA 的 32 位 CPU,GBA 解包等等这些无关语言和环境的东西,只有最后拿到 ImageData 才涉及到渲染层,看上去还挺简单,要改的东西不多。

    • 于是自己花了一两个小时,把涉及到 DOM 和 BOM 都改了,渲染全部由小游戏 canvas 接管,解决了一系列 BUG 后,终于能在模拟器上看到画面了。内心很激动,感觉要成了!

    • 1

    噩梦开始

    • 在模拟器出画面后,用真机调试,发现真机啥画面都没有,于是开始了 debug 之路,非常漫长,由于不知道是平台原因还是小游戏 API 不完善的原因,完全一行一行的 debug,一两个小时后,终于找到原因所在,一个 callback 导致的画面黑屏(为什么 Web 和模拟器都行,就是真机不行,小游戏&小程序的模拟器不靠谱啊)

    • 搞定了上一个问题,更是兴奋,感觉离成功不远了,真机上跑了一下,怎么感觉 fps 有点低呢? drawcall 只有 2,但 fps 一直上不了 20,稳定在 12-15 左右,变成了幻灯片。用模拟器看了一下,模拟器能跑满 60fps,于是我就在想,会不会是渲染效率的原因,于是又开始了漫长的 debug。这次先找渲染层,也是一行行代码的测,因为不确定小游戏的引擎有哪些未知 BUG,所以这样来测比较细,也不会遗漏什么。这一测,就是 3 个多小时,还是完全没有头绪,各种方式都试遍了,依然保持 12fps。

    • 本着不改好 bug 不睡觉的原则,继续刚,终于让我发现了问题所在。在 pc 端和手机浏览器上,能跑满 60fps,但小游戏不行,问题出在模拟 cpu 的核心代码上,用虚拟的 cpu 去运行 GBA 的 rom,pc 和手机浏览器只需要几 ms 的时间就能解析出一帧的画面,而到了小游戏里,则需要 80 多 ms,1000ms/80ms 约等于 12 左右,刚好解释了为什么 fps 在 12 左右波动。完全占据了 90%的性能开销。很奇怪为什么会开销这么大,这部分代码也没用到 polyfill,于是脑瓜更疼了。思来想去,于是想到,会不会是 ios 上小程序的 js 引擎并非系统的 js 引擎,而是自己实现了一套(突然想到了腾讯有自己的 x5 内核,会不会也有自己的"x5js")?带着疑问搜索了一圈,果真搜到了一篇文章,介绍了小程序的 js 引擎,是苹果的 JSC 引擎? WTF ? JSC 不是 Safari 的引擎吗?我明明用 Safari 试过没问题才准备移植的,带着疑问又上路搜关于 JSC 的资料,可算找到一个稍微靠谱的解释。

    • 原来在 Safari 里,JSC 是带有 JIT 的,UIWebview 不带 JIT,也没有 Safari 那么好的优化,但具体是哪部分没有优化好,我继续在代码里找。由于小程序开发工具运行流畅,不好 debug,于是只有用真机打 log 看运行时间,又是花费一两个小时时间,终于找到了,原来是 ARM 的 STM 指令耗时,90%的时间都消耗在 STM 上了,由于鄙人能力有限,对计算机底层不太熟悉,到这一步就放弃了

    结语

    • 白折腾了一个通宵,顿感失落,不知道是自己能力有限,还是平台所限,虽然不是什么正经的大项目,但是自己已经很久没有出于个人兴趣搞一些工作之外的开发了。发出此文的目的除了吐槽自己在开发小游戏过程中的种种不愉快,顺便还想看看有没有大佬能够优化这些问题。
    64 回复  |  直到 2019-02-22 17:32:52 +08:00
        1
    iamsee   27 天前 via Android   ♥ 1
    我。。。cao,看完了佩服楼主,我辈楷模
        2
    LevineChen   27 天前 via iPad
    套个 webview 就完事了……
        3
    Captions   27 天前 via Android
    佩服之情,油然而生
        4
    Actrace   27 天前
    这,,技术黑,很高端啊。。。
    虽然腾讯自己搞的生态也是没好到那里去就是了。
        5
    tanranran   27 天前
    特别佩服楼主的钻研精神,值得尊敬
        6
    qq292382270   27 天前
    真心佩服..
        7
    metalbug   27 天前
    你应该先搞 FC,有经验了再搞其他的
        8
    w88975   27 天前 via iPhone
    @metalbug 因为想玩 GBA 游戏 所以就弄 GBA 的了 FC 游戏可玩性太低了
        9
    azh7138m   27 天前 via Android
    ARMCoreArm 里面的函数看上去每次都会创建闭包。。。真酷炫,内存使用不会涨的很快吗?
        10
    pangtianyu   27 天前
    你的 stm 是怎么实现的
        11
    w88975   27 天前 via iPhone
    @LevineChen 虽然小游戏也是相当于跑在浏览器里,但不用单独打个包,跨平台,传播性和方便性都强于其他方式。最初的目的也是做个好用的 GBA 模拟器跑在小游戏平台上。
        12
    amazingrise   27 天前 via Android
    给楼主点个赞。。另外虽然我(出于爱好)做的项目没 lz 这么强,但是做项目的时候也有一样的感受。。lz 加油!
        13
    jswh   27 天前
    楼主有没有试过安卓上的执行速度,如果安卓上执行速度正常,那就说明不是硬件问题(理论上不应该,因为 safari 是好的)所以就是 js 引擎慢。微信的 webview 还是 uiwebview,是很慢的,以前做娃娃机直播的时候也遇性能问题(没有 Media Source Extensions API 只能用 jsmpeg, javascrip 性能低下,后来沟通过,只有白名单的一些网页可以开启 wkwebview,开了这个就好了。
        14
    jswh   27 天前
    另外,我不知道这个 js 库是怎么处理的,但是根据“原来是 ARM 的 STM 指令耗时,90%的时间都消耗在 STM 上了”这个,估计是直接用 js 进行内存数据到图像数据的计算的,jsmpeg 用 webgl 的相关指令来解析视频数据流到图像的计算可以大大加速这个过程,小游戏也有 webgl,我觉得楼主可以考虑下这个方向。
        15
    Mutoo   27 天前
    GBA 模拟器的本质是硬件模拟而不是游戏引擎,而 js 在手机上的运行速度是 PC 上的 1/50 左右,在这种效率下想要高帧率运行是很难的,除非用 wasm 去实现。不过现阶段 wasm 在手机平台上还不是很稳定。

    附:GameBoy 模拟器 Javascript 实现完全解析
    http://imrannazar.com/GameBoy-Emulation-in-JavaScript:-The-CPU
        16
    kios   27 天前
    厉害,钻研精神让人佩服
        17
    urmyfaith   27 天前
    看完了,初看还以为问题解决了呢,万万没想到系列...

    = =


    By the way, 赞楼主钻研精神!
        18
    jadec0der   27 天前
    我觉得 lz 还是很 nb 的
        19
    ssshooter   27 天前
    太强了,能不能做个模拟 cpu 的教程
        20
    yksoft1ex   27 天前
    @Mutoo wasm 和 js 在 js 引擎里用的后端都差不多吧,比起裸 js 的性能提升还是有限。
        21
    tianyou666shen   27 天前
    很想玩小程序版本的 GBA
        22
    zkungfu123   27 天前
    很强了,不过不知道怎么过审
        23
    imaple   27 天前
    厉害啊,
        24
    Valid   27 天前
    。。我也在搞
        25
    hjq98765   27 天前
    LZ 很强大,虽然没看懂……
        26
    dishonest   27 天前
    做了估计也上不了啊,lz 还是放弃吧
        27
    Valid   27 天前
    gba 游戏文件一个就要 10+M,云端下载体验太差了。
        28
    DeweyReed   27 天前
    为什么不试试 retroarch
        29
    bernie9   27 天前
    特地登录问一句,这样移植会涉及到版权的问题吗?会不会被游戏厂商告。。。
        30
    RoyL   27 天前
    做了也不能上吧...版权还没到期吧,虽然不知道小鸡那种版权怎么解决的
        31
    nevin47   27 天前
    @Valid #27 我觉得这个不是问题,LTE 现在 1M+/s 很常见了
        32
    mrcuya   27 天前
    我尝试移植过 FC 的模拟器到小游戏上,需要同样的问题,模拟器上很流畅,真机幻灯片。后来也是发现了这个问题,花了一个下午时间放弃了。
    另外考虑到小游戏上线还要软著,审核麻烦。尝试移植到小程序上,发现 canvas 的 api 限制了很多,无法实现。遂放弃了,想想还是可惜。
    希望前端大神能出个解决方案
        33
    xi_lin   27 天前
    赞 lz
    不过小程序应该是 WKWebview 吧
        34
    xi_lin   27 天前
    能不能出个 demo,剥离掉渲染部分,只带数据解析部分,大伙一起来试试?
        35
    lizhuoli   27 天前 via iPhone
    ?微信不是内置 WebView 从 17 年底就切换到 WKWebView,使用 JSC 了吗。

    你意思是,小程序现在还用的 WebView 容器,用的是 UIWebView ?
        36
    BXIA   27 天前 via iPhone
    PWAs 多好用,折腾微信干啥
        37
    bearqq   27 天前 via Android
    看这标题我还以为最后审核死活不过呢
        38
    ljspython   27 天前
    能审核过吗
        39
    Elethomdog   27 天前
    💯
        40
    14night   27 天前
    lz 很厉害了。。
        41
    leon0903   27 天前
    666666
        42
    superarm   27 天前 via iPhone
    钻研精神厉害 感谢分享
        43
    Exia   27 天前
    赞一下,感觉学到了不少
        44
    w88975   27 天前
    @bernie9 任天堂的律师含跟迪斯尼的差不多,但不发布 ROM 包,仅发布模拟器是不影响的
        45
    w88975   27 天前
    @lizhuoli 因为没办法具体的知道小游戏所用的内核,仅仅是通过一篇文章介绍了解的,也没办法验证
        46
    zepto   27 天前
    任天堂法务部表示严重关注
        47
    nekoyaki   26 天前
    虽然楼主很厉害但是你图里那个是众神三角&四之剑,不是梦见岛哇。。。
        48
    dreamwar   26 天前
    厉害
        49
    w88975   26 天前
    @mrcuya 我在移植 FC 模拟器的时候,只遇到过浏览器端闪屏的问题,实现一个 canvas 的双缓冲就行了。
        50
    w88975   26 天前
    @nekoyaki 对 随便找了个 rom 来测的
        51
    zyEros   26 天前
    我之前有改过,里面有些困难也解决了,坑不少,但是涉及到任天堂的版权问题,就没有继续往下做了。
        52
    w88975   26 天前 via iPhone
    @zyEros 可否分享一下经验😁 留个联系方式
        53
    Vincent720   26 天前
    期待大佬出手,让我学习学习😅
        54
    Enix   26 天前 via iPhone
    很厉害,注意休息!
        55
    chensong004   26 天前
    技术很厉害,赞一个!提前考虑版权问题,要不然白忙活了。
        56
    cantonadong   26 天前 via Android
    @w88975 FC 可玩性太低怕是没玩过霸王大陆、热血、天使之翼
        57
    fox0001   26 天前 via Android
    说起来,梦见岛好像还没通关,众神的三角力量和小人帽都没完美通关,四支剑一直玩不了…
        58
    windlee09   26 天前
    最近刚刚过审了一个小游戏, 软著通过后。单小游戏的图片、音效、背景音乐。都有严格的审核。被打回过 20 多次 基本上都是图片侵权了。开发引擎是用 layabox
        59
    libook   26 天前
    用 LLVM 把 C、C++写的 GBA 模拟器转成 Web Assembly,应该能接近原生编译的性能。

    不过不知道微信支持的怎么样,微信开发工具基本上都是黑盒吧,摸索起来挺痛苦的。
        60
    w88975   26 天前 via iPhone
    放弃了,微信小游戏的引擎限制太多了,有个问题是无法解决的,就是音频播放,小游戏的 js 引擎无法实现音频处理,只能播放预设音频😑
        61
    123s   25 天前
    牛逼啊
        62
    wake1bear   25 天前
    果真是血泪史,顺膜拜一波大佬
        63
    MINYAN   25 天前
    牛逼牛逼~
        64
    JerryLin   25 天前
    楼主这种钻研精神,相当佩服
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3313 人在线   最高记录 4385   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 21ms · UTC 10:18 · PVG 18:18 · LAX 03:18 · JFK 06:18
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1