The PokéCommunity Forums

The PokéCommunity Forums (https://www.pokecommunity.com/index.php)
-   Binary Hack Research & Development (https://www.pokecommunity.com/forumdisplay.php?f=195)
-   -   Code ASM Resource Thread (https://www.pokecommunity.com/showthread.php?t=339153)

ghoulslash March 30th, 2017 8:26 AM

Quote:

Originally Posted by jiangzhengwenjzw (Post 9605326)
I guess the rival naming func is also built-in.

Change the A9 at 0x9FD54 to C5 and then try to callasm 0x809FD31. (It's from my old note in firered db, so i'm not sure whether it's correct or not...)

Yep, that worked, thanks! :)

EDIT: actually it turns out that edits the players name instead of the rival's name

EDIT 2: looks like setting 0xA9 at 0x9FCB4 0xC5 fixed both naming the player and Jambo's routine (or I had made a mistake using it initially). Setting 0xA9 at 0x9FD54 to 0xC5 doesn't appear to change this either, but callasm 0x809FD31 will overwrite the player's name instead of the rival's

Wesley FG March 30th, 2017 9:06 AM

REQUEST for change this ROUTINE for FIRE RED

The user Andrea make this awesome ASM for icon in menu like DPPt,

Quote:

Originally Posted by ~Andrea
Hello everyone, today I would share with you this little patch:
https://image.ibb.co/d2B86F/2hclyd2.png
As you can see from the screen, the patch will add the icons of the DPP next to each menu item.
- ONLY FOR RUBY -
Note:
- If the menu item "Pokenav" should be active, the icons will be loaded out of phase respect to the corresponding menu item.
This is caused by the lack of an icon for Pokenav in DPP.

Technical information:
Offsets routine: 0x720000
Offset Images Icons (uncompressed): 0x7200D0
Offset Palette icons (uncompressed): 0x720610
To change icons you can open the ROM with NSE 2.X, click browse and input offsets earlier in the appropriate fields.

downloads:
http://www.mediafire.com/download/wzs1d0zg2i5e231/DPP_MENU.ips
Credit if you use it!
but it is only for RUBY version

the routine is it:

Spoiler:

.THUMB
.ALIGN 2
@08071174 00490847XXXXXX08
@080711C8 MOVS R0, #0x16 @coordinata x
@08071208 lunghezza cursore
@0807120E posizione X cursore

PUSH {R0-R7}
LDR R1, = 0x06008020
LDR R0, = 0x087200D0
MOV R2, #0x15
LSL R2, #4
SWI 0xC

LSL R2, #2
ADD R0, R2

MOV R3, #1
LSL R3, #10

LDR R1, = 0x0202EC48
MOV R2, #8
SWI 0xC
LDR R4, = 0x0202FEB3
LDRB R4, [R4]
CMP R4, #0x16
BNE ICONE
ADD R1, R1, R3
SWI 0xC

ICONE:
MOV R6, #0

MOV R0, #1
LSL R0, #11
ADD R0, #1
BL CHECKFLAG
CMP R0, #0
BEQ PARTY

ADD R6, #1
MOV R0, #0
MOV R1, #0
BL SPAWN

PARTY:
MOV R0, #1
LSL R0, #11
BL CHECKFLAG
CMP R0, #0
BEQ ALTRO

MOV R0, #1
ADD R6, #1
CMP R6, #2
BEQ CONTROLLO
MOV R0, #0
CONTROLLO:
MOV R1, #1
BL SPAWN

ALTRO:
LDR R5, = 0x0202E8FD
LDRB R5, [R5]

MOV R7, #2
LOOP2:
MOV R0, R6
MOV R1, R7
BL SPAWN
ADD R6, #1
ADD R7, #1
CMP R6, R5
BNE LOOP2

FINE:
POP {R0-R7}
POP {R4-R7,PC}

SPAWN:
LSL R0, #7
LDR R2, = 0x0600F8A8
ADD R0, R2
MOV R3, #6
MUL R1, R3
ADD R1, #1
MOV R2, #0xC0
LSL R2, #8
ADD R1, R2
MOV R2, #0
MOV R3, #0
LOOP:
STRH R1, [R0]
ADD R0, #2
ADD R1, #1
ADD R2, #1
CMP R2, #3
BNE LOOP
ADD R0, #0x3A
MOV R2, #0
ADD R3, #1
CMP R3, #2
BNE LOOP
BX LR

CHECKFLAG:
PUSH {R0}
LDR R0, = 0x08069341
MOV R10, R0
POP {R0}
BX R10



i no have knlowledge for ASM and i really love with some ASM expert convert it for FIRE RED and EMERALD, because it is very beautifull, and make a awesome hack improve.

BUGS:
-No have icon for dex nav- when this flag is active bug it (R, EM)
-when the player enter in map with some wheater the icons bug, probably are using same location memory pal used for it
https://i.imgur.com/OvNCIWa.png

the original thread of andrea ASM;
https://www.pokecommunity.com/showthread.php?p=8880222#post8880222

PLZ port it for FIRE RED and EMERALD

mbcn10ww March 30th, 2017 5:50 PM

Quote:

Originally Posted by MWisBest (Post 9604877)
Made another improvement to the reusable pokeballs: safari balls can now be reused as well!

Code:

.text
.align 2
.thumb

@ FE3AA - 00 21
@ 56818 - 00 48 00 47 XX+1 XX XX XX
@ 3F008 - 02 E0 C0 46 C0 46 C0 46 ! NEW
@ Optional: change initial safari ball count?: FC0E6 - XX 20, XX = initial count

main:
        @ if safari ball counter is not 0, then that's what we need to delete
        ldr r1, .safari_ball_count
        ldrb r0, [r1]
        cmp r0, #0x0
        bne delete_safari_ball

        @ ...otherwise, delete the last used item (if it's a pokeball)
        ldr r0, .last_used_item
        ldrh r0, [r0]
        @ checks that the item id is premier ball or lower
        cmp r0, #0xC
        bls delete_ball_in_bag
        @ support for custom pokeballs can be added like so:
        @ cmp r0, #CUSTOM_BALL_ID
        @ beq delete_ball_in_bag

        b finish

delete_safari_ball:
        @ r0 already contains current safari ball count, and
        @ r1 already contains safari ball count memory address
        sub r0, #1
        strb r0, [r1]
        b finish

delete_ball_in_bag:
        @ r0 already contains last_used_item.
        mov r1, #1
        ldr r2, .bag_remove_item
        bl x_r2
        b finish

x_r2:
        bx r2

finish:
        mov r9, r4
        mov r10, r5
        pop {r4-r7}
        pop {r0}
        bx r0

.align 2
.last_used_item:
        .word 0x0203CE7C
.bag_remove_item:
        .word 0x080D6AA4|1
.safari_ball_count:
        .word 0x0203A04C



sorry but can you port it to Fire Red?

MWisBest March 30th, 2017 11:09 PM

Change Daycare Cost [EM]

There's 2 versions of this routine.

The first is completely configurable (when you compile it), and the changes you need to make to do so are very simple and explained well in the code:
Spoiler:
Code:

.text
.align 2
.thumb

@ 0x6FE9E: 0A 31 00 48 00 47 XX+1 XX XX XX (original: 64 20 44 43 64 34 05 48 21 1C)

main:
        @ at this point, r4 contains the "levels gained"
        @ when we're finished, r4 will contain the money amnt
        @ r0-r4 are all safe to use here, *however*: r1 contains
        @ the address this routine was jumped to from, and using
        @ that we can jump back there easier.
        @
        @ the original code we're replacing, for reference:
        @ mov r0, #100
        @ mul r4, r0
        @ add r4, #100

        @ need to copy r1 to r3 because r1 is clobbered later
        mov r3, r1

        @ adjust the following code like so:
        @ mov r0, #BASE_PER_LEVEL_COST
        @ mov r1, #PER_LEVEL_COST_MULTIPLIER
        @ ...
        mov r0, #100
        mov r1, #2
        mul r0, r1

        @ ...
        @ and adjust this like so:
        @ mov r2, #BASE_MINIMUM_COST
        @ mov r1, #MINIMUM_COST_MULTIPLIER
        mov r2, #100
        mov r1, #2
        mul r2, r1

        mul r4, r0 @ cost = levels gained * per level cost
        add r4, r2 @ cost += minimum cost

        @ the following instructions were chopped off to insert jump to this routine
        ldr r0, .dword_806FEBC
        mov r1, r4

        @ resume execution of the original code
        bx r3

.align 2
.dword_806FEBC:
        .word 0x02021DC4




The second is a little different. Rather than a configurable multiplier, it uses the "XP per step" value as the multiplier, so if you're using this modification to adjust the XP per step amount it will scale the daycare cost accordingly, e.x. 2 XP per step will multiply the normal daycare cost by 2:
Spoiler:
Code:

.text
.align 2
.thumb

@ 0x6FE9E: 0A 31 00 48 00 47 XX+1 XX XX XX (original: 64 20 44 43 64 34 05 48 21 1C)

main:
        @ at this point, r4 contains the "levels gained"
        @ when we're finished, r4 will contain the money amnt
        @ r0-r4 are all safe to use here, *however*: r1 contains
        @ the address this routine was jumped to from, and using
        @ that we can jump back there easier.
        @
        @ the original code we're replacing, for reference:
        @ mov r0, #100
        @ mul r4, r0
        @ add r4, #100

        @ need to copy r1 to r3 because r1 is clobbered later
        mov r3, r1

        mov r0, #100
        ldr r1, .xp_per_step
        ldrb r1, [r1]
        mul r0, r1

        mul r4, r0 @ cost = levels gained * per level cost
        add r4, r0 @ cost += minimum cost

        @ the following instructions were chopped off to insert jump to this routine
        ldr r0, .dword_806FEBC
        mov r1, r4

        @ resume execution of the original code
        bx r3

.align 2
.xp_per_step:
        .word 0x08070AE8
.dword_806FEBC:
        .word 0x02021DC4




Quote:

Originally Posted by mbcn10ww (Post 9605799)
sorry but can you port it to Fire Red?

I am planning on porting the stuff I've done for Emerald to Fire Red soon. I just got back into playing the Gen III games a little while ago and decided to start with Emerald for some reason.

EDIT: Made some changes to the original code I posted to make it more compact/efficient. For those that were already using the old version, note that the first 2 bytes of the byte edit required have also been changed.

Compumax March 31st, 2017 5:09 AM

Request!

1) Load 240x160 static images into BG1 or BG2 using (image, palette, RAW) table and allow (if possible) use BG0 to load texts (as in the presentation of Oak, Pokédex, etc.) and objects like pokepic, Mugshots, etc. And their respective routine to remove the image. If it is very difficult or impossible with ASM, it can be a routine that loads the image in BG0 and its respective routine to remove it. What I want to do is cinematic with frame sequences. I can not use the diploma hack because I need to make decisions by pressing the A, B and the arrow keys.

I tried this routine: FR - Vs. Bar Personalizable but it has no routine to remove the image so in the end I have to do a warp to refresh the screen and erase the image . Finally after 5
continuous frames the game freezes.

2) Load different dialogs in the presentation of Oak depending on the selected genre. What I want to do is a multi-language effect depending on gender. Example: Boy = Spanish, Girl = English.

Thanks for the help you can give me.

Here is the link to my current project:


Pokémon Terranova

PD: Sorry for my English

BluRose March 31st, 2017 8:27 AM

Quote:

Originally Posted by Compumax (Post 9606234)
Spoiler:
Request!

1) Load 240x160 static images into BG1 or BG2 using (image, palette, RAW) table and allow (if possible) use BG0 to load texts (as in the presentation of Oak, Pokédex, etc.) and objects like pokepic, Mugshots, etc. And their respective routine to remove the image. If it is very difficult or impossible with ASM, it can be a routine that loads the image in BG0 and its respective routine to remove it. What I want to do is cinematic with frame sequences. I can not use the diploma hack because I need to make decisions by pressing the A, B and the arrow keys.

I tried this routine: FR - Vs. Bar Personalizable but it has no routine to remove the image so in the end I have to do a warp to refresh the screen and erase the image . Finally after 5
continuous frames the game freezes.

2) Load different dialogs in the presentation of Oak depending on the selected genre. What I want to do is a multi-language effect depending on gender. Example: Boy = Spanish, Girl = English.

Thanks for the help you can give me.

Here is the link to my current project:


Pokémon Terranova

PD: Sorry for my English

for the first one, try this
for your second request, just use the checkgender command and branch accordingly. i believe it returns 0 for male and 1 for female

para tu primer, prueba esta rutina
para tu segundo, usa "checkgender" y haz lo que necesitas. creo que vuelve 0 si eres hombre y 1 si eres mujer

pd: doesn't use bg0. can switch it to any other bg easily tho, edit for text and lay an rbox above or something

mbcn10ww March 31st, 2017 8:43 AM

Quote:

Originally Posted by MWisBest (Post 9605943)
Change Daycare Cost [EM]

There's 2 versions of this routine.

The first is completely configurable (when you compile it), and the changes you need to make to do so are very simple and explained well in the code:
Spoiler:
Code:

.text
.align 2
.thumb

@ 0x6FE9E: C0 46 00 48 00 47 XX+1 XX XX XX (original: 64 20 44 43 64 34 05 48 21 1C)

main:
        @ at this point, r4 contains the "levels gained"
        @ when we're finished, r4 will contain the money amnt
        @ r0-r4 are all safe to use here.
        @
        @ the original code:
        @ mov r0, #100
        @ mul r4, r0
        @ add r4, #100

        @ adjust the following code like so:
        @ mov r0, #BASE_PER_LEVEL_COST
        @ mov r1, #PER_LEVEL_COST_MULTIPLIER
        @ mov r2, #BASE_MINIMUM_COST
        @ mov r3, #MINIMUM_COST_MULTIPLIER
        mov r0, #100
        mov r1, #2
        mov r2, #100
        mov r3, #2

        mul r0, r1
        mul r2, r3

        mul r4, r0 @ cost = levels gained * per level cost
        add r4, r2 @ cost += minimum cost

        @ the following instructions were chopped off to insert jump to this routine
        ldr r0, .dword_806FEBC
        mov r1, r4

        @ resume execution of the original code
        ldr r2, .continue_function
        bx r2

.align 2
.dword_806FEBC:
        .word 0x02021DC4
.continue_function:
        .word 0x0806FEA8|1




The second is a little different. Rather than a configurable multiplier, it uses the "XP per step" value as the multiplier, so if you're using this modification to adjust the XP per step amount it will scale the daycare cost accordingly, e.x. 2 XP per step will multiply the normal daycare cost by 2:
Spoiler:
Code:

.text
.align 2
.thumb

@ 0x6FE9E: C0 46 00 48 00 47 XX+1 XX XX XX (original: 64 20 44 43 64 34 05 48 21 1C)

main:
        @ at this point, r4 contains the "levels gained"
        @ when we're finished, r4 will contain the money amnt
        @ r0-r4 are all safe to use here.
        @
        @ the original code:
        @ mov r0, #100
        @ mul r4, r0
        @ add r4, #100

        mov r0, #100
        ldr r1, .xp_per_step
        ldrb r1, [r1]
        mul r0, r1

        mul r4, r0 @ cost = levels gained * per level cost
        add r4, r0 @ cost += minimum cost

        @ the following instructions were chopped off to insert jump to this routine
        ldr r0, .dword_806FEBC
        mov r1, r4

        @ resume execution of the original code
        ldr r2, .continue_function
        bx r2

.align 2
.xp_per_step:
        .word 0x08070AE8
.dword_806FEBC:
        .word 0x02021DC4
.continue_function:
        .word 0x0806FEA8|1






I am planning on porting the stuff I've done for Emerald to Fire Red soon. I just got back into playing the Gen III games a little while ago and decided to start with Emerald for some reason.

Thank you for the reply. You're doing a great work with your routines, I like the way you explain them, it becomes very easy to understand for people who haven't learned ASM (or are learning like me), nice work.

MWisBest March 31st, 2017 10:27 PM

Quote:

Originally Posted by mbcn10ww (Post 9606318)
Thank you for the reply. You're doing a great work with your routines, I like the way you explain them, it becomes very easy to understand for people who haven't learned ASM (or are learning like me), nice work.

Thanks, I appreciate hearing that. My code comments can be a little excessive, but with reverse-engineering stuff I like to make notes of anything relevant in case I revisit it later. Glad it's helpful for you too.

Compumax April 1st, 2017 7:36 PM

Quote:

Originally Posted by BluRose (Post 9606307)
for the first one, try this
for your second request, just use the checkgender command and branch accordingly. i believe it returns 0 for male and 1 for female

pd: doesn't use bg0. can switch it to any other bg easily tho, edit for text and lay an rbox above or something

Thanks for the prompt response!
1) I only need to load images (preferably compressed in LZ77) from a table through the control of a variable, in BG1 or BG2 to be able to use the BG0 text box. I think I can do it from the example you left me, although I assume that it does not work with compressed images. Really thank you very much. I am starting in ASM and would like to learn more. And of course how to erase that image, the rest would do with scripting controlling the variable. Finally what doo to do is a system of choice of the initial pokémon this way:


So I just need 2 routines. One that loads the image in with the following features preferably:

- That depends on the value of a variable (I can do it)
- Use a table (image) (pal) (raw) (I can do it)
- 16 colors (I can do it)
- Image compressed in LZ77 (since I need to insert many images)
- Use BG1 or BG2 to use the BG0 to load text boxes and OBJ

And another one that safely removes the image from said background

2) What I wanted was for the genre to be selected in Oak's presentation, immediately after selecting boy to show a text; And if you select girl it would show another different text. For example:

https://k60.kn3.net/B/C/B/5/0/9/5FC.gif

And here I need to know how to point to the next text depending on the gender selected.

Thank you in advance for the help you can give me.

PD: Gifs are not made since the rom, they were made with sequences of images obviously.

mbcn10ww April 3rd, 2017 9:09 AM

Hi everyone, does anyone knows how to remove the Field Moves options (like Flash, Dig, Fly...) from the Pokémon menu? Because I want to move them to some place but don't know how to make them never show up when I teach the respective move to a Pokémon. Thanks in advance.

MWisBest April 3rd, 2017 5:37 PM

Breeding: Same Offspring = Same Species [EM]

This is kind of a continuation of this post. To put it simply, if you put a Bulbasaur and an Ivysaur in the daycare, they produce fewer eggs than if you paired two Bulbasaurs or two Ivysaurs. This changes it so the Bulbasaur+Ivysaur pair produce the same amount of eggs as a Bulbasaur pair (meaning more than they used to).

Code:

.text
.align 2
.thumb
.thumb_func

@ 0x70D88: 00 48 00 47 XX+1 XX XX XX (original: 20 1C 0B 21 F9 F7 72 FC)

main:
        mov r0, r4  @ move pointer to pokemon to r0
        mov r1, #0xB @ req_species
        ldr r2, .pokemon_getattr_encrypted
        bl x_r2

        @ r0 now contains the species index, which the game *used* to use.
        @ instead, replace it with the offspring index, so different Pokemon
        @ from the same evolution chain are properly recognized as the same species
        @ (e.x. breeding a Charmander and Charizard works as well as 2 Charmanders does)
        ldr r2, .determine_offspring_from_species_index
        bl x_r2

        @ go back to where we came from. (this falls through to the bx r2 below)
        ldr r2, .resume_execution

x_r2:
        bx r2

.align 2
.pokemon_getattr_encrypted:
        .word 0x0806A674|1
.determine_offspring_from_species_index:
        .word 0x08070004|1
.resume_execution:
        .word 0x08070D90|1



NewDenverCity April 3rd, 2017 6:12 PM

Quote:

Originally Posted by tkim (Post 9609111)
I've been trying to study how to decrypt/encrypt a pokemon in party all day and I think the routine would be fairly short and simple but I just don't get how to set up the routine. This page shows a brief explanation and the offsets for decrypting/encrypting: http://www.romhack.me/database/23/fire-red-commonly-used-asm-rom-offsets/ . All I know is that there should be a 'mov r1, 0x#C' (held item) somewhere in the routine. Also are we supposed to decrypt a pokemon before encrypting?

Decrypt and encrypt is a misnomer, it actually should be something like get_attribute and set_attribute or something. To encrypt, or set an attribute, you need to have the pointer to the pokemon structure in r0. r1 is the attribute to set, and r2 must be the pointer to the thing you're setting. Here's an example.
Code:

.thumb

main:
    @get the address in r0
    mov r1, #0x24 @catch level
    mov r2, #0x10
    push {r2}
    mov r2, sp
    bl encrypt
    pop {r2}


This sets the catch level to 16. Now, I don't know why you'd want to set the catch level to something else, but you can do it. You can also just store the thing for r2 in some RAM address but I don't know an open word. And yes, the data must be stored as a word, so using var 0x8009 or whatever probably won't work.

AkameTheBulbasaur April 4th, 2017 11:48 AM

JPAN had as part of his engine a way to make wild Pokemon and Trainers have dynamic levels (you can set a variable to certain values to change the levels to your liking, for example: setting the variable to 0x100 makes Wild/Trainer Pokemon levels match your highest Pokemon.)

However I've noticed that this doesn't seem to work with scripted battles (aka setwildbattle). It just uses the level that you buffered regardless of the routine.

Is there a way to make scripted battles have levels that match your highest level Pokemon?

ghoulslash April 5th, 2017 5:26 AM

edit: figured it out!

MWisBest April 6th, 2017 11:22 AM

Quote:

Originally Posted by DizzyEgg (Post 9165010)
FR has different stat summary screen display from Emerald, so you can't really change offsets. You're in luck though, as I wrote a routine that does that in EM.
LeftStats color change:
Spoiler:

Code:

.text
.thumb
.thumb_func
.align 2

main:
    push {r5}
    sub sp, sp, #0x20
    ldr r0, [r4] @pokemon summary pointer
    add r0, #0xA3 @poke nature
    ldrb r1, [r0]
    ldr r0, nature_stat_table
    lsl r2, r1, #2
    add r2, r1, r2 @multiply by 5
    add r2, r2, r0 @r2 contains nature info
    ldr r3, left_stats_string
    mov r1, sp
    mov r5, #0

handle_hp:
    ldrb r0, [r3, r5]
    strb r0, [r1, r5]
    add r5, #1
    cmp r5, #6
    bne handle_hp
    add r3, #6
    add r1, #6
    mov r5, #0

handle_atk:
    ldrb r0, [r2]
    cmp r0, #1
    beq red_font_atk
    cmp r0, #0xFF
    bne copy_atk
    bl blue_font
    b copy_atk

red_font_atk:
    bl red_font

copy_atk:
    ldrb r0, [r3, r5]
    strb r0, [r1, r5]
    add r5, #1
    cmp r5, #3
    bne copy_atk
    add r3, #3
    add r1, #3
    mov r5, #0

handle_def:
    add r2, #1
    ldrb r0, [r2]
    cmp r0, #1
    beq red_font_def
    cmp r0, #0xFF
    beq blue_font_def
    bl default_font
    b copy_def

red_font_def:
    bl red_font
    b copy_def

blue_font_def:
    bl blue_font

copy_def:
    ldrb r0, [r3, r5]
    strb r0, [r1, r5]
    add r5, #1
    cmp r5, #3
    bne copy_def

copy_string:
    ldr r0, displayed_string
    mov r1, sp
    ldr r2, special_f7_string_fct
    bl callvia_r2

return:
    mov r0, r9
    add sp, sp, #0x20
    pop {r5}
    ldr r2, =(0x081C37A8 + 1)
    b callvia_r2

blue_font: @FC 01 07
    mov r0, #0xFC
    strb r0, [r1]
    add r1, #1
    mov r0, #1
    strb r0, [r1]
    add r1, #1
    mov r0, #7 @color of the lowered stat
    strb r0, [r1]
    add r1, #1
    bx lr

red_font: @FC 01 05
    mov r0, #0xFC
    strb r0, [r1]
    add r1, #1
    mov r0, #1
    strb r0, [r1]
    add r1, #1
    mov r0, #5 @color of the raised stat
    strb r0, [r1]
    add r1, #1
    bx lr

default_font: @FC 01 01
    mov r0, #0xFC
    strb r0, [r1]
    add r1, #1
    mov r0, #1
    strb r0, [r1]
    add r1, #1
    strb r0, [r1]
    add r1, #1
    bx lr

callvia_r2:
    bx r2

.align 2

nature_stat_table: .word 0x0831E818
left_stats_string: .word 0x0861CE82
displayed_string: .word 0x02021FC4
special_f7_string_fct: .word 0x081AFC29

@at 0x1C379E insert: 00 00 00 4A 10 47 XX+1 XX XX 08 where XX is the address of the inserted routine



RightStats color change:
Spoiler:

Code:

.text
.thumb
.thumb_func
.align 2

main:
    push {r5}
    sub sp, sp, #0x20
    ldr r0, [r4] @pokemon summary pointer
    add r0, #0xA3 @poke nature
    ldrb r1, [r0]
    ldr r0, nature_stat_table
    lsl r2, r1, #2
    add r2, r1, r2 @multiply by 5
    add r2, r2, r0 @r2 contains nature info
    add r2, #3 @r2 contains beg of spatk stat
    ldr r3, right_stats_string
    mov r1, sp
    mov r5, #0

handle_spatk:
    ldrb r0, [r2]
    cmp r0, #1
    beq red_font_spatk
    cmp r0, #0xFF
    bne copy_spatk
    bl blue_font
    b copy_spatk

red_font_spatk:
    bl red_font

copy_spatk:
    ldrb r0, [r3, r5]
    strb r0, [r1, r5]
    add r5, #1
    cmp r5, #3
    bne copy_spatk
    add r3, #3
    add r1, #3
    mov r5, #0

handle_spdef:
    add r2, #1
    ldrb r0, [r2]
    cmp r0, #1
    beq red_font_spdef
    cmp r0, #0xFF
    beq blue_font_spdef
    bl default_font
    b copy_spdef

red_font_spdef:
    bl red_font
    b copy_spdef

blue_font_spdef:
    bl blue_font

copy_spdef:
    ldrb r0, [r3, r5]
    strb r0, [r1, r5]
    add r5, #1
    cmp r5, #3
    bne copy_spdef
    add r3, #3
    add r1, #3
    mov r5, #0

handle_spd:
    sub r2, #2
    ldrb r0, [r2]
    cmp r0, #1
    beq red_font_spd
    cmp r0, #0xFF
    beq blue_font_spd
    bl default_font
    b copy_spd

red_font_spd:
    bl red_font
    b copy_spd

blue_font_spd:
    bl blue_font

copy_spd:
    ldrb r0, [r3, r5]
    strb r0, [r1, r5]
    add r5, #1
    cmp r5, #3
    bne copy_spd
    add r3, #3
    add r1, #3

return:
    ldr r0, displayed_string
    mov r1, sp
    ldr r2, special_f7_string_fct
    bl callvia_r2
    add sp, sp, #0x20
    pop {r5}
    ldr r2, =(0x081C386C + 1)
    bx r2

blue_font: @FC 01 07
    mov r0, #0xFC
    strb r0, [r1]
    add r1, #1
    mov r0, #1
    strb r0, [r1]
    add r1, #1
    mov r0, #7 @color of the lowered stat
    strb r0, [r1]
    add r1, #1
    bx lr

red_font: @FC 01 05
    mov r0, #0xFC
    strb r0, [r1]
    add r1, #1
    mov r0, #1
    strb r0, [r1]
    add r1, #1
    mov r0, #5 @color of the raised stat
    strb r0, [r1]
    add r1, #1
    bx lr

default_font: @FC 01 01
    mov r0, #0xFC
    strb r0, [r1]
    add r1, #1
    mov r0, #1
    strb r0, [r1]
    add r1, #1
    strb r0, [r1]
    add r1, #1
    bx lr

callvia_r2:
    bx r2   

.align 2

nature_stat_table: .word 0x0831E818
right_stats_string: .word 0x0861CE8E
displayed_string: .word 0x02021FC4
special_f7_string_fct: .word 0x081AFC29

@at 0x1C3864 insert 00 4A 10 47 XX+1 XX XX 08



Image:

I combined this into 1 routine and cut the total size down a lot. All credit to DizzyEgg of course, this is nothing compared to creating the mod in the first place.

Code:

.text
.thumb
.thumb_func
.align 2

@ 0x1C379E: 02 30 00 4A 10 47 XX+1 XX XX 08
@ 0x1C3864: 00 4A 10 47 XX+1 XX XX 08

main:
        @ at this point... r0 contains our return address (- 8). Convenient!
        push {r5-r7}

        @ save return address for later.
        mov r6, r0
        add r6, #0x8

        @ to determine what function we were called from:
        @ if it was right stats, r9 is 0. if it was left stats, r9 has something in it.
        mov r7, r9 @ can't really use hi registers in thumb, mov it down.
        @ so, to check the function type: cmp r7, #0. eq means right stats.

        sub sp, sp, #0x20
        ldr r0, [r4] @pokemon summary pointer. we're free to use r4 after this.
        add r0, #0xA3 @poke nature
        ldrb r1, [r0]
        ldr r0, nature_stat_table

        mov r2, #5
        mul r2, r1

        mov r1, sp
        mov r5, #0

        add r2, r2, r0 @r2 contains nature info
        cmp r7, #0
        beq right_stats_begin

@@ LEFT STAT COLORING BEGIN @@@

left_stats_begin:
        ldr r3, left_stats_string

handle_hp:
        ldrb r0, [r3, r5]
        strb r0, [r1, r5]
        add r5, #1
        cmp r5, #6
        bne handle_hp
        add r3, #6
        add r1, #6
        mov r5, #0

handle_atk:
        ldrb r0, [r2]
        cmp r0, #1
        beq red_font_atk
        cmp r0, #0xFF
        bne copy_atk
        bl blue_font
        b copy_atk

red_font_atk:
        bl red_font

copy_atk:
        ldrb r0, [r3, r5]
        strb r0, [r1, r5]
        add r5, #1
        cmp r5, #3
        bne copy_atk
        add r3, #3
        add r1, #3
        mov r5, #0

handle_def:
        add r2, #1
        ldrb r0, [r2]
        cmp r0, #1
        beq red_font_def
        cmp r0, #0xFF
        beq blue_font_def
        bl default_font
        b copy_def

red_font_def:
        bl red_font
        b copy_def

blue_font_def:
        bl blue_font

copy_def:
        ldrb r0, [r3, r5]
        strb r0, [r1, r5]
        add r5, #1
        cmp r5, #3
        bne copy_def
        b return

@@@ LEFT STAT COLORING END @@

@@@ RIGHT STAT COLORING BEGIN @@@

right_stats_begin:
        add r2, #3 @r2 contains beg of spatk stat
        ldr r3, right_stats_string

handle_spatk:
        ldrb r0, [r2]
        cmp r0, #1
        beq red_font_spatk
        cmp r0, #0xFF
        bne copy_spatk
        bl blue_font
        b copy_spatk

red_font_spatk:
        bl red_font

copy_spatk:
        ldrb r0, [r3, r5]
        strb r0, [r1, r5]
        add r5, #1
        cmp r5, #3
        bne copy_spatk
        add r3, #3
        add r1, #3
        mov r5, #0

handle_spdef:
        add r2, #1
        ldrb r0, [r2]
        cmp r0, #1
        beq red_font_spdef
        cmp r0, #0xFF
        beq blue_font_spdef
        bl default_font
        b copy_spdef

red_font_spdef:
        bl red_font
        b copy_spdef

blue_font_spdef:
        bl blue_font

copy_spdef:
        ldrb r0, [r3, r5]
        strb r0, [r1, r5]
        add r5, #1
        cmp r5, #3
        bne copy_spdef
        add r3, #3
        add r1, #3
        mov r5, #0

handle_spd:
        sub r2, #2
        ldrb r0, [r2]
        cmp r0, #1
        beq red_font_spd
        cmp r0, #0xFF
        beq blue_font_spd
        bl default_font
        b copy_spd

red_font_spd:
        bl red_font
        b copy_spd

blue_font_spd:
        bl blue_font

copy_spd:
        ldrb r0, [r3, r5]
        strb r0, [r1, r5]
        add r5, #1
        cmp r5, #3
        bne copy_spd
        b return

@@@ RIGHT STAT COLORING END @@@

@@@ FONT FUNCTIONS BEGIN @@@

blue_font: @FC 01 07
        mov r4, #7 @color of the lowered stat
        b font_common

red_font: @FC 01 05
        mov r4, #5 @color of the raised stat
        b font_common

default_font: @FC 01 01
        mov r4, #1 @color of the regular stats
        @ just fall through to font_common (no need to branch)

font_common:
        mov r0, #0xFC
        strb r0, [r1]
        add r1, #1
        mov r0, #1
        strb r0, [r1]
        add r1, #1
        strb r4, [r1]
        add r1, #1
        bx lr

@@@ FONT FUNCTIONS END @@@

return:
        ldr r0, displayed_string
        mov r1, sp
        ldr r2, special_f7_string_fct
        bl x_r2
        cmp r7, #0
        beq skip_mov_r0_r9
        mov r0, r9
skip_mov_r0_r9:
        add sp, sp, #0x20
        mov r2, r6
        pop {r5-r7}
x_r2:
        bx r2

.align 2
nature_stat_table: .word 0x0831E818
left_stats_string: .word 0x0861CE82
right_stats_string: .word 0x0861CE8E
displayed_string: .word 0x02021FC4
special_f7_string_fct: .word 0x081AFC29



DizzyEgg April 7th, 2017 1:10 AM

Quote:

Originally Posted by MWisBest (Post 9611218)
I combined this into 1 routine and cut the total size down a lot. All credit to DizzyEgg of course, this is nothing compared to creating the mod in the first place.

Code:

.text
.thumb
.thumb_func
.align 2

@ 0x1C379E: 02 30 00 4A 10 47 XX+1 XX XX 08
@ 0x1C3864: 00 4A 10 47 XX+1 XX XX 08

main:
    @ at this point... r0 contains our return address (- 8). Convenient!
    push {r5-r7}

    @ save return address for later.
    mov r6, r0
    add r6, #0x8

    @ to determine what function we were called from:
    @ if it was right stats, r9 is 0. if it was left stats, r9 has something in it.
    mov r7, r9 @ can't really use hi registers in thumb, mov it down.
    @ so, to check the function type: cmp r7, #0. eq means right stats.

    sub sp, sp, #0x20
    ldr r0, [r4] @pokemon summary pointer. we're free to use r4 after this.
    add r0, #0xA3 @poke nature
    ldrb r1, [r0]
    ldr r0, nature_stat_table

    mov r2, #5
    mul r2, r1

    mov r1, sp
    mov r5, #0

    add r2, r2, r0 @r2 contains nature info
    cmp r7, #0
    beq right_stats_begin

@@ LEFT STAT COLORING BEGIN @@@

left_stats_begin:
    ldr r3, left_stats_string

