Riivolution Memory Patch + PowerPC + Gecko Code Generators
Quick and simple Riivoution Memory Patch, PowerPC and Gecko Code generators (this description is a work in progress)

Riivolution
1. XML Memory Patch Generator
2. Branch to 0x80002388
3. Branch Anywhere
4. Universal Memory Patch

ASM (PowerPC)
1. ASM Generator

Gecko Codes
1. C2 and 04 Code Generator
2. Conditional Code
3. Button Activator

GCT Files
1. GCT "Decoder"

Other
1. C2 Code to Riivolution Patch Generator

Regional Things
1. How To find a PAL address

-----


Memory Patch Type 1:


Enter An Address in Memory:
Enter the value you want to insert at that address:
Riivotion Patch Output:
 

 

EXAMPLE:

Enter An Address in Memory: 80000004
Enter the value you want to insert at that Address: FFFFFFFF

Output:
<memory value="ffffffff" offset="0x80000004" />

 



Memory Patch Type 2: (Branch to 0x80002388)

Enter an Address in memory: 
# 0x80002388 - Inputted Address Above
Branch Instruction Output:

 


 


 

 

 

Memory Patch Type 3: (Branch Anywhere)


Enter the address you want to branch from: 
Enter the destination address: 
Riivotion Patch Output:

 

 

 

EXAMPLE:


Example #1

Enter the address you want to branch from: 80000000
Enter the destination address: 80000064

output:
48000064

Example #2
Enter the address you want to branch from: 80000064
Enter the destination address: 80000000

output:
4BFFFF9C


 

 

 


Memory Patch Type 4: "Universal" Memory Patch

Enter the hex value of the instructions that you want to patch in (hex values, without spaces) 
Enter the hex value of at least 5 consecutive instructions (hex values, without spaces) 

Output:

Regular Riivolution memory patches work by directly replacing an instruction
in the game's code (although they won't work if the game writes a value to the
address they replace the value of after boot. You'll need a 04 RAM Write code
to keep that from happening).

The thing with memory patches is that you have to enter a memory address specific
to the region of the game you're working with. This means that if you made a patch
to replace the value at an address in the NTSC version of a game, it won't work on
the PAL version since the addresses are different. 

Riivolution memory patches have a "search" feature. A "search patch" scans the game's
memory for a specific set of bytes and replaces them with custom bytes if found.
It can search for any sequence of bytes. This includes the bytes that make up the hex
values of instructions in the game's code. This generator takes full advantage of that.

The generator creates a search patch for you. You need to enter the exact sequence of bytes
corresponding to the instructions surrounding the target instruction ("target instruction" refers
to the memory address you want to alter the value of, so start by entering the original hex
value of that)
. The generated search patch will search the game's memory for the specific
sequence of bytes you entered to locate the correct function containing the target instruction.
Once found, the patch replaces the instruction(s) with the custom bytes provided.
This allows the memory patch to be "universal" and work across all regions.

It works because the game's actual code is pretty much unchanged between
regions, which means that the byte sequences that make up its code are too.

The only issue with this type of patch is that it sometimes has trouble finding the byte
values of instructions that load specific addresses into registers. It also doesn't work
with function callers ("bl" instructions), but apart from that, it works perfectly!

 

EXAMPLE:

