Thread: Development: Take/Return Pokemon
View Single Post
Old February 3rd, 2009 (11:42 AM).
thethethethe thethethethe is offline
Join Date: Jun 2007
Location: Melbourne, Australia
Gender: Male
Posts: 1,104

ASM Take and Return Pokémon

NOTE:This is currently only for Fire Red. I’ll add support for other ROM’s when I find time.

To do this all you’ll need is a little knowledge about command #23 (callasm) and the ability to use a hex editor very basically. You don’t need to be an expert, because I’ll even give you an example script.

Okay here’s the code for those who know what to do with it. Its also is partly commented for those you have trouble understanding. Don’t ask what to do with this if you don’t already know. For those who don’t know what to do with this, I’ll give the other way to get the ASM code into the ROM. The code may not be the best but it works.

Take Pokemon
.align 2
.global main

main: push {r0-r4, lr} ldr r0, .var1 @var for Pokemon to take ldrh r0, [r0] @store Pokemon's number in party ldr r1, .var2 @+2, var for total Pokemon(use command #43) ldrh r1, [r1] @store max Pokemon in current party

cmp r0, r1 @If number to store is greater than number in party bgt error

b taken

error: mov r0, #1 ldr r1, .var3 strh r0, [r1] @+4, For error it will return 1 to var. pop {r0-r4, pc}

taken: ldr r3, .pokedata @loads Pokemon party data to reg cmp r0, #0 @if Pokemon to take is first, jump further ahead beq take

mov r2, #0 @loop counter

multiply: add r3, #100 @For each Pokemon in party has 100 bytes add r2, #1 @r2+=1 cmp r2, r0 @if counter equals Pokemon to copy bne multiply take: mov r0, r3 ldr r1, =0x02010000 @Destination to place data until Pokemon is given back. mov r2, #25 @or 50, I can't remember off the top of my head. swi 0xC @Either 0xC or oxB I can't remember which one is 4 byte write and which is two byte write.

mov r0, #0 @loop counter ldr r1, =0x00000000 @to overwrite old data with nothing.

remove: str r1, [r3] @pverwrite Pokemon data with 0 add r3, #4 @add 4 to location for next spot add r0, #1 @r0+=1 for loop cmp r0, #25 @If all data is overwritten blt remove

fix: @to fix up party if needed mov r1, #100 sub r2, r3, r1 @original calculated party spot ldr r1, .pokedata sub r1, r2, r1 @difference between data and Pokemon taken ldr r4, =500 cmp r1, r4 @If last Pokemon beq finish cmp r1, #0 beq finish

mov r0, r1 mov r1, #4 @calculate length (Maybe two I need to check swi 0x06 @divide interrupt result returned at r0

mov r1, r2 @r2 = Where to move party MOVE TO: r1 mov r2, r0 @r0 = Length MOVE TO: r2 mov r0, r3 @r3 = Rest of party MOVE TO: r0 swi 0xC

finish: mov r0, #0 @If work correctly, returns 0 to var number 3. ldr r1, .var3 strh r0, [r1] pop {r0-r4, pc}

.align 2 .pokedata: .word 0x02024284 .var1: .word 0x020370b8 .var2: .word 0x020370ba .var3: .word 0x020370b8

Return Pokemon

.align 2
.global main

main: push {r0-r2, lr} ldr r0, .var1 ldrh r0, [r0] @Load amount of Pokemon in party cmp r0, #5 beq error

b given

error: mov r0, #1 ldr r1, .var3 str r0, [r1] pop {r0-r2, pc}

given: ldr r1, .pokedata cmp r0, #0 beq ahead

mov r2, #0

loop1: add r1, #100 add r2, #1 cmp r2, r0 bne loop1

ahead: ldr r0, .space mov r2, #25 swi 0xC

mov r2, #0 mov r1, #0

remove: str r1, [r0] add r0, #4 add r2, #1 cmp r2, #25 blt remove

finish: mov r0, #0 ldr r1, .var3 strh r0, [r1] pop {r0-r2, pc}