handle_hp:
    ldrb r0, [r3, r5]
    strb r0, [r1, r5]
    add r5, #1
    cmp r5, #6
    bne handle_hp
    add r3, #6
    add r1, #6
    mov r5, #0

handle_atk:
    ldrb r0, [r2]
    cmp r0, #1
    beq red_font_atk
    cmp r0, #0xFF
    bne copy_atk
    bl blue_font
    b copy_atk

red_font_atk:
    bl red_font

copy_atk:
    ldrb r0, [r3, r5]
    strb r0, [r1, r5]
    add r5, #1
    cmp r5, #3
    bne copy_atk
    add r3, #3
    add r1, #3
    mov r5, #0

handle_def:
    add r2, #1
    ldrb r0, [r2]
    cmp r0, #1
    beq red_font_def
    cmp r0, #0xFF
    beq blue_font_def
    bl default_font
    b copy_def

red_font_def:
    bl red_font
    b copy_def

blue_font_def:
    bl blue_font

copy_def:
    ldrb r0, [r3, r5]
    strb r0, [r1, r5]
    add r5, #1
    cmp r5, #3
    bne copy_def
    b return

@@@ LEFT STAT COLORING END @@

@@@ RIGHT STAT COLORING BEGIN @@@

right_stats_begin:
    add r2, #3 @r2 contains beg of spatk stat
    ldr r3, right_stats_string

handle_spatk:
    ldrb r0, [r2]
    cmp r0, #1
    beq red_font_spatk
    cmp r0, #0xFF
    bne copy_spatk
    bl blue_font
    b copy_spatk

red_font_spatk:
    bl red_font

copy_spatk:
    ldrb r0, [r3, r5]
    strb r0, [r1, r5]
    add r5, #1
    cmp r5, #3
    bne copy_spatk
    add r3, #3
    add r1, #3
    mov r5, #0

handle_spdef:
    add r2, #1
    ldrb r0, [r2]
    cmp r0, #1
    beq red_font_spdef
    cmp r0, #0xFF
    beq blue_font_spdef
    bl default_font
    b copy_spdef

red_font_spdef:
    bl red_font
    b copy_spdef

blue_font_spdef:
    bl blue_font

copy_spdef:
    ldrb r0, [r3, r5]
    strb r0, [r1, r5]
    add r5, #1
    cmp r5, #3
    bne copy_spdef
    add r3, #3
    add r1, #3
    mov r5, #0

handle_spd:
    sub r2, #2
    ldrb r0, [r2]
    cmp r0, #1
    beq red_font_spd
    cmp r0, #0xFF
    beq blue_font_spd
    bl default_font
    b copy_spd

red_font_spd:
    bl red_font
    b copy_spd

blue_font_spd:
    bl blue_font

copy_spd:
    ldrb r0, [r3, r5]
    strb r0, [r1, r5]
    add r5, #1
    cmp r5, #3
    bne copy_spd
    b return

@@@ RIGHT STAT COLORING END @@@

@@@ FONT FUNCTIONS BEGIN @@@

blue_font: @FC 01 07
    mov r4, #7 @color of the lowered stat
    b font_common

red_font: @FC 01 05
    mov r4, #5 @color of the raised stat
    b font_common

default_font: @FC 01 01
    mov r4, #1 @color of the regular stats
    @ just fall through to font_common (no need to branch)

font_common:
    mov r0, #0xFC
    strb r0, [r1]
    add r1, #1
    mov r0, #1
    strb r0, [r1]
    add r1, #1
    strb r4, [r1]
    add r1, #1
    bx lr

@@@ FONT FUNCTIONS END @@@

return:
    ldr r0, displayed_string
    mov r1, sp
    ldr r2, special_f7_string_fct
    bl x_r2
    cmp r7, #0
    beq skip_mov_r0_r9
    mov r0, r9
skip_mov_r0_r9:
    add sp, sp, #0x20
    mov r2, r6
    pop {r5-r7}
x_r2:
    bx r2

.align 2
nature_stat_table: .word 0x0831E818
left_stats_string: .word 0x0861CE82
right_stats_string: .word 0x0861CE8E
displayed_string: .word 0x02021FC4
special_f7_string_fct: .word 0x081AFC29



Good job :). I was pretty lazy back then and just duplicated the font functions :D.

Seems you're quite proficient in ASM. Wonder if you use IDE?

MWisBest April 7th, 2017 7:04 AM

Quote:

Originally Posted by DizzyEgg (Post 9611696)
Good job :). I was pretty lazy back then and just duplicated the font functions :D.

Seems you're quite proficient in ASM. Wonder if you use IDE?

Thanks! Did you mean to ask if I use IDA? If so, yes. Been using it for years now, mainly with Android OS development (patching old closed-source libs to work on newer Android versions for example). This is my first time writing any substantial assembly though, just so happens that reading assembly the past few years translated well into writing it.

In a way, ARM assembly is really not that different from programming in high-level languages like C. I just look at all the opcodes like functions, registers are variables, etc. Just takes more steps to do a particular task.

I've also made use of the no$gba debugger, that's how I find tricks to save instructions, like r0 containing a return address and the usage of r9 to determine which code to run for the stat coloring merger.

Sorry, I tend to ramble on and talk a lot. :p

DizzyEgg April 7th, 2017 8:43 AM

Quote:

Originally Posted by MWisBest (Post 9611902)
Thanks! Did you mean to ask if I use IDA? If so, yes. Been using it for years now, mainly with Android OS development (patching old closed-source libs to work on newer Android versions for example). This is my first time writing any substantial assembly though, just so happens that reading assembly the past few years translated well into writing it.

In a way, ARM assembly is really not that different from programming in high-level languages like C. I just look at all the opcodes like functions, registers are variables, etc. Just takes more steps to do a particular task.

I've also made use of the no$gba debugger, that's how I find tricks to save instructions, like r0 containing a return address and the usage of r9 to determine which code to run for the stat coloring merger.

Sorry, I tend to ramble on and talk a lot. :p

Yeah I meant IDA, lol. I asked, because I've got an up-to-date Emerald IDB. I know Touched has one in its signature, but it has less stuff labeled. Here's the link: https://www.dropbox.com/s/mksltpeelzj1tmi/BPEE_updated2.idb?dl=0

And yeah I use no$gba debugger too, a pretty handy tool.

mbcn10ww April 17th, 2017 7:57 AM

Quote:

Originally Posted by MWisBest (Post 9604877)
Made another improvement to the reusable pokeballs: safari balls can now be reused as well!

Code:

.text
.align 2
.thumb

@ FE3AA - 00 21
@ 56818 - 00 48 00 47 XX+1 XX XX XX
@ 3F008 - 02 E0 C0 46 C0 46 C0 46 ! NEW
@ Optional: change initial safari ball count?: FC0E6 - XX 20, XX = initial count

