爱意满满的作品展示区。
esw

用 Typescript 写了个 NES 模拟器

  •  4
     
  •   esw · Apr 6, 2020 · 9339 views
    This topic created in 2403 days ago, the information mentioned may be changed or developed.

    假期无聊想着搞一个 NES 模拟器玩玩,目标在浏览器中运行,断断续续搞了一个月之后基本五脏俱全了,声音和图像都没啥大问题

    github 地址:tsnes

    在线演示地址:tsnes-demo

    当初做模拟器的时候网上也找不到完整的入门教程,所以干脆就自己抽空慢慢更新教程了:NES 模拟器开发教程

    模拟器效果图:

    重装机兵 p1

    Mario1 p2

    我的 18 款 MBP i7 CPU,在 Chrome 中运行 CPU 占用大概 70%,所以理论上 i5 应该也可以全速模拟。

    另外由于音频和绘图也会占用不少 CPU,所以如果采用 Web worker 将模拟器的线程分离出去,理论上在手机中应该也能全速模拟

    由于我是以库的形式进行开发的,所以没有花心思美化页面(~~主要还是懒~~)

    55 replies  •  2020-04-11 12:20:23 +08:00
    zhuawadao
    zhuawadao
    Apr 6, 2020
    1
    别让楼主灰心,支持一下~
    lzdyes
    lzdyes
    Apr 6, 2020
    3
    厉害了!
    yuuko
    yuuko
    Apr 6, 2020
    4
    厉害了
    anUglyDog
    anUglyDog
    Apr 6, 2020
    5
    强
    anUglyDog
    anUglyDog
    Apr 6, 2020
    6
    你这做好看点可以引流啊,太有情怀了
    idealhs
    idealhs
    Apr 6, 2020
    7
    挺好奇,为什么如此低性能的一个机器,浏览器的模拟器跑起来这么吃资源啊
    GPLer
    GPLer
    Apr 6, 2020
    8
    @idealhs 模拟本身就有性能损失,更不用说用的是脚本语言,执行效率本身就不高,原始的机器性能虽然低,但好歹利用率高,性能浪费的少。
    LukeChien
    LukeChien
    Apr 6, 2020 via Android
    9
    好像见过 WebAssembly 做的,那个性能会好一些,楼主同样🐮🍺
    zj
    zj
    Apr 6, 2020
    10
    这个要支持下。
    across
    across
    Apr 6, 2020
    11
    看了文档还没写到显示部分,是用 webgl 画?
    across
    across
    Apr 6, 2020
    12
    @across 看了下 ppu 代码是纯手动画的啊,怪不得····
    renmu
    renmu
    Apr 6, 2020 via Android
    13
    我不当勇士了,我要回家修战车
    esw
    esw
    OP
    Apr 6, 2020
    14
    @zhuawadao 谢谢!
    esw
    esw
    OP
    Apr 6, 2020
    15
    @idealhs NES PPU 时钟 5MHZ 以上,也就是说模拟的时候每秒要执行 500w 以上次运算,而且每次运算需要很多逻辑来完成,再加上 JS 性能损耗,所以比较费 CPU
    esw
    esw
    OP
    Apr 6, 2020
    16
    @across 目前是 PPU 生成 RGB 点阵数据直接扔给 canvas 画图和缩放,只不过都在一个线程完成了
    firefox12
    firefox12
    Apr 6, 2020
    17
    很牛逼 我想问是不是要把 cpu ppu 系统本身全模拟出来 再做?
    esw
    esw
    OP
    Apr 6, 2020
    18
    @firefox12 我是找一些简单的或者自己写的测试程序,然后一点一点开发,不需要一下子全模拟好,在不熟悉所有硬件行为的情况下也不现实
    firefox12
    firefox12
    Apr 6, 2020
    19
    @esw 但是 没有模拟 cpu 和 ppu 你怎么让卡带里的内容跑起来? 我的看法 是读卡带文件 ,然后让模拟 cpu 开始运行里面的二进制,然后让结果显示出来吧。
    zwxharry
    zwxharry
    Apr 6, 2020
    20
    重装机兵回忆杀,红狼,尼娜
    esw
    esw
    OP
    Apr 6, 2020
    21
    @firefox12 对,首先开发 CPU,使用 http://nickmass.com/images/nestest.nes 来开发,它有 log 可以对照: http://www.qmtpro.com/~nes/misc/nestest.log ,这样就可以一条指令一条指令地开发,同时用 log 来检测错误,最终整个文件正常运行完就说明 CPU 大部分工作开发完了,然后使用同样的方法,一点一点开发 PPU
    Arrowing
    Arrowing
    Apr 6, 2020
    22
    重装机兵好评,upupup
    Warder
    Warder
    Apr 6, 2020
    23
    很强,一个月就做好了啊
    mengkun
    mengkun
    Apr 6, 2020
    24
    太强了……
    hive
    hive
    Apr 6, 2020
    25
    收下我的膝盖
    superliwei
    superliwei
    Apr 6, 2020
    26
    很强。。。
    esw
    esw
    OP
    Apr 6, 2020
    27
    @Warder 不算完全做好,nes mapper 太多了,简直就是无底洞,目前只完成了一些常用 mapper
    esw
    esw
    OP
    Apr 6, 2020
    28
    @Mohanson 学习了!
    Mohanson
    Mohanson
    Apr 6, 2020
    29
    @esw 哈哈, 我还写过雅达利街机的模拟器: https://github.com/mohanson/space-invaders, 这些游戏机因为没有操作系统所以模拟起来比较容易, 到 PS 时代后的机器就不好模拟了, 去年想过做 switch emu, 调研了一下就立马放弃了.
    Meltdown
    Meltdown
    Apr 6, 2020 via Android
    30
    膜拜
    zhw2590582
    zhw2590582
    Apr 6, 2020
    31
    可以大概说说怎么个原理吗
    luny
    luny
    Apr 6, 2020
    32
    学习了!
    Archeb
    Archeb
    Apr 7, 2020 via iPhone
    33
    楼主🐮🍺!
    happy8109
    happy8109
    Apr 7, 2020
    34
    实现个实时存盘吧
    esw
    esw
    OP
    Apr 7, 2020
    35
    @Mohanson 是啊,资料太少,其他主机基本都没有 nesdev 这样全的网站了
    esw
    esw
    OP
    Apr 7, 2020
    36
    @zhw2590582 其实就是软件模拟 NES 里面芯片的逻辑,然后电信号变成函数调用
    esw
    esw
    OP
    Apr 7, 2020
    37
    @happy8109 存盘已经实现了,现在每 3 秒保存在 localstorage 里面
    esw
    esw
    OP
    Apr 7, 2020
    38
    @happy8109 刚看错了,才反应过来你说的是实时存档,这个确实还没搞
    augustheart
    augustheart
    Apr 7, 2020
    39
    @esw gba 啊,唯一一台主机发售前就让人给模拟了的游戏机……
    UnknownR
    UnknownR
    Apr 7, 2020
    40
    卧槽🐂🍺,star 一个学习一下
    eivs
    eivs
    Apr 7, 2020
    41
    这个感觉更流程一些

    https://github.com/bfirsh/jsnes
    wanguorui123
    wanguorui123
    Apr 7, 2020
    42
    666
    baxtergu
    baxtergu
    Apr 7, 2020
    43
    在 github 发现了这个仓库看了下代码,一开始以为是对 jsnes 的 ts 实现,后来发现好像不是。不过楼主厉害 一个月能做成这样,666
    sivacohan
    sivacohan
    Apr 7, 2020
    44
    @Mohanson 我支持了一个小额赞助~
    yun77op
    yun77op
    Apr 7, 2020
    45
    厉害,可以尝试下用 assemblyscript 把 ts 转成 WebAssembly
    Mohanson
    Mohanson
    Apr 7, 2020
    46
    @sivacohan 天啦噜, 这是我收到过最大的一笔赞助费! 谢谢老板(认真
    exceptionplayer1
    exceptionplayer1
    Apr 7, 2020
    47
    真厉害,大佬
    lneoi
    lneoi
    Apr 7, 2020
    48
    厉害厉害
    boks
    boks
    Apr 7, 2020
    49
    牛逼,我最近刚好也想搞这个。
    lights
    lights
    Apr 7, 2020
    50
    重装机兵在国内真的好有名啊
    esw
    esw
    OP
    Apr 7, 2020
    51
    @eivs jsnes 之前看过源码,不过 es5 看得脑阔疼
    esw
    esw
    OP
    Apr 7, 2020
    52
    @yun77op js 的动态特性不一定能转把?
    nazhenhuiyi294
    nazhenhuiyi294
    Apr 8, 2020
    53
    有点流批
    uestcfei
    uestcfei
    Apr 9, 2020
    54
    这个是没有支持所有的 nes 格式的吗?我下载的有一些 nes 的游戏,运行提示:Unsupported mapper: 150,file 看了一下,没啥区别啊。和好奇这个 nes 文件的格式。
    esw
    esw
    OP
    Apr 11, 2020❤️2
    55
    @uestcfei 没有,nes 有几百种 mapper,大部分 mapper 逻辑都是不同的,所以要全支持的话相当于要实现上百颗芯片的逻辑,这是非常耗时耗力的,所以目前只支持了任天堂官方几个常用的 mapper 和重装机兵的 mapper:mapper 0-4,mapper 74
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4787 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 267ms · UTC 01:15 · PVG 09:15 · LAX 17:15 · JFK 20:15
    ♥ Do have faith in what you're doing.