MrCheeze

Ocarina of Time Credits Warp - Extended Description

Jan 3rd, 2020
1,632
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.42 KB | None | 0 0
  1. In this video, I use stale reference manipulation and arbitrary code execution to wrong warp into the credits from the very beginning of the game, in Kokiri Forest. This cuts the amount of time needed to beat Ocarina of Time any% lower than it has ever been before.
  2.  
  3.  
  4. The reason this is possible is because of "Camera Lock SRM", a new kind of SRM which was originally discovered by Hylian Freddy of the Ocarina of Time 3D community, and researched further by Blini and Fig.
  5.  
  6. In general, to achieve SRM, we want to move Link one room to another while holding or picking up an actor, so that the actor unloads but Link is still pointing at the part of memory where the actor used to be loaded. The reason that we can't simply pick up a rock and walk over to the Great Deku Tree's room to achieve SRM, is that whenever a holdable actor's main update function runs, it will check whether it's being held or not. If it is being held, the actor sets its own associated room to -1, a value which means that the actor should not unload no matter what room Link is in.
  7.  
  8. Separately, whenever an actor is far from the camera view, it becomes "culled", meaning its draw and update functions do not run. If we can pick up a rock and immediately cull it, and keep it culled the entire time as we walk over into a differerent room, it will never set its room to -1, and will unload, thereby achieving SRM. Using the Walking While Talking glitch to lock the camera near the crawlspace far from Link, we can achieve exactly that.
  9.  
  10. Once SRM is achieved, our goal is to leverage that into ACE, and use that to immediately warp into the credits and beat the game. It's worth taking a moment here for a moment to discuss why we're playing on the Chinese iQue version of OoT, the strangest and most obscure release of the game. Essentially, Ocarina of Time has been released on four platforms:
  11. - Nintendo 64: The original builds of the game, running natively.
  12. - iQue: A console unique to the Chinese market, which shares some hardware with the N64 but also has unique characteristic. The builds for this version were created a few years later, but still run natively.
  13. - GameCube: Yet another set of builds of the game, that are only possible to run via a Nintendo-made emulator. This emulator dynamically transforms all N64 code it runs into GC code via Just-In-Time compilation (JIT).
  14. - Virtual Console: Available on Wii and Wii U, this likewise emulates the game via JIT. However it emulates the original N64 builds of the game.
  15.  
  16. Achieving arbitrary code execution on GC and VC is all but impossible. The reason for this is how the JIT works: rather than only look at the current N64 instruction being executed, it will "look ahead" and try to detect an entire valid function, and compile the whole function at once. If it sees any invalid opcodes before it reaches a return instruction, the game will just crash (thanks KrimtonZ for researching this). Setting up an entire valid function in manipulable memory on the heap is not likely to ever be possible.
  17.  
  18. The N64 and iQue, on the other hand, look at one opcode at a time and do not have this issue. The difference has to with heap memory allocation. The N64 builds of the game, being the oldest ones made, include certain debug information in the header of each block of memory that gets allocated on the heap, making each block have a header of size 0x30. The iQue and GC builds removed this debug info so that the header size is only 0x10. Because of this, the arrangement of blocks in the heap will follow different patterns on N64 versus iQue/GC, and a heap manip that works with 0x30 headers will not work with 0x10, and vice versa.
  19.  
  20. At least theoretically, finding heap manips that lead to ACE is equally possible regardless of 0x30 or 0x10. But right now, despite a fair bit of heap manip research by me, Blini, and Tharo, we currently have several viable manips for 0x10 and none for 0x30. So for the time being, the iQue - being the only version of the game with 0x10 headers and no JIT - is the fastest possible way to beat the game. Long live the Chinese cheat box.
  21.  
  22.  
  23. Breakdown of the video:
  24. 3:35-11:35 The setup section. There are four mandatory prerequisites before we can get into the SRM itself. We need nuts to be able to trigger WWT; Ocarina, which lets us manipulate camera while WWT is active; and slingshot, because it lets us fire a seed at a semi-arbitrary angle that lets us write a custom opcode onto the heap. We also need to move Mido out of the way, which requires sword/shield/rupees. Finally, it's worth mentioning I don't get any of the "one-time" blue rupees in the main room of Kokiri Forest, as that could potentially affect the heap manip later.
  25.  
  26. 11:40-12:05 With the specific choice of ACE and that I'm going to be using, it's necessary to save and quit so that the last viewed cutscene will be the title screen to prevent a crash later. We also need to load Kokiri Forest from the Deku Tree room so the heap manip and ACE will work. These are not hard requirements, though.
  27.  
  28. 11:32 For the heap manip, collect the rupee and break the specific rock that I do here.
  29.  
  30. 12:52-13:25 Trigger WWT. With the help of ocarina camera adjustments, load the rock circle and break the three rocks that I do.
  31.  
  32. 13:25 This part is trickier than it looks. Walk to where the westmost circle rock should be. Use the ocarina to bring the camera close, as culled actors can't be picked up. Exit the ocarina. When the camera zooms out again, it needs to go in the direction it does for me, otherwise things won't work. During the zoom, you need to press A to trigger the grab BEFORE the camera is far enough for the rock to cull, but Link needs to actually execute the grab AFTER the rock culls. Also, to even get into position to be able to grab the rock at all, you may need to have Link be moving while the camera zooms out.
  33.  
  34. 13:30-13:57 With the culled rock in hand, navigate semi-blindly all the way to the Deku Tree's room. Do not at any point come close enough to the camera for the rock to become visible, and don't fall in the water either.
  35.  
  36. 13:59 We have now achieved SRM, and Link is now pointing at unallocated memory. With the heap manip we used, we're pointing at what WOULD be the draw function pointer of the green rupee we collected earlier, but since we collected it, we're pointing at free memory instead. If we go back and approach the circle of rocks, a rock will load in the same location, and we'll be modifying its draw function pointer. At this point we have to be extremely careful: if we ever actually turn the camera close enough for the rock to become visible, the draw function will run and the game will crash! So we need to keep it well off camera. But at the same time, if we go far enough that the rock unloads entirely, our SRM will be useless. So our movement and camera is highly limited here.
  37.  
  38. 14:20 Link needs to have an exact angle to set the draw pointer to the value we actually want it to be. This step, and this step alone, probably makes this whole method not really possible for a human at this time - the game still technically thinks we're in Walking While Talking mode, and as a consequence, disables our Z button. Getting an exact angle without using Z is not really something a human player can do at this time, let along while still having to be very careful with the camera to prevent crashes. In any case, the specific value we set the draw pointer to points at another spot of free memory, one that we're just about to shoot a seed into.
  39.  
  40. 14:26-14:41 Set Link's angle to somewhere between 21DE8800-21DE880F like I do, and press C to start readying a seed. Then press B almost immediately to cancel the seed on the first frame of its existence (the timing on this is easier than it sounds). This will form the seed's angle into a jump instruction that points to a block of memory that contains the value of controller 1 and controller 3 inputs. (Yes, iQue supports multiple controllers, although the required multitap is not cheap.) Now that we've done that, the moment we make the rock visible, its draw function will run start running every frame - jumping to the seed's rotation, which jumps to our controllers. This is extremely powerful - we can now run as much arbitrary code that we like, by changing our controller inputs as we like!
  41.  
  42. 14:42-15:07 Set up controller 3 to simply contain a jump to a return instruction. Make the rock visible, while making sure that controller 1 doesn't input an instruction that will crash! Then set up controller 1 to input the instruction "addiu $gp, $r0, 0xFFF6" - which is MIPS for "load 0xFFF6 to the GP register". The GP register is absolutely unique in that Ocarina of Time never uses it at all! This means that unlike other registers, if we load a value into it, that value will remain there forever, and we can keep using it in later frames! So now we just need to GP to the "current cutscene" location of memory, which we can do on iQue by giving controller inputs that form the instruction "sh $gp, 0x7F4A($at)". The instant we do that, the cutscene triggers.
  43.  
  44. 15:08 The game is now trying to run cutscene FFF6 for Kokiri Forest. But when we set the cutscene value in this way, it doesn't actually load the cutscene - instead it executes leftover data from the last cutscene in memory, which is the title screen. This causes Link to get warped far out of bounds and void out. But that's actually exactly what we want, because voiding out reloads the scene and the proper data for cutscene FFF6, thereby giving us...
  45.  
  46. 15:18 KOKIRI FOREST CREDITS WARP. 😎
Add Comment
Please, Sign In to add comment