
任天堂
以前我看到有人对超级马里奥的汇编源码进行逆向研究。红白机那个时候,内存才2KB,显存也只有4KB,放在现在这配置写个Hello World或许都难。可
任天堂却能在其中设置32个关卡、8种敌人,还有流畅的模拟物理引擎。下面我列出当时看到的几个令人震撼的用法。马里奥的跳跃动作玩起来特别逼真,有加减速过程,当时觉得实现起来会很复杂。可看了源码才知道用的是查表法。由于当时红白机没有标配浮点运算单元,
任天堂就在卡带里预存了一张跳跃轨迹Y轴坐标表,每次起跳就按索引从表中取值。逆向扒出的代码如下:空间被极致压缩,不通过复杂重力公式计算,而是单纯靠查表来解决。这张仅16字节的表,模拟出起跳加速到顶点再下落减速的效果,还特意调整数值营造出跳跃手感。在嵌入式开发中,以ROM空间换取CPU时间的操作很常见。像用Q格式定点数取代浮点时,常常预先存储sin/cos查找表。红白机的音频处理器(APU)仅有五个通道,这让我印象深刻。马里奥跳跃音效与背景音里的低音鼓点共用一个通道,一旦共用,跳跃音效优先。因此,踩
乌龟连杀时有时会突然变调,这也堪称极度压榨资源的实例。还有一个是马里奥吃蘑菇变大的动画,其成长动画与金币旋转动画共用一块内存,所有动态对象都使用同一个对象池,通过状态机切换身份。用C语言伪代码实现大概如下:
上面这些例子当时让我惊艳不已。后来自己做项目时,我也会思考,如何在资源有限的情况下实现所需功能。很多时候,硬件的限制反而促使自己水平提升。评论区有兄弟想自己试试,我放个类似项目的开源链接,里面有反编译的汇编文件。