The PokéCommunity Forums Fan Games ROM Hacking Help Research & Development
Development ASM Resource Thread

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
  #1426    
Old 5 Days Ago (5:07 PM).
Sagiri's Avatar
Sagiri Sagiri is offline
     
    Join Date: Mar 2007
    Posts: 757
    Since it got mentioned above, I figured I'd post this here.

    It's been tweaked slightly so that it only uses armips, rather than the build system I use for my C stuff. All it really did for it was find free space automatically, and, while that's kind of useful, I feel it unnecessarily overcomplicated it.

    In any case:

    Clear JPAN Save Block During New Game [FR]

    Fixes an oddity with JPAN's Save Block Recycle where the saved memory doesn't get zeroed upon starting a new game. Instead, it'll retain whatever it happened to be in the previous save file.

    To be clear, this does not actually include JPAN's Save Block Recycle itself.
    Reply With Quote
      #1427    
    Old 4 Days Ago (9:22 AM).
    Petuuuhhh's Avatar
    Petuuuhhh Petuuuhhh is offline
     
    Join Date: Apr 2017
    Location: Georgia
    Age: 25
    Gender: Male
    Posts: 537
    Quote:
    Originally Posted by DarkPsychic View Post
    So for anyone who has used this they know that only the Pre-Compiled version works, and the routine given does not compile to match either and don't work at all for that matter.

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

    Now I worked on this all day and was able to rebuild the Pre-Compiled routine so we could actually have the working source.
    FBI's - Pre-Compiled Storage System - Disassembled/Rebuilt Routine
    Code:
    Code:
    .text
    .align 2
    .thumb
    .thumb_func
    
    main:
    push {r0, r4, lr}
        ldr r0, .FROM
        ldr r1,[r0]
        cmp r1, #0x0               @party
        beq addParty
    
    addStorage:    
        ldr r0, .STORAGE
        sub r0, #0x1
        ldrb r1, [r0]
        cmp r1, #0x6               @limit of storage. Change depending on your space situation
        beq end
        add r0, #0x1
        mov r2, #0x50
        mul r1, r2
        add r0, r0, r1             @destination
        ldr r1, =(0x20370C0)       @ 2b Var_8004
        ldrb r1, [r1]
        ldr r2, .PARTY
        mov r3, #0x64
        mul r1, r3
        add r1, r1, r2             @source
        mov r2, #0x50              @size
        ldr r3, =(0x8040B09)       @memcpy_pkm 'void __fastcall memcpy_pkm(void *dst, void *src, unsigned int size)'
        bl linker
        ldr r1, =(0x20370C0)       @need to fix up Player's party slots @ 2b Var_8004
        ldrb r1, [r1]
        cmp r1, #0x5
        beq writeLastZero
        mov r2, #0x5
        sub r2, r2, r1
        mov r3, #0x64
        mul r2, r3                 @size
        ldr r0, .PARTY
        mul r1, r3
        add r0, r0, r1             @dest
        add r3, r3, r0
        mov r1, r3                 @src
        ldr r3, =(0x8040B09)       @memcpy_pkm 'void __fastcall memcpy_pkm(void *dst, void *src, unsigned int size)'
        bl linker
        
    writeLastZero:
        ldr r0, =(0x2024478)       @ 100b    Party Pokemon 6
        mov r1, #0x0
        mov r2, #0x64
        ldr r3, =(0x81E5ED9)       @memset  'void __fastcall memset(char *dst, char pattern, int size)'
        bl linker
    
    correctCounters:
        ldr r0, .STORAGE
        sub r0, #0x1
        ldrb r2, [r0]              @pks in storage counter
        ldr r1, =(0x2024029)       @ 1b    Repeattrainerbattle: Unknown. Loaded if battle type is 9.
        ldrb r3, [r1]              @pks in party
        add r2, #0x1
        strb r2,[r0]
        sub r3, #0x1
        strb r3, [r1]
        b end
        
    addParty:
        ldr r0, =(0x2024029)       @ 1b    Repeattrainerbattle: Unknown. Loaded if battle type is 9.
        ldrb r0, [r0]
        cmp r0, #0x6
        beq end
        ldr r1, .PARTY
        mov r2, #0x64
        mul r0, r2
        add r0, r0, r1             @destination
        mov r4, r0
        ldr r3, .STORAGE
        ldr r1, =(0x20370C0)       @'var 0x8004 determines which slot of storage to take from'
        ldrb r1, [r1]
        mov r2, #0x50              @size
        mul r1, r2
        add r1, r1, r3             @source
        ldr r3, =(0x8040B09)       @memcpy_pkm 'void __fastcall memcpy_pkm(void *dst, void *src, unsigned int size)'
        bl linker
        mov r0, r4                 @update stats
        ldr r3, =(0x803E47D)       @pokemon_calc_effective_stats
        bl linker
        ldr r0, =(0x20370C0)       @adjust the storage   @ 2b Var_8004
        ldrb r0, [r0]
        cmp r0, #0x5               @storage limit minus 1
        beq writeZero
        mov r2, #0x5
        sub r2, r2, r0
        mov r3, #0x50
        mul r2, r3                 @size
        ldr r1, .STORAGE
        mul r0, r3
        add r0, r0, r1             @dest
        add r3, r3, r0
        mov r1, r3                 @src
        ldr r3, =(0x8040B09)       @memcpy_pkm 'void __fastcall memcpy_pkm(void *dst, void *src, unsigned int size)'
        bl linker
    
    writeZero:
        ldr r0, .STORAGE
        mov r1, #0xC8
        lsl r1, r1, #0x1
        add r0, r0, r1
        mov r1, #0x0
        mov r2, #0x50 
        ldr r3, =(0x81E5ED9)       @memset  'void __fastcall memset(char *dst, char pattern, int size)'
        bl linker
        
    updateCounters:
        ldr r0, .STORAGE
        sub r0, #0x1
        ldrb r2, [r0]
        ldr r1, =(0x2024029)       @ 1b    Repeattrainerbattle: Unknown. Loaded if battle type is 9.
        ldrb r3, [r1]
        sub r2, #0x1
        strb r2,[r0]
        add r3, #0x1
        strb r3, [r1]
    
    end:
        pop {r0-r4, pc}
        
    linker:
        bx r3
    
    .align 2
    
    .FROM:
        .word 0x20370B8            @var_8000
    
    .STORAGE:
        .word 0x203C001            @storage location
    
    .PARTY:
        .word 0x2024284            @player's party
    And to go along with that is the XSE script.
    Code:
    Code:
    #dynamic 0xFreeSpaceToStartFrom
    
    //---------------
    #org @start
    lock
    faceplayer
    copybyte 0x20370D0 0x203C000
    compare 0x800D 0x0
    if 0x1 goto @snippet1
    msgbox @string1 0x5 //"Want your Pokemon back?"
    compare 0x800D 0x1
    if 0x1 goto @snippet2
    goto @snippet1
    
    //---------------
    #org @snippet1
    countpokemon
    copyvar 0x8000 0x800D
    compare 0x8000 0x1
    if 0x3 goto @snippet3
    msgbox @string2 0x5 //"Want to give me a pokemon?"
    compare 0x800D 0x1
    if 0x1 goto @snippet4
    msgbox @string3 0x6 //"Alright, next time then."
    release
    end
    
    //---------------
    #org @snippet2
    setvar 0x8000 0x0
    countpokemon
    compare 0x800D 0x6
    if 0x1 goto @snippet5
    msgbox @string4 0x6 //"Alright, I'll give it to you."
    setvar 0x8004 0x0
    callasm 0xWhereYouPutYourTheRoutine+1
    fanfare 0x101
    msgbox @string5 0x6 //"I gave it back."
    release
    end
    
    //---------------
    #org @snippet3
    msgbox @string6 0x6 //"Hi, I can't do anything\nyour slot..."
    release
    end
    
    //---------------
    #org @snippet4
    setvar 0x8000 0x1
    special 0xBC
    waitstate
    countpokemon
    compare 0x800D 0x1
    if 0x3 goto @snippet6
    callasm 0xWhereYouPutYourTheRoutine+1
    msgbox @string7 0x6 //"Thanks for giving me this."
    release
    end
    
    //---------------
    #org @snippet5
    msgbox @string8 0x6 //"You're party is full!"
    release
    end
    
    //---------------
    #org @snippet6
    msgbox @string3 0x6 //"Alright, next time then."
    release
    end
    
    
    //---------
    // Strings
    //---------
    #org @string1
    = Want your Pokemon back?
    
    #org @string2
    = Want to give me a pokemon?
    
    #org @string3
    = Alright, next time then.
    
    #org @string4
    = Alright, I'll give it to you.
    
    #org @string5
    = I gave it back.
    
    #org @string6
    = Hi, I can't do anything\nyour slots are full or empty\lor mine are full while yours are\lfull[.]
    
    #org @string7
    = Thanks for giving me this.
    
    #org @string8
    = You're party is full!
    Edit the orange text before compiling.


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


    Edit:
    Found the bug!
    It was as simple as changing the special 0x9F to special 0xBC.
    Fixed the above XSE script as well
    This has been giving me bad eggs and taking away Pokemon in my party when I want my Pokemon back. What I want to do with this is make this into an item called a Laptop that is a portable storage system. I'm not really making a request since this isn't a request thread, but I'd at least like this routine fixed.
    Reply With Quote
      #1428    
    Old 4 Days Ago (9:58 AM). Edited 4 Days Ago by Petuuuhhh.
    Petuuuhhh's Avatar
    Petuuuhhh Petuuuhhh is offline
     
    Join Date: Apr 2017
    Location: Georgia
    Age: 25
    Gender: Male
    Posts: 537
    Quote:
    Originally Posted by FBI View Post

    Current Time into variables



    This routine basically takes the current ingame hours, minutes, and seconds and places the three into the variables 0x8000 = hours(2 bytes), 0x8001 = mins(1 byte), 0x8002 = seconds(1 byte). I suppose you can merge into 0x8001 both the minutes and seconds, but this way is easier to access.

    How to insert:

    Compile and insert the following routine into free space.

    Spoiler:

    Code:
    .text
    .align 2
    .thumb
    .thumb_func
    
    main:
    	push {r0-r2, lr}
    	ldr r0, .PlayTime
    	ldr r0, [r0]
    	add r0, r0, #0xE @hours
    	ldr r2, =(0x20370B8)
    	ldrh r1, [r0]
    	strh r1, [r2]
    	add r0, r0, #0x2 @mins
    	ldr r2, =(0x20370BA)
    	ldrb r1, [r0]
    	strb r1, [r2]
    	add r0, r0, #0x1 @seconds
    	ldr r2, =(0x20370BC)
    	ldrb r1, [r0]
    	strb r1, [r2]
    	pop {r0-r2, pc}
    
    
    .align 2
    .PlayTime:
    	.word 0x300500C
    Here's a compiled version:
    Code:
    07 B5 07 48 00 68 0E 30 06 4A 03 88 13 80 02 30 05 4A 03 78 13 70 01 30 04 4A 03 78 13 70 07 BD 0C 50 00 03 B8 70 03 02 BA 70 03 02 BC 70 03 02


    Usage:
    In a script callasm 0x[where you inserted this routine +1]. The variables 0x8000, 0x8001, 0x8002 will be updated with the current hours, minutes and seconds respectively.
    Hey, so I tried using this by giving an item a field script of the routine +1. It freezes my game when I try to use it. Is there something I'm not doing correctly?
    Reply With Quote
      #1429    
    Old 4 Days Ago (9:35 PM).
    Sagiri's Avatar
    Sagiri Sagiri is offline
       
      Join Date: Mar 2007
      Posts: 757
      Unhidden Power [FR]

      This routine makes the game calculate and display the actual type of Hidden Power in battle and in status screens. If, for example, a Pokémon's Hidden Power type is Water, it will display as a Water-type move, just like Surf or any other Water-type move.



      Note that this only calculates and displays the type, not the base power.
      Reply With Quote
        #1430    
      Old 2 Days Ago (5:15 PM).
      Sagiri's Avatar
      Sagiri Sagiri is offline
         
        Join Date: Mar 2007
        Posts: 757
        Evolve by Leveling Up While Holding An Item [FR]

        Adds evolution methods to allow Pokémon to evolve by leveling up while holding a particular item. Also included are day and night variations for use with Happiny, Gligar, and Sneasel.

        Other implementations of this evolution method have a subtle bug - they remove the item even if the player hits Ⓑ to cancel the evolution. This avoids that.
        Reply With Quote
          #1431    
        Old 51 Minutes Ago (1:14 AM).
        Sagiri's Avatar
        Sagiri Sagiri is offline
           
          Join Date: Mar 2007
          Posts: 757
          Summary Screen Wraps Around [FR]

          Allows you to hit Up on the summary screen of the first Pokémon in the party to move to the last Pokémon in your party, and likewise hit Down on the last to move to the first. This change originated in XY and has become standard in all later games.
          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
          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 2:06 AM.