Contents
前言
今天闲来无事,忽然想着搭建一个web的老游戏模拟器,于是在hub.docker上搜索了一番,发现了 linuxserver/emulatorjs这个项目,官方解释是:"基于浏览器的网络仿真,几乎可移植到任何设备,用于许多复古游戏机",其实这个就是用web方式来实现RetroArch模拟器。
其支持的架构为:
我主力docker环境是m1的mac-mini(arm64),备用docker环境是基于inter 13代i5的mini主机(x86-64),都可以,这次就部署在备用docker环境吧。
部署emulatorjs
提前创建要用到的目录
创建配置文件目录:
mkdir -p /docker/emulatorjs/config
创建游戏rom目录:
mkdir -p /docker/emulatorjs/data
我因为有现成的nes和gba的rom,所以额外创建了2个文件夹并把对应的rom拷贝了进去:
mkdir -p /docker/emulatorjs/data/nes/roms
mkdir -p /docker/emulatorjs/data/gba/roms
重要:
emulatorjs支持多种游戏机的模拟器,类型如下:
- 3do
- arcade
- atari2600
- atari7800
- colecovision
- doom
- gb
- gba
- gbc
- jaguar
- lynx
- msx
- n64
- nds
- nes
- ngp
- odyssey2
- pce
- psx
- sega32x
- segaCD
- segaGG
- segaMD
- segaMS
- segaSaturn
- segaSG
- snes
- vb
- vectrex
- ws
这些游戏机的rom在data文件夹中是以”游戏机类型命名”的文件夹/roms来区分的,例如nes的rom的存放路径为:/data/nes/roms
,gba的rom存放路径为:/data/gba/roms
,所以如果大家本来就有对应游戏机的rom,可以提前就建好相应的文件夹,并把rom拷进去,然后在创建docker的时候就用-v的方式绑定,这样就免去了之后单独上传rom的麻烦。
部署emulatorjs
命令如下:
docker run --name=emulatorjs -d --restart=always --network=public-net \
-e PUID=0 \ #可选功能,PUID和PGID的具体数值由id命令决定,比如我的root账号,用"id root"输出为"uid=0(root) gid=0(root) groups=0(root)",如果遇到权限问题可以尝试该参数
-e PGID=0 \ #同上
-e TZ=Asia/Shanghai \ #指定时区
-e SUBFOLDER=/ \ #可选功能,如果反向代理使用了代理目录功能,则需该参数配合使用(例如该容器部署在云主机上,需要通过一个域名同时访问管理控制台和模拟器前端这种场景)。
-p 3500:3000 \ #将宿主机3500端口映射到容器3000端口,这是管理控制台端口,大家根据实际情况修改
-p 9600:80 \ #将宿主机9600端口映射到容器80端口,这是模拟器前端访问端口,用于浏览和启动游戏,大家根据实际情况修改
-p 4001:4001 \ #可选功能,IPFS对等端口,如果想参与P2P网络分发前端作品,请在出口设备上做好此端口的映射
-v /docker/emulatorjs/config:/config \ #配置文件挂载目录
-v /docker/emulatorjs/data:/data \ # 游戏数据文件挂载目录
-v /docker/emulatorjs/data/nes/roms:/data/nes/roms \ #可选操作,指定nes游戏rom目录
-v /docker/emulatorjs/data/gba/roms:/data/gba/roms \ #可选操作,指定gba游戏rom
linuxserver/emulatorjs:latest
以上命令使用的时候请大家自行删除#后面的注释内容。
通过管理控制台访问emulatorjs进行管理
初始化文件
使用http://宿主机IP:3500访问emulatorjs,出现如下界面:
点击上图红框中的download,会自动开始初始化下载文件:
当显示上图左上方红框中的Downloaded All Files则表示下载完成,这时点击右上方红框中的黑色正方形按钮关闭该界面。
Rom Management
下图是Rom Management的内容:
上图可以看到我提前映射的gba和nes的文件夹里的rom其实已经识别出来了,不过仍旧需要点scan进行扫描:
点击下图红框中的gba进入:
然后点击下图红框中的Add All Roms to Config将右边已经扫描出的游戏加入配置:
同理操作nes。
后续更新了对应的roms文件夹内容以后需要在这里用Scan重新扫描。Default的DL/Update是重新自动更新其他系统文件,就是前面初始化时候下载的那些文件。
Config Management
下图是Config Management的内容:
这里是修改各个类型模拟的关键参数,我们看看就好,不要动。
File management
下图是File Management的内容:
这里可以直接管理容器使用-v 参数挂载的 data 文件夹内容,后续rom的上传就在这里实现(当然也可以直接在宿主机上操作),例如对gba的rom上传:
如果前面没有和我一样直接用 -v 参数指定包含具体游戏 rom 目录的,就需要在这里进入对应的游戏类型的 rom 文件夹(例如上图中的/gba/roms/),用 upload 上传 rom,然后回到Rom Management 界面运行在对应的游戏类型重新运行 scan:
Profile Management
下图是 Profile Management 的内容:
这里用于创建不同账号的用户名密码及配置文件(retroarch.cfg),在访问模拟器前端的时候,可以使用相同账号登录并上传下载配置,这个非常有用处,简单来说就是用一个浏览器登录一个账号并完成按键配置,然后上传配置,在另一个浏览器登录相同账号并下载配置,这样实现了按键配置同步。而直接修改默认配置就要利用default账号了,具体参见文章:emulatorjs模拟器修改默认按键配置
另外,我也尝试过直接修改源码里面的默认设置,想直接一劳永逸的改默认配置,但是没有成功,大家也可以尝试一下,具体的文件容器内部路径如下:
/emulatorjs/frontend/data/emu-main.js,可以在宿主机上运行如下命令用容器内的vi直接打开:
docker exec -it emulatorjs vi /emulatorjs/frontend/data/emu-main.js
直接在vi中使用/defaultControllers然后回车搜索关键字”defaultControllers”:
上图中value后面的值是键盘按键,value2后面的值是手柄,前方的数字项的按键定义如下:
这个有兴趣的朋友研究下把,我改了emu-main.js以后没有生效,网上唯一提到这个的帖子里只有一句话,说还需要改loader.js文件,让emulator.js先于emu-main.js加载,因为我不懂编程,研究了半天loader.js也没搞懂(我还专门去看了java菜鸟教程。。。),最终放弃了,希望懂编程的朋友能完成这最后一步。
注:emu-main.js、emulator.js和loader.js都在容器的/emulatorjs/frontend/data/
目录中。
通过模拟器前端访问emulatorjs进行游戏
使用http://宿主机IP:9600访问前端界面:
点击左上角的红框,即可进入用户名密码登录界面:
上图中红框部分的用户名密码既是前面我们在Profile Management部分创建的,也可以不登录,这样就会对应default用户。
因为我只有 gba 和 nes 的游戏,所以上图界面上只有 2 个选项,可以用小键盘的上下键或者鼠标滚轮选择类型,然后按回车即可进入,然后看到具体的游戏:
一样使用鼠标滚轮或者小键盘的上下箭头选择对应的游戏,然后回车即可进入:
对于游戏,默认键盘按键为:上下左右分别对应4个小箭头,z,x为B和A,右shift是选择,回车是确认。(我只想问,设置这个键盘默认按键的大神是怎么想的。。?)
如果要修改按键,进入具体游戏以后,按F1,然后按如下顺序修改:
不要直接用F1调出的Quick Menu这个菜单的Controls,如下图:
这里不能改按键,只能选择已有的映射(至少我这里是)。
最终效果如下:
配置公网访问
如果要发布到公网上的,大家需要根据实际环境和自己使用的反向代理选择最适合自己的发布方式,可以参考我以前的几篇文章:
1、docker系列 使用docker基于NPM搭建自己的反向代理
2、linux面板系列 配置反向代理并使用非443端口进行发布
3、家庭数据中心系列 通过国内备案云主机白嫖cloudflare实现国外快速访问国内站点
4、家庭数据中心系列 通过无公网IP的家庭宽带白嫖cloudflare实现快速建站(通用)
其中第1,2种方式适合有公网ip却没有合法443端口的环境(家庭宽带、未备案的云主机),需要在url后面加非标端口(如果使用cloudflare建站的不需要加端口,但是需要自定义源站端口,这个可以参考:家庭数据中心系列 通过cloudflare的Origin Rules解决建站有公网IP却没有合法的80、443端口的问题)。第3种方式适合有备案的云主机,第4种方式适合所有环境(包括没有公网IP的环境),也是我建议的方式(不管你的环境有没有公网IP,因为这种方式不需要直接在公网上跑https流量)。
这里还涉及一个问题,就是有2个端口,一个是管理控制台端口,一个是前端游戏端口,我建议发布前端游戏端口即可,如果要发布2个端口又想只用一个域名,则需要用到反向代理的代理目录功能,同时需要和部署游戏时的-e SUBFOLDER
参数配合。
后话
最后我要说一下,其实,之后的配置就要涉及到另一个领域了:既RetroArch模拟器的配置。说实话,我现在都是晕的,这个模拟器的配置逻辑太反人类了,而且由于键盘上的很多按键默认都定义了功能,却又在模拟器的配置选项里却并没有体现出来,所以导致配置完以后发现有冲突,比如默认的k和p都是暂停,你如果在k和p上设置了其他功能,一按的同时还暂停游戏。。这个等我用一段时间之后看有没有心情再写一篇文章来说把。
备注:玩了一下,目前发现的默认快捷键有如下:
H:reset
K和P:暂停
L和空格:加速 (L点住加速,放开就停止加速,空格按一下就一直加速,再按一下停止加速,不要随便点空格键玩。。我魔兽世界养成的习惯在这里非常不适应)
n和m:sharder:”retroarch.glslp” (不知道啥用处)
小键盘+和-:调节音量