# The Legend of Zelda: Breath of the Wild 1.8.2 # BID: DE0B6AC4EFC1DDA7 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, 0xbf7f78] ] MASTER_WRITE: # Remove double buffer ## REF: 61 F6 42 39 - type: asm_a64 main_offset: 0xD80748 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: 0x1153314 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: 0xD874FC instructions: [ [bl, _dynamicSpeed()] ] ## Patch game speed function to use speed from $game_speed - type: asm_a64 main_offset: 0x14092A8 instructions: [ [b, +12] ] - type: asm_a64 main_offset: 0x14092CC instructions: [ [adrp, x9, $game_speed], [ldr, s1, [x9, $game_speed]] ] ## Patch UI speed function to use speeed from $game_speed - type: asm_a64 main_offset: 0x116D0D8 instructions: [ [adrp, x7, $game_speed] ] - type: asm_a64 main_offset: 0x116D0E4 instructions: [ [ldr, s0, [x7, $game_speed]] ] # Signal Cutscenes playing - type: asm_a64 main_offset: 0xC00680 instructions: [ [bl, _signalCutscene()] ] - type: asm_a64 main_offset: 0xC00E40 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, 0x1C4BA40] 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