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 */
69 /* struct definitions needed from irmem.c */
71 extern struct cdat
** cdat_stackp
;
72 extern struct odat
* curr_set_odatp
;
73 extern uint64_t ss_ref_id
;
76 /* Dynamically allocate memory for a class data structure,
77 or cdat, after a class has been identified in a grammar.
78 We also create a stack of class pointers so that
79 we can access the cdat during processing of that
80 cdats sets and elements, a requirement because the
81 nature of recursive classes prevents us from accessing
82 the cdat based on the previous index into cdat_buf,
83 which is a list of all allocated cdats*/
89 struct cdat
* curr_cdatp
;
91 curr_cdatp
= alloc_cdat();
93 memmove(curr_cdatp
->name
, name
, 32);
94 curr_cdatp
->idx
= num_cdats
;
96 /* Set the cdat as a subclass of the previous cdat */
97 (*cdat_stackp
)->class_list
[(*cdat_stackp
)->num_classes
] = curr_cdatp
;
98 /* Push the cdat onto the cdat_stack */
99 *++cdat_stackp
= curr_cdatp
;
110 /* Called in the reduction of a set. While both odats (eles and sets)
111 have identical label terminals, we are unable to give a single grammatical rule
112 for both due to how we allocate odats in the odat buf. Due to the
113 nature of bottom up parsing, the set label is recognized first, and then the
114 sets elements are recognized. This means that after we have processed the sets elemenets,
115 the curr_odat is going to be the last element and NOT the set that was first allocated.
116 To get around this, we create a global variable set_odatp that will store the pointer
117 to the odat when it is first allocated (in insert_set_label()) so that insert_set() can
118 have access to it. Curr set points the sets representation in the cdat, curr_set_odatp
119 points to the sets representation as an odat*/
128 struct set
* curr_setp
;
130 curr_setp
= curr_set();
131 curr_set_odatp
= alloc_odat();
133 memmove(curr_set_odatp
->name
, name
, 32);
134 memmove(curr_setp
->name
, name
, 32);
137 { curr_set_odatp
->ref_id
= ref_id
;
138 curr_setp
->ref_id
= ref_id
;
141 { curr_setp
->ref_id
= ss_ref_id
;
142 curr_set_odatp
->ref_id
= ss_ref_id
++;
147 /* Inserting a olink instead of a set. Set is really just a placeholder
148 for another set. Allocate the memory for the set so taht it can be populated*/
154 struct set
* curr_setp
;
156 curr_setp
= curr_set();
158 curr_setp
->ref_id
= ref_id
;
168 struct cdat
* curr_cdatp
;
169 struct odat
* curr_odatp
;
170 struct link
* curr_linkp
;
173 curr_cdatp
= curr_cdat();
174 curr_odatp
= curr_odat();
175 curr_linkp
= alloc_link();
177 /* Insert vlink into link_stack so that it gets processed at
179 curr_linkp
->type
= 2;
180 /* Store the target odat information*/
181 curr_linkp
->link_t
.vlink
.ref_id
= ref_id
;
182 memmove(curr_linkp
->link_t
.vlink
.anim_name
, anim_name
, 32);
183 /* Store the linking odat/cdat information */
184 curr_linkp
->classp
= curr_cdatp
;
185 curr_linkp
->odatp
= curr_odatp
;
186 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
187 curr_linkp
->ele_idx
= -1;
191 /* Svlinks dont have animation names */
197 struct cdat
* curr_cdatp
;
198 struct link
* curr_linkp
;
200 curr_cdatp
= curr_cdat();
201 curr_linkp
= alloc_link();
203 /* Insert svlink into link_stack so that it gets processed at
205 curr_linkp
->type
= 3;
206 curr_linkp
->classp
= curr_cdatp
;
207 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
208 curr_linkp
->ele_idx
= -1;
209 curr_linkp
->link_t
.svlink
.ref_id
= ref_id
;
213 /* At the point of reducing to a set, most of the
214 sets odat information has already been populated
215 during the reduction of its right hand side
216 non terminals (hitbox, root, quad_list). */
221 struct odat
* curr_odatp
;
222 struct cdat
* curr_cdatp
;
223 struct set
* curr_setp
;
224 struct ref
* prev_refp
;
225 struct ref
* curr_refp
;
226 struct vdat
* curr_vdatp
;
228 curr_odatp
= curr_set_odatp
; //allocated at insert_set_label, preserved in global space
229 curr_cdatp
= curr_cdat();
230 curr_setp
= curr_set();
231 prev_refp
= curr_ref();
232 curr_refp
= alloc_ref();
233 curr_vdatp
= curr_vdat();
235 curr_vdatp
->creator
= curr_set_odatp
;
237 curr_setp
->cdat_idx
= curr_cdatp
->idx
; //does a set need its class idx?
238 memmove(curr_setp
->name
, curr_odatp
->name
, 32);
239 curr_cdatp
->num_sets
++;
241 curr_odatp
->cdat_idx
= curr_cdatp
->idx
;
242 curr_odatp
->refp
= curr_refp
;
244 ref_id
= curr_setp
->ref_id
; // ref_id set by insert_set_label(name, ref_id)
246 curr_refp
->ref_id
= ref_id
;
247 curr_refp
->lastref
= prev_refp
;
248 curr_refp
->odatp
= curr_odatp
;
249 prev_refp
->nextref
= curr_refp
;
254 /* Created as a seperate function, instead of setting the ODATS vdat_id and
255 calling inc_vdat() inside of insert_set(), to account for the set reduction
256 where a vdat is not created (o/v/svlinks). */
261 struct vdat
* curr_vdatp
;
263 curr_vdatp
= curr_vdat();
265 curr_set_odatp
->vdat_id
= num_vdats
; //no vdat_id for odats that have vlinks/svlinks
266 curr_set_odatp
->vdatp
= curr_vdatp
;
267 curr_set_odatp
= NULL
; //This sets odat shouldnt be modified after populating odats vdat info
270 /* Populates the odat name and ref_id for odat, allocate the odat here for the rest of
271 the functions to use via curr_odat(). */
278 struct odat
* curr_odatp
;
280 curr_odatp
= alloc_odat();
282 memmove(curr_odatp
->name
, name
, 32);
285 curr_odatp
->ref_id
= ref_id
;
287 curr_odatp
->ref_id
= ss_ref_id
++;
291 /* We don't make an odat here, at output time we will resolve
292 the ref_id to the corresponding odat. */
298 /* Do nothing because we already know the ref_id that
299 the odat needs for this element (in the quad_file) */
308 struct cdat
* curr_cdatp
;
309 struct set
* curr_setp
;
310 struct link
* curr_linkp
;
312 curr_cdatp
= curr_cdat();
313 curr_setp
= curr_set();
314 curr_linkp
= alloc_link();
316 /* Insert vlink into link_stack so that it gets processed at
318 curr_linkp
->classp
= curr_cdatp
;
319 curr_linkp
->type
= 2;
320 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
321 //curr_linkp->ele_idx = curr_setp->num_ele;
322 curr_linkp
->link_t
.vlink
.ref_id
= ref_id
;
323 memmove(curr_linkp
->link_t
.vlink
.anim_name
, anim_name
, 32);
332 struct cdat
* curr_cdatp
;
333 struct set
* curr_setp
;
334 struct link
* curr_linkp
;
336 curr_cdatp
= curr_cdat();
337 curr_setp
= curr_set();
338 curr_linkp
= alloc_link();
340 curr_linkp
->classp
= curr_cdatp
;
341 curr_linkp
->type
= 3;
343 //curr_linkp->ele_idx = curr_setp->num_ele;
344 curr_linkp
->link_t
.svlink
.ref_id
= ref_id
;
349 //Insert element into odat_buf and cdatpages
354 struct cdat
* curr_cdatp
;
355 struct odat
* curr_odatp
;
356 struct vdat
* curr_vdatp
;
357 struct set
* curr_setp
;
358 struct ele
* curr_elep
;
359 struct ref
* curr_refp
;
360 struct ref
* prev_refp
;
363 curr_odatp
= curr_odat(); //malloced @ insert_ele_label
364 curr_vdatp
= curr_vdat();
365 curr_setp
= curr_set();
366 prev_refp
= curr_ref();
367 curr_refp
= alloc_ref();
369 curr_vdatp
->creator
= curr_odatp
;
371 /* Populate odat for ele */
372 curr_odatp
->cdat_idx
= curr_cdatp
->idx
;
373 curr_odatp
->refp
= curr_refp
;
375 ref_id
= curr_odatp
->ref_id
;
377 curr_refp
->ref_id
= ref_id
;
378 curr_refp
->lastref
= prev_refp
;
379 curr_refp
->odatp
= curr_odatp
;
380 prev_refp
->nextref
= curr_refp
;
387 { struct odat
* curr_odatp
;
388 curr_odatp
= curr_odat();
389 curr_odatp
->vdat_id
= num_vdats
;
397 struct odat
* curr_odatp
;
399 curr_odatp
->quad_filep
= quad_filep
;
402 /* Inserting the hitbox into the set
403 odat. Elements that don't have
404 a hitbox will use the sets root. */
409 { struct odat
* curr_odatp
;
411 curr_odatp
= curr_odat();
412 curr_odatp
->hitbox
= hitbox
;
415 /* Inserting the root into the set
416 odat. Elements that don't have
417 a root will use the sets root. */
424 { struct odat
* curr_odatp
;
426 curr_odatp
= curr_odat();
427 curr_odatp
->root
.x
= x
;
428 curr_odatp
->root
.y
= y
;
429 curr_odatp
->root
.z
= z
;
442 { struct vdat
* curr_vdatp
;
443 struct model
* curr_modelp
;
445 curr_vdatp
= curr_vdat();
446 curr_modelp
= curr_model();
448 curr_modelp
->spritesheet
[(int)direction
].height
= height
;
449 curr_modelp
->spritesheet
[(int)direction
].width
= width
;
450 curr_modelp
->spritesheet
[(int)direction
].num_frames
= num_frames
;
451 curr_vdatp
->num_models
++;
459 { struct model
* curr_modelp
;
461 curr_modelp
= curr_model();
463 curr_modelp
->spritesheet
[(int)direction
].frames
[curr_modelp
->spritesheet
[(int)direction
].num_frames
++] = frame
;