• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Adding new evolution methods [FR]

kearnseyboy6

Aussie's Toughest Mudder
300
Posts
15
Years
  • Seen Jun 22, 2019
Hello, I am a newbie and I'm kinda confused with this kind of method to write routines as it always push registers and use much stack space.
For example, if I want to use the "specific map evolution", I will write the following function:
Spoiler:
I think it does nothing different with the original routine in the thread so I'm really confused about it. (I haven't tested it yet)
Does evolution hack use special ways to write routines?

Anyway, I've updated the night friendship evolution and day friendship evolution routine so that they will work in fr.
Spoiler:

They're also not tested.

Then I've written the slowpoke evolution method in anime, which is linked with Shellder and the Shellder in the party will be deleted. (which is mainly based on JPAN's deletion function) However, I haven't tested it and I'm really not sure what will happen if the player abort the evolution by pressing "b".(As I haven't tested it, I absolutely haven't debugged the evolution process) Anyway, here's my routine (may have error as it is much more complicated than the others)
Spoiler:

Edit:I've tested the last one and I found that it worked ok except when the player press B to abort the evolution because the routine is also executed in this case so the shellder will be deleted although the evolution is aborted. Maybe I must look into the evolution routine to get it fixed. But I don't think the item related routine which requires to delete the pokemon's item is safe, if in the same case.
2n6uqsg.jpg

(I don't use an English ROM, sorry for that.)


It has a glitch, so temporarily removed.

That's good work ^^

For the map evolution it load the argument (map ID) an just compares it to the current map. Very simple routine :)
 

jiangzhengwenjzw

now working on katam
181
Posts
11
Years
  • Seen today
That's good work ^^

For the map evolution it load the argument (map ID) an just compares it to the current map. Very simple routine :)

Thank u for ur reply! Therefore, I think there's no point in wasting stack spaces to push & pop so many registers, maybe all the routines in the thread can all be simplified (Maybe I will do this when I have free time). By the way, could you please replace the routines in the thread with mine if my codes are tested working appropriately? (I think they should work though I haven't tested them yet XD)
 

kearnseyboy6

Aussie's Toughest Mudder
300
Posts
15
Years
  • Seen Jun 22, 2019
Thank u for ur reply! Therefore, I think there's no point in wasting stack spaces to push & pop so many registers, maybe all the routines in the thread can all be simplified (Maybe I will do this when I have free time). By the way, could you please replace the routines in the thread with mine if my codes are tested working appropriately? (I think they should work though I haven't tested them yet XD)

Yep you are right! Except you still need to push r4-7 if you use them, I know they are assumed to have random value returning from a branch or something.

Yeah anything you make I will add :)
 

jiangzhengwenjzw

now working on katam
181
Posts
11
Years
  • Seen today
Yep you are right! Except you still need to push r4-7 if you use them, I know they are assumed to have random value returning from a branch or something.

Yeah anything you make I will add :)

Thank you very much if you can test and add them ;)
For the latter sentence, r u speaking of the last function? Then r4 needn't be protected as the decrypter function pushes and pops r4 so it won't change XD
And please ignore the last function as it is very bugged and it couldn't be done if the pokemon is not the first one in the party. (I tried to change r8 to fix it as you can see in the label "adjust", but failed.)

Then I've just written a routine to evolve at specific level (the second parameter in the evolution table) when it detects a certain event has happened by checking flag 0x200.
Not tested.
Spoiler:

In addition, the routine checking if the Pokemon is shiny to go to level evolution. (Also not tested and I'm a bit not sure if the pokemon data pointer is in r8)
Spoiler:

And here I will post the simplified routines in the thread, all not tested. (The routines I write before several days will also be included)
Now the simplified routines are all finished because i only simplified some of them.
Spoiler:


I am not sure if my way of writing evolution routines is correct as it looks different from the original ones in the thread.
 
Last edited:
8
Posts
8
Years
  • Age 37
  • Seen Jul 3, 2015
kearnseyboy6, Nice Tutorial!!! I have a problem, I used your patch poke fire red new evos in my rom... The new evos works very well, but i can't do trade link... how I do to fix it???? Apeears this message...
picture.php


Hey!!! Nice tutorial!! Please help me!!! What I'm doing wrong??? The new evolution method doesn't work - Level-Up (Male)...I followed the tutorial!!! but didn't work!!! Sorry English!!!
picture.php
 
Last edited by a moderator:

Joexv

ManMadeOfGouda joexv.github.io
1,037
Posts
11
Years
Thank you very much if you can test and add them ;)
For the latter sentence, r u speaking of the last function? Then r4 needn't be protected as the decrypter function pushes and pops r4 so it won't change XD
And please ignore the last function as it is very bugged and it couldn't be done if the pokemon is not the first one in the party. (I tried to change r8 to fix it as you can see in the label "adjust", but failed.)

Then I've just written a routine to evolve at specific level (the second parameter in the evolution table) when it detects a certain event has happened by checking flag 0x200.
Not tested.
Spoiler:

