From ce1d440bfb465d6c3016cd4e642fe08da79e869f Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Fri, 18 Dec 2015 17:05:31 -0800 Subject: [PATCH] add OoT spawning the two asms will be partly merged once i have that ability --- Lua/inject.lua | 74 +++++++++++++++-------- Lua/inject/spawn oot.asm | 127 +++++++++++++++++++++++++++++++++++++++ Lua/inject/spawn.asm | 4 +- 3 files changed, 178 insertions(+), 27 deletions(-) create mode 100644 Lua/inject/spawn oot.asm diff --git a/Lua/inject.lua b/Lua/inject.lua index 20b8ec0..7454589 100644 --- a/Lua/inject.lua +++ b/Lua/inject.lua @@ -3,24 +3,57 @@ require "boilerplate" require "addrs.init" local assemble = require "inject.lips" +local injection_points = { + ['M US10'] = { + inject_addr = 0x780000, + inject_maxlen = 0x5A800, + ow_addr = 0x1749D0, + ow_before = 0x0C05CEC6, + }, + ['O US10'] = { + inject_addr = 0x3BC000, + inject_maxlen = 0x1E800, + ow_addr = 0x0A19C8, + ow_before = 0x0C0283EE, + }, +} + +local header = [[ +[overwritten]: 0x%08X + // TODO: optimize for size + // TODO: fix case where overwritten function takes 5+ args + push ra + push a0, a1, a2, a3 + bal start + nop + pop a0, a1, a2, a3 + jal @overwritten + nop + jpop ra +start: +]] + +injection_points['O JP10'] = injection_points['O US10'] + function inject(fn) local asm_dir = bizstring and 'inject/' or './mm/Lua/inject/' local asm_path = asm_dir..fn - local inject_addr -- seemingly unused region of memory - local inject_maxlen -- how much room we have to work with - local ow_addr -- the jal instruction to overwrite with our hook - local ow_before -- what its value is normally supposed to be - if version == 'M US10' then - inject_addr = 0x780000 - inject_maxlen = 0x5A800 - ow_addr = 0x1749D0 - ow_before = 0x0C05CEC6 - else + local point = injection_points[version] + if point == nil then print("Sorry, inject.lua is unimplemented for your game version.") return end + -- seemingly unused region of memory + local inject_addr = point.inject_addr + -- how much room we have to work with + local inject_maxlen = point.inject_maxlen + -- the jal instruction to overwrite with our hook + local ow_addr = point.ow_addr + -- what its value is normally supposed to be + local ow_before = point.ow_before + -- encode our jal instruction local ow_after = 0x0C000000 + math.floor(inject_addr/4) if R4(ow_addr) ~= ow_before and R4(ow_addr) ~= ow_after then @@ -32,20 +65,7 @@ function inject(fn) local ow_before_addr = (ow_before % 0x4000000)*4 -- set up a header to handle calling our function and the original - local header = ("[overwritten]: 0x%08X\n"):format(ow_before_addr) - header = header..[[ - // TODO: optimize for size - // TODO: fix case where overwritten function takes 5+ args - push ra - push a0, a1, a2, a3 - bal start - nop - pop a0, a1, a2, a3 - jal @overwritten - nop - jpop ra - start: - ]] + local header = header:format(ow_before_addr) local inject_words = {} local length = 0 @@ -84,4 +104,8 @@ function inject(fn) end end -inject('spawn.asm') +if oot then + inject('spawn oot.asm') +else + inject('spawn.asm') +end diff --git a/Lua/inject/spawn oot.asm b/Lua/inject/spawn oot.asm new file mode 100644 index 0000000..62f2deb --- /dev/null +++ b/Lua/inject/spawn oot.asm @@ -0,0 +1,127 @@ +[actor_spawn]: 0x80025110 +[max_actor_no]: 0x1D6 + +[global_context]: 0x801C84A0 +[buttons_offset]: 0x14 +[actor_spawn_offset]: 0x1C24 + +[link_actor]: 0x801DAA30 +[actor_x]: 0x24 +[actor_y]: 0x28 +[actor_z]: 0x2C +[actor_horiz_angle]: 0x46 + +[link_save]: 0x8011A5D0 +[rupees_offset]: 0x34 +[upgrades_offset]: 0xA0 +[upgrades_2_offset]: 0xA2 + +[button_L]: 0x0020 +[button_D_right]: 0x0100 +[button_D_left]: 0x0200 +[button_D_down]: 0x0400 +[button_D_up]: 0x0800 +[button_any]: 0x0F20 + +[hold_delay_amount]: 3 + + push 4, s1, ra + li t0, @link_save + li t1, @global_context +// give max rupee upgrade (set bit 13, clear bit 12 of lower halfword) + lh t2, @upgrades_2_offset(t0) + ori t2, t2, 0x2000 + andi t2, t2, 0xEFFF + sh t2, @upgrades_2_offset(t0) +// + lhu t2, @buttons_offset(t1) + lh t9, @rupees_offset(t0) + lw s1, hold_delay + andi t4, t2, @button_any + bne t4, r0, no_reset + addi s1, s1, 1 + li s1, 0 +no_reset: + subi t4, s1, 1 + beq t4, r0, first_time + nop + subi t4, s1, @hold_delay_amount + bltz t4, return + nop +first_time: + andi t3, t2, @button_D_up + beq t3, r0, no_D_up + nop + addi t9, t9, 1 +no_D_up: + andi t3, t2, @button_D_down + beq t3, r0, no_D_down + nop + subi t9, t9, 1 +no_D_down: + andi t3, t2, @button_D_right + beq t3, r0, no_D_right + nop + addi t9, t9, 10 +no_D_right: + andi t3, t2, @button_D_left + beq t3, r0, no_D_left + nop + subi t9, t9, 10 +no_D_left: + subi t4, t9, 1 + bgez t4, no_min + nop + li t9, @max_actor_no +no_min: + subi t4, t9, @max_actor_no + blez t4, no_max + nop + li t9, 1 +no_max: + sh t9, @rupees_offset(t0) + andi t3, t2, @button_L + beq t3, r0, return + nop + mov a0, t9 + bal simple_spawn + nop +return: + sw s1, hold_delay + jpop 4, s1, ra + +simple_spawn: // args: a0 (actor to spawn) + push 4, 9, ra + mov a2, a0 + li a1, @global_context + addi a0, a1, @actor_spawn_offset + li t0, @link_actor + lw t1, @actor_x(t0) + lw t2, @actor_y(t0) + lw t3, @actor_z(t0) + mov a3, t1 // X position + sw t2, 0x10(sp) // Y position + sw t3, 0x14(sp) // Z position + + li t9, 0x0 + sw t9, 0x18(sp) // rotation? + lh t7, @actor_horiz_angle(t0) + sw t7, 0x1C(sp) // horizontal rotation + li t9, 0x0 + sw t9, 0x20(sp) // rotation? + + lh t7, @actor_horiz_angle(t0) + sw t7, 0x24(sp) // actor variable + + li t9, 0x0000007F + sw t9, 0x28(sp) // unknown + li t9, 0x000003FF + sw t9, 0x2C(sp) // unknown + li t9, 0x00000000 + sw t9, 0x30(sp) // unknown + jal @actor_spawn + nop + jpop 4, 9, ra + +hold_delay: + .word 0 diff --git a/Lua/inject/spawn.asm b/Lua/inject/spawn.asm index a18db43..0d58c90 100644 --- a/Lua/inject/spawn.asm +++ b/Lua/inject/spawn.asm @@ -105,8 +105,8 @@ simple_spawn: // args: a0 (actor to spawn) li t9, 0x0 sw t9, 0x18(sp) // rotation? - li t9, 0x5080 - sw t9, 0x1C(sp) // horizontal rotation + lh t7, @actor_horiz_angle(t0) + sw t7, 0x1C(sp) // horizontal rotation li t9, 0x0 sw t9, 0x20(sp) // rotation?