2026-04-05 07:45:00 +03:00

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