In Wii Sports Resort there's a function at (NTSC) 0x8063358C that updates the time of day
in Swordplay Showdown after you complete a stage. This is what it looks like in the code
(I explained how this function works in the "developer's commentary" of The Swordplay
Showdown: Service and Shenanigans Pack
 so I'm going to refrain from doing so here):

NTSC_0x8063358C: 
 
8063358c: lwz       r3, -0x20E0(r13)
 
80633590: addi      r0, r3, 0x1
 
80633594: stw       r0, -0x20E0(r13)
 
80633598: cmpwi     r0, 0x3
 
8063359c: bltlr-    
 
806335a0: li        r0, 0
 
806335a4: stw       r0, -0x20E0(r13)
 
806335a8: blr 
Let's say I wanted to replace the "bltlr-" instruction with "nop" (no operation)
and the "li r0, 0" instruction with "li r0, 1"


The hex value for "nop" is "60000000"
The hex value for "li r0, 1" is "38000001"

So normally, I'd just make a memory patch to replace the instructions. Like this:


<memory value="60000000" offset="0x8063359C" />
<memory value="38000001" offset="0x806335A0" />


This would work perfectly fine on the NTSC version of the game, but not the
PAL version since the memory addresses are different between them.

 
With a search patch, you can't search for one specific instruction since there's no
way to narrow things down. However, you CAN use it to search for a specific function.

Here's how:

 
The function I mentioned earlier that updates the time of day... let's have a closer look at it.
The values on the left are hex values. On the right are the instructions that value translates to:


806DDF20      =     lwz r3, -0x20E0(r13)
38030001        =     addi r0, r3, 0x1
900DDF20      =     stw r0, -0x20E0(r13)
2C000003       =     cmpwi r0, 0x3
4D800020       =     bltlr-
38000000        =     li r0, 0
900DDF20       =     stw r0, -0x20E0(r13)
4E800020        =     blr


To search for this function in a search patch, I'd have to copy all the hex values of its
instructions and arrange them in sequence without spaces.

Doing so gives me this series of bytes:


806DDF2038030001900DDF202C0000034D80002038000000900DDF204E800020

This is the "original" value. It's the series of bytes the game has to check it's memory for.
This is what you'd need to enter into the 2nd textbox.

Right about now, the patch should look like this:

<memory value="" original="806DDF2038030001900DDF202C0000034D80002038000000900DDF204E800020" offset="" align="4" search="true" />


Next, let's enter the new bytes the game has to patch in...

 
Let's look at the function again, this time with the hex values of the instructions
I want to patch in.


806DDF20      =     lwz r3, -0x20E0(r13)
38030001       =     addi r0, r3, 0x1
900DDF20     =     stw r0, -0x20E0(r13)
2C000003      =     cmpwi r0, 0x3
60000000      =     nop
38000001      =     li r0, 1
900DDF20    =     stw r0, -0x20E0(r13)
4E800020     =     blr


At this point, addresses don't matter, as the game will only be patching in
the "new" bytes after it finds the original.

The highlighted lines above are the new instructions I want to patch in. The same process of
copying all the hex values and arranging them in sequence without spaces has to be repeated,
which will then give me the following bytes:

806DDF2038030001900DDF202C0000036000000038000001900DDF204E800020


Now, I have to put this value into the 1st textbox and make the patch.

 
This is the final patch:

<memory value="806DDF2038030001900DDF202C0000036000000038000001900DDF204E800020" original="806DDF2038030001900DDF202C0000034D80002038000000900DDF204E800020" offset="" align="4" search="true" />

 
What this patch does is search the game's memory for a specific set of bytes, which in this case is "806DDF2038030001900DDF202C0000034D80002038000000900DDF204E800020." Once those bytes are found, they're immediately replaced with "806DDF2038030001900DDF202C00000360000038000001900DDF204E800020." This patches my new instructions into the game's code.

 


This memory patch works on both NTSC and PAL because the
original source code in the function I modified is exactly the same
across both regions, meaning that the exact set of bytes this patch
searches for and replaces exists in both the NTSC and PAL version
of the game.

 

Hopefully, all of that made sense to you!

 

 

 


ASM GENERATOR

Enter the Address that holds the value you want to replace:
Enter the value you want to insert at said Address:
Enter an empty register for said Address: 
Enter another empty register for the value you want to insert at said Address: 
REMOVE THE BLR INSTRUCTION IF YOU EXPERIENCE CRASHING WITH THE CODE
ASM Output:

 

 

EXAMPLE:

Enter the Address that holds the value you want to replace: 802c9210
Enter the value you want to insert at said Address: 2C1811FF
Enter an empty register for said Address: r14
Enter another empty register for the value you want to replace at said Address: r15

 


 

Gecko Code Generators

Value Replacement

Enter the Address that holds the value you want to replace: 
Enter the value you want to insert at said Address: 
Code Type: 

Output:

 

 

EXAMPLE (For C2 codes)

 

Enter the Address that holds the value you want to replace: 80456780
Enter the value you want to insert at said Address: 4E800020
Code Type: Default (C2)

The output would be:

C2456780 00000001
4E800020 00000000

 

EXAMPLE (For 04 codes)

Enter the Address that holds the value you want to replace: 80456780
Enter the value you want to insert at said Address: 4E800020
Code Type: Force the game to replace the value (04)

The output would be:

04456780 4E800020


If the user enters an address starting with "90" the output would be:

42000000 90000000

04456780 4E800020


If the user enters an address starting with "91" the output would be:

42000000 90000000

05456780 4E800020

If the user enters an address starting with "92" the output would be:

42000000 92000000

04456780 4E800020

If the user enters an address starting with "93" the output would be:

42000000 92000000

05456780 4E800020
 

 


Conditional Code

If  is equal to ...

Output:

 

 

 

 

 

 




Button Activator

Game         Button    

Output:

 

 

EXAMPLE:

The first line of the code will change based on what the user sets the Game to

Wii Sports:  2040E158
Super Mario Sluggers: 20317bb0

 

If  the (A) Button is pressed in Super Mario Sluggers... the output would be

20317BB0 00000800
# Your code here (This message is included in the output)

e0000000 80008000

 

 

 


GCT Files

GCT "Decoder"
This is more of a formatter but "decoder" sounds a lot cooler.

Enter the hex bytes of your GCT file (with spaces, including the
"00 D0 C0 DE 00 D0 C0 DE" header).


Output:

 


 



Other
C2 --> Riivolution Memory Patch
Enter a C2 Code:

                        

Output:

      


 

EXAMPLE:

The following C2 code will be used as an example:

C2000004 00000003
38A00000 7CC43378
38A00006 38A00007
60000000 00000000


The output would be the following:

<memory value="48002334" offset="0x80000004" />
 <memory value="38A00000" offset="0x80002338" />
<memory value="7CC43378" offset="0x8000233c" />
<memory value="38A00006" offset="0x80002340" />
<memory value="38A00007" offset="0x80002344" />
<memory value="4bffdcc0" offset="0x80002348" />

 


Explanation
C2000004 --> <memory value="48002334" offset="0x80000004" /> --> The insertion address. 0x80000004 in this code. This instruction makes it branch to 0x80002338. It will do this for every insertion address.

00000003 ---> Number of lines the code has. Not important.


38A00000 ---> <memory value="38A00000" offset="0x80002338" /> ---> The first line in the code. Always inserted at 0x80002338


7CC43378 ---> <memory value="7CC43378" offset="0x8000233c" />


38A00006 ---> <memory value="38A00006" offset="0x80002340" />


38A00007 ---> <memory value="38A00007" offset="0x80002344" />


60000000 00000000 ---> If the very next line in the C2 code is "00000000" with nothing after it or "60000000 00000000," it will not be converted and will be replaced with a branch instruction to the insertion address + 0x4.


<memory value="4bffdcc0" offset="0x80002348" /> ---> Branches from 0x80002348 to 0x80000008 (Insertion address + 0x4)
 

 

 


Regional Things
How to find a PAL address

First, I'd like to mention that this method will only work if
you're making C2 codes or memory patches. It also won't
work correctly if the instruction at the address you want to port
is in between "bl" instructions.


Let's assume that I wanted to make the following memory patch:


<memory value="12345678" offset="0x8056ED38" />

This memory patch replaces the value at 0x8056ED38 with "12345678"
 

But that's only the NTSC Address. This wouldn't work on the PAL version
of the game I'm working with.

That means I'd have to find the PAL address and make a seperate patch for it.

So here's how I'd go about doing it...



1. FINDING THE ORIGINAL INSTRUCTION:

In dolphin debug mode, I'd enter "
8056ED38
" in the "code" tab.
This will highlight exactly what instruction is at that address.

In the game I'm working with, the instruction is "
stw r29, 0x01A8 (r31)"

Here's a small snippet of what that area of memory looks like:

8056ed38: stw r29, 0x01A8 (r31)
8056ed3c: lwz r5, -0x25A8 (r13)
8056ed40: mtctr r0
8056ed44: addi r4, r6, 1
8056ed48: addi r6, r6, 1

2. COPYING THE HEX VALUES

I'd then right click on the "stw r29, 0x01A8 (r31)" instruction
and select "copy hex" which would give me the value "
93BF01A8."

I'll have to repeat this process 4 more times (sometimes it's less if the function
is unique).

