1
0
Fork 0
mirror of https://github.com/notwa/mm synced 2024-05-18 05:23:22 -07:00

add OoT spawning

the two asms will be partly merged once i have that ability
This commit is contained in:
Connor Olding 2015-12-18 17:05:31 -08:00
parent 4e6f6a114b
commit ce1d440bfb
3 changed files with 178 additions and 27 deletions

View File

@ -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

127
Lua/inject/spawn oot.asm Normal file
View File

@ -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

View File

@ -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?