main:
        @ if safari ball counter is not 0, then that's what we need to delete
        ldr r1, .safari_ball_count
        ldrb r0, [r1]
        cmp r0, #0x0
        bne delete_safari_ball

        @ ...otherwise, delete the last used item (if it's a pokeball)
        ldr r0, .last_used_item
        ldrh r0, [r0]
        @ checks that the item id is premier ball or lower
        cmp r0, #0xC
        bls delete_ball_in_bag
        @ support for custom pokeballs can be added like so:
        @ cmp r0, #CUSTOM_BALL_ID
        @ beq delete_ball_in_bag

        b finish

delete_safari_ball:
        @ r0 already contains current safari ball count, and
        @ r1 already contains safari ball count memory address
        sub r0, #1
        strb r0, [r1]
        b finish

delete_ball_in_bag:
        @ r0 already contains last_used_item.
        mov r1, #1
        ldr r2, .bag_remove_item
        bl x_r2
        b finish

finish:
        mov r9, r4
        mov r10, r5
        pop {r4-r7}
        pop {r2}
x_r2:
        bx r2

.align 2
.last_used_item:
        .word 0x0203CE7C
.bag_remove_item:
        .word 0x080D6AA4|1
.safari_ball_count:
        .word 0x0203A04C



Ported to Fire Red

Code:

.text
.align 2
.thumb

@ 0xA1E30 - 00 21
@ 0x2D924 - 00 48 00 47 XX+1 XX XX 08
@ 0x16AD8 - 02 E0 C0 46 C0 46 C0 46
@ Optional: change initial safari ball count?: 0xA0ED2 - XX 20, XX = initial count

main:
        @ if safari ball counter is not 0, then that's what we need to delete
        ldr r1, .safari_ball_count
        ldrb r0, [r1]
        cmp r0, #0x0
        bne delete_safari_ball

        @ ...otherwise, delete the last used item (if it's a pokeball)
        ldr r0, .last_used_item
        ldrh r0, [r0]
        @ checks that the item id is premier ball or lower
        cmp r0, #0xC
        bls delete_ball_in_bag
        @ support for custom pokeballs can be added like so:
        @ cmp r0, #CUSTOM_BALL_ID
        @ beq delete_ball_in_bag

        b finish

delete_safari_ball:
        @ r0 already contains current safari ball count, and
        @ r1 already contains safari ball count memory address
        sub r0, #1
        strb r0, [r1]
        b finish

delete_ball_in_bag:
        @ r0 already contains last_used_item.
        mov r1, #1
        ldr r2, .bag_remove_item
        bl x_r2
        b finish

x_r2:
        bx r2

finish:
        mov r9, r4
        mov r10, r5
        pop {r4-r7}
        pop {r0}
        bx r0

.align 2
.last_used_item:
        .word 0x0203AD30
.bag_remove_item:
        .word 0x0809A1D8|1
.safari_ball_count:
        .word 0x02039994



ASDBUDDY April 18th, 2017 8:47 AM

Quote:

Originally Posted by FBI (Post 8520099)
I think he wants to set a default name while skipping the intro. If you skip the intro via ASM, the default name is left as 0s aka blank.

Setting a static name to the player



Well, this is beyond simple, lol. I'll keep my post the same format though, because first post :3

How to insert:

Before you begin to insert the routine, there are a few steps. Firstly player names are limited to 8 characters with the eighth character = 0xFF.
Convert the static name you want from ascii to hex. For OP, he wanted Jesse and James which convert into:
C4 D9 E7 E7 D9 FF FF FF - Jesse
C4 D5 E1 D9 E7 FF FF FF -James
Note that if all eight bytes don't get used, you should pad them with "FF" in your hex editor.
Now insert the 8 byte names into some free space in your ROM via hex editor and write down the pointers.

Now copy the following routine into a text editor:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r2, lr}
        ldr r0, .Name
        ldr r0, [r0]
        add r1, r0, #0x1
        ldrb r1, [r1]
        cmp r1, #0x1 @girl
        beq Girl
        ldr r1, .CustomNameBoy
        ldr r2, [r1]
        add r1, r1, #0x4
        ldr r1, [r1]
        str r2, [r0]
        add r0, r0, #0x4
        str r1, [r0]
        pop {r0-r2, pc}

Girl:
        ldr r1, .CustomNameGirl
        ldr r2, [r1]
        add r1, r1, #0x4
        ldr r1, [r1]
        str r2, [r0]
        add r0, r0, #0x4
        str r1, [r0]
        pop {r0-r2, pc}

.align 2
.Name:
        .word 0x300500C

.CustomNameBoy:
        .word [email protected] to boy name

.CustomNameGirl:
        .word [email protected] to girl name




You'll notice that I have the lines:
Code:

.CustomNameBoy:
        .word [email protected] to boy name

.CustomNameGirl:
        .word [email protected] to girl name


Change the [email protected] text to 0x[offset you inserted]. No need to add one.
After you've done that compile and insert into free space.

Usage:
You must callasm to the routine, and depending on the Player's gender it will set their name. To have their name inserted before the player starts playing the game, create a level script which calls this routine. If you don't know how, ask in a relevant thread (not here).

Hi, well I did exactly what you said but now my gba file just shows a blank screen when loaded into the emulator. What should I do?

easyaspi314 April 19th, 2017 7:02 AM

Hey, IDK if it is possible, but could it be made so the battle text auto-advances when in battle (like Gen 4)?

So, instead of being required to press A during certain parts (example: challenge, faint, disable, level up, etc), after 1 second, the next line will load. But you can interrupt it with A as well

I can make it automatically skip by editing the hex, but it does it immediately.

linobigatti April 20th, 2017 5:13 AM

i can manipulate the mistery gifts in FR? how?

DarkPsychic April 20th, 2017 11:47 PM

Quote:

Originally Posted by FBI (Post 8517719)

Pokemon Storage (outside the PC)



Basically, in it's current state, this is effectively a storage system. It stores Pokemon and can be interacted with by the player to withdraw or deposit Pokemon. It's standalone from the PC storage system and is also much smaller (I've limited it to 6, but it can go upto 47). Some things that you will be able to do with this routine (and conjunction with some smaller ones) include:
- Extra Pokemon storage, you can possibly get a little over 1 box worth
- Flash back battles (complete swap between stored Pokemon and party Pokemon with capabilities to swap back)
- Carry a party of greater than 6 Pokemon (you can use the 2nd party for HM slaves, or whatever)
- Trade evolver guy! He will take your Pokemon and then when you come back it can be evolved! (silent evolution ftw!)
- Separate Daycare holding larger amount of Pokemon at once

I've tested it thoroughly and there doesn't seem to be any problems. I will be adding more and more features into this because I believe that it has the potential to become a very useful feature.
Currently planning to add:
- Party swap completely all in one go (this will actually be in the very near future..maybe today even :P)
- Partial swapping (believe it or not, this is hard because there's no graphical support)
- Suggest me more :D

How to insert:

Compile into free space the following routine:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
    push {r0, r4, lr}
    ldr r0, .FROM
    ldr r1, [r0]
    cmp r1, #0x0 @party
    beq addParty

addStorage:
    ldr r0, .STORAGE
    sub r0, r0, #0x1
    ldrb r1, [r0]
    cmp r1, #0x6 @limit of storage. Change depending on your space situation
    beq end
    add r0, r0, #0x1
    mov r2, #0x50
    cmp r1, #0x0
    beq skipline
    sub r1, r1, #0x1
    mul r1, r1, r2
    add r0, r0, r1 @destination
    ldr r1, =(0x20370C0)
    ldrb r1, [r1]
    ldr r2, .PARTY
    mov r3, #0x64
    mul r1, r1, r3
    add r1, r1, r2 @source
    mov r2, #0x50 @size
    ldr r3, =(0x8040B08 +1) @func
    bl linker
    @need to fix up Player's party slots
    ldr r1, =(0x20370C0)
    ldrb r1, [r1]
    cmp r1, #0x5
    beq writeLastZero
    mov r2, #0x5
    sub r2, r2, r1
    mov r3, #0x64
    mul r2, r2, r3 @size
    ldr r0, .PARTY
    mul r1, r1, r3
    add r0, r0, r1 @dest
    add r3, r3, r0
    mov r1, r3      @src
    ldr r3, =(0x8040B08 +1) @func
    bl linker

writeLastZero:
    ldr r0, =(0x2024478)
    mov r1, #0x0
    mov r2, #0x64
    ldr r3, =(0x81E5ED8 +1)
    bl linker

correctCounters:
    ldr r0, .STORAGE
    sub r0, r0, #0x1
    ldrb r2, [r0]  @pks in storage counter
    ldr r1, =(0x2024029)
    ldrb r3, [r1] @pks in party
    add r2, r2, #0x1
    strb r2, [r0]
    sub r3, r3, #0x1
    strb r3, [r1]
    b end

addParty:
    ldr r0, =(0x2024029)
    ldrb r0, [r0]
    cmp r0, #0x6
    beq end
    ldr r1, .PARTY
    mov r2, #0x64
    mul r0, r0, r2
    add r0, r0, r1 @destination
    mov r4, r0
    ldr r3, .STORAGE
    ldr r1, =(0x20370C0) @var 0x8004 determines which slot of storage to take from
    ldrb r1, [r1]
    mov r2, #0x50 @size
    mul r1, r1, r2
    add r1, r1, r3 @source
    ldr r3, =(0x8040B08 +1) @func
    bl linker
    @update stats
    mov r0, r4
    ldr r3, =(0x803E47C +1)
    bl linker
    @adjust the storage
    ldr r0, =(0x20370C0)
    ldrb r0, [r0]
    cmp r0, #0x5 @storage limit minus 1
    beq writeZero
    mov r2, #0x5
    sub r2, r2, r0
    mov r3, #0x50
    mul r2, r2, r3 @size
    ldr r1, .STORAGE
    mul r0, r0, r3
    add r0, r0, r1 @dest
    add r3, r3, r0
    mov r1, r3      @src
    ldr r3, =(0x8040B08 +1) @func
    bl linker

writeZero:
    ldr r0, .STORAGE
    mov r1, #0xC8
    lsl r1, r1, #0x1
    add r0, r0, r1
    mov r1, #0x0
    mov r2, #0x50
    ldr r3, =(0x81E5ED8 +1)
    bl linker

updateCounters:
    ldr r0, .STORAGE
    sub r0, r0, #0x1
    ldrb r2, [r0]
    ldr r1, =(0x2024029)
    ldrb r3, [r1]
    sub r2, r2, #0x1
    strb r2, [r0]
    add r3, r3, #0x1
    strb r3, [r1]

end:
    pop {r0-r4, pc}   

linker:
    bx r3   

.align 2

.FROM:
    .word 0x20270B8 + (0x8000 *2)

.STORAGE:
    .word 0x203C001 @storage location

.PARTY:
    .word 0x2024284 @player's party




Here's a compiled version:
Code:

11 B5 38 48 01 68 00 29 32 D0 37 48 01 38 01 78 06 29 65 D0 01 30 50 22 51 43 40 18 34 49 09 78 32 4A 64 23 59 43 89 18 50 22 32 4B 00 F0 59 F8 2F 49 09 78 05 29 0B D0 05 22 52 1A 64 23 5A 43 2A 48 59 43 40 18 1B 18 19 1C 2A 4B 00 F0 49 F8 29 48 00 21 64 22 29 4B 00 F0 43 F8 22 48 01 38 02 78 27 49 0B 78 01 32 02 70 01 3B 0B 70 37 E0 23 48 00 78 06 28 33 D0 1C 49 64 22 50 43 40 18 04 1C 19 4B 1A 49 09 78 50 22 51 43 C9 18 19 4B 00 F0 27 F8 20 1C 1B 4B 00 F0 23 F8 14 48 00 78 05 28 0B D0 05 22 12 1A 50 23 5A 43 0E 49 58 43 40 18 1B 18 19 1C 0F 4B 00 F0 13 F8 0A 48 C8 21 49 00 40 18 00 21 50 22 0C 4B 00 F0 0A F8 06 48 01 38 02 78 0A 49 0B 78 01 3A 02 70 01 33 0B 70 1F BD 18 47 B8 70 03 02 01 C0 03 02 84 42 02 02 C0 70 03 02 09 0B 04 08 78 44 02 02 D9 5E 1E 08 29 40 02 02 7D E4 03 08


Usage:

The routine itself manages party storage and storage extraction. What you need to do is determine which one it performs.
If you want to remove a Pokemon from the party and into storage, setvar 0x8000 anything but zero
if you want to remove a Pokemon from storage, setvar 0x8000 0x0
Which variable you used can be changed, as always, by editing the pointer at the bottom of the routine.
The next thing is variable 0x8004. I use this variable to determine the slot of extraction for both the Party and the Storage system.
If I wanted to take the 3rd Pokemon in the party and put it in storage:
setvar 0x8004 0x2
setvar 0x8000 0x1
callasm 0x[routine] +1

The reason for this is to support easy use of special 0x9F. Though you can use copyvar, I suppose.

Finally, the routine writes to RAM a counter, which keeps track of how many Pokemon are in the storage.
This is written at 0x203C000, and can be retrieved by using the "copybyte" scripting command. For example:
copybyte 0x20370D0 0x203C000 'puts the storage counter into variable 0x800D (lastresult).

I tried to keep it simple, and do the work inside the routine, hopefully that paid off.
Here's a very poor sample script. Poor because it handles all the cases, but it doesn't display the system's full potential :P

Spoiler:

PKSV script.
Code:

#dyn 0x740000
#org @start
lock
faceplayer
copybyte 0x20370D0 0x203C000 ' storage count into last result
compare LASTRESULT 0x0
if == jump @putOnly
msgbox @add
callstd MSG_YESNO 'want to take?
compare LASTRESULT 0x1
if == jump @addParty
jump @putOnly

#org @putOnly
countpokemon
copyvar 0x8000 0x800D
compare 0x8000 0x1
if <= jump @greetings
msgbox @put
callstd MSG_YESNO 'want to put?
compare LASTRESULT 0x1
if == jump @addStorage
msgbox @exit
callstd MSG_NORMAL
release
end

#org @addStorage
setvar 0x8000 0x1
special 0x9F
waitspecial
countpokemon
compare LASTRESULT 0x8004
if < jump @noSelection
callasm 0x[routine +1]
msgbox @gave
callstd MSG_NORMAL
release
end

#org @addParty
setvar 0x8000 0x0
countpokemon
compare LASTRESULT 0x6
if == jump @fullP
msgbox @store
callstd MSG_NORMAL
setvar 0x8004 0x0 'gotta rework this to work a better way
callasm 0x[routine +1]
fanfare 0x101
msgbox @complete
callstd MSG_NORMAL
release
end

#org @greetings
msgbox @hello
callstd MSG_NORMAL
release
end

#org @fullP
msgbox @full
callstd MSG_NORMAL
release
end

#org @noSelection
msgbox @exit
callstd MSG_NORMAL
release
end

#org @full
= You're party is full!

#org @hello
= Hi, I can't do anything\nyour slots are full or empty\lor mine are full while yours are\lfull[.]

#org @complete
= I gave it back.

#org @store
= Alright, I'll give it to you.

#org @gave
= Thanks for giving me this.

#org @exit
= Alright, next time then.

#org @add
= Want your Pokemon back?

#org @put
= Want to give me a pokemon?




That's it for now. Keep an eye out for "addons" for this routine in the future :)
Sorry for the double post. I like seperate posts for my routines to keep the first post's links neat :x


So for anyone who has used this they know that only the Pre-Compiled version works, and the routine given does not compile to match either and don't work at all for that matter.

Also the Pre-Compiled version does work but has a bug from using Special 0x9F(Choose Pokemon from party).
If the player says yes to storing a Pokemon then decides to either press "B" or "Cancel" then the game will jump to the overworld view, glitch out and freeze with a Black screen.

Now I worked on this all day and was able to rebuild the Pre-Compiled routine so we could actually have the working source.
FBI's - Pre-Compiled Storage System - Disassembled/Rebuilt Routine
Code:
Code:

.text
.align 2
.thumb
.thumb_func

main:
push {r0, r4, lr}
    ldr r0, .FROM
    ldr r1,[r0]
    cmp r1, #0x0              @party
    beq addParty

addStorage:
    ldr r0, .STORAGE
    sub r0, #0x1
    ldrb r1, [r0]
    cmp r1, #0x6              @limit of storage. Change depending on your space situation
    beq end
    add r0, #0x1
    mov r2, #0x50
    mul r1, r2
    add r0, r0, r1            @destination
    ldr r1, =(0x20370C0)      @ 2b Var_8004
    ldrb r1, [r1]
    ldr r2, .PARTY
    mov r3, #0x64
    mul r1, r3
    add r1, r1, r2            @source
    mov r2, #0x50              @size
    ldr r3, =(0x8040B09)      @memcpy_pkm 'void __fastcall memcpy_pkm(void *dst, void *src, unsigned int size)'
    bl linker
    ldr r1, =(0x20370C0)      @need to fix up Player's party slots @ 2b Var_8004
    ldrb r1, [r1]
    cmp r1, #0x5
    beq writeLastZero
    mov r2, #0x5
    sub r2, r2, r1
    mov r3, #0x64
    mul r2, r3                @size
    ldr r0, .PARTY
    mul r1, r3
    add r0, r0, r1            @dest
    add r3, r3, r0
    mov r1, r3                @src
    ldr r3, =(0x8040B09)      @memcpy_pkm 'void __fastcall memcpy_pkm(void *dst, void *src, unsigned int size)'
    bl linker

writeLastZero:
    ldr r0, =(0x2024478)      @ 100b    Party Pokemon 6
    mov r1, #0x0
    mov r2, #0x64
    ldr r3, =(0x81E5ED9)      @memset  'void __fastcall memset(char *dst, char pattern, int size)'
    bl linker

correctCounters:
    ldr r0, .STORAGE
    sub r0, #0x1
    ldrb r2, [r0]              @pks in storage counter
    ldr r1, =(0x2024029)      @ 1b    Repeattrainerbattle: Unknown. Loaded if battle type is 9.
    ldrb r3, [r1]              @pks in party
    add r2, #0x1
    strb r2,[r0]
    sub r3, #0x1
    strb r3, [r1]
    b end

addParty:
    ldr r0, =(0x2024029)      @ 1b    Repeattrainerbattle: Unknown. Loaded if battle type is 9.
    ldrb r0, [r0]
    cmp r0, #0x6
    beq end
    ldr r1, .PARTY
    mov r2, #0x64
    mul r0, r2
    add r0, r0, r1            @destination
    mov r4, r0
    ldr r3, .STORAGE
    ldr r1, =(0x20370C0)      @'var 0x8004 determines which slot of storage to take from'
    ldrb r1, [r1]
    mov r2, #0x50              @size
    mul r1, r2
    add r1, r1, r3            @source
    ldr r3, =(0x8040B09)      @memcpy_pkm 'void __fastcall memcpy_pkm(void *dst, void *src, unsigned int size)'
    bl linker
    mov r0, r4                @update stats
    ldr r3, =(0x803E47D)      @pokemon_calc_effective_stats
    bl linker
    ldr r0, =(0x20370C0)      @adjust the storage  @ 2b Var_8004
    ldrb r0, [r0]
    cmp r0, #0x5              @storage limit minus 1
    beq writeZero
    mov r2, #0x5
    sub r2, r2, r0
    mov r3, #0x50
    mul r2, r3                @size
    ldr r1, .STORAGE
    mul r0, r3
    add r0, r0, r1            @dest
    add r3, r3, r0
    mov r1, r3                @src
    ldr r3, =(0x8040B09)      @memcpy_pkm 'void __fastcall memcpy_pkm(void *dst, void *src, unsigned int size)'
    bl linker

writeZero:
    ldr r0, .STORAGE
    mov r1, #0xC8
    lsl r1, r1, #0x1
    add r0, r0, r1
    mov r1, #0x0
    mov r2, #0x50
    ldr r3, =(0x81E5ED9)      @memset  'void __fastcall memset(char *dst, char pattern, int size)'
    bl linker

updateCounters:
    ldr r0, .STORAGE
    sub r0, #0x1
    ldrb r2, [r0]
    ldr r1, =(0x2024029)      @ 1b    Repeattrainerbattle: Unknown. Loaded if battle type is 9.
    ldrb r3, [r1]
    sub r2, #0x1
    strb r2,[r0]
    add r3, #0x1
    strb r3, [r1]

end:
    pop {r0-r4, pc}

linker:
    bx r3

.align 2

.FROM:
    .word 0x20370B8            @var_8000

.STORAGE:
    .word 0x203C001            @storage location

.PARTY:
    .word 0x2024284            @player's party


And to go along with that is the XSE script.
Code:
Code:

#dynamic 0xFreeSpaceToStartFrom

//---------------
#org @start
lock
faceplayer
copybyte 0x20370D0 0x203C000
compare 0x800D 0x0
if 0x1 goto @snippet1
msgbox @string1 0x5 //"Want your Pokemon back?"
compare 0x800D 0x1
if 0x1 goto @snippet2
goto @snippet1

//---------------
#org @snippet1
countpokemon
copyvar 0x8000 0x800D
compare 0x8000 0x1
if 0x3 goto @snippet3
msgbox @string2 0x5 //"Want to give me a pokemon?"
compare 0x800D 0x1
if 0x1 goto @snippet4
msgbox @string3 0x6 //"Alright, next time then."
release
end

//---------------
#org @snippet2
setvar 0x8000 0x0
countpokemon
compare 0x800D 0x6
if 0x1 goto @snippet5
msgbox @string4 0x6 //"Alright, I'll give it to you."
setvar 0x8004 0x0
callasm 0xWhereYouPutYourTheRoutine+1
fanfare 0x101
msgbox @string5 0x6 //"I gave it back."
release
end

//---------------
#org @snippet3
msgbox @string6 0x6 //"Hi, I can't do anything\nyour slot..."
release
end

//---------------
#org @snippet4
setvar 0x8000 0x1
special 0x9F
waitstate
lockall
compare 0x8004 0x7
if 0x1 goto @snippet6
countpokemon
compare 0x800D 0x1
if 0x3 goto @snippet6
callasm 0xWhereYouPutYourTheRoutine+1
msgbox @string7 0x6 //"Thanks for giving me this."
release
end

//---------------
#org @snippet5
msgbox @string8 0x6 //"You're party is full!"
release
end

//---------------
#org @snippet6
msgbox @string3 0x6 //"Alright, next time then."
release
end

//---------
// Strings
//---------
#org @string1
= Want your Pokemon back?

#org @string2
= Want to give me a pokemon?

#org @string3
= Alright, next time then.

#org @string4
= Alright, I'll give it to you.

#org @string5
= I gave it back.

#org @string6
= Hi, I can't do anything\nyour slots are full or empty\lor mine are full while yours are\lfull[.]

#org @string7
= Thanks for giving me this.

#org @string8
= You're party is full!


Edit the orange text before compiling.


Hope this helps anyone.
When I get the time I will see what I can do about fixing the bug as well.


Edit_Two:
Found the bug!
Special 0x9F lets you choose any Pokemon as well as Eggs.
And,
Special 0xBC lets you choose any Pokemon beside Eggs(used for daycare)
When pressing B var 0x8004 is set to 0x07 so I simply added a compare to fix the script.

mbcn10ww April 24th, 2017 12:15 PM

Quote:

Originally Posted by FBI (Post 8520099)
I think he wants to set a default name while skipping the intro. If you skip the intro via ASM, the default name is left as 0s aka blank.

Setting a static name to the player



Well, this is beyond simple, lol. I'll keep my post the same format though, because first post :3

How to insert:

Before you begin to insert the routine, there are a few steps. Firstly player names are limited to 8 characters with the eighth character = 0xFF.
Convert the static name you want from ascii to hex. For OP, he wanted Jesse and James which convert into:
C4 D9 E7 E7 D9 FF FF FF - Jesse
C4 D5 E1 D9 E7 FF FF FF -James
Note that if all eight bytes don't get used, you should pad them with "FF" in your hex editor.
Now insert the 8 byte names into some free space in your ROM via hex editor and write down the pointers.

Now copy the following routine into a text editor:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r2, lr}
        ldr r0, .Name
        ldr r0, [r0]
        add r1, r0, #0x1
        ldrb r1, [r1]
        cmp r1, #0x1 @girl
        beq Girl
        ldr r1, .CustomNameBoy
        ldr r2, [r1]
        add r1, r1, #0x4
        ldr r1, [r1]
        str r2, [r0]
        add r0, r0, #0x4
        str r1, [r0]
        pop {r0-r2, pc}

Girl:
        ldr r1, .CustomNameGirl
        ldr r2, [r1]
        add r1, r1, #0x4
        ldr r1, [r1]
        str r2, [r0]
        add r0, r0, #0x4
        str r1, [r0]
        pop {r0-r2, pc}

.align 2
.Name:
        .word 0x300500C

.CustomNameBoy:
        .word [email protected] to boy name

.CustomNameGirl:
        .word [email protected] to girl name




You'll notice that I have the lines:
Code:

.CustomNameBoy:
        .word [email protected] to boy name

.CustomNameGirl:
        .word [email protected] to girl name


Change the [email protected] text to 0x[offset you inserted]. No need to add one.
After you've done that compile and insert into free space.

Usage:
You must callasm to the routine, and depending on the Player's gender it will set their name. To have their name inserted before the player starts playing the game, create a level script which calls this routine. If you don't know how, ask in a relevant thread (not here).

It works, but the female player name becomes the same as the male.

Wesley FG April 25th, 2017 3:38 PM

Quote:

Originally Posted by DoesntKnowHowToPlay (Post 9043968)
I've noticed significant demand for working Dawn Stone evolutions, specifically ones that require the mon to be a specific gender. My bad if this is already posted somewhere but here y'all go:

Code:

.org 0x4318e
lsl r0, r0, #0x0
ldr r2, .MethodAddr
bx r2

.MethodAddr: .word 0x085B2521 #UPDATE THIS TO MAIN FUNCTION OFFSET+1

.org 0x5B2520 #UPDATE THIS TO MOST CONVENIENT FREE SPACE IN YOUR HACK
cmp r0, #0x7
beq StandardStone
cmp r0, #0x14 #UPDATE THIS
beq MaleStone
cmp r0, #0x15 #UPDATE THIS
beq FemaleStone
b NoEvo

MaleStone:
push {r1-r3}
mov r0, r7
mov r1, r8
ldr r1, [r1, #0x0]
bl DetermineGender
pop {r1-r3}
cmp r0, #0x0
beq StandardStone
b NoEvo

FemaleStone:
push {r1-r3}
mov r0, r7
mov r1, r8
ldr r1, [r1, #0x0]
bl DetermineGender
pop {r1-r3}
cmp r0, #0xFE
beq StandardStone
b NoEvo

StandardStone:
ldrh r0, [r1, #0x2]
cmp r0, r9
beq Finish

NoEvo:
ldr r2, .NoEvoReturn
bx r2

DetermineGender:
ldr r2, .DetermineGenderFunc
bx r2

Finish:
ldr r2, .EvoReturn
bx r2

.NoEvoReturn: .word 0x08043199
.EvoReturn: .word 0x0804317d
.DetermineGenderFunc: .word 0x0803f78d


Change the values in the lines marked UPDATE THIS to the indexes of male stone evos and female stone evos. Leave their entries blank in the general evolution table; stone evolutions function differently from level-up evolutions.

the value of "indexes of male stone" is the item value ?

will have two dawn stone, one work in male and one work in female, it is correct ?

i not understand it well


All times are GMT -8. The time now is 8:46 AM.


Like our Facebook Page Follow us on Twitter © 2002 - 2018 The PokéCommunity™, pokecommunity.com.
Pokémon characters and images belong to The Pokémon Company International and Nintendo. This website is in no way affiliated with or endorsed by Nintendo, Creatures, GAMEFREAK, The Pokémon Company or The Pokémon Company International. We just love Pokémon.
All forum styles, their images (unless noted otherwise) and site designs are © 2002 - 2016 The PokéCommunity / PokéCommunity.com.
PokéCommunity™ is a trademark of The PokéCommunity. All rights reserved. Sponsor advertisements do not imply our endorsement of that product or service. User generated content remains the property of its creator.

Acknowledgements
Use of PokéCommunity Assets
vB Optimise by DragonByte Technologies Ltd © 2023.