Seen 10 Hours Ago
Posted 1 Week Ago
47 posts
4.9 Years
Solved (more or less...)!
If you want to apply in a hack rom patched by MrDollSteak's Decap. and Attack Rombase (Version 1.5a)...
1) change source/scripts.h and source/scripts.s with 0x300 (before 0x200);
2) change version/firered/insert.asm:bs_execute_handle and source/script_commands.h with 0xFF (before 0xF8);
3) edit trainer_sliding-master\version\firered like this:


.open "firered.gba", "firered.patched.gba", 0x08000000

.definelabel free_space, 0x08(offset)

.definelabel battle_malloc_hook, 0x0802e0fa
.definelabel battle_malloc_ret, 0x0802e104|1

.definelabel battle_free_hook, 0x0802e1f8
.definelabel battle_free_ret, 0x0802e200|1

.definelabel sliding_hook, 0x08013c26
.definelabel sliding_hook_buffer, 0x02023DD0
.definelabel sliding_hook_turn_value_cleanup, 0x08015330|1
.definelabel sliding_hook_ret, 0x08013d20|1
.definelabel sliding_hook_continue, 0x08013c30|1

.definelabel string_hook, 0x080d77be
.definelabel string_hook_buffer, 0x0202298c
.definelabel string_hook_ret, 0x080d77e2|1
.definelabel string_hook_decode, 0x080d77dc|1

bs_commands equ 0x0895f480
.definelabel battlecommand_trainer_slide_ptr, (bs_commands + 0x53 * 4)
.definelabel battlecommand_trainer_slide, 0x080250dc|1

.definelabel bs_execute_hook, 0x08015c58
.definelabel battlecommand_trainer_back_slide_battler, 0x02023bc4
.definelabel battlecommand_trainer_back_slide_emit, 0x0800e114|1
.definelabel battlecommand_trainer_back_slide_unk, 0x08017248|1

.org battle_malloc_hook
    ldr r0, =battle_malloc_handle|1
    bx r0

.org battle_free_hook
    ldr r0, =battle_free_handle|1
    bx r0

.org sliding_hook
    ldr r0, =sliding_hook_handle|1
    bx r0

.org string_hook
    ldr r0, =string_hook_handle|1
    bx r0

.org battlecommand_trainer_slide_ptr
.word battlecommand_trainer_slide_handle|1

.org bs_execute_hook
    ldr r2, =bs_execute_handle|1
    bx r2

.org free_space
.incbin "trainer_sliding_firered.bin"
.include "trainer_sliding_firered.asm"

; This hooks right after all of the other battle structs have been allocated

; State:
; r0-r3, lr are fair game.

	; Run the few instructions we've overwritten
    mov r0, r5
    ldr r1, =calloc
    bl @@bx_r1
    mov r1, r0
    str r1, [r4]

    bl battle_malloc

    ldr r1, =battle_malloc_ret
    bx r1


; This hooks right after all of the other battle structs have been freed

; State:
; r5 = 0
; r0-r3, lr are fair game.

    ; Run the few instructions we've overwritten
    ldr r0, [r4]
    ldr r1, =free
    bl @@bx_r1
    str r5, [r4]

    bl battle_free

    ldr r1, =battle_free_ret
    bx r1


; This hooks right after Perish Song/Future Sight are handled at the end of a turn.
; If a battle effect is executed, it's supposed to return early.

; State:
; r0-r3, lr are fair game.

; Return hooks:
; sliding_hook_ret:
;   Returns early from the hooked function.
; sliding_hook_continue:
;   Continues running the end-of-turn function, looking for other effects to
;   run and doing other end-of-turn-y stuff.

	bl turn_end_slide
	cmp r0, #0
	beq @@continue

	ldr r1, =sliding_hook_ret
	bx r1

	; Run the few instructions we've overwritten
    mov r0, #0
    ldr r1, =sliding_hook_turn_value_cleanup
    bl @@bx_r1
	ldr r2, =sliding_hook_buffer
	ldr r0, [r2]

	ldr r1, =sliding_hook_continue
	bx r1


; This hooks the default case in the battle string engine,
;  when a string ID is higher than the size of the string table.
; We can load our custom strings here.

; State:
; r6 = String ID
; r0-r10, lr are fair game.

; Addresses of interest:
; string_buffer:
;   Contains the resulting string to print. Not sure how big it is.
;   Should be filled with a single terminator (0xFF) if no string was found.

; Return hooks:
; string_hook_decode:
;   r7 = String pointer
;   Decodes the string, copying it to string_hook_buffer in the process.
; string_hook_ret:
;   Returns from the string loading function. Should have a valid string in
;   string_hook_buffer.

    mov r0, r6
    bl get_custom_string
    cmp r0, #0
    beq @@ret

    ; Decode the string
	mov r7, r0
	ldr r0, =string_hook_decode
	bx r0

	; Run the few instructions we've overwritten
	ldr r1, =string_hook_buffer
	mov r0, #0xFF
	strb r0, [r1]
	ldr r0, =string_hook_ret
	bx r0


; This replaces the original trainer_slide command.

; We extend the trainer_slide command to handle some values in a different fashion.
; See slide_save_obj for details.

    push {lr}
    bl slide_save_obj
    cmp r0, #0
    pop {r0}
    bne @@bx_r0
    mov lr, r0
    ldr r0, =battlecommand_trainer_slide
    bx r0


; This hooks the function used to run some battle scripts,
;  after fetching the next command ID from bs_pointer.
; There are more functions where the command IDs are interpreted,
;  but this is the only one that we need to interpret trainer_back_slide.

; State:
; r0 = Command ID
; r1 = Pointer to bs_commands
; r2, r3 and lr are fair game, the rest should be preserved.

    pop {r2}
    mov lr, r2

    cmp r0, #0xf9
    beq battlecommand_trainer_back_slide

    ; Run whatever command was called upon
    lsl r0, #2
    add r0, r1
    ldr r0, [r0]
    bx r0


; Port of trainer_back_slide from emerald into firered

    push {r4, r5, lr}

    ; Get the argument, make sure any value bigger than 1 is 1.
    ldr r5, =bs_pointer
    ldr r0, [r5]
    ldrb r0, [r0, #1]
    cmp r0, #0
    beq @@zero
    mov r0, #1

    ; Get and save the position
    ldr r1, =get_battler_at_position
    bl @@bx_r1
    ldr r4, =battlecommand_trainer_back_slide_battler
    strb r0, [r4]

    ; Emit a trainer slide back
    mov r0, #0
    ldr r1, =battlecommand_trainer_back_slide_emit  ; Fun fact: This function is never used in the game
    bl @@bx_r1

    ; Call an unknown function
    ldrb r0, [r4]
    ldr r1, =battlecommand_trainer_back_slide_unk
    bl @@bx_r1

    ; Skip to the next command
    ldr r0, [r5]
    add r0, #2
    str r0, [r5]

    pop {r4, r5}
    pop {r0}
    bx r0

    bx r1


; Set up a dummy table for the sliding trainer messages.
    .word 0
    .word 0

.org sliding_trainers
.word _sliding_trainers