diff --git a/Lua/inject.lua b/Lua/inject.lua index a0c8cc9..6745888 100644 --- a/Lua/inject.lua +++ b/Lua/inject.lua @@ -8,8 +8,15 @@ local injection_points = { ['M US10'] = { inject_addr = 0x780000, inject_maxlen = 0x5A800, - ow_addr = 0x1749D0, - ow_before = 0x0C05CEC6, + -- main rendering loop: + -- the only other function (that literally just loads and returns) + --ow_addr = 0x1749D0, + --ow_before = 0x0C05CEC6, + -- just after the JALR in the actor(?) rendering loop + -- problem is we do processing AFTER it's all rendered + -- this causes an extra frame of delay for ingame changes + ow_addr = 0x1737C4, + ow_before = 0x0C05CD50, }, ['M JP10'] = { inject_addr = 0x780000, diff --git a/Lua/inject/dpad control.asm b/Lua/inject/dpad control.asm new file mode 100644 index 0000000..c10e1e4 --- /dev/null +++ b/Lua/inject/dpad control.asm @@ -0,0 +1,19 @@ +dpad_control: + // a0: number you want to control + // a1: button state + // v0: number after modifications + la t1, dpad_values + srl t0, a1, 8 + andi t0, t0, 0xF + add t0, t0, t1 + lb t0, 0(t0) + jr + add v0, a0, t0 + +dpad_values: + // use table of values for branchless operation + .byte 0, 1, -1, 0 + .byte -10, -9, -11, -10 + .byte +10, +11, +9, +10 + .byte 0, 1, -1, 0 +.align diff --git a/Lua/inject/print.asm b/Lua/inject/print.asm index a93e056..956df91 100644 --- a/Lua/inject/print.asm +++ b/Lua/inject/print.asm @@ -11,7 +11,7 @@ [SetTextXY]: 0x800FB41C [SetTextString]: 0x800FBCB4 [TxtPrinter]: 0x800FBB60 -[InitTxtStruct]: 0x800FBB8C +[InitTxtStruct]: 0x800FBB8C // unused here; we set it up inline [DoTxtStruct]: 0x800FBC1C [UpdateTxtStruct]: 0x800FBC64 @@ -24,7 +24,7 @@ li a1, 0x88CCFFFF // rgba la a2, fmt la a3, buffer - jal easytext + jal simple_text nop // reset buffer position in our per-frame hook la t0, buffer @@ -40,66 +40,7 @@ str: .byte 0x68,0x65,0x79,0x00 // hey .align -textdata: - .word 0, 0, 0, 0, 0 -easytext: - // a0: xxxxyyyy - // a1: rrggbbaa - // a2: printf formatting string - // a3: first argument for format string (optional) - // TODO: support more than 4 args - push 4, 1, s0, s1, ra - - la s0, textdata - - sw a0, 32(sp) - sw a1, 36(sp) - sw a2, 40(sp) - sw a3, 44(sp) - - li t0, @TxtPrinter - sw t0, 0(s0) // printer - sw r0, 4(s0) // dlist end - sh r0, 8(s0) // x - sh r0, 10(s0) // y - li t0, 0xC - sw t0, 12(s0) // unknown - sw r0, 16(s0) // color - - li t0, @global_context - lw s1, 0(t0) - lw t2, @dlist_offset(s1) - - mov a0, s0 - mov a1, t2 - jal @DoTxtStruct - nop - - lbu a1, 36(sp) - lbu a2, 37(sp) - lbu a3, 38(sp) - lbu t1, 39(sp) - sw t1, 0x10(sp) - jal @SetTextRGBA - mov a0, s0 - - lh a1, 32(sp) - lh a2, 34(sp) - jal @SetTextXY - mov a0, s0 - - lw a1, 40(sp) - lw a2, 44(sp) - jal @SetTextString - mov a0, s0 - - mov a0, s0 - jal @UpdateTxtStruct - nop - - sw v0, @dlist_offset(s1) - - jpop 4, 1, s0, s1, ra +.include "simple text.asm" ObjectSpawnWrap: // keep track of which objects we're spawning diff --git a/Lua/inject/simple spawn.asm b/Lua/inject/simple spawn.asm new file mode 100644 index 0000000..4479561 --- /dev/null +++ b/Lua/inject/simple spawn.asm @@ -0,0 +1,34 @@ +simple_spawn: + // a0: actor number + // a1: actor variable + push 4, 9, ra + mov a2, a0 + mov t4, a1 + 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? + lhu t7, @actor_horiz_angle(t0) + sw t7, 0x1C(sp) // horizontal rotation + li t9, 0x0 + sw t9, 0x20(sp) // rotation? + + sw t4, 0x24(sp) // actor variable + + li t9, 0x0000007F + sw t9, 0x28(sp) // unknown + li t9, 0x000003FF + sw t9, 0x2C(sp) // spawn time? (probably MM only) + li t9, 0x00000000 + sw t9, 0x30(sp) // unknown + jal @actor_spawn + nop + jpop 4, 9, ra diff --git a/Lua/inject/simple text.asm b/Lua/inject/simple text.asm new file mode 100644 index 0000000..e8f7ce1 --- /dev/null +++ b/Lua/inject/simple text.asm @@ -0,0 +1,61 @@ +textdata: + .word 0, 0, 0, 0, 0 +simple_text: + // a0: xxxxyyyy + // a1: rrggbbaa + // a2: printf formatting string + // a3: first argument for format string (optional) + // TODO: support more than 4 args + push 4, 1, s0, s1, ra + + la s0, textdata + + sw a0, 32(sp) + sw a1, 36(sp) + sw a2, 40(sp) + sw a3, 44(sp) + + li t0, @TxtPrinter + sw t0, 0(s0) // printer + sw r0, 4(s0) // dlist end + sh r0, 8(s0) // x + sh r0, 10(s0) // y + li t0, 0xC + sw t0, 12(s0) // unknown + sw r0, 16(s0) // color + + li t0, @global_context + lw s1, 0(t0) + lw t2, @dlist_offset(s1) + + mov a0, s0 + mov a1, t2 + jal @DoTxtStruct + nop + + lbu a1, 36(sp) + lbu a2, 37(sp) + lbu a3, 38(sp) + lbu t1, 39(sp) + sw t1, 0x10(sp) + jal @SetTextRGBA + mov a0, s0 + + lh a1, 32(sp) + lh a2, 34(sp) + jal @SetTextXY + mov a0, s0 + + lw a1, 40(sp) + lw a2, 44(sp) + jal @SetTextString + mov a0, s0 + + mov a0, s0 + jal @UpdateTxtStruct + nop + + sw v0, @dlist_offset(s1) + + jpop 4, 1, s0, s1, ra + diff --git a/Lua/inject/spawn mm.asm b/Lua/inject/spawn mm.asm index db6a5b9..0f52a84 100644 --- a/Lua/inject/spawn mm.asm +++ b/Lua/inject/spawn mm.asm @@ -19,6 +19,16 @@ [upgrades_offset]: 0xB8 [upgrades_2_offset]: 0xBA +[dlist_offset]: 0x2C0 + +[SetTextRGBA]: 0x800859BC +[SetTextXY]: 0x80085A2C +[SetTextString]: 0x800860D8 +[TxtPrinter]: 0x80085FE4 +[InitTxtStruct]: 0x80086010 // unused here; we set it up inline +[DoTxtStruct]: 0x8008606C +[UpdateTxtStruct]: 0x800860A0 + .include "spawn.asm" [whatever]: 0x807D0000 // stupid hack since i can't store/restore PC (not yet!) diff --git a/Lua/inject/spawn.asm b/Lua/inject/spawn.asm index 1e33893..bd270fa 100644 --- a/Lua/inject/spawn.asm +++ b/Lua/inject/spawn.asm @@ -7,19 +7,13 @@ [hold_delay_amount]: 3 - push 4, s1, ra + push 4, s0, s1, s2, ra li t0, @link_save li t1, @global_context -// give max rupee upgrade (set bit 13, clear bit 12 of lower halfword) - lhu t2, @upgrades_2_offset(t0) - ori t2, t2, 0x2000 - andi t2, t2, 0xEFFF - sh t2, @upgrades_2_offset(t0) -// - lhu t2, @buttons_offset(t1) - lhu t9, @rupees_offset(t0) + lhu s2, @buttons_offset(t1) + lhu s0, anum lw s1, hold_delay - andi t4, t2, @button_any + andi t4, s2, @button_any bnez t4, + addi s1, s1, 1 li s1, 0 @@ -30,80 +24,59 @@ bltz t4, return nop +: - andi t3, t2, @button_D_right - beqz t3, + - nop - addi t9, t9, 1 -+: - andi t3, t2, @button_D_left - beqz t3, + - nop - subi t9, t9, 1 -+: - andi t3, t2, @button_D_up - beqz t3, + - nop - addi t9, t9, 10 -+: - andi t3, t2, @button_D_down - beqz t3, + - nop - subi t9, t9, 10 -+: - subi t4, t9, 1 + mov a0, s0 + jal dpad_control + mov a1, s2 + mov s0, v0 + + subi t4, s0, 1 bgez t4, + nop - li t9, @max_actor_no + li s0, @max_actor_no +: - subi t4, t9, @max_actor_no + subi t4, s0, @max_actor_no blez t4, + nop - li t9, 1 + li s0, 1 +: - sh t9, @rupees_offset(t0) - andi t3, t2, @button_L + sh s0, anum + andi t3, s2, @button_L beqz t3, return nop - mov a0, t9 + mov a0, s0 + lhu a1, avar 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? - lhu t7, @actor_horiz_angle(t0) - sw t7, 0x1C(sp) // horizontal rotation - li t9, 0x0 - sw t9, 0x20(sp) // rotation? - -// lhu t7, @actor_horiz_angle(t0) - li t7, 0 - sw t7, 0x24(sp) // actor variable - - li t9, 0x0000007F - sw t9, 0x28(sp) // unknown - li t9, 0x000003FF - sw t9, 0x2C(sp) // spawn time? (probably MM only) - li t9, 0x00000000 - sw t9, 0x30(sp) // unknown - jal @actor_spawn +// render actor number + li a0, 0x0001001C // xy + li a1, 0x88CCFFFF // rgba + la a2, fmt + mov a3, s0 + jal simple_text nop - jpop 4, 9, ra +// render actor variable + li a0, 0x0006001C // xy + li a1, 0xFFCC88FF // rgba + la a2, fmt + lhu a3, avar + jal simple_text + nop + jpop 4, s0, s1, s2, ra + +anum: + .word 0 +avar: + .word 0 + +fmt: + .byte 0x25,0x30,0x34,0x58,0x00 // %04X +.align + +.include "dpad control.asm" +.include "simple spawn.asm" +.include "simple text.asm" hold_delay: .word 0