Hacking ROM Hack Translation The first time I use Rust on NDS game translation hacking

SteveXMH

Member
OP
Newcomer
Joined
Oct 17, 2021
Messages
6
Trophies
0
Age
20
XP
61
Country
China
The game is Megaman Star Force 2 (JPN), which is my faviourate game in my childhood. But it doesn't have a Chinese translation so I can't understand the whole story and only to play english version. Since I've already patched Megaman Star Force 1 (JPN) by assembly language (Via ARMIPS) for Chinese translation, I tried to use Rust to make a patch, which can be easier writing something like font cache and others. Here's the result:
QQ截图20221008195511.png
QQ截图20221008195624.png
 

SteveXMH

Member
OP
Newcomer
Joined
Oct 17, 2021
Messages
6
Trophies
0
Age
20
XP
61
Country
China
Interesting use of Rust.

Is the code just being compiled as ARM assembly and injected into the ROM?
I compiled rust code into an overlay file and loaded it (By calling FS_LoadPverlay API) in an memory area. To do this I also moved the heap start address to create an empty space for this overlay.
 

FAST6191

Techromancer
Editorial Team
Joined
Nov 21, 2005
Messages
36,798
Trophies
3
XP
28,348
Country
United Kingdom
I am still a bit hazy on what is happening here.

Normally if people want emulated games to execute extra code they have two options.

1) The traditional way. Extend existing code, change existing instructions... within the game itself. Probably going to be assembly unless the game uses some internal scripting language that is vaguely Turing complete (there are a few on the DS, though not many -- Puzzle Quest, El Tigre Make My Mule and a few others that slipped my mind at time of writing). Some managed to streamline a small C function into something that would compile and be usable but the libraries you have access to are minimal in that scenario and the setup for it is immense, some of the New Super Mario Brothers being this though even that is mostly still assembly.
2) Various emulators will support Lua, the DS emulator desmume having a pretty good implementation (in this case following along from the NES emulator FCEUX rather than some of the arcade/multi emulators or things some in the tool assisted speedrun world are going in for). Find some tell you are at a suitable point and use that as a hook to launch things on the PC, which could well be an external program written in whatever. http://wiki.desmume.org/index.php?title=Faq#What_is_this_Lua_stuff_I_see.3F https://fceux.com/web/help/LuaFunctionsList.html https://tasvideos.org/LuaScripting
2a) I am sure much like the cheat search tools you could hook an emulator with an external program that is not the internal Lua and do something there. Tend not to see it though.

Here did you manage to get Rust (a fairly high level language as these things go*) to compile down to machine code and inject that into it?
*granted https://www.rust-lang.org/
Rust's homepage said:
Rust is blazingly fast and memory-efficient: with no runtime or garbage collector, it can power performance-critical services, run on embedded devices, and easily integrate with other languages.

I shall have to look more into this as I had largely been ignoring Rust as just another fad language but if it is going to be able to pull stuff like this off then I might have been quick to dismiss.

Also "something like font cache"
Does the Japanese font handler not already support thousands of kanji? Such things can be harder if you are trying to translate an English language NES game to Chinese but by the DS then character lookup was almost arbitrary by that point.
 

SteveXMH

Member
OP
Newcomer
Joined
Oct 17, 2021
Messages
6
Trophies
0
Age
20
XP
61
Country
China
Such a huge message that I can't even hold it. Let me get some explain soon. I'm still learning ROM hacking so there maybe have some wrong explainations.

The Rust code is definitely compiled to ARM code and running in NDS machine (The screenshot is No$GBA but it also work in real machine (on my 3DS)), not by Emulator's features (Lua or anything else).

As we know NDS have a feature called overlay which behaved like DLLs that can be loaded into memory and executed. So I configured Rust compiler to let it compiled an pure ARM overlay file that can be injected into ROM and memory.

