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 */
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 vlink 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
->link_t
.svlink
.ref_id
= ref_id
;
209 /* At the point of reducing to a set, most of the
210 sets odat information has already been populated
211 during the reduction of its right hand side
212 non terminals (hitbox, root, quad_list). */
217 struct odat
* curr_odatp
;
218 struct cdat
* curr_cdatp
;
219 struct set
* curr_setp
;
220 struct ref
* prev_refp
;
221 struct ref
* curr_refp
;
223 curr_odatp
= curr_set_odatp
; //allocated at insert_set_label, preserved in global space
224 curr_cdatp
= curr_cdat();
225 curr_setp
= curr_set();
226 prev_refp
= prev_ref();
227 curr_refp
= alloc_ref();
230 curr_setp
->cdat_idx
= curr_cdatp
->idx
; //does a set need its class idx?
231 memmove(curr_setp
->name
, curr_odatp
->name
, 32);
232 curr_cdatp
->num_sets
++;
234 curr_odatp
->cdat_idx
= curr_cdatp
->idx
;
235 curr_odatp
->refp
= curr_refp
;
237 ref_id
= curr_setp
->ref_id
; // ref_id set by insert_set_label(name, ref_id)
239 if(ref_id
== -1) /* user did not define a ref_id */
240 { ref_id
= ss_ref_id
;
244 curr_refp
->ref_id
= ref_id
;
245 curr_refp
->lastref
= prev_refp
;
246 curr_refp
->odatp
= curr_odatp
;
247 prev_refp
->nextref
= curr_refp
;
252 /* Created as a seperate function, instead of setting the ODATS vdat_id and
253 calling inc_vdat() inside of insert_set(), to account for the set reduction
254 where a vdat is not created (o/v/svlinks). */
259 curr_set_odatp
->vdat_id
= num_vdats
; //no vdat_id for odats that have vlinks/svlinks
260 curr_set_odatp
= NULL
; //So this sets odat cant be modified after (which would be a bug)
263 /* Populates both the odat name and ref_id
271 struct ele
* curr_elep
;
272 struct odat
* curr_odatp
;
274 curr_elep
= curr_ele();
275 curr_odatp
= alloc_odat();
277 memmove(curr_odatp
->name
, name
, 32);
279 memmove(curr_elep
->name
, name
, 32);
280 curr_elep
->ref_id
= ref_id
;
288 struct cdat
* curr_cdatp
;
289 struct set
* curr_setp
;
290 struct ele
* curr_elep
;
291 struct link
* curr_linkp
;
293 curr_cdatp
= curr_cdat();
294 curr_elep
= curr_ele();
295 curr_linkp
= alloc_link();
297 curr_elep
->cdat_idx
= curr_cdatp
->idx
;
298 curr_elep
->ref_id
= ref_id
; /* Will be resolved to offset
299 when link is processed */
300 curr_linkp
->type
= 1;
301 curr_linkp
->link_t
.olink
.ref_id
= ref_id
;
302 curr_linkp
->cdat_idx
= curr_cdatp
->idx
;
303 curr_linkp
->set_idx
= curr_cdatp
->num_sets
++;
304 curr_linkp
->ele_idx
= curr_setp
->num_ele
++;
314 struct cdat
* curr_cdatp
;
315 struct set
* curr_setp
;
316 struct link
* curr_linkp
;
318 curr_cdatp
= curr_cdat();
319 curr_setp
= curr_set();
320 curr_linkp
= alloc_link();
322 /* Insert vlink into link_stack so that it gets processed at
324 curr_linkp
->cdat_idx
= curr_cdatp
->idx
;
325 curr_linkp
->type
= 2;
326 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
327 curr_linkp
->ele_idx
= curr_setp
->num_ele
;
328 curr_linkp
->link_t
.vlink
.ref_id
= ref_id
;
329 memmove(curr_linkp
->link_t
.vlink
.anim_name
, anim_name
, 32);
338 struct cdat
* curr_cdatp
;
339 struct set
* curr_setp
;
340 struct link
* curr_linkp
;
342 curr_cdatp
= curr_cdat();
343 curr_setp
= curr_set();
344 curr_linkp
= alloc_link();
346 curr_linkp
->cdat_idx
= curr_cdatp
->idx
;
347 curr_linkp
->type
= 3;
349 curr_linkp
->ele_idx
= curr_setp
->num_ele
;
350 curr_linkp
->link_t
.svlink
.ref_id
= ref_id
;
355 //Insert element into odat_buf and cdatpages
360 struct cdat
* curr_cdatp
;
361 struct odat
* curr_odatp
;
362 struct set
* curr_setp
;
363 struct ele
* curr_elep
;
364 struct ref
* curr_refp
;
365 struct ref
* prev_refp
;
367 curr_cdatp
= curr_cdat();
368 curr_odatp
= curr_odat(); //malloced @ insert_ele_label
369 curr_setp
= curr_set();
370 curr_elep
= curr_ele();
371 curr_refp
= alloc_ref();
372 prev_refp
= prev_ref();
374 /* Populate ele in cdat */
375 curr_elep
->cdat_idx
= curr_cdatp
->idx
;
376 curr_setp
->num_ele
++;
378 /* Populate odat for ele */
379 curr_odatp
->cdat_idx
= curr_cdatp
->idx
;
380 curr_odatp
->refp
= curr_refp
;
382 /* Add ele to ref_buf */
383 ref_id
= curr_elep
->ref_id
;
385 if(ref_id
== -1) /* user did not define a ref_id so */
386 { ref_id
= ss_ref_id
;
390 curr_refp
->ref_id
= ref_id
;
391 curr_refp
->lastref
= prev_refp
;
392 curr_refp
->odatp
= curr_odatp
;
393 prev_refp
->nextref
= curr_refp
;
400 { struct odat
* curr_odatp
;
401 curr_odatp
= curr_odat();
402 curr_odatp
->vdat_id
= num_vdats
;
414 struct quad
* curr_quadp
;
415 struct odat
* curr_odatp
;
417 curr_quadp
= curr_quad();
418 curr_odatp
= curr_odat();
423 curr_quadp
->ref_id
= ref_id
;
424 curr_odatp
->num_quads
++;
427 /* Inserting the hitbox into the set
428 odat. Elements that don't have
429 a hitbox will use the sets root. */
434 { struct odat
* curr_odatp
;
436 curr_odatp
= curr_odat();
437 curr_odatp
->hitbox
= hitbox
;
440 /* Inserting the root into the set
441 odat. Elements that don't have
442 a root will use the sets root. */
449 { struct odat
* curr_odatp
;
451 curr_odatp
= curr_odat();
452 curr_odatp
->root
.x
= x
;
453 curr_odatp
->root
.y
= y
;
454 curr_odatp
->root
.z
= z
;
467 { struct vdat
* curr_vdatp
;
468 struct model
* curr_modelp
;
470 curr_vdatp
= curr_vdat();
471 curr_modelp
= curr_model();
473 curr_modelp
->spritesheet
[(int)direction
].height
= height
;
474 curr_modelp
->spritesheet
[(int)direction
].width
= width
;
475 curr_modelp
->spritesheet
[(int)direction
].num_frames
= num_frames
;
476 curr_vdatp
->num_models
++;
484 { struct model
* curr_modelp
;
486 curr_modelp
= curr_model();
488 curr_modelp
->spritesheet
[(int)direction
].frames
[curr_modelp
->spritesheet
[(int)direction
].num_frames
++] = frame
;