In addition, the routine checking if the Pokemon is shiny to go to level evolution. (Also not tested and I'm a bit not sure if the pokemon data pointer is in r8)
Spoiler:

And here I will post the simplified routines in the thread, all not tested. (The routines I write before several days will also be included)
Now the simplified routines are all finished because i only simplified some of them.
Spoiler:


I am not sure if my way of writing evolution routines is correct as it looks different from the original ones in the thread.
Just gonna say this now, before anyone flips their lids trying to get your evo methods to work, they all will NOT work. You left out very important pieces of the code that must be in the routine to be able to run properly. You may want to reread the OP to be able to make actually working methods.
 

jiangzhengwenjzw

now working on katam
181
Posts
11
Years
  • Seen today
Just gonna say this now, before anyone flips their lids trying to get your evo methods to work, they all will NOT work. You left out very important pieces of the code that must be in the routine to be able to run properly. You may want to reread the OP to be able to make actually working methods.

Actually I think I know what the thread means. However, I don't think that way of writing codes is necessary and I think all that I need to do is to "insert" some codes I need to do compares or some similar things and make sure that they won't influence the routines i branch to, which is often 0x4310c, 0x43016, 0x43000 and the abort routine 0x43110. There's no point in pushing so many registers when not using a decrypter or other complex routines.

I think if you want to branch to the function at 0x4310c, you should keep the codes at the beginning (but you can use registers more flexibly) and you don't need them if you directly branch to the routine at 0x43016 as it will do all the things for you. Anyway afaik pushing r0-r7 is always useless as r0 will be immediately refreshed so at least you don't need to push r0 to the stack to waste stack space, though you pop it after that so r13 is recovered and your original code will work without any problem.

All above are my own opinions, maybe they're not right. Someone has tested some of the routines i wrote and found no problem. ;) (Absolutely i can't make sure that all my routines work, as I haven't tested them)
 
Last edited:

kearnseyboy6

Aussie's Toughest Mudder
300
Posts
15
Years
  • Seen Jun 22, 2019
Actually I think I know what the thread means. However, I don't think that way of writing codes is necessary and I think all that I need to do is to "insert" some codes I need to do compares or some similar things and make sure that they won't influence the routines i branch to, which is often 0x4310c, 0x43016, 0x43000 and the abort routine 0x43110. There's no point in pushing so many registers when not using a decrypter or other complex routines.

I think if you want to branch to the function at 0x4310c, you should keep the codes at the beginning (but you can use registers more flexibly) and you don't need them if you directly branch to the routine at 0x43016 as it will do all the things for you. Anyway afaik pushing r0-r7 is always useless as r0 will be immediately refreshed so at least you don't need to push r0 to the stack to waste stack space, though you pop it after that so r13 is recovered and your original code will work without any problem.

All above are my own opinions, maybe they're not right. Someone has tested some of the routines i wrote and found no problem. ;) (Absolutely i can't make sure that all my routines work, as I haven't tested them)

You're right, r0-r3 are assumed to be jumbled on return so you really never need to push them!
 

jiangzhengwenjzw

now working on katam
181
Posts
11
Years
  • Seen today
You're right, r0-r3 are assumed to be jumbled on return so you really never need to push them!

Really? I'm not sure about what you've said and I'm just speaking of r0 XD.

Actually I'm a bit confused that why 0x43110 is the location of the abort routine as it's the pointer of 6 different evolution methods.
The routine to read the table locates at around 0x42fb4, and i really don't know how the routine at 0x43110 work.
 

Joexv

ManMadeOfGouda joexv.github.io
1,037
Posts
11
Years
Actually I think I know what the thread means. However, I don't think that way of writing codes is necessary and I think all that I need to do is to "insert" some codes I need to do compares or some similar things and make sure that they won't influence the routines i branch to, which is often 0x4310c, 0x43016, 0x43000 and the abort routine 0x43110. There's no point in pushing so many registers when not using a decrypter or other complex routines.

I think if you want to branch to the function at 0x4310c, you should keep the codes at the beginning (but you can use registers more flexibly) and you don't need them if you directly branch to the routine at 0x43016 as it will do all the things for you. Anyway afaik pushing r0-r7 is always useless as r0 will be immediately refreshed so at least you don't need to push r0 to the stack to waste stack space, though you pop it after that so r13 is recovered and your original code will work without any problem.

All above are my own opinions, maybe they're not right. Someone has tested some of the routines i wrote and found no problem. ;) (Absolutely i can't make sure that all my routines work, as I haven't tested them)
Well if they work then I apologize! I was under the impresion that that "required" code was what determined more than just used in decrypting. So good job on simplifying those then!
 

jiangzhengwenjzw

now working on katam
181
Posts
11
Years
  • Seen today
Well if they work then I apologize! I was under the impresion that that "required" code was what determined more than just used in decrypting. So good job on simplifying those then!

Thank you for your reply!
Actually only 2 (maybe 3) are tested ok and the others are not tested and my friend is sparing his time testing them so they may have problem at the moment. Therefore, you may be right about keeping these "required" codes and i may be wrong as everything is not explicit now.
Anyway, I'm a bit confused with the function at 0x43110 as it is treated as the abort routine but also used as 6 different evolution methods. I cannot find out how it can distinguish them and I do not have much time to research it.....
 
116
Posts
16
Years
Thank you very much if you can test and add them ;)
For the latter sentence, r u speaking of the last function? Then r4 needn't be protected as the decrypter function pushes and pops r4 so it won't change XD
And please ignore the last function as it is very bugged and it couldn't be done if the pokemon is not the first one in the party. (I tried to change r8 to fix it as you can see in the label "adjust", but failed.)

