龙芯 3A4000 游戏编译运行记录

DSC03387_副本_修复后.jpg

二、游戏表现

龙芯 3A4000 的 CPU 核心仍属于 MIPS64 架构。理论上可以兼容运行绝大部分之前基于 MIPS 架构的可执行程序,但是实际测试下来,之前龙芯 2F 上编译的游戏基本都无法在 3A4000 上直接运行。一般通常是动态链接库的问题,比如库的版本不兼容,即使版本相同,也可能由于链接方式的变化导致无法找到,如下图所示。

游戏库不兼容.jpg

解决方法要么是重新手动链接库文件,要么就只能重新编译。实际上,只要没有编译工具问题,一般我都是选择重新编译源代码更方便点。之前在龙芯 2F 上编译成功的游戏,在龙芯 3A4000 上也不存在任何问题。具体编译过程可以参考前文

2.1 仙剑奇侠传

由于系统环境的更新,这次编译的仙剑使用 SDLPAL 最新版的源码。编译的过程要比旧版复杂一点,特别是 libmad 这个依赖库,需要针对 mips64el 架构修改源代码。具体编译过程记录如下。

项目地址:https://gitee.com/sdlpal/sdlpal

# 安装必要依赖
$ sudo apt install build-essential libsdl2-dev libsdl2-mixer-dev libmad0-dev libogg-dev libvorbis-dev libopus-dev libopusfile-dev libfltk1.3-dev libavcodec-dev libavformat-dev libswscale-dev libadplug-dev dosbox mame chocolate-doom upx-ucl

# 下载源代码
$ git clone https://gitee.com/sdlpal/sdlpal.git
$ cd sdlpal
$ git submodule update --init --recursive

# 下载并安装 TinySoundFont
$ git clone https://github.com/schellingb/TinySoundFont.git
$ cd TinySoundFont
$ sudo cp *.h /usr/local/include/
$ sudo make install
$ cd ..

# 下载并安装 stb_image
$ git clone https://github.com/nothings/stb.git
$ cd stb
$ sudo cp stb_image.h /usr/local/include/
$ cd ..

其中源代码依赖的 libmad 模块中的 libmad/fixed.h 代码中包含 x86 汇编,另外 mad.h 也需要从 github 源码更新文件后修改。需要根据 MIPS 架构稍作修改。

参考文档: https://blog.csdn.net/qq_38350702/article/details/108450569,注意不要按照其中的内容修改 mad.h

$ vim libmad/fixed.h

# 搜索关键字“MIPS”,有两处修改内容
# 找到相关内容,第一处修改内容

#elif defined(FPM_MIPS)   //找到这一段命令,原来就有,在这回车,在下面添加命令

//以下为添加的内容
/* Test for gcc >= maj.min, as per __GNUC_PREREQ in glibc */
#if defined (__GNUC__) && defined (__GNUC_MINOR__)
#define __GNUC_PREREQ(maj, min) \
 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
#else
#define __GNUC_PREREQ(maj, min)  0
#endif
#if __GNUC_PREREQ(4,4)
  typedef unsigned int u64_di_t __attribute__ ((mode (DI)));
# define MAD_F_MLX(hi, lo, x, y) \
  do { \
      u64_di_t __ll = (u64_di_t) (x) * (y); \
      hi = __ll >> 32; \
      lo = __ll; \
   } while (0) 
#else
//以上内容在此添加

# 第二处添加内容,紧挨着往下翻,找到这条
# if defined(OPT_SPEED)命令,在此条命令,上面添加

#endif            //原有内容
#endif /* __GNU_PREREQ(4,4) */        //添加内容
#if defined(OPT_SPEED)         //原有内容

# 保存修改,关闭

# 修改 libmad/mad.h
# 建议合并 libmad 仓库的版本和 sdlpal 修改的版本
$ wget https://github.com/fasterthanlime/libmad/blob/master/mad.h
$ vim libmad/mad.h

修改完源代码后,即可正常编译。

# 编译源代码
$ cd unix
$ make

编译完成后生成 sdlpal 可执行文件,不过游戏的其他数据文件还需要从原版文件夹获得。

image-20240603143708111.png

2.2 RetroArch 模拟器

RetroArch 是一个整合模拟器前端,界面模仿了 PS3 的 XMB 风格。