To load this overlay we need to write a little assembly to call the NitroSDK API "FS_LoadOverlay" at the start time. Here I used ARMIPS as the assembly compiler. (It's a great tool :D)

First we hooked "FS_Init" call and run our initialize code. I used CrystalTile2 to search NitroSDK API functions and their address. Then I used an useless arm9 code space to load overlay and execute it. (In this game is a 12x12 font character graph which will be useless after translation hacking)

And to have a space to load overlay in memory without being overwrote by other program, I moved the heap starting pointer to create a space that can fit the overlay code. First I used CrystalTile2 to search the heap pointer.

So we searched the address and modify it in assembly. Now we have a clear space for our overlay.

The 0x219AF60 is the heap starting address and it will be the entry point of our rust code. So we also need a linker script to define the code area to locate the entry point. Then the code should be executed as wished.

About the font cache, although NitroSDK provided their own fonts loading and printing technique but this game doesn't use it. It just placed the fonts in arm9 code directly with very little kanji which is impossible to just be replaced by thousands of Chinese characters. So I have to write external code to let it read our own font file stored in ROM and print it. And the font cache is to reduce ROM reading frequency (Some old flashcards will freeze the game when the ROM reading is too heavy and too frequently) and ensure the font in VRAM will keep in their own memory and being referenced as planned.

Back to Rust itself, it's a good language that have some modern features and let us write patch code easier. So I tried to use it on this translation hacking just for learning and fun.

As I know some of the Chinese translation rom hackers already using C language to write patch code. So I just basically learnt the method and tried to upgrade it to Rust. And that's it.

My forum user level limited me to post further message since I just started to post. Reply if there's anything I doesn't explain clearly. :D
 

FAST6191

Techromancer
Editorial Team
Joined
Nov 21, 2005
Messages
36,798
Trophies
3
XP
28,348
Country
United Kingdom
That makes things a lot clearer. Interesting twist on things and yeah I definitely seem to have overlooked Rust if is it going to compile down into something sensibly loaded as an overlay, self contained and executed as well.

Being an overlay also dodges some of the issues with either finding space* or having to shuffle it back out when the game wants to load what it expects back in there. I will also note for at least others playing along that there is not just one overlay slot as it were but a section; several games then splitting the section up such that it can have several different overlays all in at once and jump between them without cycling out. For those wanting to know what overlays are then there is usually code that you don't always want in memory -- how many times does the credits animation play if you view it as a per run basis, leave that out of what you have in memory and load when necessary, aka dynamic code. Overlays are a crude version of this compared to the DLL that you likely have met in Windows but they are what DS commercial games used and thus the would be hacker gets to know about.

*I usually tell people that if the game is a wifi sporting game then the ARM9 binary likely sports a whole load of error strings that nobody has likely ever seen load up, much less will today. Otherwise have fun with the deadbeef padding or those emulators that try to note things accordingly.
 

SteveXMH

Member
OP
Newcomer
Joined
Oct 17, 2021
Messages
6
Trophies
0
Age
20
XP
61
Country
China
That makes things a lot clearer. Interesting twist on things and yeah I definitely seem to have overlooked Rust if is it going to compile down into something sensibly loaded as an overlay, self contained and executed as well.

Being an overlay also dodges some of the issues with either finding space* or having to shuffle it back out when the game wants to load what it expects back in there. I will also note for at least others playing along that there is not just one overlay slot as it were but a section; several games then splitting the section up such that it can have several different overlays all in at once and jump between them without cycling out. For those wanting to know what overlays are then there is usually code that you don't always want in memory -- how many times does the credits animation play if you view it as a per run basis, leave that out of what you have in memory and load when necessary, aka dynamic code. Overlays are a crude version of this compared to the DLL that you likely have met in Windows but they are what DS commercial games used and thus the would be hacker gets to know about.

*I usually tell people that if the game is a wifi sporting game then the ARM9 binary likely sports a whole load of error strings that nobody has likely ever seen load up, much less will today. Otherwise have fun with the deadbeef padding or those emulators that try to note things accordingly.
Yes it is. That's why I use heap area as the space, as this always used to store dynamic data and almost no overlays will be loaded there. So moving the heap start address will create the space that nothing can use but our patch program.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    Sonic Angel Knight @ Sonic Angel Knight: DAYTONAAAAAAAA!!!!!!!!!!