The hex values for each instruction would be the following:


stw r29, 0x01A8 (r31)     = 93BF01A8
lwz r5, -0x25A8 (r13)      = 80ADDA58
mtctr r0                           = 7C0903A6
addi r4, r6, 1                    = 38860001
addi r6, r6, 1                     = 38C60001

3. PUTTING THE VALUES TOGETHER

Next, I have to put all those values together and remove the spaces.
Doing so gives me the following set of bytes:


"93BF01A880ADDA587C0903A63886000138C60001"

I'd copy this and then open the PAL version of the game.

4. FINALE

In the PAL version of the game, I'd go into the "Memory" tab in Dolphin,
look for the "Value" textbox, and then paste in the long set of bytes I copied.
Then I'd hit "Find Next."

This would bring up a match in Memory. It'll be highlighted in blue.

Right Clicking on it and selecting "view in code" would show me
that the PAL address of the original instruction I was searching for
is 0x8056F058


 So now I have the address needed to make a PAL version of the memory patch
<memory value="12345678" offset="0x8056F058" />



THE REASON THIS METHOD WORKS
IS BECAUSE THE ACTUAL CODE OF
THE GAME IS ALMOST ENTIRELY
THE SAME BETWEEN REGIONS.

MEANING THAT THE BYTE SEQUENCES
MAKING UP ITS CODE ARE AS WELL.


 



Coded by LlamaTrauma and JimmyKazakhstan