d31bc1a04be006f24409d0bc4e6293607d50b3fa
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 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
;
224 curr_odatp
= curr_set_odatp
; //allocated at insert_set_label, preserved in global space
225 curr_cdatp
= curr_cdat();
226 curr_setp
= curr_set();
227 prev_refp
= prev_ref();
228 curr_refp
= alloc_ref();
231 curr_setp
->cdat_idx
= curr_cdatp
->idx
; //does a set need its class idx?
232 memmove(curr_setp
->name
, curr_odatp
->name
, 32);
233 curr_cdatp
->num_sets
++;
235 curr_odatp
->cdat_idx
= curr_cdatp
->idx
;
236 curr_odatp
->refp
= curr_refp
;
238 ref_id
= curr_setp
->ref_id
; // ref_id set by insert_set_label(name, ref_id)
240 if(ref_id
== -1) /* user did not define a ref_id */
241 { ref_id
= ss_ref_id
;
245 curr_refp
->ref_id
= ref_id
;
246 curr_refp
->lastref
= prev_refp
;
247 curr_refp
->odatp
= curr_odatp
;
248 prev_refp
->nextref
= curr_refp
;
253 /* Created as a seperate function, instead of setting the ODATS vdat_id and
254 calling inc_vdat() inside of insert_set(), to account for the set reduction
255 where a vdat is not created (o/v/svlinks). */
260 curr_set_odatp
->vdat_id
= num_vdats
; //no vdat_id for odats that have vlinks/svlinks
261 curr_set_odatp
= NULL
; //So this sets odat cant be modified after (which would be a bug)
264 /* Populates both the odat name and ref_id
272 struct ele
* curr_elep
;
273 struct odat
* curr_odatp
;
275 curr_elep
= curr_ele();
276 curr_odatp
= alloc_odat();
278 memmove(curr_odatp
->name
, name
, 32);
280 memmove(curr_elep
->name
, name
, 32);
281 curr_elep
->ref_id
= ref_id
;
284 /* We don't make an odat here, at output time we will resolve
285 the ref_id to the corresponding odat. */
291 struct cdat
* curr_cdatp
;
292 struct set
* curr_setp
;
293 struct ele
* curr_elep
;
294 struct link
* curr_linkp
;
296 curr_cdatp
= curr_cdat();
297 curr_elep
= curr_ele();
298 curr_linkp
= alloc_link();
300 curr_elep
->cdat_idx
= curr_cdatp
->idx
;
301 curr_elep
->ref_id
= ref_id
;
303 curr_linkp
->type
= 1;
304 curr_linkp
->link_t
.olink
.ref_id
= ref_id
;
305 curr_linkp
->cdat_idx
= curr_cdatp
->idx
;
306 curr_linkp
->set_idx
= curr_cdatp
->num_sets
++;
307 curr_linkp
->ele_idx
= curr_setp
->num_ele
++;
317 struct cdat
* curr_cdatp
;
318 struct set
* curr_setp
;
319 struct link
* curr_linkp
;
321 curr_cdatp
= curr_cdat();
322 curr_setp
= curr_set();
323 curr_linkp
= alloc_link();
325 /* Insert vlink into link_stack so that it gets processed at
327 curr_linkp
->cdat_idx
= curr_cdatp
->idx
;
328 curr_linkp
->type
= 2;
329 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
330 curr_linkp
->ele_idx
= curr_setp
->num_ele
;
331 curr_linkp
->link_t
.vlink
.ref_id
= ref_id
;
332 memmove(curr_linkp
->link_t
.vlink
.anim_name
, anim_name
, 32);
341 struct cdat
* curr_cdatp
;
342 struct set
* curr_setp
;
343 struct link
* curr_linkp
;
345 curr_cdatp
= curr_cdat();
346 curr_setp
= curr_set();
347 curr_linkp
= alloc_link();
349 curr_linkp
->cdat_idx
= curr_cdatp
->idx
;
350 curr_linkp
->type
= 3;
352 curr_linkp
->ele_idx
= curr_setp
->num_ele
;
353 curr_linkp
->link_t
.svlink
.ref_id
= ref_id
;
358 //Insert element into odat_buf and cdatpages
363 struct cdat
* curr_cdatp
;
364 struct odat
* curr_odatp
;
365 struct set
* curr_setp
;
366 struct ele
* curr_elep
;
367 struct ref
* curr_refp
;
368 struct ref
* prev_refp
;
370 curr_cdatp
= curr_cdat();
371 curr_odatp
= curr_odat(); //malloced @ insert_ele_label
372 curr_setp
= curr_set();
373 curr_elep
= curr_ele();
374 curr_refp
= alloc_ref();
375 prev_refp
= prev_ref();
377 /* Populate ele in cdat */
378 curr_elep
->cdat_idx
= curr_cdatp
->idx
;
379 curr_setp
->num_ele
++;
381 /* Populate odat for ele */
382 curr_odatp
->cdat_idx
= curr_cdatp
->idx
;
383 curr_odatp
->refp
= curr_refp
;
385 /* Add ele to ref_buf */
386 ref_id
= curr_elep
->ref_id
;
388 if(ref_id
== -1) /* user did not define a ref_id so */
389 { ref_id
= ss_ref_id
;
393 curr_refp
->ref_id
= ref_id
;
394 curr_refp
->lastref
= prev_refp
;
395 curr_refp
->odatp
= curr_odatp
;
396 prev_refp
->nextref
= curr_refp
;
403 { struct odat
* curr_odatp
;
404 curr_odatp
= curr_odat();
405 curr_odatp
->vdat_id
= num_vdats
;
417 struct quad
* curr_quadp
;
418 struct odat
* curr_odatp
;
420 curr_quadp
= curr_quad();
421 curr_odatp
= curr_odat();
426 curr_quadp
->ref_id
= ref_id
;
427 curr_odatp
->num_quads
++;
430 /* Inserting the hitbox into the set
431 odat. Elements that don't have
432 a hitbox will use the sets root. */
437 { struct odat
* curr_odatp
;
439 curr_odatp
= curr_odat();
440 curr_odatp
->hitbox
= hitbox
;
443 /* Inserting the root into the set
444 odat. Elements that don't have
445 a root will use the sets root. */
452 { struct odat
* curr_odatp
;
454 curr_odatp
= curr_odat();
455 curr_odatp
->root
.x
= x
;
456 curr_odatp
->root
.y
= y
;
457 curr_odatp
->root
.z
= z
;
470 { struct vdat
* curr_vdatp
;
471 struct model
* curr_modelp
;
473 curr_vdatp
= curr_vdat();
474 curr_modelp
= curr_model();
476 curr_modelp
->spritesheet
[(int)direction
].height
= height
;
477 curr_modelp
->spritesheet
[(int)direction
].width
= width
;
478 curr_modelp
->spritesheet
[(int)direction
].num_frames
= num_frames
;
479 curr_vdatp
->num_models
++;
487 { struct model
* curr_modelp
;
489 curr_modelp
= curr_model();
491 curr_modelp
->spritesheet
[(int)direction
].frames
[curr_modelp
->spritesheet
[(int)direction
].num_frames
++] = frame
;