Advertisement
dragonbane

Why Storage "works"

Aug 11th, 2022 (edited)
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.99 KB | None | 0 0
  1. The basic rundown is:
  2. -Link is always considered in some state and he has an active function for each state. Let's call this currentProc. It is usually called every frame
  3. -Playing the WW: Link's active function is set to procTactWait, where it forces Link into the playing animation and you can control the notes
  4. -procTactWait when B is pressed uses the endDemoMode function to cancel the WW demo (HUD and black bars are removed just beforehand). endDemoMode checks in which real state Link is. If he is completely idle on the ground, it will use the changeWaitProc function to clear the current proc and you are no longer holding the WW
  5. -Several checks are done to confirm if Link is busy or not and if endDemoMode can do an immediate proc transition or not. All relevant values reside in the daPy_lk_c class. On JP it can be found dynamically with the ptr at 0x803BD910
  6. -The member at offset 0x494 (4 bytes) in the daPy_lk_c class stores some sort of Link ground state. The bit with value 32 is probably an isOnGround boolean. If isOnGround is true it will check a bunch of other parameters to figure out the correct state transition. As mentioned, completely idle on ground will end up using changeWaitProc
  7. -If isOnGround is false, it does a bunch of more checks to see if it can still transition. A traditional fall is apparently deemed as impossible to transition to in this function, so the function exits and does nothing more at this point
  8.  
  9. -daPy_lk_c::execute, the master Link player function, also runs every frame since everything else branches off from here
  10. -If the member with offset 0x304 (2 bytes) in the daPy_lk_c class is 5, the execute functions knows Link is in a demo and will not run checks if a state transition needs to happen. Let's call it linkDemoMode
  11. -linkDemoMode is always properly cleared to 0 by the endDemoMode chain, thus firing the transition checks up again
  12.  
  13. -Nintendo relied on the fact, that if a busy state is present, that the state transition checks invoked by execute will pick this up and actually transition the state if endDemoMode bails out early
  14. -One of these functions that check state transitions is daPy_lk_c::changeAutoJumpProc()
  15. -If isOnGround (0x494) is true, this function exits early
  16. -Nintendo expected this function to run with isOnGround == false, since it just confirmed with endDemoMode that it is false
  17. -If that's the case, changeAutoJumpProc() will start a procFall state transition. Which happens if you miss the storage frame (the mid air fall)
  18.  
  19. Conclusion:
  20. Storage thus happens cause endDemoMode and the next changeAutoJumpProc() happens on 2 different frames. So if you cancel the WW while in a fall, then end the fall before changeAutoJumpProc() can execute (which is frame perfect), nothing happens by the sheer fact that no state transition is ever detected.
  21.  
  22. There is seemingly no case for that and the player loop is satisfied that the current state must be correct. So the current proc remains procTactWait, allowing the B press again. Which again goes through the entire chain, but since you are on the ground right away, it now works as it should. And sets the eventCancel flag again where there is no demo to pick it up with, so it remains 1 giving storage.
  23.  
  24. On an unrelated note, using the WW again for camera lock seems to work cause the event is started and cancelled simultaneously, so the endEventCamera function called by procTactWait wanting to cancel the WW will not detect yet that the event camera is even active and thus does nothing. But since you are on the ground, the state transitions to full gameplay control. Thus the event camera is activated right after and then never cancelled, but everything else is cancelled as it should.
  25.  
  26.  
  27. What did HD do to fix it?
  28. endDemoMode implements an extra check to force transition the state back to idle when Link is in "busy" mode during procTactWait, which avoids opening the 1 frame window. Dives are additionally patched with a constant ground check in procTactWait that immediately cancels the WW state if you start to fall.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement