The PokéCommunity Forums Fan Games ROM Hacking Research & Development
Research [Ruby] Changing a Pokemon's species without ruining the checksum

Research & Development Got a well-founded knack with ROM hacking? Love reverse-engineering the Pokémon games? Or perhaps you love your assembly language. 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!

Reply
 
Thread Tools
  #1    
Old April 29th, 2012 (8:52 PM). Edited April 29th, 2012 by Chaos Rush.
Chaos Rush's Avatar
Chaos Rush Chaos Rush is offline
im sexy and i know it
     
    Join Date: May 2007
    Location: Taylor Swift
    Gender: Male
    Nature: Adamant
    Posts: 1,296
    Okay, this is my first ASM-related thing. Basically, I have figured out how to alter a Pokemon's index number, while not letting it turn into a bad egg.

    First of all, in a Ruby rom, place this routine somewhere. We'll call this "JPAN Routine 1":
    Spoiler:
    Code:
    .text
    .align 2
    .thumb
    .thumb_func
    .global newroutine
    
    main:
    PUSH {R0-R7,LR}
    LDR R5, var_8004
    LDRH R5, [R5, #0x0]
    LDR R4, party_addr
    MOV R6, #0x64
    LDR R7, New_poke_addr
    MUL R5, R6
    ADD R4, R4, R5
    B decrypt
    .hword 0x0000
    var_8004: .word 0x0202E8CC
    party_addr: .word 0x03004360
    New_poke_addr: .word 0x0203F400
    
    decrypt:
    LDR R0, [R4, #0x0]
    PUSH {R0}
    LDR R1, [R4,#0x4]
    EOR R1, R0
    STR R1, [R7, #0x0]
    LDRH R1, [R4, #0x1C]
    STRH R1, [R7, #0x6]
    MOV R2, #0x20
    ADD R0, R2, R4
    MOV R2, #0x18
    ADD R1, R2, R7
    MOV R2, #0xC
    LDR R5, [R7, #0x0]
    
    decrypt_loop: 
    LDR R3, [R0, #0x0]
    EOR R3, R5
    STR R3, [R1, #0x0]
    ADD R1, #0x4
    ADD R0, #0x4
    SUB R2, #0x1
    CMP R2, #0x0
    BNE decrypt_loop
    POP {R0}
    MOV R1, #0x18
    MOV R2, #0xC0
    LSL R2, R2, #0x18
    CMP R2, R0
    BHI lower_than_c
    SUB R0, R0, R2
    
    lower_than_c: 
    LSR R2, R2, #0x1
    CMP R2, R0
    BCS lower_than_6
    SUB R0, R0, R2
    LSL R0, R0, #0x0
    
    lower_than_6: 
    SWI #0x6
    ADD R0, R1, #0x0
    MOV R1, #6
    SWI #0x6
    
    g_in_first: 
    CMP R0, #0x0
    BNE g_in_second
    MOV R2, #0x18
    B g_final
    
    g_in_second: 
    CMP r1, #0x1
    BGT g_in_third
    MOV R2, #0x24
    B g_final
    
    g_in_third: 
    MOV R2, #1
    AND R2, R1
    CMP R2, #1
    BEQ g_in_fourth
    MOV R2, #0x30
    B g_final
    
    g_in_fourth: 
    MOV R2, #0x3C
    
    g_final: 
    ADD R2, R7, R2
    STR R2, [R7, #0x8]
    
    m_in_first: 
    CMP R0, #0x3
    BNE m_in_second
    MOV R2, #0x18
    B m_final
    
    m_in_second: 
    CMP R1, #0x4
    BLT m_in_third
    MOV R2, #0x24
    B m_final
    
    m_in_third: 
    MOV R2, #0x1
    AND R2, R1
    CMP R2, #0x1
    BNE m_in_fourth
    MOV R2, #0x30
    B m_final
    
    m_in_fourth: 
    MOV R2, #0x3C
    
    m_final: 
    ADD R2, R7, R2
    STR R2, [R7,#0x14]
    a_first: CMP R0, #0x1
    BGT a_second
    CMP R0, #0x0
    BEQ a_lesser_second
    MOV R2, #0x18
    B a_final
    
    a_second: 
    MOV R3, #0x2
    BEQ a_greater_second
    CMP R1, #0x3
    BEQ a_greater_second
    CMP R1, #0x0
    BEQ a_greater_third
    CMP R1, #0x5
    BEQ a_greater_third
    MOV R2, #0x3C
    B a_final
    
    a_greater_second: 
    MOV R2, #0x24
    B a_final
    
    a_greater_third: 
    MOV R2, #0x30
    B a_final
    
    a_lesser_second: 
    CMP R1, #0x1
    BGT a_lesser_third
    MOV R2, #0x24
    B a_final
    
    a_lesser_third: 
    MOV R2, #0x1
    AND R2, R1
    CMP R2, #0x2
    BNE a_lesser_fourth
    MOV R2, #0x30
    B a_final
    
    a_lesser_fourth: 
    MOV R2, #0x3C
    
    a_final: 
    ADD R2, R7, R2
    STR R2, [R7,#0xC]
    
    e_first: 
    CMP R0, #0x2
    BLT e_second
    CMP R0, #0x2
    BGT e_greater_second
    MOV R2, #0x18
    B e_final
    
    e_second: 
    CMP R1, #0x2
    BEQ e_lesser_second
    CMP R1, #0x3
    BEQ e_lesser_second
    CMP R1, #0x0
    BEQ e_lesser_third
    CMP R1, #0x5
    BEQ e_lesser_third
    MOV R2, #0x3C
    B e_final
    
    e_lesser_second: 
    MOV R2, #0x24
    B e_final
    
    e_lesser_third: 
    MOV R2, #0x30
    B e_final
    
    e_greater_second: 
    CMP R1, #0x5
    BLT e_greater_third
    MOV R2, #0x24
    B e_final
    
    e_greater_third: 
    MOV R2, #1
    AND R2, R1
    CMP R2, #0
    BEQ e_greater_fourth
    MOV R2, #0x30
    B e_final
    
    e_greater_fourth: 
    MOV R2, #0x3C
    
    e_final: 
    ADD R2, R7, R2
    STR R2, [R7,#0x10]
    POP {R0-R7,PC}

    It is a modified version of JPAN's decryption routine, which I changed so that it works with Ruby.



    Next, put this next code somewhere in the rom. It is also by JPAN, so we'll call it, "JPAN Routine 2":
    Spoiler:

    Code:
    .text
    .align 2
    .thumb
    .thumb_func
    .global nextroutine
    
    main: 
    push {r0-r7, lr}
    ldr r5, var_8004
    ldrh r5, [r5, #0x0]
    ldr r4, Party_addr
    mov r6, #0x64
    ldr r7, new_store_addr
    mul r5, r6
    add r4, r4, r5
    b calc_checksum
    .hword 0x0000
    var_8004: .word 0x0202E8CC
    Party_addr: .word 0x03004360
    new_store_addr: .word 0x0203f400
    
    calc_checksum: 
    mov r2, #0x1c
    add r0, r4, r2
    mov r2, #0x18
    add r1, r7, r2
    mov r5, #0x0
    
    checksum_add: 
    ldrh r3, [r1, #0x0]
    add r5, r3, r5
    add r1, #0x2
    sub r2, #0x1
    cmp r2, #0x0
    bhi checksum_add
    lsl r5, r5, #0x10
    lsr r5, r5, #0x10
    strh r5, [r0, #0x0]
    sub r1, #0x30
    add r0, #0x4
    mov r2, #0xc
    ldr r5, [r7, #0x0]
    
    store_loop: 
    ldr r3, [r1, #0x0]
    eor r3, r5
    str r3, [r0, #0x0]
    add r0, #0x4
    add r1, #0x4
    sub r2, #0x1
    cmp r2, #0x0
    bhi store_loop
    pop {r0-r7, pc}

    Both of the routines above were written by JPAN, I just modified it so that it works on Pokemon Ruby.




    However, here is a custom routine made by me (and might I say, my first ASM routine ever). Insert this into free space:
    Code:
    .text
    .align 2
    .thumb
    .thumb_func
    .global newroutine
    
    main:
     push {r0-r3, lr}
     ldr r0, .POOP
     ldr r0, [r0]
     ldr r1, .var_8005
     ldrh r3, [r1]
     mov r1, r3
     str r1, [r0]
     strh r1, [r0]
     pop {r0-r3,pc}
    
    .align 2
    .POOP:
    	.word 0x0203f408
    .var_8005:
    	.word 0x0202E8CE
    What this routine does is, is changes the first Pokemon of your party to whatever value you stored in 0x8005. It only works however, if you called JPAN's first routine before it, and if you call JPAN's second routine after my routine.

    Now that you've inserted JPAN's routines and my own routine, here is how you apply them: In any script (like a signpost), place this:
    Code:
    callasm 0x(offset of JPAN Routine 1, +1)
    setvar 0x8005 0x(index number of the Pokemon that it will change into)
    callasm 0x(offset of my routine, +1)
    callasm 0x(offset of JPAN Routine 2, +1)
    end
    Now you can easily alter the first Pokemon of your party to anything you want. For example, this is what my signpost looks like:
    Spoiler:
    Code:
    '---------------
    #org 0x14D808
    callasm 0x8C00001
    setvar 0x8005 0x9
    callasm 0x8C001C1
    callasm 0x8C00141
    msgbox 0x816AE50 MSG_SIGN '"I just changed the first Pokémon\n..."
    end
    
    
    '---------
    ' Strings
    '---------
    #org 0x16AE50
    = I just changed the first Pokémon\nof your party into a Blastoise.\lDeal with it.

    This will change the first Pokemon of my party into Blastoise (0x9 is Blastoise's hex number). Let's try it out.





    The reason why this might be useful is that I can now do form changes in my 649 Project, and I can "fake" more than 5 evolutions by having certain Pokemon switch into a different index number (but identical stat-wise), such as a second Eevee that can evolve into Leafeon or Glaceon. Hopefully this is useful to some other people as well.
    __________________

    My projects:
    Untitled Pokémon fangame (pictured above) | Final Fantasy II NES retranslation | Mother 1/EarthBound Beginnings Color Restoration for GBA
    Non-Pokémon hacks I support:
    Sonic Classic Heroes
    Sonic 3 Complete
    Reply With Quote

    Relevant Advertising!

      #2    
    Old July 20th, 2012 (8:44 PM).
    ShinyDragonHunter ShinyDragonHunter is offline
       
      Join Date: Nov 2010
      Gender: Male
      Nature: Calm
      Posts: 29
      This is a bit of a noob question.
      How do I input ASM code and stuff? Can you use a script editor like XSE?
      Reply With Quote
        #3    
      Old July 21st, 2012 (5:17 AM).
      Ark_Silvanos's Avatar
      Ark_Silvanos Ark_Silvanos is offline
         
        Join Date: Jan 2009
        Location: Texas
        Age: 25
        Gender: Male
        Posts: 150
        Quote:
        Originally Posted by ShinyDragonHunter View Post
        This is a bit of a noob question.
        How do I input ASM code and stuff? Can you use a script editor like XSE?
        You need an assembler. HackMew's got a tutorial on this here.


        also, in order for this not to become irrelevant:

        This is actually a pretty useful routine. I'll probably use it in my hack after changing it to fire-red, is that alright?

        and this is just a suggestion, but why not do like JPAN did and assemble the routine yourself so people can insert it easier?
        __________________


        Reply With Quote
          #4    
        Old July 21st, 2012 (7:04 AM).
        Chaos Rush's Avatar
        Chaos Rush Chaos Rush is offline
        im sexy and i know it
           
          Join Date: May 2007
          Location: Taylor Swift
          Gender: Male
          Nature: Adamant
          Posts: 1,296
          Quote:
          Originally Posted by Ark_Silvanos View Post
          I'll probably use it in my hack after changing it to fire-red, is that alright?
          There is absolutely no point in doing that, since I converted it from FireRed to Ruby. Meaning the original code was for FireRed. You could just use JPAN's original code (which I linked to), because it was for FireRed.

          Quote:
          and this is just a suggestion, but why not do like JPAN did and assemble the routine yourself so people can insert it easier?
          People need to learn how to insert ASM routines. ShinyDragonHunter is a perfect example of this.
          __________________

          My projects:
          Untitled Pokémon fangame (pictured above) | Final Fantasy II NES retranslation | Mother 1/EarthBound Beginnings Color Restoration for GBA
          Non-Pokémon hacks I support:
          Sonic Classic Heroes
          Sonic 3 Complete
          Reply With Quote
            #5    
          Old July 21st, 2012 (7:21 AM).
          Ark_Silvanos's Avatar
          Ark_Silvanos Ark_Silvanos is offline
             
            Join Date: Jan 2009
            Location: Texas
            Age: 25
            Gender: Male
            Posts: 150
            Quote:
            Originally Posted by Chaos Rush View Post
            There is absolutely no point in doing that, since I converted it from FireRed to Ruby. Meaning the original code was for FireRed. You could just use JPAN's original code (which I linked to), because it was for FireRed.
            lol no i meant changing the address for var 8005 in ur routine... i dont wanna write one for myself since u've already done it
            __________________


            Reply With Quote
              #6    
            Old June 30th, 2014 (6:41 PM).
            Lancekoijer32497's Avatar
            Lancekoijer32497 Lancekoijer32497 is offline
               
              Join Date: May 2014
              Gender: Male
              Posts: 57
              How if, if I want Charizard not blastoise, how is that now?
              Reply With Quote
                #7    
              Old July 1st, 2014 (12:25 PM). Edited July 1st, 2014 by Frosty~.
              Frosty~'s Avatar
              Frosty~ Frosty~ is offline
              Pancakes are a girl's BFF
                 
                Join Date: Nov 2009
                Gender: Female
                Nature: Hasty
                Posts: 44
                Quote:
                Originally Posted by Lancekoijer32497 View Post
                How if, if I want Charizard not blastoise, how is that now?
                Just change the index number. Blastoise's is 0x9, I'm pretty sure Charizard's is 0x6. There are lots of places with lists of a Pokemon's index number.
                __________________
                "The world's changing at lightning speed,
                but the faster you move the narrower your vision becomes.
                That's why you've got to stop and look around you.
                Other wise you'll lose yourself."
                - Megaman

                My deviantArt
                Reply With Quote
                  #8    
                Old July 2nd, 2014 (6:09 PM).
                Lancekoijer32497's Avatar
                Lancekoijer32497 Lancekoijer32497 is offline
                   
                  Join Date: May 2014
                  Gender: Male
                  Posts: 57
                  Quote:
                  Originally Posted by Frosty~ View Post
                  Just change the index number. Blastoise's is 0x9, I'm pretty sure Charizard's is 0x6. There are lots of places with lists of a Pokemon's index number.
                  In what part of the Asm Ill edit?
                  Reply With Quote
                    #9    
                  Old July 2nd, 2014 (9:07 PM).
                  destinedjagold's Avatar
                  destinedjagold destinedjagold is offline
                  Oh Hai Thar~
                  • Silver Tier
                   
                  Join Date: May 2007
                  Location: Philippines
                  Age: 26
                  Gender: Male
                  Nature: Careful
                  Posts: 8,507
                  Quote:
                  Originally Posted by Lancekoijer32497 View Post
                  In what part of the Asm Ill edit?
                  I believe you'll only need to edit the script in the example.
                  In the first post, the example script is...
                  Code:
                  #dynamic 0x800000
                  
                  #org @start
                  callasm 0x8C00001
                  setvar 0x8005 0x9
                  callasm 0x8C001C1
                  callasm 0x8C00141
                  msgbox @talk 0x4
                  end
                  
                  #org @talk
                  = I just changed the first Pokémon\nof your party into a Blastoise.\lDeal with it.
                  See the red part. That's Blastoise's hex number.
                  So if you want to have Charizard, just change that red part into 0x6, since that's Charizard's hex number in the game.
                  __________________


                  FC: 0061-1111-6462
                  TSV: 1364(X), 0790(OR)

                  Reply With Quote
                    #10    
                  Old July 3rd, 2014 (1:12 AM).
                  Phenom2122's Avatar
                  Phenom2122 Phenom2122 is offline
                     
                    Join Date: Jun 2014
                    Gender: Male
                    Nature: Quiet
                    Posts: 45
                    I can see very many interesting uses coming from this.. I would just like to say, it would be nice if you could specify certain stat changes as well if you want. Then it could be used with formes?
                    Reply With Quote
                      #11    
                    Old July 3rd, 2014 (3:59 AM).
                    Lancekoijer32497's Avatar
                    Lancekoijer32497 Lancekoijer32497 is offline
                       
                      Join Date: May 2014
                      Gender: Male
                      Posts: 57
                      Quote:
                      Originally Posted by Phenom2122 View Post
                      I can see very many interesting uses coming from this.. I would just like to say, it would be nice if you could specify certain stat changes as well if you want. Then it could be used with formes?
                      thanks then .........

                      Now Ill continue on ASMing
                      Reply With Quote
                        #12    
                      Old July 3rd, 2014 (4:09 AM).
                      Lancekoijer32497's Avatar
                      Lancekoijer32497 Lancekoijer32497 is offline
                         
                        Join Date: May 2014
                        Gender: Male
                        Posts: 57
                        Quote:
                        Originally Posted by destinedjagold View Post
                        I believe you'll only need to edit the script in the example.
                        In the first post, the example script is...
                        Code:
                        #dynamic 0x800000
                        
                        #org @start
                        callasm 0x8C00001
                        setvar 0x8005 0x9
                        callasm 0x8C001C1
                        callasm 0x8C00141
                        msgbox @talk 0x4
                        end
                        
                        #org @talk
                        = I just changed the first Pokémon\nof your party into a Blastoise.\lDeal with it.
                        See the red part. That's Blastoise's hex number.
                        So if you want to have Charizard, just change that red part into 0x6, since that's Charizard's hex number in the game.
                        thanks then.
                        .

                        Ill start ASMing now
                        Reply With Quote
                          #13    
                        Old July 3rd, 2014 (4:24 AM).
                        Derlo's Avatar
                        Derlo Derlo is offline
                        Working on Essence of light...
                           
                          Join Date: Aug 2007
                          Posts: 127
                          How I manage to use it in FR?
                          __________________



                          Pokémon
                          Essence of Light

                          Comming Soon...
                          Reply With Quote
                          Reply
                          Quick Reply

                          Sponsored Links
                          Thread Tools

                          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 6:36 PM.