是否可以从 SNES 模拟器(或任何其他游戏系统模拟器)和系统的游戏 ROM 中获取源代码,并以某种方式创建一个独立的可执行文件,让您在不需要的情况下玩该特定 ROM是个人rom还是模拟器本身玩?假设你已经有了 rom 和模拟器源代码,这会很困难吗?
2 回答
如果您有模拟器源代码,应该不会太难。您可以使用一种常用于将图像存储在 c 源文件中的方法。
基本上,您需要做的是char *
在头文件中创建一个变量,并将 rom 文件的内容存储在该变量中。您可能需要编写一个脚本来为您自动执行此操作。
然后,您将需要更改源代码,以便它不是从文件中读取 rom,而是使用 rom 的内存版本,存储在您的变量中并包含在您的头文件中。
如果您需要模拟文件指针等,可能需要做一些工作,或者您可能很幸运,发现 rom 加载函数只是一次加载整个文件。在这种情况下,它可能就像将文件加载函数替换为返回指针的函数一样简单。
但是,请注意许可问题。如果模拟器是在 GPL 下获得许可的,则法律上可能不允许您将专有文件存储在可执行文件中,因此值得检查一下,尤其是在您发布/分发它之前(如果您打算这样做)。
是的,超过可能,已经做了很多次。谷歌:静态二进制翻译。格雷厄姆·托尔(Graham Toal)有一篇很好的关于这个主题的文章,应该会在热门文章中出现。那里可能有一些代码我可能已经留下了一些代码。
完全删除 rom 可能比你想象的要多一些工作,但不使用模拟器,绝对有可能。实际上,这两个要求都是可能的,您可能会惊讶于有多少掌上游戏机或机顶盒游戏被翻译而不是模拟。像 Nintendo 这样的 Esp 平台没有足够的处理能力来实时模拟。
您需要一个好的模拟器作为参考和/或编写自己的模拟器作为参考。然后你需要写一个反汇编器,然后你让那个反汇编器生成C代码(请不要试图直接翻译到另一个目标,我犯过一次错误,C是可移植的,编译器会处理很多死代码消除你)。因此,假装指令集的指令可能是:
添加 r0,r0,#2
这可能会转化为:
//添加r0,r0,#2 r0=r0+2; do_zflag(r0); do_nflag(r0);
看起来 SNES 与 Asteroids 使用的 6502 相关,这是我作为爱好一直断断续续地研究了一段时间的翻译。您正在使用的模拟器可能是针对运行时性能而编写和调整的,并且可能难以将其用作参考并与翻译后的代码同步检查。6502 不错,因为与 z80 相比,指令确实不多。与任何可变字长指令集一样,反汇编程序是您的第一个大障碍。不要线性思考,思考执行顺序,像模拟器一样思考,你不能将指令从零线性转换为 N 或 N 到零。您必须遵循所有可能的执行路径,将 rom 中的字节标记为指令的第一个字节,而不是指令的第一个字节。您可以将某些字节解码为数据,如果您选择标记这些字节,则假定所有其他字节都是数据或填充。弄清楚如何处理这些数据以摆脱 rom 是摆脱 rom 的问题。有些代码直接寻址数据,有些代码在翻译时使用寄存器间接含义,您不知道该数据在哪里或有多少。一旦您为指令标记了所有起始字节,那么将 rom 从零走到 N 反汇编和/或翻译是一项微不足道的任务。有些代码直接寻址数据,有些代码在翻译时使用寄存器间接含义,您不知道该数据在哪里或有多少。一旦您为指令标记了所有起始字节,那么将 rom 从零走到 N 反汇编和/或翻译是一项微不足道的任务。有些代码直接寻址数据,有些代码在翻译时使用寄存器间接含义,您不知道该数据在哪里或有多少。一旦您为指令标记了所有起始字节,那么将 rom 从零走到 N 反汇编和/或翻译是一项微不足道的任务。
祝你好运,享受,非常值得体验。