Advertisement
dragonbane

oot-model.c

Aug 3rd, 2022 (edited)
991
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 72.12 KB | None | 0 0
  1. #include "oot-model.h"
  2. #include <math.h>
  3. #include <stdint.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <emscripten/emscripten.h>
  8.  
  9. #define true 1
  10. #define false 0
  11. #define HASHSIZE 101
  12. #define max(a, b) (((a) > (b)) ? (a) : (b))
  13. #define min(a, b) (((a) < (b)) ? (a) : (b))
  14. #define abs(a) (((a) > 0) ? (a) : (-(a)))
  15.  
  16. // LUT offsets for adult and child
  17. #define Offsets_ADULT_LINK_LUT_DL_WAIST 0x06005090
  18. #define Offsets_ADULT_LINK_LUT_DL_RTHIGH 0x06005098
  19. #define Offsets_ADULT_LINK_LUT_DL_RSHIN 0x060050A0
  20. #define Offsets_ADULT_LINK_LUT_DL_RFOOT 0x060050A8
  21. #define Offsets_ADULT_LINK_LUT_DL_LTHIGH 0x060050B0
  22. #define Offsets_ADULT_LINK_LUT_DL_LSHIN 0x060050B8
  23. #define Offsets_ADULT_LINK_LUT_DL_LFOOT 0x060050C0
  24. #define Offsets_ADULT_LINK_LUT_DL_HEAD 0x060050C8
  25. #define Offsets_ADULT_LINK_LUT_DL_HAT 0x060050D0
  26. #define Offsets_ADULT_LINK_LUT_DL_COLLAR 0x060050D8
  27. #define Offsets_ADULT_LINK_LUT_DL_LSHOULDER 0x060050E0
  28. #define Offsets_ADULT_LINK_LUT_DL_LFOREARM 0x060050E8
  29. #define Offsets_ADULT_LINK_LUT_DL_RSHOULDER 0x060050F0
  30. #define Offsets_ADULT_LINK_LUT_DL_RFOREARM 0x060050F8
  31. #define Offsets_ADULT_LINK_LUT_DL_TORSO 0x06005100
  32. #define Offsets_ADULT_LINK_LUT_DL_LHAND 0x06005108
  33. #define Offsets_ADULT_LINK_LUT_DL_LFIST 0x06005110
  34. #define Offsets_ADULT_LINK_LUT_DL_LHAND_BOTTLE 0x06005118
  35. #define Offsets_ADULT_LINK_LUT_DL_RHAND 0x06005120
  36. #define Offsets_ADULT_LINK_LUT_DL_RFIST 0x06005128
  37. #define Offsets_ADULT_LINK_LUT_DL_SWORD_SHEATH 0x06005130
  38. #define Offsets_ADULT_LINK_LUT_DL_SWORD_HILT 0x06005138
  39. #define Offsets_ADULT_LINK_LUT_DL_SWORD_BLADE 0x06005140
  40. #define Offsets_ADULT_LINK_LUT_DL_LONGSWORD_HILT 0x06005148
  41. #define Offsets_ADULT_LINK_LUT_DL_LONGSWORD_BLADE 0x06005150
  42. #define Offsets_ADULT_LINK_LUT_DL_LONGSWORD_BROKEN 0x06005158
  43. #define Offsets_ADULT_LINK_LUT_DL_SHIELD_HYLIAN 0x06005160
  44. #define Offsets_ADULT_LINK_LUT_DL_SHIELD_MIRROR 0x06005168
  45. #define Offsets_ADULT_LINK_LUT_DL_HAMMER 0x06005170
  46. #define Offsets_ADULT_LINK_LUT_DL_BOTTLE 0x06005178
  47. #define Offsets_ADULT_LINK_LUT_DL_BOW 0x06005180
  48. #define Offsets_ADULT_LINK_LUT_DL_OCARINA_TIME 0x06005188
  49. #define Offsets_ADULT_LINK_LUT_DL_HOOKSHOT 0x06005190
  50. #define Offsets_ADULT_LINK_LUT_DL_UPGRADE_LFOREARM 0x06005198
  51. #define Offsets_ADULT_LINK_LUT_DL_UPGRADE_LHAND 0x060051A0
  52. #define Offsets_ADULT_LINK_LUT_DL_UPGRADE_LFIST 0x060051A8
  53. #define Offsets_ADULT_LINK_LUT_DL_UPGRADE_RFOREARM 0x060051B0
  54. #define Offsets_ADULT_LINK_LUT_DL_UPGRADE_RHAND 0x060051B8
  55. #define Offsets_ADULT_LINK_LUT_DL_UPGRADE_RFIST 0x060051C0
  56. #define Offsets_ADULT_LINK_LUT_DL_BOOT_LIRON 0x060051C8
  57. #define Offsets_ADULT_LINK_LUT_DL_BOOT_RIRON 0x060051D0
  58. #define Offsets_ADULT_LINK_LUT_DL_BOOT_LHOVER 0x060051D8
  59. #define Offsets_ADULT_LINK_LUT_DL_BOOT_RHOVER 0x060051E0
  60. #define Offsets_ADULT_LINK_LUT_DL_FPS_LFOREARM 0x060051E8
  61. #define Offsets_ADULT_LINK_LUT_DL_FPS_LHAND 0x060051F0
  62. #define Offsets_ADULT_LINK_LUT_DL_FPS_RFOREARM 0x060051F8
  63. #define Offsets_ADULT_LINK_LUT_DL_FPS_RHAND 0x06005200
  64. #define Offsets_ADULT_LINK_LUT_DL_FPS_HOOKSHOT 0x06005208
  65. #define Offsets_ADULT_LINK_LUT_DL_HOOKSHOT_CHAIN 0x06005210
  66. #define Offsets_ADULT_LINK_LUT_DL_HOOKSHOT_HOOK 0x06005218
  67. #define Offsets_ADULT_LINK_LUT_DL_HOOKSHOT_AIM 0x06005220
  68. #define Offsets_ADULT_LINK_LUT_DL_BOW_STRING 0x06005228
  69. #define Offsets_ADULT_LINK_LUT_DL_BLADEBREAK 0x06005230
  70. #define Offsets_ADULT_LINK_LUT_DL_SWORD_SHEATHED 0x06005238
  71. #define Offsets_ADULT_LINK_LUT_DL_SHIELD_HYLIAN_BACK 0x06005258
  72. #define Offsets_ADULT_LINK_LUT_DL_SHIELD_MIRROR_BACK 0x06005268
  73. #define Offsets_ADULT_LINK_LUT_DL_SWORD_SHIELD_HYLIAN 0x06005278
  74. #define Offsets_ADULT_LINK_LUT_DL_SWORD_SHIELD_MIRROR 0x06005288
  75. #define Offsets_ADULT_LINK_LUT_DL_SHEATH0_HYLIAN 0x06005298
  76. #define Offsets_ADULT_LINK_LUT_DL_SHEATH0_MIRROR 0x060052A8
  77. #define Offsets_ADULT_LINK_LUT_DL_LFIST_SWORD 0x060052B8
  78. #define Offsets_ADULT_LINK_LUT_DL_LFIST_LONGSWORD 0x060052D0
  79. #define Offsets_ADULT_LINK_LUT_DL_LFIST_LONGSWORD_BROKEN 0x060052E8
  80. #define Offsets_ADULT_LINK_LUT_DL_LFIST_HAMMER 0x06005300
  81. #define Offsets_ADULT_LINK_LUT_DL_RFIST_SHIELD_HYLIAN 0x06005310
  82. #define Offsets_ADULT_LINK_LUT_DL_RFIST_SHIELD_MIRROR 0x06005320
  83. #define Offsets_ADULT_LINK_LUT_DL_RFIST_BOW 0x06005330
  84. #define Offsets_ADULT_LINK_LUT_DL_RFIST_HOOKSHOT 0x06005340
  85. #define Offsets_ADULT_LINK_LUT_DL_RHAND_OCARINA_TIME 0x06005350
  86. #define Offsets_ADULT_LINK_LUT_DL_FPS_RHAND_BOW 0x06005360
  87. #define Offsets_ADULT_LINK_LUT_DL_FPS_LHAND_HOOKSHOT 0x06005370
  88.  
  89. #define Offsets_CHILD_LINK_LUT_DL_SHIELD_DEKU 0x060050D0
  90. #define Offsets_CHILD_LINK_LUT_DL_WAIST 0x060050D8
  91. #define Offsets_CHILD_LINK_LUT_DL_RTHIGH 0x060050E0
  92. #define Offsets_CHILD_LINK_LUT_DL_RSHIN 0x060050E8
  93. #define Offsets_CHILD_LINK_LUT_DL_RFOOT 0x060050F0
  94. #define Offsets_CHILD_LINK_LUT_DL_LTHIGH 0x060050F8
  95. #define Offsets_CHILD_LINK_LUT_DL_LSHIN 0x06005100
  96. #define Offsets_CHILD_LINK_LUT_DL_LFOOT 0x06005108
  97. #define Offsets_CHILD_LINK_LUT_DL_HEAD 0x06005110
  98. #define Offsets_CHILD_LINK_LUT_DL_HAT 0x06005118
  99. #define Offsets_CHILD_LINK_LUT_DL_COLLAR 0x06005120
  100. #define Offsets_CHILD_LINK_LUT_DL_LSHOULDER 0x06005128
  101. #define Offsets_CHILD_LINK_LUT_DL_LFOREARM 0x06005130
  102. #define Offsets_CHILD_LINK_LUT_DL_RSHOULDER 0x06005138
  103. #define Offsets_CHILD_LINK_LUT_DL_RFOREARM 0x06005140
  104. #define Offsets_CHILD_LINK_LUT_DL_TORSO 0x06005148
  105. #define Offsets_CHILD_LINK_LUT_DL_LHAND 0x06005150
  106. #define Offsets_CHILD_LINK_LUT_DL_LFIST 0x06005158
  107. #define Offsets_CHILD_LINK_LUT_DL_LHAND_BOTTLE 0x06005160
  108. #define Offsets_CHILD_LINK_LUT_DL_RHAND 0x06005168
  109. #define Offsets_CHILD_LINK_LUT_DL_RFIST 0x06005170
  110. #define Offsets_CHILD_LINK_LUT_DL_SWORD_SHEATH 0x06005178
  111. #define Offsets_CHILD_LINK_LUT_DL_SWORD_HILT 0x06005180
  112. #define Offsets_CHILD_LINK_LUT_DL_SWORD_BLADE 0x06005188
  113. #define Offsets_CHILD_LINK_LUT_DL_SLINGSHOT 0x06005190
  114. #define Offsets_CHILD_LINK_LUT_DL_OCARINA_FAIRY 0x06005198
  115. #define Offsets_CHILD_LINK_LUT_DL_OCARINA_TIME 0x060051A0
  116. #define Offsets_CHILD_LINK_LUT_DL_DEKU_STICK 0x060051A8
  117. #define Offsets_CHILD_LINK_LUT_DL_BOOMERANG 0x060051B0
  118. #define Offsets_CHILD_LINK_LUT_DL_SHIELD_HYLIAN_BACK 0x060051B8
  119. #define Offsets_CHILD_LINK_LUT_DL_BOTTLE 0x060051C0
  120. #define Offsets_CHILD_LINK_LUT_DL_MASTER_SWORD 0x060051C8
  121. #define Offsets_CHILD_LINK_LUT_DL_GORON_BRACELET 0x060051D0
  122. #define Offsets_CHILD_LINK_LUT_DL_FPS_RIGHT_ARM 0x060051D8
  123. #define Offsets_CHILD_LINK_LUT_DL_SLINGSHOT_STRING 0x060051E0
  124. #define Offsets_CHILD_LINK_LUT_DL_MASK_BUNNY 0x060051E8
  125. #define Offsets_CHILD_LINK_LUT_DL_MASK_GERUDO 0x060051F0
  126. #define Offsets_CHILD_LINK_LUT_DL_MASK_GORON 0x060051F8
  127. #define Offsets_CHILD_LINK_LUT_DL_MASK_KEATON 0x06005200
  128. #define Offsets_CHILD_LINK_LUT_DL_MASK_SPOOKY 0x06005208
  129. #define Offsets_CHILD_LINK_LUT_DL_MASK_TRUTH 0x06005210
  130. #define Offsets_CHILD_LINK_LUT_DL_MASK_ZORA 0x06005218
  131. #define Offsets_CHILD_LINK_LUT_DL_MASK_SKULL 0x06005220
  132. #define Offsets_CHILD_LINK_DL_SWORD_SHEATHED 0x06005228
  133. #define Offsets_CHILD_LINK_LUT_DL_SWORD_SHEATHED 0x06005248
  134. #define Offsets_CHILD_LINK_DL_SHIELD_DEKU_ODD 0x06005250
  135. #define Offsets_CHILD_LINK_LUT_DL_SHIELD_DEKU_ODD 0x06005260
  136. #define Offsets_CHILD_LINK_DL_SHIELD_DEKU_BACK 0x06005268
  137. #define Offsets_CHILD_LINK_LUT_DL_SHIELD_DEKU_BACK 0x06005278
  138. #define Offsets_CHILD_LINK_DL_SWORD_SHIELD_HYLIAN 0x06005280
  139. #define Offsets_CHILD_LINK_LUT_DL_SWORD_SHIELD_HYLIAN 0x06005290
  140. #define Offsets_CHILD_LINK_DL_SWORD_SHIELD_DEKU 0x06005298
  141. #define Offsets_CHILD_LINK_LUT_DL_SWORD_SHIELD_DEKU 0x060052A8
  142. #define Offsets_CHILD_LINK_DL_SHEATH0_HYLIAN 0x060052B0
  143. #define Offsets_CHILD_LINK_LUT_DL_SHEATH0_HYLIAN 0x060052C0
  144. #define Offsets_CHILD_LINK_DL_SHEATH0_DEKU 0x060052C8
  145. #define Offsets_CHILD_LINK_LUT_DL_SHEATH0_DEKU 0x060052D8
  146. #define Offsets_CHILD_LINK_DL_LFIST_SWORD 0x060052E0
  147. #define Offsets_CHILD_LINK_LUT_DL_LFIST_SWORD 0x060052F8
  148. #define Offsets_CHILD_LINK_DL_LHAND_PEDESTALSWORD 0x06005300
  149. #define Offsets_CHILD_LINK_LUT_DL_LHAND_PEDESTALSWORD 0x06005310
  150. #define Offsets_CHILD_LINK_DL_LFIST_BOOMERANG 0x06005318
  151. #define Offsets_CHILD_LINK_LUT_DL_LFIST_BOOMERANG 0x06005328
  152. #define Offsets_CHILD_LINK_DL_RFIST_SHIELD_DEKU 0x06005330
  153. #define Offsets_CHILD_LINK_LUT_DL_RFIST_SHIELD_DEKU 0x06005340
  154. #define Offsets_CHILD_LINK_DL_RFIST_SLINGSHOT 0x06005348
  155. #define Offsets_CHILD_LINK_LUT_DL_RFIST_SLINGSHOT 0x06005358
  156. #define Offsets_CHILD_LINK_DL_RHAND_OCARINA_FAIRY 0x06005360
  157. #define Offsets_CHILD_LINK_LUT_DL_RHAND_OCARINA_FAIRY 0x06005370
  158. #define Offsets_CHILD_LINK_DL_RHAND_OCARINA_TIME 0x06005378
  159. #define Offsets_CHILD_LINK_LUT_DL_RHAND_OCARINA_TIME 0x06005388
  160. #define Offsets_CHILD_LINK_DL_FPS_RARM_SLINGSHOT 0x06005390
  161. #define Offsets_CHILD_LINK_LUT_DL_FPS_RARM_SLINGSHOT 0x060053A0
  162.  
  163. typedef struct Piece {
  164.   const char* key;
  165.   int LUT;
  166.   int offset;
  167. } Piece;
  168.  
  169. typedef struct Skip {
  170.   const char* key;
  171.   int start;
  172.   int end;
  173. } Skip;
  174.  
  175. typedef struct Limb {
  176.   int x;
  177.   int y;
  178.   int z;
  179. } Limb;
  180.  
  181. // Adult model pieces and their offsets, both in the LUT and in vanilla
  182. const Piece AdultPieces[] = {
  183.   {"Sheath", Offsets_ADULT_LINK_LUT_DL_SWORD_SHEATH, 0x249D8},
  184.   {"FPS.Hookshot", Offsets_ADULT_LINK_LUT_DL_FPS_HOOKSHOT, 0x2A738},
  185.   {"Hilt.2", Offsets_ADULT_LINK_LUT_DL_SWORD_HILT, 0x22060}, // 0x21F78 + 0xE8, skips blade
  186.   {"Hilt.3", Offsets_ADULT_LINK_LUT_DL_LONGSWORD_HILT, 0x238C8},
  187.   {"Blade.2", Offsets_ADULT_LINK_LUT_DL_SWORD_BLADE, 0x21F78},
  188.   {"Hookshot.Spike", Offsets_ADULT_LINK_LUT_DL_HOOKSHOT_HOOK, 0x2B288},
  189.   {"Hookshot", Offsets_ADULT_LINK_LUT_DL_HOOKSHOT, 0x24D70},
  190.   {"Fist.L", Offsets_ADULT_LINK_LUT_DL_LFIST, 0x21CE8},
  191.   {"Fist.R", Offsets_ADULT_LINK_LUT_DL_RFIST, 0x226E0},
  192.   {"FPS.Forearm.L", Offsets_ADULT_LINK_LUT_DL_FPS_LFOREARM, 0x29FA0},
  193.   {"FPS.Forearm.R", Offsets_ADULT_LINK_LUT_DL_FPS_RFOREARM, 0x29918},
  194.   {"Gauntlet.Fist.L", Offsets_ADULT_LINK_LUT_DL_UPGRADE_LFIST, 0x25438},
  195.   {"Gauntlet.Fist.R", Offsets_ADULT_LINK_LUT_DL_UPGRADE_RFIST, 0x257B8},
  196.   {"Gauntlet.Forearm.L", Offsets_ADULT_LINK_LUT_DL_UPGRADE_LFOREARM, 0x25218},
  197.   {"Gauntlet.Forearm.R", Offsets_ADULT_LINK_LUT_DL_UPGRADE_RFOREARM, 0x25598},
  198.   {"Gauntlet.Hand.L", Offsets_ADULT_LINK_LUT_DL_UPGRADE_LHAND, 0x252D8},
  199.   {"Gauntlet.Hand.R", Offsets_ADULT_LINK_LUT_DL_UPGRADE_RHAND, 0x25658},
  200.   {"Bottle.Hand.L", Offsets_ADULT_LINK_LUT_DL_LHAND_BOTTLE, 0x29600},
  201.   {"FPS.Hand.L", Offsets_ADULT_LINK_LUT_DL_FPS_LHAND, 0x24B58},
  202.   {"FPS.Hand.R", Offsets_ADULT_LINK_LUT_DL_FPS_RHAND, 0x29C20},
  203.   {"Bow.String", Offsets_ADULT_LINK_LUT_DL_BOW_STRING, 0x2B108},
  204.   {"Bow", Offsets_ADULT_LINK_LUT_DL_BOW, 0x22DA8},
  205.   {"Blade.3.Break", Offsets_ADULT_LINK_LUT_DL_BLADEBREAK, 0x2BA38},
  206.   {"Blade.3", Offsets_ADULT_LINK_LUT_DL_LONGSWORD_BLADE, 0x23A28}, // 0x238C8 + 0x160, skips hilt
  207.   {"Bottle", Offsets_ADULT_LINK_LUT_DL_BOTTLE, 0x2AD58},
  208.   {"Broken.Blade.3", Offsets_ADULT_LINK_LUT_DL_LONGSWORD_BROKEN,
  209.     0x23EB0}, // 0x23D50 + 0x160, skips hilt
  210.   {"Foot.2.L", Offsets_ADULT_LINK_LUT_DL_BOOT_LIRON, 0x25918},
  211.   {"Foot.2.R", Offsets_ADULT_LINK_LUT_DL_BOOT_RIRON, 0x25A60},
  212.   {"Foot.3.L", Offsets_ADULT_LINK_LUT_DL_BOOT_LHOVER, 0x25BA8},
  213.   {"Foot.3.R", Offsets_ADULT_LINK_LUT_DL_BOOT_RHOVER, 0x25DB0},
  214.   {"Hammer", Offsets_ADULT_LINK_LUT_DL_HAMMER, 0x233E0},
  215.   {"Hookshot.Aiming.Reticule", Offsets_ADULT_LINK_LUT_DL_HOOKSHOT_AIM, 0x2CB48},
  216.   {"Hookshot.Chain", Offsets_ADULT_LINK_LUT_DL_HOOKSHOT_CHAIN, 0x2AFF0},
  217.   {"Ocarina.2", Offsets_ADULT_LINK_LUT_DL_OCARINA_TIME, 0x248D8}, // 0x24698 + 0x240, skips hand
  218.   {"Shield.2", Offsets_ADULT_LINK_LUT_DL_SHIELD_HYLIAN, 0x22970},
  219.   {"Shield.3", Offsets_ADULT_LINK_LUT_DL_SHIELD_MIRROR, 0x241C0},
  220.   {"Limb 1", Offsets_ADULT_LINK_LUT_DL_WAIST, 0x35330},
  221.   {"Limb 3", Offsets_ADULT_LINK_LUT_DL_RTHIGH, 0x35678},
  222.   {"Limb 4", Offsets_ADULT_LINK_LUT_DL_RSHIN, 0x358B0},
  223.   {"Limb 5", Offsets_ADULT_LINK_LUT_DL_RFOOT, 0x358B0},
  224.   {"Limb 6", Offsets_ADULT_LINK_LUT_DL_LTHIGH, 0x35CB8},
  225.   {"Limb 7", Offsets_ADULT_LINK_LUT_DL_LSHIN, 0x35EF0},
  226.   {"Limb 8", Offsets_ADULT_LINK_LUT_DL_LFOOT, 0x361A0},
  227.   {"Limb 10", Offsets_ADULT_LINK_LUT_DL_HEAD, 0x365E8},
  228.   {"Limb 11", Offsets_ADULT_LINK_LUT_DL_HAT, 0x36D30},
  229.   {"Limb 12", Offsets_ADULT_LINK_LUT_DL_COLLAR, 0x362F8},
  230.   {"Limb 13", Offsets_ADULT_LINK_LUT_DL_LSHOULDER, 0x37210},
  231.   {"Limb 14", Offsets_ADULT_LINK_LUT_DL_LFOREARM, 0x373D8},
  232.   {"Limb 15", Offsets_ADULT_LINK_LUT_DL_LHAND, 0x21AA8},
  233.   {"Limb 16", Offsets_ADULT_LINK_LUT_DL_RSHOULDER, 0x36E58},
  234.   {"Limb 17", Offsets_ADULT_LINK_LUT_DL_RFOREARM, 0x37018},
  235.   {"Limb 18", Offsets_ADULT_LINK_LUT_DL_RHAND, 0x22498},
  236.   {"Limb 20", Offsets_ADULT_LINK_LUT_DL_TORSO, 0x363B8},
  237. };
  238.  
  239. // Note: Some skips which can be implemented by skipping the beginning portion of the model
  240. // rather than specifying those indices here, simply have their offset in the table above
  241. // increased by whatever amount of starting indices would be skipped.
  242. const Skip adultSkips[] = {
  243.   {"FPS.Hookshot", 0x2F0, 0x618},
  244.   {"Hilt.2", 0x1E8, 0x430},
  245.   {"Hilt.3", 0x160, 0x480},
  246.   {"Blade.2", 0xE8, 0x518},
  247.   {"Hookshot", 0x250, 0x4A0},
  248.   {"Bow", 0x158, 0x3B0},
  249.   {"Blade.3", 0xB8, 0x320},
  250.   {"Broken.Blade.3", 0xA0, 0x308},
  251.   {"Hammer", 0x278, 0x4E0},
  252.   {"Shield.2", 0x158, 0x2B8}, // Fist is in 2 pieces
  253.   {"Shield.2", 0x3A8, 0x430}, // Fist is in 2 pieces
  254.   {"Shield.3", 0x1B8, 0x3E8},
  255. };
  256.  
  257. const Limb adultSkeleton[] = {
  258.   {0xFFC7, 0x0D31, 0x0000}, // Limb 0
  259.   {0x0000, 0x0000, 0x0000}, // Limb 1
  260.   {0x03B1, 0x0000, 0x0000}, // Limb 2
  261.   {0xFE71, 0x0045, 0xFF07}, // Limb 3
  262.   {0x051A, 0x0000, 0x0000}, // Limb 4
  263.   {0x04E8, 0x0005, 0x000B}, // Limb 5
  264.   {0xFE74, 0x004C, 0x0108}, // Limb 6
  265.   {0x0518, 0x0000, 0x0000}, // Limb 7
  266.   {0x04E9, 0x0006, 0x0003}, // Limb 8
  267.   {0x0000, 0x0015, 0xFFF9}, // Limb 9
  268.   {0x0570, 0xFEFD, 0x0000}, // Limb 10
  269.   {0xFED6, 0xFD44, 0x0000}, // Limb 11
  270.   {0x0000, 0x0000, 0x0000}, // Limb 12
  271.   {0x040F, 0xFF54, 0x02A8}, // Limb 13
  272.   {0x0397, 0x0000, 0x0000}, // Limb 14
  273.   {0x02F2, 0x0000, 0x0000}, // Limb 15
  274.   {0x040F, 0xFF53, 0xFD58}, // Limb 16
  275.   {0x0397, 0x0000, 0x0000}, // Limb 17
  276.   {0x02F2, 0x0000, 0x0000}, // Limb 18
  277.   {0x03D2, 0xFD4C, 0x0156}, // Limb 19
  278.   {0x0000, 0x0000, 0x0000}, // Limb 20
  279. };
  280.  
  281. const Piece ChildPieces[] = {
  282.   {"Slingshot.String", Offsets_CHILD_LINK_LUT_DL_SLINGSHOT_STRING, 0x221A8},
  283.   {"Sheath", Offsets_CHILD_LINK_LUT_DL_SWORD_SHEATH, 0x15408},
  284.   {"Blade.2", Offsets_CHILD_LINK_LUT_DL_MASTER_SWORD, 0x15698}, // 0x15540 + 0x158, skips fist
  285.   {"Blade.1", Offsets_CHILD_LINK_LUT_DL_SWORD_BLADE,
  286.     0x14110}, // 0x13F38 + 0x1D8, skips fist and hilt
  287.   {"Boomerang", Offsets_CHILD_LINK_LUT_DL_BOOMERANG, 0x14660},
  288.   {"Fist.L", Offsets_CHILD_LINK_LUT_DL_LFIST, 0x13E18},
  289.   {"Fist.R", Offsets_CHILD_LINK_LUT_DL_RFIST, 0x14320},
  290.   {"Hilt.1", Offsets_CHILD_LINK_LUT_DL_SWORD_HILT, 0x14048}, // 0x13F38 + 0x110, skips fist
  291.   {"Shield.1", Offsets_CHILD_LINK_LUT_DL_SHIELD_DEKU, 0x14440},
  292.   {"Slingshot", Offsets_CHILD_LINK_LUT_DL_SLINGSHOT, 0x15F08}, // 0x15DF0 + 0x118, skips fist
  293.   {"Ocarina.1", Offsets_CHILD_LINK_LUT_DL_OCARINA_FAIRY, 0x15BA8},
  294.   {"Bottle", Offsets_CHILD_LINK_LUT_DL_BOTTLE, 0x18478},
  295.   {"Ocarina.2", Offsets_CHILD_LINK_LUT_DL_OCARINA_TIME, 0x15AB8}, // 0x15958 + 0x160, skips hand
  296.   {"Bottle.Hand.L", Offsets_CHILD_LINK_LUT_DL_LHAND_BOTTLE,
  297.     0x18478}, // Just the bottle, couldn't find one with hand and bottle
  298.   {"GoronBracelet", Offsets_CHILD_LINK_LUT_DL_GORON_BRACELET, 0x16118},
  299.   {"Mask.Bunny", Offsets_CHILD_LINK_LUT_DL_MASK_BUNNY, 0x2CA38},
  300.   {"Mask.Skull", Offsets_CHILD_LINK_LUT_DL_MASK_SKULL, 0x2AD40},
  301.   {"Mask.Spooky", Offsets_CHILD_LINK_LUT_DL_MASK_SPOOKY, 0x2AF70},
  302.   {"Mask.Gerudo", Offsets_CHILD_LINK_LUT_DL_MASK_GERUDO, 0x2B788},
  303.   {"Mask.Goron", Offsets_CHILD_LINK_LUT_DL_MASK_GORON, 0x2B350},
  304.   {"Mask.Keaton", Offsets_CHILD_LINK_LUT_DL_MASK_KEATON, 0x2B060},
  305.   {"Mask.Truth", Offsets_CHILD_LINK_LUT_DL_MASK_TRUTH, 0x2B1F0},
  306.   {"Mask.Zora", Offsets_CHILD_LINK_LUT_DL_MASK_ZORA, 0x2B580},
  307.   {"FPS.Forearm.R", Offsets_CHILD_LINK_LUT_DL_FPS_RIGHT_ARM, 0x18048},
  308.   {"DekuStick", Offsets_CHILD_LINK_LUT_DL_DEKU_STICK, 0x6CC0},
  309.   {"Shield.2", Offsets_CHILD_LINK_LUT_DL_SHIELD_HYLIAN_BACK,
  310.     0x14C30}, // 0x14B40 + 0xF0, skips sheath
  311.   {"Limb 1", Offsets_CHILD_LINK_LUT_DL_WAIST, 0x202A8},
  312.   {"Limb 3", Offsets_CHILD_LINK_LUT_DL_RTHIGH, 0x204F0},
  313.   {"Limb 4", Offsets_CHILD_LINK_LUT_DL_RSHIN, 0x206E8},
  314.   {"Limb 5", Offsets_CHILD_LINK_LUT_DL_RFOOT, 0x20978},
  315.   {"Limb 6", Offsets_CHILD_LINK_LUT_DL_LTHIGH, 0x20AD8},
  316.   {"Limb 7", Offsets_CHILD_LINK_LUT_DL_LSHIN, 0x20CD0},
  317.   {"Limb 8", Offsets_CHILD_LINK_LUT_DL_LFOOT, 0x20F60},
  318.   {"Limb 10", Offsets_CHILD_LINK_LUT_DL_HEAD, 0x21360},
  319.   {"Limb 11", Offsets_CHILD_LINK_LUT_DL_HAT, 0x219B0},
  320.   {"Limb 12", Offsets_CHILD_LINK_LUT_DL_COLLAR, 0x210C0},
  321.   {"Limb 13", Offsets_CHILD_LINK_LUT_DL_LSHOULDER, 0x21E18},
  322.   {"Limb 14", Offsets_CHILD_LINK_LUT_DL_LFOREARM, 0x21FE8},
  323.   {"Limb 15", Offsets_CHILD_LINK_LUT_DL_LHAND, 0x13CB0},
  324.   {"Limb 16", Offsets_CHILD_LINK_LUT_DL_RSHOULDER, 0x21AE8},
  325.   {"Limb 17", Offsets_CHILD_LINK_LUT_DL_RFOREARM, 0x21CB8},
  326.   {"Limb 18", Offsets_CHILD_LINK_LUT_DL_RHAND, 0x141C0},
  327.   {"Limb 20", Offsets_CHILD_LINK_LUT_DL_TORSO, 0x21130},
  328. };
  329.  
  330. const Skip childSkips[] = {
  331.   {"Boomerang", 0x140, 0x240},
  332.   {"Hilt.1", 0xC8, 0x170},
  333.   {"Shield.1", 0x140, 0x218},
  334.   {"Ocarina.1", 0x110, 0x240},
  335. };
  336.  
  337. const Limb childSkeleton[] = {
  338.   {0x0000, 0x0948, 0x0000}, // Limb 0
  339.   {0xFFFC, 0xFF98, 0x0000}, // Limb 1
  340.   {0x025F, 0x0000, 0x0000}, // Limb 2
  341.   {0xFF54, 0x0032, 0xFF42}, // Limb 3
  342.   {0x02B9, 0x0000, 0x0000}, // Limb 4
  343.   {0x0339, 0x0005, 0x000B}, // Limb 5
  344.   {0xFF56, 0x0039, 0x00C0}, // Limb 6
  345.   {0x02B7, 0x0000, 0x0000}, // Limb 7
  346.   {0x0331, 0x0008, 0x0004}, // Limb 8
  347.   {0x0000, 0xFF99, 0xFFF9}, // Limb 9
  348.   {0x03E4, 0xFF37, 0xFFFF}, // Limb 10
  349.   {0xFE93, 0xFD62, 0x0000}, // Limb 11
  350.   {0x0000, 0x0000, 0x0000}, // Limb 12
  351.   {0x02B8, 0xFF51, 0x01D2}, // Limb 13
  352.   {0x0245, 0x0000, 0x0000}, // Limb 14
  353.   {0x0202, 0x0000, 0x0000}, // Limb 15
  354.   {0x02B8, 0xFF51, 0xFE2E}, // Limb 16
  355.   {0x0241, 0x0000, 0x0000}, // Limb 17
  356.   {0x020D, 0x0000, 0x0000}, // Limb 18
  357.   {0x0291, 0xFDF5, 0x016F}, // Limb 19
  358.   {0x0000, 0x0000, 0x0000}, // Limb 20
  359. };
  360.  
  361. // Misc. constants
  362. const uint BASE_OFFSET = 0x06000000;
  363. const uint LUT_START = 0x00005000;
  364. const uint LUT_END = 0x00005800;
  365. const uint PRE_CONSTANT_START = 0X0000500C;
  366.  
  367. const uint ADULT_START = 0x00F86000;
  368. const uint ADULT_SIZE = 0x00037800;
  369. const uint ADULT_HIERARCHY = 0x06005380;
  370. const uint ADULT_POST_START = 0x00005238;
  371.  
  372. const uint CHILD_START = 0x00FBE000;
  373. const uint CHILD_SIZE = 0x0002CF80;
  374. const uint CHILD_HIERARCHY = 0x060053A8;
  375. const uint CHILD_POST_START = 0x00005228;
  376.  
  377. const int endianVal = 1;
  378. uint EndianSwap32(uint val) {
  379.   bool smallEndian = ((*(char*)&endianVal) != 0);
  380.   if (smallEndian) {
  381.     uint new_val = 0;
  382.     for (int i = 0; i < 4; i++) {
  383.       new_val <<= 8;
  384.       new_val |= (val & 0x00FF);
  385.       val = val >> 8;
  386.     }
  387.     return new_val;
  388.   }
  389.   return val;
  390. }
  391.  
  392. uint EndianSwap16(ushort val) {
  393.   bool smallEndian = ((*(char*)&endianVal) != 0);
  394.   if (smallEndian) {
  395.     ushort new_val = 0;
  396.     for (int i = 0; i < 2; i++) {
  397.       new_val <<= 8;
  398.       new_val |= (val & 0x00FF);
  399.       val = val >> 8;
  400.     }
  401.     return new_val;
  402.   }
  403.   return val;
  404. }
  405.  
  406. typedef struct IntEntry {
  407.   int key;
  408.   int value;
  409.   struct IntEntry* next;
  410. } IntEntry;
  411.  
  412. typedef struct IntMap {
  413.   IntEntry* hashTable[HASHSIZE];
  414. } IntMap;
  415.  
  416. void IntMap_Init(IntMap* map) {
  417.   for (int i = 0; i < HASHSIZE; i++) {
  418.     map->hashTable[i] = NULL;
  419.   }
  420. }
  421.  
  422. int hash(int key) { return (key * 31) % HASHSIZE; }
  423.  
  424. bool IntMap_has(IntMap* map, int key) {
  425.   IntEntry* entry = map->hashTable[hash(key)];
  426.   for (; entry != NULL; entry = entry->next) {
  427.     if (key == entry->key) {
  428.       return true;
  429.     }
  430.   }
  431.   return false;
  432. }
  433.  
  434. int IntMap_get(IntMap* map, int key) {
  435.   IntEntry* entry = map->hashTable[hash(key)];
  436.   for (; entry != NULL; entry = entry->next) {
  437.     if (key == entry->key) {
  438.       return entry->value;
  439.     }
  440.   }
  441.   return 0;
  442. }
  443.  
  444. void IntMap_set(IntMap* map, int key, int value) {
  445.   bool found = false;
  446.   IntEntry* entry = map->hashTable[hash(key)];
  447.   for (; entry != NULL; entry = entry->next) {
  448.     if (key == entry->key) {
  449.       found = true;
  450.       break;
  451.     }
  452.   }
  453.  
  454.   if (!found) {
  455.     entry = (IntEntry*)malloc(sizeof(entry));
  456.     if (entry == NULL) {
  457.       return;
  458.     }
  459.     entry->key = key;
  460.     int index = hash(key);
  461.     entry->next = map->hashTable[index];
  462.     map->hashTable[index] = entry;
  463.   }
  464.   entry->value = value;
  465. }
  466.  
  467. void IntMap_free(IntMap* map) {
  468.   for (int i = 0; i < HASHSIZE; i++) {
  469.     IntEntry* entry = map->hashTable[i];
  470.     IntEntry* nextentry;
  471.     while (entry != NULL) {
  472.       nextentry = entry->next;
  473.       free(entry);
  474.       entry = nextentry;
  475.     }
  476.     map->hashTable[i] = NULL;
  477.   }
  478. }
  479.  
  480. typedef struct IntMapIterator {
  481.   IntMap* map;
  482.   int tableIndex;
  483.   IntEntry* next;
  484. } IntMapIterator;
  485.  
  486. void IntMapIterator_Init(IntMapIterator* it, IntMap* map) {
  487.   it->map = map;
  488.   it->tableIndex = 0;
  489.   it->next = NULL;
  490. }
  491.  
  492. IntEntry* IntMapIterator_Next(IntMapIterator* it) {
  493.   if (it->tableIndex >= HASHSIZE) {
  494.     return NULL;
  495.   }
  496.  
  497.   for (; it->tableIndex < HASHSIZE; it->tableIndex++) {
  498.  
  499.     if (it->next == NULL) {
  500.       it->next = it->map->hashTable[it->tableIndex];
  501.       if (it->next == NULL) {
  502.         continue;
  503.       }
  504.       return it->next;
  505.     }
  506.  
  507.     it->next = it->next->next;
  508.     if (it->next == NULL) {
  509.       continue;
  510.     }
  511.     return it->next;
  512.   }
  513.   return NULL;
  514. }
  515.  
  516. typedef struct Vector {
  517.   uint8_t* data;
  518.   int len;
  519.   int size;
  520. } Vector;
  521.  
  522. void Vector_Init(Vector* vector) {
  523.   vector->len = 0;
  524.   vector->size = 32;
  525.   vector->data = (uint8_t*)malloc(vector->size);
  526.   if (vector->data == NULL) {
  527.     vector->size = 0;
  528.   }
  529. }
  530.  
  531. bool Vector_grow(Vector* vector) {
  532.   int size_new = vector->size * 2;
  533.   if (vector->size == 0) {
  534.     size_new = 32;
  535.   }
  536.   uint8_t* data_new = (uint8_t*)malloc(size_new);
  537.   if (data_new == NULL) {
  538.     return false;
  539.   }
  540.   if (vector->size > 0) {
  541.     memcpy(data_new, vector->data, vector->size);
  542.   }
  543.  
  544.   if (vector->data != NULL)
  545.     free(vector->data);
  546.  
  547.   vector->data = data_new;
  548.   vector->size = size_new;
  549.   return true;
  550. }
  551.  
  552. void Vector_push(Vector* vector, uint8_t b) {
  553.   while (vector->len >= vector->size) {
  554.     if (!Vector_grow(vector)) {
  555.       return;
  556.     }
  557.   }
  558.  
  559.   vector->data[vector->len] = b;
  560.   vector->len++;
  561. }
  562.  
  563. uint8_t Vector_pop(Vector* vector) {
  564.   if (vector->len == 0) {
  565.     return 0;
  566.   }
  567.  
  568.   uint8_t val = vector->data[vector->len - 1];
  569.   vector->len--;
  570.   return val;
  571. }
  572.  
  573. void Vector_extend(Vector* vector, const uint8_t* new_data, int length) {
  574.   while ((vector->len + length) >= vector->size) {
  575.     if (!Vector_grow(vector)) {
  576.       return;
  577.     }
  578.   }
  579.  
  580.   memcpy(vector->data + vector->len, new_data, length);
  581.   vector->len += length;
  582. }
  583.  
  584. void Vector_free(Vector* vector) {
  585.   if (vector->data != NULL) {
  586.     free(vector->data);
  587.     vector->data = NULL;
  588.   }
  589.   vector->size = 0;
  590.   vector->len = 0;
  591. }
  592.  
  593. typedef enum ModelBaseName {
  594.   Code,
  595.   Player,
  596.   Hook,
  597.   Shield,
  598.   Stick,
  599.   GraveyardKid,
  600.   Guard,
  601.   RunningMan
  602. } ModelBaseName;
  603.  
  604. // Used for writer model pointers to the rom in place of the vanilla pointers
  605. typedef struct ModelPointerWriter {
  606.   uint8_t* rom;
  607.   int offset;
  608.   int advance;
  609.   int base;
  610. } ModelPointerWriter;
  611.  
  612. void ModelPointerWriter_SetBase(ModelPointerWriter* writer, ModelBaseName base_name) {
  613.   switch (base_name) {
  614.     case Code:
  615.       writer->base = 0x00A87000; // start of code
  616.       break;
  617.     case Player:
  618.       writer->base = 0x00BCDB70;
  619.       break;
  620.     case Hook:
  621.       writer->base = 0x00CAD2C0;
  622.       break;
  623.     case Shield:
  624.       writer->base = 0x00DB1F40;
  625.       break;
  626.     case Stick:
  627.       writer->base = 0x00EAD0F0;
  628.       break;
  629.     case GraveyardKid:
  630.       writer->base = 0x00E60920;
  631.       break;
  632.     case Guard:
  633.       writer->base = 0x00D1A690;
  634.       break;
  635.     case RunningMan:
  636.       writer->base = 0x00E50440;
  637.       break;
  638.   }
  639. }
  640.  
  641. void ModelPointerWriter_Init(ModelPointerWriter* writer) {
  642.   writer->offset = 0;
  643.   writer->advance = 4;
  644.   writer->base = 0;
  645.   ModelPointerWriter_SetBase(writer, Code);
  646. }
  647. void ModelPointerWriter_GoTo(ModelPointerWriter* writer, int dest) { writer->offset = dest; }
  648.  
  649. void ModelPointerWriter_SetAdvance(ModelPointerWriter* writer, int adv) { writer->advance = adv; }
  650.  
  651. int ModelPointerWriter_GetAddress(ModelPointerWriter* writer) {
  652.   return writer->base + writer->offset;
  653. }
  654.  
  655. void ModelPointerWriter_WriteModelData(ModelPointerWriter* writer, uint data) {
  656.   *(uint*)(writer->rom + ModelPointerWriter_GetAddress(writer)) = EndianSwap32(data);
  657.   writer->offset += writer->advance;
  658. }
  659.  
  660. void ModelPointerWriter_WriteModelData16(ModelPointerWriter* writer, ushort data) {
  661.   *(ushort*)(writer->rom + ModelPointerWriter_GetAddress(writer)) = EndianSwap16(data);
  662.   writer->offset += 2;
  663. }
  664.  
  665. void ModelPointerWriter_WriteModelDataHi(ModelPointerWriter* writer, uint data) {
  666.   ModelPointerWriter_WriteModelData16(writer, (ushort)(data >> 16));
  667. }
  668.  
  669. void ModelPointerWriter_WriteModelDataLo(ModelPointerWriter* writer, uint data) {
  670.   ModelPointerWriter_WriteModelData16(writer, (ushort)data);
  671. }
  672.  
  673. // Either return the starting index of the requested data (when start == 0)
  674. // or the offset of the element in the footer, if it exists (start > 0)
  675. int scan(const uint8_t* bytes, int byteslen, const char* data, int datalen, int start) {
  676.   int dataindex = 0;
  677.  
  678.   if ((bytes == NULL) || (byteslen == 0) || (data == NULL)) {
  679.     // printf("[C]Scan data empty, abort\n");
  680.     return -1;
  681.   }
  682.  
  683.   bool isStr = false;
  684.   if (datalen < 0) {
  685.     isStr = true;
  686.     datalen = strlen(data);
  687.   }
  688.  
  689.   for (int i = start; i < byteslen; i++) {
  690.     // Byte matches next byte in string
  691.     if (bytes[i] == (uint8_t)data[dataindex]) {
  692.       dataindex += 1;
  693.       // Special case: Bottle, Bow, Slingshot, Fist.L, and Fist.R are subsets of
  694.       // Bottle.Hand.L, Bow.String, Slingshot.String, Gauntlet.Fist.L, and Gauntlet.Fist.R
  695.       // respectively And Hookshot which is a subset of Hookshot.Spike, Hookshot.Chain,
  696.       // Hookshot.Aiming.Reticule This leads to false positives. So if the next byte is . (0x2E)
  697.       // then reset the count.
  698.       if ((isStr) && (i < (byteslen - 1)) && (bytes[i + 1] == 0x2E) &&
  699.           ((strncmp(data, "Bottle", datalen) == 0) || (strncmp(data, "Bow", datalen) == 0) ||
  700.             (strncmp(data, "Slingshot", datalen) == 0) ||
  701.             (strncmp(data, "Hookshot", datalen) == 0) || (strncmp(data, "Fist.L", datalen) == 0) ||
  702.             (strncmp(data, "Fist.R", datalen) == 0) || (strncmp(data, "Blade.3", datalen) == 0))) {
  703.  
  704.         // Blade.3 is even wackier, as it is a subset of Blade.3.Break,
  705.         // and also a forward subset of Broken.Blade.3, and has a period in it
  706.         if (strncmp(data, "Blade.3", datalen) == 0) {
  707.           bool resetCount = false;
  708.           // If current byte is the "e" in "Blade.3", the period detected is the expected one- Carry
  709.           // on If it isn't, then reset the count
  710.           if (bytes[i] != 0x65) {
  711.             resetCount = true;
  712.           }
  713.           // Make sure i is large enough, "Broken.Blad" is 11 chars (remember we're currently at the
  714.           // e)
  715.           if (!resetCount && (i > 10)) {
  716.             // Check if "Broken." immediately preceeds this string
  717.             if (strncmp((const char*)(bytes - 11), "Broken.", 7) == 0) {
  718.               resetCount = true;
  719.             }
  720.           }
  721.           if (resetCount) {
  722.             dataindex = 0;
  723.           }
  724.         }
  725.  
  726.         // Fist.L and Fist.R are forward subsets of Gauntlet.Fist.x, check for "Gauntlet."
  727.         // "Gauntlet.Fis" is 12 chars (we are currently at the t)
  728.         else if (((strncmp(data, "Fist.L", datalen) == 0) ||
  729.                    (strncmp(data, "Fist.R", datalen) == 0)) &&
  730.                  (i > 11)) {
  731.           // Check if "Gauntlet." immediately preceeds this string
  732.           if (strncmp((const char*)(bytes - 12), "Gauntlet.", 8) == 0) {
  733.             dataindex = 0;
  734.           }
  735.         }
  736.  
  737.         // Default case for Bottle, Bow, Slingshot, Hookshot, reset count
  738.         else {
  739.           dataindex = 0;
  740.         }
  741.       }
  742.  
  743.       // Special case for Hookshot: Forward subset of FPS.Hookshot, "FPS." is 4 chars
  744.       // (Blade.3 and fists can check in the previous stanza since a . will be encountered at some
  745.       // point)
  746.       if ((isStr) && (strncmp(data, "Hookshot", datalen) == 0) && (dataindex == 1) && (i > 3)) {
  747.         // Check if "FPS." immediately preceeds this string
  748.         if (strncmp((const char*)(bytes - 4), "FPS.", 4) == 0) {
  749.           dataindex = 0;
  750.         }
  751.       }
  752.  
  753.       // All bytes have been found, so a match
  754.       if (dataindex == datalen) {
  755.         // If start is 0 then looking for the footer, return the index
  756.         if (start == 0) {
  757.           return i + 1;
  758.         }
  759.         // Else, we want to know the offset, which will be after the footer and 1 padding byte
  760.         else {
  761.           i += 2;
  762.           return EndianSwap32(*(uint*)(bytes + i));
  763.         }
  764.       }
  765.     }
  766.  
  767.     // Match has been broken, reset to start of string
  768.     else {
  769.       dataindex = 0;
  770.     }
  771.   }
  772.  
  773.   // printf("[C]Scan found nothing, aborting\n");
  774.   return -1;
  775. }
  776.  
  777. // Follows pointers from the LUT until finding the actual DList, and returns the offset of the DList
  778. int unwrap(uint8_t* zobj, int address) {
  779.   // An entry in the LUT will look something like 0xDE 01 0000 06014050
  780.   // Only the last 3 bytes should be necessary.
  781.   uint data = EndianSwap32(*(uint*)(zobj + address + 4)) & 0x00FFFFFF;
  782.  
  783.   // If the data here points to another entry in the LUT, keep searching until
  784.   // an address outside the table is found.
  785.   while ((LUT_START <= data) && (data <= LUT_END)) {
  786.     address = data;
  787.     data = EndianSwap32(*(uint*)(zobj + address + 4)) & 0x00FFFFFF;
  788.   }
  789.   return address;
  790. }
  791.  
  792. // Used to overwrite pointers in the displaylist with new ones
  793. void WriteDLPointer(uint8_t* dl, int index, uint data) {
  794.   *((uint*)(dl + index)) = EndianSwap32(data);
  795. }
  796.  
  797. // An extensive function which loads pieces from the vanilla Link model to add to the user-provided
  798. // zobj Based on
  799. // https://github.com/hylian-modding/ML64-Z64Lib/blob/master/cores/Z64Lib/API/zzoptimize.ts function
  800. // optimize()
  801. Vector LoadVanilla(uint8_t* rom, int rebase, int linkstart, int linksize, const Piece pieces[],
  802.   bool missing[], uint DLOffsets[], int pieceCount, const Skip skips[], int skipCount) {
  803.  
  804.   // Get vanilla "zobj" of Link's model
  805.   const uint8_t* vanillaData = rom + linkstart;
  806.   int vanillaDataSize = linksize;
  807.  
  808.   int segment = 0x06;
  809.   IntMap vertices;
  810.   IntMap matrices;
  811.   IntMap textures;
  812.   IntMap_Init(&vertices);
  813.   IntMap_Init(&matrices);
  814.   IntMap_Init(&textures);
  815.  
  816.   Vector* displayLists = calloc(pieceCount, sizeof(Vector));
  817.   uint* offsets = malloc(pieceCount * sizeof(uint));
  818.  
  819.   // For each missing piece, grab data from its vanilla display list
  820.   for (int m = 0; m < pieceCount; m++) {
  821.     if (!missing[m]) {
  822.       continue;
  823.     }
  824.  
  825.     const char* item = pieces[m].key;
  826.     int offset = pieces[m].offset;
  827.     int i = offset;
  828.     Vector* displayList = &displayLists[m];
  829.     Vector_Init(displayList);
  830.  
  831.     // Crawl displaylist bytecode and handle each command
  832.     while (i < vanillaDataSize) {
  833.       // Check if these bytes need to be skipped
  834.       bool skipped = false;
  835.       for (int s = 0; s < skipCount; s++) {
  836.         Skip skip = skips[s];
  837.         if (strcmp(item, skip.key) == 0) {
  838.           uint itemIndex = i - offset;
  839.           if ((skip.start <= itemIndex) && (itemIndex < skip.end)) {
  840.             skipped = true;
  841.             break;
  842.           }
  843.         }
  844.       }
  845.       if (skipped) {
  846.         i += 8;
  847.         continue;
  848.       }
  849.  
  850.       uint8_t op = vanillaData[i];
  851.       uint8_t seg = vanillaData[i + 4];
  852.       uint lo = EndianSwap32(*((uint*)(vanillaData + i + 4)));
  853.       // Source for displaylist bytecode: https://hack64.net/wiki/doku.php?id=f3dex2
  854.       if (op == 0xDF) { // End of list
  855.         // DF: G_ENDDL
  856.         // Terminates the current displaylist
  857.         // DF 00 00 00 00 00 00 00
  858.         Vector_extend(displayList, vanillaData + i, 8); // Make sure to write the DF
  859.         break;
  860.       }
  861.       // Shouldn't have to deal with DE (branch to new display list)
  862.       else if ((op == 0x01) && (seg == segment)) { // Vertex data
  863.         // 01: G_VTX
  864.         // Fills the vertex buffer with vertex information
  865.         // 01 0[N N]0 [II] [SS SS SS SS]
  866.         // N: Number of vertices
  867.         // I: Where to start writing vertices inside the vertex buffer (start = II - N*2)
  868.         // S: Segmented address to load vertices from
  869.         // Grab the address from the low byte without teh base offset
  870.         int vtxStart = lo & 0x00FFFFFF;
  871.         // Grab the length of vertices from the instruction
  872.         // (Number of vertices will be from the 4th and 5th nibble as shown above, but each length
  873.         // 16)
  874.         ushort vtxLen = EndianSwap16(*((ushort*)(vanillaData + i + 1)));
  875.         if ((!IntMap_has(&vertices, vtxStart)) || (IntMap_get(&vertices, vtxStart) < vtxLen)) {
  876.           IntMap_set(&vertices, vtxStart, vtxLen);
  877.         }
  878.       } else if ((op == 0xDA) && (seg == segment)) { // Push matrix
  879.         // DA: G_MTX
  880.         // Apply transformation matrix
  881.         // DA 38 00 [PP] [AA AA AA AA]
  882.         // P: Parameters for matrix
  883.         // A: Segmented address of vectors of matrix
  884.         // Grab the address from the low byte without the base offset
  885.         int mtxStart = lo & 0x00FFFFFF;
  886.         if (!IntMap_has(&matrices, mtxStart)) {
  887.           IntMap_set(&matrices, mtxStart, 0x40); // Matrices always 0x40 long
  888.         }
  889.       } else if ((op == 0xFD) && (seg == segment)) { // Texture
  890.         // G_SETTIMG
  891.         // Sets the texture image offset
  892.         // FD [fi] 00 00 [bb bb bb bb]
  893.         // [fi] -> fffi i000
  894.         // f: Texture format
  895.         // i: Texture bitsize
  896.         // b: Segmented address of texture
  897.         // Use 3rd nibble to get the texture type
  898.         int textureType = (vanillaData[i + 1] >> 3) & 0x1F;
  899.         // Find the number of texel bits from the type
  900.         int numTexelBits = 4 * pow(2, textureType & 0x03);
  901.         // Get how many bytes there are per texel
  902.         int bytesPerTexel = (int)(numTexelBits / 8);
  903.         // Grab the address from the low byte without the base offset
  904.         int texOffset = lo & 0x00FFFFFF;
  905.         int numTexels = -1;
  906.         Vector returnStack;
  907.         Vector_Init(&returnStack);
  908.         int j = i + 8;
  909.         // The point of this loop is just to find the number of texels
  910.         // so that it may be multiplied by the bytesPerTexel so we know
  911.         // the length of the texture.
  912.         while ((j < vanillaDataSize) && (numTexels == -1)) {
  913.           uint8_t opJ = vanillaData[j];
  914.           uint8_t segJ = vanillaData[j + 4];
  915.           uint loJ = EndianSwap32(*((uint*)(vanillaData + j + 4)));
  916.           if (opJ == 0xDF) {
  917.             // End of branched texture, or something wrong
  918.             if (returnStack.len == 0) {
  919.               numTexels = 0;
  920.               break;
  921.             } else {
  922.               j = Vector_pop(&returnStack);
  923.             }
  924.           } else if (opJ == 0xFD) {
  925.             // Another texture command encountered, something wrong
  926.             numTexels = 0;
  927.             break;
  928.           } else if (opJ == 0xDE) {
  929.             // Branch to another texture
  930.             if (segJ == segment) {
  931.               if (vanillaData[j + 1] == 0x0) {
  932.                 Vector_push(&returnStack, j);
  933.               }
  934.               j = loJ & 0x00FFFFFF;
  935.             }
  936.           } else if (opJ == 0xF0) {
  937.             // F0: G_LOADTLUT
  938.             // Loads a number of colors for a pallette
  939.             // F0 00 00 00 0[t] [cc c]0 00
  940.             // t: Tile descriptor to load from
  941.             // c: ((colour count-1) & 0x3FF) << 2
  942.             // Just grab c from the instruction above
  943.             // Shift right 12 to get past the first 3 0s, then
  944.             // 2 more since c is shifted left twice, then add 1
  945.             // to get the color count of this pallette.
  946.             numTexels = ((loJ & 0x00FFF000) >> 14) + 1;
  947.             break;
  948.             // Also error if numTexels > 256
  949.           } else if (opJ == 0xF3) {
  950.             // F3: G_LOADBLOCK
  951.             // Determines how much data to load after SETTIMG
  952.             // F3 [SS S][T TT] 0[I] [XX X][D DD]
  953.             // S: Upper left corner of texture's S-axis
  954.             // T: Upper left corner of texture's T-axis
  955.             // I: Tile descriptor
  956.             // X: Number of texels to load, minus one
  957.             // D: dxt (?)
  958.             // Just grab X from the instruction, shift
  959.             // right 12 times to get past 0s
  960.             numTexels = ((loJ & 0x00FFF000) >> 12) + 1;
  961.             break;
  962.           }
  963.           j += 8;
  964.         }
  965.         int dataLen = bytesPerTexel * numTexels;
  966.         if ((!IntMap_has(&textures, texOffset)) || (IntMap_get(&textures, texOffset) < dataLen)) {
  967.           IntMap_set(&textures, texOffset, dataLen);
  968.         }
  969.  
  970.         Vector_free(&returnStack);
  971.       }
  972.       Vector_extend(displayList, vanillaData + i, 8);
  973.       i += 8;
  974.     }
  975.  
  976.     offsets[m] = offset;
  977.   }
  978.  
  979.   // Create vanilla zobj of the pieces from data collected during crawl
  980.   Vector vanillaZobj;
  981.   Vector_Init(&vanillaZobj);
  982.   IntMapIterator iterator;
  983.   IntEntry* entry;
  984.   // Add textures, vertices, and matrices to the beginning of the zobj
  985.   // Textures
  986.   IntMap oldTex2New;
  987.   IntMap_Init(&oldTex2New);
  988.   IntMapIterator_Init(&iterator, &textures);
  989.   while ((entry = IntMapIterator_Next(&iterator)) != NULL) {
  990.     IntMap_set(&oldTex2New, entry->key, vanillaZobj.len);
  991.     Vector_extend(&vanillaZobj, vanillaData + entry->key, entry->value);
  992.   }
  993.   // Vertices
  994.   IntMap oldVer2New;
  995.   IntMap_Init(&oldVer2New);
  996.   IntMapIterator_Init(&iterator, &vertices);
  997.   while ((entry = IntMapIterator_Next(&iterator)) != NULL) {
  998.     IntMap_set(&oldVer2New, entry->key, vanillaZobj.len);
  999.     Vector_extend(&vanillaZobj, vanillaData + entry->key, entry->value);
  1000.   }
  1001.   // Matrices
  1002.   IntMap oldMtx2New;
  1003.   IntMap_Init(&oldMtx2New);
  1004.   IntMapIterator_Init(&iterator, &matrices);
  1005.   while ((entry = IntMapIterator_Next(&iterator)) != NULL) {
  1006.     IntMap_set(&oldMtx2New, entry->key, vanillaZobj.len);
  1007.     Vector_extend(&vanillaZobj, vanillaData + entry->key, entry->value);
  1008.   }
  1009.  
  1010.   // Now add display lists which will reference the data from the beginning of the zobj
  1011.   // Display lists
  1012.   IntMap oldDL2New;
  1013.   IntMap_Init(&oldDL2New);
  1014.   for (int e = 0; e < pieceCount; e++) {
  1015.     if (!missing[e]) {
  1016.       continue;
  1017.     }
  1018.  
  1019.     Vector displayList = displayLists[e];
  1020.     uint8_t* dl = displayList.data;
  1021.     int offset = offsets[e];
  1022.     IntMap_set(&oldDL2New, offset, vanillaZobj.len);
  1023.     for (int i = 0; i < displayList.len; i += 8) {
  1024.       uint8_t op = dl[i];
  1025.       uint8_t seg = dl[i + 4];
  1026.       int lo = EndianSwap32(*((uint*)(dl + i + 4)));
  1027.       if (seg == segment) {
  1028.         // If this instruction points to some data, it must be repointed
  1029.         switch (op) {
  1030.           case 0x01: {
  1031.             int vertEntry = IntMap_get(&oldVer2New, lo & 0x00FFFFFF);
  1032.             WriteDLPointer(dl, i + 4, BASE_OFFSET + vertEntry + rebase);
  1033.           } break;
  1034.           case 0xDA: {
  1035.             int mtxEntry = IntMap_get(&oldMtx2New, lo & 0x00FFFFFF);
  1036.             WriteDLPointer(dl, i + 4, BASE_OFFSET + mtxEntry + rebase);
  1037.           } break;
  1038.           case 0xFD: {
  1039.             int texEntry = IntMap_get(&oldTex2New, lo & 0x00FFFFFF);
  1040.             WriteDLPointer(dl, i + 4, BASE_OFFSET + texEntry + rebase);
  1041.           } break;
  1042.           case 0xDE: {
  1043.             int dlEntry = IntMap_get(&oldDL2New, lo & 0x00FFFFFF);
  1044.             WriteDLPointer(dl, i + 4, BASE_OFFSET + dlEntry + rebase);
  1045.           } break;
  1046.           default:
  1047.             break;
  1048.         }
  1049.       }
  1050.     }
  1051.     Vector_extend(&vanillaZobj, dl, displayList.len);
  1052.     // Pad to nearest multiple of 16
  1053.     while ((vanillaZobj.len % 0x10) != 0) {
  1054.       Vector_push(&vanillaZobj, 0x00);
  1055.     }
  1056.   }
  1057.  
  1058.   // Now find the relation of items to new offsets
  1059.   for (int m = 0; m < pieceCount; m++) {
  1060.     if (!missing[m]) {
  1061.       continue;
  1062.     }
  1063.     DLOffsets[m] = IntMap_get(&oldDL2New, pieces[m].offset);
  1064.   }
  1065.  
  1066.   IntMap_free(&vertices);
  1067.   IntMap_free(&matrices);
  1068.   IntMap_free(&textures);
  1069.   IntMap_free(&oldTex2New);
  1070.   IntMap_free(&oldVer2New);
  1071.   IntMap_free(&oldMtx2New);
  1072.   IntMap_free(&oldDL2New);
  1073.   IntMap_free(&vertices);
  1074.   IntMap_free(&vertices);
  1075.  
  1076.   for (int i = 0; i < pieceCount; i++) {
  1077.     Vector_free(&displayLists[i]);
  1078.   }
  1079.  
  1080.   free(displayLists);
  1081.   free(offsets);
  1082.  
  1083.   return vanillaZobj;
  1084. }
  1085.  
  1086. // Finds the address of the model's hierarchy so we can write the hierarchy pointer
  1087. // Based on
  1088. // https://github.com/hylian-modding/Z64Online/blob/master/src/Z64Online/common/cosmetics/UniversalAliasTable.ts
  1089. // function findHierarchy()
  1090. int FindHierarchy(uint8_t* zobj, int zobjlen, const char* agestr) {
  1091.   // Scan until we find a segmented pointer which is 0x0C or 0x10 more than
  1092.   // the preceeding data and loop until something that's not a segmented pointer is found
  1093.   // then return the position of the last segemented pointer.
  1094.   for (int i = 0; i < zobjlen; i += 4) {
  1095.     if (zobj[i] == 0x06) {
  1096.  
  1097.       int possible = EndianSwap32(*(int*)(zobj + i)) & 0x00FFFFFF;
  1098.  
  1099.       if (possible < zobjlen) {
  1100.         int possible2 = EndianSwap32(*(int*)(zobj + i - 4)) & 0x00FFFFFF;
  1101.         int diff = possible - possible2;
  1102.         if ((diff == 0x0C) || (diff == 0x10)) {
  1103.           int pos = i + 4;
  1104.           int count = 1;
  1105.           while (zobj[pos] == 0x06) {
  1106.             pos += 4;
  1107.             count += 1;
  1108.           }
  1109.           uint8_t a = zobj[pos];
  1110.           if (a != count) {
  1111.             continue;
  1112.           }
  1113.  
  1114.           // printf("[C]FindHierarchy returns pos: %i, possible1: %X, possible2: %X\n", pos - 4,
  1115.           // possible, possible2);
  1116.           return pos - 4;
  1117.         }
  1118.       }
  1119.     }
  1120.   }
  1121.  
  1122.   printf("[C]ModelDefinitionError: No hierarchy found in %s model- Did you check \"Link hierarchy "
  1123.          "format\" in zzconvert?\n",
  1124.     agestr);
  1125.   return -1;
  1126. }
  1127.  
  1128. #define TOLERANCE 0x100
  1129.  
  1130. bool CheckDiff(int limb, int skeleton) {
  1131.   // The normal difference
  1132.   int normalDiff = abs(limb - skeleton);
  1133.   // Underflow/overflow diff
  1134.   // For example, if limb is 0xFFFF and skeleton is 0x0001, then they are technically only 2 apart
  1135.   // So subtract 0xFFFF from the absolute value of the difference to get the true differene in this
  1136.   // case Necessary since values are signed, but not represented as signed here
  1137.   int flowDiff = abs(normalDiff - 0xFFFF);
  1138.   // Take the minimum of the two differences
  1139.   int diff = min(normalDiff, flowDiff);
  1140.   // Return true if diff is too big
  1141.   return diff > TOLERANCE;
  1142. }
  1143.  
  1144. bool CheckSkeleton(uint8_t* zobj, int zobjlen, const Limb* skeleton, const char* agestr) {
  1145.   // Get the hierarchy pointer
  1146.   int hierarchy = FindHierarchy(zobj, zobjlen, agestr);
  1147.   // Get what the hierarchy pointer points to (pointer to limb 0)
  1148.   int limbPointer = EndianSwap32(*(int*)(zobj + hierarchy)) & 0x00FFFFFF;
  1149.   // Get the limb this points to
  1150.   int limb = EndianSwap32(*(int*)(zobj + limbPointer)) & 0x00FFFFFF;
  1151.   // Go through each limb in the table
  1152.   bool hasVanillaSkeleton = true;
  1153.   bool withinTolerance = true;
  1154.  
  1155.   for (int i = 0; i < 21; i++) {
  1156.     int offset = limb + i * 0x10;
  1157.     // X, Y, Z components are 2 bytes each
  1158.     int limbX = EndianSwap16(*(uint16_t*)(zobj + offset));
  1159.     int limbY = EndianSwap16(*(uint16_t*)(zobj + offset + 2));
  1160.     int limbZ = EndianSwap16(*(uint16_t*)(zobj + offset + 4));
  1161.     int skeletonX = skeleton[i].x;
  1162.     int skeletonY = skeleton[i].y;
  1163.     int skeletonZ = skeleton[i].z;
  1164.  
  1165.     // Check if the X, Y, and Z components all match
  1166.     if (limbX != skeletonX || limbY != skeletonY || limbZ != skeletonZ) {
  1167.       hasVanillaSkeleton = false;
  1168.  
  1169.       // Now check if the components are within a tolerance
  1170.       // Exclude limb 0 since that one is always zeroed out on models for some reason
  1171.       if (i > 0 && (CheckDiff(limbX, skeletonX) || CheckDiff(limbY, skeletonY) || CheckDiff(limbZ, skeletonZ))) {
  1172.         withinTolerance = false;
  1173.         break;
  1174.       }
  1175.     }
  1176.   }
  1177.  
  1178.   uint8_t tmpBytes[6];
  1179.  
  1180.   if (!hasVanillaSkeleton && withinTolerance) {
  1181.     hasVanillaSkeleton = true;
  1182.  
  1183.     for (int i = 0; i < 21; i++) {
  1184.       int offset = limb + i * 0x10;
  1185.       Limb limb = skeleton[i];
  1186.  
  1187.       tmpBytes[0] = (limb.x >> 8) & 0xFF;  
  1188.       tmpBytes[1] = limb.x & 0xFF;
  1189.  
  1190.       tmpBytes[2] = (limb.y >> 8) & 0xFF;
  1191.       tmpBytes[3] = limb.y & 0xFF;
  1192.  
  1193.       tmpBytes[4] = (limb.z >> 8) & 0xFF;
  1194.       tmpBytes[5] = limb.z & 0xFF;
  1195.  
  1196.       memcpy(zobj + offset, tmpBytes, sizeof(tmpBytes));
  1197.     }
  1198.   }
  1199.  
  1200.   return hasVanillaSkeleton;
  1201. }
  1202.  
  1203. // Loads model from file and processes it by adding vanilla pieces and setting up the LUT if
  1204. // necessary.
  1205. int LoadModel(uint8_t* rom, uint8_t* zobj, int zobjlen, int age, uint8_t* preConstData,
  1206.   int preConstDataLen, uint8_t* postConstData, int postConstDataLen) {
  1207.   Vector new_zobj;
  1208.   Vector_Init(&new_zobj);
  1209.  
  1210.   bool missing[max(sizeof(AdultPieces) / sizeof(*AdultPieces),
  1211.     sizeof(ChildPieces) / sizeof(*ChildPieces))] = {false};
  1212.   uint DLOffsets[max(
  1213.     sizeof(AdultPieces) / sizeof(*AdultPieces), sizeof(ChildPieces) / sizeof(*ChildPieces))] = {0};
  1214.  
  1215.   // age 0 = adult, 1 = child
  1216.   int linkstart = ADULT_START;
  1217.   int linksize = ADULT_SIZE;
  1218.   int hierarchy = ADULT_HIERARCHY;
  1219.   int postconstantstart = ADULT_POST_START;
  1220.  
  1221.   const Piece* pieces = AdultPieces;
  1222.   const Skip* skips = adultSkips;
  1223.   const Limb* skeleton = adultSkeleton;
  1224.   int pieceCount = sizeof(AdultPieces) / sizeof(*AdultPieces);
  1225.   int skipCount = sizeof(adultSkips) / sizeof(*adultSkips);
  1226.   const char* agestr = "adult"; // Juse used for error messages
  1227.  
  1228.   if (age == 1) {
  1229.     linkstart = CHILD_START;
  1230.     linksize = CHILD_SIZE;
  1231.     hierarchy = CHILD_HIERARCHY;
  1232.     postconstantstart = CHILD_POST_START;
  1233.     pieces = ChildPieces;
  1234.     skips = childSkips;
  1235.     skeleton = childSkeleton;
  1236.     pieceCount = sizeof(ChildPieces) / sizeof(*ChildPieces);
  1237.     skipCount = sizeof(childSkips) / sizeof(*childSkips);
  1238.     agestr = "child";
  1239.   }
  1240.  
  1241.   if (zobjlen > linksize) {
  1242.     printf("[C]ModelDefinitionError: Model for %s too large- It is %i bytes, but must be at most "
  1243.            "%i bytes\n",
  1244.       agestr, zobjlen, linksize);
  1245.     return -1;
  1246.   }
  1247.  
  1248.   // See if the string MODLOADER64 appears before the LUT- if so this is a PlayAs model and needs no
  1249.   // further processing
  1250.   if (scan(zobj, zobjlen, "MODLOADER64", -1, 0) == -1) {
  1251.  
  1252.     // First, make sure all important bytes are zeroed out
  1253.     memset(zobj + LUT_START, 0x00, LUT_END - LUT_START);
  1254.     // Find which pieces are missing from this model
  1255.     int footerstart = scan(zobj, zobjlen, "!PlayAsManifest0", -1, 0);
  1256.     if (footerstart == -1) {
  1257.       printf("[C]ModelDefinitionError: No manifest found in %s model- Did you check \"Embed "
  1258.              "play-as data\" in zzconvert?\n",
  1259.         agestr);
  1260.       return -2;
  1261.     }
  1262.  
  1263.     int startaddr = footerstart - strlen("!PlayAsManifest0");
  1264.  
  1265.     bool anyMissing = false;
  1266.     for (int i = 0; i < pieceCount; i++) {
  1267.       Piece piece = pieces[i];
  1268.       int offset = scan(zobj, zobjlen, piece.key, -1, footerstart);
  1269.       if (offset == -1) {
  1270.         missing[i] = true;
  1271.         anyMissing = true;
  1272.       } else {
  1273.         missing[i] = false;
  1274.         DLOffsets[i] = offset;
  1275.       }
  1276.     }
  1277.  
  1278.     if (anyMissing) {
  1279.  
  1280.       // Load vanilla model data for missing pieces
  1281.       Vector vanillaZobj = LoadVanilla(rom, startaddr, linkstart, linksize, pieces, missing,
  1282.         DLOffsets, pieceCount, skips, skipCount);
  1283.  
  1284.       // Write vanilla zobj data to end of model zobj
  1285.       Vector_extend(&new_zobj, zobj, startaddr);
  1286.       Vector_extend(&new_zobj, vanillaZobj.data, vanillaZobj.len);
  1287.       Vector_extend(&new_zobj, zobj + startaddr, zobjlen - startaddr);
  1288.       zobj = new_zobj.data;
  1289.       zobjlen = new_zobj.len;
  1290.  
  1291.       if (zobjlen > linksize) {
  1292.  
  1293.         //FILE* test = fopen("/testModel.zobj", "wb");
  1294.         //fwrite(zobj, 1, zobjlen, test);
  1295.         //fclose(test);
  1296.  
  1297.         printf("[C]ModelDefinitionError: After processing, model for %s too large- It is %i bytes, "
  1298.                "but must be at most %i bytes\n",
  1299.           agestr, zobjlen, linksize);
  1300.         return -3;
  1301.       }
  1302.  
  1303.       // Now we have to set the lookup table for each item
  1304.       for (int i = 0; i < pieceCount; i++) {
  1305.         // Add the starting address to each offset so they're accurate to the updated zobj
  1306.         if (missing[i]) {
  1307.           DLOffsets[i] += startaddr;
  1308.         } else if (DLOffsets[i] >= startaddr) {
  1309.           DLOffsets[i] += vanillaZobj.len;
  1310.         }
  1311.       }
  1312.  
  1313.       Vector_free(&vanillaZobj);
  1314.     }
  1315.  
  1316.     for (int p = 0; p < pieceCount; p++) {
  1317.       Piece piece = pieces[p];
  1318.  
  1319.       uint lut = piece.LUT - BASE_OFFSET;
  1320.       uint entry = unwrap(zobj, lut);
  1321.  
  1322.       zobj[entry] = 0xDE;
  1323.       zobj[entry + 1] = 0x01;
  1324.       entry += 4;
  1325.       uint dladdress = DLOffsets[p] + BASE_OFFSET;
  1326.       *(uint*)(zobj + entry) = EndianSwap32(dladdress);
  1327.     }
  1328.  
  1329.     // Put prefix for easily finding LUT in RAM
  1330.     memcpy(zobj + LUT_START, "HEYLOOKHERE", strlen("HEYLOOKHERE"));
  1331.  
  1332.     // Set constants in the LUT
  1333.     memcpy(zobj + PRE_CONSTANT_START, preConstData, preConstDataLen);
  1334.  
  1335.     memcpy(zobj + postconstantstart, postConstData, postConstDataLen);
  1336.  
  1337.     // Set up hierarchy pointer
  1338.     int hierarchyOffset = FindHierarchy(zobj, zobjlen, agestr);
  1339.  
  1340.     if (hierarchyOffset == -1) {
  1341.  
  1342.       //FILE* test = fopen("/testModel.zobj", "wb");
  1343.       //fwrite(zobj, 1, zobjlen, test);
  1344.       //fclose(test);
  1345.  
  1346.       printf(
  1347.         "[C]ModelHierarchyError: After processing, found no hierarchy for model for %s\n", agestr);
  1348.       return -4;
  1349.     }
  1350.  
  1351.     uint hierarchyBytes = *(uint*)(zobj + hierarchyOffset); // Get the data the offset points to
  1352.     *(uint*)(zobj + hierarchy - BASE_OFFSET) = hierarchyBytes;
  1353.     zobj[hierarchy - BASE_OFFSET + 4] = 0x15; // Number of limbs
  1354.     zobj[hierarchy - BASE_OFFSET + 8] = 0x12; // Number of limbs to draw
  1355.                                               // // Save zobj for testing
  1356.                                               // with open(path + "Test_Processed.zobj", "wb") as f:
  1357.                                               //     f.write(zobj)
  1358.   }
  1359.  
  1360.   // Check skeleton
  1361.   if (!CheckSkeleton(zobj, zobjlen, skeleton, agestr)) {
  1362.     // If skeleton not vanilla, display message in pause screen informing of this
  1363.     // rom.write_int16(rom.sym('illegal_model'), 1)
  1364.     printf(
  1365.       "[C]ModelSkeletonWarning: The used model has a modified skeleton and is not race legal!\n");
  1366.  
  1367.     char scriptBuffer[255];
  1368.     sprintf(scriptBuffer, "raceIllegalModelUsed('%s')", agestr);
  1369.     emscripten_run_script(scriptBuffer);
  1370.   }
  1371.  
  1372.   // Write zobj to vanilla object (object_link_boy or object_link_child)
  1373.   memcpy(rom + linkstart, zobj, zobjlen);
  1374.   Vector_free(&new_zobj);
  1375.  
  1376.   // Finally, want to return an address with a DF instruction for use when writing the model data
  1377.   const char dfBytes[] = {0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  1378.  
  1379.   int dfScan = scan(zobj, zobjlen, dfBytes, 8, 0);
  1380.  
  1381.   if (dfScan == -1) {
  1382.    
  1383.     //FILE* test = fopen("/testModel.zobj", "wb");
  1384.     //fwrite(zobj, 1, zobjlen, test);
  1385.     //fclose(test);
  1386.  
  1387.     printf("[C]ModelSignatureError: After processing, found no DF instruction for model for %s\n",
  1388.       agestr);
  1389.     return -5;
  1390.   }
  1391.  
  1392.   return dfScan - 8;
  1393. }
  1394.  
  1395. // Write in the adult model and repoint references to it
  1396. int patch_model_adult(uint8_t* rom, uint8_t* zobj, int zobjlen, uint8_t* preConstData,
  1397.   int preConstDataLen, uint8_t* postConstData, int postConstDataLen) {
  1398.  
  1399.   // Load and process model
  1400.   int dfAddress = LoadModel(
  1401.     rom, zobj, zobjlen, 0, preConstData, preConstDataLen, postConstData, postConstDataLen);
  1402.  
  1403.   if (dfAddress < 0) {
  1404.     printf("[C]ModelError: Model patcher adult aborts with error code: %i\n", dfAddress);
  1405.     return dfAddress;
  1406.   }
  1407.  
  1408.   dfAddress |= 0x06000000; // Add segment to DF address
  1409.  
  1410.   // Write adult Link pointer data
  1411.   ModelPointerWriter writer = {rom};
  1412.   ModelPointerWriter_Init(&writer);
  1413.  
  1414.   ModelPointerWriter_GoTo(&writer, 0xE6718);
  1415.   ModelPointerWriter_SetAdvance(&writer, 8);
  1416.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RFIST);
  1417.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RFIST);
  1418.   ModelPointerWriter_WriteModelData(&writer, dfAddress);
  1419.   ModelPointerWriter_WriteModelData(&writer, dfAddress);
  1420.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RFIST_SHIELD_HYLIAN);
  1421.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RFIST_SHIELD_HYLIAN);
  1422.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RFIST_SHIELD_MIRROR);
  1423.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RFIST_SHIELD_MIRROR);
  1424.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_SWORD_SHEATHED);
  1425.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_SWORD_SHEATHED);
  1426.   ModelPointerWriter_WriteModelData(&writer, dfAddress);
  1427.   ModelPointerWriter_WriteModelData(&writer, dfAddress);
  1428.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_SWORD_SHIELD_HYLIAN);
  1429.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_SWORD_SHIELD_HYLIAN);
  1430.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_SWORD_SHIELD_MIRROR);
  1431.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_SWORD_SHIELD_MIRROR);
  1432.   ModelPointerWriter_WriteModelData(&writer, 0x00000000);
  1433.   ModelPointerWriter_WriteModelData(&writer, 0x00000000);
  1434.   ModelPointerWriter_WriteModelData(&writer, 0x00000000);
  1435.   ModelPointerWriter_WriteModelData(&writer, 0x00000000);
  1436.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_SWORD_SHEATH);
  1437.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_SWORD_SHEATH);
  1438.   ModelPointerWriter_WriteModelData(&writer, dfAddress);
  1439.   ModelPointerWriter_WriteModelData(&writer, dfAddress);
  1440.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_SHEATH0_HYLIAN);
  1441.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_SHEATH0_HYLIAN);
  1442.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_SHEATH0_MIRROR);
  1443.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_SHEATH0_MIRROR);
  1444.   ModelPointerWriter_WriteModelData(&writer, 0x00000000);
  1445.   ModelPointerWriter_WriteModelData(&writer, 0x00000000);
  1446.   ModelPointerWriter_WriteModelData(&writer, 0x00000000);
  1447.   ModelPointerWriter_WriteModelData(&writer, 0x00000000);
  1448.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_LFIST_LONGSWORD);
  1449.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_LFIST_LONGSWORD);
  1450.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_LFIST_LONGSWORD_BROKEN);
  1451.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_LFIST_LONGSWORD_BROKEN);
  1452.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_LHAND);
  1453.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_LHAND);
  1454.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_LFIST);
  1455.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_LFIST);
  1456.   ModelPointerWriter_WriteModelData(&writer, dfAddress);
  1457.   ModelPointerWriter_WriteModelData(&writer, dfAddress);
  1458.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_LFIST_SWORD);
  1459.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_LFIST_SWORD);
  1460.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RHAND);
  1461.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RHAND);
  1462.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RFIST);
  1463.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RFIST);
  1464.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RFIST_BOW);
  1465.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RFIST_BOW);
  1466.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_SWORD_SHEATHED);
  1467.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_SWORD_SHEATHED);
  1468.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_SWORD_SHEATH);
  1469.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_SWORD_SHEATH);
  1470.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_WAIST);
  1471.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_WAIST);
  1472.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RFIST_BOW);
  1473.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RFIST_BOW);
  1474.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RHAND_OCARINA_TIME);
  1475.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RHAND_OCARINA_TIME);
  1476.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RHAND_OCARINA_TIME);
  1477.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RHAND_OCARINA_TIME);
  1478.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RFIST_HOOKSHOT);
  1479.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RFIST_HOOKSHOT);
  1480.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_LFIST_HAMMER);
  1481.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_LFIST_HAMMER);
  1482.   ModelPointerWriter_WriteModelData(&writer, dfAddress);
  1483.   ModelPointerWriter_WriteModelData(&writer, dfAddress);
  1484.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_LHAND_BOTTLE);
  1485.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_LHAND_BOTTLE);
  1486.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_FPS_LFOREARM);
  1487.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_FPS_LHAND);
  1488.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_RSHOULDER);
  1489.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_FPS_RFOREARM);
  1490.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_FPS_RHAND_BOW);
  1491.  
  1492.   ModelPointerWriter_GoTo(&writer, 0xE6A4C);
  1493.   ModelPointerWriter_SetAdvance(&writer, 4);
  1494.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_BOOT_LIRON);
  1495.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_BOOT_RIRON);
  1496.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_BOOT_LHOVER);
  1497.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_BOOT_RHOVER);
  1498.  
  1499.   ModelPointerWriter_GoTo(&writer, 0xE6B28);
  1500.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_BOTTLE);
  1501.  
  1502.   ModelPointerWriter_GoTo(&writer, 0xE6B64);
  1503.   ModelPointerWriter_SetAdvance(&writer, 4);
  1504.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_BOW_STRING);
  1505.   ModelPointerWriter_WriteModelData(&writer, 0x00000000); // string anchor x: 0.0
  1506.   ModelPointerWriter_WriteModelData(&writer, 0xC3B43333); // string anchor y: -360.4
  1507.  
  1508.   ModelPointerWriter_GoTo(&writer, 0x69112);
  1509.   ModelPointerWriter_WriteModelDataHi(&writer, Offsets_ADULT_LINK_LUT_DL_UPGRADE_LFOREARM);
  1510.   ModelPointerWriter_GoTo(&writer, 0x69116);
  1511.   ModelPointerWriter_WriteModelDataLo(&writer, Offsets_ADULT_LINK_LUT_DL_UPGRADE_LFOREARM);
  1512.   ModelPointerWriter_GoTo(&writer, 0x6912E);
  1513.   ModelPointerWriter_WriteModelDataHi(&writer, Offsets_ADULT_LINK_LUT_DL_UPGRADE_RFOREARM);
  1514.   ModelPointerWriter_GoTo(&writer, 0x69132);
  1515.   ModelPointerWriter_WriteModelDataLo(&writer, Offsets_ADULT_LINK_LUT_DL_UPGRADE_RFOREARM);
  1516.   ModelPointerWriter_GoTo(&writer, 0x6914E);
  1517.   ModelPointerWriter_WriteModelDataHi(&writer, Offsets_ADULT_LINK_LUT_DL_UPGRADE_LFIST);
  1518.   ModelPointerWriter_GoTo(&writer, 0x69162);
  1519.   ModelPointerWriter_WriteModelDataLo(&writer, Offsets_ADULT_LINK_LUT_DL_UPGRADE_LFIST);
  1520.   ModelPointerWriter_GoTo(&writer, 0x69166);
  1521.   ModelPointerWriter_WriteModelDataHi(&writer, Offsets_ADULT_LINK_LUT_DL_UPGRADE_LHAND);
  1522.   ModelPointerWriter_GoTo(&writer, 0x69172);
  1523.   ModelPointerWriter_WriteModelDataLo(&writer, Offsets_ADULT_LINK_LUT_DL_UPGRADE_LHAND);
  1524.   ModelPointerWriter_GoTo(&writer, 0x6919E);
  1525.   ModelPointerWriter_WriteModelDataHi(&writer, Offsets_ADULT_LINK_LUT_DL_UPGRADE_RFIST);
  1526.   ModelPointerWriter_GoTo(&writer, 0x691A2);
  1527.   ModelPointerWriter_WriteModelDataLo(&writer, Offsets_ADULT_LINK_LUT_DL_UPGRADE_RFIST);
  1528.   ModelPointerWriter_GoTo(&writer, 0x691AE);
  1529.   ModelPointerWriter_WriteModelDataHi(&writer, Offsets_ADULT_LINK_LUT_DL_UPGRADE_RHAND);
  1530.   ModelPointerWriter_GoTo(&writer, 0x691B2);
  1531.   ModelPointerWriter_WriteModelDataLo(&writer, Offsets_ADULT_LINK_LUT_DL_UPGRADE_RHAND);
  1532.   ModelPointerWriter_GoTo(&writer, 0x69DEA);
  1533.   ModelPointerWriter_WriteModelDataHi(&writer, Offsets_ADULT_LINK_LUT_DL_FPS_LHAND_HOOKSHOT);
  1534.   ModelPointerWriter_GoTo(&writer, 0x69DEE);
  1535.   ModelPointerWriter_WriteModelDataLo(&writer, Offsets_ADULT_LINK_LUT_DL_FPS_LHAND_HOOKSHOT);
  1536.   ModelPointerWriter_GoTo(&writer, 0x6A666);
  1537.   ModelPointerWriter_WriteModelDataHi(&writer, Offsets_ADULT_LINK_LUT_DL_HOOKSHOT_AIM);
  1538.   ModelPointerWriter_GoTo(&writer, 0x6A66A);
  1539.   ModelPointerWriter_WriteModelDataLo(&writer, Offsets_ADULT_LINK_LUT_DL_HOOKSHOT_AIM);
  1540.  
  1541.   ModelPointerWriter_SetBase(&writer, Hook);
  1542.   ModelPointerWriter_GoTo(&writer, 0xA72);
  1543.   ModelPointerWriter_WriteModelDataHi(&writer, Offsets_ADULT_LINK_LUT_DL_HOOKSHOT_HOOK);
  1544.   ModelPointerWriter_GoTo(&writer, 0xA76);
  1545.   ModelPointerWriter_WriteModelDataLo(&writer, Offsets_ADULT_LINK_LUT_DL_HOOKSHOT_HOOK);
  1546.   ModelPointerWriter_GoTo(&writer, 0xB66);
  1547.   ModelPointerWriter_WriteModelDataHi(&writer, Offsets_ADULT_LINK_LUT_DL_HOOKSHOT_CHAIN);
  1548.   ModelPointerWriter_GoTo(&writer, 0xB6A);
  1549.   ModelPointerWriter_WriteModelDataLo(&writer, Offsets_ADULT_LINK_LUT_DL_HOOKSHOT_CHAIN);
  1550.   ModelPointerWriter_GoTo(&writer, 0xBA8);
  1551.   ModelPointerWriter_WriteModelData16(&writer, 0x0014);
  1552.  
  1553.   ModelPointerWriter_SetBase(&writer, Stick);
  1554.   ModelPointerWriter_GoTo(&writer, 0x32C);
  1555.   ModelPointerWriter_WriteModelData(&writer, Offsets_ADULT_LINK_LUT_DL_BLADEBREAK);
  1556.   ModelPointerWriter_GoTo(&writer, 0x328);
  1557.   ModelPointerWriter_WriteModelData16(&writer, 0x0014);
  1558.  
  1559.   ModelPointerWriter_SetBase(&writer, Code);
  1560.   ModelPointerWriter_GoTo(&writer, 0xE65A0);
  1561.   ModelPointerWriter_WriteModelData(&writer, ADULT_HIERARCHY); // Hierarchy pointer
  1562.  
  1563.   return 0;
  1564. }
  1565.  
  1566. // Write in the child model and repoint references to it
  1567. int patch_model_child(uint8_t* rom, uint8_t* zobj, int zobjlen, uint8_t* preConstData,
  1568.   int preConstDataLen, uint8_t* postConstData, int postConstDataLen) {
  1569.  
  1570.   // Load and process model
  1571.   int dfAddress = LoadModel(
  1572.     rom, zobj, zobjlen, 1, preConstData, preConstDataLen, postConstData, postConstDataLen);
  1573.  
  1574.   if (dfAddress < 0) {
  1575.     printf("[C]ModelError: Model patcher child aborts with error code: %i\n", dfAddress);
  1576.     return dfAddress;
  1577.   }
  1578.  
  1579.   dfAddress |= 0x06000000; // Add segment to DF address
  1580.  
  1581.   // Write child Link pointer data
  1582.   ModelPointerWriter writer = {rom};
  1583.   ModelPointerWriter_Init(&writer);
  1584.  
  1585.   ModelPointerWriter_GoTo(&writer, 0xE671C);
  1586.   ModelPointerWriter_SetAdvance(&writer, 8);
  1587.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RFIST);
  1588.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RFIST);
  1589.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RFIST_SHIELD_DEKU);
  1590.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RFIST_SHIELD_DEKU);
  1591.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RFIST);
  1592.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RFIST);
  1593.   ModelPointerWriter_WriteModelData(&writer, dfAddress);
  1594.   ModelPointerWriter_WriteModelData(&writer, dfAddress);
  1595.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SWORD_SHEATHED);
  1596.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SWORD_SHEATHED);
  1597.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SWORD_SHIELD_DEKU);
  1598.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SWORD_SHIELD_DEKU);
  1599.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SWORD_SHIELD_HYLIAN);
  1600.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SWORD_SHIELD_HYLIAN);
  1601.   ModelPointerWriter_WriteModelData(&writer, dfAddress);
  1602.   ModelPointerWriter_WriteModelData(&writer, dfAddress);
  1603.   ModelPointerWriter_WriteModelData(&writer, 0x00000000);
  1604.   ModelPointerWriter_WriteModelData(&writer, 0x00000000);
  1605.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SHIELD_DEKU_BACK);
  1606.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SHIELD_DEKU_BACK);
  1607.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SWORD_SHEATH);
  1608.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SWORD_SHEATH);
  1609.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SHEATH0_DEKU);
  1610.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SHEATH0_DEKU);
  1611.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SHEATH0_HYLIAN);
  1612.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SHEATH0_HYLIAN);
  1613.   ModelPointerWriter_WriteModelData(&writer, dfAddress);
  1614.   ModelPointerWriter_WriteModelData(&writer, dfAddress);
  1615.   ModelPointerWriter_WriteModelData(&writer, 0x00000000);
  1616.   ModelPointerWriter_WriteModelData(&writer, 0x00000000);
  1617.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SHIELD_DEKU_BACK);
  1618.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SHIELD_DEKU_BACK);
  1619.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LHAND_PEDESTALSWORD);
  1620.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LHAND_PEDESTALSWORD);
  1621.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LHAND_PEDESTALSWORD);
  1622.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LHAND_PEDESTALSWORD);
  1623.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LHAND);
  1624.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LHAND);
  1625.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LFIST);
  1626.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LFIST);
  1627.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LFIST_SWORD);
  1628.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LFIST_SWORD);
  1629.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LFIST_SWORD);
  1630.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LFIST_SWORD);
  1631.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RHAND);
  1632.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RHAND);
  1633.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RFIST);
  1634.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RFIST);
  1635.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RFIST_SLINGSHOT);
  1636.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RFIST_SLINGSHOT);
  1637.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SWORD_SHEATHED);
  1638.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SWORD_SHEATHED);
  1639.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SWORD_SHEATH);
  1640.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SWORD_SHEATH);
  1641.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_WAIST);
  1642.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_WAIST);
  1643.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RFIST_SLINGSHOT);
  1644.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RFIST_SLINGSHOT);
  1645.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RHAND_OCARINA_FAIRY);
  1646.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RHAND_OCARINA_FAIRY);
  1647.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RHAND_OCARINA_TIME);
  1648.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RHAND_OCARINA_TIME);
  1649.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RFIST);
  1650.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RFIST);
  1651.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LFIST);
  1652.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LFIST);
  1653.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LFIST_BOOMERANG);
  1654.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LFIST_BOOMERANG);
  1655.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LHAND_BOTTLE);
  1656.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_LHAND_BOTTLE);
  1657.   ModelPointerWriter_WriteModelData(&writer, 0x00000000);
  1658.   ModelPointerWriter_WriteModelData(&writer, 0x00000000);
  1659.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_RSHOULDER);
  1660.   ModelPointerWriter_WriteModelData(&writer, 0x00000000);
  1661.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_FPS_RARM_SLINGSHOT);
  1662.  
  1663.   ModelPointerWriter_GoTo(&writer, 0xE6B2C);
  1664.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_BOTTLE);
  1665.  
  1666.   ModelPointerWriter_GoTo(&writer, 0xE6B74);
  1667.   ModelPointerWriter_SetAdvance(&writer, 4);
  1668.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_SLINGSHOT_STRING);
  1669.   ModelPointerWriter_WriteModelData(&writer, 0x44178000); // string anchor x: 606.0
  1670.   ModelPointerWriter_WriteModelData(&writer, 0x436C0000); // string anchor y: 236.0
  1671.  
  1672.   ModelPointerWriter_GoTo(&writer, 0x6922E);
  1673.   ModelPointerWriter_WriteModelDataHi(&writer, Offsets_CHILD_LINK_LUT_DL_GORON_BRACELET);
  1674.   ModelPointerWriter_GoTo(&writer, 0x69232);
  1675.   ModelPointerWriter_WriteModelDataLo(&writer, Offsets_CHILD_LINK_LUT_DL_GORON_BRACELET);
  1676.   ModelPointerWriter_GoTo(&writer, 0x6A80E);
  1677.   ModelPointerWriter_WriteModelDataHi(&writer, Offsets_CHILD_LINK_LUT_DL_DEKU_STICK);
  1678.   ModelPointerWriter_GoTo(&writer, 0x6A812);
  1679.   ModelPointerWriter_WriteModelDataLo(&writer, Offsets_CHILD_LINK_LUT_DL_DEKU_STICK);
  1680.  
  1681.   ModelPointerWriter_SetBase(&writer, Stick);
  1682.   ModelPointerWriter_GoTo(&writer, 0x334);
  1683.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_DEKU_STICK);
  1684.   ModelPointerWriter_GoTo(&writer, 0x330);
  1685.   ModelPointerWriter_WriteModelData16(&writer, 0x0015);
  1686.  
  1687.   ModelPointerWriter_SetBase(&writer, Shield);
  1688.   ModelPointerWriter_GoTo(&writer, 0x7EE);
  1689.   ModelPointerWriter_WriteModelDataHi(&writer, Offsets_CHILD_LINK_LUT_DL_SHIELD_DEKU_ODD);
  1690.   ModelPointerWriter_GoTo(&writer, 0x7F2);
  1691.   ModelPointerWriter_WriteModelDataLo(&writer, Offsets_CHILD_LINK_LUT_DL_SHIELD_DEKU_ODD);
  1692.  
  1693.   ModelPointerWriter_SetBase(&writer, Player);
  1694.   ModelPointerWriter_GoTo(&writer, 0x2253C);
  1695.   ModelPointerWriter_SetAdvance(&writer, 4);
  1696.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_MASK_KEATON);
  1697.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_MASK_SKULL);
  1698.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_MASK_SPOOKY);
  1699.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_MASK_BUNNY);
  1700.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_MASK_GORON);
  1701.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_MASK_ZORA);
  1702.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_MASK_GERUDO);
  1703.   ModelPointerWriter_WriteModelData(&writer, Offsets_CHILD_LINK_LUT_DL_MASK_TRUTH);
  1704.  
  1705.   ModelPointerWriter_SetBase(&writer, GraveyardKid);
  1706.   ModelPointerWriter_GoTo(&writer, 0xE62);
  1707.   ModelPointerWriter_WriteModelDataHi(&writer, Offsets_CHILD_LINK_LUT_DL_MASK_SPOOKY);
  1708.   ModelPointerWriter_GoTo(&writer, 0xE66);
  1709.   ModelPointerWriter_WriteModelDataLo(&writer, Offsets_CHILD_LINK_LUT_DL_MASK_SPOOKY);
  1710.  
  1711.   ModelPointerWriter_SetBase(&writer, Guard);
  1712.   ModelPointerWriter_GoTo(&writer, 0x1EA2);
  1713.   ModelPointerWriter_WriteModelDataHi(&writer, Offsets_CHILD_LINK_LUT_DL_MASK_KEATON);
  1714.   ModelPointerWriter_GoTo(&writer, 0x1EA6);
  1715.   ModelPointerWriter_WriteModelDataLo(&writer, Offsets_CHILD_LINK_LUT_DL_MASK_KEATON);
  1716.  
  1717.   ModelPointerWriter_SetBase(&writer, RunningMan);
  1718.   ModelPointerWriter_GoTo(&writer, 0x1142);
  1719.   ModelPointerWriter_WriteModelDataHi(&writer, Offsets_CHILD_LINK_LUT_DL_MASK_BUNNY);
  1720.   ModelPointerWriter_GoTo(&writer, 0x1146);
  1721.   ModelPointerWriter_WriteModelDataLo(&writer, Offsets_CHILD_LINK_LUT_DL_MASK_BUNNY);
  1722.  
  1723.   ModelPointerWriter_SetBase(&writer, Code);
  1724.   ModelPointerWriter_GoTo(&writer, 0xE65A4);
  1725.   ModelPointerWriter_WriteModelData(&writer, CHILD_HIERARCHY); // Hierarchy pointer
  1726.  
  1727.   return 0;
  1728. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement