Pages: 123 »
Posted on 12-06-12, 05:44 pm (rev. 4 by RicBent on 11-03-18, 11:11 am)
Super Mario
( ͡° ͜ʖ ͡°)

Karma: 10081
Posts: 2944/4458
Since: 06-08-11

You will need



About the ASM patch template


The template contains everything you need to start creating ASM hacks. Here's an explanation of what each file does.
  • arenaoffs.txt: It contains one RAM address NSMBe needs to insert custom code in the ROM. It's needed to make free space in RAM to insert the new code.
    It's different for every game, and for every version/region of every game. The template contains the arenaoffs for NSMB U region.
  • Makefile: It contains the instructions to compile the hack. This is what gets executed when you run "make". You probably won't need to modify this file.
  • linker.x: Contains the "linker script". It basically tells the compiler how to "put together" all the source files in the hack. Don't worry about it either.
  • symbols.x: It has addresses of functions and variables from the game's code. You are going to need it to call NSMB's functions from your own code. For example, there's a getCoin() function at 0x02020354. If you want to call it from your own code, you'll need a line in this file like this:
    getCoin = 0x02020354;
    Currently, all data in this file is exported directly from the IDA Pro DB.
  • source/ folder: This is where all your code has to be. The Makefile takes all files from this folder and compiles them all. If you want to add code, you have to add a file to this folder. Supported file extensions are .c (C code), .cpp (C++ code), .s (ASM code).


How to compile an ASM hack