.align 2 .pokedata: .word 0x02024284 .var1: .word 0x020370B8 .var3: .word 0x020370BC .space: .word 0x02010000

Here’s the ASM code for those who don’t know how to compile it. This isn’t an ASM tutorial so I won’t cover anything other than what’s needed to get this working.
Input this data into your ROM through a hex editor at an address of your choice. Write the address down, because you’ll need them for the script.
Take Pokemon

1FB5 1A48 0088 1A49 0988 8842 00DC 03E0
0120 1849 0880 1FBD 134B 0028 04D0 0022
6433 0132 8242 FBD1 181C 1349 1922 0CDF
0020 0021 1960 0433 0130 1928 FADB 6421
5A1A 0949 511A 0D4C A142 08D0 0029 06D0
081C 0421 06DF 111C 021C 181C 0CDF 0020
0449 0880 1FBD 0000 8442 0202 B870 0302
BA70 0302 B870 0302 00F0 0202 F401 0000

Then you’ll also need to input this code into your Hex editor as well.
Return Pokemon

07B5 1048 0088 0528 00D0 03E0 0120 0E49
0860 07BD 0A49 0028 04D0 0022 6431 0132
8242 FBD1 0948 1922 0CDF 0022 0021 0160
0430 0132 1928 FADB 0020 0349 0880 07BD
8442 0202 B870 0302 BC70 0302 00F0 0202

Now that you have the ASM part done. This part should be easy. All we need to do now is script it. Most people are most comfortable with XSE nowadays so I’ll put my example script to use the code in XSE.
But now we’re still not ready to code. We need to know some things about your ASM code.
The first code uses 3 variables 0x8000, 0x8001, and 0x8002. The second code uses only two variables 0x8000 and 0x8002.
In the first code, 0x8000 is used to store the number of the Pokemon in your party. For example, if it’s the first Pokemon, you would store zero, if it were the sixth Pokemon, you would store 5 into the variable.
0x8001 is used to store the total amount of Pokemon in your party. This can be obtained by just using countpokemon and then a copyvar from 0x800D to 0x8001.
0x8002 is used as an error check. For example if the Pokemon’s number in your party that you wanted to take, was less than the total Pokemon in your party designated by the above two variables. This is just originating from a normal C/C++ and the fact that a returned 0 means no problems, and a return of anything else means an error occurred.

In the second script, 0x8000 is used for the total Pokemon you have.
0x8002 is used in the same way as in the first code and is an error check.

So here’s an example script using the ASM code. I’ll comment any important areas out so you should know what’s going on even if you don’t script very well.

#alias @ $

#dynamic 0x800000

#org $start 'Code to take a Pokemon lock faceplayer checkflag 0x200 if 0x1 goto $return setvar 0x8000 0x0 'Pokemon to take is first in Party. countpokemon 'Total Pokemon in party. copyvar 0x8001 0x800D callasm 0x800001 'callasm 0x(address + 1) Of course then I inserted this code at 0x800001 compare 0x800D 0x1 'If error occurred. if 0x1 goto $error msgbox $1 0x6 setflag 0x200 release end

#org $error msgbox $2 0x6 release end

#org $return countpokemon compare 0x800D 0x5 if 0x1 goto $error 'If there’s no room for the return. copyvar 0x8000 0x800D callasm 0x800101 'Callasm 0x(address +1) Mine was 0x800100 compare 0x8002 0x1 'Error Check if 0x1 goto $error msgbox $3 0x6 clearflag 0x200 release end

#org $1 = Pokemon taken.

#org $2 = Error occurred.

#org $3 = Pokemon returned

Note this will only allow you to take one Pokemon at a time. If you try to take a second it will overwrite the first Pokemon and you’ll lose the first Pokemon.
Please let me know if there are any bugs. I haven’t extensively tested it out, I only checked whether it worked with the first Pokemon being taken and returned or not. The quicker people let me know, the quicker I can fix it.

Don't take without Permission.
Tutorial and code by thethethethe.

Reply With Quote