2 \brief IR Memory Implementation
3 \details Intermediary memory management
6 ----------------------------------------------------------------------------*/
9 #include <stdint.h> //uint64_t
10 #include <string.h> //memmove
11 #include <stdlib.h> //malloc
16 /* functions needed from irmem.c */
73 /* struct definitions needed from irmem.c */
75 extern struct cdat
** cdat_stackp
;
76 extern struct odat
* curr_set_odatp
;
77 extern uint64_t ss_ref_id
;
80 /* Dynamically allocate memory for a class data structure,
81 or cdat, after a class has been identified in a grammar.
82 We also create a stack of class pointers so that
83 we can access the cdat during processing of that
84 cdats sets and elements, a requirement because the
85 nature of recursive classes prevents us from accessing
86 the cdat based on the previous index into cdat_buf,
87 which is a list of all allocated cdats*/
93 struct cdat
* curr_cdatp
;
95 curr_cdatp
= alloc_cdat();
97 memmove(curr_cdatp
->name
, name
, 32);
98 curr_cdatp
->idx
= num_cdats
;
100 /* Set the cdat as a subclass of the previous cdat */
101 (*cdat_stackp
)->class_list
[(*cdat_stackp
)->num_classes
] = curr_cdatp
;
102 /* Push the cdat onto the cdat_stack */
103 *++cdat_stackp
= curr_cdatp
;
115 /* Called in the reduction of a set. While both odats (eles and sets)
116 have identical label terminals, we are unable to give a single grammatical rule
117 for both due to how we allocate odats in the odat buf. Due to the
118 nature of bottom up parsing, the set label is recognized first, and then the
119 sets elements are recognized. This means that after we have processed the sets elemenets,
120 the curr_odat is going to be the last element and NOT the set that was first allocated.
121 To get around this, we create a global variable set_odatp that will store the pointer
122 to the odat when it is first allocated (in insert_set_label()) so that insert_set() can
123 have access to it. */
131 struct set
* curr_setp
;
133 curr_setp
= curr_set();
134 curr_set_odatp
= alloc_odat();
136 memmove(curr_set_odatp
->name
, name
, 32);
137 memmove(curr_setp
->name
, name
, 32);
138 curr_setp
->ref_id
= ref_id
;
146 struct set
* curr_setp
;
147 struct cdat
* curr_cdatp
;
148 struct link
* curr_linkp
;
150 curr_setp
= curr_set();
151 curr_cdatp
= curr_cdat();
152 curr_linkp
= alloc_link();
154 curr_setp
->cdat_idx
= curr_cdatp
->idx
;
155 curr_setp
->ref_id
= ref_id
; /* Will be resolved to offset
156 when link is processed */
157 curr_linkp
->type
= 1;
158 curr_linkp
->link_t
.olink
.ref_id
= ref_id
;
159 curr_linkp
->cdat_idx
= curr_cdatp
->idx
;
160 curr_linkp
->set_idx
= curr_cdatp
->num_sets
++;
161 curr_linkp
->ele_idx
= -1;
171 struct cdat
* curr_cdatp
;
172 struct link
* curr_linkp
;
174 curr_cdatp
= curr_cdat();
175 curr_linkp
= alloc_link();
177 /* Insert vlink into link_stack so that it gets processed at
179 curr_linkp
->type
= 2;
180 curr_linkp
->link_t
.vlink
.ref_id
= ref_id
;
181 curr_linkp
->cdat_idx
= curr_cdatp
->idx
;
182 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
183 curr_linkp
->ele_idx
= -1;
184 memmove(curr_linkp
->link_t
.vlink
.anim_name
, anim_name
, 32);
188 /* Svlinks dont have animation names */
194 struct cdat
* curr_cdatp
;
195 struct link
* curr_linkp
;
197 curr_cdatp
= curr_cdat();
198 curr_linkp
= alloc_link();
200 /* Insert svlink into link_stack so that it gets processed at
202 curr_linkp
->type
= 3;
203 curr_linkp
->cdat_idx
= curr_cdatp
->idx
;
204 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
205 curr_linkp
->ele_idx
= -1;
206 curr_linkp
->link_t
.svlink
.ref_id
= ref_id
;
210 /* At the point of reducing to a set, most of the
211 sets odat information has already been populated
212 during the reduction of its right hand side
213 non terminals (hitbox, root, quad_list). */
218 struct odat
* curr_odatp
;
219 struct cdat
* curr_cdatp
;
220 struct set
* curr_setp
;
221 struct ref
* prev_refp
;
222 struct ref
* curr_refp
;
223 struct vdat
* curr_vdatp
;
225 curr_odatp
= curr_set_odatp
; //allocated at insert_set_label, preserved in global space
226 curr_cdatp
= curr_cdat();
227 curr_setp
= curr_set();
228 prev_refp
= prev_ref();
229 curr_refp
= alloc_ref();
230 curr_vdatp
= curr_vdat();
232 curr_vdatp
->creator
= curr_set_odatp
;
234 curr_setp
->cdat_idx
= curr_cdatp
->idx
; //does a set need its class idx?
235 memmove(curr_setp
->name
, curr_odatp
->name
, 32);
236 curr_cdatp
->num_sets
++;
238 curr_odatp
->cdat_idx
= curr_cdatp
->idx
;
239 curr_odatp
->refp
= curr_refp
;
241 ref_id
= curr_setp
->ref_id
; // ref_id set by insert_set_label(name, ref_id)
243 if(ref_id
== -1) /* user did not define a ref_id */
244 { ref_id
= ss_ref_id
;
248 curr_refp
->ref_id
= ref_id
;
249 curr_refp
->lastref
= prev_refp
;
250 curr_refp
->odatp
= curr_odatp
;
251 prev_refp
->nextref
= curr_refp
;
256 /* Created as a seperate function, instead of setting the ODATS vdat_id and
257 calling inc_vdat() inside of insert_set(), to account for the set reduction
258 where a vdat is not created (o/v/svlinks). */
263 curr_set_odatp
->vdat_id
= num_vdats
; //no vdat_id for odats that have vlinks/svlinks
264 curr_set_odatp
= NULL
; //So this sets odat cant be modified after (which would be a bug)
267 /* Populates both the odat name and ref_id
275 struct ele
* curr_elep
;
276 struct odat
* curr_odatp
;
278 curr_elep
= curr_ele();
279 curr_odatp
= alloc_odat();
281 memmove(curr_odatp
->name
, name
, 32);
283 memmove(curr_elep
->name
, name
, 32);
284 curr_elep
->ref_id
= ref_id
;
287 /* We don't make an odat here, at output time we will resolve
288 the ref_id to the corresponding odat. */
294 struct cdat
* curr_cdatp
;
295 struct set
* curr_setp
;
296 struct ele
* curr_elep
;
297 struct link
* curr_linkp
;
299 curr_cdatp
= curr_cdat();
300 curr_elep
= curr_ele();
301 curr_linkp
= alloc_link();
303 curr_elep
->cdat_idx
= curr_cdatp
->idx
;
304 curr_elep
->ref_id
= ref_id
;
306 curr_linkp
->type
= 1;
307 curr_linkp
->link_t
.olink
.ref_id
= ref_id
;
308 curr_linkp
->cdat_idx
= curr_cdatp
->idx
;
309 curr_linkp
->set_idx
= curr_cdatp
->num_sets
++;
310 curr_linkp
->ele_idx
= curr_setp
->num_ele
++;
320 struct cdat
* curr_cdatp
;
321 struct set
* curr_setp
;
322 struct link
* curr_linkp
;
324 curr_cdatp
= curr_cdat();
325 curr_setp
= curr_set();
326 curr_linkp
= alloc_link();
328 /* Insert vlink into link_stack so that it gets processed at
330 curr_linkp
->cdat_idx
= curr_cdatp
->idx
;
331 curr_linkp
->type
= 2;
332 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
333 curr_linkp
->ele_idx
= curr_setp
->num_ele
;
334 curr_linkp
->link_t
.vlink
.ref_id
= ref_id
;
335 memmove(curr_linkp
->link_t
.vlink
.anim_name
, anim_name
, 32);
344 struct cdat
* curr_cdatp
;
345 struct set
* curr_setp
;
346 struct link
* curr_linkp
;
348 curr_cdatp
= curr_cdat();
349 curr_setp
= curr_set();
350 curr_linkp
= alloc_link();
352 curr_linkp
->cdat_idx
= curr_cdatp
->idx
;
353 curr_linkp
->type
= 3;
355 curr_linkp
->ele_idx
= curr_setp
->num_ele
;
356 curr_linkp
->link_t
.svlink
.ref_id
= ref_id
;
361 //Insert element into odat_buf and cdatpages
366 struct cdat
* curr_cdatp
;
367 struct odat
* curr_odatp
;
368 struct vdat
* curr_vdatp
;
369 struct set
* curr_setp
;
370 struct ele
* curr_elep
;
371 struct ref
* curr_refp
;
372 struct ref
* prev_refp
;
375 curr_cdatp
= curr_cdat();
376 curr_odatp
= curr_odat(); //malloced @ insert_ele_label
377 curr_vdatp
= curr_vdat();
378 curr_setp
= curr_set();
379 curr_elep
= curr_ele();
380 curr_refp
= alloc_ref();
381 prev_refp
= prev_ref();
383 curr_vdatp
->creator
= curr_odatp
;
384 /* Populate ele in cdat */
385 curr_elep
->cdat_idx
= curr_cdatp
->idx
;
386 curr_setp
->num_ele
++;
388 /* Populate odat for ele */
389 curr_odatp
->cdat_idx
= curr_cdatp
->idx
;
390 curr_odatp
->refp
= curr_refp
;
392 /* Add ele to ref_buf */
393 ref_id
= curr_elep
->ref_id
;
395 if(ref_id
== -1) /* user did not define a ref_id so */
396 { ref_id
= ss_ref_id
;
400 curr_refp
->ref_id
= ref_id
;
401 curr_refp
->lastref
= prev_refp
;
402 curr_refp
->odatp
= curr_odatp
;
403 prev_refp
->nextref
= curr_refp
;
410 { struct odat
* curr_odatp
;
411 curr_odatp
= curr_odat();
412 curr_odatp
->vdat_id
= num_vdats
;
424 struct quad
* curr_quadp
;
425 struct odat
* curr_odatp
;
427 curr_quadp
= curr_quad();
428 curr_odatp
= curr_odat();
433 curr_quadp
->ref_id
= ref_id
;
434 curr_odatp
->num_quads
++;
437 /* Inserting the hitbox into the set
438 odat. Elements that don't have
439 a hitbox will use the sets root. */
444 { struct odat
* curr_odatp
;
446 curr_odatp
= curr_odat();
447 curr_odatp
->hitbox
= hitbox
;
450 /* Inserting the root into the set
451 odat. Elements that don't have
452 a root will use the sets root. */
459 { struct odat
* curr_odatp
;
461 curr_odatp
= curr_odat();
462 curr_odatp
->root
.x
= x
;
463 curr_odatp
->root
.y
= y
;
464 curr_odatp
->root
.z
= z
;
477 { struct vdat
* curr_vdatp
;
478 struct model
* curr_modelp
;
480 curr_vdatp
= curr_vdat();
481 curr_modelp
= curr_model();
483 curr_modelp
->spritesheet
[(int)direction
].height
= height
;
484 curr_modelp
->spritesheet
[(int)direction
].width
= width
;
485 curr_modelp
->spritesheet
[(int)direction
].num_frames
= num_frames
;
486 curr_vdatp
->num_models
++;
494 { struct model
* curr_modelp
;
496 curr_modelp
= curr_model();
498 curr_modelp
->spritesheet
[(int)direction
].frames
[curr_modelp
->spritesheet
[(int)direction
].num_frames
++] = frame
;