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

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

  •  1
     
  •   w88975 · 2019-02-19 21:57:14 +08:00 · 11304 次点击
    这是一个创建于 2139 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前言

    • 近期任天堂直面会发布了要重制塞尔达梦见岛的消息,勾起了我想在 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 上了,由于鄙人能力有限,对计算机底层不太熟悉,到这一步就放弃了

    结语

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

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

    = =


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

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

    不过不知道微信支持的怎么样,微信开发工具基本上都是黑盒吧,摸索起来挺痛苦的。
    w88975
        60
    w88975  
    OP
       2019-02-21 14:30:47 +08:00 via iPhone
    放弃了,微信小游戏的引擎限制太多了,有个问题是无法解决的,就是音频播放,小游戏的 js 引擎无法实现音频处理,只能播放预设音频😑
    123s
        61
    123s  
       2019-02-22 09:26:59 +08:00
    牛逼啊
    wake1bear
        62
    wake1bear  
       2019-02-22 09:56:22 +08:00
    果真是血泪史,顺膜拜一波大佬
    MINYAN
        63
    MINYAN  
       2019-02-22 14:29:06 +08:00
    牛逼牛逼~
    JerryLin
        64
    JerryLin  
       2019-02-22 17:32:52 +08:00
    楼主这种钻研精神,相当佩服
    bobiscool
        65
    bobiscool  
       2020-07-31 22:19:14 +08:00
    牛皮
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1938 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 00:56 · PVG 08:56 · LAX 16:56 · JFK 19:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.