The PokéCommunity Forums  

Go Back   The PokéCommunity Forums > Fan Games > Binary ROM Hacking > Binary Hack Research & Development
Reload this Page Code ASM Resource Thread

Notices
For all updates, view the main page.

Binary Hack Research & Development Got a well-founded knack with your binary Pokémon hacks? Love reverse-engineering them? For the traditional Pokémon ROM hacker, this is the spot for polling and gathering your ideas, and then implementing them! Share your hypothesis, get ideas from others, and collaborate to create!

Ad Content
Reply
 
Thread Tools
  #1226   Link to this post, but load the entire thread.  
Old July 27th, 2017 (8:19 AM).
Lunos's Avatar
Lunos Lunos is offline
Random Uruguayan User
 
Join Date: Oct 2008
Location: Montevideo (Uruguay)
Gender: Male
Nature: Lonely
Posts: 3,000
Quote:
Originally Posted by Sakib66 View Post
use TL's quick enhancer tool
The_Learner removed the DL Link until the next update because its modifications were messing some people's ROMs.

Quote:
Originally Posted by kleenexfeu View Post
I know there's several routines like this one, but I didn't found them practical.

Check a specific pokémon with a specific slot through the use of Special 0xA2, for Emerald :
Spoiler:

Code:
.thumb

Start:
    push {r0-r7, lr}
    ldr r6, var8005
    ldr r0, party_amount
    ldrb r4, [r0]
    cmp r4, #0x0
    beq End
    ldrh r3, [r6]
    cmp r3, #0x0
    beq End
Check:
    add r0, #3
    mov r1, #0x64
    ldr r7, var8004
    ldrb r6, [r7]
    mul r1, r6
    add r0, r0, r1
    push {r0-r7}
    mov r1, #0xB
    ldr r2, decrypt_poke
    bl Jump
    mov r9, r0
    pop {r0-r7}
    cmp r9, r3
    bne NoSuccess
    mov r6, #1
    b Success
NoSuccess:
    mov r6, #0
Success:
    ldr r7, var8005
    strh r6, [r7]

End:
    pop {r0-r7, pc}
Jump:
mov pc, r2
    
.align 2
party_amount:    .word 0x020244E9
var8004:        .word 0x020275D8 + (0x8004*2)
var8005:        .word 0x020275D8 + (0x8005*2)
decrypt_poke:    .word 0x0806A519

/*var 0x8005, species you want to check*/
Basically, when you use special 0xA2, the party screen open and you can select a poke, the slot of the poke is stored in var 0x8004, so the routine check this slot.
If it is the the same species than 0x8005, then 0x8005 is set to 1, otherwise to 0
The routine has apparently some flaws.
They were fixed by @Squeetz in the community's Discord.
I don't know a single thing about ASM, but I thought someone needed to bring this up in case anyone wanted to use it.
Code:
.thumb

Start:
    push {r0-r7, lr}
    ldr r6, var8005
    ldr r0, party_amount
    ldrb r4, [r0]
    cmp r4, #0x0
    beq End
    ldrh r3, [r6]
    cmp r3, #0x0
    beq End
Check:
    ldr r0, party_player
    mov r1, #0x64
    ldr r7, var8004
    ldrb r6, [r7]
    mul r1, r6
    add r0, r0, r1
    push {r0-r7}
    mov r1, #0xB
    ldr r2, decrypt_poke
    bl Jump
    mov r9, r0
    pop {r0-r7}
    cmp r9, r3
    bne NoSuccess
    mov r6, #1
    b Success
NoSuccess:
    mov r6, #0
Success:
    ldr r7, var8005
    strh r6, [r7]

End:
    pop {r0-r7, pc}
Jump:
mov pc, r2
    
.align 2
party_amount:    .word 0x020244E9
var8004:        .word 0x020275D8 + (0x8004*2)
var8005:        .word 0x020275D8 + (0x8005*2)
decrypt_poke:    .word 0x0806A519
party_player:  .word 0x020244EC

/*var 0x8005, species you want to check*/
__________________
Reply With Quote
  #1227   Link to this post, but load the entire thread.  
Old July 27th, 2017 (8:22 AM).
ghoulslash's Avatar
ghoulslash ghoulslash is offline
 
Join Date: Mar 2016
Gender: Male
Posts: 238
Quote:
Originally Posted by Gameskiller01 View Post
Sorry for being dumb, but how do I actually implement this into the game?
I would suggest learning how to compile and insert assembly instead of relying on tools.

1. First, you'll want to download HackMew's thumb compiler, found on this page.

2. Then, save the files you quoted individually as [filename].asm, eg. attack.asm. Using the windows command prompt, type 'thumb [filename].asm [filename].bin' in the same directory as your .asm file and the compiler. Then, open the .bin file with a hex editor, and insert into free space, making sure the offset ends in a 0,4,8, or C. With these particular routines, you'll need to also insert [00 01 0A 00] for red font and [00 07 0A 00] for blue font, somewhere in your rom, and then change the pointer at the bottom of each routine to the location of each 4bytes string. So, if you inserted 00 07 0A 00 at 0x123456, 0x08BBBBBB would become 0x08123456.

3. At the top of each assembly routine you're trying to insert, there is an insertion instruction that has been commented out, eg. @ 00 49 08 47 XX XX XX XX at x137134 in the attack.asm routine. This means, at offset 0x137134 you type the above hex, where XX XX XX XX is a reverse pointer (+1) to the location of the attack.bin hex you inserted into free space from step 2. For example, if you inserted attack.bin at 0x987654, for example, XX XX XX XX will be 55 76 98 08.

Do this for each routine and you should be all set!

I hope this helps. let me know if you have any issues.
Reply With Quote
  #1228   Link to this post, but load the entire thread.  
Old July 29th, 2017 (3:01 AM). Edited July 29th, 2017 by Foxes.
Foxes's Avatar
Foxes Foxes is offline
 
Join Date: Sep 2015
Gender: Male
Posts: 59
Quote:
Originally Posted by ghoulslash View Post
I would suggest learning how to compile and insert assembly instead of relying on tools.

1. First, you'll want to download HackMew's thumb compiler, found on this page.

2. Then, save the files you quoted individually as [filename].asm, eg. attack.asm. Using the windows command prompt, type 'thumb [filename].asm [filename].bin' in the same directory as your .asm file and the compiler. Then, open the .bin file with a hex editor, and insert into free space, making sure the offset ends in a 0,4,8, or C. With these particular routines, you'll need to also insert [00 01 0A 00] for red font and [00 07 0A 00] for blue font, somewhere in your rom, and then change the pointer at the bottom of each routine to the location of each 4bytes string. So, if you inserted 00 07 0A 00 at 0x123456, 0x08BBBBBB would become 0x08123456.

3. At the top of each assembly routine you're trying to insert, there is an insertion instruction that has been commented out, eg. @ 00 49 08 47 XX XX XX XX at x137134 in the attack.asm routine. This means, at offset 0x137134 you type the above hex, where XX XX XX XX is a reverse pointer (+1) to the location of the attack.bin hex you inserted into free space from step 2. For example, if you inserted attack.bin at 0x987654, for example, XX XX XX XX will be 55 76 98 08.

Do this for each routine and you should be all set!

I hope this helps. let me know if you have any issues.
Thank you! This kind of simple, easy to follow tutorial on how to insert ASM is exactly what I've been looking for! I'll try it now and see if it works.

EDIT: So when I try that, I get this error.
Quote:
attack.asm: Assembler messages:
attack.asm:0: Warning: end of file in comment; newline inserted
attack.asm:60: Error: junk at end of line, first unrecognized character is `R'
EDIT #2: nvm, I figured out that I had to insert the redfont and bluefont and change the .asm file to show where they are.

EDIT #3: So, if I put the hex for attack.bin at 0x71A6B0, XX XX XX XX would be B1 A6 71 08?

EDIT #4: It works! Thanks! Yours is the only tutorial for inserting ASM that I could actually follow and understand.
Reply With Quote
  #1229   Link to this post, but load the entire thread.  
Old July 29th, 2017 (11:25 AM).
tkim's Avatar
tkim tkim is offline
 
Join Date: May 2011
Posts: 232
Request for FR:

Volt Tackle by breeding with either parent holding a Light Ball.
Reply With Quote
  #1230   Link to this post, but load the entire thread.  
Old July 30th, 2017 (5:07 AM).
Foxes's Avatar
Foxes Foxes is offline
 
Join Date: Sep 2015
Gender: Male
Posts: 59
Request for Platinum:

Having coloured stats based on natures. I don't know if this could be done by editing the ASM used to implement this into FireRed and changing the offsets or if they are just too different.

Either way, I think more work needs to be done on hacking 4th gen games, and I'd be happy to help (although I am very dumb). I'm currently looking into editing the hex of the 4th gen games but there doesn't seem to be any documentation on ASM for 4th gen and very little documentation on hex for 4th gen. If someone smarter than me can give me a good starting point as to where I could learn how to find out how to do this (if that makes any sense) I would be more than willing to learn.
Reply With Quote
  #1231   Link to this post, but load the entire thread.  
Old July 30th, 2017 (5:40 AM).
Lunos's Avatar
Lunos Lunos is offline
Random Uruguayan User
 
Join Date: Oct 2008
Location: Montevideo (Uruguay)
Gender: Male
Nature: Lonely
Posts: 3,000
Quote:
Originally Posted by esperance View Post
This thread is for the development of new assembly routines and hacks based off of the requests of users. Feel free to make requests.
With that being said, would a Custom Wildbattle like this one, but that also allows you to choose the Battle Background be possible for FireRed?
__________________
Reply With Quote
  #1232   Link to this post, but load the entire thread.  
Old August 1st, 2017 (12:09 AM).
ShyGuy25 ShyGuy25 is offline
 
Join Date: Jun 2012
Gender: Male
Posts: 22
Dumb question but what program is used to compile the ASM routines?
Reply With Quote
  #1233   Link to this post, but load the entire thread.  
Old August 1st, 2017 (1:46 AM).
Foxes's Avatar
Foxes Foxes is offline
 
Join Date: Sep 2015
Gender: Male
Posts: 59
Quote:
Originally Posted by ShyGuy25 View Post
Dumb question but what program is used to compile the ASM routines?
This easy to follow tutorial is what I used to be able to do it (with extremely little prior knowledge on the subject).

Quote:
Originally Posted by ghoulslash View Post
I would suggest learning how to compile and insert assembly instead of relying on tools.

1. First, you'll want to download HackMew's thumb compiler, found on this page.

2. Then, save the files you quoted individually as [filename].asm, eg. attack.asm. Using the windows command prompt, type 'thumb [filename].asm [filename].bin' in the same directory as your .asm file and the compiler. Then, open the .bin file with a hex editor, and insert into free space, making sure the offset ends in a 0,4,8, or C. With these particular routines, you'll need to also insert [00 01 0A 00] for red font and [00 07 0A 00] for blue font, somewhere in your rom, and then change the pointer at the bottom of each routine to the location of each 4bytes string. So, if you inserted 00 07 0A 00 at 0x123456, 0x08BBBBBB would become 0x08123456.

3. At the top of each assembly routine you're trying to insert, there is an insertion instruction that has been commented out, eg. @ 00 49 08 47 XX XX XX XX at x137134 in the attack.asm routine. This means, at offset 0x137134 you type the above hex, where XX XX XX XX is a reverse pointer (+1) to the location of the attack.bin hex you inserted into free space from step 2. For example, if you inserted attack.bin at 0x987654, for example, XX XX XX XX will be 55 76 98 08.

Do this for each routine and you should be all set!

I hope this helps. let me know if you have any issues.
If you run into any problems, just look at the edits I made to my response to that message. It's probable that you may come across the same problems as I did.

Quote:
Originally Posted by Gameskiller01 View Post
EDIT: So when I try that, I get this error.
Quote:
attack.asm: Assembler messages:
attack.asm:0: Warning: end of file in comment; newline inserted
attack.asm:60: Error: junk at end of line, first unrecognized character is `R'
EDIT #2: nvm, I figured out that I had to insert the redfont and bluefont and change the .asm file to show where they are.

EDIT #3: So, if I put the hex for attack.bin at 0x71A6B0, XX XX XX XX would be B1 A6 71 08?

EDIT #4: It works! Thanks! Yours is the only tutorial for inserting ASM that I could actually follow and understand.
Reply With Quote
  #1234   Link to this post, but load the entire thread.  
Old August 3rd, 2017 (5:07 PM). Edited August 4th, 2017 by tkim.
tkim's Avatar
tkim tkim is offline
 
Join Date: May 2011
Posts: 232
[FR] Volt Tackle port from EM:

If you have free space from 0x270670-0x270741 (0xD2 bytes), use the IPS patch I provide here. ...It's a long story, so I will expand on this when I get the time. Fully working, I promise. You're gonna love it.

edit: A bit of explanation now: I took a look at an Emerald disassembly and found the routine that calls to check if the egg at the Day-Care is a pichu and if either of the parents are holding a Light Ball. I ported that exact routine into FR, but I had to make a copy of the routine at sub_80460D4 as to include the pichu check. Then I had to make special 0xB8 call the new routine instead of sub_80460D4. Since I had made a copy of the routine I also had to make sure the new routine used all the same offsets as before, and therefore I placed the routine at 0x270670, which I happened to have free space. I wanted to place the routine at something like 0x760000 or higher, but the old offsets wouldn't work any more. Down below are the uncompiled stuff:

This routine (located at 0x270670 in my patch) is a copy of the routine at 0x0460D4 but now includes the pichu egg check (in orange):
Code:
sub_80460D4:                @ CODE XREF: sp0B8_daycare+Cp

var_18        = -0x18
var_14        = -0x14

        PUSH    {R4-R6,LR}
        SUB    SP, SP,    #0x6C
        ADD    R5, R0,    #0
        ADD    R6, SP,    #0x7C+var_18
        ADD    R1, R6,    #0
        BL    sub_8046000
        ADD    R4, SP,    #0x7C+var_14
        STRH    R0, [R4]
        ADD    R0, R4,    #0
        ADD    R1, R5,    #0
        BL    incense_effects
        LDRH    R1, [R4]
        MOV    R0, SP
        ADD    R2, R5,    #0
        BL    sub_8046208
        MOV    R0, SP
        ADD    R1, R5,    #0
        BL    sub_8045AC0
        LDRB    R0, [R6,#1]
        MOV    R2, #0x8C @ '?'
        ADD    R1, R0,    #0
        MUL    R1, R2
        ADD    R1, R5,    R1
        LDRB    R0, [R6]
        MUL    R2, R0
        ADD    R2, R5,    R2
        MOV    R0, SP
        BL    daycare_build_child_moveset
        ldrh r0, [r4]
        cmp r0, #0xAC
        bne _08070918
        mov r0, sp
        add r1, r5, #0
        bl sub_82706FC
_08070918:
        MOV    R2, SP
        ADD    R2, #0x6A @ 'j'
        MOV    R0, #1
        STRB    R0, [R2]
        MOV    R0, SP
        MOV    R1, #0x2D @ '-'
        BL    pokemon_setattr
        LDR    R0, off_804614C
        MOV    R1, #0xFA @ '?'
        LSL    R1, R1,    #1
        ADD    R0, R0,    R1
        MOV    R1, SP
        MOV    R2, #0x64 @ 'd'
        BL    memcpy
        BL    party_compaction
        BL    party_count_pokemon
        ADD    R0, R5,    #0
        BL    sub_8045F70
        ADD    SP, SP,    #0x6C
        POP    {R4-R6}
        POP    {R0}
        BX    R0
@ End of function sub_80460D4

@ ---------------------------------------------------------------------------
.align 2
off_804614C:    .long 0x2024284        @ DATA XREF: sub_80460D4+52r
This routine (located at 0x2706FC in my patch) handles the volt tackle inheriting:
Code:
sub_80707A4:
    push {r4-r6,lr}
    add r5, r0, #0
    add r4, r1, #0
    add r0, r4, #0
    mov r1, #0xC
    bl pokemon_getattr_encrypted
    add r6, r0, #0
    add r4, #0x8C
    add r0, r4, #0
    mov r1, #0xC
    bl pokemon_getattr_encrypted
    cmp r6, #0xCA
    beq _080707C6
    cmp r0, #0xCA
    bne _080707E2

_080707C6:
    mov r4, #0xAC
    lsl r4, r4, #0x1
    add r0, r5, #0
    add r1, r4, #0
    bl pokemon_moveset_pad_
    lsl r0, r0, #0x10
    ldr r1, =(0xffff0000)
    cmp r0, r1
    bne _080707E2
    add r0, r5, #0
    add r1, r4, #0
    bl sub_803EB94

_080707E2:
    pop {r4-r6}
    pop {r0}
    bx r0
This last one makes sure the old offsets work correctly from the new offsets:
Code:
.text
.align 2
.thumb
.thumb_func

.org 0x0462B8
bl 0x270670

.org 0x27067A
bl 0x046000

.org 0x270686
bl 0x045FA0

.org 0x270690
bl 0x046208

.org 0x270698
bl 0x045AC0

.org 0x2706AE
bl 0x045CD0

.org 0x2706BC
bl 0x2706FC

.org 0x2706CC
bl 0x04037C

.org 0x2706DC
bl 0x1E5E78

.org 0x2706E0
bl 0x0937DC

.org 0x2706E4
bl 0x040C3C

.org 0x2706EA
bl 0x045F70

.org 0x270706
bl 0x03FD44

.org 0x270712
bl 0x03FD44

.org 0x270726
bl 0x03E89C

.org 0x270736
bl 0x03EB94
If anybody has a better way of porting this, please post it here.
edit2: I could probably just use bx r3?
Attached Files
File Type: ips Volt tackle.ips‎ (232 Bytes, 9 views) (Save to Dropbox)
Reply With Quote
  #1235   Link to this post, but load the entire thread.  
Old August 8th, 2017 (1:46 PM).
tkim's Avatar
tkim tkim is offline
 
Join Date: May 2011
Posts: 232
Quote:
Originally Posted by DizzyEgg View Post
Pokemon Emerald Multichoice Scrolling Box

Spoiler:
So, the mechanic for that is already implemented, we just have to repoint some tables. So let's get down to work.
First, there's a table at 0x085B2CF0. Each entry is a pointer to text to be displayed in the box. One set consist of 16 options. This is important. Anyway, repoint to free space and change pointers to this table. It ends at 0x085B3030.

Now, there's a jumptable at 0x813A156. It ends at 0x0813A19C. It has 12 entries, repoint it to free space. Now for every new set of options you want to add, you have to add a routine like this:
Spoiler:

Code:
.text
.thumb
.thumb_func
.align 2

main:
    mov r0, #5
    strh r0, [r3, #8] @how many are displayed
    mov r0, #8
    strh r0, [r3, #0xA] @how many are in total
    mov r0, #1
    strh r0, [r3, #0xC] @X coordinate
    mov r0, #1
    strh r0, [r3, #0xE] @Y coordinate
    mov r0, #9
    strh r0, [r3, #0x10] @unkown
    mov r0, #0xA 
    strh r0, [r3, #0x12] @box height, should be displayed * 2
    mov r0, #0
    strh r0, [r3, #0x14] @unkown 
    strh r4, [r3, #0x26] @task id, don't change it
    pop {r4}
    pop {r0}
    bx r0


Note that you can change parameters in those routines. Play with them and see which ones look the best for you. Now, every routine like that above, goes at the end of the repointed jumptable. There are 12-in game sets, so you'll start with 13. Change the byte at 0x813A148 to the amount of all sets.

One more thing, even though the table of pointers to text can only hold 16 pointers, it doesn't mean you're limited to only that many options. You can go to 126 max, because 127 is treated as hitting B. How? Well, in the routine above set how many in total to the amount you want and ignore occupied slots. For example if you want your set to have 50 options, divide it by 16, so you get 3 and some remainder. That means this set occupies 4 places in the jumptable, like this:
XX XX XX 08 00 00 00 00 00 00 00 00 00 00 00 00 NEW SET GOES HERE

Using it in a script is easy, just do this:
setvar 0x8004 slot in the jumptable (starts at 13, since 12 are already occupied in-game)
special 0x1BE
waitstate
Result is stored in the 0x800D. First option chosen is 0, second is 1, and so on. Hitting B be is 0x7F.
compare 0x800D 0x0
if 0x1 goto @first_option
....
compare 0x800D 0x7F
if 0x1 goto @chose_cancel

I hope everything's understandable. :)
I'm having a bit of trouble getting this to work. First of all, isn't the jumptable at 0x813A168 and not 0x813A156? I can repoint 0x813A168, but not your given 0x813A156. Second, I can only get the default choices to work. Anything above 12 (0xC) won't work for me. As soon as special 0x1BE is called ingame with a value of 0xD or more, the game freezes without the list showing up at all.

Here's the steps I did in order:

- repointed the first table located at 0x5B2CF0 to 0xDE43E0 and changed two pointers.
- repointed the jumptable located at 0x13A168 (instead of 0x13A156 as I couldn't find the pointers for it) to 0xDE4760 and changed one pointer.
- compiled your routine and inserted at 0xDE4794 (which is right after the repointed jumptable)
- added new entry (6 pre-existing pointers) to 0xDE4720.
- changed the byte at 0x813A148 from 0xC to 0xD.
Reply With Quote
  #1236   Link to this post, but load the entire thread.  
Old August 9th, 2017 (3:37 AM). Edited August 9th, 2017 by Froosty.
Froosty's Avatar
Froosty Froosty is offline
The_Learner
 
Join Date: Sep 2014
Location: Somewhere in this world.
Age: 25
Gender: Male
Nature: Brave
Posts: 535
DIFFERENT PALS FOR THE MALE AND FEMALE BAG [FR]
Thanks to KDS for helping me fix the error. :)
Insert this code:
Spoiler:

/* at 108340 put 00 48 00 47 (insert loc of this routine +1) */

.text
.align 2
.thumb

main:
ldr r0, =(0x0300500C)
ldr r0, [r0]
ldrb r0, [r0, #0x8]
cmp r0, #0x0
bne female
ldr r0, male_pal
b pal_load_maybe

female:
ldr r0, female_pal
b pal_load_maybe

pal_load_maybe:
ldr r1, handling_something
bl call_via_r1
ldr r1, return_loc
bx r1

call_via_r1:
bx r1

.align 2
male_pal: .word 0x08XXXXXX
female_pal: .word 0x08YYYYYY
handling_something: .word 0x0800ec28|1
return_loc: .word 0x08108352|1

Code:
XXXXXX is the pointer to AA AA AA 08 64 00
YYYYYY is the pointer to BB BB BB 08 64 00

where,
AA AA AA 08 is pointer to compressed male bag pallete
BB BB BB 08 is pointer to compressed female bag pallete


example:
Spoiler:
I insreted compressed pals at 900000 and 900030 and the routine at 800000,
so have a look at my rom data.

NOTE: you dont need to leave spaces between bytes, I did that just to make it easier to understand
__________________
My works:
TOOL: TL's Quick Enhancer
TUTORIAL: Fire red habitat editing
TUTORIAL: Fire red Transparent text-box


| |
Reply With Quote
  #1237   Link to this post, but load the entire thread.  
Old August 9th, 2017 (9:04 PM). Edited January 7th, 2021 by AkameTheBulbasaur.
AkameTheBulbasaur's Avatar
AkameTheBulbasaur AkameTheBulbasaur is offline
Akame Marukawa of Iyotono
 
Join Date: May 2013
Location: A place :D
Age: 25
Gender: Male
Nature: Docile
Posts: 408
Scaled Experience Formula

In Generation V, a new way of determining the Experience Points gained after Battle was introduced. Previously, the Experience Formula was a flat one, which did not change based on Level Differences between your Pokemon and the other one.

In Black & White, they used a Scaled Experience Formula, which would cause your Pokemon to gain more experience if their opponent was a higher Level, and less if their opponent was a lower one.

Today, I am sharing a way to have this sort of Scaled Experience Points in Fire Red or Emerald. I have included the download link to a folder which contains four items.

Folder: (Download)
  1. The Routine (For Fire Red)
  2. The Routine (For Emerald)
  3. Think0028's Experience All Patch
  4. An Instruction Manual

The Instruction Manual explains how the routine works and any extra information that is necessary to know (particularly if you would like to modify this routine for your specific hack).

Important:
Considering I first uploaded the first version of this routine a long time ago, you may have an older version of it. This version may be preferable to that one, and it is smaller than the previous version is. Therefore, one can simply insert it over the old version and not have to repoint anything.

Extra Information

This routine is compatible with Think0028's Experience All Patch. His original download link is unfortunately broken, hence why I put it in the download folder. If it was still active, I would have linked directly to it.

If you inserted the Disable Experience Gain With Flag routine, originally by FBI, then you may wish to remove it, as this routine implements it. I am not sure if there is a conflict due to this, but at the very least there is a redundant check if you have two routines which both check the same Flag. It is also possible that this routine bypasses that one entirely, in which case you would want to remove it to avoid wasting space.

Thanks and credits to FBI for that original routine, as without it I would likely not have been able to find the correct branching address for this routine.

As I have nowhere else to post this information, I will say here that to remove the 1.5x Experience Boost you get for defeating a Pokemon in a Trainer Battle (like they did in Generation VII), do the following:

Put 07 E0 at 0x21DD8 (FireRed) or 0x4A698 (Emerald)

Put 1C E0 at 0x21E00 (FireRed) or put 28 E0 at 0x4A6C0 (Emerald)
__________________
"The human sacrificed himself, to save the Pokemon. I pitted them against each other, but not until they set aside their differences did I see the true power they all share deep inside. I see now that the circumstances of one's birth are irrelevant; it is what you do with the gift of life that determines who you are." -Mewtwo
Reply With Quote
  #1238   Link to this post, but load the entire thread.  
Old August 10th, 2017 (12:18 PM).
Lunos's Avatar
Lunos Lunos is offline
Random Uruguayan User
 
Join Date: Oct 2008
Location: Montevideo (Uruguay)
Gender: Male
Nature: Lonely
Posts: 3,000
The two requests I ever made over here were in vain.. allow me to try another one instead.
How about a port of JPAN's Overworld Hacks to Emerald?
I'm looking for a way to basically change a character's Front sprite, Back sprite and OWs to another one until I revert things back to how it was manually with another command.
__________________
Reply With Quote
  #1239   Link to this post, but load the entire thread.  
Old August 11th, 2017 (7:36 PM).
Hotice03 Hotice03 is offline
 
Join Date: Apr 2017
Posts: 10
I need help making an eeveelution evolution happen i need it made so when an eevee faints in battle and then you feed it a rare candy while its fainted after battle it evolves into a ghost type eeveelution
Reply With Quote
  #1240   Link to this post, but load the entire thread.  
Old August 11th, 2017 (10:31 PM).
AkameTheBulbasaur's Avatar
AkameTheBulbasaur AkameTheBulbasaur is offline
Akame Marukawa of Iyotono
 
Join Date: May 2013
Location: A place :D
Age: 25
Gender: Male
Nature: Docile
Posts: 408
Quote:
Originally Posted by Hotice03 View Post
I need help making an eeveelution evolution happen i need it made so when an eevee faints in battle and then you feed it a rare candy while its fainted after battle it evolves into a ghost type eeveelution
This is just off the top of my head, so I haven't tested this or anything, but it should give you a head start.

First here's a link to a tutorial on how to add new evolution methods.

https://www.pokecommunity.com/showthread.php?t=329357

Second, you need a way to check if a Pokémon in your party is fainted. You can check the current HP of a Pokémon using the RAM offsets I posted here.

ldr r1, .FirstPoke
mov r1, #0x39
bl Decrypt
cmp r0, #0x0
beq Evolve

.FirstPoke is the first RAM offset in the lists I posted under the "Yours" heading. Basically what this little snippet does is it checks the current HP of the first Pokémon in your party and compares it to zero. If it's zero, the Pokémon is fainted and you can then branch to the next thing. You can change the party slot it checks, but ideally you would want a way for the code to know which Pokemon you selected.

It might help to look through the evolution routines posted in the tutorial and see how they're structured.

That's all I can really do without doing testing first, but that will have to wait until later because it's 2:30 in the morning as I'm posting this. PM me later if you still need help.
__________________
"The human sacrificed himself, to save the Pokemon. I pitted them against each other, but not until they set aside their differences did I see the true power they all share deep inside. I see now that the circumstances of one's birth are irrelevant; it is what you do with the gift of life that determines who you are." -Mewtwo
Reply With Quote
  #1241   Link to this post, but load the entire thread.  
Old August 22nd, 2017 (1:08 PM).
Derlo's Avatar
Derlo Derlo is offline
Tired....
 
Join Date: Aug 2007
Location: Mossoró-RN-BR
Gender: Male
Posts: 135
Hello, I would like to request a hook routine to be added to the original TM's routine.
The new routine would be activated when the TM's were used and deleted, so a new item would be created in the ITEN bag.
If possible, include checking if the bag is full. If yes, discard new item.
Thanks in advance.
Reply With Quote
  #1242   Link to this post, but load the entire thread.  
Old August 24th, 2017 (5:38 AM).
Enn's Avatar
Enn Enn is offline
 
Join Date: Jan 2017
Gender: Male
Posts: 185
Quote:
Originally Posted by Derlo View Post
Hello, I would like to request a hook routine to be added to the original TM's routine.
The new routine would be activated when the TM's were used and deleted, so a new item would be created in the ITEM bag.
If possible, include checking if the bag is full. If yes, discard new item.
Thanks in advance.
Hello,
I think reuable tms are already done, if thats what you need...
Reply With Quote
  #1243   Link to this post, but load the entire thread.  
Old August 24th, 2017 (5:57 AM).
Lunos's Avatar
Lunos Lunos is offline
Random Uruguayan User
 
Join Date: Oct 2008
Location: Montevideo (Uruguay)
Gender: Male
Nature: Lonely
Posts: 3,000
Quote:
Originally Posted by Nisarg View Post
Hello,
I think reuable tms are already done, if thats what you need...
It looks like he wants an item to be created after a TM is used and naturally deleted.
He didn't mentioned if he wants the exact TM to be created yet again, so I'd say he's not looking for reusable TMs.
__________________
Reply With Quote
  #1244   Link to this post, but load the entire thread.  
Old August 24th, 2017 (1:16 PM).
Derlo's Avatar
Derlo Derlo is offline
Tired....
 
Join Date: Aug 2007
Location: Mossoró-RN-BR
Gender: Male
Posts: 135
Quote:
Originally Posted by Nisarg View Post
Hello,
I think reuable tms are already done, if thats what you need...
Quote:
Originally Posted by Lunos View Post
It looks like he wants an item to be created after a TM is used and naturally deleted.
He didn't mentioned if he wants the exact TM to be created yet again, so I'd say he's not looking for reusable TMs.
In fact what I need is to maintain the original routine that deletes the TM after use and add the creation of an item along with the TM exclusion.
Example: After using any TM, it is deleted from TM CASE and creates a NUGGET in the player bag.
And if possible show the informed message where the new item will be in the bag.
Reply With Quote
  #1245   Link to this post, but load the entire thread.  
Old August 25th, 2017 (6:24 AM). Edited August 30th, 2017 by Koople.
Koople's Avatar
Koople Koople is offline
 
Join Date: Nov 2016
Nature: Relaxed
Posts: 88
Fixing some major bugs/oversights with this routine seemed worthy of a new post so anyone who has implemented it can notice the changes:

Adding a Dodge Rate for Catching Wild Pokemon [FR]

This routine uses the wild pokemon's base speed stat to calculate a probability that it will dodge a thrown pokeball (nominally ~5-10%)

(credits to Urz, shanem7, and ghoulslash for bug finding, scripting, and testing!)

Important Routine Notes:
  • This routine does not affect Safari Balls
  • In its current form, the Master Ball skips all dodge rate checks (can be changed easily)
  • The hook address may have changed from previous routine versions. Make sure you are using the correct hook address!

Insertion Instructions:
  1. Insert custom 'dodging' message at 0xXXYYZZ. This is what will be displayed when the Pokemon dodges your thrown Poke Ball
  2. Insert the following custom battle script at 0x08XXXXXX (requires the setword command. Also add #command cmdF6 0xF6 to commands.bsh file)
    Quote:
    waitmessage 0x40
    setword 0x203C020 0x08XXYYZZ
    printstring 0x184
    waitmessage 0x40
    cmdF6
  3. Replace .Message: word 0x8XXXXXX in the assembly routine below with the offset you compiled this battle script in
  4. Compile and insert the routine in free space (0x08TTUUVV)
  5. Insert 00 48 00 47 (VV+1) UU TT 08 at 0802D508

The Routine:
Code:
.text
.align 2
.thumb
.thumb_func
	
Main:
	ldr r1, .BallThrown
	ldrb r0, [r1]
	cmp r0, #0x1	  @master ball
	bne OtherBall
	ldr r0, =(0x03004F90)
	ldr r1, =(0x0802D688 +1)
	bx r1

OtherBall:
	ldr r6, .TargetBank
	ldrb r0, [r6]
	ldr r1, .SpecialStatus
	lsl r0, r0, #0x2
	add r2, r1, r0
	ldr r0, [r2]
	ldr r1, =(0x000400C0)	@fly/dig/bounce/dive status flags
	and r0, r1
	cmp r0, #0x0	
	bne DodgeBall     @auto dodge if offscreen
	ldrb r0, [r2, #0x1]
	mov r1, #0x4
	and r0, r1
	cmp r0, #0x0
	bne NoDodge	@ingrain -> cant dodge
	ldrb r0, [r6]
	mov r1, #0x58
	mul r0, r1
	ldr r1, .BattleStruct
	add r5, r1, r0
	mov r0, #0x4C
	add r0, r5, r0
	ldrb r1, [r0, #0x7]
	mov r2, #0x1
	and r1, r2
	cmp r1, #0x0
	bne DodgeBall     @substitute on -> auto dodge
	ldrb r1, [r0, #0x3]
	cmp r1, #0x20
	beq NoDodge	@frozen = can't dodge
	mov r2, #0x7
	and r1, r2
	cmp r1, #0x0
	bne NoDodge	@target is asleep -> cant dodge
	
GetThreshold:
	ldrh r0, [r5]
	mov r1, #0x1C
	mul r0, r0, r1
	ldr r1, .BaseStats
	add r0, r0, r1
	ldrb r0, [r0, #0x3]		@r0 = wild pokemon base speed
	mov r1, #0xA		@number to divide base speed by (change if you want)
	bl div_func			@r0 =  base speed / 10
	mov r1, #0xD		@r1 = 13 (lower limit ~5% - change if you want)
	add r1, r0, r1		@r1 = 13 + base_speed/10 = base threshold
	
CheckParalysis:
	mov r0, r5
	add r0, #0x4F
	ldrb r0, [r0]
	cmp r0, #0x40
	bne CheckWrap
	lsr r1, r1, #0x1	@if pokemon paralyzed, its dodge rate is halved
	
CheckWrap:
	mov r0, r5
	add r0, #0x51
	ldrb r0, [r0]
	mov r2, #0xE0
	and r0, r2
	cmp r0, #0x0	
	beq CheckDodge
	lsr r2, r1, #0x2
	sub r1, r1, r2		@3/4 dodge rate if trapped by wrap effect
	
CheckDodge:
	mov r3, r1
	bl rand_func
	lsr r0, r0, #0x8
	cmp r0, r3
	bls DodgeBall	@if r0 <= threshold value, the pokemon dodges the ball

NoDodge:
	ldr r3, .BaseStats	@replaced routine from hook
	ldr r2, .BattleStruct
	ldrb r1, [r6]
	mov r0, #0x58
	ldr r5, =(0x0802D510 +1)	@return to original routine
	bx r5
	
div_func:
	ldr r2, .Divide
	bx r2
	
rand_func:
	ldr r2, .Rand
	bx r2
	
DodgeBall:
	mov r0, #0x0
	mov r1, #0x6		@change to mov r1, #0x5 for ball deflection instead of dodging animation
	ldr r2, =(0x0800E194 +1)
	bl linker
	ldr r5, =(0x02023BC4)
	ldrb r0, [r5]
	ldr r2, =(0x08017248 +1)
	bl linker
	ldr r1, =(0x02023D74)
	ldr r0, .DodgeMessage
	ldr r2, =(0x0802D7EC +1)
	
linker:
	bx r2

.align 2
.BallThrown:	.word 0x02023D68
.Rand: .word 0x08044EC9
.WildPoke:	.word 0x0202402C
.BaseStats: .word 0x08254784
.Divide:	.word 0x081E4019
.UserBank:	.word 0x02023D6B
.TargetBank:	.word 0x02023D6C
.BattleStruct:	.word 0x02023BE4
.SpecialStatus:	.word 0x02023DFC
.DodgeMessage:	.word 0x08XXXXXX	@battle script to display custom message
Current Routine Features:
  1. Target will automatically dodge a thrown ball if it is off-screen (dig, fly, bounce, dive) or has a substitute out
  2. Target will never dodge if it is asleep, frozen, or rooted in the ground (ingrain)
  3. 50% dodge rate for paralysis and 75% dodge rate if trapped by wrap effect
There are lots of other little dodge rate modifiers one could implement, such as speed/evasion stat modifiers, held item, ability, weather, etc. I have implemented some of these, so let me know if you want me to add these in!
Reply With Quote
  #1246   Link to this post, but load the entire thread.  
Old August 31st, 2017 (8:47 PM). Edited February 13th, 2019 by Skeli.
Skeli's Avatar
Skeli Skeli is offline
Lord of the Rings
 
Join Date: Apr 2014
Location: Canada
Age: 24
Gender: Male
Nature: Adamant
Posts: 300
Expanding the Bag Entirely [FR]

-Big Edit: The routines have been completely rewritten from scratch to work properly now.

This has been done in bits and pieces over the years (I believe it's actually been done completely for Emerald), so I decided to rewrite the bag storage routine for Fire Red.

Pre-Requisites
  • JPAN's Save Block Recycle
    Spoiler:
    Code:
    .thumb
    .global JPAN_Save_Block_Recycle
    .equ rom, 0x8000000
    .equ offset, 0xA00000 @YOUR INSERT OFFSET HERE
    
    .org 0xD991E, 0xFF
    	bx r7
    
    .org 0xD995C, 0xFF
    .word Recycle_2 + rom + 1
    
    .org 0xD9EDC, 0xFF
    	ldr r0, .Pointer1
    	bx r0
    .align 2
    .Pointer1: .word Recycle_1 + rom + 1
    
    .org 0x3FEC9A, 0xFF
    .byte 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xE0, 0x1F, 0xF0, 0x0F, 0xD0, 0x2F, 0x98, 0xD, 0x0, 0x0, 0xF0, 0x0F, 0xF0, 0xF, 0xF0, 0xF, 0xE0, 0x1F, 0xF0, 0xF, 0xD0, 0x2F, 0xF0, 0xF, 0xC0, 0x3F, 0xF0, 0xF, 0xB0, 0x4F, 0xF0, 0xF, 0xA0, 0x5F, 0xF0, 0xF, 0x90, 0x6F, 0xF0, 0xF, 0x80, 0x7F, 0x50, 0x4
    
    .org offset, 0xFF
    Recycle_1:
    	ldr r1, [r4]
    	mov r3, #0xFF
    	lsl r3, #0x4
    	add r3, r1
    	ldrh r0, [r3, #0x4]
    	cmp r0, #0x0
    	beq Size1
    	cmp r0, #0x4
    	beq Size2
    	cmp r0, #0xD
    	beq Size3
    
    BigLoop:
    	cmp r5, #0xD
    	ble Return
    	mov r0, #0x1
    	pop {r3}
    	mov r8, r3
    	pop {r4-r7,pc}
    
    Size1:
    	mov r1, #0xCC
    	ldr r2, .Loc1
    	b SmallLoop
    
    Size2:
    	mov r1, #0x96
    	lsl r1, #0x2
    	ldr r2, .Loc2
    	b SmallLoop
    
    Size3:
    	mov r1, #0xBA
    	lsl r1, #0x4
    	ldr r2, .Loc3
    
    SmallLoop:
    	sub r3, #0x4
    	ldr r0, [r3]
    	str r0, [r2]
    	sub r2, #0x4
    	sub r1, #0x4
    	cmp r1, #0x0
    	bne SmallLoop
    	b BigLoop
    
    .align 2
    .Loc1: .word 0x203C1C8
    .Loc2: .word 0x203C420
    .Loc3: .word 0x203CFC0
    
    Return:
    	ldr r0, .Return
    	bx r0
    
    .align 2
    .Return: .word 0x80D9E71
    .word 0xFFFFFFFF
    
    Recycle_2:
    	mov r7, #0xFF
    	lsl r7, #0x4
    	add r7, r1, r7
    	strh r0, [r7, #0x6]
    	ldrh r6, [r7, #0x4]
    	cmp r6, #0x0
    	beq Size1_2
    	cmp r6, #0x4
    	beq Size2_2
    	cmp r6, #0xD
    	beq Size3_2
    	lsl r0, #0x0
    
    Return_2:
    	ldr r0, .Return2
    	bx r0
    
    .align 2
    .Return2: .word 0x80D9923
    
    Size1_2:
    	mov r3, #0xCC
    	ldr r2, .Loc1_2
    	b SmallLoop_2
    
    Size2_2:
    	mov r3, #0x96
    	lsl r3, #0x2
    	ldr r2, .Loc2_2
    	b SmallLoop_2
    
    Size3_2:
    	mov r3, #0xBA
    	lsl r3, #0x4
    	ldr r2, .Loc3_2
    
    SmallLoop_2:
    	sub r7, #0x4
    	ldr r0, [r2]
    	str r0, [r7]
    	sub r2, #0x4
    	sub r3, #0x4
    	cmp r3, #0x0
    	bne SmallLoop_2
    	b Return_2
    
    .align 2
    .Loc1_2: .word 0x203C1C8
    .Loc2_2: .word 0x203C420
    .Loc3_2: .word 0x203CFC0
    Insertion Instructions:
    1. Change the .equ offset, 0xA00000 to the offset where you plan on inserting the routine.
    2. Compile the asm file.
    3. Open the .bin file and copy all the data from 0xD991E, 0xD995C, 0xD9EDC 0x3FEC9A, and your insert offset (your offset's data will go to the end of the bin file) to those same offsets in your rom.
  • An updated Conversion attack routine:
    Spoiler:

    In the following routine, change the location of your attack data at the top if necessary (if you haven't added new moves to your game it probably isn't). Assemble the routine, copy the data from the .bin file, and then do a paste-write at 0x28604 in your rom.

    Or if you don't understand ASM, copy and paste the compiled version to 0x28604 in your rom:
    Code:
    F0 B5 1B 4F 18 48 19 49 09 78 58 22 51 43 40 18 03 1C 44 7D 85 7D 00 88 12 49 0C 22 50 43 09 18 08 78 A0 42 10 D0 A8 42 0E D0 58 75 98 75 04 1C 10 48 FD 21 01 70 03 21 41 70 84 70 FF 21 C1 70 39 68 05 31 39 60 F0 BD 3A 68 51 78 90 78 00 02 01 43 D0 78 00 04 01 43 10 79 00 06 01 43 39 60 F0 BD C0 46 06 0C 25 08 F0 3B 02 02 6B 3D 02 02 74 3D 02 02 B8 2A 02 02
    (This compiled version assumes you haven't added any new moves)

    Routine:
    Code:
    .thumb
    .global atk90_changetypestoenemyattacktype
    
    .equ Attack_Data, 0x250C04 @0x900000 for Mr. DS
    .equ rom, 0x8000000
    
    @Conversion: Insert at 0x28604
    CheckMove:
    	push {r4-r7, lr}
    	ldr r7, .ScriptLoc
    	ldr r0, .BattleData
    	ldr r1, .UserBank
    	ldrb r1, [r1]
    	mov r2, #0x58
    	mul r1, r2
    	add r0, r1
    	mov r3, r0
    	ldrb r4, [r0, #0x15] @first type
    	ldrb r5, [r0, #0x16] @second type
    	ldrh r0, [r0] @First Move
    
    GetMoveType:
    	ldr r1, .MoveData
    	mov r2, #0xC
    	mul r0, r2
    	add r1, r0
    	ldrb r0, [r1]
    
    CheckTypeMatch:
    	cmp r0, r4
    	beq Failed
    	cmp r0, r5
    	beq Failed
    
    Store:
    	strb r0, [r3, #0x15]
    	strb r0, [r3, #0x16]
    
    Return:
    	mov r4, r0
    	ldr r0, =0x2022AB8
    	mov r1, #0xFD
    	strb r1, [r0]
    	mov r1, #0x3
    	strb r1, [r0, #0x1]
    	strb r4, [r0, #0x2]
    	mov r1, #0xFF
    	strb r1, [r0, #0x3]
    	ldr r1, [r7]
    	add r1, #0x5
    	str r1, [r7]
    	pop {r4-r7, pc}
    
    Failed:
    	ldr r2, [r7]
    	ldrb r1, [r2,#1]
    	ldrb r0, [r2,#2]
    	lsl r0, #8
    	orr r1, r0
    	ldrb r0, [r2,#3]
    	lsl r0, #0x10
    	orr r1, R0
    	ldrb r0, [r2,#4]
    	lsl r0, #0x18
    	orr r1, r0
    	str r1, [r7]
    	pop {r4-r7, pc}
    
    .align 2
    .MoveData: .word Attack_Data + 0x2  + rom
    .BattleData: .word 0x2023BE4 + 0xC
    .UserBank: .word 0x2023D6B
    .ScriptLoc: .word 0x2023D74


    Why Conversion?
    Spoiler:
    Some of the space from the old Conversion routine is used for the bag expansion. To free up this space, Conversion was rewritten to match its Gen 6+ effect.

The Code
Spoiler:
Code:
.equ Total_Item_Amount, 700 @Change to largest item index number

.equ Regular_Item_Num, 200 @Change to number of items in main bag pocket divided by 2
.equ Key_Item_Num, 30 @Change to number of items in key item pocket divided by 2
.equ Poke_Ball_Num, 14 @Change to number of items in Poke Ball pocket divided by 2
.equ TM_Num, 128 @Change to number of TMs + HMs
.equ Berry_Num, 67 @Change to number of berries

@When changing the following RAM Adresses, make sure no data is being overwritten.
@For example, if you want to change the Poke_Ball_Ram, it needs to be changed to
@a location where there are (Poke_Ball_Num * 2 * 4) bytes of memory free.
.equ TM_Ram, 0x202583C @Change to your TM Case RAM address
.equ Berry_Ram, 0x2025A3C @Change to your Berry Pouch RAM address
.equ Key_Item_Ram, 0x203C7D0 @Change to your Key Item pocket RAM address
.equ Poke_Ball_Ram, 0x203C8C0 @Change to your main Poke Ball Pocket RAM address
.equ Item_Ram, 0x203C930 @Change to your main bag pocket RAM address

.equ Free_Ram, 0x203D900 @Don't change unless you don't like this free ram
.equ offset, 0x8D1980 @Change to Free Space Offset

.equ largest_pocket_size, Regular_Item_Num * 2
.equ largest_pocket_size_plus_one, largest_pocket_size + 1
.equ strings_size, largest_pocket_size_plus_one * 19

.equ rom, 0x8000000

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@HelperRoutine

.org 0x28760, 0xFF
GetItemAmount:
	push {r1,lr}
	ldr r0, .CurrentPocket
	ldrb r0, [r0]
	lsl r0, #0x1
	ldr r1, .ItemStorage
	ldrh r0, [r0, r1]
	pop {r1,pc}

.align 2
.CurrentPocket: .word 0x203AD02
.ItemStorage: .word Free_Ram

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Decryption and DMA Negation
@The first few of these actually decrypt the Pokemon Data because why not?

.org 0x3F906, 0xFF
mov r8, r8
str r0, [r2]
ldr r1, [r3, #0x4]
mov r8, r8

.org 0x3F92A, 0xFF
mov r8, r8
str r0, [r2]
ldr r1, [r3]
mov r8, r8

.org 0x3F94C, 0xFF
mov r0, #0x0
mov r8, r8
mov r8, r8

.org 0x3FDA8, 0xFF
b 0x3FDC2

.org 0x40530, 0xFF
b 0x40550

.org 0x40AE6, 0xFF
mov r8, r8

.org 0x4C062, 0xFF
mov r1, #0x0
mov r1, #0x0

.org 0x4C13C, 0xFF
mov r4, #0x0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

.org 0x6BDEC, 0xFF
	ldr r0, .BerryFix1Ptr
	bx r0
.align 2
.BerryFix1Ptr: .word BerryFix1Ptr + rom + 1

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Removal of Item Limiters

.org 0x98998, 0xFF
.word Total_Item_Amount

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Routines Related to Obtaining Items

.org 0x99DFC, 0xFF
ldrh r0, [r0, #0x4]

.org 0x99E1A, 0xFF
ldrh r4, [r4, #0x4]

.org 0x99E44, 0xFF
ldr r1, .BagPocket0

@Regular items
ldr r0, ram_FREE_item
str r0, [r1]
mov r0, #Regular_Item_Num
lsl r0, #0x1 @400 regular items
strh r0, [r1, #0x4]

@Key items
ldr r0, ram_FREE_keyitem
str r0, [r1, #0x8]
mov r0, #(Key_Item_Num * 2) @60 key items
strh r0, [r1, #0xC]

@Poke balls
ldr r0, ball_ram
str r0, [r1, #0x10]
mov r0, #(Poke_Ball_Num * 2) @28 balls
strh r0, [r1, #0x14]

@Tms
ldr r0, tm_ram
str r0, [r1, #0x18]
mov r0, #TM_Num @128 TMs
strh r0, [r1, #0x1C]

@Berries
ldr r0, berry_ram
str r0, [r1, #0x20]
add r1, #0x24
mov r0, #Berry_Num @67 berries
strh r0, [r1]
bx lr

.align 2
.BagPocket0:		.word 0x203988C
tm_ram:			.word TM_Ram
berry_ram:		.word Berry_Ram
ram_FREE_keyitem:	.word Key_Item_Ram
ball_ram:		.word Poke_Ball_Ram
ram_FREE_item:		.word Item_Ram

.org 0x99ED8, 0xFF
ldrh r1, [r0, #0x4]

.org 0x99EEA, 0xFF
lsl r0, r2, #0x10
lsr r0, r0, #0x10

.org 0x99F16, 0xFF
ldrh r1, [r0, #0x4]

.org 0x99F32, 0xFF
lsl r0, r0, #0x10
lsl r2, r0, #0x10

.org 0x99F6E, 0xFF
ldrh r1, [r0, #0x4]

.org 0x99F9A, 0xFF
lsl r0, r0, #0x10
lsr r2, r0, #0x10
ldrh r0, [r3, #0x4]

.org 0x99FD4, 0xFF
CheckBerryInBagFix:
	ldr r4, .LastResult
	ldr r0, .CheckBerryBerryRam
	ldrh r0, [r0]
	cmp r0, #0x0
	beq NoBerriesInBag
	mov r0, #0x1
	strh r0, [r4]
	pop {r4,pc}

NoBerriesInBag:
	mov r0, #0x0
	strh r0, [r4]
	pop {r4,pc}

.align 2
.CheckBerryBerryRam: .word Berry_Ram
.LastResult: .word 0x020370D0

.org 0x9A02A, 0xFF
ldrh r1, [r0, #0x4]

.org 0x9A05E, 0xFF
lsl r0, r0, #0x10
lsr r2, r0, #0x10
ldrh r0, [r3, #0x4]

.org 0x9A06E, 0xFF
lsl r0, r0, #0x10
lsr r0, r0, #0x10

.org 0x9A0B6, 0xFF
ldrh r1, [r0, #0x4]

.org 0x9A0EA, 0xFF
lsl r0, r0, #0x10
lsr r2, r0, #0x10
ldrh r0, [r5, #0x4]

.org 0x9A110, 0xFF
lsl r0, r0, #0x10
lsr r1, r0, #0x10

.org 0x9A14C, 0xFF
lsl r0, r0, #0x10
lsr r1, r0, #0x10

.org 0x9A186, 0xFF
lsl r0, r0, #0x10
lsr r2, r0, #0x10

.org 0x9A204, 0xFF
ldrh r1, [r0, #0x4]

.org 0x9A24E, 0xFF
lsl r0, r0, #0x10
lsr r2, r0, #0x10
ldrh r0, [r6, #0x4]

.org 0x9A2E8, 0xFF
ldrh r1, [r1, #0x4]

.org 0x9A58E, 0xFF @Shifting Items Up
lsl r1, #0x10
lsr r1, #0x10

.org 0x09A8A4, 0xFF
	lsl r0, #0x10
	lsr r0, #0x10
	ldr r1, .ItemLimit
	cmp r1, r0
	bge Return
	mov r0, #0x0
Return:
	bx lr

.align 2
.ItemLimit: .word Total_Item_Amount

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Routines Related to the Pokedex

@The original ram provided above for the berries overrites a copy of the Pokedex data.
@Thus, when the Berry Pouch is sorted upon opening it, garbage data from this dex
@data is loaded. These routines prevent this copy from being read from or written to.

BerryPokedexDataFix:
.org 0x104B34, 0xFF
b 0x104B56

.org 0x104B78, 0xFF
b 0x104BB0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Routines Related to Viewing Items in Bag

Bag_Allocate_Stuff: @Credits to azurile13
.org 0x1083F4, 0xFF
	push {r4,lr}
	ldr r4, .AllocationPointer
	ldr r0, .LargestSize
	lsl r0, #0x3
	bl 0x2B9C @malloc
	str r0, [r4]
	cmp r0, #0x0
	beq No
	ldr r0, .strings_size
	bl 0x2B9C @malloc
	str r0, [r4, #0x4]
	cmp r0, #0x0
	beq No
	mov r0, #0x1
	b End

No:
	mov r0, #0x0

End:
	pop {r4,pc}

.align 2
.LargestSize: .word largest_pocket_size_plus_one
.AllocationPointer: .word 0x0203AD18
.strings_size: .word strings_size

.org 0x108440, 0xFF
bl 0x28760 @GetItemAmount
b 0x10844A

.org 0x10847E, 0xFF @Shop is dis one
bl 0x28760 @GetItemAmount
b 0x108488

.org 0x1084C2, 0xFF
bl 0x28760 @GetItemAmount
b 0x1084CA

.org 0x1085D8, 0xFF
push {r1}
bl 0x28760 @GetItemAmount
pop {r1}
cmp r0, r5

.org 0x108698, 0xFF
ldr r5, .Thing
ldrh r1, [r5, #0x6]
push {r1}
bl 0x28760 @GetItemAmount
pop {r1}
.hword 0x0
cmp r0, r4

.org 0x10871C, 0xFF
.Thing: .word 0x203ACFC

.org 0x10881E, 0xFF
ldr r1, .Thing2
ldrh r1, [r1, #0x6]
push {r1}
bl 0x28760 @GetItemAmount
pop {r1}
.hword 0x0
cmp r2, r0

.org 0x108850, 0xFF
.Thing2: .word 0x203ACFC

.org 0x108894, 0xFF
push {r1}
bl 0x28760 @GetItemAmount
pop {r1}
add r1, #0xD

.org 0x108A1C, 0xFF @Up Cursor Bug 1
ldr r1, .OpenBagBugFix1Pointer
bx r1
.align 2
.OpenBagBugFix1Pointer: .word OpenBagBugFix1 + rom + 1

.org 0x108A40, 0xFF @Up Cursor Bug 2
ldr r0, .OpenBagBugFix2Pointer
bx r0
.align 2
.OpenBagBugFix2Pointer: .word OpenBagBugFix2 + rom + 1
.hword 0x0

.org 0x108AC0, 0xFF @Up Cursor Bug 3
ldr r0, .OpenBagBugFix3Pointer
bx r0
.align 2
.OpenBagBugFix3Pointer: .word OpenBagBugFix3 + rom + 1

.org 0x108DC8, 0xFF
ldr r1, .StoreItemPointer
bx r1
.align 2
.StoreItemPointer: .word StoreItem + rom + 1

ldr r0, .Bag_Pocket_0_2
add r4, r1, r0
ldr r0, [r4]
ldrh r1, [r4, #0x4]

.org 0x108DEA, 0xFF
ldrh r0, [r4, #0x4]

.org 0x108E0A, 0xFF
ldrh r0, [r4, #0x4]

.org 0x108E20, 0xFF
ldr r0, .GetSmallestItemAmountPointer
bx r0
.align 2
.GetSmallestItemAmountPointer: .word GetSmallestItemAmount + rom + 1

.org 0x108E3C, 0xFF
.Bag_Pocket_0_2: .word 0x203988C

.org 0x108E4C, 0xFF
pop {r4-r6,pc}

.org 0x108FB6, 0xFF
ldrh r5, [r5, #0x6]
push {r1}
bl 0x28760 @GetItemAmount
pop {r1}
.hword 0x0
cmp r1, r0

.org 0x10904A, 0xFF
	ldrh r1, [r5, #0x6]
	push {r1}
	bl 0x28760 @GetItemAmount
	pop {r1}
	.hword 0x0
	cmp r4, r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Poke Dude Stuff

.org 0x10ADDE, 0xFF
	ldr r0, .PokeDudeBackupRegularBagFixPtr
	bx r0
.align 2
.PokeDudeBackupRegularBagFixPtr: .word PokeDudeBackupRegularBagFix + rom + 1

.org 0x10AE78, 0xFF
	ldr r0, .PokeDudeBackupRegularBagClearPtr
	bx r0
.align 2
.PokeDudeBackupRegularBagClearPtr: .word PokeDudeBackupRegularBagClear + rom + 1

.org 0x10AEDA, 0xFF
	ldr r0, .PokeDudeBackupBagRestorePtr
	bx r0
.align 2
.PokeDudeBackupBagRestorePtr: .word PokeDudeBackupBagRestore + rom + 1

.org 0x132E76, 0xFF
	ldr r1, .PokeDudeBackupTMCasePtr
	bx r1
.align 2
.PokeDudeBackupTMCasePtr: .word PokeDudeBackupTMCase + rom + 1

.org 0x132EB0, 0xFF
	ldr r0, .PokeDudeClearTMCasePtr
	bx r0
.align 2
.PokeDudeClearTMCasePtr: .word PokeDudeClearTMCase + rom + 1

.org 0x13318C, 0xFF
	ldr r0, .PokeDudeRestoreTMCasePtr
	bx r0
.align 2
.PokeDudeRestoreTMCasePtr: .word PokeDudeRestoreTMCase + rom + 1

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Remove Help System

.org 0x13B8C2, 0xFF
b 0x13B900

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@More Berry Stuff

.org 0x13D1C4, 0xFF
	mov r0, #Berry_Num + 1
	lsl r0, #0x3

.org 0x13D33C, 0xFF
BerryNumFixesHook:
	ldr r0, .BerryNumFixesPtr
	bx r0
.align 2
.BerryNumFixesPtr: .word BerryNumFixes + rom + 1

BerryFix2Hook:
.org 0x14A490, 0xFF
	ldr r0, .BerryFix2Ptr
	bx r0
.align 2
.BerryFix2Ptr: .word BerryFix2 + rom + 1

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@New Routine

.org offset, 0xFF
StoreItem:
	push {r4-r6,lr}
	lsl r0, r0, #0x18
	lsr r5, r0, #0x18
	mov r4, #0x0

GetItemInBagCount:
	mov r6, #0x0
	lsl r0, r4, #0x3
	ldr r1, .Table
	add r0, r1
	ldrh r3, [r0, #0x4]
	lsl r3, #0x1
	ldr r0, [r0]
	mov r1, #0x0

Loop:
	cmp r1, r3
	beq StoreAmount
	ldrh r2, [r0]
	cmp r2, #0x0
	beq CheckNextItemJustInCase
	add r0, #0x4
	add r1, #0x1
	b Loop

CheckNextItemJustInCase:
	ldrh r2, [r0, #0x4]
	cmp r2, #0x0
	beq StoreAmount
	add r0, #0x4
	add r1, #0x1
	mov r6, #0x1
	b Loop	

StoreAmount:
	cmp r6, #0x0
	beq NotShopSkip
	sub r1, #0x1
NotShopSkip:
	ldr r0, .ItemStorage2
	lsl r2, r4, #0x1
	add r0, r2
	strh r1, [r0]
	add r4, #0x1
	cmp r4, #0x3
	beq ReturnToThing
	b GetItemInBagCount

ReturnToThing:
	lsl r1, r5, #0x3
	ldr r0, =0x8108DD1
	bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

GetSmallestItemAmount:
	push {r1}
	ldr r0, .ItemStorage2
	lsl r1, r5, #0x1
	add r0, r1
	pop {r1}
	ldrh r0, [r0]
	ldr r3, =0x8108E29
	bx r3

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

OpenBagBugFix1:
	push {r0}
	lsl r0, r4, #0x1
	ldr r1, .ItemStorage2
	add r1, r0
	ldrh r1, [r1]
	pop {r0}
	add r0, r1, #0x1
	cmp r2, r0
	ldr r0, =0x8108A26 | 1
	bx r0

OpenBagBugFix2:
	lsl r3, r4, #0x1
	ldr r0, .ItemStorage2
	add r0, r3
	ldrh r0, [r0]
	add r3, r0, #0x1
	ldr r4, =0x8108A4C | 1
	bx r4

OpenBagBugFix3:
	lsl r1, r6, #0x1
	ldr r0, .ItemStorage2
	add r0, r1
	ldrh r0, [r0]
	add r0, #0x1
	ldr r1, =0x8108AC8 | 1
	bx r1

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

PokeDudeBackupRegularBagFix:
	ldr r5, .PokeDudeItemBackupPtr
	ldr r0, .NewMallocPokeDudeBagSpace
	bl Calloc
	str r0, [r5]
	ldr r1, =Item_Ram
	ldr r2, =Regular_Item_Num * 2 * 4
	mov r4, r2
	bl Memcpy

	ldr r0, [r5]
	add r0, r4
	ldr r1, =Key_Item_Ram
	ldr r2, =Key_Item_Num * 2 * 4
	add r4, r2
	bl Memcpy

	ldr r0, [r5]
	add r0, r4
	ldr r1, =Poke_Ball_Ram
	ldr r2, =Poke_Ball_Num * 2 * 4
	bl Memcpy

	ldr r4, .SaveBlock1
	ldr r0, =0x810AE22 | 1
	bx r0


@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@0x810AE78 with r0
PokeDudeBackupRegularBagClear:
	ldr r0, =Item_Ram
	ldr r1, =Regular_Item_Num * 2
	bl RemoveNItems

	ldr r0, =Key_Item_Ram
	mov r1, #Key_Item_Num * 2
	bl RemoveNItems

	ldr r0, =Poke_Ball_Ram
	mov r1, #Poke_Ball_Num * 2
	bl RemoveNItems
	
	ldr r4, .SaveBlock1
	ldr r0, =0x810AEA4 | 1
	bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@0x10AEDA with r0
PokeDudeBackupBagRestore:
	ldr r0, =Item_Ram
	ldr r1, [r5]
	ldr r2, =Regular_Item_Num * 2 * 4
	mov r4, r2
	bl Memcpy

	ldr r0, =Key_Item_Ram
	ldr r1, [r5]
	add r1, r4
	ldr r2, =Key_Item_Num * 2 * 4
	add r4, r2
	bl Memcpy

	ldr r0, =Poke_Ball_Ram
	ldr r1, [r5]
	add r1, r4
	ldr r2, =Poke_Ball_Num * 2 * 4
	bl Memcpy

	ldr r4, .SaveBlock1
	ldr r0, =0x810AF0C | 1
	bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@0x8132E76 with r1
PokeDudeBackupTMCase:
	ldr r1, =TM_Ram
	ldr r2, =TM_Num * 4
	mov r5, r2
	bl Memcpy

	ldr r0, [r4]
	add r0, r5
	ldr r1, =Key_Item_Ram * 2 * 4
	ldr r2, =Key_Item_Num * 2 * 4
	bl Memcpy

	ldr r0, =0x8132E98 | 1
	bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@0x132EB0 with r0
PokeDudeClearTMCase:
	ldr r0, =TM_Ram
	mov r1, #TM_Num
	bl RemoveNItems

	ldr r0, =Key_Item_Ram
	mov r1, #Key_Item_Num
	bl RemoveNItems

	ldr r0, =0x8132EC4 | 1
	bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@0x813318C with r0
PokeDudeRestoreTMCase:
	ldr r0, =TM_Ram
	ldr r2, =TM_Num * 4
	bl Memcpy

	ldr r0, =Key_Item_Ram
	ldr r1, [r5]
	ldr r2, =Key_Item_Num * 2 * 4
	bl Memcpy

	ldr r0, =0x81331A4 | 1
	bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

BerryFix1Ptr:
	cmp r6, #0x1
	bls BerryFix1Return
	mov r0, r5
	bl GetItemPocket
	cmp r0, #0x5 @Berry Pouch
	bne BerryFix1Return
	ldr r0, =0x806BDFC | 1
	bx r0

BerryFix1Return:
	ldr r0, =0x806BE22 | 1
	bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@0x14A490 with r0
BerryFix2:
	cmp r6, #0x0
	beq BerryFix2Return
	mov r0, r4
	bl GetItemMystery2 @BerryId

BerryFix2Return:
	ldr r0, =0x814A4C2 | 1
	bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@0x13D33C with r0
BerryNumFixes:
	mov r0, r5
	bl GetItemMystery2
	mov r1, r0
	mov r0, r6
	mov r2, #0x2
	ldr r3, =0x813D344 | 1
	bx r3

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Calloc:
	ldr r1, =0x8002BB0 | 1
	bx r1

Memcpy:
	ldr r3, =0x81E5E78 | 1
	bx r3

RemoveNItems:
	ldr r2, =0x809A274 | 1
	bx r2

GetItemPocket:
	ldr r1, =0x809A9D8 | 1
	bx r1

GetItemMystery2:
	ldr r1, =0x809A9B4 | 1
	bx r1

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

.align 2
.ItemStorage2: .word Free_Ram
.Table: .word TABLE + rom
.PokeDudeItemBackupPtr: .word 0x203AD2C
.NewMallocPokeDudeBagSpace: .word (Regular_Item_Num + Key_Item_Num + Poke_Ball_Num) * 2 * 4
.SaveBlock1: .word 0x3005008

.align 2
TABLE:
.word Item_Ram
.hword Regular_Item_Num, 0x0

.word Key_Item_Ram
.hword Key_Item_Num, 0x0

.word Poke_Ball_Ram
.hword Poke_Ball_Num, 0x0

.word 0xFFFFFFFF, 0xFFFFFFFF
The above code is written in such a way that if you were to insert it as is, you would have support for:
  • 400 Regular Items
  • 60 Key Items
  • 28 Poke Balls
  • 128 TMs/HMs
  • 67 Berries
Obviously if you don't need this many items, you're free to change the ram locations and item amounts by modifying the lines at the top of the routine. If you try to expand any of these values, make sure you change the ram locations if necessary.

Important Note About Berries: If you plan on adding new berries to your game, each berry needs to modified in G3T's item editor. Under Mystery1/2, change the value in the second box (Mystery 2) to the berry number for that berry. For instance, the Oran Berry is number 7. All berry numbers can be found on Bulbapedia.
If you don't plan on expanding berries, in the code, change Berry_Num to 43 and remove the bolded section labeled BerryNumFixesHook. Otherwise all your berries will be displayed with a berry number of 0 (or, alternatively, you could assign each berry a number like mentioned above).
If you do expand the berries, they will remain in a sorted order based on their item id. In my upcoming battle engine, a fix will be provided for this (mainly because I didn't want to write a decent sorting algorithm in Assembly).

Insertion Instructions:
  1. Customize to your liking
  2. Assemble the routine
  3. Copy the output bin file (so you should have a file called something like output.bin - Copy and fill this copy with FFs
  4. Create a patch using your blank (filled with FFs) file as the unmodified file, and the output file as the modified file
  5. Patch your rom

This has been confirmed to work with a vanilla Fire Red. However, I can't guarantee it will work with all roms in progress.


Credits
__________________
Pokemon Unbound

Reply With Quote
  #1247   Link to this post, but load the entire thread.  
Old September 5th, 2017 (10:52 AM).
Enn's Avatar
Enn Enn is offline
 
Join Date: Jan 2017
Gender: Male
Posts: 185
Alright I'm making a request!
Everyone has probably heard about Bank system...
On which can allow the player to store his money, loans, interest (ofc in support with primes RTC) and other cool banking stuff.
PS this thread has helped me a lot thanks "A free helper" Blah ;) !
Reply With Quote
  #1248   Link to this post, but load the entire thread.  
Old September 5th, 2017 (7:59 PM).
BluRose BluRose is offline
blu rass
 
Join Date: Apr 2014
Location: michigan tech
Age: 22
Gender: Male
Nature: Timid
Posts: 812
Quote:
Originally Posted by Nisarg View Post
Alright I'm making a request!
Everyone has probably heard about Bank system...
On which can allow the player to store his money, loans, interest (ofc in support with primes RTC) and other cool banking stuff.
PS this thread has helped me a lot thanks "A free helper" Blah ;) !
read the op please &lt;3
__________________
heyo check out my github:

BluRosie
highlights:
battle engine for heartgold
various feature branches in heart gold (fairy type, odd egg, mud slopes)

i'm a big part of the development team of pokemon firegold! all the code that i develop for that hack is also on my github

also on discord: BluRose#0412
Reply With Quote
  #1249   Link to this post, but load the entire thread.  
Old September 16th, 2017 (6:35 AM).
Enn's Avatar
Enn Enn is offline
 
Join Date: Jan 2017
Gender: Male
Posts: 185
Aight, this request is similar to shinyquagsire's berry selection screen...
I need an asm which can show the party screen and on selecting the pokemon, exits and stores data in a var...
However theres a twist, im not talking about special 0x9f...
The mons need to be read from Ram where PSS stored the mons... So now y'all get it why its so complex...
If that is to be pulled off, it'd be amazing;)
Reply With Quote
  #1250   Link to this post, but load the entire thread.  
Old September 17th, 2017 (9:33 AM).
BluRose BluRose is offline
blu rass
 
Join Date: Apr 2014
Location: michigan tech
Age: 22
Gender: Male
Nature: Timid
Posts: 812
Quote:
Originally Posted by Nisarg View Post
Aight, this request is similar to shinyquagsire's berry selection screen...
I need an asm which can show the party screen and on selecting the pokemon, exits and stores data in a var...
However theres a twist, im not talking about special 0x9f...
The mons need to be read from Ram where PSS stored the mons... So now y'all get it why its so complex...
If that is to be pulled off, it'd be amazing;)
legit take the routine for special 0x9F
replace the part where it accesses your party with the new ram address. this likely just involves replacing an address from the routine, literally nothing more. callasm the new special and ezpz
__________________
heyo check out my github:

BluRosie
highlights:
battle engine for heartgold
various feature branches in heart gold (fairy type, odd egg, mud slopes)

i'm a big part of the development team of pokemon firegold! all the code that i develop for that hack is also on my github

also on discord: BluRose#0412
Reply With Quote
Reply

Quick Reply

Join the conversation!

Create an account to post a reply in this thread, participate in other discussions, and more!

Create a PokéCommunity Account
Ad Content

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


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