image-20240603150102430.png

RetroArch 可以加载不同的模拟器核心 (Core),模拟运行各种怀旧主机系统,比如 DOSBOX, NES, GBA, NEOGEO 等。其中,RetroArch 的前端框架可以直接通过 apt 包安装,但是核心文件需要手动编译。

之前有 Wells 大佬分享的在龙芯 3A2000 上编译的核心文件包,已经包含了最常用的几种模拟器核心比如 FC/NES, PSX, MSX, NEOGEO 等,测试在 3A4000 上也是完全可用的,参考地址。如果还需要模拟其他机种,我自己也尝试了在 3A4000 上编译了一套更丰富的核心文件,有更多需要的可以下载,下载地址。

全部核心文件的项目地址:https://github.com/libretro/libretro-super,完整下载项目的大小达到了恐怖的 26G(去除 .git 文件大约 11G),编译的过程耗费十几个小时,极为漫长。

# 安装必要依赖
$ sudo apt install -y build-essential git pkg-config libtool autoconf automake libasound2-dev libpulse-dev libaudiofile-dev libopenal-dev libv4l-dev libgl1-mesa-dev libfreetype6-dev libgbm-dev libsdl2-dev libxml2-dev zlib1g-dev libudev-dev libsystemd-dev

# 安装 RetroArch
$ sudo apt install -y retroarch

