mirror of
https://github.com/Ultra-NX/UltraNX.git
synced 2026-05-12 19:53:12 +00:00
167 lines
4.0 KiB
YAML
167 lines
4.0 KiB
YAML
# The Legend of Zelda: Breath of the Wild 1.9.0
|
|
# BID: CD57B23FA4BBAD65
|
|
|
|
DECLARATIONS:
|
|
-
|
|
type: variable
|
|
name: game_speed
|
|
value_type: float
|
|
default_value: 1.0
|
|
-
|
|
type: variable
|
|
name: min_delta
|
|
value_type: float
|
|
default_value: 1.0
|
|
evaluate: 30 / FPS_TARGET
|
|
-
|
|
type: variable
|
|
name: dr_factor
|
|
value_type: float
|
|
default_value: 100.0
|
|
evaluate: (FPS_TARGET / 30) * 100
|
|
-
|
|
type: variable
|
|
name: frame_tick
|
|
value_type: uint64
|
|
default_value: 0
|
|
-
|
|
type: const
|
|
name: default_frame_nanoseconds
|
|
value: 33333333
|
|
-
|
|
type: code
|
|
name: dynamicSpeed
|
|
instructions: [
|
|
[stp, x29, x30, [sp, -16], "!"],
|
|
[mov, x29, sp],
|
|
[blr, x8],
|
|
[mrs, x2, cntpct_el0],
|
|
[adrp, x8, $frame_tick],
|
|
[ldr, x1, [x8, $frame_tick]],
|
|
[cmp, x1, xzr],
|
|
[str, x2, [x8, $frame_tick]],
|
|
[b.eq, :goto4],
|
|
[sub, x0, x2, x1],
|
|
[bl, _convertTickToTimeSpan()],
|
|
[ucvtf, s0, x0],
|
|
[mov, w0, $default_frame_nanoseconds],
|
|
[movk, w0, $default_frame_nanoseconds, 16],
|
|
[ucvtf, s1, w0],
|
|
[fdiv, s0, s0, s1],
|
|
[fmov, s1, 2.0],
|
|
[fcmp, s0, s1],
|
|
[b.lt, :goto2],
|
|
[fmov, s0, s1],
|
|
:goto2, [adrp, x8, $min_delta],
|
|
[ldr, s1, [x8, $min_delta]],
|
|
[fcmp, s0, s1],
|
|
[b.gt, :goto3],
|
|
[fmov, s0, s1],
|
|
:goto3, [adrp, x8, $game_speed],
|
|
[str, s0, [x8, $game_speed]],
|
|
:goto4, [ldp, x29, x30, [sp], 16],
|
|
[ret]
|
|
]
|
|
-
|
|
type: variable
|
|
name: cutscene_state
|
|
value_type: uint8
|
|
default_value: 1
|
|
-
|
|
type: code
|
|
name: signalCutscene
|
|
instructions: [
|
|
[adrp, x7, $cutscene_state],
|
|
[strb, w1, [x7, $cutscene_state]],
|
|
[b, 0xD0B208] # Update this to jump to address replaced via "Signal Cutscenes playing"
|
|
]
|
|
MASTER_WRITE:
|
|
# Remove double buffer
|
|
## REF: 61 F6 42 39
|
|
-
|
|
type: asm_a64
|
|
main_offset: 0xE93DC8
|
|
instructions: [
|
|
[mov, w1, 1]
|
|
]
|
|
# Change pointer of time factor for DR calculations to $dr_factor
|
|
## REF: 01 01 27 1E 08 59 A8 52 03 08 21 1E, replace hardcoded 100.0 float
|
|
-
|
|
type: asm_a64
|
|
main_offset: 0x12670A4
|
|
instructions: [
|
|
[adrp, x8, $dr_factor],
|
|
[fmul, s3, s0, s1],
|
|
[ldr, s1, [x8, $dr_factor]]
|
|
]
|
|
# Dynamic speed
|
|
## Replace nvnQueuePresentTexture call to code cave _dynamicSpeed()
|
|
-
|
|
type: asm_a64
|
|
main_offset: 0xE9AB7C
|
|
instructions: [
|
|
[bl, _dynamicSpeed()]
|
|
]
|
|
## Patch game speed function to use speed from $game_speed
|
|
## REF: 00 3C 40 BD 00 40 00 BD, replace CBZ W8 after it
|
|
-
|
|
type: asm_a64
|
|
main_offset: 0x151D448
|
|
instructions: [
|
|
[b, +12]
|
|
]
|
|
## REF: 01 01 23 1E 28 00 80 52 42 D8 21 7E, replace FDIV + FMUL after that
|
|
-
|
|
type: asm_a64
|
|
main_offset: 0x151D46C
|
|
instructions: [
|
|
[adrp, x9, $game_speed],
|
|
[ldr, s1, [x9, $game_speed]]
|
|
]
|
|
## Patch UI speed function to use speeed from $game_speed
|
|
## REF: 01 10 2C 1E E0 03 1F 2A
|
|
-
|
|
type: asm_a64
|
|
main_offset: 0x1280ED8
|
|
instructions: [
|
|
[adrp, x7, $game_speed]
|
|
]
|
|
## REF: 00 08 21 1E 00 21 0B BD
|
|
-
|
|
type: asm_a64
|
|
main_offset: 0x1280EE4
|
|
instructions: [
|
|
[ldr, s0, [x7, $game_speed]]
|
|
]
|
|
# Signal Cutscenes playing
|
|
## REF: A8 00 80 52 E0 03 13 AA 68 C2 01 F8, second BL after that, before second BL you should have MOV X0, X19 + MOV W1, 1
|
|
-
|
|
type: asm_a64
|
|
main_offset: 0xD13910
|
|
instructions: [
|
|
[bl, _signalCutscene()]
|
|
]
|
|
## REF: 03 1C 40 92 80 82 17 91 E1 03 15 AA, second BL after that
|
|
-
|
|
type: asm_a64
|
|
main_offset: 0xD140D0
|
|
instructions: [
|
|
[bl, _signalCutscene()]
|
|
]
|
|
ALL_FPS:
|
|
# Scrolling speed
|
|
## REF: 68 16 41 B9 D8 22 D5 1A
|
|
## ADRP + LDR above it
|
|
-
|
|
type: evaluate_write
|
|
address: [MAIN, 0x1DAD0E0]
|
|
value_type: float
|
|
value: "30 / FPS_TARGET"
|
|
# Prerendered cutscenes must be played at 30 FPS
|
|
-
|
|
type: compare
|
|
compare_address: [VARIABLE, cutscene_state]
|
|
compare_type: "=="
|
|
compare_value: 0
|
|
value_type: refresh_rate
|
|
value: 30 |