ACGC-PC-Port的emu64之谜:N64显示列表解释器如何在PC上跑通《动物森友会》
【免费下载链接】ACGC-PC-PortUnofficial PC Port of Animal Crossing Gamecube项目地址https://gitcode.com/gh_mirrors/ac/ACGC-PC-Port点击查看免费下载ACGC-PC-Port 是一个将 GameCube 版《动物森友会》Animal Crossing移植到 PC 的开源项目。它不依赖任何模拟器而是把游戏原始的 C 代码直接编译运行在 x86 上。其中最耐人寻味的部分是名为emu64的 N64 显示列表Display List解释器——游戏每帧的画面上千个图元指令都先经过它的逐条翻译才能最终落到现代显卡上。本文将拆解这套三层渲染管线讲清楚 emu64 是什么、如何工作以及移植到 PC 时踩过的坑。一、三层渲染管线只换最后一层先给结论整个渲染链路有 3 层移植项目只重写了第 3 层。层级内容处理方式第 1 层游戏代码生成 N64 显示列表原样保留第 2 层emu64 解释显示列表翻译成 GX 调用原样保留第 3 层GXGameCube GPU API替换为 OpenGL 3.3每帧主循环在 src/graph.c 的graph_task_set00()中触发游戏场景先往显存区里写脚本然后统一调用一次emu64_taskstart()把整个脚本执行完。这种脚本与执行分离的结构正是 emu64 能独立存活的原因。二、显示列表一份来自 1996 年的画图脚本所谓 N64 显示列表本质是一串 8 字节的二进制指令Gfx结构体数组每条指令 2 个 32 位字第 1 个字的低 8 位是操作码其余位段是参数。游戏代码通过gSPVertex、gSPTriangle这类宏往里填空例如gSPVertex往顶点缓冲区写入 1 个或最多 128 个顶点gSPTri1/gSPTri2/gSPQuads从顶点缓冲区取索引画三角形/四边形gsSPSegment设置 16 个段寄存器把 24 位伪地址翻译成真实内存地址gDL/gSPEndDisplayList子列表跳转与列表结束这份汇编级的画图语言就是 GBIGraphics Binary Interface。《动物森友会》在 N64 规范之外还扩展了一批自定义指令如G_TRIN、G_SETCOMBINE_TEV定义在 include/libforest/gbi_extensions.h 中——这正是emu64名字里藏着 N64 血统的由来。三、解释器核心一张 64 槽位的命令分发表emu64 的主逻辑全部在 src/static/libforest/emu64/emu64.c约 6000 行对外接口只有几个极简函数封装在 include/libforest/emu64/emu64_wrapper.hemu64_init()/emu64_cleanup()每帧初始化与收尾emu64_set_ucode_info()登记游戏使用的微码类型多边形/精灵emu64_taskstart(Gfx*)开始解释一条显示列表它的执行模型非常经典解释器emu64_taskstart_r()进入死循环每次取出一个 8 字节的Gfx取出操作码减去起始偏移G_FIRST_CMD后作为下标查表再调用对应的成员函数处理。这张 64 槽位的分发表dl_func_tbl里每个操作码都映射到一个dl_G_XXX函数如dl_G_MTX处理矩阵栈、dl_G_VTX缓存顶点、dl_G_MOVEMEM处理灯光与视点的隐藏参数通道没实现的槽位填dl_G_NOOP静默跳过。有意思的是许多 GBI 命令的参数是位域拼接的比如一个 32 位字里塞进 3 个 19 位定点整数和一个 2 位标志位。emu64 内部用大量位移宏POLY_GET_V0_5b等把它们一颗颗抠出来再按 GameCube 的 GX 语义重新组装——这也是逆向时最烧脑的部分团队借助 Ghidra 手工修正了这些结构体定义教程可参考 docs/ghidra_basics.md。四、PC 移植三大关指针、字节序、32 位把这套解释器从 PowerPC 搬到 x86有三个隐形杀手1. 16 位地址装不下 PC 指针。GBI 命令里的地址字段只有 16 位外加段号在 GC 上够用但 PC 堆指针是完整的 32 位。项目为此写了专门的打包/解包层 pc/src/pc_gbi_runtime.c偶数地址直接借用最低位标记运行时指针奇数地址则存入 8192 槽的令牌表保证解释器能还原出真实地址。2. 大端与小端。显示列表由运行时生成顶点、矩阵、纹理头等全是按 GC 大端布局读取PC 是 x86 小端所以 include/libforest/gbi_extensions.h 中 30 多个位域结构体被逐一反向重排解释器内部还有大量#ifdef TARGET_PC的字节交换块。3. 必须 32 位编译。原反编译代码到处把指针强转成u32段地址翻译全靠它64 位下必崩。因此整个移植以 i686 工具链构建指针打包逻辑也因此成立。而真正的图形输出则完全绕开了 emu64第 2 层产出的 GX 状态与顶点由 pc/src/pc_gx.c 翻译成 OpenGL 3.3 调用纹理按 GC 的 10 种格式解码后进缓存TEV 着色阶段由 GLSL 着色器模拟。架构细节与已知坑如seg2k0段地址与 PC 堆指针冲突、32 位/-O0强制要求都记录在 pc/DOCUMENTATION.md。五、小结为什么解释器是移植的最优解emu64 的存在让这次移植变得优雅游戏代码与解释器都是纯 C、无硬件依赖的逻辑只有最底层的 GPU API 需要重写。对阅读源码的新手建议按这条路线走从 src/graph.c 的graph_task_set00()看每帧如何提交显示列表进入 src/static/libforest/emu64/emu64.c 的emu64_taskstart_r()理解查表分发对照 include/libforest/emu64/emu64.hpp 中 60 余个dl_G_XXX方法声明任选一条命令如dl_G_MTX读透再看 pc/src/pc_gx.c 观察 GX 状态如何最终变成 OpenGL 调用一句话总结emu64 之谜的答案就是用一张命令分发表把1996 年的画图脚本翻译成2003 年的 GX 调用而 PC 移植只需把最后的 GX 换成 OpenGL再小心伺候好指针、字节序和 32 位这三个老朋友。赞分享【免费下载链接】ACGC-PC-PortUnofficial PC Port of Animal Crossing Gamecube项目地址https://gitcode.com/gh_mirrors/ac/ACGC-PC-Port点击查看免费下载相关推荐ACGC-PC-Port完全指南《动物森友会》GameCube版如何不靠模拟器原生上PC畅玩ACGC PC Port完全指南《动物森友会》GameCube版如何不靠模拟器原生上PC畅玩 ACGC PC Port 是一个将《动物森友会》AnimalACGC-PC-Port源码编译教程MSYS2 MinGW32环境下从零构建《动物森友会》PC版ACGC PC Port源码编译教程MSYS2 MinGW32环境下从零构建《动物森友会》PC版 ACGC PC Port 是非官方的《动物森友会》AnACGC-PC-Port快速上手只需3步把《动物森友会》搬上PC无需提取任何资产的极简流程ACGC PC Port快速上手只需3步把《动物森友会》搬上PC无需提取任何资产的极简流程 ACGC PC Port 是《动物森友会》Animal Cro创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

前后端连接最小Demo:原生fetch+Python http.server全链路解析

前后端连接最小Demo:原生fetch+Python http.server全链路解析

“前后端怎么连起来的?”这是我被问得最多的问题之一,尤其是刚接触全栈概念的朋友。我在带新人的时候发现,很多人要么只写过前端页面,要么只在后端工具里见过接口返回,就是不知道这两个东西是怎么在浏览器和服务器之间…

2026/10/12 7:24:17 阅读更多 →
Python设计模式之单例模式实例

Python设计模式之单例模式实例

前言 单例模式(Singleton Pattern)出自 1994 年的《设计模式》一书(作者常被合称为「四人组」,GoF)。它的意图用一句话概括就是:保证一个类只有一个实例,并提供一个访问它的全局入口。听起来简单…

2026/10/12 7:24:17 阅读更多 →
搞懂Java集合框架:HashMap扩容、ArrayList与选型实战深度解析

搞懂Java集合框架:HashMap扩容、ArrayList与选型实战深度解析

刚看完一段线上事故的复盘,起因是开发同学用HashMap做缓存,却忽略了并发写入的问题,结果线上服务时不时卡顿,最后排查下来是扩容时产生了循环依赖。这类问题其实和“Java 集合框架”本身无关,而是因为你只记住了 API&a…

2026/10/12 7:24:17 阅读更多 →

最新新闻

哈希算法在系统安全中的关键作用:从密码存储到完整性校验

哈希算法在系统安全中的关键作用:从密码存储到完整性校验

你有没有遇到过这样的情况:下载一个软件安装包时,官网页面会贴出一串长长的十六进制字符,比如e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855。大多数人都把这串字符当成可有可无的“官网装饰”,但你有没有想…

2026/10/12 9:43:27 阅读更多 →
Java函数复写深度解析:从语法规则到Android实战避坑

Java函数复写深度解析:从语法规则到Android实战避坑

1. 从一次编译报错说起:为什么函数复写值得单独拎出来讲刚接触Java4Android那会儿,我写了一个继承自父类的子类,想当然地给某个方法换了个参数类型,以为这就是"复写"。结果运行起来,程序走的还是父类的逻辑&…

2026/10/12 9:43:27 阅读更多 →
JSP+MySQL构建BBS论坛:核心架构与完整开发实战

JSP+MySQL构建BBS论坛:核心架构与完整开发实战

简介:基于JSP与MySQL构建的BBS论坛项目源码包,面向正在学习Java Web开发的学生与开发者,完整演示了论坛系统的核心业务流程:用户注册登录、板块管理、主题发帖、回复互动、关键词搜索以及后台权限控制等。包内共493个文件&#xf…

2026/10/12 9:43:27 阅读更多 →
5G下行数据传输流程图形化:从GTP-U隧道到空口调度完整解析

5G下行数据传输流程图形化:从GTP-U隧道到空口调度完整解析

简介:5G NR下行数据传输完整流程的图解资料,以图形化方式呈现从应用层到物理层的端到端数据传递过程,面向5G网络工程师、通信专业学生或初识5G NR协议的读者。内容以独立基站为场景,基于CU-DU高层切分架构展示用户平面协议栈&…

2026/10/12 9:43:27 阅读更多 →
LeetCode 406 贪心与排序实战:C语言重建队列

LeetCode 406 贪心与排序实战:C语言重建队列

1. 从一道题看贪心与排序的配合逻辑Leetcode 406 这道题,标题叫“根据身高重建队列”,乍一看像是数据结构题,实际上它是一道非常典型的排序 贪心 插入的综合题。我当年第一次做的时候,第一反应是“这题是不是得用拓扑排序”&…

2026/10/12 9:43:27 阅读更多 →
用AI精准生成健身动作画册:从姿态控制到批量出图

用AI精准生成健身动作画册:从姿态控制到批量出图

做这类“给AI出题”的项目,最怕的不是AI翻车,而是你的需求本身就模糊。Stretchbook这个标题看起来简单——用AI做一本健身动作画册,但它背后其实藏着一条相当完整的技术链路:动作姿态怎么保持准确?风格怎么统一&#x…

2026/10/12 9:42:25 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →