# Xenoblade Chronicles 3 2.0.0
# BID: 8E18600222CE90C2

unsafeCheck: true

MASTER_WRITE:
  # Redirect DR frametime target reading to .bss code cave [MAIN, 0x2369B00]
  -
    type: bytes
    main_offset: 0x124E638
    value_type: uint32
    value:
      - 0xF00088C8
      - 0xBD4B0100
  # Original DR frametime target
  -
    type: bytes
    main_offset: 0x2369B00
    value_type: float
    value:
      - 0.0166666666
# For 15-20 FPS use internal FPS lock, for 25-30 set default value
15FPS:
  # vsync
  -
    type: write
    address: [MAIN, 0x1B41DB0]
    value_type: int32
    value: [4, 4]
  -
    type: write
    address: [MAIN, 0x2369B00]
    value_type: float
    value: 0.0166666666
  # UI speed
  -
    type: write
    address: [MAIN, 0x1BA0A90, 128]
    value_type: float
    value: 0.0666666666
  -
    type: block
    what: timing
20FPS:
  -
    type: write
    address: [MAIN, 0x1B41DB0]
    value_type: int32
    value: [3, 3]
  -
    type: write
    address: [MAIN, 0x2369B00]
    value_type: float
    value: 0.0166666666
  -
    type: write
    address: [MAIN, 0x1BA0A90, 128]
    value_type: float
    value: 0.05
  -
    type: block
    what: timing
25FPS:
  -
    type: write
    address: [MAIN, 0x1B41DB0]
    value_type: int32
    value: [2, 2]
  -
    type: write
    address: [MAIN, 0x2369B00]
    value_type: float
    value: 0.02
  -
    type: write
    address: [MAIN, 0x1BA0A90, 128]
    value_type: float
    value: 0.04
30FPS:
  -
    type: write
    address: [MAIN, 0x1B41DB0]
    value_type: int32
    value: [2, 2]
  -
    type: write
    address: [MAIN, 0x2369B00]
    value_type: float
    value: 0.0166666666
  -
    type: write
    address: [MAIN, 0x1BA0A90, 128]
    value_type: float
    value: 0.0333333333

# For 35-60 FPS check if cutscene is played. If it is, set 30 FPS lock. If not, disable it.
35FPS:
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x1B41DB0]
    value_type: int32
    value: [1, 1]
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x2369B00]
    value_type: float
    value: 0.024
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x1B41DB0]
    value_type: int32
    value: [2, 2]
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x2369B00]
    value_type: float
    value: 0.0166666666
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x1BA0A90, 128]
    value_type: float
    value: 0.028571
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x1BA0A90, 128]
    value_type: float
    value: 0.0333333333
40FPS:
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x1B41DB0]
    value_type: int32
    value: [1, 1]
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x2369B00]
    value_type: float
    value: 0.021
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x1B41DB0]
    value_type: int32
    value: [2, 2]
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x2369B00]
    value_type: float
    value: 0.0166666666
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x1BA0A90, 128]
    value_type: float
    value: 0.025
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x1BA0A90, 128]
    value_type: float
    value: 0.0333333333
45FPS:
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x1B41DB0]
    value_type: int32
    value: [1, 1]
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x2369B00]
    value_type: float
    value: 0.018
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x1B41DB0]
    value_type: int32
    value: [2, 2]
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x2369B00]
    value_type: float
    value: 0.0166666666
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x1BA0A90, 128]
    value_type: float
    value: 0.0222222222
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x1BA0A90, 128]
    value_type: float
    value: 0.0333333333
50FPS:
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x1B41DB0]
    value_type: int32
    value: [1, 1]
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x2369B00]
    value_type: float
    value: 0.016
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x1B41DB0]
    value_type: int32
    value: [2, 2]
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x2369B00]
    value_type: float
    value: 0.0166666666
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x1BA0A90, 128]
    value_type: float
    value: 0.02
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x1BA0A90, 128]
    value_type: float
    value: 0.0333333333
55FPS:
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x1B41DB0]
    value_type: int32
    value: [1, 1]
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x2369B00]
    value_type: float
    value: 0.014
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x1B41DB0]
    value_type: int32
    value: [2, 2]
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x2369B00]
    value_type: float
    value: 0.0166666666
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x1BA0A90, 128]
    value_type: float
    value: 0.01818181818
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x1BA0A90, 128]
    value_type: float
    value: 0.0333333333
60FPS:
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x1B41DB0]
    value_type: int32
    value: [1, 1]
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x1B41DB0]
    value_type: int32
    value: [2, 2]
  # Set lowest possible resolution since DR is glitching framebuffer on 60 FPS if we allow even small changes in res
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x2369B00]
    value_type: float
    value: 0.000001
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x2369B00]
    value_type: float
    value: 0.0166666666
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 1
    address: [MAIN, 0x1BA0A90, 128]
    value_type: float
    value: 0.0166666666
  -
    type: compare
    compare_address: [MAIN, 0x1BA0A98]
    compare_type: "!="
    compare_value_type: int8
    compare_value: 0
    address: [MAIN, 0x1BA0A90, 128]
    value_type: float
    value: 0.0333333333