Hacker News new | past | comments | ask | show | jobs | submit login

I saw this when it came out, and as someone that doesn't follow the ROM hacking scene, I'm wondering - why did this approach take so long to come up with? Translating the assembly instructions to C and then recompiling them seems like an obvious method to try early on, but I'm wondering if there was some other breakthrough that made this possible in a way it wasn't before?



The N64 has a GPU, which is not the same as modern GPUs, and you need that GPU to render graphics.

Skimming the Github repo, looks like this uses rt64 under the hood for the raytracing support ( https://github.com/rt64/rt64 ), and that uses the ubershader technique to emulate the GPU. This excellent article talks about the what, why, and insanity that are ubershaders: https://dolphin-emu.org/blog/2017/07/30/ubershaders/


Was raytracing support necessary to get the compilation working to circumvent "normal" GPU calls?


Other emulators want to solve the problem generically, and this solution doesn't quite.

Static recompilation from one machine language to one other language is somewhere between extremely difficult to not being generally possible in practice [1]. To make recompiling something like this properly, you need some help from the binaries that make recompilation easier [2] and on top of that you need to patch certain things to make this work [3].

Dynamic recompilation doesn't have this problem. It allows you to create software you can dump the original binaries+assets ("ROMs") in and it will generally emulate it.

There's a lot of confusion about how generic this solution it. It's extremely impressive in how much work it saves making recompilations/"ports" much easier, and it will be very valuable. But it is not able to replace the need for traditional emulators.

[1]: https://cs.stackexchange.com/questions/155511/why-is-static-...

[2]: N64 game binaries may happen to avoid a bunch of things that make general static recompilation hard that help this approach, but I don't actually know.

[3]: The Majora's Mask recompilation repository contains a lot of handcrafted patches to make it work: https://github.com/Mr-Wiseguy/Zelda64Recomp


Emulating the hardware usually requires cycle-accurate emulation of things running in parallel, so it's not quite so simple as just the program in the ROM.


Yes and no, with the 8bits and probably 16bits like the C64, NES, etc you really want cycle accuracy and emulating something like the PS2 really well would probably need a fair bit of accuracy.

HOWEVER.. writing an recompiler (not feasible for 8bits due to the amount of self-mod code) you could probably insert pattern checks to detect writes to DMA-starting locations,etc (thinking back to our PS2 games) and transform it to safe sequences without accurate timing for most games that really only would be happy with some extra cycles.


Good point about 8bit self modifying code.

The UK C64 disk for “Skate or Die” had copy protection that did exactly that, as an example.


It's pretty much best practice on the 6502. Loading code from disk or tape is basically the sane thing too.


With Skate or Die, it’d pull a byte off the genuine disk and use it to decrypt (xor) a loop immediately after the current PC.

I think it went through about five iterations.

My crack was to step it with the original disk to decrypt the encrypted part and modify the code to jump over the decryption. It was pretty sophisticated for the day.

To another extreme, Ocean disk games had a “IsGenuineDisk” style function. It returned 1 or 0 in the accumulator. I could crack it in under a minute with a disk sector editor.

Oddly, I ended up doing Mac copy protection years later.


Watching the video, it seems like the explanation is mostly "tag the code and transpile to C" - im assuming the tags are acting as the hardware-aware part?


Are they using self-modifying code or anything else that would make this tricky?


Really surprised this topic didn't come up anywhere. I couldn't find anything in the linked repositories either. I guess there's no self-modifying code due to it being mapped into the address space from a cartridge?


You definitely do need code execution from RAM for high-fidelity emulation. How else are people going to implement Flappy Bird in Super Mario World? :) https://www.youtube.com/watch?v=hB6eY73sLV0


Basically every game is written in C on a modern processor (MIPS) so i highly doubt it. Maybe some weird homebrew stuff like that flappy bird video uses it but emulators tend to deal with problems like that by ignoring them (e.g. IIRC there is no emulator that can properly run that N64 linux port from a few years ago, and there have been plenty of SM64 glitches that work differently on emulators vs real hardware)




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: