Thread: Research: Items
View Single Post
Old January 11th, 2010 (7:10 PM).
JPAN JPAN is offline
pokemon rom researcher
Join Date: Dec 2008
Posts: 104
I created an alternative way to run the script through an item, using a really cheap method.
The return is executed as normally would, and the script starts executing as soon as it leaves the bag.
But the script it runs is not the one the hacker placed therem but one at a fixed ROM position.
A "header" that forces the BAG window to close before starting to execute the main code.
This is the final result asm source file, the version I shall make available in my next hack release:
.align 2
/*this is the final result of the first stage of item usage. This code will allow you to run scripts through an item.
Usage Requirements:
Compiled key_change_hack;
compiled special 0xc9 (force key), even if not as a special
to use:
1 - place the pointer to this routine in the OW execution word of the item of your choice
2 - Place the Script pointer in the last word (right next to the name of the next item)
2.5 - this code does not remove the item, to make it easier to code Key items. Just place in your script somewhere a "removeitem item_num 0x1" to destroy it.
This has been made to run trainer battles, map display, pokemon selection screen and some specials. seems to work well with all scripting commands.
New_item_start:  push {r4,lr}
                        ldr r0, RAM_item
                        ldrh r0, [r0]
                        mov r1, #0x2c
                        mul r0, r1
                        ldr r1, item_addr
                        add r0, r0, r1
                        ldr r4, [r0]            /*loads item script*/
                        ldr r2, script_area
                        str r4, [r2]
                        mov r4, #0x5
                        sub r2, #0x1
                        strb r4, [r2]       /*creates a bypass for our real script*/
                        ldr r0, script_pos /*the starter script with the menu shut*/
                        bl script_executer
                        ldr     R1, Script_flag_set
                        mov  R0, #0x1
                        strb R0, [R1]
                        bl bag_exiter
                        pop {r4,pc}
RAM_item: .word 0x0203ad30
item_addr: .word 0x083db050
Script_flag_set: .word 0x03000f9c
script_executer: ldr r1, exe_addr
                       bx r1
exe_addr: .word 0x08069AE5
bag_exiter:  ldr r1, exit_code
                 bx r1
exit_code: .word 0x080a103d
script_area: .word 0x0203f3ec
script_pos: .word 0x00000000
This script must be compiled and put somewhere in the rom, and the pointer to this placed in script_pos. 
Compiled version already comes with it compiled, but you need to put the pointer in the 4 zero bytes area in the middle of the code.
copyvar 0x8012 0x8004
copyvar 0x8013 0x8005
setvar 0x8004 0x2
setvar 0x8005 0x7
pause 0x16
special 0xC9 'or callasm @location_you_put_key_presser
pause 0x1
copyvar 0x8004 0x8012
copyvar 0x8005 0x8013
goto 0x203F3EB
And the dependencies
.align 2
This code will be replacing the two lines at 0x80005e8, the Key loader
This will, at an end, allow for us to input keys of our own, to create several key-manipulation techniques. Examples:
 key inibition; key replacement.
to apply, place a bx r0 (00 47) at 0x080005ec and replace the pointer at 0x08000624 to this routine's one.
Stuff this will do:
type of change will depend on 0203f4ec contents.
bit set -> effect
0 -> change value to and with, so it makes the game believe a certain key is pressed.
       This key value is placed at 0x0203f4de.
1 -> makes sure a key is not detected. However, that key is allways detected by the key specials.
      Allows you to delete the access to the help menu, or start, etc.
      That keymap must be placed at 0203f4fc.
2 -> if the player is in the OW, forces the script at 0203f4f4 to run when a key in 
       the position 0x0203f4ee
Key_wrecker_start: push {r4-r7} 
                           ldr r0, key_addr
                           ldrh r0, [r0]
                           ldr r4, switches
                           ldrb r1, [r4]
                           cmp r1, #0x0
                           beq nothing_to_do
                           bl check_for_script
                           bl check_for_forced
                           bl check_for_cancel
nothing_to_do:       pop {r4-r7}
                           add r1, r0, #0x0
                           ldr r0, return_place
                           bx r0
.hword 0x0000
key_addr: .word 0x04000130
switches: .word 0x0203f4ec
return_place: .word 0x080005ef
check_for_script: push {r0-r1,lr}
                        mov r2, #0x4       /*check for flag*/
                        and r2, r1
                        cmp r2, #0x0
                        beq end_all
                        ldr r5, script_on    /*check if a script is executing*/
                        ldrb r3, [r5]
                        cmp r3, #0x1
                        beq end_all
                        ldrh r2, [r4, #0x2]  /*check if the keys are pressed*/
                        and r2, r0
                        cmp r2, #0x0
                        bne end_all
                        ldr r3, first_function    /*checks if we are in the OW*/
                        ldr r2, [r3]
                        ldr r3, OW_function
                        cmp r2, r3
                        bne end_all
                        mov r2, #0x1 /*if all is ok, run script*/
                        strb r2, [r5]
                        ldr  r0, [r4, #0x8]
                        bl script_executer
end_all:              pop {r0-r1,pc}
script_on: .word 0x03000f9c
first_function: .word 0x03005090
OW_function: .word 0x08079e0d
check_for_forced: push {lr}
                         mov r2, #0x1 /*check for flag*/
                         and r2, r1
                         cmp r2, #0x0
                         beq end_all_2
                         ldrb r2, [r4, #0x1] /*check if it should apply it*/
                         cmp r2, #0x0
                         beq end_all_2
                         sub r2, #0x1
                         strb r2, [r4, #0x1] /*updates counter*/
                         sub r4, #0xE
                         ldrh r2, [r4]     /*gets keymap to force*/
                         add r4, #0xe
                         mvn r2, r2
                         and r0, r2         /*keys changed*/
end_all_2:           pop {pc}
check_for_cancel: push {lr}
                         mov r2, #0x2 /*check for flag*/
                         and r2, r1
                         cmp r2, #0x0
                         beq end_all_3
                         ldr r2, [r4, #0x10] /*loads key to ignore*/
                         orr r0, r2 /*ignored*/
end_all_3:           pop {pc}
script_executer: ldr r1, exe_addr
                       bx r1
exe_addr: .word 0x08069AE5
The special is only a setter for the Force B flag. If you understood the above code, you could probably do the same with writebytes
.align 2
/*this code forces one keyMap stored on your ROM to run for the asked number of times
Special c9 receives:
0x8004 is the keys to set
0x8005 is the times to set it to
returns nothing
Special_c9:  push {r0-r2, lr}
                 ldr r0, key_store_addr
                 ldr r2, var_8004
                 ldrh r1, [r2]
                 strh r1, [r0]
                 ldrh r1, [r2, #0x2]
                 add r0, #0xe
                 strb r1, [r0, #0x1]
                 ldrb r1, [r0]
                 mov r2, #0x1
                 orr r1, r2
                 strb r1, [r0]
                 pop {r0-r2, pc}
.hword 0x0000
key_store_addr: .word 0x0203f4de
var_8004: .word 0x020370c0
This method will only not work if the player holds down the B button at the same time it exits the bag.
It could be made certain that B button was not pressed at least for one check, but probably wouldn't be worth it.

And that's it for Script Items. Just as mentioned in the code above, this is a generic item for any OW activity, and as such, is only guaranteed to work at the Overworld. Next step, finding the battle items code and usages.
Here are the links for my work

Currently working on:
Battle Script Documentation
Another large project
Reply With Quote