3442 lines
85 KiB
NASM
3442 lines
85 KiB
NASM
//==============================================================================
|
|
c980c_custom_codes:
|
|
push {r1-r2,lr}
|
|
mov r1,r7
|
|
mov r2,r5
|
|
bl custom_codes_parse
|
|
ldr r1,[r6]
|
|
|
|
// If 0, return [r6]+2; otherwise, return [r6]+r0
|
|
cmp r0,#0
|
|
beq @@next
|
|
cmp r0,#0
|
|
bge @@continue //If -1, then set this to 0
|
|
mov r0,#0
|
|
@@continue:
|
|
add r0,r0,r1
|
|
pop {r1-r2,pc}
|
|
@@next:
|
|
add r0,r1,2
|
|
pop {r1-r2,pc}
|
|
|
|
//==============================================================================
|
|
c980c_weld_entry:
|
|
push {r0-r3,lr}
|
|
mov r0,r5
|
|
mov r1,r7
|
|
bl weld_entry
|
|
pop {r0-r3,pc}
|
|
|
|
//==============================================================================
|
|
c8ffc_custom_codes:
|
|
push {r2,r5,lr}
|
|
ldrb r0,[r2]
|
|
mov r5,r0
|
|
mov r1,r2
|
|
mov r2,r4
|
|
bl custom_codes_parse
|
|
cmp r0,0
|
|
beq @@next
|
|
mov r2,r12
|
|
add r0,r0,r2
|
|
strh r0,[r4,0x14]
|
|
pop {r2,r5}
|
|
add sp,4
|
|
ldr r1,=0x80C904D
|
|
bx r1
|
|
@@next:
|
|
mov r0,r5
|
|
cmp r0,1
|
|
pop {r2,r5,pc}
|
|
.pool
|
|
|
|
|
|
//==============================================================================
|
|
c8ffc_weld_entry:
|
|
push {r0-r1,lr}
|
|
mov r0,r4
|
|
mov r1,r2
|
|
bl weld_entry
|
|
pop {r0-r1,pc}
|
|
|
|
//==============================================================================
|
|
c980c_resetx:
|
|
push {r1,lr}
|
|
mov r1,0
|
|
strb r1,[r0,2]
|
|
pop {r1}
|
|
bl 0x80C87D0
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
c980c_resetx_newline:
|
|
push {lr}
|
|
strh r0,[r5,0x2C]
|
|
strh r4,[r5,0x2A]
|
|
strb r4,[r5,2]
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
c980c_resetx_scroll:
|
|
push {lr}
|
|
strh r0,[r5,0x2C]
|
|
strh r1,[r5,0x2A]
|
|
strb r1,[r5,2]
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
c980c_resetx_other:
|
|
push {lr}
|
|
strh r0,[r5,0x2C]
|
|
strh r2,[r5,0x2A]
|
|
strb r2,[r5,2]
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
c980c_resetx_other2:
|
|
push {lr}
|
|
mov r2,0
|
|
strh r2,[r5,0x2A]
|
|
strb r2,[r5,2]
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
c980c_resetx_other3:
|
|
push {lr}
|
|
mov r1,0
|
|
strh r1,[r5,0x2A]
|
|
strb r1,[r5,2]
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
c980c_resetx_other4:
|
|
push {lr}
|
|
strh r0,[r5,0x2C]
|
|
strh r6,[r5,0x2A]
|
|
strb r6,[r5,2]
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
c87d0_clear_entry:
|
|
push {lr}
|
|
|
|
// Reset X
|
|
mov r1,0
|
|
strb r1,[r0,2]
|
|
|
|
// Clear window
|
|
bl clear_window
|
|
|
|
// Clobbered code
|
|
ldr r4,=0x3005270
|
|
mov r1,0x24
|
|
pop {pc}
|
|
.pool
|
|
|
|
|
|
//==============================================================================
|
|
c9634_resetx:
|
|
push {lr}
|
|
mov r4,0
|
|
strb r4,[r6,2]
|
|
|
|
// Clobbered code
|
|
strh r5,[r1]
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
// Only render the (None) strings in the equip window if there's nothing equipped
|
|
c4b2c_skip_nones:
|
|
push {r7,lr}
|
|
add sp,-4
|
|
mov r7,0
|
|
|
|
// Get the (none) pointer
|
|
mov r0,r4
|
|
mov r1,r10
|
|
mov r2,0x2A
|
|
bl 0x80BE260
|
|
mov r5,r0
|
|
|
|
// Check each equip slot
|
|
ldr r6,=0x3001D40
|
|
ldr r3,=0x3005264
|
|
ldrh r0,[r3] // active party character
|
|
mov r1,0x6C
|
|
mul r0,r1
|
|
add r6,r0,r6
|
|
add r6,0x75
|
|
ldrb r0,[r6]
|
|
cmp r0,0
|
|
bne @@next
|
|
|
|
// Weapon
|
|
mov r0,r8
|
|
mov r1,r5
|
|
mov r2,0x6
|
|
mov r3,0
|
|
str r7,[sp]
|
|
bl 0x80C9634
|
|
|
|
@@next:
|
|
ldrb r0,[r6,1]
|
|
cmp r0,0
|
|
bne @@next2
|
|
|
|
// Body
|
|
mov r0,r8
|
|
mov r1,r5
|
|
mov r2,0x6
|
|
mov r3,1
|
|
str r7,[sp]
|
|
bl 0x80C9634
|
|
|
|
@@next2:
|
|
ldrb r0,[r6,2]
|
|
cmp r0,0
|
|
bne @@next3
|
|
|
|
// Arms
|
|
mov r0,r8
|
|
mov r1,r5
|
|
mov r2,0x6
|
|
mov r3,2
|
|
str r7,[sp]
|
|
bl 0x80C9634
|
|
|
|
@@next3:
|
|
ldrb r0,[r6,3]
|
|
cmp r0,0
|
|
bne @@next4
|
|
|
|
// Other
|
|
mov r0,r8
|
|
mov r1,r5
|
|
mov r2,0x6
|
|
mov r3,3
|
|
str r7,[sp]
|
|
bl 0x80C9634
|
|
|
|
@@next4:
|
|
mov r0,0
|
|
mov r10,r0
|
|
add sp,4
|
|
pop {r7,pc}
|
|
.pool
|
|
|
|
|
|
//==============================================================================
|
|
//Print numbers in the numbers window at the beginning - Used in order to make sure the one-person version prints the numbers
|
|
print_equip_base_numbers:
|
|
push {lr}
|
|
add sp,#-4
|
|
bl 0x80BC034
|
|
lsl r0,r0,#0x18
|
|
lsr r0,r0,#0x18
|
|
mov r1,r8
|
|
mov r2,#3
|
|
bl m2_formatnumber
|
|
mov r5,#0
|
|
mov r0,r10
|
|
strb r5,[r0,#0x15]
|
|
mov r0,#0xFF
|
|
mov r1,r10
|
|
strb r0,[r1,#0x16]
|
|
ldr r0,[r4,#0x14]
|
|
str r5,[sp]
|
|
mov r1,r8
|
|
mov r2,#0x37
|
|
mov r3,#3
|
|
bl printnumberequip //Prints Offense number
|
|
bl 0x80BC0CC
|
|
lsl r0,r0,#0x18
|
|
lsr r0,r0,#0x18
|
|
mov r1,r8
|
|
mov r2,#3
|
|
bl m2_formatnumber
|
|
mov r0,r10
|
|
strb r5,[r0,#0x15]
|
|
mov r0,#0xFF
|
|
mov r1,r10
|
|
strb r0,[r1,#0x16]
|
|
ldr r0,[r4,#0x14]
|
|
str r5,[sp]
|
|
mov r1,r8
|
|
mov r2,#0x37
|
|
mov r3,#0x13
|
|
bl printnumberequip //Prints Defense number
|
|
bl store_pixels_overworld
|
|
add sp,#4
|
|
pop {pc}
|
|
//==============================================================================
|
|
// Clears the equipment portion of the equip window
|
|
// r0 = window pointer
|
|
clear_equipment:
|
|
push {r0-r4,lr}
|
|
add sp,-4
|
|
mov r3,r0
|
|
ldr r0,=0x44444444
|
|
str r0,[sp]
|
|
ldrh r0,[r3,0x22]
|
|
add r0,6
|
|
ldrh r1,[r3,0x24]
|
|
ldrh r2,[r3,0x26]
|
|
sub r2,6
|
|
ldrh r3,[r3,0x28]
|
|
bl clear_rect
|
|
add sp,4
|
|
pop {r0-r4,pc}
|
|
.pool
|
|
|
|
|
|
//==============================================================================
|
|
// Clear equipment and offense/defense when moving left/right on equip screen
|
|
// r6 = window pointer
|
|
c4b2c_clear_left:
|
|
mov r0,r6
|
|
bl clear_equipment
|
|
|
|
// Clear offense/defense
|
|
push {r0-r3}
|
|
mov r0,9
|
|
mov r1,0xB
|
|
mov r2,8
|
|
bl bb21c_print_blankstr_buffer
|
|
mov r0,9
|
|
mov r1,0xD
|
|
mov r2,8
|
|
bl bb21c_print_blankstr_buffer
|
|
pop {r0-r3}
|
|
|
|
// Clobbered code
|
|
strh r1,[r3]
|
|
ldr r0,=0x80C4F3B
|
|
bx r0
|
|
|
|
c4b2c_clear_right:
|
|
mov r0,r6
|
|
bl clear_equipment
|
|
|
|
// Clear offense/defense
|
|
push {r0-r3}
|
|
mov r0,9
|
|
mov r1,0xB
|
|
mov r2,8
|
|
bl bb21c_print_blankstr_buffer
|
|
mov r0,9
|
|
mov r1,0xD
|
|
mov r2,8
|
|
bl bb21c_print_blankstr_buffer
|
|
pop {r0-r3}
|
|
|
|
// Clobbered code
|
|
strh r1,[r3]
|
|
ldr r0,=0x80C4EFF
|
|
bx r0
|
|
.pool
|
|
|
|
//==============================================================================
|
|
// Prints a string in the status window
|
|
c0a5c_printstr:
|
|
push {r0-r2,lr}
|
|
mov r0,r1
|
|
mov r1,r2
|
|
mov r2,r3
|
|
bl print_string
|
|
pop {r0-r2,pc}
|
|
|
|
//==============================================================================
|
|
// Prints an empty space instead of the "Press A for PSI info" string
|
|
c0a5c_psi_info_blank:
|
|
push {r0-r3,lr}
|
|
mov r0,5
|
|
mov r1,0xF
|
|
mov r2,0x14
|
|
bl bb21c_print_blankstr_buffer
|
|
pop {r0-r3,pc}
|
|
|
|
//==============================================================================
|
|
// Redraws the status window (when exiting the PSI submenu, etc.)
|
|
bac18_redraw_status:
|
|
push {r4,lr}
|
|
|
|
ldr r4,=0x3005230
|
|
ldr r4,[r4,0x18]
|
|
|
|
// Get the address of the status text
|
|
ldr r0,=0x8B17EE4
|
|
ldr r1,=0x8B17424
|
|
mov r2,0x11
|
|
bl 0x80BE260
|
|
|
|
// Prepare the window for parsing
|
|
mov r1,r0
|
|
mov r0,r4
|
|
mov r2,0
|
|
bl initWindow_buffer
|
|
|
|
// Render text
|
|
mov r0,r4
|
|
bl statusWindowText
|
|
|
|
// Render numbers
|
|
mov r0,r4
|
|
ldrh r1,[r0,#0]
|
|
ldr r2,=#0xFBFF
|
|
and r1,r2
|
|
strh r1,[r0,#0]
|
|
mov r1,0
|
|
bl statusNumbersPrint
|
|
|
|
pop {r4,pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
// Redraws the status window (when exiting the PSI menu) and stores it
|
|
bac18_redraw_status_store:
|
|
push {lr}
|
|
bl bac18_redraw_status
|
|
bl store_pixels_overworld
|
|
pop {pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
// Calls m2_soundeffect only if we're going in either talk or check
|
|
beaa6_fix_sounds:
|
|
push {lr}
|
|
mov r1,r10
|
|
add r1,r1,r4
|
|
mov r2,r5
|
|
add r2,#0x42
|
|
ldrb r2,[r2,#0] //Is this the status window? If not, then do the sound
|
|
cmp r2,#0
|
|
beq @@sound
|
|
cmp r1,#0
|
|
beq @@sound
|
|
cmp r1,#4
|
|
bne @@end
|
|
@@sound:
|
|
bl m2_soundeffect
|
|
@@end:
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
// Loads the buffer up in battle
|
|
dc22a_load_buffer_battle:
|
|
push {lr}
|
|
mov r9,r0
|
|
ldr r3,[r5,#0]
|
|
bl load_pixels_overworld
|
|
push {r0-r3}
|
|
swi #5
|
|
pop {r0-r3}
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
// Calls m2_soundeffect only if we're out of the main menu
|
|
bea88_fix_sounds:
|
|
push {lr}
|
|
mov r2,r5
|
|
add r2,#0x42
|
|
ldrb r2,[r2,#0] //Is this the status window? If not, then we may not want to do the sound
|
|
cmp r2,#0
|
|
bne @@sound
|
|
ldrb r2,[r5,#3] //If we are printing, then don't do the sound
|
|
mov r1,#1
|
|
and r1,r2
|
|
cmp r1,#0
|
|
beq @@end
|
|
@@sound:
|
|
bl m2_soundeffect
|
|
@@end:
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
// Only if the character changed store the buffer - called when reading inputs
|
|
bac6e_statusWindowNumbersInputManagement:
|
|
push {lr}
|
|
ldr r2,=#m2_active_window_pc
|
|
ldrb r2,[r2,#0]
|
|
push {r2}
|
|
bl statusWindowNumbers
|
|
pop {r2}
|
|
ldr r1,=#m2_active_window_pc
|
|
ldrb r1,[r1,#0]
|
|
cmp r1,r2
|
|
beq @@end
|
|
bl store_pixels_overworld
|
|
|
|
@@end:
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Prints the attack target choice menu and stores the buffer
|
|
e02c6_print_target_store:
|
|
push {lr}
|
|
bl printTargetOfAttack
|
|
bl store_pixels_overworld
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
// Clears the PSI window when switching classes
|
|
// r5 = 0x3005230
|
|
bac18_clear_psi:
|
|
push {r0,lr}
|
|
ldr r0,[r5,0x20] // PSI class window pointer
|
|
ldrb r0,[r0]
|
|
mov r1,0x10
|
|
and r0,r1
|
|
cmp r0,0
|
|
beq @@next
|
|
|
|
// If flag 0x10 is set, clear the PSI window
|
|
bl check_overworld_buffer
|
|
ldr r1,=#buffer_subtractor
|
|
sub r1,r0,r1
|
|
ldr r0,[r5,0x1C] // PSI window
|
|
bl clear_window_buffer
|
|
|
|
@@next:
|
|
// Clobbered code
|
|
pop {r0}
|
|
lsl r0,r0,0x10
|
|
asr r4,r0,0x10
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
// Clear offense/defense when re-equipping (or un-equipping) something
|
|
baef8_reequip_erase:
|
|
push {r0-r3,lr}
|
|
mov r0,8
|
|
mov r1,0xB
|
|
mov r2,4
|
|
bl bb21c_print_blankstr_buffer
|
|
mov r0,8
|
|
mov r1,0xD
|
|
mov r2,4
|
|
bl bb21c_print_blankstr_buffer
|
|
|
|
// Clobbered code
|
|
pop {r0-r3}
|
|
mov r0,2
|
|
strh r0,[r1]
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
// Redraw main menu when exiting PSI target window
|
|
b8bbc_redraw_menu_2to1:
|
|
push {r1-r4,lr}
|
|
add sp,-4
|
|
|
|
swi #5
|
|
|
|
// Copied from 80B7A74
|
|
mov r0,0
|
|
str r0,[sp]
|
|
ldr r0,=0x3005230
|
|
ldr r0,[r0] // main menu window pointer
|
|
ldr r1,[r0,4] // text pointer
|
|
mov r2,5
|
|
mov r3,2
|
|
mov r4,r0
|
|
bl 0x80BE4C8
|
|
mov r0,r4
|
|
bl print_window_with_buffer
|
|
|
|
swi #5
|
|
|
|
// Clobbered code (restore the window borders, etc.)
|
|
mov r0,1
|
|
bl m2_swapwindowbuf
|
|
|
|
add sp,4
|
|
pop {r1-r4,pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
// Redraw main menu when exiting PSI window from using a PSI and stores the buffer
|
|
b8bbc_redraw_menu_13to2_store:
|
|
push {lr}
|
|
bl b8bbc_redraw_menu_13to2
|
|
mov r3,r9
|
|
cmp r3,#0
|
|
beq @@end //store only if we're exiting the menu
|
|
bl store_pixels_overworld
|
|
@@end:
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
// Redraw main menu when entering PSI target window
|
|
b8bbc_redraw_menu_13to2:
|
|
push {r1-r4,lr}
|
|
add sp,-4
|
|
|
|
swi #5
|
|
|
|
// Copied from 80B7A74
|
|
mov r0,0
|
|
str r0,[sp]
|
|
ldr r0,=0x3005230
|
|
ldr r0,[r0] // main menu window pointer
|
|
ldr r1,[r0,4] // text pointer
|
|
mov r2,5
|
|
mov r3,2
|
|
mov r4,r0
|
|
bl 0x80BE4C8
|
|
mov r0,r4
|
|
bl print_window_with_buffer
|
|
|
|
swi #5
|
|
|
|
// Clobbered code (restore the window borders, etc.)
|
|
mov r0,1
|
|
bl 0x80BD7F8
|
|
|
|
add sp,4
|
|
pop {r1-r4,pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
// Print a space before the Greek letter
|
|
d3934_print_space:
|
|
push {r2-r3,lr}
|
|
mov r0,r4
|
|
bl print_space
|
|
pop {r2-r3}
|
|
|
|
// Clobbered code
|
|
ldrb r1,[r3,1]
|
|
lsl r0,r1,1
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
// Copy a tile up one line
|
|
// r4: (x << 16) (relative)
|
|
// r5: dest tilemap
|
|
// r6: window
|
|
// r7: source tilemap
|
|
// r8: y (dest, relative)
|
|
// r10: 3005270
|
|
ca4bc_copy_tile_up:
|
|
push {r4-r7,lr}
|
|
|
|
// Four cases:
|
|
// 1) copy blank to blank
|
|
// 2) copy blank to non-blank
|
|
// 3) copy non-blank to blank
|
|
// 4) copy non-blank to non-blank
|
|
|
|
// 1) we don't have to do anything: pixels are blank for source and dest,
|
|
// and the tilemap won't change either
|
|
// 2) we have to erase dest pixels and set dest tilemap to 0xE2FF
|
|
// 3) we have to copy source pixels to dest pixels and set dest tilemap
|
|
// to the proper tile index
|
|
// 4) we only have to copy the source pixels to dest pixels
|
|
|
|
// Check blank by comparing tilemap with 0xE2FF
|
|
// 0xE2FF is already stored to [sp+(# of regs pushed * 4)]
|
|
ldr r0,[sp,20]
|
|
ldrh r1,[r7]
|
|
ldrh r2,[r5]
|
|
|
|
cmp r1,r0
|
|
bne @@next
|
|
cmp r2,r0
|
|
bne @@blank_to_nonblank
|
|
|
|
// Case 1: blank to blank
|
|
b @@end
|
|
|
|
@@next:
|
|
cmp r2,r0
|
|
bne @@nonblank_to_nonblank
|
|
|
|
// Case 3: non-blank to blank
|
|
@@nonblank_to_blank:
|
|
|
|
// Copy pixels up
|
|
ldrh r0,[r6,0x22]
|
|
lsl r0,r0,16
|
|
add r0,r0,r4
|
|
lsr r0,r0,16 // x
|
|
ldrh r1,[r6,0x24]
|
|
add r1,r8 // dest y
|
|
mov r4,r1
|
|
add r1,2 // source y
|
|
mov r6,r0
|
|
bl copy_tile_up
|
|
|
|
// Set proper tilemap
|
|
mov r0,r6 // dest x
|
|
mov r1,r4 // dest y
|
|
bl get_tile_number
|
|
ldr r1,=0x30051EC
|
|
ldrh r2,[r1]
|
|
add r0,r0,r2 // dest tile number
|
|
ldrh r1,[r1,0x3C] // 0xE000
|
|
orr r0,r1
|
|
strh r0,[r5]
|
|
b @@end
|
|
|
|
// Case 2: blank to non-blank
|
|
@@blank_to_nonblank:
|
|
|
|
// Set dest tilemap to 0xE2FF
|
|
strh r0,[r5]
|
|
|
|
// Case 4: non-blank to non-blank
|
|
@@nonblank_to_nonblank:
|
|
|
|
// Copy pixels up
|
|
ldrh r0,[r6,0x22]
|
|
lsl r0,r0,16
|
|
add r0,r0,r4
|
|
lsr r0,r0,16 // x
|
|
ldrh r1,[r6,0x24]
|
|
add r1,r8 // dest y
|
|
add r1,2 // source y
|
|
bl copy_tile_up
|
|
|
|
@@end:
|
|
pop {r4-r7,pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
// Erase tile (for short windows)
|
|
// r2: 100
|
|
// r4: (x << 16) (relative)
|
|
// r5: dest tilemap
|
|
// r6: window
|
|
// r8: y (dest, relative)
|
|
ca4bc_erase_tile_short:
|
|
push {r0-r1,lr}
|
|
|
|
// Clobbered code
|
|
orr r0,r1 // 0xE2FF
|
|
strh r0,[r5] // dest tilemap
|
|
|
|
// We need to erase the pixels
|
|
ca4bc_erase_tile_common:
|
|
ldrh r2,[r6,0x22]
|
|
lsl r2,r2,16
|
|
add r2,r2,r4
|
|
lsr r0,r2,16 // x
|
|
ldrh r1,[r6,0x24]
|
|
add r1,r8 // y
|
|
ldr r2,=0x44444444
|
|
bl clear_tile
|
|
|
|
pop {r0-r1,pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
// Erase tile
|
|
ca4bc_erase_tile:
|
|
push {r0-r1,lr}
|
|
|
|
// Clobbered code
|
|
ldrh r1,[r1]
|
|
strh r1,[r5]
|
|
|
|
// We need to erase the pixels
|
|
b ca4bc_erase_tile_common
|
|
.pool
|
|
|
|
//==============================================================================
|
|
// Clear PSI window when scrolling through classes
|
|
e06ec_clear_window:
|
|
push {r0-r1,lr}
|
|
ldr r0,=0x3002500
|
|
ldrh r0,[r0]
|
|
cmp r0,0
|
|
beq @@next
|
|
bl check_overworld_buffer
|
|
ldr r1,=#buffer_subtractor
|
|
sub r1,r0,r1
|
|
ldr r0,=#0x3005230
|
|
ldr r0,[r0,0x1C]
|
|
bl clear_window_buffer
|
|
|
|
@@next:
|
|
pop {r0-r1}
|
|
|
|
// Clobbered code
|
|
lsl r0,r0,0x10
|
|
asr r4,r0,0x10
|
|
pop {pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
// Redraw PSI command when exiting PSI subwindow
|
|
e06ec_redraw_psi:
|
|
push {r0-r3,lr}
|
|
|
|
mov r0,#1
|
|
mov r1,#2
|
|
mov r2,#2
|
|
bl printBattleMenu
|
|
|
|
// Clobbered code
|
|
pop {r0-r3}
|
|
bl 0x80BD7F8 // restore tilemaps
|
|
pop {pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
// Redraw Bash/Do Nothing and PSI commands when exiting PSI ally target subwindow
|
|
e06ec_redraw_bash_psi:
|
|
push {r0-r3,lr}
|
|
mov r0,#1
|
|
mov r1,#3
|
|
mov r2,#2
|
|
bl printBattleMenu
|
|
|
|
// Clobbered code
|
|
pop {r0-r3}
|
|
bl 0x80BD7F8 // restore tilemaps
|
|
pop {pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
// Redraw Bash/Do Nothing, PSI commands, Goods and Defend when choosing enemy target
|
|
e06ec_redraw_bash_psi_goods_defend:
|
|
push {lr}
|
|
push {r0-r3}
|
|
ldr r2,=#0x8B204E4 //Is this an offensive PSI which needs a target? If so, redraw the background window
|
|
ldr r1,=#0x8B2A9B0
|
|
ldr r0,[r6,#0x1C]
|
|
ldr r0,[r0,#0x10]
|
|
ldrh r3,[r0,#2]
|
|
lsl r3,r3,#4
|
|
add r0,r3,r1
|
|
ldrh r3,[r0,#4]
|
|
lsl r0,r3,#1
|
|
add r0,r0,r3
|
|
lsl r0,r0,#2
|
|
add r3,r0,r2
|
|
ldrb r0,[r3,#1]
|
|
cmp r0,#1
|
|
beq @@keep
|
|
cmp r0,#3
|
|
bne @@notOffensive //Otherwise, do not do it
|
|
@@keep:
|
|
ldrb r0,[r3]
|
|
cmp r0,#0
|
|
bne @@notOffensive
|
|
|
|
mov r0,#3
|
|
mov r1,#3
|
|
mov r2,#2
|
|
bl printBattleMenu
|
|
|
|
@@notOffensive:
|
|
|
|
pop {r0-r3}
|
|
|
|
bl 0x80C2480 //Prints the target
|
|
pop {pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Redraw main battle window for "goods" targets
|
|
e0ce4_redraw_battle_window_first_four:
|
|
push {lr}
|
|
push {r0-r3}
|
|
mov r0,#3
|
|
mov r1,#3
|
|
mov r2,#4
|
|
bl printBattleMenu
|
|
pop {r0-r3}
|
|
bl initWindow_buffer
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Redraw main battle window for going back to Goods from targets
|
|
e0faa_redraw_battle_window_first_two:
|
|
push {r4,lr}
|
|
push {r0-r3}
|
|
mov r0,#1
|
|
mov r1,#1
|
|
mov r2,#4
|
|
bl printBattleMenu
|
|
pop {r0-r3}
|
|
ldr r4,[sp,#8]
|
|
add sp,#-4
|
|
str r4,[sp,#0]
|
|
bl initWindow_cursor_buffer
|
|
mov r0,#4
|
|
bl store_pixels_overworld_buffer_totalTiles
|
|
mov r0,#0
|
|
add sp,#4
|
|
pop {r4,pc}
|
|
|
|
//==============================================================================
|
|
//Calls the funcion which loads the targets in and then stores the buffer
|
|
ba8ac_load_targets_print:
|
|
push {lr}
|
|
ldr r2,=#0x20248AC
|
|
ldrh r2,[r2,#0]
|
|
push {r2}
|
|
bl 0x80BAA80
|
|
pop {r2}
|
|
cmp r2,#0
|
|
bne @@end //Store the buffer to vram only if the target window was printed.
|
|
bl store_pixels_overworld
|
|
@@end:
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
// Print "PSI "
|
|
c239c_print_psi:
|
|
push {lr}
|
|
add sp,-4
|
|
mov r2,0
|
|
str r2,[sp]
|
|
mov r2,r4
|
|
lsl r3,r3,3 // tiles-to-pixels
|
|
bl printstr_hlight_pixels_buffer
|
|
add sp,4
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
// Use new pointer for user/target strings
|
|
ebfd4_user_pointer:
|
|
push {lr}
|
|
bl save_last_pc_overworld
|
|
mov r4,0x4C
|
|
lsl r4,r4,4
|
|
add r0,r0,r4
|
|
mov r5,r0
|
|
lsl r4,r1,0x10
|
|
asr r4,r4,0x10
|
|
mov r1,r2
|
|
mov r2,r4
|
|
bl 0x80F4C78
|
|
add r0,r4,r5
|
|
mov r1,0
|
|
strb r1,[r0]
|
|
mov r1,0xFF
|
|
strb r1,[r0,1]
|
|
pop {pc}
|
|
|
|
ec004_user_pointer:
|
|
push {r1}
|
|
ldr r1,[sp,4]
|
|
mov lr,r1
|
|
pop {r1}
|
|
add sp,4
|
|
ldr r0,=0x3005220
|
|
ldr r0,[r0]
|
|
mov r1,0x4C
|
|
lsl r1,r1,4
|
|
add r0,r0,r1
|
|
bx lr
|
|
|
|
ec010_target_pointer:
|
|
push {lr}
|
|
mov r4,0x50
|
|
lsl r4,r4,4
|
|
add r0,r0,r4
|
|
mov r5,r0
|
|
lsl r4,r1,0x10
|
|
asr r4,r4,0x10
|
|
mov r1,r2
|
|
mov r2,r4
|
|
bl 0x80F4C78
|
|
add r0,r4,r5
|
|
mov r1,0
|
|
strb r1,[r0]
|
|
mov r1,0xFF
|
|
strb r1,[r0,1]
|
|
pop {pc}
|
|
|
|
ec046_target_pointer:
|
|
push {r1}
|
|
ldr r1,[sp,4]
|
|
mov lr,r1
|
|
pop {r1}
|
|
add sp,4
|
|
ldr r0,[r0]
|
|
mov r1,0x50
|
|
lsl r1,r1,4
|
|
add r0,r0,r1
|
|
bx lr
|
|
|
|
c980c_user_pointer:
|
|
push {lr}
|
|
bl custom_user_pointer
|
|
ldr r0,[r5,0x1C]
|
|
pop {pc}
|
|
|
|
c980c_target_pointer:
|
|
ldr r0,[r0]
|
|
mov r7,0x50
|
|
lsl r7,r7,4
|
|
add r0,r0,r7
|
|
bx lr
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Saves the last loaded pc for the overworld
|
|
save_last_pc_overworld:
|
|
push {r0-r1,lr}
|
|
ldr r1,=m2_is_battle
|
|
ldrh r1,[r1]
|
|
cmp r1,#0 //Are we in the overworld?
|
|
bne @@total_end
|
|
mov r1,0 //If we are, find out which pc it is...
|
|
ldr r0,=m2_ness_name //Ness
|
|
cmp r0,r2
|
|
beq @@end
|
|
mov r1,1
|
|
add r0,7 //Paula
|
|
cmp r0,r2
|
|
beq @@end
|
|
mov r1,2
|
|
add r0,7 //Jeff
|
|
cmp r0,r2
|
|
beq @@end
|
|
mov r1,3
|
|
add r0,7 //Poo
|
|
cmp r0,r2
|
|
beq @@end
|
|
mov r1,0xFF
|
|
|
|
@@end:
|
|
ldr r0,=m2_cstm_last_pc //Save it here
|
|
strb r1,[r0]
|
|
|
|
@@total_end:
|
|
pop {r0-r1,pc}
|
|
|
|
|
|
//==============================================================================
|
|
//Sets the names' background to a default
|
|
_215a_load_names:
|
|
push {lr}
|
|
bl 0x8012460
|
|
bl set_background_loaded_names
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
// Add a space between enemy name and letter in multi-enemy fights for the selection window. Called only by enemies.
|
|
dcd00_enemy_letter:
|
|
push {r1-r2,lr}
|
|
ldrb r1,[r5,#0]
|
|
cmp r1,#1 //In case the name has a "the " at the beginning, remove it
|
|
bne @@end
|
|
mov r2,sp
|
|
add r2,#0xC //Get where the writing stack for the name starts
|
|
sub r5,r5,#4
|
|
@@cycle: //The removed and shifted everything by 4 bytes
|
|
ldr r1,[r2,#4]
|
|
str r1,[r2,#0]
|
|
add r2,#4
|
|
cmp r2,r5
|
|
ble @@cycle
|
|
|
|
@@end:
|
|
sub r5,r5,#2 //The the flag must be accounted for. It moves the pointer by 2, so we put it back
|
|
sub r0,0x90
|
|
strb r0,[r5,#1] //Put the letter near the enemy writing space
|
|
mov r0,#0x50 //Store the space
|
|
strb r0,[r5]
|
|
mov r0,#0 //Store the the flag as 0
|
|
strb r0,[r5,#4]
|
|
pop {r1-r2,pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
// Add a space between enemy name and letter in multi-enemy fights for 9F FF and AD FF. Only enemies call this.
|
|
dae00_enemy_letter:
|
|
push {lr}
|
|
sub r0,0x90
|
|
strb r0,[r4,#1] //Put the letter near the enemy writing space
|
|
mov r0,#0x50 //Store the space
|
|
strb r0,[r4]
|
|
mov r0,#0 //Store the the flag as 0
|
|
strb r0,[r4,#4]
|
|
pop {pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
// "The" flag checks for the Target window. It will always be lowercase, this makes things much simpler because it will never be changed due to the character printed before it, unlike how it happens with 9F FF and AD FF.
|
|
dcd5c_theflag:
|
|
push {r4,lr}
|
|
|
|
// Clobbered code: get enemy string pointer
|
|
lsl r4,r2,1
|
|
bl 0x80BE260
|
|
mov r1,r0
|
|
mov r0,sp
|
|
add r0,8
|
|
|
|
// Check for "The" flag
|
|
ldr r3,=m2_enemy_attributes
|
|
ldrb r3,[r3,r4] // "The" flag
|
|
cmp r3,0
|
|
beq @@next
|
|
|
|
// Write "the " before the enemy name
|
|
ldr r2,=0x509598A4
|
|
str r2,[r0]
|
|
add r0,4
|
|
|
|
@@next:
|
|
pop {r4,pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
db08e_theflagflag: //Puts a flag at the end of the name that is 1 if the has been added. 0 otherwise. (called right after db04c_theflag or dcd5c_theflag)
|
|
push {r3,lr}
|
|
bl 0x80DAEEC
|
|
pop {r3}
|
|
add r0,#2
|
|
strb r3,[r0,#0]
|
|
mov r3,r0
|
|
pop {pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
ca442_store_letter:
|
|
push {r1,lr}
|
|
ldr r1,=m2_cstm_last_printed
|
|
ldrb r0,[r7,#0]
|
|
strb r0,[r1,#0]
|
|
lsl r0,r0,#1
|
|
pop {r1,pc}
|
|
|
|
//==============================================================================
|
|
custom_user_pointer: //Routine that gives in r1 the user string pointer
|
|
ldr r1,[r0,#0]
|
|
mov r0,#0x4C
|
|
lsl r0,r0,#4
|
|
add r1,r0,r1
|
|
bx lr
|
|
|
|
//==============================================================================
|
|
// r0 = window
|
|
// r9 = item index
|
|
// Return: r2 = x location for item string (relative to window location)
|
|
// Can use: r1, r3, r5
|
|
b998e_get_itemstring_x:
|
|
push {lr}
|
|
mov r5,r0
|
|
|
|
// r2 = cursor_x + 1 + (is_equipped(current_item_index) ? 1 : 0)
|
|
mov r0,r9
|
|
add r0,1
|
|
bl m2_isequipped
|
|
ldrh r1,[r5,0x34] // cursor_x
|
|
add r0,r0,r1
|
|
add r2,r0,1
|
|
|
|
mov r0,r5
|
|
pop {pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Loads the player's name properly
|
|
eeb1a_player_name:
|
|
push {lr}
|
|
mov r2,#0x18 //Maximum amount of characters in the name
|
|
ldr r1,=m2_player1 //Player's name new location
|
|
mov r3,#0
|
|
|
|
@@continue_cycle: //Count the amount of characters
|
|
cmp r3,r2
|
|
bge @@exit_cycle
|
|
add r0,r1,r3
|
|
ldrb r0,[r0,#0]
|
|
cmp r0,#0xFF
|
|
beq @@exit_cycle
|
|
add r3,#1
|
|
b @@continue_cycle
|
|
|
|
@@exit_cycle:
|
|
mov r4,r3 //Store the amount of characters in r4
|
|
|
|
bl 0x80A322C //Clobbered code: load at which letter the routine is
|
|
lsl r1,r4,#0x10
|
|
lsl r0,r0,#0x10
|
|
cmp r1,r0
|
|
blt @@ended
|
|
bl 0x80A322C
|
|
|
|
mov r3,#1
|
|
ldr r1,=m2_player1 //Player's name new location. The routine starts from 1 because the original routine had a flag before the name, so we subtract 1 to the address we look at in order to avoid skipping a character
|
|
sub r1,r1,r3
|
|
lsl r0,r0,#0x10
|
|
asr r0,r0,#0x10
|
|
add r1,r1,r0
|
|
ldrb r0,[r1,#0]
|
|
b @@next
|
|
|
|
@@ended:
|
|
mov r0,#0
|
|
|
|
@@next: //Do the rest of the routine
|
|
pop {pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//These three hacks remove the game's ability to read the script instantly out of a won battle
|
|
|
|
cb936_battle_won: //Called at the end of a battle if it is won
|
|
push {lr}
|
|
ldr r0,=m2_script_readability //Remove the ability to instantly read the script
|
|
mov r1,#8
|
|
strb r1,[r0,#0]
|
|
|
|
ldr r0,=#0x3000A6C //Clobbered code
|
|
mov r1,#0
|
|
pop {pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
|
|
b7702_check_script_reading: //Makes the game wait six extra frames before being able to read the script out of battle
|
|
push {lr}
|
|
ldr r0,=m2_script_readability
|
|
ldrb r1,[r0,#0]
|
|
cmp r1,#2 //If the value is > 2, then lower it
|
|
ble @@next
|
|
sub r1,r1,#1
|
|
strb r1,[r0,#0]
|
|
b @@end
|
|
|
|
@@next:
|
|
cmp r1,#2 //If the value is 2, change it to 0 and allow reading the script
|
|
bne @@end
|
|
mov r1,#0
|
|
strb r1,[r0,#0]
|
|
|
|
@@end:
|
|
mov r7,r10 //Clobbered code
|
|
mov r6,r9
|
|
pop {pc}
|
|
.pool
|
|
|
|
//==============================================================================
|
|
|
|
a1f8c_set_script_reading: //Changes the way the game sets the ability to read the script
|
|
push {lr}
|
|
ldrb r1,[r0,#0]
|
|
cmp r1,#8 //If this particular flag is set, then don't do a thing. Allows to make it so the game waits before reading the script.
|
|
beq @@next
|
|
mov r1,#0
|
|
strb r1,[r0,#0]
|
|
b @@end
|
|
|
|
@@next:
|
|
mov r1,#0
|
|
|
|
@@end:
|
|
pop {pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Hacks that load specific numbers for the new names
|
|
_2352_load_1d7:
|
|
mov r0,#0xEB
|
|
lsl r0,r0,#1
|
|
add r0,r0,#1
|
|
bx lr
|
|
|
|
_2372_load_1e5:
|
|
mov r0,#0xF2
|
|
lsl r0,r0,#1
|
|
add r0,r0,#1
|
|
bx lr
|
|
|
|
c98c4_load_1d7:
|
|
mov r4,#0xEB
|
|
lsl r4,r4,#1
|
|
add r4,r4,#1
|
|
bx lr
|
|
|
|
c98d4_load_1e5:
|
|
mov r4,#0xF2
|
|
lsl r4,r4,#1
|
|
add r4,r4,#1
|
|
bx lr
|
|
|
|
//==============================================================================
|
|
//Fast routine that uses the defaults and stores them. Original one is a nightmare. Rewriting it from scratch. r1 has the target address. r5 has 0.
|
|
cb2f2_hardcoded_defaults:
|
|
push {lr}
|
|
mov r0,#0x7E //Ness' name
|
|
strb r0,[r1,#0]
|
|
mov r2,#0x95
|
|
strb r2,[r1,#1]
|
|
strb r2,[r1,#0xF]
|
|
mov r0,#0xA3
|
|
strb r0,[r1,#2]
|
|
strb r0,[r1,#3]
|
|
mov r4,#0xFF
|
|
lsl r5,r4,#8
|
|
strh r5,[r1,#4]
|
|
add r1,#7
|
|
mov r0,#0x80 //Paula's name
|
|
strb r0,[r1,#0]
|
|
strb r0,[r1,#0xE]
|
|
mov r3,#0x91
|
|
strb r3,[r1,#1]
|
|
strb r3,[r1,#4]
|
|
mov r0,#0xA5
|
|
strb r0,[r1,#2]
|
|
mov r0,#0x9C
|
|
strb r0,[r1,#3]
|
|
strb r5,[r1,#5]
|
|
strb r4,[r1,#6]
|
|
add r1,#7
|
|
mov r0,#0x7A //Jeff's name
|
|
strb r0,[r1,#0]
|
|
mov r0,#0x95
|
|
strb r0,[r1,#1]
|
|
mov r0,#0x96
|
|
strb r0,[r1,#2]
|
|
strb r0,[r1,#3]
|
|
strh r5,[r1,#4]
|
|
add r1,#7
|
|
strb r4,[r1,#4]
|
|
mov r4,#0x9F //Poo's name
|
|
strb r4,[r1,#1]
|
|
strb r4,[r1,#2]
|
|
strb r5,[r1,#3]
|
|
add r1,#7
|
|
mov r0,#0x7B //King's name
|
|
strb r0,[r1,#0]
|
|
mov r0,#0x99
|
|
strb r0,[r1,#1]
|
|
mov r0,#0x9E
|
|
strb r0,[r1,#2]
|
|
mov r0,#0x97
|
|
strb r0,[r1,#3]
|
|
strh r5,[r1,#4]
|
|
add r1,#8
|
|
mov r0,#0x83 //Steak's name
|
|
strb r0,[r1,#0]
|
|
mov r0,#0xA4
|
|
strb r0,[r1,#1]
|
|
strb r2,[r1,#2]
|
|
strb r3,[r1,#3]
|
|
mov r3,#0x9B
|
|
strb r3,[r1,#4]
|
|
mov r2,#0xFF
|
|
strb r5,[r1,#5]
|
|
strb r2,[r1,#6]
|
|
add r1,#8
|
|
mov r0,#0x82 //Rockin's name
|
|
strb r0,[r1,#0]
|
|
strb r4,[r1,#1]
|
|
mov r0,#0x93
|
|
strb r0,[r1,#2]
|
|
strb r3,[r1,#3]
|
|
mov r0,#0x99
|
|
strb r0,[r1,#4]
|
|
mov r0,#0x9E
|
|
strb r0,[r1,#5]
|
|
strh r5,[r1,#6]
|
|
mov r2,#1
|
|
mov r5,#0
|
|
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Routine for window headers that fixes the issue character - tiles
|
|
fix_char_tiles:
|
|
push {lr}
|
|
lsl r0,r2,#1
|
|
lsl r1,r2,#2
|
|
add r1,r1,r0 //Multiply r2 (character count) by 6
|
|
lsr r0,r1,#3 //Divide by 8
|
|
lsl r0,r0,#3 //Re-multiply by 8
|
|
cmp r0,r1 //Can it stay in r0 pixels? (Was this a division by 8 without remainder?)
|
|
beq @@next
|
|
add r0,#8 //If it cannot stay in x tiles, add 1 to the amount of tiles needed
|
|
|
|
@@next:
|
|
lsr r0,r0,#3 //Get the amount of tiles needed
|
|
cmp r0,r2 //If it's not the same amout as the characters...
|
|
beq @@end
|
|
sub r0,r2,r0
|
|
lsl r0,r0,#1
|
|
sub r6,r6,r0 //Remove the amount of extra tiles
|
|
|
|
@@end:
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Specific fix_char_tiles routine - Status window
|
|
c0b28_fix_char_tiles:
|
|
push {lr}
|
|
bl fix_char_tiles
|
|
ldr r0,[r4,#0] //Clobbered code
|
|
add r0,#0xB3
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Specific fix_char_tiles routine - Give window
|
|
c009e_fix_char_tiles:
|
|
push {lr}
|
|
mov r2,r5
|
|
bl fix_char_tiles
|
|
ldr r2,=#0x30051EC //Clobbered code
|
|
ldrh r0,[r2]
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Specific fix_char_tiles routine - Equip window
|
|
c4bd6_fix_char_tiles:
|
|
push {lr}
|
|
mov r6,r7
|
|
bl fix_char_tiles
|
|
mov r7,r6
|
|
ldr r2,=#0x30051EC //Clobbered code
|
|
ldrh r0,[r2]
|
|
pop {pc}
|
|
|
|
.pool
|
|
//==============================================================================
|
|
//Specific fix_char_tiles routine - Outer PSI window
|
|
c42e0_fix_char_tiles:
|
|
push {lr}
|
|
bl fix_char_tiles
|
|
mov r2,r9 //Clobbered code
|
|
ldrh r0,[r2,#0]
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Specific fix_char_tiles routine - Inner PSI window - part 2
|
|
c4448_fix_char_tiles:
|
|
push {lr}
|
|
bl fix_char_tiles
|
|
mov r2,r8 //Clobbered code
|
|
ldrh r0,[r2,#0]
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Routine which clears the header and THEN makes it so the string is printed
|
|
c6190_clean_print:
|
|
push {lr}
|
|
push {r0-r3}
|
|
mov r1,#6 //Number of tiles to clean
|
|
bl clear_window_header
|
|
pop {r0-r3}
|
|
bl 0x80CAB90
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Routine which prints just the number with a tiny buffer
|
|
c6190_buffer_number:
|
|
push {lr}
|
|
lsl r2,r2,#3
|
|
lsl r3,r3,#3
|
|
bl print_window_number_header_string
|
|
add r0,#7
|
|
lsr r0,r0,#3
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Routine which clears the header and THEN makes it so the string is printed
|
|
c65da_clean_print:
|
|
push {lr}
|
|
push {r0-r3}
|
|
mov r1,#3 //Number of tiles to clean
|
|
bl clear_window_header
|
|
pop {r0-r3}
|
|
bl 0x80CAB90
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Routine which clears the header and THEN makes it so the string is printed
|
|
_0x10_clean_print:
|
|
push {lr}
|
|
push {r0-r3}
|
|
mov r1,#0x10 //Number of tiles to clean
|
|
bl clear_window_header
|
|
pop {r0-r3}
|
|
bl 0x80CAB90
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Routine which calls the header clearer and changes the position of Stored Goods in the arrangement
|
|
c6570_clean_print_change_pos:
|
|
push {lr}
|
|
ldrb r0,[r6,#2] //Load pixel_x
|
|
cmp r0,#0xFF
|
|
bne @@after_header
|
|
mov r0,#0
|
|
strb r0,[r6,#2]
|
|
mov r0,r7
|
|
bl _0x10_clean_print
|
|
|
|
@@after_header:
|
|
ldr r2,=#0x230 //Change starting position
|
|
mov r0,r2 //Clobbered code
|
|
ldrh r3,[r4,#0]
|
|
add r0,r0,r3
|
|
mov r2,r8
|
|
ldrh r1,[r2,#0]
|
|
orr r0,r1
|
|
mov r2,#0
|
|
|
|
@@cycle: //Print 9 tiles in the arrangement
|
|
lsl r0,r0,#0x10
|
|
lsr r0,r0,#0x10
|
|
mov r1,r0
|
|
add r0,r1,#1
|
|
strh r1,[r5,#0]
|
|
add r5,#2
|
|
add r2,#1
|
|
cmp r2,#9
|
|
bne @@cycle
|
|
|
|
bl store_pixels_overworld // Stores buffer after printing happened
|
|
|
|
pop {pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Routine which gives the address to the party member's inventory
|
|
get_inventory_selected:
|
|
push {r3,lr}
|
|
ldr r0,=m2_source_pc //Load source pc
|
|
ldrb r0,[r0,#0]
|
|
ldr r3,=#0x3001D40 //Get inventory
|
|
mov r2,#0x6C
|
|
mul r0,r2
|
|
add r3,#0x14
|
|
add r0,r0,r3
|
|
pop {r3,pc}
|
|
|
|
//==============================================================================
|
|
//Routine which gets the address to the selected party member's inventory and then prints it
|
|
get_print_inventory_window:
|
|
push {r0-r4,lr}
|
|
bl get_inventory_selected
|
|
mov r1,r0 //Inventory
|
|
ldr r0,[r4,#0x10] //Window
|
|
|
|
ldr r3,=m2_active_window_pc //Change the pc of the window so m2_isequipped can work properly
|
|
ldr r2,[r3,#0]
|
|
lsl r2,r2,#0x10
|
|
asr r2,r2,#0x10
|
|
push {r2}
|
|
ldr r2,=m2_source_pc //Load source pc
|
|
ldrb r2,[r2,#0]
|
|
str r2,[r3,#0] //Store it
|
|
|
|
mov r2,#0 //No y offset
|
|
bl goods_print_items //Print the inventory
|
|
bl store_pixels_overworld
|
|
|
|
pop {r2}
|
|
ldr r3,=m2_active_window_pc //Restore pc of the window
|
|
lsl r2,r2,#0x10
|
|
asr r2,r2,#0x10
|
|
str r2,[r3,#0]
|
|
|
|
pop {r0-r4,pc}
|
|
|
|
//==============================================================================
|
|
//Specific Routine which calls get_print_inventory_window
|
|
ba48e_get_print_inventory_window:
|
|
push {lr}
|
|
push {r4}
|
|
ldr r4,=#0x3005230
|
|
bl get_print_inventory_window //Prints old inventory
|
|
pop {r4}
|
|
bl 0x80BD7F8 //Copies old arrangements, this includes the highlight
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Specific Routine which calls get_print_inventory_window
|
|
b9ecc_get_print_inventory_window:
|
|
push {lr}
|
|
push {r4}
|
|
ldr r4,=#0x3005230
|
|
bl get_print_inventory_window //Prints old inventory
|
|
pop {r4}
|
|
bl 0x80BD7F8 //Copies old arrangements, this includes the highlight
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Specific Routine which calls get_print_inventory_window
|
|
ba61c_get_print_inventory_window:
|
|
push {r5,lr}
|
|
mov r5,r7
|
|
bl get_print_inventory_window //Prints old inventory
|
|
bl 0x80BD7F8 //Copies old arrangements, this includes the highlight
|
|
pop {r5,pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Reprints both the Main window and the Cash window if need be
|
|
generic_reprinting_first_menu:
|
|
push {lr}
|
|
push {r0-r6}
|
|
add sp,#-8
|
|
ldr r6,=#0x3005078 //Make sure the game expects only the right amount of lines to be written (so only 1)
|
|
ldrb r4,[r6,#0]
|
|
str r4,[sp,#4]
|
|
mov r4,#0
|
|
strb r4,[r6,#0]
|
|
ldr r4,=#0x3005230 //Window generic address
|
|
|
|
//Main window
|
|
mov r2,#1
|
|
ldr r0,[r4,#0] //Main window place in ram
|
|
ldrb r0,[r0,#0]
|
|
and r2,r0
|
|
cmp r2,#0
|
|
beq @@cash //Check if window is enabled before printing in it
|
|
|
|
ldr r0,=#0x8B17EE4
|
|
ldr r1,=#0x8B17424
|
|
ldr r3,=m2_psi_exist //Flag which if not 0xFF means no one has PSI
|
|
ldrb r3,[r3,#0]
|
|
cmp r3,#0xFF
|
|
beq @@psiNotFound
|
|
mov r2,#0
|
|
b @@keep_going
|
|
@@psiNotFound:
|
|
mov r2,#1
|
|
@@keep_going:
|
|
bl m2_strlookup //Load the proper menu string based on m2_psi_exist
|
|
mov r1,#0
|
|
str r1,[sp,#0]
|
|
mov r1,r0
|
|
ldr r0,[r4,#0]
|
|
mov r2,#5
|
|
mov r3,#2
|
|
bl 0x80BE4C8 //Let it do its things
|
|
ldr r0,[r4,#0]
|
|
bl print_window_with_buffer //Print text in the window
|
|
mov r2,#1
|
|
ldr r0,[r4,#4] //Cash window place in ram
|
|
ldrb r0,[r0,#0]
|
|
and r2,r0
|
|
cmp r2,#0
|
|
bne @@insidecash
|
|
bl store_pixels_overworld_options //Only this window must be reprinted
|
|
b @@end
|
|
|
|
@@cash:
|
|
//Cash
|
|
mov r2,#1
|
|
ldr r0,[r4,#4] //Cash window place in ram
|
|
ldrb r0,[r0,#0]
|
|
and r2,r0
|
|
cmp r2,#0
|
|
beq @@end //Check if window is enabled before printing in it
|
|
|
|
@@insidecash:
|
|
ldr r2,=#0x300130C
|
|
ldr r0,[r2,#0]
|
|
mov r1,#2
|
|
orr r0,r1
|
|
str r0,[r2,#0]
|
|
ldr r0,=#0x3001D40
|
|
mov r1,#0xD2
|
|
lsl r1,r1,#3
|
|
add r0,r0,r1
|
|
ldr r0,[r0,#0] //Load the money
|
|
ldr r5,=#0x3005200
|
|
ldr r1,[r5,#0]
|
|
mov r2,r1 //Load the string address
|
|
mov r1,#0x30 //Padding
|
|
bl format_cash_window
|
|
ldr r0,[r4,#4]
|
|
ldr r1,[r5,#0]
|
|
mov r2,#0
|
|
bl initWindow_buffer //Let it do its things
|
|
ldr r0,[r4,#4]
|
|
bl print_window_with_buffer //Print text in the window
|
|
bl store_pixels_overworld_psi_window
|
|
|
|
@@end:
|
|
ldr r4,[sp,#4]
|
|
strb r4,[r6,#0] //Restore expected amount of lines to be written
|
|
add sp,#8
|
|
pop {r0-r6}
|
|
pop {pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Reprints both the Main window and the Cash window if need be, but highlights "Talk to"
|
|
generic_reprinting_first_menu_talk_to_highlight:
|
|
push {lr}
|
|
push {r0-r6}
|
|
add sp,#-8
|
|
ldr r6,=#0x3005078 //Make sure the game expects only the right amount of lines to be written (so only 1)
|
|
ldrb r4,[r6,#0]
|
|
str r4,[sp,#4]
|
|
mov r4,#0
|
|
strb r4,[r6,#0]
|
|
ldr r4,=#0x3005230 //Window generic address
|
|
|
|
//Main window
|
|
mov r2,#1
|
|
ldr r0,[r4,#0] //Main window place in ram
|
|
ldrb r0,[r0,#0]
|
|
and r2,r0
|
|
cmp r2,#0
|
|
beq @@cash //Check if window is enabled before printing in it
|
|
|
|
ldr r0,=#0x8B17EE4
|
|
ldr r1,=#0x8B17424
|
|
ldr r3,=m2_psi_exist //Flag which if not 0xFF means no one has PSI
|
|
ldrb r3,[r3,#0]
|
|
cmp r3,#0xFF
|
|
beq @@psiNotFound
|
|
mov r2,#0
|
|
b @@keep_going
|
|
@@psiNotFound:
|
|
mov r2,#1
|
|
@@keep_going:
|
|
bl m2_strlookup //Load the proper menu string based on m2_psi_exist
|
|
mov r1,#0
|
|
str r1,[sp,#0]
|
|
mov r1,r0
|
|
ldr r0,[r4,#0]
|
|
mov r2,#5
|
|
mov r3,#2
|
|
bl 0x80BE4C8 //Let it do its things
|
|
ldr r0,[r4,#0]
|
|
bl print_window_with_buffer //Print text in the window
|
|
bl highlight_talk_to
|
|
mov r2,#1
|
|
ldr r0,[r4,#4] //Cash window place in ram
|
|
ldrb r0,[r0,#0]
|
|
and r2,r0
|
|
cmp r2,#0
|
|
bne @@insidecash
|
|
bl store_pixels_overworld_options //Only this window must be reprinted
|
|
b @@end
|
|
|
|
@@cash:
|
|
//Cash
|
|
mov r2,#1
|
|
ldr r0,[r4,#4] //Cash window place in ram
|
|
ldrb r0,[r0,#0]
|
|
and r2,r0
|
|
cmp r2,#0
|
|
beq @@end //Check if window is enabled before printing in it
|
|
|
|
@@insidecash:
|
|
ldr r2,=#0x300130C
|
|
ldr r0,[r2,#0]
|
|
mov r1,#2
|
|
orr r0,r1
|
|
str r0,[r2,#0]
|
|
ldr r0,=#0x3001D40
|
|
mov r1,#0xD2
|
|
lsl r1,r1,#3
|
|
add r0,r0,r1
|
|
ldr r0,[r0,#0] //Load the money
|
|
ldr r5,=#0x3005200
|
|
ldr r1,[r5,#0]
|
|
mov r2,r1 //Load the string address
|
|
mov r1,#0x30 //Padding
|
|
bl format_cash_window
|
|
ldr r0,[r4,#4]
|
|
ldr r1,[r5,#0]
|
|
mov r2,#0
|
|
bl initWindow_buffer //Let it do its things
|
|
ldr r0,[r4,#4]
|
|
bl print_window_with_buffer //Print text in the window
|
|
bl store_pixels_overworld_psi_window
|
|
|
|
@@end:
|
|
ldr r4,[sp,#4]
|
|
strb r4,[r6,#0] //Restore expected amount of lines to be written
|
|
add sp,#8
|
|
pop {r0-r6}
|
|
pop {pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Specific (But still very generic) call to generic_reprinting_first_menu which then calls swapwindowbuf as expected from the game
|
|
_reprint_first_menu:
|
|
push {lr}
|
|
bl generic_reprinting_first_menu
|
|
mov r0,#1
|
|
bl m2_swapwindowbuf
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Specific call to b9aa2_special_string, needed for the help function
|
|
ba7be_reprint_first_menu:
|
|
push {lr}
|
|
bl b9aa2_special_string
|
|
ldr r1,=#0x40000D4
|
|
ldr r0,=#0x3005200
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Specific call to b9aa2_special_string, needed for when you exit the item action function
|
|
b9aa2_reprint_first_menu:
|
|
push {lr}
|
|
bl b9aa2_special_string
|
|
mov r0,#1
|
|
bl 0x80BD7F8
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Setup which only prints either "Check" or "PSI \n Check" in the main window. Needed in order to avoid the not-needed options popping in the item window for 2-3 frames
|
|
b9aa2_special_string:
|
|
push {lr}
|
|
push {r0-r5}
|
|
add sp,#-68
|
|
ldr r5,=#0x3005078 //Make sure the game expects only the right amount of lines to be written (so only 1)
|
|
ldrb r4,[r5,#0]
|
|
str r4,[sp,#4]
|
|
mov r4,#0
|
|
strb r4,[r5,#0]
|
|
ldr r4,=#0x3005230 //Window generic address
|
|
|
|
//Main window
|
|
mov r2,#1
|
|
ldr r0,[r4,#0] //Main window place in ram
|
|
ldrb r0,[r0,#0]
|
|
and r2,r0
|
|
cmp r2,#0
|
|
beq @@end //Check if window is enabled before printing in it
|
|
|
|
ldr r1,=m2_psi_exist
|
|
ldrb r1,[r1,#0]
|
|
add r0,sp,#8
|
|
bl setupShortMainMenu //Get shortened menu string
|
|
mov r1,#0
|
|
str r1,[sp,#0]
|
|
add r1,sp,#8
|
|
ldr r0,[r4,#0]
|
|
mov r2,#5
|
|
mov r3,#2
|
|
bl 0x80BE4C8 //Let it do its things
|
|
ldr r0,[r4,#0]
|
|
ldrb r1,[r0,#0]
|
|
mov r2,#0xDF
|
|
and r2,r1
|
|
strb r2,[r0,#0] //Do not redraw the window
|
|
mov r3,r0
|
|
mov r0,#1
|
|
mov r1,#2
|
|
mov r2,#4
|
|
bl print_blankstr_window_buffer //Clears PSI
|
|
mov r0,#1
|
|
mov r1,#4
|
|
mov r2,#4
|
|
ldr r3,[r4,#0]
|
|
bl print_blankstr_window_buffer //Clears Check
|
|
ldr r0,[r4,#0]
|
|
bl print_window_with_buffer //Print text in the window
|
|
bl store_pixels_overworld_options
|
|
|
|
@@end:
|
|
ldr r4,[sp,#4]
|
|
strb r4,[r5,#0] //Restore expected amount of lines to be written
|
|
add sp,#68
|
|
pop {r0-r5}
|
|
pop {pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Setup which only prints either "Talk to" and "Goods" in the main window.
|
|
b9040_special_string:
|
|
push {lr}
|
|
push {r0-r5}
|
|
add sp,#-76
|
|
ldr r5,=#0x3005078 //Make sure the game expects only the right amount of lines to be written (so only 1)
|
|
ldrb r4,[r5,#0]
|
|
str r4,[sp,#4]
|
|
mov r4,#0
|
|
strb r4,[r5,#0]
|
|
ldr r4,=#0x3005230 //Window generic address
|
|
|
|
//Main window
|
|
lsl r1,r0,#0x18
|
|
lsr r1,r1,#0x18
|
|
cmp r1,#0
|
|
bne @@end //Print only if there is an effective need to do so (So the routine before returned 0)
|
|
ldr r0,[r4,#0] //Main window place in ram
|
|
ldr r2,[r0,#4] //Save proper text_start and text_start2
|
|
str r2,[sp,#8]
|
|
ldr r2,[r0,#8]
|
|
str r2,[sp,#0xC]
|
|
ldrb r0,[r0,#0]
|
|
mov r2,#1
|
|
and r2,r0
|
|
cmp r2,#0
|
|
beq @@end //Check if window is enabled before printing in it
|
|
|
|
add r0,sp,#16
|
|
bl setupShortMainMenu_Talk_to_Goods //Get shortened menu string
|
|
mov r1,#0
|
|
str r1,[sp,#0]
|
|
add r1,sp,#16
|
|
ldr r0,[r4,#0]
|
|
mov r2,#5
|
|
mov r3,#2
|
|
bl 0x80BE4C8 //Let it do its things
|
|
ldr r0,[r4,#0]
|
|
bl print_window_with_buffer //Print text in the window
|
|
ldr r0,[r4,#0] //Restore text_start and text_start2
|
|
ldr r1,[sp,#8]
|
|
str r1,[r0,#4]
|
|
ldr r1,[sp,#0xC]
|
|
str r1,[r0,#8]
|
|
|
|
@@end:
|
|
ldr r4,[sp,#4]
|
|
strb r4,[r5,#0] //Restore expected amount of lines to be written
|
|
add sp,#76
|
|
pop {r0-r5}
|
|
lsl r0,r0,#0x18 //Clobbered code
|
|
lsr r0,r0,#0x18
|
|
pop {pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Makes it sure the outer PSI window of the PSI Overworld menu prints the PSIs only once
|
|
b8cd2_psi_window:
|
|
push {lr}
|
|
ldrb r1,[r0,#3] //Checks vwf_skip
|
|
mov r2,#1
|
|
and r2,r1
|
|
cmp r2,#1
|
|
beq @@do_not_print
|
|
mov r2,#1 //Goes on as usual and sets vwf_skip to true
|
|
orr r2,r1
|
|
strb r2,[r0,#3]
|
|
bl clearWindowTiles_buffer
|
|
pop {pc}
|
|
|
|
@@do_not_print: //Doesn't print in the PSI window
|
|
ldr r1,=#m2_active_window_pc
|
|
mov r2,#0
|
|
ldsh r1,[r1,r2]
|
|
push {r1} //Stores the active window pc
|
|
bl 0x80C3F28 //Input management function
|
|
pop {r1} //Restores the active window pc
|
|
cmp r0,#0 //Are we changing the window we're in? If this is 0, we're not
|
|
beq @@no_change_in_window
|
|
lsl r0,r0,#0x10 //If r0 is 0xFFFFFFFF, then we're exiting the window
|
|
lsr r5,r0,#0x10 //Set up r5 properly
|
|
b @@goToInner
|
|
|
|
@@no_change_in_window:
|
|
mov r5,#0
|
|
ldr r0,=#m2_active_window_pc
|
|
mov r2,#0
|
|
ldsh r0,[r0,r2] //Has the main character changed?
|
|
cmp r0,r1
|
|
beq @@keep
|
|
ldr r0,[r4,#0x1C] //If it has, set wvf_skip to false
|
|
mov r2,#0
|
|
strb r2,[r0,#3]
|
|
pop {r0}
|
|
add r0,#0xA
|
|
bx r0
|
|
|
|
@@goToInner:
|
|
ldr r0,[r4,#0x1C] //Stores false in vwf_skip, which means the window will be printed
|
|
mov r2,#0
|
|
strb r2,[r0,#3]
|
|
|
|
@@keep:
|
|
ldr r7,=#m2_active_window_pc //The game sets this up in the code we jump, so we need to set it up here
|
|
pop {r0}
|
|
add r0,#0x18
|
|
bx r0 //Jump to the next useful piece of code
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Makes it sure the outer PSI window of the PSI Status menu prints the PSIs only once
|
|
bacea_status_psi_window:
|
|
push {lr}
|
|
ldrh r2,[r0,#0x36]
|
|
push {r2} //Stores the cursor's Y position
|
|
bl 0x80BE53C //Input management function
|
|
push {r0} //Stores the input
|
|
ldr r0,[r5,#0x20] //Loads vwf_skip
|
|
ldrb r1,[r0,#3]
|
|
mov r2,#1
|
|
and r2,r1
|
|
cmp r2,#1 //Checks if true
|
|
beq @@do_not_print
|
|
mov r2,#1 //Sets vwf_skip to true and proceeds as usual
|
|
orr r2,r1
|
|
strb r2,[r0,#3]
|
|
pop {r0}
|
|
pop {r2}
|
|
pop {pc}
|
|
|
|
@@do_not_print:
|
|
pop {r0}
|
|
cmp r0,#0 //If the input is > 0, then we're entering one of the submenus (Offensive, Healing, etc.)
|
|
bgt @@goToInner
|
|
cmp r0,#0
|
|
beq @@noAction
|
|
lsl r0,r0,0x10 //If the input is 0xFFFFFFFF we're exiting the window. Sets r4 up and vwf_skip to false, then exits the routine.
|
|
asr r4,r0,0x10
|
|
ldr r0,[r5,#0x20]
|
|
mov r2,#0
|
|
strb r2,[r0,#3]
|
|
pop {r0}
|
|
pop {r0}
|
|
add r0,#4
|
|
bx r0
|
|
|
|
@@noAction:
|
|
mov r4,#0
|
|
pop {r1}
|
|
ldr r0,[r5,#0x20]
|
|
ldrh r2,[r0,#0x36]
|
|
cmp r1,r2 //Checks if the cursor's Y position is the same as it was before
|
|
beq @@noActionAtAll
|
|
mov r2,#0 //If it's not, then sets vwf_skip to false
|
|
strb r2,[r0,#3]
|
|
@@noActionAtAll:
|
|
b @@end //Goes to the end of the routine
|
|
|
|
@@goToInner:
|
|
lsl r0,r0,0x10 //Properly stores the output into r4 and, since we're going into the inner window, sets vwf_skip to false
|
|
asr r4,r0,0x10
|
|
ldr r0,[r5,#0x20]
|
|
mov r2,#0
|
|
strb r2,[r0,#3]
|
|
pop {r0}
|
|
|
|
@@end:
|
|
pop {r0}
|
|
add r0,#0x3E
|
|
bx r0 //Jump to the next useful piece of code
|
|
|
|
//==============================================================================
|
|
//Makes it sure the outer PSI window of the PSI battle menu prints the PSIs only once
|
|
//It's the same as the one above, but the bottom exit is different
|
|
e079a_battle_psi_window:
|
|
push {lr}
|
|
ldrh r2,[r0,#0x36]
|
|
push {r2} //Stores the cursor's Y position
|
|
bl 0x80BE53C //Input management function
|
|
push {r0} //Stores the input
|
|
ldr r0,[r5,#0x20] //Loads vwf_skip
|
|
ldrb r1,[r0,#3]
|
|
mov r2,#1
|
|
and r2,r1
|
|
cmp r2,#1 //Checks if true
|
|
beq @@do_not_print
|
|
mov r2,#1 //Sets vwf_skip to true and proceeds as usual
|
|
orr r2,r1
|
|
strb r2,[r0,#3]
|
|
pop {r0}
|
|
pop {r2}
|
|
pop {pc}
|
|
|
|
@@do_not_print:
|
|
pop {r0}
|
|
cmp r0,#0 //If the input is > 0, then we're entering one of the submenus (Offensive, Healing, etc.)
|
|
bgt @@goToInner
|
|
cmp r0,#0
|
|
beq @@noAction
|
|
lsl r0,r0,0x10 //If the input is 0xFFFFFFFF we're exiting the window. Sets r4 up and vwf_skip to false, then exits the routine.
|
|
asr r4,r0,0x10
|
|
ldr r0,[r5,#0x20]
|
|
mov r2,#0
|
|
strb r2,[r0,#3]
|
|
pop {r0}
|
|
pop {r0}
|
|
add r0,#4
|
|
bx r0
|
|
|
|
@@noAction:
|
|
mov r4,#0
|
|
pop {r1}
|
|
ldr r0,[r5,#0x20]
|
|
ldrh r2,[r0,#0x36]
|
|
cmp r1,r2 //Checks if the cursor's Y position is the same as it was before
|
|
beq @@noActionAtAll
|
|
mov r2,#0 //If it's not, then sets vwf_skip to false
|
|
strb r2,[r0,#3]
|
|
@@noActionAtAll:
|
|
b @@end //Goes to the end of the routine
|
|
|
|
@@goToInner:
|
|
lsl r0,r0,0x10 //Properly stores the output into r4 and, since we're going into the inner window, sets vwf_skip to false
|
|
asr r4,r0,0x10
|
|
ldr r0,[r5,#0x20]
|
|
mov r2,#0
|
|
strb r2,[r0,#3]
|
|
pop {r0}
|
|
|
|
@@end:
|
|
pop {r0}
|
|
add r0,#0x36
|
|
bx r0 //Jump to the next useful piece of code
|
|
|
|
//==============================================================================
|
|
//Makes it sure the inner PSI window of the PSI status menu prints the descriptions only once
|
|
//It also sets things up to make it so the target window is only printed once
|
|
badb0_status_inner_window:
|
|
push {lr}
|
|
ldrh r1,[r0,#0x36] //Stores the cursor's Y of the window
|
|
push {r1}
|
|
ldrh r1,[r0,#0x34] //Stores the cursor's X of the window
|
|
push {r1}
|
|
bl PSITargetWindowInput //Input management, target printing and header printing function. Now the function takes the cursor's Y and X as arguments too in the stack
|
|
lsl r0,r0,#0x10
|
|
lsr r4,r0,#0x10 //Properly stores the output into r4
|
|
|
|
ldr r1,=#0x8B2A9B0 //Clobbered code
|
|
ldr r0,[r5,#0x1C]
|
|
add r0,#0x42
|
|
ldrb r0,[r0,#0]
|
|
lsl r0,r0,#4
|
|
add r1,#0xC
|
|
add r0,r0,r1
|
|
ldr r2,[r0,#0]
|
|
|
|
ldr r0,[r5,#0x1C]
|
|
ldrh r1,[r0,#0x34]
|
|
ldr r3,[sp,#0]
|
|
cmp r1,r3 //Checks if the cursor's X changed
|
|
bne @@ChangedPosition
|
|
ldr r3,[sp,#4] //If it did not, checks if the cursor's Y changed
|
|
ldrh r1,[r0,#0x36]
|
|
cmp r1,r3
|
|
beq @@print
|
|
|
|
@@ChangedPosition:
|
|
ldr r0,[r5,0x28] //Sets wvf_skip to false
|
|
mov r1,#0
|
|
strb r1,[r0,#3]
|
|
|
|
@@print: //Description printing
|
|
ldr r0,[r5,0x28]
|
|
ldrb r1,[r0,#3]
|
|
mov r3,#1
|
|
and r1,r3
|
|
cmp r1,#0 //Checks if vwf_skip is false
|
|
bne @@end
|
|
mov r1,r2 //If it is, prints the PSI description
|
|
mov r2,0
|
|
bl initWindow_buffer //Initializes the PSI description window
|
|
ldr r0,[r5,0x28]
|
|
bl print_window_with_buffer //Prints the PSI description window
|
|
bl store_pixels_overworld
|
|
ldr r0,[r5,0x28]
|
|
ldrb r1,[r0,#3] //Sets vwf_skip to true
|
|
mov r3,#1
|
|
orr r1,r3
|
|
strb r1,[r0,#3]
|
|
|
|
@@end:
|
|
ldr r0,=#0xFFFF //Are we exiting this window?
|
|
cmp r4,r0
|
|
bne @@ending
|
|
|
|
//If we are, set vwf_skip to false for both the description window and the target window
|
|
ldr r0,[r5,0x28] //Description window
|
|
mov r2,#0
|
|
strb r2,[r0,#3]
|
|
ldr r0,[r5,0x24] //Target window
|
|
strb r2,[r0,#3]
|
|
|
|
@@ending:
|
|
pop {r0}
|
|
pop {r0}
|
|
pop {r0}
|
|
add r0,#0x18
|
|
bx r0 //Jump to the next useful piece of code
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Stores the buffer for the Stored Goods window when switching the page
|
|
c6ac0_store_buffer_stored_goods_switch_page:
|
|
mov r0,#8
|
|
str r0,[sp,#0x2C]
|
|
push {lr}
|
|
bl store_pixels_overworld
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Calls print_window_with_buffer and then stores the buffer
|
|
baf9c_print_window_store_buffer:
|
|
push {lr}
|
|
bl print_window_with_buffer
|
|
bl store_pixels_overworld
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Calls print_window_with_buffer and then stores the buffer if need be
|
|
baf9c_print_window_store_buffer_needed:
|
|
push {lr}
|
|
add sp,#-4
|
|
mov r1,#0x44
|
|
add r1,r1,r0
|
|
ldrb r1,[r1,#0]
|
|
str r1,[sp,#0]
|
|
bl print_window_with_buffer
|
|
ldr r1,[sp,#0]
|
|
cmp r1,#0
|
|
beq @@end
|
|
bl store_pixels_overworld_use
|
|
@@end:
|
|
add sp,#4
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Calls print_window_with_buffer and then stores the buffer if need be - Special edition which does only a few tiles
|
|
b98b8_print_window_store_buffer_needed:
|
|
push {lr}
|
|
add sp,#-4
|
|
mov r1,#0x44
|
|
add r1,r1,r0
|
|
ldrb r1,[r1,#0]
|
|
str r1,[sp,#0]
|
|
bl print_window_with_buffer
|
|
ldr r1,[sp,#0]
|
|
cmp r1,#0
|
|
beq @@end
|
|
mov r0,#4
|
|
bl store_pixels_overworld_buffer_totalTiles
|
|
@@end:
|
|
add sp,#4
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Calls print_window_with_buffer and then stores the buffer
|
|
baf9c_print_window_store_buffer_top:
|
|
push {lr}
|
|
bl print_window_with_buffer
|
|
bl store_pixels_overworld_top
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Calls printstr_hlight_buffer and then stores the buffer
|
|
c5f80_printstr_hlight_buffer_store_buffer:
|
|
push {r4,lr}
|
|
ldr r4,[sp,#8]
|
|
add sp,#-4
|
|
str r4,[sp,#0]
|
|
bl printstr_hlight_buffer
|
|
bl store_pixels_overworld
|
|
add sp,#4
|
|
pop {r4,pc}
|
|
|
|
//==============================================================================
|
|
//Fixes issue with sounds when going from the PSI window to the inner PSI window
|
|
b8d40_psi_going_inner_window:
|
|
push {lr}
|
|
bl PSITargetWindowInput
|
|
bl store_pixels_overworld
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//It sets things up to make it so the target window is only printed once
|
|
b8db4_psi_inner_window:
|
|
push {r4,lr}
|
|
mov r4,r0
|
|
ldrb r1,[r4,#3]
|
|
push {r1}
|
|
ldrh r1,[r4,#0x36] //Stores the cursor's Y of the window
|
|
push {r1}
|
|
ldrh r1,[r4,#0x34] //Stores the cursor's X of the window
|
|
push {r1}
|
|
bl PSITargetWindowInput //Input management, target printing and header printing function. Now the function takes the cursor's Y and X as arguments too in the stack
|
|
pop {r2}
|
|
ldrh r1,[r4,#0x34] //Stores the cursor's X of the window
|
|
cmp r1,r2
|
|
bne @@store_buffer_first
|
|
pop {r2}
|
|
ldrh r1,[r4,#0x36] //Stores the cursor's Y of the window
|
|
cmp r1,r2
|
|
bne @@store_buffer_second
|
|
pop {r2}
|
|
mov r1,#1
|
|
and r1,r2
|
|
cmp r1,#1
|
|
beq @@continue
|
|
b @@store_buffer
|
|
|
|
@@store_buffer_first:
|
|
pop {r2}
|
|
@@store_buffer_second:
|
|
pop {r2}
|
|
@@store_buffer:
|
|
cmp r0,#0
|
|
bne @@continue
|
|
bl store_pixels_overworld
|
|
|
|
@@continue:
|
|
cmp r0,#0
|
|
beq @@ending
|
|
|
|
mov r2,#0 //Sets vwf_skip to false since the window is changed
|
|
strb r2,[r4,#3]
|
|
|
|
@@ending:
|
|
pop {r4,pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//It sets things up to make it so the target window is only printed once
|
|
e0854_psi_inner_window_battle:
|
|
push {r4,lr}
|
|
mov r4,r0
|
|
ldrb r1,[r4,#3]
|
|
push {r1}
|
|
ldrh r1,[r4,#0x36] //Stores the cursor's Y of the window
|
|
push {r1}
|
|
ldrh r1,[r4,#0x34] //Stores the cursor's X of the window
|
|
push {r1}
|
|
bl PSITargetWindowInput //Input management, target printing and header printing function. Now the function takes the cursor's Y and X as arguments too in the stack
|
|
pop {r2}
|
|
ldrh r1,[r4,#0x34] //Stores the cursor's X of the window
|
|
cmp r1,r2
|
|
bne @@store_buffer_first
|
|
pop {r2}
|
|
ldrh r1,[r4,#0x36] //Stores the cursor's Y of the window
|
|
cmp r1,r2
|
|
bne @@store_buffer_second
|
|
pop {r2}
|
|
mov r1,#1
|
|
and r1,r2
|
|
cmp r1,#1
|
|
beq @@continue
|
|
b @@store_buffer
|
|
|
|
@@store_buffer_first:
|
|
pop {r2}
|
|
@@store_buffer_second:
|
|
pop {r2}
|
|
@@store_buffer:
|
|
cmp r0,#0
|
|
bne @@continue
|
|
bl store_pixels_overworld_psi_window
|
|
|
|
@@continue:
|
|
cmp r0,#0
|
|
beq @@ending
|
|
|
|
mov r2,#0 //Sets vwf_skip to false since the window is changed
|
|
strb r2,[r4,#3]
|
|
|
|
@@ending:
|
|
pop {r4,pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Reverses the order in which the target window and the psi window are printed
|
|
//when the "Not enough PP!" message goes away in battle in order to make it so
|
|
//the graphics are properly stored.
|
|
e0b34_psi_not_enough_pp_reverse_windows:
|
|
push {lr}
|
|
ldr r0,[r4,#0x24] //Initializes the target window
|
|
mov r1,#0
|
|
mov r2,#0
|
|
bl initWindow_buffer
|
|
ldr r0,[r4,#0x1C] //Target window printing
|
|
bl 0x80C438C
|
|
|
|
ldr r0,[r4,#0x20] //PSI window printing, grab the type from the types menu
|
|
ldrh r0,[r0,#0x36]
|
|
add r0,#1
|
|
lsl r0,r0,#0x10
|
|
asr r0,r0,#0x10
|
|
bl 0x80BAE98 //Do the printing
|
|
|
|
pop {pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
_4092_print_window:
|
|
push {lr}
|
|
push {r0-r4}
|
|
bl print_windows
|
|
pop {r0-r4}
|
|
bl 0x800341C
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
_4294_print_window_store:
|
|
push {lr}
|
|
push {r0-r4}
|
|
ldr r2,[sp,#0x20]
|
|
bl print_windows
|
|
bl store_pixels
|
|
pop {r0-r4}
|
|
mov r2,#0
|
|
mov r3,#0
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
c7ea2_shop_clear:
|
|
push {lr}
|
|
bl m2_store_to_win_memory
|
|
ldr r0,=#0x3005230 //Window generic address
|
|
ldr r0,[r0,#8] //Load the dialogue window
|
|
bl clear_window
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//X cursor for the Options submenu position
|
|
_position_X_Options:
|
|
push {lr}
|
|
|
|
cmp r0,#1
|
|
bne @@next1
|
|
mov r0,#5
|
|
b @@end
|
|
@@next1:
|
|
cmp r0,#6
|
|
bne @@next2
|
|
mov r0,#11
|
|
b @@end
|
|
@@next2:
|
|
cmp r0,#11
|
|
bne @@next3
|
|
mov r0,#15
|
|
b @@end
|
|
@@next3:
|
|
mov r0,#20
|
|
|
|
@@end:
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Sets X for highlighting the Options submenu in the File Select window
|
|
_40e2_cursor_X:
|
|
push {lr}
|
|
mov r0,r1
|
|
bl _position_X_Options
|
|
sub r1,r0,#3
|
|
mov r0,#2
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Sets X cursor for the Options submenu in the File Select window
|
|
_41d4_cursor_X:
|
|
push {lr}
|
|
bl _position_X_Options
|
|
lsl r0,r0,#3
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Makes sure Paula's window is loaded properly since the name length has been changed to 5 and the game previously used the 4 to load the window too
|
|
_4f7c_window_selector:
|
|
push {lr}
|
|
mov r0,#4
|
|
mov r10,r0
|
|
ldr r1,=#0x82B7FF8
|
|
pop {pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Prints and stores the PSI window in the PSI menu
|
|
baec6_psi_window_print_buffer:
|
|
push {lr}
|
|
bl psiWindow_buffer
|
|
bl store_pixels_overworld
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Loads the buffer in if entering another window from the main window
|
|
b7d9a_main_window_manage_input:
|
|
push {lr}
|
|
bl 0x80BE53C
|
|
cmp r0,#0
|
|
beq @@end
|
|
cmp r0,#0
|
|
blt @@end
|
|
bl load_pixels_overworld
|
|
push {r0-r2}
|
|
swi #5
|
|
pop {r0-r2}
|
|
|
|
@@end:
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Prints the target window if and only if the cursor's position changed in this input management function
|
|
c495a_status_target:
|
|
push {r4,lr}
|
|
ldr r1,=#0x3005230
|
|
ldr r4,[r1,#0x24] //Loads the target window
|
|
ldr r3,[sp,#0x30]
|
|
ldrh r2,[r5,#0x34]
|
|
cmp r2,r3 //Has the cursor's X changed?
|
|
bne @@Updated
|
|
ldr r3,[sp,#0x34] //If not, has the cursor's Y changed?
|
|
ldrh r2,[r5,#0x36]
|
|
cmp r2,r3
|
|
beq @@printing
|
|
|
|
@@Updated:
|
|
mov r2,#0 //If the cursor's position changed, set vwf_skip to false
|
|
strb r2,[r4,#3]
|
|
|
|
@@printing:
|
|
ldrb r1,[r4,#0x3]
|
|
mov r2,#1
|
|
and r2,r1
|
|
cmp r2,#0 //Checks if vwf_skip is false
|
|
bne @@end
|
|
ldrb r1,[r4,#0x3] //If it is, sets vwf_skip to true, clears the window and updates the target window
|
|
mov r2,#1
|
|
orr r2,r1
|
|
strb r2,[r4,#0x3]
|
|
push {r0}
|
|
bl check_overworld_buffer
|
|
ldr r1,=#buffer_subtractor
|
|
sub r1,r0,r1
|
|
mov r0,r4
|
|
pop {r4}
|
|
bl clear_window_buffer
|
|
mov r0,r4
|
|
bl psiTargetWindow_buffer
|
|
|
|
@@end:
|
|
pop {r4,pc}
|
|
|
|
//==============================================================================
|
|
//Makes sure m2_initwindow properly sets vwf_skip to false
|
|
be45a_set_proper_wvf_skip:
|
|
push {lr}
|
|
mov r3,r0
|
|
mov r0,#0
|
|
strb r0,[r3,#3]
|
|
pop {pc}
|
|
|
|
|
|
//==============================================================================
|
|
//Makes sure this initialization routine properly sets vwf_skip to false. This fixes an issue where due to a background the Goods window in battle might have not be printed
|
|
be4ca_set_proper_wvf_skip_goods_battle_window:
|
|
push {lr}
|
|
mov r4,#0
|
|
strb r4,[r0,#3]
|
|
|
|
mov r12,r0 //Clobbered code
|
|
mov r4,r1
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Makes sure the window type is set to 0 for the inner PSI overworld menu window. Fixes an issue in M2GBA.
|
|
b8c2a_set_proper_wvf_skip_and_window_type:
|
|
push {lr}
|
|
strb r1,[r0,#1]
|
|
bl initWindow_buffer
|
|
pop {pc}
|
|
|
|
|
|
//==============================================================================
|
|
//Fix the random garbage issue for the alphabet for good
|
|
_2322_setup_windowing:
|
|
push {lr}
|
|
bl 0x8012460 //Default code which sets up the names by copying memory which can be random
|
|
push {r0-r1}
|
|
ldr r0,=#m2_cstm_last_printed //Set the window flag to 0 so no issue can happen
|
|
mov r1,#0
|
|
strb r1,[r0,#0]
|
|
pop {r0-r1}
|
|
pop {pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Loads the vram into the buffer, it's called each time there is only the main file_select window active (a good way to set the whole thing up)
|
|
_38c0_load_pixels:
|
|
push {lr}
|
|
ldr r3,=#0x40000B0 //DMA transfer 0
|
|
ldr r0,=#0x6008000 //Source
|
|
str r0,[r3]
|
|
ldr r0,=#0x2015000 //Target
|
|
str r0,[r3,#4]
|
|
ldr r0,=#0x84001200 //Store 0x4800 bytes
|
|
str r0,[r3,#8]
|
|
ldr r0,[r3,#8]
|
|
ldr r3,[r5,#0]
|
|
mov r0,#0x84
|
|
lsl r0,r0,#2
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Stores the buffer into the vram. This avoids screen tearing.
|
|
store_pixels:
|
|
push {r0-r1,lr}
|
|
ldr r1,=#0x40000B0 //DMA transfer 0
|
|
ldr r0,=#0x2015000 //Source
|
|
str r0,[r1]
|
|
ldr r0,=#0x6008000 //Target
|
|
str r0,[r1,#4]
|
|
ldr r0,=#0x94001200 //Store 0x4800 bytes
|
|
str r0,[r1,#8]
|
|
ldr r0,[r1,#8]
|
|
pop {r0-r1,pc}
|
|
|
|
//==============================================================================
|
|
//Specific routine which calls store_pixels for the main file_select window
|
|
_38f8_store_pixels:
|
|
push {lr}
|
|
bl store_pixels
|
|
ldr r1,[r5,#0]
|
|
mov r3,#0xC
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Generic routine which prints a window and then stores the pixels of all the other windows. It's called once, after all the other windows (which will use _4092_print_window) have printed.
|
|
_4092_print_window_store:
|
|
push {lr}
|
|
bl _4092_print_window
|
|
bl store_pixels
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Routine for the top part of the screen only. Used in order to make printing the names less CPU intensive when naming the characters
|
|
_4edc_print_window_store:
|
|
push {lr}
|
|
bl _4092_print_window
|
|
push {r0-r1}
|
|
ldr r1,=#0x40000B0 //DMA transfer 0
|
|
ldr r0,=#0x2015000 //Source
|
|
str r0,[r1]
|
|
ldr r0,=#0x6008000 //Target
|
|
str r0,[r1,#4]
|
|
ldr r0,=#0x94000200 //Store 0x800 bytes
|
|
str r0,[r1,#8]
|
|
ldr r0,[r1,#8]
|
|
pop {r0-r1}
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Loads and prints the text lines for the file select main window
|
|
_setup_file_strings:
|
|
push {r4-r5,lr}
|
|
add sp,#-8
|
|
ldr r5,=#0x3000024
|
|
ldr r2,[r5,#0]
|
|
ldr r4,[r2,#4]
|
|
str r4,[sp,#4] //Save this here
|
|
mov r4,#0
|
|
str r4,[r2,#4]
|
|
mov r0,#0
|
|
bl 0x8002170 //Routine which loads the save corresponding to r0
|
|
mov r0,#1
|
|
bl 0x8002170
|
|
mov r0,#2
|
|
bl 0x8002170
|
|
ldr r3,[r5,#0]
|
|
mov r0,#0x84
|
|
lsl r0,r0,#2
|
|
add r3,r3,r0
|
|
str r4,[sp,#0]
|
|
mov r0,#2
|
|
mov r1,#1
|
|
mov r2,#0x40
|
|
bl wrapper_file_string_selection
|
|
ldr r3,[r5,#0]
|
|
ldr r0,=#0x454
|
|
add r3,r3,r0
|
|
str r4,[sp,#0]
|
|
mov r0,#2
|
|
mov r1,#3
|
|
mov r2,#0x40
|
|
bl wrapper_file_string_selection
|
|
ldr r3,[r5,#0]
|
|
mov r0,#0xD3
|
|
lsl r0,r0,#3
|
|
add r3,r3,r0
|
|
str r4,[sp,#0]
|
|
mov r0,#2
|
|
mov r1,#5
|
|
mov r2,#0x40
|
|
bl wrapper_file_string_selection
|
|
mov r0,#1
|
|
mov r1,#0
|
|
mov r2,#0
|
|
bl 0x800341C
|
|
ldr r2,[r5,#0]
|
|
ldr r4,[sp,#4]
|
|
str r4,[r2,#4] //Restore this
|
|
add sp,#8
|
|
pop {r4-r5,pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Prints a digit to the dialogue window
|
|
d37ec_print_number:
|
|
push {lr}
|
|
bl decode_character
|
|
mov r1,r5
|
|
bl print_character_to_window
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Makes it sure the outer equip menu prints the window only when needed
|
|
baf60_outer_equip_setup:
|
|
push {lr}
|
|
ldr r1,=#m2_active_window_pc
|
|
ldrb r1,[r1,#0]
|
|
push {r1} //Stores the active_window_pc
|
|
bl equipReadInput //Input management function
|
|
pop {r1}
|
|
cmp r0,#0 //Has an action happened? (Are we entering/exiting the menu?)
|
|
beq @@check_character_change
|
|
|
|
ldr r1,[r6,#0x18] //Main equip window - If it has, then set vwf_skip to false for both the equipment numbers window and the main equipment window
|
|
mov r2,#0
|
|
strb r2,[r1,#3]
|
|
ldr r1,[r6,#0x14] //Offense and Defense window
|
|
strb r2,[r1,#3]
|
|
b @@end
|
|
|
|
@@check_character_change:
|
|
ldr r2,=#m2_active_window_pc
|
|
ldrb r2,[r2,#0] //Has the character changed?
|
|
cmp r2,r1
|
|
beq @@end
|
|
ldr r1,[r6,#0x14] //Offense and Defense window - If it has, then set vwf_skip to false for the equipment numbers window
|
|
mov r2,#0
|
|
strb r2,[r1,#3]
|
|
|
|
@@end:
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Prints the outer equip window only when needed - makes it so 0x80C4EB0 takes the previous m2_active_window_pc as a function parameter
|
|
c518e_outer_equip:
|
|
push {lr}
|
|
ldr r1,[sp,#0x1C]
|
|
lsl r1,r1,#0x18
|
|
lsr r1,r1,#0x18
|
|
ldr r2,=#m2_active_window_pc
|
|
ldrb r2,[r2,#0]
|
|
cmp r1,r2 //Has the active_window_pc changed?
|
|
beq @@printing
|
|
mov r2,#0 //If it has, then reprint the window
|
|
strb r2,[r0,#3]
|
|
|
|
@@printing:
|
|
ldrb r1,[r0,#3]
|
|
mov r2,#1
|
|
and r2,r1
|
|
cmp r2,#1
|
|
beq @@skip //Check if vwf_skip is false
|
|
|
|
mov r2,#1 //If it is, print and set it to true
|
|
orr r2,r1
|
|
strb r2,[r0,#3]
|
|
bl 0x80C4B2C //Prints the equip menu
|
|
|
|
@@skip:
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Prints the numbers in the offense/defense window for the outer equip window only when needed
|
|
bafc8_outer_equip_attack_defense:
|
|
push {lr}
|
|
ldr r1,[r6,#0x14] //Offense and Defense window
|
|
ldrb r2,[r1,#3]
|
|
mov r3,#1
|
|
and r3,r2
|
|
cmp r3,#1 //Is vwf_skip false?
|
|
beq @@skip
|
|
cmp r5,#0 //If it is, then print, but only if no action was performed
|
|
bne @@skip
|
|
|
|
mov r3,#1 //Set vwf_skip to true and continue as usual
|
|
orr r3,r2
|
|
strb r3,[r1,#3]
|
|
lsl r0,r0,#0x18 //Clobbered code
|
|
lsr r0,r0,#0x18
|
|
pop {pc}
|
|
|
|
@@skip:
|
|
mov r5,r7
|
|
add r5,#0x12 //Setup r5 just like the code skipped does
|
|
pop {r0}
|
|
mov r1,#0xF1
|
|
lsl r1,r1,#1
|
|
add r0,r0,r1 //Jump to 0x80BB1AE
|
|
bx r0
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Prints defense number and then sotres the buffer
|
|
bb1aa_printnumberequip_store:
|
|
push {r4,lr}
|
|
mov r4,r3
|
|
mov r3,#0
|
|
push {r3}
|
|
mov r3,r4
|
|
bl printNumberEquip
|
|
bl store_pixels_overworld
|
|
pop {r3}
|
|
pop {r4,pc}
|
|
|
|
//==============================================================================
|
|
//Prints blankstr in the buffer
|
|
bb21c_print_blankstr_buffer:
|
|
push {lr}
|
|
push {r0-r2}
|
|
bl check_overworld_buffer
|
|
ldr r3,=#buffer_subtractor
|
|
sub r3,r0,r3
|
|
pop {r0-r2}
|
|
bl print_blankstr_buffer
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Prints blankstr in the buffer and stores it
|
|
bb21c_print_blankstr_buffer_store:
|
|
push {lr}
|
|
push {r0-r2}
|
|
bl check_overworld_buffer
|
|
ldr r3,=#buffer_subtractor
|
|
sub r3,r0,r3
|
|
pop {r0-r2}
|
|
bl print_blankstr_buffer
|
|
bl store_pixels_overworld
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Set things up so the numbers for Offense and Defense for the innermost equipment window is only printed when needed
|
|
bb990_inner_equip_attack_defense_setup:
|
|
push {lr}
|
|
ldr r1,=#0x3005200
|
|
ldr r1,[r1,#0xC] //Window's item list
|
|
mov r2,#0x36
|
|
ldsh r2,[r0,r2] //Window's Y cursor
|
|
add r1,r1,r2
|
|
ldrb r1,[r1,#0] //Selected item
|
|
push {r1}
|
|
bl equippableReadInput //Input management function - returns the currently selected item
|
|
pop {r1}
|
|
cmp r1,r0 //Has the currently selected item changed?
|
|
bne @@refresh
|
|
|
|
ldr r1,=#0x3005230 //If not, check if A has been pressed
|
|
ldr r1,[r1,#0x10]
|
|
ldr r2,=#0xFFFF
|
|
ldrh r3,[r1,#0x32] //If A has been pressed this becomes 0xFFFF
|
|
cmp r2,r3
|
|
bne @@end
|
|
|
|
@@refresh:
|
|
ldr r1,=#0x3005230 //Set wvf_skip to false
|
|
ldr r1,[r1,#0x14]
|
|
mov r2,#0
|
|
strb r2,[r1,#3]
|
|
|
|
@@end:
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Prints the numbers for Offense and Defense for the innermost window only if needed - Valid weapons
|
|
bb6b2_inner_equip_attack_defense_weapon:
|
|
push {lr}
|
|
mov r1,r9
|
|
ldr r1,[r1,#0x14]
|
|
ldrb r0,[r1,#3]
|
|
mov r2,#1
|
|
and r2,r0
|
|
cmp r2,#1 //Is vwf_skip false?
|
|
beq @@skip
|
|
|
|
mov r2,#1 //If it is, set vwf_skip to true, clear the numbers' space and proceed normally
|
|
orr r2,r0
|
|
strb r2,[r1,#3]
|
|
bl clear_offense_defense_inner_equip
|
|
mov r1,r8
|
|
mov r2,#0
|
|
pop {pc}
|
|
|
|
@@skip:
|
|
mov r5,r7 //Otherwise skip some code
|
|
add r5,#0x12
|
|
mov r4,#0
|
|
pop {r0}
|
|
add r0,#0x62 //Go to 0x80BB718
|
|
bx r0
|
|
|
|
//==============================================================================
|
|
//Prints the numbers for Offense and Defense for the innermost window only if needed - None in weapons
|
|
bb64e_inner_equip_attack_defense_none_weapon:
|
|
push {lr}
|
|
mov r1,r9
|
|
ldr r1,[r1,#0x14]
|
|
ldrb r0,[r1,#3]
|
|
mov r2,#1
|
|
and r2,r0
|
|
cmp r2,#1 //Is vwf_skip false?
|
|
beq @@skip
|
|
|
|
mov r2,#1 //If it is, set vwf_skip to true, clear the numbers' space and proceed normally
|
|
orr r2,r0
|
|
strb r2,[r1,#3]
|
|
bl clear_offense_defense_inner_equip
|
|
mov r3,r8 //This is where this differs from the routine above
|
|
mov r1,#0
|
|
pop {pc}
|
|
|
|
@@skip:
|
|
mov r5,r7 //Otherwise skip some code
|
|
add r5,#0x12
|
|
mov r4,#0
|
|
pop {r0}
|
|
add r0,#0xC6 //Go to 0x80BB718 - The routine differs here too
|
|
bx r0
|
|
|
|
//==============================================================================
|
|
//Prints the numbers for Offense and Defense for the innermost window only if needed - Defensive equipment
|
|
bbe7c_inner_equip_attack_defense_defensive_equipment:
|
|
push {lr}
|
|
ldr r1,=#0x3005230
|
|
ldr r1,[r1,#0x14]
|
|
ldrb r0,[r1,#3]
|
|
mov r2,#1
|
|
and r2,r0
|
|
cmp r2,#1 //Is vwf_skip false?
|
|
beq @@skip
|
|
|
|
mov r2,#1 //If it is, set vwf_skip to true, clear the numbers' space and proceed normally
|
|
orr r2,r0
|
|
strb r2,[r1,#3]
|
|
bl clear_offense_defense_inner_equip
|
|
mov r4,#0
|
|
strb r4,[r7,#0x15]
|
|
pop {pc}
|
|
|
|
@@skip:
|
|
pop {r0} //Otherwise go to the routine's end
|
|
ldr r0,=#0x80BBEC7 //End of routine
|
|
bx r0
|
|
|
|
//==============================================================================
|
|
//Clears the rightmost part of the Offense/Defense window for the innermost equipment menu
|
|
clear_offense_defense_inner_equip:
|
|
push {lr}
|
|
mov r0,0xD
|
|
mov r1,0xB
|
|
mov r2,0x3
|
|
bl bb21c_print_blankstr_buffer
|
|
mov r0,0xD
|
|
mov r1,0xD
|
|
mov r2,0x3
|
|
bl bb21c_print_blankstr_buffer
|
|
pop {pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Fixes issue with file select menu not printing after going back to it from the alphabet
|
|
_53f6_fix_out_of_description:
|
|
push {lr}
|
|
bl 0x800341C
|
|
bl _setup_file_strings
|
|
mov r0,#3
|
|
mov r1,#0xA
|
|
mov r2,#1
|
|
bl _4092_print_window //Prints the text speed menu
|
|
mov r0,#0xF
|
|
mov r1,#4
|
|
mov r2,#2
|
|
bl _4092_print_window //Prints the text flavour menu
|
|
bl store_pixels
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Fixes issue with the option submenu (if it's there) and the file select menu after going back to the text speed window from the text flavour window
|
|
_3dce_fix_out_of_text_flavour:
|
|
push {lr}
|
|
bl 0x8003F44
|
|
mov r0,#0
|
|
ldsh r0,[r5,r0] //Checks whether or not to print the option menu
|
|
cmp r0,#0
|
|
blt @@end
|
|
|
|
mov r0,#4
|
|
mov r1,#7
|
|
mov r2,#0xE
|
|
bl _4092_print_window //Prints the option menu
|
|
|
|
@@end:
|
|
bl _setup_file_strings
|
|
bl store_pixels
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Fixes text reprinting when pressing up or down in the text flavour window
|
|
_3e86_special_setup:
|
|
push {lr}
|
|
push {r0-r2}
|
|
ldr r0,=#m2_cstm_last_printed
|
|
ldrb r2,[r0,#0]
|
|
mov r1,#0x80
|
|
orr r1,r2
|
|
strb r1,[r0,#0]
|
|
pop {r0-r2}
|
|
bl 0x8003F44
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Highlights all of the file string with the proper palette
|
|
_highlight_file:
|
|
push {lr}
|
|
mov r0,#2
|
|
ldr r1,=#0x3000024 //Load in r1 the y co-ordinate
|
|
ldr r1,[r1,#0]
|
|
ldr r1,[r1,#8]
|
|
lsl r1,r1,#1
|
|
add r1,#1
|
|
mov r2,#0
|
|
mov r3,r4
|
|
bl setPaletteOnFile
|
|
pop {pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//File highlighting for the up-down arrows in the text flavour window
|
|
_3f78_highlight_file:
|
|
push {lr}
|
|
bl _highlight_file
|
|
mov r0,#4 //Clobbered code
|
|
ldsh r2,[r4,r0]
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//File highlighting for when a file is selected
|
|
_3a04_highlight_file:
|
|
push {lr}
|
|
bl _highlight_file
|
|
mov r0,#1 //Clobbered code
|
|
mov r1,#0
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//A Press
|
|
c75b4_overworld_naming_top_printing:
|
|
push {lr}
|
|
ldr r0,=#m2_player1
|
|
mov r1,r2
|
|
str r3,[sp,#0x24]
|
|
bl player_name_printing_registration
|
|
bl store_pixels_overworld_player_naming
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//B Press
|
|
c780e_overworld_naming_top_printing:
|
|
push {lr}
|
|
ldr r1,=#0x3005230
|
|
ldr r1,[r1,#0x0C]
|
|
ldr r0,=#m2_player1
|
|
bl player_name_printing_registration
|
|
bl store_pixels_overworld_player_naming
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Backspace
|
|
c74cc_overworld_naming_top_printing:
|
|
push {lr}
|
|
ldr r1,=#0x3005230
|
|
ldr r1,[r1,#0x0C]
|
|
ldr r0,=#m2_player1
|
|
bl player_name_printing_registration
|
|
bl store_pixels_overworld_player_naming
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Re-enter the menu
|
|
c6cc6_overworld_naming_top_printing:
|
|
push {lr}
|
|
mov r2,r0
|
|
mov r0,r1
|
|
mov r1,r2
|
|
bl player_name_printing_registration
|
|
str r0,[sp,#0x24]
|
|
mov r9,r0
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Cursor movement of overworld alphabet
|
|
c6f24_overworld_alphabet_movement:
|
|
push {lr}
|
|
mov r0,r7
|
|
ldr r1,=#0x3002500
|
|
add r1,#0x18
|
|
bl setupCursorMovement_Overworld_Alphabet
|
|
mov r9,r0
|
|
ldr r2,=#0x3002500
|
|
pop {pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Generic alphabet printing routine. Uses the default code. r0 is the alphabet and r1 is the alphabet string to print if need be
|
|
print_alphabet_if_needed:
|
|
push {lr}
|
|
ldr r2,[sp,#0x2C]
|
|
cmp r2,r0 //Is the alphabet loaded different from the one we're going in?
|
|
beq @@end
|
|
|
|
str r0,[sp,#0x2C] //If it is, print the new alphabet
|
|
ldr r5,=#0x3005230 //Default printing code
|
|
ldr r4,[r5,#0x10] //Window
|
|
mov r2,r1 //String to load
|
|
ldr r0,=#0x8B17EE4 //String
|
|
ldr r1,=#0x8B17424
|
|
bl m2_strlookup
|
|
mov r1,r0
|
|
mov r0,r4
|
|
mov r2,#0
|
|
bl initWindow_buffer
|
|
ldr r0,[r5,#0x10]
|
|
bl print_alphabet_buffer //Print alphabet in buffer
|
|
bl store_pixels_overworld
|
|
|
|
@@end:
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Prints the first alphabet and stores the buffer
|
|
c6d78_print_slphabet_store:
|
|
push {lr}
|
|
bl print_alphabet_buffer
|
|
bl store_pixels_overworld
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Loads stuff up for the small alphabet and calls print_alphabet_if_needed
|
|
c73c0_small_overworld_alphabet:
|
|
push {lr}
|
|
mov r0,#1 //Alphabet 1, small
|
|
mov r1,#0x62 //String 0x62, small alphabet
|
|
bl print_alphabet_if_needed
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Loads stuff up for the CAPITAL alphabet and calls print_alphabet_if_needed
|
|
c7394_CAPITAL_overworld_alphabet:
|
|
push {lr}
|
|
mov r0,#0 //Alphabet 0, CAPITAL
|
|
mov r1,#0x63 //String 0x63, CAPITAL alphabet
|
|
bl print_alphabet_if_needed
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Loads the proper letter table based on the loaded alphabet
|
|
c7578_load_letters:
|
|
push {lr}
|
|
ldr r2,=#m2_overworld_alphabet_table //Letter table
|
|
ldr r0,[sp,#0x28]
|
|
cmp r0,#1
|
|
bne @@generic_end
|
|
mov r0,#0x90 //If this is the small alphabet, go to its alphabet
|
|
add r2,r2,r0
|
|
|
|
@@generic_end:
|
|
mov r3,#0x36 //Clobbered code
|
|
pop {pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
//Prints the cash window and then stores the buffer to vram
|
|
b8894_printCashWindowAndStore:
|
|
push {lr}
|
|
bl printCashWindow
|
|
bl store_pixels_overworld
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//UNUSED
|
|
bac46_statusWindowNumbersStore:
|
|
push {lr}
|
|
bl statusWindowNumbers
|
|
bl store_pixels_overworld
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Prints the status text and numbers in the buffer, then loads it in vram
|
|
b8320_statusWindowTextStore:
|
|
push {lr}
|
|
push {r0}
|
|
bl statusWindowText
|
|
pop {r0}
|
|
mov r1,#0
|
|
bl statusNumbersPrint
|
|
bl store_pixels_overworld
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Routine which checks if all the teleport locations have been printed. If they do, it stores the buffer
|
|
c5f04_store_if_done:
|
|
push {lr}
|
|
lsr r5,r0,#0x10
|
|
ldr r2,[sp,#0x18]
|
|
cmp r0,r2
|
|
blt @@end
|
|
bl store_pixels_overworld
|
|
@@end:
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Allocs the printing buffer's pointer. It needs 4 bytes
|
|
_05b80_alloc_buffer_pointer:
|
|
push {lr}
|
|
|
|
mov r0,#4
|
|
bl 0x8005B9C
|
|
|
|
ldr r0,=#0x3002A4C
|
|
str r4,[r0,#0]
|
|
pop {pc}
|
|
|
|
|
|
//==============================================================================
|
|
//Loads the vram into the buffer, it's called each time there is only the main file_select window active (a good way to set the whole thing up)
|
|
load_pixels_overworld:
|
|
push {r0-r3,lr}
|
|
bl load_pixels_overworld_buffer
|
|
pop {r0-r3,pc}
|
|
|
|
//==============================================================================
|
|
//Stores the buffer into the vram. This avoids screen tearing.
|
|
store_pixels_overworld:
|
|
push {r0-r3,lr}
|
|
swi #5 //The improved performances allow using a VBlank before the storage in order to prevent screen tearing effectively
|
|
mov r0,#0x10
|
|
bl store_pixels_overworld_buffer
|
|
pop {r0-r3,pc}
|
|
|
|
//==============================================================================
|
|
//Stores the buffer into the vram. This avoids screen tearing.
|
|
store_pixels_overworld_options:
|
|
push {r0-r3,lr}
|
|
swi #5 //The improved performances allow using a VBlank before the storage in order to prevent screen tearing effectively
|
|
mov r0,#6
|
|
bl store_pixels_overworld_buffer
|
|
pop {r0-r3,pc}
|
|
|
|
//==============================================================================
|
|
//Stores the buffer into the vram. This avoids screen tearing.
|
|
store_pixels_overworld_use:
|
|
push {r0-r3,lr}
|
|
swi #5 //The improved performances allow using a VBlank before the storage in order to prevent screen tearing effectively
|
|
mov r0,#8
|
|
bl store_pixels_overworld_buffer
|
|
pop {r0-r3,pc}
|
|
|
|
//==============================================================================
|
|
//Stores the buffer into the vram. This avoids screen tearing.
|
|
store_pixels_overworld_top:
|
|
push {r0-r3,lr}
|
|
swi #5 //The improved performances allow using a VBlank before the storage in order to prevent screen tearing effectively
|
|
mov r0,#0x2
|
|
bl store_pixels_overworld_buffer
|
|
pop {r0-r3,pc}
|
|
|
|
//==============================================================================
|
|
//Stores the buffer into the vram. This avoids screen tearing.
|
|
store_pixels_overworld_player_naming:
|
|
push {r0-r3,lr}
|
|
swi #5 //The improved performances allow using a VBlank before the storage in order to prevent screen tearing effectively
|
|
mov r0,#0x4
|
|
bl store_pixels_overworld_buffer
|
|
pop {r0-r3,pc}
|
|
|
|
//==============================================================================
|
|
//Stores the buffer into the vram. This avoids screen tearing.
|
|
store_pixels_overworld_psi_window:
|
|
push {r0-r3,lr}
|
|
swi #5 //The improved performances allow using a VBlank before the storage in order to prevent screen tearing effectively
|
|
mov r0,#0xA
|
|
bl store_pixels_overworld_buffer
|
|
pop {r0-r3,pc}
|
|
|
|
//==============================================================================
|
|
//Change tile only if need be (it's different) - foreground call
|
|
change_palette_needed_foreground:
|
|
push {lr}
|
|
mov r3,#0
|
|
bl change_palette_needed
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Change tile only if need be (it's different) - background call
|
|
change_palette_needed_background:
|
|
push {lr}
|
|
mov r3,#1
|
|
bl change_palette_needed
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Change tile only if need be (it's different), r3 contains whether the EB cart is in the background or not
|
|
change_palette_needed:
|
|
push {lr}
|
|
ldrh r2,[r1,#0]
|
|
ldrh r1,[r0,#0]
|
|
cmp r1,r2
|
|
beq @@end
|
|
mov r0,r3
|
|
bl eb_cartridge_palette_change
|
|
@@end:
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Prevents changing the palette based on the flavour for the cast roll sequence
|
|
prevent_cast_changed_palettes:
|
|
push {lr}
|
|
ldr r1,=#m2_cast_roll_pointers
|
|
cmp r0,r1
|
|
beq @@alternate_end
|
|
bl 0x8010028
|
|
pop {pc}
|
|
|
|
@@alternate_end:
|
|
bl 0x8010028
|
|
ldr r1,=#0x40000D4
|
|
ldr r0,=#0x2010000
|
|
str r0,[r1,#0]
|
|
ldr r3,=#0x3001B30
|
|
str r3,[r1,#4]
|
|
ldr r0,=#0x84000080
|
|
str r0,[r1,#8]
|
|
ldr r0,[r1,#8]
|
|
pop {r0}
|
|
ldr r0,=#0x8010501 //Go to the end of the routine
|
|
bx r0
|
|
|
|
//==============================================================================
|
|
//Creates a new event that updates the "THE END..." screen to the second frame
|
|
extra_event_end_question_mark:
|
|
push {lr}
|
|
add r0,r0,r1
|
|
asr r0,r0,#0x10
|
|
cmp r0,#0x48
|
|
bne @@end
|
|
push {r0}
|
|
ldr r0,=#m2_end_frame1
|
|
ldr r1,=#0x6001000
|
|
mov r2,#0xA0
|
|
lsl r2,r2,#1
|
|
swi #0xC
|
|
pop {r0}
|
|
|
|
@@end:
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Prints the sick tiles and then the names
|
|
sick_name:
|
|
push {lr}
|
|
push {r0-r3}
|
|
bl 0x80CAC70 //Purple tiles
|
|
mov r4,r0
|
|
pop {r0-r3}
|
|
bl 0x80CABF8 //Name
|
|
mov r0,r4
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Prints the dead tiles and then the names
|
|
dead_name:
|
|
push {lr}
|
|
push {r0-r3}
|
|
bl 0x80CACE8 //Red tiles
|
|
mov r4,r0
|
|
pop {r0-r3}
|
|
bl 0x80CABF8 //Name
|
|
mov r0,r4
|
|
pop {pc}
|
|
|
|
//==============================================================================
|
|
//Prints the alive tiles and then the names - right after the normal status is restored
|
|
d6dac_alive_name:
|
|
push {r7,lr}
|
|
mov r7,r5
|
|
bl alive_name
|
|
pop {r7,pc}
|
|
|
|
//==============================================================================
|
|
//Prints the alive tiles and then the names
|
|
alive_name:
|
|
push {r4,lr}
|
|
push {r5}
|
|
mov r5,r2
|
|
push {r0-r3}
|
|
mov r0,r7
|
|
mov r1,#0x4D
|
|
mov r2,r5
|
|
mov r3,#0x12
|
|
bl 0x80CAD60 //The 1st alive tile
|
|
mov r0,r7
|
|
mov r1,#0x4D
|
|
mov r2,#1
|
|
add r2,r2,r5
|
|
mov r3,#0x12
|
|
bl 0x80CAD60 //The 2nd alive tile
|
|
mov r0,r7
|
|
mov r1,#0x4D
|
|
mov r2,#2
|
|
add r2,r2,r5
|
|
mov r3,#0x12
|
|
bl 0x80CAD60 //The 3rd alive tile
|
|
mov r0,r7
|
|
mov r1,#0x4D
|
|
mov r2,#3
|
|
add r2,r2,r5
|
|
mov r3,#0x12
|
|
bl 0x80CAD60 //The 4th alive tile
|
|
mov r0,r7
|
|
mov r1,#0x4D
|
|
mov r2,#4
|
|
add r2,r2,r5
|
|
mov r3,#0x12
|
|
bl 0x80CAD60 //The 5th alive tile
|
|
mov r4,#5
|
|
pop {r0-r3}
|
|
pop {r5}
|
|
bl 0x80CABF8 //Name
|
|
mov r0,r4
|
|
pop {r4,pc}
|
|
|
|
.pool
|
|
|
|
//==============================================================================
|
|
// Returns in r0 the result of m2_div, and in r1 the result of m2_remainder
|
|
__aeabi_uidiv:
|
|
__aeabi_uidivmod:
|
|
push {r4,lr}
|
|
push {r0,r1}
|
|
bl m2_remainder
|
|
mov r4,r0
|
|
pop {r0,r1}
|
|
bl m2_div
|
|
mov r1,r4
|
|
pop {r4,pc}
|
|
|
|
.pool
|