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