diff --git a/Lua/inject.lua b/Lua/inject.lua index 1a23e99..ef659dc 100644 --- a/Lua/inject.lua +++ b/Lua/inject.lua @@ -162,8 +162,8 @@ end local asms = { ['O US10'] = {'spawn oot.asm'}, ['O JP10'] = {'spawn oot.asm'}, - ['O EUDB MQ'] = {'widescreen.asm'}, --- ['O EUDB MQ'] = {'widescreen-inline.asm', true}, +-- ['O EUDB MQ'] = {'widescreen.asm'}, + ['O EUDB MQ'] = {'widescreen-inline.asm', true}, ['M US10'] = {'beta.asm'}, ['M JP10'] = {'spawn mm early.asm'}, diff --git a/Lua/inject/widescreen-either.asm b/Lua/inject/widescreen-either.asm new file mode 100644 index 0000000..85c64b6 --- /dev/null +++ b/Lua/inject/widescreen-either.asm @@ -0,0 +1,199 @@ +/* +.org 0x18F30 +; add an entry to the end of dmatable to hold our extra code +; this actually just crashes the game so don't bother +; (no debug filename associated with it = bad pointer dereference? maybe?) + .word @vstart ; virtual start + .word 0x035E0000 ; virtual end (@vstart + @size) + .word @vstart ; physical start (should be same as virtual start) + .word 0 ; physical end (should be 0 for uncompressed) +*/ + +start: + push 4, 1, ra + +; time for dlist misuse +; TODO: check if the game has even loaded yet + li t0, @dlists + jal adjust_dlist + lw a0, 4(t0) ; HUD display list start + + jpop 4, 1, ra + +adjust_dlist: + ; args: pointer to start of dlist + push 4, s0, s1, s2, s3, s4, s5, s6, s7, s8, ra + cl s7 ; iteration count + mov s8, a0 + +-: + bgei s7, 0x1000, +return ; give up after a while + addiu s7, s7, 1 + lw t1, 0(s8) ; load a command + li t9, 0xDF000000 + beq t1, t9, +return ; stop if we're at the end of the display list + li t9, 0xDE010000 + beq t1, t9, +return ; jumps count as ends too + li t9, 0xDC080008 + beq t1, t9, screen_dim ; check if these are screen dimensions + li t9, 0xFF000000 + and t3, t1, t9 + li t9, 0xE4000000 + beq t3, t9, texscale ; check if this is a 2D texture + li t9, 0xED000000 + beq t3, t9, setscissor ; check if... yeah + li t9, 0xDE000000 + beq t3, t9, recurse ; check if this is a "call" and recurse into it + nop +next: + b - + addiu s8, s8, 8 ; next command + +; FIXME: +; don't recurse into the pause menu background +; jiggle jiggle +recurse: + lw a0, 4(s8) + li t9, 0xFF000000 + and t3, a0, t9 + li t9, 0x80000000 + ; only follow this if it's a pointer (not a bank offset!) + bne t3, t9, next + nop + sw a0, debug + jal adjust_dlist + nop + b next + nop + +texscale: + addiu s8, s8, 8 ; next command +; get the coordinate and scale data + andi s1, t1, 0xFFF ; get bottom right y + srl t3, t1, 12 + andi s0, t3, 0xFFF ; get bottom right x + lw t1, -4(s8) ; load second word of E4 command + andi s3, t1, 0xFFF ; get top right y + srl t3, t1, 12 + andi s2, t3, 0xFFF ; get top right x + lw t1, 0xC(s8) ; load second word of F1 command + ; (last word of E4 command chain) + andi s5, t1, 0xFFFF ; get y scale + srl t3, t1, 16 + andi s4, t3, 0xFFFF ; get x scale + +; scale coordinates + jal scale_xy + mov a0, s0 + mov s0, v0 + jal scale_xy + mov a0, s2 + mov s2, v0 + +; scale pixel steps + jal scale_step + mov a0, s4 + mov s4, v0 + +; reconstruct commands + li t9, 0xE4000000 + sll t3, s0, 12 + or t1, t9, s1 + or t1, t1, t3 + sw t1, -8(s8) +; + lw t1, -4(s8) + srl t1, t1, 24 ; clear the lower 3 bytes + sll t1, t1, 24 + sll t3, s2, 12 + or t1, t3, s3 + or t1, t1, t3 + sw t1, -4(s8) +; + sll t1, s4, 16 + or t1, t1, s5 + sw t1, 0xC(s8) + b - + addiu s8, s8, 0x10 ; next two commands + +screen_dim: ; handle screen dimensions for A Button, beating heart, map icons + lw t1, 4(s8) + lw t4, 0(t1) + li t9, 0x005A005A ; probably the A button, we want it to be 0x0044 + beq t4, t9, abutt + li t9, 0x028001E0 ; general screen stuff + ; FIXME: this causes the "jiggling" effect. + ; we need to be more picky about which structs we modify. + beq t4, t9, general + nop +; sw t4, debug + b next + nop +abutt: + li t9, 0x0044005A + sw t9, 0(t1) + li t9, 0x0312007E + sw t9, 8(t1) + b next + nop +general: + li t9, 0x01E001E0 + b next + sw t9, 0(t1) + +setscissor: + lw t1, 0(s8) + lw t3, 4(s8) +; change setscissor of A Button +; from ED2E8024 0039C0D8 +; to ED2B8024 0036C0D8 +; TODO: just calculate this dynamically + li t9, 0xED2E8024 + bne t1, t9, next + li t9, 0xED2B8024 + sw t9, 0(s8) + li t9, 0x0039C0D8 + b next + sw t9, 4(s8) + +;8008A8F8 sets up a button/text matrix? +; call at 8008B684 sets up matrix/viewport for A button +; 80168938 end of HUD dlist +;802114C4 +;80167FB0 + ++return: + jpop 4, s0, s1, s2, s3, s4, s5, s6, s7, s8, ra + +.align 4 + .word 0xDEADBEEF +debug: + .word 0 + .word 0 + .word 0xDEADBEEF + +scale_xy: + li at, 0x3F400000 ; 0.75f + mtc1 a0, f30 ; note: we blindly assume f30 is fine to overwrite here + mtc1 at, f31 ; likewise + cvt.s.w f30, f30 + mul.s f30, f30, f31 + nop + trunc.w.s f31, f30 + mfc1 v0, f31 + ; TODO: add before truncation? (proper rounding etc.) + addiu v0, v0, 0xA0 ; round((((240 * 16 / 9. - 320) / 2.) * 0.75) * 4) + jr + andi v0, v0, 0xFFF + +scale_step: + li at, 0x3FAAAAAB ; 1.3333334f + mtc1 a0, f30 ; note: we blindly assume f30 is fine to overwrite here + mtc1 at, f31 ; likewise + cvt.s.w f30, f30 + mul.s f30, f30, f31 + nop + trunc.w.s f31, f30 + mfc1 v0, f31 + jr + andi v0, v0, 0xFFFF diff --git a/Lua/inject/widescreen-inline.asm b/Lua/inject/widescreen-inline.asm new file mode 100644 index 0000000..84127bf --- /dev/null +++ b/Lua/inject/widescreen-inline.asm @@ -0,0 +1,44 @@ +; oot debug rom +; mess with display lists +; game note: #2 jumps to #3 which jumps to #1 which calls pieces of #2 +; what a mess + +[ctxt]: 0x80212020 +[dlists]: 0x80168930 + +[original]: 0x800C6AC4 +[inject_from]: 0x800C62B8 +[inject_to]: 0x80700000 + +.org @inject_from + jal @inject_to + +.org @inject_to + sw ra, -4(sp) + sw a0, 0(sp) + sw a1, 4(sp) + sw a2, 8(sp) + sw a3, 12(sp) + bal start + subi sp, sp, 24 + lw ra, 20(sp) + lw a0, 24(sp) + lw a1, 28(sp) + lw a2, 32(sp) + lw a3, 36(sp) + j @original + addi sp, sp, 24 + +.include "widescreen-either.asm" + +; set up screen dimensions to render widescreen. +[res2_L]: 0 +[res2_T]: 30 +[res2_R]: 320 +[res2_B]: 210 +.org 0x800AAB90 + li t3, @res2_B ; 240B00D2 + li t4, @res2_T ; 240C001E +.org 0x800AABA8 + li t1, @res2_R ; 24090140 + li t2, @res2_L ; 240A0000 diff --git a/Lua/inject/widescreen.asm b/Lua/inject/widescreen.asm deleted file mode 100644 index d81cce4..0000000 --- a/Lua/inject/widescreen.asm +++ /dev/null @@ -1,218 +0,0 @@ -; oot debug rom -; mess with display lists -; game note: #2 jumps to #3 which jumps to #1 which calls pieces of #2 -; what a mess - -[ctxt]: 0x80212020 -[dlists]: 0x80168930 - - push 4, 1, s0, s1, s2, s3, s4, s5, ra - -; time for dlist misuse - li t0, @dlists - lw t0, 0x04(t0) ; HUD display list start - cl t2 ; iteration count - -; DEBUG -/* -;; kill an entire display list by ending it immediately -; li t9, 0xE9000000 -; sw t9, 0(t0) -; sw r0, 4(t0) -; li t9, 0xDF000000 -; sw t9, 8(t0) -; sw r0, 0xC(t0) -; b finish ; DEBUG -; nop - -; nop certain command types - cl t2 ; iteration count - cl t3 ; functions overwritten -[nop_target]: 256 --: - bgei t2, 0x1000, + ; give up after a while - addiu t2, t2, 1 - bgei t3, @nop_target, + ; stop after this many commands nop'd - nop - lw t1, (t0) ; load command - li t9, 0xDF000000 - beq t1, t9, + ; stop if we're at the end of the display list - li t9, 0xDE000000 ; check if it's a call -; li t9, 0xDC080008 ; sets the video resolution and whatnot - bne t1, t9, - - addiu t0, t0, 8 ; next command - sw r0, -8(t0) ; nop the last command - sw r0, -4(t0) - b - - addiu t3, t3, 1 -+: - jpop 4, 1, s0, s1, s2, s3, s4, s5, ra -*/ - --: - bgei t2, 0x1000, finish ; give up after a while - addiu t2, t2, 1 - lw t1, (t0) ; load a command - li t9, 0xDF000000 - beq t1, t9, finish ; stop if we're at the end of the display list - li t9, 0xDC080008 - beq t1, t9, screen_dim ; check if these are screen dimensions - li t9, 0xFF000000 - and t3, t1, t9 - li t9, 0xE4000000 - beq t3, t9, texscale ; check if this is a 2D texture - addiu t0, t0, 8 ; next command - b - - nop - -texscale: -; DEBUG -/* -; nop an entire 2d texture draw command sequence - sw r0, -8(t0) - sw r0, -4(t0) - sw r0, 0(t0) - sw r0, 4(t0) - sw r0, 8(t0) - sw r0, 0xC(t0) - addiu t0, t0, 0x10 ; next 2 commands - b - - nop -*/ - -; get the coordinate and scale data - andi s1, t1, 0xFFF ; get bottom right y - srl t3, t1, 12 - andi s0, t3, 0xFFF ; get bottom right x - lw t1, -4(t0) ; load second word of E4 command - andi s3, t1, 0xFFF ; get top right y - srl t3, t1, 12 - andi s2, t3, 0xFFF ; get top right x - lw t1, 0xC(t0) ; load second word of F1 command - ; (last word of E4 command chain) - andi s5, t1, 0xFFFF ; get y scale - srl t3, t1, 16 - andi s4, t3, 0xFFFF ; get x scale - -; scale coordinates - jal scale_xy - mov a0, s0 - mov s0, v0 - jal scale_xy - mov a0, s2 - mov s2, v0 - -; scale pixel steps - jal scale_step - mov a0, s4 - mov s4, v0 - -; reconstruct commands - li t9, 0xE4000000 - sll t3, s0, 12 - or t1, t9, s1 - or t1, t1, t3 - sw t1, -8(t0) -; - lw t1, -4(t0) - srl t1, t1, 24 ; clear the lower 3 bytes - sll t1, t1, 24 - sll t3, s2, 12 - or t1, t3, s3 - or t1, t1, t3 - sw t1, -4(t0) -; - sll t1, s4, 16 - or t1, t1, s5 - sw t1, 0xC(t0) - b - - addiu t0, t0, 0x10 ; next two commands - -screen_dim: ; handle screen dimensions for A Button, beating heart, map icons -/* NOTES: -1C4164 -heart/map matrix DA380007 801BEBA0 -a button matrix DA380007 801BF0D0 (thereabouts) -search for DC080008 -a button sometimes: 1CFD60? -0342007E 01FF0000 -DC080008 801CFD60 -*/ - lw t1, 4(t0) - lw t4, 0(t1) - li t9, 0x005A005A ; probably the A button, we want it to be 0x0044 - beq t4, t9, abutt - li t9, 0x028001E0 ; general screen stuff - beq t4, t9, general - nop - sw t4, debug -; b desperate -; nop - b next - nop -abutt: - li t9, 0x0044005A - sw t9, 0(t1) - li t9, 0x0312007E ; FIXME: clips left side of button - sw t9, 8(t1) - b next - nop -general: - li t9, 0x01E001E0 - b next - sw t9, 0(t1) -;desperate: -; li t9, 0x00200020 -; b next -; sw t9, 0(t1) -next: - b - - addiu t0, t0, 8 ; next command - -finish: - jpop 4, 1, s0, s1, s2, s3, s4, s5, ra - -.align 4 - .word 0xDEADBEEF -debug: - .word 0 - .word 0 - .word 0xDEADBEEF - -scale_xy: - li at, 0x3F400000 ; 0.75f - mtc1 a0, f30 ; note: we blindly assume f30 is fine to overwrite here - mtc1 at, f31 ; likewise - cvt.s.w f30, f30 - mul.s f30, f30, f31 - nop - trunc.w.s f31, f30 - mfc1 v0, f31 - ; TODO: add before truncation? (proper rounding etc.) - addiu v0, v0, 0xA0 ; round((((240 * 16 / 9. - 320) / 2.) * 0.75) * 4) - jr - andi v0, v0, 0xFFF - -scale_step: - li at, 0x3FAAAAAB ; 1.3333334f - mtc1 a0, f30 ; note: we blindly assume f30 is fine to overwrite here - mtc1 at, f31 ; likewise - cvt.s.w f30, f30 - mul.s f30, f30, f31 - nop - trunc.w.s f31, f30 - mfc1 v0, f31 - jr - andi v0, v0, 0xFFFF - -; set up screen dimensions to render widescreen. -[res2_L]: 0 -[res2_T]: 30 -[res2_R]: 320 -[res2_B]: 210 -.org 0x800AAB90 - li t3, @res2_B ; 240B00D2 - li t4, @res2_T ; 240C001E -.org 0x800AABA8 - li t1, @res2_R ; 24090140 - li t2, @res2_L ; 240A0000 diff --git a/patch/.gitignore b/patch/.gitignore index 2017253..d77b3d9 100644 --- a/patch/.gitignore +++ b/patch/.gitignore @@ -2,4 +2,5 @@ patchme lips entrances.asm crc32.asm +widescreen-either.asm labels.lua diff --git a/patch/oot-widescreen b/patch/oot-widescreen index 45c2631..49276b0 100755 --- a/patch/oot-widescreen +++ b/patch/oot-widescreen @@ -1,6 +1,7 @@ #!/usr/bin/env bash set -e +inject=../Lua/inject rom=../roms/everything/"Legend of Zelda, The - Ocarina of Time - Master Quest (E) (Debug) [f1].z64" lips=../Lua/lib/lips @@ -9,6 +10,7 @@ lips=../Lua/lib/lips # don't copy entire dir; avoid copying dotfiles (.git) mkdir -p lips cp "$lips"/* lips +cp "$inject/"widescreen-either.asm . luajit patch.lua -o 0 --extra-rom 0x035D0000 --extra-ram 0x80700000 widescreen-inline.asm oot-widescreen.z64 diff --git a/patch/widescreen-inline.asm b/patch/widescreen-inline.asm index 15e514d..7c6659f 100644 --- a/patch/widescreen-inline.asm +++ b/patch/widescreen-inline.asm @@ -8,7 +8,7 @@ [DMARomToRam]: 0x80000BFC -[vstart]: 0x035D0000 +[vstart]: 0x035D0000 [start]: 0x80700000 [size]: 0x10000 @@ -71,142 +71,7 @@ j @original addi sp, sp, 24 -start: - push 4, 1, s0, s1, s2, s3, s4, s5, ra - -; time for dlist misuse - li t0, @dlists - lw t0, 0x04(t0) ; HUD display list start - cl t2 ; iteration count - --: - bgei t2, 0x1000, finish ; give up after a while - addiu t2, t2, 1 - lw t1, (t0) ; load a command - li t9, 0xDF000000 - beq t1, t9, finish ; stop if we're at the end of the display list - li t9, 0xDC080008 - beq t1, t9, screen_dim ; check if these are screen dimensions - li t9, 0xFF000000 - and t3, t1, t9 - li t9, 0xE4000000 - beq t3, t9, texscale ; check if this is a 2D texture - addiu t0, t0, 8 ; next command - b - - nop - -texscale: -; get the coordinate and scale data - andi s1, t1, 0xFFF ; get bottom right y - srl t3, t1, 12 - andi s0, t3, 0xFFF ; get bottom right x - lw t1, -4(t0) ; load second word of E4 command - andi s3, t1, 0xFFF ; get top right y - srl t3, t1, 12 - andi s2, t3, 0xFFF ; get top right x - lw t1, 0xC(t0) ; load second word of F1 command - ; (last word of E4 command chain) - andi s5, t1, 0xFFFF ; get y scale - srl t3, t1, 16 - andi s4, t3, 0xFFFF ; get x scale - -; scale coordinates - jal scale_xy - mov a0, s0 - mov s0, v0 - jal scale_xy - mov a0, s2 - mov s2, v0 - -; scale pixel steps - jal scale_step - mov a0, s4 - mov s4, v0 - -; reconstruct commands - li t9, 0xE4000000 - sll t3, s0, 12 - or t1, t9, s1 - or t1, t1, t3 - sw t1, -8(t0) -; - lw t1, -4(t0) - srl t1, t1, 24 ; clear the lower 3 bytes - sll t1, t1, 24 - sll t3, s2, 12 - or t1, t3, s3 - or t1, t1, t3 - sw t1, -4(t0) -; - sll t1, s4, 16 - or t1, t1, s5 - sw t1, 0xC(t0) - b - - addiu t0, t0, 0x10 ; next two commands - -screen_dim: ; handle screen dimensions for A Button, beating heart, map icons - lw t1, 4(t0) - lw t4, 0(t1) - li t9, 0x005A005A ; probably the A button, we want it to be 0x0044 - beq t4, t9, abutt - li t9, 0x028001E0 ; general screen stuff - ; FIXME: this causes the "jiggling" effect. - ; we need to be more picky about which structs we modify. - beq t4, t9, general - nop - sw t4, debug - b next - nop -abutt: - li t9, 0x0044005A - sw t9, 0(t1) - li t9, 0x0312007E ; FIXME: clips left side of button - sw t9, 8(t1) - b next - nop -general: - li t9, 0x01E001E0 - b next - sw t9, 0(t1) -next: - b - - addiu t0, t0, 8 ; next command - -finish: - jpop 4, 1, s0, s1, s2, s3, s4, s5, ra - -.align 4 - .word 0xDEADBEEF -debug: - .word 0 - .word 0 - .word 0xDEADBEEF - -scale_xy: - li at, 0x3F400000 ; 0.75f - mtc1 a0, f30 ; note: we blindly assume f30 is fine to overwrite here - mtc1 at, f31 ; likewise - cvt.s.w f30, f30 - mul.s f30, f30, f31 - nop - trunc.w.s f31, f30 - mfc1 v0, f31 - ; TODO: add before truncation? (proper rounding etc.) - addiu v0, v0, 0xA0 ; round((((240 * 16 / 9. - 320) / 2.) * 0.75) * 4) - jr - andi v0, v0, 0xFFF - -scale_step: - li at, 0x3FAAAAAB ; 1.3333334f - mtc1 a0, f30 ; note: we blindly assume f30 is fine to overwrite here - mtc1 at, f31 ; likewise - cvt.s.w f30, f30 - mul.s f30, f30, f31 - nop - trunc.w.s f31, f30 - mfc1 v0, f31 - jr - andi v0, v0, 0xFFFF +.include "widescreen-either.asm" ; set up screen dimensions to render widescreen. [res2_L]: 0