2 \brief IR Memory Implementation
3 \details Intermediary memory management
6 ----------------------------------------------------------------------------*/
9 #include <unitypes.h> //uint8_t as a char
10 #include <unistr.h> //u32_cpy
11 #include <stdint.h> //uint64_t
12 #include <stdlib.h> //malloc
16 //scanner_scanpixels(int*, int);
18 /* functions needed from irmem.c */
87 /* struct definitions needed from irmem.c */
89 extern struct cdat
** cdat_stackp
;
90 extern struct odat
* curr_set_odatp
;
94 /* Dynamically allocate memory for a class data structure,
95 or cdat, after a class has been identified in a grammar.
96 We also create a stack of class pointers so that
97 we can access the cdat during processing of that
98 cdats sets and elements, a requirement because the
99 nature of recursive classes prevents us from accessing
100 the cdat based on the previous index into cdat_buf,
101 which is a list of all allocated cdats*/
107 struct cdat
* curr_cdatp
;
109 curr_cdatp
= alloc_cdat();
111 u8_cpy(curr_cdatp
->name
, name
, 32);
112 curr_cdatp
->idx
= num_cdats
;
114 /* Set the cdat as a subclass of the previous cdat */
115 (*cdat_stackp
)->class_list
[(*cdat_stackp
)->num_classes
] = curr_cdatp
;
116 /* Push the cdat onto the cdat_stack */
117 *++cdat_stackp
= curr_cdatp
;
129 /* Every odat has a single map variant. We track the odats that have related map variants
130 by adding the name of the map to the end of the odat name. E.g. for an odat with name
131 A and map variants a,b,c we get A_a, A_b, A_c. We create new odats for each map variant*/
140 struct odat
* curr_odatp
;
141 int curr_odat_vdatid
;
143 curr_odatp
= curr_odat();
145 curr_odat_vdatid
= curr_odatp
->vdat_id
;
149 if(curr_odatp
->map
.name
[0] != 0) //odat already has a map so make a new odat
150 { curr_odatp
= alloc_odat();
151 curr_odatp
->vdat_id
= curr_odat_vdatid
;
153 /* Add a delimiter '_' in between odat name and map variant name */
154 u8_strcat(curr_odatp
->map
.name
, (uint8_t*) '_');
155 u8_strcat(curr_odatp
->map
.name
, name
);
157 u8_strcpy(curr_odatp
->map
.filepath
, filepath
);
158 curr_odatp
->map
.height
= height
;
159 curr_odatp
->map
.width
= width
;
167 /* Called in the reduction of a set. While both odats (eles and sets)
168 have identical label terminals, we are unable to give a single grammatical rule
169 for both due to how we allocate odats in the odat buf. Due to the
170 nature of bottom up parsing, the set label is recognized first, and then the
171 sets elements are recognized. This means that after we have processed the sets elemenets,
172 the curr_odat is going to be the last element and NOT the set that was first allocated.
173 To get around this, we create a global variable set_odatp that will store the pointer
174 to the odat when it is first allocated (in insert_set_label()) so that insert_set() can
175 have access to it. Curr set points the sets representation in the cdat, curr_set_odatp
176 points to the sets representation as an odat*/
185 struct set
* curr_setp
;
187 curr_setp
= curr_set();
188 curr_set_odatp
= alloc_odat();
190 u8_cpy(curr_set_odatp
->name
, name
, 32);
191 u8_cpy(curr_setp
->name
, name
, 32);
192 curr_set_odatp
->parent_odatp
= NULL
;
193 curr_set_odatp
->map
.name
[0] = 0;
196 { curr_set_odatp
->ref_id
= ref_id
;
197 curr_setp
->ref_id
= ref_id
;
200 { curr_setp
->ref_id
= ss_ref_id
;
201 curr_set_odatp
->ref_id
= ss_ref_id
++;
206 /* Inserting a olink instead of a set. Set is really just a placeholder
207 for another set. Allocate the memory for the set so taht it can be populated*/
213 struct set
* curr_setp
;
215 curr_setp
= curr_set();
217 curr_setp
->ref_id
= ref_id
;
227 struct cdat
* curr_cdatp
;
228 struct odat
* curr_odatp
;
229 struct link
* curr_linkp
;
232 curr_cdatp
= curr_cdat();
233 curr_odatp
= curr_odat();
234 curr_linkp
= alloc_link();
236 /* Insert vlink into link_stack so that it gets processed at
238 curr_linkp
->type
= 2;
239 /* Store the target odat information*/
240 curr_linkp
->link_t
.vlink
.ref_id
= ref_id
;
241 u8_cpy(curr_linkp
->link_t
.vlink
.anim_name
, anim_name
, 32);
242 /* Store the linking odat/cdat information */
243 curr_linkp
->classp
= curr_cdatp
;
244 curr_linkp
->odatp
= curr_odatp
;
245 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
246 curr_linkp
->ele_idx
= -1;
250 /* Svlinks dont have animation names */
256 struct cdat
* curr_cdatp
;
257 struct link
* curr_linkp
;
259 curr_cdatp
= curr_cdat();
260 curr_linkp
= alloc_link();
262 /* Insert svlink into link_stack so that it gets processed at
264 curr_linkp
->type
= 3;
265 curr_linkp
->classp
= curr_cdatp
;
266 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
267 curr_linkp
->ele_idx
= -1;
268 curr_linkp
->link_t
.svlink
.ref_id
= ref_id
;
272 /* At the point of reducing to a set, most of the
273 sets odat information has already been populated
274 during the reduction of its right hand side
275 non terminals (hitbox, root, quad_list). */
280 struct odat
* curr_odatp
;
281 struct cdat
* curr_cdatp
;
282 struct set
* curr_setp
;
283 struct ref
* prev_refp
;
284 struct ref
* curr_refp
;
285 struct vdat
* curr_vdatp
;
287 curr_odatp
= curr_set_odatp
; //allocated at insert_set_label
288 curr_cdatp
= curr_cdat();
289 curr_setp
= curr_set();
290 prev_refp
= curr_ref();
291 curr_refp
= alloc_ref();
292 curr_vdatp
= curr_vdat();
294 curr_vdatp
->creator
= curr_set_odatp
;
296 curr_setp
->cdat_idx
= curr_cdatp
->idx
; //does a set need its class idx?
297 u8_cpy(curr_setp
->name
, curr_odatp
->name
, 32);
298 curr_cdatp
->num_sets
++;
300 curr_odatp
->cdat_idx
= curr_cdatp
->idx
;
301 curr_odatp
->refp
= curr_refp
;
303 ref_id
= curr_setp
->ref_id
; // ref_id set by insert_set_label(name, ref_id)
305 curr_refp
->ref_id
= ref_id
;
306 curr_refp
->lastref
= prev_refp
;
307 curr_refp
->odatp
= curr_odatp
;
308 prev_refp
->nextref
= curr_refp
;
313 /* Created as a seperate function, instead of setting the ODATS vdat_id and
314 calling inc_vdat() inside of insert_set(), to account for the set reduction
315 where a vdat is not created (o/v/svlinks). */
320 struct vdat
* curr_vdatp
;
322 curr_vdatp
= curr_vdat();
324 curr_set_odatp
->vdat_id
= num_vdats
; //no vdat_id for odats that have vlinks/svlinks
325 curr_set_odatp
->vdatp
= curr_vdatp
;
326 curr_set_odatp
= NULL
; //This sets odat shouldnt be modified after populating odats vdat info
329 /* Populates the odat name and ref_id for odat, allocate the odat here for the rest of
330 the functions to use via curr_odat(). */
337 struct odat
* curr_odatp
;
339 curr_odatp
= alloc_odat();
341 u8_cpy(curr_odatp
->name
, name
, 32);
342 curr_odatp
->map
.name
[0] = 0;
345 curr_odatp
->ref_id
= ref_id
;
347 curr_odatp
->ref_id
= ss_ref_id
++;
351 /* We don't make an odat here, at output time we will resolve
352 the ref_id to the corresponding odat. */
358 /* Do nothing because we already know the ref_id that
359 the odat needs for this element (in the quad_file) */
368 struct cdat
* curr_cdatp
;
369 struct set
* curr_setp
;
370 struct link
* curr_linkp
;
372 curr_cdatp
= curr_cdat();
373 curr_setp
= curr_set();
374 curr_linkp
= alloc_link();
376 /* Insert vlink into link_stack so that it gets processed at
378 curr_linkp
->classp
= curr_cdatp
;
379 curr_linkp
->type
= 2;
380 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
381 //curr_linkp->ele_idx = curr_setp->num_ele;
382 curr_linkp
->link_t
.vlink
.ref_id
= ref_id
;
383 u8_cpy(curr_linkp
->link_t
.vlink
.anim_name
, anim_name
, 32);
392 struct cdat
* curr_cdatp
;
393 struct set
* curr_setp
;
394 struct link
* curr_linkp
;
396 curr_cdatp
= curr_cdat();
397 curr_setp
= curr_set();
398 curr_linkp
= alloc_link();
400 curr_linkp
->classp
= curr_cdatp
;
401 curr_linkp
->type
= 3;
403 //curr_linkp->ele_idx = curr_setp->num_ele;
404 curr_linkp
->link_t
.svlink
.ref_id
= ref_id
;
409 //Insert element into odat_buf and cdatpages
414 struct cdat
* curr_cdatp
;
415 struct odat
* curr_odatp
;
416 struct vdat
* curr_vdatp
;
417 struct set
* curr_setp
;
418 struct ele
* curr_elep
;
419 struct ref
* curr_refp
;
420 struct ref
* prev_refp
;
423 curr_odatp
= curr_odat(); //malloced @ insert_ele_label
424 curr_vdatp
= curr_vdat();
425 curr_setp
= curr_set();
426 prev_refp
= curr_ref();
427 curr_refp
= alloc_ref();
429 curr_vdatp
->creator
= curr_odatp
;
431 /* Populate odat for ele */
432 curr_odatp
->cdat_idx
= curr_cdatp
->idx
;
433 curr_odatp
->refp
= curr_refp
;
434 curr_odatp
->parent_odatp
= curr_set_odatp
;
436 ref_id
= curr_odatp
->ref_id
;
438 curr_refp
->ref_id
= ref_id
;
439 curr_refp
->lastref
= prev_refp
;
440 curr_refp
->odatp
= curr_odatp
;
441 prev_refp
->nextref
= curr_refp
;
448 { struct odat
* curr_odatp
;
449 curr_odatp
= curr_odat();
450 curr_odatp
->vdat_id
= num_vdats
;
455 (uint8_t* filename
, int height
, int width
, uint8_t* filepath
)
457 struct vdat
* curr_vdatp
;
458 int filename_len
, filepath_len
;
460 curr_vdatp
= alloc_vdat();
462 u8_strcpy(curr_vdatp
->filename
, filename
);
463 u8_strcpy(curr_vdatp
->filepath
, filepath
);
464 curr_vdatp
->height
= height
;
465 curr_vdatp
->width
= width
;
466 curr_vdatp
->creator
= curr_odat();
475 /* ( int x, int y, int z, int ref_id */
478 /* struct quad* curr_quadp; */
480 /* curr_quadp = curr_quad(); */
482 /* curr_quadp->x = x; */
483 /* curr_quadp->y = y; */
484 /* curr_quadp->z = z; */
485 /* curr_quadp->ref_id = ref_id; */
491 /* /\* serting the hitbox into the set */
492 /* odat. Elements that don't have */
493 /* a hitbox will use the sets root. *\/ */
498 /* { struct odat* curr_odatp; */
500 /* curr_odatp = curr_odat(); */
501 /* curr_odatp->hitbox = hitbox; */
504 /* /\* Inserting the root into the set */
505 /* odat. Elements that don't have */
506 /* a root will use the sets root. *\/ */
513 /* { struct odat* curr_odatp; */
515 /* curr_odatp = curr_odat(); */
516 /* curr_odatp->root.x = x; */
517 /* curr_odatp->root.y = y; */
518 /* curr_odatp->root.z = z; */
524 /* insert_framesheet */
525 /* ( uint8_t direction, */
532 /* { struct vdat* curr_vdatp; */
533 /* struct model* curr_modelp; */
535 /* curr_vdatp = curr_vdat(); */
536 /* curr_modelp = curr_model(); */
538 /* curr_modelp->spritesheet[(int)direction].height = height; */
539 /* curr_modelp->spritesheet[(int)direction].width = width; */
540 /* curr_modelp->spritesheet[(int)direction].num_frames = num_frames; */
541 /* curr_vdatp->num_models++; */
545 /* insert_frame_pointer */
546 /* ( uint8_t direction, */
549 /* { struct model* curr_modelp; */
551 /* curr_modelp = curr_model(); */
553 /* curr_modelp->spritesheet[(int)direction].frames[curr_modelp->spritesheet[(int)direction].num_frames++] = frame; */