Advertisement
dragonbane

Sequence System (Devil Glitch)

Dec 25th, 2019
270
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.97 KB | None | 0 0
  1. Flow for event scene changes:
  2.  
  3. setNextStage called by dStage_changeScene4Event
  4. dStage_changeScene4Event called by dEvt_control_c::sceneChange
  5. dEvt_control_c::sceneChange called by 6 possible points from dEvent_manager_c::Sequencer
  6. Sequencer can only call sceneChange when dEvDtEvent_c::finishCheck returns true, see: https://pastebin.com/1UkPrBUh (by default getting past finishCheck even with no additional flags set away from the default you get a sceneChange to the next event in the chain)
  7. Sequencer called by dEvt_control_c::Step (every frame only when an event is active)
  8. Step is executed every single frame at the end of d_s_play::dScnPly_Execute regardless if an event is active
  9.  
  10.  
  11. Skip (Start twice pressed):
  12.  
  13. sceneChange is called from 0x800472f4 (3rd point in Sequencer) repeatedly until load starts
  14.  
  15.  
  16. Normal End:
  17. Abort (presumably due missing cutscene arc archive due wrong state):
  18.  
  19. sceneChange is called from 0x80047310 (4th point in Sequencer) repeatedly until load starts
  20.  
  21.  
  22. Finish Check:
  23. dEvDtEvent_c::finishCheck(), see: https://pastebin.com/39j0WAGS
  24.  
  25. finishCheck returns true if any of the 3 flag offsets stored at dEvDtEvent_c + 0x88-0x90 is -1 (not used?) when checked or if all the flags that are in use (g_dComIfG_gameInfo + 0x51B4 + (bit)flagOffset) are ON
  26. dEvDtEvent_c address comes from (0x800474bc)getEventData(dEvent_manager_c,*(short *)(dEvent_manager_c + 0x1aa));
  27.  
  28. (0x80043efc)dEvDtEvent_c::forceFinish (only called from 0x80042c40 Step) is used to set all 3 flags at dEvDtEvent_c + 0x88-0x90 to true as long as they exist (not -1)
  29. Cutscene skips (Start twice pressed) aka dEvt_control_c::skipper trigger forceFinish (unlikely Devil Glitch or anything else triggers it)
  30.  
  31. Event flags including finish flags are stored at 0x8040B374 (4 bytes) (e.g. bits 14-19 from right can be used as finish flags, starting at 0)
  32.  
  33. The abort due missing cutscene arc archive due wrong state is caused by the finish flag at 0x8040B374 (+ bit offset) being set to ON (by 0x80043dc8 dEvDtFlag_c::flagSet)
  34. Error seemingly makes the event system "jump to the last cut" in the event which triggers the exit load to the next cutscene and thus sets the finish flag "naturally"
  35.  
  36. Demo Arc (STB data) load flow:
  37. 1. Loads Demo Arc Stb data: Step -> Experts -> specialStaffProc -> specialProc -> specialProcPackage -> dEvt_control_c::getStbDemoData
  38. 2. Check if current Stage has a Demo arc string set (0x80043340), fails on wrong state as it's not set to an arc name
  39. 3. Res is never loaded as a result, jumps to 0x80043378 (empty/removed debug message)
  40. 4. Function getStbDemoData returns with 0 instead of a valid arc archive ptr
  41. 5. d_demo::dDemo_c::start is triggered with the empty pointer and fails
  42. 6. As a result dDemo_c::m_mode is never set 1 (active) at 0x80039cb4
  43. 7. This causes a mode != 0 check in specialProcPackage at 0x80045abc to fail which triggers dEvent_manager_c::cutEnd using the staff ID of the PACKAGE chunk (ID 3 in ZD Meteor case) which cancels the cutscene early by jumping to the last cut
  44. 8. Orders Staff event: Step -> Sequencer -> advanceCut -> advanceCutLocal -> dEvDtStaff_c::advanceCut
  45. 9. Executes Staff event: Chain is Step -> Experts -> specialStaffProc -> specialProc -> specialProcPackage -> specialProc_WaitProc -> cutEnd -> flagSet
  46.  
  47. Leads:
  48. -"Devil Glitch like cs skips" can likely only be caused by calling cutEnd from within specialProcPackage, several paths lead to it
  49. -StageDemoArcName is always reset by d_stage::dStage_Create FIRST
  50. -All broken cutscenes of Ben and Devil use State 8
  51.  
  52. Likely theory for Devil Glitch:
  53. dEvt_control_c::getStbDemoData succeeds, but d_demo::dDemo_c::start still fails at the parse_next step for the Stb data blocks. Otherwise the cutscene would have started and you don't get the same visual with the camera behind Link. Except this time the failure is not because of the missing Stb data, but because parsing a specific Stb block failed. This could be due some other actor needed for the cutscene having failed to spawn or having an invalid property causing an abort. If any parsing step returns with false, parse_next fails as a whole immediately which in turn makes dDemo_c::start fail leading to the same abort as with a missing demo stb arc file.
  54.  
  55. Stb data block parsing:
  56. One specific chain known to cause failure is that of a Stb block making use of a stage/room actor that hasn't spawned properly. Such as sequences trying to use the Horse (Epona) actor when Epona is locked. Stb block parsing also performs validation for some of the blocks.
  57.  
  58. Ilya cs in the Ordon spring fails when Epona isn't available. The chain that leads to failure is:
  59. 1. dDemo_c::start
  60. 2. JGadget::binary::TParse_header_block::parse_next. Parses header successfully, then loop parses the blocks
  61. 3. JStudio::stb::TParse::parseBlock_next (8028978c) ---> JStudio::TParse::parseBlock_block (802857e4) ---> Branches to...
  62. 4. Studio::stb::TParse::parseBlock_block (802897e8) ---> JStudio::stb::TParse::parseBlock_object (80289820). Object = stb object
  63. 5. JStudio::TFactory::create (802855ac). Tries to create a new memory stb object from a stb data block which ends up failing. First call goes to...
  64. 6. JStudio_JStage::TCreateObject::create (80289b60). First function called from TFactory:create which already fails. Attempts to create a reference to an existing Stage/Room actor (Horse in this case). A JSG object is created first, then the actor is looked up to connect it. Other TFactory::create functions afterwards fail too as a result (e.g. JAudio2, JParticle and d_demo::jstudio_tCreateObject_message::create)
  65. 7. d_demo::dDemo_system_c::JSGFindObject (80039528). Fails looking up Epona via fopAcM_searchFromName("Horse") since she was never spawned. This results in final failure and returning 1. In the case of a demo specific actor shipped with the demo arc file, e.g. "d_actX", this failure is handled/expected and the actor is spawned in return. Failing to spawn it however would also result in an abort
  66. 8. JStudio_JStage::TCreateObject::create fails as a result returning 0. This causes an abort chain and eventual cutscene abort
  67.  
  68. There are likely many other ways a block parse can fail. Devil Glitch most likely is caused by a block that relies on outside data to work, as the stb data should be consistent and static. Perhaps some of the JSG functions are the cause.
  69.  
  70. Currently known failure routes:
  71. -STB file wasn't loaded due wrong state for the cutscene (mDemoArcName wasn't set to the right arc file or was empty)
  72. -STB file wasn't loaded due not enough memory
  73. -An actor referenced by the STB from the stage/room (e.g. Link/Midna/Horse) wasn't spawned properly (e.g. due not enough memory or a specific flag or because the actor got unloaded before)
  74. -A demo specific actor "d_actX" couldn't get spawned (with fopAcM_fastCreate) due not enough memory (maybe they can be unloaded too?)
  75.  
  76. Actors needed for starting Meteor cutscene (inside) (failed):
  77. Link, Midna, d_act0-d_act4
  78.  
  79. Actors needed for starting the second Meteor cutscene (outside) (worked):
  80. d_act0-d_act2, d_act4, d_act5
  81.  
  82. Actors needed for starting the final Meteor cutscene (inside) (worked):
  83. Link, Midna, d_act0-d_act1
  84.  
  85. Actors needed for starting Ilya cutscene in Ordon Spring (failed):
  86. Link, Horse, d_act0-d_act14
  87.  
  88. Actors needed for starting the Zelda 1 cutscene (worked):
  89. Link, Midna, d_act0-d_act1, 15
  90.  
  91. Actors needed for starting Hyrule Castle overtaken cutscene (failed):
  92. Link, d_act0-d_act4, d_act7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 28
  93.  
  94. Conclusion:
  95. A permanent break of d_act3 could result in Devil/Ben glitch, even if unlikely to happen
  96.  
  97. Theory 2 (unlikely): For some reason d_s_room::loadDemoArchive didn't get called or failed to load arc res. Or dRes_control_c::syncRes in objectSetCheck failed. Or dEvent_manager_c::demoInit failed
  98. This failure state is logged in the Event System via OSReport (maybe hook it so we can see those logs in real time?)
  99.  
  100. Other unlikely theories:
  101. -The area state wasn't 8 as it should be (highly unlikely due state override)
  102. -Event Some State ID at 0x8040B16C (1 byte) was set to 0 for 1 frame when the cs started, then set back to 2 properly. This would cause dEvent_manager_c::getMyStaffId and getIsAddvance to fail and the cs to skip ahead (unlikely)
  103. -Event Manager IsAdvance1 at 0x8040B362 (2 bytes) was set to -1 which could cause failure in getIsAddvance (unlikely)
  104. -Event Manager IsAdvance2 at 0x8040B36C (4 bytes) was set wrong so getIsAddvance would return 0 for 1 frame (unlikely)
  105. -specialProcPackage gets never called with a PLAY instruction, resulting in no Stb data being loaded (unlikely)
  106. -A memory allocation fail during parse_next in dDemo_c::start (unlikely)
  107. -dDemo_c::m_mode was somehow 2 at some point (unlikely)
  108. -dEvent_manager_c::getMySubstanceP at 0x8004595c returned a bad FileName for getStbDemoData (very unlikely)
  109. -dRes_control_c::getRes in getStbDemoData failed (very unlikely, unless actor was previously unloaded)
  110.  
  111.  
  112. Aborts like Devil Glitch could also get caused by all 3 flag offsets stored at dEvDtEvent_c + 0x88-0x90 to start out at -1 due corruption/error (rather unlikely)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement