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
  #26    
Old August 7th, 2010 (6:08 PM). Edited August 7th, 2010 by JPAN.
JPAN JPAN is offline
pokemon rom researcher
     
    Join Date: Dec 2008
    Posts: 104

    The disobedience check is part of the BattleScript commands, namely command 0, that checks what the pokemon will do. The actual obedience check is at 0801D438, covering all types of disobedience. The code checks for the obedience flag first, then proceeds to check for badges and levels. I'll post here the relevant piece of code for this matter:

    Spoiler:
    Code:
    ROM:0801D460                 BL      Disobey_byte_check     ;decompiled below, the code that was talked about earlier
    ROM:0801D464                 CMP     R0, #0
    ROM:0801D466                 BEQ     loc_801D4BE
    ROM:0801D468                 LDR     R2, =0x2023BE4
    ROM:0801D46A                 LDRB    R1, [R4]
    ROM:0801D46C                 MOVS    R0, #0x58
    ROM:0801D46E                 MULS    R1, R0
    ROM:0801D470                 MOVS    R0, R2
    ROM:0801D472                 ADDS    R0, #0x54
    ROM:0801D474                 ADDS    R0, R1, R0
    ROM:0801D476                 LDR     R0, [R0]
    ROM:0801D478                 ADDS    R2, #0x3C
    ROM:0801D47A                 ADDS    R1, R1, R2

    ROM:0801D47C BL Compare_trainer_values ;compares your trainer IDS with the pokemon trainer IDS ROM:0801D480 LSLS R0, R0, #0x18 ROM:0801D482 CMP R0, #0 ROM:0801D484 BEQ loc_801D4F4 ;the same, is obedient ;from here on it's the badge checks. R6 is the maximum level the pokemon may have ROM:0801D486 LDR R0, =0x827 ROM:0801D488 BL Check_active_flag ROM:0801D48C LSLS R0, R0, #0x18 ROM:0801D48E CMP R0, #0 ROM:0801D490 BNE loc_801D4F4 ;earthbadge on = obedience

    ROM:0801D492 MOVS R6, #0xA ROM:0801D494 LDR R0, =0x821 ROM:0801D496 BL Check_active_flag ROM:0801D49A LSLS R0, R0, #0x18 ROM:0801D49C CMP R0, #0 ROM:0801D49E BEQ loc_801D4A2

    ROM:0801D4A0 MOVS R6, #0x1E ROM:0801D4A2 ROM:0801D4A2 loc_801D4A2 ; CODE XREF: Disobedience_check+66j ROM:0801D4A2 LDR R0, =0x823 ROM:0801D4A4 BL Check_active_flag ROM:0801D4A8 LSLS R0, R0, #0x18 ROM:0801D4AA CMP R0, #0 ROM:0801D4AC BEQ loc_801D4B0

    ROM:0801D4AE MOVS R6, #0x32 ROM:0801D4B0 ROM:0801D4B0 loc_801D4B0 ; CODE XREF: Disobedience_check+74j ROM:0801D4B0 LDR R0, =0x825 ROM:0801D4B2 BL Check_active_flag ROM:0801D4B6 LSLS R0, R0, #0x18 ROM:0801D4B8 CMP R0, #0 ROM:0801D4BA BEQ loc_801D4BE

    ROM:0801D4BC MOVS R6, #0x46 ROM:0801D4BE ROM:0801D4BE loc_801D4BE ; CODE XREF: Disobedience_check+2Ej ROM:0801D4BE ; Disobedience_check+82j ROM:0801D4BE LDR R5, =0x2023BE4 ROM:0801D4C0 LDR R0, =0x2023D6B ROM:0801D4C2 MOV R8, R0 ROM:0801D4C4 LDRB R0, [R0] ROM:0801D4C6 MOVS R7, #0x58 ROM:0801D4C8 MULS R0, R7 ROM:0801D4CA ADDS R0, R0, R5 ROM:0801D4CC ADDS R0, #0x2A ROM:0801D4CE LDRB R0, [R0] ;gets pokemon current level ROM:0801D4D0 CMP R0, R6 ROM:0801D4D2 BLS loc_801D4F4 ;if current level <= max level, is obedient

    ROM:0801D4D4 BL RNG_halfword ROM:0801D4D8 MOVS R1, #0xFF ROM:0801D4DA ANDS R1, R0 ROM:0801D4DC MOV R2, R8 ROM:0801D4DE LDRB R0, [R2] ROM:0801D4E0 MOVS R2, R0 ROM:0801D4E2 MULS R2, R7 ROM:0801D4E4 ADDS R0, R2, R5 ROM:0801D4E6 ADDS R0, #0x2A ROM:0801D4E8 LDRB R0, [R0] ROM:0801D4EA ADDS R0, R0, R6 ROM:0801D4EC MULS R0, R1 ROM:0801D4EE ASRS R4, R0, #8 ROM:0801D4F0 CMP R4, R6 ROM:0801D4F2 BGE loc_801D518 ROM:0801D4F4 ROM:0801D4F4 loc_801D4F4 ; CODE XREF: Disobedience_check+14j ROM:0801D4F4 ; Disobedience_check+24j ... ROM:0801D4F4 MOVS R0, #0 ROM:0801D4F6 B loc_801D738

    Code:
    Disobey_byte_check                      ; CODE XREF: Disobedience_check+28p
    ROM:0801D3C0                 PUSH    {R4-R7,LR}
    ROM:0801D3C2                 LSLS    R0, R0, #0x18
    ROM:0801D3C4                 LSRS    R4, R0, #0x18
    ROM:0801D3C6                 MOVS    R0, R4
    ROM:0801D3C8                 BL      sub_80751C4
    ROM:0801D3CC                 LSLS    R0, R0, #0x18
    ROM:0801D3CE                 LSRS    R0, R0, #0x18
    ROM:0801D3D0                 CMP     R0, #1
    ROM:0801D3D2                 BEQ     loc_801D406
    ROM:0801D3D4                 LDR     R0, =0x2023BCE
    ROM:0801D3D6                 LSLS    R4, R4, #1
    ROM:0801D3D8                 ADDS    R5, R4, R0
    ROM:0801D3DA                 LDRH    R0, [R5]
    ROM:0801D3DC                 MOVS    R7, #0x64
    ROM:0801D3DE                 MULS    R0, R7
    ROM:0801D3E0                 LDR     R6, =0x2024284
    ROM:0801D3E2                 ADDS    R0, R0, R6
    ROM:0801D3E4                 MOVS    R1, #0xB
    ROM:0801D3E6                 MOVS    R2, #0
    ROM:0801D3E8                 BL      get_party_status     ;get pokemon species
    ROM:0801D3EC                 MOVS    R1, 0x19A            ;compares with deoxys
    ROM:0801D3F0                 CMP     R0, R1
    ROM:0801D3F2                 BEQ     loc_801D414         ; if so, check obedience flag

    ROM:0801D3F4 LDRH R0, [R5] ROM:0801D3F6 MULS R0, R7 ROM:0801D3F8 ADDS R0, R0, R6 ROM:0801D3FA MOVS R1, #0xB ROM:0801D3FC MOVS R2, #0 ROM:0801D3FE BL get_party_status ; redundant, checks your pokemon again for its species ROM:0801D402 CMP R0, #0x97 ROM:0801D404 BEQ loc_801D414 ;if mew, check for obedience ROM:0801D406 ROM:0801D406 loc_801D406 ; CODE XREF: Disobey_byte_check+12j ROM:0801D406 MOVS R0, #1 ROM:0801D408 B loc_801D42A ; is obedient, end ROM:0801D408 ; --------------------------------------------------------------------------- ROM:0801D40A DCB 0 ROM:0801D40B DCB 0 ROM:0801D40C dword_801D40C DCD 0x2023BCE ; DATA XREF: Disobey_byte_check+14r ROM:0801D410 dword_801D410 DCD 0x2024284 ; DATA XREF: Disobey_byte_check+20r ROM:0801D414 ; --------------------------------------------------------------------------- ROM:0801D414 ROM:0801D414 loc_801D414 ; CODE XREF: Disobey_byte_check+32j ROM:0801D414 ; Disobey_byte_check+44j ROM:0801D414 LDR R0, =0x2023BCE ROM:0801D416 ADDS R0, R4, R0 ROM:0801D418 LDRH R1, [R0] ROM:0801D41A MOVS R0, #0x64 ROM:0801D41C MULS R0, R1 ROM:0801D41E LDR R1, =0x2024284 ROM:0801D420 ADDS R0, R0, R1 ROM:0801D422 MOVS R1, #0x50 ROM:0801D424 MOVS R2, #0 ROM:0801D426 BL get_party_status ;checks last ribbon, that is the obedience flag, and returns it ROM:0801D42A ROM:0801D42A loc_801D42A ; CODE XREF: Disobey_byte_check+48j ROM:0801D42A POP {R4-R7} ROM:0801D42C POP {R1} ROM:0801D42E BX R1

    0801D4D4 checks one last time if, by chance, the attack will go trough. If not it will proceed to 0x0801d518, where what will the pokemon actually do\say is calculated.
    So, several modifications can be made here to change the level a pokemon will become disobedient and in what conditions will it become disobedient.
    The location of the obedience flag is actually in the last part of the Ribbon data in the Misc block, the topmost flag (bit 31 of the Ribbon word), but it's only useful for the species listed on the disobedience byte. And as for why Mew\Deoxys only disobey, it's because the chance of attack is determined by a random number (from 0-ff) to be smaller than the max level (that in the byte case is 0).

    Edit: If I understood correctly, the code needed here is one that, if a pokemon doesn't have the flag, the pokemon has some chances of attacking, instead of just laying around all the time. With that in mind, I made a code for the occasion

    Spoiler:
    Code:
    .align 2
    .thumb
    /*to use this code, place 00 49 08 47 at 0x0801d3f4, and the reversed pointer to  where
    you put this code at 0x0801d3f8*/
        cmp r0, #0x5
        beq disobey_or_not
        cmp r0, #0x6
        beq disobey_or_not    /*add more checks here for other pokemon*/
        ldr r1, mew_check
        bx r1
    mew_check:   .word 0x0801D403
    disobey_or_not: ldr r1, random_addr
        ldrb r1, [r1]
        mov r0, #0xb4 /*change here the "perform attack" chance. percentage  is r0 divided by 256 times 100 */
        cmp r1, r0 /*aprox 70% chance of not performing an attack*/
        bgt is_obedient
        ldr r0, disobedient_ret_addr
        bx r0
    is_obedient:   mov r0, #0x1
        pop {r4-r7,pc}
    .hword 0x0000
    random_addr: .word 0x03005000
    disobedient_ret_addr: .word 0x0801d415

    The trick in that code is that the pokemon will act as if it was obedient every once in a while thanks to the random number stored at 0x03005000.

    __________________

    Here are the links for my work

    Currently working on:
    Battle Script Documentation
    Another large project

    Reply With Quote

    Relevant Advertising!

      #27    
    Old August 7th, 2010 (7:49 PM). Edited August 8th, 2010 by metapod23.
    metapod23's Avatar
    metapod23 metapod23 is offline
    Hardened Trainer
       
      Join Date: Mar 2009
      Gender: Male
      Nature: Timid
      Posts: 673

      ^ That's an interesting code, JPAN. I might have to try it out. I think it might be useful to have the disobedient Pokemon attack every once in a while. I'll add it to the main page, too.

      Oh, and colcolstyles, I'm so pleased with routine you made that I added you to the credits of my hack. I just want you to know that it's appreciated. Thanks again!

      Quote:
      Originally Posted by JPAN View Post
      The disobedience check is part of the BattleScript commands, namely command 0, that checks what the pokemon will do. The actual obedience check is at 0801D438, covering all types of disobedience. The code checks for the obedience flag first, then proceeds to check for badges and levels. I'll post here the relevant piece of code for this matter:
      Spoiler:
      Code:
      ROM:0801D460                 BL      Disobey_byte_check     ;decompiled below, the code that was talked about earlier
      ROM:0801D464                 CMP     R0, #0
      ROM:0801D466                 BEQ     loc_801D4BE
      ROM:0801D468                 LDR     R2, =0x2023BE4
      ROM:0801D46A                 LDRB    R1, [R4]
      ROM:0801D46C                 MOVS    R0, #0x58
      ROM:0801D46E                 MULS    R1, R0
      ROM:0801D470                 MOVS    R0, R2
      ROM:0801D472                 ADDS    R0, #0x54
      ROM:0801D474                 ADDS    R0, R1, R0
      ROM:0801D476                 LDR     R0, [R0]
      ROM:0801D478                 ADDS    R2, #0x3C
      ROM:0801D47A                 ADDS    R1, R1, R2

      ROM:0801D47C BL Compare_trainer_values ;compares your trainer IDS with the pokemon trainer IDS ROM:0801D480 LSLS R0, R0, #0x18 ROM:0801D482 CMP R0, #0 ROM:0801D484 BEQ loc_801D4F4 ;the same, is obedient ;from here on it's the badge checks. R6 is the maximum level the pokemon may have ROM:0801D486 LDR R0, =0x827 ROM:0801D488 BL Check_active_flag ROM:0801D48C LSLS R0, R0, #0x18 ROM:0801D48E CMP R0, #0 ROM:0801D490 BNE loc_801D4F4 ;earthbadge on = obedience

      ROM:0801D492 MOVS R6, #0xA ROM:0801D494 LDR R0, =0x821 ROM:0801D496 BL Check_active_flag ROM:0801D49A LSLS R0, R0, #0x18 ROM:0801D49C CMP R0, #0 ROM:0801D49E BEQ loc_801D4A2

      ROM:0801D4A0 MOVS R6, #0x1E ROM:0801D4A2 ROM:0801D4A2 loc_801D4A2 ; CODE XREF: Disobedience_check+66j ROM:0801D4A2 LDR R0, =0x823 ROM:0801D4A4 BL Check_active_flag ROM:0801D4A8 LSLS R0, R0, #0x18 ROM:0801D4AA CMP R0, #0 ROM:0801D4AC BEQ loc_801D4B0

      ROM:0801D4AE MOVS R6, #0x32 ROM:0801D4B0 ROM:0801D4B0 loc_801D4B0 ; CODE XREF: Disobedience_check+74j ROM:0801D4B0 LDR R0, =0x825 ROM:0801D4B2 BL Check_active_flag ROM:0801D4B6 LSLS R0, R0, #0x18 ROM:0801D4B8 CMP R0, #0 ROM:0801D4BA BEQ loc_801D4BE

      ROM:0801D4BC MOVS R6, #0x46 ROM:0801D4BE ROM:0801D4BE loc_801D4BE ; CODE XREF: Disobedience_check+2Ej ROM:0801D4BE ; Disobedience_check+82j ROM:0801D4BE LDR R5, =0x2023BE4 ROM:0801D4C0 LDR R0, =0x2023D6B ROM:0801D4C2 MOV R8, R0 ROM:0801D4C4 LDRB R0, [R0] ROM:0801D4C6 MOVS R7, #0x58 ROM:0801D4C8 MULS R0, R7 ROM:0801D4CA ADDS R0, R0, R5 ROM:0801D4CC ADDS R0, #0x2A ROM:0801D4CE LDRB R0, [R0] ;gets pokemon current level ROM:0801D4D0 CMP R0, R6 ROM:0801D4D2 BLS loc_801D4F4 ;if current level <= max level, is obedient

      ROM:0801D4D4 BL RNG_halfword ROM:0801D4D8 MOVS R1, #0xFF ROM:0801D4DA ANDS R1, R0 ROM:0801D4DC MOV R2, R8 ROM:0801D4DE LDRB R0, [R2] ROM:0801D4E0 MOVS R2, R0 ROM:0801D4E2 MULS R2, R7 ROM:0801D4E4 ADDS R0, R2, R5 ROM:0801D4E6 ADDS R0, #0x2A ROM:0801D4E8 LDRB R0, [R0] ROM:0801D4EA ADDS R0, R0, R6 ROM:0801D4EC MULS R0, R1 ROM:0801D4EE ASRS R4, R0, #8 ROM:0801D4F0 CMP R4, R6 ROM:0801D4F2 BGE loc_801D518 ROM:0801D4F4 ROM:0801D4F4 loc_801D4F4 ; CODE XREF: Disobedience_check+14j ROM:0801D4F4 ; Disobedience_check+24j ... ROM:0801D4F4 MOVS R0, #0 ROM:0801D4F6 B loc_801D738

      Code:
      Disobey_byte_check                      ; CODE XREF: Disobedience_check+28p
      ROM:0801D3C0                 PUSH    {R4-R7,LR}
      ROM:0801D3C2                 LSLS    R0, R0, #0x18
      ROM:0801D3C4                 LSRS    R4, R0, #0x18
      ROM:0801D3C6                 MOVS    R0, R4
      ROM:0801D3C8                 BL      sub_80751C4
      ROM:0801D3CC                 LSLS    R0, R0, #0x18
      ROM:0801D3CE                 LSRS    R0, R0, #0x18
      ROM:0801D3D0                 CMP     R0, #1
      ROM:0801D3D2                 BEQ     loc_801D406
      ROM:0801D3D4                 LDR     R0, =0x2023BCE
      ROM:0801D3D6                 LSLS    R4, R4, #1
      ROM:0801D3D8                 ADDS    R5, R4, R0
      ROM:0801D3DA                 LDRH    R0, [R5]
      ROM:0801D3DC                 MOVS    R7, #0x64
      ROM:0801D3DE                 MULS    R0, R7
      ROM:0801D3E0                 LDR     R6, =0x2024284
      ROM:0801D3E2                 ADDS    R0, R0, R6
      ROM:0801D3E4                 MOVS    R1, #0xB
      ROM:0801D3E6                 MOVS    R2, #0
      ROM:0801D3E8                 BL      get_party_status     ;get pokemon species
      ROM:0801D3EC                 MOVS    R1, 0x19A            ;compares with deoxys
      ROM:0801D3F0                 CMP     R0, R1
      ROM:0801D3F2                 BEQ     loc_801D414         ; if so, check obedience flag

      ROM:0801D3F4 LDRH R0, [R5] ROM:0801D3F6 MULS R0, R7 ROM:0801D3F8 ADDS R0, R0, R6 ROM:0801D3FA MOVS R1, #0xB ROM:0801D3FC MOVS R2, #0 ROM:0801D3FE BL get_party_status ; redundant, checks your pokemon again for its species ROM:0801D402 CMP R0, #0x97 ROM:0801D404 BEQ loc_801D414 ;if mew, check for obedience ROM:0801D406 ROM:0801D406 loc_801D406 ; CODE XREF: Disobey_byte_check+12j ROM:0801D406 MOVS R0, #1 ROM:0801D408 B loc_801D42A ; is obedient, end ROM:0801D408 ; --------------------------------------------------------------------------- ROM:0801D40A DCB 0 ROM:0801D40B DCB 0 ROM:0801D40C dword_801D40C DCD 0x2023BCE ; DATA XREF: Disobey_byte_check+14r ROM:0801D410 dword_801D410 DCD 0x2024284 ; DATA XREF: Disobey_byte_check+20r ROM:0801D414 ; --------------------------------------------------------------------------- ROM:0801D414 ROM:0801D414 loc_801D414 ; CODE XREF: Disobey_byte_check+32j ROM:0801D414 ; Disobey_byte_check+44j ROM:0801D414 LDR R0, =0x2023BCE ROM:0801D416 ADDS R0, R4, R0 ROM:0801D418 LDRH R1, [R0] ROM:0801D41A MOVS R0, #0x64 ROM:0801D41C MULS R0, R1 ROM:0801D41E LDR R1, =0x2024284 ROM:0801D420 ADDS R0, R0, R1 ROM:0801D422 MOVS R1, #0x50 ROM:0801D424 MOVS R2, #0 ROM:0801D426 BL get_party_status ;checks last ribbon, that is the obedience flag, and returns it ROM:0801D42A ROM:0801D42A loc_801D42A ; CODE XREF: Disobey_byte_check+48j ROM:0801D42A POP {R4-R7} ROM:0801D42C POP {R1} ROM:0801D42E BX R1

      0801D4D4 checks one last time if, by chance, the attack will go trough. If not it will proceed to 0x0801d518, where what will the pokemon actually do\say is calculated.
      So, several modifications can be made here to change the level a pokemon will become disobedient and in what conditions will it become disobedient.
      The location of the obedience flag is actually in the last part of the Ribbon data in the Misc block, the topmost flag (bit 31 of the Ribbon word), but it's only useful for the species listed on the disobedience byte. And as for why Mew\Deoxys only disobey, it's because the chance of attack is determined by a random number (from 0-ff) to be smaller than the max level (that in the byte case is 0).

      Edit: If I understood correctly, the code needed here is one that, if a pokemon doesn't have the flag, the pokemon has some chances of attacking, instead of just laying around all the time. With that in mind, I made a code for the occasion

      Spoiler:
      Code:
      .align 2
      .thumb
      /*to use this code, place 00 49 08 47 at 0x0801d3f4, and the reversed pointer to  where
      you put this code at 0x0801d3f8*/
          cmp r0, #0x5
          beq disobey_or_not
          cmp r0, #0x6
          beq disobey_or_not    /*add more checks here for other pokemon*/
          ldr r1, mew_check
          bx r1
      mew_check:   .word 0x0801D403
      disobey_or_not: ldr r1, random_addr
          ldrb r1, [r1]
          mov r0, #0xb4 /*change here the "perform attack" chance. percentage  is r0 divided by 256 times 100 */
          cmp r1, r0 /*aprox 70% chance of not performing an attack*/
          bgt is_obedient
          ldr r0, disobedient_ret_addr
          bx r0
      is_obedient:   mov r0, #0x1
          pop {r4-r7,pc}
      .hword 0x0000
      random_addr: .word 0x03005000
      disobedient_ret_addr: .word 0x0801d415

      The trick in that code is that the pokemon will act as if it was obedient every once in a while thanks to the random number stored at 0x03005000.

      JPAN, I tried to assemble this code I got some error messages: invalid offset, target not word aligned; invalid offset, value too big.

      I couldn't get it to assemble.

      __________________

      Reply With Quote
        #28    
      Old August 9th, 2010 (8:21 AM).
      NarutoActor's Avatar
      NarutoActor NarutoActor is offline
      The rocks cry out to me
      • Silver Tier
       
      Join Date: Jan 2009
      Location: Brooklyn/Marlboro
      Age: 23
      Gender: Female
      Nature: Bashful
      Posts: 1,979

      Yup. Also, You can edit the asm routine to compare with a var. For an example if var 0x8000 is 0x1 then it will be a bulbasaur. That would make the asm routine more universal for other hackers. All you need to do is set the var before the asm routine, copy the var value into a registry, and compare.

      __________________

      ~There are those people who understand hex, F the rest

      Reply With Quote
        #29    
      Old August 9th, 2010 (12:44 PM).
      metapod23's Avatar
      metapod23 metapod23 is offline
      Hardened Trainer
         
        Join Date: Mar 2009
        Gender: Male
        Nature: Timid
        Posts: 673

        Quote:
        Originally Posted by NarutoActor View Post
        Yup. Also, You can edit the asm routine to compare with a var. For an example if var 0x8000 is 0x1 then it will be a bulbasaur. That would make the asm routine more universal for other hackers. All you need to do is set the var before the asm routine, copy the var value into a registry, and compare.

        So could I create a routine that only has Charmeleon or Charizard obey or disobey if a certain variable (or flag) was set? That would be the best thing, imho. Then I could just set the variable (say, to 0x1) when I want them to obey, and unset it when I want them to disobey.

        If that's possible, any chance you can enlighten me on to how that routine might be written?

        (And I still can't get JPAN's routine to assemble. )

        __________________

        Reply With Quote
          #30    
        Old January 2nd, 2011 (12:20 PM).
        metapod23's Avatar
        metapod23 metapod23 is offline
        Hardened Trainer
           
          Join Date: Mar 2009
          Gender: Male
          Nature: Timid
          Posts: 673

          Quote:
          Originally Posted by NarutoActor View Post
          Yup. Also, You can edit the asm routine to compare with a var. For an example if var 0x8000 is 0x1 then it will be a bulbasaur. That would make the asm routine more universal for other hackers. All you need to do is set the var before the asm routine, copy the var value into a registry, and compare.

          So I spent a good part of my day trying to get this to work with this code. I've tried various things, but here's what I tried recently:

          Code:
          .text
          .align 2
          .thumb
          .thumb_func
          .global obedience

          main: cmp r0, #0x97 beq disobey cmp r0, #0x05 beq disobey cmp r0, #0x06 beq disobey

          mov r0, #0x01 ldr r1, .RESUME bx r1

          disobey: ldr r1, .VAR cmp r1, #0x00 beq disobey2

          mov r0, #0x01 ldr r1, .RESUME bx r1

          disobey2: ldr r1, .DISOBEY bx r1

          resume: ldr r1, .RESUME bx r1

          branchlink: bx r3

          .align 2 .RESUME: .word 0x0801D42B .DISOBEY: .word 0x0801D415 .VAR: .word 0x020370d2

          I bolded what I was attempting to do, which is to set a variable to a register, compare it to a number (in this case, 0) and if it's set to 0, have the Poké disobey; if not, have it obey.

          I want to use variable 6187, just because I haven't used that one yet, but I'm just trying to experiment with 0x800d to see if I can get it to work. So far with my attempts, Charizard has either obeyed the entire time, whether 0x800d was set to 0x0 or 0x1, or has disobeyed in either event.

          Any input would be appreciated.

          __________________

          Reply With Quote
            #31    
          Old January 2nd, 2011 (4:16 PM).
          colcolstyles's Avatar
          colcolstyles colcolstyles is offline

          Yours truly

          • Crystal Tier
           
          Join Date: May 2008
          Location: The Bay Area
          Gender: Male
          Nature: Lonely
          Posts: 1,584

          You need a 'ldrh r1, [r1]' instruction after 'ldr r1, .VAR'.

          Also, you can get rid of the "branchlink" section. That must have been left in from a previous project. It's unnecessary here.

          __________________


          Brother of Vrai

          Reply With Quote
            #32    
          Old January 3rd, 2011 (8:53 AM).
          metapod23's Avatar
          metapod23 metapod23 is offline
          Hardened Trainer
             
            Join Date: Mar 2009
            Gender: Male
            Nature: Timid
            Posts: 673

            Quote:
            Originally Posted by colcolstyles View Post
            You need a 'ldrh r1, [r1]' instruction after 'ldr r1, .VAR'.

            Also, you can get rid of the "branchlink" section. That must have been left in from a previous project. It's unnecessary here.

            It worked! Thanks!

            Now I'm just trying to find the right register for variable 0x6200. I tried debugging with VBA-SLD-H, but when I try to use the breakpoint command for the script I'm testing, it kind of freezes, and I haven't had any luck comparing registers when I hit F11 right after I activate the script and after/before I activate a different script. At least none of the ones I have tried have worked.

            Anybody have any advice?

            __________________

            Reply With Quote
              #33    
            Old January 3rd, 2011 (2:27 PM).
            colcolstyles's Avatar
            colcolstyles colcolstyles is offline

            Yours truly

            • Crystal Tier
             
            Join Date: May 2008
            Location: The Bay Area
            Gender: Male
            Nature: Lonely
            Posts: 1,584

            I'm not really sure what you're asking but if you want to retrieve the value of a non-0x8000 variable, you should call the THUMB routine at '0x0806E454' and pass the variable number as a parameter through r0.

            __________________


            Brother of Vrai

            Reply With Quote
              #34    
            Old January 3rd, 2011 (7:18 PM).
            metapod23's Avatar
            metapod23 metapod23 is offline
            Hardened Trainer
               
              Join Date: Mar 2009
              Gender: Male
              Nature: Timid
              Posts: 673

              Quote:
              Originally Posted by colcolstyles View Post
              I'm not really sure what you're asking but if you want to retrieve the value of a non-0x8000 variable, you should call the THUMB routine at '0x0806E454' and pass the variable number as a parameter through r0.

              Unfortunately, I have no idea how to do that. :\

              I'll keep searching the forums/google to see if I can scrounge up something. None of the tutorials or topics I've found have made it very clear to me.

              __________________

              Reply With Quote
                #35    
              Old January 4th, 2011 (2:13 AM). Edited January 4th, 2011 by TheDarkShark.
              TheDarkShark TheDarkShark is offline
              Metal Headed Hacker
                 
                Join Date: May 2010
                Location: Germany
                Gender: Male
                Nature: Calm
                Posts: 56

                My ASM isn't very good, but I think the code would be something like this:

                ldrh r0, <whatever variable you want to use>
                bal 0x0806E454

                EDIT: Here's the full code. I'm not shure if this will work, but here it is (changes in bold) :
                .text
                .align 2
                .thumb
                .thumb_func
                .global obedience

                main:
                cmp r0, #0x97
                beq disobey
                cmp r0, #0x05
                beq disobey
                cmp r0, #0x06
                beq disobey

                mov r0, #0x01
                ldr r1, .RESUME
                bx r1

                disobey:
                ldrh r0, 0x6187 @The number of the variable is stored
                bal 0x0806E454 @The Routine is called
                cmp r0, #0x00 @Maybe, you have to compare another Register, as I don't know, where the value of the variable is stored
                beq disobey2[/B]

                mov r0, #0x01
                ldr r1, .RESUME
                bx r1

                disobey2:
                ldr r1, .DISOBEY
                bx r1

                resume:
                ldr r1, .RESUME
                bx r1

                branchlink:
                bx r3

                .align 2
                .RESUME:
                .word 0x0801D42B
                .DISOBEY:
                .word 0x0801D415

                Reply With Quote
                  #36    
                Old January 4th, 2011 (7:18 AM).
                metapod23's Avatar
                metapod23 metapod23 is offline
                Hardened Trainer
                   
                  Join Date: Mar 2009
                  Gender: Male
                  Nature: Timid
                  Posts: 673

                  Quote:
                  Originally Posted by TheDarkShark View Post
                  My ASM isn't very good, but I think the code would be something like this:

                  ldrh r0, <whatever variable you want to use>
                  bal 0x0806E454

                  .........

                  Thanks for responding. It didn't work, but it got me trying some different things. Taking word for word what colcol instructed, I tried this:

                  Code:
                  .text
                  .align 2
                  .thumb
                  .thumb_func
                  .global obedience

                  main: cmp r0, #0x97 beq disobey cmp r0, #0x05 beq disobey cmp r0, #0x06 beq disobey

                  mov r0, #0x01 ldr r1, .RESUME bx r1

                  disobey: bl =0x0806E454 ldr r0, =0x00006200 ldrh r0, [r0] cmp r0, #0x00 beq disobey2

                  mov r0, #0x01 ldr r1, .RESUME bx r1

                  disobey2: ldr r1, .DISOBEY bx r1

                  resume: ldr r1, .RESUME bx r1

                  .align 2 .RESUME: .word 0x0801D42B .DISOBEY: .word 0x0801D415

                  It doesn't work, though, so obviously I'm doing something wrong. I was trying to use this tut - http://pkmnhackersonline.com/zodiacdagreat/ASM/Lesson3.htm - as reference.

                  It doesn't crash/freeze the game like some of my attempts (like using labels for the variable/routine), but the Pokemon obeys no matter what the variable is set to.

                  Maybe someone could help me figure out my mistakes?

                  __________________

                  Reply With Quote
                    #37    
                  Old January 4th, 2011 (12:11 PM). Edited January 4th, 2011 by Jambo51.
                  Jambo51's Avatar
                  Jambo51 Jambo51 is offline
                  Glory To Arstotzka
                     
                    Join Date: Jun 2009
                    Gender: Male
                    Nature: Quiet
                    Posts: 732

                    Quote:
                    Originally Posted by metapod23 View Post
                    ...Maybe someone could help me figure out my mistakes?

                    The Line of code I left in bold is the problem here. The bl thumb command has a VERY short range (0xFFFF bytes I think), so instead of trying to directly link to it, try this instead. Unless you are inserting this code within that range. First of all, what you're doing here, because the code is written the wrong way around, is running the variable decrypting routine, then overwriting the result with "garbage".

                    Try this instead. Essentially the same, but should work better:

                    Code:
                    .text
                    .align 2
                    .thumb
                    .thumb_func
                    .global obedience

                    main: cmp r0, #0x97 beq disobey cmp r0, #0x05 beq disobey cmp r0, #0x06 beq disobey

                    mov r0, #0x01 ldr r1, .RESUME bx r1

                    disobey: ldr r0, =0x00006200 push {lr} bl vardecrypt pop {r1} mov lr, r1 ldrh r0, [r0] cmp r0, #0x00 beq disobey2

                    mov r0, #0x01 ldr r1, .RESUME bx r1

                    disobey2: ldr r1, .DISOBEY bx r1

                    resume: ldr r1, .RESUME bx r1

                    vardecrypt: ldr r1, .VARDEC bx r1

                    .align 2 .RESUME: .word 0x0801D42B .DISOBEY: .word 0x0801D415 .VARDEC: .word 0x0806E455

                    For the record, you should ALWAYS precede a bl command with a push {lr} command and follow it with a combo of pop {whatever}, mov lr, whatever; as you don't know if the calling routine needs the value held in lr for the rest of the routine. Better safe than sorry!

                    Incidentally, I'd assume that this is the same routine which runs the checks on Mew and Deoxys for disobedience? If so, could we rewrite it to exclude those rather frustrating checks?

                    __________________

                    Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!

                    Reply With Quote
                      #38    
                    Old January 4th, 2011 (1:24 PM).
                    metapod23's Avatar
                    metapod23 metapod23 is offline
                    Hardened Trainer
                       
                      Join Date: Mar 2009
                      Gender: Male
                      Nature: Timid
                      Posts: 673

                      Quote:
                      Originally Posted by Jambo51 View Post
                      The Line of code I left in bold is the problem here. The bl thumb command has a VERY short range (0xFFFF bytes I think), so instead of trying to directly link to it, try this instead. Unless you are inserting this code within that range. First of all, what you're doing here, because the code is written the wrong way around, is running the variable decrypting routine, then overwriting the result with "garbage".

                      Try this instead. Essentially the same, but should work better:

                      Code:
                      .text
                      .align 2
                      .thumb
                      .thumb_func
                      .global obedience

                      main: cmp r0, #0x97 beq disobey cmp r0, #0x05 beq disobey cmp r0, #0x06 beq disobey

                      mov r0, #0x01 ldr r1, .RESUME bx r1

                      disobey: ldr r0, =0x00006200 push {lr} bl vardecrypt pop {r1} mov lr, r1 ldrh r0, [r0] cmp r0, #0x00 beq disobey2

                      mov r0, #0x01 ldr r1, .RESUME bx r1

                      disobey2: ldr r1, .DISOBEY bx r1

                      resume: ldr r1, .RESUME bx r1

                      vardecrypt: ldr r1, .VARDEC bx r1

                      .align 2 .RESUME: .word 0x0801D42B .DISOBEY: .word 0x0801D415 .VARDEC: .word 0x0806E455

                      For the record, you should ALWAYS precede a bl command with a push {lr} command and follow it with a combo of pop {whatever}, mov lr, whatever; as you don't know if the calling routine needs the value held in lr for the rest of the routine. Better safe than sorry!

                      Thanks for the response, but it's still not working for me.
                      Charizard obeys whether the variable is set to 0x0 or 0x1 ...

                      Quote:
                      Incidentally, I'd assume that this is the same routine which runs the checks on Mew and Deoxys for disobedience? If so, could we rewrite it to exclude those rather frustrating checks?

                      That's correct, it's the same routine. I would guess that you could just alter the routine at 0x0801D404, which I think was the original location of the routine to check for disobedience? I would guess you could just write a new routine that doesn't really do anything and insert it there?

                      I'm sure there's a routine before this that goes to the routine at 0x0801D404 if an attack is selected, though, and it would be best to edit that routine to not have it go to the routine at 0x0801D404 at all, but I don't know what the offset of that one would be ...

                      __________________

                      Reply With Quote
                        #39    
                      Old January 4th, 2011 (3:17 PM).
                      Jambo51's Avatar
                      Jambo51 Jambo51 is offline
                      Glory To Arstotzka
                         
                        Join Date: Jun 2009
                        Gender: Male
                        Nature: Quiet
                        Posts: 732

                        Quote:
                        Originally Posted by metapod23 View Post
                        Thanks for the response, but it's still not working for me.
                        Charizard obeys whether the variable is set to 0x0 or 0x1 ...

                        That's correct, it's the same routine. I would guess that you could just alter the routine at 0x0801D404, which I think was the original location of the routine to check for disobedience? I would guess you could just write a new routine that doesn't really do anything and insert it there?

                        I'm sure there's a routine before this that goes to the routine at 0x0801D404 if an attack is selected, though, and it would be best to edit that routine to not have it go to the routine at 0x0801D404 at all, but I don't know what the offset of that one would be ...

                        This might sound a bit iffy, but let me insert this routine and i'll see if I can find why it isn't working for you. If you say yes, you'll need to tell me the insertion location so I can do it. Also, 2 seconds after posting this, I found and removed the Mew and Deoxys checks. Hooray! Now we can all catch and actually use Mew. Simply replace the cmp r1, #0x97 line with lsl r0, r0, #0x0 (97 29 with 00 00) and the check won't run.

                        __________________

                        Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!

                        Reply With Quote
                          #40    
                        Old January 4th, 2011 (4:09 PM). Edited January 5th, 2011 by metapod23.
                        metapod23's Avatar
                        metapod23 metapod23 is offline
                        Hardened Trainer
                           
                          Join Date: Mar 2009
                          Gender: Male
                          Nature: Timid
                          Posts: 673

                          Quote:
                          Originally Posted by Jambo51 View Post
                          This might sound a bit iffy, but let me insert this routine and i'll see if I can find why it isn't working for you. If you say yes, you'll need to tell me the insertion location so I can do it. Also, 2 seconds after posting this, I found and removed the Mew and Deoxys checks. Hooray! Now we can all catch and actually use Mew. Simply replace the cmp r1, #0x97 line with lsl r0, r0, #0x0 (97 29 with 00 00) and the check won't run.

                          Sure, go ahead. I've been placing the routine at 0x859000.

                          EDIT

                          Actually, now I realize that it does work. Thanks!! :D

                          For some reason variable 0x6200 wasn't already set to 0, even though I hadn't used it in my game yet - I was assuming that it was.

                          I switched it to 0x6199 and it works perfectly. Thanks again, Jambo51! I really appreciate it.

                          Also, I put the code in the first post, and I'll add you and others that helped on this code to the credits for my hack.

                          __________________

                          Reply With Quote
                            #41    
                          Old August 10th, 2011 (1:12 PM).
                          metapod23's Avatar
                          metapod23 metapod23 is offline
                          Hardened Trainer
                             
                            Join Date: Mar 2009
                            Gender: Male
                            Nature: Timid
                            Posts: 673

                            I'm just reviving this thread to post that I figured out how to combine JPAN's routine of having a Pokemon obey once in a while and Jambo51's routine of having it only do so when a certain variable is or isn't set. Again, I want to thank colcolstyles, Jambo51, and JPAN for working on this for me! Thanks!

                            So here's the routine:

                            First place 00 49 08 47 at 0x0801D3F4, and the reversed pointer to the code below at 0x0801D3F8 (per JPAN's routine).

                            Code:
                            .text
                            .align 2
                            .thumb
                            .thumb_func
                            .global obedience

                            main: cmp r0, #0x97 @Mew's number, if you want it to disobey still beq disobey cmp r0, #0x05 @Pokemon you want to disobey only sometimes beq disobey (Charmeleon) cmp r0, #0x06 @Pokemon you want to disobey only sometimes beq disobey (Charizard) ldr r1, mew_check bx r1

                            mew_check: .word 0x0801D403

                            disobey: ldr r0, =0x00006199 @Variable you want to use push {lr} bl vardecrypt pop {r1} mov lr, r1 ldrh r0, [r0] cmp r0, #0x00 @the value of the variable you want to cause the beq disobey2 Pokemon to sometimes disobey mov r0, #0x01 ldr r1, .RESUME bx r1

                            disobey2: ldr r1, random_addr ldrb r1, [r1] mov r0, #0xcd the number, divided by 256, that will be the cmp r1, r0 percentage of how often the Pokemon disobeys bgt is_obedient (in this case, cd (205)/256 = 80% disobey) ldr r0, disobedient_ret_addr bx r0

                            resume: ldr r1, .RESUME bx r1

                            vardecrypt: ldr r1, .VARDEC bx r1

                            is_obedient: mov r0, #0x1 pop {r4-r7,pc} .hword 0x0000

                            .align 2 .RESUME: .word 0x0801D42B .DISOBEY: .word 0x0801D415 .VARDEC: .word 0x0806E455 random_addr: .word 0x03005000

                            disobedient_ret_addr: .word 0x0801d415

                            __________________

                            Reply With Quote
                              #42    
                            Old December 30th, 2012 (2:07 PM).
                            Wynchester's Avatar
                            Wynchester Wynchester is offline
                            Legendary Trainer
                               
                              Join Date: Dec 2012
                              Location: With your sister
                              Gender: Male
                              Posts: 24

                              My question is this... Does this then affect every Poke of a species (i.e. all Charmeleon and Charizard) or only one specific pokemon you have? My instinct says all of the Species, but if that's the case, I need help making it so it only affects a very specific Poke.

                              __________________

                              To all people who I was trying to help: my computer has encountered a major virus wiping out all of my emulators and related files. My computer and USB drives are in critical condition as far as infection. Please forgive me for any work you were hoping I could do for you, but I don't even have the files for the original games anymore. So for now, I have to resign from work until my computer gets cleaned. I will try to return to hacking as soon as I can, but it may not be for a while.

                              UPDATE: My computer and devices are cleaned, but atm, I do NOT have access to my hack tools. I can not hack for anyone including myself. My apologies to anyone this inconveniences.

                              Reply With Quote
                                #43    
                              Old December 31st, 2012 (12:34 AM).
                              tinix's Avatar
                              tinix tinix is offline
                              PearlShipper & C Programmer
                                 
                                Join Date: Feb 2010
                                Location: Bratislava, Slovakia
                                Age: 20
                                Gender: Male
                                Posts: 86

                                It affects all of species. I think you could make a specific poke disobey by storing its personality value(it is unique as it is randomly generated) from its data in some variable and then comparing the variable to the personality value of active pokemon. If I am wrong feel free to correct me.

                                __________________

                                Pokémon games I own:
                                Pokémon Diamond
                                Pokémon Platinum
                                Pokémon Ranger: Shadows of Almia
                                Pokémon HeartGold Version

                                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 11:58 AM.