# 导入核心文件,以 .so 为后缀
# 通过下载或者自行编译,获取核心文件
# 将所有.so文件复制到特定位置
# 这个位置也可以通过 ~/.config/retroarch/retroarch.cfg 文件修改
$ cp yourcore/*.so /usr/lib/mips64el-linux-gnuabi64/libretro/

# 另外需要修改中文字体支持,否则默认显示方块
# 修改 ~/.config/retroarch/retroarch.cfg 文件
# 修改 xmb_font 为一个中文字体
xmb_font = "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc"

正确导入核心文件之后,重启 RetroArch 后在 Load Core 菜单下即可看到各种核心。

image-20240603150305052.png

初次加载某个 ROM 时,可以在 Load Content 中按照目录结构寻找。成功运行一次之后就能在游玩列表中直接选择了。

image-20240603151116165.png

简单测试了 FC/NES, GBA, NEOGEO, PSX 几种模拟核心,前面三种核心比较简单,基本都能顺利模拟运行。但是 PSX 的三种模拟核心均不能完美运行,运行起来会非常卡顿,或者声音有问题。

NES 模拟器

经典的任天堂 FC/NES 主机模拟器,当年红极一时的小霸王学习机的一大“重要”功能就是“兼容 FC 卡带”。我之前在玩 RetroPIE 系统的时候自行整理了一套精选的 NES ROM,下载地址,在这里测试基本没有问题,只是一直没搞清楚对应图片和演示视频的加载,不过无伤大雅。

项目地址:https://github.com/libretro/nestopia

image-20240603152238822.png

GBA 模拟器

经典的任天堂 GBA 掌机模拟器,我这里仅仅测试了逆转裁判的几个 ROM,基本没有问题。

项目地址:https://github.com/libretro/gpsp

image-20240603153009107.png

NEO GEO 模拟器

SNK 出品的 NEO GEO MVS 街机,一般可以用来打打经典的拳皇系列,和合金弹头系列,均没有问题。

项目地址:https://github.com/libretro/fbalpha2012_neogeo

image-20240603153504030.png

2.3 PCSX-ReARMed 模拟器

上面使用 RetroArch 无法完美模拟 PS1,并不一定是龙芯的机能限制导致的,毕竟 PS1 的机能也很古老了。更多原因应该还是 RetroArch 整合的模拟核心的代码质量不高,也没有针对 MIPS64 架构的优化。我这里又尝试了一下单独的 PCSX-ReARMed 模拟器,发现模拟效果效果要好得多,基本属于可玩的状态了。唯一的缺陷是对于手柄的支持不佳,只能使用键盘游玩。

项目地址:https://github.com/libretro/pcsx1-libretro

编译这个项目很简单,直接 make 即可。

# 编译
$ make

实际运行合金装备的效果。

image-20240603154844090.png

其他还有一些 PSX 核心项目,比如这个 Beetle PSX,不过我个人测试都不太合适,有需要可以自行尝试测试。

项目地址:https://github.com/libretro/beetle-psx-libretro

编译方法也很简单,直接 make 即可。

# 默认编译
$ make

# HW模式编译,我也不知道有啥区别
$ make HAVE_HW=1

2.4 PS2 模拟器

在成功编译了 PS1 模拟器后,自然会进一步想要编译 PS2 模拟器。我这里尝试了 PCSX2 和 Play! 模拟器,但是目前所有的 PS2 模拟器代码都深度依赖 x86 的 SSE 系列指令集 (最低 SSE2 版本),这也意味着将其移植到 MIPS 架构上会非常困难。

我在花费了数十个小时反复 DEBUG,修改增加针对 MIPS64 架构支持的头文件代码定义,改到代码深处统计了一下,发现这个移植工程太过于浩大,所以只能暂时放弃了。如果有愿意移植这个模拟器的大佬,我可以分享之前 DEBUG 代码的笔记和修改后源代码,应该能提供一些基础思路。

PCSX2 项目地址:https://github.com/PCSX2/pcsx2/

Play! 项目地址:https://github.com/jpd002/Play-

2.5 PSP 模拟器

索尼的 PSP 掌机模拟器 PPSSPP 也是一个非常优秀的项目,虽然上面的 RetroArch 也有这个项目的整合核心,但是我并没有编译成功。但是这个项目是有独立的版本的。

项目地址:https://github.com/hrydgard/ppsspp

具体的编译过程如下:

# 克隆 PPSSPP 项目
$ git clone --recurse-submodules https://github.com/hrydgard/ppsspp.git

# 如果有子模块没有下载成功,可以执行同步补全
$ git pull --rebase https://gitee.com/mirrors/ppsspp.git
$ git submodule sync
$ git submodule update --init --recursive

# 安装基本依赖
$ sudo apt install build-essential cmake libgl1-mesa-dev libsdl2-dev libsdl2-ttf-dev libfontconfig1-dev libvulkan-dev libcurl4-openssl-dev libsnappy-dev libunistring-dev libopenxr-dev

# 编译 PPSSPP
$ cmake path/to/ppsspp
$ make -j 4

相比于 PCSX2 而言,PPSSPP 的项目代码倒是没有依赖 SSE 指令集,也提供了 MIPS 架构的代码分支。不过可能是由于子项目的依赖比较复杂,MIPS 架构端的代码似乎没有经过太多验证,基本上每编译几步就会有一段代码有一些小问题,改到 Core/MIPS/IR/IRJit.h 这里的时候,有一个 mips_ 指针出现了空引用错误,但是找了半天也定位不到错误,只能作罢,可惜最终还是没有编译成功,

参考文档:https://github.com/hrydgard/ppsspp/wiki

2.6 我的世界

折腾了这么久的 C++,这次来个 Java 端的游戏吧。这里我们就尝试一下经典游戏『我的世界 Minecraft』,使用 HCML 启动器,官网下载地址,下载 jar 格式的版本。虽然 Java 号称“一次编译,到处运行”,但是复杂的项目还是需要依赖具体的 CPU 架构。比如想要顺利运行我的世界,除了 Java 环境本身,还需要 JavaFX 和 LWJGL 这两个图形库。

对于 JavaFX 库,可以通过安装 OpenJFX 来替代执行;而对于 LWJGL 这个库,目前 Loongnix 20 和 Debian 12 都有 LWJGL2 版本,但是似乎不太支持 LWJGL 3。所以运行 MC 的不同版本,情况也不太一样。

1.12.2 版本

这个版本相对简单,在配置好 Java 基本环境和 OpenJFX 的前提下,只要下载 HCML 最新的 jar 文件,下载地址,写一个执行脚本即可。

# 编写启动文件
# 其中 /usr/share/openjfx/lib 为 JavaFX 库所在位置
$ vim run.sh
java -p /usr/share/openjfx/lib --add-modules ALL-MODULE-PATH -jar HMCL-3.5.8.jar

# 增加执行权限
$ chmod +x run.sh

# 启动 HCML 启动器,下载 Minecraft 客户端文件
# 我这里选择 1.20.2 版本的客户端
$ ./run.sh

除了客户端单机游玩,还可以同时部署 MC Java 服务端,我尝试了使用 Mohist 服务端的 1.12.2 版本,这个服务端的好处是各种历史版本的支持都很好,下载源速度也很快。稍加配置就可以在龙芯机器上运行一个简易的 MC 服务器了。

1.14.4 以上版本

对于 LWJGL3 这个库,官方并没有针对 MIPS64 的编译版本,不过之前有 FlyGoat 大佬编译好的文件可以用,参考地址。编译好的 JAR 下载地址。我这里尝试安装的 MC 版本是 1.20.2,具体步骤如下:

# 安装 Java 17 环境
$ sudo apt-get install default-jre default-jdk openjfx

# 安装 OpenJFX 库
$ sudo apt install openjfx

# 下载 HCML 启动器 jar 文件
$ wget https://github.com/HMCL-dev/HMCL/releases/download/release-3.5.8/HMCL-3.5.8.jar

# 编写启动文件
# 其中 /usr/share/openjfx/lib 为 JavaFX 库所在位置
$ vim run.sh
java -p /usr/share/openjfx/lib --add-modules ALL-MODULE-PATH -jar HMCL-3.5.8.jar

# 增加执行权限
$ chmod +x run.sh

# 启动 HCML 启动器,下载 Minecraft 客户端文件
# 我这里选择 1.20.2 版本的客户端
$ ./run.sh

第一次先启动 HCML 一次,只要 JavaFX 基本环境正常就可以正常启动界面。我们先把账号登陆上,同时下载对应的游戏版本,这里下载 1.20.2 版本,默认的自动下载文件都在 HCML 启动器所在 .minecraft 目录下。

此时如果试图启动 Minecraft 会因为默认下载的 lwjgl 库的问题无法执行。我们需要下载 MIPS64 专用的版本进行替换。

# 下载 liblwjgl.so 库文件
# 复制 /usr/lib/jni/liblwjgl.so 到 minecraft 客户端内
# 这里的 MC 版本为 1.20.2
$ apt-get install liblwjgl-java
$ cp /usr/lib/jni/liblwjgl.so .minecraft/versions/1.20.2/natives-linux-mips64el/

# 下载 FlyGoat 编译的 MIPS 版的 lwjgl3 库
$ wget https://github.com/FlyGoat/lwjgl3-mips64/releases/download/3.2.3mips64%2B2/lwjgl3-mips64-release.tar.gz

# 替换原有的 lwjgl3 jar 文件
# 注意实际的文件名可能有细微差异,需要手动修改
# lwjgl 相关的 jar 文件位置在这里:
$ .minecraft/libraries/org/lwjgl/
# 有多个不同的组件,最好一一对比后复制替换

此时仍然会报错,但是没有找到解决办法。

image-20240605020305610.png

另外又使用创学院百科提供的客户端整合包,发现其自带 1.14.4、1.15.1 和 1.15.2 版本可以顺利进入游戏,但是会卡在 MOJANG 标题画面,读取进度一半的位置。

最终还是以失败告终,感觉就差临门一脚,但是最终还是没有找到解决方法。考虑到这个整合包也比较旧了,主要是针对 Fedora 28 系统制作的,而且明确不支持 Loongnix 系统,其在 Debian 12 上的兼容性是可以遇见的。FlyGoat 修改后的 LWJGL 库也无法顺利在新系统上编译成功。

其他开源版本

除了死磕原版, Github 上还有很多开源版的 Minecraft 项目,编译方式都很简单,不再赘述。

ClassiCube 项目地址:https://github.com/ClassiCube/ClassiCube

这个项目构建的比较完善,不过启动器在下载游戏资源时总是会报 403 错误,估计是仓库源屏蔽了国内 IP,试了很多方法都无法成功下载,虽然可以用迅雷等其他工具下载,但是由于不知道文件存储结构,也就只好作罢,不想继续研究了。没有正确贴图的情况下,就呈现了一下这种状态:

image-20240605021749363.png

Craft 项目地址:https://github.com/fogleman/Craft

这个项目倒是没有贴图问题,不过做的更加简单,没啥好说的。

image-20240605022223475.png

  • 龙芯
    4 引用
  • 3A4000
    3 引用
  • 游戏

    沉迷游戏伤身,强撸灰飞烟灭。

    174 引用 • 814 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...