Then I've just written a routine to evolve at specific level (the second parameter in the evolution table) when it detects a certain event has happened by checking flag 0x200.
Not tested.
Spoiler:

In addition, the routine checking if the Pokemon is shiny to go to level evolution. (Also not tested and I'm a bit not sure if the pokemon data pointer is in r8)
Spoiler:

And here I will post the simplified routines in the thread, all not tested. (The routines I write before several days will also be included)
Now the simplified routines are all finished because i only simplified some of them.
Spoiler:


I am not sure if my way of writing evolution routines is correct as it looks different from the original ones in the thread.

All the ASM codes who was simplified by jiangzhengwenjzw have been tested by me, they were working properly. Very nice to see these.
 

jiangzhengwenjzw

now working on katam
181
Posts
11
Years
  • Seen today
All the ASM codes who was simplified by jiangzhengwenjzw have been tested by me, they were working properly. Very nice to see these.

Thank you very much for your testing!

If you (or anyone) make sure that my simplified routines work properly in FR, you can just use them and bear in mind that you should absolutely keep the original credits and credit of mine is not needed as I actually only do the simplification work.

I hope that someone will check the 2 custom routines written by me though they are not such useful as far as I know XD
 

Joexv

ManMadeOfGouda joexv.github.io
1,037
Posts
11
Years
New working and tested routine:
Item and Level evolution!
Note: This works based on one item per routine!!! So you can reuse this for every Pokemon that needs metal coat, but if you want another one to use a Pokeball then you need to edit the routine(just one byte real simple)
Once G3HS is updated to support multiple arguments for evolutions this will make the routine customizable.
Code:
.text
.align 2
.thumb
.thumb_func
.global LevelItemEvo

main:
push {r0-r7}
add r0, r6, r7
lsl r0, r0, #0x3
add r0, r2, r0
add r3, r0, r3
ldrb r2, [r3, #0x2]
@Item Check
mov r0, r8
mov r1, #0xC
bl decrypt
mov r11, r0
pop {r0-r7}
mov r1, r11
[COLOR="Red"]cmp r1, #0xc7 @Change this to change item[/COLOR]
bne exit
@Item removal
mov r1, #0xC
mov r0, r8
bl encrypt
pop {r0-r7}
mov r9, r3
pop {r0-r7}
mov r1, r9
ldr r0, levelcheckloc
bx r0

exit: 
pop {r0-r7}
ldr r0, noevo
bx r0

encrypt:
push {r0-r7}
ldr r2, blank
ldr r5, encryptpoke
bx r5

decrypt: 
push {r0-r7}
ldr r2, decryptpoke
bx r2

.align
levelcheckloc: .word 0x0804310D
noevo: .word 0x08043111
decryptpoke: .word 0x0803FBE9
encryptpoke: .word 0x0804037D
blank: .word 0x020242A2
 
275
Posts
8
Years
New working and tested routine:
Item and Level evolution!
Note: This works based on one item per routine!!! So you can reuse this for every Pokemon that needs metal coat, but if you want another one to use a Pokeball then you need to edit the routine(just one byte real simple)
Once G3HS is updated to support multiple arguments for evolutions this will make the routine customizable.
Spoiler:

Great work joexv! Congratulations bro, and thanks a lot!
 

jiangzhengwenjzw

now working on katam
181
Posts
11
Years
  • Seen today
Specific coordinate evolution in specific map:
Code:
.thumb
.align 2
add r0, r6, r7
lsl r0, r0, #3
add r0, r2, r0
add r1, r0, r3
ldrh r0, [r1, #2]
push {r1}
ldr r1, =0x2031DBC
ldrh r1, [r1]
cmp r0, r1
bne end
ldr r0, =0x3005008
ldr r0, [r0]
ldr r0, [r0]
ldr r1, =0x000f003c @for example, 0x000f003c for (3c,f)
cmp r0, r1
bne end
pop {r1}
ldr r0, =0x0804310d
bx r0
end:
pop {r1}
ldr r0, =0x0804310d
add r0, #4
bx r0
Tested. The parameter in G3HS (or you use HxD) is the same as "specific map evolution", which means [byte-mapbank][byte-mapnumber]
The coordinates are reversed in the routine, so please be careful. It should be [hword-Y][hword-X]
For example, if you want your pokemon to evolve in (0x23,0x10e), You should put 0x010e0023 in the above routine.
 
Last edited:
Back
Top