Place a ROM in the template folder (NOT in data/ or source/. In the main folder). Also the path to the template may not include spaces ("C:\this\is\very wrong\" "C:\this\works\"). Open it with NSMB Editor. Go to the Tools tab and click "Run make and insert".
Yes, it's that easy.

You will see some new files appear when you compile your hack:
  • bak/ folder. This folder contains backups of overlays and arm9.bin that are modified. These are restored when you import the hack again.
    This is because bad things happen when you insert ASM hacks multiple times into the same ROM. So, don't delete the folder.
    If you delete it, there's no problem, but you have to place again an unhacked ROM.
  • build/ folder. This folder contains temporary files used when compiling.
  • newcode.elf. Contains the final compiled code to be inserted.
  • newcode.bin. The .elf file converted to .bin. This is what NSMBe inserts into the ROM.
  • newcode.sym. This contains all the "symbols" (function/variable names) inside the .elf. NSMBe reads this to find out what hooks you defined and insert them properly.

When you run "make clean" all these temporary files will be deleted. (except the bak/ folder).


How to make an ASM hack


Now comes the cool part!

ASM hacks are made with hooks. You hook an address in the game's code, this means the code in your hook gets executed when the code you hooked gets executed.

There are multiple types of hooks:
  • hook_02xxxxxx: This hook replaces the instruction at that address with a jump instruction to your code. It puts the replaced instruction before your code so it doesn't get deleted. It saves all the registers so you can't modify them.
    This is the easiest way to run custom code at a certain place.
  • repl_02xxxxxx: Replaces the instruction with a BL instruction to your code. It destroys the value in LR, and doesn't save any register, so be careful to save to stack every register you don't want to modify.
  • nsub_02xxxxxx: Replaces the instruction with a jump to your code. It's useful to replace entire functions. To do that you have to give it the starting address for the function.


To create a hook, simply make a function, or a label in ASM, with the hook name. See examples below.


Example 1: replacing getCoin() function


So... We know the function at 02020354 is called when Mario gets a coin. It increments the coin counter and gives an 1up if there's 100 coins. It basically "gives a coin to Mario".

Now, what if we replace that function with an empty function, hmm?
void nsub_02020354() {
}


We put that code into a file named noCoin.cpp in the source folder and compile...
Now what happens? When Mario gets a coin, the coin counter doesn't go up! Yay!


Example 2: calling a function from the game's code


Now let's make Mario get a 1up every time he gets a coin!
extern "C" {
        void get1up(int something, int somethingElse);
}

void nsub_02020354(int something) {
        get1up(8, something);
}


The first part of the code "declares" that there's a function named get1up() so the compiler allows us to call it. The compiler already knows the address for the function because it's listed in symbols.x.

The "something" is a value the get1up function needs. If we look at getCoin in IDA Pro, we see that it's passed as a param to getCoin, and getCoin passes it to get1up. We don't really care what it really is, we just pass it around and it will work.

(If you're curious, I think it's the player number. In singleplayer it's always 0)

Now every time Mario gets a coin, he gets a 1up instead!
Posted on 06-26-13, 09:39 am


Karma: 228
Posts: 12/22
Since: 10-18-12
I don't know how symbols.x works, but is it possible to make GCC believe we derived a class from any other classes such as the enemy or player base classes? Kinda like how Microsoft Component Object Model (COM) works thanks to the vtable being the first data member in the class.

Even if we cheat and have a dummy class call the original classes, getting the connection (I don't know if it is CONNECT that is displayed on the debug screen) to other objects for free is intriguing!
Posted on 06-26-13, 11:28 am
Super Mario
( ͡° ͜ʖ ͡°)

Karma: 10081
Posts: 3456/4458
Since: 06-08-11
What you say is very possible. Treeki already did that with nsmbw and I'm halfway done with it in NSMB.

Basically you have to put the mangled names for the vtables and functions, then make the headers for the classes and you can then subclass them.
Posted on 06-26-13, 12:28 pm


Karma: 228
Posts: 13/22
Since: 10-18-12
Posted by Dirbaio
What you say is very possible. Treeki already did that with nsmbw and I'm halfway done with it in NSMB.

Basically you have to put the mangled names for the vtables and functions, then make the headers for the classes and you can then subclass them.

Sounds like a lot of work. But it is worth it in the end for sure.
I was trying to do mangled names but several virtual functions are very annoying to decode, and then there are the two destructors for each derived class, both handling either
delete ClassPtr;

or
delete [] ClassPtr;

... I think.
Posted on 06-26-13, 12:53 pm
Super Mario
( ͡° ͜ʖ ͡°)

Karma: 10081
Posts: 3458/4458
Since: 06-08-11
Yeah there are two destructors. First one destructs, second one destructs and frees. I think there's even a third one that's called from the derived classes destructors.

I think that's not a problem when making our own classes, GCC also follows that convention.
Posted on 06-26-13, 12:54 pm
☭ coffee and cream


Karma: 10542
Posts: 997/2780
Since: 06-26-11
The problem with making your own classes though, is that NSMB was compiled with CodeWarrior, and CodeWarrior lays out vtables differently from GCC.
_________________________
Kuribo64 - RH-fucking-cafe - Kafuka

zrghij
Posted on 06-26-13, 02:39 pm
Super Mario
( ͡° ͜ʖ ͡°)

Karma: 10081
Posts: 3460/4458
Since: 06-08-11
It is different in case of the Wii (PPC compiler) but on ARM it seems to be compatible. I still haven't seen anything that could cause incompatibilities.
Posted on 09-06-13, 10:38 am (rev. 1 by  snake block on 09-06-13, 04:30 pm)
a

Karma: 1589
Posts: 82/1290
Since: 02-12-13
I can't do it!
I put the ASM in the folder with all the files because there is no "main" folder and do it but instead it says "make" is not a valid command in cmd.
EDIT: Accid. said that I put the asm in the folder with all the files. I meant, i put the rom in the folder with the asm hack files.
Posted on 09-06-13, 10:41 am (rev. 1 by  Dirbaio on 09-06-13, 10:41 am)
Super Mario
( ͡° ͜ʖ ͡°)

Karma: 10081
Posts: 3723/4458
Since: 06-08-11
You need to put the source files in source/ and install DevkitARM.
Posted on 09-06-13, 12:19 pm (rev. 7 by ImageBot on 11-21-16, 02:37 am)
a

Karma: 1589
Posts: 84/1290
Since: 02-12-13
What source files and where to install DevkitARM (Can not find it )
EDIT: OK, done downloading devkitARM. is version r24 fine? And again, what source files?
EDIT2: Tried putting the devkitARM files in the source folder so it looks like: B ut it still ain't no gonna work!
Posted on 09-06-13, 05:49 pm (rev. 1 by  Dirbaio on 09-06-13, 05:49 pm)
Super Mario
( ͡° ͜ʖ ͡°)

Karma: 10081
Posts: 3724/4458
Since: 06-08-11
No.

You just need to install DevkitARM. Use the automated installer and install it: http://sourceforge.net/projects/devkitpro/files/Automated%20Installer/devkitProUpdater-1.5.3.exe/download

You just need to have it installed, you don't need to do anything with its files.

Then download the ASM Patch Template, put the ROM in the main folder, and the source files in the "source" folder. Then open the ROM with NSMBe, go to Tools tab and click "Run make and insert".
Posted on 09-07-13, 04:34 am (rev. 1 by  snake block on 09-07-13, 04:51 am)
a

Karma: 1589
Posts: 95/1290
Since: 02-12-13
OK, but will it work with the community remix asm? (Don't worry, I am not gonna use it since I don't have any project to use it in just gonna test it)
EDIT: Oh gosh it works now but I still have a problem which I will ask at the Community Remix forum. Thank you Dirbaio!
Posted on 04-22-14, 06:31 pm (rev. 1 by Domich150 on 04-22-14, 06:31 pm)
Newcomer


Karma: 42
Posts: 8/9
Since: 12-21-12
I followed the steps in the first post,but when I clicked on "run make and insert",it gave me an error:

My rom's region is U,I have the latest devkitpro release,and I have the latest NSMBe build (build 337). It gives me an error even when I don't add anything. It also doesn't create the files it should. What have I done wrong?
Posted on 04-23-14, 11:02 pm
Super Mario
( ͡° ͜ʖ ͡°)

Karma: 10081
Posts: 4018/4458
Since: 06-08-11
I'm... not sure.

There has been a new devkitPro release on April 4th (r42), which updates GCC and other stuff, maybe it has broken the ASM patch template.

Try either of these two things, maybe they help:

1. Remove -lgcc in the Makefile

or:

2. Install dekvitPro r41 instead (I don't know if there's any easy way to install older versions of DKP though ) (but if you do add the -lgcc back or it won't work)

I'll try to check what's wrong and update the template ASAP, in the meantime you could try these two solutions.
Posted on 04-24-14, 08:59 pm
Newcomer


Karma: 42
Posts: 9/9
Since: 12-21-12
I removed -lgcc in the Makefile and now it works. Thanks!
Posted on 04-30-14, 04:09 pm (rev. 2 by koopa95 on 04-30-14, 04:13 pm)


Karma: 2
Posts: 1/3
Since: 09-18-13
When I -Run 'make' and insert- the code provided from ASMPatchTemplate-master unmodified as a test I get

make: make: Command not found
make: *** [build] Error 127
Press any key to continue . . .

Thanks
Posted on 04-30-14, 08:19 pm
Fuzzy
Full mod

Karma: 1183
Posts: 746/785
Since: 06-28-11
Have you installed devkitPro? Make is included in the installation. You can download it for Windows here.
Posted on 04-30-14, 09:13 pm


Karma: 2
Posts: 2/3
Since: 09-18-13
Yes twice, I'm at a loss.
Posted on 05-01-14, 12:11 am
Fuzzy
Full mod

Karma: 1183
Posts: 747/785
Since: 06-28-11
Then I would first check to see if make.exe actually exists. It should be located in devkitPro/msys/bin/. If it exists, then add that to your PATH environment variable. If not, then download a copy of make.exe, I can upload mine if you need.
Posted on 05-01-14, 06:25 pm


Karma: 2
Posts: 3/3
Since: 09-18-13
Yes, I've found the file and set the PATH environment variable like suggested and still nothing. I'll have to play around some more, but at least I have a direction to pursue.
Pages: 123 »