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