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 <string.h> //memset
13 #include <unistd.h> //u8_* functions
19 name_u8_cpy(struct name
*, struct name
*);
23 name_u8_cmp(struct name
*, struct name
*);
27 name_u8_set(struct name
*, ucs4_t
);
64 push_cdat(struct name
*);
70 insert_link_name(struct name
*);
72 insert_link_namelist(struct name
*);
74 insert_ss_name(struct name
*);
76 insert_ss_namelist(struct name
*);
78 insert_mlink(struct name
*, int);
80 insert_vlink(struct name
*, int);
82 insert_ref(struct odat
*, int);
88 insert_map(struct name
*, int, int, int, int, uint8_t*);
90 insert_framesheet(struct name
*, int, int, int, int, uint8_t*);
94 //type safety handled by macro expansion (do not call these directly from code, make dependent macros for access to these)
95 #define CHUNKS_LEN(STACK) ((STACK).csp - (STACK).chunks)
96 #define CURRENT_CHUNK(STACK) ((STACK).chunks[CHUNKS_LEN(STACK) - 1])
97 #define CHUNKS_FULL(STACK) ( (STACK).csp >= \
98 (STACK).chunks + MAX_CHUNKS * (STACK).chunk_size)
99 #define CURRENT_DSP(STACK,TYPE) ((TYPE*) ((STACK).dsp[CHUNKS_LEN(STACK) - 1]))
100 #define DATA_FULL(STACK,TYPE) ((void*) CURRENT_DSP(STACK,TYPE) >= \
101 (CURRENT_CHUNK(STACK) + (STACK).chunk_size))
102 #define CSP_PUSH(STACK) (*(++(STACK).csp) = malloc((STACK).chunk_size))
103 #define CURRENT_DATP(STACK,TYPE) (((TYPE**)(STACK).dsp)[CHUNKS_LEN(STACK) - 1])
104 #define PREVIOUS_DATP(STACK,TYPE) (((TYPE**)(STACK).dsp)[CHUNKS_LEN(STACK) - 2])
105 #define ALLOC_DAT(STACK,TYPE) (++CURRENT_DATP(STACK,TYPE))
106 #define INIT_STACK(STACK,TYPE) \
108 (STACK).chunk_size = PAGES_PER_CHUNK * pagesize; \
109 (STACK).max_dats = (STACK).chunk_size / sizeof (TYPE); \
111 for( i = 0; i < MAX_CHUNKS; i++){ \
112 (STACK).dsp[i] += pagesize; \
115 //Stack-specific macros (called directly from code (safety enforcement)
116 #define INIT_ODAT() (INIT_STACK(ocs, struct odat))
117 #define CURRENT_ODAT() (CURRENT_DATP(ocs,struct odat))
118 #define ODAT_FULL() (DATA_FULL(ocs,struct odat))
119 #define ODAT_ALLOC() (ALLOC_DAT(ocs,struct odat))
120 #define OCS_FULL() (CHUNKS_FULL(ocs))
121 #define INIT_VDAT() (INIT_STACK(vcs, struct vdat))
122 #define CURRENT_VDAT() (CURRENT_DATP(vcs,struct vdat))
123 #define VDAT_FULL() (DATA_FULL(vcs,struct vdat))
124 #define VDAT_ALLOC() (ALLOC_DAT(vcs,struct vdat))
125 #define VCS_FULL() (CHUNKS_FULL(vcs))
126 #define INIT_CDAT() (INIT_STACK(ccs, struct cdat))
127 #define CURRENT_CDAT() (CURRENT_DATP(ccs,struct cdat))
128 #define CDAT_FULL() (DATA_FULL(ccs, struct cdat))
129 #define CDAT_ALLOC() (ALLOC_DAT(ccs, struct cdat))
130 #define CCS_FULL() (CHUNKS_FULL(ccs))
131 #define INIT_SET() (INIT_STACK(scs, struct set))
132 #define CURRENT_SET() (CURRENT_DATP(scs, struct set))
133 #define SET_FULL() (DATA_FULL(scs, struct set))
134 #define SET_ALLOC() (ALLOC_DAT(scs, struct set))
135 #define SCS_FULL() (CHUNKS_FULL(scs))
136 #define INIT_LINK() (INIT_STACK(lcs, struct link))
137 #define CURRENT_LINK() (CURRENT_DATP(lcs,struct link))
138 #define LDAT_FULL() (DATA_FULL(lcs, struct link))
139 #define LDAT_ALLOC() (ALLOC_DAT(lcs, struct link))
140 #define LCS_FULL() (CHUNKS_FULL(lcs))
141 #define INIT_POST() (INIT_STACK(rcs, struct ref))
142 #define CURRENT_POST() (CURRENT_DATP(pcs,struct ref))
143 #define POST_FULL() (DATA_FULL(pcs,struct ref))
144 #define POST_ALLOC() (ALLOC_DAT(pcs,struct ref))
145 #define PCS_FULL() (CHUNKS_FULL(pcs))
146 #define INIT_REF() (INIT_STACK(rcs, struct ref))
147 #define CURRENT_REF() (CURRENT_DATP(rcs,struct ref))
148 #define PREVIOUS_REF() (PREVIOUS_DATP(rcs, struct ref))
149 #define REF_FULL() (DATA_FULL(rcs,struct ref))
150 #define REF_ALLOC() (ALLOC_DAT(rcs,struct ref))
151 #define RCS_FULL() (CHUNKS_FULL(rcs))
153 #define CURRENT_MODEL() (CURRENT_VDAT()->model_list[CURRENT_VDAT()->num_models])
157 /* Dynamically allocate memory for a class data structure, */
158 /* or cdat, after a class has been identified in a grammar. */
159 /* We also create a stack of class pointers so that */
160 /* we can access the cdat during processing of that */
161 /* cdats sets and elements, a requirement because the */
162 /* nature of recursive classes prevents us from accessing */
163 /* the cdat based on the previous index into cdat_buf, */
164 /* which is a list of all allocated cdats */
165 /* Cdats: A cdat is a class data structure. Cdats serve as the central */
166 /* data types of the IR. Cdats contain pointers to their subclasses so that the relationship between */
167 /* classes can be determined, but the subclasses are not represented inside */
168 /* of the cdat itself but rather in subsequent cdats in cdat_buf. We */
169 /* can determine the number of subclasses (the last index into cdat_buf */
170 /* that represents a subclass of some arbitrary cdat) each cdat has by */
171 /* incrementing num_classes during parse time. */
172 /* TODO: Should classes point to their parent class? */
173 /* TODO: Talk more about cdat set structure */
179 struct cdat
* class_list
[MAX_CLASSES
];
180 struct set
* set_list
[MAX_SETS
];
184 /* Sets: What is a set?
189 The set is populated at parse time AFTER the elements are populated, due to
190 the nature of bottom up parsing. */
194 struct set
* set_list
[MAX_SETS
];
197 /* Refs: Each set/ele has a reference to its object data (odat) through a refid.
198 refids are unsigned 64 byte integers that map to the hex values RGBA. During
199 the construction of the directory structure, users can choose a RGBA value for
200 each object that any other object can refer to via links (see link). If a user
201 does not choose an RGBA value, then the object is given one from the system space.
202 We maintain a doubly linked list of refs in the ref_buf at parse time so that
203 links can be resolved after the parsing of the directory structure is complete.
204 For every 16th ref, we create a post so that we can reduce on the search time for
208 int type
; //TODO: Is this needed?
212 int refid
; //0xFFFFFF->digit
215 /* Links: At parse time, a set/ele can include a link in their
216 grammar representation instead of the actual data and this signifies
217 to the APC that that set/ele wishes to use the data of another
218 set/ele, either its video data (vdat) or object data (odat). The link
219 itself contains the type of link it is, the refid OR name, and
220 which set/ele created the link. During parse time, links can be made
221 to o/vdats that have yet to be parsed. In order to accomodate for this,
222 we resolve all links AFTER parse time by iterating through the link_buf,
223 finding the refid that was stored for some object (if the refid exists),
224 and creating a relative pointer from the original object to the data that
227 /* TODO: Explain links more betta */
235 struct name src_animname
;
236 struct name src_namelist
[MAX_DEPTH
];
241 struct name src_mapname
;
242 struct name src_namelist
[MAX_DEPTH
];
253 /* From: src odat ()To: dest odat (refid)*/
255 int type
; //1 = olink, 2 = vlink, 3 = mlink
257 int dest_refid
; //if it exists
258 struct odat
* dest_odatp
;
266 uint8_t filepath
[FPATH_MAX
];
269 /* Odats: Odats consist of the object data necessary for
270 each object. Odats are sometimes referred to as archetypes
271 at compile-time, in order to distinguish the difference from
272 a runtime object and a compile-time object.
273 TODO: Need more info about objects at runtime, to described
274 the reasoning behind odat structure at compile-time*/
282 struct odat
* parent_odatp
; // odat == set ? null : set refid
283 struct ref
* refp
; /* pointer to it's ref on ref_list */
284 struct map map
; //only valid if odat ismap
288 /* A framesheet is a grouping of animation frames in
289 a single direction (N,W,S,E) */
293 uint8_t filepath
[FPATH_MAX
];
298 /* A model is a collection of framesheets for every
299 direction (N,W,S,E,NW,NE,SW,SE)*/
300 /* NAMED spritesheet */
303 struct framesheet spritesheet
[8]; //one for each
306 /* Vdat: Vdats are the video data of each object. They can not be
307 created as a stand alone object (because they consist solely
308 of animation information and not the map which the
309 animation manipulates). Vdats have a list of models for every
310 animation that the vdats odat can do for that vdat*/
312 struct odat
* creator
; //pointer to odat that made this vdat
314 uint8_t filename
[FNAME_MAX
];
317 uint8_t filepath
[FPATH_MAX
];
318 struct model model_list
[MAX_MODELS
];
323 { struct name namelist
[MAX_DEPTH
];
332 { struct set_frame set_frames
[MAX_DEPTH
];
333 int curr_depth
; //used to get most recently created set/odat + to check for undefined parents of namelists
337 //"type free" chunk stacking
339 { void* chunks
[MAX_CHUNKS
];
340 void* *csp
; //chunk stack pointer
341 void* dsp
[MAX_CHUNKS
]; //dat stack pointer (per chunk)
342 int chunk_size
; //size of a chunk (including its forfeited page)
343 int max_dats
; //number of dats per chunk for this stack
344 } ocs
, vcs
, ccs
, rcs
, lcs
, pcs
, scs
; //odat, vdat, cdat, ref, link, post stacks
349 /* The cdat_stack is a stack pointers to cdat pointers, the top of which is
350 the cdat that is currently being parsed. Whenever a new cdat is recognized
351 by the grammar (CLOPEN), a cdat is pushed onto the cdat_stack, and we refer
352 to this cdat through the macro CURR_CDAT. By keeping a cdat_stack, we have
353 access to the current cdat so that the elements and sets can populate themselves
354 in the cdat accordingly. */
357 struct cdat
* cdat_stack
[MAX_CLASSES
];
358 struct cdat
** cdat_stackp
;
361 struct name set_namelist
[MAX_DEPTH
];
362 int set_numnames
= 0;
364 struct name link_namelist
[MAX_DEPTH
];
365 int link_numnames
= 0;
372 int ss_refid
= 0x0FFFFFFF; /* system space for refids */
379 /* The initalization function of the IR. */
385 uint8_t root
[4] = "root";
387 u8_stpncpy(name
.name
, root
, 4);
389 pagesize
= sysconf(_SC_PAGESIZE
);
392 *cdat_stackp
= CURRENT_CDAT();
393 name_u8_cpy(&(*cdat_stackp
)->name
, &name
);
397 VDAT_ALLOC(); //NULL vdat
398 VDAT_ALLOC(); //First vdat req. because alloc_vdat happens after vdat is reduced
414 for(i
= 0; i
< CHUNKS_LEN(ccs
) ; i
++)
418 for(i
= 0; i
< CHUNKS_LEN(ocs
); i
++)
422 for(i
= 0; i
< CHUNKS_LEN(vcs
) ; i
++)
426 for(i
= 0; i
< CHUNKS_LEN(rcs
); i
++)
430 for(i
= 0; i
< CHUNKS_LEN(lcs
); i
++)
434 for(i
= 0; i
< CHUNKS_LEN(pcs
); i
++)
447 { fprintf(stderr
, "You have allocated to many (%d) cdats ", num_cdats
);
456 return CURRENT_CDAT();
459 //these should probably be inline
467 { fprintf(stderr
, "You have allocated to many (%d) odats ", num_odats
);
476 return CURRENT_ODAT();
485 { fprintf(stderr
, "You have allocated to many (%d) vdats ", num_vdats
);
503 { fprintf(stderr
, "You have allocated to many (%d) sets ", num_sets
);
512 return CURRENT_SET();
522 { fprintf(stderr
, "You have allocated to many (%d) links ", num_links
);
531 return CURRENT_LINK();
541 { fprintf(stderr
, "You have allocated to many (%d) refs ", num_refs
);
551 if(num_refs
% 16 == 0)
552 { CURRENT_POST() = CURRENT_REF();
556 return CURRENT_REF();
564 { fprintf(stderr
, "You have allocated to many (%d) refs ", num_posts
);
579 return (*cdat_stackp
);
586 return CURRENT_ODAT();
593 return CURRENT_VDAT();
600 return CURRENT_SET();
607 return CURRENT_SET();
614 return CURRENT_REF();
620 return PREVIOUS_REF();
626 return &CURRENT_MODEL();
635 struct cdat
* curr_cdatp
;
637 curr_cdatp
= alloc_cdat();
639 name_u8_cpy(&curr_cdatp
->name
, name
);
640 curr_cdatp
->idx
= num_cdats
;
642 /* Set the cdat as a subclass of the previous cdat */
643 (*cdat_stackp
)->class_list
[(*cdat_stackp
)->num_classes
] = curr_cdatp
;
644 /* Push the cdat onto the cdat_stack */
645 *++cdat_stackp
= curr_cdatp
;
662 //Push name onto current namelist, set the set_namelist.
663 name_u8_cpy(&set_namelist
[set_numnames
++], name
);
673 { int depth
, nameidx
, i
;
675 insert_set_name(name
);
677 //Check if entire string matches first? Only possible if namelist is contiguous (uint8_t strings seperated by \0)
678 //Create odats/sets for each name in namelist where nameidx > ns_depth
679 //first check if any parts of namelist matches what is currently on namestack
680 //we can gauruntee that from ns_depth + 1 -> set_numnames namelists dont match. x
683 //if name_list doesnt match, from the first depth at which namelist doesnt match
684 //remove the nameframes namelist (zero out ones below?) and replace with current namelist,
685 //then allocate a new odat and set it to the current set_frame.
686 for( depth
= 0; depth
< set_numnames
; depth
++ )
687 { for (nameidx
= 0; nameidx
<= depth
; nameidx
++)
688 { if( name_u8_cmp(&set_namelist
[nameidx
], &ss
.set_frames
[depth
].namelist
[nameidx
]) != 0 )
689 { /* Populate the namelist of the set at the current depth */
690 for(i
= 0; i
<= depth
; i
++)
691 name_u8_cpy(&ss
.set_frames
[depth
].namelist
[i
], &set_namelist
[i
]);
693 /* Alloc set and odat */
694 ss
.set_frames
[depth
].odatp
= alloc_odat();
695 ss
.set_frames
[depth
].setp
= alloc_set();
697 /* populate set/odat name and cdat_idx */
698 name_u8_cpy(&ss
.set_frames
[depth
].odatp
->name
, &set_namelist
[depth
]);
699 ss
.set_frames
[depth
].setp
->cdat_idx
= ( *cdat_stackp
)->idx
;
701 /* Insert allocated set and odat into their respective trees if there is a depth
702 (they have parents) */
704 { ss
.set_frames
[depth
].odatp
->parent_odatp
= ss
.set_frames
[depth
-1].odatp
;
705 if(ss
.set_frames
[depth
-1].setp
->num_sets
< MAX_SETS
)
706 ss
.set_frames
[depth
-1].setp
->set_list
[ss
.set_frames
[depth
-1].setp
->num_sets
++] = ss
.set_frames
[depth
].setp
;
708 { printf("you have allocated too many sets in insert_namelist()\n");
712 else /* no parent set, so assign to cdat set_list */
713 { ss
.set_frames
[depth
].odatp
->parent_odatp
= NULL
; //no parent odat = NULL.
714 if(curr_cdat_set()->num_sets
< MAX_SETS
)
715 curr_cdat_set()->set_list
[curr_cdat_set()->num_sets
++] = ss
.set_frames
[depth
].setp
;
717 { printf("you have allocated too many sets in insert_namelist()\n");
723 ss
.set_frames
[depth
].num_names
= set_numnames
;
724 ss
.curr_depth
= depth
;
732 /*. We create new odats for each map variant that are children of the current odat/set
733 , set their name as the map name, and identify them by marking them as a map. This lets
734 us distinguish between sibling odatsthat have the same name because the map of the parent
735 odat had the same name as another, regular odat*/
736 #define CURR_SS_FRAME() (ss.set_frames[ss.curr_depth])
737 #define CURR_SS_SETP() (CURR_SS_FRAME().setp)
738 #define CURR_SS_ODATP() (CURR_SS_FRAME().odatp)
741 ( name
, direction
, height
, width
, refid
, filepath
)
743 int direction
, height
, width
, refid
;
746 struct odat
* curr_mem_odatp
; //pointer to odat in odat_buf
747 struct set
* curr_mem_setp
; //pointer to set in set_buf
750 curr_mem_odatp
= alloc_odat();
751 curr_mem_setp
= alloc_set();
752 //Create a new odat, make its parent be the set. Make a set for mdat, its name should
753 //be the name of the odat + name of model. That makes a conflict beween odats that are named
754 //the same thing as the model of a sibling odat that was created from a map. They can have
755 //same name if the map odat is marked. So mark the map odat.
758 curr_mem_odatp
->parent_odatp
= CURR_SS_ODATP();
759 //insert into set_list
760 if(CURR_SS_SETP()->num_sets
< MAX_SETS
)
761 CURR_SS_SETP()->set_list
[CURR_SS_SETP()->num_sets
++] = curr_mem_setp
;
763 { printf("You have allocated to many sets, error in insert_map()\n");
767 //indicate that newly created odat is a map
768 curr_mem_odatp
->ismap
= 1;
769 //set odat and set name
770 name_u8_cpy(&curr_mem_odatp
->name
, name
);
772 /* set cdat idx values for both set and odat */
773 curr_mem_setp
->cdat_idx
= num_cdats
;
775 /* TODO: INSERT MAP HEIGHT/WIDTH/NAME/FILEPATH INTO ODAT */
778 /* Generate refid if needed, put into ref_buf */
782 insert_ref(curr_mem_odatp
, refid
);
784 /* If current odatp on stack has a link, then we need to make our own link. just set the vdat_idx */
785 if(CURR_SS_ODATP()->vdat_idx
== 0)
787 linkp
= alloc_link();
788 linkp
->type
= CURR_SS_ODATP()->linkp
->type
;
789 linkp
->dest_odatp
= CURR_SS_ODATP();
790 linkp
->dest_refid
= refid
;
791 linkp
->link_t
.mlink
.src_refid
= CURR_SS_ODATP()->linkp
->link_t
.mlink
.src_refid
;
793 /* Copy the animation name of the vlink*/
794 name_u8_cpy(&linkp
->link_t
.vlink
.src_animname
, &CURR_SS_ODATP()->linkp
->link_t
.vlink
.src_animname
);
795 /* Copy the namelist of the vlink*/
796 for(i
= 0; i
< MAX_DEPTH
; i
++)
797 name_u8_cpy(&linkp
->link_t
.vlink
.src_namelist
[i
], &CURR_SS_ODATP()->linkp
->link_t
.vlink
.src_namelist
[i
]);
800 curr_mem_odatp
->vdat_idx
= CURR_SS_ODATP()->vdat_idx
;
808 /* 11/22 Each vdat has a multiple models. Each model has 8 framesheets, one in each
809 direction, that create a spritesheet. Inserting framesheets into the correct
810 model is just a matter of checking whether or not the last models name matches
812 the current one. We can never get a framesheet that is for the same model before
813 AND after some other model, due to alphasorting of the files in each directory */
816 ( model_name
, direction
, height
, width
, refid
, filepath
)
817 struct name
* model_name
;
818 int direction
, height
, width
, refid
;
820 { struct vdat
* curr_vdatp
;
821 struct model
* curr_modelp
;
822 static struct name last_model_name
[32];
825 curr_vdatp
= curr_vdat();
827 /* If the model name changed, that means there are no more
828 framesheets for that model to be processed, a guaruntee we make
829 b/c the filenames are alphabetically sorted */
830 if(!name_u8_cmp(last_model_name
, model_name
))
831 { if(curr_vdatp
->num_models
)
832 curr_vdatp
->num_models
++;
833 num_models
++; // total number of models
837 if(CURR_SS_ODATP()->refid
== 0)
840 insert_ref(CURR_SS_ODATP(), refid
);//given a odatp and a refid, insert the odatp into the ref_buf.
841 //push ref into ref_buf.
844 printf("error: redefining a previously set refid\n");
846 curr_modelp
= curr_model();
848 name_u8_cpy(&curr_modelp
->name
, model_name
);
849 curr_modelp
->spritesheet
[direction
].height
= height
;
850 curr_modelp
->spritesheet
[direction
].width
= width
;
851 /* TODO: INSERT FILEPATH INTO VDAT */
852 u8_stpncpy(curr_modelp
->spritesheet
[direction
].filepath
, filepath
, FPATH_MAX
);
854 name_u8_cpy(last_model_name
, model_name
);
861 //src_path is stored in link_namelist
864 ( src_mapname
, src_refid
)
865 struct name
* src_mapname
;
867 { struct link
* linkp
;
870 linkp
= alloc_link();
874 /* set the name of the src map for the link, if a name exists */
876 name_u8_cpy(&linkp
->link_t
.mlink
.src_mapname
, src_mapname
);
877 /* Set the source ref id of the link */
878 linkp
->link_t
.mlink
.src_refid
= src_refid
;
879 /* Copy the entire namelist of the link, if it exists */
880 for(i
= 0; i
< link_numnames
; i
--) //TODO MAX_DEPTH -> link_namelist_num??
881 { name_u8_cpy(&linkp
->link_t
.mlink
.src_namelist
[i
], &link_namelist
[i
]);
882 name_u8_set(&link_namelist
[i
], (ucs4_t
) 0);
886 linkp
->dest_odatp
= CURR_SS_ODATP();//current odat on set_stack
895 //Push name onto current namelist, set the set_namelist.
896 name_u8_cpy(&link_namelist
[link_numnames
++], name
);
900 /* Nearly identical to mlink */
903 ( src_animname
, src_refid
)
904 struct name
* src_animname
;
906 { struct link
* linkp
;
909 linkp
= alloc_link();
914 /* set the name of the src animname for the link, if a name exists */
916 name_u8_cpy(&linkp
->link_t
.vlink
.src_animname
, src_animname
);
918 /* Set the source ref id of the link */
919 linkp
->link_t
.mlink
.src_refid
= src_refid
;
921 /* Copy the entire namelist of the link, if it exists */
922 for(i
= 0; i
< link_numnames
; i
++) //TODO MAX_DEPTH -> link_namelist_num??
923 { name_u8_cpy(&linkp
->link_t
.vlink
.src_namelist
[i
], &link_namelist
[i
]);
924 name_u8_set(&link_namelist
[i
], (ucs4_t
) 0);//set to null for next link_namelist
927 linkp
->dest_odatp
= CURR_SS_ODATP();//current odat on set_stack
932 /* TODO: Do we really need to store the prev/next pointer? iterating through the
933 ref_buf could be achieved by iterating until the num_refs anyway. */
939 { struct ref
* curr_refp
;
940 struct ref
* prev_refp
;
942 curr_refp
= alloc_ref();
943 prev_refp
= prev_ref();
945 prev_refp
->nextref
= curr_refp
;
946 curr_refp
->lastref
= prev_refp
;
948 curr_refp
->odatp
= odatp
;
949 curr_refp
->refid
= refid
;
953 CURRENT_POST()->refid
= refid
;
954 CURRENT_POST()->odatp
= odatp
;
964 { struct vdat
* curr_vdatp
;
966 curr_vdatp
= curr_vdat();
968 curr_vdatp
->creator
= CURR_SS_ODATP();
969 CURR_SS_ODATP()->vdat_idx
= num_vdats
;
970 CURR_SS_ODATP()->vdatp
= curr_vdatp
;
978 { CURR_SS_ODATP()->refid
= refid
;
983 /* Called in the reduction of a set. While both odats (eles and sets)
984 have identical label terminals, we are unable to give a single grammatical rule
985 for both due to how we allocate odats in the odat buf. Due to the
986 nature of bottom up parsing, the set label is recognized first, and then the
987 sets elements are recognized. This means that after we have processed the sets elemenets,
988 the curr_odat is going to be the last element and NOT the set that was first allocated.
989 To get around this, we create a global variable set_odatp that will store the pointer
990 to the odat when it is first allocated (in insert_set_label()) so that insert_set() can
991 have access to it. Curr set points the sets representation in the cdat, curr_set_odatp
992 points to the sets representation as an odat*/
994 //TODO: Add insert_set_ref()
995 //TODO: Is this the correct allocation scheme? No do the one ken suggested
1002 struct set
* curr_setp
;
1004 curr_setp
= curr_set();
1005 curr_set_odatp
= alloc_odat();
1007 u8_cpy(curr_set_odatp
->name
, name
, 32);
1008 u8_cpy(curr_setp
->name
, name
, 32);
1009 curr_set_odatp
->parent_odatp
= NULL
;
1014 /* Inserting a olink instead of a set. Set is really just a placeholder
1015 for another set. Allocate the memory for the set so taht it can be populated*/
1021 struct set
* curr_setp
;
1023 curr_setp
= curr_set();
1025 curr_setp
->refid
= refid
;
1035 struct cdat
* curr_cdatp
;
1036 struct odat
* curr_odatp
;
1037 struct link
* curr_linkp
;
1040 curr_cdatp
= curr_cdat();
1041 curr_odatp
= curr_odat();
1042 curr_linkp
= alloc_link();
1044 /* Insert vlink into link_stack so that it gets processed at
1046 curr_linkp
->type
= 2;
1047 /* Store the target odat information*/
1048 curr_linkp
->link_t
.vlink
.refid
= refid
;
1049 u8_cpy(curr_linkp
->link_t
.vlink
.anim_name
, anim_name
, 32);
1050 /* Store the linking odat/cdat information */
1051 curr_linkp
->classp
= curr_cdatp
;
1052 curr_linkp
->odatp
= curr_odatp
;
1053 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
1054 // curr_linkp->ele_idx = -1;
1058 /* Svlinks dont have animation names */
1064 struct cdat
* curr_cdatp
;
1065 struct link
* curr_linkp
;
1067 curr_cdatp
= curr_cdat();
1068 curr_linkp
= alloc_link();
1070 /* Insert svlink into link_stack so that it gets processed at
1072 curr_linkp
->type
= 3;
1073 curr_linkp
->classp
= curr_cdatp
;
1074 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
1075 // curr_linkp->ele_idx = -1;
1076 curr_linkp
->link_t
.svlink
.refid
= refid
;
1080 /* At the point of reducing to a set, most of the
1081 sets odat information has already been populated
1082 during the reduction of its right hand side
1083 non terminals (hitbox, root, quad_list). */
1088 struct odat
* curr_odatp
;
1089 struct cdat
* curr_cdatp
;
1090 struct set
* curr_setp
;
1091 struct ref
* prev_refp
;
1092 struct ref
* curr_refp
;
1093 struct vdat
* curr_vdatp
;
1095 curr_odatp
= curr_set_odatp
; //allocated at insert_set_label
1096 curr_cdatp
= curr_cdat();
1097 curr_setp
= curr_set();
1098 prev_refp
= curr_ref();
1099 curr_refp
= alloc_ref();
1100 curr_vdatp
= curr_vdat();
1102 curr_vdatp
->creator
= curr_set_odatp
;
1104 curr_setp
->cdat_idx
= curr_cdatp
->idx
; //does a set need its class idx?
1105 u8_cpy(curr_setp
->name
, curr_odatp
->name
, 32);
1106 curr_cdatp
->num_sets
++;
1108 curr_odatp
->cdat_idx
= curr_cdatp
->idx
;
1109 curr_odatp
->refp
= curr_refp
;
1111 refid
= curr_setp
->refid
; // refid set by insert_set_label(name, refid)
1113 curr_refp
->refid
= refid
;
1114 curr_refp
->lastref
= prev_refp
;
1115 curr_refp
->odatp
= curr_odatp
;
1116 prev_refp
->nextref
= curr_refp
;
1121 /* Created as a seperate function, instead of setting the ODATS vdat_id and
1122 calling inc_vdat() inside of insert_set(), to account for the set reduction
1123 where a vdat is not created (o/v/svlinks). */
1128 struct vdat
* curr_vdatp
;
1130 curr_vdatp
= curr_vdat();
1132 curr_set_odatp
->vdat_id
= num_vdats
; //no vdat_id for odats that have vlinks/svlinks
1133 curr_set_odatp
->vdatp
= curr_vdatp
;
1134 curr_set_odatp
= NULL
; //This sets odat shouldnt be modified after populating odats vdat info
1137 /* Populates the odat name and refid for odat, allocate the odat here for the rest of
1138 the functions to use via curr_odat(). */
1145 struct odat
* curr_odatp
;
1147 curr_odatp
= alloc_odat();
1149 u8_cpy(curr_odatp
->name
, name
, 32);
1150 curr_odatp
->map
[0] = 0;
1153 curr_odatp
->refid
= refid
;
1155 curr_odatp
->refid
= ss_refid
++;
1159 /* We don't make an odat here, at output time we will resolve
1160 the refid to the corresponding odat. */
1166 /* Do nothing because we already know the refid that
1167 the odat needs for this element (in the quad_file) */
1176 struct cdat
* curr_cdatp
;
1177 struct set
* curr_setp
;
1178 struct link
* curr_linkp
;
1180 curr_cdatp
= curr_cdat();
1181 curr_setp
= curr_set();
1182 curr_linkp
= alloc_link();
1184 /* Insert vlink into link_stack so that it gets processed at
1186 curr_linkp
->classp
= curr_cdatp
;
1187 curr_linkp
->type
= 2;
1188 curr_linkp
->set_idx
= curr_cdatp
->num_sets
;
1189 //curr_linkp->ele_idx = curr_setp->num_ele;
1190 curr_linkp
->link_t
.vlink
.refid
= refid
;
1191 u8_cpy(curr_linkp
->link_t
.vlink
.anim_name
, anim_name
, 32);
1200 struct cdat
* curr_cdatp
;
1201 struct set
* curr_setp
;
1202 struct link
* curr_linkp
;
1204 curr_cdatp
= curr_cdat();
1205 curr_setp
= curr_set();
1206 curr_linkp
= alloc_link();
1208 curr_linkp
->classp
= curr_cdatp
;
1209 curr_linkp
->type
= 3;
1211 //curr_linkp->ele_idx = curr_setp->num_ele;
1212 curr_linkp
->link_t
.svlink
.refid
= refid
;
1217 //Insert element into odat_buf and cdatpages
1222 struct cdat
* curr_cdatp
;
1223 struct odat
* curr_odatp
;
1224 struct vdat
* curr_vdatp
;
1225 struct set
* curr_setp
;
1226 struct ele
* curr_elep
;
1227 struct ref
* curr_refp
;
1228 struct ref
* prev_refp
;
1231 curr_odatp
= curr_odat(); //malloced @ insert_ele_label
1232 curr_vdatp
= curr_vdat();
1233 curr_setp
= curr_set();
1234 prev_refp
= curr_ref();
1235 curr_refp
= alloc_ref();
1237 curr_vdatp
->creator
= curr_odatp
;
1239 /* Populate odat for ele */
1240 curr_odatp
->cdat_idx
= curr_cdatp
->idx
;
1241 curr_odatp
->refp
= curr_refp
;
1242 curr_odatp
->parent_odatp
= curr_set_odatp
;
1244 refid
= curr_odatp
->refid
;
1246 curr_refp
->refid
= refid
;
1247 curr_refp
->lastref
= prev_refp
;
1248 curr_refp
->odatp
= curr_odatp
;
1249 prev_refp
->nextref
= curr_refp
;
1256 { struct odat
* curr_odatp
;
1257 curr_odatp
= curr_odat();
1258 curr_odatp
->vdat_id
= num_vdats
;
1270 /* ( int x, int y, int z, int refid */
1273 /* struct quad* curr_quadp; */
1275 /* curr_quadp = curr_quad(); */
1277 /* curr_quadp->x = x; */
1278 /* curr_quadp->y = y; */
1279 /* curr_quadp->z = z; */
1280 /* curr_quadp->refid = refid; */
1286 /* /\* serting the hitbox into the set */
1287 /* odat. Elements that don't have */
1288 /* a hitbox will use the sets root. *\/ */
1293 /* { struct odat* curr_odatp; */
1295 /* curr_odatp = curr_odat(); */
1296 /* curr_odatp->hitbox = hitbox; */
1299 /* /\* Inserting the root into the set */
1300 /* odat. Elements that don't have */
1301 /* a root will use the sets root. *\/ */
1308 /* { struct odat* curr_odatp; */
1310 /* curr_odatp = curr_odat(); */
1311 /* curr_odatp->root.x = x; */
1312 /* curr_odatp->root.y = y; */
1313 /* curr_odatp->root.z = z; */
1320 /* insert_frame_pointer */
1321 /* ( uint8_t direction, */
1324 /* { struct model* curr_modelp; */
1326 /* curr_modelp = curr_model(); */
1328 /* curr_modelp->spritesheet[(int)direction].frames[curr_modelp->spritesheet[(int)direction].num_frames++] = frame; */