The PokéCommunity Forums  

Go Back   The PokéCommunity Forums > Fan Games > Binary ROM Hacking > Binary Hack Research & Development
Reload this Page Code ASM Resource Thread

Notices
For all updates, view the main page.

Binary Hack Research & Development Got a well-founded knack with your binary Pokémon hacks? Love reverse-engineering them? For the traditional Pokémon ROM hacker, 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!

Ad Content
Reply
 
Thread Tools
  #1451   Link to this post, but load the entire thread.  
Old May 19th, 2019 (11:02 AM).
Diego98 Diego98 is offline
 
Join Date: Jan 2015
Gender: Male
Posts: 22
I'm searching for a routine that opens the bag to select an item (like when you give some item to a pokemon from the pokemon menu) and it saves the item ID into a variable. Does anyone know something about it or how to do it?
Reply With Quote
  #1452   Link to this post, but load the entire thread.  
Old May 19th, 2019 (11:16 AM).
mattymannnn's Avatar
mattymannnn mattymannnn is offline
 
Join Date: May 2018
Gender: Male
Posts: 55
Quote:
Originally Posted by Diego98 View Post
I'm searching for a routine that opens the bag to select an item (like when you give some item to a pokemon from the pokemon menu) and it saves the item ID into a variable. Does anyone know something about it or how to do it?
https://www.pokecommunity.com/showthread.php?t=295749
Reply With Quote
  #1453   Link to this post, but load the entire thread.  
Old May 19th, 2019 (1:23 PM).
Diego98 Diego98 is offline
 
Join Date: Jan 2015
Gender: Male
Posts: 22
Quote:
Originally Posted by mattymannnn View Post
Great! That's just what I needed
Reply With Quote
  #1454   Link to this post, but load the entire thread.  
Old May 24th, 2019 (3:02 PM).
Dragoonite Dragoonite is offline
 
Join Date: May 2019
Posts: 1
Would it be possible to remove the character and rival naming process and make them both a set name in FireRed?
Reply With Quote
  #1455   Link to this post, but load the entire thread.  
Old May 29th, 2019 (6:01 AM). Edited May 29th, 2019 by Spherical Ice.
Spherical Ice's Avatar
Spherical Ice Spherical Ice is offline
 
Join Date: Nov 2007
Location: Leicester, UK
Age: 25
Posts: 5,251

[FR] Switch the title screen's "Charizard" tilemap based on a flag



Code:
.thumb

.equ rom, 0x08000000
.equ free_space, 0x
.equ title_screen_default_palette, 0xEAD5E8 @ these are the default for FireRed's Charizard tilemap
.equ title_screen_default_tileset, 0xEAD608
.equ title_screen_default_tilemap, 0xEADEE4
.equ title_screen_new_palette, 0x
.equ title_screen_new_tileset, 0x
.equ title_screen_new_tilemap, 0x
.equ new_flag, 0x

.org 0x78A1A, 0xFF
hook:
    ldr r0, =(rom + main + 1)
    bx r0
.pool

.org 0x78F62, 0xFF
hook1:
    ldr r0, =(rom + main1 + 1)
    bx r0
.pool

.org 0x79670, 0xFF
hook2:
    ldr r0, =(rom + main2 + 1)
    bx r0
.pool

.org free_space, 0xFF
main:
    push {r5}
    mov r5, r4

    ldr r0, =new_flag
    bl flag_check
    cmp r0, #1
    beq new

default:
    ldr r0, =(rom + title_screen_default_palette)
    mov r1, #0xD0
    mov r2, #0x20
    bl gpu_pal_apply

    ldr r1, =(rom + title_screen_default_tileset)
    str r4, [sp]
    mov r0, #1
    mov r2, #0
    mov r3, #0
    bl decompress_with_fallback_maybe

    ldr r1, =(rom + title_screen_default_tilemap)
    b continue

new:
    ldr r0, =(rom + title_screen_new_palette)
    mov r1, #0xD0
    mov r2, #0x20
    bl gpu_pal_apply

    ldr r1, =(rom + title_screen_new_tileset)
    str r4, [sp]
    mov r0, #1
    mov r2, #0
    mov r3, #0
    bl decompress_with_fallback_maybe

    ldr r1, =(rom + title_screen_new_tilemap)

continue:
    str r6, [sp]
    mov r0, #1
    mov r2, #0
    mov r3, #0
    bl decompress_with_fallback_maybe

    mov r4, r5
    pop {r5}    
    ldr r0, =(rom + 0x78a40 + 1)
    bx r0

.pool

main1:
    ldr r0, =new_flag
    bl flag_check
    cmp r0, #1
    beq new1

default1:
    ldr r0, =(rom + title_screen_default_palette)
    b continue1
    
new1:
    ldr r0, =(rom + title_screen_new_palette)

continue1:
    ldr r1, =0x2037398
    mov r2, #0x10
    bl CpuSet
    mov r0, #0x2
    lsl r0, r0, #0xC
    str r5, [sp]
    str r7, [sp, #4]
    str r7, [sp, #4]
    ldr r1, =(rom + 0x78f76 + 1)
    bx r1

.pool

main2:
    ldr r0, =new_flag
    bl flag_check
    cmp r0, #1
    beq new2

default2:
    ldr r0, =(rom + title_screen_default_palette)
    b continue2
    
new2:
    ldr r0, =(rom + title_screen_new_palette)

continue2:
    mov r1, #0xD0
    mov r2, #0x20
    bl gpu_pal_apply

    ldr r4, =(rom + 0x7967a + 1)
    bx r4

.pool

gpu_pal_apply:
    ldr r3, =(rom + 0x703EC + 1)
    bx r3

flag_check:
    ldr r1, =(rom + 0x6E6D0 + 1)
    bx r1

decompress_with_fallback_maybe:
    ldr r4, =(rom + 0xF6878 + 1)
    bx r4

CpuSet:
    ldr r3, =(rom + 0x1E3B64 + 1)
    bx r3

.pool
Pretty easily extendible for more than 2 different ones, if you swap out the flag for a variable (obviously assuming you have some ASM fluency).
__________________
Reply With Quote
  #1456   Link to this post, but load the entire thread.  
Old June 6th, 2019 (2:54 PM).
/JASHIN/'s Avatar
/JASHIN/ /JASHIN/ is offline
 
Join Date: Nov 2018
Location: Canada
Age: 29
Gender: Male
Nature: Adamant
Posts: 62
Quote:
Originally Posted by daniilS View Post
Actually, I wouldn't recommend using JPAN's method: for some reason he wrote a completely custom decryptor, while there is an existing one in the rom already. It's way easier to use because changing a pokémon's species requires just a single callasm. (If anybody is interested, I made this in ancient times: )
Spoiler:
Code:
.text
.align 2
.thumb
.thumb_func
.global Indexnumber_changeand20bytes_recalc

main:
	push {r0-r3, lr}
getpokeoffset:
	ldr r0, varnumber_8004
	ldr r3, vardecrypt
	bl bxr3
	ldrh r2, [r0]
	mov r0, #100
	mul r2, r0
	ldr r0, partystart
	add r3, r2, r0
	push {r3}
getandsetnewindexnumber:
	ldr r0, vartocontainnewindexnumber
	ldr r3, vardecrypt
	bl bxr3
	mov r2, r0
	mov r1, #0xB
	ldr r0, [sp]
	ldr r3, pokeencrypt
	bl bxr3
recalc20bytes:
	pop {r0}
	ldr r3, effectivestatsrecalc
	bl bxr3
	pop {r0-r3, pc}
bxr3:
	bx r3
	
.align 2
	varnumber_8004:			.word 0x8004
	vardecrypt:			.word 0x0806E454+1
	partystart:			.word 0x02024284
	vartocontainnewindexnumber:	.word 0x8005
	pokeencrypt:			.word 0x0804037C+1
	effectivestatsrecalc:		.word 0x0803e47c+1
	
/*Insert anywhere. then use special 0x9F to select a pokemon, waitstate, setvar 0x8005 to the desired index number, and callasm this routine+1*/


However, I believe the thing that's important about his request is playing the evolution animation, which isn't as easy to do as this.
My question regarding this how can I make it so that not every pokemon that is picked can change into the form?
Also, I noticed that when you change forms it changes the pokemon's level to be one less than it was before.
__________________
POKEMON PULSAR VERSION PHASE 02 THREAD: https://www.pokecommunity.com/showthread.php?t=421565
(Phase 03 in development)


POKEMON PULSAR VERSION PHASE 02 TRAILER:https://www.youtube.com/watch?v=zPY7_ZvoO7E
(Formerly known as Pokemon Jashin Version)


-Praise Be To Jashin
Reply With Quote
  #1457   Link to this post, but load the entire thread.  
Old June 6th, 2019 (2:58 PM).
/JASHIN/'s Avatar
/JASHIN/ /JASHIN/ is offline
 
Join Date: Nov 2018
Location: Canada
Age: 29
Gender: Male
Nature: Adamant
Posts: 62
Quote:
Originally Posted by FBI View Post
I just copy-pasted and compiled it with no problems.

usage:

So if I wanted to evolve the 3rd Pokemon in my party I would put:
setvar 0x8001 0x2
callasm 0xOffset +1

Here's a compiled version:
Code:
FF B5 49 48 00 88 64 21 48 43 48 49 40 18 07 1C 0B 21 47 4B 00 F0 84 F8 05 1C 00 F0 29 F8 06 1C 38 1C 38 21 42 4B 00 F0 7B F8 04 1C 38 1C 3D 4A 31 1C 11 80 0B 21 3F 4B 00 F0 72 F8 38 1C 3E 4B 00 F0 6E F8 30 1C 3D 4B 00 F0 6A F8 30 1C 02 21 3B 4B 00 F0 65 F8 30 1C 03 21 39 4B 00 F0 60 F8 38 1C 38 21 32 4B 00 F0 5B F8 A0 42 37 D1 0C E0 04 21 41 43 40 18 C0 00 32 4B C1 18 48 88 8A 88 90 42 00 DC 70 47 10 1C 70 47 38 1C 2E 49 0A 1C 02 21 27 4B 00 F0 44 F8 2C 48 0B 21 69 43 09 18 0D 1C 29 49 0C 1C 00 20 0A 28 0D D0 01 35 29 78 01 34 22 78 8A 42 32 D1 FF 2A 00 D0 02 E0 FF 29 02 D0 2C E0 01 30 EF E7 20 4A 0B 20 46 43 B6 18 38 1C 32 1C 02 21 17 4B 00 F0 22 F8 1F E0 A0 42 D3 D0 02 1C 38 1C 19 21 11 4B 00 F0 19 F8 01 1C 00 09 A2 42 01 D9 09 18 00 E0 09 1A 09 4A 11 60 19 21 38 1C 0B 4B 00 F0 0B F8 38 1C 0A 4B 00 F0 07 F8 38 1C 38 21 06 4B 00 F0 02 F8 DF E7 FF BD 18 47 C0 46 B8 70 03 02 BA 70 03 02 84 42 02 02 E9 FB 03 08 7D 03 04 08 7D E4 03 08 99 32 04 08 75 8E 08 08 54 97 25 08 D0 1C 02 02 E0 5E 24 08
So let's say I wanted to make Deoxys "evolve" into another form of Deoxys when I talk to a meteor. How would I go about making the "evolve" Deoxys specifically whether it is in slot 1 or 3 or 5, etc?
__________________
POKEMON PULSAR VERSION PHASE 02 THREAD: https://www.pokecommunity.com/showthread.php?t=421565
(Phase 03 in development)


POKEMON PULSAR VERSION PHASE 02 TRAILER:https://www.youtube.com/watch?v=zPY7_ZvoO7E
(Formerly known as Pokemon Jashin Version)


-Praise Be To Jashin
Reply With Quote
  #1458   Link to this post, but load the entire thread.  
Old June 6th, 2019 (4:59 PM).
/JASHIN/'s Avatar
/JASHIN/ /JASHIN/ is offline
 
Join Date: Nov 2018
Location: Canada
Age: 29
Gender: Male
Nature: Adamant
Posts: 62
Quote:
Originally Posted by jiangzhengwenjzw View Post
Misc:

Evolution via Callasm in FR


Spoiler:
I will show you the GIF result of the hack:

Firstly, we just insert a function at 0xYYYYYY:
Code:
.thumb
push {r4, lr}
ldr r0, =0x300537C
ldr r1, =0x80568E1
str r1, [r0]
ldr r0, =0x020370C0
ldrh r1, [r0, #2]
mov r2, #1
ldrh r3, [r0, #0x10]
ldr r4, =0x80cdda9
bl bx_r4
pop {r4, pc}
bx_r4: bx r4
After that we should insert another function at 0xZZZZZZ:
Code:
.thumb
push {r4, lr}
mov r4, #0
loop:
ldr r0, =0x02024284
mov r1, #0x64
mul r1, r4
add r0, r0, r1
mov r1, #0xb
ldr r2, =0x803FBE9
bl bx_r2
ldr r1, =0x20370C0
ldrh r2, [r1]
cmp r0, r2
beq have_pre
add r4, #1
cmp r4, #6
bne loop

no_pokemon:
mov r4, #0xFF
b back

increment:
add r4, #1
cmp r4, #6
beq no_pokemon
b loop

have_pre:
ldr r0, =0x2024284
mov r1, #0x64
mul r1, r4
add r0, r0, r1
mov r1, #0x2d
ldr r2, =0x803FBE9
bl bx_r2
ldr r1, =0x20370C0
cmp r0, #1
beq increment

back:
strh r4, [r1, #0x10]
pop {r4, pc}
bx_r2:
bx r2
To use it via a script:
Code:
#org @start
lock
faceplayer
setvar 0x8004 0x4 //the species number of pokemon you want it to evolve(here's chamander)
setvar 0x8005 0x2 //the species number of pokemon after evolution(here's ivysaur)
callasm 0x8ZZZZZZ+1 //check the slot number of the pokemon
compare 0x800D 0xFF //check if the pokemon exists in the player's party
if1 1 @no_that_pokemon
callasm 0x8YYYYYY+1 //evolution
waitstate
//setweather 3 //you can define other events after waitstate
//doweather
release
end

//---------------
#org @no_that_pokemon
msgbox @message_string 6 //"You don't have that pokemon. "
release
end


//---------
// Strings
//---------
#org @message_string
= You don't have that pokemon.
Note: Only the first pokemon in your party with the species number in 0x8004 will evolve. I think that's better.

A EV-IV Display Screen


RENEWAL:
Spoiler:
The new version is here (no difference, but codes will be automatically inserted into the ROM):
FIRERED:
https://github.com/jiangzhengwenjz/EV-IV-Screen
EMERALD:
https://github.com/jiangzhengwenjz/EV-IV-Screen-EM
Read Readme.md to know how to compile.

Quick Preview:

OLD CONTENT:
Spoiler:
Quick Preview:

Download:
https://github.com/jiangzhengwenjz/EV-IV-Screen/tree/c1b303e17788f21e1a663204f9db59ffdcfc2a2d
Usage:
1. Make sure that you have Devkitarm and GNU make/cygwin installed.
2. Download this repo and create a new folder called "build".
3. Assign the free space you want to use in linker.lsc.
4. Open your cmd prompt and type in make. Then press enter.
5. Now main.bin should be generated. Paste it to the offset specified in step3.
6. Write a script to test (You should callasm to the offset of insertion + 0x79).
Code:
Example:
lock
faceplayer
callasm 0x8800079 //I inserted the code at 0x8800000 
msgbox 0x8FD0013 0x2 //"It's nice, huh?"
releaseall
end

80x80 mugshots


Spoiler:
Intro:
In Ruby, many hackers uses the BG0 to make mugshots. However, the same way that simply writing tileset, tilemap and palette to the RAM won't work for FR & EM as it will be cleared by the MSGBOX.

However, there's still a way to do it, which requires the knowledge of "rboxes". I've figured out some simple usage of the related functions, so I will show you my work:


The most ****ing thing should be that only 1 BG palette for FR can be used, which is the palette for the money box (the box with thinner border). Therefore, it will only be able to launch 1 mugshot at a time and you can't use it with the money box!

How to use:
The routines are provided at the bottom.
1. Change 0x8900000 in mugshot_make.asm to free space, which is ended in 0,4,8,c. It will be the location of our custom table.
2. Compile the 2 routines and insert them to some free space (Not the table location in step 1)
3. Get/draw some 80x80 mugshots, here's 2 examples:

They should be indexed to 16 colors.
4. Open your UNLZ-GBA and insert your images and palettes.
Note: the image and the palette should all be LZ77 compressed, which means that you should insert them by using "export image" and "export palette" in UNLZ-GBA. Aparrently they should all be inserted at some free space.
5. Build the table at the offset in step 1, whose format should be [image0 pointer][image0 pal pointer][image1 pointer][image1 pal pointer][image2 pointer][image2 pal pointer]...................
It can load up to 65536 images in algorithm, which means that it's enough.
6. Test time! use
setvar 0x8004 [image index in the table]
setvar 0x8005 [0 or 1] // 0 = left, 1 = right
callasm 0x8[mugshot_make.asm+1]
to launch the mugshot and
callasm 0x8[mugshot_del.asm+1] to delete it.

An example:
I insert the 2 images at 0xFA0000, 0xFA09CC and the 2 palettes at 0xFA09A4, 0xFA1484. Then the table should be:
Code:
00 00 FA 08 A4 09 FA 08 CC 09 FA 08 84 14 FA 08
The script:
Code:
//---------------
#org 0xF00000
lock
setvar 0x8004 0x0 //image0
setvar 0x8005 0x1 //right side
callasm 0x8800001 //mugshot_make.asm+1
msgbox 0x8F00030 0x6
callasm 0x8800089 //mugshot_del.asm+1
release
end

#org 0xF00030
= ABCD.
The routines:
mugshot_make.asm:
Code:
/*
Note: both image and palette should be LZ77 compressed!
Table format: [image pointer][pal pointer]..........
*/
.equiv table_location, 0x8900000
.thumb
push {r4-r5, lr}
sub sp, sp, #0x18
ldr r0, =0x20370C0
ldrh r0, [r0, #2]
mov r1, #0
mov r2, #0x14
mul r2, r0
mov r3, #4
mov r0, #10
str r0, [sp]
str r0, [sp, #4]
mov r0, #0xD
str r0, [sp, #8]
mov r0, #0x40
str r0, [sp, #0xC]
add r0, sp, #0x10
ldr r4, =0x810FE51
bl bx_r4
add r0, sp, #0x10
ldr r4, =0x8003CE5
bl bx_r4
ldr r4, =0x2039990
strb r0, [r4]
ldr r4, =0x8003FA1
bl bx_r4
ldr r0, =0x20370C0
ldrh r0, [r0]
ldr r1, =table_location
lsl r0, r0, #3
add r0, r0, r1
ldr r5, [r0, #4]
ldr r0, [r0]
ldr r1, =0x6008800
swi 0x12
mov r0, r5
mov r1, #0xd0
mov r2, #0x20
ldr r4, =0x80703A9
bl bx_r4
mov r0, #0
ldr r4, =0x80020BD
bl bx_r4
add sp, sp, #0x18
pop {r4-r5, pc}

bx_r4: bx r4
mugshot_del.asm:
Code:
.thumb
push {r4, lr}
ldr r4, =0x2039990
ldrb r4, [r4]
mov r1, #0
mov r0, r4
ldr r3, =0x810F4D9
bl bx_r3
mov r0, r4
mov r1, #2
ldr r3, =0x8003F21
bl bx_r3
mov r0, r4
ldr r3, =0x8003E3D
bl bx_r3
pop {r4, pc}

bx_r3: bx r3

Some new movement bytes (including a patch)


Spoiler:
The patch will write new data to the offset 0xF80000, so make sure that area of your hack has not been used yet. Here's the download link:
http://www.mediafire.com/download/hfb2s47jq3k4oow/movements.ips

I haven't tested much on this hack, so it may have some bugs but you can modify it on your own as I've released the source code at the bottom.

The new bytes are:
Code:
0xAA - move up backwards (very slow)
0xAB - move down backwards (very slow)
0xAC - move right backwards (very slow)
0xAD - move left backwards (very slow)
0xAE - move up backwards (slow)
0xAF - move down backwards (slow)
0xB0 - move right backwards (slow)
0xB1 - move left backwards (slow)
0xB2 - move up backwards (normal)
0xB3 - move down backwards (normal)
0xB4 - move right backwards (normal)
0xB5 - move left backwards (normal)
0xB6 - move up backwards (fast)
0xB7 - move down backwards (fast)
0xB8 - move right backwards (fast)
0xB9 - move left backwards (fast)
0xBA - jump up backwards (2 squares)
0xBB - jump down backwards (2 squares)
0xBC - jump right backwards (2 squares)
0xBD - jump left backwards (2 squares)
0xBE - jump up backwards (1 square)
0xBF - jump down backwards (1 square)
0xC0 - jump right backwards (1 square)
0xC1 - jump left backwards (1 square)
0xC2 - face down and move left-down (normal)
0xC3 - face up and move left-up (normal)
0xC4 - face left and move left-down (normal)
0xC5 - face right and move right-down (normal)
0xC6 - face down and move right-down (normal)
0xC7 - face up and move right-up (normal)
0xC8 - face left and move left-up (normal)
0xC9 - face right and move right-up (normal)
Here's a picture including all the bytes above in a script:


The diagonal ones (0xc2~0xc9) can be used in some kind of stairs, as [MENTION=26643]Invert[/MENTION] asked of me about that kind of stairs.

Some people may be interested in the source code, so I will put it here:
Code:
.equ ins_ofs, 0x8F802A8
.thumb
.align 2
table_expansion:
.word ins_ofs+walk_ldmu, ins_ofs+walk_lumd, ins_ofs+walk_llmr, ins_ofs+walk_lrml
.word ins_ofs+go_ldmu, ins_ofs+go_lumd, ins_ofs+go_llmr, ins_ofs+go_lrml
.word ins_ofs+pulse_ldmu, ins_ofs+pulse_lumd, ins_ofs+pulse_llmr, ins_ofs+pulse_lrml
.word ins_ofs+run_ldmu, ins_ofs+run_lumd, ins_ofs+run_llmr, ins_ofs+run_lrml
.word ins_ofs+jump_2sq_ldmu, ins_ofs+jump_2sq_lumd, ins_ofs+jump_2sq_llmr, ins_ofs+jump_2sq_lrml
.word ins_ofs+jump_1sq_ldmu, ins_ofs+jump_1sq_lumd, ins_ofs+jump_1sq_llmr, ins_ofs+jump_1sq_lrml
.word ins_ofs+pulse_15, ins_ofs+pulse_27, ins_ofs+pulse_35, ins_ofs+pulse_46
.word ins_ofs+pulse_16, ins_ofs+pulse_28, ins_ofs+pulse_37, ins_ofs+pulse_48

walk_ldmu: .word ins_ofs+walk_ldmu_func+1, ins_ofs+an_walk_dn_2+1, 0x8067935
walk_lumd: .word ins_ofs+walk_lumd_func+1, ins_ofs+an_walk_dn_2+1, 0x8067935
walk_llmr: .word ins_ofs+walk_llmr_func+1, ins_ofs+an_walk_dn_2+1, 0x8067935
walk_lrml: .word ins_ofs+walk_lrml_func+1, ins_ofs+an_walk_dn_2+1, 0x8067935

go_ldmu: .word ins_ofs+go_ldmu_func+1, ins_ofs+an_go_dn_2+1, 0x8067935
go_lumd: .word ins_ofs+go_lumd_func+1, ins_ofs+an_go_dn_2+1, 0x8067935
go_llmr: .word ins_ofs+go_llmr_func+1, ins_ofs+an_go_dn_2+1, 0x8067935
go_lrml: .word ins_ofs+go_lrml_func+1, ins_ofs+an_go_dn_2+1, 0x8067935

pulse_ldmu: .word ins_ofs+pulse_ldmu_func+1, ins_ofs+an_pulse_dn_2+1, 0x8067935
pulse_lumd: .word ins_ofs+pulse_lumd_func+1, ins_ofs+an_pulse_dn_2+1, 0x8067935
pulse_llmr: .word ins_ofs+pulse_llmr_func+1, ins_ofs+an_pulse_dn_2+1, 0x8067935
pulse_lrml: .word ins_ofs+pulse_lrml_func+1, ins_ofs+an_pulse_dn_2+1, 0x8067935

run_ldmu: .word ins_ofs+run_ldmu_func+1, ins_ofs+an_run_dn_2+1, 0x8067935
run_lumd: .word ins_ofs+run_lumd_func+1, ins_ofs+an_run_dn_2+1, 0x8067935
run_llmr: .word ins_ofs+run_llmr_func+1, ins_ofs+an_run_dn_2+1, 0x8067935
run_lrml: .word ins_ofs+run_lrml_func+1, ins_ofs+an_run_dn_2+1, 0x8067935

jump_2sq_ldmu: .word ins_ofs+jump_2sq_ldmu_func+1, ins_ofs+an_jump_2sq_dn_2+1, 0x8067935
jump_2sq_lumd: .word ins_ofs+jump_2sq_lumd_func+1, ins_ofs+an_jump_2sq_dn_2+1, 0x8067935
jump_2sq_llmr: .word ins_ofs+jump_2sq_llmr_func+1, ins_ofs+an_jump_2sq_dn_2+1, 0x8067935
jump_2sq_lrml: .word ins_ofs+jump_2sq_lrml_func+1, ins_ofs+an_jump_2sq_dn_2+1, 0x8067935

jump_1sq_ldmu: .word ins_ofs+jump_1sq_ldmu_func+1, ins_ofs+an_jump_1sq_dn_2+1, 0x8067935
jump_1sq_lumd: .word ins_ofs+jump_1sq_lumd_func+1, ins_ofs+an_jump_1sq_dn_2+1, 0x8067935
jump_1sq_llmr: .word ins_ofs+jump_1sq_llmr_func+1, ins_ofs+an_jump_1sq_dn_2+1, 0x8067935
jump_1sq_lrml: .word ins_ofs+jump_1sq_lrml_func+1, ins_ofs+an_jump_1sq_dn_2+1, 0x8067935

pulse_15: .word ins_ofs+pulse_15_func+1, ins_ofs+pulse15_func_2+1, 0x8067935
pulse_27: .word ins_ofs+pulse_27_func+1, ins_ofs+pulse15_func_2+1, 0x8067935
pulse_35: .word ins_ofs+pulse_35_func+1, ins_ofs+pulse15_func_2+1, 0x8067935
pulse_46: .word ins_ofs+pulse_46_func+1, ins_ofs+pulse15_func_2+1, 0x8067935
pulse_16: .word ins_ofs+pulse_16_func+1, ins_ofs+pulse16_func_2+1, 0x8067935
pulse_28: .word ins_ofs+pulse_28_func+1, ins_ofs+pulse16_func_2+1, 0x8067935
pulse_37: .word ins_ofs+pulse_37_func+1, ins_ofs+pulse16_func_2+1, 0x8067935
pulse_48: .word ins_ofs+pulse_48_func+1, ins_ofs+pulse16_func_2+1, 0x8067935

pulse_15_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #1
mov r3, #0
bl an_run_any_f
mov r0, r4
mov r1, r5
bl pulse15_func_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

pulse_27_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #2
mov r3, #0
bl an_run_any_f
mov r0, r4
mov r1, r5
bl pulse15_func_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

pulse_35_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #3
mov r3, #0
bl an_run_any_f
mov r0, r4
mov r1, r5
bl pulse15_func_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

pulse_46_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #4
mov r3, #0
bl an_run_any_f
mov r0, r4
mov r1, r5
bl pulse15_func_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

pulse_16_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #1
mov r3, #0
bl an_run_any_g
mov r0, r4
mov r1, r5
bl pulse16_func_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

pulse_28_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #2
mov r3, #0
bl an_run_any_g
mov r0, r4
mov r1, r5
bl pulse16_func_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

pulse_37_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #3
mov r3, #0
bl an_run_any_g
mov r0, r4
mov r1, r5
bl pulse16_func_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

pulse_48_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #4
mov r3, #0
bl an_run_any_g
mov r0, r4
mov r1, r5
bl pulse16_func_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

pulse15_func_2:
push {r4, lr}
mov r4, r1
bl sub_8064788_f
ldr r1, =0x8064D65
bx r1
.ltorg

pulse16_func_2:
push {r4, lr}
mov r4, r1
bl sub_8064788_g
ldr r1, =0x8064D65
bx r1
.ltorg

sub_8064788_f:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r0, r5
bl obj_npc_ministep_f
ldr r1, =0x8064795
bx r1
.ltorg

sub_8064788_g:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r0, r5
bl obj_npc_ministep_g
ldr r1, =0x8064795
bx r1
.ltorg

obj_npc_ministep_f:
push {r4, r5, lr}
mov r4, r0
ldr r5, =0x83a71b0
mov r0, #0x36
ldrsh r2, [r4, r0]
lsl r0, r2, #1
add r0, r0, r5
mov r3, #0x38
ldrsh r1, [r4, r3]
mov r3, #0
ldrsh r0, [r0, r3]
cmp r1, r0
bge loc_8068BB4_f
ldr r1, =0x83A719C
lsl r0, r2, #2
add r0, r0, r1
mov r1, #0x38
ldrsh r2, [r4, r1]
ldr r0, [r0]
lsl r2, r2, #2
add r2, r2, r0
ldrh r1, [r4, #0x34]
lsl r1, r1, #0x18
lsr r1, r1, #0x18
ldr r0, =ins_ofs+custom_table
sub r1, #1
lsl r1, r1, #1
ldrsh r1, [r0, r1]
ldr r2, [r2]
mov r0, r4
bl bx_r2
ldr r0, =0x8068B8D
bx r0

loc_8068BB4_f:
mov r0, #0
pop {r4, r5, pc}
.ltorg

obj_npc_ministep_g:
push {r4, r5, lr}
mov r4, r0
ldr r5, =0x83a71b0
mov r0, #0x36
ldrsh r2, [r4, r0]
lsl r0, r2, #1
add r0, r0, r5
mov r3, #0x38
ldrsh r1, [r4, r3]
mov r3, #0
ldrsh r0, [r0, r3]
cmp r1, r0
bge loc_8068BB4_g
ldr r1, =0x83A719C
lsl r0, r2, #2
add r0, r0, r1
mov r1, #0x38
ldrsh r2, [r4, r1]
ldr r0, [r0]
lsl r2, r2, #2
add r2, r2, r0
ldrh r1, [r4, #0x34]
lsl r1, r1, #0x18
lsr r1, r1, #0x18
ldr r0, =ins_ofs+custom_table
add r1, #3
lsl r1, r1, #1
ldrsh r1, [r0, r1]
ldr r2, [r2]
mov r0, r4
bl bx_r2
ldr r0, =0x8068B8D
bx r0

loc_8068BB4_g:
mov r0, #0
pop {r4, r5, pc}
.ltorg

an_run_any_f:
push {r4-r7, lr}
mov r7, r8
push {r7}
sub sp, sp, #0x14
mov r5, r0
mov r8, r1
mov r4, r3
lsl r2, r2, #0x18
lsr r2, r2, #0x18
lsl r4, r4, #0x18
lsr r4, r4, #0x18
mov r1, sp
ldr r0, =0x83a6884
ldmia r0!, {r3, r6, r7}
stmia r1!, {r3, r6, r7}
ldmia r0!, {r3, r6}
stmia r1!, {r3, r6}
mov r0, r5
mov r1, r8
mov r3, r4
bl npc_apply_direction_f
ldr r7, =0x8064729
bx r7
.ltorg

npc_apply_direction_f:
push {r4-r6, lr}
mov r6, r9
mov r5, r8
push {r5, r6}
sub sp, sp, #4
mov r8, r0
mov r9, r1
mov r4, r2
mov r6, r3
lsl r4, r4, #0x18
lsr r4, r4, #0x18
lsl r6, r6, #0x18
lsr r6, r6, #0x18
ldrh r1, [r0, #0x10]
mov r0, sp
strh r1, [r0, #0]
mov r1, r8
ldrh r0, [r1, #0x12]
mov r5, sp
add r5, #2
strh r0, [r5]
mov r0, r8
mov r1, r4
ldr r3, =0x805FBDD
bl bx_r3
ldr r1, =ins_ofs+custom_table
sub r2, r4, #1
lsl r2, r2, #1
ldrsh r0, [r1, r2]
ldr r1, =0x80646AD
bx r1
.ltorg

an_run_any_g:
push {r4-r7, lr}
mov r7, r8
push {r7}
sub sp, sp, #0x14
mov r5, r0
mov r8, r1
mov r4, r3
lsl r2, r2, #0x18
lsr r2, r2, #0x18
lsl r4, r4, #0x18
lsr r4, r4, #0x18
mov r1, sp
ldr r0, =0x83a6884
ldmia r0!, {r3, r6, r7}
stmia r1!, {r3, r6, r7}
ldmia r0!, {r3, r6}
stmia r1!, {r3, r6}
mov r0, r5
mov r1, r8
mov r3, r4
bl npc_apply_direction_g
ldr r7, =0x8064729
bx r7
.ltorg

npc_apply_direction_g:
push {r4-r6, lr}
mov r6, r9
mov r5, r8
push {r5, r6}
sub sp, sp, #4
mov r8, r0
mov r9, r1
mov r4, r2
mov r6, r3
lsl r4, r4, #0x18
lsr r4, r4, #0x18
lsl r6, r6, #0x18
lsr r6, r6, #0x18
ldrh r1, [r0, #0x10]
mov r0, sp
strh r1, [r0, #0]
mov r1, r8
ldrh r0, [r1, #0x12]
mov r5, sp
add r5, #2
strh r0, [r5]
mov r0, r8
mov r1, r4
ldr r3, =0x805FBDD
bl bx_r3
ldr r1, =ins_ofs+custom_table
add r2, r4, #3
lsl r2, r2, #1
ldrsh r0, [r1, r2]
ldr r1, =0x80646AD
bx r1
.ltorg

.align 2
custom_table: .hword 5, 7, 5, 6, 6, 8, 7, 8

jump_1sq_ldmu_func:
push {r4, r5, lr}
sub sp, sp, #4
mov r4, r0
mov r5, r1
mov r0, #2
str r0, [sp]
mov r0, r4
mov r2, #1
mov r3, #1
bl maybe_shadow_1
mov r0, r4
mov r1, r5
bl an_jump_1sq_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
add sp, sp, #4
pop {r4, r5, pc}
.ltorg

jump_1sq_lumd_func:
push {r4, r5, lr}
sub sp, sp, #4
mov r4, r0
mov r5, r1
mov r0, #2
str r0, [sp]
mov r0, r4
mov r2, #2
mov r3, #1
bl maybe_shadow_1
mov r0, r4
mov r1, r5
bl an_jump_1sq_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
add sp, sp, #4
pop {r4, r5, pc}
.ltorg

jump_1sq_llmr_func:
push {r4, r5, lr}
sub sp, sp, #4
mov r4, r0
mov r5, r1
mov r0, #2
str r0, [sp]
mov r0, r4
mov r2, #3
mov r3, #1
bl maybe_shadow_1
mov r0, r4
mov r1, r5
bl an_jump_1sq_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
add sp, sp, #4
pop {r4, r5, pc}
.ltorg

jump_1sq_lrml_func:
push {r4, r5, lr}
sub sp, sp, #4
mov r4, r0
mov r5, r1
mov r0, #2
str r0, [sp]
mov r0, r4
mov r2, #4
mov r3, #1
bl maybe_shadow_1
mov r0, r4
mov r1, r5
bl an_jump_1sq_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
add sp, sp, #4
pop {r4, r5, pc}
.ltorg

an_jump_1sq_dn_2:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
bl sub_8065028
ldr r1, =0x8066493
bx r1
.ltorg

jump_2sq_ldmu_func:
push {r4, r5, lr}
sub sp, sp, #4
mov r4, r0
mov r5, r1
mov r0, #0
str r0, [sp, #0]
mov r0, r4
mov r2, #1
mov r3, #2
bl maybe_shadow_1
mov r0, r4
mov r1, r5
bl an_jump_2sq_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
add sp, sp, #4
pop {r4, r5, pc}
.ltorg

jump_2sq_lumd_func:
push {r4, r5, lr}
sub sp, sp, #4
mov r4, r0
mov r5, r1
mov r0, #0
str r0, [sp, #0]
mov r0, r4
mov r2, #2
mov r3, #2
bl maybe_shadow_1
mov r0, r4
mov r1, r5
bl an_jump_2sq_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
add sp, sp, #4
pop {r4, r5, pc}
.ltorg

jump_2sq_llmr_func:
push {r4, r5, lr}
sub sp, sp, #4
mov r4, r0
mov r5, r1
mov r0, #0
str r0, [sp, #0]
mov r0, r4
mov r2, #3
mov r3, #2
bl maybe_shadow_1
mov r0, r4
mov r1, r5
bl an_jump_2sq_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
add sp, sp, #4
pop {r4, r5, pc}
.ltorg

jump_2sq_lrml_func:
push {r4, r5, lr}
sub sp, sp, #4
mov r4, r0
mov r5, r1
mov r0, #0
str r0, [sp, #0]
mov r0, r4
mov r2, #4
mov r3, #2
bl maybe_shadow_1
mov r0, r4
mov r1, r5
bl an_jump_2sq_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
add sp, sp, #4
pop {r4, r5, pc}
.ltorg

maybe_shadow_1:
push {r4, r5, lr}
sub sp, sp, #4
mov r4, r0
mov r5, r1
ldr r0, [sp, #0x10]
lsl r2, r2, #0x18
lsr r2, r2, #0x18
lsl r3, r3, #0x18
lsr r3, r3, #0x18
lsl r0, r0, #0x18
lsr r0, r0, #0x18
str r0, [sp]
mov r0, r4
bl sub_8064E3C
ldr r0, =0x8064f17
bx r0
.ltorg

sub_8064E3C:
push {r4-r7, lr}
mov r7, r10
mov r6, r9
mov r5, r8
push {r5-r7}
sub sp, sp, #0x10
mov r7, r0
mov r10, r1
mov r4, r2
mov r8, r3
ldr r0, [sp, #0x30]
lsl r4, r4, #0x18
lsr r4, r4, #0x18
mov r1, r8
lsl r1, r1, #0x18
lsr r1, r1, #0x18
mov r8, r1
lsl r0, r0, #0x18
lsr r0, r0, #0x18
mov r9, r0
ldr r1, =0x83a6958
add r0, sp, #4
mov r2, #6
ldr r3, =0x81E5E79
bl bx_r3
add r5, sp, #0xc
mov r0, #0
strh r0, [r5]
mov r6, r13
add r6, #0xe
strh r0, [r6]
mov r0, r7
mov r1, r4
ldr r3, =0x805FBDD
bl bx_r3
mov r1, r8
lsl r0, r1, #1
add r0, sp
add r0, #4
mov r1, #0
ldrsh r3, [r0, r1]
str r3, [sp, #0]
sub r0, r4, #1
mov r1, #1
eor r0, r1
add r0, #1
ldr r1, =0x8064E93
bx r1
.ltorg

an_jump_2sq_dn_2:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
bl sub_8065028
ldr r1, =0x80650DF
bx r1
.ltorg

sub_8065028:
push {lr}
bl sub_8065000
ldr r1, =0x806502F
bx r1
.ltorg

sub_8065000:
push {lr}
ldr r2, =ins_ofs+sub_8068D3C+1
bl sub_8064F3C
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {pc}
.ltorg

sub_8068D3C:
push {r4-r6, lr}
sub sp, sp, #0xc
mov r4, r0
ldr r1, =0x83a71f8
mov r0, sp
mov r2, #6
ldr r3, =0x81E5E79
bl bx_r3
add r5, sp, #8
ldr r1, =0x83a71fe
mov r0, r5
mov r2, #3
ldr r3, =0x81E5E79
bl bx_r3
mov r6, #0
mov r1, #0x36
ldrsh r0, [r4, r1]
cmp r0, #0
beq loc_8068D6E
ldrh r1, [r4, #0x34]
lsl r1, r1, #0x18
lsr r1, r1, #0x18
sub r1, #1
mov r0, #1
eor r1, r0
add r1, #1
ldr r0, =0x8068D69
bx r0
loc_8068D6E:
ldr r0, =0x8068D6F
bx r0
.ltorg

sub_8064F3C:
push {r4-r7, lr}
mov r7, r8
push {r7}
sub sp, sp, #0x10
mov r6, r0
mov r7, r1
mov r4, r2
ldr r1, =0x83a695e
add r0, sp, #4
mov r2, #6
ldr r3, =0x81E5E79
bl bx_r3
mov r0, r7
bl bx_r4
lsl r0, r0, #0x18
lsr r0, r0, #0x18
mov r8, r0
cmp r0, #1
bne loc_8064FCC
mov r1, #0x36
ldrsh r0, [r7, r1]
lsl r0, r0, #1
add r0, sp
add r0, #4
mov r2, #0
ldrsh r0, [r0, r2]
cmp r0, #0
beq loc_8064FCC
add r4, sp, #0xc
mov r0, #0
strh r0, [r4]
mov r5, r13
add r5, #0xe
strh r0, [r5]
ldrb r0, [r6, #0x18]
lsr r0, r0, #4
sub r0, #1
mov r1, #1
eor r0, r1
add r0, #1
ldr r1, =0x8064F87
bx r1

loc_8064FCC:
ldr r1, =0x8064fcd
bx r1
.ltorg

run_ldmu_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #1
mov r3, #1
bl an_run_any
mov r0, r4
mov r1, r5
bl an_run_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

run_lumd_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #2
mov r3, #1
bl an_run_any
mov r0, r4
mov r1, r5
bl an_run_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

run_llmr_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #3
mov r3, #1
bl an_run_any
mov r0, r4
mov r1, r5
bl an_run_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

run_lrml_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #4
mov r3, #1
bl an_run_any
mov r0, r4
mov r1, r5
bl an_run_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

an_run_dn_2:
push {r4, lr}
mov r4, r1
bl sub_8064788
ldr r1, =0x80652F5
bx r1
.ltorg

pulse_ldmu_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #1
mov r3, #0
bl an_run_any
mov r0, r4
mov r1, r5
bl an_pulse_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

pulse_lumd_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #2
mov r3, #0
bl an_run_any
mov r0, r4
mov r1, r5
bl an_pulse_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

pulse_llmr_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #3
mov r3, #0
bl an_run_any
mov r0, r4
mov r1, r5
bl an_pulse_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

pulse_lrml_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #4
mov r3, #0
bl an_run_any
mov r0, r4
mov r1, r5
bl an_pulse_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

an_run_any:
push {r4-r7, lr}
mov r7, r8
push {r7}
sub sp, sp, #0x14
mov r5, r0
mov r8, r1
mov r4, r3
lsl r2, r2, #0x18
lsr r2, r2, #0x18
lsl r4, r4, #0x18
lsr r4, r4, #0x18
mov r1, sp
ldr r0, =0x83a6884
ldmia r0!, {r3, r6, r7}
stmia r1!, {r3, r6, r7}
ldmia r0!, {r3, r6}
stmia r1!, {r3, r6}
mov r0, r5
mov r1, r8
mov r3, r4
bl npc_apply_direction
ldr r7, =0x8064729
bx r7
.ltorg

npc_apply_direction:
push {r4-r6, lr}
mov r6, r9
mov r5, r8
push {r5, r6}
sub sp, sp, #4
mov r8, r0
mov r9, r1
mov r4, r2
mov r6, r3
lsl r4, r4, #0x18
lsr r4, r4, #0x18
lsl r6, r6, #0x18
lsr r6, r6, #0x18
ldrh r1, [r0, #0x10]
mov r0, sp
strh r1, [r0, #0]
mov r1, r8
ldrh r0, [r1, #0x12]
mov r5, sp
add r5, #2
strh r0, [r5]
mov r0, r8
mov r1, r4
ldr r3, =0x805FBDD
bl bx_r3
sub r0, r4, #1
mov r1, #1
eor r0, r1
add r0, #1
ldr r1, =0x80646AD
bx r1
.ltorg

an_pulse_dn_2:
push {r4, lr}
mov r4, r1
bl sub_8064788
ldr r1, =0x8064D65
bx r1
.ltorg

sub_8064788:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r0, r5
bl obj_npc_ministep
ldr r1, =0x8064795
bx r1
.ltorg

obj_npc_ministep:
push {r4, r5, lr}
mov r4, r0
ldr r5, =0x83a71b0
mov r0, #0x36
ldrsh r2, [r4, r0]
lsl r0, r2, #1
add r0, r0, r5
mov r3, #0x38
ldrsh r1, [r4, r3]
mov r3, #0
ldrsh r0, [r0, r3]
cmp r1, r0
bge loc_8068BB4
ldr r1, =0x83A719C
lsl r0, r2, #2
add r0, r0, r1
mov r1, #0x38
ldrsh r2, [r4, r1]
ldr r0, [r0]
lsl r2, r2, #2
add r2, r2, r0
ldrh r1, [r4, #0x34]
lsl r1, r1, #0x18
lsr r1, r1, #0x18
sub r1, #1
mov r0, #1
eor r1, r0
add r1, #1
ldr r2, [r2]
mov r0, r4
bl bx_r2
ldr r0, =0x8068B8D
bx r0

loc_8068BB4:
mov r0, #0
pop {r4, r5, pc}
.ltorg

go_ldmu_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #1
bl an_go_any_1
mov r0, r4
mov r1, r5
bl an_go_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

go_lumd_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #2
bl an_go_any_1
mov r0, r4
mov r1, r5
bl an_go_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

go_llmr_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #3
bl an_go_any_1
mov r0, r4
mov r1, r5
bl an_go_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

go_lrml_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #4
bl an_go_any_1
mov r0, r4
mov r1, r5
bl an_go_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

an_go_any_1:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
lsl r2, r2, #0x18
lsr r2, r2, #0x18
bl sub_8064B68
ldr r0, =0x8064be7
bx r0
.ltorg

sub_8064B68:
push {r4-r6, lr}
mov r6, r8
push {r6}
sub sp, sp, #4
mov r6, r0
mov r8, r1
lsl r5, r2, #0x18
lsr r5, r5, #0x18
ldrh r1, [r6, #0x10]
mov r0, sp
strh r1, [r0, #0]
ldrh r0, [r6, #0x12]
mov r4, sp
add r4, #2
strh r0, [r4]
mov r0, r6
mov r1, r5
ldr r3, =0x805FBDD
bl bx_r3
sub r0, r5, #1
mov r1, #1
eor r0, r1
add r0, #1
mov r1, sp
ldr r2, =0x8064b93
bx r2
.ltorg

an_go_dn_2:
push {r4, lr}
mov r4, r1
bl sub_8064C04
ldr r1, =0x8064ca5
bx r1
.ltorg

sub_8064C04:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r0, r5
bl sub_8068C18
ldr r1, =0x8064c11
bx r1
.ltorg

sub_8068C18:
push {r4, lr}
mov r4, r0
ldrh r0, [r4, #0x36]
add r0, #1
strh r0, [r4, #0x36]
lsl r0, r0, #0x10
asr r0, r0, #0x10
cmp r0, #2
bgt loc_8068C3E
ldrh r1, [r4, #0x34]
lsl r1, r1, #0x18
lsr r1, r1, #0x18
sub r1, #1
mov r0, #1
eor r1, r0
add r1, #1
ldr r0, =0x8068c31
bx r0
loc_8068C3E:
ldr r0, =0x8068C3F
bx r0
.ltorg

walk_ldmu_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #1
bl an_walk_any_1
mov r0, r4
mov r1, r5
bl an_walk_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

walk_lumd_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #2
bl an_walk_any_1
mov r0, r4
mov r1, r5
bl an_walk_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

walk_llmr_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #3
bl an_walk_any_1
mov r0, r4
mov r1, r5
bl an_walk_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

walk_lrml_func:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r2, #4
bl an_walk_any_1
mov r0, r4
mov r1, r5
bl an_walk_dn_2
lsl r0, r0, #0x18
lsr r0, r0, #0x18
pop {r4, r5, pc}
.ltorg

an_walk_dn_2:
push {r4, lr}
mov r4, r1
bl an_walk_any_2
lsl r0, r0, #0x18
cmp r0, #0
beq loc_8064aa0
mov r0, #2
strh r0, [r4, #0x32]
mov r0, #1

loc_8064aa0:
pop {r4, pc}
.ltorg

an_walk_any_1:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
lsl r2, r2, #0x18
lsr r2, r2, #0x18
bl sub_80647C0
ldrb r0, [r4, #0x18]
lsl r0, r0, #0x1c
lsr r0, r0, #0x1c
ldr r3, =0x8063441
bl bx_r3
mov r2, r0
lsl r2, r2, #0x18
lsr r2, r2, #0x18
mov r0, r4
mov r1, r5
ldr r3, =0x8063555
bl bx_r3
pop {r4, r5, pc}
.ltorg

sub_80647C0:
push {r4-r6, lr}
mov r6, r8
push {r6}
sub sp, sp, #4
mov r6, r0
mov r8, r1
lsl r5, r2, #0x18
lsr r5, r5, #0x18
ldrh r1, [r6, #0x10]
mov r0, sp
strh r1, [r0, #0]
ldrh r0, [r6, #0x12]
mov r4, sp
add r4, #2
strh r0, [r4]
mov r0, r6
mov r1, r5
ldr r3, =0x805FBDD
bl bx_r3
sub r0, r5, #1
mov r1, #1
eor r0, r1
add r0, #1
mov r1, sp
mov r2, r4
ldr r3, =0x80647ED
bx r3
.ltorg

an_walk_any_2:
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r0, r5
bl sub_8068BCC
ldr r1, =0x8064869
bx r1
.ltorg

sub_8068BCC:
push {r4, lr}
mov r4, r0
ldrh r1, [r4, #0x36]
mov r0, #1
and r0, r1
cmp r0, #0
bne loc_8068bec
ldrh r1, [r4, #0x34]
sub r1, #1
mov r0, #1
eor r1, r0
add r1, #1
mov r0, r4
ldr r3, =0x8068be3
bx r3

loc_8068bec:
ldr r0, =0x8068bed
bx r0
.ltorg

bx_r3: bx r3
bx_r2: bx r2
bx_r4: bx r4
How to insert if you don't like the offset 0xF80000 and don't want to use the patch:
1. Repoint the table at 0x3A65BC (3 pointers totally)
2. Change the 0x8F802A8 at the first line to the insert offset of the table + 0x2a8.
3. Compile it and insert it at the insert offset of the table + 0x2a8.
4. Write a script to test.


Credits:
Back~, Invert, Knizz
Hey would you by chance have a variant of that code that skips the evolution cutscene? I'm trying to do it for form changes, and the form change ASM routines here base it off of slot number and don't really give the option to check if you have a certain pokemon or not. For example. One will let you choose any pokemon to evolve into what you want and the other bases it on what slot number the pokemon is in. I need a code that will change a specific pokemon's index number or even making it "evolve" silently.
__________________
POKEMON PULSAR VERSION PHASE 02 THREAD: https://www.pokecommunity.com/showthread.php?t=421565
(Phase 03 in development)


POKEMON PULSAR VERSION PHASE 02 TRAILER:https://www.youtube.com/watch?v=zPY7_ZvoO7E
(Formerly known as Pokemon Jashin Version)


-Praise Be To Jashin
Reply With Quote
  #1459   Link to this post, but load the entire thread.  
Old June 6th, 2019 (6:03 PM). Edited June 6th, 2019 by jiangzhengwenjzw.
jiangzhengwenjzw's Avatar
jiangzhengwenjzw jiangzhengwenjzw is offline
now working on katam
 
Join Date: Sep 2012
Gender: Male
Posts: 175
Quote:
Originally Posted by /JASHIN/ View Post
Hey would you by chance have a variant of that code that skips the evolution cutscene? I'm trying to do it for form changes, and the form change ASM routines here base it off of slot number and don't really give the option to check if you have a certain pokemon or not. For example. One will let you choose any pokemon to evolve into what you want and the other bases it on what slot number the pokemon is in. I need a code that will change a specific pokemon's index number or even making it "evolve" silently.
For silent evo you'd better take a look at FBI's routine which is also posted under this thread.

If you still want to use my routine:
Spoiler:
You need to modify the routine because the logic will be completely different and I currently don't have the desire for polishing my old trash routines. In addition, the way to implement it is strongly dependent of the author's requirement.

It will be easy if you want to edit it on your own. Basically it should be:
(From the script's view)
call special XX (the pokemon selection screen with OW callback) -> get the slot number from var -> decrypt its species with a built-in function -> find its evo form in evolution table -> ... ???

Yes, here comes the question: if a pokemon has several different evo method, which should it be taken?
There will be several apparent options:
1. ban those pokemons in this event
2. always take the first form
3. ask the player (how? should we generate a dynamic option list? )
4. randomly pick one (pointless for players abusing S/L)
5. build a custom table to control everything
......

That's why I think you'd better implement it yourself. The code I wrote should be easy to understand but I still want to explain the addresses used here:
Code:
0x300537C: RAM location to store the callback to be called post evolution
0x80568E0: the callback function for returning to OW
0x20370C0: var 0x8004
0x80CDDA8: the evolution function (*)
0x803FBE8: The built-in pokemon data decrypter
*: actually it adds a task but you don't need to know its inner logic if you don't have much experience with ASM hacking.


(I posted detailed explanation because several people asked me about that routine. )
Reply With Quote
  #1460   Link to this post, but load the entire thread.  
Old June 7th, 2019 (6:26 PM).
/JASHIN/'s Avatar
/JASHIN/ /JASHIN/ is offline
 
Join Date: Nov 2018
Location: Canada
Age: 29
Gender: Male
Nature: Adamant
Posts: 62
Quote:
Originally Posted by FBI View Post
No, no! Use a modified one.
Here:

Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r7, lr}
	ldr r0, .SLOT @calculate address of Pokemon we want to evolve
	ldrh r0, [r0]
	mov r1, #0x64
	mul r0, r0, r1
	ldr r1, =(0x2024284)
	add r0, r0, r1
	mov r7, r0
	mov r1, #0xB 
	ldr r3, =(0x803FBE8 +1) @get current species, prior to evolving
	bl linker
	mov r5, r0
	bl getEvolvedForm @check what species it evolves into
	mov r6, r0
	mov r0, r7
	mov r1, #0x38
	ldr r3, =(0x803FBE8 +1) @save level before evolution
	bl linker
	mov r4, r0

SetEvolve:
	mov r0, r7 @evolve it
	ldr r2, .VAR
	mov r1, r6
	strh r1, [r2]
	mov r1, #0xB
	ldr r3, =(0x804037C +1)
	bl linker
	mov r0, r7
	ldr r3, =(0x803E47C +1) @recalculate stats
	bl linker

AddToDex:
	mov r0, r6
	ldr r3, =(0x8043298 +1) @get dex index of species
	bl linker
	mov r0, r6
	mov r1, #0x2
	ldr r3, =(0x8088E74 +1) @normal dex
	bl linker
	mov r0, r6
	mov r1, #0x3
	ldr r3, =(0x8088E74 +1) @national
	bl linker

FinishCalc:
	mov r0, r7 @check current level (after evolving)
	mov r1, #0x38
	ldr r3, =(0x803FBE8 +1)
	bl linker
	cmp r0, r4 @exp curves skewed level
	bne AdjustLvl
	b Nickname

getEvolvedForm:
	ldr r0, =(0x20370BC)
	ldrh r0, [r0]
	bx lr

Nickname:
	mov r0, r7
	ldr r1, =(0x2021CD0) @store current nickname here
	mov r2, r1
	mov r1, #0x2
	ldr r3, =(0x803FBE8 +1)
	bl linker
	ldr r0, =(0x8245EE0)@calculate species default name
	mov r1, #0xB
	mul r1, r1, r5
	add r1, r1, r0
	mov r5, r1
	ldr r1, =(0x2021CD0)
	mov r4, r1
	mov r0, #0x0
	
checkEqual:
	cmp r0, #0xA            @While nickname has char
	beq setName
	add r5, r5, #0x1        @get next char of species name
	ldrb r1, [r5]
	add r4, r4, #0x1        @get next char of nickname
	ldrb r2, [r4]
	cmp r2, r1                @if x != y ==> has nickname
	bne end
	cmp r2, #0xFF          @strings are 0xFF terminated
	beq checkOne
	b contLoop

checkOne:
	cmp r1, #0xFF
	beq setName
	b end

contLoop:
	add r0, r0, #0x1 @loop counter ++
	b checkEqual

setName:
	ldr r2, =(0x8245EE0) @set nickname as species name
	mov r0, #0xB
	mul r6, r6, r0
	add r6, r6, r2
	mov r0, r7
	mov r2, r6
	mov r1, #0x2
	ldr r3, =(0x804037C +1)
	bl linker
	b end
	
	
AdjustLvl:
	cmp r0, r4
	beq Nickname
	mov r2, r0
	mov r0, r7
	mov r1, #0x19
	ldr r3, =(0x803FBE8 +1) @x = currentExp * 1.1
	bl linker
	mov r1, r0
	lsr r0, #0x4
	cmp r2, r4           @if current lvl < old lvl; currentExp -= x
	bls subtract
	add r1, r1, r0 
	b updateExp
	
subtract:
	sub r1, r1, r0       @else currentExp += x

updateExp:
	ldr r2, .VAR
	str r1, [r2]
	mov r1, #0x19
	mov r0, r7
	ldr r3, =(0x804037C +1)
	bl linker
	mov r0, r7
	ldr r3, =(0x803E47C +1)
	bl linker
	mov r0, r7
	mov r1, #0x38
	ldr r3, =(0x803FBE8 +1)
	bl linker
	b AdjustLvl


end:
	pop {r0-r7, pc}
	
 
linker:
	bx r3
	

.align 2

.VAR:
	.word 0x20270B8 + (0x8000 *2) @change to any 2 byte free space in RAM
.SLOT:
	.word 0x20270B8 + (0x8001 *2) @slot of Pokemon to evolve


That one uses the variable 0x8002 to determine it's evolution. You can use it to evolve into a specific evolution that way. Or be silly and evolve Rattata into a Venasaur :3


Mini update:

Remember how the TMs were showing quantities? Well I fixed that now. I'll edit my original post with the details as well. Here it is:

Compile and insert into free space:
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	cmp r5, #0x0
	bne end
	ldr r3, =(0x8131EFE +1)
	bx r3

end:
	mov r0, r7
	mov r1, #0x8
	mov r2, r4
	ldr r6, =(0x81335B0 +1)
	bl link
	ldr r3, =(0x8131EFE +1)
	bx r3

link:
	bx r6

.align 2


Now navigate to 0x131EF4 and insert:
Code:
00 48 00 47 XX XX XX 08
Where XX XX XX is the pointer to where you assembled the routine +1

Now navigate to 0x131EA5 and change the byte to E0
That's all.
So I'm having an issue using both codes when using them. The first code only works on pokemon that are not part of my expanded dex, as well as it doesn't work on custom evolutions for some reason. For example, I use it on deoxys to try to evolve it to some random pokemon and it just freezes the game upon execution.

The second code works for my expanded mons, but for some reason, when I use it on expanded pokemon it changes the pokemon's name. For example I evolved clefairy into Ribombee and its name turned into SHADOW PU lol what is going on here?
__________________
POKEMON PULSAR VERSION PHASE 02 THREAD: https://www.pokecommunity.com/showthread.php?t=421565
(Phase 03 in development)


POKEMON PULSAR VERSION PHASE 02 TRAILER:https://www.youtube.com/watch?v=zPY7_ZvoO7E
(Formerly known as Pokemon Jashin Version)


-Praise Be To Jashin
Reply With Quote
  #1461   Link to this post, but load the entire thread.  
Old July 6th, 2019 (4:00 PM).
dGxx dGxx is offline
 
Join Date: Oct 2015
Gender: Male
Posts: 46
Hi, I'm new here, don't know if this has been said already, but I've been working on my own hack for a while, I've been stuck at this one thing, i made the evolution stones like water stone, etc, cost like 20,000 pokedollars, but when i go to buy them, i see they cost ?000...when i select it, it shows it's 20,000, i just would like to increase the length of the prices to show 5 digits, i followed the advice of a person named Touched, he said to change 04 to 05 at some offset i cant remeber right now...i changed it to 05 but the game froze, changed it back to 04 and the game went back to normal. Please help me, anyone, I'm doing fire red
Reply With Quote
  #1462   Link to this post, but load the entire thread.  
Old July 7th, 2019 (6:11 PM). Edited July 7th, 2019 by RichterSnipes.
RichterSnipes's Avatar
RichterSnipes RichterSnipes is offline
Not even a nibble...
 
Join Date: Oct 2011
Location: USA
Age: 30
Gender: Male
Nature: Modest
Posts: 507
Quote:
Originally Posted by dGxx View Post
Hi, I'm new here, don't know if this has been said already, but I've been working on my own hack for a while, I've been stuck at this one thing, i made the evolution stones like water stone, etc, cost like 20,000 pokedollars, but when i go to buy them, i see they cost ?000...when i select it, it shows it's 20,000, i just would like to increase the length of the prices to show 5 digits, i followed the advice of a person named Touched, he said to change 04 to 05 at some offset i cant remeber right now...i changed it to 05 but the game froze, changed it back to 04 and the game went back to normal. Please help me, anyone, I'm doing fire red
This isn't really the place to ask these questions. This thread is about developing ASM routines to add/modify functions to the game. The Quick Research & Development Thread is what you're looking for.

Your answer seems to be there, too! Try following this post and see if it fixes your problems.
__________________
My hacks:


Reply With Quote
  #1463   Link to this post, but load the entire thread.  
Old July 7th, 2019 (10:42 PM).
dGxx dGxx is offline
 
Join Date: Oct 2015
Gender: Male
Posts: 46
Thanks Ritcher! I thought I could ask here because I thought I needed an ASM code or something, but now I see I just needed to change 3 different value not just two. Thanks I did get the result I needed. And thanks to all you guys being so great at all this ASM coding and being so helpful with your great skill of programming!
Reply With Quote
  #1464   Link to this post, but load the entire thread.  
Old July 10th, 2019 (3:35 PM).
RichterSnipes's Avatar
RichterSnipes RichterSnipes is offline
Not even a nibble...
 
Join Date: Oct 2011
Location: USA
Age: 30
Gender: Male
Nature: Modest
Posts: 507
Quote:
Originally Posted by dGxx View Post
Thanks Ritcher! I thought I could ask here because I thought I needed an ASM code or something, but now I see I just needed to change 3 different value not just two. Thanks I did get the result I needed. And thanks to all you guys being so great at all this ASM coding and being so helpful with your great skill of programming!
No problem, glad to be of help!

Anyways, I've got my own idea. I don't know how much anyone cares to implement something like this, or if it's even possible. It's a pretty crazy thing to begin with. I'll still ask nonetheless.

Would it be possible to modify the GBA games to have two dedicated save files for two different people? The games already use all the space for a second save file to store a backup save. If possible, why not make a more practical use for it?

I know that this would cause problems with functions that don't require you to load up a save first, such as New Game, Options, Mystery Gift, GameCube to Game Boy Advance linking, migrating Pokémon to the Gen IV games, and save editing. My idea would be to make it so the most recently used save is the "active" save file. This way these functions interface with the active save, the Options menu reflects the settings of the active user, and New Game will save over the active save. Or, alternatively, change the New Game saving situation to be like the later games where you have to delete a save first. Then you can change the active save by loading up the "secondary" save file, which would now push the other save into secondary status.

I've always loved the idea of having multiple save files on one Pokémon cartridge. I know that it'll never be a feature in the official games, early on because of technical reasons (the first couple of generations couldn't handle it) and later on strictly for monetary reasons (buy more copies of the games!). But it'd still be a watershed moment in my eyes for it to become a reality.
__________________
My hacks:


Reply With Quote
  #1465   Link to this post, but load the entire thread.  
Old July 12th, 2019 (8:02 PM).
dGxx dGxx is offline
 
Join Date: Oct 2015
Gender: Male
Posts: 46
Quote:
Originally Posted by RichterSnipes View Post
No problem, glad to be of help!

Anyways, I've got my own idea. I don't know how much anyone cares to implement something like this, or if it's even possible. It's a pretty crazy thing to begin with. I'll still ask nonetheless.

Would it be possible to modify the GBA games to have two dedicated save files for two different people? The games already use all the space for a second save file to store a backup save. If possible, why not make a more practical use for it?

I know that this would cause problems with functions that don't require you to load up a save first, such as New Game, Options, Mystery Gift, GameCube to Game Boy Advance linking, migrating Pokémon to the Gen IV games, and save editing. My idea would be to make it so the most recently used save is the "active" save file. This way these functions interface with the active save, the Options menu reflects the settings of the active user, and New Game will save over the active save. Or, alternatively, change the New Game saving situation to be like the later games where you have to delete a save first. Then you can change the active save by loading up the "secondary" save file, which would now push the other save into secondary status.

I've always loved the idea of having multiple save files on one Pokémon cartridge. I know that it'll never be a feature in the official games, early on because of technical reasons (the first couple of generations couldn't handle it) and later on strictly for monetary reasons (buy more copies of the games!). But it'd still be a watershed moment in my eyes for it to become a reality.
yes richter, I agree with you and your idea as well. My daughter is always playing my savefiles, luckily for the switch has different profiles so she plays her own pokemon go pikachu file while she doesnt mess with mine. It's a great feature!
Reply With Quote
  #1466   Link to this post, but load the entire thread.  
Old July 17th, 2019 (5:11 PM).
Sudonim's Avatar
Sudonim Sudonim is offline
Doing things that are completely unnecessary since conception.
 
Join Date: Jul 2019
Location: Petalburg City
Age: 20
Gender: Male
Posts: 20
I'm going to go ahead and feel free to request something. So a while back i wanted to edit emerald to force only super effective moves to deal damage, and i figured the best way to do this was to edit the type chart. After doing that and playing the game, i quickly realized that editing the type chart also applies to status moves (e.g. Toxic, Growl, etc.) which is undesirable. I could have also edited the abilities for every Pokémon to have Wonder guard instead, but i feel like that's taking a lazy approach, and in that situation Slaking not having truant would make it even more over powered. So now that i have free time again i decided to come back to this project, and see if i can finally make this come to fruition. I would do this myself, but i don't understand ASM at all, and through my searching i haven't come up with any info about how i would even go about adding this rule in (I'm guessing it needs to be added to the damage calculation?).

TL;DR Wonder Guard at all times while keeping abilities and status moves in tact.
__________________
Feel free to correct my grammar and spelling.
Quote:
Originally Posted by Luigi
Quote:
Originally Posted by Mario
Nice of the princess to invite us over for a picnic, eh Luigi?
I hope she made lots-a SPAGHETTI!
Reply With Quote
  #1467   Link to this post, but load the entire thread.  
Old August 25th, 2019 (10:14 PM).
seoluis's Avatar
seoluis seoluis is offline
 
Join Date: Aug 2016
Gender: Male
Posts: 17
i have same issues in pokemon stadium i cant add new types due to next addresses being for moves animations , accuracy and evasion i dont know how to reallocate the chart
Reply With Quote
  #1468   Link to this post, but load the entire thread.  
Old August 26th, 2019 (3:33 AM). Edited August 26th, 2019 by Xcisor.
Xcisor's Avatar
Xcisor Xcisor is offline
 
Join Date: Jun 2006
Gender:
Nature: Adamant
Posts: 46
Can someone please help me with the Sitrus Berry Updates for Pokemon Emerald? I'm a bit new to ASM and not sure if I should run an overworld script with callasm command in game somewhere to change the effect the Sitrus Berry has or if I insert the pointer somewhere else in the Rom to get the desired effect out of the ASM in the First Post.

Diluting the process down to Hex and Free Space finding would be appreciated too!

Right now I've got an ASM folder with the thumb compiler. What all would I then need to copy/paste save and convert to HEX? With such a HEX code I'd insert it into freespace ending in 0 and then where do I go from here?
Reply With Quote
  #1469   Link to this post, but load the entire thread.  
Old August 26th, 2019 (12:09 PM).
Zeturic's Avatar
Zeturic Zeturic is offline
 
Join Date: Mar 2007
Posts: 787
After spending way too much time tinkering with the build system and README, I can finally present:

Move Item [FR]

Black and White 2 introduced a feature where you can move items directly between two Pokémon in your party from within the party menu, rather than having to use the bag as middle man. This ports that feature to FR ROMs.

Reply With Quote
  #1470   Link to this post, but load the entire thread.  
Old September 18th, 2019 (12:04 PM). Edited September 18th, 2019 by K1llerCruz.
K1llerCruz K1llerCruz is offline
 
Join Date: Aug 2018
Posts: 5
I would like to ask if anyone can do a routine wich maximizes the IV's/EV's stats of my team's first pokemon
Reply With Quote
  #1471   Link to this post, but load the entire thread.  
Old September 25th, 2019 (3:48 AM). Edited September 25th, 2019 by U.Flame.
U.Flame's Avatar
U.Flame U.Flame is offline
Maker of Short Games
 
Join Date: Jun 2008
Location: Unknown
Age: 27
Gender: Male
Nature: Jolly
Posts: 1,322
Having some issues with Spherical Ice's Dive ASM here in this thread: https://www.pokecommunity.com/showthread.php?t=257723

This is the ASM as I inserted it:
Spoiler:
.thumb
.global firered_dive

@ FireRed v1.0 HM08 DIVE Port
@ Credits: Spherical Ice, Squeetz

@ CHANGE THESE:
.equ offset, 0xB7DCB0 @ ROM address of 0x400 bytes of free space
.equ OW_MALE_DIVE, 148 @ male player's diving overworld sprite number
.equ OW_FEMALE_DIVE, 149 @ female player's diving overworld sprite number
.equ FLAG_ALLOW_DIVE, 0x827 @ flag which allows the use of Dive
@ YOU MUST CHANGE THE ABOVE VALUES

@ INSTALL:
@ 1. Change the .equ values above, labelled CHANGE THESE
@ 2. If you wish to disable badge checking, follow the DISABLE BADGE CHECKING instructions below
@ 3. Save this file
@ 4. Assemble this file using the following command:
@ thumb firered_dive.s firered_dive.gba
@ 5. Create a .IPS patch using Lunar IPS:
@ Use the included base.gba file as the base ROM
@ Use the newly generated firered_dive.gba file as the modified ROM
@ 6. Patch your FireRed v1.0 ROM with the generated .IPS patch
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@ DISABLE BADGE CHECKS:
@ Find and remove the appropriately labelled lines of code below
@ Ctrl + F: REMOVE THE FOLLOWING 5 LINES TO DISABLE BADGE CHECK
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@ MAKE DIVE POSSIBLE IN MAPS:
@ Set the second behaviour byte of Dive-able tiles to the value of DIVE_TILE_BYTE below (0x23 by default)
@ Set their second behaviour byte of Emerge-able tiles to the value of EMERGE_TILE_BYTE below (0x24 by default)
@ Set underwater maps' light level (the Type: field in the Header view on AdvanceMap) to Underwater (0x5)
@ Create Emerge map connections to underwater maps leading to their surface maps
@ Create Dive map connections to surface maps leading to their underwater maps
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@ Changing these is optional (they are the default FireRed currently)
.equ OW_MALE_WALK, 0 @ male player's normal, walking overworld sprite number
.equ OW_MALE_CYCLE, 1 @ male player's cycling overworld sprite number
.equ OW_MALE_SURF, 2 @ male player's surfing/"sat down" overworld sprite number
.equ OW_MALE_ITEM_0, 3 @ male player's first item usage overworld sprite number
.equ OW_MALE_FISH, 4 @ male player's fishing overworld sprite number
.equ OW_MALE_ITEM_1, 5 @ male player's second item usage overworld sprite number
.equ OW_FEMALE_WALK, 7 @ female player's normal, walking overworld sprite number
.equ OW_FEMALE_CYCLE, 8 @ female player's cycling overworld sprite number
.equ OW_FEMALE_SURF, 9 @ female player's surfing/"sat down" overworld sprite number
.equ OW_FEMALE_ITEM_0, 10 @ female player's first item usage overworld sprite number
.equ OW_FEMALE_FISH, 11 @ female player's fishing overworld sprite number
.equ OW_FEMALE_ITEM_1, 12 @ female player's second item usage overworld sprite number
.equ DIVE_TILE_BYTE, 0x23 @ second behaviour byte value for diving
.equ EMERGE_TILE_BYTE, 0x24 @ second behaviour byte value for emerging
.equ FLAG_ALLOW_RUN, 0x82F @ flag which allows the use of the Running Shoes
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@ DO NOT CHANGE THESE VALUES:
.equ rom, 0x08000000
@ DO NOT CHANGE THE ABOVE VALUES

@ Hooks and branches
.org 0x5BA30, 0xFF
ldr r0, =(disable_running_underwater + rom + 1)
bx r0
.pool

.org 0x5C7F4, 0xFF
.word player_overworld_list + rom

.org 0x5C826, 0xFF
ldr r1, =(get_gender_from_sprite + rom + 1)
bx r1
.pool

.org 0x5C9B0, 0xFF
.word walkrun_overworld_list + rom

.org 0x5C9BA, 0xFF
cmp r2, #3

.org 0x5C9F4, 0xFF
.word walkrun_overworld_list + rom

.org 0x6CB30, 0xFF
ldr r0, =(check_for_events + rom + 1)
bx r0
.pool

.org 0x6CCCC, 0xFF
ldr r1, =(check_dive + rom + 1)
bx r1
.pool

.org 0x6DF78, 0xFF
b 0x6DF84

.org 0x35B854, 0xFF
.word change_sprite_to_diving + rom + 1

.org 0x471EEC, 0xFF
.word player_behaviour_dive + rom + 1

.org offset, 0xFF
@ New data
player_overworld_list:
.byte OW_MALE_WALK, OW_FEMALE_WALK
.byte OW_MALE_CYCLE, OW_FEMALE_CYCLE
.byte OW_MALE_SURF, OW_FEMALE_SURF
.byte OW_MALE_ITEM_0, OW_FEMALE_ITEM_0
.byte OW_MALE_FISH, OW_FEMALE_FISH
.byte OW_MALE_ITEM_1, OW_FEMALE_ITEM_1
.byte OW_MALE_DIVE, OW_FEMALE_DIVE

walkrun_overworld_list:
.byte OW_MALE_WALK, 0b00001
.byte OW_MALE_CYCLE, 0b00010
.byte OW_MALE_SURF, 0b01000
.byte OW_MALE_DIVE, 0b10000
.byte OW_FEMALE_WALK, 0b00001
.byte OW_FEMALE_CYCLE, 0b00010
.byte OW_FEMALE_SURF, 0b01000
.byte OW_FEMALE_DIVE, 0b10000

@ New code
disable_running_underwater:
ldr r6, =(0x02037078) @ walkrun_state
ldrb r1, [r6, #0] @ walkrun->bitfield
mov r0, #16
and r0, r1
cmp r0, #0
bne i_forgot_what_this_label_is
mov r0, #2
and r5, r0
cmp r5, #0
beq cannot_run
ldr r0, =(FLAG_ALLOW_RUN)
ldr r3, =(0x0806E6D0+1) @ flag_check
bl call_via_r3
lsl r0, r0, #24
lsr r0, r0, #24
cmp r0, #0
beq cannot_run
ldr r2, =(0x02036E38) @ npc_states
ldrb r1, [r6, #5]
lsl r0, r1, #3
add r0, r0, r1
lsl r0, r0, #2
add r0, r0, r2
ldrb r0, [r0, #30]
ldr r3, =(0x080BD488+1) @ is_tile_to_run_on
bl call_via_r3
cmp r0, #0
bne cannot_run

can_run:
ldr r0, =(0x0805BA5A+1)
bx r0

i_forgot_what_this_label_is:
ldr r0, =(0x0805BA9E+1)
bx r0

cannot_run:
ldr r0, =(0x0805BA8C+1)
bx r0

.pool

get_gender_from_sprite:
lsl r0, r0, #24
lsr r0, r0, #24
cmp r0, #OW_MALE_DIVE
beq male
cmp r0, #OW_FEMALE_DIVE
beq female
cmp r0, #OW_FEMALE_FISH
bgt male
cmp r0, #OW_FEMALE_WALK
blt male

female:
mov r0, #1
b return_to_x5C838

male:
mov r0, #0

return_to_x5C838:
ldr r1, =(0x0805C838 + 1)
bx r1
.pool

check_for_events:
mov r0, #0x80
and r0, r1
cmp r0, #0
beq check_aftermove
bl consider_dive_emerging
cmp r0, #1
beq something_happened

check_aftermove:
ldrb r1, [r5]
mov r0, #0x40
and r0, r1
cmp r0, #0
beq check_move
ldr r0, =(0x0806CB38 + 1)
bx r0

something_happened:
ldr r0, =(0x0806CB6C + 1)
bx r0

check_move:
ldr r0, =(0x0806CB74 + 1)
bx r0
.pool

consider_dive_emerging:
push {lr}
@ REMOVE THE FOLLOWING 5 LINES TO DISABLE BADGE CHECK
ldr r0, =(FLAG_ALLOW_DIVE)
ldr r1, =(0x0806E6D0 + 1) @ checkflag
bl call_via_r1
cmp r0, #0
beq no_emerging
@ REMOVE THE ABOVE 5 LINES TO DISABLE BADGE CHECK
ldr r0, =(0x02036DFC) @ map_header
ldrb r0, [r0, #23] @ map_header->light_level
cmp r0, #5
bne no_emerging
bl get_block_secondary_role
cmp r0, #EMERGE_TILE_BYTE
bne no_emerging
ldr r0, =(0x081BE3D4) @ emerge_script
ldr r1, =(0x08069AE4 + 1) @ script_start
bl call_via_r1
mov r0, #1
b dive_return

no_emerging:
mov r0, #0

dive_return:
pop {r1}
bx r1
.pool

check_dive:
ldrb r1, [r5]
mov r0, #1
and r0, r1
cmp r0, #0
beq no_dive
bl consider_diving
cmp r0, #1
beq something_happened

no_dive:
ldrb r1, [r5]
mov r0, #4
and r0, r1
cmp r0, #0
beq something
ldr r2, =(0x0806CCD6 + 1)
bx r2

something:
ldr r0, =(0x0806CCFC + 1)
bx r0
.pool

consider_diving:
push {lr}
@ REMOVE THE FOLLOWING 5 LINES TO DISABLE BADGE CHECK
ldr r0, =(FLAG_ALLOW_DIVE)
ldr r1, =(0x0806E6D0 + 1) @ checkflag
bl call_via_r1
cmp r0, #0
beq cant_dive
@ REMOVE THE ABOVE 5 LINES TO DISABLE BADGE CHECK
bl get_block_secondary_role
cmp r0, #DIVE_TILE_BYTE
bne cant_dive
ldr r0, =(0x081BE38B) @ dive_script
ldr r1, =(0x08069AE4 + 1) @ script_start
bl call_via_r1
mov r0, #1
b dive_pop

cant_dive:
mov r0, #0

dive_pop:
pop {r1}
bx r1
.pool

get_block_secondary_role:
push {r4, lr}
sub sp, sp, #4
mov r4, sp
add r4, #2
mov r0, sp
mov r1, r4
ldr r3, =(0x0805C538 + 1) @ player_get_pos_to
bl call_via_r3
mov r0, sp
mov r1, #0
ldsh r0, [r0, r1]
mov r2, #0
ldsh r1, [r4, r2]
lsl r0, r0, #16
asr r0, r0, #16
lsl r1, r1, #16
asr r1, r1, #16
mov r2, #8
ldr r3, =(0x08058F48 + 1) @ cur_mapdata_block_get_field_at
bl call_via_r3
lsl r0, r0, #16
lsr r0, r0, #24
add sp, sp, #4
pop {r4}
pop {r1}
bx r1
.pool

player_behaviour_dive:
push {r4, lr}
ldr r0, =(0x02037078) @ walkrun_state
ldrb r0, [r0, #5] @ walkrun_state->npcid
lsl r4, r0, #3
add r4, r4, r0
lsl r4, r4, #2
ldr r0, =(0x02036E38) @ npc_states
add r4, r4, r0
mov r0, #6
ldr r3, =(0x0805C808 + 1) @ get_sprite_for_player
bl call_via_r3
add r1, r0, #0
lsl r1, r1, #24
lsr r1, r1, #24
add r0, r4, #0
ldr r3, =(0x081507BC + 1) @ npc_change_sprite_call
bl call_via_r3
ldrb r1, [r4, #24]
lsr r1, r1, #4
add r0, r4, #0
ldr r3, =(0x0805F218 + 1) @ npc_turn
bl call_via_r3
mov r0, #16
ldr r3, =(0x0805C970 + 1) @ change_sprite_bitfield
bl call_via_r3
ldrb r0, [r4, #4]
ldr r3, =(0x080DC6B0 + 1) @ bobbing
bl call_via_r3
strb r0,[r4, #26]
pop {r4}
pop {r0}
bx r0
.pool

change_sprite_to_diving:
push {lr}
mov r0, #4

set:
ldr r1, =(0x08150498 + 1) @ set_player_behaviour
bl call_via_r1
pop {r1}

call_via_r1:
bx r1

call_via_r3:
bx r3
.pool

.org 0xFFFFFF, 0xFF
.byte 0xFF


I had asked about this in Rom Hacking Help with no luck, since this is an ASM specific thread maybe this is a better place to ask. Basically, it functions but has problems with female players. Firstly, the Dive sprite uses the Dive overworld sprites but with the palette of the normal walking overworld sprites. It does this for both genders, but upon entering and exiting a menu or battle, the palette is corrected to the dive sprite palette. This in itself can be a non-issue if both sprites share palettes. For male players, this is the only issue.

The main problem is with female players upon entering a menu/battle, the dive sprite is reverted to the normal walking sprite. This includes behavior as well, no longer bobbing and is now able to run. There's an additional oddity if the dive and walk sprites are different sizes. The reverted sprite appears glitched, but upon another menu/battle, fully reverts to a normal looking walk state.

So what's causing female players to undo the dive state like that, and not males? One other thing I noticed is that the underwater fog still appears but the bubbles only appear after entering and exiting a menu. I tried implementing this in both my ongoing project and in vanilla Firered, no change in results. Then I checked diving in Pokemon Gaia, and found that the sprites function perfectly well for both genders, no palette issue, no reversion issue. But that the bubbles not appearing until after a menu thing is there. My main concern is just the female players breaking. The palette and bubbles issue isn't important, I can live with that, but I can't have players walking underwater.
__________________
The more you learn about something, the more you realize just how much you don't know. I've shelved my more ambitious ideas in favor of smaller, more feasible projects and contributions. While I still have an ongoing project, and still intend to experiment with improving Gen 3's multiplayer, it's been much less stressful doing smaller things, like entries for Anthroyd's MAGM contests.

Of which you can check out here:
Naillevaihcam
Magical Altering Gym Menagerie
Reply With Quote
  #1472   Link to this post, but load the entire thread.  
Old October 16th, 2019 (10:50 AM).
jvhbv jvhbv is offline
 
Join Date: Sep 2019
Posts: 3
Quote:
Originally Posted by FBI View Post

Getting IVs and EVs



The routines are very similar so I ended up just combining the two routines into one. Basically given a slot number of a Pokemon in 0x8004, the routines will return the EVs or IVs, respectively, into the vars 0x8005-0x800A with 0x8003 as the IV/EV switch.


How to insert:

Compile and insert the following routine into free space:

Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r5, lr}
	mov r4, #0x0
	
loop:
	cmp r4, #0x6
	bhi end
	ldr r0, =(0x20370C0) @var 0x8004 = slot number
	ldrh r0, [r0]
	mov r1, #0x64
	mul r1, r1, r0
	ldr r0, =(0x2024284)
	add r0, r0, r1
	ldr r3, =(0x20370BE)
	ldrh r3, [r3]
	cmp r3, #0x0
	beq EVs
	add r1, r1, #0x27 @IV
	b continue
	
EVs:
	add r1, r1, #0x1A
	
continue:
	ldr r2, =(0x803FBE8 +1)
	bl linker
	mov r1, r0
	@get var
	ldr r2, =(0x20370C2) @using vars 0x8005-0x800A
	lsl r0, r4, #0x1
	add r2, r2, r0
	strh r1, [r2] @store IV in var
	add r4, r4, #0x1
	b loop

linker:
	bx r2
	
end:
	pop {r0-r5, pc}

.align 2



Usage:
setvar 0x8003 0x[anything except 0 = IV, 0 = EV]
setvar 0x8004 0x[slot number 0 to 5]
callasm 0x[this routine +1]

The variables will be:
0x8005: HP IV/EV
0x8006: Atk IV/EV
0x8007: Def IV/EV
0x8008: Spd IV/EV
0x8009: S.atk IV/EV
0x800A: S.def IV/EV
So for about the last 10 hours I've been trying to figure something out with this code.
It works completely fine, other than the fact that when I run it, it sets all 6 variables to the IV of the pokemon I specified in the scripts HP IV

Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r5, lr} @loads registers r0-r5
	mov r4, #0x0 @copies 0(aka 0x0) to register r4
	
loop:
	cmp r4, #0x6 @finds the difference between the value in register r4 and the number 6(aka 0x6)
	bhi end @I believe this is roughly equivalent to if(r4==6) goto end
	ldr r0, =(0x20370C0) @var 0x8004 = slot number
	ldrh r0, [r0] @loads register r0 at the offset stored in r0 (set right before this to 0x20370C0) ONLY A HALFWORD IS LOADED
	mov r1, #0x64 @copies 100(aka 0x64) to register r1
	mul r1, r1, r0 @multiplies r0(the value at 0x20370C0/var 0x8004) by r1(100 aka 0x64) and stores the result in r1
	ldr r0, =(0x2024284) @loads register r0 at offset 0x2024284, upon inspection of this memory location, it is where the pokemon in your party are stored
	add r0, r0, r1 @adds the value in r1 to the offset r0 is loaded at, getting the party member location
	ldr r3, =(0x20370BE) @loads register r3 at 0x20370BE, the location of var 0x8003
	ldrh r3, [r3] @reads the halfword at 0x20370BE and writes it to r3, aka sets r3 equal to var 8003
	cmp r3, #0x0 @checks if r3(at this point effectively var 0x8003) is 0
	beq EVs @goes to evs if var 0x8003 is 0
	add r1, r1, #0x27 @IV r1 at this point is equal to the offset at whatever pokemon party number you want, adding 0x27 sets the offset to the ivs section of the pokemon's data
	b continue @goes to continue
	
EVs:
	add r1, r1, #0x1A
	
continue:
	ldr r2, =(0x803FBE8 +1) @I think this sets register r2 equal to the offset 0x803FBE9
	bl linker @branches to linker and stores the current offset in the link register(r14)
	mov r1, r0 @copies r0 to r1
	@get var
	ldr r2, =(0x20370C2) @using vars 0x8005-0x800A
	lsl r0, r4, #0x1 @I think shifts r0 to the left(subtracts 1 from r0)
	add r2, r2, r0
	strh r1, [r2] @store IV in var
	add r4, r4, #0x1 @adds 1 to the value of r4, allowing the assembly to terminate once it runs 6 times
	b loop @goes to loop

linker:
	bx r2 @branches to the offset stored in r2
	
end:
	pop {r0-r5, pc}

.align 2


I've taken the code and put in comments on each line summarizing what I understand each line to do. Am I mistaken? Am I completely wrong?

Spoiler:

Code:
//---------------
#org 0x2514D0
lock
faceplayer
msgbox 0x82515D0 MSG_YESNO //"Would you like to know the\npotent..."
compare LASTRESULT 0x0
if 0x1 goto 0x8251570
setvar 0x8003 0x1
setvar 0x8004 0x0
callasm 0x8251C51
buffernumber 0x0 0x8005
buffernumber 0x1 0x8006
msgbox 0x8251610 MSG_NORMAL //"HP: [buffer1] IVs\nAttack: [buffer..."
buffernumber 0x0 0x8007
buffernumber 0x1 0x8008
msgbox 0x8251630 MSG_NORMAL //"Defence: [buffer1] IVs\nSpeed: [bu..."
buffernumber 0x0 0x8009
buffernumber 0x1 0x800A
msgbox 0x8251650 MSG_NORMAL //"Special Attack: [buffer1] IVs\nSpe..."
end

//---------------
#org 0x251570

//---------
// Strings
//---------
#org 0x2515D0
= Would you like to know the\npotential of your Pokémon?

#org 0x251610
= HP: [buffer1] IVs\nAttack: [buffer2] IVs 

#org 0x251630
= Defence: [buffer1] IVs\nSpeed: [buffer2] IVs

#org 0x251650
= Special Attack: [buffer1] IVs\nSpecial Defence: [buffer2] IVs.


with the compiled thing ending up as

Code:
0x08251C50        3F B5 00 24 05 2C 17 D8 0C 48 00 88 64 21 41 43
0x08251C60        0B 48 40 18 0B 4B 1B 88 00 2B 01 D0 27 31 00 E0
0x08251C70        1A 31 09 4A 00 F0 07 F8 01 1C 08 4A 60 00 12 18
0x08251C80        11 80 01 34 E6 E7 10 47 3F BD C0 46 C0 70 03 02 
0x08251C90        86 42 02 02 BE 70 03 02 E9 FB 03 08 C4 70 03 02
Everything I have there follows the implementation instructions to a T, yet the memory still shows

Code:
0x020370BD        00 01 00 00 00 19 00 19 00 19 00 19 00 19 00 19
0x020370CD        00 19 00 01 00 02 00 04 00 00 00 00 00 FF 00 01
and just to make sure it wasn't a statistical fluke, I ran the same script with 5 or so more randomly encountered pokemon and ran them through an IV calculator. Each time, the HP IV shown by the ASM was correct, but then copied it to every other variable set in the script.
Reply With Quote
  #1473   Link to this post, but load the entire thread.  
Old October 16th, 2019 (11:00 AM).
jvhbv jvhbv is offline
 
Join Date: Sep 2019
Posts: 3
Quote:
Originally Posted by FBI View Post

Getting IVs and EVs



The routines are very similar so I ended up just combining the two routines into one. Basically given a slot number of a Pokemon in 0x8004, the routines will return the EVs or IVs, respectively, into the vars 0x8005-0x800A with 0x8003 as the IV/EV switch.


How to insert:

Compile and insert the following routine into free space:

Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r5, lr}
	mov r4, #0x0
	
loop:
	cmp r4, #0x6
	bhi end
	ldr r0, =(0x20370C0) @var 0x8004 = slot number
	ldrh r0, [r0]
	mov r1, #0x64
	mul r1, r1, r0
	ldr r0, =(0x2024284)
	add r0, r0, r1
	ldr r3, =(0x20370BE)
	ldrh r3, [r3]
	cmp r3, #0x0
	beq EVs
	add r1, r1, #0x27 @IV
	b continue
	
EVs:
	add r1, r1, #0x1A
	
continue:
	ldr r2, =(0x803FBE8 +1)
	bl linker
	mov r1, r0
	@get var
	ldr r2, =(0x20370C2) @using vars 0x8005-0x800A
	lsl r0, r4, #0x1
	add r2, r2, r0
	strh r1, [r2] @store IV in var
	add r4, r4, #0x1
	b loop

linker:
	bx r2
	
end:
	pop {r0-r5, pc}

.align 2



Usage:
setvar 0x8003 0x[anything except 0 = IV, 0 = EV]
setvar 0x8004 0x[slot number 0 to 5]
callasm 0x[this routine +1]

The variables will be:
0x8005: HP IV/EV
0x8006: Atk IV/EV
0x8007: Def IV/EV
0x8008: Spd IV/EV
0x8009: S.atk IV/EV
0x800A: S.def IV/EV
So for about the last 10 hours I've been trying to figure something out with this code.
It works completely fine, other than the fact that when I run it, it sets all 6 variables to the IV of the pokemon I specified in the scripts HP IV

Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r5, lr} @loads registers r0-r5
	mov r4, #0x0 @copies 0(aka 0x0) to register r4
	
loop:
	cmp r4, #0x6 @finds the difference between the value in register r4 and the number 6(aka 0x6)
	bhi end @I believe this is roughly equivalent to if(r4==6) goto end
	ldr r0, =(0x20370C0) @var 0x8004 = slot number
	ldrh r0, [r0] @loads register r0 at the offset stored in r0 (set right before this to 0x20370C0) ONLY A HALFWORD IS LOADED
	mov r1, #0x64 @copies 100(aka 0x64) to register r1
	mul r1, r1, r0 @multiplies r0(the value at 0x20370C0/var 0x8004) by r1(100 aka 0x64) and stores the result in r1
	ldr r0, =(0x2024284) @loads register r0 at offset 0x2024284, upon inspection of this memory location, it is where the pokemon in your party are stored
	add r0, r0, r1 @adds the value in r1 to the offset r0 is loaded at, getting the party member location
	ldr r3, =(0x20370BE) @loads register r3 at 0x20370BE, the location of var 0x8003
	ldrh r3, [r3] @reads the halfword at 0x20370BE and writes it to r3, aka sets r3 equal to var 8003
	cmp r3, #0x0 @checks if r3(at this point effectively var 0x8003) is 0
	beq EVs @goes to evs if var 0x8003 is 0
	add r1, r1, #0x27 @IV r1 at this point is equal to the offset at whatever pokemon party number you want, adding 0x27 sets the offset to the ivs section of the pokemon's data
	b continue @goes to continue
	
EVs:
	add r1, r1, #0x1A
	
continue:
	ldr r2, =(0x803FBE8 +1) @I think this sets register r2 equal to the offset 0x803FBE9
	bl linker @branches to linker and stores the current offset in the link register(r14)
	mov r1, r0 @copies r0 to r1
	@get var
	ldr r2, =(0x20370C2) @using vars 0x8005-0x800A
	lsl r0, r4, #0x1 @I think shifts r0 to the left(subtracts 1 from r0)
	add r2, r2, r0
	strh r1, [r2] @store IV in var
	add r4, r4, #0x1 @adds 1 to the value of r4, allowing the assembly to terminate once it runs 6 times
	b loop @goes to loop

linker:
	bx r2 @branches to the offset stored in r2
	
end:
	pop {r0-r5, pc}

.align 2


with the compiled thing ending up as

Code:
0x08251C50        3F B5 00 24 05 2C 17 D8 0C 48 00 88 64 21 41 43
0x08251C60        0B 48 40 18 0B 4B 1B 88 00 2B 01 D0 27 31 00 E0
0x08251C70        1A 31 09 4A 00 F0 07 F8 01 1C 08 4A 60 00 12 18
0x08251C80        11 80 01 34 E6 E7 10 47 3F BD C0 46 C0 70 03 02 
0x08251C90        86 42 02 02 BE 70 03 02 E9 FB 03 08 C4 70 03 02
I've taken the code and put in comments on each line summarizing what I understand each line to do. Am I mistaken? Am I completely wrong?

Spoiler:

Code:
//---------------
#org 0x2514D0
lock
faceplayer
msgbox 0x82515D0 MSG_YESNO //"Would you like to know the\npotent..."
compare LASTRESULT 0x0
if 0x1 goto 0x8251570
setvar 0x8003 0x1
setvar 0x8004 0x0
callasm 0x8251C51
buffernumber 0x0 0x8005
buffernumber 0x1 0x8006
msgbox 0x8251610 MSG_NORMAL //"HP: [buffer1] IVs\nAttack: [buffer..."
buffernumber 0x0 0x8007
buffernumber 0x1 0x8008
msgbox 0x8251630 MSG_NORMAL //"Defence: [buffer1] IVs\nSpeed: [bu..."
buffernumber 0x0 0x8009
buffernumber 0x1 0x800A
msgbox 0x8251650 MSG_NORMAL //"Special Attack: [buffer1] IVs\nSpe..."
end

//---------------
#org 0x251570

//---------
// Strings
//---------
#org 0x2515D0
= Would you like to know the\npotential of your Pokémon?

#org 0x251610
= HP: [buffer1] IVs\nAttack: [buffer2] IVs 

#org 0x251630
= Defence: [buffer1] IVs\nSpeed: [buffer2] IVs

#org 0x251650
= Special Attack: [buffer1] IVs\nSpecial Defence: [buffer2] IVs.


Everything I have there follows the implementation instructions to a T, yet the memory still shows

Code:
0x020370BD        00 01 00 00 00 19 00 19 00 19 00 19 00 19 00 19
0x020370CD        00 19 00 01 00 02 00 04 00 00 00 00 00 FF 00 01
and just to make sure it wasn't a statistical fluke, I ran the same script with 5 or so more randomly encountered pokemon and ran them through an IV calculator. Each time, the HP IV shown by the ASM was correct, but then copied it to every other variable set in the script.
Reply With Quote
  #1474   Link to this post, but load the entire thread.  
Old October 16th, 2019 (6:12 PM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Hi, first of all I'd like to apologize for the mistake. I haven't tested that code, and it's in assembly so a semantic error here and there tend to be around for some of them. A quick skim through it, it does seem like there is a minor error.

Quote:
add r1, r1, #0x27 @IV
This line of code I assume gets the HP IV, however, it will always be 0x27, and therefore not get any subsequent IVs.
That line should be replaced by:
Quote:
add r1, r4, #0x27
If the assembler says the above line is invalid, try:
Quote:
add r1, r1, r4
add r1, r1, #0x27
Hopefully that does the trick.
__________________
...
Reply With Quote
  #1475   Link to this post, but load the entire thread.  
Old October 17th, 2019 (4:02 AM). Edited October 17th, 2019 by jvhbv.
jvhbv jvhbv is offline
 
Join Date: Sep 2019
Posts: 3
Quote:
Originally Posted by FBI View Post
Hi, first of all I'd like to apologize for the mistake. I haven't tested that code, and it's in assembly so a semantic error here and there tend to be around for some of them. A quick skim through it, it does seem like there is a minor error.

Code:
add r1, r1, #0x27 @IV
This line of code I assume gets the HP IV, however, it will always be 0x27, and therefore not get any subsequent IVs.
That line should be replaced by:

Code:
add r1, r4, #0x27
If the assembler says the above line is invalid, try:

Code:
add r1, r1, r4
add r1, r1, #0x27
Hopefully that does the trick.
Hey FBI, thanks for the reply, and I'm happy to say that
Code:
add r1, r1, r4
add r1, r1, #0x27
did the trick perfectly! It seems to be displaying the correct IVs for each stat now and isn't causing any issues. Again, thank you so much for the help.
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
Ad Content
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 8:46 AM.